[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/3] Introduce do_snapshot_blkdev() and monitor comm
From: |
Jes . Sorensen |
Subject: |
[Qemu-devel] [PATCH 2/3] Introduce do_snapshot_blkdev() and monitor command to handle it. |
Date: |
Mon, 13 Dec 2010 08:32:58 +0100 |
From: Jes Sorensen <address@hidden>
The monitor command is:
snapshot_blkdev <device> [snapshot-file] [format]
Default format is qcow2. For now snapshots without a snapshot-file, eg
internal snapshots, are not supported.
Signed-off-by: Jes Sorensen <address@hidden>
---
blockdev.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
blockdev.h | 1 +
hmp-commands.hx | 19 +++++++++++++++++
3 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index f6ac439..1ea24d7 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -514,6 +514,67 @@ void do_commit(Monitor *mon, const QDict *qdict)
}
}
+int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ const char *filename = qdict_get_try_str(qdict, "snapshot_file");
+ const char *format = qdict_get_try_str(qdict, "format");
+ const char format_qcow2[] = "qcow2";
+ BlockDriverState *bs;
+ BlockDriver *drv, *proto_drv;
+ int ret = 0;
+ int flags;
+
+ bs = bdrv_find(device);
+ if (!bs) {
+ qerror_report(QERR_DEVICE_NOT_FOUND, device);
+ ret = -1;
+ goto out;
+ }
+
+ if (!format) {
+ format = format_qcow2;
+ }
+
+ drv = bdrv_find_format(format);
+ if (!drv) {
+ qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
+ ret = -1;
+ goto out;
+ }
+
+ proto_drv = bdrv_find_protocol(filename);
+ if (!proto_drv) {
+ qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
+ ret = -1;
+ goto out;
+ }
+
+ ret = bdrv_img_create(filename, format, bs->filename,
+ bs->drv->format_name, NULL, -1, bs->open_flags);
+ if (ret) {
+ goto out;
+ }
+
+ qemu_aio_flush();
+ bdrv_flush(bs);
+
+ flags = bs->open_flags;
+ bdrv_close(bs);
+ ret = bdrv_open(bs, filename, flags, drv);
+ /*
+ * If reopening the image file we just created fails, we really
+ * are in trouble :(
+ */
+ assert(ret == 0);
+out:
+ if (ret) {
+ ret = 1;
+ }
+
+ return ret;
+}
+
static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
{
if (!force) {
diff --git a/blockdev.h b/blockdev.h
index 4cb8ca9..4536b5c 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -52,5 +52,6 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict,
QObject **ret_data);
int do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt);
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
+int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
#endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 23024ba..97e744e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -801,6 +801,25 @@ STEXI
Set maximum tolerated downtime (in seconds) for migration.
ETEXI
+ {
+ .name = "snapshot_blkdev",
+ .args_type = "device:s,snapshot_file:s?,format:s?",
+ .params = "device [snapshot-file] [format]",
+ .help = "initiates a live snapshot\n\t\t\t"
+ "of device. If a snapshot file is specified, the\n\t\t\t"
+ "snapshot file will become the new root image.
If\n\t\t\t"
+ "format is specified, the snapshot file will be\n\t\t\t"
+ "created in that format. Otherwise the snapshot\n\t\t\t"
+ "will be internal! (currently unsupported)",
+ .mhandler.cmd_new = do_snapshot_blkdev,
+ },
+
+STEXI
address@hidden snapshot_blkdev
address@hidden snapshot_blkdev
+Snapshot device, using snapshot file as target if provided
+ETEXI
+
#if defined(TARGET_I386)
{
.name = "drive_add",
--
1.7.3.2