All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RESEND v5 0/6] save/restore on Xen
@ 2012-02-28 15:50 ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: Jan Kiszka, xen-devel, Avi Kivity, Anthony Liguori, Stefano Stabellini

Hi all,
this is the fifth version of the Xen save/restore patch series.
We have been discussing this issue for quite a while on #qemu and
qemu-devel:


http://marc.info/?l=qemu-devel&m=132346828427314&w=2
http://marc.info/?l=qemu-devel&m=132377734605464&w=2


Please review the first three patches that touch generic code.
This patch series have been lying around for quite a while and it is
now blocking patches from getting in xen-unstable.



Changes in v5:

- rebased on b4bd0b168e9f4898b98308f4a8a089f647a86d16.


Changes in v4:

- following Anthony's suggestion I have introduced a new monitor command
to save the non-ram device state to file;

- I have also removed the hack not to reset the cirrus videoram on
restore, because it turns out that the videoram doesn't need to be
reset in the reset handler at all (tested on Win2K, where the problem
was found in the first place).



This is the list of patches with a diffstat:

Anthony PERARD (2):
      xen mapcache: check if memory region has moved.
      xen: do not allocate RAM during INMIGRATE runstate

Stefano Stabellini (4):
      cirrus_vga: do not reset videoram
      Introduce "save_devices"
      xen: record physmap changes to xenstore
      Set runstate to INMIGRATE earlier

 block-migration.c |    2 +-
 hmp-commands.hx   |   14 +++++++
 hw/cirrus_vga.c   |    4 --
 qmp-commands.hx   |   17 +++++++++
 savevm.c          |   72 ++++++++++++++++++++++++++++++++++++-
 sysemu.h          |    1 +
 vl.c              |    4 +-
 vmstate.h         |    1 +
 xen-all.c         |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 xen-mapcache.c    |   22 ++++++++++--
 xen-mapcache.h    |    9 ++++-
 11 files changed, 235 insertions(+), 15 deletions(-)

git://xenbits.xen.org/people/sstabellini/qemu-dm.git saverestore-5

Cheers,

Stefano

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 0/6] save/restore on Xen
@ 2012-02-28 15:50 ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:50 UTC (permalink / raw)
  To: qemu-devel
  Cc: Jan Kiszka, xen-devel, Avi Kivity, Anthony Liguori, Stefano Stabellini

Hi all,
this is the fifth version of the Xen save/restore patch series.
We have been discussing this issue for quite a while on #qemu and
qemu-devel:


http://marc.info/?l=qemu-devel&m=132346828427314&w=2
http://marc.info/?l=qemu-devel&m=132377734605464&w=2


Please review the first three patches that touch generic code.
This patch series have been lying around for quite a while and it is
now blocking patches from getting in xen-unstable.



Changes in v5:

- rebased on b4bd0b168e9f4898b98308f4a8a089f647a86d16.


Changes in v4:

- following Anthony's suggestion I have introduced a new monitor command
to save the non-ram device state to file;

- I have also removed the hack not to reset the cirrus videoram on
restore, because it turns out that the videoram doesn't need to be
reset in the reset handler at all (tested on Win2K, where the problem
was found in the first place).



This is the list of patches with a diffstat:

Anthony PERARD (2):
      xen mapcache: check if memory region has moved.
      xen: do not allocate RAM during INMIGRATE runstate

Stefano Stabellini (4):
      cirrus_vga: do not reset videoram
      Introduce "save_devices"
      xen: record physmap changes to xenstore
      Set runstate to INMIGRATE earlier

 block-migration.c |    2 +-
 hmp-commands.hx   |   14 +++++++
 hw/cirrus_vga.c   |    4 --
 qmp-commands.hx   |   17 +++++++++
 savevm.c          |   72 ++++++++++++++++++++++++++++++++++++-
 sysemu.h          |    1 +
 vl.c              |    4 +-
 vmstate.h         |    1 +
 xen-all.c         |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 xen-mapcache.c    |   22 ++++++++++--
 xen-mapcache.h    |    9 ++++-
 11 files changed, 235 insertions(+), 15 deletions(-)

git://xenbits.xen.org/people/sstabellini/qemu-dm.git saverestore-5

Cheers,

Stefano

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

There is no need to set the videoram to 0xff in cirrus_reset, because it
is the BIOS' job.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/cirrus_vga.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 4edcb94..afedaa4 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2767,10 +2767,6 @@ static void cirrus_reset(void *opaque)
     }
     s->vga.cr[0x27] = s->device_id;
 
-    /* Win2K seems to assume that the pattern buffer is at 0xff
-       initially ! */
-    memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
-
     s->cirrus_hidden_dac_lockindex = 5;
     s->cirrus_hidden_dac_data = 0;
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

There is no need to set the videoram to 0xff in cirrus_reset, because it
is the BIOS' job.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 hw/cirrus_vga.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 4edcb94..afedaa4 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2767,10 +2767,6 @@ static void cirrus_reset(void *opaque)
     }
     s->vga.cr[0x27] = s->device_id;
 
-    /* Win2K seems to assume that the pattern buffer is at 0xff
-       initially ! */
-    memset(s->vga.vram_ptr, 0xff, s->real_vram_size);
-
     s->cirrus_hidden_dac_lockindex = 5;
     s->cirrus_hidden_dac_data = 0;
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

- add an "is_ram" flag to SaveStateEntry;

- add an "is_ram" parameter to register_savevm_live;

- introduce a "save_devices" monitor command that can be used to save
the state of non-ram devices.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 block-migration.c |    2 +-
 hmp-commands.hx   |   14 ++++++++++
 qmp-commands.hx   |   17 ++++++++++++
 savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sysemu.h          |    1 +
 vl.c              |    2 +-
 vmstate.h         |    1 +
 7 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index 4467468..d283fd0 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -722,6 +722,6 @@ void blk_mig_init(void)
     QSIMPLEQ_INIT(&block_mig_state.bmds_list);
     QSIMPLEQ_INIT(&block_mig_state.blk_list);
 
-    register_savevm_live(NULL, "block", 0, 1, block_set_params,
+    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
                          block_save_live, NULL, block_load, &block_mig_state);
 }
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 64b3656..873abc9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
 ETEXI
 
     {
+        .name       = "save_devices",
+        .args_type  = "filename:F",
+        .params     = "filename",
+        .help       = "save the state of non-ram devices.",
+        .mhandler.cmd_new = do_save_device_state,
+    },
+
+STEXI
+@item save_devices @var{filename}
+@findex save_devices
+Save the state of non-ram devices.
+ETEXI
+
+    {
         .name       = "loadvm",
         .args_type  = "name:s",
         .params     = "tag|id",
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 705f704..619d9de 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
 EQMP
 
     {
+        .name       = "save_devices",
+        .args_type  = "filename:F",
+        .params     = "filename",
+        .help       = "save the state of non-ram devices.",
+        .user_print = monitor_user_noop,	
+    .mhandler.cmd_new = do_save_device_state,
+    },
+
+SQMP
+save_devices
+-------
+
+Save the state of non-ram devices.
+
+EQMP
+
+    {
         .name       = "migrate",
         .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
         .params     = "[-d] [-b] [-i] uri",
diff --git a/savevm.c b/savevm.c
index 80be1ff..d0e62bb 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
     void *opaque;
     CompatEntry *compat;
     int no_migrate;
+    int is_ram;
 } SaveStateEntry;
 
 
@@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
                          const char *idstr,
                          int instance_id,
                          int version_id,
+                         int is_ram,
                          SaveSetParamsHandler *set_params,
                          SaveLiveStateHandler *save_live_state,
                          SaveStateHandler *save_state,
@@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
     se->opaque = opaque;
     se->vmsd = NULL;
     se->no_migrate = 0;
+    se->is_ram = is_ram;
 
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
         char *id = dev->parent_bus->info->get_dev_path(dev);
@@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
                     LoadStateHandler *load_state,
                     void *opaque)
 {
-    return register_savevm_live(dev, idstr, instance_id, version_id,
+    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
                                 NULL, NULL, save_state, load_state, opaque);
 }
 
@@ -1728,6 +1731,43 @@ out:
     return ret;
 }
 
