xref: /onnv-gate/usr/src/cmd/isns/isnsd/esi.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 <stdio.h>
28*7836SJohn.Forte@Sun.COM #include <stdlib.h>
29*7836SJohn.Forte@Sun.COM #include <string.h>
30*7836SJohn.Forte@Sun.COM #include <unistd.h>
31*7836SJohn.Forte@Sun.COM #include <sys/types.h>
32*7836SJohn.Forte@Sun.COM #include <time.h>
33*7836SJohn.Forte@Sun.COM #include <signal.h>
34*7836SJohn.Forte@Sun.COM #include <poll.h>
35*7836SJohn.Forte@Sun.COM 
36*7836SJohn.Forte@Sun.COM #include "isns_server.h"
37*7836SJohn.Forte@Sun.COM #include "isns_cache.h"
38*7836SJohn.Forte@Sun.COM #include "isns_obj.h"
39*7836SJohn.Forte@Sun.COM #include "isns_pdu.h"
40*7836SJohn.Forte@Sun.COM #include "isns_func.h"
41*7836SJohn.Forte@Sun.COM #include "isns_qry.h"
42*7836SJohn.Forte@Sun.COM #include "isns_msgq.h"
43*7836SJohn.Forte@Sun.COM #include "isns_log.h"
44*7836SJohn.Forte@Sun.COM #include "isns_sched.h"
45*7836SJohn.Forte@Sun.COM #include "isns_scn.h"
46*7836SJohn.Forte@Sun.COM #include "isns_esi.h"
47*7836SJohn.Forte@Sun.COM 
48*7836SJohn.Forte@Sun.COM /*
49*7836SJohn.Forte@Sun.COM  * global variables.
50*7836SJohn.Forte@Sun.COM  */
51*7836SJohn.Forte@Sun.COM 
52*7836SJohn.Forte@Sun.COM /*
53*7836SJohn.Forte@Sun.COM  * local variables.
54*7836SJohn.Forte@Sun.COM  */
55*7836SJohn.Forte@Sun.COM static ev_t *ev_list = NULL;
56*7836SJohn.Forte@Sun.COM 
57*7836SJohn.Forte@Sun.COM static uint32_t stopwatch = 0;
58*7836SJohn.Forte@Sun.COM static pthread_mutex_t stw_mtx = PTHREAD_MUTEX_INITIALIZER;
59*7836SJohn.Forte@Sun.COM 
60*7836SJohn.Forte@Sun.COM static int wakeup = 0;
61*7836SJohn.Forte@Sun.COM static pthread_mutex_t idl_mtx = PTHREAD_MUTEX_INITIALIZER;
62*7836SJohn.Forte@Sun.COM static pthread_cond_t idl_cond = PTHREAD_COND_INITIALIZER;
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM /*
65*7836SJohn.Forte@Sun.COM  * external variables.
66*7836SJohn.Forte@Sun.COM  */
67*7836SJohn.Forte@Sun.COM extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
68*7836SJohn.Forte@Sun.COM 
69*7836SJohn.Forte@Sun.COM extern boolean_t time_to_exit;
70*7836SJohn.Forte@Sun.COM 
71*7836SJohn.Forte@Sun.COM extern msg_queue_t *sys_q;
72*7836SJohn.Forte@Sun.COM 
73*7836SJohn.Forte@Sun.COM extern uint64_t esi_threshold;
74*7836SJohn.Forte@Sun.COM 
75*7836SJohn.Forte@Sun.COM #ifdef DEBUG
76*7836SJohn.Forte@Sun.COM extern void dump_pdu1(isns_pdu_t *);
77*7836SJohn.Forte@Sun.COM #endif
78*7836SJohn.Forte@Sun.COM 
79*7836SJohn.Forte@Sun.COM /*
80*7836SJohn.Forte@Sun.COM  * local functions.
81*7836SJohn.Forte@Sun.COM  */
82*7836SJohn.Forte@Sun.COM static void *esi_monitor(void *);
83*7836SJohn.Forte@Sun.COM 
84*7836SJohn.Forte@Sun.COM /*
85*7836SJohn.Forte@Sun.COM  * ****************************************************************************
86*7836SJohn.Forte@Sun.COM  *
87*7836SJohn.Forte@Sun.COM  * new_esi_portal:
88*7836SJohn.Forte@Sun.COM  *	Make a new portal for ESI event.
89*7836SJohn.Forte@Sun.COM  *
90*7836SJohn.Forte@Sun.COM  * uid	- the portal object UID.
91*7836SJohn.Forte@Sun.COM  * ip6	- the portal IPv6 format IP address.
92*7836SJohn.Forte@Sun.COM  * port	- the portal port.
93*7836SJohn.Forte@Sun.COM  * esip	- the ESI port.
94*7836SJohn.Forte@Sun.COM  * return - the new ESI portal.
95*7836SJohn.Forte@Sun.COM  *
96*7836SJohn.Forte@Sun.COM  * ****************************************************************************
97*7836SJohn.Forte@Sun.COM  */
98*7836SJohn.Forte@Sun.COM static esi_portal_t *
new_esi_portal(uint32_t uid,in6_addr_t * ip6,uint32_t port,uint32_t esip)99*7836SJohn.Forte@Sun.COM new_esi_portal(
100*7836SJohn.Forte@Sun.COM 	uint32_t uid,
101*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip6,
102*7836SJohn.Forte@Sun.COM 	uint32_t port,
103*7836SJohn.Forte@Sun.COM 	uint32_t esip
104*7836SJohn.Forte@Sun.COM )
105*7836SJohn.Forte@Sun.COM {
106*7836SJohn.Forte@Sun.COM 	esi_portal_t *p;
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM 	p = (esi_portal_t *)malloc(sizeof (esi_portal_t));
109*7836SJohn.Forte@Sun.COM 	if (p != NULL) {
110*7836SJohn.Forte@Sun.COM 		if (((int *)ip6)[0] == 0x00 &&
111*7836SJohn.Forte@Sun.COM 		    ((int *)ip6)[1] == 0x00 &&
112*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip6)[8] == 0x00 &&
113*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip6)[9] == 0x00 &&
114*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip6)[10] == 0xFF &&
115*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip6)[11] == 0xFF) {
116*7836SJohn.Forte@Sun.COM 			p->sz = sizeof (in_addr_t);
117*7836SJohn.Forte@Sun.COM 			p->ip4 = ((uint32_t *)ip6)[3];
118*7836SJohn.Forte@Sun.COM 		} else {
119*7836SJohn.Forte@Sun.COM 			p->sz = sizeof (in6_addr_t);
120*7836SJohn.Forte@Sun.COM 		}
121*7836SJohn.Forte@Sun.COM 		p->ip6 = ip6;
122*7836SJohn.Forte@Sun.COM 		p->port = port;
123*7836SJohn.Forte@Sun.COM 		p->esip = esip;
124*7836SJohn.Forte@Sun.COM 		p->ref = uid;
125*7836SJohn.Forte@Sun.COM 		p->so = 0;
126*7836SJohn.Forte@Sun.COM 		p->next = NULL;
127*7836SJohn.Forte@Sun.COM 	}
128*7836SJohn.Forte@Sun.COM 
129*7836SJohn.Forte@Sun.COM 	return (p);
130*7836SJohn.Forte@Sun.COM }
131*7836SJohn.Forte@Sun.COM 
132*7836SJohn.Forte@Sun.COM /*
133*7836SJohn.Forte@Sun.COM  * ****************************************************************************
134*7836SJohn.Forte@Sun.COM  *
135*7836SJohn.Forte@Sun.COM  * free_esi_portal:
136*7836SJohn.Forte@Sun.COM  *	Free a list of portal of one ESI event.
137*7836SJohn.Forte@Sun.COM  *
138*7836SJohn.Forte@Sun.COM  * p	- the ESI portal.
139*7836SJohn.Forte@Sun.COM  *
140*7836SJohn.Forte@Sun.COM  * ****************************************************************************
141*7836SJohn.Forte@Sun.COM  */
142*7836SJohn.Forte@Sun.COM static void
free_esi_portal(esi_portal_t * p)143*7836SJohn.Forte@Sun.COM free_esi_portal(
144*7836SJohn.Forte@Sun.COM 	esi_portal_t *p
145*7836SJohn.Forte@Sun.COM )
146*7836SJohn.Forte@Sun.COM {
147*7836SJohn.Forte@Sun.COM 	esi_portal_t *n;
148*7836SJohn.Forte@Sun.COM 
149*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
150*7836SJohn.Forte@Sun.COM 		n = p->next;
151*7836SJohn.Forte@Sun.COM 		free(p->ip6);
152*7836SJohn.Forte@Sun.COM 		free(p);
153*7836SJohn.Forte@Sun.COM 		p = n;
154*7836SJohn.Forte@Sun.COM 	}
155*7836SJohn.Forte@Sun.COM }
156*7836SJohn.Forte@Sun.COM 
157*7836SJohn.Forte@Sun.COM /*
158*7836SJohn.Forte@Sun.COM  * ****************************************************************************
159*7836SJohn.Forte@Sun.COM  *
160*7836SJohn.Forte@Sun.COM  * ev_new:
161*7836SJohn.Forte@Sun.COM  *	Make a new ESI event.
162*7836SJohn.Forte@Sun.COM  *
163*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
164*7836SJohn.Forte@Sun.COM  * eid	- the Entity object name.
165*7836SJohn.Forte@Sun.COM  * len	- the length of the name.
166*7836SJohn.Forte@Sun.COM  * return - the ESI event.
167*7836SJohn.Forte@Sun.COM  *
168*7836SJohn.Forte@Sun.COM  * ****************************************************************************
169*7836SJohn.Forte@Sun.COM  */
170*7836SJohn.Forte@Sun.COM static ev_t *
ev_new(uint32_t uid,uchar_t * eid,uint32_t len)171*7836SJohn.Forte@Sun.COM ev_new(
172*7836SJohn.Forte@Sun.COM 	uint32_t uid,
173*7836SJohn.Forte@Sun.COM 	uchar_t *eid,
174*7836SJohn.Forte@Sun.COM 	uint32_t len
175*7836SJohn.Forte@Sun.COM )
176*7836SJohn.Forte@Sun.COM {
177*7836SJohn.Forte@Sun.COM 	ev_t *ev;
178*7836SJohn.Forte@Sun.COM 
179*7836SJohn.Forte@Sun.COM 	ev = (ev_t *)malloc(sizeof (ev_t));
180*7836SJohn.Forte@Sun.COM 	if (ev != NULL) {
181*7836SJohn.Forte@Sun.COM 		if (pthread_mutex_init(&ev->mtx, NULL) != 0 ||
182*7836SJohn.Forte@Sun.COM 		    (ev->eid = (uchar_t *)malloc(len)) == NULL) {
183*7836SJohn.Forte@Sun.COM 			free(ev);
184*7836SJohn.Forte@Sun.COM 			return (NULL);
185*7836SJohn.Forte@Sun.COM 		}
186*7836SJohn.Forte@Sun.COM 		ev->uid = uid;
187*7836SJohn.Forte@Sun.COM 		(void) strcpy((char *)ev->eid, (char *)eid);
188*7836SJohn.Forte@Sun.COM 		ev->eid_len = len;
189*7836SJohn.Forte@Sun.COM 		/* initialization time */
190*7836SJohn.Forte@Sun.COM 		ev->flags = EV_FLAG_INIT;
191*7836SJohn.Forte@Sun.COM 	}
192*7836SJohn.Forte@Sun.COM 
193*7836SJohn.Forte@Sun.COM 	return (ev);
194*7836SJohn.Forte@Sun.COM }
195*7836SJohn.Forte@Sun.COM 
196*7836SJohn.Forte@Sun.COM /*
197*7836SJohn.Forte@Sun.COM  * ****************************************************************************
198*7836SJohn.Forte@Sun.COM  *
199*7836SJohn.Forte@Sun.COM  * cb_portal_uids:
200*7836SJohn.Forte@Sun.COM  *	Callback function which makes a copy of the portal child object
201*7836SJohn.Forte@Sun.COM  *	UIDs from a Network Entity object.
202*7836SJohn.Forte@Sun.COM  *
203*7836SJohn.Forte@Sun.COM  * p1	- the Network Entity object.
204*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
205*7836SJohn.Forte@Sun.COM  * return - the number of portal object UIDs.
206*7836SJohn.Forte@Sun.COM  *
207*7836SJohn.Forte@Sun.COM  * ****************************************************************************
208*7836SJohn.Forte@Sun.COM  */
209*7836SJohn.Forte@Sun.COM static int
cb_portal_uids(void * p1,void * p2)210*7836SJohn.Forte@Sun.COM cb_portal_uids(
211*7836SJohn.Forte@Sun.COM 	void *p1,
212*7836SJohn.Forte@Sun.COM 	void *p2
213*7836SJohn.Forte@Sun.COM )
214*7836SJohn.Forte@Sun.COM {
215*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
216*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
217*7836SJohn.Forte@Sun.COM 
218*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
219*7836SJohn.Forte@Sun.COM 
220*7836SJohn.Forte@Sun.COM 	uint32_t *cuidp;
221*7836SJohn.Forte@Sun.COM 
222*7836SJohn.Forte@Sun.COM 	uint32_t num = 0;
223*7836SJohn.Forte@Sun.COM 	uint32_t *p = NULL;
224*7836SJohn.Forte@Sun.COM 
225*7836SJohn.Forte@Sun.COM 	cuidp = get_child_t(obj, OBJ_PORTAL);
226*7836SJohn.Forte@Sun.COM 	if (cuidp != NULL) {
227*7836SJohn.Forte@Sun.COM 		p = (uint32_t *)malloc(*cuidp * sizeof (*p));
228*7836SJohn.Forte@Sun.COM 		if (p != NULL) {
229*7836SJohn.Forte@Sun.COM 			num = *cuidp ++;
230*7836SJohn.Forte@Sun.COM 			(void) memcpy(p, cuidp, num * sizeof (*p));
231*7836SJohn.Forte@Sun.COM 			lcp->data[1].ptr = (uchar_t *)p;
232*7836SJohn.Forte@Sun.COM 		}
233*7836SJohn.Forte@Sun.COM 	}
234*7836SJohn.Forte@Sun.COM 
235*7836SJohn.Forte@Sun.COM 	attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
236*7836SJohn.Forte@Sun.COM 	if (attr->tag != 0 && attr->value.ui != 0) {
237*7836SJohn.Forte@Sun.COM 		lcp->data[2].ui = attr->value.ui;
238*7836SJohn.Forte@Sun.COM 	} else {
239*7836SJohn.Forte@Sun.COM 		/* just one second before the end of the world */
240*7836SJohn.Forte@Sun.COM 		lcp->data[2].ui = INFINITY - 1;
241*7836SJohn.Forte@Sun.COM 	}
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 	return (num);
244*7836SJohn.Forte@Sun.COM }
245*7836SJohn.Forte@Sun.COM 
246*7836SJohn.Forte@Sun.COM /*
247*7836SJohn.Forte@Sun.COM  * ****************************************************************************
248*7836SJohn.Forte@Sun.COM  *
249*7836SJohn.Forte@Sun.COM  * cb_esi_portal:
250*7836SJohn.Forte@Sun.COM  *	Callback function which gets ESI port number and ESI interval
251*7836SJohn.Forte@Sun.COM  *	from a portal object.
252*7836SJohn.Forte@Sun.COM  *
253*7836SJohn.Forte@Sun.COM  * p1	- the Portal object.
254*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
255*7836SJohn.Forte@Sun.COM  * return - the ESI interval.
256*7836SJohn.Forte@Sun.COM  *
257*7836SJohn.Forte@Sun.COM  * ****************************************************************************
258*7836SJohn.Forte@Sun.COM  */
259*7836SJohn.Forte@Sun.COM static int
cb_esi_portal(void * p1,void * p2)260*7836SJohn.Forte@Sun.COM cb_esi_portal(
261*7836SJohn.Forte@Sun.COM 	void *p1,
262*7836SJohn.Forte@Sun.COM 	void *p2
263*7836SJohn.Forte@Sun.COM )
264*7836SJohn.Forte@Sun.COM {
265*7836SJohn.Forte@Sun.COM 	uint32_t intval = 0;
266*7836SJohn.Forte@Sun.COM 
267*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
268*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
269*7836SJohn.Forte@Sun.COM 
270*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip;
271*7836SJohn.Forte@Sun.COM 	uint32_t esip;
272*7836SJohn.Forte@Sun.COM 
273*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
274*7836SJohn.Forte@Sun.COM 
275*7836SJohn.Forte@Sun.COM 	if (cb_clone_attrs(p1, p2) == 0) {
276*7836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p1;
277*7836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p2;
278*7836SJohn.Forte@Sun.COM 		ip = lcp->data[1].ip;
279*7836SJohn.Forte@Sun.COM 		esip = lcp->data[2].ui;
280*7836SJohn.Forte@Sun.COM 		if (esip != 0) {
281*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PORTAL(
282*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_PORT_ATTR_ID)];
283*7836SJohn.Forte@Sun.COM 			lcp->data[0].ui = attr->value.ui;
284*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PORTAL(
285*7836SJohn.Forte@Sun.COM 			    ISNS_ESI_INTERVAL_ATTR_ID)];
286*7836SJohn.Forte@Sun.COM 			if (attr->tag != 0 && attr->value.ui != 0) {
287*7836SJohn.Forte@Sun.COM 				intval = attr->value.ui;
288*7836SJohn.Forte@Sun.COM 			} else {
289*7836SJohn.Forte@Sun.COM 				intval = DEFAULT_ESI_INTVAL;
290*7836SJohn.Forte@Sun.COM 			}
291*7836SJohn.Forte@Sun.COM 		} else {
292*7836SJohn.Forte@Sun.COM 			free(ip);
293*7836SJohn.Forte@Sun.COM 		}
294*7836SJohn.Forte@Sun.COM 	}
295*7836SJohn.Forte@Sun.COM 
296*7836SJohn.Forte@Sun.COM 	return ((int)intval);
297*7836SJohn.Forte@Sun.COM }
298*7836SJohn.Forte@Sun.COM 
299*7836SJohn.Forte@Sun.COM /*
300*7836SJohn.Forte@Sun.COM  * ****************************************************************************
301*7836SJohn.Forte@Sun.COM  *
302*7836SJohn.Forte@Sun.COM  * extract_esi_portal:
303*7836SJohn.Forte@Sun.COM  *	Extract a list of portal which have an ESI port for an Entity.
304*7836SJohn.Forte@Sun.COM  *
305*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
306*7836SJohn.Forte@Sun.COM  * intval - the ESI interval for returnning.
307*7836SJohn.Forte@Sun.COM  * return - the list of portals.
308*7836SJohn.Forte@Sun.COM  *
309*7836SJohn.Forte@Sun.COM  * ****************************************************************************
310*7836SJohn.Forte@Sun.COM  */
311*7836SJohn.Forte@Sun.COM static esi_portal_t *
extract_esi_portal(uint32_t uid,uint32_t * intval)312*7836SJohn.Forte@Sun.COM extract_esi_portal(
313*7836SJohn.Forte@Sun.COM 	uint32_t uid,
314*7836SJohn.Forte@Sun.COM 	uint32_t *intval
315*7836SJohn.Forte@Sun.COM )
316*7836SJohn.Forte@Sun.COM {
317*7836SJohn.Forte@Sun.COM 	esi_portal_t *list = NULL;
318*7836SJohn.Forte@Sun.COM 	esi_portal_t *p;
319*7836SJohn.Forte@Sun.COM 
320*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
321*7836SJohn.Forte@Sun.COM 
322*7836SJohn.Forte@Sun.COM 	uint32_t num_of_portal;
323*7836SJohn.Forte@Sun.COM 	uint32_t *portal_uids;
324*7836SJohn.Forte@Sun.COM 
325*7836SJohn.Forte@Sun.COM 	uint32_t intv;
326*7836SJohn.Forte@Sun.COM 
327*7836SJohn.Forte@Sun.COM 	/* prepare for looking up entity object */
328*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_ENTITY, uid);
329*7836SJohn.Forte@Sun.COM 	lc.data[1].ptr = NULL;
330*7836SJohn.Forte@Sun.COM 	lc.data[2].ui = INFINITY - 1;
331*7836SJohn.Forte@Sun.COM 
332*7836SJohn.Forte@Sun.COM 	/* get the array of the portal uid(s) */
333*7836SJohn.Forte@Sun.COM 	num_of_portal = (uint32_t)cache_lookup(&lc, NULL, cb_portal_uids);
334*7836SJohn.Forte@Sun.COM 	portal_uids = (uint32_t *)lc.data[1].ptr;
335*7836SJohn.Forte@Sun.COM 	*intval = lc.data[2].ui;
336*7836SJohn.Forte@Sun.COM 
337*7836SJohn.Forte@Sun.COM 	/* prepare for looking up portal object(s) */
338*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_PORTAL, 0);
339*7836SJohn.Forte@Sun.COM 	lc.id[1] = ISNS_PORTAL_IP_ADDR_ATTR_ID;
340*7836SJohn.Forte@Sun.COM 	lc.id[2] = ISNS_ESI_PORT_ATTR_ID;
341*7836SJohn.Forte@Sun.COM 	FOR_EACH_OBJS(portal_uids, num_of_portal, uid, {
342*7836SJohn.Forte@Sun.COM 		if (uid != 0) {
343*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = uid;
344*7836SJohn.Forte@Sun.COM 			intv = cache_lookup(&lc, NULL, cb_esi_portal);
345*7836SJohn.Forte@Sun.COM 			if (intv != 0) {
346*7836SJohn.Forte@Sun.COM 				p = new_esi_portal(uid,
347*7836SJohn.Forte@Sun.COM 				    (in6_addr_t *)lc.data[1].ip,
348*7836SJohn.Forte@Sun.COM 				    lc.data[0].ui, lc.data[2].ui);
349*7836SJohn.Forte@Sun.COM 				if (p != NULL) {
350*7836SJohn.Forte@Sun.COM 					p->next = list;
351*7836SJohn.Forte@Sun.COM 					list = p;
352*7836SJohn.Forte@Sun.COM 					if (*intval > intv) {
353*7836SJohn.Forte@Sun.COM 						*intval = intv;
354*7836SJohn.Forte@Sun.COM 					}
355*7836SJohn.Forte@Sun.COM 				}
356*7836SJohn.Forte@Sun.COM 			}
357*7836SJohn.Forte@Sun.COM 		}
358*7836SJohn.Forte@Sun.COM 	});
359*7836SJohn.Forte@Sun.COM 
360*7836SJohn.Forte@Sun.COM 	/* free up the portal uid array */
361*7836SJohn.Forte@Sun.COM 	free(portal_uids);
362*7836SJohn.Forte@Sun.COM 
363*7836SJohn.Forte@Sun.COM 	return (list);
364*7836SJohn.Forte@Sun.COM }
365*7836SJohn.Forte@Sun.COM 
366*7836SJohn.Forte@Sun.COM /*
367*7836SJohn.Forte@Sun.COM  * ****************************************************************************
368*7836SJohn.Forte@Sun.COM  *
369*7836SJohn.Forte@Sun.COM  * ev_add:
370*7836SJohn.Forte@Sun.COM  *	Add an ESI event.
371*7836SJohn.Forte@Sun.COM  *
372*7836SJohn.Forte@Sun.COM  * ev	- the ESI event.
373*7836SJohn.Forte@Sun.COM  * init	- 0: initialization time, otherwise not.
374*7836SJohn.Forte@Sun.COM  * return - error code.
375*7836SJohn.Forte@Sun.COM  *
376*7836SJohn.Forte@Sun.COM  * ****************************************************************************
377*7836SJohn.Forte@Sun.COM  */
378*7836SJohn.Forte@Sun.COM static int
ev_add(ev_t * ev,int init)379*7836SJohn.Forte@Sun.COM ev_add(
380*7836SJohn.Forte@Sun.COM 	ev_t *ev,
381*7836SJohn.Forte@Sun.COM 	int init
382*7836SJohn.Forte@Sun.COM )
383*7836SJohn.Forte@Sun.COM {
384*7836SJohn.Forte@Sun.COM 	uint32_t intval;
385*7836SJohn.Forte@Sun.COM 	esi_portal_t *p;
386*7836SJohn.Forte@Sun.COM 
387*7836SJohn.Forte@Sun.COM 	double rnd;
388*7836SJohn.Forte@Sun.COM 	uint32_t t = 0;
389*7836SJohn.Forte@Sun.COM 
390*7836SJohn.Forte@Sun.COM 	/* get the portal(s) which are registered for ESI monitoring */
391*7836SJohn.Forte@Sun.COM 	/* and the second interval for ESI or registration expiration */
392*7836SJohn.Forte@Sun.COM 	p = extract_esi_portal(ev->uid, &intval);
393*7836SJohn.Forte@Sun.COM 	ev->intval = intval;
394*7836SJohn.Forte@Sun.COM 	if (p != NULL) {
395*7836SJohn.Forte@Sun.COM 		ev->type = EV_ESI;
396*7836SJohn.Forte@Sun.COM 		ev->portal = p;
397*7836SJohn.Forte@Sun.COM 		/* avoid running everything at the same time */
398*7836SJohn.Forte@Sun.COM 		if (init != 0) {
399*7836SJohn.Forte@Sun.COM 			/* generate random number within range (0, 1] */
400*7836SJohn.Forte@Sun.COM 			rnd = (rand() + 1) / (double)(RAND_MAX + 1);
401*7836SJohn.Forte@Sun.COM 			t = (uint32_t)(intval * rnd);
402*7836SJohn.Forte@Sun.COM 		}
403*7836SJohn.Forte@Sun.COM 	} else {
404*7836SJohn.Forte@Sun.COM 		/* no portal is registered for ESI monitoring, make */
405*7836SJohn.Forte@Sun.COM 		/* an entry for entity registration expiration */
406*7836SJohn.Forte@Sun.COM 		ev->type = EV_REG_EXP;
407*7836SJohn.Forte@Sun.COM 		ev->portal = NULL;
408*7836SJohn.Forte@Sun.COM 		if (init != 0) {
409*7836SJohn.Forte@Sun.COM 			t = intval;
410*7836SJohn.Forte@Sun.COM 		}
411*7836SJohn.Forte@Sun.COM 	}
412*7836SJohn.Forte@Sun.COM 
413*7836SJohn.Forte@Sun.COM 	/* schedule the event */
414*7836SJohn.Forte@Sun.COM 	return (el_add(ev, t, NULL));
415*7836SJohn.Forte@Sun.COM }
416*7836SJohn.Forte@Sun.COM 
417*7836SJohn.Forte@Sun.COM /*
418*7836SJohn.Forte@Sun.COM  * global functions.
419*7836SJohn.Forte@Sun.COM  */
420*7836SJohn.Forte@Sun.COM 
421*7836SJohn.Forte@Sun.COM /*
422*7836SJohn.Forte@Sun.COM  * ****************************************************************************
423*7836SJohn.Forte@Sun.COM  *
424*7836SJohn.Forte@Sun.COM  * sigalrm:
425*7836SJohn.Forte@Sun.COM  *	The signal handler for SIGALRM, the ESI proc uses the SIGALRM
426*7836SJohn.Forte@Sun.COM  *	for waking up to perform the client status inquery.
427*7836SJohn.Forte@Sun.COM  *
428*7836SJohn.Forte@Sun.COM  * sig	- the signal.
429*7836SJohn.Forte@Sun.COM  *
430*7836SJohn.Forte@Sun.COM  * ****************************************************************************
431*7836SJohn.Forte@Sun.COM  */
432*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
433*7836SJohn.Forte@Sun.COM void
sigalrm(int sig)434*7836SJohn.Forte@Sun.COM sigalrm(
435*7836SJohn.Forte@Sun.COM 	int sig
436*7836SJohn.Forte@Sun.COM )
437*7836SJohn.Forte@Sun.COM {
438*7836SJohn.Forte@Sun.COM 	/* wake up the idle */
439*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&idl_mtx);
440*7836SJohn.Forte@Sun.COM 	wakeup = 1; /* wake up naturally */
441*7836SJohn.Forte@Sun.COM 	(void) pthread_cond_signal(&idl_cond);
442*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&idl_mtx);
443*7836SJohn.Forte@Sun.COM }
444*7836SJohn.Forte@Sun.COM 
445*7836SJohn.Forte@Sun.COM /*
446*7836SJohn.Forte@Sun.COM  * ****************************************************************************
447*7836SJohn.Forte@Sun.COM  *
448*7836SJohn.Forte@Sun.COM  * esi_load:
449*7836SJohn.Forte@Sun.COM  *	Load an ESI event from data store.
450*7836SJohn.Forte@Sun.COM  *
451*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
452*7836SJohn.Forte@Sun.COM  * eid	- the Entity object name.
453*7836SJohn.Forte@Sun.COM  * len	- the length of the name.
454*7836SJohn.Forte@Sun.COM  * return - error code.
455*7836SJohn.Forte@Sun.COM  *
456*7836SJohn.Forte@Sun.COM  * ****************************************************************************
457*7836SJohn.Forte@Sun.COM  */
458*7836SJohn.Forte@Sun.COM int
esi_load(uint32_t uid,uchar_t * eid,uint32_t len)459*7836SJohn.Forte@Sun.COM esi_load(
460*7836SJohn.Forte@Sun.COM 	uint32_t uid,
461*7836SJohn.Forte@Sun.COM 	uchar_t *eid,
462*7836SJohn.Forte@Sun.COM 	uint32_t len
463*7836SJohn.Forte@Sun.COM )
464*7836SJohn.Forte@Sun.COM {
465*7836SJohn.Forte@Sun.COM 	int ec = 0;
466*7836SJohn.Forte@Sun.COM 
467*7836SJohn.Forte@Sun.COM 	/* make a new event */
468*7836SJohn.Forte@Sun.COM 	ev_t *ev = ev_new(uid, eid, len);
469*7836SJohn.Forte@Sun.COM 
470*7836SJohn.Forte@Sun.COM 	/* put the new event to the list */
471*7836SJohn.Forte@Sun.COM 	if (ev != NULL) {
472*7836SJohn.Forte@Sun.COM 		ev->next = ev_list;
473*7836SJohn.Forte@Sun.COM 		ev_list = ev;
474*7836SJohn.Forte@Sun.COM 	} else {
475*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
476*7836SJohn.Forte@Sun.COM 	}
477*7836SJohn.Forte@Sun.COM 
478*7836SJohn.Forte@Sun.COM 	return (ec);
479*7836SJohn.Forte@Sun.COM }
480*7836SJohn.Forte@Sun.COM 
481*7836SJohn.Forte@Sun.COM /*
482*7836SJohn.Forte@Sun.COM  * ****************************************************************************
483*7836SJohn.Forte@Sun.COM  *
484*7836SJohn.Forte@Sun.COM  * verify_esi_portal:
485*7836SJohn.Forte@Sun.COM  *	Verify ESI port and add the ESI entries after the ESI are loaded.
486*7836SJohn.Forte@Sun.COM  *
487*7836SJohn.Forte@Sun.COM  * return - error code.
488*7836SJohn.Forte@Sun.COM  *
489*7836SJohn.Forte@Sun.COM  * ****************************************************************************
490*7836SJohn.Forte@Sun.COM  */
491*7836SJohn.Forte@Sun.COM int
verify_esi_portal()492*7836SJohn.Forte@Sun.COM verify_esi_portal(
493*7836SJohn.Forte@Sun.COM )
494*7836SJohn.Forte@Sun.COM {
495*7836SJohn.Forte@Sun.COM 	int ec = 0;
496*7836SJohn.Forte@Sun.COM 
497*7836SJohn.Forte@Sun.COM 	ev_t *ev;
498*7836SJohn.Forte@Sun.COM 
499*7836SJohn.Forte@Sun.COM 	/* add each event from the list */
500*7836SJohn.Forte@Sun.COM 	while (ev_list != NULL && ec == 0) {
501*7836SJohn.Forte@Sun.COM 		ev = ev_list;
502*7836SJohn.Forte@Sun.COM 		ev_list = ev->next;
503*7836SJohn.Forte@Sun.COM 		ev->next = NULL;
504*7836SJohn.Forte@Sun.COM 		ec = ev_add(ev, 1);
505*7836SJohn.Forte@Sun.COM 	}
506*7836SJohn.Forte@Sun.COM 
507*7836SJohn.Forte@Sun.COM 	return (ec);
508*7836SJohn.Forte@Sun.COM }
509*7836SJohn.Forte@Sun.COM 
510*7836SJohn.Forte@Sun.COM /*
511*7836SJohn.Forte@Sun.COM  * ****************************************************************************
512*7836SJohn.Forte@Sun.COM  *
513*7836SJohn.Forte@Sun.COM  * esi_add:
514*7836SJohn.Forte@Sun.COM  *	Add a new ESI event when a new Entity is registered.
515*7836SJohn.Forte@Sun.COM  *
516*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
517*7836SJohn.Forte@Sun.COM  * eid	- the Entity object name.
518*7836SJohn.Forte@Sun.COM  * len	- the length of the name.
519*7836SJohn.Forte@Sun.COM  * return - error code.
520*7836SJohn.Forte@Sun.COM  *
521*7836SJohn.Forte@Sun.COM  * ****************************************************************************
522*7836SJohn.Forte@Sun.COM  */
523*7836SJohn.Forte@Sun.COM int
esi_add(uint32_t uid,uchar_t * eid,uint32_t len)524*7836SJohn.Forte@Sun.COM esi_add(
525*7836SJohn.Forte@Sun.COM 	uint32_t uid,
526*7836SJohn.Forte@Sun.COM 	uchar_t *eid,
527*7836SJohn.Forte@Sun.COM 	uint32_t len
528*7836SJohn.Forte@Sun.COM )
529*7836SJohn.Forte@Sun.COM {
530*7836SJohn.Forte@Sun.COM 	int ec = 0;
531*7836SJohn.Forte@Sun.COM 
532*7836SJohn.Forte@Sun.COM 	/* make a new event */
533*7836SJohn.Forte@Sun.COM 	ev_t *ev = ev_new(uid, eid, len);
534*7836SJohn.Forte@Sun.COM 
535*7836SJohn.Forte@Sun.COM 	if (ev != NULL) {
536*7836SJohn.Forte@Sun.COM 		/* interrupt idle */
537*7836SJohn.Forte@Sun.COM 		ev->flags |= EV_FLAG_WAKEUP;
538*7836SJohn.Forte@Sun.COM 		ec = ev_add(ev, 0);
539*7836SJohn.Forte@Sun.COM 	} else {
540*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
541*7836SJohn.Forte@Sun.COM 	}
542*7836SJohn.Forte@Sun.COM 
543*7836SJohn.Forte@Sun.COM 	return (ec);
544*7836SJohn.Forte@Sun.COM }
545*7836SJohn.Forte@Sun.COM 
546*7836SJohn.Forte@Sun.COM /*
547*7836SJohn.Forte@Sun.COM  * ****************************************************************************
548*7836SJohn.Forte@Sun.COM  *
549*7836SJohn.Forte@Sun.COM  * esi_remove:
550*7836SJohn.Forte@Sun.COM  *	Remove an ESI event immediately.
551*7836SJohn.Forte@Sun.COM  *
552*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
553*7836SJohn.Forte@Sun.COM  * return - always successful.
554*7836SJohn.Forte@Sun.COM  *
555*7836SJohn.Forte@Sun.COM  * ****************************************************************************
556*7836SJohn.Forte@Sun.COM  */
557*7836SJohn.Forte@Sun.COM int
esi_remove(uint32_t uid)558*7836SJohn.Forte@Sun.COM esi_remove(
559*7836SJohn.Forte@Sun.COM 	uint32_t uid
560*7836SJohn.Forte@Sun.COM )
561*7836SJohn.Forte@Sun.COM {
562*7836SJohn.Forte@Sun.COM 	(void) el_remove(uid, 0, 0);
563*7836SJohn.Forte@Sun.COM 
564*7836SJohn.Forte@Sun.COM 	return (0);
565*7836SJohn.Forte@Sun.COM }
566*7836SJohn.Forte@Sun.COM 
567*7836SJohn.Forte@Sun.COM /*
568*7836SJohn.Forte@Sun.COM  * ****************************************************************************
569*7836SJohn.Forte@Sun.COM  *
570*7836SJohn.Forte@Sun.COM  * esi_remove_obj:
571*7836SJohn.Forte@Sun.COM  *	Update an ESI event when a Entity object or a Portal object is
572*7836SJohn.Forte@Sun.COM  *	removed from server. If the object is being removed because of
573*7836SJohn.Forte@Sun.COM  *	ESI failure, the ESI event will be removed with a pending time,
574*7836SJohn.Forte@Sun.COM  *	otherwise, the ESI will be removed immediately.
575*7836SJohn.Forte@Sun.COM  *
576*7836SJohn.Forte@Sun.COM  * obj	- the object being removed.
577*7836SJohn.Forte@Sun.COM  * pending - the pending flag.
578*7836SJohn.Forte@Sun.COM  * return - always successful.
579*7836SJohn.Forte@Sun.COM  *
580*7836SJohn.Forte@Sun.COM  * ****************************************************************************
581*7836SJohn.Forte@Sun.COM  */
582*7836SJohn.Forte@Sun.COM int
esi_remove_obj(const isns_obj_t * obj,int pending)583*7836SJohn.Forte@Sun.COM esi_remove_obj(
584*7836SJohn.Forte@Sun.COM 	const isns_obj_t *obj,
585*7836SJohn.Forte@Sun.COM 	int pending
586*7836SJohn.Forte@Sun.COM )
587*7836SJohn.Forte@Sun.COM {
588*7836SJohn.Forte@Sun.COM 	uint32_t puid, uid;
589*7836SJohn.Forte@Sun.COM 
590*7836SJohn.Forte@Sun.COM 	switch (obj->type) {
591*7836SJohn.Forte@Sun.COM 	case OBJ_PORTAL:
592*7836SJohn.Forte@Sun.COM 		puid = get_parent_uid(obj);
593*7836SJohn.Forte@Sun.COM 		uid = get_obj_uid(obj);
594*7836SJohn.Forte@Sun.COM 		break;
595*7836SJohn.Forte@Sun.COM 	case OBJ_ENTITY:
596*7836SJohn.Forte@Sun.COM 		puid = get_obj_uid(obj);
597*7836SJohn.Forte@Sun.COM 		uid = 0;
598*7836SJohn.Forte@Sun.COM 		break;
599*7836SJohn.Forte@Sun.COM 	default:
600*7836SJohn.Forte@Sun.COM 		puid = 0;
601*7836SJohn.Forte@Sun.COM 		break;
602*7836SJohn.Forte@Sun.COM 	}
603*7836SJohn.Forte@Sun.COM 
604*7836SJohn.Forte@Sun.COM 	if (puid != 0) {
605*7836SJohn.Forte@Sun.COM 		(void) el_remove(puid, uid, pending);
606*7836SJohn.Forte@Sun.COM 	}
607*7836SJohn.Forte@Sun.COM 
608*7836SJohn.Forte@Sun.COM 	return (0);
609*7836SJohn.Forte@Sun.COM }
610*7836SJohn.Forte@Sun.COM 
611*7836SJohn.Forte@Sun.COM /*
612*7836SJohn.Forte@Sun.COM  * ****************************************************************************
613*7836SJohn.Forte@Sun.COM  *
614*7836SJohn.Forte@Sun.COM  * get_stopwatch:
615*7836SJohn.Forte@Sun.COM  *	Get the stopwatch. It might need to signal the condition to
616*7836SJohn.Forte@Sun.COM  *	wake up the idle so the stopwatch gets updated.
617*7836SJohn.Forte@Sun.COM  *
618*7836SJohn.Forte@Sun.COM  * flag	- wake up flag.
619*7836SJohn.Forte@Sun.COM  * return - the stopwatch.
620*7836SJohn.Forte@Sun.COM  *
621*7836SJohn.Forte@Sun.COM  * ****************************************************************************
622*7836SJohn.Forte@Sun.COM  */
623*7836SJohn.Forte@Sun.COM uint32_t
get_stopwatch(int flag)624*7836SJohn.Forte@Sun.COM get_stopwatch(
625*7836SJohn.Forte@Sun.COM 	int flag
626*7836SJohn.Forte@Sun.COM )
627*7836SJohn.Forte@Sun.COM {
628*7836SJohn.Forte@Sun.COM 	uint32_t t;
629*7836SJohn.Forte@Sun.COM 
630*7836SJohn.Forte@Sun.COM 	/* not re-schedule, wake up idle */
631*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&idl_mtx);
632*7836SJohn.Forte@Sun.COM 	if (flag != 0) {
633*7836SJohn.Forte@Sun.COM 		wakeup = 2; /* wake up manually */
634*7836SJohn.Forte@Sun.COM 		(void) pthread_cond_signal(&idl_cond);
635*7836SJohn.Forte@Sun.COM 	} else {
636*7836SJohn.Forte@Sun.COM 		wakeup = 0; /* clear previous interruption */
637*7836SJohn.Forte@Sun.COM 	}
638*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&idl_mtx);
639*7836SJohn.Forte@Sun.COM 
640*7836SJohn.Forte@Sun.COM 	/* get most current time */
641*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&stw_mtx);
642*7836SJohn.Forte@Sun.COM 	t = stopwatch;
643*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&stw_mtx);
644*7836SJohn.Forte@Sun.COM 
645*7836SJohn.Forte@Sun.COM 	return (t);
646*7836SJohn.Forte@Sun.COM }
647*7836SJohn.Forte@Sun.COM 
648*7836SJohn.Forte@Sun.COM /*
649*7836SJohn.Forte@Sun.COM  * ****************************************************************************
650*7836SJohn.Forte@Sun.COM  *
651*7836SJohn.Forte@Sun.COM  * ev_intval:
652*7836SJohn.Forte@Sun.COM  *	Get the time interval of an ESI event.
653*7836SJohn.Forte@Sun.COM  *
654*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
655*7836SJohn.Forte@Sun.COM  * return - the time interval.
656*7836SJohn.Forte@Sun.COM  *
657*7836SJohn.Forte@Sun.COM  * ****************************************************************************
658*7836SJohn.Forte@Sun.COM  */
659*7836SJohn.Forte@Sun.COM uint32_t
ev_intval(void * p)660*7836SJohn.Forte@Sun.COM ev_intval(
661*7836SJohn.Forte@Sun.COM 	void *p
662*7836SJohn.Forte@Sun.COM )
663*7836SJohn.Forte@Sun.COM {
664*7836SJohn.Forte@Sun.COM 	return (((ev_t *)p)->intval);
665*7836SJohn.Forte@Sun.COM }
666*7836SJohn.Forte@Sun.COM 
667*7836SJohn.Forte@Sun.COM /*
668*7836SJohn.Forte@Sun.COM  * ****************************************************************************
669*7836SJohn.Forte@Sun.COM  *
670*7836SJohn.Forte@Sun.COM  * ev_match:
671*7836SJohn.Forte@Sun.COM  *	Check the ESI event maching an Entity object.
672*7836SJohn.Forte@Sun.COM  *
673*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
674*7836SJohn.Forte@Sun.COM  * uid	- the Entity object UID.
675*7836SJohn.Forte@Sun.COM  * return - 1: match, otherwise not.
676*7836SJohn.Forte@Sun.COM  *
677*7836SJohn.Forte@Sun.COM  * ****************************************************************************
678*7836SJohn.Forte@Sun.COM  */
679*7836SJohn.Forte@Sun.COM int
ev_match(void * p,uint32_t uid)680*7836SJohn.Forte@Sun.COM ev_match(
681*7836SJohn.Forte@Sun.COM 	void *p,
682*7836SJohn.Forte@Sun.COM 	uint32_t uid
683*7836SJohn.Forte@Sun.COM )
684*7836SJohn.Forte@Sun.COM {
685*7836SJohn.Forte@Sun.COM 	if (((ev_t *)p)->uid == uid) {
686*7836SJohn.Forte@Sun.COM 		return (1);
687*7836SJohn.Forte@Sun.COM 	} else {
688*7836SJohn.Forte@Sun.COM 		return (0);
689*7836SJohn.Forte@Sun.COM 	}
690*7836SJohn.Forte@Sun.COM }
691*7836SJohn.Forte@Sun.COM 
692*7836SJohn.Forte@Sun.COM /*
693*7836SJohn.Forte@Sun.COM  * ****************************************************************************
694*7836SJohn.Forte@Sun.COM  *
695*7836SJohn.Forte@Sun.COM  * ev_remove:
696*7836SJohn.Forte@Sun.COM  *	Remove a portal or an ESI event. If all of ESI portal has been
697*7836SJohn.Forte@Sun.COM  *	removed, the ESI event will be marked as removal pending, which
698*7836SJohn.Forte@Sun.COM  *	will result in removing the Entity object after the pending time.
699*7836SJohn.Forte@Sun.COM  *
700*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
701*7836SJohn.Forte@Sun.COM  * portal_uid	- the Portal object UID.
702*7836SJohn.Forte@Sun.COM  * flag	- 0: the ESI is currently in use, otherwise it is scheduled.
703*7836SJohn.Forte@Sun.COM  * pending	- flag for the ESI removal pending.
704*7836SJohn.Forte@Sun.COM  * return - 0: the ESI is physically removed, otherwise not.
705*7836SJohn.Forte@Sun.COM  *
706*7836SJohn.Forte@Sun.COM  * ****************************************************************************
707*7836SJohn.Forte@Sun.COM  */
708*7836SJohn.Forte@Sun.COM int
ev_remove(void * p,uint32_t portal_uid,int flag,int pending)709*7836SJohn.Forte@Sun.COM ev_remove(
710*7836SJohn.Forte@Sun.COM 	void *p,
711*7836SJohn.Forte@Sun.COM 	uint32_t portal_uid,
712*7836SJohn.Forte@Sun.COM 	int flag,
713*7836SJohn.Forte@Sun.COM 	int pending
714*7836SJohn.Forte@Sun.COM )
715*7836SJohn.Forte@Sun.COM {
716*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)p;
717*7836SJohn.Forte@Sun.COM 	esi_portal_t **pp, *portal;
718*7836SJohn.Forte@Sun.COM 
719*7836SJohn.Forte@Sun.COM 	int has_portal = 0;
720*7836SJohn.Forte@Sun.COM 	int state;
721*7836SJohn.Forte@Sun.COM 
722*7836SJohn.Forte@Sun.COM 	/* remove one portal only */
723*7836SJohn.Forte@Sun.COM 	if (portal_uid != 0) {
724*7836SJohn.Forte@Sun.COM 		pp = &ev->portal;
725*7836SJohn.Forte@Sun.COM 		portal = *pp;
726*7836SJohn.Forte@Sun.COM 		while (portal != NULL) {
727*7836SJohn.Forte@Sun.COM 			/* found the match portal */
728*7836SJohn.Forte@Sun.COM 			if (portal->ref == portal_uid) {
729*7836SJohn.Forte@Sun.COM 				/* mark it as removed */
730*7836SJohn.Forte@Sun.COM 				portal->ref = 0;
731*7836SJohn.Forte@Sun.COM 				if (flag != 0) {
732*7836SJohn.Forte@Sun.COM 					/* not in use, remove it physically */
733*7836SJohn.Forte@Sun.COM 					*pp = portal->next;
734*7836SJohn.Forte@Sun.COM 					portal->next = NULL;
735*7836SJohn.Forte@Sun.COM 					free_esi_portal(portal);
736*7836SJohn.Forte@Sun.COM 				} else {
737*7836SJohn.Forte@Sun.COM 					pp = &portal->next;
738*7836SJohn.Forte@Sun.COM 				}
739*7836SJohn.Forte@Sun.COM 			} else {
740*7836SJohn.Forte@Sun.COM 				/* one or more esi portals are available */
741*7836SJohn.Forte@Sun.COM 				if (portal->ref != 0) {
742*7836SJohn.Forte@Sun.COM 					has_portal = 1;
743*7836SJohn.Forte@Sun.COM 				}
744*7836SJohn.Forte@Sun.COM 				pp = &portal->next;
745*7836SJohn.Forte@Sun.COM 			}
746*7836SJohn.Forte@Sun.COM 			portal = *pp;
747*7836SJohn.Forte@Sun.COM 		}
748*7836SJohn.Forte@Sun.COM 	}
749*7836SJohn.Forte@Sun.COM 
750*7836SJohn.Forte@Sun.COM 	/* no portal available */
751*7836SJohn.Forte@Sun.COM 	if (has_portal == 0) {
752*7836SJohn.Forte@Sun.COM 		state = (pending << 1) | flag;
753*7836SJohn.Forte@Sun.COM 		switch (state) {
754*7836SJohn.Forte@Sun.COM 		case 0x0:
755*7836SJohn.Forte@Sun.COM 			/* mark the event as removed */
756*7836SJohn.Forte@Sun.COM 			ev->flags |= EV_FLAG_REMOVE;
757*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "ev_remove",
758*7836SJohn.Forte@Sun.COM 			    "%s [%d] is marked as removed.",
759*7836SJohn.Forte@Sun.COM 			    ev->type == EV_ESI ? "ESI" : "REG_EXP",
760*7836SJohn.Forte@Sun.COM 			    ev->uid);
761*7836SJohn.Forte@Sun.COM 			break;
762*7836SJohn.Forte@Sun.COM 		case 0x1:
763*7836SJohn.Forte@Sun.COM 			/* physically remove the event */
764*7836SJohn.Forte@Sun.COM 			ev_free(ev);
765*7836SJohn.Forte@Sun.COM 			break;
766*7836SJohn.Forte@Sun.COM 		case 0x2:
767*7836SJohn.Forte@Sun.COM 		case 0x3:
768*7836SJohn.Forte@Sun.COM 			/* mark the event as removal pending */
769*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "ev_remove",
770*7836SJohn.Forte@Sun.COM 			    "%s [%d] is marked as removal pending.",
771*7836SJohn.Forte@Sun.COM 			    ev->type == EV_ESI ? "ESI" : "REG_EXP",
772*7836SJohn.Forte@Sun.COM 			    ev->uid);
773*7836SJohn.Forte@Sun.COM 			ev->flags |= EV_FLAG_REM_P1;
774*7836SJohn.Forte@Sun.COM 			has_portal = 1;
775*7836SJohn.Forte@Sun.COM 			break;
776*7836SJohn.Forte@Sun.COM 		default:
777*7836SJohn.Forte@Sun.COM 			break;
778*7836SJohn.Forte@Sun.COM 		}
779*7836SJohn.Forte@Sun.COM 	} else {
780*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "ev_remove", "%s [%d] removed portal %d.",
781*7836SJohn.Forte@Sun.COM 		    ev->type == EV_ESI ? "ESI" : "REG_EXP",
782*7836SJohn.Forte@Sun.COM 		    ev->uid, portal_uid);
783*7836SJohn.Forte@Sun.COM 	}
784*7836SJohn.Forte@Sun.COM 
785*7836SJohn.Forte@Sun.COM 	return (has_portal);
786*7836SJohn.Forte@Sun.COM }
787*7836SJohn.Forte@Sun.COM 
788*7836SJohn.Forte@Sun.COM /*
789*7836SJohn.Forte@Sun.COM  * ****************************************************************************
790*7836SJohn.Forte@Sun.COM  *
791*7836SJohn.Forte@Sun.COM  * ev_free:
792*7836SJohn.Forte@Sun.COM  *	Free an ESI event.
793*7836SJohn.Forte@Sun.COM  *
794*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
795*7836SJohn.Forte@Sun.COM  *
796*7836SJohn.Forte@Sun.COM  * ****************************************************************************
797*7836SJohn.Forte@Sun.COM  */
798*7836SJohn.Forte@Sun.COM void
ev_free(void * p)799*7836SJohn.Forte@Sun.COM ev_free(
800*7836SJohn.Forte@Sun.COM 	void *p
801*7836SJohn.Forte@Sun.COM )
802*7836SJohn.Forte@Sun.COM {
803*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)p;
804*7836SJohn.Forte@Sun.COM 
805*7836SJohn.Forte@Sun.COM 	/* free up all of portals */
806*7836SJohn.Forte@Sun.COM 	free_esi_portal(ev->portal);
807*7836SJohn.Forte@Sun.COM 
808*7836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "ev_free",
809*7836SJohn.Forte@Sun.COM 	    "%s [%d] is physically removed.",
810*7836SJohn.Forte@Sun.COM 	    ev->type == EV_ESI ? "ESI" : "REG_EXP",
811*7836SJohn.Forte@Sun.COM 	    ev->uid);
812*7836SJohn.Forte@Sun.COM 
813*7836SJohn.Forte@Sun.COM 	free(ev->eid);
814*7836SJohn.Forte@Sun.COM 
815*7836SJohn.Forte@Sun.COM 	/* free the event */
816*7836SJohn.Forte@Sun.COM 	free(ev);
817*7836SJohn.Forte@Sun.COM }
818*7836SJohn.Forte@Sun.COM 
819*7836SJohn.Forte@Sun.COM /*
820*7836SJohn.Forte@Sun.COM  * ****************************************************************************
821*7836SJohn.Forte@Sun.COM  *
822*7836SJohn.Forte@Sun.COM  * evf_init:
823*7836SJohn.Forte@Sun.COM  *	Check the initial flag of an ESI event.
824*7836SJohn.Forte@Sun.COM  *
825*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
826*7836SJohn.Forte@Sun.COM  * return - 0: not initial, otherwise yes.
827*7836SJohn.Forte@Sun.COM  *
828*7836SJohn.Forte@Sun.COM  * ****************************************************************************
829*7836SJohn.Forte@Sun.COM  */
830*7836SJohn.Forte@Sun.COM int
evf_init(void * p)831*7836SJohn.Forte@Sun.COM evf_init(
832*7836SJohn.Forte@Sun.COM 	void *p
833*7836SJohn.Forte@Sun.COM )
834*7836SJohn.Forte@Sun.COM {
835*7836SJohn.Forte@Sun.COM 	return (((ev_t *)p)->flags & EV_FLAG_INIT);
836*7836SJohn.Forte@Sun.COM }
837*7836SJohn.Forte@Sun.COM 
838*7836SJohn.Forte@Sun.COM /*
839*7836SJohn.Forte@Sun.COM  * ****************************************************************************
840*7836SJohn.Forte@Sun.COM  *
841*7836SJohn.Forte@Sun.COM  * evf_again:
842*7836SJohn.Forte@Sun.COM  *	Check the again flag of an ESI event.
843*7836SJohn.Forte@Sun.COM  *	(this flag might be eliminated and use the init flag.)
844*7836SJohn.Forte@Sun.COM  *
845*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
846*7836SJohn.Forte@Sun.COM  * return - 0: not again, otherwise yes.
847*7836SJohn.Forte@Sun.COM  *
848*7836SJohn.Forte@Sun.COM  * ****************************************************************************
849*7836SJohn.Forte@Sun.COM  */
850*7836SJohn.Forte@Sun.COM int
evf_again(void * p)851*7836SJohn.Forte@Sun.COM evf_again(
852*7836SJohn.Forte@Sun.COM 	void *p
853*7836SJohn.Forte@Sun.COM )
854*7836SJohn.Forte@Sun.COM {
855*7836SJohn.Forte@Sun.COM 	return (((ev_t *)p)->flags & EV_FLAG_AGAIN);
856*7836SJohn.Forte@Sun.COM }
857*7836SJohn.Forte@Sun.COM 
858*7836SJohn.Forte@Sun.COM /*
859*7836SJohn.Forte@Sun.COM  * ****************************************************************************
860*7836SJohn.Forte@Sun.COM  *
861*7836SJohn.Forte@Sun.COM  * evf_wakeup:
862*7836SJohn.Forte@Sun.COM  *	Check the wakeup flag of an ESI event. The idle might need to
863*7836SJohn.Forte@Sun.COM  *	wake up before the event is scheduled.
864*7836SJohn.Forte@Sun.COM  *
865*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
866*7836SJohn.Forte@Sun.COM  * return - 0: no wakeup, otherwise yes.
867*7836SJohn.Forte@Sun.COM  *
868*7836SJohn.Forte@Sun.COM  * ****************************************************************************
869*7836SJohn.Forte@Sun.COM  */
870*7836SJohn.Forte@Sun.COM int
evf_wakeup(void * p)871*7836SJohn.Forte@Sun.COM evf_wakeup(
872*7836SJohn.Forte@Sun.COM 	void *p
873*7836SJohn.Forte@Sun.COM )
874*7836SJohn.Forte@Sun.COM {
875*7836SJohn.Forte@Sun.COM 	return (((ev_t *)p)->flags & EV_FLAG_WAKEUP);
876*7836SJohn.Forte@Sun.COM }
877*7836SJohn.Forte@Sun.COM 
878*7836SJohn.Forte@Sun.COM /*
879*7836SJohn.Forte@Sun.COM  * ****************************************************************************
880*7836SJohn.Forte@Sun.COM  *
881*7836SJohn.Forte@Sun.COM  * evf_rem:
882*7836SJohn.Forte@Sun.COM  *	Check the removal flag of an ESI event. The ESI entry might be
883*7836SJohn.Forte@Sun.COM  *	marked as removal.
884*7836SJohn.Forte@Sun.COM  *
885*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
886*7836SJohn.Forte@Sun.COM  * return - 0: not removed, otherwise yes.
887*7836SJohn.Forte@Sun.COM  *
888*7836SJohn.Forte@Sun.COM  * ****************************************************************************
889*7836SJohn.Forte@Sun.COM  */
890*7836SJohn.Forte@Sun.COM int
evf_rem(void * p)891*7836SJohn.Forte@Sun.COM evf_rem(
892*7836SJohn.Forte@Sun.COM 	void *p
893*7836SJohn.Forte@Sun.COM )
894*7836SJohn.Forte@Sun.COM {
895*7836SJohn.Forte@Sun.COM 	return (((ev_t *)p)->flags & EV_FLAG_REMOVE);
896*7836SJohn.Forte@Sun.COM }
897*7836SJohn.Forte@Sun.COM 
898*7836SJohn.Forte@Sun.COM /*
899*7836SJohn.Forte@Sun.COM  * ****************************************************************************
900*7836SJohn.Forte@Sun.COM  *
901*7836SJohn.Forte@Sun.COM  * evf_rem_pending:
902*7836SJohn.Forte@Sun.COM  *	Check the removal pending flag of an ESI event. The ESI entry
903*7836SJohn.Forte@Sun.COM  *	might be marked as removal pending. If it is, we will switch the
904*7836SJohn.Forte@Sun.COM  *	event type and change the time interval.
905*7836SJohn.Forte@Sun.COM  *
906*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
907*7836SJohn.Forte@Sun.COM  * return - 0: not removal pending, otherwise yes.
908*7836SJohn.Forte@Sun.COM  *
909*7836SJohn.Forte@Sun.COM  * ****************************************************************************
910*7836SJohn.Forte@Sun.COM  */
911*7836SJohn.Forte@Sun.COM int
evf_rem_pending(void * p)912*7836SJohn.Forte@Sun.COM evf_rem_pending(
913*7836SJohn.Forte@Sun.COM 	void *p
914*7836SJohn.Forte@Sun.COM )
915*7836SJohn.Forte@Sun.COM {
916*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)p;
917*7836SJohn.Forte@Sun.COM 	if ((ev->flags & EV_FLAG_REM_P) != 0) {
918*7836SJohn.Forte@Sun.COM 		if (ev->type != EV_REG_EXP) {
919*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "ev_rem_pending",
920*7836SJohn.Forte@Sun.COM 			    "%s [%d] is changed to REG_EXP.",
921*7836SJohn.Forte@Sun.COM 			    ev->type == EV_ESI ? "ESI" : "REG_EXP",
922*7836SJohn.Forte@Sun.COM 			    ev->uid);
923*7836SJohn.Forte@Sun.COM 			ev->type = EV_REG_EXP;
924*7836SJohn.Forte@Sun.COM 			ev->intval *= 2; /* after 2 ESI interval */
925*7836SJohn.Forte@Sun.COM 		}
926*7836SJohn.Forte@Sun.COM 		return (1);
927*7836SJohn.Forte@Sun.COM 	}
928*7836SJohn.Forte@Sun.COM 
929*7836SJohn.Forte@Sun.COM 	return (0);
930*7836SJohn.Forte@Sun.COM }
931*7836SJohn.Forte@Sun.COM 
932*7836SJohn.Forte@Sun.COM /*
933*7836SJohn.Forte@Sun.COM  * ****************************************************************************
934*7836SJohn.Forte@Sun.COM  *
935*7836SJohn.Forte@Sun.COM  * evf_zero:
936*7836SJohn.Forte@Sun.COM  *	Reset the event flag.
937*7836SJohn.Forte@Sun.COM  *
938*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
939*7836SJohn.Forte@Sun.COM  *
940*7836SJohn.Forte@Sun.COM  * ****************************************************************************
941*7836SJohn.Forte@Sun.COM  */
942*7836SJohn.Forte@Sun.COM void
evf_zero(void * p)943*7836SJohn.Forte@Sun.COM evf_zero(
944*7836SJohn.Forte@Sun.COM 	void *p
945*7836SJohn.Forte@Sun.COM )
946*7836SJohn.Forte@Sun.COM {
947*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)p;
948*7836SJohn.Forte@Sun.COM 
949*7836SJohn.Forte@Sun.COM 	/* not acutally clear it, need to set again flag */
950*7836SJohn.Forte@Sun.COM 	/* and keep the removal pending flag */
951*7836SJohn.Forte@Sun.COM 	ev->flags = EV_FLAG_AGAIN | (ev->flags & EV_FLAG_REM_P);
952*7836SJohn.Forte@Sun.COM }
953*7836SJohn.Forte@Sun.COM 
954*7836SJohn.Forte@Sun.COM /*
955*7836SJohn.Forte@Sun.COM  * ****************************************************************************
956*7836SJohn.Forte@Sun.COM  *
957*7836SJohn.Forte@Sun.COM  * evl_append:
958*7836SJohn.Forte@Sun.COM  *	Append an ESI event to the list, the list contains all of
959*7836SJohn.Forte@Sun.COM  *	ESI events which are being processed at present.
960*7836SJohn.Forte@Sun.COM  *
961*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
962*7836SJohn.Forte@Sun.COM  *
963*7836SJohn.Forte@Sun.COM  * ****************************************************************************
964*7836SJohn.Forte@Sun.COM  */
965*7836SJohn.Forte@Sun.COM void
evl_append(void * p)966*7836SJohn.Forte@Sun.COM evl_append(
967*7836SJohn.Forte@Sun.COM 	void *p
968*7836SJohn.Forte@Sun.COM )
969*7836SJohn.Forte@Sun.COM {
970*7836SJohn.Forte@Sun.COM 	ev_t *ev;
971*7836SJohn.Forte@Sun.COM 
972*7836SJohn.Forte@Sun.COM 	ev = (ev_t *)p;
973*7836SJohn.Forte@Sun.COM 	ev->next = ev_list;
974*7836SJohn.Forte@Sun.COM 	ev_list = ev;
975*7836SJohn.Forte@Sun.COM }
976*7836SJohn.Forte@Sun.COM 
977*7836SJohn.Forte@Sun.COM /*
978*7836SJohn.Forte@Sun.COM  * ****************************************************************************
979*7836SJohn.Forte@Sun.COM  *
980*7836SJohn.Forte@Sun.COM  * evl_strip:
981*7836SJohn.Forte@Sun.COM  *	Strip off an ESI event from the list after the event is being
982*7836SJohn.Forte@Sun.COM  *	processed, it will be scheduled in the scheduler.
983*7836SJohn.Forte@Sun.COM  *
984*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
985*7836SJohn.Forte@Sun.COM  *
986*7836SJohn.Forte@Sun.COM  * ****************************************************************************
987*7836SJohn.Forte@Sun.COM  */
988*7836SJohn.Forte@Sun.COM void
evl_strip(void * p)989*7836SJohn.Forte@Sun.COM evl_strip(
990*7836SJohn.Forte@Sun.COM 	void *p
991*7836SJohn.Forte@Sun.COM )
992*7836SJohn.Forte@Sun.COM {
993*7836SJohn.Forte@Sun.COM 	ev_t **evp = &ev_list;
994*7836SJohn.Forte@Sun.COM 	ev_t *ev = *evp;
995*7836SJohn.Forte@Sun.COM 
996*7836SJohn.Forte@Sun.COM 	while (ev != NULL) {
997*7836SJohn.Forte@Sun.COM 		if (ev == p) {
998*7836SJohn.Forte@Sun.COM 			*evp = ev->next;
999*7836SJohn.Forte@Sun.COM 			break;
1000*7836SJohn.Forte@Sun.COM 		}
1001*7836SJohn.Forte@Sun.COM 		evp = &ev->next;
1002*7836SJohn.Forte@Sun.COM 		ev = *evp;
1003*7836SJohn.Forte@Sun.COM 	}
1004*7836SJohn.Forte@Sun.COM }
1005*7836SJohn.Forte@Sun.COM 
1006*7836SJohn.Forte@Sun.COM /*
1007*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1008*7836SJohn.Forte@Sun.COM  *
1009*7836SJohn.Forte@Sun.COM  * evl_remove:
1010*7836SJohn.Forte@Sun.COM  *	Remove an ESI event or a portal of an ESI event from the event list.
1011*7836SJohn.Forte@Sun.COM  *
1012*7836SJohn.Forte@Sun.COM  * id1	- the Entity object UID.
1013*7836SJohn.Forte@Sun.COM  * id2	- the Portal object UID.
1014*7836SJohn.Forte@Sun.COM  * pending - the pending flag.
1015*7836SJohn.Forte@Sun.COM  * return - 1: found a match event, otherwise not.
1016*7836SJohn.Forte@Sun.COM  *
1017*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1018*7836SJohn.Forte@Sun.COM  */
1019*7836SJohn.Forte@Sun.COM int
evl_remove(uint32_t id1,uint32_t id2,int pending)1020*7836SJohn.Forte@Sun.COM evl_remove(
1021*7836SJohn.Forte@Sun.COM 	uint32_t id1,
1022*7836SJohn.Forte@Sun.COM 	uint32_t id2,
1023*7836SJohn.Forte@Sun.COM 	int pending
1024*7836SJohn.Forte@Sun.COM )
1025*7836SJohn.Forte@Sun.COM {
1026*7836SJohn.Forte@Sun.COM 	ev_t *ev = ev_list;
1027*7836SJohn.Forte@Sun.COM 
1028*7836SJohn.Forte@Sun.COM 	while (ev != NULL) {
1029*7836SJohn.Forte@Sun.COM 		/* found it */
1030*7836SJohn.Forte@Sun.COM 		if (ev_match(ev, id1) != 0) {
1031*7836SJohn.Forte@Sun.COM 			/* lock the event */
1032*7836SJohn.Forte@Sun.COM 			(void) pthread_mutex_lock(&ev->mtx);
1033*7836SJohn.Forte@Sun.COM 			/* mark it as removed */
1034*7836SJohn.Forte@Sun.COM 			(void) ev_remove(ev, id2, 0, pending);
1035*7836SJohn.Forte@Sun.COM 			/* unlock the event */
1036*7836SJohn.Forte@Sun.COM 			(void) pthread_mutex_unlock(&ev->mtx);
1037*7836SJohn.Forte@Sun.COM 			/* tell caller removal is done */
1038*7836SJohn.Forte@Sun.COM 			return (1);
1039*7836SJohn.Forte@Sun.COM 		}
1040*7836SJohn.Forte@Sun.COM 		ev = ev->next;
1041*7836SJohn.Forte@Sun.COM 	}
1042*7836SJohn.Forte@Sun.COM 
1043*7836SJohn.Forte@Sun.COM 	/* not found it */
1044*7836SJohn.Forte@Sun.COM 	return (0);
1045*7836SJohn.Forte@Sun.COM }
1046*7836SJohn.Forte@Sun.COM 
1047*7836SJohn.Forte@Sun.COM #define	ALARM_MAX	(21427200)
1048*7836SJohn.Forte@Sun.COM 
1049*7836SJohn.Forte@Sun.COM /*
1050*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1051*7836SJohn.Forte@Sun.COM  *
1052*7836SJohn.Forte@Sun.COM  * idle:
1053*7836SJohn.Forte@Sun.COM  *	Idle for certain amount of time or a wakeup signal is recieved.
1054*7836SJohn.Forte@Sun.COM  *
1055*7836SJohn.Forte@Sun.COM  * t	- the idle time.
1056*7836SJohn.Forte@Sun.COM  * return - the time that idle left.
1057*7836SJohn.Forte@Sun.COM  *
1058*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1059*7836SJohn.Forte@Sun.COM  */
1060*7836SJohn.Forte@Sun.COM static int
idle(uint32_t t)1061*7836SJohn.Forte@Sun.COM idle(
1062*7836SJohn.Forte@Sun.COM 	uint32_t t
1063*7836SJohn.Forte@Sun.COM )
1064*7836SJohn.Forte@Sun.COM {
1065*7836SJohn.Forte@Sun.COM 	uint32_t t1, t2, t3 = 0;
1066*7836SJohn.Forte@Sun.COM 	int idl_int = 0;
1067*7836SJohn.Forte@Sun.COM 
1068*7836SJohn.Forte@Sun.COM 	/* hold the mutex for stopwatch update */
1069*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&stw_mtx);
1070*7836SJohn.Forte@Sun.COM 
1071*7836SJohn.Forte@Sun.COM 	do {
1072*7836SJohn.Forte@Sun.COM 		if (t > ALARM_MAX) {
1073*7836SJohn.Forte@Sun.COM 			t1 = ALARM_MAX;
1074*7836SJohn.Forte@Sun.COM 		} else {
1075*7836SJohn.Forte@Sun.COM 			t1 = t;
1076*7836SJohn.Forte@Sun.COM 		}
1077*7836SJohn.Forte@Sun.COM 
1078*7836SJohn.Forte@Sun.COM 		/* start alarm */
1079*7836SJohn.Forte@Sun.COM 		(void) alarm(t1);
1080*7836SJohn.Forte@Sun.COM 
1081*7836SJohn.Forte@Sun.COM 		/* hold the mutex for idle condition */
1082*7836SJohn.Forte@Sun.COM 		(void) pthread_mutex_lock(&idl_mtx);
1083*7836SJohn.Forte@Sun.COM 
1084*7836SJohn.Forte@Sun.COM 		/* wait on condition variable to wake up idle */
1085*7836SJohn.Forte@Sun.COM 		while (wakeup == 0) {
1086*7836SJohn.Forte@Sun.COM 			(void) pthread_cond_wait(&idl_cond, &idl_mtx);
1087*7836SJohn.Forte@Sun.COM 		}
1088*7836SJohn.Forte@Sun.COM 		if (wakeup == 2) {
1089*7836SJohn.Forte@Sun.COM 			idl_int = 1;
1090*7836SJohn.Forte@Sun.COM 		}
1091*7836SJohn.Forte@Sun.COM 		/* clean wakeup flag */
1092*7836SJohn.Forte@Sun.COM 		wakeup = 0;
1093*7836SJohn.Forte@Sun.COM 
1094*7836SJohn.Forte@Sun.COM 		/* release the mutex for idle condition */
1095*7836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&idl_mtx);
1096*7836SJohn.Forte@Sun.COM 
1097*7836SJohn.Forte@Sun.COM 		/* stop alarm */
1098*7836SJohn.Forte@Sun.COM 		t2 = alarm(0);
1099*7836SJohn.Forte@Sun.COM 
1100*7836SJohn.Forte@Sun.COM 		/* seconds actually slept */
1101*7836SJohn.Forte@Sun.COM 		t3 += t1 - t2;
1102*7836SJohn.Forte@Sun.COM 		t -= t3;
1103*7836SJohn.Forte@Sun.COM 	} while (t > 0 && idl_int == 0);
1104*7836SJohn.Forte@Sun.COM 
1105*7836SJohn.Forte@Sun.COM 	/* increate the stopwatch by the actually slept time */
1106*7836SJohn.Forte@Sun.COM 	stopwatch += t3;
1107*7836SJohn.Forte@Sun.COM 
1108*7836SJohn.Forte@Sun.COM 	/* release the mutex after stopwatch is updated */
1109*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&stw_mtx);
1110*7836SJohn.Forte@Sun.COM 
1111*7836SJohn.Forte@Sun.COM 	/* return the amount of time which is not slept */
1112*7836SJohn.Forte@Sun.COM 	return (t);
1113*7836SJohn.Forte@Sun.COM }
1114*7836SJohn.Forte@Sun.COM 
1115*7836SJohn.Forte@Sun.COM /*
1116*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1117*7836SJohn.Forte@Sun.COM  *
1118*7836SJohn.Forte@Sun.COM  * ev_ex:
1119*7836SJohn.Forte@Sun.COM  *	Execute an event. To inquiry the client status or
1120*7836SJohn.Forte@Sun.COM  *	perform registration expiration.
1121*7836SJohn.Forte@Sun.COM  *
1122*7836SJohn.Forte@Sun.COM  * ev	- the event.
1123*7836SJohn.Forte@Sun.COM  *
1124*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1125*7836SJohn.Forte@Sun.COM  */
1126*7836SJohn.Forte@Sun.COM static void
ev_ex(ev_t * ev)1127*7836SJohn.Forte@Sun.COM ev_ex(
1128*7836SJohn.Forte@Sun.COM 	ev_t *ev
1129*7836SJohn.Forte@Sun.COM )
1130*7836SJohn.Forte@Sun.COM {
1131*7836SJohn.Forte@Sun.COM 	pthread_t tid;
1132*7836SJohn.Forte@Sun.COM 
1133*7836SJohn.Forte@Sun.COM 	switch (ev->type) {
1134*7836SJohn.Forte@Sun.COM 	case EV_ESI:
1135*7836SJohn.Forte@Sun.COM 		if (pthread_create(&tid, NULL,
1136*7836SJohn.Forte@Sun.COM 		    esi_monitor, (void *)ev) != 0) {
1137*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "ev_ex", "pthread_create() failed.");
1138*7836SJohn.Forte@Sun.COM 			/* reschedule for next occurence */
1139*7836SJohn.Forte@Sun.COM 			(void) el_add(ev, 0, NULL);
1140*7836SJohn.Forte@Sun.COM 		} else {
1141*7836SJohn.Forte@Sun.COM 			/* increase the thread ref count */
1142*7836SJohn.Forte@Sun.COM 			inc_thr_count();
1143*7836SJohn.Forte@Sun.COM 		}
1144*7836SJohn.Forte@Sun.COM 		break;
1145*7836SJohn.Forte@Sun.COM 	case EV_REG_EXP:
1146*7836SJohn.Forte@Sun.COM 		(void) queue_msg_set(sys_q, REG_EXP, (void *)ev);
1147*7836SJohn.Forte@Sun.COM 		break;
1148*7836SJohn.Forte@Sun.COM 	default:
1149*7836SJohn.Forte@Sun.COM 		break;
1150*7836SJohn.Forte@Sun.COM 	}
1151*7836SJohn.Forte@Sun.COM }
1152*7836SJohn.Forte@Sun.COM 
1153*7836SJohn.Forte@Sun.COM /*
1154*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1155*7836SJohn.Forte@Sun.COM  *
1156*7836SJohn.Forte@Sun.COM  * esi_proc:
1157*7836SJohn.Forte@Sun.COM  *	ESI thread entry, which:
1158*7836SJohn.Forte@Sun.COM  *	1: fetch an event from schedule,
1159*7836SJohn.Forte@Sun.COM  *	2: idle for some time,
1160*7836SJohn.Forte@Sun.COM  *	3: execute the event or re-schedule it,
1161*7836SJohn.Forte@Sun.COM  *	4: repeat from step 1 before server is being shutdown.
1162*7836SJohn.Forte@Sun.COM  *
1163*7836SJohn.Forte@Sun.COM  * arg	- the thread argument.
1164*7836SJohn.Forte@Sun.COM  *
1165*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1166*7836SJohn.Forte@Sun.COM  */
1167*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
1168*7836SJohn.Forte@Sun.COM void *
esi_proc(void * arg)1169*7836SJohn.Forte@Sun.COM esi_proc(
1170*7836SJohn.Forte@Sun.COM 	void *arg
1171*7836SJohn.Forte@Sun.COM )
1172*7836SJohn.Forte@Sun.COM {
1173*7836SJohn.Forte@Sun.COM 	uint32_t t, t1, pt;
1174*7836SJohn.Forte@Sun.COM 	ev_t *ev;
1175*7836SJohn.Forte@Sun.COM 
1176*7836SJohn.Forte@Sun.COM 	void *evp;
1177*7836SJohn.Forte@Sun.COM 
1178*7836SJohn.Forte@Sun.COM 	while (time_to_exit == B_FALSE) {
1179*7836SJohn.Forte@Sun.COM 		ev = (ev_t *)el_first(&pt);
1180*7836SJohn.Forte@Sun.COM 
1181*7836SJohn.Forte@Sun.COM 		/* caculate the idle time */
1182*7836SJohn.Forte@Sun.COM 		if (ev != NULL) {
1183*7836SJohn.Forte@Sun.COM 			if (pt > stopwatch) {
1184*7836SJohn.Forte@Sun.COM 				t = pt - stopwatch;
1185*7836SJohn.Forte@Sun.COM 			} else {
1186*7836SJohn.Forte@Sun.COM 				t = 0;
1187*7836SJohn.Forte@Sun.COM 			}
1188*7836SJohn.Forte@Sun.COM 		} else {
1189*7836SJohn.Forte@Sun.COM 			t = INFINITY;
1190*7836SJohn.Forte@Sun.COM 		}
1191*7836SJohn.Forte@Sun.COM 
1192*7836SJohn.Forte@Sun.COM 		do {
1193*7836SJohn.Forte@Sun.COM 			/* block for a certain amount of time */
1194*7836SJohn.Forte@Sun.COM 			if (t > 0) {
1195*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "esi_proc",
1196*7836SJohn.Forte@Sun.COM 				    "idle for %d seconds.", t);
1197*7836SJohn.Forte@Sun.COM 				t1 = idle(t);
1198*7836SJohn.Forte@Sun.COM 			} else {
1199*7836SJohn.Forte@Sun.COM 				t1 = 0;
1200*7836SJohn.Forte@Sun.COM 			}
1201*7836SJohn.Forte@Sun.COM 			if (t1 > 0) {
1202*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "esi_proc",
1203*7836SJohn.Forte@Sun.COM 				    "idle interrupted after idle for "
1204*7836SJohn.Forte@Sun.COM 				    "%d seconds.", t - t1);
1205*7836SJohn.Forte@Sun.COM 			}
1206*7836SJohn.Forte@Sun.COM 			if (time_to_exit != B_FALSE) {
1207*7836SJohn.Forte@Sun.COM 				ev = NULL; /* force break */
1208*7836SJohn.Forte@Sun.COM 			} else if (ev != NULL) {
1209*7836SJohn.Forte@Sun.COM 				if (t1 > 0) {
1210*7836SJohn.Forte@Sun.COM 					/* not naturally waken up */
1211*7836SJohn.Forte@Sun.COM 					/* reschedule current event */
1212*7836SJohn.Forte@Sun.COM 					evp = NULL;
1213*7836SJohn.Forte@Sun.COM 					(void) el_add(ev, pt, &evp);
1214*7836SJohn.Forte@Sun.COM 					ev = (ev_t *)evp;
1215*7836SJohn.Forte@Sun.COM 					t = t1;
1216*7836SJohn.Forte@Sun.COM 				} else {
1217*7836SJohn.Forte@Sun.COM 					/* excute */
1218*7836SJohn.Forte@Sun.COM 					isnslog(LOG_DEBUG, "esi_proc",
1219*7836SJohn.Forte@Sun.COM 					    "excute the cron job[%d].",
1220*7836SJohn.Forte@Sun.COM 					    ev->uid);
1221*7836SJohn.Forte@Sun.COM 					ev_ex(ev);
1222*7836SJohn.Forte@Sun.COM 					ev = NULL;
1223*7836SJohn.Forte@Sun.COM 				}
1224*7836SJohn.Forte@Sun.COM 			}
1225*7836SJohn.Forte@Sun.COM 		} while (ev != NULL);
1226*7836SJohn.Forte@Sun.COM 	}
1227*7836SJohn.Forte@Sun.COM 
1228*7836SJohn.Forte@Sun.COM 	return (NULL);
1229*7836SJohn.Forte@Sun.COM }
1230*7836SJohn.Forte@Sun.COM 
1231*7836SJohn.Forte@Sun.COM /*
1232*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1233*7836SJohn.Forte@Sun.COM  *
1234*7836SJohn.Forte@Sun.COM  * esi_ping:
1235*7836SJohn.Forte@Sun.COM  *	Ping the client with the ESI retry threshold for status inquiry.
1236*7836SJohn.Forte@Sun.COM  *
1237*7836SJohn.Forte@Sun.COM  * so	- the socket descriptor.
1238*7836SJohn.Forte@Sun.COM  * pdu	- the ESI packet.
1239*7836SJohn.Forte@Sun.COM  * pl	- the length of packet.
1240*7836SJohn.Forte@Sun.COM  * return - 1: status inquired, otherwise not.
1241*7836SJohn.Forte@Sun.COM  *
1242*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1243*7836SJohn.Forte@Sun.COM  */
1244*7836SJohn.Forte@Sun.COM static int
esi_ping(int so,isns_pdu_t * pdu,size_t pl)1245*7836SJohn.Forte@Sun.COM esi_ping(
1246*7836SJohn.Forte@Sun.COM 	int so,
1247*7836SJohn.Forte@Sun.COM 	isns_pdu_t *pdu,
1248*7836SJohn.Forte@Sun.COM 	size_t pl
1249*7836SJohn.Forte@Sun.COM )
1250*7836SJohn.Forte@Sun.COM {
1251*7836SJohn.Forte@Sun.COM 	int try_cnt = 0;
1252*7836SJohn.Forte@Sun.COM 	isns_pdu_t *rsp = NULL;
1253*7836SJohn.Forte@Sun.COM 	size_t rsp_sz;
1254*7836SJohn.Forte@Sun.COM 
1255*7836SJohn.Forte@Sun.COM 	int alive = 0;
1256*7836SJohn.Forte@Sun.COM 
1257*7836SJohn.Forte@Sun.COM 	do {
1258*7836SJohn.Forte@Sun.COM 		if (isns_send_pdu(so, pdu, pl) == 0) {
1259*7836SJohn.Forte@Sun.COM 			if (isns_rcv_pdu(so, &rsp, &rsp_sz,
1260*7836SJohn.Forte@Sun.COM 			    ISNS_RCV_SHORT_TIMEOUT) > 0) {
1261*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1262*7836SJohn.Forte@Sun.COM 				dump_pdu1(rsp);
1263*7836SJohn.Forte@Sun.COM #endif
1264*7836SJohn.Forte@Sun.COM 				alive = 1;
1265*7836SJohn.Forte@Sun.COM 				break;
1266*7836SJohn.Forte@Sun.COM 			}
1267*7836SJohn.Forte@Sun.COM 		} else {
1268*7836SJohn.Forte@Sun.COM 			/* retry after 1 second */
1269*7836SJohn.Forte@Sun.COM 			(void) sleep(1);
1270*7836SJohn.Forte@Sun.COM 		}
1271*7836SJohn.Forte@Sun.COM 		try_cnt ++;
1272*7836SJohn.Forte@Sun.COM 	} while (try_cnt < esi_threshold);
1273*7836SJohn.Forte@Sun.COM 
1274*7836SJohn.Forte@Sun.COM 	if (rsp != NULL) {
1275*7836SJohn.Forte@Sun.COM 		free(rsp);
1276*7836SJohn.Forte@Sun.COM 	}
1277*7836SJohn.Forte@Sun.COM 
1278*7836SJohn.Forte@Sun.COM 	return (alive);
1279*7836SJohn.Forte@Sun.COM }
1280*7836SJohn.Forte@Sun.COM 
1281*7836SJohn.Forte@Sun.COM /*
1282*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1283*7836SJohn.Forte@Sun.COM  *
1284*7836SJohn.Forte@Sun.COM  * esi_monitor:
1285*7836SJohn.Forte@Sun.COM  *	Child thread for client status mornitoring.
1286*7836SJohn.Forte@Sun.COM  *
1287*7836SJohn.Forte@Sun.COM  * arg	- the ESI event.
1288*7836SJohn.Forte@Sun.COM  *
1289*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1290*7836SJohn.Forte@Sun.COM  */
1291*7836SJohn.Forte@Sun.COM static void *
esi_monitor(void * arg)1292*7836SJohn.Forte@Sun.COM esi_monitor(
1293*7836SJohn.Forte@Sun.COM 	void *arg
1294*7836SJohn.Forte@Sun.COM )
1295*7836SJohn.Forte@Sun.COM {
1296*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)arg;
1297*7836SJohn.Forte@Sun.COM 
1298*7836SJohn.Forte@Sun.COM 	esi_portal_t *p;
1299*7836SJohn.Forte@Sun.COM 	int so;
1300*7836SJohn.Forte@Sun.COM 
1301*7836SJohn.Forte@Sun.COM 	isns_pdu_t *pdu = NULL;
1302*7836SJohn.Forte@Sun.COM 	size_t sz;
1303*7836SJohn.Forte@Sun.COM 	size_t pl;
1304*7836SJohn.Forte@Sun.COM 	size_t half;
1305*7836SJohn.Forte@Sun.COM 
1306*7836SJohn.Forte@Sun.COM 	time_t t;
1307*7836SJohn.Forte@Sun.COM 
1308*7836SJohn.Forte@Sun.COM 	int feedback;
1309*7836SJohn.Forte@Sun.COM 
1310*7836SJohn.Forte@Sun.COM 	/* lock the event for esi monitoring */
1311*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&ev->mtx);
1312*7836SJohn.Forte@Sun.COM 
1313*7836SJohn.Forte@Sun.COM 	if (evf_rem(ev) != 0) {
1314*7836SJohn.Forte@Sun.COM 		goto mon_done;
1315*7836SJohn.Forte@Sun.COM 	} else if (evf_rem_pending(ev) != 0) {
1316*7836SJohn.Forte@Sun.COM 		goto mon_done;
1317*7836SJohn.Forte@Sun.COM 	}
1318*7836SJohn.Forte@Sun.COM 
1319*7836SJohn.Forte@Sun.COM 	/* timestamp */
1320*7836SJohn.Forte@Sun.COM 	t = time(NULL);
1321*7836SJohn.Forte@Sun.COM 
1322*7836SJohn.Forte@Sun.COM 	/* allocate ESI PDU */
1323*7836SJohn.Forte@Sun.COM 	if (pdu_reset_esi(&pdu, &pl, &sz) != 0 ||
1324*7836SJohn.Forte@Sun.COM 	    pdu_add_tlv(&pdu, &pl, &sz,
1325*7836SJohn.Forte@Sun.COM 	    ISNS_TIMESTAMP_ATTR_ID, 8, (void *)&t, 1) != 0 ||
1326*7836SJohn.Forte@Sun.COM 	    pdu_add_tlv(&pdu, &pl, &sz,
1327*7836SJohn.Forte@Sun.COM 	    ISNS_EID_ATTR_ID, ev->eid_len, (void *)ev->eid, 0) != 0) {
1328*7836SJohn.Forte@Sun.COM 		/* no memory, will retry later */
1329*7836SJohn.Forte@Sun.COM 		goto mon_done;
1330*7836SJohn.Forte@Sun.COM 	}
1331*7836SJohn.Forte@Sun.COM 
1332*7836SJohn.Forte@Sun.COM 	/* set pdu head */
1333*7836SJohn.Forte@Sun.COM 	pdu->version = htons((uint16_t)ISNSP_VERSION);
1334*7836SJohn.Forte@Sun.COM 	pdu->func_id = htons((uint16_t)ISNS_ESI);
1335*7836SJohn.Forte@Sun.COM 	pdu->xid = htons(get_server_xid());
1336*7836SJohn.Forte@Sun.COM 
1337*7836SJohn.Forte@Sun.COM 	/* keep the current lenght of the playload */
1338*7836SJohn.Forte@Sun.COM 	half = pl;
1339*7836SJohn.Forte@Sun.COM 
1340*7836SJohn.Forte@Sun.COM 	p = ev->portal;
1341*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
1342*7836SJohn.Forte@Sun.COM 		if (p->ref != 0 &&
1343*7836SJohn.Forte@Sun.COM 		    /* skip IPv6 portal */
1344*7836SJohn.Forte@Sun.COM 		    p->sz != sizeof (in6_addr_t) &&
1345*7836SJohn.Forte@Sun.COM 		    pdu_add_tlv(&pdu, &pl, &sz,
1346*7836SJohn.Forte@Sun.COM 		    ISNS_PORTAL_IP_ADDR_ATTR_ID,
1347*7836SJohn.Forte@Sun.COM 		    sizeof (in6_addr_t), (void *)p->ip6, 0) == 0 &&
1348*7836SJohn.Forte@Sun.COM 		    pdu_add_tlv(&pdu, &pl, &sz,
1349*7836SJohn.Forte@Sun.COM 		    ISNS_PORTAL_PORT_ATTR_ID,
1350*7836SJohn.Forte@Sun.COM 		    4, (void *)p->port, 0) == 0) {
1351*7836SJohn.Forte@Sun.COM 			/* connect once */
1352*7836SJohn.Forte@Sun.COM 			so = connect_to(p->sz, p->ip4, p->ip6, p->esip);
1353*7836SJohn.Forte@Sun.COM 			if (so != -1) {
1354*7836SJohn.Forte@Sun.COM 				feedback = esi_ping(so, pdu, pl);
1355*7836SJohn.Forte@Sun.COM 				(void) close(so);
1356*7836SJohn.Forte@Sun.COM 				/* p->so = so; */
1357*7836SJohn.Forte@Sun.COM 			} else {
1358*7836SJohn.Forte@Sun.COM 				/* cannot connect, portal is dead */
1359*7836SJohn.Forte@Sun.COM 				feedback = 0;
1360*7836SJohn.Forte@Sun.COM 			}
1361*7836SJohn.Forte@Sun.COM 			if (feedback == 0) {
1362*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "esi_monitor",
1363*7836SJohn.Forte@Sun.COM 				    "ESI ping failed.");
1364*7836SJohn.Forte@Sun.COM 				(void) queue_msg_set(sys_q, DEAD_PORTAL,
1365*7836SJohn.Forte@Sun.COM 				    (void *)p->ref);
1366*7836SJohn.Forte@Sun.COM 			} else {
1367*7836SJohn.Forte@Sun.COM 				goto mon_done;
1368*7836SJohn.Forte@Sun.COM 			}
1369*7836SJohn.Forte@Sun.COM 		}
1370*7836SJohn.Forte@Sun.COM 		pl = half;
1371*7836SJohn.Forte@Sun.COM 		p = p->next;
1372*7836SJohn.Forte@Sun.COM 	}
1373*7836SJohn.Forte@Sun.COM 
1374*7836SJohn.Forte@Sun.COM mon_done:
1375*7836SJohn.Forte@Sun.COM 	/* unlock the event after esi monitoring is done */
1376*7836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&ev->mtx);
1377*7836SJohn.Forte@Sun.COM 
1378*7836SJohn.Forte@Sun.COM 	/* clean up pdu */
1379*7836SJohn.Forte@Sun.COM 	if (pdu != NULL) {
1380*7836SJohn.Forte@Sun.COM 		free(pdu);
1381*7836SJohn.Forte@Sun.COM 	}
1382*7836SJohn.Forte@Sun.COM 
1383*7836SJohn.Forte@Sun.COM 	/* set reschedule flags */
1384*7836SJohn.Forte@Sun.COM 	ev->flags |= EV_FLAG_WAKEUP;
1385*7836SJohn.Forte@Sun.COM 
1386*7836SJohn.Forte@Sun.COM 	/* reschedule for next occurence */
1387*7836SJohn.Forte@Sun.COM 	(void) el_add(ev, 0, NULL);
1388*7836SJohn.Forte@Sun.COM 
1389*7836SJohn.Forte@Sun.COM 	/* decrease the thread ref count */
1390*7836SJohn.Forte@Sun.COM 	dec_thr_count();
1391*7836SJohn.Forte@Sun.COM 
1392*7836SJohn.Forte@Sun.COM 	return (NULL);
1393*7836SJohn.Forte@Sun.COM }
1394*7836SJohn.Forte@Sun.COM 
1395*7836SJohn.Forte@Sun.COM /*
1396*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1397*7836SJohn.Forte@Sun.COM  *
1398*7836SJohn.Forte@Sun.COM  * portal_dies:
1399*7836SJohn.Forte@Sun.COM  *	Handles the dead portal that ESI detected.
1400*7836SJohn.Forte@Sun.COM  *
1401*7836SJohn.Forte@Sun.COM  * uid	- the Portal object UID.
1402*7836SJohn.Forte@Sun.COM  *
1403*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1404*7836SJohn.Forte@Sun.COM  */
1405*7836SJohn.Forte@Sun.COM void
portal_dies(uint32_t uid)1406*7836SJohn.Forte@Sun.COM portal_dies(
1407*7836SJohn.Forte@Sun.COM 	uint32_t uid
1408*7836SJohn.Forte@Sun.COM )
1409*7836SJohn.Forte@Sun.COM {
1410*7836SJohn.Forte@Sun.COM 	int ec = 0;
1411*7836SJohn.Forte@Sun.COM 
1412*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1413*7836SJohn.Forte@Sun.COM 
1414*7836SJohn.Forte@Sun.COM 	/* prepare the lookup control for deregistration */
1415*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_PORTAL, uid);
1416*7836SJohn.Forte@Sun.COM 
1417*7836SJohn.Forte@Sun.COM 	/* lock the cache for object deregistration */
1418*7836SJohn.Forte@Sun.COM 	(void) cache_lock_write();
1419*7836SJohn.Forte@Sun.COM 
1420*7836SJohn.Forte@Sun.COM 	/* deregister the portal */
1421*7836SJohn.Forte@Sun.COM 	ec = dereg_object(&lc, 1);
1422*7836SJohn.Forte@Sun.COM 
1423*7836SJohn.Forte@Sun.COM 	/* unlock cache and sync with data store */
1424*7836SJohn.Forte@Sun.COM 	(void) cache_unlock_sync(ec);
1425*7836SJohn.Forte@Sun.COM }
1426*7836SJohn.Forte@Sun.COM 
1427*7836SJohn.Forte@Sun.COM /*
1428*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1429*7836SJohn.Forte@Sun.COM  *
1430*7836SJohn.Forte@Sun.COM  * portal_dies:
1431*7836SJohn.Forte@Sun.COM  *	Handles the Entity registration expiration.
1432*7836SJohn.Forte@Sun.COM  *
1433*7836SJohn.Forte@Sun.COM  * p	- the ESI event.
1434*7836SJohn.Forte@Sun.COM  *
1435*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1436*7836SJohn.Forte@Sun.COM  */
1437*7836SJohn.Forte@Sun.COM void
reg_expiring(void * p)1438*7836SJohn.Forte@Sun.COM reg_expiring(
1439*7836SJohn.Forte@Sun.COM 	void *p
1440*7836SJohn.Forte@Sun.COM )
1441*7836SJohn.Forte@Sun.COM {
1442*7836SJohn.Forte@Sun.COM 	int ec = 0;
1443*7836SJohn.Forte@Sun.COM 	ev_t *ev = (ev_t *)p;
1444*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1445*7836SJohn.Forte@Sun.COM 
1446*7836SJohn.Forte@Sun.COM 	/* prepare the lookup control for deregistration */
1447*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_ENTITY, ev->uid);
1448*7836SJohn.Forte@Sun.COM 
1449*7836SJohn.Forte@Sun.COM 	/* lock the cache for object deregistration */
1450*7836SJohn.Forte@Sun.COM 	(void) cache_lock_write();
1451*7836SJohn.Forte@Sun.COM 
1452*7836SJohn.Forte@Sun.COM 	if (evf_rem(ev) == 0) {
1453*7836SJohn.Forte@Sun.COM 		/* deregister the entity */
1454*7836SJohn.Forte@Sun.COM 		ec = dereg_object(&lc, 0);
1455*7836SJohn.Forte@Sun.COM 
1456*7836SJohn.Forte@Sun.COM 		/* unlock cache and sync with data store */
1457*7836SJohn.Forte@Sun.COM 		ec = cache_unlock_sync(ec);
1458*7836SJohn.Forte@Sun.COM 
1459*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
1460*7836SJohn.Forte@Sun.COM 			/* successfuk, mark ev as removed */
1461*7836SJohn.Forte@Sun.COM 			ev->flags |= EV_FLAG_REMOVE;
1462*7836SJohn.Forte@Sun.COM 		} else {
1463*7836SJohn.Forte@Sun.COM 			/* failed, retry after 3 mintues */
1464*7836SJohn.Forte@Sun.COM 			ev->intval = 3 * 60;
1465*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "reg_expiring",
1466*7836SJohn.Forte@Sun.COM 			    "dereg failed, retry after 3 mintues.");
1467*7836SJohn.Forte@Sun.COM 		}
1468*7836SJohn.Forte@Sun.COM 	} else {
1469*7836SJohn.Forte@Sun.COM 		/* ev is marked as removed, no need to dereg */
1470*7836SJohn.Forte@Sun.COM 		(void) cache_unlock_nosync();
1471*7836SJohn.Forte@Sun.COM 	}
1472*7836SJohn.Forte@Sun.COM 
1473*7836SJohn.Forte@Sun.COM 	/* reschedule it for next occurence */
1474*7836SJohn.Forte@Sun.COM 	(void) el_add(ev, 0, NULL);
1475*7836SJohn.Forte@Sun.COM }
1476