]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: domain: skip chain detection to end of backing chain
authorPeter Krempa <pkrempa@redhat.com>
Fri, 29 Sep 2017 10:02:29 +0000 (12:02 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 3 Nov 2017 09:27:32 +0000 (10:27 +0100)
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

index 19e2af8070b2f22207c611dbfee86344a3fa3ec0..f063faaa67f4f628c8d349906a0a93db40ce1460 100644 (file)
@@ -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);