1*7836SJohn.Forte@Sun.COM /* 2*7836SJohn.Forte@Sun.COM * CDDL HEADER START 3*7836SJohn.Forte@Sun.COM * 4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 7*7836SJohn.Forte@Sun.COM * 8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 11*7836SJohn.Forte@Sun.COM * and limitations under the License. 12*7836SJohn.Forte@Sun.COM * 13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7836SJohn.Forte@Sun.COM * 19*7836SJohn.Forte@Sun.COM * CDDL HEADER END 20*7836SJohn.Forte@Sun.COM */ 21*7836SJohn.Forte@Sun.COM 22*7836SJohn.Forte@Sun.COM /* 23*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*7836SJohn.Forte@Sun.COM * Use is subject to license terms. 25*7836SJohn.Forte@Sun.COM */ 26*7836SJohn.Forte@Sun.COM 27*7836SJohn.Forte@Sun.COM #include <sys/types.h> 28*7836SJohn.Forte@Sun.COM #include <unistd.h> 29*7836SJohn.Forte@Sun.COM #include <stdio.h> 30*7836SJohn.Forte@Sun.COM #include <stdlib.h> 31*7836SJohn.Forte@Sun.COM #include <sys/stat.h> 32*7836SJohn.Forte@Sun.COM #include <fcntl.h> 33*7836SJohn.Forte@Sun.COM #include <pthread.h> 34*7836SJohn.Forte@Sun.COM #include <errno.h> 35*7836SJohn.Forte@Sun.COM #include <libscf.h> 36*7836SJohn.Forte@Sun.COM #ifdef DEBUG 37*7836SJohn.Forte@Sun.COM #include <time.h> 38*7836SJohn.Forte@Sun.COM #endif 39*7836SJohn.Forte@Sun.COM #include <signal.h> 40*7836SJohn.Forte@Sun.COM #include <semaphore.h> 41*7836SJohn.Forte@Sun.COM #include <sys/wait.h> 42*7836SJohn.Forte@Sun.COM 43*7836SJohn.Forte@Sun.COM #include "isns_server.h" 44*7836SJohn.Forte@Sun.COM #include "isns_dseng.h" 45*7836SJohn.Forte@Sun.COM #include "isns_msgq.h" 46*7836SJohn.Forte@Sun.COM #include "isns_log.h" 47*7836SJohn.Forte@Sun.COM #include "isns_cfg.h" 48*7836SJohn.Forte@Sun.COM #include "isns_utils.h" 49*7836SJohn.Forte@Sun.COM #include "isns_cache.h" 50*7836SJohn.Forte@Sun.COM #include "isns_obj.h" 51*7836SJohn.Forte@Sun.COM #include "isns_dd.h" 52*7836SJohn.Forte@Sun.COM #include "isns_scn.h" 53*7836SJohn.Forte@Sun.COM #include "isns_sched.h" 54*7836SJohn.Forte@Sun.COM #include "isns_esi.h" 55*7836SJohn.Forte@Sun.COM #include "isns_mgmt.h" 56*7836SJohn.Forte@Sun.COM 57*7836SJohn.Forte@Sun.COM /* 58*7836SJohn.Forte@Sun.COM * iSNS Server administrative settings. 59*7836SJohn.Forte@Sun.COM */ 60*7836SJohn.Forte@Sun.COM uint8_t daemonlize = 0; 61*7836SJohn.Forte@Sun.COM int dbg_level = 7; 62*7836SJohn.Forte@Sun.COM uint64_t esi_threshold; 63*7836SJohn.Forte@Sun.COM uint8_t mgmt_scn; 64*7836SJohn.Forte@Sun.COM ctrl_node_t *control_nodes = NULL; 65*7836SJohn.Forte@Sun.COM pthread_mutex_t ctrl_node_mtx = PTHREAD_MUTEX_INITIALIZER; 66*7836SJohn.Forte@Sun.COM char data_store[MAXPATHLEN]; 67*7836SJohn.Forte@Sun.COM 68*7836SJohn.Forte@Sun.COM 69*7836SJohn.Forte@Sun.COM /* semaphore for handling exit */ 70*7836SJohn.Forte@Sun.COM static sem_t isns_child_sem; 71*7836SJohn.Forte@Sun.COM static int isns_child_smf_exit_code; 72*7836SJohn.Forte@Sun.COM static pid_t isns_child_pid; 73*7836SJohn.Forte@Sun.COM 74*7836SJohn.Forte@Sun.COM #if !defined(SMF_EXIT_ERR_OTHER) 75*7836SJohn.Forte@Sun.COM #define SMF_EXIT_ERR_OTHER -1 76*7836SJohn.Forte@Sun.COM #endif 77*7836SJohn.Forte@Sun.COM 78*7836SJohn.Forte@Sun.COM /* 79*7836SJohn.Forte@Sun.COM * Globals for singal handling. time_to_exit is set by sig_handle() 80*7836SJohn.Forte@Sun.COM * when set the main thread(daemon) and othere threads should exit. 81*7836SJohn.Forte@Sun.COM * 82*7836SJohn.Forte@Sun.COM * semaphone is used to make sure all threads that are created 83*7836SJohn.Forte@Sun.COM * by isns_port_watcher and esi. 84*7836SJohn.Forte@Sun.COM */ 85*7836SJohn.Forte@Sun.COM boolean_t time_to_exit = B_FALSE; 86*7836SJohn.Forte@Sun.COM static uint32_t thr_ref_count; 87*7836SJohn.Forte@Sun.COM static pthread_mutex_t thr_count_mtx = PTHREAD_MUTEX_INITIALIZER; 88*7836SJohn.Forte@Sun.COM #define MAX_RETRY_COUNT 10 /* for checking remaining threads before exit. */ 89*7836SJohn.Forte@Sun.COM 90*7836SJohn.Forte@Sun.COM /* 91*7836SJohn.Forte@Sun.COM * global system message queue 92*7836SJohn.Forte@Sun.COM */ 93*7836SJohn.Forte@Sun.COM msg_queue_t *sys_q = NULL; 94*7836SJohn.Forte@Sun.COM msg_queue_t *scn_q = NULL; 95*7836SJohn.Forte@Sun.COM 96*7836SJohn.Forte@Sun.COM #ifdef DEBUG 97*7836SJohn.Forte@Sun.COM extern void *cli_test(void *argv); 98*7836SJohn.Forte@Sun.COM extern dump_db(void); 99*7836SJohn.Forte@Sun.COM #endif 100*7836SJohn.Forte@Sun.COM 101*7836SJohn.Forte@Sun.COM extern void sigalrm(int); 102*7836SJohn.Forte@Sun.COM 103*7836SJohn.Forte@Sun.COM /* 104*7836SJohn.Forte@Sun.COM * sigusr2_handler -- SIGUSR2 Handler 105*7836SJohn.Forte@Sun.COM * sigusr2 is exepected only when child is running okay. 106*7836SJohn.Forte@Sun.COM */ 107*7836SJohn.Forte@Sun.COM /* ARGSUSED */ 108*7836SJohn.Forte@Sun.COM static void 109*7836SJohn.Forte@Sun.COM sigusr2_handler( 110*7836SJohn.Forte@Sun.COM int sig 111*7836SJohn.Forte@Sun.COM ) 112*7836SJohn.Forte@Sun.COM { 113*7836SJohn.Forte@Sun.COM /* post okay status. */ 114*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "sigusr2_handler", 115*7836SJohn.Forte@Sun.COM "SIGUSR@ is received. Parent is existing..."); 116*7836SJohn.Forte@Sun.COM isns_child_smf_exit_code = SMF_EXIT_OK; 117*7836SJohn.Forte@Sun.COM 118*7836SJohn.Forte@Sun.COM (void) sem_post(&isns_child_sem); 119*7836SJohn.Forte@Sun.COM } 120*7836SJohn.Forte@Sun.COM 121*7836SJohn.Forte@Sun.COM /* 122*7836SJohn.Forte@Sun.COM * sigchld_handler -- SIGCHLD Handler 123*7836SJohn.Forte@Sun.COM * sigchld is exepected only when there is an error. 124*7836SJohn.Forte@Sun.COM */ 125*7836SJohn.Forte@Sun.COM /* ARGSUSED */ 126*7836SJohn.Forte@Sun.COM static void 127*7836SJohn.Forte@Sun.COM sigchld_handler( 128*7836SJohn.Forte@Sun.COM int sig 129*7836SJohn.Forte@Sun.COM ) 130*7836SJohn.Forte@Sun.COM { 131*7836SJohn.Forte@Sun.COM int status; 132*7836SJohn.Forte@Sun.COM pid_t ret_pid; 133*7836SJohn.Forte@Sun.COM 134*7836SJohn.Forte@Sun.COM /* This is the default code. */ 135*7836SJohn.Forte@Sun.COM isns_child_smf_exit_code = SMF_EXIT_ERR_OTHER; 136*7836SJohn.Forte@Sun.COM 137*7836SJohn.Forte@Sun.COM ret_pid = waitpid(isns_child_pid, &status, WNOHANG); 138*7836SJohn.Forte@Sun.COM 139*7836SJohn.Forte@Sun.COM if (ret_pid == isns_child_pid) { 140*7836SJohn.Forte@Sun.COM if (WIFEXITED(status)) { 141*7836SJohn.Forte@Sun.COM isns_child_smf_exit_code = WEXITSTATUS(status); 142*7836SJohn.Forte@Sun.COM } 143*7836SJohn.Forte@Sun.COM } 144*7836SJohn.Forte@Sun.COM (void) sem_post(&isns_child_sem); 145*7836SJohn.Forte@Sun.COM } 146*7836SJohn.Forte@Sun.COM 147*7836SJohn.Forte@Sun.COM /* ARGSUSED */ 148*7836SJohn.Forte@Sun.COM static void 149*7836SJohn.Forte@Sun.COM sighup_handler( 150*7836SJohn.Forte@Sun.COM int sig 151*7836SJohn.Forte@Sun.COM ) 152*7836SJohn.Forte@Sun.COM { 153*7836SJohn.Forte@Sun.COM 154*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "sighup_handle", 155*7836SJohn.Forte@Sun.COM "SIGHUP is received. Reloading config..."); 156*7836SJohn.Forte@Sun.COM (void) queue_msg_set(sys_q, CONFIG_RELOAD, NULL); 157*7836SJohn.Forte@Sun.COM } 158*7836SJohn.Forte@Sun.COM 159*7836SJohn.Forte@Sun.COM /* ARGSUSED */ 160*7836SJohn.Forte@Sun.COM static void 161*7836SJohn.Forte@Sun.COM sigexit_handler( 162*7836SJohn.Forte@Sun.COM int sig 163*7836SJohn.Forte@Sun.COM ) 164*7836SJohn.Forte@Sun.COM { 165*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "sigexit_handler", 166*7836SJohn.Forte@Sun.COM "Signal: %d received and sending server exit.", sig); 167*7836SJohn.Forte@Sun.COM shutdown_server(); 168*7836SJohn.Forte@Sun.COM } 169*7836SJohn.Forte@Sun.COM 170*7836SJohn.Forte@Sun.COM void 171*7836SJohn.Forte@Sun.COM inc_thr_count( 172*7836SJohn.Forte@Sun.COM ) 173*7836SJohn.Forte@Sun.COM { 174*7836SJohn.Forte@Sun.COM (void) pthread_mutex_lock(&thr_count_mtx); 175*7836SJohn.Forte@Sun.COM 176*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "inc_thr_count", 177*7836SJohn.Forte@Sun.COM "increase thread reference count(%d).", thr_ref_count); 178*7836SJohn.Forte@Sun.COM 179*7836SJohn.Forte@Sun.COM thr_ref_count++; 180*7836SJohn.Forte@Sun.COM 181*7836SJohn.Forte@Sun.COM (void) pthread_mutex_unlock(&thr_count_mtx); 182*7836SJohn.Forte@Sun.COM } 183*7836SJohn.Forte@Sun.COM 184*7836SJohn.Forte@Sun.COM void 185*7836SJohn.Forte@Sun.COM dec_thr_count( 186*7836SJohn.Forte@Sun.COM ) 187*7836SJohn.Forte@Sun.COM { 188*7836SJohn.Forte@Sun.COM (void) pthread_mutex_lock(&thr_count_mtx); 189*7836SJohn.Forte@Sun.COM 190*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "dec_thr_count", 191*7836SJohn.Forte@Sun.COM "decrease thread reference count(%d).", thr_ref_count); 192*7836SJohn.Forte@Sun.COM 193*7836SJohn.Forte@Sun.COM thr_ref_count--; 194*7836SJohn.Forte@Sun.COM 195*7836SJohn.Forte@Sun.COM (void) pthread_mutex_unlock(&thr_count_mtx); 196*7836SJohn.Forte@Sun.COM } 197*7836SJohn.Forte@Sun.COM 198*7836SJohn.Forte@Sun.COM uint32_t 199*7836SJohn.Forte@Sun.COM get_thr_count( 200*7836SJohn.Forte@Sun.COM ) 201*7836SJohn.Forte@Sun.COM { 202*7836SJohn.Forte@Sun.COM uint32_t ref; 203*7836SJohn.Forte@Sun.COM 204*7836SJohn.Forte@Sun.COM (void) pthread_mutex_lock(&thr_count_mtx); 205*7836SJohn.Forte@Sun.COM 206*7836SJohn.Forte@Sun.COM ref = thr_ref_count; 207*7836SJohn.Forte@Sun.COM 208*7836SJohn.Forte@Sun.COM (void) pthread_mutex_unlock(&thr_count_mtx); 209*7836SJohn.Forte@Sun.COM 210*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "get_thr_count", 211*7836SJohn.Forte@Sun.COM "checking thread reference count %d.", ref); 212*7836SJohn.Forte@Sun.COM 213*7836SJohn.Forte@Sun.COM return (ref); 214*7836SJohn.Forte@Sun.COM } 215*7836SJohn.Forte@Sun.COM 216*7836SJohn.Forte@Sun.COM void 217*7836SJohn.Forte@Sun.COM shutdown_server( 218*7836SJohn.Forte@Sun.COM ) 219*7836SJohn.Forte@Sun.COM { 220*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "shutdown", "raise exit flag."); 221*7836SJohn.Forte@Sun.COM time_to_exit = B_TRUE; 222*7836SJohn.Forte@Sun.COM (void) queue_msg_set(sys_q, SERVER_EXIT, NULL); 223*7836SJohn.Forte@Sun.COM } 224*7836SJohn.Forte@Sun.COM 225*7836SJohn.Forte@Sun.COM int 226*7836SJohn.Forte@Sun.COM main( 227*7836SJohn.Forte@Sun.COM /* LINTED E_FUNC_ARG_UNUSED */ 228*7836SJohn.Forte@Sun.COM int argc, 229*7836SJohn.Forte@Sun.COM /* LINTED E_FUNC_ARG_UNUSED */ 230*7836SJohn.Forte@Sun.COM char *argv[] 231*7836SJohn.Forte@Sun.COM ) 232*7836SJohn.Forte@Sun.COM { 233*7836SJohn.Forte@Sun.COM int opt_i = 0; 234*7836SJohn.Forte@Sun.COM pthread_t port_tid, esi_tid, scn_tid; 235*7836SJohn.Forte@Sun.COM uint32_t thr_cnt; 236*7836SJohn.Forte@Sun.COM int i; 237*7836SJohn.Forte@Sun.COM 238*7836SJohn.Forte@Sun.COM #ifdef DEBUG 239*7836SJohn.Forte@Sun.COM time_t t; 240*7836SJohn.Forte@Sun.COM clock_t c; 241*7836SJohn.Forte@Sun.COM #endif 242*7836SJohn.Forte@Sun.COM 243*7836SJohn.Forte@Sun.COM #ifdef DEBUG 244*7836SJohn.Forte@Sun.COM if (getopt(argc, argv, "i") == 'i') { 245*7836SJohn.Forte@Sun.COM opt_i = 1; /* interactive mode */ 246*7836SJohn.Forte@Sun.COM } 247*7836SJohn.Forte@Sun.COM #endif 248*7836SJohn.Forte@Sun.COM 249*7836SJohn.Forte@Sun.COM /* set locale */ 250*7836SJohn.Forte@Sun.COM openlog(ISNS_DAEMON_SYSLOG_PP, LOG_PID | LOG_CONS, LOG_DAEMON); 251*7836SJohn.Forte@Sun.COM 252*7836SJohn.Forte@Sun.COM /* load administative settings. pick up data location. */ 253*7836SJohn.Forte@Sun.COM if (load_config(B_TRUE) != 0) { 254*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", "administrative settings load error."); 255*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 256*7836SJohn.Forte@Sun.COM } 257*7836SJohn.Forte@Sun.COM 258*7836SJohn.Forte@Sun.COM /* A signal handler is set for SIGCHLD. */ 259*7836SJohn.Forte@Sun.COM (void) signal(SIGCHLD, sigchld_handler); 260*7836SJohn.Forte@Sun.COM (void) signal(SIGUSR2, sigusr2_handler); 261*7836SJohn.Forte@Sun.COM (void) sigset(SIGALRM, sigalrm); 262*7836SJohn.Forte@Sun.COM 263*7836SJohn.Forte@Sun.COM #ifdef DEBUG 264*7836SJohn.Forte@Sun.COM printf("start daemon\n"); 265*7836SJohn.Forte@Sun.COM #endif 266*7836SJohn.Forte@Sun.COM if (opt_i == 0 || daemonlize) { 267*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", "now forking... pid %d", getpid()); 268*7836SJohn.Forte@Sun.COM daemonlize = 1; 269*7836SJohn.Forte@Sun.COM /* daemonlize */ 270*7836SJohn.Forte@Sun.COM isns_child_pid = fork(); 271*7836SJohn.Forte@Sun.COM if (isns_child_pid < 0) { 272*7836SJohn.Forte@Sun.COM /* 273*7836SJohn.Forte@Sun.COM * cannot fork(), terminate the server. 274*7836SJohn.Forte@Sun.COM */ 275*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_CONFIG); 276*7836SJohn.Forte@Sun.COM } 277*7836SJohn.Forte@Sun.COM if (isns_child_pid > 0) { 278*7836SJohn.Forte@Sun.COM /* 279*7836SJohn.Forte@Sun.COM * terminate parent. 280*7836SJohn.Forte@Sun.COM */ 281*7836SJohn.Forte@Sun.COM (void) sem_wait(&isns_child_sem); 282*7836SJohn.Forte@Sun.COM (void) sem_destroy(&isns_child_sem); 283*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", "exiting with %d", 284*7836SJohn.Forte@Sun.COM isns_child_smf_exit_code); 285*7836SJohn.Forte@Sun.COM exit(isns_child_smf_exit_code); 286*7836SJohn.Forte@Sun.COM } 287*7836SJohn.Forte@Sun.COM 288*7836SJohn.Forte@Sun.COM /* 289*7836SJohn.Forte@Sun.COM * redirect stdout, and stderr to /dev/null. 290*7836SJohn.Forte@Sun.COM */ 291*7836SJohn.Forte@Sun.COM i = open("/dev/null", O_RDWR); 292*7836SJohn.Forte@Sun.COM (void) dup2(i, 1); 293*7836SJohn.Forte@Sun.COM (void) dup2(i, 2); 294*7836SJohn.Forte@Sun.COM } /* end of daemonlize */ 295*7836SJohn.Forte@Sun.COM 296*7836SJohn.Forte@Sun.COM #ifdef DEBUG 297*7836SJohn.Forte@Sun.COM printf("calling cache init\n"); 298*7836SJohn.Forte@Sun.COM #endif 299*7836SJohn.Forte@Sun.COM /* initialize object hash table */ 300*7836SJohn.Forte@Sun.COM if (cache_init() != 0) { 301*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", 302*7836SJohn.Forte@Sun.COM "object hash table initialization error."); 303*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 304*7836SJohn.Forte@Sun.COM } 305*7836SJohn.Forte@Sun.COM 306*7836SJohn.Forte@Sun.COM /* initialize event list */ 307*7836SJohn.Forte@Sun.COM if (el_init(10, 60, 6) != 0) { 308*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", 309*7836SJohn.Forte@Sun.COM "ESI event list initialization error."); 310*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 311*7836SJohn.Forte@Sun.COM } 312*7836SJohn.Forte@Sun.COM 313*7836SJohn.Forte@Sun.COM /* initialize iSNS database */ 314*7836SJohn.Forte@Sun.COM if (init_data() != 0) { 315*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", 316*7836SJohn.Forte@Sun.COM "internal database initialization error"); 317*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 318*7836SJohn.Forte@Sun.COM } 319*7836SJohn.Forte@Sun.COM 320*7836SJohn.Forte@Sun.COM #ifdef DEBUG 321*7836SJohn.Forte@Sun.COM printf("calling load_data\n"); 322*7836SJohn.Forte@Sun.COM t = time(NULL); 323*7836SJohn.Forte@Sun.COM c = clock(); 324*7836SJohn.Forte@Sun.COM #endif 325*7836SJohn.Forte@Sun.COM 326*7836SJohn.Forte@Sun.COM if (load_data() != 0) { 327*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", "loading data store failed"); 328*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 329*7836SJohn.Forte@Sun.COM } 330*7836SJohn.Forte@Sun.COM 331*7836SJohn.Forte@Sun.COM #ifdef DEBUG 332*7836SJohn.Forte@Sun.COM t = time(NULL) - t; 333*7836SJohn.Forte@Sun.COM c = clock() - c; 334*7836SJohn.Forte@Sun.COM printf("time %d clock %.4lf -loading data\n", 335*7836SJohn.Forte@Sun.COM t, c / (double)CLOCKS_PER_SEC); 336*7836SJohn.Forte@Sun.COM #endif 337*7836SJohn.Forte@Sun.COM 338*7836SJohn.Forte@Sun.COM #ifdef DEBUG 339*7836SJohn.Forte@Sun.COM printf("sys queue creating...\n"); 340*7836SJohn.Forte@Sun.COM #endif 341*7836SJohn.Forte@Sun.COM /* create a message queue for system control */ 342*7836SJohn.Forte@Sun.COM sys_q = queue_calloc(); 343*7836SJohn.Forte@Sun.COM if (!sys_q) { 344*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 345*7836SJohn.Forte@Sun.COM } 346*7836SJohn.Forte@Sun.COM 347*7836SJohn.Forte@Sun.COM /* create a message queue for scn thread */ 348*7836SJohn.Forte@Sun.COM scn_q = queue_calloc(); 349*7836SJohn.Forte@Sun.COM if (!scn_q) { 350*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 351*7836SJohn.Forte@Sun.COM } 352*7836SJohn.Forte@Sun.COM 353*7836SJohn.Forte@Sun.COM /* create scn thread */ 354*7836SJohn.Forte@Sun.COM /* Check for Default DD/DD-set existence and */ 355*7836SJohn.Forte@Sun.COM /* create them if they are not there. */ 356*7836SJohn.Forte@Sun.COM if (verify_ddd() != 0) { 357*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 358*7836SJohn.Forte@Sun.COM } 359*7836SJohn.Forte@Sun.COM 360*7836SJohn.Forte@Sun.COM /* setup and verify the portal(s) for scn(s) */ 361*7836SJohn.Forte@Sun.COM /* after scn registry is loaded from data store. */ 362*7836SJohn.Forte@Sun.COM if (verify_scn_portal() != 0) { 363*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 364*7836SJohn.Forte@Sun.COM } 365*7836SJohn.Forte@Sun.COM 366*7836SJohn.Forte@Sun.COM /* setup and verify the portal(s) for esi(s) */ 367*7836SJohn.Forte@Sun.COM /* after esi list is loaded from data store. */ 368*7836SJohn.Forte@Sun.COM if (verify_esi_portal() != 0) { 369*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 370*7836SJohn.Forte@Sun.COM } 371*7836SJohn.Forte@Sun.COM 372*7836SJohn.Forte@Sun.COM #ifdef DEBUG 373*7836SJohn.Forte@Sun.COM printf("scn queue creating...\n"); 374*7836SJohn.Forte@Sun.COM #endif 375*7836SJohn.Forte@Sun.COM 376*7836SJohn.Forte@Sun.COM (void) sigset(SIGHUP, sighup_handler); 377*7836SJohn.Forte@Sun.COM (void) sigset(SIGINT, sigexit_handler); 378*7836SJohn.Forte@Sun.COM (void) sigset(SIGTERM, sigexit_handler); 379*7836SJohn.Forte@Sun.COM (void) sigset(SIGQUIT, sigexit_handler); 380*7836SJohn.Forte@Sun.COM 381*7836SJohn.Forte@Sun.COM /* create scn thread */ 382*7836SJohn.Forte@Sun.COM if (pthread_create(&scn_tid, NULL, scn_proc, NULL) != 0) { 383*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", "SCN thread creating error."); 384*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 385*7836SJohn.Forte@Sun.COM } 386*7836SJohn.Forte@Sun.COM 387*7836SJohn.Forte@Sun.COM /* setup a door for management interface */ 388*7836SJohn.Forte@Sun.COM if (setup_mgmt_door(sys_q) != 0) { 389*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 390*7836SJohn.Forte@Sun.COM } 391*7836SJohn.Forte@Sun.COM 392*7836SJohn.Forte@Sun.COM /* create server port watcher */ 393*7836SJohn.Forte@Sun.COM if (pthread_create(&port_tid, NULL, 394*7836SJohn.Forte@Sun.COM isns_port_watcher, (void *)sys_q) != 0) { 395*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", "iSNS port thread creating error."); 396*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 397*7836SJohn.Forte@Sun.COM } 398*7836SJohn.Forte@Sun.COM 399*7836SJohn.Forte@Sun.COM /* create entity status inquiry thread */ 400*7836SJohn.Forte@Sun.COM if (pthread_create(&esi_tid, NULL, 401*7836SJohn.Forte@Sun.COM esi_proc, NULL) != 0) { 402*7836SJohn.Forte@Sun.COM isnslog(LOG_ERR, "main", "ESI thread creating error."); 403*7836SJohn.Forte@Sun.COM exit(SMF_EXIT_ERR_OTHER); 404*7836SJohn.Forte@Sun.COM } 405*7836SJohn.Forte@Sun.COM 406*7836SJohn.Forte@Sun.COM #ifdef DEBUG 407*7836SJohn.Forte@Sun.COM if (!daemonlize) { 408*7836SJohn.Forte@Sun.COM (void) pthread_create(&tid, 409*7836SJohn.Forte@Sun.COM NULL, 410*7836SJohn.Forte@Sun.COM cli_test, 411*7836SJohn.Forte@Sun.COM (void *)sys_q); 412*7836SJohn.Forte@Sun.COM } 413*7836SJohn.Forte@Sun.COM #endif 414*7836SJohn.Forte@Sun.COM if (opt_i == 0 || daemonlize) { 415*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", "issuing SIGUSR2.. parent pid %d", 416*7836SJohn.Forte@Sun.COM getppid()); 417*7836SJohn.Forte@Sun.COM (void) kill(getppid(), SIGUSR2); 418*7836SJohn.Forte@Sun.COM } 419*7836SJohn.Forte@Sun.COM 420*7836SJohn.Forte@Sun.COM /* pause */ 421*7836SJohn.Forte@Sun.COM for (;;) { 422*7836SJohn.Forte@Sun.COM msg_text_t *msg = queue_msg_get(sys_q); 423*7836SJohn.Forte@Sun.COM switch (msg->id) { 424*7836SJohn.Forte@Sun.COM case DATA_ADD: 425*7836SJohn.Forte@Sun.COM case DATA_UPDATE: 426*7836SJohn.Forte@Sun.COM case DATA_DELETE: 427*7836SJohn.Forte@Sun.COM case DATA_DELETE_ASSOC: 428*7836SJohn.Forte@Sun.COM case DATA_COMMIT: 429*7836SJohn.Forte@Sun.COM case DATA_RETREAT: 430*7836SJohn.Forte@Sun.COM break; 431*7836SJohn.Forte@Sun.COM case REG_EXP: 432*7836SJohn.Forte@Sun.COM /* registration expiring */ 433*7836SJohn.Forte@Sun.COM reg_expiring(msg->data); 434*7836SJohn.Forte@Sun.COM break; 435*7836SJohn.Forte@Sun.COM case DEAD_PORTAL: 436*7836SJohn.Forte@Sun.COM portal_dies((uint32_t)msg->data); 437*7836SJohn.Forte@Sun.COM break; 438*7836SJohn.Forte@Sun.COM case SERVER_EXIT: 439*7836SJohn.Forte@Sun.COM /* graceful exit. */ 440*7836SJohn.Forte@Sun.COM (void) queue_msg_free(msg); 441*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 442*7836SJohn.Forte@Sun.COM "wake up ESI and stop it."); 443*7836SJohn.Forte@Sun.COM (void) get_stopwatch(1); 444*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 445*7836SJohn.Forte@Sun.COM "sending SCN stop msg."); 446*7836SJohn.Forte@Sun.COM (void) queue_msg_set(scn_q, SCN_STOP, NULL); 447*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", "closing the door."); 448*7836SJohn.Forte@Sun.COM (void) fdetach(ISNS_DOOR_NAME); 449*7836SJohn.Forte@Sun.COM (void) pthread_join(esi_tid, NULL); 450*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 451*7836SJohn.Forte@Sun.COM "esi thread %d exited.", esi_tid); 452*7836SJohn.Forte@Sun.COM (void) pthread_join(port_tid, NULL); 453*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 454*7836SJohn.Forte@Sun.COM "port watcher thread %d exited.", port_tid); 455*7836SJohn.Forte@Sun.COM (void) pthread_join(scn_tid, NULL); 456*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 457*7836SJohn.Forte@Sun.COM "scn thread %d exited.", scn_tid); 458*7836SJohn.Forte@Sun.COM 459*7836SJohn.Forte@Sun.COM /* now check any remaining threads. */ 460*7836SJohn.Forte@Sun.COM i = 0; 461*7836SJohn.Forte@Sun.COM do { 462*7836SJohn.Forte@Sun.COM thr_cnt = get_thr_count(); 463*7836SJohn.Forte@Sun.COM if (thr_cnt == 0) { 464*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 465*7836SJohn.Forte@Sun.COM "main thread %d is done.", 466*7836SJohn.Forte@Sun.COM pthread_self()); 467*7836SJohn.Forte@Sun.COM exit(1); 468*7836SJohn.Forte@Sun.COM } else { 469*7836SJohn.Forte@Sun.COM (void) sleep(1); 470*7836SJohn.Forte@Sun.COM i++; 471*7836SJohn.Forte@Sun.COM } 472*7836SJohn.Forte@Sun.COM } while (MAX_RETRY_COUNT > i); 473*7836SJohn.Forte@Sun.COM isnslog(LOG_DEBUG, "main", 474*7836SJohn.Forte@Sun.COM "main thread %d existing ...", 475*7836SJohn.Forte@Sun.COM pthread_self()); 476*7836SJohn.Forte@Sun.COM exit(1); 477*7836SJohn.Forte@Sun.COM break; 478*7836SJohn.Forte@Sun.COM case CONFIG_RELOAD: 479*7836SJohn.Forte@Sun.COM /* load config again. don't pick data store. */ 480*7836SJohn.Forte@Sun.COM (void) load_config(B_FALSE); 481*7836SJohn.Forte@Sun.COM break; 482*7836SJohn.Forte@Sun.COM case SYS_QUIT_OK: 483*7836SJohn.Forte@Sun.COM (void) queue_msg_free(msg); 484*7836SJohn.Forte@Sun.COM exit(0); 485*7836SJohn.Forte@Sun.COM default: 486*7836SJohn.Forte@Sun.COM break; 487*7836SJohn.Forte@Sun.COM } 488*7836SJohn.Forte@Sun.COM (void) queue_msg_free(msg); 489*7836SJohn.Forte@Sun.COM } 490*7836SJohn.Forte@Sun.COM 491*7836SJohn.Forte@Sun.COM /* LINTED E_STMT_NOT_REACHED */ 492*7836SJohn.Forte@Sun.COM return (0); 493*7836SJohn.Forte@Sun.COM } 494