]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: block: Use simple backing stores string format if possible
authorPeter Krempa <pkrempa@redhat.com>
Mon, 22 Jul 2019 15:36:05 +0000 (17:36 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 25 Jul 2019 11:21:32 +0000 (13:21 +0200)
In case when the backing store can be represented with something
simpler such as a URI we can use it rather than falling back to the
json: pseudo-protocol.

In cases when it's not worth it (e.g. with the old ugly NBD or RBD
strings) let's switch to json.

The function is exported as we'll need it when overwriting the ugly
strings qemu would come up with during blockjobs.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_block.c
src/qemu/qemu_block.h
tests/qemublocktestdata/imagecreate/qcow2-backing-raw-nbd.json

index e47bc2d8f0f5b2badf9a47d470f0c3e4251f384d..47661fb8bdb4014a756d099c49b688cc5a7a83c1 100644 (file)
@@ -1923,15 +1923,80 @@ qemuBlockStorageGetCopyOnReadProps(virDomainDiskDefPtr disk)
 }
 
 
+/**
+ * qemuBlockGetBackingStoreString:
+ * @src: storage source to get the string for
+ *
+ * Formats a string used in the backing store field of a disk image which
+ * supports backing store. Non-local storage may result in use of the json:
+ * pseudo protocol for any complex configuration.
+ */
+char *
+qemuBlockGetBackingStoreString(virStorageSourcePtr src)
+{
+    int actualType = virStorageSourceGetActualType(src);
+    VIR_AUTOPTR(virJSONValue) backingProps = NULL;
+    VIR_AUTOPTR(virURI) uri = NULL;
+    VIR_AUTOFREE(char *) backingJSON = NULL;
+    char *ret = NULL;
+
+    if (virStorageSourceIsLocalStorage(src)) {
+        ignore_value(VIR_STRDUP(ret, src->path));
+        return ret;
+    }
+
+    /* generate simplified URIs for the easy cases */
+    if (actualType == VIR_STORAGE_TYPE_NETWORK &&
+        src->nhosts == 1 &&
+        src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
+
+        switch ((virStorageNetProtocol) src->protocol) {
+        case VIR_STORAGE_NET_PROTOCOL_NBD:
+        case VIR_STORAGE_NET_PROTOCOL_HTTP:
+        case VIR_STORAGE_NET_PROTOCOL_HTTPS:
+        case VIR_STORAGE_NET_PROTOCOL_FTP:
+        case VIR_STORAGE_NET_PROTOCOL_FTPS:
+        case VIR_STORAGE_NET_PROTOCOL_TFTP:
+        case VIR_STORAGE_NET_PROTOCOL_ISCSI:
+        case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
+            if (!(uri = qemuBlockStorageSourceGetURI(src)))
+                return NULL;
+
+            if (!(ret = virURIFormat(uri)))
+                return NULL;
+
+            return ret;
+
+        case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG:
+        case VIR_STORAGE_NET_PROTOCOL_RBD:
+        case VIR_STORAGE_NET_PROTOCOL_VXHS:
+        case VIR_STORAGE_NET_PROTOCOL_SSH:
+        case VIR_STORAGE_NET_PROTOCOL_LAST:
+        case VIR_STORAGE_NET_PROTOCOL_NONE:
+            break;
+        }
+    }
+
+    /* use json: pseudo protocol otherwise */
+    if (!(backingProps = qemuBlockStorageSourceGetBackendProps(src, false, true, false)))
+        return NULL;
+
+    if (!(backingJSON = virJSONValueToString(backingProps, false)))
+        return NULL;
+
+    if (virAsprintf(&ret, "json:%s", backingJSON) < 0)
+        return NULL;
+
+    return ret;
+}
+
+
 static int
 qemuBlockStorageSourceCreateAddBacking(virStorageSourcePtr backing,
                                        virJSONValuePtr props,
                                        bool format)
 {
-    VIR_AUTOPTR(virJSONValue) backingProps = NULL;
-    VIR_AUTOFREE(char *) backingJSON = NULL;
-    VIR_AUTOFREE(char *) backingPseudoprotocol = NULL;
-    const char *backingFileStr = NULL;
+    VIR_AUTOFREE(char *) backingFileStr = NULL;
     const char *backingFormatStr = NULL;
 
     if (!virStorageSourceIsBacking(backing))
@@ -1945,24 +2010,8 @@ qemuBlockStorageSourceCreateAddBacking(virStorageSourcePtr backing,
             backingFormatStr = virStorageFileFormatTypeToString(backing->format);
     }
 
-    if (virStorageSourceIsLocalStorage(backing)) {
-        backingFileStr = backing->path;
-    } else {
-        if (!(backingProps = qemuBlockStorageSourceGetBackendProps(backing, false,
-                                                                   true, false))) {
-            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-                           _("failed to generate backing file JSON properties"));
-            return -1;
-        }
-
-        if (!(backingJSON = virJSONValueToString(backingProps, false)))
-            return -1;
-
-        if (virAsprintf(&backingPseudoprotocol, "json:%s", backingJSON) < 0)
-            return -1;
-
-        backingFileStr = backingPseudoprotocol;
-    }
+    if (!(backingFileStr = qemuBlockGetBackingStoreString(backing)))
+        return -1;
 
     if (virJSONValueObjectAdd(props,
                               "S:backing-file", backingFileStr,
index 5fe5319ab931e592a23aa54b82ee174f157d0776..ab6b9dc7913e9eb7fafe189a5e14441e25c35f1d 100644 (file)
@@ -168,6 +168,10 @@ qemuBlockSnapshotAddBlockdev(virJSONValuePtr actions,
                              virDomainDiskDefPtr disk,
                              virStorageSourcePtr newsrc);
 
+char *
+qemuBlockGetBackingStoreString(virStorageSourcePtr src)
+    ATTRIBUTE_NONNULL(1);
+
 int
 qemuBlockStorageSourceCreateGetFormatProps(virStorageSourcePtr src,
                                            virStorageSourcePtr backing,
index 34ce74a54821ac6088caa3c75d9685ae0f9f7e46..b9d1d97302f4eec35d502dfb2c065f2015d35d16 100644 (file)
@@ -10,6 +10,6 @@ format:
   "driver": "qcow2",
   "file": "0123456789ABCDEF0123456789ABCDE",
   "size": 1337,
-  "backing-file": "json:{\"driver\":\"nbd\",\"server\":{\"type\":\"inet\",\"host\":\"example.com\",\"port\":\"1234\"}}",
+  "backing-file": "nbd://example.com:1234",
   "backing-fmt": "raw"
 }