mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
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: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
065e548ebf
commit
8e94e29010
@ -155,7 +155,8 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
|
||||
const char *delbitmap,
|
||||
const char *parentbitmap,
|
||||
virJSONValuePtr actions,
|
||||
const char *diskdst)
|
||||
const char *diskdst,
|
||||
GSList **reopenimages)
|
||||
{
|
||||
virStorageSourcePtr n = src;
|
||||
|
||||
@ -235,6 +236,9 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
|
||||
srcbitmap->name) < 0)
|
||||
return -1;
|
||||
|
||||
if (n != src)
|
||||
*reopenimages = g_slist_prepend(*reopenimages, n);
|
||||
|
||||
n = n->backingStore;
|
||||
}
|
||||
|
||||
@ -250,9 +254,12 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
virQEMUDriverPtr driver = priv->driver;
|
||||
g_autoptr(virHashTable) blockNamedNodeData = NULL;
|
||||
int rc;
|
||||
int rc = -1;
|
||||
g_autoptr(virJSONValue) actions = NULL;
|
||||
size_t i;
|
||||
g_autoptr(GSList) reopenimages = NULL;
|
||||
g_autoptr(GSList) relabelimages = NULL;
|
||||
GSList *next;
|
||||
|
||||
if (!(actions = virJSONValueNewArray()))
|
||||
return -1;
|
||||
@ -284,16 +291,34 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
|
||||
|
||||
if (qemuCheckpointDiscardDiskBitmaps(domdisk->src, blockNamedNodeData,
|
||||
chkdisk->bitmap, parentbitmap,
|
||||
actions, domdisk->dst) < 0)
|
||||
actions, domdisk->dst,
|
||||
&reopenimages) < 0)
|
||||
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);
|
||||
rc = qemuMonitorTransaction(priv->mon, &actions);
|
||||
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
|
||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||
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,
|
||||
const char *delbitmap,
|
||||
const char *parentbitmap,
|
||||
virJSONValuePtr actions,
|
||||
const char *diskdst);
|
||||
const char *diskdst,
|
||||
GSList **reopenimages);
|
||||
|
@ -721,6 +721,9 @@ testQemuCheckpointDeleteMerge(const void *opaque)
|
||||
g_autoptr(virJSONValue) actions = NULL;
|
||||
g_autoptr(virJSONValue) nodedatajson = 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,
|
||||
checkpointDeletePrefix, data->name);
|
||||
@ -742,14 +745,26 @@ testQemuCheckpointDeleteMerge(const void *opaque)
|
||||
data->deletebitmap,
|
||||
data->parentbitmap,
|
||||
actions,
|
||||
"testdisk") < 0) {
|
||||
"testdisk",
|
||||
&reopenimages) < 0) {
|
||||
VIR_TEST_VERBOSE("failed to generate checkpoint delete transaction\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(actual = virJSONValueToString(actions, true)))
|
||||
if (virJSONValueToBuffer(actions, &buf, true) < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -20,3 +20,5 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-3-format
|
||||
|
@ -57,3 +57,6 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-3-format
|
||||
libvirt-2-format
|
||||
|
@ -57,3 +57,5 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-2-format
|
||||
|
@ -21,3 +21,7 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-5-format
|
||||
libvirt-4-format
|
||||
libvirt-3-format
|
||||
|
@ -27,3 +27,5 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-3-format
|
||||
|
@ -30,3 +30,5 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-2-format
|
||||
|
@ -57,3 +57,5 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-2-format
|
||||
|
@ -21,3 +21,7 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
reopen nodes:
|
||||
libvirt-5-format
|
||||
libvirt-4-format
|
||||
libvirt-3-format
|
||||
|
Loading…
Reference in New Issue
Block a user