diff --git a/CHANGELOG b/CHANGELOG index 928aaa9..c1a6c15 100644 --- a/CHANGELOG +++ b/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. diff --git a/daemon/automount.c b/daemon/automount.c index 0ab85ef..2aa0bcc 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -1153,8 +1153,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); @@ -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); diff --git a/daemon/direct.c b/daemon/direct.c index 410ea98..a49960e 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 43bcb34..94e0560 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 d8b96bf..49c9ff9 100644 --- a/include/automount.h +++ b/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; diff --git a/lib/master.c b/lib/master.c index 55a6b01..fedf807 100644 --- a/lib/master.c +++ b/lib/master.c @@ -1358,7 +1358,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) { @@ -1376,7 +1377,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 b64d280..21cca4e 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.