From: Jakub Grajciar Date: Mon, 4 Mar 2019 11:42:19 +0000 (+0100) Subject: libmemif: Connection request APIs X-Git-Tag: v19.04-rc1~340 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=84b83776d3843b5eaf50dbd40007987d77ad2490 libmemif: Connection request APIs Add APIs that allow changing reconnect timer and request connection. First connection request is automatically sent once slave interface is created. Change-Id: Ie3558b7b94a780b046755f7f0ac6c3dcf07633e4 Signed-off-by: Jakub Grajciar --- diff --git a/extras/libmemif/src/libmemif.h b/extras/libmemif/src/libmemif.h index 1a5be01a99f..9fc2a70f94b 100644 --- a/extras/libmemif/src/libmemif.h +++ b/extras/libmemif/src/libmemif.h @@ -23,11 +23,12 @@ #define _LIBMEMIF_H_ /** Libmemif version. */ -#define LIBMEMIF_VERSION "2.0" +#define LIBMEMIF_VERSION "2.1" /** Default name of application using libmemif. */ #define MEMIF_DEFAULT_APP_NAME "libmemif-app" #include +#include /*! Error codes */ typedef enum @@ -49,7 +50,7 @@ typedef enum MEMIF_ERR_NOCONN, /*!< handle points to no connection */ MEMIF_ERR_CONN, /*!< handle points to existing connection */ MEMIF_ERR_CB_FDUPDATE, /*!< user defined callback memif_control_fd_update_t error */ - MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket filename + MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket filename exists, but it's not socket */ MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */ MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */ @@ -419,7 +420,7 @@ int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode, @param err_code - error code Converts error code to error message. - + \return Error string */ char *memif_strerror (int err_code); @@ -475,13 +476,13 @@ int memif_cleanup (); @param private_ctx - private contex passed back to user with callback Creates memory interface. - - SLAVE-MODE - + + SLAVE-MODE - Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler every disconnected memif in slave mode will send connection request. On success new fd is passed to user with memif_control_fd_update_t. - MASTER-MODE - + MASTER-MODE - Create listener socket and pass fd to user with memif_cntrol_fd_update_t. If this fd is passed to memif_control_fd_handler accept will be called and new fd will be passed to user with memif_control_fd_update_t. @@ -500,15 +501,15 @@ int memif_create (memif_conn_handle_t * conn, memif_conn_args_t * args, If event occures on any control fd, call memif_control_fd_handler. Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly. - - FD-TYPE - - TIMERFD - + + FD-TYPE - + TIMERFD - Every disconnected memif in slave mode will request connection. - LISTENER or CONTROL - + LISTENER or CONTROL - Handle socket messaging (internal connection establishment). - INTERRUPT - + INTERRUPT - Call on_interrupt callback (if set). - + \return memif_err_t */ @@ -593,7 +594,7 @@ int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid, /** \brief Memif poll event @param timeout - timeout in seconds - Passive event polling - + Passive event polling - timeout = 0 - dont wait for event, check event queue if there is an event and return. timeout = -1 - wait until event @@ -615,6 +616,25 @@ int memif_poll_event (int timeout); */ #define MEMIF_HAVE_CANCEL_POLL_EVENT 1 int memif_cancel_poll_event (); + +/** \brief Set connection request timer value + @param timer - new timer value + + Timer on which all disconnected slaves request connection. + See system call 'timer_settime' man-page. + + \return memif_err_t +*/ +int memif_set_connection_request_timer(struct itimerspec timer); + +/** \brief Send connection request + @param conn - memif connection handle + + Only slave interface can request connection. + + \return memif_err_t +*/ +int memif_request_connection(memif_conn_handle_t conn); /** @} */ #endif /* _LIBMEMIF_H_ */ diff --git a/extras/libmemif/src/main.c b/extras/libmemif/src/main.c index b2da9fa8513..46a57da3a71 100644 --- a/extras/libmemif/src/main.c +++ b/extras/libmemif/src/main.c @@ -451,6 +451,25 @@ memif_free_register (memif_free_t * mf) lm->free = mf; } +int +memif_set_connection_request_timer(struct itimerspec timer) +{ + libmemif_main_t *lm = &libmemif_main; + int err = MEMIF_ERR_SUCCESS; + + lm->arm = timer; + + /* overwrite timer, if already armed */ + if (lm->disconn_slaves != 0) + { + if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0) + { + err = memif_syscall_error_handler (errno); + } + } + return err; +} + int memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name, memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc, @@ -573,10 +592,10 @@ memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name, goto error; } - lm->arm.it_value.tv_sec = 2; - lm->arm.it_value.tv_nsec = 0; - lm->arm.it_interval.tv_sec = 2; - lm->arm.it_interval.tv_nsec = 0; + lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC; + lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC; + lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC; + lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC; if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0) { @@ -851,15 +870,6 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args, } else { - if (lm->disconn_slaves == 0) - { - if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0) - { - err = memif_syscall_error_handler (errno); - goto error; - } - } - lm->disconn_slaves++; list_elt.key = -1; @@ -871,9 +881,21 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args, err = MEMIF_ERR_NOMEM; goto error; } - } - conn->index = index; + conn->index = index; + + /* try connectiong to master */ + err = memif_request_connection(conn); + if ((err < 0) && (lm->disconn_slaves == 1)) + { + /* connection failed, arm reconnect timer (if not armed) */ + if (timerfd_settime (lm->timerfd, 0, &lm->arm, NULL) < 0) + { + err = memif_syscall_error_handler (errno); + goto error; + } + } + } return 0; @@ -889,10 +911,77 @@ error: return err; } +int +memif_request_connection(memif_conn_handle_t c) +{ + libmemif_main_t *lm = &libmemif_main; + memif_connection_t *conn = (memif_connection_t *) c; + int err = MEMIF_ERR_SUCCESS; + int sockfd = -1; + struct sockaddr_un sun; + + if (conn->args.is_master) + return MEMIF_ERR_INVAL_ARG; + if (conn->fd > 0) + return MEMIF_ERR_ALRCONN; + + sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0); + if (sockfd < 0) + { + err = memif_syscall_error_handler (errno); + goto error; + } + + sun.sun_family = AF_UNIX; + + strncpy (sun.sun_path, (char *) conn->args.socket_filename, + sizeof (sun.sun_path) - 1); + + if (connect (sockfd, (struct sockaddr *) &sun, + sizeof (struct sockaddr_un)) == 0) + { + conn->fd = sockfd; + conn->read_fn = memif_conn_fd_read_ready; + conn->write_fn = memif_conn_fd_write_ready; + conn->error_fn = memif_conn_fd_error; + + lm->control_list[conn->index].key = conn->fd; + + lm->control_fd_update (sockfd, + MEMIF_FD_EVENT_READ | + MEMIF_FD_EVENT_WRITE); + + lm->disconn_slaves--; + if (lm->disconn_slaves == 0) + { + if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) < 0) + { + err = memif_syscall_error_handler (errno); + return err; + } + } + } + else + { + strcpy ((char *) conn->remote_disconnect_string, + memif_strerror (memif_syscall_error_handler + (errno))); + goto error; + } + + return err; + +error: + if (sockfd > 0) + close (sockfd); + sockfd = -1; + return err; +} + int memif_control_fd_handler (int fd, uint8_t events) { - int i, sockfd = -1, err = MEMIF_ERR_SUCCESS; /* 0 */ + int i, err = MEMIF_ERR_SUCCESS; /* 0 */ uint16_t num; memif_list_elt_t *e = NULL; memif_connection_t *conn; @@ -914,51 +1003,7 @@ memif_control_fd_handler (int fd, uint8_t events) conn = lm->control_list[i].data_struct; if (conn->args.is_master) continue; - - struct sockaddr_un sun; - sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0); - if (sockfd < 0) - { - err = memif_syscall_error_handler (errno); - goto error; - } - - sun.sun_family = AF_UNIX; - - strncpy (sun.sun_path, (char *) conn->args.socket_filename, - sizeof (sun.sun_path) - 1); - - if (connect (sockfd, (struct sockaddr *) &sun, - sizeof (struct sockaddr_un)) == 0) - { - conn->fd = sockfd; - conn->read_fn = memif_conn_fd_read_ready; - conn->write_fn = memif_conn_fd_write_ready; - conn->error_fn = memif_conn_fd_error; - - lm->control_list[conn->index].key = conn->fd; - - lm->control_fd_update (sockfd, - MEMIF_FD_EVENT_READ | - MEMIF_FD_EVENT_WRITE); - - lm->disconn_slaves--; - if (lm->disconn_slaves == 0) - { - if (timerfd_settime (lm->timerfd, 0, &lm->disarm, NULL) - < 0) - { - err = memif_syscall_error_handler (errno); - goto error; - } - } - } - else - { - strcpy ((char *) conn->remote_disconnect_string, - memif_strerror (memif_syscall_error_handler - (errno))); - } + memif_request_connection(conn); } } } @@ -993,15 +1038,15 @@ memif_control_fd_handler (int fd, uint8_t events) get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd); if (e != NULL) { - memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct); - return MEMIF_ERR_SUCCESS; + err = memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct); + return err; } get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd); if (e != NULL) { - memif_read_ready (fd); - return MEMIF_ERR_SUCCESS; + err = memif_read_ready (fd); + return err; } get_list_elt (&e, lm->control_list, lm->control_list_len, fd); @@ -1037,9 +1082,6 @@ memif_control_fd_handler (int fd, uint8_t events) return MEMIF_ERR_SUCCESS; /* 0 */ error: - if (sockfd > 0) - close (sockfd); - sockfd = -1; return err; } diff --git a/extras/libmemif/src/memif_private.h b/extras/libmemif/src/memif_private.h index deca80c3350..64d5bb80c86 100644 --- a/extras/libmemif/src/memif_private.h +++ b/extras/libmemif/src/memif_private.h @@ -42,6 +42,8 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN, #define MEMIF_DEFAULT_RX_QUEUES 1 #define MEMIF_DEFAULT_TX_QUEUES 1 #define MEMIF_DEFAULT_BUFFER_SIZE 2048 +#define MEMIF_DEFAULT_RECONNECT_PERIOD_SEC 2 +#define MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC 0 #define MEMIF_MAX_M2S_RING 255 #define MEMIF_MAX_S2M_RING 255 diff --git a/extras/libmemif/src/socket.c b/extras/libmemif/src/socket.c index e1c3bd4a257..495cef9ad43 100644 --- a/extras/libmemif/src/socket.c +++ b/extras/libmemif/src/socket.c @@ -681,7 +681,6 @@ memif_msg_receive (int ifd) DBG ("recvmsg fd %d", ifd); size = recvmsg (ifd, &mh, 0); - DBG ("done"); if (size != sizeof (memif_msg_t)) { if (size == 0) @@ -903,8 +902,8 @@ int memif_read_ready (int fd) { int err; - DBG ("call recv"); + err = memif_msg_receive (fd); - DBG ("recv finished"); + return err; }