diff --git a/CHANGELOG b/CHANGELOG index af32a8e..06e5479 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -44,6 +44,7 @@ xx/xx/2018 autofs-5.1.5 - use flags for startup boolean options. - move close stdio descriptors to become_daemon(). - add systemd service command line option. +- support strictexpire mount option. 19/12/2017 autofs-5.1.4 - fix spec file url. diff --git a/daemon/direct.c b/daemon/direct.c index 3fdecdb..e3ce816 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -421,6 +421,16 @@ int do_mount_autofs_direct(struct autofs_point *ap, mp->options = make_options_string(ap->path, ap->kpipefd, str_direct); if (!mp->options) return 0; + + if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && + ((get_kver_major() == 5 && get_kver_minor() > 3) || + (get_kver_major() > 5))) { + char *tmp = realloc(mp->options, strlen(mp->options) + 12); + if (tmp) { + strcat(tmp, ",strictexpire"); + mp->options = tmp; + } + } } /* In case the directory doesn't exist, try to mkdir it */ diff --git a/daemon/indirect.c b/daemon/indirect.c index 03c081e..4f67f70 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -132,6 +132,16 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) goto out_err; } + if ((ap->flags & MOUNT_FLAG_STRICTEXPIRE) && + ((get_kver_major() == 5 && get_kver_minor() > 3) || + (get_kver_major() > 5))) { + char *tmp = realloc(options, strlen(options) + 12); + if (tmp) { + strcat(tmp, ",strictexpire"); + options = tmp; + } + } + /* In case the directory doesn't exist, try to mkdir it */ if (mkdir_path(root, mp_mode) < 0) { if (errno != EEXIST && errno != EROFS) { diff --git a/include/automount.h b/include/automount.h index 45fde53..57cb93f 100644 --- a/include/automount.h +++ b/include/automount.h @@ -553,6 +553,9 @@ struct kernel_mod_version { #define MOUNT_FLAG_SLAVE 0x0100 #define MOUNT_FLAG_PRIVATE 0x0200 +/* Use strict expire semantics if requested and kernel supports it */ +#define MOUNT_FLAG_STRICTEXPIRE 0x0400 + struct autofs_point { pthread_t thid; char *path; /* Mount point name */ diff --git a/lib/master_parse.y b/lib/master_parse.y index e40c1ba..f817f73 100644 --- a/lib/master_parse.y +++ b/lib/master_parse.y @@ -58,6 +58,7 @@ static char *format; static long timeout; static long negative_timeout; static unsigned symlnk; +static unsigned strictexpire; static unsigned slave; static unsigned private; static unsigned nobind; @@ -105,7 +106,7 @@ static int master_fprintf(FILE *, char *, ...); %token MAP %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE -%token OPT_SLAVE OPT_PRIVATE +%token OPT_STRICTEXPIRE OPT_SLAVE OPT_PRIVATE %token COLON COMMA NL DDASH %type map %type options @@ -206,6 +207,7 @@ line: | PATH OPT_DEBUG { master_notify($1); YYABORT; } | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } | PATH OPT_SYMLINK { master_notify($1); YYABORT; } + | PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; } | PATH OPT_SLAVE { master_notify($1); YYABORT; } | PATH OPT_PRIVATE { master_notify($1); YYABORT; } | PATH OPT_NOBIND { master_notify($1); YYABORT; } @@ -619,6 +621,7 @@ option: daemon_option daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } | OPT_SYMLINK { symlnk = 1; } + | OPT_STRICTEXPIRE { strictexpire = 1; } | OPT_SLAVE { slave = 1; } | OPT_PRIVATE { private = 1; } | OPT_NOBIND { nobind = 1; } @@ -693,6 +696,7 @@ static void local_init_vars(void) timeout = -1; negative_timeout = 0; symlnk = 0; + strictexpire = 0; slave = 0; private = 0; nobind = 0; @@ -901,6 +905,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; if (symlnk) entry->ap->flags |= MOUNT_FLAG_SYMLINK; + if (strictexpire) + entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE; if (slave) entry->ap->flags |= MOUNT_FLAG_SLAVE; if (private) diff --git a/lib/master_tok.l b/lib/master_tok.l index f4e940c..7486710 100644 --- a/lib/master_tok.l +++ b/lib/master_tok.l @@ -391,6 +391,7 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS}) -?nobrowse { return(OPT_NOGHOST); } -?slave { return(OPT_SLAVE); } -?private { return(OPT_PRIVATE); } + -?strictexpire { return(OPT_STRICTEXPIRE); } -g|--ghost|-?browse { return(OPT_GHOST); } -v|--verbose { return(OPT_VERBOSE); } -d|--debug { return(OPT_DEBUG); } diff --git a/man/auto.master.5.in b/man/auto.master.5.in index 68242d4..dace4a1 100644 --- a/man/auto.master.5.in +++ b/man/auto.master.5.in @@ -199,6 +199,14 @@ entries only, either in the master map (so it effects all map entries) or with individual map entries. The option is ignored for direct mounts and non-root offest mount entries. .TP +.I "strictexpire" +Use a strict expire policy for this automount. Using this option means +that last use of autofs directory entries will not be updated during +path walks so that mounts in an automount won't be kept mounted by +applications scanning the mount tree. Note that this doesn't completely +resolve the problem of expired automounts being immediately re-mounted +due to application accesses triggered by the expire itself. +.TP .I slave \fPor\fI private This option allows mount propagation of bind mounts to be set to either \fIslave\fP or \fIprivate\fP. This option may be needed when using diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c index cd0631b..72e1aba 100644 --- a/modules/mount_autofs.c +++ b/modules/mount_autofs.c @@ -57,6 +57,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int nobind = ap->flags & MOUNT_FLAG_NOBIND; int ghost = ap->flags & MOUNT_FLAG_GHOST; int symlnk = ap->flags & MOUNT_FLAG_SYMLINK; + int strictexpire = ap->flags & MOUNT_FLAG_STRICTEXPIRE; time_t timeout = get_exp_timeout(ap, ap->entry->maps); unsigned logopt = ap->logopt; struct map_type_info *info; @@ -131,6 +132,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, ghost = 1; else if (_strncmp("symlink", cp, 7) == 0) symlnk = 1; + else if (_strncmp("strictexpire", cp, 12) == 0) + strictexpire = 1; else if (_strncmp("hosts", cp, 5) == 0) hosts = 1; else if (_strncmp("timeout=", cp, 8) == 0) { @@ -173,6 +176,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, nap->parent = ap; if (symlnk) nap->flags |= MOUNT_FLAG_SYMLINK; + if (strictexpire) + nap->flags |= MOUNT_FLAG_STRICTEXPIRE; if (hosts) argc = 0;