+static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
+{
+    SaveStateEntry *se;
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    cpu_synchronize_all_states();
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        int len;
+
+        if (se->is_ram)
+            continue;
+        if (se->save_state == NULL && se->vmsd == NULL)
+            continue;
+
+        /* Section type */
+        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
+        qemu_put_be32(f, se->section_id);
+
+        /* 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);
+
+        vmstate_save(f, se);
+    }
+
+    qemu_put_byte(f, QEMU_VM_EOF);
+
+    return qemu_file_get_error(f);
+}
+
 static SaveStateEntry *find_se(const char *idstr, int instance_id)
 {
     SaveStateEntry *se;
@@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         vm_start();
 }
 
+int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    int ret;
+    QEMUFile *f;
+    int saved_vm_running;
+    const char *filename = qdict_get_try_str(qdict, "filename");
+
+    saved_vm_running = runstate_is_running();
+    vm_stop(RUN_STATE_SAVE_VM);
+
+    f = qemu_fopen(filename, "wb");
+    if (!f) {
+        monitor_printf(mon, "Could not open VM state file\n");
+        ret = -1;
+        goto the_end;
+    }
+    ret = qemu_save_device_state(mon, f);
+    qemu_fclose(f);
+    if (ret < 0) {
+        monitor_printf(mon, "Error %d while writing VM\n", ret);
+        goto the_end;
+    }
+    ret = 0;
+
+ the_end:
+    if (saved_vm_running)
+        vm_start();
+    return ret;
+}
+
 int load_vmstate(const char *name)
 {
     BlockDriverState *bs, *bs_vm_state;
diff --git a/sysemu.h b/sysemu.h
index 98118cc..f4d5bf4 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 
 void do_savevm(Monitor *mon, const QDict *qdict);
+int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int load_vmstate(const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);
 void do_info_snapshots(Monitor *mon);
diff --git a/vl.c b/vl.c
index 1d4c350..5b2b84c 100644
--- a/vl.c
+++ b/vl.c
@@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
     default_drive(default_sdcard, snapshot, machine->use_scsi,
                   IF_SD, 0, SD_OPTS);
 
-    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
+    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
                          ram_load, NULL);
 
     if (nb_numa_nodes > 0) {
diff --git a/vmstate.h b/vmstate.h
index 9d3c49c..3cef117 100644
--- a/vmstate.h
+++ b/vmstate.h
@@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
                          const char *idstr,
                          int instance_id,
                          int version_id,
+                         int is_ram,
                          SaveSetParamsHandler *set_params,
                          SaveLiveStateHandler *save_live_state,
                          SaveStateHandler *save_state,
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 2/6] Introduce "save_devices"
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

- add an "is_ram" flag to SaveStateEntry;

- add an "is_ram" parameter to register_savevm_live;

- introduce a "save_devices" monitor command that can be used to save
the state of non-ram devices.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 block-migration.c |    2 +-
 hmp-commands.hx   |   14 ++++++++++
 qmp-commands.hx   |   17 ++++++++++++
 savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sysemu.h          |    1 +
 vl.c              |    2 +-
 vmstate.h         |    1 +
 7 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/block-migration.c b/block-migration.c
index 4467468..d283fd0 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -722,6 +722,6 @@ void blk_mig_init(void)
     QSIMPLEQ_INIT(&block_mig_state.bmds_list);
     QSIMPLEQ_INIT(&block_mig_state.blk_list);
 
-    register_savevm_live(NULL, "block", 0, 1, block_set_params,
+    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
                          block_save_live, NULL, block_load, &block_mig_state);
 }
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 64b3656..873abc9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
 ETEXI
 
     {
+        .name       = "save_devices",
+        .args_type  = "filename:F",
+        .params     = "filename",
+        .help       = "save the state of non-ram devices.",
+        .mhandler.cmd_new = do_save_device_state,
+    },
+
+STEXI
+@item save_devices @var{filename}
+@findex save_devices
+Save the state of non-ram devices.
+ETEXI
+
+    {
         .name       = "loadvm",
         .args_type  = "name:s",
         .params     = "tag|id",
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 705f704..619d9de 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
 EQMP
 
     {
+        .name       = "save_devices",
+        .args_type  = "filename:F",
+        .params     = "filename",
+        .help       = "save the state of non-ram devices.",
+        .user_print = monitor_user_noop,	
+    .mhandler.cmd_new = do_save_device_state,
+    },
+
+SQMP
+save_devices
+-------
+
+Save the state of non-ram devices.
+
+EQMP
+
+    {
         .name       = "migrate",
         .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
         .params     = "[-d] [-b] [-i] uri",
diff --git a/savevm.c b/savevm.c
index 80be1ff..d0e62bb 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
     void *opaque;
     CompatEntry *compat;
     int no_migrate;
+    int is_ram;
 } SaveStateEntry;
 
 
@@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
                          const char *idstr,
                          int instance_id,
                          int version_id,
+                         int is_ram,
                          SaveSetParamsHandler *set_params,
                          SaveLiveStateHandler *save_live_state,
                          SaveStateHandler *save_state,
@@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
     se->opaque = opaque;
     se->vmsd = NULL;
     se->no_migrate = 0;
+    se->is_ram = is_ram;
 
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
         char *id = dev->parent_bus->info->get_dev_path(dev);
@@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
                     LoadStateHandler *load_state,
                     void *opaque)
 {
-    return register_savevm_live(dev, idstr, instance_id, version_id,
+    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
                                 NULL, NULL, save_state, load_state, opaque);
 }
 
@@ -1728,6 +1731,43 @@ out:
     return ret;
 }
 
+static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
+{
+    SaveStateEntry *se;
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    cpu_synchronize_all_states();
+
+    QTAILQ_FOREACH(se, &savevm_handlers, entry) {
+        int len;
+
+        if (se->is_ram)
+            continue;
+        if (se->save_state == NULL && se->vmsd == NULL)
+            continue;
+
+        /* Section type */
+        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
+        qemu_put_be32(f, se->section_id);
+
+        /* 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);
+
+        vmstate_save(f, se);
+    }
+
+    qemu_put_byte(f, QEMU_VM_EOF);
+
+    return qemu_file_get_error(f);
+}
+
 static SaveStateEntry *find_se(const char *idstr, int instance_id)
 {
     SaveStateEntry *se;
@@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         vm_start();
 }
 
+int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    int ret;
+    QEMUFile *f;
+    int saved_vm_running;
+    const char *filename = qdict_get_try_str(qdict, "filename");
+
+    saved_vm_running = runstate_is_running();
+    vm_stop(RUN_STATE_SAVE_VM);
+
+    f = qemu_fopen(filename, "wb");
+    if (!f) {
+        monitor_printf(mon, "Could not open VM state file\n");
+        ret = -1;
+        goto the_end;
+    }
+    ret = qemu_save_device_state(mon, f);
+    qemu_fclose(f);
+    if (ret < 0) {
+        monitor_printf(mon, "Error %d while writing VM\n", ret);
+        goto the_end;
+    }
+    ret = 0;
+
+ the_end:
+    if (saved_vm_running)
+        vm_start();
+    return ret;
+}
+
 int load_vmstate(const char *name)
 {
     BlockDriverState *bs, *bs_vm_state;
diff --git a/sysemu.h b/sysemu.h
index 98118cc..f4d5bf4 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 
 void do_savevm(Monitor *mon, const QDict *qdict);
+int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int load_vmstate(const char *name);
 void do_delvm(Monitor *mon, const QDict *qdict);
 void do_info_snapshots(Monitor *mon);
diff --git a/vl.c b/vl.c
index 1d4c350..5b2b84c 100644
--- a/vl.c
+++ b/vl.c
@@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
     default_drive(default_sdcard, snapshot, machine->use_scsi,
                   IF_SD, 0, SD_OPTS);
 
-    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
+    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
                          ram_load, NULL);
 
     if (nb_numa_nodes > 0) {
diff --git a/vmstate.h b/vmstate.h
index 9d3c49c..3cef117 100644
--- a/vmstate.h
+++ b/vmstate.h
@@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
                          const char *idstr,
                          int instance_id,
                          int version_id,
+                         int is_ram,
                          SaveSetParamsHandler *set_params,
                          SaveLiveStateHandler *save_live_state,
                          SaveStateHandler *save_state,
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 vl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/vl.c b/vl.c
index 5b2b84c..341775b 100644
--- a/vl.c
+++ b/vl.c
@@ -3099,6 +3099,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_incoming:
                 incoming = optarg;
+                runstate_set(RUN_STATE_INMIGRATE);
                 break;
             case QEMU_OPTION_nodefaults:
                 default_serial = 0;
@@ -3596,7 +3597,6 @@ int main(int argc, char **argv, char **envp)
     }
 
     if (incoming) {
-        runstate_set(RUN_STATE_INMIGRATE);
         int ret = qemu_start_incoming_migration(incoming);
         if (ret < 0) {
             fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 vl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/vl.c b/vl.c
index 5b2b84c..341775b 100644
--- a/vl.c
+++ b/vl.c
@@ -3099,6 +3099,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_incoming:
                 incoming = optarg;
+                runstate_set(RUN_STATE_INMIGRATE);
                 break;
             case QEMU_OPTION_nodefaults:
                 default_serial = 0;
@@ -3596,7 +3597,6 @@ int main(int argc, char **argv, char **envp)
     }
 
     if (incoming) {
-        runstate_set(RUN_STATE_INMIGRATE);
         int ret = qemu_start_incoming_migration(incoming);
         if (ret < 0) {
             fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 4/6] xen: record physmap changes to xenstore
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

Write to xenstore any physmap changes so that the hypervisor can be
aware of them.
Read physmap changes from xenstore on boot.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 1 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index b0ed1ed..f2cad82 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -65,7 +65,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 typedef struct XenPhysmap {
     target_phys_addr_t start_addr;
     ram_addr_t size;
-    MemoryRegion *mr;
+    char *name;
     target_phys_addr_t phys_offset;
 
     QLIST_ENTRY(XenPhysmap) list;
@@ -237,6 +237,7 @@ static int xen_add_to_physmap(XenIOState *state,
     XenPhysmap *physmap = NULL;
     target_phys_addr_t pfn, start_gpfn;
     target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
+    char path[80], value[17];
 
     if (get_physmapping(state, start_addr, size)) {
         return 0;
@@ -275,6 +276,7 @@ go_physmap:
 
     physmap->start_addr = start_addr;
     physmap->size = size;
+    physmap->name = (char *)mr->name;
     physmap->phys_offset = phys_offset;
 
     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
@@ -283,6 +285,30 @@ go_physmap:
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size) >> TARGET_PAGE_BITS,
                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    if (mr->name) {
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+                xen_domid, (uint64_t)phys_offset);
+        if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
+            return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -911,6 +937,55 @@ int xen_init(void)
     return 0;
 }
 
+static void xen_read_physmap(XenIOState *state)
+{
+    XenPhysmap *physmap = NULL;
+    unsigned int len, num, i;
+    char path[80], *value = NULL;
+    char **entries = NULL;
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap", xen_domid);
+    entries = xs_directory(state->xenstore, 0, path, &num);
+    if (entries == NULL)
+        return;
+
+    for (i = 0; i < num; i++) {
+        physmap = g_malloc(sizeof (XenPhysmap));
+        physmap->phys_offset = strtoull(entries[i], NULL, 16);
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/start_addr",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->start_addr = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/size",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->size = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/name",
+                xen_domid, entries[i]);
+        physmap->name = xs_read(state->xenstore, 0, path, &len);
+
+        QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+    }
+    free(entries);
+    return;
+}
+
 int xen_hvm_init(void)
 {
     int i, rc;
@@ -986,6 +1061,7 @@ int xen_hvm_init(void)
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
+    xen_read_physmap(state);
 
     return 0;
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 4/6] xen: record physmap changes to xenstore
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, xen-devel, avi, anthony, Stefano Stabellini

Write to xenstore any physmap changes so that the hypervisor can be
aware of them.
Read physmap changes from xenstore on boot.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 1 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index b0ed1ed..f2cad82 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -65,7 +65,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 typedef struct XenPhysmap {
     target_phys_addr_t start_addr;
     ram_addr_t size;
-    MemoryRegion *mr;
+    char *name;
     target_phys_addr_t phys_offset;
 
     QLIST_ENTRY(XenPhysmap) list;
@@ -237,6 +237,7 @@ static int xen_add_to_physmap(XenIOState *state,
     XenPhysmap *physmap = NULL;
     target_phys_addr_t pfn, start_gpfn;
     target_phys_addr_t phys_offset = memory_region_get_ram_addr(mr);
+    char path[80], value[17];
 
     if (get_physmapping(state, start_addr, size)) {
         return 0;
@@ -275,6 +276,7 @@ go_physmap:
 
     physmap->start_addr = start_addr;
     physmap->size = size;
+    physmap->name = (char *)mr->name;
     physmap->phys_offset = phys_offset;
 
     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
@@ -283,6 +285,30 @@ go_physmap:
                                    start_addr >> TARGET_PAGE_BITS,
                                    (start_addr + size) >> TARGET_PAGE_BITS,
                                    XEN_DOMCTL_MEM_CACHEATTR_WB);
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/start_addr",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)start_addr);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap/%"PRIx64"/size",
+            xen_domid, (uint64_t)phys_offset);
+    snprintf(value, sizeof(value), "%"PRIx64, (uint64_t)size);
+    if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
+        return -1;
+    }
+    if (mr->name) {
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
+                xen_domid, (uint64_t)phys_offset);
+        if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
+            return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -911,6 +937,55 @@ int xen_init(void)
     return 0;
 }
 
+static void xen_read_physmap(XenIOState *state)
+{
+    XenPhysmap *physmap = NULL;
+    unsigned int len, num, i;
+    char path[80], *value = NULL;
+    char **entries = NULL;
+
+    snprintf(path, sizeof(path),
+            "/local/domain/0/device-model/%d/physmap", xen_domid);
+    entries = xs_directory(state->xenstore, 0, path, &num);
+    if (entries == NULL)
+        return;
+
+    for (i = 0; i < num; i++) {
+        physmap = g_malloc(sizeof (XenPhysmap));
+        physmap->phys_offset = strtoull(entries[i], NULL, 16);
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/start_addr",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->start_addr = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/size",
+                xen_domid, entries[i]);
+        value = xs_read(state->xenstore, 0, path, &len);
+        if (value == NULL) {
+            free(physmap);
+            continue;
+        }
+        physmap->size = strtoull(value, NULL, 16);
+        free(value);
+
+        snprintf(path, sizeof(path),
+                "/local/domain/0/device-model/%d/physmap/%s/name",
+                xen_domid, entries[i]);
+        physmap->name = xs_read(state->xenstore, 0, path, &len);
+
+        QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+    }
+    free(entries);
+    return;
+}
+
 int xen_hvm_init(void)
 {
     int i, rc;
@@ -986,6 +1061,7 @@ int xen_hvm_init(void)
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
     xen_be_register("qdisk", &xen_blkdev_ops);
+    xen_read_physmap(state);
 
     return 0;
 }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 5/6] xen mapcache: check if memory region has moved.
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, avi, anthony, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

This patch changes the xen_map_cache behavior. Before trying to map a guest
addr, mapcache will look into the list of range of address that have been moved
(physmap/set_memory). There is currently one memory space like this, the vram,
"moved" from were it's allocated to were the guest will look into.

This help to have a succefull migration.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c      |   18 +++++++++++++++++-
 xen-mapcache.c |   22 +++++++++++++++++++---
 xen-mapcache.h |    9 +++++++--
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index f2cad82..972cffd 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -225,6 +225,22 @@ static XenPhysmap *get_physmapping(XenIOState *state,
     return NULL;
 }
 
+static target_phys_addr_t xen_phys_offset_to_gaddr(target_phys_addr_t start_addr,
+                                                   ram_addr_t size, void *opaque)
+{
+    target_phys_addr_t addr = start_addr & TARGET_PAGE_MASK;
+    XenIOState *xen_io_state = opaque;
+    XenPhysmap *physmap = NULL;
+
+    QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
+        if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
+            return physmap->start_addr;
+        }
+    }
+
+    return start_addr;
+}
+
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
 static int xen_add_to_physmap(XenIOState *state,
                               target_phys_addr_t start_addr,
@@ -1043,7 +1059,7 @@ int xen_hvm_init(void)
     }
 
     /* Init RAM management */
-    xen_map_cache_init();
+    xen_map_cache_init(xen_phys_offset_to_gaddr, state);
     xen_ram_init(ram_size);
 
     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 585b559..a456479 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -78,6 +78,9 @@ typedef struct MapCache {
     uint8_t *last_address_vaddr;
     unsigned long max_mcache_size;
     unsigned int mcache_bucket_shift;
+
+    phys_offset_to_gaddr_t phys_offset_to_gaddr;
+    void *opaque;
 } MapCache;
 
 static MapCache *mapcache;
@@ -91,13 +94,16 @@ static inline int test_bits(int nr, int size, const unsigned long *addr)
         return 0;
 }
 
