-From 6f87d124089c383af873d9774d3b47597dc7d5e9 Mon Sep 17 00:00:00 2001
+From aa580be154923056a52fdeec429f7e80f04b456e Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Thu, 29 Nov 2012 10:46:49 +0100
-Subject: [PATCH v3 6/6] add vm state to backups
+Subject: [PATCH v5 6/6] add vm state to backups
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
blockdev.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
hmp.c | 3 +-
- qapi-schema.json | 6 +-
- 3 files changed, 200 insertions(+), 5 deletions(-)
+ qapi-schema.json | 5 +-
+ 3 files changed, 200 insertions(+), 4 deletions(-)
diff --git a/blockdev.c b/blockdev.c
-index a030a13..d5878c5 100644
+index 683f7da..dd20631 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -22,6 +22,8 @@
- #include "arch_init.h"
+ #include "sysemu/arch_init.h"
#include "backup.h"
#include "vma.h"
-+#include "qemu-file.h"
-+#include "migration.h"
++#include "migration/qemu-file.h"
++#include "migration/migration.h"
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-@@ -1341,6 +1343,10 @@ static struct GenericBackupState {
+@@ -1355,6 +1357,10 @@ static struct GenericBackupState {
size_t total;
size_t transferred;
size_t zero_bytes;
} backup_state;
typedef struct BackupCB {
-@@ -1501,10 +1507,170 @@ static void backup_start_jobs(void)
+@@ -1510,10 +1516,170 @@ static void backup_start_jobs(void)
backup_run_next_job();
}
+ memset(backup_state.buf + backup_state.buf_index, 0,
+ BACKUP_CLUSTER_SIZE - backup_state.buf_index);
+ }
-+ int bytes = backup_state.driver->dump_cb(
++ int bytes = backup_state.driver->dump(
+ backup_state.writer, backup_state.vmstate_dev_id,
+ backup_state.buf_cluster_num,
+ backup_state.buf, &zero_bytes);
+{
+ assert(backup_state.driver);
+ assert(backup_state.writer);
-+ assert(backup_state.driver->dump_cb);
++ assert(backup_state.driver->dump);
+
+ /* Note: our backup driver expects to get whole clusters (64KB) */
+
+ size -= l;
+ if (backup_state.buf_index == BACKUP_CLUSTER_SIZE) {
+ size_t zero_bytes = 0;
-+ int bytes = backup_state.driver->dump_cb(
++ int bytes = backup_state.driver->dump(
+ backup_state.writer, backup_state.vmstate_dev_id,
+ backup_state.buf_cluster_num++,
+ backup_state.buf, &zero_bytes);
+ "backup_start_savevm: qemu_fclose failed");
+ goto abort;
+ }
-+ if (backup_state.driver->complete_cb(backup_state.writer,
++ if (backup_state.driver->complete(backup_state.writer,
+ backup_state.vmstate_dev_id, 0) < 0) {
-+ err = g_strdup("backup_start_savevm: complete_cb failed");
++ err = g_strdup("backup_start_savevm: complete failed");
+ goto abort;
+ }
+ backup_run_next_job();
+ backup_state.end_time = time(NULL);
+
+ Error *local_err = NULL;
-+ backup_state.driver->close_cb(backup_state.writer, &local_err);
++ backup_state.driver->close(backup_state.writer, &local_err);
+ backup_state.writer = NULL;
+
+ error_propagate(&backup_state.error, local_err);
+ goto out;
+}
+
- char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
- bool has_config_filename, const char *config_filename,
+ char *qmp_backup(const char *backup_file, bool has_format, BackupFormat format,
+ bool has_config_file, const char *config_file,
bool has_devlist, const char *devlist,
- bool has_speed, int64_t speed, Error **errp)
+ bool has_speed, int64_t speed,
{
BlockDriverState *bs;
Error *local_err = NULL;
-@@ -1513,6 +1679,8 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
- gchar **devs = NULL;
- GList *bcblist = NULL;
+@@ -1528,6 +1694,8 @@ char *qmp_backup(const char *backup_file, bool has_format, BackupFormat format,
+ return NULL;
+ }
+ bool save_state = has_state ? state : false;
+
/* Todo: try to auto-detect format based on file name */
format = has_format ? format : BACKUP_FORMAT_VMA;
-@@ -1593,6 +1761,22 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1608,6 +1776,22 @@ char *qmp_backup(const char *backup_file, bool has_format, BackupFormat format,
size_t total = 0;
/* register all devices for vma writer */
+ * not know that size in advance).
+ */
+ size_t ramsize = ram_bytes_total();
-+ vmstate_dev_id = driver->register_stream_cb(writer, "vmstate", ramsize);
++ vmstate_dev_id = driver->register_stream(writer, "vmstate", ramsize);
+ if (vmstate_dev_id <= 0) {
+ error_setg(errp, "register vmstate stream failed");
+ goto err;
l = bcblist;
while (l) {
BackupCB *bcb = l->data;
-@@ -1658,6 +1842,9 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1675,6 +1859,9 @@ char *qmp_backup(const char *backup_file, bool has_format, BackupFormat format,
backup_state.total = total;
backup_state.transferred = 0;
backup_state.zero_bytes = 0;
/* Grab a reference so hotplug does not delete the
* BlockDriverState from underneath us.
-@@ -1669,7 +1856,12 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1686,7 +1873,12 @@ char *qmp_backup(const char *backup_file, bool has_format, BackupFormat format,
drive_get_ref(drive_get_by_blockdev(bcb->bs));
}
+ Coroutine *co = qemu_coroutine_create(backup_start_savevm);
+ qemu_coroutine_enter(co, NULL);
+ } else {
-+ backup_start_jobs();
++ backup_start_jobs();
+ }
return g_strdup(backup_state.uuid_str);
diff --git a/hmp.c b/hmp.c
-index 27fd421..56e1cdc 100644
+index b2c1f23..370cdf8 100644
--- a/hmp.c
+++ b/hmp.c
-@@ -1031,7 +1031,8 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
+@@ -1052,7 +1052,8 @@ void hmp_backup(Monitor *mon, const QDict *qdict)
Error *errp = NULL;
- qmp_backup(backupfile, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
+ qmp_backup(backup_file, true, BACKUP_FORMAT_VMA, false, NULL, !!devlist,
- devlist, qdict_haskey(qdict, "speed"), speed, &errp);
+ devlist, qdict_haskey(qdict, "speed"), speed, false, false,
+ &errp);
if (error_is_set(&errp)) {
monitor_printf(mon, "%s\n", error_get_pretty(errp));
diff --git a/qapi-schema.json b/qapi-schema.json
-index 2d3699b..3f4889e 100644
+index 09ca8ef..1fabb67 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
-@@ -1822,13 +1822,15 @@
- #
- # @speed: #optional the maximum speed, in bytes per second
+@@ -1885,6 +1885,8 @@
+ # @devlist: #optional list of block device names (separated by ',', ';'
+ # or ':'). By default the backup includes all writable block devices.
#
+# @state: #optional flag to include vm state
+#
# Returns: the uuid of the backup job
#
- # Since: 1.4.0
- ##
- { 'command': 'backup', 'data': { 'backupfile': 'str', '*format': 'BackupFormat',
-- '*config-filename': 'str',
+ # Since: 1.5.0
+@@ -1892,7 +1894,8 @@
+ { 'command': 'backup', 'data': { 'backup-file': 'str',
+ '*format': 'BackupFormat',
+ '*config-file': 'str',
- '*devlist': 'str', '*speed': 'int' },
-+ '*config-filename': 'str', '*devlist': 'str',
-+ '*speed': 'int', '*state': 'bool' },
++ '*devlist': 'str', '*speed': 'int',
++ '*state': 'bool' },
'returns': 'str' }
##