Patchwork [RESEND,2/6] savevm: Allow vmsd->pre_save to return error

login
register
mail settings
Submitter Alex Williamson
Date Nov. 5, 2010, 9:16 p.m.
Message ID <20101105211620.19958.2661.stgit@s20.home>
Download mbox | patch
Permalink /patch/70298/
State New
Headers show

Comments

Alex Williamson - Nov. 5, 2010, 9:16 p.m.
This allows vmsd based saves to also have a way to signal that
they can't be saved or migrated.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

 hw/fdc.c              |    3 ++-
 hw/hpet.c             |    3 ++-
 hw/hw.h               |    6 +++---
 hw/i2c.c              |    3 ++-
 hw/ide/core.c         |    4 +++-
 hw/lsi53c895a.c       |    4 +++-
 hw/rtl8139.c          |    4 +++-
 hw/serial.c           |    3 ++-
 hw/twl92230.c         |    3 ++-
 hw/usb-uhci.c         |    3 ++-
 hw/wm8750.c           |    3 ++-
 savevm.c              |   36 +++++++++++++++++++++++-------------
 target-i386/machine.c |    6 +++---
 13 files changed, 52 insertions(+), 29 deletions(-)

Patch

diff --git a/hw/fdc.c b/hw/fdc.c
index c159dcb..ff48c70 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -643,11 +643,12 @@  static const VMStateDescription vmstate_fdrive = {
     }
 };
 
-static void fdc_pre_save(void *opaque)
+static int fdc_pre_save(void *opaque)
 {
     FDCtrl *s = opaque;
 
     s->dor_vmstate = s->dor | GET_CUR_DRV(s);
+    return 0;
 }
 
 static int fdc_post_load(void *opaque, int version_id)
diff --git a/hw/hpet.c b/hw/hpet.c
index d5c406c..e586e68 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -204,12 +204,13 @@  static void update_irq(struct HPETTimer *timer, int set)
     }
 }
 
-static void hpet_pre_save(void *opaque)
+static int hpet_pre_save(void *opaque)
 {
     HPETState *s = opaque;
 
     /* save current counter value */
     s->hpet_counter = hpet_get_ticks(s);
+    return 0;
 }
 
 static int hpet_pre_load(void *opaque)
diff --git a/hw/hw.h b/hw/hw.h
index c20bb2d..3ef67c8 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -328,7 +328,7 @@  struct VMStateDescription {
     LoadStateHandler *load_state_old;
     int (*pre_load)(void *opaque);
     int (*post_load)(void *opaque, int version_id);
-    void (*pre_save)(void *opaque);
+    int (*pre_save)(void *opaque);
     VMStateField *fields;
     const VMStateSubsection *subsections;
 };
@@ -787,8 +787,8 @@  extern const VMStateDescription vmstate_i2c_slave;
 
 extern int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                               void *opaque, int version_id);
-extern void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                               void *opaque);
+extern int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
+                              void *opaque);
 extern int vmstate_register(DeviceState *dev, int instance_id,
                             const VMStateDescription *vmsd, void *base);
 extern int vmstate_register_with_alias_id(DeviceState *dev,
diff --git a/hw/i2c.c b/hw/i2c.c
index f80d12d..f05c2ef 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -26,11 +26,12 @@  static struct BusInfo i2c_bus_info = {
     }
 };
 
-static void i2c_bus_pre_save(void *opaque)
+static int i2c_bus_pre_save(void *opaque)
 {
     i2c_bus *bus = opaque;
 
     bus->saved_address = bus->current_dev ? bus->current_dev->address : -1;
+    return 0;
 }
 
 static int i2c_bus_post_load(void *opaque, int version_id)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 484e0ca..7b1be41 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2812,7 +2812,7 @@  static int ide_drive_pio_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static void ide_drive_pio_pre_save(void *opaque)
+static int ide_drive_pio_pre_save(void *opaque)
 {
     IDEState *s = opaque;
     int idx;
@@ -2828,6 +2828,8 @@  static void ide_drive_pio_pre_save(void *opaque)
     } else {
         s->end_transfer_fn_idx = idx;
     }
+
+    return 0;
 }
 
 static bool ide_drive_pio_state_needed(void *opaque)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index f97335e..84dda7e 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2046,7 +2046,7 @@  static void lsi_scsi_reset(DeviceState *dev)
     lsi_soft_reset(s);
 }
 
-static void lsi_pre_save(void *opaque)
+static int lsi_pre_save(void *opaque)
 {
     LSIState *s = opaque;
 
@@ -2055,6 +2055,8 @@  static void lsi_pre_save(void *opaque)
         assert(s->current->dma_len == 0);
     }
     assert(QTAILQ_EMPTY(&s->queue));
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_lsi_scsi = {
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index d92981d..56271fb 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3173,7 +3173,7 @@  static int rtl8139_post_load(void *opaque, int version_id)
     return 0;
 }
 
-static void rtl8139_pre_save(void *opaque)
+static int rtl8139_pre_save(void *opaque)
 {
     RTL8139State* s = opaque;
     int64_t current_time = qemu_get_clock(vm_clock);
@@ -3182,6 +3182,8 @@  static void rtl8139_pre_save(void *opaque)
     rtl8139_set_next_tctr_time(s, current_time);
     s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
                        get_ticks_per_sec());
+
+    return 0;
 }
 
 static const VMStateDescription vmstate_rtl8139 = {
diff --git a/hw/serial.c b/hw/serial.c
index 9ebc452..edfdd4d 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -659,10 +659,11 @@  static void serial_event(void *opaque, int event)
         serial_receive_break(s);
 }
 
