- add changes for bug 2181545, including upstream updates.

This commit is contained in:
Ian Kent 2023-03-25 11:27:06 +08:00
parent 79c6ef3a0f
commit ee3c3e88b1
31 changed files with 3973 additions and 0 deletions

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -44,6 +44,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/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"
@@ -1662,6 +1670,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -42,6 +42,7 @@
- rename statemachine() to signal_handler().
- make signal handling consistent.
- eliminate last remaining state_pipe usage.
+- add function master_find_mapent_by_devid().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -745,6 +745,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.8.orig/include/master.h
+++ autofs-5.1.8/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.8.orig/include/mounts.h
+++ autofs-5.1.8/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.8.orig/lib/mounts.c
+++ autofs-5.1.8/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,32 @@
autofs-5.1.8 - coverity fix for invalid access
From: Ian Kent <raven@themaw.net>
Fix invalid access in modules/parse_amd.c:do_host_mount().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -22,6 +22,7 @@
- fix autofs regression due to positive_timeout.
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
+- coverity fix for invalid access.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/parse_amd.c
+++ autofs-5.1.8/modules/parse_amd.c
@@ -1366,7 +1366,6 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- close_lookup(lookup);
goto out;
}
}

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -35,6 +35,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -742,13 +742,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -37,6 +37,7 @@
- fix return status of mount_autofs().
- don't close lookup at umount.
- fix deadlock in lookups.
+- dont delay expire.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -1256,17 +1256,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.8.orig/daemon/state.c
+++ autofs-5.1.8/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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -33,6 +33,7 @@
- include addtional log info for mounts.
- fail on empty replicated host name.
- improve handling of ENOENT in sss setautomntent().
+- don't immediately call function when waiting.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/lookup_sss.c
+++ autofs-5.1.8/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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -41,6 +41,7 @@
- make amd mapent search function name clear.
- rename statemachine() to signal_handler().
- make signal handling consistent.
+- eliminate last remaining state_pipe usage.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -1068,58 +1068,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) {
@@ -1134,9 +1127,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);
}
}
}
@@ -1199,15 +1192,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.8.orig/daemon/direct.c
+++ autofs-5.1.8/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.8.orig/daemon/indirect.c
+++ autofs-5.1.8/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.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -113,8 +113,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);
@@ -1396,7 +1394,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);
@@ -1480,9 +1478,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;
@@ -1539,19 +1534,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.8.orig/daemon/state.c
+++ autofs-5.1.8/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.8.orig/include/automount.h
+++ autofs-5.1.8/include/automount.h
@@ -565,7 +565,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.8.orig/include/state.h
+++ autofs-5.1.8/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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -31,6 +31,7 @@
- fix additional tsv invalid access.
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
+- fail on empty replicated host name.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/parse_sun.c
+++ autofs-5.1.8/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,44 @@
autofs-5.1.8 - fix additional tsv invalid access
From: Ian Kent <raven@themaw.net>
When using the --dumpmaps option of automount(8) a SEGV can occur
because a thread specific data variable accessed in the code hasn't
yet been created.
There is another thread specific data variable that is accessed when
dumping the maps so it needs to be created too.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 8 ++++++++
2 files changed, 9 insertions(+)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -28,6 +28,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().
+- fix additional tsv invalid access.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -2538,6 +2538,14 @@ int main(int argc, char *argv[])
exit(1);
}
+ status = pthread_key_create(&key_thread_attempt_id, free);
+ if (status) {
+ logerr("%s: failed to create thread data key for attempt ID!",
+ program);
+ macro_free_global_table();
+ exit(1);
+ }
+
if (master)
master_list = master_new(NULL, timeout, flags);
else

View File

