vhost: clear out unused SCM_RIGHTS file descriptors
[dpdk.git] / lib / librte_vhost / socket.c
index a71e271..776336c 100644 (file)
@@ -40,6 +40,7 @@ struct vhost_user_socket {
        bool reconnect;
        bool dequeue_zero_copy;
        bool iommu_support;
+       bool use_builtin_virtio_net;
 
        /*
         * The "supported_features" indicates the feature bits the
@@ -96,6 +97,7 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
        size_t fdsize = fd_num * sizeof(int);
        char control[CMSG_SPACE(fdsize)];
        struct cmsghdr *cmsg;
+       int got_fds = 0;
        int ret;
 
        memset(&msgh, 0, sizeof(msgh));
@@ -122,11 +124,16 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
                cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
                if ((cmsg->cmsg_level == SOL_SOCKET) &&
                        (cmsg->cmsg_type == SCM_RIGHTS)) {
-                       memcpy(fds, CMSG_DATA(cmsg), fdsize);
+                       got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+                       memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
                        break;
                }
        }
 
+       /* Clear out unused file descriptors */
+       while (got_fds < fd_num)
+               fds[got_fds++] = -1;
+
        return ret;
 }
 
@@ -195,6 +202,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
        size = strnlen(vsocket->path, PATH_MAX);
        vhost_set_ifname(vid, vsocket->path, size);
 
+       vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net);
+
        if (vsocket->dequeue_zero_copy)
                vhost_enable_dequeue_zero_copy(vid);
 
@@ -444,7 +453,7 @@ vhost_user_reconnect_init(void)
 
        ret = pthread_create(&reconn_tid, NULL,
                             vhost_user_client_reconnect, NULL);
-       if (ret < 0) {
+       if (ret != 0) {
                RTE_LOG(ERR, VHOST_CONFIG, "failed to create reconnect thread");
                if (pthread_mutex_destroy(&reconn_list.mutex)) {
                        RTE_LOG(ERR, VHOST_CONFIG,
@@ -527,6 +536,12 @@ rte_vhost_driver_disable_features(const char *path, uint64_t features)
 
        pthread_mutex_lock(&vhost_user.mutex);
        vsocket = find_vhost_user_socket(path);
+
+       /* Note that use_builtin_virtio_net is not affected by this function
+        * since callers may want to selectively disable features of the
+        * built-in vhost net device backend.
+        */
+
        if (vsocket)
                vsocket->features &= ~features;
        pthread_mutex_unlock(&vhost_user.mutex);
@@ -567,6 +582,11 @@ rte_vhost_driver_set_features(const char *path, uint64_t features)
        if (vsocket) {
                vsocket->supported_features = features;
                vsocket->features = features;
+
+               /* Anyone setting feature bits is implementing their own vhost
+                * device backend.
+                */
+               vsocket->use_builtin_virtio_net = false;
        }
        pthread_mutex_unlock(&vhost_user.mutex);
 
@@ -647,6 +667,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
         * rte_vhost_driver_set_features(), which will overwrite following
         * two values.
         */
+       vsocket->use_builtin_virtio_net = true;
        vsocket->supported_features = VIRTIO_NET_SUPPORTED_FEATURES;
        vsocket->features           = VIRTIO_NET_SUPPORTED_FEATURES;
 
@@ -658,9 +679,8 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
        if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
                vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);
                if (vsocket->reconnect && reconn_tid == 0) {
-                       if (vhost_user_reconnect_init() < 0) {
+                       if (vhost_user_reconnect_init() != 0)
                                goto out_mutex;
-                       }
                }
        } else {
                vsocket->is_server = true;
@@ -817,7 +837,7 @@ rte_vhost_driver_start(const char *path)
        if (fdset_tid == 0) {
                int ret = pthread_create(&fdset_tid, NULL, fdset_event_dispatch,
                                     &vhost_user.fdset);
-               if (ret < 0)
+               if (ret != 0)
                        RTE_LOG(ERR, VHOST_CONFIG,
                                "failed to create fdset handling thread");
        }