summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fm/fmd/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/fm/fmd/common')
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd.c27
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd.h13
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd.logadm.conf27
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd.xml23
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_api.c216
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_api.h17
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_api.map8
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_builtin.c25
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_builtin.h17
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_case.c45
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_case.h5
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_dr.c2
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_idspace.c54
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_log.h11
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_main.c47
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_mdb.c7
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_module.c24
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_module.h7
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_rpc.c9
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c22
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_scheme.c12
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_self.c7
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_sysevent.c42
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_thread.c38
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_thread.h13
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_topo.c19
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_topo.h5
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_xprt.c54
28 files changed, 584 insertions, 212 deletions
diff --git a/usr/src/cmd/fm/fmd/common/fmd.c b/usr/src/cmd/fm/fmd/common/fmd.c
index 3d121f038f..8177c81049 100644
--- a/usr/src/cmd/fm/fmd/common/fmd.c
+++ b/usr/src/cmd/fm/fmd/common/fmd.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -239,6 +238,7 @@ static const fmd_conf_formal_t _fmd_conf[] = {
{ "client.buflim", &fmd_conf_size, "10m" }, /* client buffer space limit */
{ "client.dbout", &fmd_dbout_ops, NULL }, /* client debug output sinks */
{ "client.debug", &fmd_conf_bool, NULL }, /* client debug enable */
+{ "client.doorthrlim", &fmd_conf_uint32, "20" }, /* client door thread limit */
{ "client.error", &fmd_cerror_ops, "unload" }, /* client error policy */
{ "client.memlim", &fmd_conf_size, "10m" }, /* client allocation limit */
{ "client.evqlim", &fmd_conf_uint32, "256" }, /* client event queue limit */
@@ -265,6 +265,8 @@ static const fmd_conf_formal_t _fmd_conf[] = {
{ "log.creator", &fmd_conf_string, "fmd" }, /* exacct log creator string */
{ "log.error", &fmd_conf_string, "var/fm/fmd/errlog" }, /* error log path */
{ "log.fault", &fmd_conf_string, "var/fm/fmd/fltlog" }, /* fault log path */
+{ "log.info", &fmd_conf_string, "var/fm/fmd/infolog" }, /* info log path */
+{ "log.info_hival", &fmd_conf_string, "var/fm/fmd/infolog_hival" }, /* hi pri */
{ "log.minfree", &fmd_conf_size, "2m" }, /* min log fsys free space */
{ "log.rsrc", &fmd_conf_string, "var/fm/fmd/rsrc" }, /* asru log dir path */
{ "log.tryrotate", &fmd_conf_uint32, "10" }, /* max log rotation attempts */
@@ -425,6 +427,8 @@ fmd_create(fmd_t *dp, const char *arg0, const char *root, const char *conf)
(void) pthread_mutex_init(&dp->d_stats_lock, NULL);
(void) pthread_mutex_init(&dp->d_topo_lock, NULL);
(void) pthread_rwlock_init(&dp->d_log_lock, NULL);
+ (void) pthread_rwlock_init(&dp->d_hvilog_lock, NULL);
+ (void) pthread_rwlock_init(&dp->d_ilog_lock, NULL);
(void) pthread_mutex_init(&dp->d_fmd_lock, NULL);
(void) pthread_cond_init(&dp->d_fmd_cv, NULL);
@@ -695,6 +699,14 @@ fmd_gc(fmd_t *dp, id_t id, hrtime_t hrt)
(void) pthread_rwlock_rdlock(&dp->d_log_lock);
fmd_log_update(dp->d_errlog);
(void) pthread_rwlock_unlock(&dp->d_log_lock);
+
+ (void) pthread_rwlock_rdlock(&dp->d_hvilog_lock);
+ fmd_log_update(dp->d_hvilog);
+ (void) pthread_rwlock_unlock(&dp->d_hvilog_lock);
+
+ (void) pthread_rwlock_rdlock(&dp->d_ilog_lock);
+ fmd_log_update(dp->d_ilog);
+ (void) pthread_rwlock_unlock(&dp->d_ilog_lock);
}
(void) fmd_conf_getprop(dp->d_conf, "gc_interval", &delta);
@@ -771,6 +783,9 @@ fmd_door_server(void *dip)
/*
* Custom door server create callback. Any fmd services that use doors will
* require those threads to have their fmd-specific TSD initialized, etc.
+ * Modules should use door_xcreate and derivatives such as
+ * sysevent_evc_xsubscribe in order to use private doors that
+ * avoid this global door server function (see fmd_api_module comments).
*/
static void
fmd_door(door_info_t *dip)
@@ -896,6 +911,12 @@ fmd_run(fmd_t *dp, int pfd)
(void) fmd_conf_getprop(dp->d_conf, "log.fault", &name);
dp->d_fltlog = fmd_log_open(dp->d_rootdir, name, FMD_LOG_FAULT);
+ (void) fmd_conf_getprop(dp->d_conf, "log.info_hival", &name);
+ dp->d_hvilog = fmd_log_open(dp->d_rootdir, name, FMD_LOG_INFO);
+
+ (void) fmd_conf_getprop(dp->d_conf, "log.info", &name);
+ dp->d_ilog = fmd_log_open(dp->d_rootdir, name, FMD_LOG_INFO);
+
if (dp->d_asrus == NULL || dp->d_errlog == NULL || dp->d_fltlog == NULL)
fmd_error(EFMD_EXIT, "failed to initialize log files\n");
@@ -980,6 +1001,8 @@ fmd_run(fmd_t *dp, int pfd)
(void) fmd_conf_getprop(dp->d_conf, "agent.path", &pap);
fmd_modhash_loadall(dp->d_mod_hash, pap, &fmd_proc_ops, NULL);
+ dp->d_loaded = 1; /* modules are now loaded */
+
/*
* With all modules loaded, replay fault events from the ASRU cache for
* any ASRUs that must be retired, replay error events from the errlog
diff --git a/usr/src/cmd/fm/fmd/common/fmd.h b/usr/src/cmd/fm/fmd/common/fmd.h
index bbb1a9f535..272fa3c305 100644
--- a/usr/src/cmd/fm/fmd/common/fmd.h
+++ b/usr/src/cmd/fm/fmd/common/fmd.h
@@ -20,15 +20,12 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_H
#define _FMD_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <libnvpair.h>
#include <pthread.h>
@@ -70,6 +67,7 @@ typedef struct fmd {
pthread_key_t d_key; /* key for fmd's thread-specific data */
volatile int d_signal; /* signal indicating we should quit */
volatile int d_running; /* flag set when fmd_run() succeeds */
+ volatile int d_loaded; /* flag set when all modules loaded */
volatile int d_booted; /* flag set when fmd_run() completes */
uint_t d_fmd_debug; /* mask of fmd active debugging modes */
@@ -135,6 +133,13 @@ typedef struct fmd {
pthread_rwlock_t d_log_lock; /* log pointer lock (r=use, w=rotate) */
struct fmd_log *d_errlog; /* log file for error events */
struct fmd_log *d_fltlog; /* log file for fault events */
+
+ pthread_rwlock_t d_hvilog_lock; /* log pointer lock (r=use, w=rotate) */
+ struct fmd_log *d_hvilog; /* log file for hi value info events */
+
+ pthread_rwlock_t d_ilog_lock; /* log pointer lock (r=use, w=rotate) */
+ struct fmd_log *d_ilog; /* log file for info events */
+
pthread_cond_t d_fmd_cv; /* sync startup with rpc */
pthread_mutex_t d_fmd_lock; /* sync startup with rpc */
} fmd_t;
diff --git a/usr/src/cmd/fm/fmd/common/fmd.logadm.conf b/usr/src/cmd/fm/fmd/common/fmd.logadm.conf
new file mode 100644
index 0000000000..7452c6746b
--- /dev/null
+++ b/usr/src/cmd/fm/fmd/common/fmd.logadm.conf
@@ -0,0 +1,27 @@
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Entries to be added to /etc/logadm.conf by svc:/application/logadm-upgrade
+#
+/var/fm/fmd/infolog -N -A 2y -S 50m -s 10m -M '/usr/sbin/fmadm -q rotate infolog && mv /var/fm/fmd/infolog.0- $nfile'
+/var/fm/fmd/infolog_hival -N -A 2y -S 50m -s 10m -M '/usr/sbin/fmadm -q rotate infolog_hival && mv /var/fm/fmd/infolog_hival.0- $nfile'
+
diff --git a/usr/src/cmd/fm/fmd/common/fmd.xml b/usr/src/cmd/fm/fmd/common/fmd.xml
index b46fd72b19..e03bdc01a1 100644
--- a/usr/src/cmd/fm/fmd/common/fmd.xml
+++ b/usr/src/cmd/fm/fmd/common/fmd.xml
@@ -1,15 +1,13 @@
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
- Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- Use is subject to license terms.
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
CDDL HEADER START
The contents of this file are subject to the terms of the
- Common Development and Distribution License, Version 1.0 only
- (the "License"). You may not use this file except in compliance
- with the License.
+ 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.
@@ -24,8 +22,6 @@
CDDL HEADER END
- ident "%Z%%M% %I% %E% SMI"
-
NOTE: This service manifest is not editable; its contents will
be overwritten by package or patch operations, including
operating system upgrade. Make customizations in a different
@@ -61,10 +57,13 @@
<!--
Fault Manager Dependencies, Part 2
- fmd should be started after /var is mounted, syseventd and rpcbind
- are running, and dumpadm has initialized. It is resilient to the
- the failure and/or interruption of all, and therefore does not
- restart under any circumstance.
+ fmd should be started after /var is mounted and rpcbind is
+ running. It is resilient to the the failure and/or
+ interruption of rpcbind, and therefore does not restart under any
+ circumstance.
+
+ The dumpadm and sysevent services (global zone only) also list the
+ fmd service as a dependent, with restart_on='none' for both.
-->
<dependency
name='startup_req'
@@ -72,8 +71,6 @@
restart_on='none'
type='service'>
<service_fmri value='svc:/system/filesystem/minimal' />
- <service_fmri value='svc:/system/dumpadm' />
- <service_fmri value='svc:/system/sysevent' />
</dependency>
<dependency
diff --git a/usr/src/cmd/fm/fmd/common/fmd_api.c b/usr/src/cmd/fm/fmd/common/fmd_api.c
index e30a36ee51..008a55c90f 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_api.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_api.c
@@ -20,13 +20,13 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
#include <sys/fm/protocol.h>
#include <fm/topo_hc.h>
+#include <uuid/uuid.h>
#include <unistd.h>
#include <signal.h>
@@ -34,6 +34,7 @@
#include <syslog.h>
#include <alloca.h>
#include <stddef.h>
+#include <door.h>
#include <fmd_module.h>
#include <fmd_api.h>
@@ -237,10 +238,17 @@ fmd_api_module(fmd_hdl_t *hdl)
}
/*
- * If our TSD refers to the root module and is a door server thread,
- * then it was created asynchronously at the request of a module but
- * is using now the module API as an auxiliary module thread. We reset
- * tp->thr_mod to the module handle so it can act as a module thread.
+ * If our TSD refers to the root module and is a non-private
+ * door server thread, then it was created asynchronously at the
+ * request of a module but is using now the module API as an
+ * auxiliary module thread. We reset tp->thr_mod to the module
+ * handle so it can act as a module thread.
+ *
+ * If more than one module uses non-private doors then the
+ * "client handle is not valid" check below can fail since
+ * door server threads for such doors can service *any*
+ * non-private door. We use non-private door for legacy sysevent
+ * alone.
*/
if (tp->thr_mod == fmd.d_rmod && tp->thr_func == &fmd_door_server)
tp->thr_mod = (fmd_module_t *)hdl;
@@ -368,7 +376,7 @@ fmd_hdl_register(fmd_hdl_t *hdl, int version, const fmd_hdl_info_t *mip)
* the module thread to which we assigned this client handle. The info
* provided for the handle must be valid and have the minimal settings.
*/
- if (version > FMD_API_VERSION_4)
+ if (version > FMD_API_VERSION_5)
return (fmd_hdl_register_error(mp, EFMD_VER_NEW));
if (version < FMD_API_VERSION_1)
@@ -536,6 +544,25 @@ fmd_module_thrcancel(fmd_idspace_t *ids, id_t id, fmd_module_t *mp)
{
fmd_thread_t *tp = fmd_idspace_getspecific(ids, id);
+ /*
+ * Door service threads are not cancellable (worse - if they're
+ * waiting in door_return then that is interrupted, but they then spin
+ * endlessly!). Non-private door service threads are not tracked
+ * in the module thread idspace so it's only private server threads
+ * created via fmd_doorthr_create that we'll encounter. In most
+ * cases the module _fini should have tidied up (e.g., calling
+ * sysevent_evc_unbind which will cleanup door threads if
+ * sysevent_evc_xsubscribe was used). One case that does not
+ * clean up is sysev_fini which explicitly does not unbind the
+ * channel, so we must skip any remaining door threads here.
+ */
+ if (tp->thr_isdoor) {
+ fmd_dprintf(FMD_DBG_MOD, "not cancelling %s private door "
+ "thread %u\n", mp->mod_name, tp->thr_tid);
+ fmd_thread_destroy(tp, FMD_THREAD_NOJOIN);
+ return;
+ }
+
fmd_dprintf(FMD_DBG_MOD, "cancelling %s auxiliary thread %u\n",
mp->mod_name, tp->thr_tid);
@@ -1031,11 +1058,44 @@ fmd_case_t *
fmd_case_open(fmd_hdl_t *hdl, void *data)
{
fmd_module_t *mp = fmd_api_module_lock(hdl);
- fmd_case_t *cp = fmd_case_create(mp, data);
+ fmd_case_t *cp = fmd_case_create(mp, NULL, data);
fmd_module_unlock(mp);
return (cp);
}
+fmd_case_t *
+fmd_case_open_uuid(fmd_hdl_t *hdl, const char *uuidstr, void *data)
+{
+ fmd_module_t *mp;
+ fmd_case_t *cp;
+ uint_t uuidlen;
+ uuid_t uuid;
+
+ mp = fmd_api_module_lock(hdl);
+
+ (void) fmd_conf_getprop(fmd.d_conf, "uuidlen", &uuidlen);
+
+ if (uuidstr == NULL) {
+ fmd_api_error(mp, EFMD_CASE_INVAL, "NULL uuid string\n");
+ } else if (strnlen(uuidstr, uuidlen + 1) != uuidlen) {
+ fmd_api_error(mp, EFMD_CASE_INVAL, "invalid uuid string: '%s' "
+ "(expected length %d)\n", uuidstr, uuidlen);
+ } else if (uuid_parse((char *)uuidstr, uuid) == -1) {
+ fmd_api_error(mp, EFMD_CASE_INVAL, "cannot parse uuid string: "
+ "'%s'\n", uuidstr);
+ }
+
+ if ((cp = fmd_case_hash_lookup(fmd.d_cases, uuidstr)) == NULL) {
+ cp = fmd_case_create(mp, uuidstr, data);
+ } else {
+ fmd_case_rele(cp);
+ cp = NULL;
+ }
+
+ fmd_module_unlock(mp);
+ return (cp); /* May be NULL iff case already exists */
+}
+
void
fmd_case_reset(fmd_hdl_t *hdl, fmd_case_t *cp)
{
@@ -1157,6 +1217,23 @@ fmd_case_uuresolved(fmd_hdl_t *hdl, const char *uuid)
fmd_module_unlock(mp);
}
+int
+fmd_case_uuisresolved(fmd_hdl_t *hdl, const char *uuid)
+{
+ fmd_module_t *mp = fmd_api_module_lock(hdl);
+ fmd_case_t *cp = fmd_case_hash_lookup(fmd.d_cases, uuid);
+ fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
+ int rv = FMD_B_FALSE;
+
+ if (cip != NULL) {
+ rv = (cip->ci_state >= FMD_CASE_RESOLVED);
+ fmd_case_rele(cp);
+ }
+
+ fmd_module_unlock(mp);
+ return (rv);
+}
+
static int
fmd_case_instate(fmd_hdl_t *hdl, fmd_case_t *cp, uint_t state)
{
@@ -1760,6 +1837,65 @@ fmd_thr_checkpoint(fmd_hdl_t *hdl)
fmd_module_unlock(mp);
}
+/*ARGSUSED3*/
+int
+fmd_doorthr_create(door_info_t *dip, void *(*crf)(void *), void *crarg,
+ void *cookie)
+{
+ fmd_thread_t *old_tp, *new_tp;
+ fmd_module_t *mp;
+ pthread_t tid;
+
+ /*
+ * We're called either during initial door_xcreate or during
+ * a depletion callback. In both cases the current thread
+ * is already setup so we can retrieve the fmd_thread_t.
+ * If not then we panic. The new thread will be associated with
+ * the same module as the old.
+ *
+ * If dip == NULL we're being called as part of the
+ * sysevent_bind_subscriber hack - see comments there.
+ */
+ if ((old_tp = pthread_getspecific(fmd.d_key)) == NULL)
+ fmd_panic("fmd_doorthr_create from unrecognized thread\n");
+
+ mp = old_tp->thr_mod;
+ (void) fmd_api_module_lock((fmd_hdl_t *)mp);
+
+ if (dip && mp->mod_stats->ms_doorthrtotal.fmds_value.ui32 >=
+ mp->mod_stats->ms_doorthrlimit.fmds_value.ui32) {
+ fmd_module_unlock(mp);
+ (void) fmd_dprintf(FMD_DBG_XPRT, "door server %s for %p "
+ "not attemped - at max\n",
+ dip->di_attributes & DOOR_DEPLETION_CB ?
+ "depletion callback" : "startup", (void *)dip);
+ return (0);
+ }
+
+ if ((new_tp = fmd_doorthread_create(mp, (fmd_thread_f *)crf,
+ crarg)) != NULL) {
+ tid = new_tp->thr_tid;
+ mp->mod_stats->ms_doorthrtotal.fmds_value.ui32++;
+ (void) fmd_idspace_xalloc(mp->mod_threads, tid, new_tp);
+ }
+
+ fmd_module_unlock(mp);
+
+ if (dip) {
+ fmd_dprintf(FMD_DBG_XPRT, "door server startup for %p %s\n",
+ (void *)dip, new_tp ? "successful" : "failed");
+ }
+
+ return (new_tp ? 1 : -1);
+}
+
+/*ARGSUSED*/
+void
+fmd_doorthr_setup(void *cookie)
+{
+ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+}
+
id_t
fmd_timer_install(fmd_hdl_t *hdl, void *arg, fmd_event_t *ep, hrtime_t delta)
{
@@ -1816,16 +1952,19 @@ fmd_timer_remove(fmd_hdl_t *hdl, id_t id)
fmd_eventq_cancel(mp->mod_queue, FMD_EVT_TIMEOUT, (void *)id);
}
-nvlist_t *
-fmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class,
- uint8_t certainty, nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc)
+static nvlist_t *
+fmd_nvl_create_suspect(fmd_hdl_t *hdl, const char *class,
+ uint8_t certainty, nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc,
+ const char *pfx, boolean_t chkpfx)
{
fmd_module_t *mp;
nvlist_t *nvl;
mp = fmd_api_module_lock(hdl);
- if (class == NULL || class[0] == '\0')
- fmd_api_error(mp, EFMD_NVL_INVAL, "invalid fault class\n");
+ if (class == NULL || class[0] == '\0' ||
+ chkpfx == B_TRUE && strncmp(class, pfx, strlen(pfx)) != 0)
+ fmd_api_error(mp, EFMD_NVL_INVAL, "invalid %s class: '%s'\n",
+ pfx, class ? class : "(empty)");
nvl = fmd_protocol_fault(class, certainty, asru, fru, rsrc, NULL);
@@ -1834,6 +1973,57 @@ fmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class,
return (nvl);
}
+nvlist_t *
+fmd_nvl_create_fault(fmd_hdl_t *hdl, const char *class,
+ uint8_t certainty, nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc)
+{
+ /*
+ * We can't enforce that callers only specifiy classes matching
+ * fault.* since there are already a number of modules that
+ * use fmd_nvl_create_fault to create a defect event. Since
+ * fmd_nvl_create_{fault,defect} are equivalent, for now anyway,
+ * no harm is done. So call fmd_nvl_create_suspect with last
+ * argument B_FALSE.
+ */
+ return (fmd_nvl_create_suspect(hdl, class, certainty, asru,
+ fru, rsrc, FM_FAULT_CLASS ".", B_FALSE));
+}
+
+nvlist_t *
+fmd_nvl_create_defect(fmd_hdl_t *hdl, const char *class,
+ uint8_t certainty, nvlist_t *asru, nvlist_t *fru, nvlist_t *rsrc)
+{
+ return (fmd_nvl_create_suspect(hdl, class, certainty, asru,
+ fru, rsrc, FM_DEFECT_CLASS ".", B_TRUE));
+}
+
+const nvlist_t *
+fmd_hdl_fmauth(fmd_hdl_t *hdl)
+{
+ fmd_module_t *mp = fmd_api_module_lock(hdl);
+ const nvlist_t *auth;
+
+ auth = (const nvlist_t *)fmd.d_rmod->mod_fmri;
+
+ fmd_module_unlock(mp);
+
+ return (auth);
+}
+
+const nvlist_t *
+fmd_hdl_modauth(fmd_hdl_t *hdl)
+{
+ fmd_module_t *mp = fmd_api_module_lock(hdl);
+ const nvlist_t *auth;
+
+ auth = (const nvlist_t *)mp->mod_fmri;
+
+ fmd_module_unlock(mp);
+
+ return (auth);
+}
+
+
int
fmd_nvl_class_match(fmd_hdl_t *hdl, nvlist_t *nvl, const char *pattern)
{
diff --git a/usr/src/cmd/fm/fmd/common/fmd_api.h b/usr/src/cmd/fm/fmd/common/fmd_api.h
index d2af15cebb..b746484263 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_api.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_api.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_API_H
@@ -30,6 +29,7 @@
#include <sys/types.h>
#include <libnvpair.h>
#include <stdarg.h>
+#include <door.h>
#ifdef __cplusplus
extern "C" {
@@ -49,8 +49,9 @@ extern "C" {
#define FMD_API_VERSION_2 2
#define FMD_API_VERSION_3 3
#define FMD_API_VERSION_4 4
+#define FMD_API_VERSION_5 5
-#define FMD_API_VERSION FMD_API_VERSION_4
+#define FMD_API_VERSION FMD_API_VERSION_5
typedef struct fmd_hdl fmd_hdl_t;
typedef struct fmd_event fmd_event_t;
@@ -168,6 +169,7 @@ extern void fmd_stat_destroy(fmd_hdl_t *, uint_t, fmd_stat_t *);
extern void fmd_stat_setstr(fmd_hdl_t *, fmd_stat_t *, const char *);
extern fmd_case_t *fmd_case_open(fmd_hdl_t *, void *);
+extern fmd_case_t *fmd_case_open_uuid(fmd_hdl_t *, const char *, void *);
extern void fmd_case_reset(fmd_hdl_t *, fmd_case_t *);
extern void fmd_case_solve(fmd_hdl_t *, fmd_case_t *);
extern void fmd_case_close(fmd_hdl_t *, fmd_case_t *);
@@ -176,6 +178,7 @@ extern const char *fmd_case_uuid(fmd_hdl_t *, fmd_case_t *);
extern fmd_case_t *fmd_case_uulookup(fmd_hdl_t *, const char *);
extern void fmd_case_uuclose(fmd_hdl_t *, const char *);
extern int fmd_case_uuclosed(fmd_hdl_t *, const char *);
+extern int fmd_case_uuisresolved(fmd_hdl_t *, const char *);
extern void fmd_case_uuresolved(fmd_hdl_t *, const char *);
extern int fmd_case_solved(fmd_hdl_t *, fmd_case_t *);
@@ -215,12 +218,20 @@ extern void fmd_thr_destroy(fmd_hdl_t *, pthread_t);
extern void fmd_thr_signal(fmd_hdl_t *, pthread_t);
extern void fmd_thr_checkpoint(fmd_hdl_t *);
+extern door_xcreate_server_func_t fmd_doorthr_create;
+extern door_xcreate_thrsetup_func_t fmd_doorthr_setup;
+
extern id_t fmd_timer_install(fmd_hdl_t *, void *, fmd_event_t *, hrtime_t);
extern void fmd_timer_remove(fmd_hdl_t *, id_t);
+extern nvlist_t *fmd_nvl_create_defect(fmd_hdl_t *,
+ const char *, uint8_t, nvlist_t *, nvlist_t *, nvlist_t *);
extern nvlist_t *fmd_nvl_create_fault(fmd_hdl_t *,
const char *, uint8_t, nvlist_t *, nvlist_t *, nvlist_t *);
+extern const nvlist_t *fmd_hdl_fmauth(fmd_hdl_t *);
+extern const nvlist_t *fmd_hdl_modauth(fmd_hdl_t *);
+
extern int fmd_nvl_class_match(fmd_hdl_t *, nvlist_t *, const char *);
extern int fmd_nvl_fmri_expand(fmd_hdl_t *, nvlist_t *);
extern int fmd_nvl_fmri_present(fmd_hdl_t *, nvlist_t *);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_api.map b/usr/src/cmd/fm/fmd/common/fmd_api.map
index 1280513880..bb5524185b 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_api.map
+++ b/usr/src/cmd/fm/fmd/common/fmd_api.map
@@ -39,6 +39,7 @@ SYMBOL_SCOPE {
fmd_case_getspecific { TYPE = function; FLAGS = extern };
fmd_case_next { TYPE = function; FLAGS = extern };
fmd_case_open { TYPE = function; FLAGS = extern };
+ fmd_case_open_uuid { TYPE = function; FLAGS = extern };
fmd_case_prev { TYPE = function; FLAGS = extern };
fmd_case_reset { TYPE = function; FLAGS = extern };
fmd_case_setprincipal { TYPE = function; FLAGS = extern };
@@ -48,9 +49,13 @@ SYMBOL_SCOPE {
fmd_case_uuclose { TYPE = function; FLAGS = extern };
fmd_case_uuclosed { TYPE = function; FLAGS = extern };
fmd_case_uuid { TYPE = function; FLAGS = extern };
+ fmd_case_uuisresolved { TYPE = function; FLAGS = extern };
fmd_case_uulookup { TYPE = function; FLAGS = extern };
fmd_case_uuresolved { TYPE = function; FLAGS = extern };
+ fmd_doorthr_create { TYPE = function; FLAGS = extern };
+ fmd_doorthr_setup { TYPE = function; FLAGS = extern };
+
fmd_event_local { TYPE = function; FLAGS = extern };
fmd_event_ena_create { TYPE = function; FLAGS = extern };
@@ -59,7 +64,9 @@ SYMBOL_SCOPE {
fmd_hdl_debug { TYPE = function; FLAGS = extern };
fmd_hdl_error { TYPE = function; FLAGS = extern };
fmd_hdl_free { TYPE = function; FLAGS = extern };
+ fmd_hdl_fmauth { TYPE = function; FLAGS = extern };
fmd_hdl_getspecific { TYPE = function; FLAGS = extern };
+ fmd_hdl_modauth { TYPE = function; FLAGS = extern };
fmd_hdl_opendict { TYPE = function; FLAGS = extern };
fmd_hdl_register { TYPE = function; FLAGS = extern };
fmd_hdl_setspecific { TYPE = function; FLAGS = extern };
@@ -77,6 +84,7 @@ SYMBOL_SCOPE {
fmd_nvl_alloc { TYPE = function; FLAGS = extern };
fmd_nvl_class_match { TYPE = function; FLAGS = extern };
+ fmd_nvl_create_defect { TYPE = function; FLAGS = extern };
fmd_nvl_create_fault { TYPE = function; FLAGS = extern };
fmd_nvl_dup { TYPE = function; FLAGS = extern };
fmd_nvl_fmri_expand { TYPE = function; FLAGS = extern };
diff --git a/usr/src/cmd/fm/fmd/common/fmd_builtin.c b/usr/src/cmd/fm/fmd/common/fmd_builtin.c
index ce669465a5..84435216c9 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_builtin.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_builtin.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -21,23 +20,22 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <fmd_module.h>
#include <fmd_subr.h>
#include <fmd_error.h>
#include <fmd_string.h>
#include <fmd_event.h>
#include <fmd_builtin.h>
+#include <zone.h>
static const struct fmd_builtin _fmd_builtins[] = {
- { "fmd-self-diagnosis", self_init, self_fini },
- { "sysevent-transport", sysev_init, sysev_fini },
- { NULL, NULL, NULL }
+ { "fmd-self-diagnosis", self_init, self_fini, FMD_BUILTIN_ALLCTXT },
+ { "sysevent-transport", sysev_init, sysev_fini,
+ FMD_BUILTIN_CTXT_GLOBALZONE },
+ { NULL, NULL, NULL, 0 }
};
static int
@@ -106,9 +104,16 @@ int
fmd_builtin_loadall(fmd_modhash_t *mhp)
{
const fmd_builtin_t *bp;
+ uint32_t ctxt = 0;
int err = 0;
+ ctxt |= (getzoneid() == GLOBAL_ZONEID) ? FMD_BUILTIN_CTXT_GLOBALZONE :
+ FMD_BUILTIN_CTXT_NONGLOBALZONE;
+
for (bp = _fmd_builtins; bp->bltin_name != NULL; bp++) {
+ if (!(ctxt & bp->bltin_ctxts))
+ continue;
+
if (fmd_modhash_load(mhp, bp->bltin_name,
&fmd_bltin_ops) == NULL)
err = -1;
diff --git a/usr/src/cmd/fm/fmd/common/fmd_builtin.h b/usr/src/cmd/fm/fmd/common/fmd_builtin.h
index 9ef2a54d75..06710dc3ce 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_builtin.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_builtin.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -21,15 +20,12 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_BUILTIN_H
#define _FMD_BUILTIN_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -50,8 +46,15 @@ typedef struct fmd_builtin {
const char *bltin_name;
void (*bltin_init)(fmd_hdl_t *);
void (*bltin_fini)(fmd_hdl_t *);
+ int bltin_ctxts;
} fmd_builtin_t;
+#define FMD_BUILTIN_CTXT_GLOBALZONE 0x1
+#define FMD_BUILTIN_CTXT_NONGLOBALZONE 0x2
+
+#define FMD_BUILTIN_ALLCTXT \
+ (FMD_BUILTIN_CTXT_GLOBALZONE | FMD_BUILTIN_CTXT_NONGLOBALZONE)
+
extern int fmd_builtin_loadall(fmd_modhash_t *);
extern void self_init(fmd_hdl_t *); /* see fmd_self.c */
diff --git a/usr/src/cmd/fm/fmd/common/fmd_case.c b/usr/src/cmd/fm/fmd/common/fmd_case.c
index d65f24601b..9ebcced1f9 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_case.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_case.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -1247,7 +1246,7 @@ fmd_case_hash_delete(fmd_case_hash_t *chp, fmd_case_impl_t *cip)
}
fmd_case_t *
-fmd_case_create(fmd_module_t *mp, void *data)
+fmd_case_create(fmd_module_t *mp, const char *uuidstr, void *data)
{
fmd_case_impl_t *cip = fmd_zalloc(sizeof (fmd_case_impl_t), FMD_SLEEP);
fmd_case_impl_t *eip = NULL;
@@ -1272,17 +1271,35 @@ fmd_case_create(fmd_module_t *mp, void *data)
(void) fmd_conf_getprop(fmd.d_conf, "uuidlen", &cip->ci_uuidlen);
cip->ci_uuid = fmd_zalloc(cip->ci_uuidlen + 1, FMD_SLEEP);
- /*
- * We expect this loop to execute only once, but code it defensively
- * against the possibility of libuuid bugs. Keep generating uuids and
- * attempting to do a hash insert until we get a unique one.
- */
- do {
- if (eip != NULL)
- fmd_case_rele((fmd_case_t *)eip);
- uuid_generate(uuid);
- uuid_unparse(uuid, cip->ci_uuid);
- } while ((eip = fmd_case_hash_insert(fmd.d_cases, cip)) != cip);
+ if (uuidstr == NULL) {
+ /*
+ * We expect this loop to execute only once, but code it
+ * defensively against the possibility of libuuid bugs.
+ * Keep generating uuids and attempting to do a hash insert
+ * until we get a unique one.
+ */
+ do {
+ if (eip != NULL)
+ fmd_case_rele((fmd_case_t *)eip);
+ uuid_generate(uuid);
+ uuid_unparse(uuid, cip->ci_uuid);
+ } while ((eip = fmd_case_hash_insert(fmd.d_cases, cip)) != cip);
+ } else {
+ /*
+ * If a uuid was specified we must succeed with that uuid,
+ * or return NULL indicating a case with that uuid already
+ * exists.
+ */
+ (void) strncpy(cip->ci_uuid, uuidstr, cip->ci_uuidlen + 1);
+ if (fmd_case_hash_insert(fmd.d_cases, cip) != cip) {
+ fmd_free(cip->ci_uuid, cip->ci_uuidlen + 1);
+ (void) fmd_buf_hash_destroy(&cip->ci_bufs);
+ fmd_module_rele(mp);
+ pthread_mutex_destroy(&cip->ci_lock);
+ fmd_free(cip, sizeof (*cip));
+ return (NULL);
+ }
+ }
ASSERT(fmd_module_locked(mp));
fmd_list_append(&mp->mod_cases, cip);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_case.h b/usr/src/cmd/fm/fmd/common/fmd_case.h
index 891617b190..733826e91c 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_case.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_case.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_CASE_H
@@ -121,7 +120,7 @@ extern fmd_case_t *fmd_case_hash_lookup(fmd_case_hash_t *, const char *);
extern void fmd_case_hash_apply(fmd_case_hash_t *,
void (*)(fmd_case_t *, void *), void *);
-extern fmd_case_t *fmd_case_create(struct fmd_module *, void *);
+extern fmd_case_t *fmd_case_create(struct fmd_module *, const char *, void *);
extern fmd_case_t *fmd_case_recreate(struct fmd_module *,
struct fmd_xprt *, uint_t, const char *, const char *);
extern void fmd_case_destroy(fmd_case_t *, int);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_dr.c b/usr/src/cmd/fm/fmd/common/fmd_dr.c
index 3b5eba87aa..e4fec10d08 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_dr.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_dr.c
@@ -134,7 +134,7 @@ fmd_dr_event(sysevent_t *sep)
(void) pthread_mutex_unlock(&fmd.d_stats_lock);
TRACE((FMD_DBG_XPRT, "dr event %p, gen=%llu", (void *)sep, gen));
- fmd_topo_update(B_FALSE);
+ fmd_topo_update();
ftp = fmd_topo_hold();
e = fmd_event_create(FMD_EVT_TOPO, ftp->ft_time_end, NULL, ftp);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_idspace.c b/usr/src/cmd/fm/fmd/common/fmd_idspace.c
index 187dd3b67d..ce0f90563e 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_idspace.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_idspace.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -19,13 +18,11 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <fmd_alloc.h>
#include <fmd_subr.h>
#include <fmd_conf.h>
@@ -34,47 +31,6 @@
#include <fmd_idspace.h>
#include <fmd.h>
-static int
-highbit(ulong_t i)
-{
- int h = 1;
-
- if (i == 0)
- return (0);
-
-#ifdef _LP64
- if (i & 0xffffffff00000000ul) {
- h += 32;
- i >>= 32;
- }
-#endif
-
- if (i & 0xffff0000) {
- h += 16;
- i >>= 16;
- }
-
- if (i & 0xff00) {
- h += 8;
- i >>= 8;
- }
-
- if (i & 0xf0) {
- h += 4;
- i >>= 4;
- }
-
- if (i & 0xc) {
- h += 2;
- i >>= 2;
- }
-
- if (i & 0x2)
- h += 1;
-
- return (h);
-}
-
fmd_idspace_t *
fmd_idspace_create(const char *name, id_t min, id_t max)
{
@@ -93,7 +49,7 @@ fmd_idspace_create(const char *name, id_t min, id_t max)
(void) fmd_conf_getprop(fmd.d_conf, "ids.max", &ids_max);
hashmax = max - min + 1;
- hashlen = 1 << highbit(hashmax / ids_avg);
+ hashlen = 1 << fls(hashmax / ids_avg);
if (hashlen > ids_max)
hashlen = ids_max;
diff --git a/usr/src/cmd/fm/fmd/common/fmd_log.h b/usr/src/cmd/fm/fmd/common/fmd_log.h
index 11d2b1c399..56caf42bbb 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_log.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_log.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,15 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_LOG_H
#define _FMD_LOG_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
@@ -71,6 +67,7 @@ typedef void fmd_log_f(fmd_log_t *, fmd_event_t *, void *);
#define FMD_LOG_FAULT "fault" /* tag for fault log files */
#define FMD_LOG_ASRU "asru" /* tag for asru log files */
#define FMD_LOG_XPRT "xprt" /* tag for transport log files */
+#define FMD_LOG_INFO "info" /* tag for info event log files */
extern fmd_log_t *fmd_log_tryopen(const char *, const char *, const char *);
extern fmd_log_t *fmd_log_open(const char *, const char *, const char *);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_main.c b/usr/src/cmd/fm/fmd/common/fmd_main.c
index f1a8d2df31..d096b8bdbf 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_main.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_main.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -37,6 +36,7 @@
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
+#include <zone.h>
#include <fmd_error.h>
#include <fmd_string.h>
@@ -78,6 +78,7 @@ _umem_logging_init(void)
static int
daemonize_init(void)
{
+ const char *gzp1, *gzp2, *gzp3, *gzp4, *gzp5;
int status, pfds[2];
sigset_t set, oset;
struct rlimit rlim;
@@ -111,14 +112,50 @@ daemonize_init(void)
* Reset all of our privilege sets to the minimum set of required
* privileges. We continue to run as root so that files we create
* such as logs and checkpoints are secured in the /var filesystem.
+ *
+ * In a non-global zone some of the privileges we retain in a
+ * global zone are only optionally assigned to the zone, while others
+ * are prohibited:
+ *
+ * PRIV_PROC_PRIOCNTL (optional in a non-global zone):
+ * There are no calls to priocntl(2) in fmd or plugins.
+ *
+ * PRIV_SYS_CONFIG (prohibited in a non-global zone):
+ * Required, I think, for sysevent_post_event and/or
+ * other legacy sysevent activity. Legacy sysevent is not
+ * supported in a non-global zone.
+ *
+ * PRIV_SYS_DEVICES (prohibited in a non-global zone):
+ * Needed in the global zone for ioctls on various drivers
+ * such as memory-controller drivers.
+ *
+ * PRIV_SYS_RES_CONFIG (prohibited in a non-global zone):
+ * Require for p_online(2) calls to offline cpus.
+ *
+ * PRIV_SYS_NET_CONFIG (prohibited in a non-global zone):
+ * Required for ipsec in etm (which also requires
+ * PRIV_NET_PRIVADDR).
+ *
+ * We do without those privileges in a non-global zone. It's
+ * possible that there are other privs we could drop since
+ * hardware-related plugins are not present.
*/
+ if (getzoneid() == GLOBAL_ZONEID) {
+ gzp1 = PRIV_PROC_PRIOCNTL;
+ gzp2 = PRIV_SYS_CONFIG;
+ gzp3 = PRIV_SYS_DEVICES;
+ gzp4 = PRIV_SYS_RES_CONFIG;
+ gzp5 = PRIV_SYS_NET_CONFIG;
+ } else {
+ gzp1 = gzp2 = gzp3 = gzp4 = gzp5 = NULL;
+ }
+
if (__init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS | PU_INHERITPRIVS,
0, 0, /* run as uid 0 and gid 0 */
PRIV_FILE_DAC_EXECUTE, PRIV_FILE_DAC_READ, PRIV_FILE_DAC_SEARCH,
PRIV_FILE_DAC_WRITE, PRIV_FILE_OWNER, PRIV_PROC_OWNER,
- PRIV_PROC_PRIOCNTL, PRIV_SYS_ADMIN, PRIV_SYS_CONFIG,
- PRIV_SYS_DEVICES, PRIV_SYS_RES_CONFIG, PRIV_NET_PRIVADDR,
- PRIV_SYS_NET_CONFIG, NULL) != 0)
+ PRIV_SYS_ADMIN, PRIV_NET_PRIVADDR,
+ gzp1, gzp2, gzp3, gzp4, gzp5, NULL) != 0)
fmd_error(EFMD_EXIT, "additional privileges required to run\n");
/*
diff --git a/usr/src/cmd/fm/fmd/common/fmd_mdb.c b/usr/src/cmd/fm/fmd/common/fmd_mdb.c
index 05b6d25e6c..0d04f80827 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_mdb.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_mdb.c
@@ -483,6 +483,10 @@ module_stat(uintptr_t addr, const void *data, void *wsp)
DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
(void) fmd_stat((uintptr_t)&mod_stats->ms_thrlimit,
DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
+ (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrtotal,
+ DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
+ (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrlimit,
+ DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
(void) fmd_stat((uintptr_t)&mod_stats->ms_caseopen,
DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
(void) fmd_stat((uintptr_t)&mod_stats->ms_casesolved,
@@ -877,6 +881,9 @@ fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
case FMD_CASE_REPAIRED:
(void) strcpy(name, "RPAIR");
break;
+ case FMD_CASE_RESOLVED:
+ (void) strcpy(name, "RSLVD");
+ break;
default:
(void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state);
}
diff --git a/usr/src/cmd/fm/fmd/common/fmd_module.c b/usr/src/cmd/fm/fmd/common/fmd_module.c
index 8d99794125..ad3b8f424d 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_module.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_module.c
@@ -79,6 +79,8 @@ static const fmd_modstat_t _fmd_modstat_tmpl = {
{ "fmd.buflimit", FMD_TYPE_SIZE, "limit on total buffer space" },
{ "fmd.thrtotal", FMD_TYPE_UINT32, "total number of auxiliary threads" },
{ "fmd.thrlimit", FMD_TYPE_UINT32, "limit on number of auxiliary threads" },
+{ "fmd.doorthrtotal", FMD_TYPE_UINT32, "total number of door server threads" },
+{ "fmd.doorthrlimit", FMD_TYPE_UINT32, "limit on door server threads" },
{ "fmd.caseopen", FMD_TYPE_UINT64, "cases currently open by module" },
{ "fmd.casesolved", FMD_TYPE_UINT64, "total cases solved by module" },
{ "fmd.caseclosed", FMD_TYPE_UINT64, "total cases closed by module" },
@@ -247,6 +249,9 @@ fmd_module_create(const char *path, const fmd_modops_t *ops)
(void) fmd_conf_getprop(fmd.d_conf, "client.thrlim",
&mp->mod_stats->ms_thrlimit.fmds_value.ui32);
+ (void) fmd_conf_getprop(fmd.d_conf, "client.doorthrlim",
+ &mp->mod_stats->ms_doorthrlimit.fmds_value.ui32);
+
(void) fmd_conf_getprop(fmd.d_conf, "client.xprtlim",
&mp->mod_stats->ms_xprtlimit.fmds_value.ui32);
@@ -526,6 +531,7 @@ fmd_module_dispatch(fmd_module_t *mp, fmd_event_t *e)
fmd_event_impl_t *ep = (fmd_event_impl_t *)e;
fmd_hdl_t *hdl = (fmd_hdl_t *)mp;
fmd_modtimer_t *t;
+ fmd_topo_t *old_topo;
volatile int err;
/*
@@ -575,9 +581,22 @@ fmd_module_dispatch(fmd_module_t *mp, fmd_event_t *e)
fmd_case_publish(ep->ev_data, FMD_CASE_CURRENT);
break;
case FMD_EVT_TOPO:
- fmd_topo_rele(mp->mod_topo_current);
+ /*
+ * Save the pointer to the old topology and update
+ * the pointer with the updated topology.
+ * With this approach, other threads that reference the
+ * topology either
+ * - finishes with old topology since
+ * it is released after updating
+ * mod_topo_current.
+ * - or is blocked while mod_topo_current is updated.
+ */
+ old_topo = mp->mod_topo_current;
+ fmd_module_lock(mp);
mp->mod_topo_current = (fmd_topo_t *)ep->ev_data;
fmd_topo_addref(mp->mod_topo_current);
+ fmd_module_unlock(mp);
+ fmd_topo_rele(old_topo);
ops->fmdo_topo(hdl, mp->mod_topo_current->ft_hdl);
break;
}
@@ -939,8 +958,7 @@ fmd_module_dc_opendict(fmd_module_t *mp, const char *dict)
ASSERT(fmd_module_locked(mp));
- dictnam = alloca(strlen(dict) + 1);
- (void) strcpy(dictnam, fmd_strbasename(dict));
+ dictnam = strdupa(fmd_strbasename(dict));
if ((p = strrchr(dictnam, '.')) != NULL &&
strcmp(p, ".dict") == 0)
diff --git a/usr/src/cmd/fm/fmd/common/fmd_module.h b/usr/src/cmd/fm/fmd/common/fmd_module.h
index ecff784549..04917065b7 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_module.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_module.h
@@ -20,15 +20,12 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_MODULE_H
#define _FMD_MODULE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <fm/diagcode.h>
#include <pthread.h>
@@ -84,6 +81,8 @@ typedef struct fmd_modstat {
fmd_stat_t ms_buflimit; /* limit on space consumed by buffers */
fmd_stat_t ms_thrtotal; /* total number of auxiliary threads */
fmd_stat_t ms_thrlimit; /* limit on auxiliary threads */
+ fmd_stat_t ms_doorthrtotal; /* total number of doorserver threads */
+ fmd_stat_t ms_doorthrlimit; /* limit on doorserver threads */
fmd_stat_t ms_caseopen; /* cases currently open */
fmd_stat_t ms_casesolved; /* total cases solved by module */
fmd_stat_t ms_caseclosed; /* total cases closed by module */
diff --git a/usr/src/cmd/fm/fmd/common/fmd_rpc.c b/usr/src/cmd/fm/fmd/common/fmd_rpc.c
index 9f49de24d6..dd8bfa0635 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_rpc.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_rpc.c
@@ -19,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/fm/util.h>
@@ -236,7 +233,7 @@ fmd_rpc_fini(void)
/*
* Utillity function to fetch the XPRT's ucred and determine if we should deny
* the request. For now, we implement a simple policy of rejecting any caller
- * who does not have the PRIV_SYS_CONFIG bit in their Effective privilege set,
+ * who does not have the PRIV_SYS_ADMIN bit in their Effective privilege set,
* unless the caller is loading a module, which requires all privileges.
*/
int
@@ -265,5 +262,5 @@ fmd_rpc_deny(struct svc_req *rqp)
if (rqp->rq_proc == FMD_ADM_MODLOAD)
return (!priv_isfullset(psp));
#endif
- return (!priv_ismember(psp, PRIV_SYS_CONFIG));
+ return (!priv_ismember(psp, PRIV_SYS_ADMIN));
}
diff --git a/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c b/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c
index 5d56382bb9..5890c6dc99 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <strings.h>
@@ -722,6 +721,7 @@ fmd_adm_logrotate_1_svc(char *name, int *rvp, struct svc_req *req)
{
fmd_log_t **lpp, *old, *new;
int try = 1, trylimit = 1;
+ pthread_rwlock_t *lockp;
hrtime_t nsec = 0;
timespec_t tv;
@@ -731,11 +731,19 @@ fmd_adm_logrotate_1_svc(char *name, int *rvp, struct svc_req *req)
return (TRUE);
}
- if (strcmp(name, "errlog") == 0)
+ if (strcmp(name, "errlog") == 0) {
lpp = &fmd.d_errlog;
- else if (strcmp(name, "fltlog") == 0)
+ lockp = &fmd.d_log_lock;
+ } else if (strcmp(name, "fltlog") == 0) {
lpp = &fmd.d_fltlog;
- else {
+ lockp = &fmd.d_log_lock;
+ } else if (strcmp(name, "infolog") == 0) {
+ lpp = &fmd.d_ilog;
+ lockp = &fmd.d_ilog_lock;
+ } else if (strcmp(name, "infolog_hival") == 0) {
+ lpp = &fmd.d_hvilog;
+ lockp = &fmd.d_hvilog_lock;
+ } else {
*rvp = FMD_ADM_ERR_ROTSRCH;
return (TRUE);
}
@@ -755,7 +763,7 @@ fmd_adm_logrotate_1_svc(char *name, int *rvp, struct svc_req *req)
if (try > 1)
(void) nanosleep(&tv, NULL); /* wait for checkpoints */
- (void) pthread_rwlock_wrlock(&fmd.d_log_lock);
+ (void) pthread_rwlock_wrlock(lockp);
old = *lpp;
if ((new = fmd_log_rotate(old)) != NULL) {
@@ -763,7 +771,7 @@ fmd_adm_logrotate_1_svc(char *name, int *rvp, struct svc_req *req)
*lpp = new;
}
- (void) pthread_rwlock_unlock(&fmd.d_log_lock);
+ (void) pthread_rwlock_unlock(lockp);
} while (new == NULL && errno == EFMD_LOG_ROTBUSY && try++ < trylimit);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_scheme.c b/usr/src/cmd/fm/fmd/common/fmd_scheme.c
index 5568dc8b9d..4ddad713a6 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_scheme.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_scheme.c
@@ -65,6 +65,9 @@ fmd_scheme_fmd_present(nvlist_t *nvl)
nvlist_lookup_string(nvl, FM_FMRI_FMD_VERSION, &version) != 0)
return (fmd_fmri_set_errno(EINVAL));
+ if (!fmd.d_loaded)
+ return (1);
+
if ((mp = fmd_modhash_lookup(fmd.d_mod_hash, name)) != NULL) {
rv = mp->mod_vers != NULL &&
strcmp(mp->mod_vers, version) == 0;
@@ -85,6 +88,9 @@ fmd_scheme_fmd_replaced(nvlist_t *nvl)
nvlist_lookup_string(nvl, FM_FMRI_FMD_VERSION, &version) != 0)
return (fmd_fmri_set_errno(EINVAL));
+ if (!fmd.d_loaded)
+ return (FMD_OBJ_STATE_UNKNOWN);
+
if ((mp = fmd_modhash_lookup(fmd.d_mod_hash, name)) != NULL) {
rv = mp->mod_vers != NULL &&
strcmp(mp->mod_vers, version) == 0;
@@ -104,6 +110,9 @@ fmd_scheme_fmd_service_state(nvlist_t *nvl)
if (nvlist_lookup_string(nvl, FM_FMRI_FMD_NAME, &name) != 0)
return (fmd_fmri_set_errno(EINVAL));
+ if (!fmd.d_loaded)
+ return (FMD_SERVICE_STATE_UNKNOWN);
+
if ((mp = fmd_modhash_lookup(fmd.d_mod_hash, name)) != NULL) {
rv = mp->mod_error != 0;
fmd_module_rele(mp);
@@ -122,6 +131,9 @@ fmd_scheme_fmd_unusable(nvlist_t *nvl)
if (nvlist_lookup_string(nvl, FM_FMRI_FMD_NAME, &name) != 0)
return (fmd_fmri_set_errno(EINVAL));
+ if (!fmd.d_loaded)
+ return (0);
+
if ((mp = fmd_modhash_lookup(fmd.d_mod_hash, name)) != NULL) {
rv = mp->mod_error != 0;
fmd_module_rele(mp);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_self.c b/usr/src/cmd/fm/fmd/common/fmd_self.c
index 2a11fc3297..3ee514b5f3 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_self.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_self.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/fm/protocol.h>
@@ -158,6 +157,10 @@ self_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
if (self_case_lookup(hdl, SC_CLASS, class) != NULL)
return; /* case is already open against this class */
+ if (strncmp(class, FM_IREPORT_CLASS ".",
+ sizeof (FM_IREPORT_CLASS)) == 0)
+ return; /* no subscriber required for ireport.* */
+
cp = fmd_case_open(hdl, self_case_create(hdl, SC_CLASS, class));
fmd_case_add_ereport(hdl, cp, ep);
self_stats.nosub.fmds_value.ui64++;
diff --git a/usr/src/cmd/fm/fmd/common/fmd_sysevent.c b/usr/src/cmd/fm/fmd/common/fmd_sysevent.c
index 1893289b00..9f46f13411 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_sysevent.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_sysevent.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/sysevent/eventdefs.h>
@@ -41,6 +40,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
+#include <zone.h>
#undef MUTEX_HELD
#undef RW_READ_HELD
@@ -87,6 +87,8 @@ static pthread_mutex_t sysev_mutex = PTHREAD_MUTEX_INITIALIZER;
static int sysev_replay_wait = 1;
static int sysev_exiting;
+static sysevent_subattr_t *subattr;
+
/*
* Entry point for legacy sysevents. This function is responsible for two
* things: passing off interesting events to the DR handler, and converting
@@ -100,7 +102,6 @@ sysev_legacy(sysevent_t *sep)
char *fullclass;
size_t len;
nvlist_t *attr, *nvl;
- fmd_event_t *e;
hrtime_t hrt;
/* notify the DR subsystem of the event */
@@ -128,15 +129,12 @@ sysev_legacy(sysevent_t *sep)
(void) nvlist_add_uint8(nvl, FM_VERSION, FM_RSRC_VERSION);
/*
- * Dispatch the event. Ideally, we'd like to use the same transport
- * interface as sysev_recv(), but because the legacy sysevent mechanism
- * puts in a thread outside fmd's control, using the module APIs is
- * impossible.
+ * Dispatch the event. Because we have used sysevent_bind_xhandle
+ * the delivery thread is blessed as a proper fmd thread so
+ * we may use regular fmd api calls.
*/
sysevent_get_time(sep, &hrt);
- (void) nvlist_lookup_string(nvl, FM_CLASS, &fullclass);
- e = fmd_event_create(FMD_EVT_PROTOCOL, hrt, nvl, fullclass);
- fmd_dispq_dispatch(fmd.d_disp, e, fullclass);
+ fmd_xprt_post(sysev_hdl, sysev_xprt, nvl, hrt);
}
/*
@@ -444,6 +442,10 @@ sysev_init(fmd_hdl_t *hdl)
uint_t flags;
const char *subclasses[] = { EC_SUB_ALL };
+ /* This builtin is for the global zone only */
+ if (getzoneid() != GLOBAL_ZONEID)
+ return;
+
if (fmd_hdl_register(hdl, FMD_API_VERSION, &sysev_info) != 0)
return; /* invalid property settings */
@@ -482,15 +484,22 @@ sysev_init(fmd_hdl_t *hdl)
else
flags = EVCH_SUB_DUMP;
- errno = sysevent_evc_subscribe(sysev_evc,
- sysev_sid, sysev_class, sysev_recv, sysev_xprt, flags);
+ if ((subattr = sysevent_subattr_alloc()) == NULL)
+ fmd_hdl_abort(hdl, "failed to allocate subscription "
+ "attributes");
+
+ sysevent_subattr_thrcreate(subattr, fmd_doorthr_create, NULL);
+ sysevent_subattr_thrsetup(subattr, fmd_doorthr_setup, NULL);
+
+ errno = sysevent_evc_xsubscribe(sysev_evc,
+ sysev_sid, sysev_class, sysev_recv, sysev_xprt, flags, subattr);
if (errno != 0) {
if (errno == EEXIST) {
fmd_hdl_abort(hdl, "another fault management daemon is "
"active on transport channel %s\n", sysev_channel);
} else {
- fmd_hdl_abort(hdl, "failed to subscribe to %s on "
+ fmd_hdl_abort(hdl, "failed to xsubscribe to %s on "
"transport channel %s", sysev_class, sysev_channel);
}
}
@@ -512,7 +521,7 @@ sysev_init(fmd_hdl_t *hdl)
return;
if ((fmd.d_sysev_hdl =
- sysevent_bind_handle(sysev_legacy)) == NULL)
+ sysevent_bind_xhandle(sysev_legacy, subattr)) == NULL)
fmd_hdl_abort(hdl, "failed to bind to legacy sysevent channel");
if (sysevent_subscribe_event(fmd.d_sysev_hdl, EC_ALL,
@@ -540,6 +549,11 @@ sysev_fini(fmd_hdl_t *hdl)
if (fmd.d_sysev_hdl != NULL)
sysevent_unbind_handle(fmd.d_sysev_hdl);
+ if (subattr != NULL) {
+ sysevent_subattr_free(subattr);
+ subattr = NULL;
+ }
+
if (sysev_xprt != NULL) {
/*
* Wait callback returns before destroy the transport.
diff --git a/usr/src/cmd/fm/fmd/common/fmd_thread.c b/usr/src/cmd/fm/fmd/common/fmd_thread.c
index 1da654524c..cb0cb0745d 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_thread.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_thread.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,12 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <signal.h>
#include <fmd_alloc.h>
@@ -47,6 +43,7 @@ fmd_thread_xcreate(fmd_module_t *mp, pthread_t tid)
tp->thr_trdata = fmd_trace_create();
tp->thr_trfunc = (fmd_tracebuf_f *)fmd.d_thr_trace;
tp->thr_errdepth = 0;
+ tp->thr_isdoor = 0;
(void) pthread_mutex_lock(&fmd.d_thr_lock);
fmd_list_append(&fmd.d_thr_list, tp);
@@ -63,15 +60,18 @@ fmd_thread_start(void *arg)
if (pthread_setspecific(fmd.d_key, tp) != 0)
fmd_panic("failed to initialize thread key to %p", arg);
- (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
- (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ if (!tp->thr_isdoor) {
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ }
tp->thr_func(tp->thr_arg);
return (NULL);
}
-fmd_thread_t *
-fmd_thread_create(fmd_module_t *mp, fmd_thread_f *func, void *arg)
+static fmd_thread_t *
+fmd_thread_create_cmn(fmd_module_t *mp, fmd_thread_f *func, void *arg,
+ int isdoor)
{
fmd_thread_t *tp = fmd_alloc(sizeof (fmd_thread_t), FMD_SLEEP);
sigset_t oset, nset;
@@ -83,10 +83,12 @@ fmd_thread_create(fmd_module_t *mp, fmd_thread_f *func, void *arg)
tp->thr_trdata = fmd_trace_create();
tp->thr_trfunc = (fmd_tracebuf_f *)fmd.d_thr_trace;
tp->thr_errdepth = 0;
+ tp->thr_isdoor = isdoor;
(void) sigfillset(&nset);
(void) sigdelset(&nset, SIGABRT); /* always unblocked for fmd_panic() */
- (void) sigdelset(&nset, fmd.d_thr_sig); /* for fmd_thr_signal() */
+ if (!isdoor)
+ (void) sigdelset(&nset, fmd.d_thr_sig); /* fmd_thr_signal() */
(void) pthread_sigmask(SIG_SETMASK, &nset, &oset);
err = pthread_create(&tp->thr_tid, NULL, fmd_thread_start, tp);
@@ -104,6 +106,18 @@ fmd_thread_create(fmd_module_t *mp, fmd_thread_f *func, void *arg)
return (tp);
}
+fmd_thread_t *
+fmd_thread_create(fmd_module_t *mp, fmd_thread_f *func, void *arg)
+{
+ return (fmd_thread_create_cmn(mp, func, arg, 0));
+}
+
+fmd_thread_t *
+fmd_doorthread_create(fmd_module_t *mp, fmd_thread_f *func, void *arg)
+{
+ return (fmd_thread_create_cmn(mp, func, arg, 1));
+}
+
void
fmd_thread_destroy(fmd_thread_t *tp, int flag)
{
diff --git a/usr/src/cmd/fm/fmd/common/fmd_thread.h b/usr/src/cmd/fm/fmd/common/fmd_thread.h
index b397b1d36e..d28cccc4bc 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_thread.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_thread.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,15 +19,12 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_THREAD_H
#define _FMD_THREAD_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -49,11 +45,14 @@ typedef struct fmd_thread {
fmd_tracebuf_t *thr_trdata; /* thread trace buffer */
fmd_tracebuf_f *thr_trfunc; /* thread trace function */
uint_t thr_errdepth; /* fmd_verror() nesting depth */
+ int thr_isdoor; /* a private door server thread */
} fmd_thread_t;
extern fmd_thread_t *fmd_thread_xcreate(struct fmd_module *, pthread_t);
extern fmd_thread_t *fmd_thread_create(struct fmd_module *,
fmd_thread_f *, void *);
+extern fmd_thread_t *fmd_doorthread_create(struct fmd_module *,
+ fmd_thread_f *, void *);
#define FMD_THREAD_NOJOIN 0 /* do not attempt to join with thread */
#define FMD_THREAD_JOIN 1 /* wait for and join with thread */
diff --git a/usr/src/cmd/fm/fmd/common/fmd_topo.c b/usr/src/cmd/fm/fmd/common/fmd_topo.c
index 3173f82ce1..a7d80b4396 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_topo.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_topo.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -61,7 +60,7 @@ fmd_topo_rele_locked(fmd_topo_t *ftp)
}
void
-fmd_topo_update(boolean_t need_force)
+fmd_topo_update(void)
{
int err;
topo_hdl_t *tp;
@@ -87,15 +86,9 @@ fmd_topo_update(boolean_t need_force)
ftp->ft_hdl = tp;
ftp->ft_time_begin = fmd_time_gethrtime();
- if (need_force) {
- if ((id = topo_snap_hold(tp, NULL, &err)) == NULL)
- fmd_panic("failed to get topology snapshot: %s",
- topo_strerror(err));
- } else {
- if ((id = topo_snap_hold_no_forceload(tp, NULL, &err)) == NULL)
- fmd_panic("failed to get topology snapshot: %s",
- topo_strerror(err));
- }
+ if ((id = topo_snap_hold(tp, NULL, &err)) == NULL)
+ fmd_panic("failed to get topology snapshot: %s",
+ topo_strerror(err));
topo_hdl_strfree(tp, id);
@@ -166,7 +159,7 @@ fmd_topo_rele_hdl(topo_hdl_t *thp)
void
fmd_topo_init(void)
{
- fmd_topo_update(B_TRUE);
+ fmd_topo_update();
}
void
diff --git a/usr/src/cmd/fm/fmd/common/fmd_topo.h b/usr/src/cmd/fm/fmd/common/fmd_topo.h
index 9b53e8ab8a..faabb66b24 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_topo.h
+++ b/usr/src/cmd/fm/fmd/common/fmd_topo.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _FMD_TOPO_H
@@ -45,7 +44,7 @@ typedef struct fmd_topo {
hrtime_t ft_time_end;
} fmd_topo_t;
-extern void fmd_topo_update(boolean_t);
+extern void fmd_topo_update(void);
extern fmd_topo_t *fmd_topo_hold(void);
extern void fmd_topo_addref(fmd_topo_t *);
extern void fmd_topo_rele(fmd_topo_t *);
diff --git a/usr/src/cmd/fm/fmd/common/fmd_xprt.c b/usr/src/cmd/fm/fmd/common/fmd_xprt.c
index 821e92cb5c..89054a1792 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_xprt.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_xprt.c
@@ -1099,7 +1099,7 @@ fmd_xprt_list_suspect_local(fmd_xprt_t *xp, nvlist_t *nvl)
boolean_t injected;
fmd_module_lock(xip->xi_queue->eq_mod);
- cp = fmd_case_create(xip->xi_queue->eq_mod, NULL);
+ cp = fmd_case_create(xip->xi_queue->eq_mod, NULL, NULL);
if (cp == NULL) {
fmd_module_unlock(xip->xi_queue->eq_mod);
return;
@@ -1457,7 +1457,7 @@ fmd_xprt_recv(fmd_xprt_t *xp, nvlist_t *nvl, hrtime_t hrt, boolean_t logonly)
fmd_event_t *e;
char *class, *uuid;
- boolean_t isproto, isereport;
+ boolean_t isproto, isereport, isireport, ishvireport, issysevent;
uint64_t *tod;
uint8_t ttl;
@@ -1505,13 +1505,30 @@ fmd_xprt_recv(fmd_xprt_t *xp, nvlist_t *nvl, hrtime_t hrt, boolean_t logonly)
fmd_dprintf(FMD_DBG_XPRT, "xprt %u %s %s\n", xip->xi_id,
((logonly == FMD_B_TRUE) ? "logging" : "posting"), class);
- isereport = (strncmp(class, FM_EREPORT_CLASS,
- sizeof (FM_EREPORT_CLASS - 1)) == 0) ? FMD_B_TRUE : FMD_B_FALSE;
+ isereport = (strncmp(class, FM_EREPORT_CLASS ".",
+ sizeof (FM_EREPORT_CLASS)) == 0) ? FMD_B_TRUE : FMD_B_FALSE;
+
+ isireport = (strncmp(class, FM_IREPORT_CLASS ".",
+ sizeof (FM_IREPORT_CLASS)) == 0) ? FMD_B_TRUE : FMD_B_FALSE;
+
+ issysevent = (strncmp(class, SYSEVENT_RSRC_CLASS,
+ sizeof (SYSEVENT_RSRC_CLASS) - 1)) == 0 ? FMD_B_TRUE : FMD_B_FALSE;
+
+ if (isireport) {
+ char *pri;
+
+ if (nvlist_lookup_string(nvl, FM_IREPORT_PRIORITY, &pri) == 0 &&
+ strncmp(pri, "high", 5) == 0) {
+ ishvireport = 1;
+ } else {
+ ishvireport = 0;
+ }
+ }
/*
* The logonly flag should only be set for ereports.
*/
- if ((logonly == FMD_B_TRUE) && (isereport == FMD_B_FALSE)) {
+ if (logonly == FMD_B_TRUE && isereport == FMD_B_FALSE) {
fmd_error(EFMD_XPRT_INVAL, "discarding nvlist %p: "
"logonly flag is not valid for class %s",
(void *)nvl, class);
@@ -1605,13 +1622,30 @@ fmd_xprt_recv(fmd_xprt_t *xp, nvlist_t *nvl, hrtime_t hrt, boolean_t logonly)
}
/*
- * Record the event in the errlog if it is an ereport. This code will
+ * Record ereports and ireports in the log. This code will
* be replaced later with a per-transport intent log instead.
*/
- if (isereport == FMD_B_TRUE) {
- (void) pthread_rwlock_rdlock(&dp->d_log_lock);
- fmd_log_append(dp->d_errlog, e, NULL);
- (void) pthread_rwlock_unlock(&dp->d_log_lock);
+ if (isereport == FMD_B_TRUE || isireport == FMD_B_TRUE ||
+ issysevent == B_TRUE) {
+ pthread_rwlock_t *lockp;
+ fmd_log_t *lp;
+
+ if (isereport == FMD_B_TRUE) {
+ lp = fmd.d_errlog;
+ lockp = &fmd.d_log_lock;
+ } else {
+ if (ishvireport || issysevent) {
+ lp = fmd.d_hvilog;
+ lockp = &fmd.d_hvilog_lock;
+ } else {
+ lp = fmd.d_ilog;
+ lockp = &fmd.d_ilog_lock;
+ }
+ }
+
+ (void) pthread_rwlock_rdlock(lockp);
+ fmd_log_append(lp, e, NULL);
+ (void) pthread_rwlock_unlock(lockp);
}
/*