232 lines
8.3 KiB
Diff
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
|
|
|