From acc387c3936ea4a6231d1ebd276b513d8441d0f2 Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Tue, 31 Aug 2004 16:26:01 +0000 Subject: [PATCH] Enter the autofs. --- lib/libautofs/Makefile | 14 + lib/libautofs/libautofs.3 | 238 ++++++++++ lib/libautofs/libautofs.c | 465 ++++++++++++++++++++ lib/libautofs/libautofs.h | 103 +++++ sbin/mount_autofs/Makefile | 8 + sbin/mount_autofs/mount_autofs.8 | 71 +++ sbin/mount_autofs/mount_autofs.c | 103 +++++ share/examples/autofs/driver/Makefile | 18 + share/examples/autofs/driver/autodriver.c | 510 ++++++++++++++++++++++ share/examples/autofs/driver/autotab | 7 + share/man/man5/autofs.5 | 58 +++ 11 files changed, 1595 insertions(+) create mode 100644 lib/libautofs/Makefile create mode 100644 lib/libautofs/libautofs.3 create mode 100644 lib/libautofs/libautofs.c create mode 100644 lib/libautofs/libautofs.h create mode 100644 sbin/mount_autofs/Makefile create mode 100644 sbin/mount_autofs/mount_autofs.8 create mode 100644 sbin/mount_autofs/mount_autofs.c create mode 100644 share/examples/autofs/driver/Makefile create mode 100644 share/examples/autofs/driver/autodriver.c create mode 100644 share/examples/autofs/driver/autotab create mode 100644 share/man/man5/autofs.5 diff --git a/lib/libautofs/Makefile b/lib/libautofs/Makefile new file mode 100644 index 00000000000..92945c95466 --- /dev/null +++ b/lib/libautofs/Makefile @@ -0,0 +1,14 @@ +# $Id: Makefile,v 1.3 2004/08/31 08:49:56 bright Exp $ +# $FreeBSD$ + +LIB=autofs +SHLIB_MAJOR= 1 +SHLIB_MINOR= 0 +WARNS=4 +CFLAGS+= -I${.CURDIR}/../autofs -Werror +CFLAGS+= -g + +SRCS= libautofs.c +MAN+= libautofs.3 + +.include diff --git a/lib/libautofs/libautofs.3 b/lib/libautofs/libautofs.3 new file mode 100644 index 00000000000..2875c068ea9 --- /dev/null +++ b/lib/libautofs/libautofs.3 @@ -0,0 +1,238 @@ +.\" Copyright (c) 2004 Alfred Perlstein +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: libautofs.3,v 1.3 2004/08/31 15:58:40 bright Exp $ +.\" $FreeBSD$ +.Dd August 30, 2004 +.Dt LIBAUTOFS 3 +.Os +.Sh NAME +.Nm libautofs +.Nd "procedural interface to managing an autofs filesystem" +.Sh SYNOPSIS +.In libautofs.h +.Ft int +.Fn autoh_get "const char *path" "autoh_t *hndlp" +.Ft void +.Fn autoh_free "autoh_t hndl" +.Ft int +.Fn autoh_getall "autoh_t **hndlpp" "int *cnt" +.Ft void +.Fn autoh_freeall "autoh_t *hndlep" +.Ft int +.Fn autoh_fd "autoh_t hndl" +.Ft const char * +.Fn autoh_mp "autoh_t hndl" +.Ft int +.Fn autoreq_get "autoh_t hndl" "autoreq_t **reqpp" "int *cntp" +.Ft void +.Fn autoreq_free "autoh_t hndl" "autoreq_t *reqp" +.Ft int +.Fn autoreq_serv "autoh_t hndl" "autoreq_t req" +.Ft enum autoreq_op +.Fn autoreq_getop "autoreq_t req" +.Ft const char * +.Fn autoreq_getpath "autoreq_t req" +.Ft autoino_t +.Fn autoreq_getino "autoreq_t req" +.Ft autoino_t +.Fn autoreq_getdirino "autoreq_t req" +.Ft void +.Fn autoreq_getaux "autoreq_t req" "void **auxdatap" "size_t *auxsizep" +.Ft void +.Fn autoreq_getoffset "autoreq_t req" "off_t *offp" +.Ft void +.Fn autoreq_setino "autoreq_t req" "autoino_t ino" +.Ft void +.Fn autoreq_seterrno "autoreq_t req" "int errno" +.Ft void +.Fn autoreq_setaux "autoreq_t req" "void *auxdata" "size_t auxsize" +.Ft void +.Fn autoreq_seteof "autoreq_t req" "int eof" +.Ft int +.Fn autoh_togglepath "autoh_t hndl" "int toggle" "pid_t pid" "const char *path" +.Ft int +.Fn autoh_togglefd "autoh_t hndl" "int toggle" "pid_t pid" "int fd" +.Sh DESCRIPTION +The +.Nm libautofs +libarary provides a "mostly" stable interface to the +.Xr autofs 9 +filesystem. +.Pp +The inteface to +.Xr autofs 9 +is managed via handles of type +.Fa autoh_t +and +.Fa autoreq_t +which refer to handles to +.Xr autofs 9 +mount points and requests respectively. +.Pp +The +.Fn autoh_get +function returns a handle to an +.Xr autofs 9 +filesystem based on the +.Fn path +parameter. +The handle returned should be freed via the +.Fn autoh_free +function. +.Pp +The +.Fn autoh_getall +function returns an array of handles to all mounted +.Xr autofs 9 +filesystems, each of which should be released via the +.Fn autoh_free +function or released en-mass via the +.Fn autoh_freeall +function. +.Pp +The +.Fn autoh_fd +function returns a file descriptor that can selected or polled on +for "excecption" data to detect an +.Xr autofs 9 +event. +.Pp +The +.Fn autoh_mp +function returns the path to the autofs filesystem that the +.Fa hndl +is derived from. +.Pp +The +.Fn autoreq_get +function returns an array of autofs requests in +.Fa reqpp , +the number of requests is stored into +.Fa cntp . +Each request should be released using the +.Fn autoreq_free +function. +.Pp +Requests that are retrieved via the +.Fn autoreq_get +are served via the "autoreq_" functions. +.Pp +The following functions returns information about the request. +.Bl -tag -width indent +.It Fn autoreq_getop +return the operation type of the request, that would be one of +AUTOREQ_OP_UNKNOWN, AUTOREQ_OP_LOOKUP, AUTOREQ_OP_STAT, AUTOREQ_OP_READDIR +depending on the type of request that +.Xr autofs 9 +requires service from. +.It Fn autoreq_getpath +return the path of the mountpoint associated with the request +.Fa req . +.It Fn autoreq_getino +return the inode associated with the request +.Fa req . +.It Fn autoreq_getdirno +return the directory inode associated with the request +.Fa req . +.It Fn autoreq_getaux +return the auxilliray data associated with the request +.Fa req . +.It Fn autoreq_getoffset +return the offset request associated with the request +.Fa req . +(used for readdir request) +.El +.Pp +The following functions allow one to set the response sent to +.Xr autofs 9 +to the requesting userland application. +.Bl -tag -width indent +.It Fn autoreq_setino +Set the request +.Fa req +inode to +.Fa ino , +this is typically unused. +.It Fn autoreq_seterrno +set the error returned to the application sending the request, typically +this is left alone, or set to ENOENT if the request is for a non-existant +name. The default error is no error. Meaning the application will see +a successful return. +.It Fn autoreq_setaux +used to set the auxilliray data for a request, currently used to set +the dirent structures for serving a readdir request. Default is no +auxilliary data. +.It Fn autoreq_seteof +used to set the eof flag for readdir requests (default is not eof.) +.El +.Pp +The functions +.Fn autoh_togglepath +and +.Fn autoh_togglefd +are used to set options on an +.Xr autofs 9 +directory via +.Fa path +and +.Fa fd +respectively. The +.Fa pid +argument should be set to the pid of the process serving +.Xr autofs 9 +requests, or -1 to disable the option. The options are +.Bl -tag -width AUTO_INDIRECT +.It Fa AUTO_MOUNTER +set this process as the one responsible for the +.Xr autofs 9 +node, if this process exits, then requests into the autofs will begin to fail. +.It Fa AUTO_BROWSE +dispatch directory read requests for this node to the process identified by +.Fa pid . +Specifically, calls to +.Xr getdirentries 2 +and +.Xr getdents 2 +will be routed to userland after the current actual directory contents +are read into userland. +.It Fa AUTO_DIRECT +Set the directory as a mount trigger. Any request to enter the directory +will trigger a callback into the process +.Fa pid . +.It Fa AUTO_INDIRECT +Set the directory as an indirect trigger. Any request for an entry inside +the directory will be routed to the process identified by +.Fa pid . +.El +.Sh EXAMPLES +See /usr/share/examples/autofs/driver/ +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 6.0 . +.Sh AUTHORS +This manual page and the autofs filesystem suite were written by +.An Alfred Perlstein . diff --git a/lib/libautofs/libautofs.c b/lib/libautofs/libautofs.c new file mode 100644 index 00000000000..f68e90430ee --- /dev/null +++ b/lib/libautofs/libautofs.c @@ -0,0 +1,465 @@ +/* + * Copyright (c) 2004 Alfred Perlstein + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * $Id: libautofs.c,v 1.3 2004/08/31 08:49:56 bright Exp $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "libautofs.h" + +struct auto_handle { + char ah_mp[MNAMELEN]; + fsid_t ah_fsid; + int ah_fd; +}; + +static int autofs_sysctl(int, fsid_t *, void *, size_t *, void *, size_t); +static void safe_free(void *ptr); +static int getmntlst(struct statfs **sfsp, int *cntp); + +static void +safe_free(void *ptr) +{ + int saved_errno; + + saved_errno = errno; + free(ptr); + errno = saved_errno; +} + +int +getmntlst(struct statfs **sfsp, int *cntp) +{ + int cnt; + long bufsize; + + *sfsp = NULL; + cnt = getfsstat(NULL, 0, MNT_NOWAIT); + bufsize = cnt * sizeof(**sfsp); + fprintf(stderr, "getmntlst bufsize %ld, cnt %d\n", bufsize, cnt); + *sfsp = malloc(bufsize); + if (sfsp == NULL) + goto err; + cnt = getfsstat(*sfsp, bufsize, MNT_NOWAIT); + if (cnt == -1) + goto err; + *cntp = cnt; + fprintf(stderr, "getmntlst ok, cnt %d\n", cnt); + return (0); +err: + safe_free(sfsp); + *sfsp = NULL; + fprintf(stderr, "getmntlst bad\n"); + return (-1); +} + +/* get a handle based on a path. */ +int +autoh_get(const char *path, autoh_t *ahp) +{ + struct statfs *sfsp, *sp; + int cnt, fd, i; + autoh_t ret; + + ret = NULL; + /* + * We use getfsstat to prevent avoid the lookups on the mountpoints + * that statfs(2) would do. + */ + if (getmntlst(&sfsp, &cnt)) + goto err; + for (i = 0; i < cnt; i++) { + if (strcmp(sfsp[i].f_mntonname, path) == 0) + break; + } + if (i == cnt) { + fprintf(stderr, "autoh_get bad %d %d\n", i, cnt); + errno = ENOENT; + goto err; + } + sp = &sfsp[i]; + if (strcmp(sp->f_fstypename, "autofs")) { + errno = ENOTTY; + goto err; + } + fd = open(sp->f_mntonname, O_RDONLY); + if (fd == -1) + goto err; + ret = malloc(sizeof(*ret)); + if (ret == NULL) + goto err; + + ret->ah_fsid = sp->f_fsid; + ret->ah_fd = fd; + strlcpy(ret->ah_mp, sp->f_mntonname, sizeof(ret->ah_mp)); + safe_free(sfsp); + *ahp = ret; + return (0); +err: + safe_free(ret); + safe_free(sfsp); + return (-1); +} + +/* release. */ +void +autoh_free(autoh_t ah) +{ + int saved_errno; + + saved_errno = errno; + close(ah->ah_fd); + free(ah); + errno = saved_errno; +} + +/* + * Get an array of pointers to all the currently mounted autofs + * instances. + */ +int +autoh_getall(autoh_t **arrayp, int *cntp) +{ + struct statfs *sfsp; + int cnt, i, pos; + autoh_t *array; + + array = NULL; + /* + * We use getfsstat to prevent avoid the lookups on the mountpoints + * that statfs(2) would do. + */ + if (getmntlst(&sfsp, &cnt)) + goto err; + array = *arrayp = calloc(cnt + 1, sizeof(**arrayp)); + if (array == NULL) + goto err; + for (i = 0, pos = 0; i < cnt; i++) { + if (autoh_get(sfsp[i].f_mntonname, &array[pos]) == -1) { + /* not an autofs entry, that's ok, otherwise bail */ + if (errno == ENOTTY) + continue; + goto err; + } + pos++; + } + if (pos == 0) { + errno = ENOENT; + goto err; + } + *arrayp = array; + *cntp = pos; + safe_free(sfsp); + return (0); +err: + safe_free(sfsp); + if (array) + autoh_freeall(array); + return (-1); +} + +/* release. */ +void +autoh_freeall(autoh_t *ah) +{ + + while (*ah != NULL) { + autoh_free(*ah); + ah++; + } + safe_free(ah); +} + +/* return fd to select on. */ +int +autoh_fd(autoh_t ah) +{ + + return (ah->ah_fd); +} + +const char * +autoh_mp(autoh_t ah) +{ + + return (ah->ah_mp); +} + +static int do_autoreq_get(autoh_t ah, autoreq_t *reqp, int *cntp); + +/* get an array of pending requests */ +int +autoreq_get(autoh_t ah, autoreq_t **reqpp, int *cntp) +{ + int cnt, i; + autoreq_t req, *reqp; + + if (do_autoreq_get(ah, &req, &cnt)) + return (-1); + + reqp = calloc(cnt + 1, sizeof(*reqp)); + if (reqp == NULL) { + safe_free(req); + return (-1); + } + for (i = 0; i < cnt; i++) + reqp[i] = &req[i]; + *reqpp = reqp; + *cntp = cnt; + return (0); +} + +int +do_autoreq_get(autoh_t ah, autoreq_t *reqp, int *cntp) +{ + size_t olen; + struct autofs_userreq *reqs; + int cnt, error; + int vers; + + vers = AUTOFS_PROTOVERS; + + error = 0; + reqs = NULL; + olen = 0; + cnt = 0; + error = autofs_sysctl(AUTOFS_CTL_GETREQS, &ah->ah_fsid, NULL, &olen, + &vers, sizeof(vers)); + if (error == -1) + goto out; + if (olen == 0) + goto out; + + reqs = malloc(olen); + if (reqs == NULL) + goto out; + error = autofs_sysctl(AUTOFS_CTL_GETREQS, &ah->ah_fsid, reqs, &olen, + &vers, sizeof(vers)); + if (error == -1) + goto out; +out: + if (error) { + safe_free(reqs); + return (-1); + } + cnt = olen / sizeof(*reqs); + *cntp = cnt; + *reqp = reqs; + return (0); +} + +/* free an array of requests */ +void +autoreq_free(autoh_t ah __unused, autoreq_t *req) +{ + + free(*req); + free(req); +} + +/* serve a request */ +int +autoreq_serv(autoh_t ah, autoreq_t req) +{ + int error; + + error = autofs_sysctl(AUTOFS_CTL_SERVREQ, &ah->ah_fsid, NULL, NULL, + req, sizeof(*req)); + return (error); +} + +enum autoreq_op +autoreq_getop(autoreq_t req) +{ + + switch (req->au_op) { + case AREQ_LOOKUP: + return (AUTOREQ_OP_LOOKUP); + case AREQ_STAT: + return (AUTOREQ_OP_STAT); + case AREQ_READDIR: + return (AUTOREQ_OP_READDIR); + default: + return (AUTOREQ_OP_UNKNOWN); + } +} + +/* get a request's file name. */ +const char * +autoreq_getpath(autoreq_t req) +{ + + return (req->au_name); +} + +/* get a request's inode. a indirect mount may return AUTO_INODE_NONE. */ +autoino_t +autoreq_getino(autoreq_t req) +{ + + return (req->au_ino); +} + +void +autoreq_setino(autoreq_t req, autoino_t ino) +{ + + req->au_ino = ino; +} + +/* get a request's directory inode. */ +autoino_t +autoreq_getdirino(autoreq_t req) +{ + + return (req->au_dino); +} + +void +autoreq_seterrno(autoreq_t req, int error) +{ + + req->au_errno = error; +} + +void +autoreq_setaux(autoreq_t req, void *auxdata, size_t auxlen) +{ + + req->au_auxdata = auxdata; + req->au_auxlen = auxlen; +} + +void +autoreq_getaux(autoreq_t req, void **auxdatap, size_t *auxlenp) +{ + + *auxdatap = req->au_auxdata; + *auxlenp = req->au_auxlen; +} + +void +autoreq_seteof(autoreq_t req, int eof) +{ + + req->au_eofflag = eof; +} + +void +autoreq_getoffset(autoreq_t req, off_t *offp) +{ + + *offp = req->au_offset - AUTOFS_USEROFF; +} + +/* toggle by path. args = handle, AUTO_?, pid (-1 to disable), path. */ +int +autoh_togglepath(autoh_t ah, int op, pid_t pid, const char *path) +{ + int fd, ret; + + fd = open(path, O_RDONLY); + if (fd == -1) + return (-1); + ret = autoh_togglefd(ah, op, pid, fd); + close(fd); + return (ret); +} + +/* toggle by fd. args = handle, AUTO_?, pid (-1 to disable), fd. */ +int +autoh_togglefd(autoh_t ah, int op, pid_t pid, int fd) +{ + struct stat sb; + struct autofs_mounterreq mr; + int error, realop; + + switch (op) { + case AUTO_DIRECT: + realop = AUTOFS_CTL_TRIGGER; + break; + case AUTO_INDIRECT: + realop = AUTOFS_CTL_SUBTRIGGER; + break; + case AUTO_MOUNTER: + realop = AUTOFS_CTL_MOUNTER; + break; + case AUTO_BROWSE: + realop = AUTOFS_CTL_BROWSE; + break; + default: + errno = ENOTTY; + return (-1); + } + + if (fstat(fd, &sb)) + return (-1); + bzero(&mr, sizeof(mr)); + mr.amu_ino = sb.st_ino; + mr.amu_pid = pid; + error = autofs_sysctl(realop, &ah->ah_fsid, NULL, NULL, + &mr, sizeof(mr)); + return (error); +} + +int +autofs_sysctl(op, fsid, oldp, oldlenp, newp, newlen) + int op; + fsid_t *fsid; + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; +{ + struct vfsidctl vc; + + bzero(&vc, sizeof(vc)); + vc.vc_op = op; + strcpy(vc.vc_fstypename, "*"); + vc.vc_vers = VFS_CTL_VERS1; + vc.vc_fsid = *fsid; + vc.vc_ptr = newp; + vc.vc_len = newlen; + return (sysctlbyname("vfs.autofs.ctl", oldp, oldlenp, &vc, sizeof(vc))); +} + diff --git a/lib/libautofs/libautofs.h b/lib/libautofs/libautofs.h new file mode 100644 index 00000000000..98da2f83837 --- /dev/null +++ b/lib/libautofs/libautofs.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Alfred Perlstein + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * $Id: libautofs.h,v 1.3 2004/08/31 08:49:56 bright Exp $ + */ +#ifndef _LIBAUTOFS_H +#define _LIBAUTOFS_H + +struct auto_handle; +typedef struct auto_handle * autoh_t; +struct autofs_userreq; +typedef struct autofs_userreq * autoreq_t; +typedef uint64_t autoino_t; + +#define AUTO_INODE_NONE 0 + +#define AUTO_DIRECT 1 +#define AUTO_INDIRECT 2 +#define AUTO_MOUNTER 3 +#define AUTO_BROWSE 4 + +enum autoreq_op { + AUTOREQ_OP_UNKNOWN = 0, + AUTOREQ_OP_LOOKUP, + AUTOREQ_OP_STAT, + AUTOREQ_OP_READDIR +}; + +/* get a handle based on a path. */ +int autoh_get(const char *, autoh_t *); +/* release. */ +void autoh_free(autoh_t); + +/* + * Get an array of pointers to handles for all autofs mounts, returns count + * or -1 + */ +int autoh_getall(autoh_t **, int *cnt); +/* free the array of pointers */ +void autoh_freeall(autoh_t *); + +/* return fd to select on. */ +int autoh_fd(autoh_t); + +/* returns the mount point of the autofs instance. */ +const char *autoh_mp(autoh_t); + +/* get an array of pending requests */ +int autoreq_get(autoh_t, autoreq_t **, int *); +/* free an array of requests */ +void autoreq_free(autoh_t, autoreq_t *); +/* serve a request */ +int autoreq_serv(autoh_t, autoreq_t); + +/* get the operation requested */ +enum autoreq_op autoreq_getop(autoreq_t); + +/* get a request's file name. */ +const char *autoreq_getpath(autoreq_t); +/* get a request's inode. a indirect mount may return AUTO_INODE_NONE. */ +autoino_t autoreq_getino(autoreq_t); +/* + * set a request's inode. an indirect mount may return AUTO_INODE_NONE, + * this is a fixup for indirect mounts. + */ +void autoreq_setino(autoreq_t, autoino_t); +/* get a request's directory inode. */ +autoino_t autoreq_getdirino(autoreq_t); +void autoreq_seterrno(autoreq_t, int); +void autoreq_setaux(autoreq_t, void *, size_t); +void autoreq_getaux(autoreq_t, void **, size_t *); +void autoreq_seteof(autoreq_t req, int eof); +void autoreq_getoffset(autoreq_t req, off_t *offp); + +/* toggle by path. args = handle, AUTO_?, pid (-1 to disable), path. */ +int autoh_togglepath(autoh_t, int, pid_t, const char *); +/* toggle by fd. args = handle, AUTO_?, pid (-1 to disable), fd. */ +int autoh_togglefd(autoh_t, int, pid_t, int); + +#endif diff --git a/sbin/mount_autofs/Makefile b/sbin/mount_autofs/Makefile new file mode 100644 index 00000000000..a23494414ed --- /dev/null +++ b/sbin/mount_autofs/Makefile @@ -0,0 +1,8 @@ +# $Id: Makefile,v 1.4 2004/08/31 16:27:40 bright Exp $ +# $FreeBSD$ + +PROG=mount_autofs +MAN=mount_autofs.8 +BINDIR?=/usr/sbin + +.include diff --git a/sbin/mount_autofs/mount_autofs.8 b/sbin/mount_autofs/mount_autofs.8 new file mode 100644 index 00000000000..b4f0c84a24f --- /dev/null +++ b/sbin/mount_autofs/mount_autofs.8 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2004 Alfred Perlstein +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: mount_autofs.8,v 1.2 2004/08/31 08:49:56 bright Exp $ +.\" $FreeBSD$ +.Dd August 30, 2004 +.Dt MOUNT_AUTOFS 8 +.Os +.Sh NAME +.Nm mount_autofs +.Nd mount an autofs file system +.Sh SYNOPSIS +.Nm +.Op Fl o Ar options +.Ar dummy +.Ar node +.Sh DESCRIPTION +The +.Nm +utility attaches an autofs file system +device on to the file system tree at the point +.Ar node . +.Pp +This command is normally executed by +.Xr mount 8 +at boot time. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl o +Options are specified with a +.Fl o +flag followed by a comma separated string of options. +See the +.Xr mount 8 +man page for possible options and their meanings. +.El +.Sh SEE ALSO +.Xr mount 2 , +.Xr unmount 2 , +.Xr fstab 5 , +.Xr mount 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 6.0 . +.Sh AUTHORS +This manual page and the autofs filesystem suite were written by +.An Alfred Perlstein . diff --git a/sbin/mount_autofs/mount_autofs.c b/sbin/mount_autofs/mount_autofs.c new file mode 100644 index 00000000000..393ff06f2f1 --- /dev/null +++ b/sbin/mount_autofs/mount_autofs.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Alfred Perlstein + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: mount_autofs.c,v 1.4 2004/08/31 16:28:22 bright Exp $ + * $FreeBSD$ + */ +#include +#include +#include +#include +#include +#include +#include + +void usage(void); + +const char *progname; + +void +usage(void) { + + errx(1, "usage: %s node", progname); +} + +#if __FreeBSD_version < 600000 +int +mymount(const char *type, const char *dir, int flags, void *data) +{ + + return (mount(type, dir, flags, data)); +} +#else +void +ioset(struct iovec *iovp, char *str) +{ + + iovp->iov_base = str; + iovp->iov_len = strlen(str) + 1; +} + +int +mymount(char *type, char *dir, int flags, void *data) +{ + struct iovec iov[4], *iovp; + + iovp = &iov[0]; + ioset(iovp++, "fstype"); + ioset(iovp++, type); + ioset(iovp++, "fspath"); + ioset(iovp++, dir); + return (nmount(iov, 4, 0)); +} +#endif + +int +main(int argc, char **argv) +{ + int error, i; + int ch; + + progname = argv[0]; + + while ((ch = getopt(argc, argv, "o:")) != -1) { + /* just eat opts for now */ + switch (ch) { + case '?': + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + usage(); + } + + error = mymount("autofs", argv[1], 0, NULL); + if (error) + perror("mount"); + return (error == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/share/examples/autofs/driver/Makefile b/share/examples/autofs/driver/Makefile new file mode 100644 index 00000000000..51791bbee7a --- /dev/null +++ b/share/examples/autofs/driver/Makefile @@ -0,0 +1,18 @@ +# $Id: Makefile,v 1.2 2004/07/17 11:26:51 bright Exp $ +# $FreeBSD$ + +PROG=autodriver + +SRCS= autodriver.c +NOMAN= YES +WERROR= YES +WARNS= 4 +CFLAGS+= -g + +DPADD+= ${.OBJDIR}/../libautofs/libautofs.a +#LDADD+= -lautofs +LDADD+= ${.OBJDIR}/../libautofs/libautofs.a +LDFLAGS+= -L${.OBJDIR}/../libautofs +CFLAGS+= -I${.CURDIR}/../libautofs + +.include diff --git a/share/examples/autofs/driver/autodriver.c b/share/examples/autofs/driver/autodriver.c new file mode 100644 index 00000000000..e2c9b0594dd --- /dev/null +++ b/share/examples/autofs/driver/autodriver.c @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2004 Alfred Perlstein + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: autodriver.c,v 1.8 2004/08/31 08:49:56 bright Exp $ + * $FreeBSD$ + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +struct autoentry { + char *ae_mnt; /* autofs mountpoint. */ + char *ae_path; /* path under mount. */ + char *ae_type; /* fs to be mounted type. */ + char *ae_opts; /* options passed to mount. */ + char *ae_rpath; /* remote path */ + char *ae_free; /* freeme! */ + char *ae_fullpath; /* full path to mount */ + int ae_line; /* line it came from in the conf. */ + int ae_indirect; /* is this an indirect mount? */ + int ae_direct; /* is this a direct mount? */ + int ae_browse; /* browseable? */ + struct autoentry *ae_next; /* next. */ +}; + +struct autoentry *entries; +const char *mount_prog = "mount"; +const char *fstype = "autofs"; + +void *xmalloc(size_t); +void *xcalloc(size_t number, size_t size); +void parsetab(void); +void populate_tab(void); +void doreq(autoh_t, autoreq_t); +void dotheneedful(autoh_t); +void eventloop(void); +int poll_handles(autoh_t *array, int cnt); +int mount_indirect(struct autofs_userreq *req, struct autoentry *ent); +int mount_direct(struct autofs_userreq *req, struct autoentry *ent); +int mount_browse(struct autofs_userreq *req, struct autoentry *ent); + +#define DSTR(s) sizeof(s) - 1, s + +struct dirent dumbents[] = { + {50, sizeof(struct dirent), DT_DIR, DSTR("one") }, + {51, sizeof(struct dirent), DT_DIR, DSTR(".") }, + {52, sizeof(struct dirent), DT_DIR, DSTR("..") }, + {50, sizeof(struct dirent), DT_DIR, DSTR("two") }, +}; + +void * +xmalloc(size_t size) +{ + void *ret; + + ret = malloc(size); + if (ret == NULL) + err(1, "malloc %d", (int) size); + return (ret); +} + +void * +xcalloc(size_t number, size_t size) +{ + void *ret; + + ret = calloc(number, size); + if (ret == NULL) + err(1, "calloc %d %d", (int)number, (int)size); + return (ret); +} + +void +parsetab(void) +{ + FILE *fp; + const char *tab; + char *cp, *p, *line, *opt; + size_t len; + struct autoentry *ent; + int lineno, x, gotopt; + const char *expecting = "expecting 'direct', 'indirect' or 'browse'"; + + tab = "autotab"; + lineno = 0; + + fp = fopen(tab, "r"); + if (fp == NULL) + err(1, "fopen %s", tab); + + while ((cp = fgetln(fp, &len)) != NULL) { + lineno++; + while (len > 0 && isspace(cp[len - 1])) + len--; + line = xmalloc(len + 1); + bcopy(cp, line, len); + line[len] = '\0'; + cp = line; + if ((cp = strchr(line, '#')) != NULL) + *cp = '\0'; + cp = line; + while (isspace(*cp)) + cp++; + if (*cp == '\0') { + free(line); + continue; + } + ent = xcalloc(1, sizeof(*ent)); + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + ent->ae_mnt = p; + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + ent->ae_path = p; + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + ent->ae_type = p; + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + ent->ae_opts = p; + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + ent->ae_rpath = p; + if ((p = strsep(&cp, " \t")) == NULL) + goto bad; + gotopt = 0; + opt = p; + while ((p = strsep(&opt, ",")) != NULL) { + if (strcmp(p, "indirect") == 0) { + ent->ae_indirect = 1; + gotopt = 1; + } else if (strcmp(p, "direct") == 0) { + ent->ae_direct = 1; + gotopt = 1; + } else if (strcmp(p, "browse") == 0) { + ent->ae_browse = 1; + gotopt = 1; + } else { + warnx("unreconized option '%s', %s", + p, expecting); + goto bad2; + } + } + if (!gotopt) { + warnx("no options specified %s", expecting); + goto bad2; + } + if (ent->ae_direct && ent->ae_indirect) { + warnx("direct and indirect are mutually exclusive"); + goto bad2; + + } + x = asprintf(&ent->ae_fullpath, "%s/%s", + ent->ae_mnt, ent->ae_path); + if (x == -1) + err(1, "asprintf"); + + if (strlen(ent->ae_fullpath) + 1 > PATH_MAX) { + warnx("Error in file %s, line %d, " + "mountpath (%s) exceeds PATH_MAX (%d)", + tab, lineno, ent->ae_fullpath, PATH_MAX); + goto bad2; + } + ent->ae_line = lineno; + ent->ae_free = line; + ent->ae_next = entries; + entries = ent; + continue; +bad: + warnx("Parse error in file %s, line %d", tab, lineno); +bad2: + free(ent->ae_fullpath); + free(line); + free(ent); + } + if (ferror(fp)) + err(1, "error with file %s", tab); +} + +void +populate_tab(void) +{ + struct autoentry *ent; + char *path, *cmd; + int error; + autoh_t ah; + + path = cmd = NULL; + + for (ent = entries; ent != NULL; ent = ent->ae_next) { + free(path); + free(cmd); + error = asprintf(&path, "%s/%s", ent->ae_mnt, ent->ae_path); + if (error == -1) + err(1, "asprintf"); + error = asprintf(&cmd, "mkdir -p %s", path); + if (error == -1) + err(1, "asprintf"); + error = system(cmd); + if (error) { + warn("system: %s", cmd); + continue; + } + if (autoh_get(ent->ae_mnt, &ah)) { + warn("autoh_get %s", path); + continue; + } + error = autoh_togglepath(ah, AUTO_MOUNTER, getpid(), path); + if (error) { + err(1, "AUTO_MOUNTER %s", path); + continue; + } + if (ent->ae_browse) { + error = autoh_togglepath(ah, AUTO_BROWSE, getpid(), + path); + if (error) + err(1, "AUTO_BROWSE %s", path); + } + if (ent->ae_direct) { + error = autoh_togglepath(ah, AUTO_DIRECT, getpid(), + path); + if (error) + err(1, "AUTO_DIRECT %s", path); + } + if (ent->ae_indirect) { + error = autoh_togglepath(ah, AUTO_INDIRECT, getpid(), + path); + if (error) + err(1, "AUTO_INDIRECT %s", path); + } + autoh_free(ah); + } + free(path); + free(cmd); +} + +/* + * Process an autofs request, scan the list of entries in the config + * looking for our node, if found mount it. + */ +void +doreq(autoh_t ah, autoreq_t req) +{ + struct autoentry *ent; + int error; + int mcmp; + const char *mnt; + + mnt = autoh_mp(ah); + + autoreq_seterrno(req, 0); + for (ent = entries; ent != NULL; ent = ent->ae_next) { + fprintf(stderr, "comparing {%s,%s} to {%s,%s}\n", + mnt, ent->ae_mnt, autoreq_getpath(req), ent->ae_path); + fprintf(stderr, "comparing {%d,%d} to {%d,%d}\n", + (int)strlen(mnt), + (int)strlen(ent->ae_mnt), + (int)strlen(autoreq_getpath(req)), + (int)strlen(ent->ae_path)); + if ((mcmp = strcmp(mnt, ent->ae_mnt)) != 0) { + fprintf(stderr, "mcmp = %d\n", mcmp); + continue; + } + if (mount_direct(req, ent)) + goto serve; + if (mount_indirect(req, ent)) + goto serve; + if (mount_browse(req, ent)) + goto serve; + } + fprintf(stderr, "no entry found...\n"); + autoreq_seterrno(req, ENOENT); +serve: + error = autoreq_serv(ah, req); + if (error == -1) { + warn("AUTOFS_CTL_SERVREQ"); + } +} + +int +mount_indirect(req, ent) + struct autofs_userreq *req; + struct autoentry *ent; +{ + struct stat sb; + char *path, *cmd; + int error, x; + + if (ent->ae_indirect != 1) + return (0); + /* + * handle lookups, fake all stat(2) requests... this is bad, + * but we're a driver so we don't care... + * If we don't care about the type of request, then just return. + */ + switch (autoreq_getop(req)) { + case AUTOREQ_OP_LOOKUP: + break; + case AUTOREQ_OP_STAT: + return (1); + default: + return (0); + } + if (stat(ent->ae_fullpath, &sb)) + return (0); + if (sb.st_ino != autoreq_getdirino(req)) + return (0); + x = asprintf(&path, "%s/%s", ent->ae_fullpath, autoreq_getpath(req)); + if (x > PATH_MAX) { + autoreq_seterrno(req, ENAMETOOLONG); + return (1); + } + if (mkdir(path, 0555) == -1) + warn("mkdir %s", path); + error = asprintf(&cmd, "%s -t %s -o %s %s/%s %s", mount_prog, + ent->ae_type, ent->ae_opts, ent->ae_rpath, autoreq_getpath(req), path); + fprintf(stderr, "running:\n\t%s\n", cmd); + error = system(cmd); + fprintf(stderr, "error = %d\n", error); + free(cmd); + if (error) { + if (rmdir(path) == -1) + warn("rmdir %s", path); + autoreq_seterrno(req, ENOENT); + } else { + if (stat(path, &sb) != -1) + autoreq_setino(req, sb.st_ino); + /* XXX !!! */ + /* req->au_flags = 1; */ + } + free(path); + return (1); +} + +int +mount_direct(req, ent) + struct autofs_userreq *req; + struct autoentry *ent; +{ + struct stat sb; + char *cmd; + int error; + + if (ent->ae_direct != 1) + return (0); + /* + * handle lookups, fake all stat(2) requests... this is bad, + * but we're a driver so we don't care... + * If we don't care about the type of request, then just return. + */ + switch (autoreq_getop(req)) { + case AUTOREQ_OP_LOOKUP: + break; + case AUTOREQ_OP_STAT: + return (1); + default: + return (0); + } + if (stat(ent->ae_fullpath, &sb)) + return (0); + if (sb.st_ino != autoreq_getino(req)) + return (0); + error = asprintf(&cmd, "%s -t %s -o %s %s %s", mount_prog, + ent->ae_type, ent->ae_opts, ent->ae_rpath, ent->ae_fullpath); + if (error == -1) + err(1, "asprintf"); + fprintf(stderr, "running:\n\t%s\n", cmd); + error = system(cmd); + fprintf(stderr, "error = %d\n", error); + free(cmd); + if (error) { + autoreq_seterrno(req, ENOENT); + return (1); + } + /* XXX: fix ONLIST in kernel */ + /* req->au_flags = 1; */ + return (1); +} + +int +mount_browse(req, ent) + struct autofs_userreq *req; + struct autoentry *ent; +{ + off_t off; + + if (ent->ae_browse != 1) + return (0); + if (autoreq_getop(req) != AUTOREQ_OP_READDIR) + return (0); + autoreq_getoffset(req, &off); + if (off < sizeof(dumbents)) + autoreq_setaux(req, dumbents, sizeof(dumbents)); + fprintf(stderr, "mount_browse: offset %d, size %d\n", + (int)off, (int)sizeof(dumbents)); + autoreq_seteof(req, 1); + return (1); +} + +/* + * Ask the filesystem passed in if it has a pending request. + * if so process them. + */ +void +dotheneedful(autoh_t ah) +{ + int cnt, i; + autoreq_t *reqs; + + if (autoreq_get(ah, &reqs, &cnt)) + err(1, "autoreq_get"); + + for (i = 0; i < cnt; i++) { + fprintf(stderr, "processing request for '%s' '%s'\n", + autoh_mp(ah), autoreq_getpath(reqs[i])); + doreq(ah, reqs[i]); + } + free(reqs); +} + +int +poll_handles(autoh_t *array, int cnt) +{ + int i, saved_errno, x; + static struct pollfd *pfd = NULL; + + pfd = reallocf(pfd, cnt * sizeof(*pfd)); + if (pfd == NULL) + return (-1); + for (i = 0; i < cnt; i++) { + pfd[i].fd = autoh_fd(array[i]); + pfd[i].events = POLLPRI; + pfd[i].revents = 0; + } + fprintf(stderr, "start polling...\n"); + x = poll(pfd, cnt, 10000); + saved_errno = errno; + fprintf(stderr, "done polling...\n"); + errno = saved_errno; + if (x == -1) + return (-1); + /* at least one fs is ready... */ + if (x > 0) + return (0); + return (0); +} + +void +eventloop(void) +{ + autoh_t *array; + int cnt, i; + + fprintf(stderr, "starting event loop...\n"); + for ( ;; ) { + if (autoh_getall(&array, &cnt)) + err(1, "autoh_getall"); + if (poll_handles(array, cnt)) + err(1, "poll_handles"); + for (i = 0; i < cnt; i++) { + dotheneedful(array[i]); + } + } +} + +int +main(int argc __unused, char **argv __unused) +{ + + parsetab(); + populate_tab(); + eventloop(); + return (0); +} diff --git a/share/examples/autofs/driver/autotab b/share/examples/autofs/driver/autotab new file mode 100644 index 00000000000..e2f85695b9c --- /dev/null +++ b/share/examples/autofs/driver/autotab @@ -0,0 +1,7 @@ +# $Id: autotab,v 1.7 2004/08/31 15:59:44 bright Exp $ +# $FreeBSD$ +# autofs, directory, fstype, opts, path +/auto share nfs ro,-R=1 big:/vol/share direct +#/auto src nfs ro,-R=1 big:/vol/share/src indirect +/auto src nfs ro,-R=1 big:/vol/share/src direct +/auto browse nfs ro,-R=1 big:/vol/share/src browse,indirect diff --git a/share/man/man5/autofs.5 b/share/man/man5/autofs.5 new file mode 100644 index 00000000000..40eacdeda9a --- /dev/null +++ b/share/man/man5/autofs.5 @@ -0,0 +1,58 @@ +.\" Copyright (c) 2004 Alfred Perlstein +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: autofs.5,v 1.1 2004/08/31 16:05:39 bright Exp $ +.\" $FreeBSD$ +.Dd August 30, 2004 +.Dt AUTOFS 5 +.Os +.Sh NAME +.Nm autofs +.Nd auto file system +.Sh SYNOPSIS +.Bd -literal +autofs /auto autofs rw 0 0 +.Ed +.Sh DESCRIPTION +The auto file system, or +.Nm , +provides a method to dynamically graft mountpoints into the filesystem +namespace. +.Sh SEE ALSO +.Xr mount_autofs 8 +.Xr libautofs 3 +.Sh HISTORY +The +.Nm +file system first appeared in +.Fx 6.0 . +The +.Nm +manual page first appeared in +.Fx 6.0 . +.Sh AUTHORS +The +.Nm +manual page was written by +.An Alfred Perlstein Aq alfred@FreeBSD.org .