43fe83
From 29271efbf03fa88b54090dca46c42304a28c2fc3 Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <29271efbf03fa88b54090dca46c42304a28c2fc3.1377873637.git.jdenemar@redhat.com>
43fe83
From: Guannan Ren <gren@redhat.com>
43fe83
Date: Thu, 8 Aug 2013 16:07:27 +0800
43fe83
Subject: [PATCH] qemu: add helper functions for diskchain checking
43fe83
43fe83
Resovles: https://bugzilla.redhat.com/show_bug.cgi?id=910171
43fe83
(cherry picked from commit d7b7aa2c206951bef3b1bfece656394d1775cb7d)
43fe83
43fe83
*src/util/virstoragefile.c: Add a helper function to get
43fe83
the first name of missing backing files, if the name is NULL,
43fe83
it means the diskchain is not broken.
43fe83
*src/qemu/qemu_domain.c: qemuDiskChainCheckBroken(disk) to
43fe83
check if its chain is broken
43fe83
---
43fe83
 src/libvirt_private.syms  |  1 +
43fe83
 src/qemu/qemu_domain.c    | 22 ++++++++++++++++++++++
43fe83
 src/qemu/qemu_domain.h    |  3 +++
43fe83
 src/util/virstoragefile.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
43fe83
 src/util/virstoragefile.h |  2 ++
43fe83
 5 files changed, 74 insertions(+)
43fe83
43fe83
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
43fe83
index 0247a46..9cfb84c 100644
43fe83
--- a/src/libvirt_private.syms
43fe83
+++ b/src/libvirt_private.syms
43fe83
@@ -1882,6 +1882,7 @@ virSocketAddrSetPort;
43fe83
 
43fe83
 
43fe83
 # util/virstoragefile.h
43fe83
+virStorageFileChainGetBroken;
43fe83
 virStorageFileChainLookup;
43fe83
 virStorageFileFeatureTypeFromString;
43fe83
 virStorageFileFeatureTypeToString;
43fe83
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
43fe83
index 13303da..fd62deb 100644
43fe83
--- a/src/qemu/qemu_domain.c
43fe83
+++ b/src/qemu/qemu_domain.c
43fe83
@@ -2228,6 +2228,28 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,
43fe83
 }
43fe83
 
43fe83
 int
43fe83
+qemuDiskChainCheckBroken(virDomainDiskDefPtr disk)
43fe83
+{
43fe83
+    char *brokenFile = NULL;
43fe83
+
43fe83
+    if (!disk->src || !disk->backingChain)
43fe83
+        return 0;
43fe83
+
43fe83
+    if (virStorageFileChainGetBroken(disk->backingChain, &brokenFile) < 0)
43fe83
+        return -1;
43fe83
+
43fe83
+    if (brokenFile) {
43fe83
+        virReportError(VIR_ERR_INVALID_ARG,
43fe83
+                       _("Backing file '%s' of image '%s' is missing."),
43fe83
+                       brokenFile, disk->src);
43fe83
+        VIR_FREE(brokenFile);
43fe83
+        return -1;
43fe83
+    }
43fe83
+
43fe83
+    return 0;
43fe83
+}
43fe83
+
43fe83
+int
43fe83
 qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
43fe83
                              virDomainDiskDefPtr disk,
43fe83
                              bool force)
43fe83
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
43fe83
index 9a959d6..0a4a51e 100644
43fe83
--- a/src/qemu/qemu_domain.h
43fe83
+++ b/src/qemu/qemu_domain.h
43fe83
@@ -347,6 +347,9 @@ bool qemuDomainJobAllowed(qemuDomainObjPrivatePtr priv,
43fe83
 int qemuDomainCheckDiskPresence(virQEMUDriverPtr driver,
43fe83
                                 virDomainObjPtr vm,
43fe83
                                 bool start_with_state);
43fe83
+
43fe83
+int qemuDiskChainCheckBroken(virDomainDiskDefPtr disk);
43fe83
+
43fe83
 int qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
43fe83
                                  virDomainDiskDefPtr disk,
43fe83
                                  bool force);
43fe83
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
43fe83
index cb6df91..0b9cec3 100644
43fe83
--- a/src/util/virstoragefile.c
43fe83
+++ b/src/util/virstoragefile.c
43fe83
@@ -572,6 +572,13 @@ virFindBackingFile(const char *start, bool start_is_dir, const char *path,
43fe83
         goto cleanup;
43fe83
     }
43fe83
 
43fe83
+    if (virFileAccessibleAs(combined, F_OK, getuid(), getgid()) < 0) {
43fe83
+        virReportSystemError(errno,
43fe83
+                             _("Cannot access backing file '%s'"),
43fe83
+                             combined);
43fe83
+        goto cleanup;
43fe83
+    }
43fe83
+
43fe83
     if (!(*canonical = canonicalize_file_name(combined))) {
43fe83
         virReportSystemError(errno,
43fe83
                              _("Can't canonicalize path '%s'"), path);
43fe83
@@ -1097,6 +1104,45 @@ virStorageFileGetMetadata(const char *path, int format,
43fe83
 }
43fe83
 
43fe83
 /**
43fe83
+ * virStorageFileChainCheckBroken
43fe83
+ *
43fe83
+ * If CHAIN is broken, set *brokenFile to the broken file name,
43fe83
+ * otherwise set it to NULL. Caller MUST free *brokenFile after use.
43fe83
+ * Return 0 on success, negative on error.
43fe83
+ */
43fe83
+int
43fe83
+virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
43fe83
+                             char **brokenFile)
43fe83
+{
43fe83
+    virStorageFileMetadataPtr tmp;
43fe83
+    int ret = -1;
43fe83
+
43fe83
+    if (!chain)
43fe83
+        return 0;
43fe83
+
43fe83
+    *brokenFile = NULL;
43fe83
+
43fe83
+    tmp = chain;
43fe83
+    while (tmp) {
43fe83
+        /* Break if no backing store or backing store is not file */
43fe83
+       if (!tmp->backingStoreRaw)
43fe83
+           break;
43fe83
+       if (!tmp->backingStore) {
43fe83
+           if (VIR_STRDUP(*brokenFile, tmp->backingStoreRaw) < 0)
43fe83
+               goto error;
43fe83
+           break;
43fe83
+       }
43fe83
+       tmp = tmp->backingMeta;
43fe83
+    }
43fe83
+
43fe83
+    ret = 0;
43fe83
+
43fe83
+error:
43fe83
+    return ret;
43fe83
+}
43fe83
+
43fe83
+
43fe83
+/**
43fe83
  * virStorageFileFreeMetadata:
43fe83
  *
43fe83
  * Free pointers in passed structure and structure itself.
43fe83
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
43fe83
index 4cb47e6..1f89839 100644
43fe83
--- a/src/util/virstoragefile.h
43fe83
+++ b/src/util/virstoragefile.h
43fe83
@@ -90,6 +90,8 @@ virStorageFileMetadataPtr virStorageFileGetMetadata(const char *path,
43fe83
 virStorageFileMetadataPtr virStorageFileGetMetadataFromFD(const char *path,
43fe83
                                                           int fd,
43fe83
                                                           int format);
43fe83
+int virStorageFileChainGetBroken(virStorageFileMetadataPtr chain,
43fe83
+                                 char **broken_file);
43fe83
 
43fe83
 const char *virStorageFileChainLookup(virStorageFileMetadataPtr chain,
43fe83
                                       const char *start,
43fe83
-- 
43fe83
1.8.3.2
43fe83