mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
virtio-net: vhost-user: Implement internal migration
Add support of VHOST_USER_PROTOCOL_F_DEVICE_STATE in virtio-net with vhost-user backend. Cc: Hanna Czenczek <hreitz@redhat.com> Signed-off-by: Laurent Vivier <lvivier@redhat.com> Message-Id: <20250115135044.799698-3-lvivier@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
3f65357313
commit
60f543ad91
1 changed files with 112 additions and 23 deletions
|
@ -3337,6 +3337,117 @@ static const VMStateDescription vmstate_virtio_net_rss = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
|
||||
{
|
||||
VirtIONet *n = VIRTIO_NET(vdev);
|
||||
NetClientState *nc;
|
||||
struct vhost_net *net;
|
||||
|
||||
if (!n->nic) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nc = qemu_get_queue(n->nic);
|
||||
if (!nc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
net = get_vhost_net(nc->peer);
|
||||
if (!net) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &net->dev;
|
||||
}
|
||||
|
||||
static int vhost_user_net_save_state(QEMUFile *f, void *pv, size_t size,
|
||||
const VMStateField *field,
|
||||
JSONWriter *vmdesc)
|
||||
{
|
||||
VirtIONet *n = pv;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
struct vhost_dev *vhdev;
|
||||
Error *local_error = NULL;
|
||||
int ret;
|
||||
|
||||
vhdev = virtio_net_get_vhost(vdev);
|
||||
if (vhdev == NULL) {
|
||||
error_reportf_err(local_error,
|
||||
"Error getting vhost back-end of %s device %s: ",
|
||||
vdev->name, vdev->parent_obj.canonical_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vhost_save_backend_state(vhdev, f, &local_error);
|
||||
if (ret < 0) {
|
||||
error_reportf_err(local_error,
|
||||
"Error saving back-end state of %s device %s: ",
|
||||
vdev->name, vdev->parent_obj.canonical_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vhost_user_net_load_state(QEMUFile *f, void *pv, size_t size,
|
||||
const VMStateField *field)
|
||||
{
|
||||
VirtIONet *n = pv;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
struct vhost_dev *vhdev;
|
||||
Error *local_error = NULL;
|
||||
int ret;
|
||||
|
||||
vhdev = virtio_net_get_vhost(vdev);
|
||||
if (vhdev == NULL) {
|
||||
error_reportf_err(local_error,
|
||||
"Error getting vhost back-end of %s device %s: ",
|
||||
vdev->name, vdev->parent_obj.canonical_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = vhost_load_backend_state(vhdev, f, &local_error);
|
||||
if (ret < 0) {
|
||||
error_reportf_err(local_error,
|
||||
"Error loading back-end state of %s device %s: ",
|
||||
vdev->name, vdev->parent_obj.canonical_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool vhost_user_net_is_internal_migration(void *opaque)
|
||||
{
|
||||
VirtIONet *n = opaque;
|
||||
VirtIODevice *vdev = VIRTIO_DEVICE(n);
|
||||
struct vhost_dev *vhdev;
|
||||
|
||||
vhdev = virtio_net_get_vhost(vdev);
|
||||
if (vhdev == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return vhost_supports_device_state(vhdev);
|
||||
}
|
||||
|
||||
static const VMStateDescription vhost_user_net_backend_state = {
|
||||
.name = "virtio-net-device/backend",
|
||||
.version_id = 0,
|
||||
.needed = vhost_user_net_is_internal_migration,
|
||||
.fields = (const VMStateField[]) {
|
||||
{
|
||||
.name = "backend",
|
||||
.info = &(const VMStateInfo) {
|
||||
.name = "virtio-net vhost-user backend state",
|
||||
.get = vhost_user_net_load_state,
|
||||
.put = vhost_user_net_save_state,
|
||||
},
|
||||
},
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_virtio_net_device = {
|
||||
.name = "virtio-net-device",
|
||||
.version_id = VIRTIO_NET_VM_VERSION,
|
||||
|
@ -3389,6 +3500,7 @@ static const VMStateDescription vmstate_virtio_net_device = {
|
|||
},
|
||||
.subsections = (const VMStateDescription * const []) {
|
||||
&vmstate_virtio_net_rss,
|
||||
&vhost_user_net_backend_state,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
@ -3950,29 +4062,6 @@ static bool dev_unplug_pending(void *opaque)
|
|||
return vdc->primary_unplug_pending(dev);
|
||||
}
|
||||
|
||||
static struct vhost_dev *virtio_net_get_vhost(VirtIODevice *vdev)
|
||||
{
|
||||
VirtIONet *n = VIRTIO_NET(vdev);
|
||||
NetClientState *nc;
|
||||
struct vhost_net *net;
|
||||
|
||||
if (!n->nic) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nc = qemu_get_queue(n->nic);
|
||||
if (!nc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
net = get_vhost_net(nc->peer);
|
||||
if (!net) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &net->dev;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_virtio_net = {
|
||||
.name = "virtio-net",
|
||||
.minimum_version_id = VIRTIO_NET_VM_VERSION,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue