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