-void xen_map_cache_init(void)
+void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 {
     unsigned long size;
     struct rlimit rlimit_as;
 
     mapcache = g_malloc0(sizeof (MapCache));
 
+    mapcache->phys_offset_to_gaddr = f;
+    mapcache->opaque = opaque;
+
     QTAILQ_INIT(&mapcache->locked_entries);
     mapcache->last_address_index = -1;
 
@@ -193,9 +199,14 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock)
 {
     MapCacheEntry *entry, *pentry = NULL;
-    target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-    target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    target_phys_addr_t address_index;
+    target_phys_addr_t address_offset;
     target_phys_addr_t __size = size;
+    bool translated = false;
+
+tryagain:
+    address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
 
     trace_xen_map_cache(phys_addr);
 
@@ -237,6 +248,11 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
     if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
                 entry->valid_mapping)) {
         mapcache->last_address_index = -1;
+        if (!translated && mapcache->phys_offset_to_gaddr) {
+            phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
+            translated = true;
+            goto tryagain;
+        }
         trace_xen_map_cache_return(NULL);
         return NULL;
     }
diff --git a/xen-mapcache.h b/xen-mapcache.h
index da874ca..70301a5 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -11,9 +11,13 @@
 
 #include <stdlib.h>
 
+typedef target_phys_addr_t (*phys_offset_to_gaddr_t)(target_phys_addr_t start_addr,
+                                                     ram_addr_t size,
+                                                     void *opaque);
 #ifdef CONFIG_XEN
 
-void xen_map_cache_init(void);
+void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                        void *opaque);
 uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -22,7 +26,8 @@ void xen_invalidate_map_cache(void);
 
 #else
 
-static inline void xen_map_cache_init(void)
+static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                                      void *opaque)
 {
 }
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 5/6] xen mapcache: check if memory region has moved.
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, avi, anthony, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

This patch changes the xen_map_cache behavior. Before trying to map a guest
addr, mapcache will look into the list of range of address that have been moved
(physmap/set_memory). There is currently one memory space like this, the vram,
"moved" from were it's allocated to were the guest will look into.

This help to have a succefull migration.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c      |   18 +++++++++++++++++-
 xen-mapcache.c |   22 +++++++++++++++++++---
 xen-mapcache.h |    9 +++++++--
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index f2cad82..972cffd 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -225,6 +225,22 @@ static XenPhysmap *get_physmapping(XenIOState *state,
     return NULL;
 }
 
+static target_phys_addr_t xen_phys_offset_to_gaddr(target_phys_addr_t start_addr,
+                                                   ram_addr_t size, void *opaque)
+{
+    target_phys_addr_t addr = start_addr & TARGET_PAGE_MASK;
+    XenIOState *xen_io_state = opaque;
+    XenPhysmap *physmap = NULL;
+
+    QLIST_FOREACH(physmap, &xen_io_state->physmap, list) {
+        if (range_covers_byte(physmap->phys_offset, physmap->size, addr)) {
+            return physmap->start_addr;
+        }
+    }
+
+    return start_addr;
+}
+
 #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
 static int xen_add_to_physmap(XenIOState *state,
                               target_phys_addr_t start_addr,
@@ -1043,7 +1059,7 @@ int xen_hvm_init(void)
     }
 
     /* Init RAM management */
-    xen_map_cache_init();
+    xen_map_cache_init(xen_phys_offset_to_gaddr, state);
     xen_ram_init(ram_size);
 
     qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 585b559..a456479 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -78,6 +78,9 @@ typedef struct MapCache {
     uint8_t *last_address_vaddr;
     unsigned long max_mcache_size;
     unsigned int mcache_bucket_shift;
+
+    phys_offset_to_gaddr_t phys_offset_to_gaddr;
+    void *opaque;
 } MapCache;
 
 static MapCache *mapcache;
@@ -91,13 +94,16 @@ static inline int test_bits(int nr, int size, const unsigned long *addr)
         return 0;
 }
 
