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.
376 lines
10 KiB
376 lines
10 KiB
7 years ago
|
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);
|