import CS autofs-5.1.7-55.el9

This commit is contained in:
eabdullin 2023-09-21 18:04:33 +00:00
parent 9a8980ee3c
commit a11453e9dc
46 changed files with 6329 additions and 1 deletions

View File

@ -0,0 +1,104 @@
autofs-5.1.7 - add buffer length checks to autofs mount_mount()
From: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,82 @@
autofs-5.1.7 - eliminate buffer usage from handle_mounts_cleanup()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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

View File

@ -0,0 +1,40 @@
autofs-5.1.7 - fix incorrect print format specifiers in get_pkt()
From: Ian Kent <raven@themaw.net>
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,310 @@
autofs-5.1.8 - add command pipe handling functions
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,125 @@
autofs-5.1.8 - add function master_find_mapent_by_devid()
From: Ian Kent <raven@themaw.net>
Add a helper function that can locate an automount given its device id.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,270 @@
autofs-5.1.8 - add ioctlfd open helper
From: Ian Kent <raven@themaw.net>
Add an ioctl fd open helper, it simplifies the code in some areas.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
autofs-5.1.8 - change to use printf functions in amd parser
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;
}
}

View File

@ -0,0 +1,56 @@
autofs-5.1.8 - continue expire immediately after submount check
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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 &&

View File

@ -0,0 +1,40 @@
autofs-5.1.8 - dont call umount_subtree_mounts() on parent at umount
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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 */

View File

@ -0,0 +1,47 @@
autofs-5.1.8 - don't close lookup at umount
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);

View File

@ -0,0 +1,94 @@
autofs-5.1.8 - dont delay expire
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);

View File

@ -0,0 +1,101 @@
autofs-5.1.8 - dont immediately call function when waiting
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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)

View File

@ -0,0 +1,118 @@
autofs-5.1.8 - dont take parent source lock at mount shutdown
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);

View File

@ -0,0 +1,292 @@
autofs-5.1.8 - eliminate last remaining state_pipe usage
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);

View File

@ -0,0 +1,112 @@
autofs-5.1.8 - eliminate realpath from mount of submount
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);

View File

@ -0,0 +1,396 @@
autofs-5.1.8 - eliminate root param from autofs mount and umount
From: Ian Kent <raven@themaw.net>
Eliminate the "root" parameter of both mount and umount of autofs mounts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,57 @@
autofs-5.1.8 - fail on empty replicated host name
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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++;
}

View File

@ -0,0 +1,49 @@
autofs-5.1.8 - fix amd selector function matching
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,141 @@
autofs-5.1.8 - fix deadlock in lookups
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,83 @@
autofs-5.1.8 - fix expire retry looping
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,45 @@
autofs-5.1.8 - fix fix mount tree startup reconnect
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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)) {

View File

@ -0,0 +1,62 @@
autofs-5.1.8 - fix incorrect matching of cached wildcard key
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;
}

View File

@ -0,0 +1,45 @@
autofs-5.1.8 - fix memory leak in sasl_do_kinit()
From: Ian Kent <raven@themaw.net>
In sasl_do_kinit() there is a failure case that omits freeing the local
variable tgs_princ, fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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:

View File

@ -0,0 +1,54 @@
autofs-5.1.8 - fix mount tree startup reconnect
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,58 @@
autofs-5.1.8 - fix possible use after free in handle_mounts_exit()
From: Ian Kent <raven@themaw.net>
Don't free the submount map entry until it's no longer used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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.

View File

@ -0,0 +1,43 @@
autofs-5.1.8 - fix return status of mount_autofs()
From: Ian Kent <raven@themaw.net>
The function mount_autofs() collects the status of mounting an autofs
file system but doesn't actually return it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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)

View File

@ -0,0 +1,78 @@
autofs-5.1.8 - fix some sss error return cases
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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

View File

@ -0,0 +1,46 @@
autofs-5.1.8 - fix unterminated read in handle_cmd_pipe_fifo_message()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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) {

View File

@ -0,0 +1,56 @@
autofs-5.1.8 - fix use_ignore_mount_option description
From: Ian Kent <raven@themaw.net>
Fix a couple of grammer problem with the configuration setting
use_ignore_mount_option description.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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
#

View File

@ -0,0 +1,62 @@
autofs-5.1.8 - get rid entry thid field
From: Ian Kent <raven@themaw.net>
Use the autofs_point structure thid and get rid of the copy in struct
master_mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,52 @@
autofs-5.1.8 - get rid of strlen call in handle_packet_missing_direct()
From: Ian Kent <raven@themaw.net>
There is a length field in struct mapent, use it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,69 @@
autofs-5.1.8 - get rid of unused field submnt_count
From: Ian Kent <raven@themaw.net>
The autofs mount point struct field submnt_count is present but not
used, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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;

View File

@ -0,0 +1,59 @@
autofs-5.1.8 - improve handling of ENOENT in sss setautomntent()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;
}

View File

@ -0,0 +1,160 @@
autofs-5.1.8 - include addtional log info for mounts
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,81 @@
autofs-5.1.8 - make amd mapent search function name clear
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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 *);

View File

@ -0,0 +1,177 @@
autofs-5.1.8 - make open files limit configurable
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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 ]

View File

@ -0,0 +1,75 @@
autofs-5.1.8 - make signal handling consistent
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);
}

View File

@ -0,0 +1,131 @@
autofs-5.1.8 - make submount cleanup the same as top level mounts
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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",

View File

@ -0,0 +1,58 @@
autofs-5.1.8 - remove redundant stat call in lookup_ghost()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;
}

View File

@ -0,0 +1,48 @@
autofs-5.1.8 - remove redundant stat from do_mount_direct()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);
}

View File

@ -0,0 +1,63 @@
autofs-5.1.8 - rename statemachine() to signal_handler()
From: Ian Kent <raven@themaw.net>
Rename function statemachine() to signal_handler() to align with what
the function actually does.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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);

View File

@ -0,0 +1,140 @@
autofs-5.1.8 - set mapent dev and ino before adding to index
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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;

View File

@ -0,0 +1,568 @@
autofs-5.1.8 - switch to application wide command pipe
From: Ian Kent <raven@themaw.net>
Switch to use the functions previously added to allow a single
application wide command pipe to be used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
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 */

View File

@ -0,0 +1,155 @@
autofs-5.1.8 - use device id to locate autofs_point when setting log priotity
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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);
}
}
}

View File

@ -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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 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 <ikent@redhat.com> - 1:5.1.7-36
- bz2149013 - autofs: errors in autofs-5.1.4-83.el8.x86_64 when restarting
autofs with busy directories