4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 #include <libsysevent.h>
30 #include <sys/sysevent/eventdefs.h>
31 #include <sys/sysevent/dev.h>
32 #include <sys/types.h>
33 #include <libnvpair.h>
44 * sysevent_events.c - this file contains routines to retrieve sysevents
45 * from the system and package them for high level processing.
48 static sysevent_handle_t
*sysevent_handle
;
51 * At present, we only handle EC_DEV_ADD/EC_DEV_REMOVE sysevents of
52 * subclass ESC_NETWORK. These signify hotplug addition/removal.
54 * - extract the driver/instance sysevent attributes
55 * - combine these to get interface name and create associated NCUs
56 * at the link/IP level if required
57 * - enable those instances
58 * For EC_DEV_REMOVE, we:
59 * - disable the associated link/IP NCUs
62 sysevent_handler(sysevent_t
*ev
)
66 char if_name
[LIFNAMSIZ
];
69 char *event_class
= sysevent_get_class_name(ev
);
70 char *event_subclass
= sysevent_get_subclass_name(ev
);
71 nwamd_event_t link_event
= NULL
;
73 nlog(LOG_DEBUG
, "sysevent_handler: event %s/%s", event_class
,
76 /* Make sure sysevent is of expected class/subclass */
77 if ((strcmp(event_class
, EC_DEV_ADD
) != 0 &&
78 strcmp(event_class
, EC_DEV_REMOVE
) != 0) ||
79 strcmp(event_subclass
, ESC_NETWORK
) != 0) {
80 nlog(LOG_ERR
, "sysevent_handler: unexpected sysevent "
81 "class/subclass %s/%s", event_class
, event_subclass
);
85 link_added
= (strcmp(event_class
, EC_DEV_ADD
) == 0);
88 * Retrieve driver name and instance attributes, and combine to
91 if (sysevent_get_attr_list(ev
, &attr_list
) != 0) {
92 nlog(LOG_ERR
, "sysevent_handler: sysevent_get_attr_list: %m");
95 if (nvlist_lookup_string(attr_list
, DEV_DRIVER_NAME
, &driver
) != 0 ||
96 nvlist_lookup_int32(attr_list
, DEV_INSTANCE
, &instance
) != 0) {
97 nlog(LOG_ERR
, "sysevent_handler: nvlist_lookup "
98 "of attributes failed: %m");
99 nvlist_free(attr_list
);
102 (void) snprintf(if_name
, LIFNAMSIZ
, "%s%d", driver
, instance
);
103 nvlist_free(attr_list
);
105 /* Ignore sysevent events for other zones */
106 if (!nwamd_link_belongs_to_this_zone(if_name
))
109 /* Create event for link */
110 link_event
= nwamd_event_init_link_action(if_name
,
111 link_added
? NWAM_ACTION_ADD
: NWAM_ACTION_REMOVE
);
112 if (link_event
!= NULL
)
113 nwamd_event_enqueue(link_event
);
118 sysevent_initialization(void *arg
)
120 const char *subclass
= ESC_NETWORK
;
124 sysevent_handle
= sysevent_bind_handle(sysevent_handler
);
128 } while (sysevent_handle
== NULL
);
131 * Subscribe to ESC_NETWORK subclass of EC_DEV_ADD and EC_DEV_REMOVE
132 * events. As a result, we get sysevent notification of hotplug
133 * add/remove events, which we handle above in sysevent_handler().
135 if (sysevent_subscribe_event(sysevent_handle
, EC_DEV_ADD
, &subclass
, 1)
137 sysevent_subscribe_event(sysevent_handle
, EC_DEV_REMOVE
, &subclass
,
139 pfail("sysevent_subscribe_event: %s", strerror(errno
));
145 * We can't initialize in the main thread because we may need to wait until
146 * svc:/system/sysevent:default finishes starting up. So we create a thread to
150 nwamd_sysevent_events_init(void)
155 rc
= pthread_attr_init(&attr
);
157 pfail("nwamd_sysevents_init: pthread_attr_init failed: %s",
161 rc
= pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
163 pfail("nwamd_sysevents_init: pthread_attr_setdetachstate "
164 "failed: %s", strerror(rc
));
167 rc
= pthread_create(NULL
, &attr
, sysevent_initialization
, NULL
);
169 pfail("nwamd_sysevents_init: couldn't start sysevent init "
170 "thread: %s", strerror(rc
));
173 (void) pthread_attr_destroy(&attr
);
177 nwamd_sysevent_events_fini(void)
179 if (sysevent_handle
!= NULL
) {
181 sysevent_unbind_handle(sysevent_handle
);
184 sysevent_handle
= NULL
;