render / rpms / libvirt

Forked from rpms/libvirt 5 months ago
Clone
a41c76
From 9d2cbc9ca4405fcf11e5796414af0038eb7c7f9e Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <9d2cbc9ca4405fcf11e5796414af0038eb7c7f9e@dist-git>
a41c76
From: Peter Krempa <pkrempa@redhat.com>
a41c76
Date: Wed, 19 Feb 2020 15:10:24 +0100
a41c76
Subject: [PATCH] qemu: Add support for slices of type 'storage'
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
Implement support for the slice of type 'storage' which allows to set
a41c76
the offset and size which modifies where qemu should look for the start
a41c76
of the format container inside the image.
a41c76
a41c76
Since slicing is done using the 'raw' driver we need to add another
a41c76
layer into the blockdev tree if there's any non-raw image format driver
a41c76
used to access the data.
a41c76
a41c76
This patch adds the blockdev integration and setup of the image data so
a41c76
that we can use the slices for any backing image.
a41c76
a41c76
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
(cherry picked from commit 0e644e6e47a48830dc10b090a999d4ba2e7d5394)
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1791788
a41c76
Message-Id: <1f8e63abfd1836f1df91f54cf2c018a7d5047825.1582120424.git.pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_block.c    | 68 +++++++++++++++++++++++++++++++++++++++-
a41c76
 src/qemu/qemu_block.h    |  4 +++
a41c76
 src/qemu/qemu_blockjob.c |  1 +
a41c76
 src/qemu/qemu_command.c  |  8 +++++
a41c76
 src/qemu/qemu_domain.c   |  4 +++
a41c76
 5 files changed, 84 insertions(+), 1 deletion(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
a41c76
index 387a2db2e6..5bd5c955a4 100644
a41c76
--- a/src/qemu/qemu_block.c
a41c76
+++ b/src/qemu/qemu_block.c
a41c76
@@ -1423,11 +1423,16 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src,
a41c76
                                        virStorageSourcePtr backingStore)
