autofs-5.1.9 - fix handling of direct mount path in command handler

From: Ian Kent <raven@themaw.net>

Commit 16ea4156471e ("autofs-5.1.8 - switch to application wide command
pipe") broke the ability to set the log priority from the command line
for all direct mounts.

As Goldwyn Rodrigues points out the autofs_point structure for direct
mounts doesn't have a real mount associated with it so it needs special
handling which was ommitted in commit 16ea4156471e.

Fixes: 16ea4156471e ("autofs-5.1.8 - switch to application wide command pipe")
Reported-By: Goldwyn Rodrigues <rgoldwyn@suse.de>
Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG          |    1 +
 daemon/automount.c |   17 +++++++++++++++--
 daemon/master.c    |   11 +++++++++++
 include/master.h   |    3 ++-
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index d6d594e9e..0fc529f32 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -89,6 +89,7 @@
 - do_reconnect() expiry check of dclist BEFORE lookup using it.
 - fix mailing list subscription address.
 - fix table_lookup_ino() fd reference.
+- fix handling of direct mount path in command handler.
 
 02/11/2023 autofs-5.1.9
 - fix kernel mount status notification.
diff --git a/daemon/automount.c b/daemon/automount.c
index 517764119..a01d176ae 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1487,7 +1487,13 @@ static void handle_cmd_pipe_fifo_message(int fd)
 		return;
 	}
 
-	ap = master_find_mapent_by_devid(devid);
+	/* There's no "real" devid for the top level direct mount
+	 * container so we use -1.
+	 */
+	if (devid == -1)
+		ap = master_find_mapent_by_path("/-");
+	else
+		ap = master_find_mapent_by_devid(devid);
 	if (!ap) {
 		error(LOGOPT_ANY, "can't locate autofs_point for device id %ld.", devid);
 		return;
@@ -1548,7 +1554,14 @@ static int set_log_priority(const char *path, int priority)
 	if (!ops) {
 		fprintf(stderr, "Could not get ioctl ops\n");
 		return -1;
-	} else {
+	}
+
+	/* There's no "real" devid for the top level direct mount
+	 * container so we use -1.
+	 */
+	if (!strcmp(path, "/-"))
+		devid = -1;
+	else {
 		ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
 		if (ret == -1 || ret == 0) {
 			fprintf(stderr,
diff --git a/daemon/master.c b/daemon/master.c
index d85dd8975..8b7450e73 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -711,6 +711,17 @@ struct master_mapent *master_find_mapent(const char *path)
 	return NULL;
 }
 
+struct autofs_point *master_find_mapent_by_path(const char *path)
+{
+	struct autofs_point *ap = NULL;
+	struct master_mapent *entry;
+
+	entry = master_find_mapent(path);
+	if (entry)
+		ap = entry->ap;
+	return ap;
+}
+
 struct autofs_point *master_find_mapent_by_devid(dev_t devid)
 {
 	struct master *master = master_list;
diff --git a/include/master.h b/include/master.h
index 71610611f..3ca7ad8d6 100644
--- a/include/master.h
+++ b/include/master.h
@@ -105,7 +105,8 @@ void master_source_readlock(struct master_mapent *);
 void master_source_unlock(struct master_mapent *);
 void master_source_lock_cleanup(void *);
 struct master_mapent *master_find_mapent(const char *);
-struct autofs_point *master_find_mapent_by_devid(dev_t devid);
+struct autofs_point *master_find_mapent_by_path(const char *);
+struct autofs_point *master_find_mapent_by_devid(dev_t);
 struct master_mapent *master_new_mapent(const char *, time_t);
 void master_add_mapent(struct master_mapent *);
 void master_remove_mapent(struct master_mapent *);
