autofs-5.1.3 - serialize calls to open_xxxx() functions From: Ian Kent This patch is the second part of the change described in "move open_xxxx() functions to spawn.c" to serialize the open_xxxx() functions wrt. to fork(2). Signed-off-by: Ian Kent --- CHANGELOG | 1 daemon/spawn.c | 61 ++++++++++++++++++++++++++++++++++++++++------- include/automount.h | 2 + lib/mounts.c | 2 + modules/lookup_program.c | 3 ++ 5 files changed, 61 insertions(+), 8 deletions(-) --- autofs-5.0.7.orig/CHANGELOG +++ autofs-5.0.7/CHANGELOG @@ -288,6 +288,7 @@ - update configure to check for pipe2(2). - fix open calls not using open_xxxx() calls. - move open_xxxx() functions to spawn.c. +- serialize calls to open_xxxx() functions. 25/07/2012 autofs-5.0.7 ======================= --- autofs-5.0.7.orig/daemon/spawn.c +++ autofs-5.0.7/daemon/spawn.c @@ -29,6 +29,7 @@ #include "automount.h" static pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER; #define SPAWN_OPT_NONE 0x0000 #define SPAWN_OPT_LOCK 0x0001 @@ -48,6 +49,20 @@ void dump_core(void) raise(SIGSEGV); } +void open_mutex_lock(void) +{ + int _o_lock = pthread_mutex_lock(&open_mutex); + if (_o_lock) + fatal(_o_lock); +} + +void open_mutex_unlock(void) +{ + int _o_unlock = pthread_mutex_unlock(&open_mutex); + if (_o_unlock) + fatal(_o_unlock); +} + /* * Use CLOEXEC flag for open(), pipe(), fopen() (read-only case) and * socket() if possible. @@ -71,14 +86,18 @@ int open_fd(const char *path, int flags) { int fd; + open_mutex_lock(); #if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) if (cloexec_works != -1) flags |= O_CLOEXEC; #endif fd = open(path, flags); - if (fd == -1) + if (fd == -1) { + open_mutex_unlock(); return -1; + } check_cloexec(fd); + open_mutex_unlock(); return fd; } @@ -86,14 +105,18 @@ int open_fd_mode(const char *path, int f { int fd; + open_mutex_lock(); #if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) if (cloexec_works != -1) flags |= O_CLOEXEC; #endif fd = open(path, flags, mode); - if (fd == -1) + if (fd == -1) { + open_mutex_unlock(); return -1; + } check_cloexec(fd); + open_mutex_unlock(); return fd; } @@ -101,35 +124,45 @@ int open_pipe(int pipefd[2]) { int ret; + open_mutex_lock(); #if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(HAVE_PIPE2) if (cloexec_works != -1) { ret = pipe2(pipefd, O_CLOEXEC); if (ret != -1) - return 0; + goto done; if (errno != EINVAL) - return -1; + goto err; } #endif ret = pipe(pipefd); if (ret == -1) - return -1; + goto err; check_cloexec(pipefd[0]); check_cloexec(pipefd[1]); +done: + open_mutex_unlock(); return 0; +err: + open_mutex_unlock(); + return -1; } int open_sock(int domain, int type, int protocol) { int fd; + open_mutex_lock(); #ifdef SOCK_CLOEXEC if (cloexec_works != -1) type |= SOCK_CLOEXEC; #endif fd = socket(domain, type, protocol); - if (fd == -1) + if (fd == -1) { + open_mutex_unlock(); return -1; + } check_cloexec(fd); + open_mutex_unlock(); return fd; } @@ -137,19 +170,24 @@ FILE *open_fopen_r(const char *path) { FILE *f; + open_mutex_lock(); #if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) if (cloexec_works != -1) { f = fopen(path, "re"); if (f != NULL) { check_cloexec(fileno(f)); + open_mutex_unlock(); return f; } } #endif f = fopen(path, "r"); - if (f == NULL) + if (f == NULL) { + open_mutex_unlock(); return NULL; + } check_cloexec(fileno(f)); + open_mutex_unlock(); return f; } @@ -157,19 +195,24 @@ FILE *open_setmntent_r(const char *table { FILE *tab; + open_mutex_lock(); #if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) if (cloexec_works != -1) { tab = setmntent(table, "re"); if (tab != NULL) { check_cloexec(fileno(tab)); + open_mutex_unlock(); return tab; } } #endif tab = fopen(table, "r"); - if (tab == NULL) + if (tab == NULL) { + open_mutex_unlock(); return NULL; + } check_cloexec(fileno(tab)); + open_mutex_unlock(); return tab; } @@ -283,6 +326,7 @@ static int do_spawn(unsigned logopt, uns egid = tsv->gid; } + open_mutex_lock(); f = fork(); if (f == 0) { char **pargv = (char **) argv; @@ -377,6 +421,7 @@ done: sigaddset(&tmpsig, SIGCHLD); pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); + open_mutex_unlock(); close(pipefd[1]); --- autofs-5.0.7.orig/include/automount.h +++ autofs-5.0.7/include/automount.h @@ -257,6 +257,8 @@ int spawnv(unsigned logopt, const char * int spawn_mount(unsigned logopt, ...); int spawn_bind_mount(unsigned logopt, ...); int spawn_umount(unsigned logopt, ...); +void open_mutex_lock(void); +void open_mutex_unlock(void); int open_fd(const char *, int); int open_fd_mode(const char *, int, int); int open_pipe(int[2]); --- autofs-5.0.7.orig/lib/mounts.c +++ autofs-5.0.7/lib/mounts.c @@ -230,6 +230,7 @@ int check_nfs_mount_version(struct nfs_m sigfillset(&allsigs); pthread_sigmask(SIG_BLOCK, &allsigs, &oldsig); + open_mutex_lock(); f = fork(); if (f == 0) { reset_signals(); @@ -248,6 +249,7 @@ int check_nfs_mount_version(struct nfs_m sigaddset(&tmpsig, SIGCHLD); pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); + open_mutex_unlock(); close(pipefd[1]); --- autofs-5.0.7.orig/modules/lookup_program.c +++ autofs-5.0.7/modules/lookup_program.c @@ -225,6 +225,7 @@ static char *lookup_one(struct autofs_po goto out_error; } + open_mutex_lock(); f = fork(); if (f < 0) { char *estr = strerror_r(errno, buf, MAX_ERR_BUF); @@ -233,6 +234,7 @@ static char *lookup_one(struct autofs_po close(pipefd[1]); close(epipefd[0]); close(epipefd[1]); + open_mutex_unlock(); goto out_error; } else if (f == 0) { reset_signals(); @@ -262,6 +264,7 @@ static char *lookup_one(struct autofs_po } close(pipefd[1]); close(epipefd[1]); + open_mutex_unlock(); mapp = mapent; errp = errbuf;