Blame SOURCES/autofs-5.1.6-make-bind-mounts-propagation-slave-by-default.patch

beb904
autofs-5.1.6 - make bind mounts propagation slave by default
beb904
beb904
From: Ian Kent <raven@themaw.net>
beb904
beb904
Make setting mount propagation on bind mounts mandatory with a default
beb904
of propagation slave.
beb904
beb904
When using multi-mounts that have bind mounts the bind mount will have
beb904
the same properties as its parent which is commonly propagation shared.
beb904
And if the mount target is also propagation shared this can lead to a
beb904
deadlock when attempting to access the offset mounts. When this happens
beb904
an unwanted offset mount is propagated back to the target file system
beb904
resulting in a deadlock since the automount target is itself an
beb904
(unwanted) automount trigger.
beb904
beb904
This problem has been present much longer than I originally thought,
beb904
perhaps since mount propagation was introduced into the kernel, so
beb904
explicitly setting bind mount propagation is the sensible thing to do.
beb904
beb904
Signed-off-by: Ian Kent <raven@themaw.net>
beb904
---
beb904
 CHANGELOG            |    1 +
beb904
 include/automount.h  |    9 +++++----
beb904
 lib/master_parse.y   |   29 +++++++++++++++++------------
beb904
 lib/master_tok.l     |    1 +
beb904
 modules/mount_bind.c |   40 ++++++++++++++++++++++------------------
beb904
 5 files changed, 46 insertions(+), 34 deletions(-)
