During CPR migration, instead of reopening /dev/vhost-vsock device on each initialization, let's make sure the already open FD is preserved and properly reused on a subsequent initialization.
Signed-off-by: Andrey Drobyshev <[email protected]> --- hw/virtio/vhost-vsock-pci.c | 5 ----- hw/virtio/vhost-vsock.c | 27 ++++++++++++++++++++++----- include/hw/virtio/vhost-vsock.h | 6 ++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/hw/virtio/vhost-vsock-pci.c b/hw/virtio/vhost-vsock-pci.c index 3a94d06f8c0..ca86a361696 100644 --- a/hw/virtio/vhost-vsock-pci.c +++ b/hw/virtio/vhost-vsock-pci.c @@ -28,11 +28,6 @@ typedef struct VHostVSockPCI VHostVSockPCI; DECLARE_INSTANCE_CHECKER(VHostVSockPCI, VHOST_VSOCK_PCI, TYPE_VHOST_VSOCK_PCI) -struct VHostVSockPCI { - VirtIOPCIProxy parent_obj; - VHostVSock vdev; -}; - /* vhost-vsock-pci */ static const Property vhost_vsock_pci_properties[] = { diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index da244eb1657..90926f95fe1 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -20,6 +20,7 @@ #include "hw/core/qdev-properties.h" #include "hw/virtio/vhost-vsock.h" #include "monitor/monitor.h" +#include "migration/cpr.h" static void vhost_vsock_get_config(VirtIODevice *vdev, uint8_t *config) { @@ -126,6 +127,8 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostVSock *vsock = VHOST_VSOCK(dev); + DeviceState *vsock_pci = DEVICE(container_of(vsock, + struct VHostVSockPCI, vdev)); int vhostfd; int ret; @@ -141,7 +144,8 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) } if (vsock->conf.vhostfd) { - vhostfd = monitor_fd_param(monitor_cur(), vsock->conf.vhostfd, errp); + vhostfd = cpr_get_fd_param(vsock_pci->id, vsock->conf.vhostfd, 0, + errp); if (vhostfd == -1) { error_prepend(errp, "vhost-vsock: unable to parse vhostfd: "); return; @@ -151,10 +155,20 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp) return; } } else { - vhostfd = open("/dev/vhost-vsock", O_RDWR); - if (vhostfd < 0) { - error_setg_file_open(errp, errno, "/dev/vhost-vsock"); - return; + if (cpr_is_incoming()) { + vhostfd = cpr_find_fd(vsock_pci->id, 0); + if (vhostfd < 0) { + error_setg(errp, "vhost-vsock: could not restore vhost FD " + "for %s", vsock_pci->id); + return; + } + } else { + vhostfd = open("/dev/vhost-vsock", O_RDWR); + if (vhostfd < 0) { + error_setg_file_open(errp, errno, "/dev/vhost-vsock"); + return; + } + cpr_save_fd(vsock_pci->id, 0, vhostfd); } if (!qemu_set_blocking(vhostfd, false, errp)) { @@ -193,10 +207,13 @@ static void vhost_vsock_device_unrealize(DeviceState *dev) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); + DeviceState *vsock_pci = DEVICE(container_of(VHOST_VSOCK(dev), + struct VHostVSockPCI, vdev)); /* This will stop vhost backend if appropriate. */ vhost_vsock_set_status(vdev, 0); + cpr_delete_fd(vsock_pci->id, 0); vhost_dev_cleanup(&vvc->vhost_dev); vhost_vsock_common_unrealize(vdev); } diff --git a/include/hw/virtio/vhost-vsock.h b/include/hw/virtio/vhost-vsock.h index 84f4e727c70..ed91bb837fe 100644 --- a/include/hw/virtio/vhost-vsock.h +++ b/include/hw/virtio/vhost-vsock.h @@ -15,6 +15,7 @@ #define QEMU_VHOST_VSOCK_H #include "hw/virtio/vhost-vsock-common.h" +#include "hw/virtio/virtio-pci.h" #include "qom/object.h" #define TYPE_VHOST_VSOCK "vhost-vsock-device" @@ -33,4 +34,9 @@ struct VHostVSock { /*< public >*/ }; +struct VHostVSockPCI { + VirtIOPCIProxy parent_obj; + VHostVSock vdev; +}; + #endif /* QEMU_VHOST_VSOCK_H */ -- 2.47.1
