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(-) --- 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.