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