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

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