autofs-5.1.6 - add force unlink mounts and exit option From: Ian Kent 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 --- 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(-) diff --git a/CHANGELOG b/CHANGELOG index f0aa725d..fb210905 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -47,6 +47,7 @@ xx/xx/2020 autofs-5.1.7 - 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. 07/10/2019 autofs-5.1.6 - support strictexpire mount option. diff --git a/daemon/automount.c b/daemon/automount.c index 3b4dc833..70bb85dd 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -1172,8 +1172,13 @@ static int mount_autofs(struct autofs_point *ap, const char *root) { 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); @@ -1880,7 +1885,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); @@ -1972,6 +1978,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); } @@ -2222,7 +2229,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'}, @@ -2240,6 +2247,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} }; @@ -2362,6 +2370,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); @@ -2682,25 +2695,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); diff --git a/daemon/direct.c b/daemon/direct.c index 410ea980..a49960ea 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -286,7 +286,14 @@ int do_mount_autofs_direct(struct autofs_point *ap, 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_point *ap, 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; diff --git a/daemon/indirect.c b/daemon/indirect.c index 43bcb346..94e05600 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -76,6 +76,9 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) "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_point *ap, const char *root) 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); diff --git a/include/automount.h b/include/automount.h index d742ee30..78f88afe 100644 --- a/include/automount.h +++ b/include/automount.h @@ -594,6 +594,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; diff --git a/lib/master.c b/lib/master.c index cd262ba5..7b77968a 100644 --- a/lib/master.c +++ b/lib/master.c @@ -1359,7 +1359,8 @@ static int master_do_mount(struct master_mapent *entry) 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) { @@ -1377,7 +1378,8 @@ static int master_do_mount(struct master_mapent *entry) } 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; } diff --git a/man/automount.8 b/man/automount.8 index dea79370..1061c9da 100644 --- a/man/automount.8 +++ b/man/automount.8 @@ -121,6 +121,12 @@ Don't check if the daemon is currently running (see NOTES). 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.