autod_main.c revision 92373f0acc32761c8c8b08610cc8ab5e006e96b9
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <memory.h>
#include <stropts.h>
#include <netconfig.h>
#include <stdarg.h>
#include <sys/resource.h>
#include <sys/systeminfo.h>
#include <syslog.h>
#include <errno.h>
#include <netdir.h>
#include <string.h>
#include <thread.h>
#include <locale.h>
#include <ucred.h>
#include <door.h>
#include "automount.h"
#include <rpcsvc/daemon_utils.h>
#include <deflt.h>
#include <strings.h>
#include <priv.h>
static void autofs_setdoor(int);
static void autofs_mntinfo_1_r(autofs_lookupargs *,
autofs_mountres *, ucred_t *);
static void autofs_mount_1_free_r(struct autofs_mountres *);
static void autofs_lookup_1_r(autofs_lookupargs *,
autofs_lookupres *, ucred_t *);
static void autofs_lookup_1_free_args(autofs_lookupargs *);
ucred_t *);
static void autofs_unmount_1_free_args(umntrequest *);
static void autofs_readdir_1_r(autofs_rddirargs *,
autofs_rddirres *, ucred_t *);
static void autofs_readdir_1_free_r(struct autofs_rddirres *);
static void usage();
static void warn_hup(int);
static void free_action_list();
static int start_autofs_svcs();
/*
* Private autofs system call
*/
extern int _autofssys(int, void *);
#define CTIME_BUF_LEN 26
#define RESOURCE_FACTOR 8
#ifdef DEBUG
#define AUTOFS_DOOR "/var/run/autofs_door"
#endif /* DEBUG */
static thread_key_t s_thr_key;
char self[64];
int verbose = 0;
int trace = 0;
int automountd_nobrowse = 0;
int
int argc;
char *argv[];
{
int c, error;
char *defval;
if (geteuid() != 0) {
exit(1);
}
/*
* Read in the values from config file first before we check
* commandline options so the options override the file.
*/
if ((defopen(AUTOFSADMIN)) == 0) {
else
}
else
}
errno = 0;
if (errno != 0)
trace = 0;
}
/* close defaults file */
}
switch (c) {
case 'v':
verbose++;
break;
case 'n':
break;
case 'T':
trace++;
break;
case 'D':
break;
default:
usage();
}
}
"automountd: can't determine hostname, error: %d\n",
error);
exit(1);
}
#ifndef DEBUG
if (pid < 0) {
perror("cannot fork");
exit(1);
}
if (pid)
exit(0);
#endif
(void) setsid();
/*
* initialize the name services, use NULL arguments to ensure
* we don't initialize the stack of files used in file service
*/
/*
* we're using doors and its thread management now so we need to
* make sure we have more than the default of 256 file descriptors
* available.
*/
/*
* establish our lock on the lock file and write our pid to it.
* exit if some other process holds the lock, or if there's any
*/
switch (pid) {
case 0:
break;
case -1:
exit(2);
default:
/* daemon was already running */
exit(0);
}
/*
* If we coredump it'll be /core.
*/
if (chdir("/") < 0)
/*
* Create cache_cleanup thread
*/
exit(1);
}
/* other initializations */
/*
* On a labeled system, allow read-down nfs mounts if privileged
* (PRIV_NET_MAC_AWARE) to do so. Otherwise, ignore the error
* and "mount equal label only" behavior will result.
*/
if (is_system_labeled()) {
}
/* start services */
return (start_autofs_svcs());
}
/*
* The old automounter supported a SIGHUP
* to allow it to resynchronize internal
* This is no longer relevant, but we
* need to catch the signal and warn
* the user.
*/
/* ARGSUSED */
static void
warn_hup(i)
int i;
{
}
static void
usage()
{
"\t[-T]\t\t(trace requests)\n"
"\t[-v]\t\t(verbose error msgs)\n"
"\t[-D n=s]\t(define env variable)\n");
exit(1);
/* NOTREACHED */
}
static void
{
if (trace > 0)
if (trace > 0)
}
static void
{
}
}
/* ARGSUSED */
static void
umntrequest *m,
{
struct umntrequest *ul;
if (trace > 0) {
char ctime_buf[CTIME_BUF_LEN];
ctime_buf[0] = '\0';
" mntopts=%s %s\n",
}
if (trace > 0)
}
static void
{
int status;
if (trace > 0) {
char ctime_buf[CTIME_BUF_LEN];
ctime_buf[0] = '\0';
}
if (status == 0) {
/*
* Return action list to kernel.
*/
}
} else {
/*
* Entry not found
*/
}
if (trace > 0)
}
static void
{
int status;
if (trace > 0) {
char ctime_buf[CTIME_BUF_LEN];
ctime_buf[0] = '\0';
}
if (status != 0) {
/*
* An error occurred, free action list if allocated.
*/
}
}
/*
* Return action list to kernel.
*/
} else {
/*
* No work to do left for the kernel
*/
}
if (trace > 0) {
case AUTOFS_ACTION:
trace_prt(1,
"MOUNT REPLY : status=%d, AUTOFS_ACTION\n",
status);
break;
case AUTOFS_DONE:
trace_prt(1,
"MOUNT REPLY : status=%d, AUTOFS_DONE\n",
status);
break;
default:
status);
}
}
if (m->isdirect) {
/* direct mount */
} else {
/* indirect mount */
}
}
}
static void
{
if (trace > 2)
}
}
/*
* Used for reporting messages from code shared with automount command.
* Formats message into a buffer and calls syslog.
*
* Print an error. Works like printf (fmt string and variable args)
* except that it will subsititute an error message for a "%m" string
* (like syslog).
*/
void
{
const char *p1;
char *p2;
p1++;
} else {
}
}
*p2++ = '\n';
*p2 = '\0';
}
static void
{
case AUTOFS_MOUNT_RQ:
/* LINTED pointer alignment */
"nfs", 3) == 0) {
free_nfs_args((struct nfs_args *)
}
}
break;
case AUTOFS_LINK_RQ:
"non AUTOFS_MOUNT_RQ requests not implemented\n");
break;
default:
"non AUTOFS_MOUNT_RQ requests not implemented\n");
break;
}
free(p);
}
}
static void
{
}
static void
{
if (args->mntresource)
}
static void
autofs_setdoor(int did)
{
if (did < 0) {
did = 0;
}
}
void *
{
/*
* Make sure the buffer size is aligned
*/
return (NULL);
}
else
} else {
else {
}
}
}
} else {
size);
return (NULL);
}
}
/*
* Each request will automatically spawn a new thread with this
* as its entry point.
*/
/* ARGUSED */
static void
void *cookie,
char *argp,
{
char *res;
int res_size;
/*
* autofs_cred is nulled because door_cred assumes non-null
* to have been previously allocated.
*/
if (arg_size < sizeof (autofs_door_args_t)) {
sizeof (autofs_door_res_t), NULL, 0);
/*
* If we got here the door_return() failed.
*/
error);
return;
}
if (error) {
sizeof (autofs_door_res_t), NULL, 0);
/*
* If we got here, door_return() failed
*/
error);
return;
}
switch (which) {
case AUTOFS_LOOKUP:
sizeof (autofs_lookupargs))) {
" buffer");
failed_res.xdr_len = 0;
res_size = 0;
break;
}
"results buffer");
failed_res.xdr_len = 0;
} else {
door_res->res_status = 0;
}
break;
case AUTOFS_MNTINFO:
sizeof (autofs_lookupargs))) {
" buffer");
failed_res.xdr_len = 0;
res_size = 0;
break;
}
&mount_res, autofs_cred);
/*
* Only reason we would get a NULL res is because
* we could not allocate a results buffer. Use
* a local one to return the error EAGAIN as has
* always been done when memory allocations fail.
*/
"results buffer");
failed_res.xdr_len = 0;
} else {
door_res->res_status = 0;
}
break;
case AUTOFS_UNMOUNT:
"argument buffer");
failed_res.xdr_len = 0;
res_size = sizeof (autofs_door_res_t);
break;
}
&res_size)) {
"results buffer");
failed_res.xdr_len = 0;
res_size = sizeof (autofs_door_res_t);
} else {
door_res->res_status = 0;
}
break;
case AUTOFS_READDIR:
(caddr_t *)&rddir_args,
sizeof (autofs_rddirargs))) {
"error allocating readdir argument buffer");
failed_res.xdr_len = 0;
res_size = sizeof (autofs_door_res_t);
break;
}
"results buffer");
failed_res.xdr_len = 0;
res_size = sizeof (autofs_door_res_t);
} else {
door_res->res_status = 0;
}
break;
#ifdef MALLOC_DEBUG
case AUTOFS_DUMP_DEBUG:
check_leaks("/var/tmp/automountd.leak");
/*
* If we got here, door_return() failed
*/
error);
return;
#endif
case NULLPROC:
res_size = 0;
break;
default:
res = (char *)&failed_res;
res_size = sizeof (autofs_door_res_t);
break;
}
/*
* If we got here, door_return failed.
*/
}
static int
start_autofs_svcs(void)
{
int doorfd;
#ifdef DEBUG
int dfd;
#endif
return (1);
}
#ifdef DEBUG
/*
* Create a file system path for the door
*/
return (1);
}
/*
* stale associations clean up
*/
(void) fdetach(AUTOFS_DOOR);
/*
* Register in the namespace to the kernel to door_ki_open.
*/
return (1);
}
#endif /* DEBUG */
/*
* Pass door name to kernel for door_ki_open
*/
/*
* Wait for incoming calls
*/
/*CONSTCOND*/
while (1)
(void) pause();
/* NOTREACHED */
return (10);
}
static int
int size)
{
" buffer");
return (ENOMEM);
}
return (EINVAL);
}
return (0);
}
static bool_t
int *size)
{
sizeof (autofs_door_res_t) + *size);
return (FALSE);
}
return (FALSE);
}
(*results)->res_status = 0;
return (TRUE);
}