Blob Blame History Raw
autofs-5.1.6 - add force unlink mounts and exit option

From: Ian Kent <raven@themaw.net>

Add a automount program option to force an unlink umount of all
existing mounts under configured autofs mount points then exit.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG           |    1 +
 daemon/automount.c  |   51 +++++++++++++++++++++++++++++++++------------------
 daemon/direct.c     |   12 +++++++++++-
 daemon/indirect.c   |   21 ++++++++++++++++-----
 include/automount.h |    1 +
 lib/master.c        |    6 ++++--
 man/automount.8     |    6 ++++++
 7 files changed, 72 insertions(+), 26 deletions(-)

--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -89,6 +89,7 @@ xx/xx/2018 autofs-5.1.5
 - use bit flag for force unlink mounts.
 - improve force unlink option description.
 - remove command fifo on autofs mount fail.
+- add force unlink mounts and exit option.
 
 19/12/2017 autofs-5.1.4
 - fix spec file url.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -1153,8 +1153,13 @@ static int mount_autofs(struct autofs_po
 {
 	int status = 0;
 
-	if (autofs_init_ap(ap) != 0)
-		return -1;
+	/* No need to create comms fds and command fifo if
+	 * unlinking mounts and exiting.
+	 */
+	if (!(do_force_unlink & UNLINK_AND_EXIT)) {
+		if (autofs_init_ap(ap) != 0)
+			return -1;
+	}
 
 	if (ap->type == LKP_DIRECT)
 		status = mount_autofs_direct(ap);
@@ -1859,7 +1864,8 @@ void *handle_mounts(void *arg)
 	}
 
 	if (mount_autofs(ap, root) < 0) {
-		crit(ap->logopt, "mount of %s failed!", ap->path);
+		if (!(do_force_unlink & UNLINK_AND_EXIT))
+			crit(ap->logopt, "mount of %s failed!", ap->path);
 		suc->status = 1;
 		umount_autofs(ap, root, 1);
 		free(root);
@@ -1951,6 +1957,7 @@ static void usage(void)
 		"	-C --dont-check-daemon\n"
 		"			don't check if daemon is already running\n"
 		"	-F --force	forceably clean up known automounts at start\n"
+		"	-U --force-exit	forceably clean up known automounts and exit\n"
 		"	-V --version	print version, build config and exit\n"
 		, program);
 }
@@ -2202,7 +2209,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:CFM";
+	const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM";
 	static const struct option long_options[] = {
 		{"help", 0, 0, 'h'},
 		{"pid-file", 1, 0, 'p'},
@@ -2220,6 +2227,7 @@ int main(int argc, char *argv[])
 		{"set-log-priority", 1, 0, 'l'},
 		{"dont-check-daemon", 0, 0, 'C'},
 		{"force", 0, 0, 'F'},
+		{"force-exit", 0, 0, 'U'},
 		{"master-wait", 1, 0, 'M'},
 		{0, 0, 0, 0}
 	};
@@ -2342,6 +2350,11 @@ int main(int argc, char *argv[])
 			do_force_unlink = UNLINK_AND_CONT;
 			break;
 
+		case 'U':
+			flags |= DAEMON_FLAGS_FOREGROUND;
+			do_force_unlink = UNLINK_AND_EXIT;
+			break;
+
 		case '?':
 		case ':':
 			printf("%s: Ambiguous or unknown options\n", program);
@@ -2657,25 +2670,27 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	/*
-	 * Mmm ... reset force unlink umount so we don't also do this
-	 * in future when we receive a HUP signal.
-	 */
-	do_force_unlink = 0;
+	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.
+		 */
+		do_force_unlink = 0;
 
-	if (start_pipefd[1] != -1) {
-		st_stat = 0;
-		res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
-		close(start_pipefd[1]);
-	}
+		if (start_pipefd[1] != -1) {
+			st_stat = 0;
+			res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
+			close(start_pipefd[1]);
+		}
 
 #ifdef WITH_SYSTEMD
-	if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE)
-		sd_notify(1, "READY=1");
+		if (flags & DAEMON_FLAGS_SYSTEMD_SERVICE)
+			sd_notify(1, "READY=1");
 #endif
 
