[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 15/18] savevm: introduce qemu_savevm_trans_{begin, c
From: |
Yoshiaki Tamura |
Subject: |
[Qemu-devel] [PATCH 15/18] savevm: introduce qemu_savevm_trans_{begin, commit}. |
Date: |
Wed, 23 Mar 2011 13:10:23 +0900 |
Introduce qemu_savevm_trans_{begin,commit} to send the memory and
device info together, while avoiding cancelling memory state tracking.
This patch also abstracts common code between
qemu_savevm_state_{begin,iterate,commit}.
Signed-off-by: Yoshiaki Tamura <address@hidden>
---
savevm.c | 157 +++++++++++++++++++++++++++++++++++++++-----------------------
sysemu.h | 2 +
2 files changed, 101 insertions(+), 58 deletions(-)
diff --git a/savevm.c b/savevm.c
index 48a0f65..4793be0 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1629,29 +1629,68 @@ bool qemu_savevm_state_blocked(Monitor *mon)
return false;
}
-int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
- int shared)
+/*
+ * section: header to write
+ * inc: if true, forces to pass SECTION_PART instead of SECTION_START
+ * pause: if true, breaks the loop when live handler returned 0
+ */
+static int qemu_savevm_state_live(Monitor *mon, QEMUFile *f, int section,
+ bool inc, bool pause)
{
SaveStateEntry *se;
+ int skip = 0, ret;
QTAILQ_FOREACH(se, &savevm_handlers, entry) {
- if(se->set_params == NULL) {
+ int len, stage;
+
+ if (se->save_live_state == NULL) {
continue;
- }
- se->set_params(blk_enable, shared, se->opaque);
+ }
+
+ /* Section type */
+ qemu_put_byte(f, section);
+ qemu_put_be32(f, se->section_id);
+
+ if (section == QEMU_VM_SECTION_START) {
+ /* ID string */
+ len = strlen(se->idstr);
+ qemu_put_byte(f, len);
+ qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+
+ qemu_put_be32(f, se->instance_id);
+ qemu_put_be32(f, se->version_id);
+
+ stage = inc ? QEMU_VM_SECTION_PART : QEMU_VM_SECTION_START;
+ } else {
+ assert(inc);
+ stage = section;
+ }
+
+ ret = se->save_live_state(mon, f, stage, se->opaque);
+ if (!ret) {
+ skip++;
+ if (pause) {
+ break;
+ }
+ }
}
-
- qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
- qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+ return skip;
+}
+
+static void qemu_savevm_state_full(QEMUFile *f)
+{
+ SaveStateEntry *se;
QTAILQ_FOREACH(se, &savevm_handlers, entry) {
int len;
- if (se->save_live_state == NULL)
+ if (se->save_state == NULL && se->vmsd == NULL) {
continue;
+ }
/* Section type */
- qemu_put_byte(f, QEMU_VM_SECTION_START);
+ qemu_put_byte(f, QEMU_VM_SECTION_FULL);
qemu_put_be32(f, se->section_id);
/* ID string */
@@ -1662,9 +1701,29 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f,
int blk_enable,
qemu_put_be32(f, se->instance_id);
qemu_put_be32(f, se->version_id);
- se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque);
+ vmstate_save(f, se);
+ }
+
+ qemu_put_byte(f, QEMU_VM_EOF);
+}
+
+int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
+ int shared)
+{
+ SaveStateEntry *se;
+
+ QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+ if (se->set_params == NULL) {
+ continue;
+ }
+ se->set_params(blk_enable, shared, se->opaque);
}
+ qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+ qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+ qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_START, 0, 0);
+
if (qemu_file_has_error(f)) {
qemu_savevm_state_cancel(mon, f);
return -EIO;
@@ -1675,29 +1734,16 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f,
int blk_enable,
int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
{
- SaveStateEntry *se;
int ret = 1;
- QTAILQ_FOREACH(se, &savevm_handlers, entry) {
- if (se->save_live_state == NULL)
- continue;
-
- /* Section type */
- qemu_put_byte(f, QEMU_VM_SECTION_PART);
- qemu_put_be32(f, se->section_id);
-
- ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque);
- if (!ret) {
- /* Do not proceed to the next vmstate before this one reported
- completion of the current stage. This serializes the migration
- and reduces the probability that a faster changing state is
- synchronized over and over again. */
- break;
- }
- }
-
- if (ret)
+ /* Do not proceed to the next vmstate before this one reported
+ completion of the current stage. This serializes the migration
+ and reduces the probability that a faster changing state is
+ synchronized over and over again. */
+ ret = qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_PART, 1, 1);
+ if (!ret) {
return 1;
+ }
if (qemu_file_has_error(f)) {
qemu_savevm_state_cancel(mon, f);
@@ -1709,46 +1755,41 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f)
int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)
{
- SaveStateEntry *se;
-
cpu_synchronize_all_states();
- QTAILQ_FOREACH(se, &savevm_handlers, entry) {
- if (se->save_live_state == NULL)
- continue;
-
- /* Section type */
- qemu_put_byte(f, QEMU_VM_SECTION_END);
- qemu_put_be32(f, se->section_id);
+ qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_END, 1, 0);
+ qemu_savevm_state_full(f);
- se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);
+ if (qemu_file_has_error(f)) {
+ return -EIO;
}
- QTAILQ_FOREACH(se, &savevm_handlers, entry) {
- int len;
+ return 0;
+}
- if (se->save_state == NULL && se->vmsd == NULL)
- continue;
+int qemu_savevm_trans_begin(Monitor *mon, QEMUFile *f, int init)
+{
+ int ret;
- /* Section type */
- qemu_put_byte(f, QEMU_VM_SECTION_FULL);
- qemu_put_be32(f, se->section_id);
+ ret = qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_START, !init, 0);
- /* ID string */
- len = strlen(se->idstr);
- qemu_put_byte(f, len);
- qemu_put_buffer(f, (uint8_t *)se->idstr, len);
+ if (qemu_file_has_error(f)) {
+ return -EIO;
+ }
- qemu_put_be32(f, se->instance_id);
- qemu_put_be32(f, se->version_id);
+ return ret;
+}
- vmstate_save(f, se);
- }
+int qemu_savevm_trans_complete(Monitor *mon, QEMUFile *f)
+{
+ cpu_synchronize_all_states();
- qemu_put_byte(f, QEMU_VM_EOF);
+ qemu_savevm_state_live(mon, f, QEMU_VM_SECTION_PART, 1, 0);
+ qemu_savevm_state_full(f);
- if (qemu_file_has_error(f))
+ if (qemu_file_has_error(f)) {
return -EIO;
+ }
return 0;
}
diff --git a/sysemu.h b/sysemu.h
index c43c7af..1269f08 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -93,6 +93,8 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int
blk_enable,
int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f);
int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
+int qemu_savevm_trans_begin(Monitor *mon, QEMUFile *f, int init);
+int qemu_savevm_trans_complete(Monitor *mon, QEMUFile *f);
int qemu_loadvm_state(QEMUFile *f);
/* SLIRP */
--
1.7.1.2
- [Qemu-devel] [PATCH 14/18] block: insert event-tap to bdrv_aio_writev(), bdrv_aio_flush() and bdrv_flush()., (continued)
- [Qemu-devel] [PATCH 14/18] block: insert event-tap to bdrv_aio_writev(), bdrv_aio_flush() and bdrv_flush()., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 11/18] ioport: insert event_tap_ioport() to ioport_write()., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 03/18] Introduce qemu_loadvm_state_no_header() and make qemu_loadvm_state() a wrapper., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 16/18] migration: introduce migrate_ft_trans_{put, get}_ready(), and modify migrate_fd_put_ready() when ft_mode is on., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 18/18] Introduce "kemari:" to enable FT migration mode (Kemari)., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 02/18] Introduce read() to FdMigrationState., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 01/18] Make QEMUFile buf expandable, and introduce qemu_realloc_buffer() and qemu_clear_buffer()., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 09/18] Introduce event-tap., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 07/18] Introduce fault tolerant VM transaction QEMUFile and ft_mode., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 08/18] savevm: introduce util functions to control ft_trans_file from savevm layer., Yoshiaki Tamura, 2011/03/23
- [Qemu-devel] [PATCH 15/18] savevm: introduce qemu_savevm_trans_{begin, commit}.,
Yoshiaki Tamura <=