diff options
author | H. Peter Anvin <hpa@zytor.com> | 1998-03-27 05:37:41 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 1998-03-27 05:37:41 +0000 |
commit | b85764b115b4cb3601c660613b094b2b042dcb0a (patch) | |
tree | 762e7ba86393ad293bf62f7763b22c7e06dcc690 /modules | |
parent | 416c8a6915ad2e45c98fd8a72a0deeb8adb5d1c1 (diff) | |
download | autofs3-b85764b115b4cb3601c660613b094b2b042dcb0a.tar.gz autofs3-b85764b115b4cb3601c660613b094b2b042dcb0a.tar.xz autofs3-b85764b115b4cb3601c660613b094b2b042dcb0a.zip |
Initial integration of rth's mount_autofs.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/Makefile | 6 | ||||
-rw-r--r-- | modules/mount_autofs.c | 147 |
2 files changed, 151 insertions, 2 deletions
diff --git a/modules/Makefile b/modules/Makefile index 3b5d849..694a8c9 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -7,11 +7,13 @@ include ../Makefile.rules SRCS = lookup_yp.c lookup_file.c lookup_program.c \ parse_sun.c \ - mount_generic.c mount_ext2.c mount_nfs.c mount_smbfs.c mount_afs.c + mount_generic.c mount_ext2.c mount_nfs.c mount_smbfs.c \ + mount_afs.c mount_autofs.c MODS = lookup_yp.so lookup_file.so lookup_program.so \ parse_sun.so \ - mount_generic.so mount_ext2.so mount_nfs.so mount_smbfs.so mount_afs.so + mount_generic.so mount_ext2.so mount_nfs.so mount_smbfs.so \ + mount_afs.so mount_autofs.so ifdef HESIOD SRCS += lookup_hesiod.c parse_hesiod.c diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c new file mode 100644 index 0000000..6ab439c --- /dev/null +++ b/modules/mount_autofs.c @@ -0,0 +1,147 @@ +#ident "$Id$" +/* + * mount_autofs.c + * + * Module for recursive autofs mounts. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <syslog.h> +#include <string.h> +#include <signal.h> +#include <alloca.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#define MODULE_MOUNT +#include "automount.h" + +#define MODPREFIX "mount(autofs): " +int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */ + +int mount_init(void **context) +{ + return 0; +} + +int mount_mount(const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *c_options, + void *context) +{ + char *fullpath; + const char **argv; + int argc, status; + struct stat sb, cb; + char *options, *p; + + fullpath = alloca(strlen(root)+name_len+2); + if ( !fullpath ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + sprintf(fullpath, "%s/%s", root, name); + + options = alloca(strlen(c_options)+1); + if ( !options ) { + syslog(LOG_ERR, MODPREFIX "alloca: %m"); + return 1; + } + strcpy(options, c_options); + + syslog(LOG_DEBUG, MODPREFIX "calling mkdir %s", fullpath); + if ( mkdir(fullpath, 0555) && errno != EEXIST ) { + syslog(LOG_NOTICE, MODPREFIX "mkdir %s failed: %m", name); + return 1; + } + + syslog(LOG_DEBUG, MODPREFIX "fullpath=%s what=%s options=%s", + fullpath, what, options); + + /* Build our argument vector. */ + + argc = 5; + if ( options ) { + char *p = options; + do { + argc++; + } while ((p = strchr(p,',')) != NULL); + } + argv = (const char **) alloca((argc+1) * sizeof(char *)); + + argc = 0; + argv[argc++] = _PATH_AUTOMOUNT; + argv[argc++] = "--submount"; + argv[argc++] = fullpath; + argv[argc++] = strcpy(alloca(strlen(what)+1), what); + + if ( (p = strchr(argv[argc-1], ':')) == NULL ) { + syslog(LOG_NOTICE, MODPREFIX "%s missing script type on %s", name, what); + goto error; + } + + argv[argc++] = p; + + if ( options ) { + argv[argc++] = strtok(options, ","); + while ((argv[argc++] = strtok(NULL, ",")) != NULL) + continue; + } + argv[argc] = NULL; + + /* Spawn a new daemon. */ + status = spawnv(LOG_DEBUG, _PATH_AUTOMOUNT, argv); + if (!WIFEXITED(status) || WEXITSTATUS(status)) { + syslog(LOG_NOTICE, MODPREFIX "sub automount returned status %d", status); + goto error; + } + + /* We must wait a bit for it to get registered. We try three times, and + if it isn't ready after that, assume it has failed. This is a real + hack; we really should make --submount make the subprocess notify us. */ + + stat(root, &cb); + usleep(10000); + + stat(fullpath, &sb); + if (cb.st_dev == sb.st_dev) { + int i; + /* First, to one second by tenths. */ + for (i = 0; i < 10; ++i) { + usleep(100000); + stat(fullpath, &sb); + if (cb.st_dev != sb.st_dev) + goto ok; + } + /* Then to one minute by seconds. */ + for (i = 1; i < 60; ++i) { + sleep(1); + stat(fullpath, &sb); + if (cb.st_dev != sb.st_dev) + goto ok; + } + syslog(LOG_NOTICE, MODPREFIX "timeout waiting for submount"); + goto error; + } + +ok: + syslog(LOG_DEBUG, MODPREFIX "mounted %s on %s", what, fullpath); + return 0; + +error: + rmdir(fullpath); + syslog(LOG_NOTICE, MODPREFIX "failed to mount %s on %s", what, fullpath); + return 1; +} + +int mount_done(void *context) +{ + return 0; +} |