[PATCH 1/9] autofs-5.1.5 - support strictexpire mount option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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;




[Index of Archives]     [Linux Filesystem Development]     [Linux Ext4]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux