Blob Blame History Raw
autofs-5.1.4 - add master map pseudo options for mount propagation

From: Ian Kent <raven@themaw.net>

Add master map entry pseudo mount option of "slave" or "private" to
allow mount propagation of bind mounts to be set to either "slave" or
"private".

This option may be needed when using multi-mounts that have bind mounts
that bind to a file system that is propagation shared. This is becuase
the bind mount will have the same properties as its target which causes
problems for offset mounts. When this happens an unwanted offset mount
is propagated back to the target file system resulting in a deadlock
when attempting to access the offset.

By default bind mounts will inherit the mount propagation of the target
file system.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG            |    1 +
 include/automount.h  |    4 ++++
 lib/master_parse.y   |   13 +++++++++++++
 lib/master_tok.l     |    2 ++
 man/auto.master.5.in |   12 ++++++++++++
 modules/mount_bind.c |   30 +++++++++++++++++++-----------
 6 files changed, 51 insertions(+), 11 deletions(-)

--- autofs-5.0.7.orig/CHANGELOG
+++ autofs-5.0.7/CHANGELOG
@@ -308,6 +308,7 @@
 - dont probe NFSv2 by default.
 - add version parameter to rpc_ping().
 - set bind mount as propagation slave.
+- add master map pseudo options for mount propagation.
 
 25/07/2012 autofs-5.0.7
 =======================
--- autofs-5.0.7.orig/include/automount.h
+++ autofs-5.0.7/include/automount.h
@@ -527,6 +527,10 @@ struct kernel_mod_version {
 /* Read amd map even if it's not to be ghosted (browsable) */
 #define MOUNT_FLAG_AMD_CACHE_ALL	0x0080
 
+/* Set mount propagation for bind mounts */
+#define MOUNT_FLAG_SLAVE		0x0100
+#define MOUNT_FLAG_PRIVATE		0x0200
+
 struct autofs_point {
 	pthread_t thid;
 	char *path;			/* Mount point name */
--- autofs-5.0.7.orig/lib/master_parse.y
+++ autofs-5.0.7/lib/master_parse.y
@@ -58,6 +58,8 @@ static char *format;
 static long timeout;
 static long negative_timeout;
 static unsigned symlnk;
+static unsigned slave;
+static unsigned private;
 static unsigned nobind;
 static unsigned ghost;
 extern unsigned global_selection_options;
@@ -102,6 +104,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
+%token OPT_SLAVE OPT_PRIVATE
 %token COLON COMMA NL DDASH
 %type <strtype> map
 %type <strtype> options
@@ -188,6 +191,8 @@ line:
 	| PATH OPT_DEBUG { master_notify($1); YYABORT; }
 	| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
 	| PATH OPT_SYMLINK { 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; }
 	| PATH OPT_GHOST { master_notify($1); YYABORT; }
 	| PATH OPT_NOGHOST { master_notify($1); YYABORT; }
@@ -569,6 +574,8 @@ option: daemon_option
 daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; }
 	| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
 	| OPT_SYMLINK	{ symlnk = 1; }
+	| OPT_SLAVE	{ slave = 1; }
+	| OPT_PRIVATE	{ private = 1; }
 	| OPT_NOBIND	{ nobind = 1; }
 	| OPT_NOGHOST	{ ghost = 0; }
 	| OPT_GHOST	{ ghost = 1; }
@@ -640,6 +647,8 @@ static void local_init_vars(void)
 	timeout = -1;
 	negative_timeout = 0;
 	symlnk = 0;
+	slave = 0;
+	private = 0;
 	nobind = 0;
 	ghost = defaults_get_browse_mode();
 	random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
@@ -845,6 +854,10 @@ int master_parse_entry(const char *buffe
 		entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY;
 	if (symlnk)
 		entry->ap->flags |= MOUNT_FLAG_SYMLINK;
+	if (slave)
+		entry->ap->flags |= MOUNT_FLAG_SLAVE;
+	if (private)
+		entry->ap->flags |= MOUNT_FLAG_PRIVATE;
 	if (negative_timeout)
 		entry->ap->negative_timeout = negative_timeout;
 
--- autofs-5.0.7.orig/lib/master_tok.l
+++ autofs-5.0.7/lib/master_tok.l
@@ -386,6 +386,8 @@ OPTNTOUT	(-n{OPTWS}|-n{OPTWS}={OPTWS}|--
 	-?symlink		{ return(OPT_SYMLINK); }
 	-?nobind		{ return(OPT_NOBIND); }
 	-?nobrowse		{ return(OPT_NOGHOST); }
+	-?slave			{ return(OPT_SLAVE); }
+	-?private		{ return(OPT_PRIVATE); }
 	-g|--ghost|-?browse	{ return(OPT_GHOST); }
 	-v|--verbose		{ return(OPT_VERBOSE); }
 	-d|--debug		{ return(OPT_DEBUG); }
--- autofs-5.0.7.orig/man/auto.master.5.in
+++ autofs-5.0.7/man/auto.master.5.in
@@ -198,6 +198,18 @@ entries only, either in the master map (
 or with individual map entries. The option is ignored for direct mounts
 and non-root offest mount entries.
 .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
+multi-mounts that have bind mounts that bind to a file system that is
+propagation shared. This is becuase the bind mount will have the same
+properties as its target which causes problems for offset mounts. When
+this happens an unwanted offset mount is propagated back to the target
+file system resulting in a deadlock when attempting to access the offset.
+This option is a an autofs pseudo mount option that can be used in the
+master map only. By default bind mounts will inherit the mount propagation
+of the target file system.
+.TP
 .I "\-r, \-\-random-multimount-selection"
 Enables the use of ramdom selection when choosing a host from a
 list of replicated servers. This option is applied to this mount
--- autofs-5.0.7.orig/modules/mount_bind.c
+++ autofs-5.0.7/modules/mount_bind.c
@@ -187,17 +187,25 @@ int mount_mount(struct autofs_point *ap,
 			      what, fstype, fullpath);
 		}
 
-		/* The bind mount has succeeded but if the target
-		 * mount is propagation shared propagation of child
-		 * mounts (autofs offset mounts for example) back to
-		 * the target of the bind mount must be avoided or
-		 * autofs trigger mounts will deadlock.
-		 */
-		err = mount(NULL, fullpath, NULL, MS_SLAVE, NULL);
-		if (err)
-			warn(ap->logopt,
-			     "failed to set propagation type for %s",
-			     fullpath);
+		if (ap->flags & (MOUNT_FLAG_SLAVE | MOUNT_FLAG_PRIVATE)) {
+			int flags = MS_SLAVE;
+
+			if (ap->flags & MOUNT_FLAG_PRIVATE)
+				flags = MS_PRIVATE;
+
+			/* The bind mount has succeeded but if the target
+			 * mount is propagation shared propagation of child
+			 * mounts (autofs offset mounts for example) back to
+			 * the target of the bind mount must be avoided or
+			 * autofs trigger mounts will deadlock.
+			 */
+			err = mount(NULL, fullpath, NULL, flags, NULL);
+			if (err) {
+				warn(ap->logopt,
+				     "failed to set propagation for %s",
+				     fullpath, root);
+			}
+		}
 
 		return 0;
 	} else {