From: Marc-André Lureau <marcandre.lur...@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> --- docs/specs/vhost-user.txt | 15 +++++++++++++++ hw/virtio/vhost-user.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt index 5e00bd3..854493e 100644 --- a/docs/specs/vhost-user.txt +++ b/docs/specs/vhost-user.txt @@ -331,6 +331,21 @@ Message types This message is only sent if VHOST_USER_PROTOCOL_F_SLAVE_REQ feature is available. +Slave message types +------------------- + + * VHOST_USER_SLAVE_SHUTDOWN: + Id: 1 + Master payload: N/A + Slave payload: u64 + + Request the master to shutdown the slave. A 0 reply is for + success, in which case the slave may close all connections + immediately and quit. A non-zero reply cancels the request. + + Before a reply comes, the master may make other requests in + order to flush or sync state. + Migration --------- diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 49f566c..949382c 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -55,6 +55,7 @@ typedef enum VhostUserRequest { typedef enum VhostUserSlaveRequest { VHOST_USER_SLAVE_NONE = 0, + VHOST_USER_SLAVE_SHUTDOWN = 1, VHOST_USER_SLAVE_MAX } VhostUserSlaveRequest; @@ -140,7 +141,7 @@ static VhostUserRequest vhost_user_request_translate(unsigned long int request) case VHOST_SET_VRING_ERR: return VHOST_USER_SET_VRING_ERR; default: - return VHOST_USER_MAX; + return request; } } @@ -375,6 +376,21 @@ static int slave_can_receive(void *opaque) return VHOST_USER_HDR_SIZE; } +static int vhost_user_slave_write(struct vhost_dev *dev, VhostUserMsg *msg, + int *fds, int fd_num) +{ + struct vhost_user *u = dev->opaque; + CharDriverState *chr = u->slave_chr; + int size = VHOST_USER_HDR_SIZE + msg->size; + + if (fd_num) { + qemu_chr_fe_set_msgfds(chr, fds, fd_num); + } + + return qemu_chr_fe_write_all(chr, (const uint8_t *) msg, size) == size ? + 0 : -1; +} + static void slave_receive(void *opaque, const uint8_t *buf, int size) { struct vhost_dev *dev = opaque; @@ -386,6 +402,18 @@ static void slave_receive(void *opaque, const uint8_t *buf, int size) } switch (msg->request) { + case VHOST_USER_SLAVE_SHUTDOWN: { + uint64_t success = 1; + + if (dev->stop) { + dev->stop(dev); + success = 0; + } + + msg->u64 = success; + vhost_user_slave_write(dev, msg, NULL, 0); + return; + } default: error_report("Received unexpected msg type."); } -- 2.4.3