diff options
Diffstat (limited to 'usr/src/cmd/fm/fmd/common')
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); } /* |
