aboutsummaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/blockdev.c b/blockdev.c
index 69b7c2a8c5..79ce52b58b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1913,7 +1913,8 @@ void qmp_block_stream(const char *device, bool has_base,
}
void qmp_block_commit(const char *device,
- bool has_base, const char *base, const char *top,
+ bool has_base, const char *base,
+ bool has_top, const char *top,
bool has_speed, int64_t speed,
Error **errp)
{
@@ -1932,6 +1933,11 @@ void qmp_block_commit(const char *device,
/* drain all i/o before commits */
bdrv_drain_all();
+ /* Important Note:
+ * libvirt relies on the DeviceNotFound error class in order to probe for
+ * live commit feature versions; for this to work, we must make sure to
+ * perform the device lookup before any generic errors that may occur in a
+ * scenario in which all optional arguments are omitted. */
bs = bdrv_find(device);
if (!bs) {
error_set(errp, QERR_DEVICE_NOT_FOUND, device);
@@ -1945,7 +1951,7 @@ void qmp_block_commit(const char *device,
/* default top_bs is the active layer */
top_bs = bs;
- if (top) {
+ if (has_top && top) {
if (strcmp(bs->filename, top) != 0) {
top_bs = bdrv_find_backing_image(bs, top);
}
@@ -1967,6 +1973,12 @@ void qmp_block_commit(const char *device,
return;
}
+ /* Do not allow attempts to commit an image into itself */
+ if (top_bs == base_bs) {
+ error_setg(errp, "cannot commit an image into itself");
+ return;
+ }
+
if (top_bs == bs) {
commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
bs, &local_err);