libmemif: Connection request APIs 93/17993/2
authorJakub Grajciar <jgrajcia@cisco.com>
Mon, 4 Mar 2019 11:42:19 +0000 (12:42 +0100)
committerDamjan Marion <dmarion@me.com>
Mon, 4 Mar 2019 14:06:37 +0000 (14:06 +0000)
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>
extras/libmemif/src/libmemif.h
extras/libmemif/src/main.c
extras/libmemif/src/memif_private.h
extras/libmemif/src/socket.c

index 1a5be01..9fc2a70 100644 (file)
 #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 <inttypes.h>
+#include <sys/timerfd.h>
 
 /*! 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_ */
index b2da9fa..46a57da 100644 (file)
@@ -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;
 }
 
index deca80c..64d5bb8 100644 (file)
@@ -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
index e1c3bd4..495cef9 100644 (file)
@@ -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;
 }