提交 8e94e290 编写于 作者: P Peter Krempa

qemu: checkpoint: Track and relabel images for bitmap merging

Allow qemu access to modify backing files in case when we want to delete
a checkpoint.

This patch adds tracking of which images need to be relabelled when
calculating the transaction, the code to relabel them and rollback.

To verify that stuff works we also output the list of images to relabel
into the test case output files in qemublocktest.
Signed-off-by: NPeter Krempa <pkrempa@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 065e548e
...@@ -155,7 +155,8 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, ...@@ -155,7 +155,8 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
const char *delbitmap, const char *delbitmap,
const char *parentbitmap, const char *parentbitmap,
virJSONValuePtr actions, virJSONValuePtr actions,
const char *diskdst) const char *diskdst,
GSList **reopenimages)
{ {
virStorageSourcePtr n = src; virStorageSourcePtr n = src;
...@@ -235,6 +236,9 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, ...@@ -235,6 +236,9 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
srcbitmap->name) < 0) srcbitmap->name) < 0)
return -1; return -1;
if (n != src)
*reopenimages = g_slist_prepend(*reopenimages, n);
n = n->backingStore; n = n->backingStore;
} }
...@@ -250,9 +254,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm, ...@@ -250,9 +254,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virQEMUDriverPtr driver = priv->driver; virQEMUDriverPtr driver = priv->driver;
g_autoptr(virHashTable) blockNamedNodeData = NULL; g_autoptr(virHashTable) blockNamedNodeData = NULL;
int rc; int rc = -1;
g_autoptr(virJSONValue) actions = NULL; g_autoptr(virJSONValue) actions = NULL;
size_t i; size_t i;
g_autoptr(GSList) reopenimages = NULL;
g_autoptr(GSList) relabelimages = NULL;
GSList *next;
if (!(actions = virJSONValueNewArray())) if (!(actions = virJSONValueNewArray()))
return -1; return -1;
...@@ -284,16 +291,34 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm, ...@@ -284,16 +291,34 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData, if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
chkdisk->bitmap, parentbitmap, chkdisk->bitmap, parentbitmap,
actions, domdisk->dst) < 0) actions, domdisk->dst,
&reopenimages) < 0)
return -1; return -1;
} }
/* label any non-top images for read-write access */
for (next = reopenimages; next; next = next->next) {
virStorageSourcePtr src = next->data;
if (qemuDomainStorageSourceAccessAllow(driver, vm, src, false, false) < 0)
goto relabel;
relabelimages = g_slist_prepend(relabelimages, src);
}
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorTransaction(priv->mon, &actions); rc = qemuMonitorTransaction(priv->mon, &actions);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) if (qemuDomainObjExitMonitor(driver, vm) < 0)
return -1; return -1;
return 0; relabel:
for (next = relabelimages; next; next = next->next) {
virStorageSourcePtr src = next->data;
ignore_value(qemuDomainStorageSourceAccessAllow(driver, vm, src, true, false));
}
return rc;
} }
......
...@@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src, ...@@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
const char *delbitmap, const char *delbitmap,
const char *parentbitmap, const char *parentbitmap,
virJSONValuePtr actions, virJSONValuePtr actions,
const char *diskdst); const char *diskdst,
GSList **reopenimages);
...@@ -721,6 +721,9 @@ testQemuCheckpointDeleteMerge(const void *opaque) ...@@ -721,6 +721,9 @@ testQemuCheckpointDeleteMerge(const void *opaque)
g_autoptr(virJSONValue) actions = NULL; g_autoptr(virJSONValue) actions = NULL;
g_autoptr(virJSONValue) nodedatajson = NULL; g_autoptr(virJSONValue) nodedatajson = NULL;
g_autoptr(virHashTable) nodedata = NULL; g_autoptr(virHashTable) nodedata = NULL;
g_autoptr(GSList) reopenimages = NULL;
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
GSList *tmp;
expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir, expectpath = g_strdup_printf("%s/%s%s-out.json", abs_srcdir,
checkpointDeletePrefix, data->name); checkpointDeletePrefix, data->name);
...@@ -742,14 +745,26 @@ testQemuCheckpointDeleteMerge(const void *opaque) ...@@ -742,14 +745,26 @@ testQemuCheckpointDeleteMerge(const void *opaque)
data->deletebitmap, data->deletebitmap,
data->parentbitmap, data->parentbitmap,
actions, actions,
"testdisk") < 0) { "testdisk",
&reopenimages) < 0) {
VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n"); VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
return -1; return -1;
} }
if (!(actual = virJSONValueToString(actions, true))) if (virJSONValueToBuffer(actions, &buf, true) < 0)
return -1; return -1;
if (reopenimages) {
virBufferAddLit(&buf, "reopen nodes:\n");
for (tmp = reopenimages; tmp; tmp = tmp->next) {
virStorageSourcePtr src = tmp->data;
virBufferAsprintf(&buf, "%s\n", src->nodeformat);
}
}
actual = virBufferContentAndReset(&buf);
return virTestCompareToFile(actual, expectpath); return virTestCompareToFile(actual, expectpath);
} }
......
...@@ -20,3 +20,5 @@ ...@@ -20,3 +20,5 @@
} }
} }
] ]
reopen nodes:
libvirt-3-format
...@@ -57,3 +57,6 @@ ...@@ -57,3 +57,6 @@
} }
} }
] ]
reopen nodes:
libvirt-3-format
libvirt-2-format
...@@ -57,3 +57,5 @@ ...@@ -57,3 +57,5 @@
} }
} }
] ]
reopen nodes:
libvirt-2-format
...@@ -21,3 +21,7 @@ ...@@ -21,3 +21,7 @@
} }
} }
] ]
reopen nodes:
libvirt-5-format
libvirt-4-format
libvirt-3-format
...@@ -27,3 +27,5 @@ ...@@ -27,3 +27,5 @@
} }
} }
] ]
reopen nodes:
libvirt-3-format
...@@ -30,3 +30,5 @@ ...@@ -30,3 +30,5 @@
} }
} }
] ]
reopen nodes:
libvirt-2-format
...@@ -57,3 +57,5 @@ ...@@ -57,3 +57,5 @@
} }
} }
] ]
reopen nodes:
libvirt-2-format
...@@ -21,3 +21,7 @@ ...@@ -21,3 +21,7 @@
} }
} }
] ]
reopen nodes:
libvirt-5-format
libvirt-4-format
libvirt-3-format
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册