xref: /onnv-gate/usr/src/cmd/isns/isnsd/main.c (revision 7836:4e95154b5b7a)
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