[PATCH 16/22] qemu: block: Add helper to add common properties for -blockdev configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The new helper replaces qemuBlockStorageSourceGetBlockdevFormatCommonProps
and the two inline instances generating the common properties for a
blockdev layer.

The new helper is to be used for both the format layer and the storage
backing layer, thus a new parameter 'effective' switches between the
modes.

Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx>
---
 src/qemu/qemu_block.c | 128 +++++++++++++++++++++++++++++-------------
 1 file changed, 88 insertions(+), 40 deletions(-)

diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 689eb535cb..aeb05a7f00 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -931,6 +931,90 @@ qemuBlockStorageSourceGetBlockdevGetCacheProps(virStorageSource *src,
 }


+/**
+ * qemuBlockStorageSourceAddBlockdevCommonProps:
+ * @props: JSON object to append the props to
+ * @src: storage source
+ * @nodename: nodename to use for @src
+ * @effective: Whether props for the effective(topmost) layer are to be formatted
+ *
+ * Add the common props (node name, read-only state, cache configuration, discard)
+ * to a JSON object for a -blockdev definition. If @effective is true,
+ * the props are configured for the topmost layer used to access the data,
+ * otherwise the props are configured for the storage protocol backing a format
+ * layer.
+ */
+static int
+qemuBlockStorageSourceAddBlockdevCommonProps(virJSONValue **props,
+                                             virStorageSource *src,
+                                             const char *nodename,
+                                             bool effective)
+{
+    virStorageType actualType = virStorageSourceGetActualType(src);
+    g_autoptr(virJSONValue) cache = NULL;
+    const char *detectZeroes = NULL;
+    const char *discard = NULL;
+    virTristateBool autoReadOnly = VIR_TRISTATE_BOOL_ABSENT;
+    virTristateBool readOnly = VIR_TRISTATE_BOOL_ABSENT;
+
+    if (qemuBlockNodeNameValidate(nodename) < 0)
+        return -1;
+
+    if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, &cache) < 0)
+        return -1;
+
+    if (effective) {
+        virDomainDiskDetectZeroes dz = virDomainDiskGetDetectZeroesMode(src->discard,
+                                                                        src->detect_zeroes);
+
+        if (src->discard != VIR_DOMAIN_DISK_DISCARD_DEFAULT)
+            discard = virDomainDiskDiscardTypeToString(src->discard);
+
+        if (dz != VIR_DOMAIN_DISK_DETECT_ZEROES_DEFAULT)
+            detectZeroes = virDomainDiskDetectZeroesTypeToString(dz);
+
+        autoReadOnly = VIR_TRISTATE_BOOL_ABSENT;
+        readOnly = virTristateBoolFromBool(src->readonly);
+    } else {
+        /* when passing a FD to qemu via the /dev/fdset mechanism qemu
+         * fetches the appropriate FD from the fdset by checking that it has
+         * the correct accessmode. Now with 'auto-read-only' in effect qemu
+         * wants to use a read-only FD first. If the user didn't pass multiple
+         * FDs the feature will not work regardless, so we'll not enable it. */
+        if ((actualType == VIR_STORAGE_TYPE_FILE || actualType == VIR_STORAGE_TYPE_BLOCK) &&
+            src->fdtuple && src->fdtuple->nfds == 1) {
+            autoReadOnly = VIR_TRISTATE_BOOL_ABSENT;
+
+            /* now we setup the normal readonly flag. If user requested write access honour it */
+            if (src->fdtuple->writable)
+                readOnly = VIR_TRISTATE_BOOL_NO;
+            else
+                readOnly = virTristateBoolFromBool(src->readonly);
+        } else {
+            autoReadOnly = VIR_TRISTATE_BOOL_YES;
+        }
+
+        discard = "unmap";
+    }
+
+    /* currently unhandled global properties:
+     * '*force-share': 'bool'
+     */
+
+    if (virJSONValueObjectAdd(props,
+                              "s:node-name", nodename,
+                              "T:read-only", readOnly,
+                              "T:auto-read-only", autoReadOnly,
+                              "S:discard", discard,
+                              "S:detect-zeroes", detectZeroes,
+                              "A:cache", &cache,
+                              NULL) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 /**
  * qemuBlockStorageSourceGetBackendProps:
  * @src: disk source
@@ -1265,52 +1349,16 @@ qemuBlockStorageSourceGetFormatQcow2Props(virStorageSource *src,
 }


-static virJSONValue *
-qemuBlockStorageSourceGetBlockdevFormatCommonProps(virStorageSource *src)
-{
-    const char *detectZeroes = NULL;
-    const char *discard = NULL;
-    virDomainDiskDetectZeroes detectZeroesMode = virDomainDiskGetDetectZeroesMode(src->discard,
-                                                                                  src->detect_zeroes);
-    g_autoptr(virJSONValue) props = NULL;
-    g_autoptr(virJSONValue) cache = NULL;
-
-    if (qemuBlockNodeNameValidate(qemuBlockStorageSourceGetFormatNodename(src)) < 0)
-        return NULL;
-
-    if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, &cache) < 0)
-        return NULL;
-
-    if (src->discard)
-        discard = virDomainDiskDiscardTypeToString(src->discard);
-
-    if (detectZeroesMode)
-        detectZeroes = virDomainDiskDetectZeroesTypeToString(detectZeroesMode);
-
-    /* currently unhandled global properties:
-     * '*force-share': 'bool'
-     */
-
-    if (virJSONValueObjectAdd(&props,
-                              "s:node-name", qemuBlockStorageSourceGetFormatNodename(src),
-                              "b:read-only", src->readonly,
-                              "S:discard", discard,
-                              "S:detect-zeroes", detectZeroes,
-                              "A:cache", &cache,
-                              NULL) < 0)
-        return NULL;
-
-    return g_steal_pointer(&props);
-}
-
-
 static virJSONValue *
 qemuBlockStorageSourceGetBlockdevFormatProps(virStorageSource *src)
 {
     const char *driver = NULL;
     g_autoptr(virJSONValue) props = NULL;

-    if (!(props = qemuBlockStorageSourceGetBlockdevFormatCommonProps(src)))
+    if (qemuBlockStorageSourceAddBlockdevCommonProps(&props,
+                                                     src,
+                                                     qemuBlockStorageSourceGetFormatNodename(src),
+                                                     true) < 0)
         return NULL;

     switch ((virStorageFileFormat) src->format) {
-- 
2.41.0




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux