0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou/*
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * CDDL HEADER START
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * The contents of this file are subject to the terms of the
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * Common Development and Distribution License (the "License").
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * You may not use this file except in compliance with the License.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * or http://www.opensolaris.org/os/licensing.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * See the License for the specific language governing permissions
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * and limitations under the License.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * When distributing Covered Code, include this CDDL HEADER in each
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * If applicable, add the following below this CDDL HEADER, with the
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * fields enclosed by brackets "[]" replaced with your own identifying
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * information: Portions Copyright [yyyy] [name of copyright owner]
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * CDDL HEADER END
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou */
0756cc7034e080027082817163d21e36e93310edYuri Pankov
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou/*
5093e10312724e92dd76c008a15bdb59d414708aCathy Zhou * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * Use is subject to license terms.
0756cc7034e080027082817163d21e36e93310edYuri Pankov * Copyright 2016 Nexenta Systems, Inc.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou */
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou/*
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * datalink syseventd module.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * The purpose of this module is to identify all datalink related events,
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou * and react accordingly.
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou */
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <errno.h>
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <sys/sysevent/eventdefs.h>
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <string.h>
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <libnvpair.h>
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <librcm.h>
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou#include <libsysevent.h>
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson#include "sysevent_signal.h"
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yeextern void syseventd_err_print(char *, ...);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestruct event_list {
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye nvlist_t *ev;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye struct event_list *next;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye};
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhoustatic rcm_handle_t *rcm_hdl = NULL;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic boolean_t dl_exiting;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic thread_t dl_notify_tid;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic mutex_t dl_mx;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic cond_t dl_cv;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic struct event_list *dl_events;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye/* ARGSUSED */
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yestatic void *
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Yedatalink_notify_thread(void *arg)
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye{
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye struct event_list *tmp_events, *ep;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_lock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye while (! dl_exiting || dl_events != NULL) {
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye if (dl_events == NULL) {
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) cond_wait(&dl_cv, &dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye continue;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye }
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye tmp_events = dl_events;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye dl_events = NULL;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_unlock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye while (tmp_events != NULL) {
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson struct sigaction cbuf, dfl;
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson /*
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson * Ignore SIGCLD for the
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson * duration of the rcm_notify_event call.
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson */
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson (void) memset(&dfl, 0, sizeof (dfl));
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson dfl.sa_handler = SIG_IGN;
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson (void) sigaction(SIGCHLD, &dfl, &cbuf);
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye /*
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * Send the PHYSLINK_NEW event to network_rcm to update
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * the network devices cache accordingly.
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye */
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye if (rcm_notify_event(rcm_hdl, RCM_RESOURCE_PHYSLINK_NEW,
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye 0, tmp_events->ev, NULL) != RCM_SUCCESS)
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson syseventd_err_print("datalink_mod: Can not "
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye "notify event: %s\n", strerror(errno));
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
5ad1f010a7b934be6e0dd6c13198af62791824beStephen Hanson (void) sigaction(SIGCHLD, &cbuf, NULL);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye ep = tmp_events;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye tmp_events = tmp_events->next;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye nvlist_free(ep->ev);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye free(ep);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye }
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_lock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye }
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_unlock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye return (NULL);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye}
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou/*ARGSUSED*/
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhoustatic int
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhoudatalink_deliver_event(sysevent_t *ev, int unused)
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou{
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou const char *class = sysevent_get_class_name(ev);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou const char *subclass = sysevent_get_subclass_name(ev);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou nvlist_t *nvl;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye struct event_list *newp, **elpp;
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou if (strcmp(class, EC_DATALINK) != 0 ||
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou strcmp(subclass, ESC_DATALINK_PHYS_ADD) != 0) {
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou return (0);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou }
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou if (sysevent_get_attr_list(ev, &nvl) != 0)
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou return (EINVAL);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
5093e10312724e92dd76c008a15bdb59d414708aCathy Zhou /*
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * rcm_notify_event() needs to be called asynchronously otherwise when
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * sysevent queue is full, deadlock will happen.
5093e10312724e92dd76c008a15bdb59d414708aCathy Zhou */
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye if ((newp = malloc(sizeof (struct event_list))) == NULL)
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye return (ENOMEM);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye newp->ev = nvl;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye newp->next = NULL;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye /*
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * queue up at the end of the event list and signal notify_thread to
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye * process it.
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye */
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_lock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye elpp = &dl_events;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye while (*elpp != NULL)
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye elpp = &(*elpp)->next;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye *elpp = newp;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) cond_signal(&dl_cv);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_unlock(&dl_mx);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye return (0);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou}
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhoustatic struct slm_mod_ops datalink_mod_ops = {
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou SE_MAJOR_VERSION,
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou SE_MINOR_VERSION,
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou SE_MAX_RETRY_LIMIT,
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou datalink_deliver_event
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou};
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhoustruct slm_mod_ops *
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhouslm_init()
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou{
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye dl_events = NULL;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye dl_exiting = B_FALSE;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou if (rcm_alloc_handle(NULL, 0, NULL, &rcm_hdl) != RCM_SUCCESS)
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou return (NULL);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0756cc7034e080027082817163d21e36e93310edYuri Pankov (void) mutex_init(&dl_mx, USYNC_THREAD, NULL);
0756cc7034e080027082817163d21e36e93310edYuri Pankov (void) cond_init(&dl_cv, USYNC_THREAD, NULL);
0756cc7034e080027082817163d21e36e93310edYuri Pankov
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye if (thr_create(NULL, 0, datalink_notify_thread, NULL, 0,
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye &dl_notify_tid) != 0) {
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) rcm_free_handle(rcm_hdl);
0756cc7034e080027082817163d21e36e93310edYuri Pankov (void) mutex_destroy(&dl_mx);
0756cc7034e080027082817163d21e36e93310edYuri Pankov (void) cond_destroy(&dl_cv);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye return (NULL);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye }
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou return (&datalink_mod_ops);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou}
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhouvoid
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhouslm_fini()
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou{
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_lock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye dl_exiting = B_TRUE;
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) cond_signal(&dl_cv);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_unlock(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) thr_join(dl_notify_tid, NULL, NULL);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) mutex_destroy(&dl_mx);
4dc927470baa43bc10074a7a7ae03610f3741e09Cheng Sean Ye (void) cond_destroy(&dl_cv);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou (void) rcm_free_handle(rcm_hdl);
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou rcm_hdl = NULL;
0dc974a9a2e66d676505db23524ebff105fb36a9Cathy Zhou}