[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] blockdev: modify blockdev-change-medium to change non-removable
From: |
Denis Plotnikov |
Subject: |
[PATCH] blockdev: modify blockdev-change-medium to change non-removable device |
Date: |
Fri, 18 Oct 2019 15:09:50 +0300 |
The modification is useful to workaround exclusive file access restrictions,
e.g. to implement VM migration with shared disk stored on a storage with
the exclusive file opening model: a destination VM is started waiting for
incomming migration with a fake image drive, and later, on the last migration
phase, the fake image file is replaced with the real one.
Signed-off-by: Denis Plotnikov <address@hidden>
---
blockdev.c | 69 +++++++++++++++++++++++++++++++-------------
hmp.c | 2 ++
qapi/block-core.json | 7 +++--
qmp.c | 3 +-
4 files changed, 57 insertions(+), 24 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index d358169995..23f3465cfc 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2609,6 +2609,8 @@ void qmp_blockdev_change_medium(bool has_device, const
char *device,
bool has_format, const char *format,
bool has_read_only,
BlockdevChangeReadOnlyMode read_only,
+ bool has_medium_name,
+ const char *medium_name,
Error **errp)
{
BlockBackend *blk;
@@ -2667,29 +2669,56 @@ void qmp_blockdev_change_medium(bool has_device, const
char *device,
goto fail;
}
- rc = do_open_tray(has_device ? device : NULL,
- has_id ? id : NULL,
- false, &err);
- if (rc && rc != -ENOSYS) {
- error_propagate(errp, err);
- goto fail;
- }
- error_free(err);
- err = NULL;
+ if (blk_dev_has_removable_media(blk)) {
+ rc = do_open_tray(has_device ? device : NULL,
+ has_id ? id : NULL,
+ false, &err);
+ if (rc && rc != -ENOSYS) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+ error_free(err);
+ err = NULL;
- blockdev_remove_medium(has_device, device, has_id, id, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
+ blockdev_remove_medium(has_device, device, has_id, id, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
- qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
+ qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
+ if (err) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
+ } else {
+ if (!medium_name) {
+ error_setg(errp, "A medium name should be given");
+ goto fail;
+ }
- qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
+ if (runstate_is_running()) {
+ error_setg(errp, "Can't set a medium for non-removable device "
+ "in a running VM");
+ goto fail;
+ }
+
+ if (strlen(blk_name(blk))) {
+ error_setg(errp, "The device already has a medium");
+ goto fail;
+ }
+
+ if (blk_insert_bs(blk, medium_bs, &err) < 0) {
+ error_propagate(errp, err);
+ goto fail;
+ }
+
+ if (!monitor_add_blk(blk, medium_name, &err)) {
+ error_propagate(errp, err);
+ }
+ }
fail:
/* If the medium has been inserted, the device has its own reference, so
diff --git a/hmp.c b/hmp.c
index 8eec768088..fc7bac5b4b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1948,6 +1948,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
const char *target = qdict_get_str(qdict, "target");
const char *arg = qdict_get_try_str(qdict, "arg");
const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
+ const char *target_name = qdict_get_try_str(qdict, "target-name");
BlockdevChangeReadOnlyMode read_only_mode = 0;
Error *err = NULL;
@@ -1982,6 +1983,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
qmp_blockdev_change_medium(true, device, false, NULL, target,
!!arg, arg, !!read_only, read_only_mode,
+ !!target_name, target_name,
&err);
}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 7ccbfff9d0..f493a7c737 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4769,6 +4769,8 @@
# @read-only-mode: change the read-only mode of the device; defaults
# to 'retain'
#
+# @medium-name: drive-name when changing the media in non-removable devices
+# ignored when changing media in removable devices
# Since: 2.5
#
# Examples:
@@ -4807,9 +4809,8 @@
'*id': 'str',
'filename': 'str',
'*format': 'str',
- '*read-only-mode': 'BlockdevChangeReadOnlyMode' } }
-
-
+ '*read-only-mode': 'BlockdevChangeReadOnlyMode',
+ '*medium-name': 'str' } }
##
# @BlockErrorAction:
#
diff --git a/qmp.c b/qmp.c
index b92d62cd5f..c95831a49f 100644
--- a/qmp.c
+++ b/qmp.c
@@ -399,7 +399,8 @@ void qmp_change(const char *device, const char *target,
#endif
} else {
qmp_blockdev_change_medium(true, device, false, NULL, target,
- has_arg, arg, false, 0, errp);
+ has_arg, arg, false, 0, false, NULL,
+ errp);
}
}
--
2.17.0
- [PATCH] blockdev: modify blockdev-change-medium to change non-removable device,
Denis Plotnikov <=
- Re: [PATCH] blockdev: modify blockdev-change-medium to change non-removable device, Eric Blake, 2019/10/18
- Re: [PATCH] blockdev: modify blockdev-change-medium to change non-removable device, Max Reitz, 2019/10/18
- Re: [PATCH] blockdev: modify blockdev-change-medium to change non-removable device, Vladimir Sementsov-Ogievskiy, 2019/10/23
- Re: [PATCH] blockdev: modify blockdev-change-medium to change non-removable device, Vladimir Sementsov-Ogievskiy, 2019/10/23
- Re: [PATCH] blockdev: modify blockdev-change-medium to change non-removable device, Max Reitz, 2019/10/24