diff --git a/autofs-5.0.4-fix-ldap-detection.patch b/autofs-5.0.4-fix-ldap-detection.patch new file mode 100644 index 0000000..b5b97ac --- /dev/null +++ b/autofs-5.0.4-fix-ldap-detection.patch @@ -0,0 +1,115 @@ +autofs-5.0.4 - fix ldap detection + +From: Guillaume Rousse + +The test for LDAP library wrongly use LDFLAGS to add -lldap to the gcc +call. However, when strict linker ordering is in effect, it doesn't work +correctly. As described in autoconf documentation, additional libs +should be added through LIBS variable instead. +--- + + aclocal.m4 | 20 ++++++++++---------- + configure | 20 ++++++++++---------- + 2 files changed, 20 insertions(+), 20 deletions(-) + + +diff --git a/aclocal.m4 b/aclocal.m4 +index bb0ab21..ab11112 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -246,9 +246,9 @@ dnl -------------------------------------------------------------------------- + AC_DEFUN([AF_CHECK_FUNC_LDAP_CREATE_PAGE_CONTROL], + [AC_MSG_CHECKING(for ldap_create_page_control in -lldap) + +-# save current ldflags +-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_create_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + AC_TRY_LINK( + [ #include ], +@@ -267,8 +267,8 @@ if test "$af_have_ldap_create_page_control" = "yes"; then + [Define to 1 if you have the `ldap_create_page_control' function.]) + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_create_page_control_save_libs" + ]) + + dnl -------------------------------------------------------------------------- +@@ -279,9 +279,9 @@ dnl -------------------------------------------------------------------------- + AC_DEFUN([AF_CHECK_FUNC_LDAP_PARSE_PAGE_CONTROL], + [AC_MSG_CHECKING(for ldap_parse_page_control in -lldap) + +-# save current ldflags +-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_parse_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + AC_TRY_LINK( + [ #include ], +@@ -300,7 +300,7 @@ if test "$af_have_ldap_create_page_control" = "yes"; then + [Define to 1 if you have the `ldap_parse_page_control' function.]) + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_parse_page_control_save_libs" + ]) + +diff --git a/configure b/configure +index ed17660..afa692c 100755 +--- a/configure ++++ b/configure +@@ -4608,9 +4608,9 @@ _ACEOF + { echo "$as_me:$LINENO: checking for ldap_create_page_control in -lldap" >&5 + echo $ECHO_N "checking for ldap_create_page_control in -lldap... $ECHO_C" >&6; } + +-# save current ldflags +-af_check_ldap_create_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_create_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4672,15 +4672,15 @@ _ACEOF + + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_create_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_create_page_control_save_libs" + + { echo "$as_me:$LINENO: checking for ldap_parse_page_control in -lldap" >&5 + echo $ECHO_N "checking for ldap_parse_page_control in -lldap... $ECHO_C" >&6; } + +-# save current ldflags +-af_check_ldap_parse_page_control_save_ldflags="$LDFLAGS" +-LDFLAGS="$LDFLAGS -lldap" ++# save current libs ++af_check_ldap_parse_page_control_save_libs="$LIBS" ++LIBS="$LIBS -lldap" + + cat >conftest.$ac_ext <<_ACEOF + /* confdefs.h. */ +@@ -4742,8 +4742,8 @@ _ACEOF + + fi + +-# restore ldflags +-LDFLAGS="$af_check_ldap_parse_page_control_save_ldflags" ++# restore libs ++LIBS="$af_check_ldap_parse_page_control_save_libs" + + fi + diff --git a/autofs-5.0.4-fix-negative-cache-non-existent-key.patch b/autofs-5.0.4-fix-negative-cache-non-existent-key.patch new file mode 100644 index 0000000..a17ffab --- /dev/null +++ b/autofs-5.0.4-fix-negative-cache-non-existent-key.patch @@ -0,0 +1,331 @@ +autofs-5.0.4 - fix negative cache non-existent key + +From: Ian Kent + +autofs was not recording map entries that don't exist for negative +caching. This was causing unwanted network map lookups. +--- + + CHANGELOG | 1 + + daemon/lookup.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- + modules/lookup_file.c | 20 ++++++++++++------- + modules/lookup_hosts.c | 21 ++++++++++++++++---- + modules/lookup_ldap.c | 20 ++++++++++++------- + modules/lookup_nisplus.c | 19 ++++++++++++------ + modules/lookup_program.c | 35 ++++++++++++++++++++++++++-------- + modules/lookup_yp.c | 19 ++++++++++++------ + 8 files changed, 143 insertions(+), 40 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 88ca579..bd35b00 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + ----------------------- + - fix dumb libxml2 check + - fix nested submount expire deadlock. ++- fix negative caching for non-existent map keys. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 803df4f..0cf6e3f 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -804,6 +804,45 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this, + return result; + } + ++static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name) ++{ ++ struct master_mapent *entry = ap->entry; ++ struct map_source *map; ++ struct mapent *me; ++ ++ /* Have we recorded the lookup fail for negative caching? */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) ++ /* ++ * Already exists in the cache, the mount fail updates ++ * will update negative timeout status. ++ */ ++ cache_unlock(me->mc); ++ else { ++ /* Notify only once after fail */ ++ error(ap->logopt, "key \"%s\" not found in map.", name); ++ ++ /* Doesn't exist in any source, just add it somewhere */ ++ if (source) ++ map = source; ++ else ++ map = entry->maps; ++ if (map) { ++ time_t now = time(NULL); ++ int rv = CHE_FAIL; ++ ++ cache_writelock(map->mc); ++ rv = cache_update(map->mc, map, name, NULL, now); ++ if (rv != CHE_FAIL) { ++ me = cache_lookup_distinct(map->mc, name); ++ me->status = now + ap->negative_timeout; ++ } ++ cache_unlock(map->mc); ++ } ++ } ++ return; ++} ++ + int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len) + { + struct master_mapent *entry = ap->entry; +@@ -907,8 +946,13 @@ int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const c + send_map_update_request(ap); + pthread_cleanup_pop(1); + +- if (result == NSS_STATUS_NOTFOUND) +- error(ap->logopt, "key \"%s\" not found in map.", name); ++ /* ++ * The last source lookup will return NSS_STATUS_NOTFOUND if the ++ * map exits and the key has not been found but the map may also ++ * not exist in which case the key is also not found. ++ */ ++ if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL) ++ update_negative_cache(ap, source, name); + + return !result; + } +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 807ceab..9e34b72 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1069,14 +1069,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- /* Check if we recorded a mount fail for this key */ +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_UNAVAIL; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index bf24d7f..f8d4269 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -136,12 +136,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + mc = source->mc; + ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ if (!me->mapent) { ++ cache_delete(me->mc, name); ++ me = NULL; ++ } ++ ++ cache_unlock(me->mc); ++ } ++ + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; +- } else if (!me) { ++ if (!me) { + cache_unlock(mc); + /* + * We haven't read the list of hosts into the +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 31c2c13..42c3235 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2709,14 +2709,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- /* Check if we recorded a mount fail for this key */ +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 755556d..f15465f 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -493,13 +493,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index daf874d..bf32d3b 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -131,13 +131,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + mc = source->mc; + ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, name, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, name); ++ ++ cache_unlock(me->mc); ++ } ++ + /* Catch installed direct offset triggers */ +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; +- } else if (!me) { ++ if (!me) { + cache_unlock(mc); + /* + * If there's a '/' in the name and the offset is not in +@@ -149,8 +161,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return NSS_STATUS_NOTFOUND; + } + } else { +- cache_unlock(mc); +- + /* Otherwise we found a valid offset so try mount it */ + debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent); + +@@ -163,19 +173,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + */ + if (strchr(name, '/') || + me->age + ap->negative_timeout > time(NULL)) { ++ char *ent = NULL; ++ ++ if (me->mapent) { ++ ent = alloca(strlen(me->mapent) + 1); ++ strcpy(ent, me->mapent); ++ } ++ cache_unlock(mc); + master_source_current_wait(ap->entry); + ap->entry->current = source; + ret = ctxt->parse->parse_mount(ap, name, +- name_len, me->mapent, ctxt->parse->context); ++ name_len, ent, ctxt->parse->context); + goto out_free; + } else { + if (me->multi) { ++ cache_unlock(mc); + warn(ap->logopt, MODPREFIX + "unexpected lookup for active multi-mount" + " key %s, returning fail", name); + return NSS_STATUS_UNAVAIL; + } + cache_delete(mc, name); ++ cache_unlock(mc); + } + } + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 8b6408b..1b62f57 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -603,13 +603,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (key_len > KEY_MAX_LEN) + return NSS_STATUS_NOTFOUND; + +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me && me->status >= time(NULL)) { +- cache_unlock(mc); +- return NSS_STATUS_NOTFOUND; ++ /* Check if we recorded a mount fail for this key anywhere */ ++ me = lookup_source_mapent(ap, key, LKP_DISTINCT); ++ if (me) { ++ if (me->status >= time(NULL)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ /* Negative timeout expired for non-existent entry. */ ++ if (!me->mapent) ++ cache_delete(me->mc, key); ++ ++ cache_unlock(me->mc); + } +- cache_unlock(mc); + + /* + * We can't check the direct mount map as if it's not in diff --git a/autofs-5.0.4-fix-select-fd-limit.patch b/autofs-5.0.4-fix-select-fd-limit.patch new file mode 100644 index 0000000..c12a59f --- /dev/null +++ b/autofs-5.0.4-fix-select-fd-limit.patch @@ -0,0 +1,275 @@ +autofs-5.0.4 - fix select fd limit + +From: Ian Kent + +Using a large number of direct mounts causes autofs to hang. This is +because select(2) is limited to 1024 file handles (usually). To resolve +this we need to convert calls to select(2) to use poll(2). +--- + + CHANGELOG | 1 + + daemon/spawn.c | 19 ++++++------ + lib/rpc_subs.c | 32 ++++++++++++++------ + modules/lookup_program.c | 74 +++++++++++++++++++++++++++------------------- + 4 files changed, 78 insertions(+), 48 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 43f3205..0fb7db5 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - fix nested submount expire deadlock. + - fix negative caching for non-existent map keys. + - use CLOEXEC flag. ++- fix select(2) fd limit. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 4ddf46f..e02d926 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -89,21 +90,21 @@ void reset_signals(void) + + static int timed_read(int pipe, char *buf, size_t len, int time) + { +- struct timeval timeout = { 0, 0 }; +- struct timeval *tout = NULL; +- fd_set wset, rset; ++ struct pollfd pfd[1]; ++ int timeout = time; + int ret; + +- FD_ZERO(&rset); +- FD_SET(pipe, &rset); +- wset = rset; ++ pfd[0].fd = pipe; ++ pfd[0].events = POLLIN; + + if (time != -1) { +- timeout.tv_sec = time; +- tout = &timeout; ++ if (time >= (INT_MAX - 1)/1000) ++ timeout = INT_MAX - 1; ++ else ++ timeout = time * 1000; + } + +- ret = select(pipe + 1, &rset, &wset, NULL, tout); ++ ret = poll(pfd, 1, timeout); + if (ret <= 0) { + if (ret == 0) + ret = -ETIMEDOUT; +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 9ac3657..7b347a7 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "mount.h" + #include "rpc_subs.h" +@@ -197,14 +198,15 @@ void rpc_destroy_udp_client(struct conn_info *info) + /* + * Perform a non-blocking connect on the socket fd. + * +- * tout contains the timeout. It will be modified to contain the time +- * remaining (i.e. time provided - time elasped). ++ * The input struct timeval always has tv_nsec set to zero, ++ * we only ever use tv_sec for timeouts. + */ + static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + { ++ struct pollfd pfd[1]; ++ int timeout = tout->tv_sec; + int flags, ret; + socklen_t len; +- fd_set wset, rset; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) +@@ -229,12 +231,10 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + if (ret == 0) + goto done; + +- /* now wait */ +- FD_ZERO(&rset); +- FD_SET(fd, &rset); +- wset = rset; ++ pfd[0].fd = fd; ++ pfd[0].events = POLLOUT; + +- ret = select(fd + 1, &rset, &wset, NULL, tout); ++ ret = poll(pfd, 1, timeout); + if (ret <= 0) { + if (ret == 0) + ret = -ETIMEDOUT; +@@ -243,13 +243,27 @@ static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout) + goto done; + } + +- if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { ++ if (pfd[0].revents) { + int status; + + len = sizeof(ret); + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &ret, &len); + if (status < 0) { ++ char buf[MAX_ERR_BUF + 1]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ ++ /* ++ * We assume getsockopt amounts to a read on the ++ * descriptor and gives us the errno we need for ++ * the POLLERR revent case. ++ */ + ret = -errno; ++ ++ /* Unexpected case, log it so we know we got caught */ ++ if (pfd[0].revents & POLLNVAL) ++ logerr("unexpected poll(2) error on connect:" ++ " %s", estr); ++ + goto done; + } + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 6f4e2a3..f62d3ef 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #define MODULE_LOOKUP + #include "automount.h" +@@ -113,14 +114,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + char errbuf[1024], *errp; + char ch; + int pipefd[2], epipefd[2]; ++ struct pollfd pfd[2]; + pid_t f; +- int files_left; + int status; +- fd_set readfds, ourfds; + enum state { st_space, st_map, st_done } state; + int quoted = 0; + int ret = 1; +- int max_fd; + int distance; + int alloci = 1; + +@@ -253,30 +252,39 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + errp = errbuf; + state = st_space; + +- FD_ZERO(&ourfds); +- FD_SET(pipefd[0], &ourfds); +- FD_SET(epipefd[0], &ourfds); ++ pfd[0].fd = pipefd[0]; ++ pfd[0].events = POLLIN; ++ pfd[1].fd = epipefd[0]; ++ pfd[1].events = POLLIN; + +- max_fd = pipefd[0] > epipefd[0] ? pipefd[0] : epipefd[0]; ++ while (1) { ++ int bytes; + +- files_left = 2; ++ if (poll(pfd, 2, -1) < 0 && errno != EINTR) ++ break; ++ ++ if (pfd[0].fd == -1 && pfd[1].fd == -1) ++ break; + +- while (files_left != 0) { +- readfds = ourfds; +- if (select(max_fd + 1, &readfds, NULL, NULL, NULL) < 0 && errno != EINTR) ++ if ((pfd[0].revents & (POLLIN|POLLHUP)) == POLLHUP && ++ (pfd[1].revents & (POLLIN|POLLHUP)) == POLLHUP) + break; + + /* Parse maps from stdout */ +- if (FD_ISSET(pipefd[0], &readfds)) { +- if (read(pipefd[0], &ch, 1) < 1) { +- FD_CLR(pipefd[0], &ourfds); +- files_left--; ++ if (pfd[0].revents) { ++cont: ++ bytes = read(pipefd[0], &ch, 1); ++ if (bytes == 0) ++ goto next; ++ else if (bytes < 0) { ++ pfd[0].fd = -1; + state = st_done; ++ goto next; + } + + if (!quoted && ch == '\\') { + quoted = 1; +- continue; ++ goto cont; + } + + switch (state) { +@@ -333,26 +341,32 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + /* Eat characters till there's no more output */ + break; + } ++ goto cont; + } + quoted = 0; +- ++next: + /* Deal with stderr */ +- if (FD_ISSET(epipefd[0], &readfds)) { +- if (read(epipefd[0], &ch, 1) < 1) { +- FD_CLR(epipefd[0], &ourfds); +- files_left--; +- } else if (ch == '\n') { +- *errp = '\0'; +- if (errbuf[0]) +- logmsg(">> %s", errbuf); +- errp = errbuf; +- } else { +- if (errp >= &errbuf[1023]) { ++ if (pfd[1].revents) { ++ while (1) { ++ bytes = read(epipefd[0], &ch, 1); ++ if (bytes == 0) ++ break; ++ else if (bytes < 0) { ++ pfd[1].fd = -1; ++ break; ++ } else if (ch == '\n') { + *errp = '\0'; +- logmsg(">> %s", errbuf); ++ if (errbuf[0]) ++ logmsg(">> %s", errbuf); + errp = errbuf; ++ } else { ++ if (errp >= &errbuf[1023]) { ++ *errp = '\0'; ++ logmsg(">> %s", errbuf); ++ errp = errbuf; ++ } ++ *(errp++) = ch; + } +- *(errp++) = ch; + } + } + } diff --git a/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch b/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch new file mode 100644 index 0000000..c5f53b2 --- /dev/null +++ b/autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch @@ -0,0 +1,294 @@ +autofs-5.0.4 - make hash table scale to thousands of entries + +From: Valerie Aurora Henson + +Originally written by Paul Wankadia . + +The autofs cache lookup performs poorly for large maps. + +The additive hashing algorithm used by autofs results in a clustering +of hash values around the average hash chain size. It is biased toward +a small range of hash indexes which becomes worse as the hash table size +increases. + +Simple testing shows that the "One-at-a-time" hash function (implemented +by this patch) gives a much better distribution of hash indexes as table +size increases. + +The only change made to the original patch is to make the hash table size +configurable with a default somewhat larger than it is currently. +--- + + CHANGELOG | 2 ++ + include/automount.h | 2 +- + include/defaults.h | 3 +++ + lib/cache.c | 47 +++++++++++++++++++++++----------------- + lib/defaults.c | 16 +++++++++++++- + redhat/autofs.sysconfig.in | 6 +++++ + samples/autofs.conf.default.in | 6 +++++ + 7 files changed, 60 insertions(+), 22 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 0fb7db5..912c088 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,8 @@ + - fix negative caching for non-existent map keys. + - use CLOEXEC flag. + - fix select(2) fd limit. ++- make hash table scale to thousands of entries (Paul Wankadia, ++ Valerie Aurora Henson). + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/include/automount.h b/include/automount.h +index a55ddbc..fa24885 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -128,7 +128,7 @@ struct autofs_point; + #define CHE_DUPLICATE 0x0020 + #define CHE_UNAVAIL 0x0040 + +-#define HASHSIZE 77 ++#define NULL_MAP_HASHSIZE 64 + #define NEGATIVE_TIMEOUT 10 + #define UMOUNT_RETRIES 8 + #define EXPIRE_RETRIES 3 +diff --git a/include/defaults.h b/include/defaults.h +index 12534ec..9a2430f 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -40,6 +40,8 @@ + #define DEFAULT_APPEND_OPTIONS 1 + #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf" + ++#define DEFAULT_MAP_HASH_TABLE_SIZE 1024 ++ + struct ldap_schema; + struct ldap_searchdn; + +@@ -62,6 +64,7 @@ void defaults_free_searchdns(struct ldap_searchdn *); + unsigned int defaults_get_append_options(void); + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); ++unsigned int defaults_get_map_hash_table_size(void); + + #endif + +diff --git a/lib/cache.c b/lib/cache.c +index 4a00367..edb3192 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -190,7 +190,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map) + if (!mc) + return NULL; + +- mc->size = HASHSIZE; ++ mc->size = defaults_get_map_hash_table_size(); + + mc->hash = malloc(mc->size * sizeof(struct entry *)); + if (!mc->hash) { +@@ -241,7 +241,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + if (!mc) + return NULL; + +- mc->size = HASHSIZE; ++ mc->size = NULL_MAP_HASHSIZE; + + mc->hash = malloc(mc->size * sizeof(struct entry *)); + if (!mc->hash) { +@@ -279,29 +279,36 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + return mc; + } + +-static unsigned int hash(const char *key) ++static u_int32_t hash(const char *key, unsigned int size) + { +- unsigned long hashval; ++ u_int32_t hashval; + char *s = (char *) key; + +- for (hashval = 0; *s != '\0';) +- hashval += *s++; ++ for (hashval = 0; *s != '\0';) { ++ hashval += (unsigned char) *s++; ++ hashval += (hashval << 10); ++ hashval ^= (hashval >> 6); ++ } ++ ++ hashval += (hashval << 3); ++ hashval ^= (hashval >> 11); ++ hashval += (hashval << 15); + +- return hashval % HASHSIZE; ++ return hashval % size; + } + +-static unsigned int ino_hash(dev_t dev, ino_t ino) ++static u_int32_t ino_hash(dev_t dev, ino_t ino, unsigned int size) + { +- unsigned long hashval; ++ u_int32_t hashval; + + hashval = dev + ino; + +- return hashval % HASHSIZE; ++ return hashval % size; + } + + int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino) + { +- unsigned int ino_index = ino_hash(dev, ino); ++ u_int32_t ino_index = ino_hash(dev, ino, mc->size); + struct mapent *me; + + me = cache_lookup_distinct(mc, key); +@@ -323,10 +330,10 @@ struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino) + { + struct mapent *me = NULL; + struct list_head *head, *p; +- unsigned int ino_index; ++ u_int32_t ino_index; + + ino_index_lock(mc); +- ino_index = ino_hash(dev, ino); ++ ino_index = ino_hash(dev, ino, mc->size); + head = &mc->ino_index[ino_index]; + + list_for_each(p, head) { +@@ -369,7 +376,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc) + struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + { + struct mapent *this; +- unsigned long hashval; ++ u_int32_t hashval; + unsigned int i; + + if (!me) +@@ -385,7 +392,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + return this; + } + +- hashval = hash(me->key) + 1; ++ hashval = hash(me->key, mc->size) + 1; + if (hashval < mc->size) { + for (i = (unsigned int) hashval; i < mc->size; i++) { + this = mc->hash[i]; +@@ -433,7 +440,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key) + if (!key) + return NULL; + +- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) { ++ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) { + if (strcmp(key, me->key) == 0) + goto done; + } +@@ -446,7 +453,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key) + goto done; + } + +- for (me = mc->hash[hash("*")]; me != NULL; me = me->next) ++ for (me = mc->hash[hash("*", mc->size)]; me != NULL; me = me->next) + if (strcmp("*", me->key) == 0) + goto done; + } +@@ -462,7 +469,7 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key) + if (!key) + return NULL; + +- for (me = mc->hash[hash(key)]; me != NULL; me = me->next) { ++ for (me = mc->hash[hash(key, mc->size)]; me != NULL; me = me->next) { + if (strcmp(key, me->key) == 0) + return me; + } +@@ -530,7 +537,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + { + struct mapent *me, *existing = NULL; + char *pkey, *pent; +- unsigned int hashval = hash(key); ++ u_int32_t hashval = hash(key, mc->size); + int status; + + me = (struct mapent *) malloc(sizeof(struct mapent)); +@@ -750,7 +757,7 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key + int cache_delete(struct mapent_cache *mc, const char *key) + { + struct mapent *me = NULL, *pred; +- unsigned int hashval = hash(key); ++ u_int32_t hashval = hash(key, mc->size); + int status, ret = CHE_OK; + char *this; + +diff --git a/lib/defaults.c b/lib/defaults.c +index ff653e3..0d39716 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -49,6 +49,8 @@ + #define ENV_UMOUNT_WAIT "UMOUNT_WAIT" + #define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE" + ++#define ENV_MAP_HASH_TABLE_SIZE "MAP_HASH_TABLE_SIZE" ++ + static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME; + static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE; + +@@ -323,7 +325,8 @@ unsigned int defaults_read_config(unsigned int to_syslog) + check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || + check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || + check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog)) ++ check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || ++ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog)) + ; + } + +@@ -672,3 +675,14 @@ const char *defaults_get_auth_conf_file(void) + return (const char *) cf; + } + ++unsigned int defaults_get_map_hash_table_size(void) ++{ ++ long size; ++ ++ size = get_env_number(ENV_MAP_HASH_TABLE_SIZE); ++ if (size < 0) ++ size = DEFAULT_MAP_HASH_TABLE_SIZE; ++ ++ return (unsigned int) size; ++} ++ +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index 8256888..fe36f45 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -89,6 +89,12 @@ BROWSE_MODE="no" + # + #AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf" + # ++# MAP_HASH_TABLE_SIZE - set the map cache hash table size. ++# Should be a power of 2 with a ratio roughly ++# between 1:10 and 1:20 for each map. ++# ++#MAP_HASH_TABLE_SIZE=1024 ++# + # General global options + # + # If the kernel supports using the autofs miscellanous device +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 844a6f3..4496738 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -89,6 +89,12 @@ BROWSE_MODE="no" + # + #AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf" + # ++# MAP_HASH_TABLE_SIZE - set the map cache hash table size. ++# Should be a power of 2 with a ratio roughly ++# between 1:10 and 1:20 for each map. ++# ++#MAP_HASH_TABLE_SIZE=1024 ++# + # General global options + # + # If the kernel supports using the autofs miscellanous device diff --git a/autofs-5.0.4-use-CLOEXEC-flag.patch b/autofs-5.0.4-use-CLOEXEC-flag.patch new file mode 100644 index 0000000..940761b --- /dev/null +++ b/autofs-5.0.4-use-CLOEXEC-flag.patch @@ -0,0 +1,1191 @@ +autofs-5.0.4 - use CLOEXEC flag + +From: Ian Kent + +Update autofs to use the new CLOEXEC flag if present. +This allows us to set close on exec atomically flag when opening files, +hopefully avoiding selinux complaining about leaked file handles. +--- + + CHANGELOG | 1 + daemon/automount.c | 42 ++++-------------- + daemon/direct.c | 2 - + daemon/flag.c | 8 ++- + daemon/indirect.c | 2 - + daemon/lookup.c | 1 + daemon/module.c | 2 - + daemon/spawn.c | 11 +---- + include/automount.h | 106 +++++++++++++++++++++++++++++++++++++++++++++ + include/state.h | 1 + lib/cache.c | 2 - + lib/defaults.c | 7 ++- + lib/dev-ioctl-lib.c | 17 +------ + lib/log.c | 2 - + lib/macros.c | 1 + lib/mounts.c | 2 - + lib/nss_parse.y | 13 +----- + lib/parse_subs.c | 1 + lib/rpc_subs.c | 21 ++------- + modules/cyrus-sasl.c | 1 + modules/lookup_file.c | 40 +++-------------- + modules/lookup_hesiod.c | 1 + modules/lookup_hosts.c | 1 + modules/lookup_ldap.c | 1 + modules/lookup_multi.c | 1 + modules/lookup_nisplus.c | 1 + modules/lookup_program.c | 5 +- + modules/lookup_userhome.c | 1 + modules/lookup_yp.c | 1 + modules/mount_afs.c | 2 - + modules/mount_autofs.c | 2 - + modules/mount_bind.c | 2 - + modules/mount_changer.c | 10 ---- + modules/mount_ext2.c | 2 - + modules/mount_generic.c | 2 - + modules/mount_nfs.c | 2 - + modules/parse_hesiod.c | 1 + modules/parse_sun.c | 2 - + modules/replicated.c | 13 +----- + 39 files changed, 149 insertions(+), 184 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index bd35b00..43f3205 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - fix dumb libxml2 check + - fix nested submount expire deadlock. + - fix negative caching for non-existent map keys. ++- use CLOEXEC flag. + + 4/11/2008 autofs-5.0.4 + ----------------------- +diff --git a/daemon/automount.c b/daemon/automount.c +index 6f078c1..e120f50 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -20,13 +20,11 @@ + * ----------------------------------------------------------------------- */ + + #include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +@@ -68,6 +66,9 @@ static pthread_t state_mach_thid; + /* Pre-calculated kernel packet length */ + static size_t kpkt_len; + ++/* Does kernel know about SOCK_CLOEXEC and friends */ ++static int cloexec_works = 0; ++ + /* Attribute to create detached thread */ + pthread_attr_t thread_attr; + +@@ -671,7 +672,7 @@ static char *automount_path_to_fifo(unsigned logopt, const char *path) + static int create_logpri_fifo(struct autofs_point *ap) + { + int ret = -1; +- int fd, cl_flags; ++ int fd; + char *fifo_name; + char buf[MAX_ERR_BUF]; + +@@ -697,7 +698,7 @@ static int create_logpri_fifo(struct autofs_point *ap) + goto out_free; + } + +- fd = open(fifo_name, O_RDWR|O_NONBLOCK); ++ fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); + if (fd < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(ap->logopt, +@@ -707,11 +708,6 @@ static int create_logpri_fifo(struct autofs_point *ap) + goto out_free; + } + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + ap->logpri_fifo = fd; + + out_free: +@@ -963,7 +959,7 @@ int do_expire(struct autofs_point *ap, const char *name, int namelen) + + static int autofs_init_ap(struct autofs_point *ap) + { +- int pipefd[2], cl_flags; ++ int pipefd[2]; + + if ((ap->state != ST_INIT)) { + /* This can happen if an autofs process is already running*/ +@@ -974,7 +970,7 @@ static int autofs_init_ap(struct autofs_point *ap) + ap->pipefd = ap->kpipefd = ap->ioctlfd = -1; + + /* Pipe for kernel communications */ +- if (pipe(pipefd) < 0) { ++ if (open_pipe(pipefd) < 0) { + crit(ap->logopt, + "failed to create commumication pipe for autofs path %s", + ap->path); +@@ -984,18 +980,8 @@ static int autofs_init_ap(struct autofs_point *ap) + ap->pipefd = pipefd[0]; + ap->kpipefd = pipefd[1]; + +- if ((cl_flags = fcntl(ap->pipefd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->pipefd, F_SETFD, cl_flags); +- } +- +- if ((cl_flags = fcntl(ap->kpipefd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->kpipefd, F_SETFD, cl_flags); +- } +- + /* Pipe state changes from signal handler to main loop */ +- if (pipe(ap->state_pipe) < 0) { ++ if (open_pipe(ap->state_pipe) < 0) { + crit(ap->logopt, + "failed create state pipe for autofs path %s", ap->path); + close(ap->pipefd); +@@ -1003,16 +989,6 @@ static int autofs_init_ap(struct autofs_point *ap) + return -1; + } + +- if ((cl_flags = fcntl(ap->state_pipe[0], F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->state_pipe[0], F_SETFD, cl_flags); +- } +- +- if ((cl_flags = fcntl(ap->state_pipe[1], F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(ap->state_pipe[1], F_SETFD, cl_flags); +- } +- + if (create_logpri_fifo(ap) < 0) { + logmsg("could not create FIFO for path %s\n", ap->path); + logmsg("dynamic log level changes not available for %s", ap->path); +@@ -1080,7 +1056,7 @@ static void become_daemon(unsigned foreground, unsigned daemon_check) + exit(0); + } + +- if (pipe(start_pipefd) < 0) { ++ if (open_pipe(start_pipefd) < 0) { + fprintf(stderr, "%s: failed to create start_pipefd.\n", + program); + exit(0); +diff --git a/daemon/direct.c b/daemon/direct.c +index 98fcc07..c0243c4 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -21,12 +21,10 @@ + + #include + #include +-#include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/daemon/flag.c b/daemon/flag.c +index d8ca61b..e43cece 100644 +--- a/daemon/flag.c ++++ b/daemon/flag.c +@@ -21,15 +21,15 @@ + #include + #include + #include +-#include + #include +-#include + #include + #include + #include + #include + #include + ++#include "automount.h" ++ + #define MAX_PIDSIZE 20 + #define FLAG_FILE AUTOFS_FLAG_DIR "/autofs-running" + +@@ -129,7 +129,7 @@ int aquire_flag_file(void) + while (!we_created_flagfile) { + int errsv, i, j; + +- i = open(linkf, O_WRONLY|O_CREAT, 0); ++ i = open_fd_mode(linkf, O_WRONLY|O_CREAT, 0); + if (i < 0) { + release_flag_file(); + return 0; +@@ -146,7 +146,7 @@ int aquire_flag_file(void) + return 0; + } + +- fd = open(FLAG_FILE, O_RDWR); ++ fd = open_fd(FLAG_FILE, O_RDWR); + if (fd < 0) { + /* Maybe the file was just deleted? */ + if (errno == ENOENT) +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 1232810..9d3745c 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -21,12 +21,10 @@ + + #include + #include +-#include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 0cf6e3f..741d846 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include "automount.h" + #include "nsswitch.h" + +diff --git a/daemon/module.c b/daemon/module.c +index 36eca00..e593d75 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -31,7 +31,7 @@ int load_autofs4_module(void) + * is an older version we will catch it at mount + * time. + */ +- fp = fopen("/proc/filesystems", "r"); ++ fp = open_fopen_r("/proc/filesystems"); + if (!fp) { + logerr("cannot open /proc/filesystems\n"); + return 0; +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 17f92f4..4ddf46f 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -13,7 +13,6 @@ + * + * ----------------------------------------------------------------------- */ + +-#include + #include + #include + #include +@@ -21,7 +20,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -125,7 +123,7 @@ static int do_spawn(unsigned logopt, unsigned int wait, + int ret, status, pipefd[2]; + char errbuf[ERRBUFSIZ + 1], *p, *sp; + int errp, errn; +- int flags, cancel_state; ++ int cancel_state; + unsigned int use_lock = options & SPAWN_OPT_LOCK; + unsigned int use_access = options & SPAWN_OPT_ACCESS; + sigset_t allsigs, tmpsig, oldsig; +@@ -133,7 +131,7 @@ static int do_spawn(unsigned logopt, unsigned int wait, + pid_t euid = 0; + gid_t egid = 0; + +- if (pipe(pipefd)) ++ if (open_pipe(pipefd)) + return -1; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); +@@ -213,11 +211,6 @@ static int do_spawn(unsigned logopt, unsigned int wait, + return -1; + } + +- if ((flags = fcntl(pipefd[0], F_GETFD, 0)) != -1) { +- flags |= FD_CLOEXEC; +- fcntl(pipefd[0], F_SETFD, flags); +- } +- + errp = 0; + do { + errn = timed_read(pipefd[0], +diff --git a/include/automount.h b/include/automount.h +index 1ba0d3c..a55ddbc 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -17,6 +17,8 @@ + #include + #include + #include ++#include ++#include + #include "config.h" + #include "list.h" + +@@ -475,5 +477,109 @@ int alarm_start_handler(void); + int alarm_add(struct autofs_point *ap, time_t seconds); + void alarm_delete(struct autofs_point *ap); + ++/* ++ * Use CLOEXEC flag for open(), pipe(), fopen() (read-only case) and ++ * socket() if possible. ++ */ ++static int cloexec_works; ++ ++static inline void check_cloexec(int fd) ++{ ++ if (cloexec_works == 0) { ++ int fl = fcntl(fd, F_GETFD); ++ cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1; ++ } ++ if (cloexec_works > 0) ++ return; ++ fcntl(fd, F_SETFD, FD_CLOEXEC); ++ return; ++} ++ ++static inline int open_fd(const char *path, int flags) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline int open_fd_mode(const char *path, int flags, int mode) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags, mode); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline int open_pipe(int pipefd[2]) ++{ ++ int ret; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(__have_pipe2) ++ if (cloexec_works != -1) { ++ ret = pipe2(pipefd, O_CLOEXEC); ++ if (ret != -1) ++ return 0; ++ if (errno != EINVAL) ++ return -1; ++ } ++#endif ++ ret = pipe(pipefd); ++ if (ret == -1) ++ return -1; ++ check_cloexec(pipefd[0]); ++ check_cloexec(pipefd[1]); ++ return 0; ++} ++ ++static inline int open_sock(int domain, int type, int protocol) ++{ ++ int fd; ++ ++#ifdef SOCK_CLOEXEC ++ if (cloexec_works != -1) ++ type |= SOCK_CLOEXEC; ++#endif ++ fd = socket(domain, type, protocol); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++static inline FILE *open_fopen_r(const char *path) ++{ ++ FILE *f; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_exec != -1) { ++ f = fopen(path, "re"); ++ if (f != NULL) { ++ check_cloexec(fileno(f)); ++ return f; ++ } ++ } ++#endif ++ f = fopen(path, "r"); ++ if (f == NULL) ++ return NULL; ++ check_cloexec(fileno(f)); ++ return f; ++} ++ + #endif + +diff --git a/include/state.h b/include/state.h +index d7349d9..b44a353 100644 +--- a/include/state.h ++++ b/include/state.h +@@ -20,7 +20,6 @@ + #ifndef STATE_H + #define STATE_H + +-#include + #include + #include + #include +diff --git a/lib/cache.c b/lib/cache.c +index ce47e04..4a00367 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -17,10 +17,8 @@ + #include + #include + #include +-#include + #include + #include +-#include + #include + #include + #include +diff --git a/lib/defaults.c b/lib/defaults.c +index 21d76d2..ff653e3 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -21,6 +21,7 @@ + #include "defaults.h" + #include "lookup_ldap.h" + #include "log.h" ++#include "automount.h" + + #define DEFAULTS_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 +@@ -255,7 +256,7 @@ struct list_head *defaults_get_uris(void) + char *res; + struct list_head *list; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return NULL; + +@@ -298,7 +299,7 @@ unsigned int defaults_read_config(unsigned int to_syslog) + char buf[MAX_LINE_LEN]; + char *res; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return 0; + +@@ -544,7 +545,7 @@ struct ldap_searchdn *defaults_get_searchdns(void) + char *res; + struct ldap_searchdn *sdn, *last; + +- f = fopen(DEFAULTS_CONFIG_FILE, "r"); ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); + if (!f) + return NULL; + +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index 57af785..056a0a9 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -121,17 +121,12 @@ void init_ioctl_ctl(void) + if (ctl.ops) + return; + +- devfd = open(CONTROL_DEVICE, O_RDONLY); ++ devfd = open_fd(CONTROL_DEVICE, O_RDONLY); + if (devfd == -1) + ctl.ops = &ioctl_ops; + else { + struct autofs_dev_ioctl param; + +- int cl_flags = fcntl(devfd, F_GETFD, 0); +- if (cl_flags != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(devfd, F_SETFD, cl_flags); +- } + /* + * Check compile version against kernel. + * Selinux may allow us to open the device but not +@@ -378,20 +373,14 @@ static int ioctl_open(unsigned int logopt, + int *ioctlfd, dev_t devid, const char *path) + { + struct statfs sfs; +- int save_errno, fd, cl_flags; ++ int save_errno, fd; + + *ioctlfd = -1; + +- fd = open(path, O_RDONLY); ++ fd = open_fd(path, O_RDONLY); + if (fd == -1) + return -1; + +- cl_flags = fcntl(fd, F_GETFD, 0); +- if (cl_flags != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + if (fstatfs(fd, &sfs) == -1) { + save_errno = errno; + goto err; +diff --git a/lib/log.c b/lib/log.c +index 65e8ad2..46220fd 100644 +--- a/lib/log.c ++++ b/lib/log.c +@@ -20,8 +20,6 @@ + + #include + #include +-#include +-#include + #include + #include + +diff --git a/lib/macros.c b/lib/macros.c +index fa6db8e..85f9cd3 100644 +--- a/lib/macros.c ++++ b/lib/macros.c +@@ -14,7 +14,6 @@ + * ----------------------------------------------------------------------- */ + + #include +-#include + #include + #include + #include +diff --git a/lib/mounts.c b/lib/mounts.c +index 6d0a69c..ce4691b 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -14,13 +14,11 @@ + + #include + #include +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +diff --git a/lib/nss_parse.y b/lib/nss_parse.y +index fa6958a..3bda6b3 100644 +--- a/lib/nss_parse.y ++++ b/lib/nss_parse.y +@@ -22,8 +22,6 @@ + #include + #include + #include +-#include +-#include + #include + + #include "automount.h" +@@ -164,9 +162,9 @@ static void parse_close_nsswitch(void *arg) + int nsswitch_parse(struct list_head *list) + { + FILE *nsswitch; +- int fd, cl_flags, status; ++ int status; + +- nsswitch = fopen(NSSWITCH_FILE, "r"); ++ nsswitch = open_fopen_r(NSSWITCH_FILE); + if (!nsswitch) { + logerr("couldn't open %s\n", NSSWITCH_FILE); + return 1; +@@ -174,13 +172,6 @@ int nsswitch_parse(struct list_head *list) + + pthread_cleanup_push(parse_close_nsswitch, nsswitch); + +- fd = fileno(nsswitch); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + parse_mutex_lock(); + pthread_cleanup_push(parse_mutex_unlock, NULL); + +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 3a04dd6..8a032e8 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include "automount.h" + + /* +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 6be86c6..9ac3657 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -21,13 +21,11 @@ + #include + #include + +-#include + #include + #include + #include + #include + #include +-#include + #include + #include + #include +@@ -36,6 +34,7 @@ + + #include "mount.h" + #include "rpc_subs.h" ++#include "automount.h" + + /* #define STANDALONE */ + #ifdef STANDALONE +@@ -59,7 +58,7 @@ inline void dump_core(void); + */ + static CLIENT *create_udp_client(struct conn_info *info) + { +- int fd, cl_flags, ret, ghn_errno; ++ int fd, ret, ghn_errno; + CLIENT *client; + struct sockaddr_in laddr, raddr; + struct hostent hp; +@@ -115,15 +114,10 @@ got_addr: + * layer, it would bind to a reserved port, which has been shown + * to exhaust the reserved port range in some situations. + */ +- fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ fd = open_sock(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) + return NULL; + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + laddr.sin_family = AF_INET; + laddr.sin_port = 0; + laddr.sin_addr.s_addr = htonl(INADDR_ANY); +@@ -274,7 +268,7 @@ done: + */ + static CLIENT *create_tcp_client(struct conn_info *info) + { +- int fd, cl_flags, ghn_errno; ++ int fd, ghn_errno; + CLIENT *client; + struct sockaddr_in addr; + struct hostent hp; +@@ -324,15 +318,10 @@ got_addr: + addr.sin_port = htons(info->port); + + if (!info->client) { +- fd = socket(PF_INET, SOCK_STREAM, info->proto->p_proto); ++ fd = open_sock(PF_INET, SOCK_STREAM, info->proto->p_proto); + if (fd < 0) + return NULL; + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + ret = connect_nb(fd, &addr, &info->timeout); + if (ret < 0) + goto out_close; +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index 902d9aa..286af15 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + #include + #include + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 9e34b72..95b9f6f 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -17,8 +17,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -395,7 +393,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + char *ent; + struct stat st; + FILE *f; +- int fd, cl_flags; ++ int fd; + unsigned int path_len, ent_len; + int entry, cur_state; + +@@ -422,7 +420,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(logopt, + MODPREFIX "could not open master map file %s", +@@ -432,11 +430,6 @@ int lookup_read_master(struct master *master, time_t age, void *context) + + fd = fileno(f); + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(logopt, f, path, &path_len, ent, &ent_len); + if (!entry) { +@@ -651,7 +644,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + char *mapent; + struct stat st; + FILE *f; +- int fd, cl_flags; ++ int fd; + unsigned int k_len, m_len; + int entry; + +@@ -684,7 +677,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_UNAVAIL; + } + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); +@@ -693,11 +686,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + + fd = fileno(f); + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len); + if (!entry) { +@@ -784,7 +772,6 @@ static int lookup_one(struct autofs_point *ap, + char mapent[MAPENT_MAX_LEN + 1]; + time_t age = time(NULL); + FILE *f; +- int fd, cl_flags; + unsigned int k_len, m_len; + int entry, ret; + +@@ -794,20 +781,13 @@ static int lookup_one(struct autofs_point *ap, + + mc = source->mc; + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); + return CHE_FAIL; + } + +- fd = fileno(f); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len); + if (entry) { +@@ -897,7 +877,6 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + char mapent[MAPENT_MAX_LEN + 1]; + time_t age = time(NULL); + FILE *f; +- int fd, cl_flags; + unsigned int k_len, m_len; + int entry, ret; + +@@ -907,20 +886,13 @@ static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) + + mc = source->mc; + +- f = fopen(ctxt->mapname, "r"); ++ f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); + return CHE_FAIL; + } + +- fd = fileno(f); +- +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + while(1) { + entry = read_one(ap->logopt, f, mkey, &k_len, mapent, &m_len); + if (entry) { +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index 737a47e..0a2ee44 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index f8d4269..93b975a 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -15,7 +15,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 42c3235..6ba80eb 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 601d48e..1bf2e0a 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + + #define MODULE_LOOKUP +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index f15465f..4c3ce60 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -6,7 +6,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index bf32d3b..6f4e2a3 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -212,12 +211,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * want to send stderr to the syslog, and we don't use spawnl() + * because we need the pipe hooks + */ +- if (pipe(pipefd)) { ++ if (open_pipe(pipefd)) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "pipe: %s", estr); + goto out_free; + } +- if (pipe(epipefd)) { ++ if (open_pipe(epipefd)) { + close(pipefd[0]); + close(pipefd[1]); + goto out_free; +diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c +index 680ddaf..fb3caaa 100644 +--- a/modules/lookup_userhome.c ++++ b/modules/lookup_userhome.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 1b62f57..ce438e8 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -16,7 +16,6 @@ + + #include + #include +-#include + #include + #include + #include +diff --git a/modules/mount_afs.c b/modules/mount_afs.c +index 96a1367..50628ce 100644 +--- a/modules/mount_afs.c ++++ b/modules/mount_afs.c +@@ -9,8 +9,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index eb63d8e..82a5ef3 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -16,8 +16,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 022d183..361f0c2 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 43b8355..92bb72b 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -19,8 +19,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +@@ -145,25 +143,19 @@ int swapCD(const char *device, const char *slotName) + { + int fd; /* file descriptor for CD-ROM device */ + int status; /* return status for system calls */ +- int cl_flags; + int slot = -1; + int total_slots_available; + + slot = atoi(slotName) - 1; + + /* open device */ +- fd = open(device, O_RDONLY | O_NONBLOCK); ++ fd = open_fd(device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + logerr(MODPREFIX "Opening device %s failed : %s", + device, strerror(errno)); + return 1; + } + +- if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(fd, F_SETFD, cl_flags); +- } +- + /* Check CD player status */ + total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS); + if (total_slots_available <= 1) { +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 4c5b271..192ec04 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index f094d07..6d7b4b3 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -15,8 +15,6 @@ + + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index c747078..20732f8 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -17,8 +17,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index ff1f0a5..d5bb0f4 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -7,7 +7,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 2c4f8b2..72e51e2 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -18,8 +18,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +diff --git a/modules/replicated.c b/modules/replicated.c +index b435f4b..63829a2 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -52,8 +52,6 @@ + #include + #include + #include +-#include +-#include + + #include "rpc_subs.h" + #include "replicated.h" +@@ -82,7 +80,7 @@ void seed_random(void) + int fd; + unsigned int seed; + +- fd = open("/dev/urandom", O_RDONLY); ++ fd = open_fd("/dev/urandom", O_RDONLY); + if (fd < 0) { + srandom(time(NULL)); + return; +@@ -145,7 +143,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + char tmp[20], buf[MAX_ERR_BUF], *ptr; + struct ifconf ifc; + struct ifreq *ifr, nmptr; +- int sock, cl_flags, ret, i; ++ int sock, ret, i; + uint32_t mask, ha, ia; + + memcpy(tmp, host_addr, addr_len); +@@ -153,18 +151,13 @@ static unsigned int get_proximity(const char *host_addr, int addr_len) + + ha = ntohl((uint32_t) hst_addr->s_addr); + +- sock = socket(AF_INET, SOCK_DGRAM, 0); ++ sock = open_sock(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("socket creation failed: %s", estr); + return PROXIMITY_ERROR; + } + +- if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) { +- cl_flags |= FD_CLOEXEC; +- fcntl(sock, F_SETFD, cl_flags); +- } +- + if (!alloc_ifreq(&ifc, sock)) { + close(sock); + return PROXIMITY_ERROR; diff --git a/autofs.spec b/autofs.spec index 8d6b612..b357cad 100644 --- a/autofs.spec +++ b/autofs.spec @@ -4,7 +4,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.0.4 -Release: 4 +Release: 5 Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -12,6 +12,11 @@ URL: http://wiki.autofs.net/ Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2 Patch1: autofs-5.0.4-fix-dumb-libxml2-check.patch Patch2: autofs-5.0.4-expire-specific-submount-only.patch +Patch3: autofs-5.0.4-fix-negative-cache-non-existent-key.patch +Patch4: autofs-5.0.4-fix-ldap-detection.patch +Patch5: autofs-5.0.4-use-CLOEXEC-flag.patch +Patch6: autofs-5.0.4-fix-select-fd-limit.patch +Patch7: autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs Requires: kernel >= 2.6.17 @@ -55,6 +60,11 @@ inkludera nÀtfilsystem, CD-ROM, floppydiskar, och sÄ vidare. echo %{version}-%{release} > .version %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir} @@ -107,6 +117,13 @@ fi %{_libdir}/autofs/ %changelog +* Thu Jan 15 2009 Ian Kent - 5.0.4-5 +- fix negative caching of non-existent keys. +- fix ldap library detection in configure. +- use CLOEXEC flag functionality if present. +- fix select(2) fd limit. +- make hash table scale to thousands of entries. + * Wed Dec 3 2008 Ian Kent - 5.0.4-4 - fix nested submount expire deadlock.