From: "Michael S. Tsirkin" <mst@redhat.com>
To: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Cc: Stefano Garzarella <sgarzare@redhat.com>,
qemu-devel@nongnu.org, farosas@suse.de, peterx@redhat.com,
dongli.zhang@oracle.com, maciej.szmigiero@oracle.com,
bchaney@akamai.com, mark.kanda@oracle.com, den@openvz.org
Subject: Re: [PATCH v3 4/7] vhost-vsock: preserve vhost FD during CPR
Date: Wed, 19 Aug 2026 11:11:34 -0400 [thread overview]
Message-ID: <20260819111110-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <bc812e7c-a30b-43f4-9803-26259bb3a65b@virtuozzo.com>
On Wed, Aug 19, 2026 at 05:38:46PM +0300, Andrey Drobyshev wrote:
> On 8/18/26 6:29 PM, Stefano Garzarella wrote:
> > On Fri, Jun 26, 2026 at 07:46:40PM +0300, Andrey Drobyshev wrote:
> >> During CPR (checkpoint-restore) migration the guest keeps running on the
> >> same host, so instead of reopening /dev/vhost-vsock on the destination,
> >> we should reuse the FD from the source. The FD is saved in the CPR
> >> namespace (hash table) with cpr_save_fd() and then reclaimed on the
> >> target via cpr_find_fd().
> >>
> >> Since the key in CPR hash table is device ID, CPR needs a unique ID.
> >> Rather than make it mandatory for every vhost-vsock device, we add CPR
> >> migration blocker which only fires once we attempt CPR with ID-less
> >> vhost-vsock.
> >>
> >> vhost_dev_init() (and thus VHOST_SET_OWNER) still runs in realize() here.
> >> Deferring the ownership handoff to pre_save/post_load is done in a
> >> following patch.
> >
> > So will this patch be bisectabale?
> >
> > Thanks,
> > Stefano
> >
>
> The issue is that cpr-exec already is broken on the current master
> branch (i.e. before the series is applied). The only difference is
> which exact error we fail with: -EBUSY or -EADDRINUSE.
>
> In this case I don't think it's feasible to make each and every commit
> bisectable - it only becomes fully working after the last one applied.
Surely just bypassing cpr things until the last commit
is feasible?
> If you want, I can prepend the series with a migration blocker which
> would fail early and gracefully instead of crashing, and lift it after
> it's working.
>
> Andrey
>
> >>
> >> Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
> >> ---
> >> hw/virtio/vhost-vsock.c | 50 ++++++++++++++++++++++++++++++---
> >> include/hw/virtio/vhost-vsock.h | 1 +
> >> 2 files changed, 47 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c
> >> index fd7ffa88990..7eacb608d07 100644
> >> --- a/hw/virtio/vhost-vsock.c
> >> +++ b/hw/virtio/vhost-vsock.c
> >> @@ -21,6 +21,8 @@
> >> #include "hw/virtio/vhost-vsock.h"
> >> #include "monitor/monitor.h"
> >> #include "migration/cpr.h"
> >> +#include "migration/blocker.h"
> >> +#include "migration/misc.h"
> >>
> >> static void vhost_vsock_get_config(VirtIODevice *vdev, uint8_t *config)
> >> {
> >> @@ -141,6 +143,7 @@ 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 *proxy = qdev_get_parent_bus(DEVICE(vsock))->parent;
> >> int vhostfd;
> >> int ret;
> >>
> >> @@ -155,23 +158,49 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
> >> return;
> >> }
> >>
> >> - if (vsock->conf.vhostfd) {
> >> + /*
> >> + * Having a unique ID is mandatory for FD preservation during CPR
> >> + * migration, thus we add migration blockers for CPR modes.
> >> + */
> >> + if (!proxy->id) {
> >> + error_setg(&vsock->migration_blocker,
> >> + "vhost-vsock: device ID is required for CPR migration");
> >> + if (migrate_add_blocker_modes(&vsock->migration_blocker,
> >> + BIT(MIG_MODE_CPR_TRANSFER) |
> >> + BIT(MIG_MODE_CPR_EXEC), errp) < 0) {
> >> + return;
> >> + }
> >> + }
> >> +
> >> + if (cpr_is_incoming()) {
> >> + /* Reuse the fd handed over from the source QEMU. */
> >> + if (!proxy->id) {
> >> + error_setg(errp, "vhost-vsock: device ID is required for "
> >> + "CPR migration");
> >> + goto err_blocker;
> >> + }
> >> + vhostfd = cpr_find_fd(proxy->id, 0);
> >> + if (vhostfd < 0) {
> >> + error_setg(errp, "vhost-vsock: could not find restored vhost FD");
> >> + goto err_blocker;
> >> + }
> >> + } else if (vsock->conf.vhostfd) {
> >> vhostfd = monitor_fd_param(monitor_cur(), vsock->conf.vhostfd, errp);
> >> if (vhostfd == -1) {
> >> error_prepend(errp, "vhost-vsock: unable to parse vhostfd: ");
> >> - return;
> >> + goto err_blocker;
> >> }
> >> } else {
> >> vhostfd = open("/dev/vhost-vsock", O_RDWR);
> >> if (vhostfd < 0) {
> >> error_setg_file_open(errp, errno, "/dev/vhost-vsock");
> >> - return;
> >> + goto err_blocker;
> >> }
> >> }
> >>
> >> if (!qemu_set_blocking(vhostfd, false, errp)) {
> >> close(vhostfd);
> >> - return;
> >> + goto err_blocker;
> >> }
> >>
> >> vhost_vsock_common_realize(vdev);
> >> @@ -192,6 +221,11 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
> >> goto err_vhost_dev;
> >> }
> >>
> >> + /* Register the fd for a future CPR after a fully successful realize */
> >> + if (proxy->id) {
> >> + cpr_save_fd(proxy->id, 0, vhostfd);
> >> + }
> >> +
> >> return;
> >>
> >> err_vhost_dev:
> >> @@ -199,16 +233,24 @@ err_vhost_dev:
> >> vhost_dev_cleanup(&vvc->vhost_dev);
> >> err_virtio:
> >> vhost_vsock_common_unrealize(vdev);
> >> +err_blocker:
> >> + migrate_del_blocker(&vsock->migration_blocker);
> >> }
> >>
> >> static void vhost_vsock_device_unrealize(DeviceState *dev)
> >> {
> >> VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(dev);
> >> VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> >> + VHostVSock *vsock = VHOST_VSOCK(dev);
> >> + DeviceState *proxy = qdev_get_parent_bus(dev)->parent;
> >>
> >> /* This will stop vhost backend if appropriate. */
> >> vhost_vsock_set_status(vdev, 0);
> >>
> >> + if (proxy->id) {
> >> + cpr_delete_fd(proxy->id, 0);
> >> + }
> >> + migrate_del_blocker(&vsock->migration_blocker);
> >> 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..5ebc63afc5a 100644
> >> --- a/include/hw/virtio/vhost-vsock.h
> >> +++ b/include/hw/virtio/vhost-vsock.h
> >> @@ -29,6 +29,7 @@ struct VHostVSock {
> >> /*< private >*/
> >> VHostVSockCommon parent;
> >> VHostVSockConf conf;
> >> + Error *migration_blocker; /* set when the device has no ID */
> >>
> >> /*< public >*/
> >> };
> >> --
> >> 2.47.1
> >>
> >
next prev parent reply other threads:[~2026-08-19 15:12 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 16:46 [PATCH v3 0/7] migration/cpr: support vhost-vsock devices Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 1/7] vhost: add vhost_reset_owner op Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 2/7] vhost-vsock: don't reset connections during CPR Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 3/7] vhost-vsock: fix FD leak in realize() Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 4/7] vhost-vsock: preserve vhost FD during CPR Andrey Drobyshev
2026-08-18 15:29 ` Stefano Garzarella
2026-08-19 14:38 ` Andrey Drobyshev
2026-08-19 15:11 ` Michael S. Tsirkin [this message]
2026-08-19 15:22 ` Andrey Drobyshev
2026-08-19 18:53 ` Michael S. Tsirkin
2026-06-26 16:46 ` [PATCH v3 5/7] vhost: factor out vhost_dev_init_backend() Andrey Drobyshev
2026-08-18 15:29 ` Stefano Garzarella
2026-08-19 14:38 ` Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 6/7] vhost: add vhost_dev_set_owner() / vhost_dev_reset_owner() helpers Andrey Drobyshev
2026-06-26 16:46 ` [PATCH v3 7/7] vhost-vsock: hand off device ownership across CPR Andrey Drobyshev
2026-08-18 15:30 ` Stefano Garzarella
2026-08-19 14:38 ` Andrey Drobyshev
2026-06-30 18:35 ` [PATCH v3 0/7] migration/cpr: support vhost-vsock devices Maciej S. Szmigiero
2026-08-11 14:12 ` Andrey Drobyshev
2026-08-18 11:02 ` Andrey Drobyshev
2026-08-18 15:33 ` Stefano Garzarella
2026-08-19 14:39 ` Andrey Drobyshev
2026-07-14 16:03 ` Vladimir Sementsov-Ogievskiy
2026-07-15 10:25 ` Andrey Drobyshev
2026-07-15 10:48 ` Vladimir Sementsov-Ogievskiy
2026-07-15 12:11 ` Andrey Drobyshev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260819111110-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=bchaney@akamai.com \
--cc=den@openvz.org \
--cc=dongli.zhang@oracle.com \
--cc=farosas@suse.de \
--cc=maciej.szmigiero@oracle.com \
--cc=mark.kanda@oracle.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=sgarzare@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.