@ -0,0 +1,284 @@
autofs-5.1.8 - fix autofs regression due to positive_timeout
From: Alexandre Merlin <alexandre.merlin@inria.fr>
Because of our use of a script-based map that dynamically creates
exports server-side based on user's rights, we see a regression since
commit 2f562f63a (autofs-5.1.6 - use a valid timeout in
lookup_prune_one_cache()).
Creating an option for a configurable positive_timeout, as mentioned in
the commit comment, would solve this problem for us.
We use autofs to mount these filesystems on the fly, using a map based
on a script which checks that the user is granted, and which asks for
the creation of the appropriate export file on the corresponding NFS
server.
When the reservation is done, we signal the node's automount daemon
using the USR1 and HUP signals in order to forget what was automounted
by the user (as compute nodes may be shared by different users, we want
to ensure that the previously mounted resource is no more in the
running configuration).
For this to work, our granting access script must be called each time a
user request to access a mounted point. But since the commit [2f562f63a]
introducing the positive timeout, when a user tries to access a mounted
point, the cache is used if a another user used the same mounted point
within the positive timeout timeframe (120s).
So we need a way to disable the cache to be sure that our granting script
is called. It can be done for the NEGATIVE_TIMEOUT but not yet for the
POSITIVE_TIMEOUT.
Signed-off-by: Alexandre Merlin <alexandre.merlin@inria.fr>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 10 +++++++++-
daemon/lookup.c | 6 ++++--
daemon/master.c | 6 ++++++
daemon/master_parse.y | 4 +++-
include/automount.h | 1 +
include/defaults.h | 2 ++
lib/defaults.c | 12 ++++++++++++
man/autofs.conf.5.in | 6 ++++++
redhat/autofs.conf.default.in | 5 +++++
samples/autofs.conf.default.in | 5 +++++
11 files changed, 54 insertions(+), 4 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -19,6 +19,7 @@
- dont use initgroups() at spawn.
- fix missing unlock in sasl_do_kinit_ext_cc().
- fix invalid tsv access.
+- fix autofs regression due to positive_timeout.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -69,6 +69,7 @@ static char *pid_file = NULL; /* File i
unsigned int global_selection_options;
long global_negative_timeout = -1;
+long global_positive_timeout = -1;
int do_force_unlink = 0; /* Forceably unlink mount tree at startup */
static int start_pipefd[2] = {-1, -1};
@@ -2019,6 +2020,8 @@ static void usage(void)
" dump automounter maps and exit\n"
" -n --negative-timeout n\n"
" set the timeout for failed key lookups.\n"
+ " -P --positive-timeout n\n"
+ " set the positive timeout for key lookups.\n"
" -O --global-options\n"
" specify global mount options\n"
" -l --set-log-priority priority path [path,...]\n"
@@ -2277,7 +2280,7 @@ int main(int argc, char *argv[])
time_t timeout;
time_t age = monotonic_time(NULL);
struct rlimit rlim;
- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:";
+ const char *options = "+hp:t:vmdD:SfVrO:l:n:P:CFUM:";
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
{"pid-file", 1, 0, 'p'},
@@ -2289,6 +2292,7 @@ int main(int argc, char *argv[])
{"foreground", 0, 0, 'f'},
{"random-multimount-selection", 0, 0, 'r'},
{"negative-timeout", 1, 0, 'n'},
+ {"positive-timeout", 1, 0, 'P'},
{"dumpmaps", 0, 0, 'm'},
{"global-options", 1, 0, 'O'},
{"version", 0, 0, 'V'},
@@ -2379,6 +2383,10 @@ int main(int argc, char *argv[])
global_negative_timeout = getnumopt(optarg, opt);
break;
+ case 'P':
+ global_positive_timeout = getnumopt(optarg, opt);
+ break;
+
case 'm':
flags |= DAEMON_FLAGS_DUMP_MAPS;
break;
--- autofs-5.1.8.orig/daemon/lookup.c
+++ autofs-5.1.8/daemon/lookup.c
@@ -25,6 +25,8 @@
#include "automount.h"
#include "nsswitch.h"
+extern long global_positive_timeout;
+
static void nsslist_cleanup(void *arg)
{
struct list_head *nsslist = (struct list_head *) arg;
@@ -1362,11 +1364,11 @@ void lookup_prune_one_cache(struct autof
/* If the map hasn't been read (nobrowse
* indirect mounts) then keep cached entries
- * for POSITIVE_TIMEOUT.
+ * for ap->positive_timeout.
*/
if (!(ap->flags & (MOUNT_FLAG_GHOST |
MOUNT_FLAG_AMD_CACHE_ALL))) {
- time_t until = me->age + POSITIVE_TIMEOUT;
+ time_t until = me->age + ap->positive_timeout;
if ((long) age - (long) until < 0) {
me = cache_enumerate(mc, me);
continue;
--- autofs-5.1.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -32,6 +32,7 @@ struct master *master_list = NULL;
extern const char *global_options;
extern long global_negative_timeout;
+extern long global_positive_timeout;
/* Attribute to create a joinable thread */
extern pthread_attr_t th_attr;
@@ -94,11 +95,16 @@ int master_add_autofs_point(struct maste
/*
* Program command line option overrides config.
* We can't use 0 negative timeout so use default.
+ * We can't use <0 positive timeout so use default.
*/
if (global_negative_timeout <= 0)
ap->negative_timeout = defaults_get_negative_timeout();
else
ap->negative_timeout = global_negative_timeout;
+ if (global_positive_timeout < 0)
+ ap->positive_timeout = defaults_get_positive_timeout();
+ else
+ ap->positive_timeout = global_positive_timeout;
ap->exp_timeout = defaults_get_timeout();
ap->exp_runfreq = 0;
ap->flags = 0;
--- autofs-5.1.8.orig/daemon/master_parse.y
+++ autofs-5.1.8/daemon/master_parse.y
@@ -58,6 +58,7 @@ static char *type;
static char *format;
static long timeout;
static long negative_timeout;
+static long positive_timeout;
static unsigned symlnk;
static unsigned strictexpire;
static unsigned nobind;
@@ -112,7 +113,7 @@ static int master_fprintf(FILE *, char *
%token COMMENT
%token MAP
-%token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
+%token OPT_TIMEOUT OPT_NTIMEOUT OPT_PTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE
%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE
%token COLON COMMA NL DDASH
@@ -635,6 +636,7 @@ option: daemon_option
daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
+ | OPT_PTIMEOUT NUMBER { positive_timeout = $2; }
| OPT_SYMLINK { symlnk = 1; }
| OPT_STRICTEXPIRE { strictexpire = 1; }
| OPT_SHARED { propagation = PROPAGATION_SHARED; }
--- autofs-5.1.8.orig/include/automount.h
+++ autofs-5.1.8/include/automount.h
@@ -559,6 +559,7 @@ struct autofs_point {
time_t exp_timeout; /* Indirect mount expire timeout */
time_t exp_runfreq; /* Frequency for polling for timeouts */
time_t negative_timeout; /* timeout in secs for failed mounts */
+ time_t positive_timeout; /* timeout in secs for using cache for map entries */
unsigned int flags; /* autofs mount flags */
unsigned int logopt; /* Per map logging */
pthread_t exp_thread; /* Thread that is expiring */
--- autofs-5.1.8.orig/include/defaults.h
+++ autofs-5.1.8/include/defaults.h
@@ -27,6 +27,7 @@
#define DEFAULT_TIMEOUT "600"
#define DEFAULT_MASTER_WAIT "10"
#define DEFAULT_NEGATIVE_TIMEOUT "60"
+#define DEFAULT_POSITIVE_TIMEOUT "120"
#define DEFAULT_MOUNT_VERBOSE "0"
#define DEFAULT_MOUNT_WAIT "-1"
#define DEFAULT_UMOUNT_WAIT "12"
@@ -160,6 +161,7 @@ int defaults_master_set(void);
unsigned int defaults_get_timeout(void);
int defaults_get_master_wait(void);
unsigned int defaults_get_negative_timeout(void);
+unsigned int defaults_get_positive_timeout(void);
unsigned int defaults_get_browse_mode(void);
unsigned int defaults_get_logging(void);
unsigned int defaults_force_std_prog_map_env(void);
--- autofs-5.1.8.orig/lib/defaults.c
+++ autofs-5.1.8/lib/defaults.c
@@ -50,6 +50,7 @@
#define NAME_TIMEOUT "timeout"
#define NAME_MASTER_WAIT "master_wait"
#define NAME_NEGATIVE_TIMEOUT "negative_timeout"
+#define NAME_POSITIVE_TIMEOUT "positive_timeout"
#define NAME_BROWSE_MODE "browse_mode"
#define NAME_LOGGING "logging"
#define NAME_FORCE_STD_PROG_MAP_ENV "force_standard_program_map_env"
@@ -1703,6 +1704,17 @@ unsigned int defaults_get_negative_timeo
return (unsigned int) n_timeout;
}
+unsigned int defaults_get_positive_timeout(void)
+{
+ long p_timeout;
+
+ p_timeout = conf_get_number(autofs_gbl_sec, NAME_POSITIVE_TIMEOUT);
+ if (p_timeout <= 0)
+ p_timeout = atol(DEFAULT_POSITIVE_TIMEOUT);
+
+ return (unsigned int) p_timeout;
+}
+
unsigned int defaults_get_browse_mode(void)
{
int res;
--- autofs-5.1.8.orig/man/autofs.conf.5.in
+++ autofs-5.1.8/man/autofs.conf.5.in
@@ -43,6 +43,12 @@ Set the default timeout for caching fail
60). If the equivalent command line option is given it will override this
setting.
.TP
+.B positive_timeout
+.br
+Set the default timeout for using cached map entries (program default
+120). If the equivalent command line option is given it will override this
+setting.
+.TP
.B mount_verbose
.br
Use the verbose flag when spawning mount(8), and log some process info
--- autofs-5.1.8.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.8/redhat/autofs.conf.default.in
@@ -29,6 +29,11 @@ timeout = 300
#
#negative_timeout = 60
#
+# positive_timeout - set the default positive timeout for
+# using cached map entries (default 120).
+#
+#positive_timeout = 120
+#
# mount_verbose - use the -v flag when calling mount(8) and log some
# process information about the requestor and its
# parent.
--- autofs-5.1.8.orig/samples/autofs.conf.default.in
+++ autofs-5.1.8/samples/autofs.conf.default.in
@@ -29,6 +29,11 @@ timeout = 300
#
#negative_timeout = 60
#
+# positive_timeout - set the default positive timeout for
+# using cached map entries (default 120).
+#
+#positive_timeout = 120
+#
# mount_verbose - use the -v flag when calling mount(8) and log some
# process information about the requestor and its
# parent.

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -36,6 +36,7 @@
- don't immediately call function when waiting.
- fix return status of mount_autofs().
- don't close lookup at umount.
+- fix deadlock in lookups.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/lookup.c
+++ autofs-5.1.8/daemon/lookup.c
@@ -320,31 +320,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.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -73,6 +73,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.8.orig/include/master.h
+++ autofs-5.1.8/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.8.orig/modules/parse_amd.c
+++ autofs-5.1.8/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,169 @@
autofs-5.1.8 - fix deadlock with hosts map reload
From: Ian Kent <raven@themaw.net>
When reloading maps the hosts map calls lookup method ->parse_mount()
for each multi-mount root entry in the map (each host) while holding
the cache read lock which leads to a cache lock deadlock.
Remove the need to hold the cache read lock by creating an independent
list of entries for the update so the lock doesn't need to be taken.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
modules/lookup_hosts.c | 100 ++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 83 insertions(+), 18 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -24,6 +24,7 @@
- serialise lookup module open and reinit.
- coverity fix for invalid access.
- fix hosts map deadlock on restart.
+- fix deadlock with hosts map reload.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/lookup_hosts.c
+++ autofs-5.1.8/modules/lookup_hosts.c
@@ -201,10 +201,72 @@ static int do_parse_mount(struct autofs_
return NSS_STATUS_SUCCESS;
}
+struct update_context {
+ char *key;
+ int key_len;
+ char *entry;
+ struct update_context *next;
+};
+
+static int add_update_entry(struct update_context **entries, struct mapent *me)
+{
+ struct update_context *upd;
+ char *key, *ent;
+
+ key = strdup(me->key);
+ if (!key)
+ return 0;
+
+ ent = strdup(me->mapent);
+ if (!ent) {
+ free(key);
+ return 0;
+ }
+
+ upd = malloc(sizeof(struct update_context));
+ if (!upd) {
+ free(ent);
+ free(key);
+ return 0;
+ }
+
+ upd->key = key;
+ upd->key_len = me->len;
+ upd->entry = ent;
+ upd->next = NULL;
+ if (*entries)
+ (*entries)->next = upd;
+ *entries = upd;
+
+ return 1;
+}
+
+static void free_update_entries(struct update_context *entries)
+{
+ struct update_context *this = entries;
+
+ while (this) {
+ struct update_context *next = this->next;
+ free(this->key);
+ free(this->entry);
+ free(this);
+ this = next;
+ }
+}
+
+void entries_cleanup(void *arg)
+{
+ struct update_context *entries = arg;
+
+ free_update_entries(entries);
+}
+
static void update_hosts_mounts(struct autofs_point *ap,
struct map_source *source, time_t age,
struct lookup_context *ctxt)
{
+ struct update_context *head = NULL;
+ struct update_context *entries = NULL;
struct mapent_cache *mc;
struct mapent *me;
char *mapent;
@@ -212,6 +274,8 @@ static void update_hosts_mounts(struct a
mc = source->mc;
+ pthread_cleanup_push(entries_cleanup, head);
+
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_writelock(mc);
me = cache_lookup_first(mc);
@@ -224,39 +288,39 @@ static void update_hosts_mounts(struct a
mapent = get_exports(ap, me->key);
if (mapent) {
- cache_update(mc, source, me->key, mapent, age);
+ int ret;
+
+ ret = cache_update(mc, source, me->key, mapent, age);
free(mapent);
+ if (!IS_MM_ROOT(me))
+ goto next;
+ if (ret != CHE_FAIL) {
+ if (!add_update_entry(&entries, me))
+ warn(ap->logopt, MODPREFIX
+ "failed to add update entry for %s", me->key);
+ else if (!head)
+ head = entries;
+ }
}
next:
me = cache_lookup_next(mc, me);
}
pthread_cleanup_pop(1);
- pthread_cleanup_push(cache_lock_cleanup, mc);
- cache_readlock(mc);
- me = cache_lookup_first(mc);
- while (me) {
- /*
- * Hosts map entry not yet expanded, already expired
- * or not the base of the tree
- */
- if (!IS_MM(me) || !IS_MM_ROOT(me))
- goto cont;
-
+ while (head) {
debug(ap->logopt, MODPREFIX
- "attempt to update exports for %s", me->key);
+ "attempt to update exports for %s", head->key);
master_source_current_wait(ap->entry);
ap->entry->current = source;
ap->flags |= MOUNT_FLAG_REMOUNT;
- ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
- me->mapent, ctxt->parse->context);
+ ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
+ head->entry, ctxt->parse->context);
if (ret)
warn(ap->logopt, MODPREFIX
- "failed to parse mount %s", me->mapent);
+ "failed to parse mount %s", head->entry);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
-cont:
- me = cache_lookup_next(mc, me);
+ head = head->next;
}
pthread_cleanup_pop(1);
}

View File

@ -0,0 +1,97 @@
autofs-5.1.8 - fix hosts map deadlock on restart
From: Ian Kent <raven@themaw.net>
When starting automount(8) with a hosts map that has mounts that were
in use at the last exit a deadlock can occur.
In this case automount(8) will perform the same steps but not actually
perform the mount to re-construct the context of each mount. But, with
the hosts map, that leads to calling back into the sun parse module
while holding the map module read lock which will again try and take
the write lock.
Fix this by only taking the write lock in the mount code path if the
module handle has not already been opened.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 22 ++++++++++++----------
modules/parse_amd.c | 18 ++++++++++--------
3 files changed, 23 insertions(+), 18 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -23,6 +23,7 @@
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
- coverity fix for invalid access.
+- fix hosts map deadlock on restart.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/lookup.c
+++ autofs-5.1.8/daemon/lookup.c
@@ -809,19 +809,21 @@ int do_lookup_mount(struct autofs_point
struct lookup_mod *lookup;
int status;
- 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_module_unlock(map);
- debug(ap->logopt,
- "lookup module %s open failed", map->type);
- return status;
+ 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_module_unlock(map);
+ debug(ap->logopt,
+ "lookup module %s open failed", map->type);
+ return status;
+ }
+ map->lookup = lookup;
}
- map->lookup = lookup;
+ map_module_unlock(map);
}
- map_module_unlock(map);
master_source_current_wait(ap->entry);
ap->entry->current = map;
--- autofs-5.1.8.orig/modules/parse_amd.c
+++ autofs-5.1.8/modules/parse_amd.c
@@ -1370,17 +1370,19 @@ static int do_host_mount(struct autofs_p
}
}
- map_module_writelock(instance);
if (!instance->lookup) {
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- map_module_unlock(instance);
- debug(ap->logopt, "open lookup module hosts failed");
- goto out;
+ map_module_writelock(instance);
+ if (!instance->lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(instance);
+ debug(ap->logopt, "open lookup module hosts failed");
+ goto out;
+ }
+ instance->lookup = lookup;
}
- instance->lookup = lookup;
+ map_module_unlock(instance);
}
- map_module_unlock(instance);
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);

