aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Burns <alagalah@gmail.com>2017-10-09 20:50:41 +0000
committerGerrit Code Review <gerrit@fd.io>2017-10-09 20:50:41 +0000
commit701b794fe0bbe2ea1238fb8273c5611140bb802f (patch)
tree6a8c0ebf6e897b528659acd79c79595076d0b28a
parentbea87a678f755b9d205dc95802a38ee91c0d067e (diff)
parent1431306b973562a04f515b7beb2f668b89e72374 (diff)
Merge "LD_PRELOAD epoll_ctl implementation"
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom.c17
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c867
-rw-r--r--vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h26
3 files changed, 711 insertions, 199 deletions
diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
index 4da2d99..7a13249 100644
--- a/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
+++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom.c
@@ -2631,8 +2631,14 @@ int
epoll_create (int __size)
{
int rv = 0;
+ pid_t pid = getpid ();
rv = vcom_epoll_create(__size);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr,
+ "[%d] epoll_create: "
+ "'%04d'='%04d'\n",
+ pid, rv, __size);
if (rv < 0)
{
errno = -rv;
@@ -2669,8 +2675,14 @@ int
epoll_create1 (int __flags)
{
int rv = 0;
+ pid_t pid = getpid ();
rv = vcom_epoll_create1(__flags);
+ if (VCOM_DEBUG > 0)
+ fprintf (stderr,
+ "[%d] epoll_create: "
+ "'%04d'='%08x'\n",
+ pid, rv, __flags);
if (rv < 0)
{
errno = -rv;
@@ -2711,10 +2723,12 @@ vcom_epoll_ctl (int __epfd, int __op, int __fd,
}
/* fd is same as epfd */
+ /* do not permit adding an epoll file descriptor inside itself */
if (__epfd == __fd)
{
return -EINVAL;
}
+
/* implementation */
return vcom_socket_epoll_ctl (__epfd, __op, __fd,
__event);
@@ -2742,7 +2756,8 @@ epoll_ctl (int __epfd, int __op, int __fd,
if (VCOM_DEBUG > 0)
fprintf (stderr,
"[%d] epoll_ctl: "
- "'%04d'='%04d', '%04d', '%04d'\n", pid, rv, __epfd, __op, __fd);
+ "'%04d'='%04d', '%04d', '%04d'\n",
+ pid, rv, __epfd, __op, __fd);
if (rv != 0)
{
errno = -rv;
diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
index 0fd2bb1..415d277 100644
--- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
+++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.c
@@ -57,7 +57,7 @@ typedef struct vcom_socket_main_t_
vcom_epitem_t *vepitems;
/* Hash table for epitemidx to epfdfd mapping */
- uword *epollidx_by_epfdfd;
+ uword *epitemidx_by_epfdfd;
/* Hash table - key:epfd, value:vec of epitemidx */
uword *epitemidxs_by_epfd;
@@ -158,171 +158,6 @@ vcom_socket_close_epoll (int epfd)
* Public API functions
*/
-int
-vcom_socket_main_init (void)
-{
- vcom_socket_main_t *vsm = &vcom_socket_main;
-
- if (VCOM_DEBUG > 0)
- printf ("vcom_socket_main_init\n");
-
- if (!vsm->init)
- {
- /* TBD: define FD_MAXSIZE and use it here */
- pool_alloc (vsm->vsockets, FD_SETSIZE);
- vsm->sockidx_by_fd = hash_create (0, sizeof (i32));
-
- pool_alloc (vsm->vepolls, FD_SETSIZE);
- vsm->epollidx_by_epfd = hash_create (0, sizeof (i32));
-
- pool_alloc (vsm->vepitems, FD_SETSIZE);
- vsm->epitemidxs_by_epfd = hash_create (0, sizeof (uword *));
- vsm->epitemidxs_by_fd = hash_create (0, sizeof (uword *));
-
- vsm->init = 1;
- }
-
- return 0;
-}
-
-void
-vcom_socket_main_destroy (void)
-{
- vcom_socket_main_t *vsm = &vcom_socket_main;
- vcom_socket_t *vsock;
-
- vcom_epoll_t *vepoll;
-
- if (VCOM_DEBUG > 0)
- printf ("vcom_socket_main_destroy\n");
-
- if (vsm->init)
- {
- /*
- * from active list of vsockets,
- * close socket and vppcom session
- * */
-
- /* *INDENT-OFF* */
- pool_foreach (vsock, vsm->vsockets,
- ({
- if (vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
- {
- vppcom_session_close (vsock->sid);
- vcom_socket_close_socket (vsock->fd);
- vsocket_init (vsock);
- }
- }));
- /* *INDENT-ON* */
-
- /*
- * return vsocket element to the pool
- * */
-
- /* *INDENT-OFF* */
- pool_flush (vsock, vsm->vsockets,
- ({
- // vsocket_init(vsock);
- ;
- }));
- /* *INDENT-ON* */
-
- pool_free (vsm->vsockets);
- hash_free (vsm->sockidx_by_fd);
-
- /*
- * from active list of vepolls,
- * close epoll and vppcom_epoll
- * */
-
- /* *INDENT-OFF* */
- pool_foreach (vepoll, vsm->vepolls,
- ({
- if (vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
- {
- vppcom_session_close (vepoll->vep_idx);
- vcom_socket_close_epoll (vepoll->epfd); /* TBD: */
- vepoll_init (vepoll);
- }
- }));
- /* *INDENT-ON* */
-
- /*
- * return vepoll element to the pool
- * */
-
- /* *INDENT-OFF* */
- pool_flush (vepoll, vsm->vepolls,
- ({
- // vepoll_init(vepoll);
- ;
- }));
- /* *INDENT-ON* */
-
- pool_free (vsm->vepolls);
- hash_free (vsm->epollidx_by_epfd);
-
-
- vsm->init = 0;
- }
-}
-
-void
-vcom_socket_main_show (void)
-{
- vcom_socket_main_t *vsm = &vcom_socket_main;
- vcom_socket_t *vsock;
-
- vcom_epoll_t *vepoll;
- vcom_epitem_t *vepitem;
-
- if (vsm->init)
- {
- /* from active list of vsockets show vsock */
-
- /* *INDENT-OFF* */
- pool_foreach (vsock, vsm->vsockets,
- ({
- printf(
- "fd='%04d', sid='%08x',type='%-30s'\n",
- vsock->fd, vsock->sid,
- vcom_socket_type_str (vsock->type));
- }));
- /* *INDENT-ON* */
-
- /* from active list of vepolls, show vepoll */
-
- /* *INDENT-OFF* */
- pool_foreach (vepoll, vsm->vepolls,
- ({
- printf(
- "epfd='%04d', vep_idx='%08x', "
- "type='%-30s', "
- "flags='%d', count='%d', close='%d'\n",
- vepoll->epfd, vepoll->vep_idx,
- vcom_socket_epoll_type_str (vepoll->type),
- vepoll->flags, vepoll->count, vepoll->close);
- }));
- /* *INDENT-ON* */
-
- /* from active list of vepitems, show vepitem */
-
- /* *INDENT-OFF* */
- pool_foreach (vepitem, vsm->vepitems,
- ({
- printf(
- "epfd='%04d', fd='%04d', "
- "next_fd='%04d', prev_fd='%04d', "
- "type='%-30s', "
- "events='%04x', revents='%04x'\n",
- vepitem->epfd, vepitem->fd,
- vepitem->next_fd, vepitem->prev_fd,
- vcom_socket_vcom_fd_type_str (vepitem->type),
- vepitem->event.events, vepitem->revent.events);
- }));
- /* *INDENT-ON* */
- }
-}
int
vcom_socket_is_vcom_fd (int fd)
@@ -396,42 +231,50 @@ vcom_socket_get_vep_idx (int epfd)
return INVALID_VEP_IDX;
}
-static int
-vcom_socket_close_vsock (int fd)
+static inline int
+vcom_socket_get_sid_and_vsock (int fd, vcom_socket_t **vsockp)
{
- int rv = -1;
vcom_socket_main_t *vsm = &vcom_socket_main;
uword *p;
vcom_socket_t *vsock;
p = hash_get (vsm->sockidx_by_fd, fd);
- if (!p)
- return -EBADF;
- vsock = pool_elt_at_index (vsm->vsockets, p[0]);
- if (!vsock)
- return -ENOTSOCK;
-
- if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
- return -EINVAL;
-
- rv = vppcom_session_close (vsock->sid);
- rv = vcom_socket_close_socket (vsock->fd);
+ if (p)
+ {
+ vsock = pool_elt_at_index (vsm->vsockets, p[0]);
+ if (vsock && vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
+ {
+ *vsockp = vsock;
+ return vsock->sid;
+ }
+ }
+ return INVALID_SESSION_ID;
+}
- vsocket_init (vsock);
- hash_unset (vsm->sockidx_by_fd, fd);
- pool_put (vsm->vsockets, vsock);
+static inline int
+vcom_socket_get_vep_idx_and_vepoll (int epfd, vcom_epoll_t **vepollp)
+{
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+ uword *p;
+ vcom_epoll_t *vepoll;
- /*
- * TBD:
- * close all epoll instances that are marked as "close"
- * of which this fd is the last remaining member
- * */
+ p = hash_get (vsm->epollidx_by_epfd, epfd);
- return rv;
+ if (p)
+ {
+ vepoll = pool_elt_at_index (vsm->vepolls, p[0]);
+ if (vepoll && vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
+ {
+ *vepollp = vepoll;
+ return vepoll->vep_idx;
+ }
+ }
+ return INVALID_VEP_IDX;
}
-int
+
+static int
vcom_socket_close_vepoll (int epfd)
{
int rv = -1;
@@ -474,6 +317,92 @@ vcom_socket_close_vepoll (int epfd)
return rv;
}
+static int
+vcom_socket_close_vsock (int fd)
+{
+ int rv = -1;
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+ uword *p;
+ vcom_socket_t *vsock;
+
+ vcom_epitem_t *vepitem;
+
+ i32 *vepitemidxs = 0;
+ i32 *vepitemidxs_var = 0;
+
+ p = hash_get (vsm->sockidx_by_fd, fd);
+ if (!p)
+ return -EBADF;
+
+ vsock = pool_elt_at_index (vsm->vsockets, p[0]);
+ if (!vsock)
+ return -ENOTSOCK;
+
+ if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND)
+ return -EINVAL;
+
+ rv = vppcom_session_close (vsock->sid);
+ rv = vcom_socket_close_socket (vsock->fd);
+
+ vsocket_init (vsock);
+ hash_unset (vsm->sockidx_by_fd, fd);
+ pool_put (vsm->vsockets, vsock);
+
+ /*
+ * NOTE:
+ * Before calling close(), user should remove
+ * this fd from the epoll-set of all epoll instances,
+ * otherwise resource(epitems) leaks ensues.
+ */
+
+ /*
+ * 00. close all epoll instances that are marked as "close"
+ * of which this fd is the "last" remaining member.
+ * 01. epitems associated with this fd are intentionally
+ * not removed, see NOTE: above.
+ * */
+
+ /* does this fd participate in epoll */
+ p = hash_get (vsm->epitemidxs_by_fd, fd);
+ if (p)
+ {
+ vepitemidxs = *(i32 **)p;
+ vec_foreach (vepitemidxs_var, vepitemidxs)
+ {
+ vepitem = pool_elt_at_index (vsm->vepitems, vepitemidxs_var[0]);
+ if (vepitem && vepitem->fd == fd &&
+ vepitem->type == FD_TYPE_VCOM_SOCKET)
+ {
+ i32 vep_idx;
+ vcom_epoll_t *vepoll;
+ if ((vep_idx =
+ vcom_socket_get_vep_idx_and_vepoll (vepitem->epfd, &vepoll)) != INVALID_VEP_IDX)
+ {
+ if (vepoll->close)
+ {
+ if (vepoll->count == 1)
+ {
+ /*
+ * force count to zero and
+ * close this epoll instance
+ * */
+ vepoll->count = 0;
+ vcom_socket_close_vepoll (vepoll->epfd);
+ }
+ else
+ {
+ vepoll->count -= 1;
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ return rv;
+}
+
int
vcom_socket_close (int __fd)
{
@@ -2364,13 +2293,6 @@ vcom_socket_shutdown (int __fd, int __how)
return rv;
}
-/*
- * TBD: remove it once vppvom.h is committed.
- */
-int vppcom_epoll_create (void)
-{
- return -ENOSYS;
-}
int
vcom_socket_epoll_create1 (int __flags)
{
@@ -2413,11 +2335,307 @@ out:
return rv;
}
+/*
+ * PRE: vppcom_epoll_ctl() is successful
+ * free_vepitem_on_del : 0 - no_pool_put, 1 - pool_put
+ */
+int
+vcom_socket_ctl_vepitem (int __epfd, int __op, int __fd,
+ struct epoll_event *__event,
+ i32 vep_idx, vcom_epoll_t *vepoll,
+ i32 vfd_id, void *vfd, vcom_fd_type_t type,
+ int free_vepitem_on_del)
+{
+ int rv = -1;
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+ vcom_epitem_t *vepitem;
+
+ vcom_epitem_key_t epfdfd = {.epfd = __epfd, .fd = __fd};
+ uword *p;
+ i32 vepitemidx;
+
+ i32 *vepitemidxs = 0;
+
+ struct epoll_event revent = {.events = 0, .data.fd = INVALID_FD};
+
+ i32 vec_idx ;
+
+ /* perform control operations on the epoll instance */
+ switch (__op)
+ {
+ case EPOLL_CTL_ADD:
+ /*
+ * supplied file descriptor is already
+ * registered with this epoll instance
+ * */
+ /* vepitem exists */
+ p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
+ if (p)
+ {
+ rv = -EEXIST;
+ goto out;
+ }
+
+ /* add a new vepitem */
+ pool_get (vsm->vepitems, vepitem);
+ vepitem_init (vepitem);
+
+ vepitemidx = vepitem - vsm->vepitems;
+ hash_set (vsm->epitemidx_by_epfdfd, epfdfd.key, vepitemidx);
+ vepitem_set (vepitem,
+ __epfd,
+ __fd, __fd, __fd,
+ type,
+ *__event, revent);
+
+ /* update epitemidxs */
+ /* by_epfd */
+ p = hash_get (vsm->epitemidxs_by_epfd, __epfd);
+ if (!p) /* not exist */
+ {
+ vepitemidxs = 0;
+ vec_add1 (vepitemidxs, vepitemidx);
+ hash_set (vsm->epitemidxs_by_epfd, __epfd, vepitemidxs);
+ }
+ else /* exists */
+ {
+ vepitemidxs = *(i32 **)p;
+ vec_add1 (vepitemidxs, vepitemidx);
+ hash_set3 (vsm->epitemidxs_by_epfd, __epfd, vepitemidxs, 0);
+ }
+ /* update epitemidxs */
+ /* by_fd */
+ p = hash_get (vsm->epitemidxs_by_fd, __fd);
+ if (!p) /* not exist */
+ {
+ vepitemidxs = 0;
+ vec_add1 (vepitemidxs, vepitemidx);
+ hash_set (vsm->epitemidxs_by_fd, __fd, vepitemidxs);
+ }
+ else /* exists */
+ {
+ vepitemidxs = *(i32 **)p;
+ vec_add1 (vepitemidxs, vepitemidx);
+ hash_set3 (vsm->epitemidxs_by_fd, __fd, vepitemidxs, 0);
+ }
+
+ /* increment vepoll fd count by 1 */
+ vepoll->count +=1;
+
+ rv = 0;
+ goto out;
+ break;
+
+ case EPOLL_CTL_MOD:
+ /*
+ * supplied file descriptor is not
+ * registered with this epoll instance
+ * */
+ /* vepitem not exist */
+ p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
+ if (!p)
+ {
+ rv = -ENOENT;
+ goto out;
+ }
+ vepitem = pool_elt_at_index (vsm->vepitems, p[0]);
+ if (vepitem)
+ {
+ vepitem->event = *__event;
+ vepitem->revent = revent;
+ }
+
+ rv = 0;
+ goto out;
+ break;
+
+ case EPOLL_CTL_DEL:
+ /*
+ * supplied file descriptor is not
+ * registered with this epoll instance
+ * */
+ /* vepitem not exist */
+ p = hash_get (vsm->epitemidx_by_epfdfd, epfdfd.key);
+ if (!p)
+ {
+ rv = -ENOENT;
+ goto out;
+ }
+ vepitemidx = *(i32 *)p;
+ hash_unset (vsm->epitemidx_by_epfdfd, epfdfd.key);
+
+ /* update epitemidxs */
+ /* by_epfd */
+ p = hash_get (vsm->epitemidxs_by_epfd, __epfd);
+ if (!p) /* not exist */
+ {
+ rv = -ENOENT;
+ goto out;
+ }
+ else /* exists */
+ {
+ vepitemidxs = *(i32 **)p;
+ vec_idx = vec_search (vepitemidxs, vepitemidx);
+ if(vec_idx != ~0)
+ {
+ vec_del1 (vepitemidxs, vec_idx);
+ if(!vec_len (vepitemidxs))
+ {
+ vec_free (vepitemidxs);
+ hash_unset (vsm->epitemidxs_by_epfd, __epfd);
+ }
+ }
+ }
+
+ /* update epitemidxs */
+ /* by_fd */
+ p = hash_get (vsm->epitemidxs_by_fd, __fd);
+ if (!p) /* not exist */
+ {
+ rv = -ENOENT;
+ goto out;
+ }
+ else /* exists */
+ {
+ vepitemidxs = *(i32 **)p;
+ vec_idx = vec_search (vepitemidxs, vepitemidx);
+ if(vec_idx != ~0)
+ {
+ vec_del1 (vepitemidxs, vec_idx);
+ if(!vec_len (vepitemidxs))
+ {
+ vec_free (vepitemidxs);
+ hash_unset (vsm->epitemidxs_by_fd, __fd);
+ }
+ }
+ }
+
+ /* pool put vepitem */
+ vepitem = pool_elt_at_index (vsm->vepitems, vepitemidx);
+ if (free_vepitem_on_del)
+ {
+ if(!vepitem)
+ {
+ rv = -ENOENT;
+ goto out;
+ }
+ vepitem_init(vepitem);
+ pool_put (vsm->vepitems, vepitem);
+ }
+ else
+ {
+ if(!vepitem)
+ {
+ vepitem_init(vepitem);
+ }
+ }
+
+ /* decrement vepoll fd count by 1 */
+ vepoll->count -=1;
+
+ rv = 0;
+ goto out;
+ break;
+
+ default:
+ rv = -EINVAL;
+ goto out;
+ break;
+ }
+
+out:
+ return rv;
+}
+
+/*
+ * PRE: 00. null pointer check on __event
+ * 01. all other parameters are validated
+ */
+
+static int
+vcom_socket_epoll_ctl_internal (int __epfd, int __op, int __fd,
+ struct epoll_event *__event,
+ int free_vepitem_on_del)
+{
+ int rv = -1;
+
+ /* vcom_socket_main_t *vsm = &vcom_socket_main; */
+ vcom_epoll_t *vepoll;
+
+ /*__fd could could be vcom socket or vcom epoll or kernel fd */
+ void *vfd;
+ vcom_epoll_t *vfd_vepoll;
+ vcom_socket_t *vfd_vsock;
+
+ i32 vep_idx;
+ i32 vfd_id;
+
+ vcom_fd_type_t type = FD_TYPE_INVALID;
+
+ /* validate __event */
+
+ /* get vep_idx and vepoll */
+ vep_idx = vcom_socket_get_vep_idx_and_vepoll (__epfd, &vepoll);
+ if (vep_idx == INVALID_VEP_IDX)
+ {
+ return -EBADF;
+ }
+
+ /* get vcom fd type, vfd_id and vfd */
+ vfd_id = vcom_socket_get_sid_and_vsock (__fd, &vfd_vsock);
+ if (vfd_id != INVALID_SESSION_ID)
+ {
+ type = FD_TYPE_VCOM_SOCKET;
+ vfd = vfd_vsock;
+ }
+ else if ((vfd_id = vcom_socket_get_vep_idx_and_vepoll (__fd, &vfd_vepoll)) != INVALID_VEP_IDX)
+ {
+ type = FD_TYPE_EPOLL;
+ vfd = vfd_vepoll;
+ }
+ else
+ {
+ /* FD_TYPE_KERNEL not supported by epoll instance */
+ type = FD_TYPE_INVALID;
+ return -EBADF;
+ }
+
+
+ /* vepoll and vsock are now valid */
+ rv = vppcom_epoll_ctl ( vep_idx, __op, vfd_id, __event);
+ if (rv < 0)
+ {
+ return rv;
+ }
+
+ rv = vcom_socket_ctl_vepitem (__epfd, __op, __fd,
+ __event,
+ vep_idx, vepoll,
+ vfd_id, vfd, type,
+ free_vepitem_on_del);
+ return rv;
+}
+
int
vcom_socket_epoll_ctl (int __epfd, int __op, int __fd,
struct epoll_event *__event)
{
- return -ENOSYS;
+ int rv = -1;
+
+ rv = vcom_socket_epoll_ctl_internal (__epfd, __op, __fd,
+ __event, 1);
+ return rv;
+}
+
+static int
+vcom_socket_epoll_ctl1 (int __epfd, int __op, int __fd,
+ struct epoll_event *__event)
+{
+ int rv = -1;
+
+ rv = vcom_socket_epoll_ctl_internal (__epfd, __op, __fd,
+ __event, 0);
+ return rv;
}
int
@@ -2428,6 +2646,259 @@ vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events,
return -ENOSYS;
}
+int
+vcom_socket_main_init (void)
+{
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+
+ if (VCOM_DEBUG > 0)
+ printf ("vcom_socket_main_init\n");
+
+ if (!vsm->init)
+ {
+ /* TBD: define FD_MAXSIZE and use it here */
+ pool_alloc (vsm->vsockets, FD_SETSIZE);
+ vsm->sockidx_by_fd = hash_create (0, sizeof (i32));
+
+ pool_alloc (vsm->vepolls, FD_SETSIZE);
+ vsm->epollidx_by_epfd = hash_create (0, sizeof (i32));
+
+ pool_alloc (vsm->vepitems, FD_SETSIZE);
+ vsm->epitemidx_by_epfdfd = hash_create (0, sizeof (i32));
+
+ vsm->epitemidxs_by_epfd = hash_create (0, sizeof (i32 *));
+ vsm->epitemidxs_by_fd = hash_create (0, sizeof (i32 *));
+
+ vsm->init = 1;
+ }
+
+ return 0;
+}
+
+
+void
+vcom_socket_main_show (void)
+{
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+ vcom_socket_t *vsock;
+
+ vcom_epoll_t *vepoll;
+
+ vcom_epitem_t *vepitem;
+
+ i32 epfd;
+ i32 fd;
+ i32 *vepitemidxs, *vepitemidxs_var;
+
+ if (vsm->init)
+ {
+ /* from active list of vsockets show vsock */
+
+ /* *INDENT-OFF* */
+ pool_foreach (vsock, vsm->vsockets,
+ ({
+ printf(
+ "fd='%04d', sid='%08x',type='%-30s'\n",
+ vsock->fd, vsock->sid,
+ vcom_socket_type_str (vsock->type));
+ }));
+ /* *INDENT-ON* */
+
+ /* from active list of vepolls, show vepoll */
+
+ /* *INDENT-OFF* */
+ pool_foreach (vepoll, vsm->vepolls,
+ ({
+ printf(
+ "epfd='%04d', vep_idx='%08x', "
+ "type='%-30s', "
+ "flags='%d', count='%d', close='%d'\n",
+ vepoll->epfd, vepoll->vep_idx,
+ vcom_socket_epoll_type_str (vepoll->type),
+ vepoll->flags, vepoll->count, vepoll->close);
+ }));
+ /* *INDENT-ON* */
+
+ /* from active list of vepitems, show vepitem */
+
+ /* *INDENT-OFF* */
+ pool_foreach (vepitem, vsm->vepitems,
+ ({
+ printf(
+ "epfd='%04d', fd='%04d', "
+ "next_fd='%04d', prev_fd='%04d', "
+ "type='%-30s', "
+ "events='%04x', revents='%04x'\n",
+ vepitem->epfd, vepitem->fd,
+ vepitem->next_fd, vepitem->prev_fd,
+ vcom_socket_vcom_fd_type_str (vepitem->type),
+ vepitem->event.events, vepitem->revent.events);
+ }));
+
+ /* *INDENT-ON* */
+
+ /* show epitemidxs for epfd */
+ /* *INDENT-OFF* */
+ hash_foreach (epfd, vepitemidxs,
+ vsm->epitemidxs_by_epfd,
+ ({
+ printf("\n[ ");
+ vec_foreach (vepitemidxs_var,vepitemidxs)
+ {
+ printf("'%04d' ", (int)vepitemidxs_var[0]);
+ }
+ printf("]\n");
+ }));
+ /* *INDENT-ON* */
+
+ /* show epitemidxs for fd */
+ /* *INDENT-OFF* */
+ hash_foreach (fd, vepitemidxs,
+ vsm->epitemidxs_by_fd,
+ ({
+ printf("\n{ ");
+ vec_foreach (vepitemidxs_var,vepitemidxs)
+ {
+ printf("'%04d' ", (int)vepitemidxs_var[0]);
+ }
+ printf("}\n");
+ }));
+ /* *INDENT-ON* */
+
+ }
+}
+
+void
+vcom_socket_main_destroy (void)
+{
+ vcom_socket_main_t *vsm = &vcom_socket_main;
+ vcom_socket_t *vsock;
+
+ vcom_epoll_t *vepoll;
+
+ vcom_epitem_t *vepitem;
+
+ i32 epfd;
+ i32 fd;
+ i32 *vepitemidxs;
+
+
+ if (VCOM_DEBUG > 0)
+ printf ("vcom_socket_main_destroy\n");
+
+ if (vsm->init)
+ {
+
+ /*
+ * from active list of vepitems,
+ * remove all "vepitem" elements from the pool in a safe way
+ * */
+
+ /* *INDENT-OFF* */
+ pool_flush (vepitem, vsm->vepitems,
+ ({
+ if (vepitem->type == FD_TYPE_EPOLL || FD_TYPE_VCOM_SOCKET)
+ {
+ vcom_socket_epoll_ctl1 (vepitem->epfd, EPOLL_CTL_DEL,
+ vepitem->fd, NULL);
+ vepitem_init (vepitem);
+ }
+ }));
+ /* *INDENT-ON* */
+
+ pool_free (vsm->vepitems);
+ hash_free (vsm->epitemidx_by_epfdfd);
+
+ /* free vepitemidxs for each epfd */
+ /* *INDENT-OFF* */
+ hash_foreach (epfd, vepitemidxs,
+ vsm->epitemidxs_by_epfd,
+ ({
+ vec_free (vepitemidxs);
+ }));
+ /* *INDENT-ON* */
+ hash_free (vsm->epitemidxs_by_epfd);
+
+ /* free vepitemidxs for each fd */
+ /* *INDENT-OFF* */
+ hash_foreach (fd, vepitemidxs,
+ vsm->epitemidxs_by_fd,
+ ({
+ vec_free (vepitemidxs);
+ }));
+ /* *INDENT-ON* */
+ hash_free (vsm->epitemidxs_by_fd);
+
+
+ /*
+ * from active list of vsockets,
+ * close socket and vppcom session
+ * */
+
+ /* *INDENT-OFF* */
+ pool_foreach (vsock, vsm->vsockets,
+ ({
+ if (vsock->type == SOCKET_TYPE_VPPCOM_BOUND)
+ {
+ vppcom_session_close (vsock->sid);
+ vcom_socket_close_socket (vsock->fd);
+ vsocket_init (vsock);
+ }
+ }));
+ /* *INDENT-ON* */
+
+ /*
+ * return vsocket element to the pool
+ * */
+
+ /* *INDENT-OFF* */
+ pool_flush (vsock, vsm->vsockets,
+ ({
+ // vsocket_init(vsock);
+ ;
+ }));
+ /* *INDENT-ON* */
+
+ pool_free (vsm->vsockets);
+ hash_free (vsm->sockidx_by_fd);
+
+ /*
+ * from active list of vepolls,
+ * close epoll and vppcom_epoll
+ * */
+
+ /* *INDENT-OFF* */
+ pool_foreach (vepoll, vsm->vepolls,
+ ({
+ if (vepoll->type == EPOLL_TYPE_VPPCOM_BOUND)
+ {
+ vppcom_session_close (vepoll->vep_idx);
+ vcom_socket_close_epoll (vepoll->epfd); /* TBD: */
+ vepoll_init (vepoll);
+ }
+ }));
+ /* *INDENT-ON* */
+
+ /*
+ * return vepoll element to the pool
+ * */
+
+ /* *INDENT-OFF* */
+ pool_flush (vepoll, vsm->vepolls,
+ ({
+ // vepoll_init(vepoll);
+ ;
+ }));
+ /* *INDENT-ON* */
+
+ pool_free (vsm->vepolls);
+ hash_free (vsm->epollidx_by_epfd);
+
+ vsm->init = 0;
+ }
+}
+
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
index e966895..56539d1 100644
--- a/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
+++ b/vcl-ldpreload/src/libvcl-ldpreload/vcom_socket.h
@@ -127,6 +127,15 @@ typedef struct
} vcom_epitem_t;
+typedef union vcom_epitem_key
+{
+ struct {
+ i32 fd;
+ i32 epfd;
+ };
+ i64 key;
+} __EPOLL_PACKED vcom_epitem_key_t;
+
static inline char *
vcom_socket_type_str (vcom_socket_type_t t)
{
@@ -243,6 +252,15 @@ vepitem_init (vcom_epitem_t * vepitem)
}
static inline void
+vepitemkey_init (vcom_epitem_key_t * epfdfd)
+{
+ memset (epfdfd, 0, sizeof (*epfdfd));
+
+ epfdfd->epfd = INVALID_EPFD;
+ epfdfd->fd = INVALID_FD;
+}
+
+static inline void
vsocket_set (vcom_socket_t * vsock,
i32 fd, i32 sid, vcom_socket_type_t type)
{
@@ -287,6 +305,14 @@ vepitem_set (vcom_epitem_t * vepitem,
/* vcom epitem attributes set here */
}
+static inline void
+vepitemkey_set (vcom_epitem_key_t * epfdfd,
+ i32 epfd, i32 fd)
+{
+ epfdfd->epfd = epfd;
+ epfdfd->fd = fd;
+}
+
static inline int
vsocket_is_vppcom_bound (vcom_socket_t * vsock)
{