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 * 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 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 * 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 * 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 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 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