Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
---
 hw/virtio/vhost-user-fs.c |  68 +++++++++----------
 hw/virtio/virtio.c        | 133 +++++++++++++++++++-------------------
 2 files changed, 100 insertions(+), 101 deletions(-)

diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index 209993918a3..215aff77282 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -307,49 +307,50 @@ static struct vhost_dev *vuf_get_vhost(VirtIODevice *vdev)
 /**
  * Fetch the internal state from virtiofsd and save it to `f`.
  */
-static int vuf_save_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field, JSONWriter *vmdesc)
+static bool vuf_save_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, JSONWriter *vmdesc,
+                           Error **errp)
 {
+    ERRP_GUARD();
     VirtIODevice *vdev = pv;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-    Error *local_error = NULL;
     int ret;
 
-    ret = vhost_save_backend_state(&fs->vhost_dev, f, &local_error);
+    ret = vhost_save_backend_state(&fs->vhost_dev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error saving back-end state of %s device %s "
-                          "(tag: \"%s\"): ",
-                          vdev->name, vdev->parent_obj.canonical_path,
-                          fs->conf.tag ?: "<none>");
-        return ret;
+        error_prepend(errp,
+                      "Error saving back-end state of %s device %s "
+                      "(tag: \"%s\"): ",
+                      vdev->name, vdev->parent_obj.canonical_path,
+                      fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 /**
  * Load virtiofsd's internal state from `f` and send it over to virtiofsd.
  */
-static int vuf_load_state(QEMUFile *f, void *pv, size_t size,
-                          const VMStateField *field)
+static bool vuf_load_state(QEMUFile *f, void *pv, size_t size,
+                           const VMStateField *field, Error **errp)
 {
+    ERRP_GUARD();
     VirtIODevice *vdev = pv;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
-    Error *local_error = NULL;
     int ret;
 
-    ret = vhost_load_backend_state(&fs->vhost_dev, f, &local_error);
+    ret = vhost_load_backend_state(&fs->vhost_dev, f, errp);
     if (ret < 0) {
-        error_reportf_err(local_error,
-                          "Error loading back-end state of %s device %s "
-                          "(tag: \"%s\"): ",
-                          vdev->name, vdev->parent_obj.canonical_path,
-                          fs->conf.tag ?: "<none>");
-        return ret;
+        error_prepend(errp,
+                      "Error loading back-end state of %s device %s "
+                      "(tag: \"%s\"): ",
+                      vdev->name, vdev->parent_obj.canonical_path,
+                      fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static bool vuf_is_internal_migration(void *opaque)
@@ -358,20 +359,21 @@ static bool vuf_is_internal_migration(void *opaque)
     return true;
 }
 
-static int vuf_check_migration_support(void *opaque)
+static bool vuf_check_migration_support(void *opaque, Error **errp)
 {
     VirtIODevice *vdev = opaque;
     VHostUserFS *fs = VHOST_USER_FS(vdev);
 
     if (!vhost_supports_device_state(&fs->vhost_dev)) {
-        error_report("Back-end of %s device %s (tag: \"%s\") does not support "
-                     "migration through qemu",
-                     vdev->name, vdev->parent_obj.canonical_path,
-                     fs->conf.tag ?: "<none>");
-        return -ENOTSUP;
+        error_setg(errp,
+                   "Back-end of %s device %s (tag: \"%s\") does not support "
+                   "migration through qemu",
+                   vdev->name, vdev->parent_obj.canonical_path,
+                   fs->conf.tag ?: "<none>");
+        return false;
     }
 
-    return 0;
+    return true;
 }
 
 static const VMStateDescription vuf_backend_vmstate;
@@ -393,15 +395,15 @@ static const VMStateDescription vuf_backend_vmstate = {
     .name = "vhost-user-fs-backend",
     .version_id = 0,
     .needed = vuf_is_internal_migration,
-    .pre_load = vuf_check_migration_support,
-    .pre_save = vuf_check_migration_support,
+    .pre_load_errp = vuf_check_migration_support,
+    .pre_save_errp = vuf_check_migration_support,
     .fields = (const VMStateField[]) {
         {
             .name = "back-end",
             .info = &(const VMStateInfo) {
                 .name = "virtio-fs back-end state",
-                .get = vuf_load_state,
-                .put = vuf_save_state,
+                .load = vuf_load_state,
+                .save = vuf_save_state,
             },
         },
         VMSTATE_END_OF_LIST()
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index a9338af6d00..0b1ec41ac97 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -62,8 +62,8 @@
  */
 #define VIRTIO_PCI_VRING_ALIGN         4096
 
-static int coroutine_mixed_fn
-virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id);
+static bool coroutine_mixed_fn
+virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id, Error **errp);
 
 typedef struct VRingDesc
 {
@@ -3070,19 +3070,17 @@ static const VMStateDescription vmstate_virtio = {
     }
 };
 
-static int virtio_save(VirtIODevice *vdev, QEMUFile *f)
+static bool virtio_save(VirtIODevice *vdev, QEMUFile *f, Error **errp)
 {
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
     uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff);
-    int i, ret;
-    Error *local_err = NULL;
+    int i;
 
     if (k->save_config) {
-        if (!k->save_config(qbus->parent, f, &local_err)) {
-            error_report_err(local_err);
-            return -EINVAL;
+        if (!k->save_config(qbus->parent, f, errp)) {
+            return false;
         }
     }
 
@@ -3124,19 +3122,13 @@ static int virtio_save(VirtIODevice *vdev, QEMUFile *f)
     }
 
     if (vdc->vmsd) {
-        ret = vmstate_save_state(f, vdc->vmsd, vdev, NULL, &local_err);
-        if (ret) {
-            error_report_err(local_err);
-            return ret;
+        if (!vmstate_save_vmsd(f, vdc->vmsd, vdev, NULL, errp)) {
+            return false;
         }
     }
 
     /* Subsections */
-    ret = vmstate_save_state(f, &vmstate_virtio, vdev, NULL, &local_err);
-    if (ret < 0) {
-        error_report_err(local_err);
-    }
-    return ret;
+    return vmstate_save_vmsd(f, &vmstate_virtio, vdev, NULL, errp);
 }
 
 VirtioSharedMemory *virtio_new_shmem_region(VirtIODevice *vdev, uint8_t shmid, 
uint64_t size)
@@ -3307,27 +3299,28 @@ void virtio_del_shmem_map(VirtioSharedMemory *shmem, 
hwaddr offset,
 }
 
 /* A wrapper for use as a VMState .put function */
-static int virtio_device_put(QEMUFile *f, void *opaque, size_t size,
-                              const VMStateField *field, JSONWriter *vmdesc)
+static bool virtio_device_save(QEMUFile *f, void *opaque, size_t size,
+                               const VMStateField *field, JSONWriter *vmdesc,
+                               Error **errp)
 {
-    return virtio_save(VIRTIO_DEVICE(opaque), f);
+    return virtio_save(VIRTIO_DEVICE(opaque), f, errp);
 }
 
 /* A wrapper for use as a VMState .get function */
-static int coroutine_mixed_fn
-virtio_device_get(QEMUFile *f, void *opaque, size_t size,
-                  const VMStateField *field)
+static bool coroutine_mixed_fn
+virtio_device_load(QEMUFile *f, void *opaque, size_t size,
+                   const VMStateField *field, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
     DeviceClass *dc = DEVICE_CLASS(VIRTIO_DEVICE_GET_CLASS(vdev));
 
-    return virtio_load(vdev, f, dc->vmsd->version_id);
+    return virtio_load(vdev, f, dc->vmsd->version_id, errp);
 }
 
 const VMStateInfo  virtio_vmstate_info = {
     .name = "virtio",
-    .get = virtio_device_get,
-    .put = virtio_device_put,
+    .load = virtio_device_load,
+    .save = virtio_device_save,
 };
 
 static int virtio_set_features_nocheck(VirtIODevice *vdev, const uint64_t *val)
@@ -3513,8 +3506,8 @@ size_t virtio_get_config_size(const 
VirtIOConfigSizeParams *params,
     return config_size;
 }
 
-static int coroutine_mixed_fn
-virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
+static bool coroutine_mixed_fn
+virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id, Error **errp)
 {
     int i, ret;
     uint32_t config_len;
@@ -3523,7 +3516,6 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
     VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
     VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
-    Error *local_err = NULL;
 
     /*
      * We poison the endianness to ensure it does not get used before
@@ -3532,8 +3524,8 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     vdev->device_endian = VIRTIO_DEVICE_ENDIAN_UNKNOWN;
 
     if (k->load_config) {
-        if (!k->load_config(qbus->parent, f, &local_err)) {
-            return -EINVAL;
+        if (!k->load_config(qbus->parent, f, errp)) {
+            return false;
         }
     }
 
@@ -3541,7 +3533,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     qemu_get_8s(f, &vdev->isr);
     qemu_get_be16s(f, &vdev->queue_sel);
     if (vdev->queue_sel >= VIRTIO_QUEUE_MAX) {
-        return -1;
+        error_setg(errp, "virtio_load: queue_sel %u out of range",
+                   vdev->queue_sel);
+        return false;
     }
     qemu_get_be32s(f, &features);
 
@@ -3566,7 +3560,9 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
 
     while (config_len > vdev->config_len) {
         if (qemu_file_get_error(f)) {
-            return -1;
+            error_setg(errp, "virtio_load: stream error while skipping "
+                       "excess config");
+            return false;
         }
         qemu_get_byte(f);
         config_len--;
@@ -3575,24 +3571,25 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     num = qemu_get_be32(f);
 
     if (num > VIRTIO_QUEUE_MAX) {
-        error_report("Invalid number of virtqueues: 0x%x", num);
-        return -1;
+        error_setg(errp, "Invalid number of virtqueues: 0x%x", num);
+        return false;
     }
 
     if (vdc->pre_load_queues) {
         ret = vdc->pre_load_queues(vdev, num);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: pre_load_queues failed");
+            return false;
         }
     }
 
     for (i = 0; i < num; i++) {
         vdev->vq[i].vring.num = qemu_get_be32(f);
         if (vdev->vq[i].vring.num > vdev->vq[i].vring.num_default) {
-            error_report("VQ %d vring.num %u exceeds allocated max %u",
-                         i, vdev->vq[i].vring.num,
-                         vdev->vq[i].vring.num_default);
-            return -1;
+            error_setg(errp, "VQ %d vring.num %u exceeds allocated max %u",
+                       i, vdev->vq[i].vring.num,
+                       vdev->vq[i].vring.num_default);
+            return false;
         }
         if (k->has_variable_vring_alignment) {
             vdev->vq[i].vring.align = qemu_get_be32(f);
@@ -3603,15 +3600,17 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
         vdev->vq[i].notification = true;
 
         if (!vdev->vq[i].vring.desc && vdev->vq[i].last_avail_idx) {
-            error_report("VQ %d address 0x0 "
-                         "inconsistent with Host index 0x%x",
-                         i, vdev->vq[i].last_avail_idx);
-            return -1;
+            error_setg(errp, "VQ %d address 0x0 "
+                       "inconsistent with Host index 0x%x",
+                       i, vdev->vq[i].last_avail_idx);
+            return false;
         }
         if (k->load_queue) {
             ret = k->load_queue(qbus->parent, i, f);
-            if (ret)
-                return ret;
+            if (ret) {
+                error_setg(errp, "virtio_load: load_queue failed for vq %d", 
i);
+                return false;
+            }
         }
     }
 
@@ -3620,23 +3619,20 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     if (vdc->load != NULL) {
         ret = vdc->load(vdev, f, version_id);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: device load failed");
+            return false;
         }
     }
 
     if (vdc->vmsd) {
-        ret = vmstate_load_state(f, vdc->vmsd, vdev, version_id, &local_err);
-        if (ret) {
-            error_report_err(local_err);
-            return ret;
+        if (!vmstate_load_vmsd(f, vdc->vmsd, vdev, version_id, errp)) {
+            return false;
         }
     }
 
     /* Subsections */
-    ret = vmstate_load_state(f, &vmstate_virtio, vdev, 1, &local_err);
-    if (ret) {
-        error_report_err(local_err);
-        return ret;
+    if (!vmstate_load_vmsd(f, &vmstate_virtio, vdev, 1, errp)) {
+        return false;
     }
 
     if (vdev->device_endian == VIRTIO_DEVICE_ENDIAN_UNKNOWN) {
@@ -3649,11 +3645,11 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
      */
     if (virtio_set_features_nocheck_maybe_co(vdev,
                                              vdev->guest_features_ex) < 0) {
-        error_report("Features 0x" VIRTIO_FEATURES_FMT " unsupported. "
-                     "Allowed features: 0x" VIRTIO_FEATURES_FMT,
-                     VIRTIO_FEATURES_PR(vdev->guest_features_ex),
-                     VIRTIO_FEATURES_PR(vdev->host_features_ex));
-        return -1;
+        error_setg(errp, "Features 0x" VIRTIO_FEATURES_FMT " unsupported. "
+                   "Allowed features: 0x" VIRTIO_FEATURES_FMT,
+                   VIRTIO_FEATURES_PR(vdev->guest_features_ex),
+                   VIRTIO_FEATURES_PR(vdev->host_features_ex));
+        return false;
     }
 
     if (!virtio_device_started(vdev, vdev->status) &&
@@ -3710,12 +3706,12 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
             vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx -
                                 vdev->vq[i].used_idx);
             if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
-                error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
-                             "used_idx 0x%x",
-                             i, vdev->vq[i].vring.num,
-                             vdev->vq[i].last_avail_idx,
-                             vdev->vq[i].used_idx);
-                return -1;
+                error_setg(errp, "VQ %d size 0x%x < last_avail_idx 0x%x - "
+                           "used_idx 0x%x",
+                           i, vdev->vq[i].vring.num,
+                           vdev->vq[i].last_avail_idx,
+                           vdev->vq[i].used_idx);
+                return false;
             }
         }
     }
@@ -3723,11 +3719,12 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
version_id)
     if (vdc->post_load) {
         ret = vdc->post_load(vdev);
         if (ret) {
-            return ret;
+            error_setg(errp, "virtio_load: post_load failed");
+            return false;
         }
     }
 
-    return 0;
+    return true;
 }
 
 void virtio_cleanup(VirtIODevice *vdev)
-- 
2.43.0


Reply via email to