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 <jgrajcia@cisco.com>
This commit is contained in:
Jakub Grajciar
2019-03-04 12:42:19 +01:00
committed by Damjan Marion
parent 608996d2bd
commit 84b83776d3
4 changed files with 147 additions and 84 deletions

View File

@ -23,11 +23,12 @@
#define _LIBMEMIF_H_ #define _LIBMEMIF_H_
/** Libmemif version. */ /** Libmemif version. */
#define LIBMEMIF_VERSION "2.0" #define LIBMEMIF_VERSION "2.1"
/** Default name of application using libmemif. */ /** Default name of application using libmemif. */
#define MEMIF_DEFAULT_APP_NAME "libmemif-app" #define MEMIF_DEFAULT_APP_NAME "libmemif-app"
#include <inttypes.h> #include <inttypes.h>
#include <sys/timerfd.h>
/*! Error codes */ /*! Error codes */
typedef enum typedef enum
@ -49,7 +50,7 @@ typedef enum
MEMIF_ERR_NOCONN, /*!< handle points to no connection */ MEMIF_ERR_NOCONN, /*!< handle points to no connection */
MEMIF_ERR_CONN, /*!< handle points to existing connection */ MEMIF_ERR_CONN, /*!< handle points to existing connection */
MEMIF_ERR_CB_FDUPDATE, /*!< user defined callback memif_control_fd_update_t error */ 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 */ exists, but it's not socket */
MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */ MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */
MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */ 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 @param err_code - error code
Converts error code to error message. Converts error code to error message.
\return Error string \return Error string
*/ */
char *memif_strerror (int err_code); char *memif_strerror (int err_code);
@ -475,13 +476,13 @@ int memif_cleanup ();
@param private_ctx - private contex passed back to user with callback @param private_ctx - private contex passed back to user with callback
Creates memory interface. 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 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. every disconnected memif in slave mode will send connection request.
On success new fd is passed to user with memif_control_fd_update_t. 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. 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 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. 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. If event occures on any control fd, call memif_control_fd_handler.
Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly. Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly.
FD-TYPE - FD-TYPE -
TIMERFD - TIMERFD -
Every disconnected memif in slave mode will request connection. Every disconnected memif in slave mode will request connection.
LISTENER or CONTROL - LISTENER or CONTROL -
Handle socket messaging (internal connection establishment). Handle socket messaging (internal connection establishment).
INTERRUPT - INTERRUPT -
Call on_interrupt callback (if set). Call on_interrupt callback (if set).
\return memif_err_t \return memif_err_t
*/ */
@ -593,7 +594,7 @@ int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
/** \brief Memif poll event /** \brief Memif poll event
@param timeout - timeout in seconds @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 = 0 - dont wait for event, check event queue if there is an event and return.
timeout = -1 - wait until event timeout = -1 - wait until event
@ -615,6 +616,25 @@ int memif_poll_event (int timeout);
*/ */
#define MEMIF_HAVE_CANCEL_POLL_EVENT 1 #define MEMIF_HAVE_CANCEL_POLL_EVENT 1
int memif_cancel_poll_event (); 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_ */ #endif /* _LIBMEMIF_H_ */

View File

@ -451,6 +451,25 @@ memif_free_register (memif_free_t * mf)
lm->free = 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 int
memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name, memif_init (memif_control_fd_update_t * on_control_fd_update, char *app_name,
memif_alloc_t * memif_alloc, memif_realloc_t * memif_realloc, 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; goto error;
} }
lm->arm.it_value.tv_sec = 2; lm->arm.it_value.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
lm->arm.it_value.tv_nsec = 0; lm->arm.it_value.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
lm->arm.it_interval.tv_sec = 2; lm->arm.it_interval.tv_sec = MEMIF_DEFAULT_RECONNECT_PERIOD_SEC;
lm->arm.it_interval.tv_nsec = 0; lm->arm.it_interval.tv_nsec = MEMIF_DEFAULT_RECONNECT_PERIOD_NSEC;
if (lm->control_fd_update (lm->timerfd, MEMIF_FD_EVENT_READ) < 0) 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 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++; lm->disconn_slaves++;
list_elt.key = -1; list_elt.key = -1;
@ -871,9 +881,21 @@ memif_create (memif_conn_handle_t * c, memif_conn_args_t * args,
err = MEMIF_ERR_NOMEM; err = MEMIF_ERR_NOMEM;
goto error; 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; return 0;
@ -889,10 +911,77 @@ error:
return err; 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 int
memif_control_fd_handler (int fd, uint8_t events) 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; uint16_t num;
memif_list_elt_t *e = NULL; memif_list_elt_t *e = NULL;
memif_connection_t *conn; memif_connection_t *conn;
@ -914,51 +1003,7 @@ memif_control_fd_handler (int fd, uint8_t events)
conn = lm->control_list[i].data_struct; conn = lm->control_list[i].data_struct;
if (conn->args.is_master) if (conn->args.is_master)
continue; continue;
memif_request_connection(conn);
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)));
}
} }
} }
} }
@ -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); get_list_elt (&e, lm->listener_list, lm->listener_list_len, fd);
if (e != NULL) if (e != NULL)
{ {
memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct); err = memif_conn_fd_accept_ready ((memif_socket_t *) e->data_struct);
return MEMIF_ERR_SUCCESS; return err;
} }
get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd); get_list_elt (&e, lm->pending_list, lm->pending_list_len, fd);
if (e != NULL) if (e != NULL)
{ {
memif_read_ready (fd); err = memif_read_ready (fd);
return MEMIF_ERR_SUCCESS; return err;
} }
get_list_elt (&e, lm->control_list, lm->control_list_len, fd); 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 */ return MEMIF_ERR_SUCCESS; /* 0 */
error: error:
if (sockfd > 0)
close (sockfd);
sockfd = -1;
return err; return err;
} }

View File

@ -42,6 +42,8 @@ _Static_assert (strlen (MEMIF_DEFAULT_APP_NAME) <= MEMIF_NAME_LEN,
#define MEMIF_DEFAULT_RX_QUEUES 1 #define MEMIF_DEFAULT_RX_QUEUES 1
#define MEMIF_DEFAULT_TX_QUEUES 1 #define MEMIF_DEFAULT_TX_QUEUES 1
#define MEMIF_DEFAULT_BUFFER_SIZE 2048 #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_M2S_RING 255
#define MEMIF_MAX_S2M_RING 255 #define MEMIF_MAX_S2M_RING 255

View File

@ -681,7 +681,6 @@ memif_msg_receive (int ifd)
DBG ("recvmsg fd %d", ifd); DBG ("recvmsg fd %d", ifd);
size = recvmsg (ifd, &mh, 0); size = recvmsg (ifd, &mh, 0);
DBG ("done");
if (size != sizeof (memif_msg_t)) if (size != sizeof (memif_msg_t))
{ {
if (size == 0) if (size == 0)
@ -903,8 +902,8 @@ int
memif_read_ready (int fd) memif_read_ready (int fd)
{ {
int err; int err;
DBG ("call recv");
err = memif_msg_receive (fd); err = memif_msg_receive (fd);
DBG ("recv finished");
return err; return err;
} }