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