autofs-5.1.8 - eliminate last remaining state_pipe usage From: Ian Kent Eliminate the last remaining usage autofs mount struct state_pipe that is used when changing state to ST_SHUTDOWN at submount exit. Ths single usage consumes a pipe file handle pair for every autofs file system mount. Signed-off-by: Ian Kent --- CHANGELOG | 1 + daemon/automount.c | 78 ++++++++++++++++++++------------------------------- daemon/direct.c | 2 - daemon/indirect.c | 7 ----- daemon/master.c | 21 ++------------ daemon/state.c | 16 +++------- include/automount.h | 1 - include/state.h | 1 - 8 files changed, 40 insertions(+), 87 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 087dff58..76dfb34a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -63,6 +63,7 @@ - make amd mapent search function name clear. - rename statemachine() to signal_handler(). - make signal handling consistent. +- eliminate last remaining state_pipe usage. 19/10/2021 autofs-5.1.8 - add xdr_exports(). diff --git a/daemon/automount.c b/daemon/automount.c index 624d3349..840c178a 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -1078,58 +1078,51 @@ static int set_log_priority(const char *path, int priority) return 0; } +static void dummy(int sig) +{ +} + static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt) { - struct pollfd fds[3]; - int pollfds = 3; + struct sigaction sa; + sigset_t signalset; + struct pollfd fds[2]; + int pollfds = 2; char buf[MAX_ERR_BUF]; size_t read; char *estr; fds[0].fd = ap->pipefd; fds[0].events = POLLIN; - fds[1].fd = ap->state_pipe[0]; + fds[1].fd = ap->logpri_fifo; fds[1].events = POLLIN; - fds[2].fd = ap->logpri_fifo; - fds[2].events = POLLIN; - if (fds[2].fd == -1) + if (fds[1].fd == -1) pollfds--; - for (;;) { - if (poll(fds, pollfds, -1) == -1) { - if (errno == EINTR) - continue; - estr = strerror_r(errno, buf, MAX_ERR_BUF); - logerr("poll failed: %s", estr); - return -1; - } - - if (fds[1].revents & POLLIN) { - enum states next_state; - size_t read_size = sizeof(next_state); - int state_pipe; + sa.sa_handler = dummy; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCONT, &sa, NULL) == -1) + error(LOGOPT_ANY, "failed to set signal handler %d", errno); - next_state = ST_INVAL; - - st_mutex_lock(); - - state_pipe = ap->state_pipe[0]; + sigfillset(&signalset); + sigdelset(&signalset, SIGCONT); - read = fullread(state_pipe, &next_state, read_size); - if (read) { - estr = strerror_r(errno, buf, MAX_ERR_BUF); - error(ap->logopt, - "read error on state pipe, " - "read %lu, error %s", - read, estr); + for (;;) { + errno = 0; + if (ppoll(fds, pollfds, NULL, &signalset) == -1) { + if (errno == EINTR) { + st_mutex_lock(); + if (ap->state == ST_SHUTDOWN) { + st_mutex_unlock(); + return -1; + } st_mutex_unlock(); continue; } - - st_mutex_unlock(); - - if (next_state == ST_SHUTDOWN) - return -1; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("poll failed: %s", estr); + return -1; } if (fds[0].revents & POLLIN) { @@ -1144,9 +1137,9 @@ static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt) return read; } - if (fds[2].fd != -1 && fds[2].revents & POLLIN) { + if (fds[1].fd != -1 && fds[1].revents & POLLIN) { debug(ap->logopt, "message pending on control fifo."); - handle_fifo_message(ap, fds[2].fd); + handle_fifo_message(ap, fds[1].fd); } } } @@ -1209,15 +1202,6 @@ static int autofs_init_ap(struct autofs_point *ap) ap->pipefd = pipefd[0]; ap->kpipefd = pipefd[1]; - /* Pipe state changes from signal handler to main loop */ - if (open_pipe(ap->state_pipe) < 0) { - crit(ap->logopt, - "failed create state pipe for autofs path %s", ap->path); - close(ap->pipefd); - close(ap->kpipefd); /* Close kernel pipe end */ - return -1; - } - 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); diff --git a/daemon/direct.c b/daemon/direct.c index 316ffd78..2a199af4 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -263,8 +263,6 @@ done: } pthread_cleanup_pop(1); - close(ap->state_pipe[0]); - close(ap->state_pipe[1]); if (ap->pipefd >= 0) close(ap->pipefd); if (ap->kpipefd >= 0) { diff --git a/daemon/indirect.c b/daemon/indirect.c index 4534907d..47d866eb 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -152,8 +152,6 @@ out_rmdir: out_err: if (options) free(options); - close(ap->state_pipe[0]); - close(ap->state_pipe[1]); close(ap->pipefd); close(ap->kpipefd); @@ -216,11 +214,6 @@ void close_mount_fds(struct autofs_point *ap) if (ap->submount) lookup_source_close_ioctlfd(ap->parent, ap->path); - close(ap->state_pipe[0]); - close(ap->state_pipe[1]); - ap->state_pipe[0] = -1; - ap->state_pipe[1] = -1; - if (ap->pipefd >= 0) close(ap->pipefd); diff --git a/daemon/master.c b/daemon/master.c index cb4fcb7e..284c5596 100644 --- a/daemon/master.c +++ b/daemon/master.c @@ -113,8 +113,6 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, ap->state = ST_INIT; - ap->state_pipe[0] = -1; - ap->state_pipe[1] = -1; ap->logpri_fifo = -1; ap->path = strdup(entry->path); @@ -1399,7 +1397,7 @@ static int master_do_mount(struct master_mapent *entry) handle_mounts_startup_cond_destroy(&suc); return 0; } - entry->thid = thid; + entry->thid = ap->thid = thid; handle_mounts_startup_cond_destroy(&suc); @@ -1483,9 +1481,6 @@ int master_mount_mounts(struct master *master, time_t age) struct master_mapent *this; struct autofs_point *ap; struct mapent *ne, *nested; - struct stat st; - int state_pipe, save_errno; - int ret; this = list_entry(p, struct master_mapent, list); p = p->next; @@ -1541,19 +1536,9 @@ int master_mount_mounts(struct master *master, time_t age) } cache_unlock(nc); cont: - st_mutex_lock(); - - state_pipe = this->ap->state_pipe[1]; - - /* No pipe so mount is needed */ - ret = fstat(state_pipe, &st); - save_errno = errno; - - st_mutex_unlock(); - - if (!ret) + if (ap->thid && is_mounted(this->path, MNTS_AUTOFS)) check_update_map_sources(this, master->readall); - else if (ret == -1 && save_errno == EBADF) { + else { if (!master_do_mount(this)) { list_del_init(&this->list); master_free_mapent_sources(ap->entry, 1); diff --git a/daemon/state.c b/daemon/state.c index 28ad68ca..9912ffec 100644 --- a/daemon/state.c +++ b/daemon/state.c @@ -52,16 +52,6 @@ void st_mutex_unlock(void) fatal(status); } -void nextstate(int statefd, enum states next) -{ - char buf[MAX_ERR_BUF]; - - if (write(statefd, &next, sizeof(next)) != sizeof(next)) { - char *estr = strerror_r(errno, buf, MAX_ERR_BUF); - logerr("write failed %s", estr); - } -} - /* * Handle expire thread cleanup and return the next state the system * should enter as a result. @@ -631,12 +621,16 @@ static unsigned int st_force_shutdown(struct autofs_point *ap) static unsigned int st_shutdown(struct autofs_point *ap) { + int ret; + debug(ap->logopt, "state %d path %s", ap->state, ap->path); assert(ap->state == ST_SHUTDOWN_PENDING || ap->state == ST_SHUTDOWN_FORCE); ap->state = ST_SHUTDOWN; - nextstate(ap->state_pipe[1], ST_SHUTDOWN); + ret = pthread_kill(ap->thid, SIGCONT); + if (ret) + error(LOGOPT_ANY, "error %d sending shutdown signal", ret); return 0; } diff --git a/include/automount.h b/include/automount.h index 9387ad1b..404777a2 100644 --- a/include/automount.h +++ b/include/automount.h @@ -570,7 +570,6 @@ struct autofs_point { pthread_t exp_thread; /* Thread that is expiring */ pthread_t readmap_thread; /* Thread that is reading maps */ enum states state; /* Current state */ - int state_pipe[2]; /* State change router pipe */ struct autofs_point *parent; /* Owner of mounts list for submount */ struct list_head mounts; /* List of autofs mounts at current level */ unsigned int submount; /* Is this a submount */ diff --git a/include/state.h b/include/state.h index 98f27d3f..fbb21cac 100644 --- a/include/state.h +++ b/include/state.h @@ -86,7 +86,6 @@ void st_mutex_unlock(void); void expire_cleanup(void *); void expire_proc_cleanup(void *); -void nextstate(int, enum states); int st_add_task(struct autofs_point *, enum states); int __st_add_task(struct autofs_point *, enum states);