[libvirt] [PATCH 1/5] conf: provide details on network backing store

Eric Blake eblake at redhat.com
Thu Apr 10 03:41:34 UTC 2014


So far, my work has been merely preserving the status quo of
backing file analysis.  But this patch starts to tread in the
territory of making the backing chain code more powerful - we
will eventually support network storage containing non-raw
formats.  Here, we expose metadata information about a network
backing store, even if that information is still hardcoded to
a raw format for now.

* src/util/virstoragefile.c (virStorageFileGetMetadataRecurse):
Also populate struct for non-file backing.
(virStorageFileGetMetadata, virStorageFileGetMetadatainternal):
Recognize non-file top image.
(virFindBackingFile): Add comment.
* tests/virstoragetest.c (mymain): Update test to reflect it.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 src/util/virstoragefile.c | 62 +++++++++++++++++++++++++++++++++++------------
 tests/virstoragetest.c    | 17 +++++++++----
 2 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index f5fe8ad..7a91a01 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -569,6 +569,14 @@ static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
 virFindBackingFile(const char *start, const char *path,
                    char **directory, char **canonical)
 {
+    /* FIXME - when we eventually allow non-raw network devices, we
+     * must ensure that we handle backing files the same way as qemu.
+     * For a qcow2 top file of gluster://server/vol/img, qemu treats
+     * the relative backing file 'rel' as meaning
+     * 'gluster://server/vol/rel', while the backing file '/abs' is
+     * used as a local file.  But we cannot canonicalize network
+     * devices via canonicalize_file_name(), because they are not part
+     * of the local file system.  */
     char *combined = NULL;
     int ret = -1;

@@ -874,6 +882,12 @@ virStorageFileGetMetadataInternal(const char *path,
                              meta->backingStoreRaw, path);

                 }
+            } else {
+                if (VIR_STRDUP(meta->backingStoreRaw, backing) < 0) {
+                    VIR_FREE(backing);
+                    goto cleanup;
+                }
+                backingFormat = VIR_STORAGE_FILE_RAW;
             }
             VIR_FREE(backing);
             meta->backingStoreFormat = backingFormat;
@@ -1132,18 +1146,32 @@ virStorageFileGetMetadataRecurse(const char *path, const char *canonPath,
     if (virHashAddEntry(cycle, canonPath, (void *)1) < 0)
         return -1;

-    if ((fd = virFileOpenAs(canonPath, O_RDONLY, 0, uid, gid, 0)) < 0) {
-        virReportSystemError(-fd, _("Failed to open file '%s'"), path);
-        return -1;
-    }
+    if (virBackingStoreIsFile(path)) {
+        if ((fd = virFileOpenAs(canonPath, O_RDONLY, 0, uid, gid, 0)) < 0) {
+            virReportSystemError(-fd, _("Failed to open file '%s'"), path);
+            return -1;
+        }

-    ret = virStorageFileGetMetadataFromFDInternal(path, canonPath, directory,
-                                                  fd, format, meta);
+        ret = virStorageFileGetMetadataFromFDInternal(path, canonPath,
+                                                      directory,
+                                                      fd, format, meta);

-    if (VIR_CLOSE(fd) < 0)
-        VIR_WARN("could not close file %s", path);
+        if (VIR_CLOSE(fd) < 0)
+            VIR_WARN("could not close file %s", path);
+    } else {
+        /* FIXME: when the proper storage drivers are compiled in, it
+         * would be nice to read metadata from the network storage to
+         * allow for non-raw images.  */
+        if (VIR_STRDUP(meta->path, path) < 0)
+            return -1;
+        if (VIR_STRDUP(meta->canonPath, path) < 0)
+            return -1;
+        meta->type = VIR_STORAGE_TYPE_NETWORK;
+        meta->format = VIR_STORAGE_FILE_RAW;
+        ret = 0;
+    }

-    if (ret == 0 && meta->backingStoreIsFile) {
+    if (ret == 0 && meta->backingStore) {
         virStorageFileMetadataPtr backing;

         if (meta->backingStoreFormat == VIR_STORAGE_FILE_AUTO && !allow_probe)
@@ -1207,12 +1235,16 @@ virStorageFileGetMetadata(const char *path, int format,
     if (!cycle)
         return NULL;

-    if (!(canonPath = canonicalize_file_name(path))) {
-        virReportSystemError(errno, _("unable to resolve '%s'"), path);
-        goto cleanup;
-    }
-    if (!(directory = mdir_name(path))) {
-        virReportOOMError();
+    if (virBackingStoreIsFile(path)) {
+        if (!(canonPath = canonicalize_file_name(path))) {
+            virReportSystemError(errno, _("unable to resolve '%s'"), path);
+            goto cleanup;
+        }
+        if (!(directory = mdir_name(path))) {
+            virReportOOMError();
+            goto cleanup;
+        }
+    } else if (VIR_STRDUP(canonPath, path) < 0) {
         goto cleanup;
     }
     if (VIR_ALLOC(meta) < 0)
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index 9a9b0d8..e8409f6 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -621,17 +621,24 @@ mymain(void)
     if (virCommandRun(cmd, NULL) < 0)
         ret = -1;
     qcow2.expBackingStore = "nbd:example.org:6000";
-    qcow2.expBackingStoreRaw = NULL;
+    qcow2.expBackingStoreRaw = "nbd:example.org:6000";
     qcow2.expBackingDirRel = NULL;
     qcow2.expBackingDirAbs = NULL;
     qcow2.expBackingFormat = VIR_STORAGE_FILE_RAW;

     /* Qcow2 file with backing protocol instead of file */
+    testFileData nbd = {
+        .pathRel = "nbd:example.org:6000",
+        .pathAbs = "nbd:example.org:6000",
+        .canonPath = "nbd:example.org:6000",
+        .type = VIR_STORAGE_TYPE_NETWORK,
+        .format = VIR_STORAGE_FILE_RAW,
+    };
     TEST_CHAIN(11, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2,
-               (&qcow2), EXP_PASS,
-               (&qcow2), ALLOW_PROBE | EXP_PASS,
-               (&qcow2), EXP_PASS,
-               (&qcow2), ALLOW_PROBE | EXP_PASS);
+               (&qcow2, &nbd), EXP_PASS,
+               (&qcow2, &nbd), ALLOW_PROBE | EXP_PASS,
+               (&qcow2, &nbd), EXP_PASS,
+               (&qcow2, &nbd), ALLOW_PROBE | EXP_PASS);

     /* qed file */
     testFileData qed = {
-- 
1.9.0




More information about the libvir-list mailing list