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.