From a92c4f7537577f1443ddd6fef4e0dfcb054e5f08 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 29 Sep 2017 12:02:29 +0200 Subject: [PATCH] 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. --- src/qemu/qemu_domain.c | 52 +++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 11 deletions(-) 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; } - qemuDomainGetImageIds(cfg, vm, disk->src, NULL, &uid, &gid); + 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 (virStorageFileGetMetadata(disk->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; + } + } + } + + /* 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(src, uid, gid, cfg->allowDiskFormatProbing, report_broken) < 0) - ret = -1; + goto cleanup; + + ret = 0; cleanup: virObjectUnref(cfg);