-static void serial_pre_save(void *opaque)
+static int serial_pre_save(void *opaque)
 {
     SerialState *s = opaque;
     s->fcr_vmstate = s->fcr;
+    return 0;
 }
 
 static int serial_post_load(void *opaque, int version_id)
diff --git a/hw/twl92230.c b/hw/twl92230.c
index e61f17f..0d6f3b6 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -782,11 +782,12 @@  static const VMStateDescription vmstate_menelaus_tm = {
     }
 };
 
-static void menelaus_pre_save(void *opaque)
+static int menelaus_pre_save(void *opaque)
 {
     MenelausState *s = opaque;
     /* Should be <= 1000 */
     s->rtc_next_vmstate =  s->rtc.next - qemu_get_clock(rt_clock);
+    return 0;
 }
 
 static int menelaus_post_load(void *opaque, int version_id)
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 1d83400..ea00386 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -355,11 +355,12 @@  static void uhci_reset(void *opaque)
     uhci_async_cancel_all(s);
 }
 
-static void uhci_pre_save(void *opaque)
+static int uhci_pre_save(void *opaque)
 {
     UHCIState *s = opaque;
 
     uhci_async_cancel_all(s);
+    return 0;
 }
 
 static const VMStateDescription vmstate_uhci_port = {
diff --git a/hw/wm8750.c b/hw/wm8750.c
index c9c6744..600a70d 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -559,11 +559,12 @@  static int wm8750_rx(i2c_slave *i2c)
     return 0x00;
 }
 
-static void wm8750_pre_save(void *opaque)
+static int wm8750_pre_save(void *opaque)
 {
     WM8750State *s = opaque;
 
     s->rate_vmstate = (s->rate - wm_rate_table) / sizeof(*s->rate);
+    return 0;
 }
 
 static int wm8750_post_load(void *opaque, int version_id)
diff --git a/savevm.c b/savevm.c
index 965f24e..ade7eb5 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1265,8 +1265,8 @@  void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
     }
 }
 
-static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
-                                    void *opaque);
+static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
+                                   void *opaque);
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque);
 
@@ -1344,13 +1344,17 @@  int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
     return 0;
 }
 
-void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                        void *opaque)
+int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
+                       void *opaque)
 {
     VMStateField *field = vmsd->fields;
+    int ret;
 
     if (vmsd->pre_save) {
-        vmsd->pre_save(opaque);
+        ret = vmsd->pre_save(opaque);
+        if (ret < 0) {
+            return ret;
+        }
     }
     while(field->name) {
         if (!field->field_exists ||
@@ -1382,7 +1386,10 @@  void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
                     addr = *(void **)addr;
                 }
                 if (field->flags & VMS_STRUCT) {
-                    vmstate_save_state(f, field->vmsd, addr);
+                    ret = vmstate_save_state(f, field->vmsd, addr);
+                    if (ret < 0) {
+                        return ret;
+                    }
                 } else {
                     field->info->put(f, addr, size);
                 }
@@ -1390,7 +1397,7 @@  void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
         }
         field++;
     }
-    vmstate_subsection_save(f, vmsd, opaque);
+    return vmstate_subsection_save(f, vmsd, opaque);
 }
 
 static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
@@ -1410,9 +1417,7 @@  static int vmstate_save(QEMUFile *f, SaveStateEntry *se)
     if (!se->vmsd) {         /* Old style */
         return se->save_state(f, se->opaque);
     }
-    vmstate_save_state(f,se->vmsd, se->opaque);
-
-    return 0;
+    return vmstate_save_state(f, se->vmsd, se->opaque);
 }
 
 #define QEMU_VM_FILE_MAGIC           0x5145564d
@@ -1656,8 +1661,8 @@  static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
     return 0;
 }
 
-static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
-                                    void *opaque)
+static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
+                                   void *opaque)
 {
     const VMStateSubsection *sub = vmsd->subsections;
 
@@ -1665,16 +1670,21 @@  static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
         if (sub->needed(opaque)) {
             const VMStateDescription *vmsd = sub->vmsd;
             uint8_t len;
+            int ret;
 
             qemu_put_byte(f, QEMU_VM_SUBSECTION);
             len = strlen(vmsd->name);
             qemu_put_byte(f, len);
             qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
             qemu_put_be32(f, vmsd->version_id);
-            vmstate_save_state(f, vmsd, opaque);
+            ret = vmstate_save_state(f, vmsd, opaque);
+            if (ret < 0) {
+                return ret;
+            }
         }
         sub++;
     }
+    return 0;
 }
 
 typedef struct LoadStateEntry {
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 540292f..e47206c 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -332,7 +332,7 @@  static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
     VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t)
 #endif
 
-static void cpu_pre_save(void *opaque)
+static int cpu_pre_save(void *opaque)
 {
     CPUState *env = opaque;
     int i;
@@ -349,6 +349,7 @@  static void cpu_pre_save(void *opaque)
 #else
     env->fpregs_format_vmstate = 1;
 #endif
+    return 0;
 }
 
 static int cpu_post_load(void *opaque, int version_id)
@@ -480,8 +481,7 @@  static const VMStateDescription vmstate_cpu = {
 
 int cpu_save(QEMUFile *f, void *opaque)
 {
-    vmstate_save_state(f, &vmstate_cpu, opaque);
-    return 0;
+    return vmstate_save_state(f, &vmstate_cpu, opaque);
 }
 
 int cpu_load(QEMUFile *f, void *opaque, int version_id)