summaryrefslogtreecommitdiff
path: root/blockdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'blockdev.c')
-rw-r--r--blockdev.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/blockdev.c b/blockdev.c
index d4b42403df..a8755bd908 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3214,7 +3214,9 @@ out:
}
void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
+ bool has_base_node, const char *base_node,
bool has_base, const char *base,
+ bool has_top_node, const char *top_node,
bool has_top, const char *top,
bool has_backing_file, const char *backing_file,
bool has_speed, int64_t speed,
@@ -3275,7 +3277,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
/* default top_bs is the active layer */
top_bs = bs;
- if (has_top && top) {
+ if (has_top_node && has_top) {
+ error_setg(errp, "'top-node' and 'top' are mutually exclusive");
+ goto out;
+ } else if (has_top_node) {
+ top_bs = bdrv_lookup_bs(NULL, top_node, errp);
+ if (top_bs == NULL) {
+ goto out;
+ }
+ if (!bdrv_chain_contains(bs, top_bs)) {
+ error_setg(errp, "'%s' is not in this backing file chain",
+ top_node);
+ goto out;
+ }
+ } else if (has_top && top) {
if (strcmp(bs->filename, top) != 0) {
top_bs = bdrv_find_backing_image(bs, top);
}
@@ -3288,7 +3303,20 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device,
assert(bdrv_get_aio_context(top_bs) == aio_context);
- if (has_base && base) {
+ if (has_base_node && has_base) {
+ error_setg(errp, "'base-node' and 'base' are mutually exclusive");
+ goto out;
+ } else if (has_base_node) {
+ base_bs = bdrv_lookup_bs(NULL, base_node, errp);
+ if (base_bs == NULL) {
+ goto out;
+ }
+ if (!bdrv_chain_contains(top_bs, base_bs)) {
+ error_setg(errp, "'%s' is not in this backing file chain",
+ base_node);
+ goto out;
+ }
+ } else if (has_base && base) {
base_bs = bdrv_find_backing_image(top_bs, base);
} else {
base_bs = bdrv_find_base(top_bs);