qemu: block: Add support for passing FDs of disk images

Prepare the internal data for passing FDs instead of having qemu open
the file internally.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Peter Krempa 2022-05-02 18:42:40 +02:00
parent 81cbfc2fc3
commit 74f3f4b93c
2 changed files with 50 additions and 3 deletions

View File

@ -673,22 +673,47 @@ qemuBlockStorageSourceGetSshProps(virStorageSource *src)
static virJSONValue * static virJSONValue *
qemuBlockStorageSourceGetFileProps(virStorageSource *src, qemuBlockStorageSourceGetFileProps(virStorageSource *src,
bool onlytarget) bool onlytarget,
virTristateBool *autoReadOnly,
virTristateBool *readOnly)
{ {
const char *path = src->path;
const char *iomode = NULL; const char *iomode = NULL;
const char *prManagerAlias = NULL; const char *prManagerAlias = NULL;
virJSONValue *ret = NULL; virJSONValue *ret = NULL;
if (!onlytarget) { if (!onlytarget) {
qemuDomainStorageSourcePrivate *srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
if (src->pr) if (src->pr)
prManagerAlias = src->pr->mgralias; prManagerAlias = src->pr->mgralias;
if (src->iomode != VIR_DOMAIN_DISK_IO_DEFAULT) if (src->iomode != VIR_DOMAIN_DISK_IO_DEFAULT)
iomode = virDomainDiskIoTypeToString(src->iomode); iomode = virDomainDiskIoTypeToString(src->iomode);
if (srcpriv && srcpriv->fdpass) {
path = qemuFDPassGetPath(srcpriv->fdpass);
/* when passing a FD to qemu via the /dev/fdset mechanism qemu
* fetches the appropriate FD from the fdset by checking that it has
* the correct accessmode. Now with 'auto-read-only' in effect qemu
* wants to use a read-only FD first. If the user didn't pass multiple
* FDs the feature will not work regardless, so we'll disable it. */
if (src->fdtuple->nfds == 1) {
*autoReadOnly = VIR_TRISTATE_BOOL_ABSENT;
/* now we setup the normal readonly flag. If user requested write
* access honour it */
if (src->fdtuple->writable)
*readOnly = VIR_TRISTATE_BOOL_NO;
else
*readOnly = virTristateBoolFromBool(src->readonly);
}
}
} }
ignore_value(virJSONValueObjectAdd(&ret, ignore_value(virJSONValueObjectAdd(&ret,
"s:filename", src->path, "s:filename", path,
"S:aio", iomode, "S:aio", iomode,
"S:pr-manager", prManagerAlias, "S:pr-manager", prManagerAlias,
NULL) < 0); NULL) < 0);
@ -818,7 +843,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSource *src,
driver = "file"; driver = "file";
} }
if (!(fileprops = qemuBlockStorageSourceGetFileProps(src, onlytarget))) if (!(fileprops = qemuBlockStorageSourceGetFileProps(src, onlytarget, &aro, &ro)))
return NULL; return NULL;
break; break;

View File

@ -2146,6 +2146,25 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommand *cmd,
} }
static int
qemuBuildDiskSourceCommandLineFDs(virCommand *cmd,
virDomainDiskDef *disk)
{
virStorageSource *n;
for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
qemuDomainStorageSourcePrivate *srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(n);
if (!srcpriv || !srcpriv->fdpass)
continue;
qemuFDPassTransferCommand(srcpriv->fdpass, cmd);
}
return 0;
}
static int static int
qemuBuildDiskSourceCommandLine(virCommand *cmd, qemuBuildDiskSourceCommandLine(virCommand *cmd,
virDomainDiskDef *disk, virDomainDiskDef *disk,
@ -2163,6 +2182,9 @@ qemuBuildDiskSourceCommandLine(virCommand *cmd,
if (virStorageSourceIsEmpty(disk->src)) if (virStorageSourceIsEmpty(disk->src))
return 0; return 0;
if (qemuBuildDiskSourceCommandLineFDs(cmd, disk) < 0)
return -1;
if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src))) if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src)))
return -1; return -1;