/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Just in case we're not in a build environment, make sure that
* TEXT_DOMAIN gets set to something.
*/
#if !defined(TEXT_DOMAIN)
#endif
/*
* setup utility
*/
#include "meta_set_prv.h"
#include <sys/resource.h>
#include <syslog.h>
/* globals */
int metasyslog = 0;
/* locals */
static int rb_signal_which = 0;
#ifdef _DEBUG_MALLOC_INC
#endif /* _DEBUG_MALLOC_INC */
/* forwards */
static void md_catcher(int sig);
/*
*/
static int
unsigned sig,
)
{
/* expand vector as neccessary */
if (metahandlers == NULL) {
} else {
}
}
/* We need to have a seperate stack to handle rollback properly */
newhandler.sa_flags = 0;
"sigfillset(&newhandler.sa_mask)"));
/* push handler */
/* return success */
return (0);
}
static int
unsigned sig,
)
{
/* can't pop what isn't pushed */
/* pop handler */
/* return success */
return (0);
}
char *
)
{
if (setno == MD_LOCAL_SET)
}
/*
* open lock
*/
static int
)
{
/* check for already open */
if (lockfd >= 0)
goto success;
lockfd = MD_NO_LOCK;
goto success;
}
goto failure;
}
0644)) < 0) {
goto failure;
}
goto failure;
}
}
/* return success */
return (0);
/* flag failure */
if (lockfd >= 0)
return (-1);
}
static int
)
{
int retval = 0;
}
retval = -1;
}
return (retval);
}
/*
* unlock
*/
int
)
{
/* ignore read-only filesystem */
if (lockfd == MD_NO_LOCK)
return (0);
/* unlock and discard */
return (-1);
}
}
/*
* lock
*/
int
int print_status,
)
{
int lockfd;
/* open lock file */
goto failure;
}
/* ignore read-only filesystem */
goto success;
/* grab lock */
goto failure;
}
if (print_status)
"%s: waiting on %s\n"),
goto failure;
}
}
/* return success */
return (0);
/* flag failure */
if (lockfd >= 0)
return (-1);
}
int
)
{
int lockfd;
/* open lock file */
goto failure;
}
/* ignore read-only filesystem */
goto success;
/* grab lock */
goto failure;
}
goto failure;
}
/* return success */
return (0);
/* flag failure */
if (lockfd >= 0)
return (-1);
}
/*
* lock status
*/
int
)
{
int lockfd;
/* open lock file */
return (-1);
}
/* ignore read-only filesystem */
if (lockfd == MD_NO_LOCK)
return (0);
/* test lock */
return (-1);
}
return (0);
}
/*
* setup for syslog daemon output
*/
static void
char *name /* name of program */
)
{
name = "md";
metasyslog = 1;
}
/*
* daemonize: put in background
*/
int
)
{
char *p;
int i;
/* debug */
return (0); /* do nothing */
}
/* get number of file descriptors */
}
/* fork and kill parent */
else if (pid != 0)
return (pid);
/*
* We need to close the admin device and reset the specialfd to force
* the child process to reopen it, since we are going to close all
* descriptors from 3 up to RLIMIT_NOFILE in the child.
*/
if (close_admin(ep) != 0)
return (-1);
/* close RPC connections */
/* drop lock */
return (-1);
/*
* close all but stdout, stderr, and metalogfp
*/
continue;
}
(void) close(i);
}
}
/* put in own process group */
if (setsid() == -1)
/* setup syslog */
/* return success */
return (0);
}
/*
* flush and sync fp
*/
static void
)
{
}
/*
* reset and exit utility
*/
void
int eval
)
{
/* close RPC connections */
mdclrerror(ep);
if (eval == 0)
eval = 1;
}
}
/* flush name caches */
#ifdef DEBUG
metaflushnames(1);
#endif /* DEBUG */
/* log exit */
"exiting with %d\n"), eval);
}
if ((metasyslog) && (eval != 0)) {
"exiting with %d\n"), eval);
closelog();
metasyslog = 0;
}
/* check arena, print malloc usage */
#ifdef _DEBUG_MALLOC_INC
(void) malloc_chain_check(1);
{
char *p;
if (malloc_inuse_end != malloc_inuse_begin) {
}
}
}
#endif /* _DEBUG_MALLOC_INC */
/* exit with value */
}
/*
* signal catcher
*/
static void
int sig
)
{
char *msg;
/* log signal */
}
/*
* In roll_back crtical section handling, the first instance of a user
* generated signal is caught, a flag is set to allow preemption at a
* "convenient" point and md_catcher returns. If the user continues
* generate the signal, the second instance will invoke the default
* handler and exit.
*/
if (rb_signal_handling == TRUE) {
if (rb_signal_caught == FALSE) {
return;
}
}
}
/* let default handler do it's thing */
mdclrerror(ep);
defhandler.sa_flags = 0;
"sigfillset(&defhandler.sa_mask)");
}
}
}
}
void
{
md_perror("kill(getpid())");
}
}
int
md_got_sig(void)
{
return (rb_signal_caught);
}
int
md_which_sig(void)
{
return (rb_signal_which);
}
void
md_rb_sig_handling_on(void)
{
}
void
{
rb_signal_which = 0;
if (sig_seen)
}
/*
* setup metaclust variables
*/
void
)
{
/* initialise externals */
start_time = gethrtime();
}
/*
* initilize utility
*/
int
int argc,
char *argv[],
int dosyslog,
int doadmin,
)
{
int ret = 0;
/* initialize everything but the signals */
return (ret);
if (sigfillset(&allsigs) < 0)
/* catch common signals */
return (-1);
}
/* return success */
return (0);
}
/*
* initilize utility without setting up sighandlers
* setting up signal handlers in libmeta can affect others
* programs that link with libmeta but have their own handlers
*/
int
int argc,
char *argv[],
int dosyslog,
int doadmin,
)
{
/* setup myname */
++myname;
else
#if !defined(TEXT_DOMAIN)
#endif
/* print malloc usage */
#ifdef _DEBUG_MALLOC_INC
{
char *p;
}
}
#endif /* _DEBUG_MALLOC_INC */
/* open syslog */
if (dosyslog)
/* log command */
int i;
for (i = 1; (i < argc); ++i)
}
}
/* make sure we can open the admin device before we do anything else */
if (doadmin)
if (open_admin(ep) < 0)
return (-1);
/* flush name caches */
metaflushnames(1);
/* return success */
return (0);
}
/*
* (re)initilize daemon
*/
int
char *name,
)
{
static int already = 0;
/* setup */
if (! already) {
return (-1);
already = 1;
}
/* return success */
return (0);
}
/*
* Roll back functions for handling sync and async cleanup.
*/
int
{
return (-1);
}
} else {
"sigprocmask(SIG_SETMASK)");
return (-1);
}
}
return (0);
}
#ifdef DEBUG
int
int rbt_sel_tpt,
char *rbt_sel_tag,
)
{
int sig = 0;
int rbt_int_tpt;
if (rbt_env_tpt) {
if (rbt_int_tpt < 0) {
sig = 1;
}
assert(rbt_sel_tpt != 0);
if (rbt_int_tpt == 0)
return (0);
if (rbt_env_tag && rbt_sel_tag)
rbt_tag_match = 0;
"******************** RB_TEST(%s, %d, sig=%s)\n",
if (sig) {
md_eprintf("********** sigsuspend()\n");
}
if (sigsuspend(&curmask) < 0) {
"sigsuspend(&curmask)");
}
if (md_got_sig())
return (-1);
}
"********** rb_test()");
md_eprintf("******************** rollback\n");
return (-1);
}
}
return (0);
}
#else
/* ARGSUSED */
int
int rbt_sel_tpt,
char *rbt_sel_tag,
)
{
return (-1);
}
#endif /* DEBUG */