From 7ce63d5a07c5798d295fed1731f6fd552c5d41cc Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 14 Dec 2022 15:35:29 +0100 Subject: [PATCH] qemu: Prepare storage backing chain traversal code for FD passed images We assume that FD passed images already exist so all existance checks are skipped. For the case that a FD-passed image is passed without a terminated backing chain (thus forcing us to detect) we attempt to read the header from the FD. Signed-off-by: Peter Krempa Reviewed-by: Pavel Hrdina --- src/qemu/qemu_domain.c | 23 ++++++++++++++--------- src/storage_file/storage_source.c | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9fd3c39646..00a54e18fe 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7611,16 +7611,20 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver, disksrc->format > VIR_STORAGE_FILE_NONE && disksrc->format < VIR_STORAGE_FILE_BACKING) { + /* terminate the chain for such images as the code below would do */ + if (!disksrc->backingStore) + disksrc->backingStore = virStorageSourceNew(); + + /* we assume that FD-passed disks always exist */ + if (virStorageSourceIsFD(disksrc)) + return 0; + if (!virFileExists(disksrc->path)) { virStorageSourceReportBrokenChain(errno, disksrc, disksrc); return -1; } - /* terminate the chain for such images as the code below would do */ - if (!disksrc->backingStore) - disksrc->backingStore = virStorageSourceNew(); - /* host cdrom requires special treatment in qemu, so we need to check * whether a block device is a cdrom */ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && @@ -7632,12 +7636,14 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver, return 0; } - src = disksrc; /* skip to the end of the chain if there is any */ - while (virStorageSourceHasBacking(src)) { - int rv = virStorageSourceSupportsAccess(src); + for (src = disksrc; virStorageSourceHasBacking(src); src = src->backingStore) { + int rv; - if (rv < 0) + if (virStorageSourceIsFD(src)) + continue; + + if ((rv = virStorageSourceSupportsAccess(src)) < 0) return -1; if (rv > 0) { @@ -7652,7 +7658,6 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver, virStorageSourceDeinit(src); } - src = src->backingStore; } /* We skipped to the end of the chain. Skip detection if there's the diff --git a/src/storage_file/storage_source.c b/src/storage_file/storage_source.c index 0db6e69591..baa182261f 100644 --- a/src/storage_file/storage_source.c +++ b/src/storage_file/storage_source.c @@ -1304,6 +1304,21 @@ virStorageSourceGetMetadataRecurseReadHeader(virStorageSource *src, int ret = -1; ssize_t len; + if (virStorageSourceIsFD(src)) { + if (!src->fdtuple) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("fd passed image source not initialized")); + return -1; + } + + if ((len = virFileReadHeaderFD(src->fdtuple->fds[0], + VIR_STORAGE_MAX_HEADER, buf)) < 0) + return -1; + + *headerLen = len; + return 0; + } + if (virStorageSourceInitAs(src, uid, gid) < 0) return -1;