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> 39*5ad1f010SStephen Hanson #include "sysevent_signal.h" 400dc974a9SCathy Zhou 414dc92747SCheng Sean Ye extern void syseventd_err_print(char *, ...); 424dc92747SCheng Sean Ye 434dc92747SCheng Sean Ye struct event_list { 444dc92747SCheng Sean Ye nvlist_t *ev; 454dc92747SCheng Sean Ye struct event_list *next; 464dc92747SCheng Sean Ye }; 474dc92747SCheng Sean Ye 480dc974a9SCathy Zhou static rcm_handle_t *rcm_hdl = NULL; 494dc92747SCheng Sean Ye static boolean_t dl_exiting; 504dc92747SCheng Sean Ye static thread_t dl_notify_tid; 514dc92747SCheng Sean Ye static mutex_t dl_mx; 524dc92747SCheng Sean Ye static cond_t dl_cv; 534dc92747SCheng Sean Ye static struct event_list *dl_events; 544dc92747SCheng Sean Ye 554dc92747SCheng Sean Ye /* ARGSUSED */ 564dc92747SCheng Sean Ye static void * 574dc92747SCheng Sean Ye datalink_notify_thread(void *arg) 584dc92747SCheng Sean Ye { 594dc92747SCheng Sean Ye struct event_list *tmp_events, *ep; 604dc92747SCheng Sean Ye 614dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 624dc92747SCheng Sean Ye 634dc92747SCheng Sean Ye while (! dl_exiting || dl_events != NULL) { 644dc92747SCheng Sean Ye if (dl_events == NULL) { 654dc92747SCheng Sean Ye (void) cond_wait(&dl_cv, &dl_mx); 664dc92747SCheng Sean Ye continue; 674dc92747SCheng Sean Ye } 684dc92747SCheng Sean Ye 694dc92747SCheng Sean Ye tmp_events = dl_events; 704dc92747SCheng Sean Ye dl_events = NULL; 714dc92747SCheng Sean Ye 724dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 734dc92747SCheng Sean Ye 744dc92747SCheng Sean Ye while (tmp_events != NULL) { 75*5ad1f010SStephen Hanson struct sigaction cbuf, dfl; 76*5ad1f010SStephen Hanson 77*5ad1f010SStephen Hanson /* 78*5ad1f010SStephen Hanson * Ignore SIGCLD for the 79*5ad1f010SStephen Hanson * duration of the rcm_notify_event call. 80*5ad1f010SStephen Hanson */ 81*5ad1f010SStephen Hanson (void) memset(&dfl, 0, sizeof (dfl)); 82*5ad1f010SStephen Hanson dfl.sa_handler = SIG_IGN; 83*5ad1f010SStephen Hanson (void) sigaction(SIGCHLD, &dfl, &cbuf); 84*5ad1f010SStephen Hanson 854dc92747SCheng Sean Ye /* 864dc92747SCheng Sean Ye * Send the PHYSLINK_NEW event to network_rcm to update 874dc92747SCheng Sean Ye * the network devices cache accordingly. 884dc92747SCheng Sean Ye */ 894dc92747SCheng Sean Ye if (rcm_notify_event(rcm_hdl, RCM_RESOURCE_PHYSLINK_NEW, 904dc92747SCheng Sean Ye 0, tmp_events->ev, NULL) != RCM_SUCCESS) 914dc92747SCheng Sean Ye syseventd_err_print("datalink_mod: Can not " 924dc92747SCheng Sean Ye "notify event: %s\n", strerror(errno)); 934dc92747SCheng Sean Ye 94*5ad1f010SStephen Hanson (void) sigaction(SIGCHLD, &cbuf, NULL); 954dc92747SCheng Sean Ye ep = tmp_events; 964dc92747SCheng Sean Ye tmp_events = tmp_events->next; 974dc92747SCheng Sean Ye nvlist_free(ep->ev); 984dc92747SCheng Sean Ye free(ep); 994dc92747SCheng Sean Ye } 1004dc92747SCheng Sean Ye 1014dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 1024dc92747SCheng Sean Ye } 1034dc92747SCheng Sean Ye 1044dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 1054dc92747SCheng Sean Ye 1064dc92747SCheng Sean Ye return (NULL); 1074dc92747SCheng Sean Ye } 1080dc974a9SCathy Zhou 1090dc974a9SCathy Zhou /*ARGSUSED*/ 1100dc974a9SCathy Zhou static int 1110dc974a9SCathy Zhou datalink_deliver_event(sysevent_t *ev, int unused) 1120dc974a9SCathy Zhou { 1130dc974a9SCathy Zhou const char *class = sysevent_get_class_name(ev); 1140dc974a9SCathy Zhou const char *subclass = sysevent_get_subclass_name(ev); 1150dc974a9SCathy Zhou nvlist_t *nvl; 1164dc92747SCheng Sean Ye struct event_list *newp, **elpp; 1170dc974a9SCathy Zhou 1180dc974a9SCathy Zhou if (strcmp(class, EC_DATALINK) != 0 || 1190dc974a9SCathy Zhou strcmp(subclass, ESC_DATALINK_PHYS_ADD) != 0) { 1200dc974a9SCathy Zhou return (0); 1210dc974a9SCathy Zhou } 1220dc974a9SCathy Zhou 1230dc974a9SCathy Zhou if (sysevent_get_attr_list(ev, &nvl) != 0) 1240dc974a9SCathy Zhou return (EINVAL); 1250dc974a9SCathy Zhou 1265093e103SCathy Zhou /* 1274dc92747SCheng Sean Ye * rcm_notify_event() needs to be called asynchronously otherwise when 1284dc92747SCheng Sean Ye * sysevent queue is full, deadlock will happen. 1295093e103SCathy Zhou */ 1304dc92747SCheng Sean Ye if ((newp = malloc(sizeof (struct event_list))) == NULL) 1314dc92747SCheng Sean Ye return (ENOMEM); 1320dc974a9SCathy Zhou 1334dc92747SCheng Sean Ye newp->ev = nvl; 1344dc92747SCheng Sean Ye newp->next = NULL; 1354dc92747SCheng Sean Ye 1364dc92747SCheng Sean Ye /* 1374dc92747SCheng Sean Ye * queue up at the end of the event list and signal notify_thread to 1384dc92747SCheng Sean Ye * process it. 1394dc92747SCheng Sean Ye */ 1404dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 1414dc92747SCheng Sean Ye elpp = &dl_events; 1424dc92747SCheng Sean Ye while (*elpp != NULL) 1434dc92747SCheng Sean Ye elpp = &(*elpp)->next; 1444dc92747SCheng Sean Ye *elpp = newp; 1454dc92747SCheng Sean Ye (void) cond_signal(&dl_cv); 1464dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 1474dc92747SCheng Sean Ye 1484dc92747SCheng Sean Ye return (0); 1490dc974a9SCathy Zhou } 1500dc974a9SCathy Zhou 1510dc974a9SCathy Zhou static struct slm_mod_ops datalink_mod_ops = { 1520dc974a9SCathy Zhou SE_MAJOR_VERSION, 1530dc974a9SCathy Zhou SE_MINOR_VERSION, 1540dc974a9SCathy Zhou SE_MAX_RETRY_LIMIT, 1550dc974a9SCathy Zhou datalink_deliver_event 1560dc974a9SCathy Zhou }; 1570dc974a9SCathy Zhou 1580dc974a9SCathy Zhou struct slm_mod_ops * 1590dc974a9SCathy Zhou slm_init() 1600dc974a9SCathy Zhou { 1614dc92747SCheng Sean Ye dl_events = NULL; 1624dc92747SCheng Sean Ye dl_exiting = B_FALSE; 1634dc92747SCheng Sean Ye 1640dc974a9SCathy Zhou if (rcm_alloc_handle(NULL, 0, NULL, &rcm_hdl) != RCM_SUCCESS) 1650dc974a9SCathy Zhou return (NULL); 1660dc974a9SCathy Zhou 1674dc92747SCheng Sean Ye if (thr_create(NULL, 0, datalink_notify_thread, NULL, 0, 1684dc92747SCheng Sean Ye &dl_notify_tid) != 0) { 1694dc92747SCheng Sean Ye (void) rcm_free_handle(rcm_hdl); 1704dc92747SCheng Sean Ye return (NULL); 1714dc92747SCheng Sean Ye } 1724dc92747SCheng Sean Ye 1734dc92747SCheng Sean Ye (void) mutex_init(&dl_mx, USYNC_THREAD, NULL); 1744dc92747SCheng Sean Ye (void) cond_init(&dl_cv, USYNC_THREAD, NULL); 1754dc92747SCheng Sean Ye 1760dc974a9SCathy Zhou return (&datalink_mod_ops); 1770dc974a9SCathy Zhou } 1780dc974a9SCathy Zhou 1790dc974a9SCathy Zhou void 1800dc974a9SCathy Zhou slm_fini() 1810dc974a9SCathy Zhou { 1824dc92747SCheng Sean Ye (void) mutex_lock(&dl_mx); 1834dc92747SCheng Sean Ye dl_exiting = B_TRUE; 1844dc92747SCheng Sean Ye (void) cond_signal(&dl_cv); 1854dc92747SCheng Sean Ye (void) mutex_unlock(&dl_mx); 1864dc92747SCheng Sean Ye (void) thr_join(dl_notify_tid, NULL, NULL); 1874dc92747SCheng Sean Ye 1884dc92747SCheng Sean Ye (void) mutex_destroy(&dl_mx); 1894dc92747SCheng Sean Ye (void) cond_destroy(&dl_cv); 1900dc974a9SCathy Zhou (void) rcm_free_handle(rcm_hdl); 1910dc974a9SCathy Zhou rcm_hdl = NULL; 1920dc974a9SCathy Zhou } 193