summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCathy Zhou <Cathy.Zhou@Sun.COM>2008-08-13 14:57:47 -0700
committerCathy Zhou <Cathy.Zhou@Sun.COM>2008-08-13 14:57:47 -0700
commit0dc974a9a2e66d676505db23524ebff105fb36a9 (patch)
tree05b6f06b156223b4807e2bc8e71bc3001ac98c93
parent8c8a8d17e0c6c68e047f0e531c3f8ce133b9aea6 (diff)
downloadillumos-joyent-0dc974a9a2e66d676505db23524ebff105fb36a9.tar.gz
PSARC 2008/498 datalink sysevents
6696737 ndi_devi_enter() can deadlock with stopped threads, hanging system 6729044 race between network_rcm and softmac when a physical device is attached 6729144 dlmgmtd process_db_write() leaks dlmgmt_link_t
-rw-r--r--usr/src/cmd/devfsadm/devfsadm.c322
-rw-r--r--usr/src/cmd/devfsadm/devfsadm_impl.h15
-rw-r--r--usr/src/cmd/devfsadm/message.h16
-rw-r--r--usr/src/cmd/dlmgmtd/Makefile4
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_db.c7
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_door.c47
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_main.c7
-rw-r--r--usr/src/cmd/rcm_daemon/common/network_rcm.c293
-rw-r--r--usr/src/cmd/syseventd/modules/Makefile5
-rw-r--r--usr/src/cmd/syseventd/modules/datalink_mod/Makefile41
-rw-r--r--usr/src/cmd/syseventd/modules/datalink_mod/datalink_mod.c89
-rw-r--r--usr/src/lib/libdevinfo/device_info.h6
-rw-r--r--usr/src/lib/librcm/librcm.h12
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_com3
-rw-r--r--usr/src/uts/common/io/softmac/softmac_main.c149
-rw-r--r--usr/src/uts/common/sys/sysevent/eventdefs.h8
16 files changed, 284 insertions, 740 deletions
diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c
index d897db16c6..4fcd9e2e3d 100644
--- a/usr/src/cmd/devfsadm/devfsadm.c
+++ b/usr/src/cmd/devfsadm/devfsadm.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Devfsadm replaces drvconfig, audlinks, disks, tapes, ports, devlinks
* as a general purpose device administrative utility. It creates
@@ -229,16 +227,6 @@ static mutex_t nfp_mutex = DEFAULTMUTEX;
static char *packaged_dirs[] =
{"dsk", "rdsk", "term", NULL};
-/* RCM related globals */
-static void *librcm_hdl;
-static rcm_handle_t *rcm_hdl = NULL;
-static thread_t process_rcm_events_tid;
-static struct rcm_eventq *volatile rcm_eventq_head = NULL;
-static struct rcm_eventq *rcm_eventq_tail = NULL;
-static mutex_t rcm_eventq_lock;
-static cond_t rcm_eventq_cv;
-static volatile int need_to_exit_rcm_event_thread = 0;
-
/* Devname globals */
static int devname_debug_msg = 1;
static nvlist_t *devname_maps = NULL;
@@ -416,16 +404,11 @@ main(int argc, char *argv[])
/*
- * No need for rcm notifications when running
- * with an alternate root. So initialize rcm only
- * when devfsadm is running with root dir "/".
- * Similarly, logindevperms need only be set
+ * logindevperms need only be set
* in daemon mode and when root dir is "/".
*/
- if (root_dir[0] == '\0') {
- (void) rcm_init();
+ if (root_dir[0] == '\0')
login_dev_enable = TRUE;
- }
daemon_update();
devfsadm_exit(0);
/*NOTREACHED*/
@@ -1034,15 +1017,12 @@ devi_tree_walk(struct dca_impl *dcip, int flags, char *ev_subclass)
/*
* Finished creating devfs files and dev links.
- * Log sysevent and notify RCM.
+ * Log sysevent.
*/
if (ev_subclass)
build_and_enq_event(EC_DEV_ADD, ev_subclass, dcip->dci_root,
node, dcip->dci_minor);
- if ((dcip->dci_flags & DCA_NOTIFY_RCM) && rcm_hdl)
- (void) notify_rcm(node, dcip->dci_minor);
-
/* Add new device to device allocation database */
if (system_labeled && update_devdb) {
_update_devalloc_db(&devlist, 0, DA_ADD, NULL, root_dir);
@@ -1769,9 +1749,7 @@ add_minor_pathname(char *node, char *minor, char *ev_subclass)
}
/*
- * We are being invoked in response to a hotplug
- * event. Also, notify RCM if nodetype indicates
- * a network device has been hotplugged.
+ * We are being invoked in response to a hotplug event.
*/
dci.dci_flags = DCA_HOT_PLUG | DCA_CHECK_TYPE;
@@ -1835,7 +1813,6 @@ check_minor_type(di_node_t node, di_minor_t minor, void *arg)
if ((dcip->dci_flags & DCA_CHECK_TYPE) &&
(nt = di_minor_nodetype(minor)) &&
(strcmp(nt, DDI_NT_NET) == 0)) {
- dcip->dci_flags |= DCA_NOTIFY_RCM;
dcip->dci_flags &= ~DCA_CHECK_TYPE;
}
@@ -7010,20 +6987,6 @@ devfsadm_exit(int status)
vprint(INFO_MID, "exit status = %d\n", status);
}
- if (rcm_hdl) {
- if (thr_self() != process_rcm_events_tid) {
- (void) mutex_lock(&rcm_eventq_lock);
- need_to_exit_rcm_event_thread = 1;
- (void) cond_broadcast(&rcm_eventq_cv);
- (void) mutex_unlock(&rcm_eventq_lock);
-
- /* wait until process_rcm_events() thread exits */
- (void) thr_join(process_rcm_events_tid, NULL, NULL);
- }
- librcm_free_handle(rcm_hdl);
- (void) dlclose(librcm_hdl);
- }
-
exit_dev_lock(1);
exit_daemon_lock(1);
@@ -7787,283 +7750,6 @@ is_minor_node(char *contents, char **mn_root)
}
/*
- * Lookup nvpair corresponding to the given name and type:
- *
- * The standard nvlist_lookup functions in libnvpair don't work as our
- * nvlist is not allocated with NV_UNIQUE_NAME or NV_UNIQUE_NAME_TYPE.
- */
-static nvpair_t *
-lookup_nvpair(nvlist_t *nvl, char *name, data_type_t type)
-{
- nvpair_t *nvp;
-
- for (nvp = nvlist_next_nvpair(nvl, NULL); nvp != NULL;
- nvp = nvlist_next_nvpair(nvl, nvp)) {
- if (strcmp(name, nvpair_name(nvp)) == 0 &&
- nvpair_type(nvp) == type)
- return (nvp);
- }
-
- return (NULL);
-}
-
-/*ARGSUSED*/
-static void
-process_rcm_events(void *arg)
-{
- struct rcm_eventq *ev, *ev_next;
- nvpair_t *nvp;
- char *path, *driver;
- int instance;
- int err;
- int need_to_exit;
-
- for (;;) {
- (void) mutex_lock(&rcm_eventq_lock);
- while (rcm_eventq_head == NULL &&
- need_to_exit_rcm_event_thread == 0)
- (void) cond_wait(&rcm_eventq_cv, &rcm_eventq_lock);
-
- need_to_exit = need_to_exit_rcm_event_thread;
- ev = rcm_eventq_head;
- rcm_eventq_head = rcm_eventq_tail = NULL;
- (void) mutex_unlock(&rcm_eventq_lock);
-
- for (; ev != NULL; ev = ev_next) {
- /*
- * Private notification interface to RCM:
- * Do not retry the RCM notification on an error since
- * we do not know whether the failure occurred in
- * librcm, rcm_daemon or rcm modules or scripts.
- */
- if (librcm_notify_event(rcm_hdl,
- RCM_RESOURCE_NETWORK_NEW, 0, ev->nvl, NULL)
- != RCM_SUCCESS) {
-
- err = errno;
-
- if (((nvp = lookup_nvpair(ev->nvl,
- RCM_NV_DEVFS_PATH, DATA_TYPE_STRING))
- == NULL) ||
- (nvpair_value_string(nvp, &path) != 0))
- path = "unknown";
-
- if (((nvp = lookup_nvpair(ev->nvl,
- RCM_NV_DRIVER_NAME, DATA_TYPE_STRING))
- == NULL) ||
- (nvpair_value_string(nvp, &driver) != 0))
- driver = "unknown";
- if (((nvp = lookup_nvpair(ev->nvl,
- RCM_NV_INSTANCE, DATA_TYPE_INT32))
- == NULL) ||
- (nvpair_value_int32(nvp, &instance) != 0))
- instance = -1;
-
- err_print(RCM_NOTIFY_FAILED, path, driver,
- instance, strerror(err));
- }
-
- ev_next = ev->next;
- nvlist_free(ev->nvl);
- free(ev);
- }
-
- if (need_to_exit)
- return;
- }
-}
-
-/*
- * Initialize rcm related handles and function pointers.
- * Since RCM need not present in miniroot, we dlopen librcm.
- */
-static int
-rcm_init(void)
-{
-#define LIBRCM_PATH "/lib/librcm.so"
- rcm_handle_t *hdl = NULL;
- int err;
-
- if ((librcm_hdl = dlopen(LIBRCM_PATH, RTLD_LAZY)) == NULL) {
- /*
- * don't log an error here, since librcm may not be present
- * in miniroot.
- */
- return (-1);
- }
-
- librcm_alloc_handle = (int (*)())dlsym(librcm_hdl, "rcm_alloc_handle");
- librcm_free_handle = (void (*)())dlsym(librcm_hdl, "rcm_free_handle");
- librcm_notify_event = (int (*)())dlsym(librcm_hdl, "rcm_notify_event");
-
- if (librcm_alloc_handle == NULL || librcm_notify_event == NULL ||
- librcm_free_handle == NULL) {
- err_print(MISSING_SYMBOLS, LIBRCM_PATH);
- goto out;
- }
-
- /* Initialize the rcm handle */
- if (librcm_alloc_handle(NULL, 0, NULL, &hdl) != RCM_SUCCESS) {
- err_print(RCM_ALLOC_HANDLE_ERROR);
- goto out;
- }
-
- (void) cond_init(&rcm_eventq_cv, USYNC_THREAD, 0);
- (void) mutex_init(&rcm_eventq_lock, USYNC_THREAD, 0);
-
- /* create a thread to notify RCM of events */
- if ((err = thr_create(NULL, 0, (void *(*)(void *))process_rcm_events,
- NULL, 0, &process_rcm_events_tid)) != 0) {
- err_print(CANT_CREATE_THREAD, "process_rcm_events",
- strerror(err));
- goto out;
- }
-
- rcm_hdl = hdl;
- return (0);
-
-out:
- if (hdl)
- librcm_free_handle(hdl);
- (void) dlclose(librcm_hdl);
- return (-1);
-}
-
-/*
- * Build an nvlist using the minor data. Pack it and add the packed nvlist
- * as a byte array to nv_list parameter.
- * Return 0 on success, errno on failure.
- */
-static int
-add_minor_data_to_nvl(nvlist_t *nv_list, di_minor_t minor)
-{
- nvlist_t *nvl = NULL;
- int32_t minor_type;
- char *minor_name, *minor_node_type;
- int err;
- char *buf = NULL;
- size_t buflen = 0;
-
- if ((err = nvlist_alloc(&nvl, 0, 0)) != 0)
- return (err);
-
- minor_type = (int32_t)di_minor_type(minor);
- if ((err = nvlist_add_int32(nvl, RCM_NV_MINOR_TYPE, minor_type)) != 0)
- goto error;
-
- minor_name = di_minor_name(minor);
- if ((err = nvlist_add_string(nvl, RCM_NV_MINOR_NAME, minor_name)) != 0)
- goto error;
-
- if ((minor_node_type = di_minor_nodetype(minor)) == NULL)
- minor_node_type = "";
- if ((err = nvlist_add_string(nvl, RCM_NV_MINOR_NODE_TYPE,
- minor_node_type)) != 0)
- goto error;
-
- if ((err = nvlist_pack(nvl, &buf, &buflen, NV_ENCODE_NATIVE, 0)) != 0)
- goto error;
-
- err = nvlist_add_byte_array(nv_list, RCM_NV_MINOR_DATA,
- (uchar_t *)(buf), (uint_t)(buflen));
-
-error:
- nvlist_free(nvl);
- if (buf)
- free(buf);
- return (err);
-}
-
-static void
-enqueue_rcm_event(nvlist_t *nvl)
-{
- struct rcm_eventq *ev;
-
- ev = (struct rcm_eventq *)s_zalloc(sizeof (struct rcm_eventq));
- ev->nvl = nvl;
-
- (void) mutex_lock(&rcm_eventq_lock);
- if (rcm_eventq_head == NULL)
- rcm_eventq_head = ev;
- else
- rcm_eventq_tail->next = ev;
- rcm_eventq_tail = ev;
- (void) cond_broadcast(&rcm_eventq_cv);
- (void) mutex_unlock(&rcm_eventq_lock);
-}
-
-/*
- * Generate an nvlist using the information given in node and minor_name.
- * If minor_name is NULL the nvlist will contain information on
- * all minor nodes. Otherwise the nvlist will contain information
- * only on the given minor_name. Notify RCM passing the nvlist.
- *
- * Return 0 upon successfully notifying RCM, errno on failure.
- */
-static int
-notify_rcm(di_node_t node, char *minor_name)
-{
- nvlist_t *nvl = NULL;
- char *path, *driver_name;
- char *node_name;
- int err;
- int32_t instance;
- di_minor_t minor;
-
- if ((driver_name = di_driver_name(node)) == NULL)
- driver_name = "";
-
- instance = (int32_t)di_instance(node);
-
- if ((path = di_devfs_path(node)) == NULL) {
- err = errno;
- goto error;
- }
-
- if ((err = nvlist_alloc(&nvl, 0, 0)) != 0)
- goto error;
-
- if ((err = nvlist_add_string(nvl, RCM_NV_DRIVER_NAME, driver_name))
- != 0)
- goto error;
-
- if ((err = nvlist_add_int32(nvl, RCM_NV_INSTANCE, instance)) != 0)
- goto error;
-
- if ((node_name = di_node_name(node)) == NULL)
- node_name = "";
- if ((err = nvlist_add_string(nvl, RCM_NV_NODE_NAME, node_name)) != 0)
- goto error;
-
- if ((err = nvlist_add_string(nvl, RCM_NV_DEVFS_PATH, path)) != 0)
- goto error;
-
- minor = di_minor_next(node, DI_MINOR_NIL);
- while (minor != DI_MINOR_NIL) {
- if ((minor_name == NULL) ||
- (strcmp(minor_name, di_minor_name(minor)) == 0)) {
- if ((err = add_minor_data_to_nvl(nvl, minor)) != 0)
- goto error;
- }
- minor = di_minor_next(node, minor);
- }
-
- enqueue_rcm_event(nvl);
- di_devfs_path_free(path);
- return (0);
-
-error:
- err_print(RCM_NVLIST_BUILD_ERROR, ((path != NULL) ? path : "unknown"),
- driver_name, instance, strerror(err));
-
- if (path)
- di_devfs_path_free(path);
- if (nvl)
- nvlist_free(nvl);
- return (err);
-}
-
-/*
* Add the specified property to nvl.
* Returns:
* 0 successfully added
diff --git a/usr/src/cmd/devfsadm/devfsadm_impl.h b/usr/src/cmd/devfsadm/devfsadm_impl.h
index 40d05e414b..4f27eb1b3a 100644
--- a/usr/src/cmd/devfsadm/devfsadm_impl.h
+++ b/usr/src/cmd/devfsadm/devfsadm_impl.h
@@ -25,8 +25,6 @@
#ifndef _DEVFSADM_IMPL_H
#define _DEVFSADM_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -70,7 +68,6 @@ extern "C" {
#include <thread.h>
#include <message.h>
#include <sys/cladm.h>
-#include <librcm.h>
#include <sys/sysevent/dev.h>
#include <libzonecfg.h>
#include <device_info.h>
@@ -352,12 +349,6 @@ struct dca_impl {
int dci_flags;
};
-/* RCM related */
-struct rcm_eventq {
- nvlist_t *nvl;
- struct rcm_eventq *next;
-};
-
/* sysevent queue related */
typedef struct syseventq_s {
struct syseventq_s *next;
@@ -478,8 +469,6 @@ static void sync_handler(void *cookie, char *ap, size_t asize,
static int zone_pathcheck(char *checkpath);
static void process_deferred_links(struct dca_impl *dcip, int flag);
static void event_handler(sysevent_t *ev);
-static int rcm_init(void);
-static int notify_rcm(di_node_t node, char *minor_name);
static void dca_impl_init(char *root, char *minor, struct dca_impl *dcip);
static void lock_dev(void);
static void unlock_dev(int flag);
@@ -490,10 +479,6 @@ int load_devpolicy(void);
static void load_dev_acl(void);
static void load_minor_perm_file(void);
-static int (*librcm_alloc_handle)(char *, uint_t, void *, rcm_handle_t **);
-static void (*librcm_free_handle)(rcm_handle_t *);
-static int (*librcm_notify_event)(rcm_handle_t *, char *, uint_t, nvlist_t *,
- rcm_info_t *);
static nvlist_t *build_event_attributes(char *, char *, char *,
di_node_t, char *, int, char *);
static void log_event(char *, char *, nvlist_t *);
diff --git a/usr/src/cmd/devfsadm/message.h b/usr/src/cmd/devfsadm/message.h
index 60f790293d..d3edbb6dd3 100644
--- a/usr/src/cmd/devfsadm/message.h
+++ b/usr/src/cmd/devfsadm/message.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _MESSAGE_H
#define _MESSAGE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -218,18 +216,6 @@ major_number ]\n\t\t[ -n ]\n\t\t[ -r rootdir ]\n\t\t[ -v ]\n")
#define INVOKED_WITH gettext("invoked with %s\n")
-#define MISSING_SYMBOLS gettext("missing symbols in %s\n")
-
-#define RCM_ALLOC_HANDLE_ERROR gettext("Unable to allocate rcm handle\n")
-
-#define RCM_NOTIFY_FAILED \
- gettext("RCM notification failed: " \
- "path = %s, driver = %s, instance = %d: %s\n")
-
-#define RCM_NVLIST_BUILD_ERROR \
- gettext("failed to build nvlist for notifying RCM: " \
- "path = %s, driver = %s, instance = %d: %s\n")
-
#define INVALID_DEVLINK_SPEC gettext("Invalid devlink spec: '%s'\n")
#define DRV_LOAD_REQD gettext("-n option cannot be used with -i. Ignoring\n")
diff --git a/usr/src/cmd/dlmgmtd/Makefile b/usr/src/cmd/dlmgmtd/Makefile
index 2e117d884e..baef35c3f8 100644
--- a/usr/src/cmd/dlmgmtd/Makefile
+++ b/usr/src/cmd/dlmgmtd/Makefile
@@ -22,8 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
PROG= dlmgmtd
OBJS= dlmgmt_main.o dlmgmt_door.o dlmgmt_util.o dlmgmt_db.o
@@ -42,7 +40,7 @@ $(ROOTCFGFILES) := OWNER= dladm
$(ROOTCFGFILES) := GROUP= sys
$(ROOTCFGDIR)/datalink.conf := FILEMODE= 644
-LDLIBS += -ldladm -ldlpi -lavl
+LDLIBS += -ldladm -ldlpi -lavl -lnvpair -lsysevent
.KEEP_STATE:
diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_db.c b/usr/src/cmd/dlmgmtd/dlmgmt_db.c
index 013deaf388..e65722613b 100644
--- a/usr/src/cmd/dlmgmtd/dlmgmt_db.c
+++ b/usr/src/cmd/dlmgmtd/dlmgmt_db.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -648,10 +646,13 @@ process_db_write(dlmgmt_db_req_t *req, FILE *fp, FILE *nfp)
process_link_line(buf, &link_in_file)) {
if (link_in_file == NULL || done) {
/*
- * this is a comment line, write it out.
+ * this is a comment line or we are done updating the
+ * link of the given link, write the rest of lines out.
*/
if (fputs(buf, nfp) == EOF)
err = errno;
+ if (link_in_file != NULL)
+ link_destroy(link_in_file);
continue;
}
diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c
index 50892004a9..8e1a1d9cd3 100644
--- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c
+++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Main door handler functions used by dlmgmtd to process the different door
* call requests. Door call requests can come from the user-land applications,
@@ -38,7 +36,11 @@
#include <priv_utils.h>
#include <stdlib.h>
#include <strings.h>
+#include <syslog.h>
+#include <sys/sysevent/eventdefs.h>
+#include <libsysevent.h>
#include <libdlmgmt.h>
+#include <librcm.h>
#include "dlmgmt_impl.h"
typedef void dlmgmt_door_handler_t(void *, void *);
@@ -67,6 +69,35 @@ dlmgmt_getlink_by_dev(char *devname)
return (NULL);
}
+/*
+ * Post the EC_DATALINK sysevent for the given linkid. This sysevent will
+ * be consumed by the datalink sysevent module.
+ */
+static void
+dlmgmt_post_sysevent(const char *subclass, datalink_id_t linkid)
+{
+ nvlist_t *nvl = NULL;
+ sysevent_id_t eid;
+ int err;
+
+ if (((err = nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0)) != 0) ||
+ ((err = nvlist_add_uint64(nvl, RCM_NV_LINKID, linkid)) != 0)) {
+ goto done;
+ }
+
+ if (sysevent_post_event(EC_DATALINK, (char *)subclass, SUNW_VENDOR,
+ (char *)progname, nvl, &eid) == -1) {
+ err = errno;
+ }
+
+done:
+ if (err != 0) {
+ dlmgmt_log(LOG_WARNING, "dlmgmt_post_sysevent(%d) failed: %s",
+ linkid, strerror(err));
+ }
+ nvlist_free(nvl);
+}
+
static void
dlmgmt_upcall_create(void *argp, void *retp)
{
@@ -165,8 +196,18 @@ done:
if (err == 0)
retvalp->lr_linkid = linkp->ll_linkid;
- retvalp->lr_err = err;
dlmgmt_table_unlock();
+
+ if (err == 0) {
+ /*
+ * Post the ESC_DATALINK_PHYS_ADD sysevent. This sysevent
+ * is consumed by the datalink sysevent module which in
+ * turn generates the RCM_RESOURCE_LINK_NEW RCM event.
+ */
+ dlmgmt_post_sysevent(ESC_DATALINK_PHYS_ADD, retvalp->lr_linkid);
+ }
+
+ retvalp->lr_err = err;
}
static void
diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_main.c b/usr/src/cmd/dlmgmtd/dlmgmt_main.c
index 43e627d4f0..15472f670d 100644
--- a/usr/src/cmd/dlmgmtd/dlmgmt_main.c
+++ b/usr/src/cmd/dlmgmtd/dlmgmt_main.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* The dlmgmtd daemon is started by the datalink-management SMF service.
* This daemon is used to manage <link name, linkid> mapping and the
@@ -251,8 +249,11 @@ dlmgmt_init_privileges()
if ((dld_control_fd = open(DLD_CONTROL_DEV, O_RDWR)) < 0)
return (errno);
+ /*
+ * The PRIV_SYS_CONFIG privilege is needed to post sysevents.
+ */
if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, UID_DLADM,
- GID_SYS, PRIV_SYS_NET_CONFIG, NULL) == -1) {
+ GID_SYS, PRIV_SYS_NET_CONFIG, PRIV_SYS_CONFIG, NULL) == -1) {
(void) close(dld_control_fd);
dld_control_fd = -1;
return (EPERM);
diff --git a/usr/src/cmd/rcm_daemon/common/network_rcm.c b/usr/src/cmd/rcm_daemon/common/network_rcm.c
index 406eb4ff03..b3199ed936 100644
--- a/usr/src/cmd/rcm_daemon/common/network_rcm.c
+++ b/usr/src/cmd/rcm_daemon/common/network_rcm.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* This RCM module adds support to the RCM framework for an abstract
* namespace for network devices (DLPI providers).
@@ -56,20 +54,6 @@
#define CACHE_STALE 1 /* flags */
#define CACHE_NEW 2 /* flags */
-/* devfsadm attach nvpair values */
-#define PROP_NV_DDI_NETWORK "ddi_network"
-
-/*
- * Global NIC list to be configured after DR-attach
- */
-struct ni_list {
- struct ni_list *next;
- char dev[MAXNAMELEN]; /* device instance name (le0, ie0, etc.) */
-};
-
-static struct ni_list *nil_head = NULL; /* Global new if list */
-static mutex_t nil_lock; /* NIC list lock */
-
/* operations */
#define NET_OFFLINE 1
#define NET_ONLINE 2
@@ -91,12 +75,6 @@ static net_cache_t cache_tail;
static mutex_t cache_lock;
static int events_registered = 0;
-struct devfs_minor_data {
- int32_t minor_type;
- char *minor_name;
- char *minor_node_type;
-};
-
/* module interface routines */
static int net_register(rcm_handle_t *);
static int net_unregister(rcm_handle_t *);
@@ -123,9 +101,6 @@ static void cache_remove(net_cache_t *node);
static net_cache_t *cache_lookup(const char *resource);
static void free_node(net_cache_t *);
static void cache_insert(net_cache_t *);
-static int notify_new_link(rcm_handle_t *, const char *);
-static void process_minor(char *, int, struct devfs_minor_data *);
-static int process_nvlist(rcm_handle_t *, nvlist_t *);
/*
* Module-Private data
@@ -210,15 +185,15 @@ net_register(rcm_handle_t *hd)
* getting attached, so we get attach event notifications
*/
if (!events_registered) {
- if (rcm_register_event(hd, RCM_RESOURCE_NETWORK_NEW, 0, NULL)
+ if (rcm_register_event(hd, RCM_RESOURCE_LINK_NEW, 0, NULL)
!= RCM_SUCCESS) {
rcm_log_message(RCM_ERROR,
_("NET: failed to register %s\n"),
- RCM_RESOURCE_NETWORK_NEW);
+ RCM_RESOURCE_LINK_NEW);
return (RCM_FAILURE);
} else {
rcm_log_message(RCM_DEBUG, _("NET: registered %s\n"),
- RCM_RESOURCE_NETWORK_NEW);
+ RCM_RESOURCE_LINK_NEW);
events_registered++;
}
}
@@ -256,15 +231,15 @@ net_unregister(rcm_handle_t *hd)
* Need to unregister interest in all new resources
*/
if (events_registered) {
- if (rcm_unregister_event(hd, RCM_RESOURCE_NETWORK_NEW, 0)
+ if (rcm_unregister_event(hd, RCM_RESOURCE_LINK_NEW, 0)
!= RCM_SUCCESS) {
rcm_log_message(RCM_ERROR,
_("NET: failed to unregister %s\n"),
- RCM_RESOURCE_NETWORK_NEW);
+ RCM_RESOURCE_LINK_NEW);
return (RCM_FAILURE);
} else {
rcm_log_message(RCM_DEBUG, _("NET: unregistered %s\n"),
- RCM_RESOURCE_NETWORK_NEW);
+ RCM_RESOURCE_LINK_NEW);
events_registered--;
}
}
@@ -821,22 +796,16 @@ free_cache(void)
* net_notify_event - Project private implementation to receive new
* resource events. It intercepts all new resource
* events. If the new resource is a network resource,
- * pass up a event for the resource. The new resource
- * need not be cached, since it is done at register again.
+ * update the physical link cache.
*/
/*ARGSUSED*/
static int
net_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
char **errorp, nvlist_t *nvl, rcm_info_t **depend_info)
{
- assert(hd != NULL);
- assert(rsrc != NULL);
- assert(id == (id_t)0);
- assert(nvl != NULL);
-
rcm_log_message(RCM_TRACE1, _("NET: notify_event(%s)\n"), rsrc);
- if (strcmp(rsrc, RCM_RESOURCE_NETWORK_NEW) != 0) {
+ if (strcmp(rsrc, RCM_RESOURCE_LINK_NEW) != 0) {
rcm_log_message(RCM_INFO,
_("NET: unrecognized event for %s\n"), rsrc);
errno = EINVAL;
@@ -846,254 +815,8 @@ net_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
/* Update cache to reflect latest physical links */
update_cache(hd);
- /* Process the nvlist for the event */
- if (process_nvlist(hd, nvl) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: Error processing resource attributes(%s)\n"), rsrc);
- rcm_log_message(RCM_WARNING,
- _("NET: One or more devices may not be configured.\n"));
- }
-
rcm_log_message(RCM_TRACE1,
_("NET: notify_event: device configuration complete\n"));
return (RCM_SUCCESS);
}
-
-/*
- * process_nvlist() - Determine network interfaces on a new attach by
- * processing the nvlist
- */
-static int
-process_nvlist(rcm_handle_t *hd, nvlist_t *nvl)
-{
- nvpair_t *nvp = NULL;
- char *driver;
- char *devfspath;
- int32_t instance;
- char *minor_byte_array; /* packed nvlist of minor_data */
- uint_t nminor; /* # of minor nodes */
- struct devfs_minor_data *mdata;
- nvlist_t *mnvl;
- nvpair_t *mnvp = NULL;
- struct ni_list *nilp, *next;
-
- rcm_log_message(RCM_TRACE1, "NET: process_nvlist\n");
-
- while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
- /* Get driver name */
- if (strcmp(nvpair_name(nvp), RCM_NV_DRIVER_NAME) == 0) {
- if (nvpair_value_string(nvp, &driver) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get driver name\n"));
- return (-1);
- }
- }
- /* Get instance */
- if (strcmp(nvpair_name(nvp), RCM_NV_INSTANCE) == 0) {
- if (nvpair_value_int32(nvp, &instance) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get device instance\n"));
- return (-1);
- }
- }
- /* Get devfspath */
- if (strcmp(nvpair_name(nvp), RCM_NV_DEVFS_PATH) == 0) {
- if (nvpair_value_string(nvp, &devfspath) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get device path\n"));
- return (-1);
- }
- if (strncmp("/pseudo", devfspath,
- strlen("/pseudo")) == 0) {
- /* Ignore pseudo devices, not really NICs */
- rcm_log_message(RCM_DEBUG,
- _("NET: ignoring pseudo device %s\n"),
- devfspath);
- return (0);
- }
- }
-
- /* Get minor data */
- if (strcmp(nvpair_name(nvp), RCM_NV_MINOR_DATA) == 0) {
- if (nvpair_value_byte_array(nvp,
- (uchar_t **)&minor_byte_array, &nminor) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get device minor data\n"));
- return (-1);
- }
- if (nvlist_unpack(minor_byte_array,
- nminor, &mnvl, 0) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get minor node data\n"));
- return (-1);
- }
- mdata = (struct devfs_minor_data *)calloc(1,
- sizeof (struct devfs_minor_data));
- if (mdata == NULL) {
- rcm_log_message(RCM_WARNING,
- _("NET: calloc error(%s)\n"),
- strerror(errno));
- nvlist_free(mnvl);
- return (-1);
- }
- /* Enumerate minor node data */
- while ((mnvp = nvlist_next_nvpair(mnvl, mnvp)) !=
- NULL) {
- /* Get minor type */
- if (strcmp(nvpair_name(mnvp),
- RCM_NV_MINOR_TYPE) == 0) {
- if (nvpair_value_int32(mnvp,
- &mdata->minor_type) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get minor "
- "type \n"));
- nvlist_free(mnvl);
- return (-1);
- }
- }
- /* Get minor name */
- if (strcmp(nvpair_name(mnvp),
- RCM_NV_MINOR_NAME) == 0) {
- if (nvpair_value_string(mnvp,
- &mdata->minor_name) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get minor "
- "name \n"));
- nvlist_free(mnvl);
- return (-1);
- }
- }
- /* Get minor node type */
- if (strcmp(nvpair_name(mnvp),
- RCM_NV_MINOR_NODE_TYPE) == 0) {
- if (nvpair_value_string(mnvp,
- &mdata->minor_node_type) != 0) {
- rcm_log_message(RCM_WARNING,
- _("NET: cannot get minor "
- "node type \n"));
- nvlist_free(mnvl);
- return (-1);
- }
- }
- }
- (void) process_minor(driver, instance, mdata);
- nvlist_free(mnvl);
- }
- }
-
- (void) mutex_lock(&nil_lock);
-
- /* Notify the event for all new devices found, then clean up the list */
- for (nilp = nil_head; nilp != NULL; nilp = next) {
- if (notify_new_link(hd, nilp->dev) != 0) {
- rcm_log_message(RCM_ERROR,
- _(": Notify %s event failed (%s)\n"),
- RCM_RESOURCE_LINK_NEW, nilp->dev);
- }
- next = nilp->next;
- free(nilp);
- }
- nil_head = NULL;
-
- (void) mutex_unlock(&nil_lock);
-
- rcm_log_message(RCM_TRACE1, _("NET: process_nvlist success\n"));
- return (0);
-}
-
-static void
-process_minor(char *name, int instance, struct devfs_minor_data *mdata)
-{
- char dev[MAXNAMELEN];
- struct ni_list **pp;
- struct ni_list *p;
-
- rcm_log_message(RCM_TRACE1, _("NET: process_minor %s%d\n"),
- name, instance);
-
- if ((mdata->minor_node_type != NULL) &&
- strcmp(mdata->minor_node_type, PROP_NV_DDI_NETWORK) != 0) {
- /* Process network devices only */
- return;
- }
-
- (void) snprintf(dev, sizeof (dev), "%s%d", name, instance);
-
- /* Add new interface to the list */
- (void) mutex_lock(&nil_lock);
- for (pp = &nil_head; (p = *pp) != NULL; pp = &(p->next)) {
- if (strcmp(dev, p->dev) == 0)
- break;
- }
- if (p != NULL) {
- rcm_log_message(RCM_TRACE1,
- _("NET: secondary node - ignoring\n"));
- goto done;
- }
-
- /* Add new device to the list */
- if ((p = malloc(sizeof (struct ni_list))) == NULL) {
- rcm_log_message(RCM_ERROR, _("NET: malloc failure(%s)\n"),
- strerror(errno));
- goto done;
- }
- (void) strncpy(p->dev, dev, sizeof (p->dev));
- p->next = NULL;
- *pp = p;
-
- rcm_log_message(RCM_TRACE1, _("NET: added new node %s\n"), dev);
-done:
- (void) mutex_unlock(&nil_lock);
-}
-
-/*
- * Notify the RCM_RESOURCE_LINK_NEW event to other modules.
- * Return 0 on success, -1 on failure.
- */
-static int
-notify_new_link(rcm_handle_t *hd, const char *dev)
-{
- nvlist_t *nvl = NULL;
- datalink_id_t linkid;
- uint64_t id;
- int ret = -1;
-
- rcm_log_message(RCM_TRACE1, _("NET: notify_new_link %s\n"), dev);
- if (dladm_dev2linkid(dev, &linkid) != DLADM_STATUS_OK) {
- rcm_log_message(RCM_TRACE1,
- _("NET: new link %s has not attached yet\n"), dev);
- ret = 0;
- goto done;
- }
-
- id = linkid;
- if ((nvlist_alloc(&nvl, 0, 0) != 0) ||
- (nvlist_add_uint64(nvl, RCM_NV_LINKID, id) != 0)) {
- rcm_log_message(RCM_ERROR,
- _("NET: failed to construct nvlist for %s\n"), dev);
- goto done;
- }
-
- /*
- * Reset the active linkprop of this specific link.
- */
- (void) dladm_init_linkprop(linkid, B_FALSE);
-
- rcm_log_message(RCM_TRACE1, _("NET: notify new link %u (%s)\n"),
- linkid, dev);
-
- if (rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW, 0, nvl, NULL) !=
- RCM_SUCCESS) {
- rcm_log_message(RCM_ERROR,
- _("NET: failed to notify %s event for %s\n"),
- RCM_RESOURCE_LINK_NEW, dev);
- goto done;
- }
-
- ret = 0;
-done:
- if (nvl != NULL)
- nvlist_free(nvl);
- return (ret);
-}
diff --git a/usr/src/cmd/syseventd/modules/Makefile b/usr/src/cmd/syseventd/modules/Makefile
index f54659eab3..f1e8b25e00 100644
--- a/usr/src/cmd/syseventd/modules/Makefile
+++ b/usr/src/cmd/syseventd/modules/Makefile
@@ -19,9 +19,7 @@
# CDDL HEADER END
#
#
-#ident "%Z%%M% %I% %E% SMI"
-#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/syseventd/modules/Makefile
@@ -30,6 +28,7 @@
.PARALLEL:
SUBDIRS= \
+ datalink_mod \
devfsadmd_mod \
sysevent_conf_mod \
sysevent_reg_mod \
diff --git a/usr/src/cmd/syseventd/modules/datalink_mod/Makefile b/usr/src/cmd/syseventd/modules/datalink_mod/Makefile
new file mode 100644
index 0000000000..5c847665ae
--- /dev/null
+++ b/usr/src/cmd/syseventd/modules/datalink_mod/Makefile
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY= datalink_mod
+
+include ../Makefile.com
+
+LDLIBS += -lnvpair -lrcm
+
+.KEEP_STATE:
+
+all: $(DYNLIB)
+
+install: all \
+ $(ROOTLIBSYSEVENTDIR) \
+ $(ROOTLIBDIR) \
+ $(ROOTLIBS)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/syseventd/modules/datalink_mod/datalink_mod.c b/usr/src/cmd/syseventd/modules/datalink_mod/datalink_mod.c
new file mode 100644
index 0000000000..520b68226f
--- /dev/null
+++ b/usr/src/cmd/syseventd/modules/datalink_mod/datalink_mod.c
@@ -0,0 +1,89 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * datalink syseventd module.
+ *
+ * The purpose of this module is to identify all datalink related events,
+ * and react accordingly.
+ */
+
+#include <errno.h>
+#include <sys/sysevent/eventdefs.h>
+#include <string.h>
+#include <libnvpair.h>
+#include <librcm.h>
+#include <libsysevent.h>
+
+static rcm_handle_t *rcm_hdl = NULL;
+
+/*ARGSUSED*/
+static int
+datalink_deliver_event(sysevent_t *ev, int unused)
+{
+ const char *class = sysevent_get_class_name(ev);
+ const char *subclass = sysevent_get_subclass_name(ev);
+ nvlist_t *nvl;
+ int err = 0;
+
+ if (strcmp(class, EC_DATALINK) != 0 ||
+ strcmp(subclass, ESC_DATALINK_PHYS_ADD) != 0) {
+ return (0);
+ }
+
+ if (sysevent_get_attr_list(ev, &nvl) != 0)
+ return (EINVAL);
+
+ if (rcm_notify_event(rcm_hdl, RCM_RESOURCE_LINK_NEW, 0, nvl, NULL) !=
+ RCM_SUCCESS) {
+ err = EINVAL;
+ }
+
+ nvlist_free(nvl);
+ return (err);
+}
+
+static struct slm_mod_ops datalink_mod_ops = {
+ SE_MAJOR_VERSION,
+ SE_MINOR_VERSION,
+ SE_MAX_RETRY_LIMIT,
+ datalink_deliver_event
+};
+
+struct slm_mod_ops *
+slm_init()
+{
+ if (rcm_alloc_handle(NULL, 0, NULL, &rcm_hdl) != RCM_SUCCESS)
+ return (NULL);
+
+ return (&datalink_mod_ops);
+}
+
+void
+slm_fini()
+{
+ (void) rcm_free_handle(rcm_hdl);
+ rcm_hdl = NULL;
+}
diff --git a/usr/src/lib/libdevinfo/device_info.h b/usr/src/lib/libdevinfo/device_info.h
index d53a5b86f8..32e65ac8d8 100644
--- a/usr/src/lib/libdevinfo/device_info.h
+++ b/usr/src/lib/libdevinfo/device_info.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,8 +33,6 @@
#ifndef _DEVICE_INFO_H
#define _DEVICE_INFO_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -179,7 +177,7 @@ extern int devfs_rm_minor_perm(char *, void (*)(minorperm_err_t, int));
#define DCA_FREE_LIST 0x000000002
#define DCA_LOAD_DRV 0x000000004
#define DCA_CHECK_TYPE 0x000000010
-#define DCA_NOTIFY_RCM 0x000000020
+/* UNUSED was DCA_NOTIFY_RCM 0x000000020 (can be recycled) */
#define DCA_FLUSH_PATHINST 0x000000040
#define DCA_HOT_PLUG 0x000000080
#define DCA_DEVLINK_SYNC 0x000000100
diff --git a/usr/src/lib/librcm/librcm.h b/usr/src/lib/librcm/librcm.h
index 49ca304a08..6cd4c91409 100644
--- a/usr/src/lib/librcm/librcm.h
+++ b/usr/src/lib/librcm/librcm.h
@@ -26,8 +26,6 @@
#ifndef _LIBRCM_H
#define _LIBRCM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <libnvpair.h>
#include <sys/types.h>
#include <sys/processor.h>
@@ -97,20 +95,10 @@ extern "C" {
#define RCM_CLIENT_NAME "rcm.client_name"
#define RCM_CLIENT_EXPORTS "rcm.client_exports"
-/* Resource name to register for new resources */
-#define RCM_RESOURCE_NETWORK_NEW "SUNW_event/resource/new/network"
/* Resource name to register for new links come up */
#define RCM_RESOURCE_LINK_NEW "SUNW_event/resource/new/link"
/* name-value pair definitions for rcm_notify_event() */
-#define RCM_NV_DRIVER_NAME "driver_name"
-#define RCM_NV_INSTANCE "instance"
-#define RCM_NV_NODE_NAME "node_name"
-#define RCM_NV_DEVFS_PATH "devfs_path"
-#define RCM_NV_MINOR_DATA "minor_data"
-#define RCM_NV_MINOR_TYPE "minor_type"
-#define RCM_NV_MINOR_NAME "minor_name"
-#define RCM_NV_MINOR_NODE_TYPE "minor_node_type"
#define RCM_NV_LINKID "linkid"
/*
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_com b/usr/src/pkgdefs/SUNWcsu/prototype_com
index 1705cd5a93..22506a1f15 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_com
@@ -22,8 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# This required package information file contains a list of package contents.
# The 'pkgmk' command uses this file to identify the contents of a package
# and their location on the development machine when building the package.
@@ -677,6 +675,7 @@ s none usr/lib/secure/32=.
d none usr/lib/security 755 root bin
d none usr/lib/sysevent 755 root bin
d none usr/lib/sysevent/modules 755 root bin
+f none usr/lib/sysevent/modules/datalink_mod.so 755 root bin
f none usr/lib/sysevent/modules/devfsadmd_mod.so 755 root bin
f none usr/lib/sysevent/modules/sysevent_conf_mod.so 755 root bin
f none usr/lib/sysevent/modules/sysevent_reg_mod.so 755 root bin
diff --git a/usr/src/uts/common/io/softmac/softmac_main.c b/usr/src/uts/common/io/softmac/softmac_main.c
index 5cdc70db12..d325e3b4c6 100644
--- a/usr/src/uts/common/io/softmac/softmac_main.c
+++ b/usr/src/uts/common/io/softmac/softmac_main.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* The softmac driver is used to "unify" non-GLDv3 drivers to the GLDv3
* framework. It also creates the kernel datalink structure for each
@@ -63,7 +61,8 @@ static mod_hash_t *softmac_hash;
#define SOFTMAC_HASHSZ 64
-static void softmac_mac_register(void *);
+static void softmac_create_task(void *);
+static void softmac_mac_register(softmac_t *);
static int softmac_create_datalink(softmac_t *);
static int softmac_m_start(void *);
static void softmac_m_stop(void *);
@@ -147,10 +146,8 @@ softmac_create(dev_info_t *dip, dev_t dev)
char devname[MAXNAMELEN];
softmac_t *softmac;
softmac_dev_t *softmac_dev = NULL;
- datalink_id_t linkid;
int index;
int ppa, err = 0;
- mac_handle_t mh;
/*
* Force the softmac driver to be attached.
@@ -264,14 +261,6 @@ softmac_create(dev_info_t *dip, dev_t dev)
rw_exit(&softmac_hash_lock);
/*
- * Inform dlmgmtd of this link so that softmac_hold_device() is able
- * to know the existence of this link. This could fail if dlmgmtd
- * is not yet started.
- */
- (void) dls_mgmt_create(devname, makedevice(ddi_driver_major(dip),
- ppa + 1), DATALINK_CLASS_PHYS, DL_OTHER, B_TRUE, &linkid);
-
- /*
* No lock is needed for access this softmac pointer, as pre-detach and
* post-attach won't happen at the same time.
*/
@@ -290,58 +279,26 @@ softmac_create(dev_info_t *dip, dev_t dev)
return (0);
}
- if (!GLDV3_DRV(ddi_driver_major(dip))) {
-
- /*
- * Note that this function could be called as a result of
- * a open() system call, and spec_open() already locked the
- * snode (SLOCKED is set). Therefore, we must start a
- * taskq to finish the rest of work to sidestep the risk
- * that our ldi_open_by_dev() call would again try to hold
- * the same lock.
- *
- * If all the minor nodes have been attached, start the taskq
- * to finish the rest of the work.
- */
- ASSERT(softmac->smac_taskq == NULL);
- softmac->smac_taskq = taskq_dispatch(system_taskq,
- softmac_mac_register, softmac, TQ_SLEEP);
- mutex_exit(&softmac->smac_mutex);
- return (0);
- }
-
- if ((err = mac_open(softmac->smac_devname, &mh)) != 0)
- goto done;
-
- softmac->smac_media = (mac_info(mh))->mi_nativemedia;
- softmac->smac_mh = mh;
-
- /*
- * We can safely release the reference on the mac because
- * this mac will only be unregistered and destroyed when
- * the device detaches, and the softmac will be destroyed
- * before then (in the pre-detach routine of the device).
- */
- mac_close(mh);
-
/*
- * Create the GLDv3 datalink for this mac.
+ * All of the minor nodes have been attached; start a taskq
+ * to do the rest of the work. We use a taskq instead of of
+ * doing the work here because:
+ *
+ * - We could be called as a result of an open() system call
+ * where spec_open() already SLOCKED the snode. Using a taskq
+ * sidesteps the risk that our ldi_open_by_dev() call would
+ * deadlock trying to set SLOCKED on the snode again.
+ *
+ * - The devfs design requires no interruptible function calls
+ * in the device post-attach routine, but we need to make an
+ * (interruptible) upcall. Using a taskq to make the upcall
+ * sidesteps this.
*/
- err = softmac_create_datalink(softmac);
-
-done:
- if (err != 0) {
- softmac->smac_mh = NULL;
- kmem_free(softmac_dev, sizeof (softmac_dev_t));
- softmac->smac_softmac[index] = NULL;
- --softmac->smac_attachok_cnt;
- }
- ASSERT(!(softmac->smac_flags & SOFTMAC_ATTACH_DONE));
- softmac->smac_flags |= SOFTMAC_ATTACH_DONE;
- softmac->smac_attacherr = err;
- cv_broadcast(&softmac->smac_cv);
+ ASSERT(softmac->smac_taskq == NULL);
+ softmac->smac_taskq = taskq_dispatch(system_taskq,
+ softmac_create_task, softmac, TQ_SLEEP);
mutex_exit(&softmac->smac_mutex);
- return (err);
+ return (0);
}
static boolean_t
@@ -442,15 +399,23 @@ softmac_create_datalink(softmac_t *softmac)
ASSERT(MUTEX_HELD(&softmac->smac_mutex));
/*
- * First provide the media type of the physical link to dlmgmtd.
- *
- * If the new <linkname, linkid> mapping operation failed with EBADF
- * or ENOENT, it might because the dlmgmtd was not started in time
- * (e.g., diskless boot); ignore the failure and continue. The
- * mapping will be recreated once the daemon has started.
+ * Inform dlmgmtd of this link so that softmac_hold_device() is able
+ * to know the existence of this link. If this failed with EBADF,
+ * it might be because dlmgmtd was not started in time (e.g.,
+ * diskless boot); ignore the failure and continue to create
+ * the GLDv3 datalink if needed.
+ */
+ err = dls_mgmt_create(softmac->smac_devname,
+ makedevice(softmac->smac_umajor, softmac->smac_uppa + 1),
+ DATALINK_CLASS_PHYS, DL_OTHER, B_TRUE, &linkid);
+ if (err != 0 && err != EBADF)
+ return (err);
+
+ /*
+ * Provide the media type of the physical link to dlmgmtd.
*/
- if (((err = softmac_update_info(softmac, &linkid)) != 0) &&
- (err != EBADF) && (err != ENOENT)) {
+ if ((err != EBADF) &&
+ ((err = softmac_update_info(softmac, &linkid)) != 0)) {
return (err);
}
@@ -470,6 +435,47 @@ softmac_create_datalink(softmac_t *softmac)
return (0);
}
+static void
+softmac_create_task(void *arg)
+{
+ softmac_t *softmac = arg;
+ mac_handle_t mh;
+ int err;
+
+ if (!GLDV3_DRV(softmac->smac_umajor)) {
+ softmac_mac_register(softmac);
+ return;
+ }
+
+ if ((err = mac_open(softmac->smac_devname, &mh)) != 0)
+ goto done;
+
+ mutex_enter(&softmac->smac_mutex);
+ softmac->smac_media = (mac_info(mh))->mi_nativemedia;
+ softmac->smac_mh = mh;
+
+ /*
+ * We can safely release the reference on the mac because
+ * this mac will only be unregistered and destroyed when
+ * the device detaches, and the softmac will be destroyed
+ * before then (in the pre-detach routine of the device).
+ */
+ mac_close(mh);
+
+ /*
+ * Create the GLDv3 datalink for this mac.
+ */
+ err = softmac_create_datalink(softmac);
+
+done:
+ ASSERT(!(softmac->smac_flags & SOFTMAC_ATTACH_DONE));
+ softmac->smac_flags |= SOFTMAC_ATTACH_DONE;
+ softmac->smac_attacherr = err;
+ softmac->smac_taskq = NULL;
+ cv_broadcast(&softmac->smac_cv);
+ mutex_exit(&softmac->smac_mutex);
+}
+
/*
* This function is only called for legacy devices. It:
* 1. registers the MAC for the legacy devices whose media type is supported
@@ -477,9 +483,8 @@ softmac_create_datalink(softmac_t *softmac)
* 2. creates the GLDv3 datalink if the media type is supported by GLDv3.
*/
static void
-softmac_mac_register(void *arg)
+softmac_mac_register(softmac_t *softmac)
{
- softmac_t *softmac = arg;
softmac_dev_t *softmac_dev;
dev_t dev;
ldi_handle_t lh = NULL;
diff --git a/usr/src/uts/common/sys/sysevent/eventdefs.h b/usr/src/uts/common/sys/sysevent/eventdefs.h
index 71565d933c..ac21686e84 100644
--- a/usr/src/uts/common/sys/sysevent/eventdefs.h
+++ b/usr/src/uts/common/sys/sysevent/eventdefs.h
@@ -26,8 +26,6 @@
#ifndef _SYS_SYSEVENT_EVENTDEFS_H
#define _SYS_SYSEVENT_EVENTDEFS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -53,6 +51,7 @@ extern "C" {
#define EC_DEV_STATUS "EC_dev_status" /* device status event class */
#define EC_FM "EC_fm" /* FMA error report event */
#define EC_ZFS "EC_zfs" /* ZFS event */
+#define EC_DATALINK "EC_datalink" /* datalink event */
/*
* The following event class is reserved for exclusive use
@@ -236,6 +235,11 @@ extern "C" {
#define ESC_ZFS_VDEV_CHECK "ESC_ZFS_vdev_check"
#define ESC_ZFS_CONFIG_SYNC "ESC_ZFS_config_sync"
+/*
+ * datalink subclass definitions.
+ */
+#define ESC_DATALINK_PHYS_ADD "ESC_datalink_phys_add" /* new physical link */
+
#ifdef __cplusplus
}
#endif