10dc974a9SCathy Zhou /* 20dc974a9SCathy Zhou * CDDL HEADER START 30dc974a9SCathy Zhou * 40dc974a9SCathy Zhou * The contents of this file are subject to the terms of the 50dc974a9SCathy Zhou * Common Development and Distribution License (the "License"). 60dc974a9SCathy Zhou * You may not use this file except in compliance with the License. 70dc974a9SCathy Zhou * 80dc974a9SCathy Zhou * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90dc974a9SCathy Zhou * or http://www.opensolaris.org/os/licensing. 100dc974a9SCathy Zhou * See the License for the specific language governing permissions 110dc974a9SCathy Zhou * and limitations under the License. 120dc974a9SCathy Zhou * 130dc974a9SCathy Zhou * When distributing Covered Code, include this CDDL HEADER in each 140dc974a9SCathy Zhou * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150dc974a9SCathy Zhou * If applicable, add the following below this CDDL HEADER, with the 160dc974a9SCathy Zhou * fields enclosed by brackets "[]" replaced with your own identifying 170dc974a9SCathy Zhou * information: Portions Copyright [yyyy] [name of copyright owner] 180dc974a9SCathy Zhou * 190dc974a9SCathy Zhou * CDDL HEADER END 200dc974a9SCathy Zhou */ 210dc974a9SCathy Zhou /* 225093e103SCathy Zhou * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230dc974a9SCathy Zhou * Use is subject to license terms. 240dc974a9SCathy Zhou */ 250dc974a9SCathy Zhou 260dc974a9SCathy Zhou /* 270dc974a9SCathy Zhou * datalink syseventd module. 280dc974a9SCathy Zhou * 290dc974a9SCathy Zhou * The purpose of this module is to identify all datalink related events, 300dc974a9SCathy Zhou * and react accordingly. 310dc974a9SCathy Zhou */ 320dc974a9SCathy Zhou 330dc974a9SCathy Zhou #include <errno.h> 340dc974a9SCathy Zhou #include <sys/sysevent/eventdefs.h> 350dc974a9SCathy Zhou #include <string.h> 360dc974a9SCathy Zhou #include <libnvpair.h> 370dc974a9SCathy Zhou #include <librcm.h> 380dc974a9SCathy Zhou #include <libsysevent.h> 390dc974a9SCathy Zhou 40*4dc92747SCheng Sean Ye extern void syseventd_err_print(char *, ...); 41*4dc92747SCheng Sean Ye 42*4dc92747SCheng Sean Ye struct event_list { 43*4dc92747SCheng Sean Ye nvlist_t *ev; 44*4dc92747SCheng Sean Ye struct event_list *next; 45*4dc92747SCheng Sean Ye }; 46*4dc92747SCheng Sean Ye 470dc974a9SCathy Zhou static rcm_handle_t *rcm_hdl = NULL; 48*4dc92747SCheng Sean Ye static boolean_t dl_exiting; 49*4dc92747SCheng Sean Ye static thread_t dl_notify_tid; 50*4dc92747SCheng Sean Ye static mutex_t dl_mx; 51*4dc92747SCheng Sean Ye static cond_t dl_cv; 52*4dc92747SCheng Sean Ye static struct event_list *dl_events; 53*4dc92747SCheng Sean Ye 54*4dc92747SCheng Sean Ye /* ARGSUSED */ 55*4dc92747SCheng Sean Ye static void * 56*4dc92747SCheng Sean Ye datalink_notify_thread(void *arg) 57*4dc92747SCheng Sean Ye { 58*4dc92747SCheng Sean Ye struct event_list *tmp_events, *ep; 59*4dc92747SCheng Sean Ye 60*4dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 61*4dc92747SCheng Sean Ye 62*4dc92747SCheng Sean Ye while (! dl_exiting || dl_events != NULL) { 63*4dc92747SCheng Sean Ye if (dl_events == NULL) { 64*4dc92747SCheng Sean Ye (void) cond_wait(&dl_cv, &dl_mx); 65*4dc92747SCheng Sean Ye continue; 66*4dc92747SCheng Sean Ye } 67*4dc92747SCheng Sean Ye 68*4dc92747SCheng Sean Ye tmp_events = dl_events; 69*4dc92747SCheng Sean Ye dl_events = NULL; 70*4dc92747SCheng Sean Ye 71*4dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 72*4dc92747SCheng Sean Ye 73*4dc92747SCheng Sean Ye while (tmp_events != NULL) { 74*4dc92747SCheng Sean Ye /* 75*4dc92747SCheng Sean Ye * Send the PHYSLINK_NEW event to network_rcm to update 76*4dc92747SCheng Sean Ye * the network devices cache accordingly. 77*4dc92747SCheng Sean Ye */ 78*4dc92747SCheng Sean Ye if (rcm_notify_event(rcm_hdl, RCM_RESOURCE_PHYSLINK_NEW, 79*4dc92747SCheng Sean Ye 0, tmp_events->ev, NULL) != RCM_SUCCESS) 80*4dc92747SCheng Sean Ye syseventd_err_print("datalink_mod: Can not" 81*4dc92747SCheng Sean Ye "notify event: %s\n", strerror(errno)); 82*4dc92747SCheng Sean Ye 83*4dc92747SCheng Sean Ye ep = tmp_events; 84*4dc92747SCheng Sean Ye tmp_events = tmp_events->next; 85*4dc92747SCheng Sean Ye nvlist_free(ep->ev); 86*4dc92747SCheng Sean Ye free(ep); 87*4dc92747SCheng Sean Ye } 88*4dc92747SCheng Sean Ye 89*4dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 90*4dc92747SCheng Sean Ye } 91*4dc92747SCheng Sean Ye 92*4dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 93*4dc92747SCheng Sean Ye 94*4dc92747SCheng Sean Ye return (NULL); 95*4dc92747SCheng Sean Ye } 960dc974a9SCathy Zhou 970dc974a9SCathy Zhou /*ARGSUSED*/ 980dc974a9SCathy Zhou static int 990dc974a9SCathy Zhou datalink_deliver_event(sysevent_t *ev, int unused) 1000dc974a9SCathy Zhou { 1010dc974a9SCathy Zhou const char *class = sysevent_get_class_name(ev); 1020dc974a9SCathy Zhou const char *subclass = sysevent_get_subclass_name(ev); 1030dc974a9SCathy Zhou nvlist_t *nvl; 104*4dc92747SCheng Sean Ye struct event_list *newp, **elpp; 1050dc974a9SCathy Zhou 1060dc974a9SCathy Zhou if (strcmp(class, EC_DATALINK) != 0 || 1070dc974a9SCathy Zhou strcmp(subclass, ESC_DATALINK_PHYS_ADD) != 0) { 1080dc974a9SCathy Zhou return (0); 1090dc974a9SCathy Zhou } 1100dc974a9SCathy Zhou 1110dc974a9SCathy Zhou if (sysevent_get_attr_list(ev, &nvl) != 0) 1120dc974a9SCathy Zhou return (EINVAL); 1130dc974a9SCathy Zhou 1145093e103SCathy Zhou /* 115*4dc92747SCheng Sean Ye * rcm_notify_event() needs to be called asynchronously otherwise when 116*4dc92747SCheng Sean Ye * sysevent queue is full, deadlock will happen. 1175093e103SCathy Zhou */ 118*4dc92747SCheng Sean Ye if ((newp = malloc(sizeof (struct event_list))) == NULL) 119*4dc92747SCheng Sean Ye return (ENOMEM); 1200dc974a9SCathy Zhou 121*4dc92747SCheng Sean Ye newp->ev = nvl; 122*4dc92747SCheng Sean Ye newp->next = NULL; 123*4dc92747SCheng Sean Ye 124*4dc92747SCheng Sean Ye /* 125*4dc92747SCheng Sean Ye * queue up at the end of the event list and signal notify_thread to 126*4dc92747SCheng Sean Ye * process it. 127*4dc92747SCheng Sean Ye */ 128*4dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 129*4dc92747SCheng Sean Ye elpp = &dl_events; 130*4dc92747SCheng Sean Ye while (*elpp != NULL) 131*4dc92747SCheng Sean Ye elpp = &(*elpp)->next; 132*4dc92747SCheng Sean Ye *elpp = newp; 133*4dc92747SCheng Sean Ye (void) cond_signal(&dl_cv); 134*4dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 135*4dc92747SCheng Sean Ye 136*4dc92747SCheng Sean Ye return (0); 1370dc974a9SCathy Zhou } 1380dc974a9SCathy Zhou 1390dc974a9SCathy Zhou static struct slm_mod_ops datalink_mod_ops = { 1400dc974a9SCathy Zhou SE_MAJOR_VERSION, 1410dc974a9SCathy Zhou SE_MINOR_VERSION, 1420dc974a9SCathy Zhou SE_MAX_RETRY_LIMIT, 1430dc974a9SCathy Zhou datalink_deliver_event 1440dc974a9SCathy Zhou }; 1450dc974a9SCathy Zhou 1460dc974a9SCathy Zhou struct slm_mod_ops * 1470dc974a9SCathy Zhou slm_init() 1480dc974a9SCathy Zhou { 149*4dc92747SCheng Sean Ye dl_events = NULL; 150*4dc92747SCheng Sean Ye dl_exiting = B_FALSE; 151*4dc92747SCheng Sean Ye 1520dc974a9SCathy Zhou if (rcm_alloc_handle(NULL, 0, NULL, &rcm_hdl) != RCM_SUCCESS) 1530dc974a9SCathy Zhou return (NULL); 1540dc974a9SCathy Zhou 155*4dc92747SCheng Sean Ye if (thr_create(NULL, 0, datalink_notify_thread, NULL, 0, 156*4dc92747SCheng Sean Ye &dl_notify_tid) != 0) { 157*4dc92747SCheng Sean Ye (void) rcm_free_handle(rcm_hdl); 158*4dc92747SCheng Sean Ye return (NULL); 159*4dc92747SCheng Sean Ye } 160*4dc92747SCheng Sean Ye 161*4dc92747SCheng Sean Ye (void) mutex_init(&dl_mx, USYNC_THREAD, NULL); 162*4dc92747SCheng Sean Ye (void) cond_init(&dl_cv, USYNC_THREAD, NULL); 163*4dc92747SCheng Sean Ye 1640dc974a9SCathy Zhou return (&datalink_mod_ops); 1650dc974a9SCathy Zhou } 1660dc974a9SCathy Zhou 1670dc974a9SCathy Zhou void 1680dc974a9SCathy Zhou slm_fini() 1690dc974a9SCathy Zhou { 170*4dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 171*4dc92747SCheng Sean Ye dl_exiting = B_TRUE; 172*4dc92747SCheng Sean Ye (void) cond_signal(&dl_cv); 173*4dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 174*4dc92747SCheng Sean Ye (void) thr_join(dl_notify_tid, NULL, NULL); 175*4dc92747SCheng Sean Ye 176*4dc92747SCheng Sean Ye (void) mutex_destroy(&dl_mx); 177*4dc92747SCheng Sean Ye (void) cond_destroy(&dl_cv); 1780dc974a9SCathy Zhou (void) rcm_free_handle(rcm_hdl); 1790dc974a9SCathy Zhou rcm_hdl = NULL; 1800dc974a9SCathy Zhou } 181