X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibmemory%2Fsocket_client.c;h=fcd31992fa59f21677e116803f4580e12e0ecf28;hb=2959d42fe;hp=d7a9ad5fe865686f919b09fd07ec4cd3374b6a6f;hpb=90a63988fa01685626b6d6a01b79ea5370f7fbac;p=vpp.git diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c index d7a9ad5fe86..fcd31992fa5 100644 --- a/src/vlibmemory/socket_client.c +++ b/src/vlibmemory/socket_client.c @@ -18,35 +18,12 @@ */ #include -#include -#include -#include #define __USE_GNU #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include + +#include +#include +#include #include @@ -79,6 +56,7 @@ int vl_socket_client_read (int wait) { socket_client_main_t *scm = &socket_client_main; + u32 data_len = 0, msg_size; int n, current_rx_index; msgbuf_t *mbp = 0; f64 timeout; @@ -91,10 +69,9 @@ vl_socket_client_read (int wait) while (1) { - current_rx_index = vec_len (scm->socket_rx_buffer); - while (vec_len (scm->socket_rx_buffer) < - sizeof (*mbp) + 2 /* msg id */ ) + while (vec_len (scm->socket_rx_buffer) < sizeof (*mbp)) { + current_rx_index = vec_len (scm->socket_rx_buffer); vec_validate (scm->socket_rx_buffer, current_rx_index + scm->socket_buffer_size - 1); _vec_len (scm->socket_rx_buffer) = current_rx_index; @@ -102,6 +79,9 @@ vl_socket_client_read (int wait) scm->socket_buffer_size); if (n < 0) { + if (errno == EAGAIN) + continue; + clib_unix_warning ("socket_read"); return -1; } @@ -113,20 +93,38 @@ vl_socket_client_read (int wait) clib_warning ("read %d bytes", n); #endif - if (mbp == 0) - mbp = (msgbuf_t *) (scm->socket_rx_buffer); + mbp = (msgbuf_t *) (scm->socket_rx_buffer); + data_len = ntohl (mbp->data_len); + current_rx_index = vec_len (scm->socket_rx_buffer); + vec_validate (scm->socket_rx_buffer, current_rx_index + data_len); + _vec_len (scm->socket_rx_buffer) = current_rx_index; + mbp = (msgbuf_t *) (scm->socket_rx_buffer); + msg_size = data_len + sizeof (*mbp); - if (vec_len (scm->socket_rx_buffer) >= ntohl (mbp->data_len) - + sizeof (*mbp)) + while (vec_len (scm->socket_rx_buffer) < msg_size) + { + n = read (scm->socket_fd, + scm->socket_rx_buffer + vec_len (scm->socket_rx_buffer), + msg_size - vec_len (scm->socket_rx_buffer)); + if (n < 0) + { + if (errno == EAGAIN) + continue; + + clib_unix_warning ("socket_read"); + return -1; + } + _vec_len (scm->socket_rx_buffer) += n; + } + + if (vec_len (scm->socket_rx_buffer) >= data_len + sizeof (*mbp)) { vl_msg_api_socket_handler ((void *) (mbp->data)); - if (vec_len (scm->socket_rx_buffer) == ntohl (mbp->data_len) - + sizeof (*mbp)) + if (vec_len (scm->socket_rx_buffer) == data_len + sizeof (*mbp)) _vec_len (scm->socket_rx_buffer) = 0; else - vec_delete (scm->socket_rx_buffer, ntohl (mbp->data_len) - + sizeof (*mbp), 0); + vec_delete (scm->socket_rx_buffer, data_len + sizeof (*mbp), 0); mbp = 0; /* Quit if we're out of data, and not expecting a ping reply */ @@ -134,7 +132,6 @@ vl_socket_client_read (int wait) && scm->control_pings_outstanding == 0) break; } - if (wait && clib_time_now (&scm->clib_time) >= timeout) return -1; } @@ -181,6 +178,12 @@ void vl_socket_client_disconnect (void) { socket_client_main_t *scm = &socket_client_main; + + if (vl_mem_client_is_connected ()) + { + vl_client_disconnect_from_vlib_no_unmap (); + ssvm_delete_memfd (&scm->memfd_segment); + } if (scm->socket_fd && (close (scm->socket_fd) < 0)) clib_unix_warning ("close"); scm->socket_fd = 0; @@ -193,19 +196,22 @@ vl_socket_client_enable_disable (int enable) scm->socket_enable = enable; } -static clib_error_t * -receive_fd_msg (int socket_fd, int *my_fd) +clib_error_t * +vl_sock_api_recv_fd_msg (int socket_fd, int fds[], int n_fds, u32 wait) { + socket_client_main_t *scm = &socket_client_main; char msgbuf[16]; - char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))]; + char ctl[CMSG_SPACE (sizeof (int) * n_fds) + + CMSG_SPACE (sizeof (struct ucred))]; struct msghdr mh = { 0 }; struct iovec iov[1]; - ssize_t size; + ssize_t size = 0; struct ucred *cr = 0; struct cmsghdr *cmsg; pid_t pid __attribute__ ((unused)); uid_t uid __attribute__ ((unused)); gid_t gid __attribute__ ((unused)); + f64 timeout; iov[0].iov_base = msgbuf; iov[0].iov_len = 5; @@ -214,10 +220,17 @@ receive_fd_msg (int socket_fd, int *my_fd) mh.msg_control = ctl; mh.msg_controllen = sizeof (ctl); - memset (ctl, 0, sizeof (ctl)); + clib_memset (ctl, 0, sizeof (ctl)); + + if (wait != ~0) + { + timeout = clib_time_now (&scm->clib_time) + wait; + while (size != 5 && clib_time_now (&scm->clib_time) < timeout) + size = recvmsg (socket_fd, &mh, MSG_DONTWAIT); + } + else + size = recvmsg (socket_fd, &mh, 0); - /* receive the incoming message */ - size = recvmsg (socket_fd, &mh, 0); if (size != 5) { return (size == 0) ? clib_error_return (0, "disconnected") : @@ -239,7 +252,7 @@ receive_fd_msg (int socket_fd, int *my_fd) } else if (cmsg->cmsg_type == SCM_RIGHTS) { - clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int)); + clib_memcpy_fast (fds, CMSG_DATA (cmsg), sizeof (int) * n_fds); } } cmsg = CMSG_NXTHDR (&mh, cmsg); @@ -251,11 +264,11 @@ static void vl_api_sock_init_shm_reply_t_handler (vl_api_sock_init_shm_reply_t * mp) { socket_client_main_t *scm = &socket_client_main; - int my_fd = -1; - clib_error_t *error; + ssvm_private_t *memfd = &scm->memfd_segment; i32 retval = ntohl (mp->retval); - memfd_private_t memfd; api_main_t *am = &api_main; + clib_error_t *error; + int my_fd = -1; u8 *new_name; if (retval) @@ -267,31 +280,42 @@ static void vl_api_sock_init_shm_reply_t_handler /* * Check the socket for the magic fd */ - error = receive_fd_msg (scm->socket_fd, &my_fd); + error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 1, 5); if (error) { + clib_error_report (error); retval = -99; return; } - memset (&memfd, 0, sizeof (memfd)); - memfd.fd = my_fd; + clib_memset (memfd, 0, sizeof (*memfd)); + memfd->fd = my_fd; /* Note: this closes memfd.fd */ - retval = memfd_slave_init (&memfd); + retval = ssvm_slave_init_memfd (memfd); if (retval) clib_warning ("WARNING: segment map returned %d", retval); /* * Pivot to the memory client segment that vpp just created */ - am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE); + am->vlib_rp = (void *) (memfd->requested_va + MMAP_PAGESIZE); am->shmem_hdr = (void *) am->vlib_rp->user_ctx; new_name = format (0, "%v[shm]%c", scm->name, 0); vl_client_install_client_message_handlers (); - vl_client_connect_to_vlib_no_map ("pvt", (char *) new_name, - 32 /* input_queue_length */ ); + if (scm->want_shm_pthread) + { + vl_client_connect_to_vlib_no_map ("pvt", (char *) new_name, + 32 /* input_queue_length */ ); + } + else + { + vl_client_connect_to_vlib_no_rx_pthread_no_map ("pvt", + (char *) new_name, 32 + /* input_queue_length */ + ); + } vl_socket_client_enable_disable (0); vec_free (new_name); } @@ -301,7 +325,10 @@ vl_api_sockclnt_create_reply_t_handler (vl_api_sockclnt_create_reply_t * mp) { socket_client_main_t *scm = &socket_client_main; if (!mp->response) - scm->socket_enable = 1; + { + scm->socket_enable = 1; + scm->client_index = clib_net_to_host_u32 (mp->index); + } } #define foreach_sock_client_api_msg \ @@ -347,7 +374,7 @@ vl_socket_client_connect (char *socket_path, char *client_name, sock = &scm->client_socket; sock->config = socket_path; - sock->flags = CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET; + sock->flags = CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_NON_BLOCKING_CONNECT; if ((error = clib_socket_init (sock))) { @@ -368,32 +395,37 @@ vl_socket_client_connect (char *socket_path, char *client_name, mp = vl_socket_client_msg_alloc (sizeof (*mp)); mp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE); - strncpy ((char *) mp->name, client_name, sizeof (mp->name) - 1); - mp->name[sizeof (mp->name) - 1] = 0; + + vl_api_to_api_string (strnlen_s (client_name, 64), client_name, &mp->name); mp->context = 0xfeedface; + clib_time_init (&scm->clib_time); + if (vl_socket_client_write () <= 0) return (-1); - if (vl_socket_client_read (1)) + if (vl_socket_client_read (5)) return (-1); - clib_time_init (&scm->clib_time); return (0); } int -vl_socket_client_init_shm (vl_api_shm_elem_config_t * config) +vl_socket_client_init_shm (vl_api_shm_elem_config_t * config, + int want_pthread) { + socket_client_main_t *scm = &socket_client_main; vl_api_sock_init_shm_t *mp; int rv, i; u64 *cfg; + scm->want_shm_pthread = want_pthread; + mp = vl_socket_client_msg_alloc (sizeof (*mp) + vec_len (config) * sizeof (u64)); - memset (mp, 0, sizeof (*mp)); + clib_memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_SOCK_INIT_SHM); - mp->client_index = ~0; + mp->client_index = clib_host_to_net_u32 (scm->client_index); mp->requested_size = 64 << 20; if (config) @@ -415,6 +447,15 @@ vl_socket_client_init_shm (vl_api_shm_elem_config_t * config) return 0; } +clib_error_t * +vl_socket_client_recv_fd_msg (int fds[], int n_fds, u32 wait) +{ + socket_client_main_t *scm = &socket_client_main; + if (!scm->socket_fd) + return clib_error_return (0, "no socket"); + return vl_sock_api_recv_fd_msg (scm->client_socket.fd, fds, n_fds, wait); +} + /* * fd.io coding-style-patch-verification: ON *