beb904
beb904
--- autofs-5.1.4.orig/include/automount.h
beb904
+++ autofs-5.1.4/include/automount.h
beb904
@@ -551,14 +551,15 @@ struct kernel_mod_version {
beb904
 #define MOUNT_FLAG_AMD_CACHE_ALL	0x0080
beb904
 
beb904
 /* Set mount propagation for bind mounts */
beb904
-#define MOUNT_FLAG_SLAVE		0x0100
beb904
-#define MOUNT_FLAG_PRIVATE		0x0200
beb904
+#define MOUNT_FLAG_SHARED		0x0100
beb904
+#define MOUNT_FLAG_SLAVE		0x0200
beb904
+#define MOUNT_FLAG_PRIVATE		0x0400
beb904
 
beb904
 /* Use strict expire semantics if requested and kernel supports it */
beb904
-#define MOUNT_FLAG_STRICTEXPIRE		0x0400
beb904
+#define MOUNT_FLAG_STRICTEXPIRE		0x0800
beb904
 
beb904
 /* Indicator for applications to ignore the mount entry */
beb904
-#define MOUNT_FLAG_IGNORE		0x0800
beb904
+#define MOUNT_FLAG_IGNORE		0x1000
beb904
 
beb904
 struct autofs_point {
beb904
 	pthread_t thid;
beb904
--- autofs-5.1.4.orig/lib/master_parse.y
beb904
+++ autofs-5.1.4/lib/master_parse.y
beb904
@@ -59,8 +59,6 @@ static long timeout;
beb904
 static long negative_timeout;
beb904
 static unsigned symlnk;
beb904
 static unsigned strictexpire;
beb904
-static unsigned slave;
beb904
-static unsigned private;
beb904
 static unsigned nobind;
beb904
 static unsigned ghost;
beb904
 extern unsigned global_selection_options;
beb904
@@ -72,6 +70,14 @@ static int tmp_argc;
beb904
 static char **local_argv;
beb904
 static int local_argc;
beb904
 
beb904
+#define PROPAGATION_SHARED	MOUNT_FLAG_SHARED
beb904
+#define PROPAGATION_SLAVE	MOUNT_FLAG_SLAVE
beb904
+#define PROPAGATION_PRIVATE	MOUNT_FLAG_PRIVATE
beb904
+#define PROPAGATION_MASK	(MOUNT_FLAG_SHARED | \
beb904
+				 MOUNT_FLAG_SLAVE  | \
beb904
+				 MOUNT_FLAG_PRIVATE)
beb904
+static unsigned int propagation;
beb904
+
beb904
 static char errstr[MAX_ERR_LEN];
beb904
 
beb904
 static unsigned int verbose;
beb904
@@ -106,7 +112,7 @@ static int master_fprintf(FILE *, char *
beb904
 %token MAP
beb904
 %token OPT_TIMEOUT OPT_NTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE
beb904
 %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE
beb904
-%token OPT_STRICTEXPIRE OPT_SLAVE OPT_PRIVATE
beb904
+%token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE
beb904
 %token COLON COMMA NL DDASH
beb904
 %type <strtype> map
beb904
 %type <strtype> options
beb904
@@ -208,6 +214,7 @@ line:
beb904
 	| PATH OPT_TIMEOUT { master_notify($1); YYABORT; }
beb904
 	| PATH OPT_SYMLINK { master_notify($1); YYABORT; }
beb904
 	| PATH OPT_STRICTEXPIRE { master_notify($1); YYABORT; }
beb904
+	| PATH OPT_SHARED { master_notify($1); YYABORT; }
beb904
 	| PATH OPT_SLAVE { master_notify($1); YYABORT; }
beb904
 	| PATH OPT_PRIVATE { master_notify($1); YYABORT; }
beb904
 	| PATH OPT_NOBIND { master_notify($1); YYABORT; }
beb904
@@ -622,8 +629,9 @@ daemon_option: OPT_TIMEOUT NUMBER { time
beb904
 	| OPT_NTIMEOUT NUMBER { negative_timeout = $2; }
beb904
 	| OPT_SYMLINK	{ symlnk = 1; }
beb904
 	| OPT_STRICTEXPIRE { strictexpire = 1; }
beb904
-	| OPT_SLAVE	{ slave = 1; }
beb904
-	| OPT_PRIVATE	{ private = 1; }
beb904
+	| OPT_SHARED	{ propagation = PROPAGATION_SHARED; }
beb904
+	| OPT_SLAVE	{ propagation = PROPAGATION_SLAVE; }
beb904
+	| OPT_PRIVATE	{ propagation = PROPAGATION_PRIVATE; }
beb904
 	| OPT_NOBIND	{ nobind = 1; }
beb904
 	| OPT_NOGHOST	{ ghost = 0; }
beb904
 	| OPT_GHOST	{ ghost = 1; }
beb904
@@ -697,8 +705,7 @@ static void local_init_vars(void)
beb904
 	negative_timeout = 0;
beb904
 	symlnk = 0;
beb904
 	strictexpire = 0;
beb904
-	slave = 0;
beb904
-	private = 0;
beb904
+	propagation = PROPAGATION_SLAVE;
beb904
 	nobind = 0;
beb904
 	ghost = defaults_get_browse_mode();
beb904
 	random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT;
beb904
@@ -888,7 +895,6 @@ int master_parse_entry(const char *buffe
beb904
 			ghost = 1;
beb904
 	}
beb904
 
beb904
-
beb904
 	if (!entry->ap) {
beb904
 		ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0);
beb904
 		if (!ret) {
beb904
@@ -899,6 +905,9 @@ int master_parse_entry(const char *buffe
beb904
 			return 0;
beb904
 		}
beb904
 	}
beb904
+	entry->ap->flags &= ~(PROPAGATION_MASK);
beb904
+	entry->ap->flags |= propagation;
beb904
+
beb904
 	if (random_selection)
beb904
 		entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
beb904
 	if (use_weight)
beb904
@@ -907,10 +916,6 @@ int master_parse_entry(const char *buffe
beb904
 		entry->ap->flags |= MOUNT_FLAG_SYMLINK;
beb904
 	if (strictexpire)
beb904
 		entry->ap->flags |= MOUNT_FLAG_STRICTEXPIRE;
beb904
-	if (slave)
beb904
-		entry->ap->flags |= MOUNT_FLAG_SLAVE;
beb904
-	if (private)
beb904
-		entry->ap->flags |= MOUNT_FLAG_PRIVATE;
beb904
 	if (negative_timeout)
beb904
 		entry->ap->negative_timeout = negative_timeout;
beb904
 	if (mode && mode < LONG_MAX)
beb904
--- autofs-5.1.4.orig/lib/master_tok.l
beb904
+++ autofs-5.1.4/lib/master_tok.l
beb904
@@ -389,6 +389,7 @@ MODE		(--mode{OPTWS}|--mode{OPTWS}={OPTW
beb904
 	-?symlink		{ return(OPT_SYMLINK); }
beb904
 	-?nobind		{ return(OPT_NOBIND); }
beb904
 	-?nobrowse		{ return(OPT_NOGHOST); }
beb904
+	-?shared		{ return(OPT_SHARED); }
beb904
 	-?slave			{ return(OPT_SLAVE); }
beb904
 	-?private		{ return(OPT_PRIVATE); }
beb904
 	-?strictexpire		{ return(OPT_STRICTEXPIRE); }
beb904
--- autofs-5.1.4.orig/modules/mount_bind.c
beb904
+++ autofs-5.1.4/modules/mount_bind.c
beb904
@@ -153,6 +153,7 @@ int mount_mount(struct autofs_point *ap,
beb904
 
beb904
 	if (!symlnk && bind_works) {
beb904
 		int status, existed = 1;
beb904
+		int flags;
beb904
 
beb904
 		debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath);
beb904
 
beb904
@@ -190,24 +191,27 @@ int mount_mount(struct autofs_point *ap,
beb904
 			      what, fstype, fullpath);
beb904
 		}
beb904
 
beb904
-		if (ap->flags & (MOUNT_FLAG_SLAVE | MOUNT_FLAG_PRIVATE)) {
beb904
-			int flags = MS_SLAVE;
beb904
-
beb904
-			if (ap->flags & MOUNT_FLAG_PRIVATE)
beb904
-				flags = MS_PRIVATE;
beb904
-
beb904
-			/* The bind mount has succeeded but if the target
beb904
-			 * mount is propagation shared propagation of child
beb904
-			 * mounts (autofs offset mounts for example) back to
beb904
-			 * the target of the bind mount must be avoided or
beb904
-			 * autofs trigger mounts will deadlock.
beb904
-			 */
beb904
-			err = mount(NULL, fullpath, NULL, flags, NULL);
beb904
-			if (err) {
beb904
-				warn(ap->logopt,
beb904
-				     "failed to set propagation for %s",
beb904
-				     fullpath, root);
beb904
-			}
beb904
+		/* The bind mount has succeeded, now set the mount propagation.
beb904
+		 *
beb904
+		 * The default is propagation shared, change it if the master
beb904
+		 * map entry has a different option specified.
beb904
+		 */
beb904
+		flags = MS_SLAVE;
beb904
+		if (ap->flags & MOUNT_FLAG_PRIVATE)
beb904
+			flags = MS_PRIVATE;
beb904
+		else if (ap->flags & MOUNT_FLAG_SHARED)
beb904
+			flags = MS_SHARED;
beb904
+
beb904
+		/* Note: If the parent mount is propagation shared propagation
beb904
+		 *  of child mounts (autofs offset mounts for example) back to
beb904
+		 *  the target of the bind mount can happen in some cases and
beb904
+		 *  must be avoided or autofs trigger mounts will deadlock.
beb904
+		 */
beb904
+		err = mount(NULL, fullpath, NULL, flags, NULL);
beb904
+		if (err) {
beb904
+			warn(ap->logopt,
beb904
+			     "failed to set propagation for %s",
beb904
+			     fullpath, root);
beb904
 		}
beb904
 
beb904
 		return 0;
beb904
--- autofs-5.1.4.orig/CHANGELOG
beb904
+++ autofs-5.1.4/CHANGELOG
beb904
@@ -114,6 +114,7 @@ xx/xx/2018 autofs-5.1.5
beb904
 - use defines for expire type.
beb904
 - remove unused function dump_master().
beb904
 - fix additional typing errors.
beb904
+- make bind mounts propagation slave by default.
beb904
 
beb904
 19/12/2017 autofs-5.1.4
beb904
 - fix spec file url.