/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* probedev issues ioctls for all the metadevices
*/
#include "md_monitord.h"
#include <sdssc.h>
extern char queue_name[];
/* levels less than DEBUG_LEVEL_FORK */
/* function prototypes */
static void usage(void);
static void catch_sig(int);
static pid_t enter_daemon_lock(void);
static void exit_daemon_lock(void);
/*
* Global variable
*/
static int hold_daemon_lock;
static int daemon_lock_fd;
static int debug_level;
static int logflag;
static char *prog;
static void
usage() {
"usage: mdmonitord [-d <debug_level>] [-t poll time]\n"
"higher debug levels get progressively more"
"detailed debug information.\n\n"
"mdmonitord will run in background if run"
"with a debug_level less than %d.\n"), DEBUG_LEVEL_FORK);
exit(-1);
}
/* common exit function which ensures releasing locks */
void
{
if (hold_daemon_lock) {
}
}
/*
* When SIGHUP is received, reload modules?
*/
void
{
if (probe_started == True) {
" probe_started returning\n"));
return;
}
" starting probe from signal handler\n"));
}
}
/*
* Use an advisory lock to ensure that only one daemon process is
* active at any point in time.
*/
static pid_t
check_daemon_lock(void)
{
if (daemon_lock_fd < 0) {
monitord_exit(-1);
}
monitord_exit(-1);
}
}
static pid_t
enter_daemon_lock(void)
{
"enter_daemon_lock: lock file = %s\n"), daemon_lock_file);
if (daemon_lock_fd < 0) {
monitord_print(0, "open(%s) - %s\n",
monitord_exit(-1);
}
monitord_print(0, "lock(%s) - %s",
monitord_exit(-1);
}
}
}
hold_daemon_lock = 1;
return (0);
}
/*
* Drop the advisory daemon lock, close lock file
*/
static void
exit_daemon_lock(void)
{
monitord_print(0, "unlock(%s) - %s",
}
monitord_print(0, "close(%s) failed - %s\n",
monitord_exit(-1);
}
(void) unlink(daemon_lock_file);
}
/*
* print error messages to the terminal or to syslog
*/
/*PRINTFLIKE2*/
void
{
if (level > debug_level) {
return;
}
if (level == 0) {
if (logflag) {
} else {
}
} else {
if (logflag) {
} else {
if (newline) {
} else {
}
}
}
newline = 1;
} else {
newline = 0;
}
}
char *
{
break;
}
}
/* No match. Convert the string to an int. */
} else {
}
}
void
{
"Can't find max number of sets\n"));
monitord_exit(1);
}
/*
* We delete the FF_Q to avoid recurse errors. Yes we will lose
* some but its the corner case.
*/
"delete queue failed\n"));
monitord_exit(1);
}
/*
* done break the loop
*/
break;
} else {
continue;
}
}
/* if we dont have ownership or cannot lock it continue. */
continue;
/* Skip if a MN set */
continue;
}
}
"create queue failed"));
monitord_exit(1);
}
/*
* need to do it here only at startup.
* The daemon will restart the alarm.
*/
}
{
do {
statusp) < 0) {
"meta_notify_getev: errno 0x%x\n", -errno);
}
}
int
{
int i;
char c;
unsigned long timerval = 0;
/*
* Get the locale set up before calling any other routines
* with messages to ouput. Just in case we're not in a build
* environment, make sure that TEXT_DOMAIN gets set to
* something.
*/
#if !defined(TEXT_DOMAIN)
#endif
(void) textdomain(TEXT_DOMAIN);
if (sdssc_bind_library() == SDSSC_ERROR) {
"%s: Interface error with libsds_sc.so\n"), argv[0]);
exit(1);
}
meta_check_root(&status) != 0) {
monitord_exit(1);
}
(void) sigfillset(&mask);
if (argc > 7) {
usage();
}
} else {
prog++;
}
/*
* parsed. This is in case anything has already called getopt,
* for example sdssc_cmd_proxy which is not currently used but
* may be in the future.
*/
optind = 1;
opterr = 1;
switch (c) {
case 'v':
break;
case 'i':
issue_ioctl = True;
break;
case 'd':
break;
case 't':
break;
default:
usage();
exit(0);
}
}
if (timerval == 0) {
"operating in interrupt mode\n"));
} else {
"set value and interval %lu sec mode\n"), timerval);
}
/*
* set up our signal handler for SIGALRM. The
* rest are setup by md_init.
*/
(void) sigemptyset(&mask);
/* demonize ourselves */
if (debug_level < DEBUG_LEVEL_FORK) {
if ((pid = check_daemon_lock()) != 0) {
"mdmonitord daemon pid %ld already running\n"),
pid);
exit(-1);
}
if (fork()) {
exit(0);
}
/* only one daemon can run at a time */
if ((pid = enter_daemon_lock()) != 0) {
"mdmonitord daemon pid %ld already running\n"),
pid);
exit(-1);
}
(void) chdir("/");
(void) setsid();
if (debug_level <= 1) {
for (i = 0; i < 3; i++) {
(void) close(i);
}
(void) dup2(0, 1);
(void) dup2(0, 2);
logflag = 1;
}
}
"mdmonitord started, debug level = %d\n"), debug_level);
/* loop forever waiting for events */
do {
metaflushnames(1);
} while (wait_for_event(&status));
return (0);
}