/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2011 Bayard G. Bell. All rights reserved.
*/
#include <sys/vfs_opreg.h>
#include <sys/sysmacros.h>
#include <sys/pathname.h>
static int autofs_init(int, char *);
/*
* The AUTOFS system call.
*/
2,
};
"AUTOFS syscall",
};
#ifdef _SYSCALL32_IMPL
"AUTOFS syscall (32-bit)",
};
#endif /* _SYSCALL32_IMPL */
"autofs",
};
/*
* Module linkage information for the kernel.
*/
};
&modlfs,
&modlsys,
#ifdef _SYSCALL32_IMPL
#endif
};
/*
* This is the module initialization routine.
*/
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
/*
* Don't allow the autofs module to be unloaded for now.
*/
return (EBUSY);
}
int
{
}
static int autofs_fstype;
/*
* autofs VFS operations
*/
/*
* Auto Mount options table
*/
/*
* option name cancel options default arg flags
*/
NULL },
NULL },
NULL },
NULL },
NULL },
NULL },
};
};
/*ARGSUSED*/
static void
{
return;
/*
* vn_alloc() initialized the rootnode with a count of 1; we need to
* make this 0 to placate auto_freefnnode().
*/
}
/*
* rootfnnodep is allocated here. Its sole purpose is to provide
* persistent and will not be deallocated until the zone is destroyed.
*
* The current zone is implied as the zone of interest, since we will be
* calling zthread_create() which must be called from the correct zone.
*/
struct autofs_globals *
autofs_zone_init(void)
{
zoneid);
fngp);
/*
* Don't need to hold fng_rootfnnodep as it's never really used for
* anything.
*/
NULL);
fngp->fng_unmount_threads = 0;
/*
* Start the unmounter thread for this zone.
*/
return (fngp);
}
int
{
};
int error;
ASSERT(autofs_fstype != 0);
/*
* Associate VFS ops vector with this fstype
*/
if (error != 0) {
return (error);
}
if (error != 0) {
(void) vfs_freevfsops_by_type(fstype);
return (error);
}
/*
* Assign unique major number for all autofs mounts
*/
"autofs: autofs_init: can't get unique device number");
return (1);
}
/*
* We'd like to be able to provide a constructor here, but we can't
* since it wants to zthread_create(), something it can't do in a ZSD
* constructor.
*/
return (0);
}
static char *restropts[] = {
};
/*
* This routine adds those options to the option string `buf' which are
* forced by secpolicy_fs_mount. If the automatic "security" options
* are set, the option string gets them added if they aren't already
* there. We search the string with "strstr" and make sure that
* the string we find is bracketed with <start|",">MNTOPT<","|"\0">
*
* This is one half of the option inheritence algorithm which
* implements the "restrict" option. The other half is implemented
* in automountd; it takes its cue from the options we add here.
*/
static int
{
int i;
char *p;
/* Unrestricted */
return (0);
/* Add "restrict" always and the others insofar set */
return (-1);
if (*buf != '\0')
}
}
return (0);
}
/* ARGSUSED */
static int
{
int error;
(void *)vp));
return (EPERM);
if (zone == global_zone) {
return (EBUSY);
}
}
/*
* Stop the mount from going any further if the zone is going away.
*/
return (EBUSY);
/*
* We need a lock to serialize this; minor_lock is as good as any.
*/
fngp = autofs_zone_init();
}
/*
* Get arguments
*/
return (EINVAL);
} else {
if (get_udatamodel() == DATAMODEL_NATIVE) {
return (EINVAL);
} else {
return (EINVAL);
}
}
if (error)
return (EFAULT);
/*
* For a remount, only update mount information
* i.e. default mount options, map name, etc.
*/
return (EINVAL);
else
/*
* Get default options
*/
&len);
else
&len);
if (error)
return (EFAULT);
!= 0) {
return (EFAULT);
}
/*
*/
&len);
else
&len);
if (error)
return (EFAULT);
return (0);
}
/*
* Allocate fninfo struct and attach it to vfs
*/
/*
* Assign a unique device id to the mount
*/
do {
} while (vfs_devismounted(autofs_dev));
vfsp->vfs_bcount = 0;
/*
* Get daemon address
*/
else
if (error) {
goto errout;
}
/*
* Get path for mountpoint
*/
else
if (error) {
goto errout;
}
/*
* Get default options
*/
else
if (error != 0 ||
goto errout;
}
/*
*/
else
if (error) {
goto errout;
}
/*
* Get subdirectory within map
*/
else
if (error) {
goto errout;
}
/*
* Get the key
*/
else
if (error) {
goto errout;
}
/*
* Is this a direct mount?
*/
/*
* Setup netconfig.
* Can I pass in knconf as mount argument? what
* happens when the daemon gets restarted?
*/
goto errout;
}
/*
* Make the root vnode
*/
goto errout;
}
/* account for ".." entry */
/*
* Add to list of top level AUTOFS' if it is being mounted by
* a user level process.
*/
}
return (0);
return (error);
}
/* ARGSUSED */
static int
{
(void *)fnip));
return (EPERM);
/*
* forced unmount is not supported by this file system
* and thus, ENOTSUP, is being returned.
*/
return (ENOTSUP);
return (EBUSY);
/*
* The root vnode is on the linked list of root fnnodes only if
* this was not a trigger node. Since we have no way of knowing,
* if we don't find it, then we assume it was a trigger node.
*/
/*
* A check here is made to see if rvp is busy. If
* so, return EBUSY. Otherwise proceed with
* disconnecting it from the list.
*/
return (EBUSY);
}
if (pfnp)
else
break;
}
}
/*
* The following drops linkcnt to 0, therefore the disconnect is
* not attempted when auto_inactive() is called by
* vn_rele(). This is necessary because we have nothing to get
* disconnected from since we're the root of the filesystem. As a
* side effect the node is not freed, therefore I should free the
* node here.
*
* XXX - I really need to think of a better way of doing this.
*/
rfnp->fn_linkcnt--;
/*
* release of last reference causes node
* to be freed
*/
return (0);
}
/*
* find root of autofs
*/
static int
{
(void *)*vpp));
return (0);
}
/*
* Get file system statistics.
*/
static int
{
return (0);
}