vhost: add user callbacks for socket open/close

Added new callbacks to notify about socket connection status.
As destroy_device is used for virtqueue processing *pause* as well as
connection close, the user has no distinction between those.

Consider the following scenario:
rte_vhost: received SET_VRING_BASE message,
           calling destroy_device() as usual

user:  end-user asks to remove the device (together with socket file),
       OK, device is not *in use* - that's NOT the behavior we want
       calling rte_vhost_driver_unregister() etc.

Instead of changing new_device/destroy_device callbacks and breaking
the ABI, a set of new functions new_connection/destroy_connection
has been added.

Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-by: Jens Freimann <jfreimann@redhat.com>
This commit is contained in:
Dariusz Stojaczyk 2017-08-30 12:50:58 +02:00 committed by Yuanhan Liu
parent 66a6210124
commit efba12a78d
3 changed files with 41 additions and 10 deletions

View File

@ -129,8 +129,7 @@ The following is an overview of some key Vhost API functions:
* ``destroy_device(int vid)``
This callback is invoked when a virtio device shuts down (or when the
vhost connection is broken).
This callback is invoked when a virtio device is paused or shut down.
* ``vring_state_changed(int vid, uint16_t queue_id, int enable)``
@ -143,6 +142,18 @@ The following is an overview of some key Vhost API functions:
``VHOST_F_LOG_ALL`` will be set/cleared at the start/end of live
migration, respectively.
* ``new_connection(int vid)``
This callback is invoked on new vhost-user socket connection. If DPDK
acts as the server the device should not be deleted before
``destroy_connection`` callback is received.
* ``destroy_connection(int vid)``
This callback is invoked when vhost-user socket connection is closed.
It indicates that device with id ``vid`` is no longer in use and can be
safely deleted.
* ``rte_vhost_driver_disable/enable_features(path, features))``
This function disables/enables some features. For example, it can be used to

View File

@ -107,7 +107,10 @@ struct vhost_device_ops {
*/
int (*features_changed)(int vid, uint64_t features);
void *reserved[4]; /**< Reserved for future extension */
int (*new_connection)(int vid);
void (*destroy_connection)(int vid);
void *reserved[2]; /**< Reserved for future extension */
};
/**

View File

@ -217,9 +217,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
vid = vhost_new_device();
if (vid == -1) {
close(fd);
free(conn);
return;
goto err;
}
size = strnlen(vsocket->path, PATH_MAX);
@ -230,24 +228,40 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", vid);
if (vsocket->notify_ops->new_connection) {
ret = vsocket->notify_ops->new_connection(vid);
if (ret < 0) {
RTE_LOG(ERR, VHOST_CONFIG,
"failed to add vhost user connection with fd %d\n",
fd);
goto err;
}
}
conn->connfd = fd;
conn->vsocket = vsocket;
conn->vid = vid;
ret = fdset_add(&vhost_user.fdset, fd, vhost_user_read_cb,
NULL, conn);
if (ret < 0) {
conn->connfd = -1;
free(conn);
close(fd);
RTE_LOG(ERR, VHOST_CONFIG,
"failed to add fd %d into vhost server fdset\n",
fd);
return;
if (vsocket->notify_ops->destroy_connection)
vsocket->notify_ops->destroy_connection(conn->vid);
goto err;
}
pthread_mutex_lock(&vsocket->conn_mutex);
TAILQ_INSERT_TAIL(&vsocket->conn_list, conn, next);
pthread_mutex_unlock(&vsocket->conn_mutex);
return;
err:
free(conn);
close(fd);
}
/* call back when there is new vhost-user connection from client */
@ -277,6 +291,9 @@ vhost_user_read_cb(int connfd, void *dat, int *remove)
*remove = 1;
vhost_destroy_device(conn->vid);
if (vsocket->notify_ops->destroy_connection)
vsocket->notify_ops->destroy_connection(conn->vid);
pthread_mutex_lock(&vsocket->conn_mutex);
TAILQ_REMOVE(&vsocket->conn_list, conn, next);
pthread_mutex_unlock(&vsocket->conn_mutex);