diff --git a/SOURCES/autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch b/SOURCES/autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch new file mode 100644 index 0000000..04c6d7d --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch @@ -0,0 +1,104 @@ +autofs-5.1.7 - add buffer length checks to autofs mount_mount() + +From: Ian Kent + + +--- + CHANGELOG | 1 + modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++---------------- + 2 files changed, 41 insertions(+), 19 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -138,6 +138,7 @@ + - fix amd selector function matching. + - get rid entry thid field. + - continue expire immediately after submount check. ++- add buffer length checks to autofs mount_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/mount_autofs.c ++++ autofs-5.1.7/modules/mount_autofs.c +@@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap, + { + struct startup_cond suc; + pthread_t thid; +- char realpath[PATH_MAX]; +- char mountpoint[PATH_MAX]; ++ char realpath[PATH_MAX + 1]; ++ char mountpoint[PATH_MAX + 1]; + const char **argv; + int argc, status; + int nobind = ap->flags & MOUNT_FLAG_NOBIND; +@@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap, + struct mnt_list *mnt; + char buf[MAX_ERR_BUF]; + char *options, *p; +- int len, ret; ++ int err, ret; + int hosts = 0; + + /* Root offset of multi-mount */ +- len = strlen(root); +- if (root[len - 1] == '/') { +- strcpy(realpath, ap->path); +- strcat(realpath, "/"); +- strcat(realpath, name); +- len--; +- strncpy(mountpoint, root, len); +- mountpoint[len] = '\0'; ++ if (root[strlen(root) - 1] == '/') { ++ err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for realpath"); ++ return 1; ++ } ++ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for mountpoint"); ++ return 1; ++ } ++ mountpoint[err - 1] = 0; + } else if (*name == '/') { + if (ap->flags & MOUNT_FLAG_REMOUNT) { +- strcpy(mountpoint, name); +- strcpy(realpath, name); ++ err = snprintf(mountpoint, PATH_MAX + 1, "%s", name); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for mountpoint"); ++ return 1; ++ } ++ err = snprintf(realpath, PATH_MAX + 1, "%s", name); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for realpath"); ++ return 1; ++ } + } else { +- strcpy(mountpoint, root); +- strcpy(realpath, name); ++ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for mountpoint"); ++ return 1; ++ } ++ err = snprintf(realpath, PATH_MAX + 1, "%s", name); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for realpath"); ++ return 1; ++ } + } + } else { +- strcpy(mountpoint, root); +- strcat(mountpoint, "/"); ++ err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name); ++ if (err > PATH_MAX) { ++ error(ap->logopt, MODPREFIX "string too long for mountpoint"); ++ return 1; ++ } + strcpy(realpath, mountpoint); +- strcat(mountpoint, name); +- strcat(realpath, name); + } + + options = NULL; diff --git a/SOURCES/autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch b/SOURCES/autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch new file mode 100644 index 0000000..d894264 --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch @@ -0,0 +1,82 @@ +autofs-5.1.7 - eliminate buffer usage from handle_mounts_cleanup() + +From: Ian Kent + +This buffer was originally added because a SEGV was seen accessing +the ap->path field on shutdown. + +But this was actually caused by calling master_remove_mapent() too +early which adds the map entry to the master map join list that leads +to freeing the autofs_point (ap in the code) which also frees ap->path. + +But the master map join list is protected by the master map mutex which +is held until after all the accesses are completed. So whatever the +problem was it doesn't appear to be present any more. + +Nevertheless, to be sure, delay the call to master_remove_mapent() until +after all accesses to ap->path are completed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 13 ++++++------- + 2 files changed, 7 insertions(+), 7 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -148,6 +148,7 @@ + - change to use printf functions in amd parser. + - dont call umount_subtree_mounts() on parent at umount. + - dont take parent source lock at mount shutdown. ++- eliminate buffer usage from handle_mounts_cleanup(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1724,7 +1724,6 @@ void handle_mounts_startup_cond_destroy( + static void handle_mounts_cleanup(void *arg) + { + struct autofs_point *ap; +- char path[PATH_MAX + 1]; + char buf[MAX_ERR_BUF]; + unsigned int clean = 0, submount, logopt; + unsigned int pending = 0; +@@ -1734,7 +1733,6 @@ static void handle_mounts_cleanup(void * + logopt = ap->logopt; + submount = ap->submount; + +- strcpy(path, ap->path); + if (!submount && strcmp(ap->path, "/-") && + ap->flags & MOUNT_FLAG_DIR_CREATED) + clean = 1; +@@ -1756,8 +1754,8 @@ static void handle_mounts_cleanup(void * + /* Don't signal the handler if we have already done so */ + if (!list_empty(&master_list->completed)) + pending = 1; +- master_remove_mapent(ap->entry); +- master_source_unlock(ap->entry); ++ ++ info(logopt, "shut down path %s", ap->path); + + /* + * Submounts are detached threads and don't belong to the +@@ -1770,14 +1768,15 @@ static void handle_mounts_cleanup(void * + } + + if (clean) { +- if (rmdir(path) == -1) { ++ if (rmdir(ap->path) == -1) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + warn(logopt, "failed to remove dir %s: %s", +- path, estr); ++ ap->path, estr); + } + } + +- info(logopt, "shut down path %s", path); ++ master_remove_mapent(ap->entry); ++ master_source_unlock(ap->entry); + + /* + * If we are not a submount send a signal to the signal handler diff --git a/SOURCES/autofs-5.1.7-fix-incorrect-print-format-specifiers.patch b/SOURCES/autofs-5.1.7-fix-incorrect-print-format-specifiers.patch new file mode 100644 index 0000000..40a9052 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-incorrect-print-format-specifiers.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - fix incorrect print format specifiers in get_pkt() + +From: Ian Kent + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -122,6 +122,7 @@ + - make amd mapent search function name clear. + - rename statemachine() to signal_handler(). + - make signal handling consistent. ++- fix incorrect print format specifiers in get_pkt(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1105,7 +1105,7 @@ static int get_pkt(struct autofs_point * + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + "read error on state pipe, " +- "read %u, error %s", ++ "read %lu, error %s", + read, estr); + st_mutex_unlock(); + continue; +@@ -1123,7 +1123,7 @@ static int get_pkt(struct autofs_point * + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + "read error on request pipe, " +- "read %u, expected %u error %s", ++ "read %lu, expected %lu error %s", + read, kpkt_len, estr); + } + return read; diff --git a/SOURCES/autofs-5.1.8-add-command-pipe-handling-functions.patch b/SOURCES/autofs-5.1.8-add-command-pipe-handling-functions.patch new file mode 100644 index 0000000..0cd330b --- /dev/null +++ b/SOURCES/autofs-5.1.8-add-command-pipe-handling-functions.patch @@ -0,0 +1,310 @@ +autofs-5.1.8 - add command pipe handling functions + +From: Ian Kent + +In order to use a single file handle for a command pipe the pipe needs +to be independent of the kernel message packet handling function. + +Add most of the functions needed for this as preperation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 270 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -126,6 +126,7 @@ + - eliminate last remaining state_pipe usage. + - add function master_find_mapent_by_devid(). + - use device id to locate autofs_point when setting log priotity. ++- add command pipe handling functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -60,6 +60,14 @@ unsigned int nfs_mount_uses_string_optio + static struct nfs_mount_vers vers, check = {1, 1, 1}; + + #define FIFO_BUF_SIZE 25 ++static int cmd_pipe_fifo = -1; ++ ++/* autofs cmd fifo name */ ++#define FIFO_NAME "autofs.cmd.fifo" ++const char *cmd_pipe_name = AUTOFS_FIFO_DIR "/" FIFO_NAME; ++ ++int start_cmd_pipe_handler(void); ++void finish_cmd_pipe_handler(void); + + /* autofs fifo name prefix */ + #define FIFO_NAME_PREFIX "autofs.fifo" +@@ -1654,6 +1662,267 @@ static void *signal_handler(void *arg) + } + } + ++static pthread_mutex_t cmd_pipe_mutex = PTHREAD_MUTEX_INITIALIZER; ++static unsigned int done = 0; ++static pthread_t cmd_pipe_thid; ++ ++void cmd_pipe_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&cmd_pipe_mutex); ++ if (status) ++ fatal(status); ++} ++ ++void cmd_pipe_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&cmd_pipe_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static int create_cmd_pipe_fifo(void) ++{ ++ char buf[MAX_ERR_BUF]; ++ int ret = -1; ++ int fd; ++ ++ if (cmd_pipe_fifo != -1) ++ return 0; ++ ++ ret = unlink(cmd_pipe_name); ++ if (ret != 0 && errno != ENOENT) { ++ fprintf(stderr, ++ "%s: failed to unlink command pipe. Is the " ++ "automount daemon already running?", program); ++ return ret; ++ } ++ ++ ret = mkfifo(cmd_pipe_name, S_IRUSR|S_IWUSR); ++ if (ret != 0 && errno != EEXIST) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ fprintf(stderr, "%s: mkfifo for %s failed: %s", ++ program, cmd_pipe_name, estr); ++ return ret; ++ } ++ ++ fd = open_fd(cmd_pipe_name, O_RDWR|O_NONBLOCK); ++ if (fd < 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ unlink(cmd_pipe_name); ++ fprintf(stderr, "%s: failed to open cwcommand pipe %s: %s", ++ program, cmd_pipe_name, estr); ++ return -1; ++ } ++ ++ cmd_pipe_fifo = fd; ++ ++ return 0; ++} ++ ++static int destroy_cmd_pipe_fifo(void) ++{ ++ char buf[MAX_ERR_BUF]; ++ int ret = -1; ++ ++ if (cmd_pipe_fifo == -1) ++ return 0; ++ ++ ret = close(cmd_pipe_fifo); ++ if (ret != 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ warn(LOGOPT_ANY, ++ "close for command pipe %s: %s", cmd_pipe_name, estr); ++ } ++ ++ cmd_pipe_fifo = -1; ++ ++ ret = unlink(cmd_pipe_name); ++ if (ret != 0) { ++ warn(LOGOPT_ANY, ++ "failed to unlink FIFO. Was the fifo created OK?"); ++ } ++ ++ return 0; ++} ++ ++static void handle_cmd_pipe_fifo_message(int fd) ++{ ++ struct autofs_point *ap; ++ char buffer[PIPE_BUF]; ++ char *end, *sep; ++ char buf[MAX_ERR_BUF]; ++ dev_t devid; ++ int ret; ++ long pri; ++ ++ memset(buffer, 0, sizeof(buffer)); ++ ret = read(fd, &buffer, sizeof(buffer)); ++ if (ret < 0) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ warn(LOGOPT_ANY, ++ "read on command pipe returned error: %s", estr); ++ return; ++ } ++ ++ sep = strrchr(buffer, ' '); ++ if (!sep) { ++ error(LOGOPT_ANY, ++ "incorrect command pipe message format %s.", buffer); ++ return; ++ } ++ sep++; ++ ++ errno = 0; ++ devid = strtol(buffer, &end, 10); ++ if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) { ++ debug(LOGOPT_ANY, "strtol reported a range error."); ++ error(LOGOPT_ANY, "invalid command pipe message format %s.", buffer); ++ return; ++ } ++ ++ if ((devid == 0 && errno == EINVAL) || end == buffer) { ++ debug(LOGOPT_ANY, "devid id is expected to be a integer."); ++ return; ++ } ++ ++ ap = master_find_mapent_by_devid(master_list, devid); ++ if (!ap) { ++ error(LOGOPT_ANY, "can't locate autofs_point for device id %ld.", devid); ++ return; ++ } ++ ++ errno = 0; ++ pri = strtol(sep, &end, 10); ++ if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) { ++ error(ap->logopt, "failed to set log priority."); ++ error(ap->logopt, "strtol reported an %s.", ++ pri == LONG_MIN ? "underflow" : "overflow"); ++ return; ++ } ++ ++ if ((pri == 0 && errno == EINVAL) || end == sep) { ++ debug(ap->logopt, "priority is expected to be an integer " ++ "in the range 0-7 inclusive."); ++ return; ++ } ++ ++ if (pri > LOG_DEBUG || pri < LOG_EMERG) { ++ debug(ap->logopt, ++ "invalid log priority (%ld) received on fifo", pri); ++ return; ++ } ++ ++ /* ++ * OK, the message passed all of the sanity checks. The ++ * automounter actually only supports three log priorities. ++ * Everything is logged at log level debug, deamon messages ++ * and everything except debug messages are logged with the ++ * verbose setting and only error and critical messages are ++ * logged when debugging isn't enabled. ++ */ ++ if (pri >= LOG_WARNING) { ++ if (pri == LOG_DEBUG) { ++ set_log_debug_ap(ap); ++ info(ap->logopt, "debug logging set for %s", ap->path); ++ } else { ++ set_log_verbose_ap(ap); ++ info(ap->logopt, "verbose logging set for %s", ap->path); ++ } ++ } else { ++ if (ap->logopt & LOGOPT_ANY) ++ info(ap->logopt, "basic logging set for %s", ap->path); ++ set_log_norm_ap(ap); ++ } ++} ++ ++static void cmd_pipe_dummy(int sig) ++{ ++} ++ ++static void *cmd_pipe_handler(void *arg) ++{ ++ struct sigaction sa; ++ sigset_t signalset; ++ struct pollfd fds[1]; ++ int pollfds = 1; ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ ++ if (create_cmd_pipe_fifo()) ++ return NULL; ++ ++ fds[0].fd = cmd_pipe_fifo; ++ fds[0].events = POLLIN; ++ ++ sa.sa_handler = cmd_pipe_dummy; ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = 0; ++ if (sigaction(SIGPIPE, &sa, NULL) == -1) { ++ error(LOGOPT_ANY, "failed to set signal handler %d", errno); ++ return NULL; ++ } ++ ++ sigfillset(&signalset); ++ sigdelset(&signalset, SIGPIPE); ++ ++ while (1) { ++ cmd_pipe_mutex_lock(); ++ if (done) { ++ cmd_pipe_mutex_unlock(); ++ break; ++ } ++ cmd_pipe_mutex_unlock(); ++ ++ errno = 0; ++ if (ppoll(fds, pollfds, NULL, &signalset) == -1) { ++ if (errno == EINTR) ++ continue; ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr("poll failed: %s", estr); ++ return NULL; ++ } ++ ++ if (fds[0].revents & POLLIN) { ++ debug(LOGOPT_ANY, "message pending on control fifo."); ++ handle_cmd_pipe_fifo_message(fds[0].fd); ++ } ++ } ++ destroy_cmd_pipe_fifo(); ++ return NULL; ++} ++ ++int start_cmd_pipe_handler(void) ++{ ++ pthread_t thid; ++ pthread_attr_t attrs; ++ pthread_attr_t *pattrs = &attrs; ++ int status; ++ ++ status = pthread_attr_init(pattrs); ++ if (status) ++ pattrs = NULL; ++ else ++ pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED); ++ ++ status = pthread_create(&thid, pattrs, cmd_pipe_handler, NULL); ++ ++ if (pattrs) ++ pthread_attr_destroy(pattrs); ++ ++ if (!status) ++ cmd_pipe_thid = thid; ++ ++ return !status; ++} ++ ++void finish_cmd_pipe_handler(void) ++{ ++ cmd_pipe_mutex_lock(); ++ done = 1; ++ pthread_kill(cmd_pipe_thid, SIGPIPE); ++ cmd_pipe_mutex_unlock(); ++} ++ + static void return_start_status(void *arg) + { + struct startup_cond *sc; diff --git a/SOURCES/autofs-5.1.8-add-function-master_find_mapent_by_devid.patch b/SOURCES/autofs-5.1.8-add-function-master_find_mapent_by_devid.patch new file mode 100644 index 0000000..75a15f4 --- /dev/null +++ b/SOURCES/autofs-5.1.8-add-function-master_find_mapent_by_devid.patch @@ -0,0 +1,125 @@ +autofs-5.1.8 - add function master_find_mapent_by_devid() + +From: Ian Kent + +Add a helper function that can locate an automount given its device id. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 28 ++++++++++++++++++++++++++++ + include/master.h | 1 + + include/mounts.h | 1 + + lib/mounts.c | 34 ++++++++++++++++++++++++++++++++++ + 5 files changed, 65 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -124,6 +124,7 @@ + - make signal handling consistent. + - fix incorrect print format specifiers in get_pkt(). + - eliminate last remaining state_pipe usage. ++- add function master_find_mapent_by_devid(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -739,6 +739,34 @@ struct master_mapent *master_find_mapent + return NULL; + } + ++struct autofs_point *master_find_mapent_by_devid(struct master *master, dev_t devid) ++{ ++ struct autofs_point *ap = NULL; ++ struct list_head *head, *p; ++ ++ master_mutex_lock(); ++ ++ head = &master->mounts; ++ list_for_each(p, head) { ++ struct master_mapent *entry; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ if (entry->ap->dev == devid) { ++ ap = entry->ap; ++ break; ++ } ++ ++ ap = mnt_find_submount_by_devid(&entry->ap->submounts, devid); ++ if (ap) ++ break; ++ } ++ ++ master_mutex_unlock(); ++ ++ return ap; ++} ++ + static unsigned int master_partial_match_amd_mapent(struct master *master, const char *path) + { + struct list_head *head, *p; +--- autofs-5.1.7.orig/include/master.h ++++ autofs-5.1.7/include/master.h +@@ -110,6 +110,7 @@ void master_source_lock_cleanup(void *); + void master_source_current_wait(struct master_mapent *); + void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); ++struct autofs_point *master_find_mapent_by_devid(struct master *master, dev_t devid); + struct master_mapent *master_new_mapent(struct master *, const char *, time_t); + void master_add_mapent(struct master *, struct master_mapent *); + void master_remove_mapent(struct master_mapent *); +--- autofs-5.1.7.orig/include/mounts.h ++++ autofs-5.1.7/include/mounts.h +@@ -160,6 +160,7 @@ int ext_mount_inuse(const char *); + struct mnt_list *mnts_lookup_mount(const char *mp); + void mnts_put_mount(struct mnt_list *mnt); + struct mnt_list *mnts_find_submount(const char *path); ++struct autofs_point *mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid); + struct mnt_list *mnts_add_submount(struct autofs_point *ap); + void mnts_remove_submount(const char *mp); + struct mnt_list *mnts_find_amdmount(const char *path); +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -1059,6 +1059,40 @@ struct mnt_list *mnts_find_submount(cons + return NULL; + } + ++static struct autofs_point *__mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid) ++{ ++ struct autofs_point *ap = NULL; ++ struct list_head *p; ++ ++ list_for_each(p, submounts) { ++ struct mnt_list *this; ++ ++ this = list_entry(p, struct mnt_list, submount); ++ ++ if (this->ap->dev == devid) { ++ ap = this->ap; ++ break; ++ } ++ ++ ap = mnt_find_submount_by_devid(&this->ap->submounts, devid); ++ if (ap) ++ break; ++ } ++ ++ return ap; ++} ++ ++struct autofs_point *mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid) ++{ ++ struct autofs_point *ap = NULL; ++ ++ mnts_hash_mutex_lock(); ++ ap = __mnt_find_submount_by_devid(submounts, devid); ++ mnts_hash_mutex_unlock(); ++ ++ return ap; ++} ++ + struct mnt_list *mnts_add_submount(struct autofs_point *ap) + { + struct mnt_list *this; diff --git a/SOURCES/autofs-5.1.8-add-ioctlfd-open-helper.patch b/SOURCES/autofs-5.1.8-add-ioctlfd-open-helper.patch new file mode 100644 index 0000000..efb7a2c --- /dev/null +++ b/SOURCES/autofs-5.1.8-add-ioctlfd-open-helper.patch @@ -0,0 +1,270 @@ +autofs-5.1.8 - add ioctlfd open helper + +From: Ian Kent + +Add an ioctl fd open helper, it simplifies the code in some areas. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 25 ++++++++-------- + daemon/indirect.c | 9 ++--- + include/mounts.h | 3 + + lib/mounts.c | 82 ++++++++++++++++++++++++++++++------------------------ + 5 files changed, 68 insertions(+), 52 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -152,6 +152,7 @@ + - fix possible use after free in handle_mounts_exit(). + - make submount cleanup the same as top level mounts. + - add soucre parameter to module functions. ++- add ioctlfd open helper. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -121,7 +121,9 @@ int do_umount_autofs_direct(struct autof + } + ioctlfd = me->ioctlfd; + } else { +- ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); ++ if (ioctlfd == -1) ++ return 1; + opened = 1; + } + +@@ -317,8 +319,7 @@ int do_mount_autofs_direct(struct autofs + save_ioctlfd = ioctlfd = me->ioctlfd; + + if (ioctlfd == -1) +- ops->open(ap->logopt, +- &ioctlfd, me->dev, me->key); ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); + + if (ioctlfd < 0) { + error(ap->logopt, +@@ -416,7 +417,7 @@ int do_mount_autofs_direct(struct autofs + if (ap->mode && (err = chmod(me->key, ap->mode))) + warn(ap->logopt, "failed to change mode of %s", me->key); + +- ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); + if (ioctlfd < 0) { + crit(ap->logopt, "failed to create ioctl fd for %s", me->key); + goto out_umount; +@@ -540,7 +541,9 @@ int umount_autofs_offset(struct autofs_p + me->key); + return 0; + } +- ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); ++ if (ioctlfd == -1) ++ return 1; + opened = 1; + } + +@@ -770,11 +773,9 @@ int mount_autofs_offset(struct autofs_po + me->dev = st.st_dev; + me->ino = st.st_ino; + +- ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); +- if (ioctlfd < 0) { +- crit(ap->logopt, "failed to create ioctl fd for %s", me->key); ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); ++ if (ioctlfd < 0) + goto out_umount; +- } + + ops->timeout(ap->logopt, ioctlfd, timeout); + cache_set_ino_index(me->mc, me); +@@ -1059,9 +1060,9 @@ int handle_packet_expire_direct(struct a + /* Can't expire it if it isn't mounted */ + if (me->ioctlfd == -1) { + int ioctlfd; +- ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); + if (ioctlfd == -1) { +- crit(ap->logopt, "can't open ioctlfd for %s", me->key); + cache_unlock(mc); + master_source_unlock(ap->entry); + pthread_setcancelstate(state, NULL); +@@ -1355,8 +1356,8 @@ int handle_packet_missing_direct(struct + close(me->ioctlfd); + me->ioctlfd = -1; + } +- ops->open(ap->logopt, &ioctlfd, me->dev, me->key); + ++ ioctlfd = open_ioctlfd(ap, me->key, me->dev); + if (ioctlfd == -1) { + cache_unlock(mc); + master_source_unlock(ap->entry); +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/daemon/indirect.c +@@ -124,18 +124,18 @@ static int do_mount_autofs_indirect(stru + "failed to stat mount for autofs path %s", ap->path); + goto out_umount; + } ++ ap->dev = st.st_dev; /* Device number for mount point checks */ + + if (ap->mode && (err = chmod(ap->path, ap->mode))) + warn(ap->logopt, "failed to change mode of %s", ap->path); + +- if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, ap->path)) { ++ ap->ioctlfd = open_ioctlfd(ap, ap->path, ap->dev); ++ if (ap->ioctlfd == -1) { + crit(ap->logopt, + "failed to create ioctl fd for autofs path %s", ap->path); + goto out_umount; + } + +- ap->dev = st.st_dev; /* Device number for mount point checks */ +- + ops->timeout(ap->logopt, ap->ioctlfd, timeout); + notify_mount_result(ap, ap->path, timeout, str_indirect); + +@@ -284,8 +284,7 @@ int umount_autofs_indirect(struct autofs + return 0; + } + #endif +- ops->open(ap->logopt, +- &ap->ioctlfd, ap->dev, ap->path); ++ ap->ioctlfd = open_ioctlfd(ap, ap->path, ap->dev); + if (ap->ioctlfd < 0) { + warn(ap->logopt, + "could not recover autofs path %s", +--- autofs-5.1.7.orig/include/mounts.h ++++ autofs-5.1.7/include/mounts.h +@@ -151,6 +151,9 @@ void free_amd_entry_list(struct list_hea + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); ++ ++int open_ioctlfd(struct autofs_point *ap, const char *path, dev_t dev); ++ + char *make_options_string(char *path, int pipefd, + const char *type, unsigned int flags); + char *make_mnt_name_string(char *path); +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -231,6 +231,32 @@ unsigned int get_kver_minor(void) + return kver.minor; + } + ++int open_ioctlfd(struct autofs_point *ap, const char *path, dev_t dev) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ int fd = -1; ++ int error; ++ ++ error = ops->open(ap->logopt, &fd, dev, path); ++ if (error == -1) { ++ char buf[MAX_ERR_BUF]; ++ int err = errno; ++ char *estr; ++ ++ if (errno == ENOENT) ++ return -1; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to open ioctlfd for %s, error: %s", ++ path, estr); ++ errno = err; ++ return -1; ++ } ++ ++ return fd; ++} ++ + #ifdef HAVE_MOUNT_NFS + static int extract_version(char *start, struct nfs_mount_vers *vers) + { +@@ -2719,7 +2745,7 @@ static int remount_active_mount(struct a + *ioctlfd = -1; + + /* Open failed, no mount present */ +- ops->open(ap->logopt, &fd, devid, path); ++ fd = open_ioctlfd(ap, path, devid); + if (fd == -1) + return REMOUNT_OPEN_FAIL; + +@@ -2918,10 +2944,9 @@ static int set_mount_catatonic(struct au + { + struct ioctl_ops *ops = get_ioctl_ops(); + unsigned int opened = 0; +- char buf[MAX_ERR_BUF]; +- char *path; +- int fd = -1; +- int error; ++ const char *path; ++ int fd; ++ int err; + dev_t dev; + + path = ap->path; +@@ -2936,44 +2961,31 @@ static int set_mount_catatonic(struct au + else if (me && me->ioctlfd >= 0) + fd = me->ioctlfd; + else { +- error = ops->open(ap->logopt, &fd, dev, path); +- if (error == -1) { +- int err = errno; +- char *estr; +- +- if (errno == ENOENT) +- return 0; +- +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, +- "failed to open ioctlfd for %s, error: %s", +- path, estr); +- return err; +- } ++ fd = open_ioctlfd(ap, path, dev); ++ if (fd == -1) ++ return (errno == ENOENT ? 0 : errno); + opened = 1; + } + +- if (fd >= 0) { +- error = ops->catatonic(ap->logopt, fd); +- if (error == -1) { +- int err = errno; +- char *estr; ++ err = ops->catatonic(ap->logopt, fd); ++ if (err == -1) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; + +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, +- "failed to set %s catatonic, error: %s", +- path, estr); +- if (opened) +- ops->close(ap->logopt, fd); +- return err; +- } +- if (opened) +- ops->close(ap->logopt, fd); ++ err = errno; ++ estr = strerror_r(err, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to set %s catatonic, error: %s", ++ path, estr); ++ goto out; + } + + debug(ap->logopt, "set %s catatonic", path); ++out: ++ if (opened) ++ ops->close(ap->logopt, fd); + +- return 0; ++ return err; + } + + static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr) diff --git a/SOURCES/autofs-5.1.8-add-soucre-parameter-to-module-functions.patch b/SOURCES/autofs-5.1.8-add-soucre-parameter-to-module-functions.patch new file mode 100644 index 0000000..89bd55d --- /dev/null +++ b/SOURCES/autofs-5.1.8-add-soucre-parameter-to-module-functions.patch @@ -0,0 +1,1105 @@ +autofs-5.1.8 - add soucre parameter to module functions + +From: Ian Kent + +There's a unnecessarily complicated method used to pass the map source +to module read map and lookup mount functions. This also confuses +coverity which constantly complains about unmatched locking. + +Just add a parameter to those functions to simplify it and elliminate +the coverity false positives not to mention slightly less overhead by +the lock removal. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/lookup.c | 10 +------ + daemon/master.c | 57 ---------------------------------------- + include/automount.h | 16 ++++++----- + include/master.h | 4 -- + modules/lookup_dir.c | 8 +---- + modules/lookup_file.c | 29 +++++--------------- + modules/lookup_hesiod.c | 15 ++-------- + modules/lookup_hosts.c | 36 +++++++------------------ + modules/lookup_ldap.c | 35 ++++++++----------------- + modules/lookup_multi.c | 24 ++++------------- + modules/lookup_nisplus.c | 27 +++++-------------- + modules/lookup_program.c | 29 +++++--------------- + modules/lookup_sss.c | 64 ++++++++++------------------------------------ + modules/lookup_userhome.c | 16 ++--------- + modules/lookup_yp.c | 35 ++++++++----------------- + modules/parse_amd.c | 16 +++-------- + modules/parse_hesiod.c | 8 ++--- + modules/parse_sun.c | 15 +++------- + 19 files changed, 112 insertions(+), 333 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -151,6 +151,7 @@ + - eliminate buffer usage from handle_mounts_cleanup(). + - fix possible use after free in handle_mounts_exit(). + - make submount cleanup the same as top level mounts. ++- add soucre parameter to module functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/lookup.c ++++ autofs-5.1.7/daemon/lookup.c +@@ -361,13 +361,10 @@ static int do_read_map(struct autofs_poi + map_module_unlock(map); + } + +- master_source_current_wait(ap->entry); +- ap->entry->current = map; +- + pthread_cleanup_push(map_module_lock_cleanup, map); + map_module_readlock(map); + lookup = map->lookup; +- status = lookup->lookup_read_map(ap, age, lookup->context); ++ status = lookup->lookup_read_map(ap, map, age, lookup->context); + pthread_cleanup_pop(1); + + if (status != NSS_STATUS_SUCCESS) +@@ -829,12 +826,9 @@ int do_lookup_mount(struct autofs_point + map_module_unlock(map); + } + +- master_source_current_wait(ap->entry); +- ap->entry->current = map; +- + map_module_readlock(map); + lookup = map->lookup; +- status = lookup->lookup_mount(ap, name, name_len, lookup->context); ++ status = lookup->lookup_mount(ap, map, name, name_len, lookup->context); + map_module_unlock(map); + + return status; +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -682,47 +682,6 @@ void master_source_lock_cleanup(void *ar + return; + } + +-void master_source_current_wait(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_mutex_lock(&entry->current_mutex); +- if (status) { +- logmsg("entry current source lock failed"); +- fatal(status); +- } +- +- while (entry->current != NULL) { +- status = pthread_cond_wait( +- &entry->current_cond, &entry->current_mutex); +- if (status) { +- logmsg("entry current source condition wait failed"); +- fatal(status); +- } +- } +- +- return; +-} +- +-void master_source_current_signal(struct master_mapent *entry) +-{ +- int status; +- +- status = pthread_cond_signal(&entry->current_cond); +- if (status) { +- logmsg("entry current source condition signal failed"); +- fatal(status); +- } +- +- status = pthread_mutex_unlock(&entry->current_mutex); +- if (status) { +- logmsg("entry current source unlock failed"); +- fatal(status); +- } +- +- return; +-} +- + struct master_mapent *master_find_mapent(struct master *master, const char *path) + { + struct list_head *head, *p; +@@ -845,14 +804,6 @@ struct master_mapent *master_new_mapent( + if (status) + fatal(status); + +- status = pthread_mutex_init(&entry->current_mutex, NULL); +- if (status) +- fatal(status); +- +- status = pthread_cond_init(&entry->current_cond, NULL); +- if (status) +- fatal(status); +- + INIT_LIST_HEAD(&entry->list); + + return entry; +@@ -920,14 +871,6 @@ void master_free_mapent(struct master_ma + if (status) + fatal(status); + +- status = pthread_mutex_destroy(&entry->current_mutex); +- if (status) +- fatal(status); +- +- status = pthread_cond_destroy(&entry->current_cond); +- if (status) +- fatal(status); +- + free(entry); + + return; +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -282,15 +282,15 @@ int lookup_source_close_ioctlfd(struct a + int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context); + int lookup_reinit(const char *mapfmt, int argc, const char *const *argv, void **context); + int lookup_read_master(struct master *master, time_t age, void *context); +-int lookup_read_map(struct autofs_point *, time_t, void *context); +-int lookup_mount(struct autofs_point *, const char *, int, void *); ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context); ++int lookup_mount(struct autofs_point *, struct map_source *map, const char *name, int name_len, void *context); + int lookup_done(void *); + #endif + typedef int (*lookup_init_t) (const char *, int, const char *const *, void **); + typedef int (*lookup_reinit_t) (const char *, int, const char *const *, void **); + typedef int (*lookup_read_master_t) (struct master *master, time_t, void *); +-typedef int (*lookup_read_map_t) (struct autofs_point *, time_t, void *); +-typedef int (*lookup_mount_t) (struct autofs_point *, const char *, int, void *); ++typedef int (*lookup_read_map_t) (struct autofs_point *, struct map_source *, time_t, void *); ++typedef int (*lookup_mount_t) (struct autofs_point *, struct map_source *, const char *, int, void *); + typedef int (*lookup_done_t) (void *); + + struct lookup_mod { +@@ -319,13 +319,15 @@ int close_lookup(struct lookup_mod *); + #ifdef MODULE_PARSE + int parse_init(int argc, const char *const *argv, void **context); + int parse_reinit(int argc, const char *const *argv, void **context); +-int parse_mount(struct autofs_point *ap, const char *name, +- int name_len, const char *mapent, void *context); ++int parse_mount(struct autofs_point *ap, struct map_source *map, ++ const char *name, int name_len, const char *mapent, ++ void *context); + int parse_done(void *); + #endif + typedef int (*parse_init_t) (int, const char *const *, void **); + typedef int (*parse_reinit_t) (int, const char *const *, void **); +-typedef int (*parse_mount_t) (struct autofs_point *, const char *, int, const char *, void *); ++typedef int (*parse_mount_t) (struct autofs_point *, struct map_source *, ++ const char *, int, const char *, void *); + typedef int (*parse_done_t) (void *); + + struct parse_mod { +--- autofs-5.1.7.orig/include/master.h ++++ autofs-5.1.7/include/master.h +@@ -49,8 +49,6 @@ struct master_mapent { + time_t age; + struct master *master; + pthread_rwlock_t source_lock; +- pthread_mutex_t current_mutex; +- pthread_cond_t current_cond; + struct map_source *current; + struct map_source *maps; + struct autofs_point *ap; +@@ -106,8 +104,6 @@ void master_source_writelock(struct mast + void master_source_readlock(struct master_mapent *); + void master_source_unlock(struct master_mapent *); + void master_source_lock_cleanup(void *); +-void master_source_current_wait(struct master_mapent *); +-void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); + struct autofs_point *master_find_mapent_by_devid(struct master *master, dev_t devid); + struct master_mapent *master_new_mapent(struct master *, const char *, time_t); +--- autofs-5.1.7.orig/modules/lookup_dir.c ++++ autofs-5.1.7/modules/lookup_dir.c +@@ -225,17 +225,13 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_SUCCESS; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); + return NSS_STATUS_UNKNOWN; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); + return NSS_STATUS_UNKNOWN; + } + +--- autofs-5.1.7.orig/modules/lookup_file.c ++++ autofs-5.1.7/modules/lookup_file.c +@@ -689,23 +689,17 @@ prepare_plus_include(struct autofs_point + return new; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + char key[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; + FILE *f; + unsigned int k_len, m_len; + int entry; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + if (source->recurse) + return NSS_STATUS_TRYAGAIN; + +@@ -1128,11 +1122,11 @@ static int map_update_needed(struct auto + return ret; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + int key_len; +@@ -1143,12 +1137,6 @@ int lookup_mount(struct autofs_point *ap + int status = 0; + int ret = 1; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + if (source->recurse) + return NSS_STATUS_UNAVAIL; + +@@ -1282,10 +1270,7 @@ do_cache_lookup: + + free(lkp_key); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, key, key_len, ++ ret = ctxt->parse->parse_mount(ap, source, key, key_len, + mapent, ctxt->parse->context); + if (ret) { + /* Don't update negative cache when re-connecting */ +--- autofs-5.1.7.orig/modules/lookup_hesiod.c ++++ autofs-5.1.7/modules/lookup_hesiod.c +@@ -160,11 +160,8 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + return NSS_STATUS_UNKNOWN; + } + +@@ -360,11 +357,11 @@ done: + return ret; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; + char buf[MAX_ERR_BUF]; +- struct map_source *source; ++ struct map_source *source = map; + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + size_t key_len; +@@ -373,10 +370,6 @@ int lookup_mount(struct autofs_point *ap + char *mapent; + int rv; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + debug(ap->logopt, + MODPREFIX "looking up root=\"%s\", name=\"%s\"", + ap->path, name); +@@ -468,7 +461,7 @@ int lookup_mount(struct autofs_point *ap + + free(lkp_key); + +- rv = ctxt->parser->parse_mount(ap, key, key_len, ++ rv = ctxt->parser->parse_mount(ap, source, key, key_len, + mapent, ctxt->parser->context); + free(mapent); + +--- autofs-5.1.7.orig/modules/lookup_hosts.c ++++ autofs-5.1.7/modules/lookup_hosts.c +@@ -182,10 +182,7 @@ static int do_parse_mount(struct autofs_ + { + int ret; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, name, name_len, ++ ret = ctxt->parse->parse_mount(ap, source, name, name_len, + mapent, ctxt->parse->context); + if (ret) { + struct mapent_cache *mc = source->mc; +@@ -312,11 +309,10 @@ next: + debug(ap->logopt, MODPREFIX + "attempt to update exports for %s", entries->key); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; + ap->flags |= MOUNT_FLAG_REMOUNT; +- ret = ctxt->parse->parse_mount(ap, entries->key, strlen(entries->key), +- entries->entry, ctxt->parse->context); ++ ret = ctxt->parse->parse_mount(ap, source, entries->key, ++ strlen(entries->key), entries->entry, ++ ctxt->parse->context); + if (ret) + warn(ap->logopt, MODPREFIX + "failed to parse mount %s", entries->entry); +@@ -326,20 +322,14 @@ next: + pthread_cleanup_pop(1); + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct hostent *host; + int status; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "read hosts map"); + + /* +@@ -381,23 +371,17 @@ int lookup_read_map(struct autofs_point + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct mapent *me; + char *mapent = NULL; + int mapent_len; + time_t now = monotonic_time(NULL); + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +--- autofs-5.1.7.orig/modules/lookup_ldap.c ++++ autofs-5.1.7/modules/lookup_ldap.c +@@ -83,6 +83,8 @@ struct ldap_search_params { + + static int decode_percent_hack(const char *, char **); + ++pthread_mutex_t defaults_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + #ifdef WITH_SASL + static int set_env(unsigned logopt, const char *name, const char *val) + { +@@ -2935,17 +2937,13 @@ static int read_one_map(struct autofs_po + return NSS_STATUS_SUCCESS; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; ++ struct map_source *source = map; + int rv = LDAP_SUCCESS; + int ret, cur_state; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ret = read_one_map(ap, source, ctxt, age, &rv); + if (ret != NSS_STATUS_SUCCESS) { +@@ -3558,7 +3556,7 @@ static int check_map_indirect(struct aut + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + +- status = pthread_mutex_lock(&ap->entry->current_mutex); ++ status = pthread_mutex_lock(&defaults_mutex); + if (status) + fatal(status); + if (is_amd_format) { +@@ -3580,7 +3578,7 @@ static int check_map_indirect(struct aut + ctxt->check_defaults = 0; + } + } +- status = pthread_mutex_unlock(&ap->entry->current_mutex); ++ status = pthread_mutex_unlock(&defaults_mutex); + if (status) + fatal(status); + +@@ -3627,12 +3625,12 @@ static int check_map_indirect(struct aut + } + cache_unlock(mc); + +- status = pthread_mutex_lock(&ap->entry->current_mutex); ++ status = pthread_mutex_lock(&defaults_mutex); + if (status) + fatal(status); + if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED) + source->stale = 1; +- status = pthread_mutex_unlock(&ap->entry->current_mutex); ++ status = pthread_mutex_unlock(&defaults_mutex); + if (status) + fatal(status); + } +@@ -3648,11 +3646,11 @@ static int check_map_indirect(struct aut + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + int key_len; +@@ -3663,12 +3661,6 @@ int lookup_mount(struct autofs_point *ap + int status = 0; + int ret = 1; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "looking up %s", name); + + if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { +@@ -3797,10 +3789,7 @@ int lookup_mount(struct autofs_point *ap + + free(lkp_key); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, key, key_len, ++ ret = ctxt->parse->parse_mount(ap, source, key, key_len, + mapent, ctxt->parse->context); + if (ret) { + /* Don't update negative cache when re-connecting */ +--- autofs-5.1.7.orig/modules/lookup_multi.c ++++ autofs-5.1.7/modules/lookup_multi.c +@@ -525,20 +525,14 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; ++ struct map_source *source = map; + int i, ret, at_least_1 = 0; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + for (i = 0; i < ctxt->n; i++) { +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- ret = ctxt->m[i].mod->lookup_read_map(ap, age, ++ ret = ctxt->m[i].mod->lookup_read_map(ap, source, age, + ctxt->m[i].mod->context); + if (ret & LKP_FAIL || ret == LKP_NOTSUP) + continue; +@@ -552,20 +546,14 @@ int lookup_read_map(struct autofs_point + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; ++ struct map_source *source = map; + int i; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + for (i = 0; i < ctxt->n; i++) { +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- if (ctxt->m[i].mod->lookup_mount(ap, name, name_len, ++ if (ctxt->m[i].mod->lookup_mount(ap, source, name, name_len, + ctxt->m[i].mod->context) == 0) + return NSS_STATUS_SUCCESS; + } +--- autofs-5.1.7.orig/modules/lookup_nisplus.c ++++ autofs-5.1.7/modules/lookup_nisplus.c +@@ -220,11 +220,11 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_SUCCESS; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + char *tablename; + nis_result *result; + nis_object *this; +@@ -233,10 +233,6 @@ int lookup_read_map(struct autofs_point + char buf[MAX_ERR_BUF]; + int cur_state; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + /* + * If we don't need to create directories (or don't need + * to read an amd cache:=all map) then there's no use +@@ -670,11 +666,11 @@ static int check_map_indirect(struct aut + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + char key[KEY_MAX_LEN + 1]; + int key_len; + char *lkp_key; +@@ -685,12 +681,6 @@ int lookup_mount(struct autofs_point *ap + int status; + int ret = 1; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "looking up %s", name); + + if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { +@@ -821,10 +811,7 @@ int lookup_mount(struct autofs_point *ap + + free(lkp_key); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, key, key_len, ++ ret = ctxt->parse->parse_mount(ap, source, key, key_len, + mapent, ctxt->parse->context); + if (ret) { + free(mapent); +--- autofs-5.1.7.orig/modules/lookup_program.c ++++ autofs-5.1.7/modules/lookup_program.c +@@ -166,11 +166,8 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + return NSS_STATUS_UNKNOWN; + } + +@@ -580,21 +577,15 @@ static int match_key(struct autofs_point + return ret; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + char *mapent = NULL; + struct mapent *me; + int ret = 1; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +@@ -644,10 +635,9 @@ int lookup_mount(struct autofs_point *ap + 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, ent, ctxt->parse->context); ++ ret = ctxt->parse->parse_mount(ap, source, ++ name, name_len, ent, ++ ctxt->parse->context); + if (ent) + free(ent); + goto out_free; +@@ -679,10 +669,7 @@ int lookup_mount(struct autofs_point *ap + + debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, name, name_len, ++ ret = ctxt->parse->parse_mount(ap, source, name, name_len, + mapent, ctxt->parse->context); + out_free: + if (mapent) +--- autofs-5.1.7.orig/modules/lookup_sss.c ++++ autofs-5.1.7/modules/lookup_sss.c +@@ -771,23 +771,17 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_SUCCESS; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + void *sss_ctxt = NULL; + char *key; + char *value = NULL; + char *s_key; + int count, ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + /* + * If we don't need to create directories (or don't need + * to read an amd cache:=all map) then there's no use +@@ -873,11 +867,10 @@ int lookup_read_map(struct autofs_point + return NSS_STATUS_SUCCESS; + } + +-static int lookup_one(struct autofs_point *ap, +- char *qKey, int qKey_len, struct lookup_context *ctxt) ++static int lookup_one(struct autofs_point *ap, struct map_source *source, ++ char *qKey, int qKey_len, struct lookup_context *ctxt) + { +- struct map_source *source; +- struct mapent_cache *mc; ++ struct mapent_cache *mc = source->mc; + struct mapent *we; + void *sss_ctxt = NULL; + time_t age = monotonic_time(NULL); +@@ -885,12 +878,6 @@ static int lookup_one(struct autofs_poin + char *s_key; + int err, ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + ret = setautomntent(ap->logopt, ctxt, &sss_ctxt, SSS_LOOKUP_KEY); + if (ret) + return ret; +@@ -983,24 +970,14 @@ wild: + } + + static int check_map_indirect(struct autofs_point *ap, +- char *key, int key_len, ++ struct map_source *source, char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; +- struct mapent_cache *mc; ++ struct mapent_cache *mc = source->mc; + int ret, cur_state; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = lookup_one(ap, key, key_len, ctxt); ++ ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret == NSS_STATUS_NOTFOUND) { + pthread_setcancelstate(cur_state, NULL); + return ret; +@@ -1026,11 +1003,11 @@ static int check_map_indirect(struct aut + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + int key_len; +@@ -1038,12 +1015,6 @@ int lookup_mount(struct autofs_point *ap + char mapent_buf[MAPENT_MAX_LEN + 1]; + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "looking up %s", name); + + key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); +@@ -1078,10 +1049,7 @@ int lookup_mount(struct autofs_point *ap + if (!lkp_key) + return NSS_STATUS_UNKNOWN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); ++ status = check_map_indirect(ap, source, lkp_key, strlen(lkp_key), ctxt); + free(lkp_key); + if (status) + return status; +@@ -1128,11 +1096,9 @@ int lookup_mount(struct autofs_point *ap + if (!mapent) + return NSS_STATUS_TRYAGAIN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- + debug(ap->logopt, MODPREFIX "%s -> %s", key, mapent); +- ret = ctxt->parse->parse_mount(ap, key, key_len, ++ ++ ret = ctxt->parse->parse_mount(ap, source, key, key_len, + mapent, ctxt->parse->context); + if (ret) { + /* Don't update negative cache when re-connecting */ +--- autofs-5.1.7.orig/modules/lookup_userhome.c ++++ autofs-5.1.7/modules/lookup_userhome.c +@@ -46,27 +46,19 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); + return NSS_STATUS_UNKNOWN; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct passwd *pw; + char buf[MAX_ERR_BUF]; + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "looking up %s", name); + + /* Get the equivalent username */ +--- autofs-5.1.7.orig/modules/lookup_yp.c ++++ autofs-5.1.7/modules/lookup_yp.c +@@ -59,6 +59,8 @@ struct callback_data { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + ++static pthread_mutex_t defaults_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + static unsigned int get_map_order(const char *domain, const char *map) + { + char key[] = "YP_LAST_MODIFIED"; +@@ -392,20 +394,16 @@ int yp_all_callback(int status, char *yp + return 0; + } + +-int lookup_read_map(struct autofs_point *ap, time_t age, void *context) ++int lookup_read_map(struct autofs_point *ap, struct map_source *map, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; + struct ypall_callback ypcb; + struct callback_data ypcb_data; + unsigned int logopt = ap->logopt; +- struct map_source *source; ++ struct map_source *source = map; + char *mapname; + int err; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + /* + * If we don't need to create directories (or don't need + * to read an amd cache:=all map) then there's no use +@@ -457,9 +455,9 @@ int lookup_read_map(struct autofs_point + } + + source->age = age; +- pthread_mutex_lock(&ap->entry->current_mutex); ++ pthread_mutex_lock(&defaults_mutex); + ctxt->check_defaults = 0; +- pthread_mutex_unlock(&ap->entry->current_mutex); ++ pthread_mutex_unlock(&defaults_mutex); + + return NSS_STATUS_SUCCESS; + } +@@ -685,7 +683,7 @@ static int check_map_indirect(struct aut + mc = source->mc; + + /* Only read map if it has been modified */ +- pthread_mutex_lock(&ap->entry->current_mutex); ++ pthread_mutex_lock(&defaults_mutex); + map_order = get_map_order(ctxt->domainname, ctxt->mapname); + if (map_order > ctxt->order) { + ctxt->order = map_order; +@@ -702,7 +700,7 @@ static int check_map_indirect(struct aut + } else + ctxt->check_defaults = 0; + } +- pthread_mutex_unlock(&ap->entry->current_mutex); ++ pthread_mutex_unlock(&defaults_mutex); + + /* check map and if change is detected re-read map */ + ret = match_key(ap, source, key, key_len, ctxt); +@@ -782,11 +780,11 @@ static int check_map_indirect(struct aut + return NSS_STATUS_SUCCESS; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++int lookup_mount(struct autofs_point *ap, struct map_source *map, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + char key[KEY_MAX_LEN + 1]; + int key_len; + char *lkp_key; +@@ -797,12 +795,6 @@ int lookup_mount(struct autofs_point *ap + int status = 0; + int ret = 1; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + debug(ap->logopt, MODPREFIX "looking up %s", name); + + if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { +@@ -939,10 +931,7 @@ int lookup_mount(struct autofs_point *ap + + free(lkp_key); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = ctxt->parse->parse_mount(ap, key, key_len, ++ ret = ctxt->parse->parse_mount(ap, source, key, key_len, + mapent, ctxt->parse->context); + free(mapent); + if (ret) { +--- autofs-5.1.7.orig/modules/parse_amd.c ++++ autofs-5.1.7/modules/parse_amd.c +@@ -1383,12 +1383,9 @@ static int do_host_mount(struct autofs_p + cache_push_mapent(me, NULL); + cache_unlock(source->mc); + +- master_source_current_wait(ap->entry); +- ap->entry->current = instance; +- + map_module_readlock(instance); + lookup = instance->lookup; +- ret = lookup->lookup_mount(ap, entry->rhost, ++ ret = lookup->lookup_mount(ap, instance, entry->rhost, + strlen(entry->rhost), lookup->context); + map_module_unlock(instance); + +@@ -2203,13 +2200,14 @@ done: + return defaults_entry; + } + +-int parse_mount(struct autofs_point *ap, const char *name, +- int name_len, const char *mapent, void *context) ++int parse_mount(struct autofs_point *ap, struct map_source *map, ++ const char *name, int name_len, const char *mapent, ++ void *context) + { + struct parse_context *ctxt = (struct parse_context *) context; + unsigned int flags = conf_amd_get_flags(ap->path); + struct substvar *sv = NULL; +- struct map_source *source; ++ struct map_source *source = map; + unsigned int at_least_one; + struct list_head entries, *p, *head; + struct amd_entry *defaults_entry; +@@ -2219,10 +2217,6 @@ int parse_mount(struct autofs_point *ap, + int cur_state; + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + if (!mapent) { + warn(ap->logopt, MODPREFIX "error: empty map entry"); + return 1; +--- autofs-5.1.7.orig/modules/parse_hesiod.c ++++ autofs-5.1.7/modules/parse_hesiod.c +@@ -272,8 +272,9 @@ int parse_done(void *context) + return 0; + } + +-int parse_mount(struct autofs_point *ap, const char *name, +- int name_len, const char *mapent, void *context) ++int parse_mount(struct autofs_point *ap, struct map_source *map, ++ const char *name, int name_len, const char *mapent, ++ void *context) + { + char source[HESIOD_LEN + 1]; + char fstype[HESIOD_LEN + 1]; +@@ -282,9 +283,6 @@ int parse_mount(struct autofs_point *ap, + const char *p; + int ret; + +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + p = mapent; + q = fstype; + +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -1310,13 +1310,14 @@ static void cleanup_offset_entries(struc + * level nexting point. Finally to mount non multi-mounts and to mount a + * lower level multi-mount nesting point and its offsets. + */ +-int parse_mount(struct autofs_point *ap, const char *name, +- int name_len, const char *mapent, void *context) ++int parse_mount(struct autofs_point *ap, struct map_source *map, ++ const char *name, int name_len, const char *mapent, ++ void *context) + { + struct parse_context *ctxt = (struct parse_context *) context; + char buf[MAX_ERR_BUF]; +- struct map_source *source; +- struct mapent_cache *mc; ++ struct map_source *source = map; ++ struct mapent_cache *mc = source->mc; + struct mapent *me, *oe, *tmp; + LIST_HEAD(offsets); + char *pmapent, *options; +@@ -1326,12 +1327,6 @@ int parse_mount(struct autofs_point *ap, + int slashify = ctxt->slashify_colons; + unsigned int append_options; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + if (!mapent) { + warn(ap->logopt, MODPREFIX "error: empty map entry"); + return 1; diff --git a/SOURCES/autofs-5.1.8-change-to-use-printf-functions-in-amd-parser.patch b/SOURCES/autofs-5.1.8-change-to-use-printf-functions-in-amd-parser.patch new file mode 100644 index 0000000..beeaa68 --- /dev/null +++ b/SOURCES/autofs-5.1.8-change-to-use-printf-functions-in-amd-parser.patch @@ -0,0 +1,144 @@ +autofs-5.1.8 - change to use printf functions in amd parser + +From: Ian Kent + +Change to use the printf(3) functions in the amd parser rather than +string functions. These functions seem to have less overhead and they +are a little more compact. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 45 +++++++++++++++++---------------------------- + 2 files changed, 18 insertions(+), 28 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -145,6 +145,7 @@ + - get rid of strlen call in handle_packet_missing_direct(). + - remove redundant stat call in lookup_ghost(). + - set mapent dev and ino before adding to index. ++- change to use printf functions in amd parser. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/parse_amd.c ++++ autofs-5.1.7/modules/parse_amd.c +@@ -170,11 +170,9 @@ static struct substvar *add_lookup_vars( + + if (*key == '/') + strcpy(path, key); +- else { +- strcpy(path, ap->path); +- strcat(path, "/"); +- strcat(path, key); +- } ++ else ++ sprintf(path, "%s/%s", ap->path, key); ++ + list = macro_addvar(list, "path", 4, path); + + me = cache_lookup_distinct(source->mc, lkp_key); +@@ -1067,24 +1065,23 @@ static int do_auto_mount(struct autofs_p + struct amd_entry *entry, unsigned int flags) + { + char target[PATH_MAX + 1]; ++ int len; + + if (!entry->map_type) { +- if (strlen(entry->fs) > PATH_MAX) { ++ len = snprintf(target, PATH_MAX, "%s", entry->fs); ++ if (len > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: fs option length is too long"); + return 0; + } +- strcpy(target, entry->fs); + } else { +- if (strlen(entry->fs) + +- strlen(entry->map_type) + 5 > PATH_MAX) { ++ len = snprintf(target, PATH_MAX, ++ "%s,amd:%s", entry->map_type, entry->fs); ++ if (len > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: fs + maptype options length is too long"); + return 0; + } +- strcpy(target, entry->map_type); +- strcat(target, ",amd:"); +- strcat(target, entry->fs); + } + + return do_mount(ap, ap->path, +@@ -1207,17 +1204,15 @@ static int do_nfs_mount(struct autofs_po + char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; + unsigned int umount = 0; + int ret = 0; ++ int len; + +- if (strlen(entry->rhost) + strlen(entry->rfs) + 1 > PATH_MAX) { ++ len = snprintf(target, PATH_MAX, "%s:%s", entry->rhost, entry->rfs); ++ if (len > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: rhost + rfs options length is too long"); + return 1; + } + +- strcpy(target, entry->rhost); +- strcat(target, ":"); +- strcat(target, entry->rfs); +- + proximity = get_network_proximity(entry->rhost); + if (proximity == PROXIMITY_OTHER && entry->remopts && *entry->remopts) + opts = entry->remopts; +@@ -1319,7 +1314,7 @@ static int do_host_mount(struct autofs_p + */ + if (strcmp(name, entry->rhost)) { + char *target; +- size_t len; ++ int len; + + len = ap->len + strlen(entry->rhost) + 2; + target = malloc(len); +@@ -1328,9 +1323,7 @@ static int do_host_mount(struct autofs_p + "failed to alloc target to hosts mount base"); + goto out; + } +- strcpy(target, ap->path); +- strcat(target, "/"); +- strcat(target, entry->rhost); ++ sprintf(target, "%s/%s", ap->path, entry->rhost); + if (entry->path) + free(entry->path); + entry->path = target; +@@ -1819,7 +1812,7 @@ static void normalize_sublink(unsigned i + struct amd_entry *entry, struct substvar *sv) + { + char *new; +- size_t len; ++ int len; + + /* Normalizing sublink requires a non-blank fs option */ + if (!*entry->fs) +@@ -1833,9 +1826,7 @@ static void normalize_sublink(unsigned i + "error: couldn't allocate storage for sublink"); + return; + } +- strcpy(new, entry->fs); +- strcat(new, "/"); +- strcat(new, entry->sublink); ++ sprintf(new, "%s/%s", entry->fs, entry->sublink); + debug(logopt, MODPREFIX + "rfs dequote(\"%.*s\") -> %s", + strlen(entry->sublink), entry->sublink, new); +@@ -1866,9 +1857,7 @@ static void update_prefix(struct autofs_ + len = strlen(ap->pref) + strlen(name) + 2; + new = malloc(len); + if (new) { +- strcpy(new, ap->pref); +- strcat(new, name); +- strcat(new, "/"); ++ sprintf(new, "%s%s/", ap->pref, name); + entry->pref = new; + } + } diff --git a/SOURCES/autofs-5.1.8-continue-expire-immediately-after-submount-check.patch b/SOURCES/autofs-5.1.8-continue-expire-immediately-after-submount-check.patch new file mode 100644 index 0000000..c4e1669 --- /dev/null +++ b/SOURCES/autofs-5.1.8-continue-expire-immediately-after-submount-check.patch @@ -0,0 +1,56 @@ +autofs-5.1.8 - continue expire immediately after submount check + +From: Ian Kent + +The expire proc for both direct and indirect mounts doesn't immediately +continue after seeing an autofs submount and sending it a notification. + +Add the "continue" to avoid some wasted overhead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 5 ++++- + daemon/indirect.c | 5 ++++- + 3 files changed, 9 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -137,6 +137,7 @@ + - include addtional log info for mounts. + - fix amd selector function matching. + - get rid entry thid field. ++- continue expire immediately after submount check. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -854,8 +854,11 @@ void *expire_proc_direct(void *arg) + * one of them and pass on state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (mnt->flags & MNTS_AUTOFS) ++ if (mnt->flags & MNTS_AUTOFS) { + master_notify_submount(ap, mnt->mp, ap->state); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } + + if (me->ioctlfd == -1) { + pthread_setcancelstate(cur_state, NULL); +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/daemon/indirect.c +@@ -392,8 +392,11 @@ void *expire_proc_indirect(void *arg) + * one of them and pass on the state change. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- if (mnt->flags & MNTS_AUTOFS) ++ if (mnt->flags & MNTS_AUTOFS) { + master_notify_submount(ap, mnt->mp, ap->state); ++ pthread_setcancelstate(cur_state, NULL); ++ continue; ++ } + + /* An offset without a real mount, check for manual umount */ + if (mnt->flags & MNTS_OFFSET && diff --git a/SOURCES/autofs-5.1.8-dont-call-umount_subtree_mounts-on-parent-at-umount.patch b/SOURCES/autofs-5.1.8-dont-call-umount_subtree_mounts-on-parent-at-umount.patch new file mode 100644 index 0000000..8c1d350 --- /dev/null +++ b/SOURCES/autofs-5.1.8-dont-call-umount_subtree_mounts-on-parent-at-umount.patch @@ -0,0 +1,40 @@ +autofs-5.1.8 - dont call umount_subtree_mounts() on parent at umount + +From: Ian Kent + +There shouldn't be any multi-mount offsets mounted within a submount +because the submount will be a nesting point and offsets will be mounted +within it when it gets mounted and expired before it's umounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ------- + 2 files changed, 1 insertion(+), 7 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -146,6 +146,7 @@ + - remove redundant stat call in lookup_ghost(). + - set mapent dev and ino before adding to index. + - change to use printf functions in amd parser. ++- dont call umount_subtree_mounts() on parent at umount. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -706,13 +706,6 @@ int umount_multi(struct autofs_point *ap + + left = 0; + +- /* +- * If we are a submount we need to umount any offsets our +- * parent may have mounted over top of us. +- */ +- if (ap->submount) +- left += umount_subtree_mounts(ap->parent, path, 1); +- + left += umount_subtree_mounts(ap, path, is_autofs_fs); + + /* Delete detritus like unwanted mountpoints and symlinks */ diff --git a/SOURCES/autofs-5.1.8-dont-close-lookup-at-umount.patch b/SOURCES/autofs-5.1.8-dont-close-lookup-at-umount.patch new file mode 100644 index 0000000..e7ffa80 --- /dev/null +++ b/SOURCES/autofs-5.1.8-dont-close-lookup-at-umount.patch @@ -0,0 +1,47 @@ +autofs-5.1.8 - don't close lookup at umount + +From: Ian Kent + +Since map sources are reference counted they persist beyond autofs +submounts. + +Now the map source moudule lookup gets closed at submount umount and +if we are unlucky enough to be using the same map in other submounts +and a lookup is underway at the time of the umount a crash can occur. + +To resolve this it's much better to just not close the lookup at +submount umount and rely on the map source free to close the module +lookup and instances when the map source is no longer referenced. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ------- + 2 files changed, 1 insertion(+), 7 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -116,6 +116,7 @@ + - improve handling of ENOENT in sss setautomntent(). + - don't immediately call function when waiting. + - fix return status of mount_autofs(). ++- don't close lookup at umount. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -737,13 +737,6 @@ static int umount_autofs(struct autofs_p + if (ap->state == ST_INIT) + return -1; + +- /* +- * Since lookup.c is lazy about closing lookup modules +- * to prevent unneeded opens, we need to clean them up +- * before umount. +- */ +- lookup_close_lookup(ap); +- + if (ap->type == LKP_INDIRECT) { + umount_all(ap); + ret = umount_autofs_indirect(ap, root); diff --git a/SOURCES/autofs-5.1.8-dont-delay-expire.patch b/SOURCES/autofs-5.1.8-dont-delay-expire.patch new file mode 100644 index 0000000..5eb7b7c --- /dev/null +++ b/SOURCES/autofs-5.1.8-dont-delay-expire.patch @@ -0,0 +1,94 @@ +autofs-5.1.8 - dont delay expire + +From: Ian Kent + +There's a delay on expire of submounts that can be as much as the +expire timeout. This was originally an attempt to reduce re-reading +the map but it can cause very long delays on expire. + +So get rid of the delay and allow submounts to expire normally. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 9 ++++----- + daemon/state.c | 30 ++++-------------------------- + 3 files changed, 9 insertions(+), 31 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -118,6 +118,7 @@ + - fix return status of mount_autofs(). + - don't close lookup at umount. + - fix deadlock in lookups. ++- dont delay expire. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -1250,17 +1250,16 @@ int master_notify_submount(struct autofs + st_wait_task(this->ap, state, 0); + + /* +- * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or +- * ST_SHUTDOWN_FORCE we need to wait until it goes away or changes +- * to ST_READY. ++ * If our submount gets to state ST_SHUTDOWN_PENDING or ++ * ST_SHUTDOWN_FORCE we need to wait until it goes away ++ * or changes to state ST_SHUTDOWN or ST_READY. + */ + st_mutex_lock(); + while ((sbmnt = mnts_find_submount(path))) { + struct timespec t = { 0, 300000000 }; + struct timespec r; + +- if (sbmnt->ap->state != ST_SHUTDOWN && +- sbmnt->ap->state != ST_SHUTDOWN_PENDING && ++ if (sbmnt->ap->state != ST_SHUTDOWN_PENDING && + sbmnt->ap->state != ST_SHUTDOWN_FORCE) { + ret = 0; + mnts_put_mount(sbmnt); +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/daemon/state.c +@@ -99,36 +99,14 @@ void expire_cleanup(void *arg) + /* + * If we're a submount and we've just pruned or + * expired everything away, try to shut down. +- * +- * Since we use the the fact that a mount will not +- * expire for at least ap->exp_timeout to avoid a +- * mount <-> expire race we need to wait before +- * letting a submount expire away. We also need +- * them to go away fairly quickly so the owner +- * mount expires in a reasonable time. Just skip +- * one expire check after it's no longer busy before +- * allowing it to shutdown. +- * +- * But if this mount point is an amd format map it +- * is better to keep the mount around longer. This +- * is because of the common heavy reuse of maps in +- * amd maps and we want to try and avoid constantly +- * re-reading large maps. + */ + if (ap->submount && !success) { + rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle); +- if (!rv && idle && ap->submount > 1) { +- struct map_source *map = ap->entry->maps; +- +- if (ap->submount > 4 || +- !(map->flags & MAP_FLAG_FORMAT_AMD)) { +- next = ST_SHUTDOWN_PENDING; +- break; +- } ++ if (!rv && idle) { ++ next = ST_SHUTDOWN_PENDING; ++ break; + } +- ap->submount++; +- } else if (ap->submount > 1) +- ap->submount = 1; ++ } + + if (ap->state == ST_EXPIRE) + conditional_alarm_add(ap, ap->exp_runfreq); diff --git a/SOURCES/autofs-5.1.8-dont-immediately-call-function-when-waiting.patch b/SOURCES/autofs-5.1.8-dont-immediately-call-function-when-waiting.patch new file mode 100644 index 0000000..9ca6878 --- /dev/null +++ b/SOURCES/autofs-5.1.8-dont-immediately-call-function-when-waiting.patch @@ -0,0 +1,101 @@ +autofs-5.1.8 - dont immediately call function when waiting + +From: Ian Kent + +When autofs needs to wait for a sss connection the connection function +is immediately called a second time without first waiting. Adjust the +calling so that there's a wait before the next call. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 24 ++++++++++++------------ + 2 files changed, 13 insertions(+), 12 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -114,6 +114,7 @@ + - fix incorrect path for is_mounted() in try_remount(). + - fail on empty replicated host name. + - improve handling of ENOENT in sss setautomntent(). ++- don't immediately call function when waiting. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/lookup_sss.c ++++ autofs-5.1.7/modules/lookup_sss.c +@@ -338,10 +338,13 @@ static int setautomntent_wait(unsigned i + "can't connect to sssd, retry for %d seconds", + retries); + +- while (++retry <= retries) { ++ while (++retry < retries) { + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ + ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt); + if (proto_version(ctxt) == 0) { + if (ret != ENOENT) +@@ -355,9 +358,6 @@ static int setautomntent_wait(unsigned i + free(*sss_ctxt); + *sss_ctxt = NULL; + } +- +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); + } + + if (!ret) +@@ -475,10 +475,13 @@ static int getautomntent_wait(unsigned i + "can't contact sssd to to get map entry, retry for %d seconds", + retries); + +- while (++retry <= retries) { ++ while (++retry < retries) { + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ + ret = ctxt->getautomntent_r(key, value, sss_ctxt); + if (proto_version(ctxt) == 0) { + if (ret != ENOENT) +@@ -487,9 +490,6 @@ static int getautomntent_wait(unsigned i + if (ret != EHOSTDOWN) + break; + } +- +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); + } + + if (!ret) +@@ -600,10 +600,13 @@ static int getautomntbyname_wait(unsigne + "can't contact sssd to to lookup key value, retry for %d seconds", + retries); + +- while (++retry <= retries) { ++ while (++retry < retries) { + struct timespec t = { SSS_WAIT_INTERVAL, 0 }; + struct timespec r; + ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ + ret = ctxt->getautomntbyname_r(key, value, sss_ctxt); + if (proto_version(ctxt) == 0) { + if (ret != ENOENT) +@@ -612,9 +615,6 @@ static int getautomntbyname_wait(unsigne + if (ret != EHOSTDOWN) + break; + } +- +- while (nanosleep(&t, &r) == -1 && errno == EINTR) +- memcpy(&t, &r, sizeof(struct timespec)); + } + + if (!ret) diff --git a/SOURCES/autofs-5.1.8-dont-take-parent-source-lock-at-mount-shutdown.patch b/SOURCES/autofs-5.1.8-dont-take-parent-source-lock-at-mount-shutdown.patch new file mode 100644 index 0000000..d645444 --- /dev/null +++ b/SOURCES/autofs-5.1.8-dont-take-parent-source-lock-at-mount-shutdown.patch @@ -0,0 +1,118 @@ +autofs-5.1.8 - dont take parent source lock at mount shutdown + +From: Ian Kent + +There shouldn't be any need to take the parent source lock at autofs mount +shutdown so don't take it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 60 ++--------------------------------------------------- + 2 files changed, 4 insertions(+), 57 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -147,6 +147,7 @@ + - set mapent dev and ino before adding to index. + - change to use printf functions in amd parser. + - dont call umount_subtree_mounts() on parent at umount. ++- dont take parent source lock at mount shutdown. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1765,7 +1765,6 @@ static void handle_mounts_cleanup(void * + * here. + */ + if (submount) { +- master_source_unlock(ap->parent->entry); + master_free_mapent_sources(ap->entry, 1); + master_free_mapent(ap->entry); + } +@@ -1793,36 +1792,6 @@ static void handle_mounts_cleanup(void * + return; + } + +-static int submount_source_writelock_nested(struct autofs_point *ap) +-{ +- struct autofs_point *parent = ap->parent; +- int status; +- +- status = pthread_rwlock_trywrlock(&parent->entry->source_lock); +- if (status) +- goto done; +- +- status = pthread_rwlock_trywrlock(&ap->entry->source_lock); +- if (status) +- master_source_unlock(parent->entry); +- +-done: +- if (status && status != EBUSY) { +- logmsg("submount nested master_mapent source write lock failed"); +- fatal(status); +- } +- +- return status; +-} +- +-static void submount_source_unlock_nested(struct autofs_point *ap) +-{ +- struct autofs_point *parent = ap->parent; +- +- master_source_unlock(ap->entry); +- master_source_unlock(parent->entry); +-} +- + int handle_mounts_exit(struct autofs_point *ap) + { + int ret, cur_state; +@@ -1837,33 +1806,13 @@ int handle_mounts_exit(struct autofs_poi + + master_mutex_lock(); + +- if (!ap->submount) +- master_source_writelock(ap->entry); +- else { +- /* +- * If a mount request arrives before the locks are +- * aquired just return to ready state. +- */ +- ret = submount_source_writelock_nested(ap); +- if (ret) { +- warn(ap->logopt, +- "can't shutdown submount: mount in progress"); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- master_mutex_unlock(); +- pthread_setcancelstate(cur_state, NULL); +- return 0; +- } +- } ++ master_source_writelock(ap->entry); + + if (ap->state != ST_SHUTDOWN) { + conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); ++ master_source_unlock(ap->entry); + master_mutex_unlock(); + + pthread_setcancelstate(cur_state, NULL); +@@ -1904,10 +1853,7 @@ int handle_mounts_exit(struct autofs_poi + conditional_alarm_add(ap, ap->exp_runfreq); + /* Return to ST_READY is done immediately */ + st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); ++ master_source_unlock(ap->entry); + master_mutex_unlock(); + + pthread_setcancelstate(cur_state, NULL); diff --git a/SOURCES/autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch b/SOURCES/autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch new file mode 100644 index 0000000..30db6de --- /dev/null +++ b/SOURCES/autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch @@ -0,0 +1,292 @@ +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(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -123,6 +123,7 @@ + - rename statemachine() to signal_handler(). + - make signal handling consistent. + - fix incorrect print format specifiers in get_pkt(). ++- eliminate last remaining state_pipe usage. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1063,58 +1063,51 @@ static int set_log_priority(const char * + 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; ++ sigfillset(&signalset); ++ sigdelset(&signalset, SIGCONT); + +- st_mutex_lock(); +- +- state_pipe = ap->state_pipe[0]; +- +- 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) { +@@ -1129,9 +1122,9 @@ static int get_pkt(struct autofs_point * + 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); + } + } + } +@@ -1191,15 +1184,6 @@ static int autofs_init_ap(struct autofs_ + 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); +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/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) { +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/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 + 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); + +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -112,8 +112,6 @@ int master_add_autofs_point(struct maste + + ap->state = ST_INIT; + +- ap->state_pipe[0] = -1; +- ap->state_pipe[1] = -1; + ap->logpri_fifo = -1; + + ap->path = strdup(entry->path); +@@ -1390,7 +1388,7 @@ static int master_do_mount(struct master + handle_mounts_startup_cond_destroy(&suc); + return 0; + } +- entry->thid = thid; ++ entry->thid = ap->thid = thid; + + handle_mounts_startup_cond_destroy(&suc); + +@@ -1474,9 +1472,6 @@ int master_mount_mounts(struct master *m + 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; +@@ -1533,19 +1528,9 @@ int master_mount_mounts(struct master *m + } + 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); +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/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(st + + 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; + } +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -564,7 +564,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 */ +--- autofs-5.1.7.orig/include/state.h ++++ autofs-5.1.7/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); diff --git a/SOURCES/autofs-5.1.8-eliminate-realpath-from-mount-of-submount.patch b/SOURCES/autofs-5.1.8-eliminate-realpath-from-mount-of-submount.patch new file mode 100644 index 0000000..f46d9a8 --- /dev/null +++ b/SOURCES/autofs-5.1.8-eliminate-realpath-from-mount-of-submount.patch @@ -0,0 +1,112 @@ +autofs-5.1.8 - eliminate realpath from mount of submount + +From: Ian Kent + +None of the tests I have show that the realpath local variable in the +autofs submount mount function is needed, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_autofs.c | 25 ++++--------------------- + 2 files changed, 5 insertions(+), 21 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -139,6 +139,7 @@ + - get rid entry thid field. + - continue expire immediately after submount check. + - add buffer length checks to autofs mount_mount(). ++- eliminate realpath from mount of submount. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/mount_autofs.c ++++ autofs-5.1.7/modules/mount_autofs.c +@@ -50,7 +50,6 @@ int mount_mount(struct autofs_point *ap, + { + struct startup_cond suc; + pthread_t thid; +- char realpath[PATH_MAX + 1]; + char mountpoint[PATH_MAX + 1]; + const char **argv; + int argc, status; +@@ -73,11 +72,6 @@ int mount_mount(struct autofs_point *ap, + + /* Root offset of multi-mount */ + if (root[strlen(root) - 1] == '/') { +- err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name); +- if (err > PATH_MAX) { +- error(ap->logopt, MODPREFIX "string too long for realpath"); +- return 1; +- } + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); +@@ -91,22 +85,12 @@ int mount_mount(struct autofs_point *ap, + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } +- err = snprintf(realpath, PATH_MAX + 1, "%s", name); +- if (err > PATH_MAX) { +- error(ap->logopt, MODPREFIX "string too long for realpath"); +- return 1; +- } + } else { + err = snprintf(mountpoint, PATH_MAX + 1, "%s", root); + if (err > PATH_MAX) { + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } +- err = snprintf(realpath, PATH_MAX + 1, "%s", name); +- if (err > PATH_MAX) { +- error(ap->logopt, MODPREFIX "string too long for realpath"); +- return 1; +- } + } + } else { + err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name); +@@ -114,7 +98,6 @@ int mount_mount(struct autofs_point *ap, + error(ap->logopt, MODPREFIX "string too long for mountpoint"); + return 1; + } +- strcpy(realpath, mountpoint); + } + + options = NULL; +@@ -180,7 +163,7 @@ int mount_mount(struct autofs_point *ap, + + master = ap->entry->master; + +- entry = master_new_mapent(master, realpath, ap->entry->age); ++ entry = master_new_mapent(master, mountpoint, ap->entry->age); + if (!entry) { + error(ap->logopt, + MODPREFIX "failed to malloc master_mapent struct"); +@@ -332,7 +315,7 @@ int mount_mount(struct autofs_point *ap, + mnt = mnts_add_submount(nap); + if (!mnt) { + crit(ap->logopt, +- MODPREFIX "failed to allocate mount %s", realpath); ++ MODPREFIX "failed to allocate mount %s", mountpoint); + handle_mounts_startup_cond_destroy(&suc); + master_free_map_source(source, 1); + master_free_mapent(entry); +@@ -349,7 +332,7 @@ int mount_mount(struct autofs_point *ap, + crit(ap->logopt, + MODPREFIX + "failed to create mount handler thread for %s", +- realpath); ++ mountpoint); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); + master_free_map_source(source, 1); +@@ -370,7 +353,7 @@ int mount_mount(struct autofs_point *ap, + + if (suc.status) { + crit(ap->logopt, +- MODPREFIX "failed to create submount for %s", realpath); ++ MODPREFIX "failed to create submount for %s", mountpoint); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); + master_free_map_source(source, 1); diff --git a/SOURCES/autofs-5.1.8-eliminate-root-param-from-autofs-mount-and-umount.patch b/SOURCES/autofs-5.1.8-eliminate-root-param-from-autofs-mount-and-umount.patch new file mode 100644 index 0000000..ee39ffc --- /dev/null +++ b/SOURCES/autofs-5.1.8-eliminate-root-param-from-autofs-mount-and-umount.patch @@ -0,0 +1,396 @@ +autofs-5.1.8 - eliminate root param from autofs mount and umount + +From: Ian Kent + +Eliminate the "root" parameter of both mount and umount of autofs mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 30 ++++++------------------- + daemon/indirect.c | 57 ++++++++++++++++++++----------------------------- + daemon/lookup.c | 4 +-- + daemon/master.c | 1 + daemon/state.c | 2 - + include/automount.h | 7 ++---- + modules/mount_autofs.c | 1 + 8 files changed, 39 insertions(+), 64 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -140,6 +140,7 @@ + - continue expire immediately after submount check. + - add buffer length checks to autofs mount_mount(). + - eliminate realpath from mount of submount. ++- eliminate root param from autofs mount and umount. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -736,7 +736,7 @@ static void umount_all(struct autofs_poi + left, ap->path); + } + +-static int umount_autofs(struct autofs_point *ap, const char *root) ++static int umount_autofs(struct autofs_point *ap) + { + int ret = 0; + +@@ -745,7 +745,7 @@ static int umount_autofs(struct autofs_p + + if (ap->type == LKP_INDIRECT) { + umount_all(ap); +- ret = umount_autofs_indirect(ap, root); ++ ret = umount_autofs_indirect(ap); + } else + ret = umount_autofs_direct(ap); + +@@ -915,7 +915,7 @@ static int autofs_init_ap(struct autofs_ + return 0; + } + +-static int mount_autofs(struct autofs_point *ap, const char *root) ++static int mount_autofs(struct autofs_point *ap) + { + int status; + +@@ -930,7 +930,7 @@ static int mount_autofs(struct autofs_po + if (ap->type == LKP_DIRECT) + status = mount_autofs_direct(ap); + else +- status = mount_autofs_indirect(ap, root); ++ status = mount_autofs_indirect(ap); + + st_add_task(ap, ST_READY); + +@@ -1888,7 +1888,7 @@ int handle_mounts_exit(struct autofs_poi + * to check for possible recovery. + */ + if (ap->type == LKP_DIRECT) { +- umount_autofs(ap, NULL); ++ umount_autofs(ap); + handle_mounts_cleanup(ap); + return 1; + } +@@ -1899,7 +1899,7 @@ int handle_mounts_exit(struct autofs_poi + * so we can continue. This can happen if a lookup + * occurs while we're trying to umount. + */ +- ret = umount_autofs(ap, NULL); ++ ret = umount_autofs(ap); + if (!ret) { + set_indirect_mount_tree_catatonic(ap); + handle_mounts_cleanup(ap); +@@ -1927,12 +1927,10 @@ void *handle_mounts(void *arg) + struct startup_cond *suc; + struct autofs_point *ap; + int cancel_state, status = 0; +- char *root; + + suc = (struct startup_cond *) arg; + + ap = suc->ap; +- root = strdup(suc->root); + + pthread_cleanup_push(return_start_status, suc); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); +@@ -1940,30 +1938,18 @@ void *handle_mounts(void *arg) + status = pthread_mutex_lock(&suc->mutex); + if (status) { + logerr("failed to lock startup condition mutex!"); +- if (root) +- free(root); + fatal(status); + } + +- if (!root) { +- crit(ap->logopt, "failed to alloc string root"); +- suc->status = 1; +- pthread_setcancelstate(cancel_state, NULL); +- pthread_exit(NULL); +- } +- +- if (mount_autofs(ap, root) < 0) { ++ if (mount_autofs(ap) < 0) { + if (!(do_force_unlink & UNLINK_AND_EXIT)) + crit(ap->logopt, "mount of %s failed!", ap->path); + suc->status = 1; +- umount_autofs(ap, root); +- free(root); ++ umount_autofs(ap); + pthread_setcancelstate(cancel_state, NULL); + pthread_exit(NULL); + } + +- free(root); +- + if (ap->flags & MOUNT_FLAG_NOBIND) + info(ap->logopt, "bind mounts disabled"); + +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/daemon/indirect.c +@@ -40,7 +40,7 @@ + /* Attribute to create detached thread */ + extern pthread_attr_t th_attr_detached; + +-static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) ++static int do_mount_autofs_indirect(struct autofs_point *ap) + { + const char *str_indirect = mount_type_str(t_indirect); + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -89,11 +89,11 @@ static int do_mount_autofs_indirect(stru + } + + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(root, mp_mode) < 0) { ++ if (mkdir_path(ap->path, mp_mode) < 0) { + if (errno != EEXIST && errno != EROFS) { + crit(ap->logopt, + "failed to create autofs directory %s", +- root); ++ ap->path); + goto out_err; + } + /* If we recieve an error, and it's EEXIST or EROFS we know +@@ -108,27 +108,27 @@ static int do_mount_autofs_indirect(stru + if (!type || strcmp(ap->entry->maps->type, "hosts")) + map_name = ap->entry->maps->argv[0]; + +- ret = mount(map_name, root, "autofs", MS_MGC_VAL, options); ++ ret = mount(map_name, ap->path, "autofs", MS_MGC_VAL, options); + if (ret) { + crit(ap->logopt, +- "failed to mount autofs path %s at %s", ap->path, root); ++ "failed to mount autofs at %s", ap->path); + goto out_rmdir; + } + + free(options); + options = NULL; + +- ret = stat(root, &st); ++ ret = stat(ap->path, &st); + if (ret == -1) { + crit(ap->logopt, + "failed to stat mount for autofs path %s", ap->path); + goto out_umount; + } + +- if (ap->mode && (err = chmod(root, ap->mode))) ++ if (ap->mode && (err = chmod(ap->path, ap->mode))) + warn(ap->logopt, "failed to change mode of %s", ap->path); + +- if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) { ++ if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, ap->path)) { + crit(ap->logopt, + "failed to create ioctl fd for autofs path %s", ap->path); + goto out_umount; +@@ -137,18 +137,15 @@ static int do_mount_autofs_indirect(stru + ap->dev = st.st_dev; /* Device number for mount point checks */ + + ops->timeout(ap->logopt, ap->ioctlfd, timeout); +- if (ap->logopt & LOGOPT_DEBUG) +- notify_mount_result(ap, root, timeout, str_indirect); +- else +- notify_mount_result(ap, ap->path, timeout, str_indirect); ++ notify_mount_result(ap, ap->path, timeout, str_indirect); + + return 0; + + out_umount: +- umount(root); ++ umount(ap->path); + out_rmdir: + if (ap->flags & MOUNT_FLAG_DIR_CREATED) +- rmdir(root); ++ rmdir(ap->path); + out_err: + if (options) + free(options); +@@ -158,7 +155,7 @@ out_err: + return -1; + } + +-int mount_autofs_indirect(struct autofs_point *ap, const char *root) ++int mount_autofs_indirect(struct autofs_point *ap) + { + time_t now = monotonic_time(NULL); + int status; +@@ -180,11 +177,11 @@ int mount_autofs_indirect(struct autofs_ + } + } + +- status = do_mount_autofs_indirect(ap, root); ++ status = do_mount_autofs_indirect(ap); + if (status < 0) + return -1; + +- map = lookup_ghost(ap, root); ++ map = lookup_ghost(ap); + if (map & LKP_FAIL) { + if (map & LKP_DIRECT) { + error(ap->logopt, +@@ -223,19 +220,13 @@ void close_mount_fds(struct autofs_point + return; + } + +-int umount_autofs_indirect(struct autofs_point *ap, const char *root) ++int umount_autofs_indirect(struct autofs_point *ap) + { + struct ioctl_ops *ops = get_ioctl_ops(); + char buf[MAX_ERR_BUF]; +- char mountpoint[PATH_MAX + 1]; + int rv, retries; + unsigned int unused; + +- if (root) +- strcpy(mountpoint, root); +- else +- strcpy(mountpoint, ap->path); +- + /* If we are trying to shutdown make sure we can umount */ + rv = ops->askumount(ap->logopt, ap->ioctlfd, &unused); + if (rv == -1) { +@@ -257,7 +248,7 @@ int umount_autofs_indirect(struct autofs + sched_yield(); + + retries = UMOUNT_RETRIES; +- while ((rv = umount(mountpoint)) == -1 && retries--) { ++ while ((rv = umount(ap->path)) == -1 && retries--) { + struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; +@@ -269,13 +260,13 @@ int umount_autofs_indirect(struct autofs + case ENOENT: + case EINVAL: + error(ap->logopt, +- "mount point %s does not exist", mountpoint); ++ "mount point %s does not exist", ap->path); + close_mount_fds(ap); + return 0; + break; + case EBUSY: + debug(ap->logopt, +- "mount point %s is in use", mountpoint); ++ "mount point %s is in use", ap->path); + if (ap->state == ST_SHUTDOWN_FORCE) { + close_mount_fds(ap); + goto force_umount; +@@ -294,11 +285,11 @@ int umount_autofs_indirect(struct autofs + } + #endif + ops->open(ap->logopt, +- &ap->ioctlfd, ap->dev, mountpoint); ++ &ap->ioctlfd, ap->dev, ap->path); + if (ap->ioctlfd < 0) { + warn(ap->logopt, + "could not recover autofs path %s", +- mountpoint); ++ ap->path); + close_mount_fds(ap); + return 0; + } +@@ -323,12 +314,12 @@ int umount_autofs_indirect(struct autofs + force_umount: + if (rv != 0) { + warn(ap->logopt, +- "forcing umount of indirect mount %s", mountpoint); +- rv = umount2(mountpoint, MNT_DETACH); ++ "forcing umount of indirect mount %s", ap->path); ++ rv = umount2(ap->path, MNT_DETACH); + } else { +- info(ap->logopt, "umounting indirect mount %s succeeded", mountpoint); ++ info(ap->logopt, "umounting indirect mount %s succeeded", ap->path); + if (ap->submount) +- rm_unwanted(ap, mountpoint, 1); ++ rm_unwanted(ap, ap->path, 1); + } + + return rv; +--- autofs-5.1.7.orig/daemon/lookup.c ++++ autofs-5.1.7/daemon/lookup.c +@@ -712,7 +712,7 @@ static char *make_browse_path(unsigned i + return path; + } + +-int lookup_ghost(struct autofs_point *ap, const char *root) ++int lookup_ghost(struct autofs_point *ap) + { + struct master_mapent *entry = ap->entry; + struct map_source *map; +@@ -776,7 +776,7 @@ int lookup_ghost(struct autofs_point *ap + } + + fullpath = make_browse_path(ap->logopt, +- root, me->key, ap->pref); ++ ap->path, me->key, ap->pref); + if (!fullpath) + goto next; + +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -1384,7 +1384,6 @@ static int master_do_mount(struct master + } + + suc.ap = ap; +- suc.root = ap->path; + suc.done = 0; + suc.status = 0; + +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/daemon/state.c +@@ -429,7 +429,7 @@ static void *do_readmap(void *arg) + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + ops->timeout(ap->logopt, ap->ioctlfd, timeout); + lookup_prune_cache(ap, now); +- status = lookup_ghost(ap, ap->path); ++ status = lookup_ghost(ap); + } else { + struct mapent *me; + unsigned int append_alarm = !ap->exp_runfreq; +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -270,7 +270,7 @@ int lookup_nss_read_master(struct master + int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age); + int lookup_enumerate(struct autofs_point *ap, + int (*fn)(struct autofs_point *,struct mapent *, int), time_t now); +-int lookup_ghost(struct autofs_point *ap, const char *root); ++int lookup_ghost(struct autofs_point *ap); + int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len); + void lookup_close_lookup(struct autofs_point *ap); + void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age); +@@ -392,7 +392,6 @@ struct startup_cond { + pthread_mutex_t mutex; + pthread_cond_t cond; + struct autofs_point *ap; +- char *root; + unsigned int done; + unsigned int status; + }; +@@ -589,13 +588,13 @@ int do_expire(struct autofs_point *ap, c + void *expire_proc_indirect(void *); + void *expire_proc_direct(void *); + int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now); +-int mount_autofs_indirect(struct autofs_point *ap, const char *root); ++int mount_autofs_indirect(struct autofs_point *ap); + int do_mount_autofs_direct(struct autofs_point *ap, struct mapent *me, time_t timeout); + int mount_autofs_direct(struct autofs_point *ap); + int mount_autofs_offset(struct autofs_point *ap, struct mapent *me); + void submount_signal_parent(struct autofs_point *ap, unsigned int success); + void close_mount_fds(struct autofs_point *ap); +-int umount_autofs_indirect(struct autofs_point *ap, const char *root); ++int umount_autofs_indirect(struct autofs_point *ap); + int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me); + int umount_autofs_direct(struct autofs_point *ap); + int umount_autofs_offset(struct autofs_point *ap, struct mapent *me); +--- autofs-5.1.7.orig/modules/mount_autofs.c ++++ autofs-5.1.7/modules/mount_autofs.c +@@ -324,7 +324,6 @@ int mount_mount(struct autofs_point *ap, + + + suc.ap = nap; +- suc.root = mountpoint; + suc.done = 0; + suc.status = 0; + diff --git a/SOURCES/autofs-5.1.8-fail-on-empty-replicated-host-name.patch b/SOURCES/autofs-5.1.8-fail-on-empty-replicated-host-name.patch new file mode 100644 index 0000000..beec004 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fail-on-empty-replicated-host-name.patch @@ -0,0 +1,57 @@ +autofs-5.1.8 - fail on empty replicated host name + +From: Ian Kent + +If a mount location host (or hosts) has an empty host name it has to be +a mistake so fail the automount request. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 18 ++++++++++++++++++ + 2 files changed, 19 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -112,6 +112,7 @@ + - fix memory leak in update_hosts_mounts(). + - fix minus only option handling in concat_options(). + - fix incorrect path for is_mounted() in try_remount(). ++- fail on empty replicated host name. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -935,6 +935,12 @@ static int validate_location(unsigned in + if (*ptr == ':') + return 1; + ++ /* Fail on replicated entry with empty first host name */ ++ if (*ptr == ',') { ++ error(logopt, "missing first host name in location %s", loc); ++ return 0; ++ } ++ + /* + * If a ':/' is present now it must be a host name, except + * for those special file systems like sshfs which use "#" +@@ -971,6 +977,18 @@ static int validate_location(unsigned in + "found in location %s", *ptr, loc); + return 0; + } ++ ++ /* Fail on replicated entry with empty host name */ ++ if (*ptr == ',') { ++ char next = *(ptr + 1); ++ ++ if (next == ',' || next == ':') { ++ error(logopt, ++ "missing host name in location %s", loc); ++ return 0; ++ } ++ } ++ + ptr++; + } + diff --git a/SOURCES/autofs-5.1.8-fix-amd-selector-function-matching.patch b/SOURCES/autofs-5.1.8-fix-amd-selector-function-matching.patch new file mode 100644 index 0000000..b63de59 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-amd-selector-function-matching.patch @@ -0,0 +1,49 @@ +autofs-5.1.8 - fix amd selector function matching + +From: Ian Kent + +The top level lexical analyser matching of 1 and 2 arg selector +functions did not have enough context to match correctly. + +This was causing it to attempt to match the selector function and its +parameter(s) against the selector function names which wasn't working. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/amd_tok.l | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -135,6 +135,7 @@ + - fix fix mount tree startup reconnect. + - fix use_ignore_mount_option description. + - include addtional log info for mounts. ++- fix amd selector function matching. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/amd_tok.l ++++ autofs-5.1.7/modules/amd_tok.l +@@ -159,15 +159,17 @@ CUTSEP (\|\||\/) + return SELECTOR; + } + +- "!"/({SEL1ARG}|{SEL2ARG}) { return NOT; } ++ "!"/({SEL1ARG})(\([^,]+\)) { return NOT; } + +- {SEL1ARG} { ++ "!"/({SEL2ARG})(\(([^,]+)(,([^,]+))?\)) { return NOT; } ++ ++ ({SEL1ARG})/(\([^,]+\)) { + BEGIN(SELARGVAL); + amd_copy_buffer(); + return SELECTOR; + } + +- {SEL2ARG} { ++ ({SEL2ARG})/(\([^,]+)(,([^,]+))?\) { + BEGIN(SELARGVAL); + amd_copy_buffer(); + return SELECTOR; diff --git a/SOURCES/autofs-5.1.8-fix-deadlock-in-lookups.patch b/SOURCES/autofs-5.1.8-fix-deadlock-in-lookups.patch new file mode 100644 index 0000000..f4138c1 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-deadlock-in-lookups.patch @@ -0,0 +1,141 @@ +autofs-5.1.8 - fix deadlock in lookups + +From: Ian Kent + +After adding locking to fix a crash during lookups we're seeing a +deadlock becuase of recursive calls. + +But once the lookup is open we shouldn't need to open it again during +the recursive call, fix it based on that. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/lookup.c | 62 +++++++++++++++++++++++++++++++++------------------- + daemon/master.c | 8 ++++++ + include/master.h | 1 + modules/parse_amd.c | 2 - + 5 files changed, 51 insertions(+), 23 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -117,6 +117,7 @@ + - don't immediately call function when waiting. + - fix return status of mount_autofs(). + - don't close lookup at umount. ++- fix deadlock in lookups. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/lookup.c ++++ autofs-5.1.7/daemon/lookup.c +@@ -318,31 +318,49 @@ static int do_read_map(struct autofs_poi + struct lookup_mod *lookup; + int status; + +- pthread_cleanup_push(map_module_lock_cleanup, map); +- map_module_writelock(map); +- if (!map->lookup) { +- status = open_lookup(map->type, "", map->format, +- map->argc, map->argv, &lookup); +- if (status == NSS_STATUS_SUCCESS) +- map->lookup = lookup; +- else +- debug(ap->logopt, +- "lookup module %s open failed", map->type); +- } else { +- status = map->lookup->lookup_reinit(map->format, +- map->argc, map->argv, +- &map->lookup->context); +- if (status) +- warn(ap->logopt, +- "lookup module %s reinit failed", map->type); +- } +- pthread_cleanup_pop(1); +- if (status != NSS_STATUS_SUCCESS) +- return status; +- + if (!map->stale) + return NSS_STATUS_SUCCESS; + ++ /* If this readmap is the result of trying to mount a submount ++ * the readlock may already be held if the map is the same as ++ * that of the caller. In that case the map has already been ++ * read so just skip the map open/reinit. ++ */ ++ status = map_module_try_writelock(map); ++ if (status) { ++ if (!map->lookup) { ++ error(ap->logopt, "map module lock not held as expected"); ++ return NSS_STATUS_UNAVAIL; ++ } ++ } else { ++ if (!map->lookup) { ++ pthread_cleanup_push(map_module_lock_cleanup, map); ++ status = open_lookup(map->type, "", map->format, ++ map->argc, map->argv, &lookup); ++ pthread_cleanup_pop(0); ++ if (status != NSS_STATUS_SUCCESS) { ++ map_module_unlock(map); ++ debug(ap->logopt, ++ "lookup module %s open failed", map->type); ++ return status; ++ } ++ map->lookup = lookup; ++ } else { ++ pthread_cleanup_push(map_module_lock_cleanup, map); ++ status = map->lookup->lookup_reinit(map->format, ++ map->argc, map->argv, ++ &map->lookup->context); ++ pthread_cleanup_pop(0); ++ if (status) { ++ map_module_unlock(map); ++ warn(ap->logopt, ++ "lookup module %s reinit failed", map->type); ++ return status; ++ } ++ } ++ map_module_unlock(map); ++ } ++ + master_source_current_wait(ap->entry); + ap->entry->current = map; + +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -72,6 +72,14 @@ void map_module_writelock(struct map_sou + fatal(status); + } + ++int map_module_try_writelock(struct map_source *map) ++{ ++ int status = pthread_rwlock_trywrlock(&map->module_lock); ++ if (status && status != EBUSY && status != EDEADLK) ++ fatal(status); ++ return status; ++} ++ + void map_module_readlock(struct map_source *map) + { + int status = pthread_rwlock_rdlock(&map->module_lock); +--- autofs-5.1.7.orig/include/master.h ++++ autofs-5.1.7/include/master.h +@@ -128,6 +128,7 @@ int master_list_empty(struct master *); + int master_done(struct master *); + int master_kill(struct master *); + void map_module_writelock(struct map_source *map); ++int map_module_try_writelock(struct map_source *map); + void map_module_readlock(struct map_source *map); + void map_module_unlock(struct map_source *map); + void map_module_lock_cleanup(void *arg); +--- autofs-5.1.7.orig/modules/parse_amd.c ++++ autofs-5.1.7/modules/parse_amd.c +@@ -1391,7 +1391,7 @@ static int do_host_mount(struct autofs_p + cache_unlock(source->mc); + + master_source_current_wait(ap->entry); +- ap->entry->current = source; ++ ap->entry->current = instance; + + map_module_readlock(instance); + lookup = instance->lookup; diff --git a/SOURCES/autofs-5.1.8-fix-expire-retry-looping.patch b/SOURCES/autofs-5.1.8-fix-expire-retry-looping.patch new file mode 100644 index 0000000..20a5bdf --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-expire-retry-looping.patch @@ -0,0 +1,83 @@ +autofs-5.1.8 - fix expire retry looping + +From: Ian Kent + +Commit aa6da48d1 (autofs-5.1.7 - eliminate count_mounts() from +expire_proc_indirect()) stopped using the count_mounts() function +in indirect mount expires because it can be a significant overhead +and shouldn't be needed if the kernel expire dentry selection works +as it should. + +Unfortunately there is a case where it doesn't work properly, when +a USR1 signal is sent to the automount process it is meant to expire +mounts regardless of the expire timeout. In this case if a mount has +been propagated to a mount namespace and is held busy the mount will +fail to umount and because setting the last used field of the mount +dentry doesn't prevent the mount dentry from being selected for expire +again immediately in this case automount will look continually. + +The problem occurs because the the kernel doesn't know how to check +these propagated mounts for busyness and the init namespace automount +process tries to expire the mount but fails and continues trying to +expire the mount because the expire function assumes only mounts that +are not busy will be selected for expire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/indirect.c | 13 ++++++++++++- + include/automount.h | 2 +- + 3 files changed, 14 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -156,6 +156,7 @@ + - make open files limit configurable. + - fix some sss error return cases. + - fix incorrect matching of cached wildcard key. ++- fix expire retry looping. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/daemon/indirect.c +@@ -343,6 +343,7 @@ void *expire_proc_indirect(void *arg) + int offsets, submnts, count; + int ioctlfd, cur_state; + int status, ret, left; ++ int retries; + + ea = (struct expire_args *) arg; + +@@ -490,9 +491,19 @@ void *expire_proc_indirect(void *arg) + * If there are no more real mounts left we could still + * have some offset mounts with no '/' offset or symlinks + * so we need to umount or unlink them here. ++ * ++ * The dentry info last_used field is set to 'now' when a ++ * dentry is selected for expire so that it isn't immediately ++ * selected again if the expire fails. But this can't work ++ * for immediate expires so the count_mounts() function must ++ * be used to limit the number of expire iterations. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- while (1) { ++ if (how == AUTOFS_EXP_IMMEDIATE) ++ retries = count_mounts(ap, ap->path, ap->dev); ++ else ++ retries = -1; ++ while (retries--) { + ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how); + if (ret != 0 && errno == EAGAIN) + break; +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -141,7 +141,7 @@ struct autofs_point; + #define NEGATIVE_TIMEOUT 10 + #define POSITIVE_TIMEOUT 120 + #define UMOUNT_RETRIES 16 +-#define EXPIRE_RETRIES 3 ++#define EXPIRE_RETRIES 1 + + struct mapent_cache { + pthread_rwlock_t rwlock; diff --git a/SOURCES/autofs-5.1.8-fix-fix-mount-tree-startup-reconnect.patch b/SOURCES/autofs-5.1.8-fix-fix-mount-tree-startup-reconnect.patch new file mode 100644 index 0000000..f157885 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-fix-mount-tree-startup-reconnect.patch @@ -0,0 +1,45 @@ +autofs-5.1.8 - fix fix mount tree startup reconnect + +From: Ian Kent + +In function master_mount_mounts() commit 635b90eccee9 checks if the +current top level mount is already running by using two things, if the +mount handling thread id is set in the autofs mount point structure and +if the mount point path is a mounted autofs file system. + +But the top level master map entry for a direct mount map is the +reserved path "/-" and doesn't have an actual mount associated with it +so a mounted check can't be used. But we know that top level mounts +start in state ST_INIT and once that state is changed it never changes +back to it. So using the presence of the mount handling thread id and +the state not being ST_INIT is sufficient to know if this is a new +mount or not. + +Fixes: 635b90eccee9 ("autofs-5.1.8 - fix mount tree startup reconnect") +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -132,6 +132,7 @@ + - fix mount tree startup reconnect. + - fix unterminated read in handle_cmd_pipe_fifo_message(). + - fix memory leak in sasl_do_kinit() ++- fix fix mount tree startup reconnect. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -1553,7 +1553,7 @@ int master_mount_mounts(struct master *m + } + cache_unlock(nc); + cont: +- if (ap->thid && is_mounted(this->path, MNTS_AUTOFS)) ++ if (ap->thid && ap->state != ST_INIT) + check_update_map_sources(this, master->readall); + else { + if (!master_do_mount(this)) { diff --git a/SOURCES/autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch b/SOURCES/autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch new file mode 100644 index 0000000..294aac4 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch @@ -0,0 +1,62 @@ +autofs-5.1.8 - fix incorrect matching of cached wildcard key + +From: Ian Kent + +During the implementation of amd format map entry support the code +to match a cached key was modified. + +Unfortunately there's a case were the key lookup behaves incorrectly. + +That case is when there are included maps in the map itself and one +of the maps (usually the last) has a wildcard key entry. In this case +the wildcard key may be found during lookup but the map it blongs to +isn't checked so it can be incorrectly returned instead of a matching +entry in a subsequent included map. + +Another problem case is when there's a wildcard match and a cache prune +occurs while the mount is being done. In this case the matched cache +entry that has been added is seen as stale and removed along with the +mount point directory during the prune leading to a mount fail. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/parse_subs.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -155,6 +155,7 @@ + - add ioctlfd open helper. + - make open files limit configurable. + - fix some sss error return cases. ++- fix incorrect matching of cached wildcard key. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/lib/parse_subs.c ++++ autofs-5.1.7/lib/parse_subs.c +@@ -532,8 +532,11 @@ struct mapent *match_cached_key(struct a + while ((me = cache_lookup_key_next(me))) + if (me->source == source) + break; +- if (!me) ++ if (!me) { + me = cache_lookup_distinct(mc, "*"); ++ if (me && (me->source != source)) ++ me = NULL; ++ } + } + + if (!me) +@@ -545,7 +548,9 @@ struct mapent *match_cached_key(struct a + */ + if (!(ap->flags & MOUNT_FLAG_REMOUNT) && + ap->type == LKP_INDIRECT && *me->key == '*') { +- ret = cache_update(mc, source, key, me->mapent, me->age); ++ time_t now = monotonic_time(NULL); ++ ++ ret = cache_update(mc, source, key, me->mapent, now); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; + } diff --git a/SOURCES/autofs-5.1.8-fix-memory-leak-in-sasl_do_kinit.patch b/SOURCES/autofs-5.1.8-fix-memory-leak-in-sasl_do_kinit.patch new file mode 100644 index 0000000..134b667 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-memory-leak-in-sasl_do_kinit.patch @@ -0,0 +1,45 @@ +autofs-5.1.8 - fix memory leak in sasl_do_kinit() + +From: Ian Kent + +In sasl_do_kinit() there is a failure case that omits freeing the local +variable tgs_princ, fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -131,6 +131,7 @@ + - get rid of unused field submnt_count. + - fix mount tree startup reconnect. + - fix unterminated read in handle_cmd_pipe_fifo_message(). ++- fix memory leak in sasl_do_kinit() + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/cyrus-sasl.c ++++ autofs-5.1.7/modules/cyrus-sasl.c +@@ -503,7 +503,7 @@ sasl_do_kinit(unsigned logopt, struct lo + if (ret) { + error(logopt, "krb5_unparse_name failed with error %d", + ret); +- goto out_cleanup_client_princ; ++ goto out_cleanup_tgs_princ; + } + + debug(logopt, "Using tgs name %s", tgs_name); +@@ -565,8 +565,9 @@ out_cleanup_creds: + krb5cc_in_use--; + krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds); + out_cleanup_unparse: +- krb5_free_principal(ctxt->krb5ctxt, tgs_princ); + krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name); ++out_cleanup_tgs_princ: ++ krb5_free_principal(ctxt->krb5ctxt, tgs_princ); + out_cleanup_client_princ: + krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ); + out_cleanup_cc: diff --git a/SOURCES/autofs-5.1.8-fix-mount-tree-startup-reconnect.patch b/SOURCES/autofs-5.1.8-fix-mount-tree-startup-reconnect.patch new file mode 100644 index 0000000..00cfdbe --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-mount-tree-startup-reconnect.patch @@ -0,0 +1,54 @@ +autofs-5.1.8 - fix mount tree startup reconnect + +From: Ian Kent + +When reconnecting to an existing mount tree at startup trying to work +out if we created the mountpoint directory uses the parent path of the +current map entry. + +But if the current map entry has no parent we should use the map entry +path. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -129,6 +129,7 @@ + - add command pipe handling functions. + - switch to application wide command pipe. + - get rid of unused field submnt_count. ++- fix mount tree startup reconnect. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -2807,6 +2807,7 @@ static int remount_active_mount(struct a + int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type) + { + struct ioctl_ops *ops = get_ioctl_ops(); ++ struct mapent *mapent; + const char *path; + int ret, fd; + dev_t devid; +@@ -2841,12 +2842,13 @@ int try_remount(struct autofs_point *ap, + } + + me->flags &= ~MOUNT_FLAG_DIR_CREATED; ++ mapent = IS_MM(me) ? MM_PARENT(me) : me; + /* Direct or offset mount, key is full path */ +- if (MM_PARENT(me)->key[0] == '/') { +- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL)) ++ if (mapent->key[0] == '/') { ++ if (!is_mounted(mapent->key, MNTS_REAL)) + me->flags |= MOUNT_FLAG_DIR_CREATED; + } else { +- char *p_key = MM_PARENT(me)->key; ++ char *p_key = mapent->key; + char mp[PATH_MAX + 1]; + int len; + diff --git a/SOURCES/autofs-5.1.8-fix-possible-use-after-free-in-handle_mounts_exit.patch b/SOURCES/autofs-5.1.8-fix-possible-use-after-free-in-handle_mounts_exit.patch new file mode 100644 index 0000000..321ab86 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-possible-use-after-free-in-handle_mounts_exit.patch @@ -0,0 +1,58 @@ +autofs-5.1.8 - fix possible use after free in handle_mounts_exit() + +From: Ian Kent + +Don't free the submount map entry until it's no longer used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 10 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -149,6 +149,7 @@ + - dont call umount_subtree_mounts() on parent at umount. + - dont take parent source lock at mount shutdown. + - eliminate buffer usage from handle_mounts_cleanup(). ++- fix possible use after free in handle_mounts_exit(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1757,16 +1757,6 @@ static void handle_mounts_cleanup(void * + + info(logopt, "shut down path %s", ap->path); + +- /* +- * Submounts are detached threads and don't belong to the +- * master map entry list so we need to free their resources +- * here. +- */ +- if (submount) { +- master_free_mapent_sources(ap->entry, 1); +- master_free_mapent(ap->entry); +- } +- + if (clean) { + if (rmdir(ap->path) == -1) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -1779,6 +1769,16 @@ static void handle_mounts_cleanup(void * + master_source_unlock(ap->entry); + + /* ++ * Submounts are detached threads and don't belong to the ++ * master map entry list so we need to free their resources ++ * here. ++ */ ++ if (submount) { ++ master_free_mapent_sources(ap->entry, 1); ++ master_free_mapent(ap->entry); ++ } ++ ++ /* + * If we are not a submount send a signal to the signal handler + * so it can join with any completed handle_mounts() threads and + * perform final cleanup. diff --git a/SOURCES/autofs-5.1.8-fix-return-status-of-mount_autofs.patch b/SOURCES/autofs-5.1.8-fix-return-status-of-mount_autofs.patch new file mode 100644 index 0000000..38e41ca --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-return-status-of-mount_autofs.patch @@ -0,0 +1,43 @@ +autofs-5.1.8 - fix return status of mount_autofs() + +From: Ian Kent + +The function mount_autofs() collects the status of mounting an autofs +file system but doesn't actually return it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -115,6 +115,7 @@ + - fail on empty replicated host name. + - improve handling of ENOENT in sss setautomntent(). + - don't immediately call function when waiting. ++- fix return status of mount_autofs(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1217,7 +1217,7 @@ static int autofs_init_ap(struct autofs_ + + static int mount_autofs(struct autofs_point *ap, const char *root) + { +- int status = 0; ++ int status; + + /* No need to create comms fds and command fifo if + * unlinking mounts and exiting. +@@ -1239,7 +1239,7 @@ static int mount_autofs(struct autofs_po + + st_add_task(ap, ST_READY); + +- return 0; ++ return status; + } + + static int handle_packet(struct autofs_point *ap) diff --git a/SOURCES/autofs-5.1.8-fix-some-sss-error-return-cases.patch b/SOURCES/autofs-5.1.8-fix-some-sss-error-return-cases.patch new file mode 100644 index 0000000..ae1ab4c --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-some-sss-error-return-cases.patch @@ -0,0 +1,78 @@ +autofs-5.1.8 - fix some sss error return cases + +From: Ian Kent + +There are some cases where the error return handling isn't quite right, +fix them. + +Also fix a typo. in configuration file comment. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 6 +++--- + redhat/autofs.conf.default.in | 2 +- + samples/autofs.conf.default.in | 2 +- + 4 files changed, 6 insertions(+), 5 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -154,6 +154,7 @@ + - add soucre parameter to module functions. + - add ioctlfd open helper. + - make open files limit configurable. ++- fix some sss error return cases. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/lookup_sss.c ++++ autofs-5.1.7/modules/lookup_sss.c +@@ -368,7 +368,7 @@ static int setautomntent_wait(unsigned i + *sss_ctxt = NULL; + } + +- if (proto_version(ctxt) == 0 && retry > retries) ++ if (proto_version(ctxt) == 0 && retry >= retries) + ret = ETIMEDOUT; + } + return ret; +@@ -496,7 +496,7 @@ static int getautomntent_wait(unsigned i + info(logopt, + "successfully contacted sssd to get map entry"); + else { +- if (retry == retries) ++ if (proto_version(ctxt) == 0 && retry >= retries) + ret = ETIMEDOUT; + } + return ret; +@@ -621,7 +621,7 @@ static int getautomntbyname_wait(unsigne + info(logopt, + "successfully contacted sssd to lookup key value"); + else { +- if (proto_version(ctxt) == 0 && retry > retries) ++ if (proto_version(ctxt) == 0 && retry >= retries) + ret = ETIMEDOUT; + } + return ret; +--- autofs-5.1.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.7/redhat/autofs.conf.default.in +@@ -209,7 +209,7 @@ mount_nfs_default_protocol = 4 + # sss_master_map_wait - When sssd is starting up it can sometimes return + # "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 +-# (don't wait) or 10 if sss supports returning EHSTDOWN. ++# (don't wait) or 10 if sss supports returning EHOSTDOWN. + # If there is a problem with autofs not finding the + # master map at startup (when it should) then try setting + # this to 10 or more. If the sss library supports returning +--- autofs-5.1.7.orig/samples/autofs.conf.default.in ++++ autofs-5.1.7/samples/autofs.conf.default.in +@@ -208,7 +208,7 @@ browse_mode = no + # sss_master_map_wait - When sssd is starting up it can sometimes return + # "no such entry" for a short time until it has read + # in the LDAP map information. Internal default is 0 +-# (don't wait) or 10 if sss supports returning EHSTDOWN. ++# (don't wait) or 10 if sss supports returning EHOSTDOWN. + # If there is a problem with autofs not finding the + # master map at startup (when it should) then try setting + # this to 10 or more. If the sss library supports returning diff --git a/SOURCES/autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch b/SOURCES/autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch new file mode 100644 index 0000000..b37a8fa --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch @@ -0,0 +1,46 @@ +autofs-5.1.8 - fix unterminated read in handle_cmd_pipe_fifo_message() + +From: Ian Kent + +As Coverity points out the buffer in handle_cmd_pipe_fifo_message() +could be overflowed and end up not terminated so fix it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -130,6 +130,7 @@ + - switch to application wide command pipe. + - get rid of unused field submnt_count. + - fix mount tree startup reconnect. ++- fix unterminated read in handle_cmd_pipe_fifo_message(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1419,7 +1419,6 @@ static void handle_cmd_pipe_fifo_message + int ret; + long pri; + +- memset(buffer, 0, sizeof(buffer)); + ret = read(fd, &buffer, sizeof(buffer)); + if (ret < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -1427,6 +1426,12 @@ static void handle_cmd_pipe_fifo_message + "read on command pipe returned error: %s", estr); + return; + } ++ if (ret >= sizeof(buffer)) { ++ error(LOGOPT_ANY, ++ "read overrun on command pipe message"); ++ return; ++ } ++ buffer[ret] = 0; + + sep = strrchr(buffer, ' '); + if (!sep) { diff --git a/SOURCES/autofs-5.1.8-fix-use_ignore_mount_option-description.patch b/SOURCES/autofs-5.1.8-fix-use_ignore_mount_option-description.patch new file mode 100644 index 0000000..d249a74 --- /dev/null +++ b/SOURCES/autofs-5.1.8-fix-use_ignore_mount_option-description.patch @@ -0,0 +1,56 @@ +autofs-5.1.8 - fix use_ignore_mount_option description + +From: Ian Kent + +Fix a couple of grammer problem with the configuration setting +use_ignore_mount_option description. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + redhat/autofs.conf.default.in | 4 ++-- + samples/autofs.conf.default.in | 4 ++-- + 3 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -133,6 +133,7 @@ + - fix unterminated read in handle_cmd_pipe_fifo_message(). + - fix memory leak in sasl_do_kinit() + - fix fix mount tree startup reconnect. ++- fix use_ignore_mount_option description. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.7/redhat/autofs.conf.default.in +@@ -187,11 +187,11 @@ mount_nfs_default_protocol = 4 + #disable_not_found_message = "no" + # + # use_ignore_mount_option - This option is used to enable the use of autofs +-# pseudo option "disable". This option is used as a ++# pseudo option "ignore". This option is used as a + # hint to user space that the mount entry should be + # ommitted from mount table listings. The default is + # "no" to avoid unexpected changes in behaviour and +-# so is an opt-in setting. ++# is an opt-in setting. + # + #use_ignore_mount_option = no + # +--- autofs-5.1.7.orig/samples/autofs.conf.default.in ++++ autofs-5.1.7/samples/autofs.conf.default.in +@@ -186,11 +186,11 @@ browse_mode = no + #disable_not_found_message = "no" + # + # use_ignore_mount_option - This option is used to enable the use of autofs +-# pseudo option "disable". This option is used as a ++# pseudo option "ignore". This option is used as a + # hint to user space that the mount entry should be + # ommitted from mount table listings. The default is + # "no" to avoid unexpected changes in behaviour and +-# so is an opt-in setting. ++# is an opt-in setting. + # + #use_ignore_mount_option = no + # diff --git a/SOURCES/autofs-5.1.8-get-rid-entry-thid-field.patch b/SOURCES/autofs-5.1.8-get-rid-entry-thid-field.patch new file mode 100644 index 0000000..854bf74 --- /dev/null +++ b/SOURCES/autofs-5.1.8-get-rid-entry-thid-field.patch @@ -0,0 +1,62 @@ +autofs-5.1.8 - get rid entry thid field + +From: Ian Kent + +Use the autofs_point structure thid and get rid of the copy in struct +master_mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 5 ++--- + include/master.h | 1 - + 3 files changed, 3 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -136,6 +136,7 @@ + - fix use_ignore_mount_option description. + - include addtional log info for mounts. + - fix amd selector function matching. ++- get rid entry thid field. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -831,7 +831,6 @@ struct master_mapent *master_new_mapent( + entry->path = tmp; + entry->len = strlen(tmp); + +- entry->thid = 0; + entry->age = age; + entry->master = master; + entry->current = NULL; +@@ -1413,7 +1412,7 @@ static int master_do_mount(struct master + handle_mounts_startup_cond_destroy(&suc); + return 0; + } +- entry->thid = ap->thid = thid; ++ ap->thid = thid; + + handle_mounts_startup_cond_destroy(&suc); + +@@ -1969,7 +1968,7 @@ int master_done(struct master *master) + entry = list_entry(p, struct master_mapent, join); + p = p->next; + list_del(&entry->join); +- pthread_join(entry->thid, NULL); ++ pthread_join(entry->ap->thid, NULL); + master_free_mapent_sources(entry, 1); + master_free_mapent(entry); + } +--- autofs-5.1.7.orig/include/master.h ++++ autofs-5.1.7/include/master.h +@@ -46,7 +46,6 @@ struct map_source { + struct master_mapent { + char *path; + size_t len; +- pthread_t thid; + time_t age; + struct master *master; + pthread_rwlock_t source_lock; diff --git a/SOURCES/autofs-5.1.8-get-rid-of-strlen-call-in-handle_packet_missing_direct.patch b/SOURCES/autofs-5.1.8-get-rid-of-strlen-call-in-handle_packet_missing_direct.patch new file mode 100644 index 0000000..775d86f --- /dev/null +++ b/SOURCES/autofs-5.1.8-get-rid-of-strlen-call-in-handle_packet_missing_direct.patch @@ -0,0 +1,52 @@ +autofs-5.1.8 - get rid of strlen call in handle_packet_missing_direct() + +From: Ian Kent + +There is a length field in struct mapent, use it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 7 +++---- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -142,6 +142,7 @@ + - eliminate realpath from mount of submount. + - eliminate root param from autofs mount and umount. + - remove redundant fstat from do_mount_direct(). ++- get rid of strlen call in handle_packet_missing_direct(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -1288,7 +1288,7 @@ int handle_packet_missing_direct(struct + char buf[MAX_ERR_BUF]; + int status = 0; + struct timespec wait; +- int ioctlfd, len, state; ++ int ioctlfd, state; + unsigned int kver_major = get_kver_major(); + unsigned int kver_minor = get_kver_minor(); + +@@ -1390,8 +1390,7 @@ int handle_packet_missing_direct(struct + return 0; + } + +- len = strlen(me->key); +- if (len >= PATH_MAX) { ++ if (me->len >= PATH_MAX) { + error(ap->logopt, "direct mount path too long %s", me->key); + ops->send_fail(ap->logopt, + ioctlfd, pkt->wait_queue_token, -ENAMETOOLONG); +@@ -1430,7 +1429,7 @@ int handle_packet_missing_direct(struct + mt->ioctlfd = ioctlfd; + mt->mc = mc; + strcpy(mt->name, me->key); +- mt->len = len; ++ mt->len = me->len; + mt->dev = me->dev; + mt->type = NFY_MOUNT; + mt->uid = pkt->uid; diff --git a/SOURCES/autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch b/SOURCES/autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch new file mode 100644 index 0000000..e9b82ab --- /dev/null +++ b/SOURCES/autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch @@ -0,0 +1,69 @@ +autofs-5.1.8 - get rid of unused field submnt_count + +From: Ian Kent + +The autofs mount point struct field submnt_count is present but not +used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 --- + daemon/master.c | 1 - + include/automount.h | 1 - + modules/mount_autofs.c | 2 -- + 5 files changed, 1 insertion(+), 7 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -128,6 +128,7 @@ + - use device id to locate autofs_point when setting log priotity. + - add command pipe handling functions. + - switch to application wide command pipe. ++- get rid of unused field submnt_count. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1741,9 +1741,6 @@ static void handle_mounts_cleanup(void * + if (submount) { + struct mnt_list *mnt; + +- /* We are finishing up */ +- ap->parent->submnt_count--; +- + /* Submount at ap->path belongs to parent submount list. */ + mnts_remove_submount(ap->path); + /* Also remove from parent mounted list */ +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -152,7 +152,6 @@ int master_add_autofs_point(struct maste + + ap->parent = NULL; + ap->thid = 0; +- ap->submnt_count = 0; + ap->submount = submount; + INIT_LIST_HEAD(&ap->mounts); + INIT_LIST_HEAD(&ap->submounts); +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -566,7 +566,6 @@ struct autofs_point { + 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 */ +- unsigned int submnt_count; /* Number of submounts */ + struct list_head submounts; /* List of child submounts */ + struct list_head amdmounts; /* List of non submount amd mounts */ + unsigned int shutdown; /* Shutdown notification */ +--- autofs-5.1.7.orig/modules/mount_autofs.c ++++ autofs-5.1.7/modules/mount_autofs.c +@@ -358,8 +358,6 @@ int mount_mount(struct autofs_point *ap, + } + nap->thid = thid; + +- ap->submnt_count++; +- + handle_mounts_startup_cond_destroy(&suc); + + return 0; diff --git a/SOURCES/autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch b/SOURCES/autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch new file mode 100644 index 0000000..68bb0d2 --- /dev/null +++ b/SOURCES/autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch @@ -0,0 +1,59 @@ +autofs-5.1.8 - improve handling of ENOENT in sss setautomntent() + +From: Ian Kent + +In the sss lookup module function setautomntent() a return of ENOENT +isn't handled quite right. + +If ENOENT (rather than EHOSTDOWN) is returned from sss setautomntent() +we should assume the LDAP info. has been read by sss and the entry in +fact doesn't exist. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 16 +++++++++++++++- + 2 files changed, 16 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -113,6 +113,7 @@ + - fix minus only option handling in concat_options(). + - fix incorrect path for is_mounted() in try_remount(). + - fail on empty replicated host name. ++- improve handling of ENOENT in sss setautomntent(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/lookup_sss.c ++++ autofs-5.1.7/modules/lookup_sss.c +@@ -394,7 +394,17 @@ static int setautomntent(unsigned int lo + if (ret != ENOENT) + goto error; + } else { +- if (ret != ENOENT && ret != EHOSTDOWN) ++ /* If we get an ENOENT here assume it's accurrate ++ * and return the error. ++ */ ++ if (ret == ENOENT) { ++ error(logopt, MODPREFIX ++ "setautomountent: entry for map %s not found", ++ ctxt->mapname); ++ err = NSS_STATUS_NOTFOUND; ++ goto free; ++ } ++ if (ret != EHOSTDOWN) + goto error; + } + +@@ -410,6 +420,10 @@ static int setautomntent(unsigned int lo + if (ret == EINVAL) + goto free; + if (ret == ENOENT) { ++ /* Map info. not found after host became available */ ++ error(logopt, MODPREFIX ++ "setautomountent: entry for map %s not found", ++ ctxt->mapname); + err = NSS_STATUS_NOTFOUND; + goto free; + } diff --git a/SOURCES/autofs-5.1.8-include-addtional-log-info-for-mounts.patch b/SOURCES/autofs-5.1.8-include-addtional-log-info-for-mounts.patch new file mode 100644 index 0000000..a955d3b --- /dev/null +++ b/SOURCES/autofs-5.1.8-include-addtional-log-info-for-mounts.patch @@ -0,0 +1,160 @@ +autofs-5.1.8 - include addtional log info for mounts + +From: Ian Kent + +There has been a request to include some additional information when +logging mounts and umounts, specifically host and mount location path. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 +++++-- + daemon/indirect.c | 2 +- + daemon/spawn.c | 6 +++--- + modules/mount_bind.c | 4 ++-- + modules/mount_ext2.c | 2 +- + modules/mount_generic.c | 2 +- + modules/mount_nfs.c | 4 +++- + 8 files changed, 17 insertions(+), 11 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -134,6 +134,7 @@ + - fix memory leak in sasl_do_kinit() + - fix fix mount tree startup reconnect. + - fix use_ignore_mount_option description. ++- include addtional log info for mounts. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -857,14 +857,17 @@ static int get_pkt(struct autofs_point * + int do_expire(struct autofs_point *ap, const char *name, int namelen) + { + char buf[PATH_MAX]; ++ const char *parent; + int len, ret; + + if (*name != '/') { + len = ncat_path(buf, sizeof(buf), ap->path, name, namelen); ++ parent = ap->path; + } else { + len = snprintf(buf, PATH_MAX, "%s", name); + if (len >= PATH_MAX) + len = 0; ++ parent = name; + } + + if (!len) { +@@ -872,13 +875,13 @@ int do_expire(struct autofs_point *ap, c + return 1; + } + +- info(ap->logopt, "expiring path %s", buf); ++ info(ap->logopt, "expiring path %s on %s", buf, parent); + + pthread_cleanup_push(master_source_lock_cleanup, ap->entry); + master_source_readlock(ap->entry); + ret = umount_multi(ap, buf, 1); + if (ret == 0) +- info(ap->logopt, "expired %s", buf); ++ info(ap->logopt, "umounting %s succeeded", buf); + else + warn(ap->logopt, "couldn't complete expire of %s", buf); + pthread_cleanup_pop(1); +--- autofs-5.1.7.orig/daemon/indirect.c ++++ autofs-5.1.7/daemon/indirect.c +@@ -326,7 +326,7 @@ force_umount: + "forcing umount of indirect mount %s", mountpoint); + rv = umount2(mountpoint, MNT_DETACH); + } else { +- info(ap->logopt, "umounted indirect mount %s", mountpoint); ++ info(ap->logopt, "umounting indirect mount %s succeeded", mountpoint); + if (ap->submount) + rm_unwanted(ap, mountpoint, 1); + } +--- autofs-5.1.7.orig/daemon/spawn.c ++++ autofs-5.1.7/daemon/spawn.c +@@ -541,7 +541,7 @@ done: + while (errp && (p = memchr(sp, '\n', errp))) { + *p++ = '\0'; + if (sp[0]) /* Don't output empty lines */ +- warn(logopt, ">> %s", sp); ++ debug(logopt, ">> %s", sp); + errp -= (p - sp); + sp = p; + } +@@ -552,7 +552,7 @@ done: + if (errp >= ERRBUFSIZ) { + /* Line too long, split */ + errbuf[errp] = '\0'; +- warn(logopt, ">> %s", errbuf); ++ debug(logopt, ">> %s", errbuf); + errp = 0; + } + } +@@ -566,7 +566,7 @@ done: + if (errp > 0) { + /* End of file without \n */ + errbuf[errp] = '\0'; +- warn(logopt, ">> %s", errbuf); ++ debug(logopt, ">> %s", errbuf); + } + + if (waitpid(f, &ret, 0) != f) +--- autofs-5.1.7.orig/modules/mount_bind.c ++++ autofs-5.1.7/modules/mount_bind.c +@@ -177,7 +177,7 @@ int mount_mount(struct autofs_point *ap, + + return err; + } else { +- debug(ap->logopt, ++ mountlog(ap->logopt, + MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); + } +@@ -252,7 +252,7 @@ int mount_mount(struct autofs_point *ap, + } + return 1; + } else { +- debug(ap->logopt, ++ mountlog(ap->logopt, + MODPREFIX "symlinked %s -> %s", fullpath, what); + return 0; + } +--- autofs-5.1.7.orig/modules/mount_ext2.c ++++ autofs-5.1.7/modules/mount_ext2.c +@@ -140,7 +140,7 @@ int mount_mount(struct autofs_point *ap, + + return 1; + } else { +- debug(ap->logopt, ++ mountlog(ap->logopt, + MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); + return 0; +--- autofs-5.1.7.orig/modules/mount_generic.c ++++ autofs-5.1.7/modules/mount_generic.c +@@ -99,7 +99,7 @@ int mount_mount(struct autofs_point *ap, + + return 1; + } else { +- debug(ap->logopt, MODPREFIX "mounted %s type %s on %s", ++ mountlog(ap->logopt, MODPREFIX "mounted %s type %s on %s", + what, fstype, fullpath); + return 0; + } +--- autofs-5.1.7.orig/modules/mount_nfs.c ++++ autofs-5.1.7/modules/mount_nfs.c +@@ -403,7 +403,9 @@ dont_probe: + } + + if (!err) { +- debug(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath); ++ mountlog(ap->logopt, ++ MODPREFIX "mounted %s type %s on %s", ++ loc, fstype, fullpath); + free(loc); + free_host_list(&hosts); + return 0; diff --git a/SOURCES/autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch b/SOURCES/autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch new file mode 100644 index 0000000..b4a8a5f --- /dev/null +++ b/SOURCES/autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch @@ -0,0 +1,81 @@ +autofs-5.1.8 - make amd mapent search function name clear + +From: Ian Kent + +When looking for amd sections in the configuration the function to +find mount entries is not named so it is clear what it's trying to +do so change its name. Also make it static since it is called only +once in the same source file. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 7 ++++--- + include/master.h | 2 +- + 3 files changed, 6 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -119,6 +119,7 @@ + - don't close lookup at umount. + - fix deadlock in lookups. + - dont delay expire. ++- make amd mapent search function name clear. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -741,7 +741,7 @@ struct master_mapent *master_find_mapent + return NULL; + } + +-unsigned int master_partial_match_mapent(struct master *master, const char *path) ++static unsigned int master_partial_match_amd_mapent(struct master *master, const char *path) + { + struct list_head *head, *p; + size_t path_len = strlen(path); +@@ -755,7 +755,7 @@ unsigned int master_partial_match_mapent + + entry = list_entry(p, struct master_mapent, list); + +- entry_len = strlen(entry->path); ++ entry_len = entry->len; + cmp_len = min(entry_len, path_len); + + if (!strncmp(entry->path, path, cmp_len)) { +@@ -806,6 +806,7 @@ struct master_mapent *master_new_mapent( + return NULL; + } + entry->path = tmp; ++ entry->len = strlen(tmp); + + entry->thid = 0; + entry->age = age; +@@ -1038,7 +1039,7 @@ static void master_add_amd_mount_section + char *map = NULL; + char *opts; + +- ret = master_partial_match_mapent(master, path); ++ ret = master_partial_match_amd_mapent(master, path); + if (ret) { + /* If this amd entry is already present in the + * master map it's not a duplicate, don't issue +--- autofs-5.1.7.orig/include/master.h ++++ autofs-5.1.7/include/master.h +@@ -45,6 +45,7 @@ struct map_source { + + struct master_mapent { + char *path; ++ size_t len; + pthread_t thid; + time_t age; + struct master *master; +@@ -109,7 +110,6 @@ void master_source_lock_cleanup(void *); + void master_source_current_wait(struct master_mapent *); + void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); +-unsigned int master_partial_match_mapent(struct master *, const char *); + struct master_mapent *master_new_mapent(struct master *, const char *, time_t); + void master_add_mapent(struct master *, struct master_mapent *); + void master_remove_mapent(struct master_mapent *); diff --git a/SOURCES/autofs-5.1.8-make-open-files-limit-configurable.patch b/SOURCES/autofs-5.1.8-make-open-files-limit-configurable.patch new file mode 100644 index 0000000..f30011d --- /dev/null +++ b/SOURCES/autofs-5.1.8-make-open-files-limit-configurable.patch @@ -0,0 +1,177 @@ +autofs-5.1.8 - make open files limit configurable + +From: Ian Kent + +autofs can use quite a few file handles, particularly with very large +direct mount maps or many submounts as is often seen with amd maps. + +So make the maximum number of open files configurable. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 13 +++++++------ + include/defaults.h | 2 ++ + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 7 +++++++ + redhat/autofs.conf.default.in | 11 +++++++++++ + samples/autofs.conf.default.in | 11 +++++++++++ + 7 files changed, 56 insertions(+), 6 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -153,6 +153,7 @@ + - make submount cleanup the same as top level mounts. + - add soucre parameter to module functions. + - add ioctlfd open helper. ++- make open files limit configurable. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -100,8 +100,6 @@ struct startup_cond suc = { + pthread_key_t key_thread_stdenv_vars; + pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L; + +-#define MAX_OPEN_FILES 20480 +- + int aquire_flag_file(void); + void release_flag_file(void); + +@@ -2205,6 +2203,7 @@ int main(int argc, char *argv[]) + time_t timeout; + time_t age = monotonic_time(NULL); + struct rlimit rlim; ++ unsigned long max_open_files; + const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, +@@ -2409,11 +2408,13 @@ int main(int argc, char *argv[]) + exit(1); + } + ++ max_open_files = defaults_get_open_file_limit(); ++ + res = getrlimit(RLIMIT_NOFILE, &rlim); +- if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) { +- rlim.rlim_cur = MAX_OPEN_FILES; +- if (rlim.rlim_max < MAX_OPEN_FILES) +- rlim.rlim_max = MAX_OPEN_FILES; ++ if (res == -1 || rlim.rlim_cur <= max_open_files) { ++ rlim.rlim_cur = max_open_files; ++ if (rlim.rlim_max < max_open_files) ++ rlim.rlim_max = max_open_files; + } + res = setrlimit(RLIMIT_NOFILE, &rlim); + if (res) +--- autofs-5.1.7.orig/include/defaults.h ++++ autofs-5.1.7/include/defaults.h +@@ -24,6 +24,7 @@ + + #define DEFAULT_MASTER_MAP_NAME "auto.master" + ++#define DEFAULT_OPEN_FILE_LIMIT "20480" + #define DEFAULT_TIMEOUT "600" + #define DEFAULT_MASTER_WAIT "10" + #define DEFAULT_NEGATIVE_TIMEOUT "60" +@@ -157,6 +158,7 @@ unsigned int defaults_read_config(unsign + void defaults_conf_release(void); + const char *defaults_get_master_map(void); + int defaults_master_set(void); ++unsigned long defaults_get_open_file_limit(void); + unsigned int defaults_get_timeout(void); + int defaults_get_master_wait(void); + unsigned int defaults_get_negative_timeout(void); +--- autofs-5.1.7.orig/lib/defaults.c ++++ autofs-5.1.7/lib/defaults.c +@@ -47,6 +47,7 @@ + + #define NAME_MASTER_MAP "master_map_name" + ++#define NAME_OPEN_FILE_LIMIT "open_file_limit" + #define NAME_TIMEOUT "timeout" + #define NAME_MASTER_WAIT "master_wait" + #define NAME_NEGATIVE_TIMEOUT "negative_timeout" +@@ -290,6 +291,11 @@ static int conf_load_autofs_defaults(voi + const char *sec = autofs_gbl_sec; + int ret; + ++ ret = conf_update(sec, NAME_OPEN_FILE_LIMIT, ++ DEFAULT_OPEN_FILE_LIMIT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_TIMEOUT, + DEFAULT_TIMEOUT, CONF_ENV); + if (ret == CFG_FAIL) +@@ -1670,6 +1676,17 @@ int defaults_master_set(void) + return 0; + } + ++unsigned long defaults_get_open_file_limit(void) ++{ ++ long limit; ++ ++ limit = conf_get_number(autofs_gbl_sec, NAME_OPEN_FILE_LIMIT); ++ if (limit < 0) ++ limit = atol(DEFAULT_OPEN_FILE_LIMIT); ++ ++ return limit; ++} ++ + unsigned int defaults_get_timeout(void) + { + long timeout; +--- autofs-5.1.7.orig/man/autofs.conf.5.in ++++ autofs-5.1.7/man/autofs.conf.5.in +@@ -23,6 +23,13 @@ configuration settings. + .P + Configuration settings available are: + .TP +++.B open_file_limit +++.br +++Set the maximum number of open files. Note there may be other limits +++within the system that prevent this from being set, systemd for example +++may need a setting in the unit file to increase its default. The autofs +++default is 20480. +++.TP + .B timeout + .br + Sets the default mount timeout in seconds. The internal program +--- autofs-5.1.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.1.7/redhat/autofs.conf.default.in +@@ -1,4 +1,15 @@ + # ++# Global configuration options. ++# ++# open_file_limit - set the maximum number of open files. Note there ++# may be other limits within the system that prevent ++# this from being set, systemd for example may need ++# a setting in the unit file to increase its default. ++# The autofs default is 20480. ++# ++#open_file_limit = 20480 ++# ++# + # Define default options for autofs. + # + [ autofs ] +--- autofs-5.1.7.orig/samples/autofs.conf.default.in ++++ autofs-5.1.7/samples/autofs.conf.default.in +@@ -1,4 +1,15 @@ + # ++# Global configuration options. ++# ++# open_file_limit - set the maximum number of open files. Note there ++# may be other limits within the system that prevent ++# this from being set, systemd for example may need ++# a setting in the unit file to increase its default. ++# The autofs default is 20480. ++# ++#open_file_limit = 20480 ++# ++# + # Define default options for autofs. + # + [ autofs ] diff --git a/SOURCES/autofs-5.1.8-make-signal-handling-consistent.patch b/SOURCES/autofs-5.1.8-make-signal-handling-consistent.patch new file mode 100644 index 0000000..51e73b9 --- /dev/null +++ b/SOURCES/autofs-5.1.8-make-signal-handling-consistent.patch @@ -0,0 +1,75 @@ +autofs-5.1.8 - make signal handling consistent + +From: Ian Kent + +There's a mixture of usage of sigprocmask() and pthread_sigmask(), change +to use the pthread versions of this for correctness. + +The only exception to this is reset_signals() which is done in a forked +process that is single threaded so it's valid to keep them as they are. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 8 ++++---- + daemon/spawn.c | 1 - + 3 files changed, 5 insertions(+), 5 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -121,6 +121,7 @@ + - dont delay expire. + - make amd mapent search function name clear. + - rename statemachine() to signal_handler(). ++- make signal handling consistent. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -2214,7 +2214,7 @@ static void do_master_list_reset(struct + + static int do_master_read_master(struct master *master, time_t *age, int wait) + { +- sigset_t signalset; ++ sigset_t signalset, savesigset; + /* Wait must be at least 1 second */ + unsigned int retry_wait = 2; + unsigned int elapsed = 0; +@@ -2225,7 +2225,7 @@ static int do_master_read_master(struct + sigaddset(&signalset, SIGTERM); + sigaddset(&signalset, SIGINT); + sigaddset(&signalset, SIGHUP); +- sigprocmask(SIG_UNBLOCK, &signalset, NULL); ++ pthread_sigmask(SIG_UNBLOCK, &signalset, &savesigset); + + while (1) { + struct timespec t = { retry_wait, 0 }; +@@ -2251,7 +2251,7 @@ static int do_master_read_master(struct + } + } + +- sigprocmask(SIG_BLOCK, &signalset, NULL); ++ pthread_sigmask(SIG_SETMASK, &savesigset, NULL); + + return ret; + } +@@ -2298,7 +2298,7 @@ int main(int argc, char *argv[]) + sigdelset(&block_sigs, SIGILL); + sigdelset(&block_sigs, SIGFPE); + sigdelset(&block_sigs, SIGTRAP); +- sigprocmask(SIG_BLOCK, &block_sigs, NULL); ++ pthread_sigmask(SIG_BLOCK, &block_sigs, NULL); + + program = argv[0]; + +--- autofs-5.1.7.orig/daemon/spawn.c ++++ autofs-5.1.7/daemon/spawn.c +@@ -46,7 +46,6 @@ void dump_core(void) + sigemptyset(&segv); + sigaddset(&segv, SIGSEGV); + pthread_sigmask(SIG_UNBLOCK, &segv, NULL); +- sigprocmask(SIG_UNBLOCK, &segv, NULL); + + raise(SIGSEGV); + } diff --git a/SOURCES/autofs-5.1.8-make-submount-cleanup-the-same-as-top-level-mounts.patch b/SOURCES/autofs-5.1.8-make-submount-cleanup-the-same-as-top-level-mounts.patch new file mode 100644 index 0000000..df84c44 --- /dev/null +++ b/SOURCES/autofs-5.1.8-make-submount-cleanup-the-same-as-top-level-mounts.patch @@ -0,0 +1,131 @@ +autofs-5.1.8 - make submount cleanup the same as top level mounts + +From: Ian Kent + +We often see segfaults when cleaning up resources at submount shutdown +after changes are made to resolve problems. It's always really hard to +work out what's causing these to happen. + +But changing submounts to use the same final cleanup method as top level +mounts eliminates the faulting, at least in the case of the most recent +changes, hopefully this change in proceedure will continue to work. +Admitedly there's some setting of fields to NULL after freeing but that +didn't fix the problem until the procedure change was also made. + +In any case the result is a consistency improvement. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 17 +++-------------- + daemon/master.c | 19 +++++++++++++++++-- + modules/mount_autofs.c | 6 +++--- + 4 files changed, 24 insertions(+), 19 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -150,6 +150,7 @@ + - dont take parent source lock at mount shutdown. + - eliminate buffer usage from handle_mounts_cleanup(). + - fix possible use after free in handle_mounts_exit(). ++- make submount cleanup the same as top level mounts. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -1769,21 +1769,10 @@ static void handle_mounts_cleanup(void * + master_source_unlock(ap->entry); + + /* +- * Submounts are detached threads and don't belong to the +- * master map entry list so we need to free their resources +- * here. ++ * Send a signal to the signal handler so it can join with any ++ * completed handle_mounts() threads and perform final cleanup. + */ +- if (submount) { +- master_free_mapent_sources(ap->entry, 1); +- master_free_mapent(ap->entry); +- } +- +- /* +- * If we are not a submount send a signal to the signal handler +- * so it can join with any completed handle_mounts() threads and +- * perform final cleanup. +- */ +- if (!submount && !pending) ++ if (!pending) + pthread_kill(signal_handler_thid, SIGTERM); + + master_mutex_unlock(); +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -384,11 +384,14 @@ static void __master_free_map_source(str + + instance = source->instance; + while (instance) { +- if (instance->lookup) ++ if (instance->lookup) { + close_lookup(instance->lookup); ++ instance->lookup = NULL; ++ } + instance = instance->next; + } + close_lookup(source->lookup); ++ source->lookup = NULL; + } + if (source->argv) + free_argv(source->argc, source->argv); +@@ -401,6 +404,7 @@ static void __master_free_map_source(str + __master_free_map_source(instance, 0); + instance = next; + } ++ source->instance = NULL; + } + + status = pthread_rwlock_destroy(&source->module_lock); +@@ -863,9 +867,20 @@ void master_add_mapent(struct master *ma + void master_remove_mapent(struct master_mapent *entry) + { + struct master *master = entry->master; ++ struct autofs_point *ap = entry->ap; ++ ++ if (ap->submount) { ++ struct mnt_list *mnt; + +- if (entry->ap->submount) ++ mnt = mnts_find_submount(ap->path); ++ if (mnt) { ++ warn(ap->logopt, ++ "map entry %s in use at shutdown", ap->path); ++ mnts_put_mount(mnt); ++ } ++ list_add(&entry->join, &master->completed); + return; ++ } + + if (!list_empty(&entry->list)) { + list_del_init(&entry->list); +--- autofs-5.1.7.orig/modules/mount_autofs.c ++++ autofs-5.1.7/modules/mount_autofs.c +@@ -28,8 +28,8 @@ + + #define MODPREFIX "mount(autofs): " + +-/* Attribute to create detached thread */ +-extern pthread_attr_t th_attr_detached; ++/* Attributes to create handle_mounts() thread */ ++extern pthread_attr_t th_attr; + extern struct startup_cond suc; + + int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */ +@@ -327,7 +327,7 @@ int mount_mount(struct autofs_point *ap, + suc.done = 0; + suc.status = 0; + +- if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) { ++ if (pthread_create(&thid, &th_attr, handle_mounts, &suc)) { + crit(ap->logopt, + MODPREFIX + "failed to create mount handler thread for %s", diff --git a/SOURCES/autofs-5.1.8-remove-redundant-stat-call-in-lookup_ghost.patch b/SOURCES/autofs-5.1.8-remove-redundant-stat-call-in-lookup_ghost.patch new file mode 100644 index 0000000..682b766 --- /dev/null +++ b/SOURCES/autofs-5.1.8-remove-redundant-stat-call-in-lookup_ghost.patch @@ -0,0 +1,58 @@ +autofs-5.1.8 - remove redundant stat call in lookup_ghost() + +From: Ian Kent + +There's nothing to be gained by checking for existence of the path +here, just trust the mkdir_path() call will return the correct error +if the path exists. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 24 ++++++------------------ + 2 files changed, 7 insertions(+), 18 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -143,6 +143,7 @@ + - eliminate root param from autofs mount and umount. + - remove redundant fstat from do_mount_direct(). + - get rid of strlen call in handle_packet_missing_direct(). ++- remove redundant stat call in lookup_ghost(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/lookup.c ++++ autofs-5.1.7/daemon/lookup.c +@@ -780,25 +780,13 @@ int lookup_ghost(struct autofs_point *ap + if (!fullpath) + goto next; + +- ret = stat(fullpath, &st); +- if (ret == -1 && errno != ENOENT) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(ap->logopt, "stat error %s", estr); +- free(fullpath); +- goto next; +- } +- +- /* Directory already exists? */ +- if (!ret) { +- free(fullpath); +- goto next; +- } +- + ret = mkdir_path(fullpath, mp_mode); +- if (ret < 0 && errno != EEXIST) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(ap->logopt, +- "mkdir_path %s failed: %s", fullpath, estr); ++ if (ret < 0) { ++ if (errno != EEXIST) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ warn(ap->logopt, ++ "mkdir_path %s failed: %s", fullpath, estr); ++ } + free(fullpath); + goto next; + } diff --git a/SOURCES/autofs-5.1.8-remove-redundant-stat-from-do_mount_direct.patch b/SOURCES/autofs-5.1.8-remove-redundant-stat-from-do_mount_direct.patch new file mode 100644 index 0000000..12cdcb8 --- /dev/null +++ b/SOURCES/autofs-5.1.8-remove-redundant-stat-from-do_mount_direct.patch @@ -0,0 +1,48 @@ +autofs-5.1.8 - remove redundant stat from do_mount_direct() + +From: Ian Kent + +In do_mount_direct() a stat() call is used to check mount point +attributes but the fstat() of the ioctlfd is for the same path so +the lower overhead fstat() call can be used to do these checks as +well. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 10 +--------- + 2 files changed, 2 insertions(+), 9 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -141,6 +141,7 @@ + - add buffer length checks to autofs mount_mount(). + - eliminate realpath from mount of submount. + - eliminate root param from autofs mount and umount. ++- remove redundant fstat from do_mount_direct(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -1197,19 +1197,11 @@ static void *do_mount_direct(void *arg) + } + + status = fstat(mt.ioctlfd, &st); +- if (status == -1) { +- error(ap->logopt, +- "can't stat direct mount trigger %s", mt.name); +- mt.status = -ENOENT; +- pthread_setcancelstate(state, NULL); +- pthread_exit(NULL); +- } +- +- status = stat(mt.name, &st); + if (status != 0 || !S_ISDIR(st.st_mode) || st.st_dev != mt.dev) { + error(ap->logopt, + "direct trigger not valid or already mounted %s", + mt.name); ++ mt.status = -EINVAL; + pthread_setcancelstate(state, NULL); + pthread_exit(NULL); + } diff --git a/SOURCES/autofs-5.1.8-rename-statemachine-to-signal_handler.patch b/SOURCES/autofs-5.1.8-rename-statemachine-to-signal_handler.patch new file mode 100644 index 0000000..87cfa20 --- /dev/null +++ b/SOURCES/autofs-5.1.8-rename-statemachine-to-signal_handler.patch @@ -0,0 +1,63 @@ +autofs-5.1.8 - rename statemachine() to signal_handler() + +From: Ian Kent + +Rename function statemachine() to signal_handler() to align with what +the function actually does. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 10 +++++----- + 2 files changed, 6 insertions(+), 5 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -120,6 +120,7 @@ + - fix deadlock in lookups. + - dont delay expire. + - make amd mapent search function name clear. ++- rename statemachine() to signal_handler(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -74,7 +74,7 @@ int do_force_unlink = 0; /* Forceably u + static int start_pipefd[2] = {-1, -1}; + static int st_stat = 1; + static int *pst_stat = &st_stat; +-static pthread_t state_mach_thid; ++static pthread_t signal_handler_thid; + + static sigset_t block_sigs; + +@@ -1580,7 +1580,7 @@ static int do_hup_signal(struct master * + } + + /* Deal with all the signal-driven events in the state machine */ +-static void *statemachine(void *arg) ++static void *signal_handler(void *arg) + { + sigset_t signalset; + int sig; +@@ -1768,7 +1768,7 @@ static void handle_mounts_cleanup(void * + * perform final cleanup. + */ + if (!submount && !pending) +- pthread_kill(state_mach_thid, SIGTERM); ++ pthread_kill(signal_handler_thid, SIGTERM); + + master_mutex_unlock(); + +@@ -2743,8 +2743,8 @@ int main(int argc, char *argv[]) + sd_notify(1, "READY=1"); + #endif + +- state_mach_thid = pthread_self(); +- statemachine(NULL); ++ signal_handler_thid = pthread_self(); ++ signal_handler(NULL); + } + + master_kill(master_list); diff --git a/SOURCES/autofs-5.1.8-set-mapent-dev-and-ino-before-adding-to-index.patch b/SOURCES/autofs-5.1.8-set-mapent-dev-and-ino-before-adding-to-index.patch new file mode 100644 index 0000000..a841c3c --- /dev/null +++ b/SOURCES/autofs-5.1.8-set-mapent-dev-and-ino-before-adding-to-index.patch @@ -0,0 +1,140 @@ +autofs-5.1.8 - set mapent dev and ino before adding to index + +From: Ian Kent + +Set the struct fields dev and ino straight after getting them with +stat() or fstat() so they can be used in cache_set_ino_index() without +being passed in. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 8 ++++++-- + daemon/state.c | 2 +- + include/automount.h | 3 +-- + lib/cache.c | 11 ++--------- + lib/mounts.c | 16 +++++++++++++--- + 6 files changed, 24 insertions(+), 17 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -144,6 +144,7 @@ + - remove redundant fstat from do_mount_direct(). + - get rid of strlen call in handle_packet_missing_direct(). + - remove redundant stat call in lookup_ghost(). ++- set mapent dev and ino before adding to index. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -410,6 +410,8 @@ int do_mount_autofs_direct(struct autofs + "failed to stat direct mount trigger %s", me->key); + goto out_umount; + } ++ me->dev = st.st_dev; ++ me->ino = st.st_ino; + + if (ap->mode && (err = chmod(me->key, ap->mode))) + warn(ap->logopt, "failed to change mode of %s", me->key); +@@ -422,7 +424,7 @@ int do_mount_autofs_direct(struct autofs + + ops->timeout(ap->logopt, ioctlfd, timeout); + notify_mount_result(ap, me->key, timeout, str_direct); +- cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); ++ cache_set_ino_index(me->mc, me); + ops->close(ap->logopt, ioctlfd); + + debug(ap->logopt, "mounted trigger %s", me->key); +@@ -765,6 +767,8 @@ int mount_autofs_offset(struct autofs_po + goto out_umount; + goto out_err; + } ++ me->dev = st.st_dev; ++ me->ino = st.st_ino; + + ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); + if (ioctlfd < 0) { +@@ -773,7 +777,7 @@ int mount_autofs_offset(struct autofs_po + } + + ops->timeout(ap->logopt, ioctlfd, timeout); +- cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); ++ cache_set_ino_index(me->mc, me); + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/daemon/state.c +@@ -362,7 +362,7 @@ static int do_readmap_mount(struct autof + valid->ioctlfd = me->ioctlfd; + me->ioctlfd = -1; + /* Set device and inode number of the new mapent */ +- cache_set_ino_index(vmc, me->key, me->dev, me->ino); ++ cache_set_ino_index(vmc, me); + cache_unlock(vmc); + /* Set timeout and calculate the expire run frequency */ + timeout = get_exp_timeout(ap, map); +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -199,8 +199,7 @@ int cache_push_mapent(struct mapent *me, + int cache_pop_mapent(struct mapent *me); + struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map); + struct mapent_cache *cache_init_null_cache(struct master *master); +-int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino); +-/* void cache_set_ino(struct mapent *me, dev_t dev, ino_t ino); */ ++int cache_set_ino_index(struct mapent_cache *mc, struct mapent *me); + struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino); + struct mapent *cache_lookup_first(struct mapent_cache *mc); + struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me); +--- autofs-5.1.7.orig/lib/cache.c ++++ autofs-5.1.7/lib/cache.c +@@ -290,20 +290,13 @@ static u_int32_t ino_hash(dev_t dev, ino + return hashval % size; + } + +-int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino) ++int cache_set_ino_index(struct mapent_cache *mc, struct mapent *me) + { +- u_int32_t ino_index = ino_hash(dev, ino, mc->size); +- struct mapent *me; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) +- return 0; ++ u_int32_t ino_index = ino_hash(me->dev, me->ino, mc->size); + + ino_index_lock(mc); + list_del_init(&me->ino_index); + list_add(&me->ino_index, &mc->ino_index[ino_index]); +- me->dev = dev; +- me->ino = ino; + ino_index_unlock(mc); + + return 1; +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -2761,10 +2761,20 @@ static int remount_active_mount(struct a + ops->close(ap->logopt, fd); + return REMOUNT_STAT_FAIL; + } +- if (type != t_indirect) +- cache_set_ino_index(me->mc, path, st.st_dev, st.st_ino); +- else ++ if (type == t_indirect) + ap->dev = st.st_dev; ++ else { ++ if (strcmp(path, me->key)) { ++ error(ap->logopt, ++ "mount point path mismatch, path %s mapent %s", path, me->key); ++ debug(ap->logopt, "couldn't re-connect to mount %s", path); ++ ops->close(ap->logopt, fd); ++ return REMOUNT_STAT_FAIL; ++ } ++ me->dev = st.st_dev; ++ me->ino = st.st_ino; ++ cache_set_ino_index(me->mc, me); ++ } + notify_mount_result(ap, path, timeout, str_type); + + *ioctlfd = fd; diff --git a/SOURCES/autofs-5.1.8-switch-to-application-wide-command-pipe.patch b/SOURCES/autofs-5.1.8-switch-to-application-wide-command-pipe.patch new file mode 100644 index 0000000..8a7cc59 --- /dev/null +++ b/SOURCES/autofs-5.1.8-switch-to-application-wide-command-pipe.patch @@ -0,0 +1,568 @@ +autofs-5.1.8 - switch to application wide command pipe + +From: Ian Kent + +Switch to use the functions previously added to allow a single +application wide command pipe to be used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 426 +++++++++------------------------------------------- + daemon/master.c | 2 + include/automount.h | 1 + modules/parse_sun.c | 1 + 5 files changed, 80 insertions(+), 351 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -127,6 +127,7 @@ + - add function master_find_mapent_by_devid(). + - use device id to locate autofs_point when setting log priotity. + - add command pipe handling functions. ++- switch to application wide command pipe. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -69,10 +69,6 @@ const char *cmd_pipe_name = AUTOFS_FIFO_ + int start_cmd_pipe_handler(void); + void finish_cmd_pipe_handler(void); + +-/* autofs fifo name prefix */ +-#define FIFO_NAME_PREFIX "autofs.fifo" +-const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX; +- + const char *global_options; /* Global option, from command line */ + + static char *pid_file = NULL; /* File in which to keep pid */ +@@ -801,319 +797,6 @@ static int fullread(int fd, void *ptr, s + return len; + } + +-static char *automount_path_to_fifo(unsigned logopt, const char *path) +-{ +- char *fifo_name, *p; +- int name_len = strlen(path) + strlen(fifodir) + 1; +- int ret; +- +- fifo_name = malloc(name_len); +- if (!fifo_name) +- return NULL; +- ret = snprintf(fifo_name, name_len, "%s%s", fifodir, path); +- if (ret >= name_len) { +- info(logopt, +- "fifo path for \"%s\" truncated to \"%s\". This may " +- "lead to --set-log-priority commands being sent to the " +- "wrong automount daemon.", path, fifo_name); +- } +- +- /* +- * An automount path can be made up of subdirectories. So, to +- * create the fifo name, we will just replace instances of '/' with +- * '-'. +- */ +- p = fifo_name + strlen(fifodir); +- while (*p != '\0') { +- if (*p == '/') +- *p = '-'; +- p++; +- } +- +- debug(logopt, "fifo name %s",fifo_name); +- +- return fifo_name; +-} +- +-static int create_logpri_fifo(struct autofs_point *ap) +-{ +- int ret = -1; +- int fd; +- char *fifo_name; +- char buf[MAX_ERR_BUF]; +- +- fifo_name = automount_path_to_fifo(ap->logopt, ap->path); +- if (!fifo_name) { +- crit(ap->logopt, "Failed to allocate memory!"); +- goto out_free; /* free(NULL) is okay */ +- } +- +- ret = unlink(fifo_name); +- if (ret != 0 && errno != ENOENT) { +- crit(ap->logopt, +- "Failed to unlink FIFO. Is the automount daemon " +- "already running?"); +- goto out_free; +- } +- +- ret = mkfifo(fifo_name, S_IRUSR|S_IWUSR); +- if (ret != 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- crit(ap->logopt, +- "mkfifo for %s failed: %s", fifo_name, estr); +- goto out_free; +- } +- +- fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK); +- if (fd < 0) { +- unlink(fifo_name); +- ret = -1; +- goto out_free; +- } +- +- ap->logpri_fifo = fd; +- +-out_free: +- free(fifo_name); +- return ret; +-} +- +-int destroy_logpri_fifo(struct autofs_point *ap) +-{ +- int ret = -1; +- int fd = ap->logpri_fifo; +- char *fifo_name; +- char buf[MAX_ERR_BUF]; +- +- if (fd == -1) +- return 0; +- +- fifo_name = automount_path_to_fifo(ap->logopt, ap->path); +- if (!fifo_name) { +- crit(ap->logopt, "Failed to allocate memory!"); +- goto out_free; /* free(NULL) is okay */ +- } +- +- ap->logpri_fifo = -1; +- +- ret = close(fd); +- if (ret != 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(ap->logopt, +- "close for fifo %s: %s", fifo_name, estr); +- } +- +- ret = unlink(fifo_name); +- if (ret != 0) { +- warn(ap->logopt, +- "Failed to unlink FIFO. Was the fifo created OK?"); +- } +- +-out_free: +- free(fifo_name); +- return ret; +-} +- +-static void cleanup_stale_logpri_fifo_pipes(void) +-{ +- size_t prefix_len = strlen(FIFO_NAME_PREFIX); +- char *dir = AUTOFS_FIFO_DIR; +- size_t dir_len = strlen(dir); +- struct dirent *dent; +- DIR *dfd; +- int ret; +- +- dfd = opendir(dir); +- if (!dfd) { +- warn(LOGOPT_ANY, "failed to open fifo dir %s", dir); +- return; +- } +- +- while ((dent = readdir(dfd))) { +- char fifo_path[PATH_MAX]; +- +- if (!(dent->d_type & DT_FIFO)) +- continue; +- if (strncmp(FIFO_NAME_PREFIX, dent->d_name, prefix_len)) +- continue; +- if ((dir_len + 1 + strlen(dent->d_name)) >= PATH_MAX) { +- warn(LOGOPT_ANY, "fifo path too long for buffer"); +- continue; +- } +- +- strcpy(fifo_path, dir); +- strcat(fifo_path, "/"); +- strcat(fifo_path, dent->d_name); +- +- ret = unlink(fifo_path); +- if (ret == -1) { +- char buf[MAX_ERR_BUF]; +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(LOGOPT_ANY, "unlink of fifo failed: %s", estr); +- } +- } +- +- closedir(dfd); +-} +- +-static void handle_fifo_message(int fd) +-{ +- struct autofs_point *ap; +- int ret; +- char buffer[PIPE_BUF]; +- char *end, *sep; +- long pri; +- char buf[MAX_ERR_BUF]; +- dev_t devid; +- +- memset(buffer, 0, sizeof(buffer)); +- ret = read(fd, &buffer, sizeof(buffer)); +- if (ret < 0) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(LOGOPT_ANY, "read on fifo returned error: %s", estr); +- return; +- } +- +- sep = strrchr(buffer, ' '); +- if (!sep) { +- error(LOGOPT_ANY, "Incorrect cmd message format %s.", buffer); +- return; +- } +- sep++; +- +- errno = 0; +- devid = strtol(buffer, &end, 10); +- if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) { +- debug(LOGOPT_ANY, "strtol reported a range error."); +- error(LOGOPT_ANY, "Invalid cmd message format %s.", buffer); +- return; +- } +- if ((devid == 0 && errno == EINVAL) || end == buffer) { +- debug(LOGOPT_ANY, "devid id is expected to be a integer."); +- return; +- } +- +- ap = master_find_mapent_by_devid(master_list, devid); +- if (!ap) { +- error(LOGOPT_ANY, "Can't locate autofs_point for device id %ld.", devid); +- return; +- } +- +- errno = 0; +- pri = strtol(sep, &end, 10); +- if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) { +- debug(ap->logopt, "strtol reported an %s. Failed to set " +- "log priority.", pri == LONG_MIN ? "underflow" : "overflow"); +- return; +- } +- if ((pri == 0 && errno == EINVAL) || end == sep) { +- debug(ap->logopt, "priority is expected to be an integer " +- "in the range 0-7 inclusive."); +- return; +- } +- +- if (pri > LOG_DEBUG || pri < LOG_EMERG) { +- debug(ap->logopt, "invalid log priority (%ld) received " +- "on fifo", pri); +- return; +- } +- +- /* +- * OK, the message passed all of the sanity checks. The +- * automounter actually only supports three log priorities. +- * Everything is logged at log level debug, deamon messages +- * and everything except debug messages are logged with the +- * verbose setting and only error and critical messages are +- * logged when debugging isn't enabled. +- */ +- if (pri >= LOG_WARNING) { +- if (pri == LOG_DEBUG) { +- set_log_debug_ap(ap); +- info(ap->logopt, "Debug logging set for %s", ap->path); +- } else { +- set_log_verbose_ap(ap); +- info(ap->logopt, "Verbose logging set for %s", ap->path); +- } +- } else { +- if (ap->logopt & LOGOPT_ANY) +- info(ap->logopt, "Basic logging set for %s", ap->path); +- set_log_norm_ap(ap); +- } +-} +- +-static int set_log_priority(const char *path, int priority) +-{ +- struct ioctl_ops *ops = get_ioctl_ops(); +- int fd; +- char *fifo_name; +- char buf[FIFO_BUF_SIZE]; +- int ret; +- dev_t devid; +- +- if (!ops) { +- fprintf(stderr, "Could not get ioctl ops\n"); +- return -1; +- } else { +- ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid); +- if (ret == -1 || ret == 0) { +- fprintf(stderr, +- "Could not find device id for mount %s\n", path); +- return -1; +- } +- } +- +- if (priority > LOG_DEBUG || priority < LOG_EMERG) { +- fprintf(stderr, "Log priority %d is invalid.\n", priority); +- fprintf(stderr, "Please specify a number in the range 0-7.\n"); +- return -1; +- } +- +- /* +- * This is an ascii based protocol, so we want the string +- * representation of the integer log priority. +- */ +- ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority); +- if (ret >= FIFO_BUF_SIZE) { +- fprintf(stderr, "Invalid device id or log priotity\n"); +- return -1; +- } +- +- fifo_name = automount_path_to_fifo(LOGOPT_NONE, path); +- if (!fifo_name) { +- fprintf(stderr, "%s: Failed to allocate memory!\n", +- __FUNCTION__); +- return -1; +- } +- +- /* +- * Specify O_NONBLOCK so that the open will fail if there is no +- * daemon reading from the other side of the FIFO. +- */ +- fd = open_fd(fifo_name, O_WRONLY|O_NONBLOCK); +- if (fd < 0) { +- fprintf(stderr, "%s: open of %s failed with %s\n", +- __FUNCTION__, fifo_name, strerror(errno)); +- fprintf(stderr, "%s: perhaps the fifo wasn't setup," +- " please check your log for more information\n", __FUNCTION__); +- free(fifo_name); +- return -1; +- } +- +- if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { +- fprintf(stderr, "Failed to change logging priority. "); +- fprintf(stderr, "write to fifo failed: %s.\n", +- strerror(errno)); +- close(fd); +- free(fifo_name); +- return -1; +- } +- close(fd); +- free(fifo_name); +- fprintf(stdout, "Successfully set log priority for %s.\n", path); +- +- return 0; +-} +- + static void dummy(int sig) + { + } +@@ -1122,18 +805,14 @@ static int get_pkt(struct autofs_point * + { + struct sigaction sa; + sigset_t signalset; +- struct pollfd fds[2]; +- int pollfds = 2; ++ struct pollfd fds[1]; ++ int pollfds = 1; + char buf[MAX_ERR_BUF]; + size_t read; + char *estr; + + fds[0].fd = ap->pipefd; + fds[0].events = POLLIN; +- fds[1].fd = ap->logpri_fifo; +- fds[1].events = POLLIN; +- if (fds[1].fd == -1) +- pollfds--; + + sa.sa_handler = dummy; + sigemptyset(&sa.sa_mask); +@@ -1172,11 +851,6 @@ static int get_pkt(struct autofs_point * + } + return read; + } +- +- if (fds[1].fd != -1 && fds[1].revents & POLLIN) { +- debug(ap->logopt, "message pending on control fifo."); +- handle_fifo_message(fds[1].fd); +- } + } + } + +@@ -1235,11 +909,6 @@ static int autofs_init_ap(struct autofs_ + ap->pipefd = pipefd[0]; + ap->kpipefd = pipefd[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); +- } +- + return 0; + } + +@@ -1260,11 +929,6 @@ static int mount_autofs(struct autofs_po + else + status = mount_autofs_indirect(ap, root); + +- if (status < 0) { +- destroy_logpri_fifo(ap); +- return -1; +- } +- + st_add_task(ap, ST_READY); + + return status; +@@ -1835,6 +1499,68 @@ static void handle_cmd_pipe_fifo_message + } + } + ++static int set_log_priority(const char *path, int priority) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ char buf[FIFO_BUF_SIZE]; ++ dev_t devid; ++ int fd; ++ int ret; ++ ++ if (!ops) { ++ fprintf(stderr, "Could not get ioctl ops\n"); ++ return -1; ++ } else { ++ ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid); ++ if (ret == -1 || ret == 0) { ++ fprintf(stderr, ++ "Could not find device id for mount %s\n", path); ++ return -1; ++ } ++ } ++ ++ if (priority > LOG_DEBUG || priority < LOG_EMERG) { ++ fprintf(stderr, "Log priority %d is invalid.\n", priority); ++ fprintf(stderr, "Please specify a number in the range 0-7.\n"); ++ return -1; ++ } ++ ++ /* ++ * This is an ascii based protocol, so we want the string ++ * representation of the integer log priority. ++ */ ++ ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority); ++ if (ret >= FIFO_BUF_SIZE) { ++ fprintf(stderr, "Invalid device id or log priotity\n"); ++ return -1; ++ } ++ ++ /* ++ * Specify O_NONBLOCK so that the open will fail if there is no ++ * daemon reading from the other side of the FIFO. ++ */ ++ fd = open_fd(cmd_pipe_name, O_WRONLY|O_NONBLOCK); ++ if (fd < 0) { ++ fprintf(stderr, "%s: open of %s failed with %s\n", ++ __FUNCTION__, cmd_pipe_name, strerror(errno)); ++ fprintf(stderr, "%s: perhaps the fifo wasn't setup," ++ " please check your log for more information\n", __FUNCTION__); ++ return -1; ++ } ++ ++ if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { ++ fprintf(stderr, "Failed to change logging priority. "); ++ fprintf(stderr, "write to fifo failed: %s.\n", ++ strerror(errno)); ++ close(fd); ++ return -1; ++ } ++ close(fd); ++ fprintf(stdout, "Successfully set log priority for %s.\n", path); ++ ++ return 0; ++} ++ + static void cmd_pipe_dummy(int sig) + { + } +@@ -2035,8 +1761,6 @@ static void handle_mounts_cleanup(void * + master_remove_mapent(ap->entry); + master_source_unlock(ap->entry); + +- destroy_logpri_fifo(ap); +- + /* + * Submounts are detached threads and don't belong to the + * master map entry list so we need to free their resources +@@ -2950,6 +2674,18 @@ int main(int argc, char *argv[]) + + init_ioctl_ctl(); + ++ if (!start_cmd_pipe_handler()) { ++ logerr("%s: failed to create command pipe handler thread!", program); ++ master_kill(master_list); ++ if (start_pipefd[1] != -1) { ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ } ++ release_flag_file(); ++ macro_free_global_table(); ++ exit(1); ++ } ++ + if (!alarm_start_handler()) { + logerr("%s: failed to create alarm handler thread!", program); + master_kill(master_list); +@@ -3015,13 +2751,7 @@ int main(int argc, char *argv[]) + } + } + +- /* If the option to unlink all autofs mounts and exit has +- * been given remove logpri fifo pipe files as all the mounts +- * will be detached leaving them stale. +- */ +- if (do_force_unlink & UNLINK_AND_EXIT) +- cleanup_stale_logpri_fifo_pipes(); +- else { ++ if (!(do_force_unlink & UNLINK_AND_EXIT)) { + /* + * Mmm ... reset force unlink umount so we don't also do + * this in future when we receive a HUP signal. +@@ -3045,6 +2775,8 @@ int main(int argc, char *argv[]) + + master_kill(master_list); + ++ finish_cmd_pipe_handler(); ++ + if (pid_file) { + unlink(pid_file); + pid_file = NULL; +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -112,8 +112,6 @@ int master_add_autofs_point(struct maste + + ap->state = ST_INIT; + +- ap->logpri_fifo = -1; +- + ap->path = strdup(entry->path); + if (!ap->path) { + free(ap); +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -552,7 +552,6 @@ struct autofs_point { + int pipefd; /* File descriptor for pipe */ + int kpipefd; /* Kernel end descriptor for pipe */ + int ioctlfd; /* File descriptor for ioctls */ +- int logpri_fifo; /* FIFO used for changing log levels */ + dev_t dev; /* "Device" number assigned by kernel */ + struct master_mapent *entry; /* Master map entry for this mount */ + unsigned int type; /* Type of map direct or indirect */ +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -82,7 +82,6 @@ static struct parse_context default_cont + 1 /* Do slashify_colons */ + }; + +-int destroy_logpri_fifo(struct autofs_point *ap); + static char *concat_options(char *left, char *right); + + /* Free all storage associated with this context */ diff --git a/SOURCES/autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch b/SOURCES/autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch new file mode 100644 index 0000000..1f8ae61 --- /dev/null +++ b/SOURCES/autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch @@ -0,0 +1,155 @@ +autofs-5.1.8 - use device id to locate autofs_point when setting log priotity + +From: Ian Kent + +Using a fifo pipe for every autofs mount to dynamically set the log +priority is expensive in terms of the number of file handles used. + +It would be better to use a single file handle and locate the autofs +mount point by it's id to set the log priority. + +Start by making the communication pipe send the device id as well as +the log priority to be set and use the newly added helper function +master_find_mapent_by_devid() to locate the autofs mount to change the +log priority. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 63 ++++++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 54 insertions(+), 10 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -125,6 +125,7 @@ + - fix incorrect print format specifiers in get_pkt(). + - eliminate last remaining state_pipe usage. + - add function master_find_mapent_by_devid(). ++- use device id to locate autofs_point when setting log priotity. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -59,6 +59,8 @@ unsigned int mp_mode = 0755; + unsigned int nfs_mount_uses_string_options = 0; + static struct nfs_mount_vers vers, check = {1, 1, 1}; + ++#define FIFO_BUF_SIZE 25 ++ + /* autofs fifo name prefix */ + #define FIFO_NAME_PREFIX "autofs.fifo" + const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX; +@@ -946,35 +948,57 @@ static void cleanup_stale_logpri_fifo_pi + closedir(dfd); + } + +-static void handle_fifo_message(struct autofs_point *ap, int fd) ++static void handle_fifo_message(int fd) + { ++ struct autofs_point *ap; + int ret; + char buffer[PIPE_BUF]; +- char *end; ++ char *end, *sep; + long pri; + char buf[MAX_ERR_BUF]; ++ dev_t devid; + + memset(buffer, 0, sizeof(buffer)); + ret = read(fd, &buffer, sizeof(buffer)); + if (ret < 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(ap->logopt, "read on fifo returned error: %s", estr); ++ warn(LOGOPT_ANY, "read on fifo returned error: %s", estr); ++ return; ++ } ++ ++ sep = strrchr(buffer, ' '); ++ if (!sep) { ++ error(LOGOPT_ANY, "Incorrect cmd message format %s.", buffer); ++ return; ++ } ++ sep++; ++ ++ errno = 0; ++ devid = strtol(buffer, &end, 10); ++ if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) { ++ debug(LOGOPT_ANY, "strtol reported a range error."); ++ error(LOGOPT_ANY, "Invalid cmd message format %s.", buffer); ++ return; ++ } ++ if ((devid == 0 && errno == EINVAL) || end == buffer) { ++ debug(LOGOPT_ANY, "devid id is expected to be a integer."); + return; + } + +- if (ret != 2) { +- debug(ap->logopt, "expected 2 bytes, received %d.", ret); ++ ap = master_find_mapent_by_devid(master_list, devid); ++ if (!ap) { ++ error(LOGOPT_ANY, "Can't locate autofs_point for device id %ld.", devid); + return; + } + + errno = 0; +- pri = strtol(buffer, &end, 10); ++ pri = strtol(sep, &end, 10); + if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) { + debug(ap->logopt, "strtol reported an %s. Failed to set " + "log priority.", pri == LONG_MIN ? "underflow" : "overflow"); + return; + } +- if ((pri == 0 && errno == EINVAL) || end == buffer) { ++ if ((pri == 0 && errno == EINVAL) || end == sep) { + debug(ap->logopt, "priority is expected to be an integer " + "in the range 0-7 inclusive."); + return; +@@ -1011,9 +1035,24 @@ static void handle_fifo_message(struct a + + static int set_log_priority(const char *path, int priority) + { ++ struct ioctl_ops *ops = get_ioctl_ops(); + int fd; + char *fifo_name; +- char buf[2]; ++ char buf[FIFO_BUF_SIZE]; ++ int ret; ++ dev_t devid; ++ ++ if (!ops) { ++ fprintf(stderr, "Could not get ioctl ops\n"); ++ return -1; ++ } else { ++ ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid); ++ if (ret == -1 || ret == 0) { ++ fprintf(stderr, ++ "Could not find device id for mount %s\n", path); ++ return -1; ++ } ++ } + + if (priority > LOG_DEBUG || priority < LOG_EMERG) { + fprintf(stderr, "Log priority %d is invalid.\n", priority); +@@ -1025,7 +1064,11 @@ static int set_log_priority(const char * + * This is an ascii based protocol, so we want the string + * representation of the integer log priority. + */ +- snprintf(buf, sizeof(buf), "%d", priority); ++ ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority); ++ if (ret >= FIFO_BUF_SIZE) { ++ fprintf(stderr, "Invalid device id or log priotity\n"); ++ return -1; ++ } + + fifo_name = automount_path_to_fifo(LOGOPT_NONE, path); + if (!fifo_name) { +@@ -1124,7 +1167,7 @@ static int get_pkt(struct autofs_point * + + if (fds[1].fd != -1 && fds[1].revents & POLLIN) { + debug(ap->logopt, "message pending on control fifo."); +- handle_fifo_message(ap, fds[1].fd); ++ handle_fifo_message(fds[1].fd); + } + } + } diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec index 4e237df..2761b0f 100644 --- a/SPECS/autofs.spec +++ b/SPECS/autofs.spec @@ -12,7 +12,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.7 -Release: 36%{?dist} +Release: 55%{?dist} Epoch: 1 License: GPLv2+ Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz @@ -138,6 +138,53 @@ Patch110: autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch Patch111: autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch Patch112: autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch Patch113: autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch +Patch114: autofs-5.1.8-fail-on-empty-replicated-host-name.patch +Patch115: autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch +Patch116: autofs-5.1.8-dont-immediately-call-function-when-waiting.patch + +Patch120: autofs-5.1.8-fix-return-status-of-mount_autofs.patch +Patch121: autofs-5.1.8-dont-close-lookup-at-umount.patch +Patch122: autofs-5.1.8-fix-deadlock-in-lookups.patch +Patch123: autofs-5.1.8-dont-delay-expire.patch +Patch124: autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch +Patch125: autofs-5.1.8-rename-statemachine-to-signal_handler.patch +Patch126: autofs-5.1.8-make-signal-handling-consistent.patch +Patch127: autofs-5.1.7-fix-incorrect-print-format-specifiers.patch +Patch128: autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch +Patch129: autofs-5.1.8-add-function-master_find_mapent_by_devid.patch +Patch130: autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch +Patch131: autofs-5.1.8-add-command-pipe-handling-functions.patch +Patch132: autofs-5.1.8-switch-to-application-wide-command-pipe.patch +Patch133: autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch +Patch134: autofs-5.1.8-fix-mount-tree-startup-reconnect.patch +Patch135: autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch + +Patch150: autofs-5.1.8-fix-memory-leak-in-sasl_do_kinit.patch +Patch151: autofs-5.1.8-fix-fix-mount-tree-startup-reconnect.patch +Patch152: autofs-5.1.8-fix-use_ignore_mount_option-description.patch +Patch153: autofs-5.1.8-include-addtional-log-info-for-mounts.patch +Patch154: autofs-5.1.8-fix-amd-selector-function-matching.patch +Patch155: autofs-5.1.8-get-rid-entry-thid-field.patch +Patch156: autofs-5.1.8-continue-expire-immediately-after-submount-check.patch +Patch157: autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch +Patch158: autofs-5.1.8-eliminate-realpath-from-mount-of-submount.patch +Patch159: autofs-5.1.8-eliminate-root-param-from-autofs-mount-and-umount.patch +Patch160: autofs-5.1.8-remove-redundant-stat-from-do_mount_direct.patch +Patch161: autofs-5.1.8-get-rid-of-strlen-call-in-handle_packet_missing_direct.patch +Patch162: autofs-5.1.8-remove-redundant-stat-call-in-lookup_ghost.patch +Patch163: autofs-5.1.8-set-mapent-dev-and-ino-before-adding-to-index.patch +Patch164: autofs-5.1.8-change-to-use-printf-functions-in-amd-parser.patch +Patch165: autofs-5.1.8-dont-call-umount_subtree_mounts-on-parent-at-umount.patch +Patch166: autofs-5.1.8-dont-take-parent-source-lock-at-mount-shutdown.patch +Patch167: autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch +Patch168: autofs-5.1.8-fix-possible-use-after-free-in-handle_mounts_exit.patch +Patch169: autofs-5.1.8-make-submount-cleanup-the-same-as-top-level-mounts.patch +Patch170: autofs-5.1.8-add-soucre-parameter-to-module-functions.patch +Patch171: autofs-5.1.8-add-ioctlfd-open-helper.patch +Patch172: autofs-5.1.8-make-open-files-limit-configurable.patch +Patch173: autofs-5.1.8-fix-some-sss-error-return-cases.patch +Patch174: autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch +Patch175: autofs-5.1.8-fix-expire-retry-looping.patch %if %{with_systemd} BuildRequires: systemd-units @@ -320,6 +367,53 @@ echo %{version}-%{release} > .version %patch111 -p1 %patch112 -p1 %patch113 -p1 +%patch114 -p1 +%patch115 -p1 +%patch116 -p1 + +%patch120 -p1 +%patch121 -p1 +%patch122 -p1 +%patch123 -p1 +%patch124 -p1 +%patch125 -p1 +%patch126 -p1 +%patch127 -p1 +%patch128 -p1 +%patch129 -p1 +%patch130 -p1 +%patch131 -p1 +%patch132 -p1 +%patch133 -p1 +%patch134 -p1 +%patch135 -p1 + +%patch150 -p1 +%patch151 -p1 +%patch152 -p1 +%patch153 -p1 +%patch154 -p1 +%patch155 -p1 +%patch156 -p1 +%patch157 -p1 +%patch158 -p1 +%patch159 -p1 +%patch160 -p1 +%patch161 -p1 +%patch162 -p1 +%patch163 -p1 +%patch164 -p1 +%patch165 -p1 +%patch166 -p1 +%patch167 -p1 +%patch168 -p1 +%patch169 -p1 +%patch170 -p1 +%patch171 -p1 +%patch172 -p1 +%patch173 -p1 +%patch174 -p1 +%patch175 -p1 %build LDFLAGS=-Wl,-z,now @@ -428,6 +522,89 @@ fi %dir /etc/auto.master.d %changelog +* Wed Aug 02 2023 Ian Kent - 1:5.1.7-55 +- bz2223252 - filesystems mount and expire immediately + - fix expire retry looping. + - correct day in changelog entry for revision 53. +- Resolves: rhbz#2223252 + +* Mon Jul 17 2023 Ian Kent - 1:5.1.7-54 +- bz2223236 - When looking up included maps, sometimes autofs does not + consult all the included files in order + - fix incorrect matching of cached wildcard key. +- Resolves: rhbz#2223236 + +* Thu Jul 13 2023 Ian Kent - 1:5.1.7-53 +- bz2215661 - The sss lookup modules handles error return incorrectly in + some cases + - fix some sss error return cases. +- Resolves: rhbz#2215661 + +* Tue Jun 13 2023 Ian Kent - 1:5.1.7-52 +- bz2210899 - amd map format netgoup selector function not working + - fix use_ignore_mount_option description. + - include addtional log info for mounts. + - fix amd selector function matching. + - get rid entry thid field. + - continue expire immediately after submount check. + - add buffer length checks to autofs mount_mount(). + - eliminate realpath from mount of submount. + - eliminate root param from autofs mount and umount. + - remove redundant fstat from do_mount_direct(). + - get rid of strlen call in handle_packet_missing_direct(). + - remove redundant stat call in lookup_ghost(). + - set mapent dev and ino before adding to index. + - change to use printf functions in amd parser. + - dont call umount_subtree_mounts() on parent at umount. + - dont take parent source lock at mount shutdown. + - eliminate buffer usage from handle_mounts_cleanup(). + - fix possible use after free in handle_mounts_exit(). + - make submount cleanup the same as top level mounts. + - add soucre parameter to module functions. + - add ioctlfd open helper. + - make open files limit configurable. +- Resolves: rhbz#2210899 + +* Fri Jun 02 2023 Ian Kent - 1:5.1.7-51 +- bz2210161 - autofs fails to start with combination of +auto.master and + local direct map lookups after upgrading to 5.1.4-93.el8 + - fix memory leak in sasl_do_kinit() (Coverity). + - fix fix mount tree startup reconnect. +- Resolves: rhbz#2210161 + +* Tue Mar 28 2023 Ian Kent - 1:5.1.7-50 +- bz2179753 - deadlock while reading amd maps + - fix return status of mount_autofs(). + - don't close lookup at umount. + - fix deadlock in lookups. + - dont delay expire. + - make amd mapent search function name clear. + - rename statemachine() to signal_handler(). + - make signal handling consistent. + - fix incorrect print format specifiers in get_pkt(). + - eliminate last remaining state_pipe usage. + - add function master_find_mapent_by_devid(). + - use device id to locate autofs_point when setting log priotity. + - add command pipe handling functions. + - switch to application wide command pipe. + - get rid of unused field submnt_count. + - fix mount tree startup reconnect. + - fix unterminated read in handle_cmd_pipe_fifo_message() (Coverity). +- Resolves: rhbz#2179753 + +* Mon Mar 27 2023 Ian Kent - 1:5.1.7-38 +- bz2170287 - Autofs reports can't connect to sssd, retry for 10 + seconds when real problem is empty LDAP object + - improve handling of ENOENT in sss setautomntent(). + - dont immediately call function when waiting. +- Resolves: rhbz#2170287 + +* Mon Mar 27 2023 Ian Kent - 1:5.1.7-37 +- bz2170285 - Users can trigger a simple autofs DoS with wildcard + automounter maps + - fail on empty trailing replicated host name. +- Resolves: rhbz#2170285 + * Tue Dec 06 2022 Ian Kent - 1:5.1.7-36 - bz2149013 - autofs: errors in autofs-5.1.4-83.el8.x86_64 when restarting autofs with busy directories