Enter the autofs.
This commit is contained in:
parent
9b56caaef4
commit
acc387c393
14
lib/libautofs/Makefile
Normal file
14
lib/libautofs/Makefile
Normal file
@ -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 <bsd.lib.mk>
|
238
lib/libautofs/libautofs.3
Normal file
238
lib/libautofs/libautofs.3
Normal file
@ -0,0 +1,238 @@
|
||||
.\" Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
.\" 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 .
|
465
lib/libautofs/libautofs.c
Normal file
465
lib/libautofs/libautofs.c
Normal file
@ -0,0 +1,465 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
* 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 <err.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <autofs.h>
|
||||
|
||||
#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)));
|
||||
}
|
||||
|
103
lib/libautofs/libautofs.h
Normal file
103
lib/libautofs/libautofs.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
* 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
|
8
sbin/mount_autofs/Makefile
Normal file
8
sbin/mount_autofs/Makefile
Normal file
@ -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 <bsd.prog.mk>
|
71
sbin/mount_autofs/mount_autofs.8
Normal file
71
sbin/mount_autofs/mount_autofs.8
Normal file
@ -0,0 +1,71 @@
|
||||
.\" Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
.\" 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 .
|
103
sbin/mount_autofs/mount_autofs.c
Normal file
103
sbin/mount_autofs/mount_autofs.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
* 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 <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/uio.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
18
share/examples/autofs/driver/Makefile
Normal file
18
share/examples/autofs/driver/Makefile
Normal file
@ -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 <bsd.prog.mk>
|
510
share/examples/autofs/driver/autodriver.c
Normal file
510
share/examples/autofs/driver/autodriver.c
Normal file
@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
* 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 <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libautofs.h>
|
||||
|
||||
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);
|
||||
}
|
7
share/examples/autofs/driver/autotab
Normal file
7
share/examples/autofs/driver/autotab
Normal file
@ -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
|
58
share/man/man5/autofs.5
Normal file
58
share/man/man5/autofs.5
Normal file
@ -0,0 +1,58 @@
|
||||
.\" Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org>
|
||||
.\" 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 .
|
Loading…
x
Reference in New Issue
Block a user