mmsmnt.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <libgen.h>
#include <errno.h>
#include <door.h>
#include <pthread.h>
#include <signal.h>
#include <dirent.h>
#include <string.h>
#include <stdarg.h>
#include <libnvpair.h>
#include "mms.h"
#include "mms_mgmt.h"
#include "mgmt_util.h"
/*
* MMS Mount service daemon.
*
* Uses the "door" interface for inter-process communication.
*/
/* structure for session list */
typedef struct mnt_sess {
void *session;
char *volname;
char *library;
char *cartridge;
char *app;
char *localdev;
} mnt_sess_t;
/* Function declarations */
static void *handle_signal(void *arg);
static void incr_active(void);
static void decr_active(void);
/* Globals */
char *ourdoor = "/var/run/mmsmnt_door";
char *ourlock = "/var/run/mmsmnt_door_lk";
/* session list lock */
/* mutex and condition for activity */
int active = 0;
/* error log file */
static char *errLog = "/var/log/mms/mmsmnt.log";
static char *timefmt = "%e %b %Y %T %Z";
/*
* This mount server process typically runs as an independent
* daemon. For debugging purposes, use the "-d" option to run
* the server in the foreground. "-d" is only available if the
* server has been compiled with -DDEBUG.
*
*/
int
{
int st;
char c;
int nullfd;
int doorfd = -1;
int lockfd = -1;
int logfd = -1;
char *errpfx = "main";
switch (c) {
case 'd':
break;
default:
/* ignore invalid args */
break;
}
}
/* make sure we didn't inherit a weird creation mask */
(void) umask(0);
/* close any inherited file descriptors */
/* and disassociate from our parent */
if (do_daemon) {
if (pid < 0) {
(void) printf("Cannot fork process, exiting\n");
exit(1);
} else if (pid > 0) {
/* parent exits now */
exit(0);
}
/* become session leader */
(void) setsid();
/* set out working directory to something rational */
}
/* block most signals. We only care about the die now ones */
(void) sigfillset(&mask);
/*
* if we're in debug mode, most likely in the debugger so
* allow SIGINT
*/
if (!do_daemon) {
}
if (do_daemon) {
/*
* One last fork to make sure we're really really
* not going to inherit a controlling terminal...
*/
if (pid != 0) {
exit(0);
};
} else {
/* assign stderr to stdout */
}
/* initialize log - defaults to stderr if log can't be opened */
if (logfd != -1) {
}
/* all threads we create should be detached */
(void) pthread_attr_init(&pattr);
/* Set up a signal handling thread */
/* start the activity thread */
/* lock so multiple processes don't start */
if (lockfd == -1) {
return (errno);
}
if (st == -1) {
/* already locked */
st = 0;
}
goto done;
}
/* open the doors! */
if (doorfd == -1) {
st = -1;
goto done;
}
/*
* recreate the door itself. If a previous process exited
* abnormally (core dump, whatever), the door won't be revoked
* and we won't be able to start a new process. Yet another
* weird door-ism. The locking above should prevent a door
* from being removed out from under a running process.
*/
if (st == -1) {
goto done;
}
if (st == -1) {
/* shouldn't happen - another process got here first */
st = 0;
} else {
}
goto done;
}
/* the mntsvr function now does all the work. Sit and wait to exit */
(void) pthread_mutex_lock(&glock);
while (!stopserver) {
}
(void) pthread_mutex_unlock(&glock);
done:
/* don't let any more calls in */
if (lockfd != -1) {
}
/* all done */
return (st);
}
/* exit cleanly if we're told to stop */
static void *
{
int count;
int st = 0;
#ifndef __lint
int signum;
#endif /* __lint */
(void) sigemptyset(&mask);
/*
* wait forever, or until sigwait fails 10 times. sigwait()
* shouldn't fail, but we don't want to be looping frantically
* if it does.
*/
/*
* for reasons I don't understand, lint is unhappy with
* the sigwait() function declaration in signal.h.
*/
#ifndef __lint
#endif
if (st == 0) {
break;
}
}
if (st == 0) {
/* we've been asked to exit */
(void) pthread_mutex_lock(&glock);
stopserver = B_TRUE;
(void) pthread_mutex_unlock(&glock);
(void) pthread_cond_broadcast(&quitcond);
}
return (NULL);
}
/* main dispatch function */
static void
void *cookie, /* ARGSUSED */
char *argp,
{
int st;
char *errpfx = "mntsvr";
/* LINTED [E_BAD_PTR_CAST_ALIGN] */
incr_active();
goto done;
}
} else {
}
done:
if (st != 0) {
}
decr_active();
}
static int
{
int st;
char tid[64];
char cmd[8192];
if (!in) {
return (EINVAL);
}
if (!old) {
/* nothing to do, just return */
return (0);
}
"unmount task['%s'] type[VOLUME] "
"match[and (streq(LIBRARY.'LibraryName' '%s') "
"streq(CARTRIDGE.'CartridgePCL' '%s'))] ",
}
/* use existing session to unmount */
&response);
decr_active();
return (st);
}
static void
{
if (!in) {
return;
}
}
static void
{
if (!in) {
return;
}
}
}
}
}
}
static int
{
int st;
char *val;
return (EINVAL);
}
incr_active();
}
}
}
if (st != 0) {
goto done;
}
goto done;
}
if (st == 0) {
&mntattrs);
}
if (st != 0) {
goto done;
}
/* should never happen! */
goto done;
}
if (st != 0) {
goto done;
}
if (st != 0) {
goto done;
}
done:
if (st != 0) {
if (sess) {
mms_goodbye(sess, 0);
}
if (new) {
}
decr_active();
}
return (st);
}
static void
{
break;
}
}
break;
}
}
if (ent) {
if (!prev) {
/* first on list */
} else {
}
}
}
static void
const char *errpfx,
const char *msg)
{
char timbuf[MAXPATHLEN];
return;
}
pfxp = "";
}
}
static void
{
char buf[2048];
/* LINTED [E_SEC_PRINTF_VAR_FMT] */
}
static void
incr_active(void)
{
active++;
}
static void
decr_active(void)
{
active--;
}
/*
* function to shut down this server if we timeout waiting for requests
*/
static void *
{
/* sleep for 1 minute waiting for activity after we first start */
while (active > 0) {
/* 1 minute of idle time, only */
/* sleep for a little while */
}
/* signal exit */
return (NULL);
}