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) {
}
+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)
{
return;
virJSONValueFree(data->storageProps);
+ virJSONValueFree(data->storageSliceProps);
virJSONValueFree(data->formatProps);
virJSONValueFree(data->prmgrProps);
virJSONValueFree(data->authsecretProps);
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);
}
}
+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
{
if (qemuBlockStorageSourceAttachApplyStorageDeps(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyStorage(mon, data) < 0 ||
+ qemuBlockStorageSourceAttachApplyStorageSlice(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyFormatDeps(mon, data) < 0 ||
qemuBlockStorageSourceAttachApplyFormat(mon, data) < 0)
return -1;
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));
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 &&