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:
Peter Krempa 2020-01-09 17:34:29 +01:00
parent 065e548ebf
commit 8e94e29010
11 changed files with 70 additions and 8 deletions

View File

@ -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;
}

View File

@ -78,4 +78,5 @@ qemuCheckpointDiscardDiskBitmaps(virStorageSourcePtr src,
const char *delbitmap,
const char *parentbitmap,
virJSONValuePtr actions,
const char *diskdst);
const char *diskdst,
GSList **reopenimages);

View File

@ -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);
}

View File

@ -20,3 +20,5 @@
}
}
]
reopen nodes:
libvirt-3-format

View File

@ -57,3 +57,6 @@
}
}
]
reopen nodes:
libvirt-3-format
libvirt-2-format

View File

@ -57,3 +57,5 @@
}
}
]
reopen nodes:
libvirt-2-format

View File

@ -21,3 +21,7 @@
}
}
]
reopen nodes:
libvirt-5-format
libvirt-4-format
libvirt-3-format

View File

@ -27,3 +27,5 @@
}
}
]
reopen nodes:
libvirt-3-format

View File

@ -30,3 +30,5 @@
}
}
]
reopen nodes:
libvirt-2-format

View File

@ -57,3 +57,5 @@
}
}
]
reopen nodes:
libvirt-2-format

View File

@ -21,3 +21,7 @@
}
}
]
reopen nodes:
libvirt-5-format
libvirt-4-format
libvirt-3-format