From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55828) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9cr-0001Vn-FU for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:10:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zw9cq-0004Ad-3h for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:10:21 -0500 From: Kevin Wolf Date: Tue, 10 Nov 2015 15:09:14 +0100 Message-Id: <1447164580-31094-15-git-send-email-kwolf@redhat.com> In-Reply-To: <1447164580-31094-1-git-send-email-kwolf@redhat.com> References: <1447164580-31094-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PULL v2 14/40] blockdev: read-only-mode for blockdev-change-medium List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org From: Max Reitz Add an option to qmp_blockdev_change_medium() which allows changing the read-only status of the block device whose medium is changed. Some drives do not have a inherently fixed read-only status; for instance, floppy disks can be set read-only or writable independently of the drive. Some users may find it useful to be able to therefore change the read-only status of a block device when changing the medium. Signed-off-by: Max Reitz Signed-off-by: Kevin Wolf --- blockdev.c | 22 ++++++++++++++++++++++ hmp.c | 2 +- qapi/block-core.json | 24 +++++++++++++++++++++++- qmp-commands.hx | 24 +++++++++++++++++++++++- qmp.c | 3 ++- 5 files changed, 71 insertions(+), 4 deletions(-) diff --git a/blockdev.c b/blockdev.c index b3a958c..34f6e5b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2145,6 +2145,8 @@ void qmp_blockdev_insert_medium(const char *device, const char *node_name, void qmp_blockdev_change_medium(const char *device, const char *filename, bool has_format, const char *format, + bool has_read_only, + BlockdevChangeReadOnlyMode read_only, Error **errp) { BlockBackend *blk; @@ -2166,6 +2168,26 @@ void qmp_blockdev_change_medium(const char *device, const char *filename, bdrv_flags = blk_get_open_flags_from_root_state(blk); + if (!has_read_only) { + read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN; + } + + switch (read_only) { + case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN: + break; + + case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY: + bdrv_flags &= ~BDRV_O_RDWR; + break; + + case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE: + bdrv_flags |= BDRV_O_RDWR; + break; + + default: + abort(); + } + if (has_format) { options = qdict_new(); qdict_put(options, "driver", qstring_from_str(format)); diff --git a/hmp.c b/hmp.c index 5e5358f..efa07a2 100644 --- a/hmp.c +++ b/hmp.c @@ -1348,7 +1348,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) } qmp_change("vnc", target, !!arg, arg, &err); } else { - qmp_blockdev_change_medium(device, target, !!arg, arg, &err); + qmp_blockdev_change_medium(device, target, !!arg, arg, false, 0, &err); if (err && error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) { error_free(err); diff --git a/qapi/block-core.json b/qapi/block-core.json index e9fa649..fa08ba9 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1959,6 +1959,24 @@ ## +# @BlockdevChangeReadOnlyMode: +# +# Specifies the new read-only mode of a block device subject to the +# @blockdev-change-medium command. +# +# @retain: Retains the current read-only mode +# +# @read-only: Makes the device read-only +# +# @read-write: Makes the device writable +# +# Since: 2.3 +## +{ 'enum': 'BlockdevChangeReadOnlyMode', + 'data': ['retain', 'read-only', 'read-write'] } + + +## # @blockdev-change-medium: # # Changes the medium inserted into a block device by ejecting the current medium @@ -1973,12 +1991,16 @@ # @format: #optional, format to open the new image with (defaults to # the probed format) # +# @read-only-mode: #optional, change the read-only mode of the device; defaults +# to 'retain' +# # Since: 2.5 ## { 'command': 'blockdev-change-medium', 'data': { 'device': 'str', 'filename': 'str', - '*format': 'str' } } + '*format': 'str', + '*read-only-mode': 'BlockdevChangeReadOnlyMode' } } ## diff --git a/qmp-commands.hx b/qmp-commands.hx index d6e4d7e..707e0bd 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -4164,7 +4164,7 @@ EQMP { .name = "blockdev-change-medium", - .args_type = "device:B,filename:F,format:s?", + .args_type = "device:B,filename:F,format:s?,read-only-mode:s?", .mhandler.cmd_new = qmp_marshal_blockdev_change_medium, }, @@ -4180,6 +4180,8 @@ Arguments: - "device": device name (json-string) - "filename": filename of the new image (json-string) - "format": format of the new image (json-string, optional) +- "read-only-mode": new read-only mode (json-string, optional) + - Possible values: "retain" (default), "read-only", "read-write" Examples: @@ -4191,6 +4193,26 @@ Examples: "format": "raw" } } <- { "return": {} } +2. Load a read-only medium into a writable drive + +-> { "execute": "blockdev-change-medium", + "arguments": { "device": "isa-fd0", + "filename": "/srv/images/ro.img", + "format": "raw", + "read-only-mode": "retain" } } + +<- { "error": + { "class": "GenericError", + "desc": "Could not open '/srv/images/ro.img': Permission denied" } } + +-> { "execute": "blockdev-change-medium", + "arguments": { "device": "isa-fd0", + "filename": "/srv/images/ro.img", + "format": "raw", + "read-only-mode": "read-only" } } + +<- { "return": {} } + EQMP { diff --git a/qmp.c b/qmp.c index 4e44f98..ddc63ea 100644 --- a/qmp.c +++ b/qmp.c @@ -414,7 +414,8 @@ void qmp_change(const char *device, const char *target, if (strcmp(device, "vnc") == 0) { qmp_change_vnc(target, has_arg, arg, errp); } else { - qmp_blockdev_change_medium(device, target, has_arg, arg, errp); + qmp_blockdev_change_medium(device, target, has_arg, arg, false, 0, + errp); } } -- 1.8.3.1