From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:46912) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S4pM8-0001Rw-P6 for qemu-devel@nongnu.org; Tue, 06 Mar 2012 03:02:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S4pM2-0000eU-4z for qemu-devel@nongnu.org; Tue, 06 Mar 2012 03:02:48 -0500 Received: from mail-pw0-f45.google.com ([209.85.160.45]:32847) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S4pM1-0000eA-MW for qemu-devel@nongnu.org; Tue, 06 Mar 2012 03:02:42 -0500 Received: by pbcuo5 with SMTP id uo5so5474277pbc.4 for ; Tue, 06 Mar 2012 00:02:39 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Tue, 6 Mar 2012 09:02:29 +0100 Message-Id: <1331020949-30957-1-git-send-email-pbonzini@redhat.com> In-Reply-To: <1330968842-24635-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH v3 9/8] Add the drive-reopen command List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, Federico Simoncelli , eblake@redhat.com, stefanha@linux.vnet.ibm.com, lcapitulino@redhat.com From: Federico Simoncelli Signed-off-by: Federico Simoncelli Signed-off-by: Paolo Bonzini --- blockdev.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hmp-commands.hx | 16 +++++++++++++ hmp.c | 11 +++++++++ hmp.h | 1 + qapi-schema.json | 22 ++++++++++++++++++ 5 files changed, 113 insertions(+), 0 deletions(-) diff --git a/blockdev.c b/blockdev.c index 60fdc7b..1fb2a17 100644 --- a/blockdev.c +++ b/blockdev.c @@ -646,6 +646,69 @@ void do_commit(Monitor *mon, const QDict *qdict) } } +static void change_blockdev_image(const char *device, const char *new_image_file, + const char *format, Error **errp) +{ + BlockDriverState *bs; + BlockDriver *drv, *old_drv, *proto_drv; + int ret = 0; + int flags; + char old_filename[1024]; + + bs = bdrv_find(device); + if (!bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; + } + if (bdrv_in_use(bs)) { + error_set(errp, QERR_DEVICE_IN_USE, device); + return; + } + + pstrcpy(old_filename, sizeof(old_filename), bs->filename); + + old_drv = bs->drv; + flags = bs->open_flags; + + drv = bdrv_find_format(format); + if (!drv) { + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); + return; + } + + proto_drv = bdrv_find_protocol(new_image_file); + if (!proto_drv) { + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); + return; + } + + bdrv_drain_all(); + bdrv_flush(bs); + + bdrv_close(bs); + ret = bdrv_open(bs, new_image_file, flags, drv); + /* + * If reopening the image file we just created fails, fall back + * and try to re-open the original image. If that fails too, we + * are in serious trouble. + */ + if (ret != 0) { + ret = bdrv_open(bs, old_filename, flags, old_drv); + if (ret != 0) { + error_set(errp, QERR_OPEN_FILE_FAILED, old_filename); + } else { + error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file); + } + } +} + +void qmp_drive_reopen(const char *device, const char *new_image_file, + bool has_format, const char *format, Error **errp) +{ + change_blockdev_image(device, new_image_file, + has_format ? format : "qcow2", errp); +} + void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file, bool has_format, const char *format, bool has_mode, enum NewImageMode mode, diff --git a/hmp-commands.hx b/hmp-commands.hx index 9c49c33..4afde71 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -925,6 +925,22 @@ using the specified target. ETEXI { + .name = "drive_reopen", + .args_type = "device:B,new-image-file:s,format:s?", + .params = "device new-image-file [format]", + .help = "Assigns a new image file to a device.\n\t\t\t" + "The image will be opened using the format\n\t\t\t" + "specified or 'qcow2' by default.\n\t\t\t", + .mhandler.cmd = hmp_drive_reopen, + }, + +STEXI +@item drive_reopen +@findex drive_reopen +Assigns a new image file to a device. +ETEXI + + { .name = "drive_add", .args_type = "pci_addr:s,opts:s", .params = "[[:]:]\n" diff --git a/hmp.c b/hmp.c index e706db9..ec41d83 100644 --- a/hmp.c +++ b/hmp.c @@ -738,6 +738,17 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &errp); } +void hmp_drive_reopen(Monitor *mon, const QDict *qdict) +{ + const char *device = qdict_get_str(qdict, "device"); + const char *filename = qdict_get_str(qdict, "new-image-file"); + const char *format = qdict_get_try_str(qdict, "format"); + Error *errp = NULL; + + qmp_drive_reopen(device, filename, !!format, format, &errp); + hmp_handle_error(mon, &errp); +} + void hmp_migrate_cancel(Monitor *mon, const QDict *qdict) { qmp_migrate_cancel(NULL); diff --git a/hmp.h b/hmp.h index 5352f00..648a84f 100644 --- a/hmp.h +++ b/hmp.h @@ -49,6 +49,7 @@ void hmp_balloon(Monitor *mon, const QDict *qdict); void hmp_block_resize(Monitor *mon, const QDict *qdict); void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict); void hmp_drive_mirror(Monitor *mon, const QDict *qdict); +void hmp_drive_reopen(Monitor *mon, const QDict *qdict); void hmp_migrate_cancel(Monitor *mon, const QDict *qdict); void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict); void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict); diff --git a/qapi-schema.json b/qapi-schema.json index 4cebf78..21eb256 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1235,6 +1235,28 @@ '*mode': 'NewImageMode'} } ## +# @drive-reopen +# +# Assigns a new image file to a device. +# +# @device: the name of the device for which we are changing the image file. +# +# @new-image-file: the target of the new image. If the file doesn't exists the +# command will fail. +# +# @format: #optional the format of the new image, default is 'qcow2'. +# +# Returns: nothing on success +# If @device is not a valid block device, DeviceNotFound +# If @new-image-file can't be opened, OpenFileFailed +# If @format is invalid, InvalidBlockFormat +# +# Since 1.1 +## +{ 'command': 'drive-reopen', + 'data': { 'device': 'str', 'new-image-file': 'str', '*format': 'str' } } + +## # @human-monitor-command: # # Execute a command on the human monitor and return the output. -- 1.7.7.6