You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
7.7 KiB
215 lines
7.7 KiB
autofs-5.1.5 - support strictexpire mount option
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Kernel commit 092a53452b (("autofs: take more care to not update
|
|
last_used on path walk") helped to (partially) resolve a problem
|
|
where automounts were not expiring due to aggressive accesses from
|
|
user space.
|
|
|
|
This patch was later reverted because, for very large environments,
|
|
it meant more mount requests from clients and when there are a lot
|
|
of clients this caused a fairly significant increase in server load.
|
|
|
|
But there is a need for both types of expire check, depending on use
|
|
case, so a mount option to allow for strict update of last use of
|
|
autofs dentrys has been added ito the autofs file system (which just
|
|
means not updating the last use on path walk accesses).
|
|
|
|
So add support for this master map mount entry option in the user
|
|
space code.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 3 +++
|
|
daemon/direct.c | 10 ++++++++++
|
|
daemon/indirect.c | 10 ++++++++++
|
|
include/automount.h | 3 +++
|
|
lib/master_parse.y | 8 +++++++-
|
|
lib/master_tok.l | 1 +
|
|
man/auto.master.5.in | 8 ++++++++
|
|
modules/mount_autofs.c | 5 +++++
|
|
8 files changed, 47 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index ca036f19..f671dc52 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -1,3 +1,6 @@
|
|
+xx/xx/2019 autofs-5.1.6
|
|
+- support strictexpire mount option.
|
|
+
|
|
30/10/2018 autofs-5.1.5
|
|
- fix flag file permission.
|
|
- fix directory create permission.
|
|
diff --git a/daemon/direct.c b/daemon/direct.c
|
|
index b885d12f..9c61c4b4 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 438a0a21..d0724293 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 947daa10..1bb32015 100644
|
|
--- a/include/automount.h
|
|
+++ b/include/automount.h
|
|
@@ -554,6 +554,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 9aa57327..8fe8b128 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 <strtype> map
|
|
%type <strtype> 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 f4e940ce..7486710b 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 68242d45..dace4a1c 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 cd0631b8..72e1aba4 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;
|
|
|