[Qemu-devel] [PATCH] Add the drive-reopen command

2012-03-05 Thread Federico Simoncelli
Signed-off-by: Federico Simoncelli 
---
 blockdev.c   |   40 +++-
 hmp-commands.hx  |   16 
 hmp.c|   11 +++
 hmp.h|1 +
 qapi-schema.json |   22 ++
 5 files changed, 77 insertions(+), 13 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 058b6d5..56da5c9 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -646,9 +646,8 @@ void do_commit(Monitor *mon, const QDict *qdict)
 }
 }
 
-void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
-bool has_format, const char *format,
-Error **errp)
+static void change_blockdev_image(const char *device, const char 
*new_image_file,
+  const char *format, bool create, Error 
**errp)
 {
 BlockDriverState *bs;
 BlockDriver *drv, *old_drv, *proto_drv;
@@ -671,7 +670,7 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
char *snapshot_file,
 old_drv = bs->drv;
 flags = bs->open_flags;
 
-if (!has_format) {
+if (!format) {
 format = "qcow2";
 }
 
@@ -681,24 +680,26 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
char *snapshot_file,
 return;
 }
 
-proto_drv = bdrv_find_protocol(snapshot_file);
+proto_drv = bdrv_find_protocol(new_image_file);
 if (!proto_drv) {
 error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
 return;
 }
 
-ret = bdrv_img_create(snapshot_file, format, bs->filename,
-  bs->drv->format_name, NULL, -1, flags);
-if (ret) {
-error_set(errp, QERR_UNDEFINED_ERROR);
-return;
+if (create) {
+ret = bdrv_img_create(new_image_file, format, bs->filename,
+  bs->drv->format_name, NULL, -1, flags);
+if (ret) {
+error_set(errp, QERR_UNDEFINED_ERROR);
+return;
+}
 }
 
 bdrv_drain_all();
 bdrv_flush(bs);
 
 bdrv_close(bs);
-ret = bdrv_open(bs, snapshot_file, flags, drv);
+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
@@ -709,11 +710,25 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
char *snapshot_file,
 if (ret != 0) {
 error_set(errp, QERR_OPEN_FILE_FAILED, old_filename);
 } else {
-error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
+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 : NULL, false, errp);
+}
+
+void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
+bool has_format, const char *format,
+Error **errp)
+{
+change_blockdev_image(device, snapshot_file,
+  has_format ? format : NULL, true, errp);
+}
 
 /* New and old BlockDriverState structs for group snapshots */
 typedef struct BlkTransactionStates {
@@ -877,7 +892,6 @@ exit:
 return;
 }
 
-
 static void eject_device(BlockDriverState *bs, int force, Error **errp)
 {
 if (bdrv_in_use(bs)) {
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 64b3656..9e08123 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -900,6 +900,22 @@ Snapshot device, using snapshot file as target if provided
 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 3a54455..ab069ad 100644
--- a/hmp.c
+++ b/hmp.c
@@ -706,6 +706,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_can

Re: [Qemu-devel] [PATCH] Add the drive-reopen command

2012-03-05 Thread Paolo Bonzini
Il 05/03/2012 20:36, Federico Simoncelli ha scritto:
> Signed-off-by: Federico Simoncelli 
> ---
>  blockdev.c   |   40 +++-
>  hmp-commands.hx  |   16 
>  hmp.c|   11 +++
>  hmp.h|1 +
>  qapi-schema.json |   22 ++
>  5 files changed, 77 insertions(+), 13 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 058b6d5..56da5c9 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -646,9 +646,8 @@ void do_commit(Monitor *mon, const QDict *qdict)
>  }
>  }
>  
> -void qmp_blockdev_snapshot_sync(const char *device, const char 
> *snapshot_file,
> -bool has_format, const char *format,
> -Error **errp)
> +static void change_blockdev_image(const char *device, const char 
> *new_image_file,
> +  const char *format, bool create, Error 
> **errp)
>  {
>  BlockDriverState *bs;
>  BlockDriver *drv, *old_drv, *proto_drv;
> @@ -671,7 +670,7 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
> char *snapshot_file,
>  old_drv = bs->drv;
>  flags = bs->open_flags;
>  
> -if (!has_format) {
> +if (!format) {
>  format = "qcow2";
>  }
>  
> @@ -681,24 +680,26 @@ void qmp_blockdev_snapshot_sync(const char *device, 
> const char *snapshot_file,
>  return;
>  }
>  
> -proto_drv = bdrv_find_protocol(snapshot_file);
> +proto_drv = bdrv_find_protocol(new_image_file);
>  if (!proto_drv) {
>  error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
>  return;
>  }
>  
> -ret = bdrv_img_create(snapshot_file, format, bs->filename,
> -  bs->drv->format_name, NULL, -1, flags);
> -if (ret) {
> -error_set(errp, QERR_UNDEFINED_ERROR);
> -return;
> +if (create) {
> +ret = bdrv_img_create(new_image_file, format, bs->filename,
> +  bs->drv->format_name, NULL, -1, flags);
> +if (ret) {
> +error_set(errp, QERR_UNDEFINED_ERROR);
> +return;
> +}
>  }
>  
>  bdrv_drain_all();
>  bdrv_flush(bs);
>  
>  bdrv_close(bs);
> -ret = bdrv_open(bs, snapshot_file, flags, drv);
> +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
> @@ -709,11 +710,25 @@ void qmp_blockdev_snapshot_sync(const char *device, 
> const char *snapshot_file,
>  if (ret != 0) {
>  error_set(errp, QERR_OPEN_FILE_FAILED, old_filename);
>  } else {
> -error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
> +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 : NULL, false, errp);
> +}
> +
> +void qmp_blockdev_snapshot_sync(const char *device, const char 
> *snapshot_file,
> +bool has_format, const char *format,
> +Error **errp)
> +{
> +change_blockdev_image(device, snapshot_file,
> +  has_format ? format : NULL, true, errp);
> +}
>  
>  /* New and old BlockDriverState structs for group snapshots */
>  typedef struct BlkTransactionStates {
> @@ -877,7 +892,6 @@ exit:
>  return;
>  }
>  
> -
>  static void eject_device(BlockDriverState *bs, int force, Error **errp)
>  {
>  if (bdrv_in_use(bs)) {
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 64b3656..9e08123 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -900,6 +900,22 @@ Snapshot device, using snapshot file as target if 
> provided
>  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 3a54455..ab069ad 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -706,6 +706,17 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict 
> *qdict)
>  hmp_handle_error(mon, &errp);
>  }
>  
> +void hmp_drive_reopen(Monitor *mon, const QDict