]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
qemu: add helper functions for diskchain checking
authorGuannan Ren <gren@redhat.com>
Mon, 29 Jul 2013 12:51:15 +0000 (20:51 +0800)
committerGuannan Ren <gren@redhat.com>
Thu, 1 Aug 2013 05:26:27 +0000 (13:26 +0800)
*src/util/virstoragefile.c: Add a helper function to get
the first name of missing backing files, if the name is NULL,
it means the diskchain is not broken.
*src/qemu/qemu_domain.c: qemuDiskChainCheckBroken(disk) to
check if its chain is broken

src/libvirt_private.syms
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/util/virstoragefile.c
src/util/virstoragefile.h

index 6e6e280f8c46b1ae3ed0ceb1687301e2b8efb673..a958d94436874c5a20962fba2fd951a5a3a333c4 100644 (file)
@@ -1883,6 +1883,7 @@ virSocketAddrSetPort;
 
 
 # util/virstoragefile.h
+virStorageFileChainGetBroken;
 virStorageFileChainLookup;
 virStorageFileFeatureTypeFromString;
 virStorageFileFeatureTypeToString;
index 03a2aa6c73304266eaa2768ac1c6d7dbe553e627..be779918bdcf24b722ecbff733b70c87dd91471c 100644 (file)
@@ -2186,6 +2186,28 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,
     priv->ncleanupCallbacks_max = 0;
 }
 
+int
+qemuDiskChainCheckBroken(virDomainDiskDefPtr disk)
+{
+    char *brokenFile = NULL;
+
+    if (!disk->src || !disk->backingChain)
+        return 0;
+
+    if (virStorageFileChainGetBroken(disk->backingChain, &brokenFile) < 0)
+        return -1;
+
+    if (brokenFile) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Backing file '%s' of image '%s' is missing."),
+                       brokenFile, disk->src);
+        VIR_FREE(brokenFile);
+        return -1;
+    }
+
+    return 0;
+}
+
 int
 qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
                              virDomainDiskDefPtr disk,
index 9a959d6ec0e83884cbe707ce90947502ac880127..0a4a51ec4ea402b35d4f232f50264f4ca490ef1c 100644 (file)
@@ -347,6 +347,9 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
 int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
                                 virDomainObjPtr vm,
                                 bool start_with_state);
+
+int qemuDiskChainCheckBroken(virDomainDiskDefPtr disk);
+
 int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
                                  virDomainDiskDefPtr disk,
                                  bool force);
index cb6df91642aadf952c8abc7c2919e04a65d59985..0b9cec3b048decf8c1f9d2156350b1e00e22caad 100644 (file)
@@ -572,6 +572,13 @@ virFindBackingFile(const char *start, bool start_is_dir, const char *path,
         goto cleanup;
     }
 
+    if (virFileAccessibleAs(combined, F_OK, getuid(), getgid()) < 0) {
+        virReportSystemError(errno,
+                             _("Cannot access backing file '%s'"),
+                             combined);
+        goto cleanup;
+    }
+
     if (!(*canonical = canonicalize_file_name(combined))) {
         virReportSystemError(errno,
                              _("Can't canonicalize path '%s'"), path);
@@ -1096,6 +1103,45 @@ virStorageFileGetMetadata(const char *path, int format,
     return ret;
 }
 
+/**
+ * virStorageFileChainCheckBroken
+ *
+ * If CHAIN is broken, set *brokenFile to the broken file name,
+ * otherwise set it to NULL. Caller MUST free *brokenFile after use.
+ * Return 0 on success, negative on error.
+ */
+int
+virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
+                             char **brokenFile)
+{
+    virStorageFileMetadataPtr tmp;
+    int ret = -1;
+
+    if (!chain)
+        return 0;
+
+    *brokenFile = NULL;
+
+    tmp = chain;
+    while (tmp) {
+        /* Break if no backing store or backing store is not file */
+       if (!tmp->backingStoreRaw)
+           break;
+       if (!tmp->backingStore) {
+           if (VIR_STRDUP(*brokenFile, tmp->backingStoreRaw) < 0)
+               goto error;
+           break;
+       }
+       tmp = tmp->backingMeta;
+    }
+
+    ret = 0;
+
+error:
+    return ret;
+}
+
+
 /**
  * virStorageFileFreeMetadata:
  *
index 4cb47e62404f3eea9187c57a8dbd78bd9f3b8f85..1f89839b09799fde6537c18a0512fb9c6f2c60ce 100644 (file)
@@ -90,6 +90,8 @@ virStorageFileMetadataPtr virStorageFileGetMetadata(const char *path,
 virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
                                                           int fd,
                                                           int format);
+int virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
+                                 char **broken_file);
 
 const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
                                       const char *start,