16ba597c5SAnurag S. Maskey /* 26ba597c5SAnurag S. Maskey * CDDL HEADER START 36ba597c5SAnurag S. Maskey * 46ba597c5SAnurag S. Maskey * The contents of this file are subject to the terms of the 56ba597c5SAnurag S. Maskey * Common Development and Distribution License (the "License"). 66ba597c5SAnurag S. Maskey * You may not use this file except in compliance with the License. 76ba597c5SAnurag S. Maskey * 86ba597c5SAnurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96ba597c5SAnurag S. Maskey * or http://www.opensolaris.org/os/licensing. 106ba597c5SAnurag S. Maskey * See the License for the specific language governing permissions 116ba597c5SAnurag S. Maskey * and limitations under the License. 126ba597c5SAnurag S. Maskey * 136ba597c5SAnurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each 146ba597c5SAnurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156ba597c5SAnurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the 166ba597c5SAnurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying 176ba597c5SAnurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner] 186ba597c5SAnurag S. Maskey * 196ba597c5SAnurag S. Maskey * CDDL HEADER END 206ba597c5SAnurag S. Maskey */ 216ba597c5SAnurag S. Maskey 226ba597c5SAnurag S. Maskey /* 236ba597c5SAnurag S. Maskey * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 246ba597c5SAnurag S. Maskey * Use is subject to license terms. 256ba597c5SAnurag S. Maskey */ 266ba597c5SAnurag S. Maskey 276ba597c5SAnurag S. Maskey #include <assert.h> 286ba597c5SAnurag S. Maskey #include <errno.h> 296ba597c5SAnurag S. Maskey #include <libsysevent.h> 306ba597c5SAnurag S. Maskey #include <sys/sysevent/eventdefs.h> 316ba597c5SAnurag S. Maskey #include <sys/sysevent/dev.h> 326ba597c5SAnurag S. Maskey #include <sys/types.h> 336ba597c5SAnurag S. Maskey #include <libnvpair.h> 346ba597c5SAnurag S. Maskey #include <string.h> 356ba597c5SAnurag S. Maskey #include <unistd.h> 366ba597c5SAnurag S. Maskey 376ba597c5SAnurag S. Maskey #include "events.h" 386ba597c5SAnurag S. Maskey #include "ncp.h" 396ba597c5SAnurag S. Maskey #include "ncu.h" 406ba597c5SAnurag S. Maskey #include "objects.h" 416ba597c5SAnurag S. Maskey #include "util.h" 426ba597c5SAnurag S. Maskey 436ba597c5SAnurag S. Maskey /* 446ba597c5SAnurag S. Maskey * sysevent_events.c - this file contains routines to retrieve sysevents 456ba597c5SAnurag S. Maskey * from the system and package them for high level processing. 466ba597c5SAnurag S. Maskey */ 476ba597c5SAnurag S. Maskey 486ba597c5SAnurag S. Maskey static sysevent_handle_t *sysevent_handle; 496ba597c5SAnurag S. Maskey 506ba597c5SAnurag S. Maskey /* 516ba597c5SAnurag S. Maskey * At present, we only handle EC_DEV_ADD/EC_DEV_REMOVE sysevents of 526ba597c5SAnurag S. Maskey * subclass ESC_NETWORK. These signify hotplug addition/removal. 536ba597c5SAnurag S. Maskey * For EC_DEV_ADD, we: 546ba597c5SAnurag S. Maskey * - extract the driver/instance sysevent attributes 556ba597c5SAnurag S. Maskey * - combine these to get interface name and create associated NCUs 566ba597c5SAnurag S. Maskey * at the link/IP level if required 576ba597c5SAnurag S. Maskey * - enable those instances 586ba597c5SAnurag S. Maskey * For EC_DEV_REMOVE, we: 596ba597c5SAnurag S. Maskey * - disable the associated link/IP NCUs 606ba597c5SAnurag S. Maskey */ 616ba597c5SAnurag S. Maskey static void 626ba597c5SAnurag S. Maskey sysevent_handler(sysevent_t *ev) 636ba597c5SAnurag S. Maskey { 646ba597c5SAnurag S. Maskey int32_t instance; 656ba597c5SAnurag S. Maskey char *driver; 666ba597c5SAnurag S. Maskey char if_name[LIFNAMSIZ]; 676ba597c5SAnurag S. Maskey boolean_t link_added; 686ba597c5SAnurag S. Maskey nvlist_t *attr_list; 696ba597c5SAnurag S. Maskey char *event_class = sysevent_get_class_name(ev); 706ba597c5SAnurag S. Maskey char *event_subclass = sysevent_get_subclass_name(ev); 716ba597c5SAnurag S. Maskey nwamd_event_t link_event = NULL; 726ba597c5SAnurag S. Maskey 736ba597c5SAnurag S. Maskey nlog(LOG_DEBUG, "sysevent_handler: event %s/%s", event_class, 746ba597c5SAnurag S. Maskey event_subclass); 756ba597c5SAnurag S. Maskey 766ba597c5SAnurag S. Maskey /* Make sure sysevent is of expected class/subclass */ 776ba597c5SAnurag S. Maskey if ((strcmp(event_class, EC_DEV_ADD) != 0 && 786ba597c5SAnurag S. Maskey strcmp(event_class, EC_DEV_REMOVE) != 0) || 796ba597c5SAnurag S. Maskey strcmp(event_subclass, ESC_NETWORK) != 0) { 806ba597c5SAnurag S. Maskey nlog(LOG_ERR, "sysevent_handler: unexpected sysevent " 816ba597c5SAnurag S. Maskey "class/subclass %s/%s", event_class, event_subclass); 826ba597c5SAnurag S. Maskey return; 836ba597c5SAnurag S. Maskey } 846ba597c5SAnurag S. Maskey 856ba597c5SAnurag S. Maskey link_added = (strcmp(event_class, EC_DEV_ADD) == 0); 866ba597c5SAnurag S. Maskey 876ba597c5SAnurag S. Maskey /* 886ba597c5SAnurag S. Maskey * Retrieve driver name and instance attributes, and combine to 896ba597c5SAnurag S. Maskey * get interface name. 906ba597c5SAnurag S. Maskey */ 916ba597c5SAnurag S. Maskey if (sysevent_get_attr_list(ev, &attr_list) != 0) { 926ba597c5SAnurag S. Maskey nlog(LOG_ERR, "sysevent_handler: sysevent_get_attr_list: %m"); 936ba597c5SAnurag S. Maskey return; 946ba597c5SAnurag S. Maskey } 956ba597c5SAnurag S. Maskey if (nvlist_lookup_string(attr_list, DEV_DRIVER_NAME, &driver) != 0 || 966ba597c5SAnurag S. Maskey nvlist_lookup_int32(attr_list, DEV_INSTANCE, &instance) != 0) { 976ba597c5SAnurag S. Maskey nlog(LOG_ERR, "sysevent_handler: nvlist_lookup " 986ba597c5SAnurag S. Maskey "of attributes failed: %m"); 996ba597c5SAnurag S. Maskey nvlist_free(attr_list); 1006ba597c5SAnurag S. Maskey return; 1016ba597c5SAnurag S. Maskey } 1026ba597c5SAnurag S. Maskey (void) snprintf(if_name, LIFNAMSIZ, "%s%d", driver, instance); 1036ba597c5SAnurag S. Maskey nvlist_free(attr_list); 1046ba597c5SAnurag S. Maskey 1056ba597c5SAnurag S. Maskey /* Ignore sysevent events for other zones */ 1066ba597c5SAnurag S. Maskey if (!nwamd_link_belongs_to_this_zone(if_name)) 1076ba597c5SAnurag S. Maskey return; 1086ba597c5SAnurag S. Maskey 1096ba597c5SAnurag S. Maskey /* Create event for link */ 1106ba597c5SAnurag S. Maskey link_event = nwamd_event_init_link_action(if_name, 1116ba597c5SAnurag S. Maskey link_added ? NWAM_ACTION_ADD : NWAM_ACTION_REMOVE); 1126ba597c5SAnurag S. Maskey if (link_event != NULL) 1136ba597c5SAnurag S. Maskey nwamd_event_enqueue(link_event); 1146ba597c5SAnurag S. Maskey } 1156ba597c5SAnurag S. Maskey 1166ba597c5SAnurag S. Maskey /* ARGSUSED0 */ 1176ba597c5SAnurag S. Maskey static void * 1186ba597c5SAnurag S. Maskey sysevent_initialization(void *arg) 1196ba597c5SAnurag S. Maskey { 1206ba597c5SAnurag S. Maskey const char *subclass = ESC_NETWORK; 1216ba597c5SAnurag S. Maskey 1226ba597c5SAnurag S. Maskey do { 123*38f140aaSMichael Hunter nwamd_escalate(); 1246ba597c5SAnurag S. Maskey sysevent_handle = sysevent_bind_handle(sysevent_handler); 125*38f140aaSMichael Hunter nwamd_deescalate(); 1266ba597c5SAnurag S. Maskey 1276ba597c5SAnurag S. Maskey (void) sleep(1); 1286ba597c5SAnurag S. Maskey } while (sysevent_handle == NULL); 1296ba597c5SAnurag S. Maskey 1306ba597c5SAnurag S. Maskey /* 1316ba597c5SAnurag S. Maskey * Subscribe to ESC_NETWORK subclass of EC_DEV_ADD and EC_DEV_REMOVE 1326ba597c5SAnurag S. Maskey * events. As a result, we get sysevent notification of hotplug 1336ba597c5SAnurag S. Maskey * add/remove events, which we handle above in sysevent_handler(). 1346ba597c5SAnurag S. Maskey */ 1356ba597c5SAnurag S. Maskey if (sysevent_subscribe_event(sysevent_handle, EC_DEV_ADD, &subclass, 1) 1366ba597c5SAnurag S. Maskey != 0 || 1376ba597c5SAnurag S. Maskey sysevent_subscribe_event(sysevent_handle, EC_DEV_REMOVE, &subclass, 1386ba597c5SAnurag S. Maskey 1) != 0) 1396ba597c5SAnurag S. Maskey pfail("sysevent_subscribe_event: %s", strerror(errno)); 1406ba597c5SAnurag S. Maskey 1416ba597c5SAnurag S. Maskey return (NULL); 1426ba597c5SAnurag S. Maskey } 1436ba597c5SAnurag S. Maskey 1446ba597c5SAnurag S. Maskey /* 1456ba597c5SAnurag S. Maskey * We can't initialize in the main thread because we may need to wait until 1466ba597c5SAnurag S. Maskey * svc:/system/sysevent:default finishes starting up. So we create a thread to 1476ba597c5SAnurag S. Maskey * initialize in. 1486ba597c5SAnurag S. Maskey */ 1496ba597c5SAnurag S. Maskey void 1506ba597c5SAnurag S. Maskey nwamd_sysevent_events_init(void) 1516ba597c5SAnurag S. Maskey { 1526ba597c5SAnurag S. Maskey int rc; 1536ba597c5SAnurag S. Maskey pthread_attr_t attr; 1546ba597c5SAnurag S. Maskey 1556ba597c5SAnurag S. Maskey rc = pthread_attr_init(&attr); 1566ba597c5SAnurag S. Maskey if (rc != 0) { 1576ba597c5SAnurag S. Maskey pfail("nwamd_sysevents_init: pthread_attr_init failed: %s", 1586ba597c5SAnurag S. Maskey strerror(rc)); 1596ba597c5SAnurag S. Maskey } 1606ba597c5SAnurag S. Maskey 1616ba597c5SAnurag S. Maskey rc = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 1626ba597c5SAnurag S. Maskey if (rc != 0) { 1636ba597c5SAnurag S. Maskey pfail("nwamd_sysevents_init: pthread_attr_setdetachstate " 1646ba597c5SAnurag S. Maskey "failed: %s", strerror(rc)); 1656ba597c5SAnurag S. Maskey } 1666ba597c5SAnurag S. Maskey 1676ba597c5SAnurag S. Maskey rc = pthread_create(NULL, &attr, sysevent_initialization, NULL); 1686ba597c5SAnurag S. Maskey if (rc != 0) { 1696ba597c5SAnurag S. Maskey pfail("nwamd_sysevents_init: couldn't start sysevent init " 1706ba597c5SAnurag S. Maskey "thread: %s", strerror(rc)); 1716ba597c5SAnurag S. Maskey } 1726ba597c5SAnurag S. Maskey 1736ba597c5SAnurag S. Maskey (void) pthread_attr_destroy(&attr); 1746ba597c5SAnurag S. Maskey } 1756ba597c5SAnurag S. Maskey 1766ba597c5SAnurag S. Maskey void 1776ba597c5SAnurag S. Maskey nwamd_sysevent_events_fini(void) 1786ba597c5SAnurag S. Maskey { 1796ba597c5SAnurag S. Maskey if (sysevent_handle != NULL) { 180*38f140aaSMichael Hunter nwamd_escalate(); 1816ba597c5SAnurag S. Maskey sysevent_unbind_handle(sysevent_handle); 182*38f140aaSMichael Hunter nwamd_deescalate(); 1836ba597c5SAnurag S. Maskey } 1846ba597c5SAnurag S. Maskey sysevent_handle = NULL; 1856ba597c5SAnurag S. Maskey } 186