From: Peter Krempa Date: Fri, 29 Sep 2017 10:02:29 +0000 (+0200) Subject: qemu: domain: skip chain detection to end of backing chain X-Git-Tag: v3.10.0-rc1~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a92c4f7537577f1443ddd6fef4e0dfcb054e5f08;p=thirdparty%2Flibvirt.git qemu: domain: skip chain detection to end of backing chain When a user provides the backing chain, we will not need to re-detect all the backing stores again, but should move to the end of the user specified chain. Additionally if a user provides a full terminated chain we should not attempt any further detection. --- diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 19e2af8070..f063faaa67 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6050,27 +6050,57 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, bool report_broken) { virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - int ret = 0; + virStorageSourcePtr src = disk->src; + int ret = -1; uid_t uid; gid_t gid; - if (virStorageSourceIsEmpty(disk->src)) + if (virStorageSourceIsEmpty(src)) { + ret = 0; goto cleanup; + } - if (virStorageSourceHasBacking(disk->src)) { - if (force_probe) - virStorageSourceBackingStoreClear(disk->src); - else - goto cleanup; + if (virStorageSourceHasBacking(src)) { + if (force_probe) { + virStorageSourceBackingStoreClear(src); + } else { + /* skip to the end of the chain */ + while (virStorageSourceIsBacking(src)) { + if (report_broken && + virStorageFileSupportsAccess(src)) { + + if (qemuDomainStorageFileInit(driver, vm, src, disk->src) < 0) + goto cleanup; + + if (virStorageFileAccess(src, F_OK) < 0) { + virStorageFileReportBrokenChain(errno, src, disk->src); + virStorageFileDeinit(src); + goto cleanup; + } + + virStorageFileDeinit(src); + } + src = src->backingStore; + } + } } - qemuDomainGetImageIds(cfg, vm, disk->src, NULL, &uid, &gid); + /* We skipped to the end of the chain. Skip detection if there's the + * terminator. (An allocated but empty backingStore) */ + if (src->backingStore) { + ret = 0; + goto cleanup; + } + + qemuDomainGetImageIds(cfg, vm, src, disk->src, &uid, &gid); - if (virStorageFileGetMetadata(disk->src, + if (virStorageFileGetMetadata(src, uid, gid, cfg->allowDiskFormatProbing, report_broken) < 0) - ret = -1; + goto cleanup; + + ret = 0; cleanup: virObjectUnref(cfg);