提交 0e644e6e 编写于 作者: P Peter Krempa

qemu: Add support for slices of type 'storage'

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: NPeter Krempa <pkrempa@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 9b804ef5
...@@ -1423,11 +1423,16 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src, ...@@ -1423,11 +1423,16 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src,
virStorageSourcePtr backingStore) virStorageSourcePtr backingStore)
{ {
g_autoptr(virJSONValue) props = NULL; 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))) if (!(props = qemuBlockStorageSourceGetBlockdevFormatProps(src)))
return NULL; return NULL;
if (virJSONValueObjectAppendString(props, "file", src->nodestorage) < 0) if (virJSONValueObjectAppendString(props, "file", storagenode) < 0)
return NULL; return NULL;
if (backingStore) { if (backingStore) {
...@@ -1456,6 +1461,32 @@ qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src, ...@@ -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 void
qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data) qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
{ {
...@@ -1463,6 +1494,7 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data) ...@@ -1463,6 +1494,7 @@ qemuBlockStorageSourceAttachDataFree(qemuBlockStorageSourceAttachDataPtr data)
return; return;
virJSONValueFree(data->storageProps); virJSONValueFree(data->storageProps);
virJSONValueFree(data->storageSliceProps);
virJSONValueFree(data->formatProps); virJSONValueFree(data->formatProps);
virJSONValueFree(data->prmgrProps); virJSONValueFree(data->prmgrProps);
virJSONValueFree(data->authsecretProps); virJSONValueFree(data->authsecretProps);
...@@ -1513,6 +1545,13 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src, ...@@ -1513,6 +1545,13 @@ qemuBlockStorageSourceAttachPrepareBlockdev(virStorageSourcePtr src,
data->storageNodeName = src->nodestorage; data->storageNodeName = src->nodestorage;
data->formatNodeName = src->nodeformat; 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); return g_steal_pointer(&data);
} }
...@@ -1581,6 +1620,21 @@ qemuBlockStorageSourceAttachApplyFormat(qemuMonitorPtr mon, ...@@ -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: * qemuBlockStorageSourceAttachApply:
* @mon: monitor object * @mon: monitor object
...@@ -1600,6 +1654,7 @@ qemuBlockStorageSourceAttachApply(qemuMonitorPtr mon, ...@@ -1600,6 +1654,7 @@ qemuBlockStorageSourceAttachApply(qemuMonitorPtr mon,
{ {
if (qemuBlockStorageSourceAttachApplyStorageDeps(mon, data) < 0 || if (qemuBlockStorageSourceAttachApplyStorageDeps(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyStorage(mon, data) < 0 || qemuBlockStorageSourceAttachApplyStorage(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyStorageSlice(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyFormatDeps(mon, data) < 0 || qemuBlockStorageSourceAttachApplyFormatDeps(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyFormat(mon, data) < 0) qemuBlockStorageSourceAttachApplyFormat(mon, data) < 0)
return -1; return -1;
...@@ -1642,6 +1697,9 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon, ...@@ -1642,6 +1697,9 @@ qemuBlockStorageSourceAttachRollback(qemuMonitorPtr mon,
if (data->formatAttached) if (data->formatAttached)
ignore_value(qemuMonitorBlockdevDel(mon, data->formatNodeName)); ignore_value(qemuMonitorBlockdevDel(mon, data->formatNodeName));
if (data->storageSliceAttached)
ignore_value(qemuMonitorBlockdevDel(mon, data->storageSliceNodeName));
if (data->storageAttached) if (data->storageAttached)
ignore_value(qemuMonitorBlockdevDel(mon, data->storageNodeName)); ignore_value(qemuMonitorBlockdevDel(mon, data->storageNodeName));
...@@ -1689,6 +1747,14 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src, ...@@ -1689,6 +1747,14 @@ qemuBlockStorageSourceDetachPrepare(virStorageSourcePtr src,
data->formatAttached = true; data->formatAttached = true;
data->storageNodeName = src->nodestorage; data->storageNodeName = src->nodestorage;
data->storageAttached = true; 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 && if (src->pr &&
......
...@@ -82,6 +82,10 @@ struct qemuBlockStorageSourceAttachData { ...@@ -82,6 +82,10 @@ struct qemuBlockStorageSourceAttachData {
const char *storageNodeName; const char *storageNodeName;
bool storageAttached; bool storageAttached;
virJSONValuePtr storageSliceProps;
const char *storageSliceNodeName;
bool storageSliceAttached;
virJSONValuePtr formatProps; virJSONValuePtr formatProps;
const char *formatNodeName; const char *formatNodeName;
bool formatAttached; bool formatAttached;
......
...@@ -1316,6 +1316,7 @@ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver, ...@@ -1316,6 +1316,7 @@ qemuBlockJobProcessEventConcludedCreate(virQEMUDriverPtr driver,
backend->formatAttached = false; backend->formatAttached = false;
if (job->data.create.storage) { if (job->data.create.storage) {
backend->storageAttached = false; backend->storageAttached = false;
backend->storageSliceAttached = false;
VIR_FREE(backend->encryptsecretAlias); VIR_FREE(backend->encryptsecretAlias);
} }
......
...@@ -2411,6 +2411,14 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd, ...@@ -2411,6 +2411,14 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
VIR_FREE(tmp); 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 (data->formatProps) {
if (!(tmp = virJSONValueToString(data->formatProps, false))) if (!(tmp = virJSONValueToString(data->formatProps, false)))
return -1; return -1;
......
...@@ -16264,6 +16264,10 @@ qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk, ...@@ -16264,6 +16264,10 @@ qemuDomainPrepareStorageSourceBlockdev(virDomainDiskDefPtr disk,
src->nodestorage = g_strdup_printf("libvirt-%u-storage", src->id); src->nodestorage = g_strdup_printf("libvirt-%u-storage", src->id);
src->nodeformat = g_strdup_printf("libvirt-%u-format", 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) if (qemuDomainValidateStorageSource(src, priv->qemuCaps) < 0)
return -1; return -1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册