The branch, master has been updated via e3b6402b8b6 third_party: Update socket_wrapper to version 1.2.1 via ce6b5919b71 s4:torture: Use 65520 for maxopenfiles from a4a85aca324 s3: VFS: Remove logically dead code. Coverity CID: 1419117
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e3b6402b8b60f5af22a1097847aa7389f147e580 Author: Andreas Schneider <a...@samba.org> Date: Wed May 2 15:57:38 2018 +0200 third_party: Update socket_wrapper to version 1.2.1 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Nov 15 04:50:31 CET 2018 on sn-devel-144 commit ce6b5919b71e0e5ee8c32696da3cf5243fd810eb Author: Andreas Schneider <a...@samba.org> Date: Mon Nov 12 11:51:17 2018 +0100 s4:torture: Use 65520 for maxopenfiles The socket_wrapper limit is 65535 open sockets. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: buildtools/wafsamba/samba_third_party.py | 2 +- source4/torture/smb2/maxfid.c | 10 +- third_party/socket_wrapper/socket_wrapper.c | 988 +++++++++++++++++++--------- third_party/socket_wrapper/wscript | 2 +- 4 files changed, 686 insertions(+), 316 deletions(-) Changeset truncated at 500 lines: diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py index be73dbe4218..e0dd3e1b9a0 100644 --- a/buildtools/wafsamba/samba_third_party.py +++ b/buildtools/wafsamba/samba_third_party.py @@ -42,7 +42,7 @@ Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA @conf def CHECK_SOCKET_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.1.9') + return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.1') Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER @conf diff --git a/source4/torture/smb2/maxfid.c b/source4/torture/smb2/maxfid.c index dbe3fac9d39..853b13de6de 100644 --- a/source4/torture/smb2/maxfid.c +++ b/source4/torture/smb2/maxfid.c @@ -36,7 +36,15 @@ bool torture_smb2_maxfid(struct torture_context *tctx) struct smb2_handle *handles, dir_handle = { }; size_t max_handles; - max_handles = torture_setting_int(tctx, "maxopenfiles", 0x11000); + /* + * We limited this to 65520 as socket_wrapper has a limit of + * 65535 (0xfff0) open sockets. + * + * It could be increased by setting the following env variable: + * + * SOCKET_WRAPPER_MAX_SOCKETS=100000 + */ + max_handles = torture_setting_int(tctx, "maxopenfiles", 65520); if (!torture_smb2_connection(tctx, &tree)) { return false; diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c index 539d27dbc9d..df70df5008d 100644 --- a/third_party/socket_wrapper/socket_wrapper.c +++ b/third_party/socket_wrapper/socket_wrapper.c @@ -1,8 +1,11 @@ /* - * Copyright (c) 2005-2008 Jelmer Vernooij <jel...@samba.org> - * Copyright (C) 2006-2014 Stefan Metzmacher <me...@samba.org> - * Copyright (C) 2013-2014 Andreas Schneider <a...@samba.org> + * BSD 3-Clause License * + * Copyright (c) 2005-2008, Jelmer Vernooij <jel...@samba.org> + * Copyright (c) 2006-2018, Stefan Metzmacher <me...@samba.org> + * Copyright (c) 2013-2018, Andreas Schneider <a...@samba.org> + * Copyright (c) 2014-2017, Michael Adam <ob...@samba.org> + * Copyright (c) 2016-2018, Anoop C S <anoo...@redhat.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +34,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * */ /* @@ -111,7 +113,7 @@ enum swrap_dbglvl_e { # ifdef HAVE_FALLTHROUGH_ATTRIBUTE # define FALL_THROUGH __attribute__ ((fallthrough)) # else /* HAVE_FALLTHROUGH_ATTRIBUTE */ -# define FALL_THROUGH +# define FALL_THROUGH ((void)0) # endif /* HAVE_FALLTHROUGH_ATTRIBUTE */ #endif /* FALL_THROUGH */ @@ -142,6 +144,10 @@ enum swrap_dbglvl_e { } while(0) #endif +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) +#endif + #ifndef discard_const #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) #endif @@ -169,67 +175,25 @@ enum swrap_dbglvl_e { # endif #endif -/* Macros for accessing mutexes */ -# define SWRAP_LOCK(m) do { \ - pthread_mutex_lock(&(m ## _mutex)); \ -} while(0) - -# define SWRAP_UNLOCK(m) do { \ - pthread_mutex_unlock(&(m ## _mutex)); \ -} while(0) - /* Add new global locks here please */ # define SWRAP_LOCK_ALL \ - SWRAP_LOCK(libc_symbol_binding); \ + swrap_mutex_lock(&libc_symbol_binding_mutex); \ # define SWRAP_UNLOCK_ALL \ - SWRAP_UNLOCK(libc_symbol_binding); \ - - -#define SWRAP_DLIST_ADD(list,item) do { \ - if (!(list)) { \ - (item)->prev = NULL; \ - (item)->next = NULL; \ - (list) = (item); \ - } else { \ - (item)->prev = NULL; \ - (item)->next = (list); \ - (list)->prev = (item); \ - (list) = (item); \ - } \ -} while (0) - -#define SWRAP_DLIST_REMOVE(list,item) do { \ - if ((list) == (item)) { \ - (list) = (item)->next; \ - if (list) { \ - (list)->prev = NULL; \ - } \ - } else { \ - if ((item)->prev) { \ - (item)->prev->next = (item)->next; \ - } \ - if ((item)->next) { \ - (item)->next->prev = (item)->prev; \ - } \ - } \ - (item)->prev = NULL; \ - (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) + swrap_mutex_unlock(&libc_symbol_binding_mutex); \ + +#define SOCKET_INFO_CONTAINER(si) \ + (struct socket_info_container *)(si) + +#define SWRAP_LOCK_SI(si) do { \ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \ + swrap_mutex_lock(&sic->meta.mutex); \ +} while(0) + +#define SWRAP_UNLOCK_SI(si) do { \ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); \ + swrap_mutex_unlock(&sic->meta.mutex); \ +} while(0) #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) #define swrapGetTimeOfDay(tval) gettimeofday(tval,NULL) @@ -259,7 +223,6 @@ do { \ #define SOCKET_MAX_SOCKETS 1024 - /* * Maximum number of socket_info structures that can * be used. Can be overriden by the environment variable @@ -267,7 +230,7 @@ do { \ */ #define SOCKET_WRAPPER_MAX_SOCKETS_DEFAULT 65535 -#define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 256000 +#define SOCKET_WRAPPER_MAX_SOCKETS_LIMIT 262140 /* 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 @@ -287,25 +250,10 @@ struct swrap_address { } sa; }; -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 { - unsigned int refcount; - - int next_free; - int family; int type; int protocol; @@ -330,19 +278,54 @@ struct socket_info } io; }; -static struct socket_info *sockets; -static size_t max_sockets = 0; +struct socket_info_meta +{ + unsigned int refcount; + int next_free; + pthread_mutex_t mutex; +}; + +struct socket_info_container +{ + struct socket_info info; + struct socket_info_meta meta; +}; + +static struct socket_info_container *sockets; + +static size_t socket_info_max = 0; /* - * 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. + * Allocate the socket array always on the limit value. We want it to be + * at least bigger than the default so if we reach the limit we can + * still deal with duplicate fds pointing to the same socket_info. */ -static struct socket_info_fd *socket_fds; +static size_t socket_fds_max = SOCKET_WRAPPER_MAX_SOCKETS_LIMIT; + +/* Hash table to map fds to corresponding socket_info index */ +static int *socket_fds_idx; -/* The mutex for accessing the global libc.symbols */ +/* Mutex to synchronize access to global libc.symbols */ static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; +/* Mutex for syncronizing port selection during swrap_auto_bind() */ +static pthread_mutex_t autobind_start_mutex; + +/* Mutex to guard the initialization of array of socket_info structures */ +static pthread_mutex_t sockets_mutex; + +/* Mutex to guard the socket reset in swrap_close() and swrap_remove_stale() */ +static pthread_mutex_t socket_reset_mutex; + +/* Mutex to synchronize access to first free index in socket_info array */ +static pthread_mutex_t first_free_mutex; + +/* Mutex to synchronize access to packet capture dump file */ +static pthread_mutex_t pcap_dump_mutex; + +/* Mutex for synchronizing mtu value fetch*/ +static pthread_mutex_t mtu_update_mutex; + /* Function prototypes */ bool socket_wrapper_enabled(void); @@ -350,6 +333,19 @@ bool socket_wrapper_enabled(void); void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE; void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE; +#ifndef HAVE_GETPROGNAME +static const char *getprogname(void) +{ +#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) + return program_invocation_short_name; +#elif defined(HAVE_GETEXECNAME) + return getexecname(); +#else + return NULL; +#endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ +} +#endif /* HAVE_GETPROGNAME */ + static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *func, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); # define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__) @@ -362,6 +358,7 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl, const char *d; unsigned int lvl = 0; const char *prefix = "SWRAP"; + const char *progname = getprogname(); d = getenv("SOCKET_WRAPPER_DEBUGLEVEL"); if (d != NULL) { @@ -391,9 +388,17 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl, break; } + if (progname == NULL) { + progname = "<unknown>"; + } + fprintf(stderr, - "%s(%d) - %s: %s\n", - prefix, (int)getpid(), func, buffer); + "%s[%s (%u)] - %s: %s\n", + prefix, + progname, + (unsigned int)getpid(), + func, + buffer); } /********************************************************* @@ -582,7 +587,15 @@ static void *swrap_load_lib_handle(enum swrap_lib lib) int i; #ifdef RTLD_DEEPBIND - flags |= RTLD_DEEPBIND; + const char *env = getenv("LD_PRELOAD"); + + /* Don't do a deepbind if we run with libasan */ + if (env != NULL && strlen(env) < 1024) { + const char *p = strstr(env, "libasan.so"); + if (p == NULL) { + flags |= RTLD_DEEPBIND; + } + } #endif switch (lib) { @@ -670,34 +683,62 @@ static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name) return func; } +static void swrap_mutex_lock(pthread_mutex_t *mutex) +{ + int ret; + + ret = pthread_mutex_lock(mutex); + if (ret != 0) { + SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't lock pthread mutex - %s", + strerror(ret)); + } +} + +static void swrap_mutex_unlock(pthread_mutex_t *mutex) +{ + int ret; + + ret = pthread_mutex_unlock(mutex); + if (ret != 0) { + SWRAP_LOG(SWRAP_LOG_ERROR, "Couldn't unlock pthread mutex - %s", + strerror(ret)); + } +} + +/* + * These macros have a thread race condition on purpose! + * + * This is an optimization to avoid locking each time we check if the symbol is + * bound. + */ #define swrap_bind_symbol_libc(sym_name) \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - SWRAP_LOCK(libc_symbol_binding); \ + swrap_mutex_lock(&libc_symbol_binding_mutex); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ swrap.libc.symbols._libc_##sym_name.obj = \ _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \ } \ - SWRAP_UNLOCK(libc_symbol_binding); \ + swrap_mutex_unlock(&libc_symbol_binding_mutex); \ } #define swrap_bind_symbol_libsocket(sym_name) \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - SWRAP_LOCK(libc_symbol_binding); \ + swrap_mutex_lock(&libc_symbol_binding_mutex); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ swrap.libc.symbols._libc_##sym_name.obj = \ _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \ } \ - SWRAP_UNLOCK(libc_symbol_binding); \ + swrap_mutex_unlock(&libc_symbol_binding_mutex); \ } #define swrap_bind_symbol_libnsl(sym_name) \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ - SWRAP_LOCK(libc_symbol_binding); \ + swrap_mutex_lock(&libc_symbol_binding_mutex); \ if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \ swrap.libc.symbols._libc_##sym_name.obj = \ _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \ } \ - SWRAP_UNLOCK(libc_symbol_binding); \ + swrap_mutex_unlock(&libc_symbol_binding_mutex); \ } /**************************************************************************** @@ -1194,6 +1235,45 @@ static size_t socket_length(int family) return 0; } +static struct socket_info *swrap_get_socket_info(int si_index) +{ + return (struct socket_info *)(&(sockets[si_index].info)); +} + +static int swrap_get_refcount(struct socket_info *si) +{ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); + return sic->meta.refcount; +} + +static void swrap_inc_refcount(struct socket_info *si) +{ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); + + sic->meta.refcount += 1; +} + +static void swrap_dec_refcount(struct socket_info *si) +{ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); + + sic->meta.refcount -= 1; +} + +static int swrap_get_next_free(struct socket_info *si) +{ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); + + return sic->meta.next_free; +} + +static void swrap_set_next_free(struct socket_info *si, int next_free) +{ + struct socket_info_container *sic = SOCKET_INFO_CONTAINER(si); + + sic->meta.next_free = next_free; +} + static const char *socket_wrapper_dir(void) { const char *s = getenv("SOCKET_WRAPPER_DIR"); @@ -1216,8 +1296,10 @@ static unsigned int socket_wrapper_mtu(void) const char *s; char *endp; + swrap_mutex_lock(&mtu_update_mutex); + if (max_mtu != 0) { - return max_mtu; + goto done; } max_mtu = SOCKET_WRAPPER_MTU_DEFAULT; @@ -1238,20 +1320,44 @@ static unsigned int socket_wrapper_mtu(void) max_mtu = tmp; done: + swrap_mutex_unlock(&mtu_update_mutex); return max_mtu; } +static int socket_wrapper_init_mutex(pthread_mutex_t *m) +{ + pthread_mutexattr_t ma; + int ret; + + ret = pthread_mutexattr_init(&ma); + if (ret != 0) { + return ret; + } + + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) { + goto done; + } + + ret = pthread_mutex_init(m, &ma); + +done: + pthread_mutexattr_destroy(&ma); + + return ret; +} + static size_t socket_wrapper_max_sockets(void) { const char *s; - unsigned long tmp; + size_t tmp; char *endp; - if (max_sockets != 0) { -- Samba Shared Repository