-	state_mach_thid = pthread_self();
-	statemachine(NULL);
+		state_mach_thid = pthread_self();
+		statemachine(NULL);
+	}
 
 	master_kill(master_list);
 
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -286,7 +286,14 @@ int do_mount_autofs_direct(struct autofs
 		if (ret == 0)
 			return -1;
 	} else {
-		if (ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) {
+		/* I don't remember why this is here for the force
+		 * unlink case. I don't think it should be but I may
+		 * have done it for a reason so keep it for the unlink
+		 * and continue case but not for the unlink and exit
+		 * case.
+		 */
+		if (!(do_force_unlink & UNLINK_AND_EXIT) &&
+		    ap->state == ST_READMAP && is_mounted(me->key, MNTS_ALL)) {
 			time_t tout = get_exp_timeout(ap, me->source);
 			int save_ioctlfd, ioctlfd;
 
@@ -319,6 +326,9 @@ int do_mount_autofs_direct(struct autofs
 			goto out_err;
 		}
 
+		if (do_force_unlink & UNLINK_AND_EXIT)
+			return -1;
+
 		if (me->ioctlfd != -1) {
 			error(ap->logopt, "active direct mount %s", me->key);
 			return -1;
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -76,6 +76,9 @@ static int do_mount_autofs_indirect(stru
 			      "or failed to unlink entry in tree");
 			goto out_err;
 		}
+
+		if (do_force_unlink & UNLINK_AND_EXIT)
+			return -1;
 	}
 
 	options = make_options_string(ap->path,
@@ -163,12 +166,20 @@ int mount_autofs_indirect(struct autofs_
 	int status;
 	int map;
 
+	/* Don't read the map if the unlink and exit option has been
+	 * given. do_mount_autofs_indirect() will return -1 if this
+	 * option has been given so there's no need to do anything
+	 * else.
+	 */
+
 	/* TODO: read map, determine map type is OK */
-	if (lookup_nss_read_map(ap, NULL, now))
-		lookup_prune_cache(ap, now);
-	else {
-		error(ap->logopt, "failed to read map for %s", ap->path);
-		return -1;
+	if (!(do_force_unlink & UNLINK_AND_EXIT)) {
+		if (lookup_nss_read_map(ap, NULL, now))
+			lookup_prune_cache(ap, now);
+		else {
+			error(ap->logopt, "failed to read map for %s", ap->path);
+			return -1;
+		}
 	}
 
 	status = do_mount_autofs_indirect(ap, root);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -591,6 +591,7 @@ struct autofs_point {
 };
 
 #define UNLINK_AND_CONT		0x01
+#define UNLINK_AND_EXIT		0x02
 
 /* Foreably unlink existing mounts at startup. */
 extern int do_force_unlink;
--- autofs-5.1.4.orig/lib/master.c
+++ autofs-5.1.4/lib/master.c
@@ -1358,7 +1358,8 @@ static int master_do_mount(struct master
 	suc.done = 0;
 	suc.status = 0;
 
-	debug(ap->logopt, "mounting %s", entry->path);
+	if (!(do_force_unlink & UNLINK_AND_EXIT))
+		debug(ap->logopt, "mounting %s", entry->path);
 
 	status = pthread_create(&thid, &th_attr, handle_mounts, &suc);
 	if (status) {
@@ -1376,7 +1377,8 @@ static int master_do_mount(struct master
 	}
 
 	if (suc.status) {
-		error(ap->logopt, "failed to startup mount");
+		if (!(do_force_unlink & UNLINK_AND_EXIT))
+			error(ap->logopt, "failed to startup mount");
 		handle_mounts_startup_cond_destroy(&suc);
 		return 0;
 	}
--- autofs-5.1.4.orig/man/automount.8
+++ autofs-5.1.4/man/automount.8
@@ -121,6 +121,12 @@ Don't check if the daemon is currently r
 Force an unlink umount of existing mounts under configured autofs managed
 mount points during startup. This can cause problems for processes with
 working directories within these mounts (see NOTES).
+.TP
+.I "\-U, \-\-force-exit"
+Force an unlink umount of existing mounts under configured autofs managed
+mount points and exit rather than continuing the startup. This can cause
+problems for processes with working directories within these mounts (see
+NOTES).
 .SH ARGUMENTS
 \fBautomount\fP takes one optional argument, the name of the master map to
 use.