-void xen_map_cache_init(void)
+void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque)
 {
     unsigned long size;
     struct rlimit rlimit_as;
 
     mapcache = g_malloc0(sizeof (MapCache));
 
+    mapcache->phys_offset_to_gaddr = f;
+    mapcache->opaque = opaque;
+
     QTAILQ_INIT(&mapcache->locked_entries);
     mapcache->last_address_index = -1;
 
@@ -193,9 +199,14 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock)
 {
     MapCacheEntry *entry, *pentry = NULL;
-    target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
-    target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    target_phys_addr_t address_index;
+    target_phys_addr_t address_offset;
     target_phys_addr_t __size = size;
+    bool translated = false;
+
+tryagain:
+    address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
+    address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
 
     trace_xen_map_cache(phys_addr);
 
@@ -237,6 +248,11 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
     if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
                 entry->valid_mapping)) {
         mapcache->last_address_index = -1;
+        if (!translated && mapcache->phys_offset_to_gaddr) {
+            phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque);
+            translated = true;
+            goto tryagain;
+        }
         trace_xen_map_cache_return(NULL);
         return NULL;
     }
diff --git a/xen-mapcache.h b/xen-mapcache.h
index da874ca..70301a5 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -11,9 +11,13 @@
 
 #include <stdlib.h>
 
+typedef target_phys_addr_t (*phys_offset_to_gaddr_t)(target_phys_addr_t start_addr,
+                                                     ram_addr_t size,
+                                                     void *opaque);
 #ifdef CONFIG_XEN
 
-void xen_map_cache_init(void);
+void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                        void *opaque);
 uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
                        uint8_t lock);
 ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
@@ -22,7 +26,8 @@ void xen_invalidate_map_cache(void);
 
 #else
 
-static inline void xen_map_cache_init(void)
+static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
+                                      void *opaque)
 {
 }
 
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [Qemu-devel] [PATCH RESEND v5 6/6] xen: do not allocate RAM during INMIGRATE runstate
  2012-02-28 15:50 ` Stefano Stabellini
@ 2012-02-28 15:51   ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, avi, anthony, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 972cffd..10d53d1 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -190,6 +190,14 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
     xen_pfn_t *pfn_list;
     int i;
 
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        /* RAM already populated in Xen */
+        fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
+                " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
+                __func__, size, ram_addr); 
+        return;
+    }
+
     if (mr == &ram_memory) {
         return;
     }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH RESEND v5 6/6] xen: do not allocate RAM during INMIGRATE runstate
@ 2012-02-28 15:51   ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-02-28 15:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, avi, anthony, Anthony PERARD

From: Anthony PERARD <anthony.perard@citrix.com>

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 xen-all.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 972cffd..10d53d1 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -190,6 +190,14 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, MemoryRegion *mr)
     xen_pfn_t *pfn_list;
     int i;
 
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        /* RAM already populated in Xen */
+        fprintf(stderr, "%s: do not alloc "RAM_ADDR_FMT
+                " bytes of ram at "RAM_ADDR_FMT" when runstate is INMIGRATE\n",
+                __func__, size, ram_addr); 
+        return;
+    }
+
     if (mr == &ram_memory) {
         return;
     }
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
  2012-02-28 15:51   ` Stefano Stabellini
  (?)
@ 2012-02-28 18:35   ` Anthony PERARD
  -1 siblings, 0 replies; 33+ messages in thread
From: Anthony PERARD @ 2012-02-28 18:35 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On 28/02/12 15:51, Stefano Stabellini wrote:
> There is no need to set the videoram to 0xff in cirrus_reset, because it
> is the BIOS' job.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
  2012-02-28 15:51   ` Stefano Stabellini
@ 2012-02-28 18:58     ` Anthony PERARD
  -1 siblings, 0 replies; 33+ messages in thread
From: Anthony PERARD @ 2012-02-28 18:58 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On 28/02/12 15:51, Stefano Stabellini wrote:
> - add an "is_ram" flag to SaveStateEntry;
>
> - add an "is_ram" parameter to register_savevm_live;
>
> - introduce a "save_devices" monitor command that can be used to save
> the state of non-ram devices.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   block-migration.c |    2 +-
>   hmp-commands.hx   |   14 ++++++++++
>   qmp-commands.hx   |   17 ++++++++++++
>   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   sysemu.h          |    1 +
>   vl.c              |    2 +-
>   vmstate.h         |    1 +
>   7 files changed, 106 insertions(+), 3 deletions(-)
>
> diff --git a/block-migration.c b/block-migration.c
> index 4467468..d283fd0 100644
> --- a/block-migration.c
> +++ b/block-migration.c
> @@ -722,6 +722,6 @@ void blk_mig_init(void)
>       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
>       QSIMPLEQ_INIT(&block_mig_state.blk_list);
>
> -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
>                            block_save_live, NULL, block_load,&block_mig_state);
>   }
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 64b3656..873abc9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
>   ETEXI
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +STEXI
> +@item save_devices @var{filename}
> +@findex save_devices
> +Save the state of non-ram devices.
> +ETEXI
> +
> +    {
>           .name       = "loadvm",
>           .args_type  = "name:s",
>           .params     = "tag|id",
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 705f704..619d9de 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
>   EQMP
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .user_print = monitor_user_noop,	
> +    .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +SQMP
> +save_devices
> +-------
> +
> +Save the state of non-ram devices.
> +
> +EQMP
> +
> +    {
>           .name       = "migrate",
>           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
>           .params     = "[-d] [-b] [-i] uri",
> diff --git a/savevm.c b/savevm.c
> index 80be1ff..d0e62bb 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
>       void *opaque;
>       CompatEntry *compat;
>       int no_migrate;
> +    int is_ram;
>   } SaveStateEntry;
>
>
> @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,
> @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
>       se->opaque = opaque;
>       se->vmsd = NULL;
>       se->no_migrate = 0;
> +    se->is_ram = is_ram;
>
>       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
>           char *id = dev->parent_bus->info->get_dev_path(dev);
> @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
>                       LoadStateHandler *load_state,
>                       void *opaque)
>   {
> -    return register_savevm_live(dev, idstr, instance_id, version_id,
> +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
>                                   NULL, NULL, save_state, load_state, opaque);
>   }
>
> @@ -1728,6 +1731,43 @@ out:
>       return ret;
>   }
>
> +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> +{
> +    SaveStateEntry *se;
> +
> +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> +
> +    cpu_synchronize_all_states();
> +
> +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> +        int len;
> +
> +        if (se->is_ram)
> +            continue;
> +        if (se->save_state == NULL&&  se->vmsd == NULL)
> +            continue;
> +
> +        /* Section type */
> +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> +        qemu_put_be32(f, se->section_id);
> +
> +        /* 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);
> +
> +        vmstate_save(f, se);
> +    }
> +
> +    qemu_put_byte(f, QEMU_VM_EOF);
> +
> +    return qemu_file_get_error(f);
> +}
> +
>   static SaveStateEntry *find_se(const char *idstr, int instance_id)
>   {
>       SaveStateEntry *se;
> @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
>           vm_start();
>   }
>
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +{
> +    int ret;
> +    QEMUFile *f;
> +    int saved_vm_running;
> +    const char *filename = qdict_get_try_str(qdict, "filename");
> +
> +    saved_vm_running = runstate_is_running();
> +    vm_stop(RUN_STATE_SAVE_VM);
> +
> +    f = qemu_fopen(filename, "wb");
> +    if (!f) {
> +        monitor_printf(mon, "Could not open VM state file\n");
> +        ret = -1;
> +        goto the_end;
> +    }
> +    ret = qemu_save_device_state(mon, f);
> +    qemu_fclose(f);
> +    if (ret<  0) {
> +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> +        goto the_end;
> +    }
> +    ret = 0;
> +
> + the_end:
> +    if (saved_vm_running)
> +        vm_start();
> +    return ret;
> +}
> +
>   int load_vmstate(const char *name)
>   {
>       BlockDriverState *bs, *bs_vm_state;
> diff --git a/sysemu.h b/sysemu.h
> index 98118cc..f4d5bf4 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
>   void qemu_add_machine_init_done_notifier(Notifier *notify);
>
>   void do_savevm(Monitor *mon, const QDict *qdict);
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int load_vmstate(const char *name);
>   void do_delvm(Monitor *mon, const QDict *qdict);
>   void do_info_snapshots(Monitor *mon);
> diff --git a/vl.c b/vl.c
> index 1d4c350..5b2b84c 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
>       default_drive(default_sdcard, snapshot, machine->use_scsi,
>                     IF_SD, 0, SD_OPTS);
>
> -    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
> +    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
>                            ram_load, NULL);
>
>       if (nb_numa_nodes>  0) {
> diff --git a/vmstate.h b/vmstate.h
> index 9d3c49c..3cef117 100644
> --- a/vmstate.h
> +++ b/vmstate.h
> @@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 2/6] Introduce "save_devices"
@ 2012-02-28 18:58     ` Anthony PERARD
  0 siblings, 0 replies; 33+ messages in thread
