New flags in the master map: autofsshared autofsprivate autofsslave cause the corresponding mount propagation flags to be set on the autofs mount point. If none are specified the current behaviour of inheriting from the parent unchanged. For example specify "autofsprivate" allows mount points to be moved away from autofs using "mount -M .....". This is not supported by the kernel for the normal default of "shared". Better flag names should be chosen. I would have liked to use "shared", "private", and "slave", but they are already in use and only affect bind mounts. Signed-off-by: NeilBrown <neilb@xxxxxxx> --- daemon/direct.c | 18 ++++++++++++++++++ daemon/indirect.c | 18 ++++++++++++++++++ daemon/master_parse.y | 20 ++++++++++++++++++++ daemon/master_tok.l | 3 +++ include/automount.h | 5 +++++ man/auto.master.5.in | 9 +++++++++ 6 files changed, 73 insertions(+) diff --git a/daemon/direct.c b/daemon/direct.c index 316ffd781762..c11e27816990 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -285,6 +285,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, int status, ret, ioctlfd; const char *map_name; time_t runfreq; + int flags; int err; if (timeout) { @@ -406,6 +407,23 @@ int do_mount_autofs_direct(struct autofs_point *ap, goto out_err; } + flags = 0; + if (ap->flags & MOUNT_FLAG_AUTOFS_PRIVATE) + flags = MS_PRIVATE; + if (ap->flags & MOUNT_FLAG_AUTOFS_SHARED) + flags = MS_SHARED; + if (ap->flags & MOUNT_FLAG_AUTOFS_SLAVE) + flags = MS_SLAVE; + if (flags) { + ret = mount(NULL, me->key, NULL, flags, NULL); + if (ret == -1) { + error(ap->logopt, + "failed to set mount propagatoin %s", + me->key); + goto out_umount; + } + } + ret = stat(me->key, &st); if (ret == -1) { error(ap->logopt, diff --git a/daemon/indirect.c b/daemon/indirect.c index 23ef9f41398d..f521c66ba109 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -50,6 +50,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) const char *map_name = hosts_map_name; const char *type; struct stat st; + int flags; int ret; int err; @@ -118,6 +119,23 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root) free(options); options = NULL; + flags = 0; + if (ap->flags & MOUNT_FLAG_AUTOFS_PRIVATE) + flags = MS_PRIVATE; + if (ap->flags & MOUNT_FLAG_AUTOFS_SHARED) + flags = MS_SHARED; + if (ap->flags & MOUNT_FLAG_AUTOFS_SLAVE) + flags = MS_SLAVE; + if (flags) { + ret = mount(NULL, root, NULL, flags, NULL); + if (ret == -1) { + error(ap->logopt, + "failed to set mount propagatoin %s", + ap->path); + goto out_umount; + } + } + ret = stat(root, &st); if (ret == -1) { crit(ap->logopt, diff --git a/daemon/master_parse.y b/daemon/master_parse.y index 469cfe9765ac..0b4ac6117390 100644 --- a/daemon/master_parse.y +++ b/daemon/master_parse.y @@ -72,6 +72,7 @@ static int tmp_argc; static char **local_argv; static int local_argc; +/* Propagation flags for bind mounts */ #define PROPAGATION_SHARED MOUNT_FLAG_SHARED #define PROPAGATION_SLAVE MOUNT_FLAG_SLAVE #define PROPAGATION_PRIVATE MOUNT_FLAG_PRIVATE @@ -80,6 +81,15 @@ static int local_argc; MOUNT_FLAG_PRIVATE) static unsigned int propagation; +/* Propagation flags for autofs mount points */ +#define PROPAGATION_AUTOFS_SHARED MOUNT_FLAG_AUTOFS_SHARED +#define PROPAGATION_AUTOFS_SLAVE MOUNT_FLAG_AUTOFS_SLAVE +#define PROPAGATION_AUTOFS_PRIVATE MOUNT_FLAG_AUTOFS_PRIVATE +#define PROPAGATION_AUTOFS_MASK (MOUNT_FLAG_AUTOFS_SHARED | \ + MOUNT_FLAG_AUTOFS_SLAVE | \ + MOUNT_FLAG_AUTOFS_PRIVATE) +static unsigned int autofs_propagation; + static char errstr[MAX_ERR_LEN]; static int errlen; @@ -116,6 +126,7 @@ static int master_fprintf(FILE *, char *, ...); %token OPT_TIMEOUT OPT_NTIMEOUT OPT_PTIMEOUT OPT_NOBIND OPT_NOGHOST OPT_GHOST OPT_VERBOSE %token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK OPT_MODE %token OPT_STRICTEXPIRE OPT_SHARED OPT_SLAVE OPT_PRIVATE +%token OPT_AUTOFS_SHARED OPT_AUTOFS_SLAVE OPT_AUTOFS_PRIVATE %token COLON COMMA NL DDASH %type <strtype> map %type <strtype> options @@ -222,6 +233,9 @@ line: | PATH OPT_SHARED { master_notify($1); YYABORT; } | PATH OPT_SLAVE { master_notify($1); YYABORT; } | PATH OPT_PRIVATE { master_notify($1); YYABORT; } + | PATH OPT_AUTOFS_SHARED { master_notify($1); YYABORT; } + | PATH OPT_AUTOFS_SLAVE { master_notify($1); YYABORT; } + | PATH OPT_AUTOFS_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; } @@ -642,6 +656,9 @@ daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } | OPT_SHARED { propagation = PROPAGATION_SHARED; } | OPT_SLAVE { propagation = PROPAGATION_SLAVE; } | OPT_PRIVATE { propagation = PROPAGATION_PRIVATE; } + | OPT_AUTOFS_SHARED { autofs_propagation = PROPAGATION_AUTOFS_SHARED; } + | OPT_AUTOFS_SLAVE { autofs_propagation = PROPAGATION_AUTOFS_SLAVE; } + | OPT_AUTOFS_PRIVATE { autofs_propagation = PROPAGATION_AUTOFS_PRIVATE; } | OPT_NOBIND { nobind = 1; } | OPT_NOGHOST { ghost = 0; } | OPT_GHOST { ghost = 1; } @@ -716,6 +733,7 @@ static void local_init_vars(void) symlnk = 0; strictexpire = 0; propagation = PROPAGATION_SLAVE; + autofs_propagation = 0; nobind = 0; ghost = defaults_get_browse_mode(); random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; @@ -917,6 +935,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne } entry->ap->flags &= ~(PROPAGATION_MASK); entry->ap->flags |= propagation; + entry->ap->flags &= ~(PROPAGATION_AUTOFS_MASK); + entry->ap->flags |= autofs_propagation; if (random_selection) entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; diff --git a/daemon/master_tok.l b/daemon/master_tok.l index e2d15bce8b4d..e995f96d0df9 100644 --- a/daemon/master_tok.l +++ b/daemon/master_tok.l @@ -437,6 +437,9 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS}) -?shared { return(OPT_SHARED); } -?slave { return(OPT_SLAVE); } -?private { return(OPT_PRIVATE); } + -?autofsshared { return(OPT_AUTOFS_SHARED); } + -?autofsslave { return(OPT_AUTOFS_SLAVE); } + -?autofsprivate { return(OPT_AUTOFS_PRIVATE); } -?strictexpire { return(OPT_STRICTEXPIRE); } -g|--ghost|-?browse { return(OPT_GHOST); } -v|--verbose { return(OPT_VERBOSE); } diff --git a/include/automount.h b/include/automount.h index 9387ad1b1ce2..142c6ecb36cc 100644 --- a/include/automount.h +++ b/include/automount.h @@ -548,6 +548,11 @@ struct kernel_mod_version { /* Indicator for applications to ignore the mount entry */ #define MOUNT_FLAG_IGNORE 0x1000 +/* Propagation flag to be used on the autofs mount point */ +#define MOUNT_FLAG_AUTOFS_SHARED 0x2000 +#define MOUNT_FLAG_AUTOFS_SLAVE 0x4000 +#define MOUNT_FLAG_AUTOFS_PRIVATE 0x8000 + struct autofs_point { pthread_t thid; char *path; /* Mount point name */ diff --git a/man/auto.master.5.in b/man/auto.master.5.in index 167170150292..343a78470d8c 100644 --- a/man/auto.master.5.in +++ b/man/auto.master.5.in @@ -221,6 +221,15 @@ since the automount target is itself an (unwanted) automount trigger. This option is an autofs pseudo mount option that can be used in the master map only. .TP +.I autofsslave\fP, \fIautofsprivate\fP, or \fIautofsshared\fP +These options allow mount propagation of the automount point +itself to be set to one of \fIslave\fP, \fIprivate\fP, or +\fIshared\fP. This will be inherited by whatever is mounted there. +If none are specified the propagation of the automount point +will be inherted from its parent. +This option is an autofs pseudo mount option that can be used in the +master map only. +.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 -- 2.39.2