View File

@ -0,0 +1,63 @@
autofs-5.1.8 - fix incorrect path for is_mounted() in try_remount()
From: Ian Kent <raven@themaw.net>
A regression was introduced when the offset mount handling was rewritten.
It resulted in an incorrect path sometimes being used in an is_mounted()
check.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 26 +++++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -27,6 +27,7 @@
- fix deadlock with hosts map reload.
- fix memory leak in update_hosts_mounts().
- fix minus only option handling in concat_options().
+- fix incorrect path for is_mounted() in try_remount().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/lib/mounts.c
+++ autofs-5.1.8/lib/mounts.c
@@ -2803,14 +2803,30 @@ int try_remount(struct autofs_point *ap,
ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
else
ap->flags |= MOUNT_FLAG_DIR_CREATED;
+ goto done;
+ }
+
+ me->flags &= ~MOUNT_FLAG_DIR_CREATED;
+ /* Direct or offset mount, key is full path */
+ if (MM_PARENT(me)->key[0] == '/') {
+ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
} else {
- me->flags &= ~MOUNT_FLAG_DIR_CREATED;
- if (type == t_offset) {
- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
- me->flags |= MOUNT_FLAG_DIR_CREATED;
+ char *p_key = MM_PARENT(me)->key;
+ char mp[PATH_MAX + 1];
+ int len;
+
+ len = mount_fullpath(mp, PATH_MAX, ap->path, ap->len, p_key);
+ if (len > PATH_MAX) {
+ /* This should never happen due to earlier checks */
+ error(ap->logopt, "mountpoint path too long");
+ return 0;
}
- }
+ if (!is_mounted(mp, MNTS_REAL))
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
+ }
+done:
/*
* Either we opened the mount or we're re-reading the map.
* If we opened the mount and ioctlfd is not -1 we have

View File

@ -0,0 +1,53 @@
autofs-5.1.8 - fix memory leak in update_hosts_mounts()
From: Ian Kent <raven@themaw.net>
Coverity has reported a memory leak in update_hosts_mounts() introduced
by the map reload deadlock fix.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 13 +++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -25,6 +25,7 @@
- coverity fix for invalid access.
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
+- fix memory leak in update_hosts_mounts().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/lookup_hosts.c
+++ autofs-5.1.8/modules/lookup_hosts.c
@@ -307,20 +307,21 @@ next:
}
pthread_cleanup_pop(1);
- while (head) {
+ entries = head;
+ while (entries) {
debug(ap->logopt, MODPREFIX
- "attempt to update exports for %s", head->key);
+ "attempt to update exports for %s", entries->key);
master_source_current_wait(ap->entry);
ap->entry->current = source;
ap->flags |= MOUNT_FLAG_REMOUNT;
- ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
- head->entry, ctxt->parse->context);
+ ret = ctxt->parse->parse_mount(ap, entries->key, strlen(entries->key),
+ entries->entry, ctxt->parse->context);
if (ret)
warn(ap->logopt, MODPREFIX
- "failed to parse mount %s", head->entry);
+ "failed to parse mount %s", entries->entry);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
- head = head->next;
+ entries = entries->next;
}
pthread_cleanup_pop(1);
}

View File

@ -0,0 +1,88 @@
autofs-5.1.8 - fix minus only option handling in concat_options()
From: Ian Kent <raven@themaw.net>
While a '-' alone isn't strictly valid it hadn't previously cuased a
parse error. So commit 9047e91ffa69 (autofs-5.1.7 - fix concat_options()
error handling) introduced a regression by no longer allowing this.
Fix this regression by only failing if errno is set to a non-zero value
on return from concat_options() as well as returning NULL.
Fixes: 9047e91ffa69 (autofs-5.1.7 - fix concat_options() error handling)
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 25 +++++++++++++++++++------
2 files changed, 20 insertions(+), 6 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -26,6 +26,7 @@
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
- fix memory leak in update_hosts_mounts().
+- fix minus only option handling in concat_options().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/parse_sun.c
+++ autofs-5.1.8/modules/parse_sun.c
@@ -376,10 +376,16 @@ static int do_init(int argc, const char
if (gbl_options) {
append_options = defaults_get_append_options();
if (append_options) {
- char *tmp = concat_options(gbl_options, ctxt->optstr);
+ char *tmp;
+
+ errno = 0;
+ tmp = concat_options(gbl_options, ctxt->optstr);
if (!tmp) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "concat_options: %s", estr);
+ /* Ignore non-error NULL return */
+ if (errno) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "concat_options: %s", estr);
+ }
/* freed in concat_options */
ctxt->optstr = NULL;
} else
@@ -1007,9 +1013,12 @@ static int parse_mapent(const char *ent,
free(myoptions);
myoptions = newopt;
} else if (newopt) {
+ errno = 0;
tmp = concat_options(myoptions, newopt);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr;
+
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
@@ -1381,8 +1390,10 @@ dont_expand:
free(mnt_options);
mnt_options = noptions;
} else if (noptions) {
+ errno = 0;
tmp = concat_options(mnt_options, noptions);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
MODPREFIX "concat_options: %s", estr);
@@ -1406,8 +1417,10 @@ dont_expand:
free(options);
options = mnt_options;
} else if (mnt_options) {
+ errno = 0;
tmp = concat_options(options, mnt_options);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "concat_options: %s", estr);
free(pmapent);

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -47,6 +47,7 @@
- add command pipe handling functions.
- switch to application wide command pipe.
- get rid of unused field submnt_count.
+- fix mount tree startup reconnect.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/lib/mounts.c
+++ autofs-5.1.8/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,183 @@
autofs-5.1.8 - fix parse module instance mutex naming
From: Ian Kent <raven@themaw.net>
The naming used for parse module instance locks is the same as that
used for map lookup instances. Rename these to make it clear they
are being used in the parse modules.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 28 ++++++++++++++--------------
modules/parse_sun.c | 20 ++++++++++----------
3 files changed, 25 insertions(+), 24 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -20,6 +20,7 @@
- fix missing unlock in sasl_do_kinit_ext_cc().
- fix invalid tsv access.
- fix autofs regression due to positive_timeout.
+- fix parse module instance mutex naming.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/parse_amd.c
+++ autofs-5.1.8/modules/parse_amd.c
@@ -39,18 +39,18 @@ int parse_version = AUTOFS_PARSE_VERSION
static struct mount_mod *mount_nfs = NULL;
static int init_ctr = 0;
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
-static void instance_mutex_lock(void)
+static void parse_instance_mutex_lock(void)
{
- int status = pthread_mutex_lock(&instance_mutex);
+ int status = pthread_mutex_lock(&parse_instance_mutex);
if (status)
fatal(status);
}
-static void instance_mutex_unlock(void)
+static void parse_instance_mutex_unlock(void)
{
- int status = pthread_mutex_unlock(&instance_mutex);
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
if (status)
fatal(status);
}
@@ -112,7 +112,7 @@ int parse_init(int argc, const char *con
/* We only need this once. NFS mounts are so common that we cache
this module. */
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (mount_nfs)
init_ctr++;
else {
@@ -121,11 +121,11 @@ int parse_init(int argc, const char *con
} else {
kill_context(ctxt);
*context = NULL;
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 1;
}
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 0;
}
@@ -1358,11 +1358,11 @@ static int do_host_mount(struct autofs_p
argc = 1;
}
- instance_mutex_lock();
+ parse_instance_mutex_lock();
status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt, "open lookup module hosts failed");
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
goto out;
}
@@ -1374,13 +1374,13 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
close_lookup(lookup);
goto out;
}
}
instance->lookup = lookup;
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);
@@ -2373,12 +2373,12 @@ int parse_done(void *context)
int rv = 0;
struct parse_context *ctxt = (struct parse_context *) context;
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (--init_ctr == 0) {
rv = close_mount(mount_nfs);
mount_nfs = NULL;
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
if (ctxt)
kill_context(ctxt);
--- autofs-5.1.8.orig/modules/parse_sun.c
+++ autofs-5.1.8/modules/parse_sun.c
@@ -41,18 +41,18 @@ int parse_version = AUTOFS_PARSE_VERSION
static struct mount_mod *mount_nfs = NULL;
static int init_ctr = 0;
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
-static void instance_mutex_lock(void)
+static void parse_instance_mutex_lock(void)
{
- int status = pthread_mutex_lock(&instance_mutex);
+ int status = pthread_mutex_lock(&parse_instance_mutex);
if (status)
fatal(status);
}
-static void instance_mutex_unlock(void)
+static void parse_instance_mutex_unlock(void)
{
- int status = pthread_mutex_unlock(&instance_mutex);
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
if (status)
fatal(status);
}
@@ -424,7 +424,7 @@ int parse_init(int argc, const char *con
/* We only need this once. NFS mounts are so common that we cache
this module. */
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (mount_nfs)
init_ctr++;
else {
@@ -432,11 +432,11 @@ int parse_init(int argc, const char *con
init_ctr++;
} else {
kill_context(ctxt);
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 1;
}
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
*context = (void *) ctxt;
@@ -1728,12 +1728,12 @@ int parse_done(void *context)
int rv = 0;
struct parse_context *ctxt = (struct parse_context *) context;
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (--init_ctr == 0) {
rv = close_mount(mount_nfs);
mount_nfs = NULL;
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
if (ctxt)
kill_context(ctxt);

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -34,6 +34,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().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -1225,7 +1225,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.
@@ -1247,7 +1247,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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -48,6 +48,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().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -1427,7 +1427,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);
@@ -1435,6 +1434,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -29,6 +29,7 @@
- fix minus only option handling in concat_options().
- fix incorrect path for is_mounted() in try_remount().
- fix additional tsv invalid access.
+- fix use_ignore_mount_option description.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.8/redhat/autofs.conf.default.in
@@ -192,11 +192,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.8.orig/samples/autofs.conf.default.in
+++ autofs-5.1.8/samples/autofs.conf.default.in
@@ -191,11 +191,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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -46,6 +46,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -1747,9 +1747,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.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -158,7 +158,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.8.orig/include/automount.h
+++ autofs-5.1.8/include/automount.h
@@ -567,7 +567,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.8.orig/modules/mount_autofs.c
+++ autofs-5.1.8/modules/mount_autofs.c
@@ -379,8 +379,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -32,6 +32,7 @@
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
- fail on empty replicated host name.
+- improve handling of ENOENT in sss setautomntent().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/modules/lookup_sss.c
+++ autofs-5.1.8/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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -30,6 +30,7 @@
- fix incorrect path for is_mounted() in try_remount().
- fix additional tsv invalid access.
- fix use_ignore_mount_option description.
+- include addtional log info for mounts.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -1151,14 +1151,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) {
@@ -1166,13 +1169,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.8.orig/daemon/indirect.c
+++ autofs-5.1.8/daemon/indirect.c
@@ -342,7 +342,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.8.orig/daemon/spawn.c
+++ autofs-5.1.8/daemon/spawn.c
@@ -542,7 +542,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;
}
@@ -553,7 +553,7 @@ done:
if (errp >= ERRBUFSIZ) {
/* Line too long, split */
errbuf[errp] = '\0';
- warn(logopt, ">> %s", errbuf);
+ debug(logopt, ">> %s", errbuf);
errp = 0;
}
}
@@ -567,7 +567,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.8.orig/modules/mount_bind.c
+++ autofs-5.1.8/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.8.orig/modules/mount_ext2.c
+++ autofs-5.1.8/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.8.orig/modules/mount_generic.c
+++ autofs-5.1.8/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.8.orig/modules/mount_nfs.c
+++ autofs-5.1.8/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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -38,6 +38,7 @@
- don't close lookup at umount.
- fix deadlock in lookups.
- dont delay expire.
+- make amd mapent search function name clear.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -747,7 +747,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);
@@ -761,7 +761,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)) {
@@ -812,6 +812,7 @@ struct master_mapent *master_new_mapent(
return NULL;
}
entry->path = tmp;
+ entry->len = strlen(tmp);
entry->thid = 0;
entry->age = age;
@@ -1044,7 +1045,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.8.orig/include/master.h
+++ autofs-5.1.8/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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -40,6 +40,7 @@
- dont delay expire.
- make amd mapent search function name clear.
- rename statemachine() to signal_handler().
+- make signal handling consistent.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -2223,7 +2223,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;
@@ -2234,7 +2234,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 };
@@ -2260,7 +2260,7 @@ static int do_master_read_master(struct
}
}
- sigprocmask(SIG_BLOCK, &signalset, NULL);
+ pthread_sigmask(SIG_SETMASK, &savesigset, NULL);
return ret;
}
@@ -2308,7 +2308,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.8.orig/daemon/spawn.c
+++ autofs-5.1.8/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,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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -39,6 +39,7 @@
- fix deadlock in lookups.
- dont delay expire.
- make amd mapent search function name clear.
+- rename statemachine() to signal_handler().
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/daemon/automount.c
@@ -75,7 +75,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;
@@ -1588,7 +1588,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;
@@ -1775,7 +1775,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();
@@ -2765,8 +2765,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,272 @@
autofs-5.1.8 - serialise lookup module open and reinit
From: Ian Kent <raven@themaw.net>
Add a map source lock to serialise map setting and use of module
structure fields such as the context.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 35 +++++++++++++++++++++--------------
daemon/master.c | 43 +++++++++++++++++++++++++++++++++++++++++++
include/master.h | 5 +++++
modules/parse_amd.c | 26 +++++++++++++++-----------
5 files changed, 85 insertions(+), 25 deletions(-)
--- autofs-5.1.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -21,6 +21,7 @@
- fix invalid tsv access.
- fix autofs regression due to positive_timeout.
- fix parse module instance mutex naming.
+- serialise lookup module open and reinit.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/lookup.c
+++ autofs-5.1.8/daemon/lookup.c
@@ -320,28 +320,27 @@ static int do_read_map(struct autofs_poi
struct lookup_mod *lookup;
int status;
- lookup = NULL;
- master_source_writelock(ap->entry);
+ 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) {
- master_source_unlock(ap->entry);
+ if (status == NSS_STATUS_SUCCESS)
+ map->lookup = lookup;
+ else
debug(ap->logopt,
"lookup module %s open failed", map->type);
- return status;
- }
- map->lookup = lookup;
} else {
- lookup = map->lookup;
- status = lookup->lookup_reinit(map->format,
- map->argc, map->argv,
- &lookup->context);
+ 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);
}
- master_source_unlock(ap->entry);
+ pthread_cleanup_pop(1);
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
if (!map->stale)
return NSS_STATUS_SUCCESS;
@@ -349,7 +348,11 @@ static int do_read_map(struct autofs_poi
master_source_current_wait(ap->entry);
ap->entry->current = map;
+ pthread_cleanup_push(map_module_lock_cleanup, map);
+ map_module_readlock(map);
+ lookup = map->lookup;
status = lookup->lookup_read_map(ap, age, lookup->context);
+ pthread_cleanup_pop(1);
if (status != NSS_STATUS_SUCCESS)
map->stale = 0;
@@ -806,23 +809,27 @@ int do_lookup_mount(struct autofs_point
struct lookup_mod *lookup;
int status;
+ 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_module_unlock(map);
debug(ap->logopt,
"lookup module %s open failed", map->type);
return status;
}
map->lookup = lookup;
}
-
- lookup = map->lookup;
+ map_module_unlock(map);
master_source_current_wait(ap->entry);
ap->entry->current = map;
+ map_module_readlock(map);
+ lookup = map->lookup;
status = lookup->lookup_mount(ap, name, name_len, lookup->context);
+ map_module_unlock(map);
return status;
}
--- autofs-5.1.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -66,6 +66,34 @@ void master_mutex_lock_cleanup(void *arg
return;
}
+void map_module_writelock(struct map_source *map)
+{
+ int status = pthread_rwlock_wrlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_readlock(struct map_source *map)
+{
+ int status = pthread_rwlock_rdlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_unlock(struct map_source *map)
+{
+ int status = pthread_rwlock_unlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_lock_cleanup(void *arg)
+{
+ struct map_source *map = (struct map_source *) arg;
+
+ map_module_unlock(map);
+}
+
int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
unsigned nobind, unsigned ghost, int submount)
{
@@ -161,6 +189,7 @@ master_add_map_source(struct master_mape
struct map_source *source;
char *ntype, *nformat;
const char **tmpargv;
+ int status;
source = malloc(sizeof(struct map_source));
if (!source)
@@ -247,6 +276,10 @@ master_add_map_source(struct master_mape
master_source_unlock(entry);
+ status = pthread_rwlock_init(&source->module_lock, NULL);
+ if (status)
+ fatal(status);
+
return source;
}
@@ -336,6 +369,8 @@ master_get_map_source(struct master_mape
static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
{
+ int status;
+
/* instance map sources are not ref counted */
if (source->ref && --source->ref)
return;
@@ -371,6 +406,10 @@ static void __master_free_map_source(str
}
}
+ status = pthread_rwlock_destroy(&source->module_lock);
+ if (status)
+ fatal(status);
+
free(source);
return;
@@ -502,6 +541,10 @@ master_add_source_instance(struct map_so
if (status)
fatal(status);
+ status = pthread_rwlock_init(&new->module_lock, NULL);
+ if (status)
+ fatal(status);
+
return new;
}
--- autofs-5.1.8.orig/include/master.h
+++ autofs-5.1.8/include/master.h
@@ -35,6 +35,7 @@ struct map_source {
unsigned int stale;
unsigned int recurse;
unsigned int depth;
+ pthread_rwlock_t module_lock;
struct lookup_mod *lookup;
int argc;
const char **argv;
@@ -126,5 +127,9 @@ int __master_list_empty(struct master *)
int master_list_empty(struct master *);
int master_done(struct master *);
int master_kill(struct master *);
+void map_module_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);
#endif
--- autofs-5.1.8.orig/modules/parse_amd.c
+++ autofs-5.1.8/modules/parse_amd.c
@@ -1358,14 +1358,6 @@ static int do_host_mount(struct autofs_p
argc = 1;
}
- parse_instance_mutex_lock();
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- debug(ap->logopt, "open lookup module hosts failed");
- parse_instance_mutex_unlock();
- goto out;
- }
-
instance = master_find_source_instance(source,
"hosts", "sun", argc, pargv);
if (!instance) {
@@ -1374,13 +1366,22 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- parse_instance_mutex_unlock();
close_lookup(lookup);
goto out;
}
}
- instance->lookup = lookup;
- parse_instance_mutex_unlock();
+
+ map_module_writelock(instance);
+ if (!instance->lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(instance);
+ debug(ap->logopt, "open lookup module hosts failed");
+ goto out;
+ }
+ instance->lookup = lookup;
+ }
+ map_module_unlock(instance);
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);
@@ -1391,8 +1392,11 @@ static int do_host_mount(struct autofs_p
master_source_current_wait(ap->entry);
ap->entry->current = source;
+ map_module_readlock(instance);
+ lookup = instance->lookup;
ret = lookup->lookup_mount(ap, entry->rhost,
strlen(entry->rhost), lookup->context);
+ map_module_unlock(instance);
if (!strcmp(name, entry->rhost))
goto out;

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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -45,6 +45,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.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/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 */
@@ -806,319 +802,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)
{
}
@@ -1127,18 +810,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);
@@ -1177,11 +856,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);
- }
}
}
@@ -1243,11 +917,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;
}
@@ -1268,11 +937,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;
@@ -1843,6 +1507,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)
{
}
@@ -2041,8 +1767,6 @@ static void handle_mounts_cleanup(void *
info(logopt, "shut down path %s", ap->path);
- 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
@@ -2972,6 +2696,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);
@@ -3037,13 +2773,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.
@@ -3067,6 +2797,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.8.orig/daemon/master.c
+++ autofs-5.1.8/daemon/master.c
@@ -113,8 +113,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.8.orig/include/automount.h
+++ autofs-5.1.8/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.8.orig/modules/parse_sun.c
+++ autofs-5.1.8/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.8.orig/CHANGELOG
+++ autofs-5.1.8/CHANGELOG
@@ -43,6 +43,7 @@
- make signal handling consistent.
- eliminate last remaining state_pipe usage.
- add function master_find_mapent_by_devid().
+- use device id to locate autofs_point when setting log priotity.
19/10/2021 autofs-5.1.8
- add xdr_exports().
--- autofs-5.1.8.orig/daemon/automount.c
+++ autofs-5.1.8/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;
@@ -951,35 +953,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;
@@ -1016,9 +1040,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);
@@ -1030,7 +1069,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) {
@@ -1129,7 +1172,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

@ -38,6 +38,36 @@ Patch19: autofs-5.1.8-dont-use-initgroups-at-spawn.patch
Patch20: autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch
Patch21: autofs-5.1.8-fix-invalid-tsv-access.patch
Patch22: autofs-5.1.8-configure-c99.patch
Patch23: autofs-5.1.8-fix-autofs-regression-due-to-positive_timeout.patch
Patch24: autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch
Patch25: autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch
Patch26: autofs-5.1.8-coverity-fix-for-invalid-access.patch
Patch27: autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch
Patch28: autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch
Patch29: autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch
Patch30: autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch
Patch31: autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch
Patch32: autofs-5.1.8-fix-additional-tsv-invalid-access.patch
Patch33: autofs-5.1.8-fix-use_ignore_mount_option-description.patch
Patch34: autofs-5.1.8-include-addtional-log-info-for-mounts.patch
Patch35: autofs-5.1.8-fail-on-empty-replicated-host-name.patch
Patch36: autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch
Patch37: autofs-5.1.8-dont-immediately-call-function-when-waiting.patch
Patch38: autofs-5.1.8-fix-return-status-of-mount_autofs.patch
Patch39: autofs-5.1.8-dont-close-lookup-at-umount.patch
Patch40: autofs-5.1.8-fix-deadlock-in-lookups.patch
Patch41: autofs-5.1.8-dont-delay-expire.patch
Patch42: autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch
Patch43: autofs-5.1.8-rename-statemachine-to-signal_handler.patch
Patch44: autofs-5.1.8-make-signal-handling-consistent.patch
Patch45: autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch
Patch46: autofs-5.1.8-add-function-master_find_mapent_by_devid.patch
Patch47: autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch
Patch48: autofs-5.1.8-add-command-pipe-handling-functions.patch
Patch49: autofs-5.1.8-switch-to-application-wide-command-pipe.patch
Patch50: autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch
Patch51: autofs-5.1.8-fix-mount-tree-startup-reconnect.patch
Patch52: autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch
%if %{with_systemd}
BuildRequires: systemd-units
@ -124,6 +154,36 @@ echo %{version}-%{release} > .version
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
%patch44 -p1
%patch45 -p1
%patch46 -p1
%patch47 -p1
%patch48 -p1
%patch49 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
%build
LDFLAGS=-Wl,-z,now
@ -231,6 +291,38 @@ fi
%dir /etc/auto.master.d
%changelog
* Sat Mar 25 2023 Ian Kent <ikent@redhat.com> - 1:5.1.8-20
- fix autofs regression due to positive_timeout.
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
- coverity fix for invalid access.
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
- fix memory leak in update_hosts_mounts().
- fix minus only option handling in concat_options().
- fix incorrect path for is_mounted() in try_remount().
- fix additional tsv invalid access.
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
- 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().
- 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.
- 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().
* Fri Mar 10 2023 Arjun Shankar <arjun@redhat.com> - 1:5.1.8-9
- Port configure script to C99