Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
hw/virtio/vhost-user-fs.c | 65 ++++++++++++++--------------
hw/virtio/virtio-mmio.c | 10 +++--
hw/virtio/virtio-pci.c | 10 +++--
hw/virtio/virtio.c | 78 ++++++++++++++++++++--------------
include/hw/virtio/virtio-bus.h | 4 +-
include/hw/virtio/virtio.h | 2 -
6 files changed, 94 insertions(+), 75 deletions(-)
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index e77c69eb12..84a7663ea8 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -306,9 +306,11 @@ 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;
@@ -316,39 +318,39 @@ static int vuf_save_state(QEMUFile *f, void *pv, size_t size,
ret = vhost_save_backend_state(&fs->vhost_dev, f, &local_error);
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)
@@ -357,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;
@@ -392,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-mmio.c b/hw/virtio/virtio-mmio.c
index fb58c36452..9d37ee029b 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -609,18 +609,20 @@ static const VMStateDescription vmstate_virtio_mmio = {
}
};
-static void virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_save_extra_state(DeviceState *opaque, QEMUFile *f,
+ Error **errp)
{
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
- vmstate_save_state(f, &vmstate_virtio_mmio, proxy, NULL, &error_fatal);
+ return vmstate_save_vmsd(f, &vmstate_virtio_mmio, proxy, NULL, errp);
}
-static int virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f)
+static bool virtio_mmio_load_extra_state(DeviceState *opaque, QEMUFile *f,
+ Error **errp)
{
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
- return vmstate_load_state(f, &vmstate_virtio_mmio, proxy, 1, &error_fatal);
+ return vmstate_load_vmsd(f, &vmstate_virtio_mmio, proxy, 1, errp);
}
static bool virtio_mmio_has_extra_state(DeviceState *opaque)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 937e22f08a..95faa84a58 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -184,18 +184,20 @@ static bool virtio_pci_has_extra_state(DeviceState *d)
return true;
}
-static void virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f,
+ Error **errp)
{
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
- vmstate_save_state(f, &vmstate_virtio_pci, proxy, NULL, &error_fatal);
+ return vmstate_save_vmsd(f, &vmstate_virtio_pci, proxy, NULL, errp);
}
-static int virtio_pci_load_extra_state(DeviceState *d, QEMUFile *f)
+static bool virtio_pci_load_extra_state(DeviceState *d, QEMUFile *f,
+ Error **errp)
{
VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
- return vmstate_load_state(f, &vmstate_virtio_pci, proxy, 1, &error_fatal);
+ return vmstate_load_vmsd(f, &vmstate_virtio_pci, proxy, 1, errp);
}
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 153ee0a0cf..36e0493344 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2873,35 +2873,37 @@ static const VMStateDescription vmstate_virtio_ringsize = {
}
};
-static int get_extra_state(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field)
+static bool load_extra_state(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field,
+ Error **errp)
{
VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
if (!k->load_extra_state) {
- return -1;
+ error_setg(errp, "extra state is unsupported");
+ return false;
} else {
- return k->load_extra_state(qbus->parent, f);
+ return k->load_extra_state(qbus->parent, f, errp);
}
}
-static int put_extra_state(QEMUFile *f, void *pv, size_t size,
- const VMStateField *field, JSONWriter *vmdesc)
+static bool save_extra_state(QEMUFile *f, void *pv, size_t size,
+ const VMStateField *field, JSONWriter *vmdesc,
+ Error **errp)
{
VirtIODevice *vdev = pv;
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
- k->save_extra_state(qbus->parent, f);
- return 0;
+ return k->save_extra_state(qbus->parent, f, errp);
}
static const VMStateInfo vmstate_info_extra_state = {
.name = "virtqueue_extra_state",
- .get = get_extra_state,
- .put = put_extra_state,
+ .load = load_extra_state,
+ .save = save_extra_state,
};
static const VMStateDescription vmstate_virtio_extra_state = {
@@ -3024,14 +3026,13 @@ static const VMStateDescription vmstate_virtio = {
}
};
-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;
- Error *local_err = NULL;
if (k->save_config) {
k->save_config(qbus->parent, f);
@@ -3075,39 +3076,54 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f)
}
if (vdc->vmsd) {
- int 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 */
- return vmstate_save_state(f, &vmstate_virtio, vdev, NULL, &error_fatal);
+ return vmstate_save_vmsd(f, &vmstate_virtio, vdev, NULL, &error_fatal);
}
/* 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);
+ /* TODO: update virtio_load() to set errp and return bool */
+ int ret = virtio_load(vdev, f, dc->vmsd->version_id);
+
+ if (ret < 0) {
+ /*
+ * Using error_setg_errn or strerror would be incorrect,
+ * because virtio_load may mix simple -1 with -errno
+ * values on different paths.
+ *
+ * TODO: update virtio_load and all related callbacks
+ * to "errp + boolean return value" API.
+ */
+ error_setg(errp, "virtio_load failed: %d", ret);
+ return false;
+ }
+
+ return true;
}
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)
@@ -3387,18 +3403,16 @@ virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
}
if (vdc->vmsd) {
- ret = vmstate_load_state(f, vdc->vmsd, vdev, version_id, &local_err);
- if (ret) {
+ if (!vmstate_load_vmsd(f, vdc->vmsd, vdev, version_id, &local_err)) {
error_report_err(local_err);
- return ret;
+ return -EINVAL;
}
}
/* Subsections */
- ret = vmstate_load_state(f, &vmstate_virtio, vdev, 1, &local_err);
- if (ret) {
+ if (!vmstate_load_vmsd(f, &vmstate_virtio, vdev, 1, &local_err)) {
error_report_err(local_err);
- return ret;
+ return -EINVAL;
}
if (vdev->device_endian == VIRTIO_DEVICE_ENDIAN_UNKNOWN) {
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index 7ab8c9dab0..31bf2cd607 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -42,11 +42,11 @@ struct VirtioBusClass {
void (*notify)(DeviceState *d, uint16_t vector);
void (*save_config)(DeviceState *d, QEMUFile *f);
void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
- void (*save_extra_state)(DeviceState *d, QEMUFile *f);
+ bool (*save_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
int (*load_config)(DeviceState *d, QEMUFile *f);
int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
int (*load_done)(DeviceState *d, QEMUFile *f);
- int (*load_extra_state)(DeviceState *d, QEMUFile *f);
+ bool (*load_extra_state)(DeviceState *d, QEMUFile *f, Error **errp);
bool (*has_extra_state)(DeviceState *d);
bool (*query_guest_notifiers)(DeviceState *d);
int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d97529c3f1..d729502eca 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -296,8 +296,6 @@ int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
-int virtio_save(VirtIODevice *vdev, QEMUFile *f);
-
extern const VMStateInfo virtio_vmstate_info;
#define VMSTATE_VIRTIO_DEVICE \
--
2.48.1
© 2016 - 2025 Red Hat, Inc.