libvirt/SOURCES/libvirt-qemu-Add-support-fo...

232 lines
8.3 KiB
Diff

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