a41c76
 {
a41c76
     g_autoptr(virJSONValue) props = NULL;
a41c76
+    const char *storagenode = src->nodestorage;
a41c76
+
a41c76
+    if (src->sliceStorage &&
a41c76
+        src->format != VIR_STORAGE_FILE_RAW)
a41c76
+        storagenode = src->sliceStorage->nodename;
a41c76
 
a41c76
     if (!(props = qemuBlockStorageSourceGetBlockdevFormatProps(src)))
a41c76
         return NULL;
a41c76
 
a41c76
-    if (virJSONValueObjectAppendString(props, "file", src->nodestorage) < 0)
a41c76
+    if (virJSONValueObjectAppendString(props, "file", storagenode) < 0)
a41c76
         return NULL;
a41c76
 
a41c76
     if (backingStore) {
a41c76
@@ -1456,6 +1461,32 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+static virJSONValuePtr
a41c76
+qemuBlockStorageSourceGetBlockdevStorageSliceProps(virStorageSourcePtr src)
a41c76
+{
a41c76
+    g_autoptr(virJSONValue) props = NULL;
a41c76
+
a41c76
+    if (qemuBlockNodeNameValidate(src->sliceStorage->nodename) < 0)
a41c76
+        return NULL;
a41c76
+
a41c76
+    if (virJSONValueObjectCreate(&props,
a41c76
+                                 "s:driver", "raw",
a41c76
+                                 "s:node-name", src->sliceStorage->nodename,
a41c76
+                                 "U:offset", src->sliceStorage->offset,
a41c76
+                                 "U:size", src->sliceStorage->size,
a41c76
+                                 "s:file", src->nodestorage,
a41c76
+                                 "b:auto-read-only", true,
a41c76
+                                 "s:discard", "unmap",
a41c76
+                                 NULL) < 0)
a41c76
+        return NULL;
a41c76
+
a41c76
+    if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, props) < 0)
a41c76
+        return NULL;
a41c76
+
a41c76
+    return g_steal_pointer(&props;;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 void
a41c76
 qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
a41c76
 {
a41c76
@@ -1463,6 +1494,7 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
a41c76
         return;
a41c76
 
a41c76
     virJSONValueFree(data->storageProps);
a41c76
+    virJSONValueFree(data->storageSliceProps);
a41c76
     virJSONValueFree(data->formatProps);
a41c76
     virJSONValueFree(data->prmgrProps);
a41c76
     virJSONValueFree(data->authsecretProps);
a41c76
@@ -1513,6 +1545,13 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src,
a41c76
     data->storageNodeName = src->nodestorage;
a41c76
     data->formatNodeName = src->nodeformat;
a41c76
 
a41c76
+    if (src->sliceStorage && src->format != VIR_STORAGE_FILE_RAW) {
a41c76
+        if (!(data->storageSliceProps = qemuBlockStorageSourceGetBlockdevStorageSliceProps(src)))
a41c76
+            return NULL;
a41c76
+
a41c76
+        data->storageSliceNodeName = src->sliceStorage->nodename;
a41c76
+    }
a41c76
+
a41c76
     return g_steal_pointer(&data);
a41c76
 }
a41c76
 
a41c76
@@ -1581,6 +1620,21 @@ qemuBlockStorageSourceAttachApplyFormat(qemuMonitorPtr mon,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+static int
a41c76
+qemuBlockStorageSourceAttachApplyStorageSlice(qemuMonitorPtr mon,
a41c76
+                                              qemuBlockStorageSourceAttachDataPtr data)
a41c76
+{
a41c76
+    if (data->storageSliceProps) {
a41c76
+        if (qemuMonitorBlockdevAdd(mon, &data->storageSliceProps) < 0)
a41c76
+            return -1;
a41c76
+
a41c76
+        data->storageSliceAttached = true;
a41c76
+    }
a41c76
+
a41c76
+    return 0;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 /**
a41c76
  * qemuBlockStorageSourceAttachApply:
a41c76
  * @mon: monitor object
a41c76
@@ -1600,6 +1654,7 @@ qemuBlockStorageSourceAttachApply(qemuMonitorPtr mon,
a41c76
 {
a41c76
     if (qemuBlockStorageSourceAttachApplyStorageDeps(mon, data) < 0 ||
a41c76
         qemuBlockStorageSourceAttachApplyStorage(mon, data) < 0 ||
a41c76
+        qemuBlockStorageSourceAttachApplyStorageSlice(mon, data) < 0 ||
a41c76
         qemuBlockStorageSourceAttachApplyFormatDeps(mon, data) < 0 ||
a41c76
         qemuBlockStorageSourceAttachApplyFormat(mon, data) < 0)
a41c76
         return -1;
a41c76
@@ -1642,6 +1697,9 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon,
a41c76
     if (data->formatAttached)
a41c76
         ignore_value(qemuMonitorBlockdevDel(mon, data->formatNodeName));
a41c76
 
a41c76
+    if (data->storageSliceAttached)
a41c76
+        ignore_value(qemuMonitorBlockdevDel(mon, data->storageSliceNodeName));
a41c76
+
a41c76
     if (data->storageAttached)
a41c76
         ignore_value(qemuMonitorBlockdevDel(mon, data->storageNodeName));
a41c76
 
a41c76
@@ -1689,6 +1747,14 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
a41c76
         data->formatAttached = true;
a41c76
         data->storageNodeName = src->nodestorage;
a41c76
         data->storageAttached = true;
a41c76
+
a41c76
+        /* 'raw' format doesn't need the extra 'raw' layer when slicing, thus
a41c76
+         * the nodename is NULL */
a41c76
+        if (src->sliceStorage &&
a41c76
+            src->sliceStorage->nodename) {
a41c76
+            data->storageSliceNodeName = src->sliceStorage->nodename;
a41c76
+            data->storageSliceAttached = true;
a41c76
+        }
a41c76
     }
a41c76
 
a41c76
     if (src->pr &&
a41c76
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
a41c76
index a816190bb7..eab0128d5d 100644
a41c76
--- a/src/qemu/qemu_block.h
a41c76
+++ b/src/qemu/qemu_block.h
a41c76
@@ -82,6 +82,10 @@ struct qemuBlockStorageSourceAttachData {
a41c76
     const char *storageNodeName;
a41c76
     bool storageAttached;
a41c76
 
a41c76
+    virJSONValuePtr storageSliceProps;
a41c76
+    const char *storageSliceNodeName;
a41c76
+    bool storageSliceAttached;
a41c76
+
a41c76
     virJSONValuePtr formatProps;
a41c76
     const char *formatNodeName;
a41c76
     bool formatAttached;
a41c76
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
a41c76
index 6b59bbeb2c..71df0d1ab2 100644
a41c76
--- a/src/qemu/qemu_blockjob.c
a41c76
+++ b/src/qemu/qemu_blockjob.c
a41c76
@@ -1316,6 +1316,7 @@ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
a41c76
     backend->formatAttached = false;
a41c76
     if (job->data.create.storage) {
a41c76
         backend->storageAttached = false;
a41c76
+        backend->storageSliceAttached = false;
a41c76
         VIR_FREE(backend->encryptsecretAlias);
a41c76
     }
a41c76
 
a41c76
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
a41c76
index 1a5142d472..252809a8d7 100644
a41c76
--- a/src/qemu/qemu_command.c
a41c76
+++ b/src/qemu/qemu_command.c
a41c76
@@ -2427,6 +2427,14 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
a41c76
         VIR_FREE(tmp);
a41c76
     }
a41c76
 
a41c76
+    if (data->storageSliceProps) {
a41c76
+        if (!(tmp = virJSONValueToString(data->storageSliceProps, false)))
a41c76
+            return -1;
a41c76
+
a41c76
+        virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
a41c76
+        VIR_FREE(tmp);
a41c76
+    }
a41c76
+
a41c76
     if (data->formatProps) {
a41c76
         if (!(tmp = virJSONValueToString(data->formatProps, false)))
a41c76
             return -1;
a41c76
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
a41c76
index 948bf3011c..0baa80582c 100644
a41c76
--- a/src/qemu/qemu_domain.c
a41c76
+++ b/src/qemu/qemu_domain.c
a41c76
@@ -16444,6 +16444,10 @@ qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk,
a41c76
     src->nodestorage = g_strdup_printf("libvirt-%u-storage", src->id);
a41c76
     src->nodeformat = g_strdup_printf("libvirt-%u-format", src->id);
a41c76
 
a41c76
+    if (src->sliceStorage &&
a41c76
+        src->format != VIR_STORAGE_FILE_RAW)
a41c76
+        src->sliceStorage->nodename = g_strdup_printf("libvirt-%u-slice-sto", src->id);
a41c76
+
a41c76
     if (qemuDomainValidateStorageSource(src, priv->qemuCaps) < 0)
a41c76
         return -1;
a41c76
 
a41c76
-- 
a41c76
2.25.0
a41c76