diff --git a/CHANGELOG b/CHANGELOG index e70f8a3..16b77b8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -31,6 +31,7 @@ xx/xx/2018 autofs-5.1.5 - fix update_negative_cache() map source usage. - mark removed cache entry negative. - set bind mount as propagation slave. +- add master map pseudo options for mount propagation. 19/12/2017 autofs-5.1.4 - fix spec file url. diff --git a/include/automount.h b/include/automount.h index e5c19d2..417dacb 100644 --- a/include/automount.h +++ b/include/automount.h @@ -549,6 +549,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 */ diff --git a/lib/master_parse.y b/lib/master_parse.y index 5d687a7..84ca5ca 100644 --- a/lib/master_parse.y +++ b/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; @@ -103,6 +105,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 COLON COMMA NL DDASH %type map %type options @@ -196,6 +199,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; } @@ -600,6 +605,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; } @@ -672,6 +679,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; @@ -878,6 +887,10 @@ 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 (slave) + entry->ap->flags |= MOUNT_FLAG_SLAVE; + if (private) + entry->ap->flags |= MOUNT_FLAG_PRIVATE; if (negative_timeout) entry->ap->negative_timeout = negative_timeout; if (mode && mode < LONG_MAX) diff --git a/lib/master_tok.l b/lib/master_tok.l index 41ac499..f4e940c 100644 --- a/lib/master_tok.l +++ b/lib/master_tok.l @@ -389,6 +389,8 @@ MODE (--mode{OPTWS}|--mode{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); } diff --git a/man/auto.master.5.in b/man/auto.master.5.in index e9afb97..68242d4 100644 --- a/man/auto.master.5.in +++ b/man/auto.master.5.in @@ -199,6 +199,18 @@ 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 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 random selection when choosing a host from a list of replicated servers. This option is applied to this mount diff --git a/modules/mount_bind.c b/modules/mount_bind.c index fe1ad9b..b64cdcc 100644 --- a/modules/mount_bind.c +++ b/modules/mount_bind.c @@ -186,17 +186,25 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int 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 {