[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 6/6] snapshot: human monitor interface
From: |
Wenchao Xia |
Subject: |
[Qemu-devel] [PATCH 6/6] snapshot: human monitor interface |
Date: |
Mon, 17 Dec 2012 14:25:09 +0800 |
This patch add support in human monitor to create/delete/check
internal snapshot on a single blk device.
To make info command get parameter, added a new info handler
type which can take QDict as parameter.
Signed-off-by: Wenchao Xia <address@hidden>
---
hmp-commands.hx | 50 +++++++++++++++++++++++++++++++++++++-------------
hmp.c | 30 +++++++++++++++++++++++++-----
hmp.h | 1 +
monitor.c | 21 +++++++++++++++------
savevm.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
sysemu.h | 2 +-
6 files changed, 133 insertions(+), 26 deletions(-)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 010b8c9..ee74723 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -983,17 +983,22 @@ ETEXI
{
.name = "snapshot_blkdev",
- .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
- .params = "[-n] device [new-image-file] [format]",
- .help = "initiates a live snapshot\n\t\t\t"
- "of device. If a new image file is specified,
the\n\t\t\t"
- "new image file will become the new root image.\n\t\t\t"
- "If format is specified, the snapshot file will\n\t\t\t"
- "be created in that format. Otherwise the\n\t\t\t"
- "snapshot will be internal! (currently
unsupported).\n\t\t\t"
- "The default format is qcow2. The -n flag requests
QEMU\n\t\t\t"
- "to reuse the image found in new-image-file, instead
of\n\t\t\t"
- "recreating it from scratch.",
+ .args_type =
"internal:-i,reuse:-n,device:B,snapshot-file:s?,format:s?",
+ .params = "[-i] [-n] device [new-image-file] [format]",
+ .help = "initiates a live snapshot of device.\n\t\t\t"
+ " The -i flag requests QEMU to create internal
snapshot\n\t\t\t"
+ "instead of external one.\n\t\t\t"
+ " The -n flag requests QEMU to use existing
snapshot\n\t\t\t"
+ "instead of creating new snapshot, which would fails
if\n\t\t\t"
+ "snapshot does not exist ahead.\n\t\t\t"
+ " new-image-file is the snapshot's name, in external
case\n\t\t\t"
+ "it is the new image's name which will become the new
root\n\t\t\t"
+ "image and must be specified, in internal case it is
the\n\t\t\t"
+ "record's name and if not specified QEMU will
create\n\t\t\t"
+ "internal snapshot with name generated according to
time.\n\t\t\t"
+ " format is only valid in external case, which is the
new\n\t\t\t"
+ "snapshot image's format. If not sepcified default
format\n\t\t\t"
+ "qcow2 will be used.",
.mhandler.cmd = hmp_snapshot_blkdev,
},
@@ -1004,6 +1009,25 @@ Snapshot device, using snapshot file as target if
provided
ETEXI
{
+ .name = "snapshot_delete_blkdev",
+ .args_type = "internal:-i,device:B,snapshot-file:s",
+ .params = "[-i] device new-image-file",
+ .help = "delete a snapshot synchronous.\n\t\t\t"
+ " The -i flag requests QEMU to delete internal
snapshot\n\t\t\t"
+ "instead of external one.\n\t\t\t"
+ " new-image-file is the snapshot's name, in external
case\n\t\t\t"
+ "it is the image's name which is not supported
now.\n\t\t\t"
+ "in internal case it is the snapshot record's id or
name.",
+ .mhandler.cmd = hmp_snapshot_delete_blkdev,
+ },
+
+STEXI
address@hidden snapshot_delete_blkdev
address@hidden snapshot_delete_blkdev
+Delete a snapshot on a block device.
+ETEXI
+
+ {
.name = "drive_mirror",
.args_type = "reuse:-n,full:-f,device:B,target:s,format:s?",
.params = "[-n] [-f] device target [format]",
@@ -1486,8 +1510,8 @@ ETEXI
{
.name = "info",
- .args_type = "item:s?",
- .params = "[subcommand]",
+ .args_type = "item:s?,params:s?",
+ .params = "[subcommand] [params]",
.help = "show various information about the system state",
.mhandler.cmd = do_info,
},
diff --git a/hmp.c b/hmp.c
index 180ba2b..f247f51 100644
--- a/hmp.c
+++ b/hmp.c
@@ -806,20 +806,40 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
const char *filename = qdict_get_try_str(qdict, "snapshot-file");
const char *format = qdict_get_try_str(qdict, "format");
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
+ int internal = qdict_get_try_bool(qdict, "internal", 0);
enum NewImageMode mode;
+ enum SnapshotType type;
Error *errp = NULL;
- if (!filename) {
- /* In the future, if 'snapshot-file' is not specified, the snapshot
- will be taken internally. Today it's actually required. */
+ if ((!internal) && (!filename)) {
+ /* in external case filename must be set, should we generate
+ it automatically? */
error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
hmp_handle_error(mon, &errp);
return;
}
-
+ type = internal ? SNAPSHOT_TYPE_INTERNAL : SNAPSHOT_TYPE_EXTERNAL;
mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
qmp_blockdev_snapshot_sync(device, filename, !!format, format,
- true, mode, &errp);
+ true, mode, true, type, &errp);
+ hmp_handle_error(mon, &errp);
+}
+
+void hmp_snapshot_delete_blkdev(Monitor *mon, const QDict *qdict)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ const char *filename = qdict_get_try_str(qdict, "snapshot-file");
+ int internal = qdict_get_try_bool(qdict, "internal", 0);
+ enum SnapshotType type;
+ Error *errp = NULL;
+
+ if (!internal) {
+ error_setg(&errp, "external snapshot delete not supported now.");
+ hmp_handle_error(mon, &errp);
+ return;
+ }
+ type = internal ? SNAPSHOT_TYPE_INTERNAL : SNAPSHOT_TYPE_EXTERNAL;
+ qmp_blockdev_snapshot_delete_sync(device, filename, true, type, &errp);
hmp_handle_error(mon, &errp);
}
diff --git a/hmp.h b/hmp.h
index 0ab03be..2ea67be 100644
--- a/hmp.h
+++ b/hmp.h
@@ -51,6 +51,7 @@ void hmp_block_passwd(Monitor *mon, const QDict *qdict);
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_snapshot_delete_blkdev(Monitor *mon, const QDict *qdict);
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index c0e32d6..81de470 100644
--- a/monitor.c
+++ b/monitor.c
@@ -124,11 +124,14 @@ typedef struct mon_cmd_t {
void (*user_print)(Monitor *mon, const QObject *data);
union {
void (*info)(Monitor *mon);
+ void (*info_qdict)(Monitor *mon, const QDict *qdict);
void (*cmd)(Monitor *mon, const QDict *qdict);
- int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
+ int (*cmd_new)(Monitor *mon, const QDict *params,
+ QObject **ret_data);
int (*cmd_async)(Monitor *mon, const QDict *params,
MonitorCompletion *cb, void *opaque);
} mhandler;
+ int info_cmd_need_qdict;
int flags;
} mon_cmd_t;
@@ -824,7 +827,11 @@ static void do_info(Monitor *mon, const QDict *qdict)
goto help;
}
- cmd->mhandler.info(mon);
+ if (cmd->info_cmd_need_qdict) {
+ cmd->mhandler.info_qdict(mon, qdict);
+ } else {
+ cmd->mhandler.info(mon);
+ }
return;
help:
@@ -2605,10 +2612,12 @@ static mon_cmd_t info_cmds[] = {
},
{
.name = "snapshots",
- .args_type = "",
- .params = "",
- .help = "show the currently saved VM snapshots",
- .mhandler.info = do_info_snapshots,
+ .args_type = "device:B?",
+ .params = "[device]",
+ .help = "show the currently saved VM snapshots or snapshots on "
+ "a single device.",
+ .mhandler.info_qdict = do_info_snapshots,
+ .info_cmd_need_qdict = 1,
},
{
.name = "status",
diff --git a/savevm.c b/savevm.c
index c027529..5982aa9 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2336,7 +2336,7 @@ void do_delvm(Monitor *mon, const QDict *qdict)
}
}
-void do_info_snapshots(Monitor *mon)
+static void do_info_snapshots_vm(Monitor *mon)
{
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s;
@@ -2400,6 +2400,59 @@ void do_info_snapshots(Monitor *mon)
}
+static void do_info_snapshots_blk(Monitor *mon, const char *device)
+{
+ BlockDriverState *bs;
+ QEMUSnapshotInfo *sn_tab, *sn;
+ int nb_sns, i;
+ char buf[256];
+
+ /* find the target bs */
+ bs = bdrv_find(device);
+ if (!bs) {
+ monitor_printf(mon, "Device '%s' not found.\n", device);
+ return ;
+ }
+
+ if (!bdrv_can_snapshot(bs)) {
+ monitor_printf(mon, "Device '%s' can't have snapshot.\n", device);
+ return ;
+ }
+
+ nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+ if (nb_sns < 0) {
+ monitor_printf(mon, "Device %s bdrv_snapshot_list: error %d\n",
+ device, nb_sns);
+ return;
+ }
+
+ if (nb_sns == 0) {
+ monitor_printf(mon, "There is no snapshot available.\n");
+ return;
+ }
+
+ monitor_printf(mon, "Device %s:\n", device);
+ monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
+ for (i = 0; i < nb_sns; i++) {
+ sn = &sn_tab[i];
+ monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
+ }
+ g_free(sn_tab);
+ return;
+}
+
+void do_info_snapshots(Monitor *mon, const QDict *qdict)
+{
+ /* Todo, there should be a layer rebuild qdict before enter this func. */
+ const char *device = qdict_get_try_str(qdict, "params");
+ if (!device) {
+ do_info_snapshots_vm(mon);
+ } else {
+ do_info_snapshots_blk(mon, device);
+ }
+ return;
+}
+
void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev)
{
qemu_ram_set_idstr(memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK,
diff --git a/sysemu.h b/sysemu.h
index 1b6add2..a1254bf 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -68,7 +68,7 @@ void qemu_add_machine_init_done_notifier(Notifier *notify);
void do_savevm(Monitor *mon, const QDict *qdict);
int load_vmstate(const char *name);
void do_delvm(Monitor *mon, const QDict *qdict);
-void do_info_snapshots(Monitor *mon);
+void do_info_snapshots(Monitor *mon, const QDict *qdict);
void qemu_announce_self(void);
--
1.7.1
- [Qemu-devel] [PATCH 0/6] snapshot: take snapshots in unified way, Wenchao Xia, 2012/12/17
- [Qemu-devel] [PATCH 2/6] snapshot: add error set function, Wenchao Xia, 2012/12/17
- [Qemu-devel] [PATCH 5/6] snapshot: qmp interface, Wenchao Xia, 2012/12/17
- [Qemu-devel] [PATCH 1/6] snapshot: export function in block.c, Wenchao Xia, 2012/12/17
- [Qemu-devel] [PATCH 6/6] snapshot: human monitor interface,
Wenchao Xia <=
- [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Wenchao Xia, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Dietmar Maurer, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Wenchao Xia, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Dietmar Maurer, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Wenchao Xia, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Dietmar Maurer, 2012/12/17
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Eric Blake, 2012/12/20
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Wenchao Xia, 2012/12/20
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Dietmar Maurer, 2012/12/21
- Re: [Qemu-devel] [PATCH 4/6] snapshot: implemention of common API to take snapshots, Dietmar Maurer, 2012/12/17