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 <pkrempa@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Peter Krempa 2022-12-14 15:35:29 +01:00
parent 6f3d13bfbd
commit 7ce63d5a07
2 changed files with 29 additions and 9 deletions

View File

@ -7611,16 +7611,20 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver,
disksrc->format > VIR_STORAGE_FILE_NONE && disksrc->format > VIR_STORAGE_FILE_NONE &&
disksrc->format < VIR_STORAGE_FILE_BACKING) { 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)) { if (!virFileExists(disksrc->path)) {
virStorageSourceReportBrokenChain(errno, disksrc, disksrc); virStorageSourceReportBrokenChain(errno, disksrc, disksrc);
return -1; 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 /* host cdrom requires special treatment in qemu, so we need to check
* whether a block device is a cdrom */ * whether a block device is a cdrom */
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
@ -7632,12 +7636,14 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver,
return 0; return 0;
} }
src = disksrc;
/* skip to the end of the chain if there is any */ /* skip to the end of the chain if there is any */
while (virStorageSourceHasBacking(src)) { for (src = disksrc; virStorageSourceHasBacking(src); src = src->backingStore) {
int rv = virStorageSourceSupportsAccess(src); int rv;
if (rv < 0) if (virStorageSourceIsFD(src))
continue;
if ((rv = virStorageSourceSupportsAccess(src)) < 0)
return -1; return -1;
if (rv > 0) { if (rv > 0) {
@ -7652,7 +7658,6 @@ qemuDomainDetermineDiskChain(virQEMUDriver *driver,
virStorageSourceDeinit(src); virStorageSourceDeinit(src);
} }
src = src->backingStore;
} }
/* We skipped to the end of the chain. Skip detection if there's the /* We skipped to the end of the chain. Skip detection if there's the

View File

@ -1304,6 +1304,21 @@ virStorageSourceGetMetadataRecurseReadHeader(virStorageSource *src,
int ret = -1; int ret = -1;
ssize_t len; 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) if (virStorageSourceInitAs(src, uid, gid) < 0)
return -1; return -1;