vhost: add user callbacks for socket open/close
authorDariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Wed, 30 Aug 2017 10:50:58 +0000 (12:50 +0200)
committerYuanhan Liu <yliu@fridaylinux.org>
Tue, 10 Oct 2017 13:54:31 +0000 (15:54 +0200)
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>
doc/guides/prog_guide/vhost_lib.rst
lib/librte_vhost/rte_vhost.h
lib/librte_vhost/socket.c

index 5979290..d02e3cf 100644 (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
index 8c974eb..fe5c94c 100644 (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 */
 };
 
 /**
index 41aa3f9..7018150 100644 (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);