[SCM] Socket Wrapper Repository - branch master updated
Andreas Schneider
asn at samba.org
Thu Oct 20 08:52:47 UTC 2016
The branch, master has been updated
via b61f5df tests: Add a test for max_sockets
via f9fbda9 swrap: Introduce a freelist in the socket_info array
via 69aee42 swrap: Replace linked list of socket_info with preallocated array of structures
via c3e5f78 swrap: Optimization in (commented out) check_addr_port_in_use()
via 1e7528c swrap: Improve vfcntl to add the dup'd fd after the source fd
via d3d09e6 swrap: Improve dup2 to add the dup'd fd after the source fd
via ebe5f15 swrap: Improve dup to add the dup'd fd after the source fd
via 97d2372 swrap: Add SWRAP_DLIST_ADD_AFTER macro
via 087f9ae swrap: Untangle socket_info_fd from socket_info structure.
from f43d383 swrap: remove ununsed members from struct swrap.
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit b61f5df9f4a7c57cb9ad313a20d7dbe316f42072
Author: Michael Adam <obnox at samba.org>
Date: Thu Sep 22 02:13:20 2016 +0200
tests: Add a test for max_sockets
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit f9fbda9ef0f7b279e8e618a3888ab2e50884da1b
Author: Michael Adam <obnox at samba.org>
Date: Wed Sep 14 13:24:47 2016 +0200
swrap: Introduce a freelist in the socket_info array
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 69aee42f1d4a0e563b9e85e899dc8b4f18303af0
Author: Anoop C S <anoopcs at redhat.com>
Date: Thu Aug 25 11:41:12 2016 +0530
swrap: Replace linked list of socket_info with preallocated array of structures
Pair-Programmed-With: Michael Adam <obnox at samba.org>
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit c3e5f78016f4319fb22126163d0ddbcac0bdeed5
Author: Michael Adam <obnox at samba.org>
Date: Tue Aug 16 13:38:50 2016 +0200
swrap: Optimization in (commented out) check_addr_port_in_use()
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 1e7528c2b1a027538b54bd3576eba1206265ae8c
Author: Michael Adam <obnox at samba.org>
Date: Tue Aug 16 11:04:43 2016 +0200
swrap: Improve vfcntl to add the dup'd fd after the source fd
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit d3d09e631aa7f9b5ffe88a786ad21e7e51aee909
Author: Michael Adam <obnox at samba.org>
Date: Tue Aug 16 11:04:12 2016 +0200
swrap: Improve dup2 to add the dup'd fd after the source fd
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit ebe5f15854866c225febe73c952356873b958305
Author: Michael Adam <obnox at samba.org>
Date: Tue Aug 16 11:03:27 2016 +0200
swrap: Improve dup to add the dup'd fd after the source fd
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 97d23728cfc392fe5f2c33831f4c85aa31d083fc
Author: Michael Adam <obnox at samba.org>
Date: Tue Aug 16 11:00:50 2016 +0200
swrap: Add SWRAP_DLIST_ADD_AFTER macro
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Michael Adam <obnox at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 087f9aea821cceffd3ced15b576106cace8a2c9d
Author: Anoop C S <anoopcs at redhat.com>
Date: Wed Aug 10 16:32:19 2016 +0530
swrap: Untangle socket_info_fd from socket_info structure.
This reverses the dependency of socket_info on socket_info_fd:
Instead of maintaining the list of socket_info structures,
and keeping a list of referencing fds (created by dup),
we now maintain the list of fds with pointers to the
corresponding socket_info structures, and count the
references in the socket_info.
This makes the treatment of the lists more obvious,
especially seen in the removing part.
This change is a preparatory step for implementing
fd-passing in socket-wrapper.
Pair-programmed-with: Michael Adam <obnox at samba.org>
Signed-off-by: Anoop C S <anoopcs at redhat.com>
Signed-off-by: Michael Adam <obnox at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
src/socket_wrapper.c | 330 +++++++++++++++++++++++++++++++++++------------
tests/CMakeLists.txt | 3 +-
tests/test_max_sockets.c | 110 ++++++++++++++++
3 files changed, 358 insertions(+), 85 deletions(-)
create mode 100644 tests/test_max_sockets.c
Changeset truncated at 500 lines:
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 6c4ae3b..84dfc07 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -184,6 +184,20 @@ enum swrap_dbglvl_e {
(item)->next = NULL; \
} while (0)
+#define SWRAP_DLIST_ADD_AFTER(list, item, el) \
+do { \
+ if ((list) != NULL || (el) != NULL) { \
+ SWRAP_DLIST_ADD(list, item); \
+ } else { \
+ (item)->prev = (el); \
+ (item)->next = (el)->next; \
+ (el)->next = (item); \
+ if ((item)->next != NULL) { \
+ (item)->next->prev = (item); \
+ } \
+ } \
+} while (0)
+
#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
#define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL)
#else
@@ -212,6 +226,14 @@ enum swrap_dbglvl_e {
#define SOCKET_MAX_SOCKETS 1024
+
+/*
+ * Maximum number of socket_info structures that can
+ * be used. Can be overriden by the environment variable
+ * SOCKET_WRAPPER_MAX_SOCKETS.
+ */
+#define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535
+
/* This limit is to avoid broadcast sendto() needing to stat too many
* files. It may be raised (with a performance cost) to up to 254
* without changing the format above */
@@ -233,11 +255,21 @@ struct swrap_address {
struct socket_info_fd {
struct socket_info_fd *prev, *next;
int fd;
+
+ /*
+ * Points to corresponding index in array of
+ * socket_info structures
+ */
+ int si_index;
};
+int first_free;
+
struct socket_info
{
- struct socket_info_fd *fds;
+ unsigned int refcount;
+
+ int next_free;
int family;
int type;
@@ -261,15 +293,17 @@ struct socket_info
unsigned long pck_snd;
unsigned long pck_rcv;
} io;
-
- struct socket_info *prev, *next;
};
+static struct socket_info *sockets;
+static size_t max_sockets = 0;
+
/*
- * File descriptors are shared between threads so we should share socket
- * information too.
+ * While socket file descriptors are passed among different processes, the
+ * numerical value gets changed. So its better to store it locally to each
+ * process rather than including it within socket_info which will be shared.
*/
-struct socket_info *sockets;
+static struct socket_info_fd *socket_fds;
/* Function prototypes */
@@ -970,11 +1004,73 @@ done:
return max_mtu;
}
+static size_t socket_wrapper_max_sockets(void)
+{
+ const char *s;
+ unsigned long tmp;
+ char *endp;
+
+ if (max_sockets != 0) {
+ return max_sockets;
+ }
+
+ max_sockets = SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT;
+
+ s = getenv("SOCKET_WRAPPER_MAX_SOCKETS");
+ if (s == NULL || s[0] == '\0') {
+ goto done;
+ }
+
+ tmp = strtoul(s, &endp, 10);
+ if (s == endp) {
+ goto done;
+ }
+
+ max_sockets = tmp;
+
+done:
+ return max_sockets;
+}
+
+static void socket_wrapper_init_sockets(void)
+{
+ size_t i;
+
+ if (sockets != NULL) {
+ return;
+ }
+
+ max_sockets = socket_wrapper_max_sockets();
+
+ sockets = (struct socket_info *)calloc(max_sockets,
+ sizeof(struct socket_info));
+
+ if (sockets == NULL) {
+ SWRAP_LOG(SWRAP_LOG_ERROR,
+ "Failed to allocate sockets array.\n");
+ exit(-1);
+ }
+
+ first_free = 0;
+
+ for (i = 0; i < max_sockets; i++) {
+ sockets[i].next_free = i+1;
+ }
+
+ sockets[max_sockets-1].next_free = -1;
+}
+
bool socket_wrapper_enabled(void)
{
const char *s = socket_wrapper_dir();
- return s != NULL ? true : false;
+ if (s == NULL) {
+ return false;
+ }
+
+ socket_wrapper_init_sockets();
+
+ return true;
}
static unsigned int socket_wrapper_default_iface(void)
@@ -992,6 +1088,25 @@ static unsigned int socket_wrapper_default_iface(void)
return 1;/* 127.0.0.1 */
}
+/*
+ * Return the first free entry (if any) and make
+ * it re-usable again (by nulling it out)
+ */
+static int socket_wrapper_first_free_index(void)
+{
+ int next_free;
+
+ if (first_free == -1) {
+ return -1;
+ }
+
+ next_free = sockets[first_free].next_free;
+ ZERO_STRUCT(sockets[first_free]);
+ sockets[first_free].next_free = next_free;
+
+ return first_free;
+}
+
static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, socklen_t *len)
{
unsigned int iface;
@@ -1359,26 +1474,46 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
return 0;
}
-static struct socket_info *find_socket_info(int fd)
+static struct socket_info_fd *find_socket_info_fd(int fd)
{
- struct socket_info *i;
+ struct socket_info_fd *f;
- for (i = sockets; i; i = i->next) {
- struct socket_info_fd *f;
- for (f = i->fds; f; f = f->next) {
- if (f->fd == fd) {
- return i;
- }
+ for (f = socket_fds; f; f = f->next) {
+ if (f->fd == fd) {
+ return f;
}
}
return NULL;
}
+static int find_socket_info_index(int fd)
+{
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+
+ if (fi == NULL) {
+ return -1;
+ }
+
+ return fi->si_index;
+}
+
+static struct socket_info *find_socket_info(int fd)
+{
+ int idx = find_socket_info_index(fd);
+
+ if (idx == -1) {
+ return NULL;
+ }
+
+ return &sockets[idx];
+}
+
#if 0 /* FIXME */
static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
{
- struct socket_info *s;
+ struct socket_info_fd *f;
+ const struct socket_info *last_s = NULL;
/* first catch invalid input */
switch (sa->sa_family) {
@@ -1399,7 +1534,14 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
break;
}
- for (s = sockets; s != NULL; s = s->next) {
+ for (f = socket_fds; f; f = f->next) {
+ struct socket_info *s = &sockets[f->si_index];
+
+ if (s == last_s) {
+ continue;
+ }
+ last_s = s;
+
if (s->myname == NULL) {
continue;
}
@@ -1461,29 +1603,31 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
static void swrap_remove_stale(int fd)
{
- struct socket_info *si = find_socket_info(fd);
- struct socket_info_fd *fi;
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+ struct socket_info *si;
- if (si == NULL) {
+ if (fi == NULL) {
return;
}
- for (fi = si->fds; fi; fi = fi->next) {
- if (fi->fd == fd) {
- SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
- SWRAP_DLIST_REMOVE(si->fds, fi);
- free(fi);
- break;
- }
+ si = &sockets[fi->si_index];
+
+ SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
+ SWRAP_DLIST_REMOVE(socket_fds, fi);
+ free(fi);
+
+ si->refcount--;
+
+ if (si->refcount > 0) {
+ return;
}
- if (si->fds == NULL) {
- SWRAP_DLIST_REMOVE(sockets, si);
- if (si->un_addr.sun_path[0] != '\0') {
- unlink(si->un_addr.sun_path);
- }
- free(si);
+ if (si->un_addr.sun_path[0] != '\0') {
+ unlink(si->un_addr.sun_path);
}
+
+ si->next_free = first_free;
+ first_free = fi->si_index;
}
static int sockaddr_convert_to_un(struct socket_info *si,
@@ -2377,6 +2521,7 @@ static int swrap_socket(int family, int type, int protocol)
struct socket_info *si;
struct socket_info_fd *fi;
int fd;
+ int idx;
int real_type = type;
/*
@@ -2455,12 +2600,14 @@ static int swrap_socket(int family, int type, int protocol)
/* Check if we have a stale fd and remove it */
swrap_remove_stale(fd);
- si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
- if (si == NULL) {
+ idx = socket_wrapper_first_free_index();
+ if (idx == -1) {
errno = ENOMEM;
return -1;
}
+ si = &sockets[idx];
+
si->family = family;
/* however, the rest of the socket_wrapper code expects just
@@ -2492,22 +2639,24 @@ static int swrap_socket(int family, int type, int protocol)
break;
}
default:
- free(si);
errno = EINVAL;
return -1;
}
fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
if (fi == NULL) {
- free(si);
errno = ENOMEM;
return -1;
}
+ si->refcount = 1;
+ first_free = si->next_free;
+ si->next_free = 0;
+
fi->fd = fd;
+ fi->si_index = idx;
- SWRAP_DLIST_ADD(si->fds, fi);
- SWRAP_DLIST_ADD(sockets, si);
+ SWRAP_DLIST_ADD(socket_fds, fi);
SWRAP_LOG(SWRAP_LOG_TRACE,
"Created %s socket for protocol %s",
@@ -2601,6 +2750,7 @@ static int swrap_accept(int s,
struct socket_info *parent_si, *child_si;
struct socket_info_fd *child_fi;
int fd;
+ int idx;
struct swrap_address un_addr = {
.sa_socklen = sizeof(struct sockaddr_un),
};
@@ -2660,16 +2810,16 @@ static int swrap_accept(int s,
return ret;
}
- child_si = (struct socket_info *)calloc(1, sizeof(struct socket_info));
- if (child_si == NULL) {
- close(fd);
+ idx = socket_wrapper_first_free_index();
+ if (idx == -1) {
errno = ENOMEM;
return -1;
}
+ child_si = &sockets[idx];
+
child_fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
if (child_fi == NULL) {
- free(child_si);
close(fd);
errno = ENOMEM;
return -1;
@@ -2702,7 +2852,6 @@ static int swrap_accept(int s,
&un_my_addr.sa_socklen);
if (ret == -1) {
free(child_fi);
- free(child_si);
close(fd);
return ret;
}
@@ -2715,7 +2864,6 @@ static int swrap_accept(int s,
&in_my_addr.sa_socklen);
if (ret == -1) {
free(child_fi);
- free(child_si);
close(fd);
return ret;
}
@@ -2729,8 +2877,13 @@ static int swrap_accept(int s,
};
memcpy(&child_si->myname.sa.ss, &in_my_addr.sa.ss, in_my_addr.sa_socklen);
- SWRAP_DLIST_ADD(child_si->fds, child_fi);
- SWRAP_DLIST_ADD(sockets, child_si);
+ child_si->refcount = 1;
+ first_free = child_si->next_free;
+ child_si->next_free = 0;
+
+ child_fi->si_index = idx;
+
+ SWRAP_DLIST_ADD(socket_fds, child_fi);
if (addr != NULL) {
swrap_pcap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
@@ -5078,29 +5231,26 @@ ssize_t writev(int s, const struct iovec *vector, int count)
static int swrap_close(int fd)
{
- struct socket_info *si = find_socket_info(fd);
- struct socket_info_fd *fi;
+ struct socket_info_fd *fi = find_socket_info_fd(fd);
+ struct socket_info *si = NULL;
int ret;
- if (!si) {
+ if (fi == NULL) {
return libc_close(fd);
}
- for (fi = si->fds; fi; fi = fi->next) {
- if (fi->fd == fd) {
- SWRAP_DLIST_REMOVE(si->fds, fi);
- free(fi);
- break;
- }
- }
+ si = &sockets[fi->si_index];
+
+ SWRAP_DLIST_REMOVE(socket_fds, fi);
+ free(fi);
+
+ si->refcount--;
- if (si->fds) {
+ if (si->refcount > 0) {
/* there are still references left */
return libc_close(fd);
}
- SWRAP_DLIST_REMOVE(sockets, si);
-
if (si->myname.sa_socklen > 0 && si->peername.sa_socklen > 0) {
swrap_pcap_dump_packet(si, NULL, SWRAP_CLOSE_SEND, NULL, 0);
}
@@ -5115,7 +5265,9 @@ static int swrap_close(int fd)
if (si->un_addr.sun_path[0] != '\0') {
unlink(si->un_addr.sun_path);
}
- free(si);
+
+ si->next_free = first_free;
+ first_free = fi->si_index;
return ret;
}
@@ -5132,14 +5284,15 @@ int close(int fd)
static int swrap_dup(int fd)
{
struct socket_info *si;
- struct socket_info_fd *fi;
-
- si = find_socket_info(fd);
+ struct socket_info_fd *src_fi, *fi;
- if (!si) {
+ src_fi = find_socket_info_fd(fd);
+ if (src_fi == NULL) {
return libc_dup(fd);
}
+ si = &sockets[src_fi->si_index];
+
fi = (struct socket_info_fd *)calloc(1, sizeof(struct socket_info_fd));
if (fi == NULL) {
errno = ENOMEM;
@@ -5154,10 +5307,13 @@ static int swrap_dup(int fd)
return -1;
}
+ si->refcount++;
+ fi->si_index = src_fi->si_index;
+
--
Socket Wrapper Repository
More information about the samba-cvs
mailing list