You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
10 KiB
375 lines
10 KiB
autofs-5.1.3 - add amd mount type program mount support |
|
|
|
From: Ian Kent <raven@themaw.net> |
|
|
|
Add support for the amd mount type "program" and its option "mount", |
|
and its mutually exclusive options "umount" or "unmount" for specifying |
|
the program to be used to perform the mount and optionally also the |
|
umount. |
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net> |
|
--- |
|
CHANGELOG | 1 |
|
README.amd-maps | 6 +- |
|
include/parse_amd.h | 3 + |
|
lib/mounts.c | 42 ++++++++++++++- |
|
modules/amd_parse.y | 36 +++++++++---- |
|
modules/parse_amd.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
6 files changed, 216 insertions(+), 15 deletions(-) |
|
|
|
--- autofs-5.0.7.orig/CHANGELOG |
|
+++ autofs-5.0.7/CHANGELOG |
|
@@ -281,6 +281,7 @@ |
|
- add function umount_amd_ext_mount(). |
|
- add function ext_mount_inuse(). |
|
- add function construct_argv(). |
|
+- add amd mount type program mount support. |
|
|
|
25/07/2012 autofs-5.0.7 |
|
======================= |
|
--- autofs-5.0.7.orig/README.amd-maps |
|
+++ autofs-5.0.7/README.amd-maps |
|
@@ -146,9 +146,9 @@ always used for available map sources. |
|
|
|
The regex map key matching feature is not implemented. |
|
|
|
-Mount types lustre, nfsx, jfs, program and direct haven't been |
|
-implemented and other mount types that aren't implemented in amd are |
|
-also not available. |
|
+Mount types lustre, nfsx, jfs and direct haven't been implemented |
|
+and other mount types that aren't implemented in amd are also not |
|
+available. |
|
|
|
How to find out more |
|
-------------------- |
|
--- autofs-5.0.7.orig/include/parse_amd.h |
|
+++ autofs-5.0.7/include/parse_amd.h |
|
@@ -30,6 +30,7 @@ |
|
#define AMD_MOUNT_TYPE_JFS 0x00000800 |
|
#define AMD_MOUNT_TYPE_CACHEFS 0x00001000 |
|
#define AMD_MOUNT_TYPE_CDFS 0x00002000 |
|
+#define AMD_MOUNT_TYPE_PROGRAM 0x00004000 |
|
#define AMD_MOUNT_TYPE_MASK 0x0000ffff |
|
|
|
#define AMD_ENTRY_CUT 0x00010000 |
|
@@ -60,6 +61,8 @@ struct amd_entry { |
|
char *addopts; |
|
char *remopts; |
|
char *sublink; |
|
+ char *mount; |
|
+ char *umount; |
|
struct selector *selector; |
|
struct list_head list; |
|
struct list_head entries; |
|
--- autofs-5.0.7.orig/lib/mounts.c |
|
+++ autofs-5.0.7/lib/mounts.c |
|
@@ -2056,6 +2056,46 @@ int umount_amd_ext_mount(struct autofs_p |
|
{ |
|
int rv = 1; |
|
|
|
+ if (entry->umount) { |
|
+ char *prog, *str; |
|
+ char **argv; |
|
+ int argc = -1; |
|
+ |
|
+ str = strdup(entry->umount); |
|
+ if (!str) |
|
+ goto out; |
|
+ |
|
+ prog = NULL; |
|
+ argv = NULL; |
|
+ |
|
+ argc = construct_argv(str, &prog, &argv); |
|
+ if (argc == -1) { |
|
+ free(str); |
|
+ goto out; |
|
+ } |
|
+ |
|
+ if (!ext_mount_remove(&entry->ext_mount, entry->fs)) { |
|
+ rv =0; |
|
+ goto out; |
|
+ } |
|
+ |
|
+ rv = spawnv(ap->logopt, prog, (const char * const *) argv); |
|
+ if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv))) |
|
+ error(ap->logopt, |
|
+ "failed to umount program mount at %s", entry->fs); |
|
+ else { |
|
+ rv = 0; |
|
+ debug(ap->logopt, |
|
+ "umounted program mount at %s", entry->fs); |
|
+ rmdir_path(ap, entry->fs, ap->dev); |
|
+ } |
|
+ |
|
+ free_argv(argc, (const char **) argv); |
|
+ free(str); |
|
+ |
|
+ goto out; |
|
+ } |
|
+ |
|
if (ext_mount_remove(&entry->ext_mount, entry->fs)) { |
|
rv = umount_ent(ap, entry->fs); |
|
if (rv) |
|
@@ -2065,7 +2105,7 @@ int umount_amd_ext_mount(struct autofs_p |
|
debug(ap->logopt, |
|
"umounted external mount %s", entry->fs); |
|
} |
|
- |
|
+out: |
|
return rv; |
|
} |
|
|
|
--- autofs-5.0.7.orig/modules/amd_parse.y |
|
+++ autofs-5.0.7/modules/amd_parse.y |
|
@@ -347,13 +347,18 @@ option_assignment: MAP_OPTION OPTION_ASS |
|
amd_set_value(&entry.rfs, fs_opt_val); |
|
else if (!strcmp($1, "dev")) |
|
amd_set_value(&entry.dev, fs_opt_val); |
|
- else if (!strcmp($1, "mount") || |
|
- !strcmp($1, "unmount") || |
|
+ else if (!strcmp($1, "mount")) |
|
+ amd_set_value(&entry.mount, fs_opt_val); |
|
+ else if (!strcmp($1, "unmount") || |
|
!strcmp($1, "umount")) { |
|
- amd_info("file system type program is not " |
|
- "yet implemented, option ignored"); |
|
- free(fs_opt_val); |
|
- YYABORT; |
|
+ if (entry.umount) { |
|
+ sprintf(msg_buf, |
|
+ "unmount or umount may only be used once"); |
|
+ amd_info(msg_buf); |
|
+ free(fs_opt_val); |
|
+ YYABORT; |
|
+ } |
|
+ entry.umount = fs_opt_val; |
|
} else if (!strcmp($1, "delay") || |
|
!strcmp($1, "cachedir")) { |
|
sprintf(msg_buf, "option %s is not used by autofs", $1); |
|
@@ -381,7 +386,14 @@ option_assignment: MAP_OPTION OPTION_ASS |
|
amd_set_value(&entry.rfs, empty); |
|
else if (!strcmp($1, "dev")) |
|
amd_set_value(&entry.dev, empty); |
|
- else { |
|
+ else if (!strcmp($1, "mount")) { |
|
+ amd_set_value(&entry.mount, NULL); |
|
+ free(empty); |
|
+ } else if (!strcmp($1, "umount") || |
|
+ !strcmp($1, "unmount")) { |
|
+ amd_set_value(&entry.umount, NULL); |
|
+ free(empty); |
|
+ } else { |
|
amd_notify($1); |
|
free(empty); |
|
YYABORT; |
|
@@ -426,8 +438,7 @@ option_assignment: MAP_OPTION OPTION_ASS |
|
options: OPTION |
|
{ |
|
if (!strcmp($1, "fullybrowsable") || |
|
- !strcmp($1, "nounmount") || |
|
- !strcmp($1, "unmount")) { |
|
+ !strcmp($1, "nounmount")) { |
|
sprintf(msg_buf, "option %s is not currently " |
|
"implemented, ignored", $1); |
|
amd_info(msg_buf); |
|
@@ -496,7 +507,9 @@ static int match_map_option_fs_type(char |
|
!strcmp(fs_type, "ext3") || |
|
!strcmp(fs_type, "ext4")) |
|
entry.flags |= AMD_MOUNT_TYPE_EXT; |
|
- } else if (!strcmp(fs_type, "ufs")) { |
|
+ else if (!strcmp(fs_type, "program")) |
|
+ entry.flags |= AMD_MOUNT_TYPE_PROGRAM; |
|
+ else if (!strcmp(fs_type, "ufs")) { |
|
entry.flags |= AMD_MOUNT_TYPE_UFS; |
|
entry.type = conf_amd_get_linux_ufs_mount_type(); |
|
if (!entry.type) { |
|
@@ -520,7 +533,6 @@ static int match_map_option_fs_type(char |
|
fs_type = NULL; |
|
} else if (!strcmp(fs_type, "jfs") || |
|
!strcmp(fs_type, "nfsx") || |
|
- !strcmp(fs_type, "program") || |
|
!strcmp(fs_type, "lustre") || |
|
!strcmp(fs_type, "direct")) { |
|
sprintf(msg_buf, "file system type %s is " |
|
@@ -880,6 +892,8 @@ static int add_location(void) |
|
new->addopts = entry.addopts; |
|
new->remopts = entry.remopts; |
|
new->sublink = entry.sublink; |
|
+ new->mount = entry.mount; |
|
+ new->umount = entry.umount; |
|
new->selector = entry.selector; |
|
list_add_tail(&new->list, entries); |
|
memset(&entry, 0, sizeof(struct amd_entry)); |
|
--- autofs-5.0.7.orig/modules/parse_amd.c |
|
+++ autofs-5.0.7/modules/parse_amd.c |
|
@@ -790,6 +790,35 @@ next: |
|
sv = macro_addvar(sv, "remopts", 7, entry->remopts); |
|
} |
|
|
|
+ if (entry->mount) { |
|
+ if (!expand_selectors(ap, entry->mount, &expand, sv)) { |
|
+ free(entry->mount); |
|
+ if (entry->umount) |
|
+ free(entry->umount); |
|
+ entry->mount = NULL; |
|
+ entry->umount = NULL; |
|
+ goto done; |
|
+ } |
|
+ debug(logopt, MODPREFIX |
|
+ "mount expand(\"%s\") -> %s", entry->mount, expand); |
|
+ free(entry->mount); |
|
+ entry->mount = expand; |
|
+ sv = macro_addvar(sv, "mount", 5, entry->mount); |
|
+ } |
|
+ |
|
+ if (entry->umount) { |
|
+ if (!expand_selectors(ap, entry->umount, &expand, sv)) { |
|
+ free(entry->umount); |
|
+ entry->umount = NULL; |
|
+ goto done; |
|
+ } |
|
+ debug(logopt, MODPREFIX |
|
+ "umount expand(\"%s\") -> %s", entry->umount, expand); |
|
+ free(entry->umount); |
|
+ entry->umount = expand; |
|
+ sv = macro_addvar(sv, "umount", 5, entry->umount); |
|
+ } |
|
+done: |
|
return sv; |
|
} |
|
|
|
@@ -1224,6 +1253,91 @@ out: |
|
return ret; |
|
} |
|
|
|
+static int do_program_mount(struct autofs_point *ap, |
|
+ struct amd_entry *entry, const char *name) |
|
+{ |
|
+ char *prog, *str; |
|
+ char **argv; |
|
+ int argc = -1; |
|
+ int rv = 1; |
|
+ |
|
+ str = strdup(entry->mount); |
|
+ if (!str) |
|
+ goto out; |
|
+ |
|
+ prog = NULL; |
|
+ argv = NULL; |
|
+ |
|
+ argc = construct_argv(str, &prog, &argv); |
|
+ if (argc == -1) { |
|
+ error(ap->logopt, MODPREFIX |
|
+ "%s: error creating mount arguments", entry->type); |
|
+ free(str); |
|
+ goto out; |
|
+ } |
|
+ |
|
+ /* The am-utils documentation doesn't actually say that the |
|
+ * mount (and umount, if given) command need to use ${fs} as |
|
+ * the mount point in the command. |
|
+ * |
|
+ * For program mounts there's no way to know what the mount |
|
+ * point is so ${fs} must be used in the mount (and umount, |
|
+ * if given) in order to create the mount point directory |
|
+ * before executing the mount command and removing it at |
|
+ * umount. |
|
+ */ |
|
+ if (ext_mount_inuse(entry->fs)) { |
|
+ rv = 0; |
|
+ ext_mount_add(&entry->ext_mount, entry->fs, 1); |
|
+ } else { |
|
+ rv = mkdir_path(entry->fs, 0555); |
|
+ if (rv && errno != EEXIST) { |
|
+ char *buf[MAX_ERR_BUF]; |
|
+ char * estr; |
|
+ |
|
+ estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|
+ error(ap->logopt, |
|
+ MODPREFIX "%s: mkdir_path %s failed: %s", |
|
+ entry->type, entry->fs, estr); |
|
+ goto do_free; |
|
+ } |
|
+ |
|
+ rv = spawnv(ap->logopt, prog, (const char * const *) argv); |
|
+ if (WIFEXITED(rv) && !WEXITSTATUS(rv)) { |
|
+ rv = 0; |
|
+ ext_mount_add(&entry->ext_mount, entry->fs, 1); |
|
+ debug(ap->logopt, MODPREFIX |
|
+ "%s: mounted %s", entry->type, entry->fs); |
|
+ } else { |
|
+ if (!ext_mount_inuse(entry->fs)) |
|
+ rmdir_path(ap, entry->fs, ap->dev); |
|
+ error(ap->logopt, MODPREFIX |
|
+ "%s: failed to mount using: %s", |
|
+ entry->type, entry->mount); |
|
+ } |
|
+ } |
|
+do_free: |
|
+ free_argv(argc, (const char **) argv); |
|
+ free(str); |
|
+ |
|
+ if (rv) |
|
+ goto out; |
|
+ |
|
+ rv = do_link_mount(ap, name, entry, 0); |
|
+ if (!rv) |
|
+ goto out; |
|
+ |
|
+ if (umount_amd_ext_mount(ap, entry)) { |
|
+ if (!ext_mount_inuse(entry->fs)) |
|
+ rmdir_path(ap, entry->fs, ap->dev); |
|
+ debug(ap->logopt, MODPREFIX |
|
+ "%s: failed to umount external mount at %s", |
|
+ entry->type, entry->fs); |
|
+ } |
|
+out: |
|
+ return rv; |
|
+} |
|
+ |
|
static unsigned int validate_auto_options(unsigned int logopt, |
|
struct amd_entry *entry) |
|
{ |
|
@@ -1350,6 +1464,29 @@ static unsigned int validate_host_option |
|
return 1; |
|
} |
|
|
|
+static unsigned int validate_program_options(unsigned int logopt, |
|
+ struct amd_entry *entry) |
|
+{ |
|
+ /* |
|
+ * entry->mount will be NULL if there is a problem expanding |
|
+ * ${} macros in expandamdent(). |
|
+ */ |
|
+ if (!entry->mount) { |
|
+ error(logopt, MODPREFIX |
|
+ "%s: mount program invalid or not set", entry->type); |
|
+ return 0; |
|
+ } |
|
+ |
|
+ if (!entry->fs && !*entry->fs) { |
|
+ error(logopt, MODPREFIX |
|
+ "%s: ${fs} must be used as the mount point but is not set", |
|
+ entry->type); |
|
+ return 0; |
|
+ } |
|
+ |
|
+ return 1; |
|
+} |
|
+ |
|
static int amd_mount(struct autofs_point *ap, const char *name, |
|
struct amd_entry *entry, struct map_source *source, |
|
struct substvar *sv, unsigned int flags, |
|
@@ -1415,6 +1552,12 @@ static int amd_mount(struct autofs_point |
|
ret = do_host_mount(ap, name, entry, source, flags); |
|
break; |
|
|
|
+ case AMD_MOUNT_TYPE_PROGRAM: |
|
+ if (!validate_program_options(ap->logopt, entry)) |
|
+ return 1; |
|
+ ret = do_program_mount(ap, entry, name); |
|
+ break; |
|
+ |
|
default: |
|
info(ap->logopt, |
|
MODPREFIX "unkown file system type %x", fstype);
|
|
|