From: Anthony PERARD @ 2012-02-28 18:58 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On 28/02/12 15:51, Stefano Stabellini wrote:
> - add an "is_ram" flag to SaveStateEntry;
>
> - add an "is_ram" parameter to register_savevm_live;
>
> - introduce a "save_devices" monitor command that can be used to save
> the state of non-ram devices.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   block-migration.c |    2 +-
>   hmp-commands.hx   |   14 ++++++++++
>   qmp-commands.hx   |   17 ++++++++++++
>   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   sysemu.h          |    1 +
>   vl.c              |    2 +-
>   vmstate.h         |    1 +
>   7 files changed, 106 insertions(+), 3 deletions(-)
>
> diff --git a/block-migration.c b/block-migration.c
> index 4467468..d283fd0 100644
> --- a/block-migration.c
> +++ b/block-migration.c
> @@ -722,6 +722,6 @@ void blk_mig_init(void)
>       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
>       QSIMPLEQ_INIT(&block_mig_state.blk_list);
>
> -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
>                            block_save_live, NULL, block_load,&block_mig_state);
>   }
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 64b3656..873abc9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
>   ETEXI
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +STEXI
> +@item save_devices @var{filename}
> +@findex save_devices
> +Save the state of non-ram devices.
> +ETEXI
> +
> +    {
>           .name       = "loadvm",
>           .args_type  = "name:s",
>           .params     = "tag|id",
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 705f704..619d9de 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
>   EQMP
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .user_print = monitor_user_noop,	
> +    .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +SQMP
> +save_devices
> +-------
> +
> +Save the state of non-ram devices.
> +
> +EQMP
> +
> +    {
>           .name       = "migrate",
>           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
>           .params     = "[-d] [-b] [-i] uri",
> diff --git a/savevm.c b/savevm.c
> index 80be1ff..d0e62bb 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
>       void *opaque;
>       CompatEntry *compat;
>       int no_migrate;
> +    int is_ram;
>   } SaveStateEntry;
>
>
> @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,
> @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
>       se->opaque = opaque;
>       se->vmsd = NULL;
>       se->no_migrate = 0;
> +    se->is_ram = is_ram;
>
>       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
>           char *id = dev->parent_bus->info->get_dev_path(dev);
> @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
>                       LoadStateHandler *load_state,
>                       void *opaque)
>   {
> -    return register_savevm_live(dev, idstr, instance_id, version_id,
> +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
>                                   NULL, NULL, save_state, load_state, opaque);
>   }
>
> @@ -1728,6 +1731,43 @@ out:
>       return ret;
>   }
>
> +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> +{
> +    SaveStateEntry *se;
> +
> +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> +
> +    cpu_synchronize_all_states();
> +
> +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> +        int len;
> +
> +        if (se->is_ram)
> +            continue;
> +        if (se->save_state == NULL&&  se->vmsd == NULL)
> +            continue;
> +
> +        /* Section type */
> +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> +        qemu_put_be32(f, se->section_id);
> +
> +        /* 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);
> +
> +        vmstate_save(f, se);
> +    }
> +
> +    qemu_put_byte(f, QEMU_VM_EOF);
> +
> +    return qemu_file_get_error(f);
> +}
> +
>   static SaveStateEntry *find_se(const char *idstr, int instance_id)
>   {
>       SaveStateEntry *se;
> @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
>           vm_start();
>   }
>
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +{
> +    int ret;
> +    QEMUFile *f;
> +    int saved_vm_running;
> +    const char *filename = qdict_get_try_str(qdict, "filename");
> +
> +    saved_vm_running = runstate_is_running();
> +    vm_stop(RUN_STATE_SAVE_VM);
> +
> +    f = qemu_fopen(filename, "wb");
> +    if (!f) {
> +        monitor_printf(mon, "Could not open VM state file\n");
> +        ret = -1;
> +        goto the_end;
> +    }
> +    ret = qemu_save_device_state(mon, f);
> +    qemu_fclose(f);
> +    if (ret<  0) {
> +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> +        goto the_end;
> +    }
> +    ret = 0;
> +
> + the_end:
> +    if (saved_vm_running)
> +        vm_start();
> +    return ret;
> +}
> +
>   int load_vmstate(const char *name)
>   {
>       BlockDriverState *bs, *bs_vm_state;
> diff --git a/sysemu.h b/sysemu.h
> index 98118cc..f4d5bf4 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
>   void qemu_add_machine_init_done_notifier(Notifier *notify);
>
>   void do_savevm(Monitor *mon, const QDict *qdict);
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int load_vmstate(const char *name);
>   void do_delvm(Monitor *mon, const QDict *qdict);
>   void do_info_snapshots(Monitor *mon);
> diff --git a/vl.c b/vl.c
> index 1d4c350..5b2b84c 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
>       default_drive(default_sdcard, snapshot, machine->use_scsi,
>                     IF_SD, 0, SD_OPTS);
>
> -    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
> +    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
>                            ram_load, NULL);
>
>       if (nb_numa_nodes>  0) {
> diff --git a/vmstate.h b/vmstate.h
> index 9d3c49c..3cef117 100644
> --- a/vmstate.h
> +++ b/vmstate.h
> @@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
  2012-02-28 15:51   ` Stefano Stabellini
@ 2012-02-28 19:34     ` Anthony PERARD
  -1 siblings, 0 replies; 33+ messages in thread
From: Anthony PERARD @ 2012-02-28 19:34 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On 28/02/12 15:51, Stefano Stabellini wrote:
> Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
@ 2012-02-28 19:34     ` Anthony PERARD
  0 siblings, 0 replies; 33+ messages in thread
From: Anthony PERARD @ 2012-02-28 19:34 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On 28/02/12 15:51, Stefano Stabellini wrote:
> Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>

Acked-by: Anthony PERARD <anthony.perard@citrix.com>

-- 
Anthony PERARD

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
  2012-02-28 15:51   ` Stefano Stabellini
@ 2012-03-07 17:41     ` Luiz Capitulino
  -1 siblings, 0 replies; 33+ messages in thread
From: Luiz Capitulino @ 2012-03-07 17:41 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On Tue, 28 Feb 2012 15:51:32 +0000
Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:

> Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Would be nice to explain why, but I suggested this myself so:

 Acked-by: Luiz Capitulino <lcapitulino@redhat.com>

> ---
>  vl.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/vl.c b/vl.c
> index 5b2b84c..341775b 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3099,6 +3099,7 @@ int main(int argc, char **argv, char **envp)
>                  break;
>              case QEMU_OPTION_incoming:
>                  incoming = optarg;
> +                runstate_set(RUN_STATE_INMIGRATE);
>                  break;
>              case QEMU_OPTION_nodefaults:
>                  default_serial = 0;
> @@ -3596,7 +3597,6 @@ int main(int argc, char **argv, char **envp)
>      }
>  
>      if (incoming) {
> -        runstate_set(RUN_STATE_INMIGRATE);
>          int ret = qemu_start_incoming_migration(incoming);
>          if (ret < 0) {
>              fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
@ 2012-03-07 17:41     ` Luiz Capitulino
  0 siblings, 0 replies; 33+ messages in thread
From: Luiz Capitulino @ 2012-03-07 17:41 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, avi

On Tue, 28 Feb 2012 15:51:32 +0000
Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:

> Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Would be nice to explain why, but I suggested this myself so:

 Acked-by: Luiz Capitulino <lcapitulino@redhat.com>

> ---
>  vl.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/vl.c b/vl.c
> index 5b2b84c..341775b 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3099,6 +3099,7 @@ int main(int argc, char **argv, char **envp)
>                  break;
>              case QEMU_OPTION_incoming:
>                  incoming = optarg;
> +                runstate_set(RUN_STATE_INMIGRATE);
>                  break;
>              case QEMU_OPTION_nodefaults:
>                  default_serial = 0;
> @@ -3596,7 +3597,6 @@ int main(int argc, char **argv, char **envp)
>      }
>  
>      if (incoming) {
> -        runstate_set(RUN_STATE_INMIGRATE);
>          int ret = qemu_start_incoming_migration(incoming);
>          if (ret < 0) {
>              fprintf(stderr, "Migration failed. Exit code %s(%d), exiting.\n",

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
  2012-03-07 17:41     ` Luiz Capitulino
@ 2012-03-12 12:17       ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-12 12:17 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, qemu-devel, avi, anthony

On Wed, 7 Mar 2012, Luiz Capitulino wrote:
> On Tue, 28 Feb 2012 15:51:32 +0000
> Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:
> 
> > Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> Would be nice to explain why, but I suggested this myself so:
> 
>  Acked-by: Luiz Capitulino <lcapitulino@redhat.com>

Thanks!
It would be nice if somebody took the time to review patch #1 and #2 too
considering that they have been sitting there for a while...

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier
@ 2012-03-12 12:17       ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-12 12:17 UTC (permalink / raw)
  To: Luiz Capitulino
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, qemu-devel, avi, anthony

On Wed, 7 Mar 2012, Luiz Capitulino wrote:
> On Tue, 28 Feb 2012 15:51:32 +0000
> Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:
> 
> > Set runstate to RUN_STATE_INMIGRATE as soon as we can on resume.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> Would be nice to explain why, but I suggested this myself so:
> 
>  Acked-by: Luiz Capitulino <lcapitulino@redhat.com>

Thanks!
It would be nice if somebody took the time to review patch #1 and #2 too
considering that they have been sitting there for a while...

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
  2012-02-28 15:51   ` Stefano Stabellini
@ 2012-03-12 12:43     ` Avi Kivity
  -1 siblings, 0 replies; 33+ messages in thread
From: Avi Kivity @ 2012-03-12 12:43 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony

On 02/28/2012 05:51 PM, Stefano Stabellini wrote:
> There is no need to set the videoram to 0xff in cirrus_reset, because it
> is the BIOS' job.
>

Reviewed-by: Avi Kivity <avi@redhat.com>

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
@ 2012-03-12 12:43     ` Avi Kivity
  0 siblings, 0 replies; 33+ messages in thread
From: Avi Kivity @ 2012-03-12 12:43 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony

On 02/28/2012 05:51 PM, Stefano Stabellini wrote:
> There is no need to set the videoram to 0xff in cirrus_reset, because it
> is the BIOS' job.
>

Reviewed-by: Avi Kivity <avi@redhat.com>

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
  2012-03-12 12:43     ` Avi Kivity
@ 2012-03-12 13:18       ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-12 13:18 UTC (permalink / raw)
  To: Avi Kivity; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, Stefano Stabellini

On Mon, 12 Mar 2012, Avi Kivity wrote:
> On 02/28/2012 05:51 PM, Stefano Stabellini wrote:
> > There is no need to set the videoram to 0xff in cirrus_reset, because it
> > is the BIOS' job.
> >
> 
> Reviewed-by: Avi Kivity <avi@redhat.com>

thanks!!

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram
@ 2012-03-12 13:18       ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-12 13:18 UTC (permalink / raw)
  To: Avi Kivity; +Cc: jan.kiszka, xen-devel, qemu-devel, anthony, Stefano Stabellini

On Mon, 12 Mar 2012, Avi Kivity wrote:
> On 02/28/2012 05:51 PM, Stefano Stabellini wrote:
> > There is no need to set the videoram to 0xff in cirrus_reset, because it
> > is the BIOS' job.
> >
> 
> Reviewed-by: Avi Kivity <avi@redhat.com>

thanks!!

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
  2012-02-28 15:51   ` Stefano Stabellini
@ 2012-03-12 18:33     ` Anthony Liguori
  -1 siblings, 0 replies; 33+ messages in thread
From: Anthony Liguori @ 2012-03-12 18:33 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Luiz Capitulino, jan.kiszka, xen-devel, qemu-devel, avi

On 02/28/2012 09:51 AM, Stefano Stabellini wrote:
> - add an "is_ram" flag to SaveStateEntry;
>
> - add an "is_ram" parameter to register_savevm_live;
>
> - introduce a "save_devices" monitor command that can be used to save
> the state of non-ram devices.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   block-migration.c |    2 +-
>   hmp-commands.hx   |   14 ++++++++++
>   qmp-commands.hx   |   17 ++++++++++++
>   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   sysemu.h          |    1 +
>   vl.c              |    2 +-
>   vmstate.h         |    1 +
>   7 files changed, 106 insertions(+), 3 deletions(-)
>
> diff --git a/block-migration.c b/block-migration.c
> index 4467468..d283fd0 100644
> --- a/block-migration.c
> +++ b/block-migration.c
> @@ -722,6 +722,6 @@ void blk_mig_init(void)
>       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
>       QSIMPLEQ_INIT(&block_mig_state.blk_list);
>
> -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
>                            block_save_live, NULL, block_load,&block_mig_state);

Do you really want the block live migration to be part of Xen?

If not, then you can simplify by just making register_savevm_live always imply 
!device and adjust register_savevm() accordingly.  Otherwise, the likelihood of 
a casual observer knowing what '0, 1, 0' means is pretty bad...

>   }
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 64b3656..873abc9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
>   ETEXI
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +STEXI
> +@item save_devices @var{filename}
> +@findex save_devices
> +Save the state of non-ram devices.
> +ETEXI
> +
> +    {
>           .name       = "loadvm",
>           .args_type  = "name:s",
>           .params     = "tag|id",
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 705f704..619d9de 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
>   EQMP
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .user_print = monitor_user_noop,	
> +    .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +SQMP
> +save_devices
> +-------
> +
> +Save the state of non-ram devices.
> +
> +EQMP
> +
> +    {
>           .name       = "migrate",
>           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
>           .params     = "[-d] [-b] [-i] uri",


Should be QAPI commands and documented a great deal more (see other examples in 
qapi-schema.json).  Please CC Luiz too when adding new QMP commands.

> diff --git a/savevm.c b/savevm.c
> index 80be1ff..d0e62bb 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
>       void *opaque;
>       CompatEntry *compat;
>       int no_migrate;
> +    int is_ram;
>   } SaveStateEntry;
>
>
> @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,
> @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
>       se->opaque = opaque;
>       se->vmsd = NULL;
>       se->no_migrate = 0;
> +    se->is_ram = is_ram;
>
>       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
>           char *id = dev->parent_bus->info->get_dev_path(dev);
> @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
>                       LoadStateHandler *load_state,
>                       void *opaque)
>   {
> -    return register_savevm_live(dev, idstr, instance_id, version_id,
> +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
>                                   NULL, NULL, save_state, load_state, opaque);
>   }
>
> @@ -1728,6 +1731,43 @@ out:
>       return ret;
>   }
>
> +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> +{
> +    SaveStateEntry *se;
> +
> +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> +
> +    cpu_synchronize_all_states();
> +
> +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> +        int len;
> +
> +        if (se->is_ram)
> +            continue;

Violating CODING_STYLE.

> +        if (se->save_state == NULL&&  se->vmsd == NULL)
> +            continue;
> +
> +        /* Section type */
> +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> +        qemu_put_be32(f, se->section_id);
> +
> +        /* 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);
> +
> +        vmstate_save(f, se);
> +    }
> +
> +    qemu_put_byte(f, QEMU_VM_EOF);
> +
> +    return qemu_file_get_error(f);
> +}

Please add something to docs/ documenting this format.

> +
>   static SaveStateEntry *find_se(const char *idstr, int instance_id)
>   {
>       SaveStateEntry *se;
> @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
>           vm_start();
>   }
>
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +{
> +    int ret;
> +    QEMUFile *f;
> +    int saved_vm_running;
> +    const char *filename = qdict_get_try_str(qdict, "filename");
> +
> +    saved_vm_running = runstate_is_running();
> +    vm_stop(RUN_STATE_SAVE_VM);
> +
> +    f = qemu_fopen(filename, "wb");
> +    if (!f) {
> +        monitor_printf(mon, "Could not open VM state file\n");
> +        ret = -1;
> +        goto the_end;
> +    }
> +    ret = qemu_save_device_state(mon, f);
> +    qemu_fclose(f);
> +    if (ret<  0) {
> +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> +        goto the_end;
> +    }
> +    ret = 0;
> +
> + the_end:
> +    if (saved_vm_running)
> +        vm_start();
> +    return ret;
> +}
> +

Would it be useful/interesting to return a binary blob via QMP instead of 
writing to a file?

Regards,

Anthony Liguori

>   int load_vmstate(const char *name)
>   {
>       BlockDriverState *bs, *bs_vm_state;
> diff --git a/sysemu.h b/sysemu.h
> index 98118cc..f4d5bf4 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
>   void qemu_add_machine_init_done_notifier(Notifier *notify);
>
>   void do_savevm(Monitor *mon, const QDict *qdict);
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int load_vmstate(const char *name);
>   void do_delvm(Monitor *mon, const QDict *qdict);
>   void do_info_snapshots(Monitor *mon);
> diff --git a/vl.c b/vl.c
> index 1d4c350..5b2b84c 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
>       default_drive(default_sdcard, snapshot, machine->use_scsi,
>                     IF_SD, 0, SD_OPTS);
>
> -    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
> +    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
>                            ram_load, NULL);
>
>       if (nb_numa_nodes>  0) {
> diff --git a/vmstate.h b/vmstate.h
> index 9d3c49c..3cef117 100644
> --- a/vmstate.h
> +++ b/vmstate.h
> @@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 2/6] Introduce "save_devices"
@ 2012-03-12 18:33     ` Anthony Liguori
  0 siblings, 0 replies; 33+ messages in thread
From: Anthony Liguori @ 2012-03-12 18:33 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: Luiz Capitulino, jan.kiszka, xen-devel, qemu-devel, avi

On 02/28/2012 09:51 AM, Stefano Stabellini wrote:
> - add an "is_ram" flag to SaveStateEntry;
>
> - add an "is_ram" parameter to register_savevm_live;
>
> - introduce a "save_devices" monitor command that can be used to save
> the state of non-ram devices.
>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   block-migration.c |    2 +-
>   hmp-commands.hx   |   14 ++++++++++
>   qmp-commands.hx   |   17 ++++++++++++
>   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   sysemu.h          |    1 +
>   vl.c              |    2 +-
>   vmstate.h         |    1 +
>   7 files changed, 106 insertions(+), 3 deletions(-)
>
> diff --git a/block-migration.c b/block-migration.c
> index 4467468..d283fd0 100644
> --- a/block-migration.c
> +++ b/block-migration.c
> @@ -722,6 +722,6 @@ void blk_mig_init(void)
>       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
>       QSIMPLEQ_INIT(&block_mig_state.blk_list);
>
> -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
>                            block_save_live, NULL, block_load,&block_mig_state);

Do you really want the block live migration to be part of Xen?

If not, then you can simplify by just making register_savevm_live always imply 
!device and adjust register_savevm() accordingly.  Otherwise, the likelihood of 
a casual observer knowing what '0, 1, 0' means is pretty bad...

>   }
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 64b3656..873abc9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
>   ETEXI
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +STEXI
> +@item save_devices @var{filename}
> +@findex save_devices
> +Save the state of non-ram devices.
> +ETEXI
> +
> +    {
>           .name       = "loadvm",
>           .args_type  = "name:s",
>           .params     = "tag|id",
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 705f704..619d9de 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
>   EQMP
>
>       {
> +        .name       = "save_devices",
> +        .args_type  = "filename:F",
> +        .params     = "filename",
> +        .help       = "save the state of non-ram devices.",
> +        .user_print = monitor_user_noop,	
> +    .mhandler.cmd_new = do_save_device_state,
> +    },
> +
> +SQMP
> +save_devices
> +-------
> +
> +Save the state of non-ram devices.
> +
> +EQMP
> +
> +    {
>           .name       = "migrate",
>           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
>           .params     = "[-d] [-b] [-i] uri",


Should be QAPI commands and documented a great deal more (see other examples in 
qapi-schema.json).  Please CC Luiz too when adding new QMP commands.

> diff --git a/savevm.c b/savevm.c
> index 80be1ff..d0e62bb 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
>       void *opaque;
>       CompatEntry *compat;
>       int no_migrate;
> +    int is_ram;
>   } SaveStateEntry;
>
>
> @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,
> @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
>       se->opaque = opaque;
>       se->vmsd = NULL;
>       se->no_migrate = 0;
> +    se->is_ram = is_ram;
>
>       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
>           char *id = dev->parent_bus->info->get_dev_path(dev);
> @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
>                       LoadStateHandler *load_state,
>                       void *opaque)
>   {
> -    return register_savevm_live(dev, idstr, instance_id, version_id,
> +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
>                                   NULL, NULL, save_state, load_state, opaque);
>   }
>
> @@ -1728,6 +1731,43 @@ out:
>       return ret;
>   }
>
> +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> +{
> +    SaveStateEntry *se;
> +
> +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> +
> +    cpu_synchronize_all_states();
> +
> +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> +        int len;
> +
> +        if (se->is_ram)
> +            continue;

Violating CODING_STYLE.

> +        if (se->save_state == NULL&&  se->vmsd == NULL)
> +            continue;
> +
> +        /* Section type */
> +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> +        qemu_put_be32(f, se->section_id);
> +
> +        /* 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);
> +
> +        vmstate_save(f, se);
> +    }
> +
> +    qemu_put_byte(f, QEMU_VM_EOF);
> +
> +    return qemu_file_get_error(f);
> +}

Please add something to docs/ documenting this format.

> +
>   static SaveStateEntry *find_se(const char *idstr, int instance_id)
>   {
>       SaveStateEntry *se;
> @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
>           vm_start();
>   }
>
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +{
> +    int ret;
> +    QEMUFile *f;
> +    int saved_vm_running;
> +    const char *filename = qdict_get_try_str(qdict, "filename");
> +
> +    saved_vm_running = runstate_is_running();
> +    vm_stop(RUN_STATE_SAVE_VM);
> +
> +    f = qemu_fopen(filename, "wb");
> +    if (!f) {
> +        monitor_printf(mon, "Could not open VM state file\n");
> +        ret = -1;
> +        goto the_end;
> +    }
> +    ret = qemu_save_device_state(mon, f);
> +    qemu_fclose(f);
> +    if (ret<  0) {
> +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> +        goto the_end;
> +    }
> +    ret = 0;
> +
> + the_end:
> +    if (saved_vm_running)
> +        vm_start();
> +    return ret;
> +}
> +

Would it be useful/interesting to return a binary blob via QMP instead of 
writing to a file?

Regards,

Anthony Liguori

>   int load_vmstate(const char *name)
>   {
>       BlockDriverState *bs, *bs_vm_state;
> diff --git a/sysemu.h b/sysemu.h
> index 98118cc..f4d5bf4 100644
> --- a/sysemu.h
> +++ b/sysemu.h
> @@ -70,6 +70,7 @@ void qemu_remove_exit_notifier(Notifier *notify);
>   void qemu_add_machine_init_done_notifier(Notifier *notify);
>
>   void do_savevm(Monitor *mon, const QDict *qdict);
> +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data);
>   int load_vmstate(const char *name);
>   void do_delvm(Monitor *mon, const QDict *qdict);
>   void do_info_snapshots(Monitor *mon);
> diff --git a/vl.c b/vl.c
> index 1d4c350..5b2b84c 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -3393,7 +3393,7 @@ int main(int argc, char **argv, char **envp)
>       default_drive(default_sdcard, snapshot, machine->use_scsi,
>                     IF_SD, 0, SD_OPTS);
>
> -    register_savevm_live(NULL, "ram", 0, 4, NULL, ram_save_live, NULL,
> +    register_savevm_live(NULL, "ram", 0, 4, 1, NULL, ram_save_live, NULL,
>                            ram_load, NULL);
>
>       if (nb_numa_nodes>  0) {
> diff --git a/vmstate.h b/vmstate.h
> index 9d3c49c..3cef117 100644
> --- a/vmstate.h
> +++ b/vmstate.h
> @@ -44,6 +44,7 @@ int register_savevm_live(DeviceState *dev,
>                            const char *idstr,
>                            int instance_id,
>                            int version_id,
> +                         int is_ram,
>                            SaveSetParamsHandler *set_params,
>                            SaveLiveStateHandler *save_live_state,
>                            SaveStateHandler *save_state,

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
  2012-03-12 18:33     ` Anthony Liguori
@ 2012-03-13 11:51       ` Stefano Stabellini
  -1 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-13 11:51 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, qemu-devel,
	Luiz Capitulino, avi

On Mon, 12 Mar 2012, Anthony Liguori wrote:
> On 02/28/2012 09:51 AM, Stefano Stabellini wrote:
> > - add an "is_ram" flag to SaveStateEntry;
> >
> > - add an "is_ram" parameter to register_savevm_live;
> >
> > - introduce a "save_devices" monitor command that can be used to save
> > the state of non-ram devices.
> >
> > Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> > ---
> >   block-migration.c |    2 +-
> >   hmp-commands.hx   |   14 ++++++++++
> >   qmp-commands.hx   |   17 ++++++++++++
> >   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >   sysemu.h          |    1 +
> >   vl.c              |    2 +-
> >   vmstate.h         |    1 +
> >   7 files changed, 106 insertions(+), 3 deletions(-)
> >
> > diff --git a/block-migration.c b/block-migration.c
> > index 4467468..d283fd0 100644
> > --- a/block-migration.c
> > +++ b/block-migration.c
> > @@ -722,6 +722,6 @@ void blk_mig_init(void)
> >       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
> >       QSIMPLEQ_INIT(&block_mig_state.blk_list);
> >
> > -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> > +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
> >                            block_save_live, NULL, block_load,&block_mig_state);
> 
> Do you really want the block live migration to be part of Xen?
> 
> If not, then you can simplify by just making register_savevm_live always imply 
> !device and adjust register_savevm() accordingly.  Otherwise, the likelihood of 
> a casual observer knowing what '0, 1, 0' means is pretty bad...

That's a good point, I'll do that.


> >   }
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index 64b3656..873abc9 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
> >   ETEXI
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +STEXI
> > +@item save_devices @var{filename}
> > +@findex save_devices
> > +Save the state of non-ram devices.
> > +ETEXI
> > +
> > +    {
> >           .name       = "loadvm",
> >           .args_type  = "name:s",
> >           .params     = "tag|id",
> > diff --git a/qmp-commands.hx b/qmp-commands.hx
> > index 705f704..619d9de 100644
> > --- a/qmp-commands.hx
> > +++ b/qmp-commands.hx
> > @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
> >   EQMP
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .user_print = monitor_user_noop,	
> > +    .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +SQMP
> > +save_devices
> > +-------
> > +
> > +Save the state of non-ram devices.
> > +
> > +EQMP
> > +
> > +    {
> >           .name       = "migrate",
> >           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
> >           .params     = "[-d] [-b] [-i] uri",
> 
> 
> Should be QAPI commands and documented a great deal more (see other examples in 
> qapi-schema.json).  Please CC Luiz too when adding new QMP commands.

OK, I'll do.


> > diff --git a/savevm.c b/savevm.c
> > index 80be1ff..d0e62bb 100644
> > --- a/savevm.c
> > +++ b/savevm.c
> > @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
> >       void *opaque;
> >       CompatEntry *compat;
> >       int no_migrate;
> > +    int is_ram;
> >   } SaveStateEntry;
> >
> >
> > @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
> >                            const char *idstr,
> >                            int instance_id,
> >                            int version_id,
> > +                         int is_ram,
> >                            SaveSetParamsHandler *set_params,
> >                            SaveLiveStateHandler *save_live_state,
> >                            SaveStateHandler *save_state,
> > @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
> >       se->opaque = opaque;
> >       se->vmsd = NULL;
> >       se->no_migrate = 0;
> > +    se->is_ram = is_ram;
> >
> >       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
> >           char *id = dev->parent_bus->info->get_dev_path(dev);
> > @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
> >                       LoadStateHandler *load_state,
> >                       void *opaque)
> >   {
> > -    return register_savevm_live(dev, idstr, instance_id, version_id,
> > +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
> >                                   NULL, NULL, save_state, load_state, opaque);
> >   }
> >
> > @@ -1728,6 +1731,43 @@ out:
> >       return ret;
> >   }
> >
> > +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> > +{
> > +    SaveStateEntry *se;
> > +
> > +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> > +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> > +
> > +    cpu_synchronize_all_states();
> > +
> > +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> > +        int len;
> > +
> > +        if (se->is_ram)
> > +            continue;
> 
> Violating CODING_STYLE.

I'll fix that.


> > +        if (se->save_state == NULL&&  se->vmsd == NULL)
> > +            continue;
> > +
> > +        /* Section type */
> > +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> > +        qemu_put_be32(f, se->section_id);
> > +
> > +        /* 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);
> > +
> > +        vmstate_save(f, se);
> > +    }
> > +
> > +    qemu_put_byte(f, QEMU_VM_EOF);
> > +
> > +    return qemu_file_get_error(f);
> > +}
> 
> Please add something to docs/ documenting this format.

OK


> > +
> >   static SaveStateEntry *find_se(const char *idstr, int instance_id)
> >   {
> >       SaveStateEntry *se;
> > @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
> >           vm_start();
> >   }
> >
> > +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> > +{
> > +    int ret;
> > +    QEMUFile *f;
> > +    int saved_vm_running;
> > +    const char *filename = qdict_get_try_str(qdict, "filename");
> > +
> > +    saved_vm_running = runstate_is_running();
> > +    vm_stop(RUN_STATE_SAVE_VM);
> > +
> > +    f = qemu_fopen(filename, "wb");
> > +    if (!f) {
> > +        monitor_printf(mon, "Could not open VM state file\n");
> > +        ret = -1;
> > +        goto the_end;
> > +    }
> > +    ret = qemu_save_device_state(mon, f);
> > +    qemu_fclose(f);
> > +    if (ret<  0) {
> > +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> > +        goto the_end;
> > +    }
> > +    ret = 0;
> > +
> > + the_end:
> > +    if (saved_vm_running)
> > +        vm_start();
> > +    return ret;
> > +}
> > +
> 
> Would it be useful/interesting to return a binary blob via QMP instead of 
> writing to a file?

Yes, it is potentially useful. I have just gone with the file interface
because it is easier to handle but I could change it or maybe have QMP
return the binary as an alternative option.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 2/6] Introduce "save_devices"
@ 2012-03-13 11:51       ` Stefano Stabellini
  0 siblings, 0 replies; 33+ messages in thread
From: Stefano Stabellini @ 2012-03-13 11:51 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: xen-devel, Stefano Stabellini, jan.kiszka, qemu-devel,
	Luiz Capitulino, avi

On Mon, 12 Mar 2012, Anthony Liguori wrote:
> On 02/28/2012 09:51 AM, Stefano Stabellini wrote:
> > - add an "is_ram" flag to SaveStateEntry;
> >
> > - add an "is_ram" parameter to register_savevm_live;
> >
> > - introduce a "save_devices" monitor command that can be used to save
> > the state of non-ram devices.
> >
> > Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> > ---
> >   block-migration.c |    2 +-
> >   hmp-commands.hx   |   14 ++++++++++
> >   qmp-commands.hx   |   17 ++++++++++++
> >   savevm.c          |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >   sysemu.h          |    1 +
> >   vl.c              |    2 +-
> >   vmstate.h         |    1 +
> >   7 files changed, 106 insertions(+), 3 deletions(-)
> >
> > diff --git a/block-migration.c b/block-migration.c
> > index 4467468..d283fd0 100644
> > --- a/block-migration.c
> > +++ b/block-migration.c
> > @@ -722,6 +722,6 @@ void blk_mig_init(void)
> >       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
> >       QSIMPLEQ_INIT(&block_mig_state.blk_list);
> >
> > -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> > +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
> >                            block_save_live, NULL, block_load,&block_mig_state);
> 
> Do you really want the block live migration to be part of Xen?
> 
> If not, then you can simplify by just making register_savevm_live always imply 
> !device and adjust register_savevm() accordingly.  Otherwise, the likelihood of 
> a casual observer knowing what '0, 1, 0' means is pretty bad...

That's a good point, I'll do that.


> >   }
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index 64b3656..873abc9 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. More info at
> >   ETEXI
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +STEXI
> > +@item save_devices @var{filename}
> > +@findex save_devices
> > +Save the state of non-ram devices.
> > +ETEXI
> > +
> > +    {
> >           .name       = "loadvm",
> >           .args_type  = "name:s",
> >           .params     = "tag|id",
> > diff --git a/qmp-commands.hx b/qmp-commands.hx
> > index 705f704..619d9de 100644
> > --- a/qmp-commands.hx
> > +++ b/qmp-commands.hx
> > @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest currently, it will
> >   EQMP
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .user_print = monitor_user_noop,	
> > +    .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +SQMP
> > +save_devices
> > +-------
> > +
> > +Save the state of non-ram devices.
> > +
> > +EQMP
> > +
> > +    {
> >           .name       = "migrate",
> >           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
> >           .params     = "[-d] [-b] [-i] uri",
> 
> 
> Should be QAPI commands and documented a great deal more (see other examples in 
> qapi-schema.json).  Please CC Luiz too when adding new QMP commands.

OK, I'll do.


> > diff --git a/savevm.c b/savevm.c
> > index 80be1ff..d0e62bb 100644
> > --- a/savevm.c
> > +++ b/savevm.c
> > @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
> >       void *opaque;
> >       CompatEntry *compat;
> >       int no_migrate;
> > +    int is_ram;
> >   } SaveStateEntry;
> >
> >
> > @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
> >                            const char *idstr,
> >                            int instance_id,
> >                            int version_id,
> > +                         int is_ram,
> >                            SaveSetParamsHandler *set_params,
> >                            SaveLiveStateHandler *save_live_state,
> >                            SaveStateHandler *save_state,
> > @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
> >       se->opaque = opaque;
> >       se->vmsd = NULL;
> >       se->no_migrate = 0;
> > +    se->is_ram = is_ram;
> >
> >       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
> >           char *id = dev->parent_bus->info->get_dev_path(dev);
> > @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
> >                       LoadStateHandler *load_state,
> >                       void *opaque)
> >   {
> > -    return register_savevm_live(dev, idstr, instance_id, version_id,
> > +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
> >                                   NULL, NULL, save_state, load_state, opaque);
> >   }
> >
> > @@ -1728,6 +1731,43 @@ out:
> >       return ret;
> >   }
> >
> > +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> > +{
> > +    SaveStateEntry *se;
> > +
> > +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> > +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> > +
> > +    cpu_synchronize_all_states();
> > +
> > +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> > +        int len;
> > +
> > +        if (se->is_ram)
> > +            continue;
> 
> Violating CODING_STYLE.

I'll fix that.


> > +        if (se->save_state == NULL&&  se->vmsd == NULL)
> > +            continue;
> > +
> > +        /* Section type */
> > +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> > +        qemu_put_be32(f, se->section_id);
> > +
> > +        /* 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);
> > +
> > +        vmstate_save(f, se);
> > +    }
> > +
> > +    qemu_put_byte(f, QEMU_VM_EOF);
> > +
> > +    return qemu_file_get_error(f);
> > +}
> 
> Please add something to docs/ documenting this format.

OK


> > +
> >   static SaveStateEntry *find_se(const char *idstr, int instance_id)
> >   {
> >       SaveStateEntry *se;
> > @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
> >           vm_start();
> >   }
> >
> > +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject **ret_data)
> > +{
> > +    int ret;
> > +    QEMUFile *f;
> > +    int saved_vm_running;
> > +    const char *filename = qdict_get_try_str(qdict, "filename");
> > +
> > +    saved_vm_running = runstate_is_running();
> > +    vm_stop(RUN_STATE_SAVE_VM);
> > +
> > +    f = qemu_fopen(filename, "wb");
> > +    if (!f) {
> > +        monitor_printf(mon, "Could not open VM state file\n");
> > +        ret = -1;
> > +        goto the_end;
> > +    }
> > +    ret = qemu_save_device_state(mon, f);
> > +    qemu_fclose(f);
> > +    if (ret<  0) {
> > +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> > +        goto the_end;
> > +    }
> > +    ret = 0;
> > +
> > + the_end:
> > +    if (saved_vm_running)
> > +        vm_start();
> > +    return ret;
> > +}
> > +
> 
> Would it be useful/interesting to return a binary blob via QMP instead of 
> writing to a file?

Yes, it is potentially useful. I have just gone with the file interface
because it is easier to handle but I could change it or maybe have QMP
return the binary as an alternative option.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
  2012-03-13 11:51       ` Stefano Stabellini
@ 2012-03-13 19:26         ` Luiz Capitulino
  -1 siblings, 0 replies; 33+ messages in thread
From: Luiz Capitulino @ 2012-03-13 19:26 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: jan.kiszka, xen-devel, qemu-devel, Anthony Liguori, avi

On Tue, 13 Mar 2012 11:51:56 +0000
Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:

> > Should be QAPI commands and documented a great deal more (see other examples in 
> > qapi-schema.json).  Please CC Luiz too when adding new QMP commands.
> 
> OK, I'll do.

I reviewed the RunState patch but missed that one... Btw Stefano, there's a
tutorial for new QMP commands: docs/writing-qmp-commands.txt.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH RESEND v5 2/6] Introduce "save_devices"
@ 2012-03-13 19:26         ` Luiz Capitulino
  0 siblings, 0 replies; 33+ messages in thread
From: Luiz Capitulino @ 2012-03-13 19:26 UTC (permalink / raw)
  To: Stefano Stabellini
  Cc: jan.kiszka, xen-devel, qemu-devel, Anthony Liguori, avi

On Tue, 13 Mar 2012 11:51:56 +0000
Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:

> > Should be QAPI commands and documented a great deal more (see other examples in 
> > qapi-schema.json).  Please CC Luiz too when adding new QMP commands.
> 
> OK, I'll do.

I reviewed the RunState patch but missed that one... Btw Stefano, there's a
tutorial for new QMP commands: docs/writing-qmp-commands.txt.

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2012-03-13 19:26 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-28 15:50 [Qemu-devel] [PATCH RESEND v5 0/6] save/restore on Xen Stefano Stabellini
2012-02-28 15:50 ` Stefano Stabellini
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 1/6] cirrus_vga: do not reset videoram Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini
2012-02-28 18:35   ` [Qemu-devel] " Anthony PERARD
2012-03-12 12:43   ` Avi Kivity
2012-03-12 12:43     ` Avi Kivity
2012-03-12 13:18     ` [Qemu-devel] " Stefano Stabellini
2012-03-12 13:18       ` Stefano Stabellini
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices" Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini
2012-02-28 18:58   ` [Qemu-devel] " Anthony PERARD
2012-02-28 18:58     ` Anthony PERARD
2012-03-12 18:33   ` [Qemu-devel] " Anthony Liguori
2012-03-12 18:33     ` Anthony Liguori
2012-03-13 11:51     ` [Qemu-devel] " Stefano Stabellini
2012-03-13 11:51       ` Stefano Stabellini
2012-03-13 19:26       ` [Qemu-devel] " Luiz Capitulino
2012-03-13 19:26         ` Luiz Capitulino
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 3/6] Set runstate to INMIGRATE earlier Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini
2012-02-28 19:34   ` [Qemu-devel] " Anthony PERARD
2012-02-28 19:34     ` Anthony PERARD
2012-03-07 17:41   ` [Qemu-devel] " Luiz Capitulino
2012-03-07 17:41     ` Luiz Capitulino
2012-03-12 12:17     ` [Qemu-devel] " Stefano Stabellini
2012-03-12 12:17       ` Stefano Stabellini
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 4/6] xen: record physmap changes to xenstore Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 5/6] xen mapcache: check if memory region has moved Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini
2012-02-28 15:51 ` [Qemu-devel] [PATCH RESEND v5 6/6] xen: do not allocate RAM during INMIGRATE runstate Stefano Stabellini
2012-02-28 15:51   ` Stefano Stabellini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.