changeset 1303:6e5751a0b831

PSARC 2005/754 FMA SNMP Agent 6365742 fault management data needs an SNMP interface 6365743 need 64-bit fmd scheme plugins
author wesolows
date Fri, 20 Jan 2006 16:06:55 -0800
parents 5f5721284f8d
children ae3fd4243c79
files usr/src/Targetdirs usr/src/cmd/fm/fmd/common/fmd_case.c usr/src/cmd/fm/fmd/common/fmd_case.h usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c usr/src/cmd/fm/fmd/common/fmd_rpc_adm.x usr/src/cmd/fm/modules/common/Makefile usr/src/cmd/fm/modules/common/snmp-trapgen/Makefile usr/src/cmd/fm/modules/common/snmp-trapgen/fmd-trapgen.conf usr/src/cmd/fm/modules/common/snmp-trapgen/snmp-trapgen.conf usr/src/cmd/fm/modules/common/snmp-trapgen/snmp.c usr/src/cmd/fm/schemes/Makefile.com usr/src/cmd/fm/schemes/Makefile.targ usr/src/cmd/fm/schemes/cpu/Makefile usr/src/cmd/fm/schemes/cpu/Makefile.com usr/src/cmd/fm/schemes/cpu/Makefile.targ usr/src/cmd/fm/schemes/cpu/amd64/Makefile usr/src/cmd/fm/schemes/cpu/i386/Makefile usr/src/cmd/fm/schemes/cpu/sparc/Makefile usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile usr/src/cmd/fm/schemes/dev/Makefile usr/src/cmd/fm/schemes/dev/Makefile.com usr/src/cmd/fm/schemes/dev/amd64/Makefile usr/src/cmd/fm/schemes/dev/i386/Makefile usr/src/cmd/fm/schemes/dev/sparc/Makefile usr/src/cmd/fm/schemes/dev/sparcv9/Makefile usr/src/cmd/fm/schemes/fmd/Makefile usr/src/cmd/fm/schemes/fmd/amd64/Makefile usr/src/cmd/fm/schemes/fmd/i386/Makefile usr/src/cmd/fm/schemes/fmd/sparc/Makefile usr/src/cmd/fm/schemes/fmd/sparcv9/Makefile usr/src/cmd/fm/schemes/hc/Makefile usr/src/cmd/fm/schemes/hc/amd64/Makefile usr/src/cmd/fm/schemes/hc/i386/Makefile usr/src/cmd/fm/schemes/hc/sparc/Makefile usr/src/cmd/fm/schemes/hc/sparcv9/Makefile usr/src/cmd/fm/schemes/legacy-hc/Makefile usr/src/cmd/fm/schemes/legacy-hc/amd64/Makefile usr/src/cmd/fm/schemes/legacy-hc/i386/Makefile usr/src/cmd/fm/schemes/legacy-hc/sparc/Makefile usr/src/cmd/fm/schemes/legacy-hc/sparcv9/Makefile usr/src/cmd/fm/schemes/mem/Makefile usr/src/cmd/fm/schemes/mem/Makefile.com usr/src/cmd/fm/schemes/mem/Makefile.targ usr/src/cmd/fm/schemes/mem/mem.c usr/src/cmd/fm/schemes/mem/mem_unum.c usr/src/cmd/fm/schemes/mem/sparc/Makefile usr/src/cmd/fm/schemes/mem/sparcv9/Makefile usr/src/cmd/fm/schemes/mod/Makefile usr/src/cmd/fm/schemes/mod/amd64/Makefile usr/src/cmd/fm/schemes/mod/i386/Makefile usr/src/cmd/fm/schemes/mod/sparc/Makefile usr/src/cmd/fm/schemes/mod/sparcv9/Makefile usr/src/cmd/fm/schemes/pkg/Makefile usr/src/cmd/fm/schemes/pkg/amd64/Makefile usr/src/cmd/fm/schemes/pkg/i386/Makefile usr/src/cmd/fm/schemes/pkg/sparc/Makefile usr/src/cmd/fm/schemes/pkg/sparcv9/Makefile usr/src/lib/fm/Makefile usr/src/lib/fm/libfmd_adm/Makefile.com usr/src/lib/fm/libfmd_adm/common/fmd_adm.c usr/src/lib/fm/libfmd_adm/common/fmd_adm.h usr/src/lib/fm/libfmd_adm/spec/fmd_adm.spec usr/src/lib/fm/libfmd_snmp/Makefile usr/src/lib/fm/libfmd_snmp/Makefile.com usr/src/lib/fm/libfmd_snmp/amd64/Makefile usr/src/lib/fm/libfmd_snmp/common/debug_subr.c usr/src/lib/fm/libfmd_snmp/common/fmd_snmp.h usr/src/lib/fm/libfmd_snmp/common/init.c usr/src/lib/fm/libfmd_snmp/common/llib-lfmd_snmp usr/src/lib/fm/libfmd_snmp/common/module.c usr/src/lib/fm/libfmd_snmp/common/module.h usr/src/lib/fm/libfmd_snmp/common/problem.c usr/src/lib/fm/libfmd_snmp/common/problem.h usr/src/lib/fm/libfmd_snmp/common/resource.c usr/src/lib/fm/libfmd_snmp/common/resource.h usr/src/lib/fm/libfmd_snmp/common/scheme.c usr/src/lib/fm/libfmd_snmp/common/sunFM_impl.h usr/src/lib/fm/libfmd_snmp/i386/Makefile usr/src/lib/fm/libfmd_snmp/mibs/SUN-FM-MIB.mib usr/src/lib/fm/libfmd_snmp/sparc/Makefile usr/src/lib/fm/libfmd_snmp/sparcv9/Makefile usr/src/lib/fm/libfmd_snmp/spec/Makefile usr/src/lib/fm/libfmd_snmp/spec/Makefile.targ usr/src/lib/fm/libfmd_snmp/spec/amd64/Makefile usr/src/lib/fm/libfmd_snmp/spec/fmd_snmp.spec usr/src/lib/fm/libfmd_snmp/spec/i386/Makefile usr/src/lib/fm/libfmd_snmp/spec/sparc/Makefile usr/src/lib/fm/libfmd_snmp/spec/sparcv9/Makefile usr/src/lib/fm/libfmd_snmp/spec/versions usr/src/pkgdefs/Makefile usr/src/pkgdefs/SUNWckr/prototype_com usr/src/pkgdefs/SUNWfmd/Makefile usr/src/pkgdefs/SUNWfmd/depend usr/src/pkgdefs/SUNWfmd/prototype_com usr/src/pkgdefs/SUNWfmd/prototype_i386 usr/src/pkgdefs/SUNWfmd/prototype_sparc usr/src/pkgdefs/SUNWfmdr/Makefile usr/src/pkgdefs/SUNWfmdr/pkginfo.tmpl usr/src/pkgdefs/SUNWfmdr/prototype_com usr/src/pkgdefs/SUNWfmdr/prototype_i386 usr/src/pkgdefs/SUNWfmdr/prototype_sparc usr/src/tools/scripts/check_rtime.pl
diffstat 102 files changed, 7052 insertions(+), 211 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/Targetdirs	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/Targetdirs	Fri Jan 20 16:06:55 2006 -0800
@@ -1,13 +1,9 @@
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
 #
 # 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.
@@ -22,8 +18,15 @@
 #
 # CDDL HEADER END
 #
+
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
+
+#
 # The list is built of owner-group combinations.  ROOT.SYS occurs twice
 # because some directories owned by root and in group sys are subdirectories
 # of directories having other owner-group attributes.
@@ -169,6 +172,8 @@
 
 ROOT.BIN= \
 	/etc/saf \
+	/etc/sma \
+	/etc/sma/snmp \
 	/lib \
 	/lib/secure \
 	/lib/svc \
--- a/usr/src/cmd/fm/fmd/common/fmd_case.c	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/fmd/common/fmd_case.c	Fri Jan 20 16:06:55 2006 -0800
@@ -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,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -365,6 +364,10 @@
 	case FMD_CASE_SOLVED:
 		fmd_case_convict(cp);
 		nvl = fmd_case_mkevent(cp, FM_LIST_SUSPECT_CLASS);
+		(void) pthread_mutex_lock(&cip->ci_lock);
+		if (cip->ci_diag == NULL)
+			(void) nvlist_xdup(nvl, &cip->ci_diag, &fmd.d_nva);
+		(void) pthread_mutex_unlock(&cip->ci_lock);
 		(void) nvlist_lookup_string(nvl, FM_CLASS, &class);
 
 		e = fmd_event_create(FMD_EVT_PROTOCOL, FMD_HRT_NOW, nvl, class);
@@ -656,6 +659,9 @@
 	fmd_free(cip->ci_code, cip->ci_codelen);
 	fmd_buf_hash_destroy(&cip->ci_bufs);
 
+	if (cip->ci_diag != NULL)
+		nvlist_free(cip->ci_diag);
+
 	fmd_module_rele(cip->ci_mod);
 	fmd_free(cip, sizeof (fmd_case_impl_t));
 }
--- a/usr/src/cmd/fm/fmd/common/fmd_case.h	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/fmd/common/fmd_case.h	Fri Jan 20 16:06:55 2006 -0800
@@ -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,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -74,6 +73,7 @@
 	uint_t ci_nsuspects;		/* number of ci_suspects */
 	size_t ci_nvsz;			/* packed suspect nvlist array size */
 	fmd_buf_hash_t ci_bufs;		/* hash of bufs associated with case */
+	nvlist_t *ci_diag;		/* cached event payload */
 } fmd_case_impl_t;
 
 #define	FMD_CASE_CURRENT	-1u	/* flag for current state */
--- a/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.c	Fri Jan 20 16:06:55 2006 -0800
@@ -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,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -705,6 +705,132 @@
 	return (TRUE);
 }
 
+void
+fmd_adm_caselist_case(fmd_case_t *cp, void *arg)
+{
+	fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
+	struct fmd_rpc_caselist *rcl = arg;
+	size_t uuid_len, buf_len;
+	void *p;
+
+	if (rcl->rcl_err != 0)
+		return;
+
+	/*
+	 * Lock the case and reallocate rcl_buf[] to be large enough to hold
+	 * another string, doubling it as needed.  Then copy the new string
+	 * on to the end, and increment rcl_len to indicate the used space.
+	 */
+	if (!(cip->ci_flags & FMD_CF_SOLVED))
+		return;
+
+	(void) pthread_mutex_lock(&cip->ci_lock);
+
+	uuid_len = cip->ci_uuidlen + 1;
+
+	while (rcl->rcl_len + uuid_len > rcl->rcl_buf.rcl_buf_len) {
+		if (rcl->rcl_buf.rcl_buf_len != 0)
+			buf_len = rcl->rcl_buf.rcl_buf_len * 2;
+		else
+			buf_len = 1024; /* default buffer size */
+
+		if ((p = realloc(rcl->rcl_buf.rcl_buf_val, buf_len)) != NULL) {
+			bzero((char *)p + rcl->rcl_buf.rcl_buf_len,
+			    buf_len - rcl->rcl_buf.rcl_buf_len);
+			rcl->rcl_buf.rcl_buf_val = p;
+			rcl->rcl_buf.rcl_buf_len = buf_len;
+		} else {
+			rcl->rcl_err = FMD_ADM_ERR_NOMEM;
+			break;
+		}
+	}
+
+	if (rcl->rcl_err == 0) {
+		bcopy(cip->ci_uuid, (char *)rcl->rcl_buf.rcl_buf_val +
+		    rcl->rcl_len, uuid_len);
+		rcl->rcl_len += uuid_len;
+		rcl->rcl_cnt++;
+	}
+
+	(void) pthread_mutex_unlock(&cip->ci_lock);
+}
+
+bool_t
+fmd_adm_caselist_1_svc(struct fmd_rpc_caselist *rvp, struct svc_req *req)
+{
+	rvp->rcl_buf.rcl_buf_len = 0;
+	rvp->rcl_buf.rcl_buf_val = NULL;
+	rvp->rcl_len = 0;
+	rvp->rcl_cnt = 0;
+	rvp->rcl_err = 0;
+
+	if (fmd_rpc_deny(req))
+		rvp->rcl_err = FMD_ADM_ERR_PERM;
+	else
+		fmd_case_hash_apply(fmd.d_cases, fmd_adm_caselist_case, rvp);
+
+	return (TRUE);
+}
+
+bool_t
+fmd_adm_caseinfo_1_svc(char *uuid, struct fmd_rpc_caseinfo *rvp,
+    struct svc_req *req)
+{
+	fmd_case_impl_t *cip;
+	nvlist_t *nvl;
+	int err = 0;
+
+	bzero(rvp, sizeof (struct fmd_rpc_caseinfo));
+
+	if (fmd_rpc_deny(req)) {
+		rvp->rci_err = FMD_ADM_ERR_PERM;
+		return (TRUE);
+	}
+
+	if ((cip = (fmd_case_impl_t *)fmd_case_hash_lookup(fmd.d_cases, uuid))
+	    == NULL) {
+		rvp->rci_err = FMD_ADM_ERR_CASESRCH;
+		return (TRUE);
+	}
+
+	if (!(cip->ci_flags & FMD_CF_SOLVED)) {
+		fmd_case_rele((fmd_case_t *)cip);
+		rvp->rci_err = FMD_ADM_ERR_CASESRCH;
+		return (TRUE);
+	}
+
+	/*
+	 * Avoid a race on cip->ci_diag; we can't call fmd_case_mkevent
+	 * while holding the case lock, so we do this dance instead.
+	 */
+	(void) pthread_mutex_lock(&cip->ci_lock);
+	nvl = cip->ci_diag;
+	(void) pthread_mutex_unlock(&cip->ci_lock);
+
+	if (nvl == NULL)
+		nvl = fmd_case_mkevent((fmd_case_t *)cip,
+		    FM_LIST_SUSPECT_CLASS);
+
+	(void) pthread_mutex_lock(&cip->ci_lock);
+	if (cip->ci_diag == NULL) {
+		cip->ci_diag = nvl;
+	} else if (nvl != cip->ci_diag) {
+		nvlist_free(nvl);
+		nvl = cip->ci_diag;
+	}
+	(void) pthread_mutex_unlock(&cip->ci_lock);
+
+	err = nvlist_pack(nvl, &rvp->rci_evbuf.rci_evbuf_val,
+	    &rvp->rci_evbuf.rci_evbuf_len, NV_ENCODE_XDR, 0);
+
+	if (err != 0)
+		rvp->rci_err = FMD_ADM_ERR_NOMEM;
+
+	fmd_case_rele((fmd_case_t *)cip);
+
+	return (TRUE);
+}
+
 /*ARGSUSED*/
 static void
 fmd_adm_xprtlist_one(fmd_idspace_t *ids, id_t id, void *arg)
--- a/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.x	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/fmd/common/fmd_rpc_adm.x	Fri Jan 20 16:06:55 2006 -0800
@@ -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,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -111,6 +110,18 @@
 	enum fmd_adm_error rxl_err;
 };
 
+struct fmd_rpc_caseinfo {
+	opaque rci_evbuf<>;
+	enum fmd_adm_error rci_err;
+};
+
+struct fmd_rpc_caselist {
+	opaque rcl_buf<>;
+	uint32_t rcl_len;
+	uint32_t rcl_cnt;
+	enum fmd_adm_error rcl_err;
+};
+
 program FMD_ADM {
 	version FMD_ADM_VERSION_1 {
 		struct fmd_rpc_modlist FMD_ADM_MODINFO(void) = 1;
@@ -131,6 +142,8 @@
 		int FMD_ADM_CASEREPAIR(string) = 16;
 		struct fmd_rpc_xprtlist FMD_ADM_XPRTLIST(void) = 17;
 		struct fmd_rpc_modstat FMD_ADM_XPRTSTAT(int32_t) = 18;
+		struct fmd_rpc_caselist FMD_ADM_CASELIST(void) = 19;
+		struct fmd_rpc_caseinfo FMD_ADM_CASEINFO(string) = 20;
 	} = 1;
 } = 100169;
 
--- a/usr/src/cmd/fm/modules/common/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/modules/common/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,12 +18,15 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
-SUBDIRS = cpumem-retire eversholt io-retire ip-transport syslog-msgs
+SUBDIRS = cpumem-retire eversholt io-retire ip-transport snmp-trapgen	\
+	syslog-msgs
 
 include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/modules/common/snmp-trapgen/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,51 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MODULE = snmp-trapgen
+CLASS = common
+SRCS = snmp.c
+SMASNMPCONFS = fmd-trapgen.conf
+
+ROOTSMASNMPDIR = $(ROOT)/etc/sma/snmp
+ROOTSMASNMPCONFS = $(SMASNMPCONFS:%=$(ROOTSMASNMPDIR)/%)
+
+include ../../Makefile.plugin
+
+SNMPLIBS = -lnetsnmp -lnetsnmpagent
+lint := SNMPLIBS =
+
+CPPFLAGS += -I/usr/sfw/include
+LDFLAGS += -L/usr/sfw/lib -R/usr/sfw/lib
+LDLIBS += $(SNMPLIBS)
+
+$(ROOTSMASNMPCONFS) := FILEMODE = 0600
+
+$(ROOTSMASNMPDIR)/%: %
+	$(INS.file)
+
+install: $(ROOTSMASNMPCONFS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/modules/common/snmp-trapgen/fmd-trapgen.conf	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,34 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+#
+# Supplemental configuration for the snmp-trapgen FMA module.  Normal
+# configuration of this module should be made via trap sink directives
+# in /etc/sma/snmp/snmpd.conf, not in this file.  See snmpd(4) and
+# snmp_config(4).
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/modules/common/snmp-trapgen/snmp-trapgen.conf	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,31 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+#
+# snmp-trapgen agent properties:
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/modules/common/snmp-trapgen/snmp.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,386 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/fm/protocol.h>
+#include <fm/fmd_api.h>
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <locale.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <alloca.h>
+
+/*
+ * SNMP_DOMAIN defines the dgettext() parameters the agent
+ * can use to retrieve the localized format string for diagnosis messages.
+ * The format string retrieved from SNMP_DOMAIN is the default format
+ * string, but when processing each suspect list, dgettext() is also called
+ * for the domain that matches the diagcode dictname.
+ *
+ * Similarly, SNMP_URL is also checked to see if snmp_url
+ * should be overridden for each suspect list.
+ *
+ * The net effect of all this is that for a given diagcode DICT-1234-56:
+ *
+ *	- If DICT.mo defines snmp-url, it is used when filling
+ *	  in the sunFmProblemURL variable.
+ *
+ *	- Otherwise, if snmp-trapgen.conf defines a "url" property, that
+ *	  value is used.
+ *
+ *	- Otherwise, the default "http://sun.com/msg/" is used (via the
+ *	  fmd_props[] table defined in this file).
+ */
+static const char SNMP_DOMAIN[] = "FMD";
+static const char SNMP_URL[] = SNMP_URL_MSG;
+
+static struct stats {
+	fmd_stat_t bad_vers;
+	fmd_stat_t bad_code;
+	fmd_stat_t bad_uuid;
+	fmd_stat_t no_trap;
+} snmp_stats = {
+	{ "bad_vers", FMD_TYPE_UINT64, "event version is missing or invalid" },
+	{ "bad_code", FMD_TYPE_UINT64, "event code has no dictionary name" },
+	{ "bad_uuid", FMD_TYPE_UINT64, "event uuid is too long to send" },
+	{ "no_trap", FMD_TYPE_UINT64, "trap generation suppressed" }
+};
+
+static char *snmp_locdir;	/* l10n messages directory (if alternate) */
+static char *snmp_url;		/* current value of "url" property */
+static int snmp_trapall;	/* set to trap on all faults */
+
+static const char SNMP_SUPPCONF[] = "fmd-trapgen";
+
+/*ARGSUSED*/
+static void
+send_trap(fmd_hdl_t *hdl, const char *uuid, const char *code, const char *url)
+{
+	static const oid sunFmProblemTrap_oid[] = { SUNFMPROBLEMTRAP_OID };
+	const size_t sunFmProblemTrap_len = OID_LENGTH(sunFmProblemTrap_oid);
+
+	static const oid sunFmProblemUUID_oid[] =
+	    { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_UUID };
+	static const oid sunFmProblemCode_oid[] =
+	    { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_CODE };
+	static const oid sunFmProblemURL_oid[] =
+	    { SUNFMPROBLEMTABLE_OID, 1, SUNFMPROBLEM_COL_URL };
+
+	const size_t sunFmProblem_base_len = OID_LENGTH(sunFmProblemUUID_oid);
+
+	size_t uuid_len = strlen(uuid);
+	size_t var_len = sunFmProblem_base_len + 1 + uuid_len;
+	oid var_name[MAX_OID_LEN];
+	int i;
+
+	netsnmp_variable_list *notification_vars = NULL;
+
+	/*
+	 * The format of our trap varbinds' oids is as follows:
+	 *
+	 * +-----------------------+---+--------+----------+------+
+	 * | SUNFMPROBLEMTABLE_OID | 1 | column | uuid_len | uuid |
+	 * +-----------------------+---+--------+----------+------+
+	 *					 \---- index ----/
+	 *
+	 * A common mistake here is to send the trap with varbinds that
+	 * do not contain the index.  All the indices are the same, and
+	 * all the oids are the same length, so the only thing we need to
+	 * do for each varbind is set the table and column parts of the
+	 * variable name.
+	 */
+
+	if (var_len > MAX_OID_LEN) {
+		snmp_stats.bad_uuid.fmds_value.ui64++;
+		return;
+	}
+
+	var_name[sunFmProblem_base_len] = (oid)uuid_len;
+	for (i = 0; i < uuid_len; i++)
+		var_name[i + sunFmProblem_base_len + 1] = (oid)uuid[i];
+
+	/*
+	 * Ordinarily, we would need to add the OID of the trap itself
+	 * to the head of the variable list; this is required by SNMP v2.
+	 * However, send_enterprise_trap_vars does this for us as a part
+	 * of converting between v1 and v2 traps, so we skip directly to
+	 * the objects we're sending.
+	 */
+
+	(void) memcpy(var_name, sunFmProblemUUID_oid,
+	    sunFmProblem_base_len * sizeof (oid));
+	(void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
+	    ASN_OCTET_STR, (uchar_t *)uuid, strlen(uuid));
+	(void) memcpy(var_name, sunFmProblemCode_oid,
+	    sunFmProblem_base_len * sizeof (oid));
+	(void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
+	    ASN_OCTET_STR, (uchar_t *)code, strlen(code));
+	(void) memcpy(var_name, sunFmProblemURL_oid,
+	    sunFmProblem_base_len * sizeof (oid));
+	(void) snmp_varlist_add_variable(&notification_vars, var_name, var_len,
+	    ASN_OCTET_STR, (uchar_t *)url, strlen(url));
+
+	/*
+	 * This function is capable of sending both v1 and v2/v3 traps.
+	 * Which is sent to a specific destination is determined by the
+	 * configuration file(s).
+	 */
+	send_enterprise_trap_vars(SNMP_TRAP_ENTERPRISESPECIFIC,
+	    sunFmProblemTrap_oid[sunFmProblemTrap_len - 1],
+	    (oid *)sunFmProblemTrap_oid, sunFmProblemTrap_len - 2,
+	    notification_vars);
+
+	snmp_free_varbind(notification_vars);
+}
+
+/*ARGSUSED*/
+static void
+snmp_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
+{
+	char *uuid, *code, *dict, *url, *urlcode, *p;
+	boolean_t domsg;
+
+	uint8_t version;
+	char *olang = NULL;
+	size_t len;
+
+	if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 ||
+	    version > FM_SUSPECT_VERSION) {
+		fmd_hdl_debug(hdl, "invalid event version: %u\n", version);
+		snmp_stats.bad_vers.fmds_value.ui64++;
+		return;
+	}
+
+	if (!snmp_trapall && nvlist_lookup_boolean_value(nvl,
+	    FM_SUSPECT_MESSAGE, &domsg) == 0 && !domsg) {
+		fmd_hdl_debug(hdl, "%s requested no trap\n", class);
+		snmp_stats.no_trap.fmds_value.ui64++;
+		return;
+	}
+
+	/*
+	 * Extract the uuid and diagcode dictionary from the event code.  The
+	 * dictionary name is the text preceding the first "-" in the code.
+	 */
+	(void) nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid);
+	(void) nvlist_lookup_string(nvl, FM_SUSPECT_DIAG_CODE, &code);
+
+	if ((p = strchr(code, '-')) == NULL || p == code) {
+		fmd_hdl_debug(hdl, "invalid diagnosis code: %s\n", code);
+		snmp_stats.bad_code.fmds_value.ui64++;
+		return;
+	}
+
+	dict = alloca((size_t)(p - code) + 1);
+	(void) strncpy(dict, code, (size_t)(p - code));
+	dict[(size_t)(p - code)] = '\0';
+
+	if (snmp_locdir != NULL)
+		(void) bindtextdomain(dict, snmp_locdir);
+
+	if ((url = dgettext(dict, SNMP_URL)) == SNMP_URL) {
+		/*
+		 * We didn't find a translation in the dictionary for the
+		 * current language.  Fall back to C and try again.
+		 */
+		olang = setlocale(LC_MESSAGES, NULL);
+		fmd_hdl_debug(hdl, "dgettext(%s, %s) in %s failed; trying C\n",
+		    dict, SNMP_URL, olang);
+		(void) setlocale(LC_MESSAGES, "C");
+		if ((url = dgettext(dict, SNMP_URL)) == SNMP_URL)
+			url = snmp_url;
+	}
+
+	/*
+	 * If the URL ends with a slash, that indicates the code should be
+	 * appended to it.  After formatting the URL, reformat the DESC
+	 * text using the URL as an snprintf argument.
+	 */
+	len = strlen(url);
+	if (url[len - 1] == '/') {
+		urlcode = alloca(len + strlen(code) + 1);
+		(void) snprintf(urlcode, INT_MAX, "%s%s", url, code);
+	} else {
+		urlcode = url;
+	}
+
+	/*
+	 * We have what we need; now send the trap.
+	 */
+	send_trap(hdl, uuid, code, urlcode);
+
+	/*
+	 * Switch back to our original language if we had to fall back to C.
+	 */
+	if (olang != NULL)
+		(void) setlocale(LC_MESSAGES, olang);
+}
+
+static int
+init_sma(void)
+{
+	int err;
+
+	/*
+	 * The only place we could possibly log is syslog, but the
+	 * full agent doesn't normally log there.  It would be confusing
+	 * if this agent did so; therefore we disable logging entirely.
+	 */
+	snmp_disable_log();
+
+	/*
+	 * Net-SNMP has a provision for reading an arbitrary number of
+	 * configuration files.  A configuration file is read if it has
+	 * had any handlers registered for it, or if it's the value in
+	 * of NETSNMP_DS_LIB_APPTYPE.  Our objective here is to read
+	 * both snmpd.conf and fmd-trapgen.conf.
+	 */
+	if ((err = netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+	    NETSNMP_DS_AGENT_ROLE, 0 /* MASTER_AGENT */)) != SNMPERR_SUCCESS)
+		return (err);
+
+	init_agent_read_config("snmpd");
+	if ((err = netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID,
+	    NETSNMP_DS_LIB_APPTYPE, SNMP_SUPPCONF)) != SNMPERR_SUCCESS)
+		return (err);
+	if (register_app_config_handler("trapsink", snmpd_parse_config_trapsink,
+	    snmpd_free_trapsinks, "host [community] [port]") == NULL)
+		return (SNMPERR_MALLOC);
+	if (register_app_config_handler("trap2sink",
+	    snmpd_parse_config_trap2sink, NULL, "host [community] [port]") ==
+	    NULL)
+		return (SNMPERR_MALLOC);
+	if (register_app_config_handler("trapsess", snmpd_parse_config_trapsess,
+	    NULL, "[snmpcmdargs] host") == NULL)
+		return (SNMPERR_MALLOC);
+
+	init_traps();
+	init_snmp(SNMP_SUPPCONF);
+
+	return (SNMPERR_SUCCESS);
+}
+
+static const fmd_prop_t fmd_props[] = {
+	{ "url", FMD_TYPE_STRING, "http://sun.com/msg/" },
+	{ "trap_all", FMD_TYPE_BOOL, "false" },
+	{ NULL, 0, NULL }
+};
+
+static const fmd_hdl_ops_t fmd_ops = {
+	snmp_recv,	/* fmdo_recv */
+	NULL,		/* fmdo_timeout */
+	NULL,		/* fmdo_close */
+	NULL,		/* fmdo_stats */
+	NULL,		/* fmdo_gc */
+};
+
+static const fmd_hdl_info_t fmd_info = {
+	"SNMP Trap Generation Agent", "1.0", &fmd_ops, fmd_props
+};
+
+void
+_fmd_init(fmd_hdl_t *hdl)
+{
+	char *rootdir, *locdir;
+
+	if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
+		return; /* invalid data in configuration file */
+
+	(void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, sizeof (snmp_stats) /
+	    sizeof (fmd_stat_t), (fmd_stat_t *)&snmp_stats);
+
+	if (init_sma() != SNMPERR_SUCCESS)
+		fmd_hdl_abort(hdl, "snmp-trapgen agent initialization failed");
+
+	/*
+	 * All FMA event dictionaries use msgfmt(1) message objects to produce
+	 * messages, even for the C locale.  We therefore want to use dgettext
+	 * for all message lookups, but its defined behavior in the C locale is
+	 * to return the input string.  Since our input strings are event codes
+	 * and not format strings, this doesn't help us.  We resolve this nit
+	 * by setting NLSPATH to a non-existent file: the presence of NLSPATH
+	 * is defined to force dgettext(3C) to do a full lookup even for C.
+	 */
+	if (getenv("NLSPATH") == NULL && putenv(fmd_hdl_strdup(hdl,
+	    "NLSPATH=/usr/lib/fm/fmd/fmd.cat", FMD_SLEEP)) != 0)
+		fmd_hdl_abort(hdl, "snmp-trapgen failed to set NLSPATH");
+
+	(void) setlocale(LC_MESSAGES, "");
+	fmd_hdl_debug(hdl, "locale=%s\n", setlocale(LC_MESSAGES, NULL));
+
+	/*
+	 * Cache any properties we use every time we receive an event and
+	 * subscribe to list.suspect events regardless of the .conf file.
+	 */
+	snmp_url = fmd_prop_get_string(hdl, "url");
+	snmp_trapall = fmd_prop_get_int32(hdl, "trap_all");
+
+	/*
+	 * If fmd's rootdir property is set to a non-default root, then we are
+	 * going to need to rebind the text domains we use for dgettext() as
+	 * we go.  Look up the default l10n messages directory and make
+	 * snmp_locdir be this path with fmd.rootdir prepended to it.
+	 */
+	rootdir = fmd_prop_get_string(hdl, "fmd.rootdir");
+
+	if (*rootdir != '\0' && strcmp(rootdir, "/") != 0 &&
+	    (locdir = bindtextdomain(SNMP_DOMAIN, NULL)) != NULL) {
+		size_t len = strlen(rootdir) + strlen(locdir) + 1;
+		snmp_locdir = fmd_hdl_alloc(hdl, len, FMD_SLEEP);
+		(void) snprintf(snmp_locdir, len, "%s%s", rootdir, locdir);
+		(void) bindtextdomain(SNMP_DOMAIN, snmp_locdir);
+		fmd_hdl_debug(hdl, "binding textdomain to %s\n", snmp_locdir);
+	}
+
+	fmd_prop_free_string(hdl, rootdir);
+	fmd_hdl_subscribe(hdl, FM_LIST_SUSPECT_CLASS);
+}
+
+void
+_fmd_fini(fmd_hdl_t *hdl)
+{
+	fmd_hdl_strfree(hdl, snmp_locdir);
+	fmd_prop_free_string(hdl, snmp_url);
+
+	/*
+	 * snmp_shutdown, which we would normally use here, calls free_slots,
+	 * a callback that is supposed to tear down the pkcs11 state; however,
+	 * it abuses C_Finalize, causing fmd to drop core on shutdown.  Avoid
+	 * this by shutting down the library piecemeal.
+	 */
+	snmp_store(SNMP_SUPPCONF);
+	snmp_alarm_unregister_all();
+	snmp_close_sessions();
+	shutdown_mib();
+	unregister_all_config_handlers();
+	netsnmp_ds_shutdown();
+}
--- a/usr/src/cmd/fm/schemes/Makefile.com	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -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,17 +18,19 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 .KEEP_STATE:
 .SUFFIXES:
 
-include ../../../Makefile.cmd
-SCHEME :sh= basename `pwd`
+include ../../../../Makefile.cmd
+SCHEME :sh= cd ..; basename `pwd`
 
 #
 # For now, we assume a scheme is named after its directory and its source file
@@ -41,13 +42,17 @@
 OBJS = $(SRCS:%.c=%.o)
 
 ROOTPROG = $(ROOT)/usr/lib/fm/fmd/schemes/$(PROG)
-MAPFILE = ../../fmd/common/fmd_fmri.map
+ROOTPROG64 = $(ROOT)/usr/lib/fm/fmd/schemes/$(MACH64)/$(PROG)
+MAPFILE = ../../../fmd/common/fmd_fmri.map
 
 LINTFLAGS += -u
+LINTFLAGS64 += -u
 LINTFILES = $(SRCS:%.c=%.ln)
 
 CFLAGS += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS)
 CFLAGS += -G $(XREGSFLAG)
-CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -D$(MACH) -I.
+CFLAGS64 += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS)
+CFLAGS64 += -G $(XREGSFLAG)
+CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -D$(MACH) -I..
 LDFLAGS += $(ZTEXT) $(ZCOMBRELOC) $(ZDEFS) $(ZIGNORE) -M$(MAPFILE)
 LDLIBS += -lnvpair -lc
--- a/usr/src/cmd/fm/schemes/Makefile.targ	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/Makefile.targ	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,13 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 all: $(PROG)
 
@@ -35,7 +36,7 @@
 	$(CTFMERGE) -L VERSION -o $@ $(OBJS)
 	$(POST_PROCESS_SO)
 
-%.o: %.c
+%.o: ../%.c
 	$(COMPILE.c) $<
 	$(CTFCONVERT_O)
 
@@ -45,7 +46,7 @@
 clobber: clean
 	$(RM) $(PROG)
 
-%.ln: %.c
+%.ln: ../%.c
 	$(LINT.c) -c $<
 
 lint: $(LINTFILES)
@@ -59,10 +60,14 @@
 $(ROOT)/usr/lib/fm/fmd: $(ROOT)/usr/lib/fm
 	$(INS.dir)
 
-$(ROOT)/usr/lib/fm/fmd/%: $(ROOT)/usr/lib/fm/fmd
+$(ROOT)/usr/lib/fm/fmd/schemes: $(ROOT)/usr/lib/fm/fmd
+	$(INS.dir)
+
+$(ROOT)/usr/lib/fm/fmd/schemes/$(MACH64): $(ROOT)/usr/lib/fm/fmd/schemes
 	$(INS.dir)
 
 $(ROOTPROG): $$(@D) $(PROG)
 	$(RM) $@; $(INS) -s -m 0555 -f $(@D) $(PROG)
 
-install: $(ROOTPROG)
+$(ROOTPROG64): $$(@D) $(PROG)
+	$(RM) $@; $(INS) -s -m 0555 -f $(@D) $(PROG)
--- a/usr/src/cmd/fm/schemes/cpu/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/cpu/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -20,33 +20,15 @@
 #
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
-
-include ../Makefile.com
-
-SCHEME_COMMON = ../common
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
-sparc_SRCS =	\
-	cpu_mdesc.c \
-	mdesc_devinit.c
-
-SRCS =	\
-	cpu.c \
-	$($(MACH)_SRCS)
+include ../../../Makefile.cmd
 
-sparc_LDLIBS = -L$(ROOTLIB)/fm -lmdesc
-LDLIBS += -lkstat $($(MACH)_LDLIBS)
-
-LDFLAGS += -R/usr/lib/fm
-
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
 
-%.o: $(SCHEME_COMMON)/%.c
-	$(COMPILE.c) -o $@ $<
-	$(CTFCONVERT_O)
-
-%.ln: $(SCHEME_COMMON)/%.c
-	$(LINT.c) -erroff=E_BAD_PTR_CAST_ALIGN -v -c $<
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+
+SCHEME_COMMON = ../../common
+
+sparc_SRCS =	\
+	cpu_mdesc.c \
+	mdesc_devinit.c
+
+SRCS =	\
+	cpu.c \
+	$($(MACH)_SRCS)
+
+LDLIBS += -lkstat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/Makefile.targ	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.targ
+
+%.o: $(SCHEME_COMMON)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
+%.ln: $(SCHEME_COMMON)/%.c
+	$(LINT.c) -erroff=E_BAD_PTR_CAST_ALIGN -v -c $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+LDFLAGS += -R/usr/lib/fm/$(MACH64)
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,35 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+
+LDFLAGS += -R/usr/lib/fm
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+
+LDLIBS += -L$(ROOTLIB)/fm -lmdesc
+LDFLAGS += -R/usr/lib/fm
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/cpu/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+LDLIBS += -L$(ROOTLIB)/fm/$(MACH64) -lmdesc
+LDFLAGS += -R/usr/lib/fm/$(MACH64)
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/dev/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/dev/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -20,13 +20,15 @@
 #
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
-include ../Makefile.com
+include ../../../Makefile.cmd
 
-LDLIBS +=-ldevinfo
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
 
-include ../Makefile.targ
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/dev/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,31 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+
+LDLIBS += -ldevinfo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/dev/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/dev/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/dev/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/dev/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/fmd/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/fmd/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../../Makefile.cmd
 
-include ../Makefile.com
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/fmd/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/fmd/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/fmd/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/fmd/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/hc/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/hc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../../Makefile.cmd
 
-include ../Makefile.com
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/hc/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/hc/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/hc/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/hc/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/legacy-hc/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/legacy-hc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../../Makefile.cmd
 
-include ../Makefile.com
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/legacy-hc/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/legacy-hc/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/legacy-hc/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/legacy-hc/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/mem/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,33 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
-include ../Makefile.com
-
-SCHEME_COMMON = ../common
+include ../../../Makefile.cmd
 
-SRCS = \
-	mdesc_devinit.c \
-	mem.c \
-	mem_disc.c \
-	mem_read.c \
-	mem_unum.c \
-	mem_util.c
-
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
 
-LDLIBS += -L$(ROOTLIB)/fm -lmdesc -lrt
-LDFLAGS += -R/usr/lib/fm
-
-include ../Makefile.targ
-
-%.o: $(SCHEME_COMMON)/%.c
-	$(COMPILE.c) -o $@ $<
-	$(CTFCONVERT_O)
-
-%.ln: $(SCHEME_COMMON)/%.c
-	$(LINT.c) -erroff=E_BAD_PTR_CAST_ALIGN -v -c $<
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mem/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,41 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+
+SCHEME_COMMON = ../../common
+
+SRCS =	\
+	mdesc_devinit.c \
+	mem.c \
+	mem_disc.c \
+	mem_read.c \
+	mem_unum.c \
+	mem_util.c
+
+LDLIBS += -lrt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mem/Makefile.targ	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.targ
+
+%.o: $(SCHEME_COMMON)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
+%.ln: $(SCHEME_COMMON)/%.c
+	$(LINT.c) -erroff=E_BAD_PTR_CAST_ALIGN -v -c $<
--- a/usr/src/cmd/fm/schemes/mem/mem.c	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/mem.c	Fri Jan 20 16:06:55 2006 -0800
@@ -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,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -296,14 +296,15 @@
 fmd_fmri_expand(nvlist_t *nvl)
 {
 	char *unum, **serids;
-	uint_t nserids;
+	uint_t nnvlserids;
+	size_t nserids;
 	int rc;
 
 	if (mem_fmri_get_unum(nvl, &unum) < 0)
 		return (fmd_fmri_set_errno(EINVAL));
 
 	if ((rc = nvlist_lookup_string_array(nvl, FM_FMRI_MEM_SERIAL_ID,
-	    &serids, &nserids)) == 0)
+	    &serids, &nnvlserids)) == 0)
 		return (0); /* fmri is already expanded */
 	else if (rc != ENOENT)
 		return (fmd_fmri_set_errno(EINVAL));
@@ -347,7 +348,8 @@
 fmd_fmri_present(nvlist_t *nvl)
 {
 	char *unum, **nvlserids, **serids;
-	uint_t nnvlserids, nserids;
+	uint_t nnvlserids;
+	size_t nserids;
 	uint64_t memconfig;
 	int rc;
 
--- a/usr/src/cmd/fm/schemes/mem/mem_unum.c	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mem/mem_unum.c	Fri Jan 20 16:06:55 2006 -0800
@@ -264,7 +264,7 @@
 unum_contains_bypat(const char *erunum, const char *eeunum)
 {
 	char **ernms, **eenms;
-	uint_t nernms, neenms;
+	size_t nernms, neenms;
 	int i, j, rv = 1;
 
 	if (mem_unum_burst(erunum, &ernms, &nernms) < 0)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mem/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+
+LDLIBS += -L$(ROOTLIB)/fm -lmdesc
+LDFLAGS += -R/usr/lib/fm
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mem/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+include $(SRC)/Makefile.master.64
+
+LDLIBS += -L$(ROOTLIB)/fm/$(MACH64) -lmdesc
+LDFLAGS += -R/usr/lib/fm/$(MACH64)
+
+include ../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/mod/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/mod/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../../Makefile.cmd
 
-include ../Makefile.com
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mod/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mod/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mod/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/mod/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/cmd/fm/schemes/pkg/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/cmd/fm/schemes/pkg/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../../Makefile.cmd
 
-include ../Makefile.com
-include ../Makefile.targ
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+include ../../Makefile.subdirs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/pkg/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/pkg/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/pkg/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include ../../Makefile.targ
+
+install: all $(ROOTPROG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/schemes/pkg/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.com
+include $(SRC)/Makefile.master.64
+include ../../Makefile.targ
+
+install: all $(ROOTPROG64)
--- a/usr/src/lib/fm/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/lib/fm/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,14 +18,17 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 sparc_SUBDIRS = libmdesc
 
-SUBDIRS = libdiagcode libfmd_adm libfmd_log libtopo $($(MACH)_SUBDIRS)
+SUBDIRS = libdiagcode libfmd_adm libfmd_log libfmd_snmp libtopo \
+	$($(MACH)_SUBDIRS)
 
 include ./Makefile.subdirs
--- a/usr/src/lib/fm/libfmd_adm/Makefile.com	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/lib/fm/libfmd_adm/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,12 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
 
 LIBRARY = libfmd_adm.a
 VERS = .1
@@ -44,7 +44,7 @@
 CPPFLAGS += -I../common -I.
 CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS)
 CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS)
-LDLIBS += -lnsl -lc
+LDLIBS += -lnvpair -lnsl -lc
 
 LINTFLAGS = -msux
 LINTFLAGS64 = -msux -Xarch=$(MACH64:sparcv9=v9)
--- a/usr/src/lib/fm/libfmd_adm/common/fmd_adm.c	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/lib/fm/libfmd_adm/common/fmd_adm.c	Fri Jan 20 16:06:55 2006 -0800
@@ -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,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,11 +30,16 @@
 #include <stdlib.h>
 #include <netdir.h>
 #include <errno.h>
+#include <alloca.h>
+#include <locale.h>
+#include <uuid/uuid.h>
 
+#include <sys/fm/protocol.h>
 #include <fmd_adm_impl.h>
 #include <fmd_rpc_adm.h>
 
 static const uint_t _fmd_adm_bufsize = 128 * 1024;
+static const char _url_fallback[] = "http://sun.com/msg/";
 
 fmd_adm_t *
 fmd_adm_open(const char *host, uint32_t prog, int version)
@@ -392,6 +396,29 @@
 	return (0);
 }
 
+int
+fmd_adm_rsrc_count(fmd_adm_t *ap, int all, uint32_t *rcp)
+{
+	struct fmd_rpc_rsrclist rrl;
+
+	if (rcp == NULL)
+		return (fmd_adm_set_errno(ap, EINVAL));
+
+	bzero(&rrl, sizeof (rrl)); /* tell xdr to allocate memory for us */
+
+	if (fmd_adm_rsrclist_1(all, &rrl, ap->adm_clnt) != RPC_SUCCESS)
+		return (fmd_adm_set_errno(ap, EPROTO));
+
+	if (rrl.rrl_err != 0) {
+		xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
+		return (fmd_adm_set_svcerr(ap, rrl.rrl_err));
+	}
+
+	*rcp = rrl.rrl_cnt;
+	xdr_free(xdr_fmd_rpc_rsrclist, (char *)&rrl);
+	return (0);
+}
+
 static int
 fmd_adm_rsrc_cmp(const void *lp, const void *rp)
 {
@@ -533,6 +560,162 @@
 }
 
 static int
+fmd_adm_case_cmp(const void *lp, const void *rp)
+{
+	return (strcmp(*(char **)lp, *(char **)rp));
+}
+
+static int
+fmd_adm_case_one(fmd_adm_caseinfo_t *acp, const char *url_token,
+    fmd_adm_case_f *func, void *arg)
+{
+	char *p, *urlcode, *dict, *olang;
+	const char *url;
+	size_t	len;
+
+	if ((p = strchr(acp->aci_code, '-')) == NULL ||
+	    p == acp->aci_code) {
+		acp->aci_url = NULL;
+	} else {
+		dict = alloca((size_t)(p - acp->aci_code) + 1);
+		(void) strncpy(dict, acp->aci_code,
+		    (size_t)(p - acp->aci_code));
+		dict[(size_t)(p - acp->aci_code)] = '\0';
+
+		/*
+		 * If we're given a token to use in looking up the URL, try
+		 * to use it.  Otherwise, or if we don't find it that way,
+		 * use the fallback.
+		 */
+		if (url_token == NULL) {
+			url = _url_fallback;
+		} else if ((url = dgettext(dict, url_token)) == url_token) {
+			/*
+			 * We didn't find a translation in the
+			 * dictionary for the current language.  Fall
+			 * back to C and try again.
+			 */
+			olang = setlocale(LC_MESSAGES, NULL);
+			(void) setlocale(LC_MESSAGES, "C");
+			if ((url = dgettext(dict, url_token)) == url_token)
+				url = _url_fallback;
+			(void) setlocale(LC_MESSAGES, olang);
+		}
+		len = strlen(url);
+		if (url[len - 1] == '/') {
+			len += strlen(acp->aci_code) + 1;
+			urlcode = alloca(len);
+			(void) snprintf(urlcode, len, "%s%s", url,
+			    acp->aci_code);
+		} else {
+			urlcode = (char *)url;
+		}
+		acp->aci_url = urlcode;
+	}
+
+	return (func(acp, arg));
+}
+
+/*
+ * Our approach to cases is the same as for resources: we first obtain a
+ * list of UUIDs, sort them, then obtain the case information for each.
+ */
+int
+fmd_adm_case_iter(fmd_adm_t *ap, const char *url_token, fmd_adm_case_f *func,
+    void *arg)
+{
+	struct fmd_rpc_caselist rcl;
+	struct fmd_rpc_caseinfo rci;
+	fmd_adm_caseinfo_t aci;
+	char **uuids, *p;
+	int i, rv;
+
+	bzero(&rcl, sizeof (rcl)); /* tell xdr to allocate memory for us */
+
+	if (fmd_adm_caselist_1(&rcl, ap->adm_clnt) != RPC_SUCCESS)
+		return (fmd_adm_set_errno(ap, EPROTO));
+
+	if (rcl.rcl_err != 0) {
+		xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+		return (fmd_adm_set_svcerr(ap, rcl.rcl_err));
+	}
+
+	if ((uuids = malloc(sizeof (char *) * rcl.rcl_cnt)) == NULL) {
+		xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+		return (fmd_adm_set_errno(ap, EAGAIN));
+	}
+
+	p = rcl.rcl_buf.rcl_buf_val;
+
+	for (i = 0; i < rcl.rcl_cnt; i++, p += strlen(p) + 1)
+		uuids[i] = p;
+
+	qsort(uuids, rcl.rcl_cnt, sizeof (char *), fmd_adm_case_cmp);
+
+	for (i = 0; i < rcl.rcl_cnt; i++) {
+		bzero(&rci, sizeof (rci));
+
+		if (fmd_adm_caseinfo_1(uuids[i], &rci, ap->adm_clnt)
+		    != RPC_SUCCESS) {
+			free(uuids);
+			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+			return (fmd_adm_set_errno(ap, EPROTO));
+		}
+
+		if (rci.rci_err != 0 && rci.rci_err != FMD_ADM_ERR_CASESRCH) {
+			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+			free(uuids);
+			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+			return (fmd_adm_set_svcerr(ap, rci.rci_err));
+		}
+
+		if (rci.rci_err == FMD_ADM_ERR_CASESRCH) {
+			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+			continue;
+		}
+
+		bzero(&aci, sizeof (aci));
+
+		if ((rv = nvlist_unpack(rci.rci_evbuf.rci_evbuf_val,
+		    rci.rci_evbuf.rci_evbuf_len, &aci.aci_event, 0)) != 0) {
+			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+			free(uuids);
+			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+			return (fmd_adm_set_errno(ap, rv));
+		}
+
+		if ((rv = nvlist_lookup_string(aci.aci_event, FM_SUSPECT_UUID,
+		    (char **)&aci.aci_uuid)) != 0) {
+			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+			free(uuids);
+			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+			nvlist_free(aci.aci_event);
+			return (fmd_adm_set_errno(ap, rv));
+		}
+		if ((rv = nvlist_lookup_string(aci.aci_event,
+		    FM_SUSPECT_DIAG_CODE, (char **)&aci.aci_code)) != 0) {
+			xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+			free(uuids);
+			xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+			nvlist_free(aci.aci_event);
+			return (fmd_adm_set_errno(ap, rv));
+		}
+
+		rv = fmd_adm_case_one(&aci, url_token, func, arg);
+
+		xdr_free(xdr_fmd_rpc_caseinfo, (char *)&rci);
+		nvlist_free(aci.aci_event);
+
+		if (rv != 0)
+			break;
+	}
+
+	free(uuids);
+	xdr_free(xdr_fmd_rpc_caselist, (char *)&rcl);
+	return (0);
+}
+
+static int
 fmd_adm_serd_cmp(const void *lp, const void *rp)
 {
 	return (strcmp((*(struct fmd_rpc_serdinfo **)lp)->rsi_name,
--- a/usr/src/lib/fm/libfmd_adm/common/fmd_adm.h	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/lib/fm/libfmd_adm/common/fmd_adm.h	Fri Jan 20 16:06:55 2006 -0800
@@ -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,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -91,12 +91,23 @@
 #define	FMD_ADM_RSRC_UNUSABLE	0x2	/* resource is unusable */
 #define	FMD_ADM_RSRC_INVISIBLE	0x4	/* resource is not directly visible */
 
+typedef struct fmd_adm_caseinfo {
+	const char *aci_uuid;
+	const char *aci_code;
+	const char *aci_url;
+	nvlist_t *aci_event;
+} fmd_adm_caseinfo_t;
+
 typedef int fmd_adm_rsrc_f(const fmd_adm_rsrcinfo_t *, void *);
+typedef int fmd_adm_case_f(const fmd_adm_caseinfo_t *, void *);
 
+extern int fmd_adm_rsrc_count(fmd_adm_t *, int, uint32_t *);
 extern int fmd_adm_rsrc_iter(fmd_adm_t *, int, fmd_adm_rsrc_f *, void *);
 extern int fmd_adm_rsrc_flush(fmd_adm_t *, const char *);
 extern int fmd_adm_rsrc_repair(fmd_adm_t *, const char *);
 extern int fmd_adm_case_repair(fmd_adm_t *, const char *);
+extern int fmd_adm_case_iter(fmd_adm_t *, const char *, fmd_adm_case_f *,
+    void *);
 
 typedef struct fmd_adm_serdinfo {
 	const char *asi_name;		/* name of serd engine */
--- a/usr/src/lib/fm/libfmd_adm/spec/fmd_adm.spec	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/lib/fm/libfmd_adm/spec/fmd_adm.spec	Fri Jan 20 16:06:55 2006 -0800
@@ -1,13 +1,9 @@
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
 #
 # 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.
@@ -22,12 +18,22 @@
 #
 # CDDL HEADER END
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 function	fmd_adm_case_repair
 version		SUNWprivate
 end
 
+function	fmd_adm_case_iter
+version		SUNWprivate
+end
+
 function        fmd_adm_close
 version         SUNWprivate
 end
@@ -68,6 +74,10 @@
 version		SUNWprivate
 end
 
+function	fmd_adm_rsrc_count
+version		SUNWprivate
+end
+
 function	fmd_adm_rsrc_flush
 version		SUNWprivate
 end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,78 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../../Makefile.lib
+include ../Makefile.lib
+
+FMHDRS = fmd_snmp.h
+HDRDIR = common
+
+SUBDIRS = $(MACH) 
+$(BUILD64)SUBDIRS += $(MACH64)
+
+MIBFILES = SUN-FM-MIB.mib
+
+ROOTSMAMIBDIR = $(ROOT)/etc/sma/snmp/mibs
+ROOTMIBS = $(MIBFILES:%=$(ROOTSMAMIBDIR)/%)
+
+$(ROOTMIBS) := FILEMODE = 0644
+$(ROOTSMAMIBDIR) := DIRMODE = 0755
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+all clean clobber: spec .WAIT $(SUBDIRS)
+
+install: install_h install_mibs spec .WAIT $(SUBDIRS)
+
+lint:
+
+install_h: $(ROOTFMHDRS)
+
+install_mibs: $(ROOTSMAMIBDIR) $(ROOTMIBS)
+
+check: $(CHECKHDRS)
+
+spec $(SUBDIRS): FRC
+	@cd $@; pwd; $(MAKE) $(TARGET)
+
+$(ROOTSMAMIBDIR):
+	$(INS.dir)
+
+$(ROOTSMAMIBDIR)/%: mibs/%
+	$(INS.file)
+
+FRC:
+
+include ../../Makefile.targ
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/Makefile.com	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,84 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+
+LIBRARY = libfmd_snmp.a
+VERS = .1
+
+LIBSRCS = \
+	debug_subr.c	\
+	init.c		\
+	module.c	\
+	problem.c	\
+	resource.c	\
+	scheme.c
+
+OBJECTS = $(LIBSRCS:%.c=%.o)
+
+include ../../../Makefile.lib
+include ../../Makefile.lib
+
+SRCS = $(LIBSRCS:%.c=../common/%.c)
+LIBS = $(DYNLIB) $(LINTLIB)
+
+SRCDIR = ../common
+SPECMAPFILE = $(MAPDIR)/mapfile
+
+CPPFLAGS += -I../common -I. -I/usr/sfw/include
+$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG
+CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS)
+CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS)
+
+LDLIBS += $(MACH_LDLIBS)
+LDLIBS += -lfmd_adm -luutil -lnvpair
+LDLIBS += -L$(SFWLIBDIR) -lnetsnmp -lnetsnmphelpers -lnetsnmpagent -lc
+DYNFLAGS += -R$(SFWLIBDIR)
+
+LINTFLAGS = -msux
+LINTFLAGS64 = -msux -Xarch=$(MACH64:sparcv9=v9)
+
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+$(LINTLIB) := LINTFLAGS = -nsvx
+$(LINTLIB) := LINTFLAGS64 = -nsvx -Xarch=$(MACH64:sparcv9=v9)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: $(LINTLIB) lintcheck
+
+pics/%.o: ../$(MACH)/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+%.o: ../common/%.c
+	$(COMPILE.c) -o $@ $<
+	$(POST_PROCESS_O)
+
+include ../../../Makefile.targ
+include ../../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MAPDIR = ../spec/amd64
+MACH_LDLIBS = -L$(ROOT)/usr/lib/fm/$(MACH64)
+
+include ../Makefile.com
+include ../../../Makefile.lib.64
+
+DYNFLAGS += -R/usr/lib/fm/$(MACH64)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/debug_subr.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,60 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <stdarg.h>
+
+void
+sunFm_vpanic(const char *format, va_list ap)
+{
+	snmp_vlog(LOG_ERR, format, ap);
+#ifdef DEBUG
+	abort();
+	exit(1);
+#endif
+}
+
+void
+sunFm_panic(const char *format, ...)
+{
+	va_list	ap;
+
+	va_start(ap, format);
+	sunFm_vpanic(format, ap);
+	va_end(ap);
+}
+
+int
+sunFm_assert(const char *expr, const char *file, int line)
+{
+	sunFm_panic("\"%s\", line %d: assertion failed: %s\n", file, line,
+	    expr);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/fmd_snmp.h	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,114 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SUNFM_H
+#define	_SUNFM_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * These values are derived from, and must remain consistent with, the
+ * MIB definitions.
+ */
+#define	MODNAME_STR	"sunFM"
+#define	SUNFM_OID	1, 3, 6, 1, 4, 1, 42, 2, 195, 1
+
+#define	SUNFMPROBLEMTABLE_OID		SUNFM_OID, 1
+
+#define	SUNFMPROBLEM_COL_UUIDINDEX	1
+#define	SUNFMPROBLEM_COL_UUID		2
+#define	SUNFMPROBLEM_COL_CODE		3
+#define	SUNFMPROBLEM_COL_URL		4
+#define	SUNFMPROBLEM_COL_DIAGENGINE	5
+#define	SUNFMPROBLEM_COL_DIAGTIME	6
+#define	SUNFMPROBLEM_COL_SUSPECTCOUNT	7
+
+#define	SUNFMPROBLEM_COLMIN		SUNFMPROBLEM_COL_UUID
+#define	SUNFMPROBLEM_COLMAX		SUNFMPROBLEM_COL_SUSPECTCOUNT
+
+#define	SUNFMFAULTEVENTTABLE_OID	SUNFM_OID, 2
+
+#define	SUNFMFAULTEVENT_COL_UUIDINDEX	1
+#define	SUNFMFAULTEVENT_COL_INDEX	2
+#define	SUNFMFAULTEVENT_COL_PROBLEMUUID	3
+#define	SUNFMFAULTEVENT_COL_CLASS	4
+#define	SUNFMFAULTEVENT_COL_CERTAINTY	5
+#define	SUNFMFAULTEVENT_COL_ASRU	6
+#define	SUNFMFAULTEVENT_COL_FRU		7
+#define	SUNFMFAULTEVENT_COL_RESOURCE	8
+
+#define	SUNFMFAULTEVENT_COLMIN		SUNFMFAULTEVENT_COL_PROBLEMUUID
+#define	SUNFMFAULTEVENT_COLMAX		SUNFMFAULTEVENT_COL_RESOURCE
+
+#define	SUNFMMODULETABLE_OID		SUNFM_OID, 3
+
+#define	SUNFMMODULE_COL_INDEX		1
+#define	SUNFMMODULE_COL_NAME		2
+#define	SUNFMMODULE_COL_VERSION		3
+#define	SUNFMMODULE_COL_STATUS		4
+#define	SUNFMMODULE_COL_DESCRIPTION	5
+
+#define	SUNFMMODULE_COLMIN		SUNFMMODULE_COL_NAME
+#define	SUNFMMODULE_COLMAX		SUNFMMODULE_COL_DESCRIPTION
+
+#define	SUNFMMODULE_STATE_OTHER		1
+#define	SUNFMMODULE_STATE_ACTIVE	2
+#define	SUNFMMODULE_STATE_FAILED	3
+
+#define	SUNFMRESOURCECOUNT_OID		SUNFM_OID, 4
+
+#define	SUNFMRESOURCETABLE_OID		SUNFM_OID, 5
+
+#define	SUNFMRESOURCE_COL_INDEX		1
+#define	SUNFMRESOURCE_COL_FMRI		2
+#define	SUNFMRESOURCE_COL_STATUS	3
+#define	SUNFMRESOURCE_COL_DIAGNOSISUUID	4
+
+#define	SUNFMRESOURCE_COLMIN		SUNFMRESOURCE_COL_FMRI
+#define	SUNFMRESOURCE_COLMAX		SUNFMRESOURCE_COL_DIAGNOSISUUID
+
+#define	SUNFMRESOURCE_STATE_OTHER	1
+#define	SUNFMRESOURCE_STATE_OK		2
+#define	SUNFMRESOURCE_STATE_DEGRADED	3
+#define	SUNFMRESOURCE_STATE_UNKNOWN	4
+#define	SUNFMRESOURCE_STATE_FAULTED	5
+
+#define	SUNFMTRAPS_OID			SUNFM_OID, 7, 0
+#define	SUNFMPROBLEMTRAP_OID		SUNFMTRAPS_OID, 1
+
+#define	SNMP_URL_MSG	"snmp-url"
+
+extern int	init_sunFM(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SUNFM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/init.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,86 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "sunFM_impl.h"
+#include "module.h"
+#include "resource.h"
+#include "problem.h"
+
+static const sunFm_table_t sun_fm_tables[] = {
+	TABLE_REG(sunFmModuleTable),
+	TABLE_REG(sunFmResourceTable),
+	TABLE_REG(sunFmProblemTable),
+	TABLE_REG(sunFmFaultEventTable),
+	TABLE_NULL
+};
+
+/*
+ * This is our entry point for initialization by the agent, which
+ * (for reasons unknown) ignores the return value.  The name is fixed
+ * by the agent API.
+ */
+int
+init_sunFM(void)
+{
+	int			max_err = MIB_REGISTERED_OK;
+	const sunFm_table_t	*table;
+
+	for (table = sun_fm_tables; table->t_name != NULL; table++) {
+		int err = table->t_init();
+
+		switch (err) {
+		case MIB_REGISTERED_OK:
+			DEBUGMSGTL((MODNAME_STR, "registered table %s\n",
+			    table->t_name));
+			break;
+		case MIB_DUPLICATE_REGISTRATION:
+			(void) snmp_log(LOG_ERR, MODNAME_STR
+			    ": table %s initialization failed: duplicate "
+			    "registration\n", table->t_name);
+			break;
+		case MIB_REGISTRATION_FAILED:
+			(void) snmp_log(LOG_ERR, MODNAME_STR
+			    ": table %s initialization failed: agent "
+			    "registration failure\n", table->t_name);
+			break;
+		default:
+			snmp_log(LOG_ERR, MODNAME_STR
+			    ": table %s initialization failed: "
+			    "unknown reason\n", table->t_name);
+		}
+
+		if (err > max_err)
+			max_err = err;
+	}
+
+	return (max_err);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/llib-lfmd_snmp	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*LINTLIBRARY*/
+/*PROTOLIB1*/
+
+#include <fm/fmd_snmp.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/module.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,688 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <fm/fmd_adm.h>
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <errno.h>
+#include <libuutil.h>
+#include "sunFM_impl.h"
+#include "module.h"
+
+static uu_avl_pool_t	*mod_name_avl_pool;
+static uu_avl_pool_t	*mod_index_avl_pool;
+static uu_avl_t		*mod_name_avl;
+static uu_avl_t		*mod_index_avl;
+
+#define	VALID_AVL_STATE	(mod_name_avl_pool != NULL &&		\
+	mod_index_avl_pool != NULL && mod_name_avl != NULL &&	\
+	mod_index_avl != NULL)
+
+#define	UPDATE_WAIT_MILLIS	10	/* poll interval in milliseconds */
+
+/*
+ * Update types.  Single-index and all are mutually exclusive.
+ */
+#define	UCT_INDEX	0x1
+#define	UCT_ALL		0x2
+#define	UCT_FLAGS	0x3
+
+#define	MODULE_DATA_VALID(d)	((d)->d_valid == valid_stamp)
+
+/*
+ * Locking rules are straightforward.  There is only one updater thread
+ * for each table, and requests for update that are received while
+ * another update is in progress are ignored.  The single per-table lock
+ * protects all the data for the table, the valid_stamp and max_index
+ * tags for new data, and - importantly - all the hidden static data
+ * used by the Net-SNMP library.  The result return callbacks are always
+ * called in the master agent thread; holding the table lock is
+ * therefore sufficient since only one table's callback can be run at
+ * any one time.  Finer-grained locking is possible here but
+ * substantially more difficult because nearly all Net-SNMP functions
+ * are unsafe.
+ *
+ * In practice this is more than adequate, since the purpose of
+ * threading out the update is to prevent excessively time-consuming
+ * data collection from bottlenecking the entire agent, not to improve
+ * result throughput (SNMP is not intended to be used for applications
+ * requiring high throughput anyway).  If the agent itself ever becomes
+ * multithreaded, locking requirements become limited to our local
+ * per-table data (the tree, max_index, and valid_stamp), and the
+ * implementation could be revisited for better performance.
+ */
+
+static ulong_t		max_index;
+static int		valid_stamp;
+static pthread_mutex_t	update_lock;
+static pthread_cond_t	update_cv;
+static volatile enum { US_QUIET, US_NEEDED, US_INPROGRESS } update_status;
+
+static Netsnmp_Node_Handler	sunFmModuleTable_handler;
+
+static sunFmModule_data_t *
+key_build(const char *name, const ulong_t index)
+{
+	static sunFmModule_data_t	key;
+
+	key.d_index = index;
+	if (name)
+		strlcpy(key.d_ami_name, name, sizeof (key.d_ami_name));
+	else
+		key.d_ami_name[0] = '\0';
+
+	return (&key);
+}
+
+/*
+ * If name is the name of a module we have previously seen and indexed, return
+ * data for it.  Otherwise, return NULL.  Note that the module may not be
+ * valid; that is, it may have been removed from the fault manager since its
+ * information was last updated.
+ */
+static sunFmModule_data_t *
+module_lookup_name(const char *name)
+{
+	sunFmModule_data_t	*key;
+
+	key = key_build(name, 0);
+	return (uu_avl_find(mod_name_avl, key, NULL, NULL));
+}
+
+/*
+ * If index corresponds to a module we have previously seen and indexed, return
+ * data for it.  Otherwise, return NULL.  Note that the module may not be
+ * valid; that is, it may have been removed from the fault manager since its
+ * information was last updated.
+ */
+static sunFmModule_data_t *
+module_lookup_index_exact(const ulong_t index)
+{
+	sunFmModule_data_t	*key;
+
+	key = key_build(NULL, index);
+	return (uu_avl_find(mod_index_avl, key, NULL, NULL));
+}
+
+/*
+ * If index corresponds to a valid (that is, extant as of latest information
+ * from the fault manager) fmd module, return the data for that module.
+ * Otherwise, return the data for the valid module whose index is as close as
+ * possible to index but not lower.  This preserves the lexicographical
+ * ordering required for GETNEXT processing.
+ */
+static sunFmModule_data_t *
+module_lookup_index_nextvalid(const ulong_t index)
+{
+	sunFmModule_data_t	*key, *data;
+	uu_avl_index_t		idx;
+
+	key = key_build(NULL, index);
+
+	if ((data = uu_avl_find(mod_index_avl, key, NULL, &idx)) != NULL &&
+	    MODULE_DATA_VALID(data))
+		return (data);
+
+	data = uu_avl_nearest_next(mod_index_avl, idx);
+
+	while (data != NULL && !MODULE_DATA_VALID(data)) {
+		(void) uu_avl_find(mod_index_avl, data, NULL, &idx);
+		data = uu_avl_nearest_next(mod_index_avl, idx);
+	}
+
+	return (data);
+}
+
+/*
+ * Possible update the contents of a single module within the cache.  This
+ * is our callback from fmd_module_iter.
+ */
+static int
+modinfo_update_one(const fmd_adm_modinfo_t *modinfo, void *arg)
+{
+	const sunFmModule_update_ctx_t *update_ctx =
+	    (sunFmModule_update_ctx_t *)arg;
+	sunFmModule_data_t *data = module_lookup_name(modinfo->ami_name);
+
+	/*
+	 * An fmd module we haven't seen before.  We're obligated to index
+	 * it and link it into our cache so that we can find it, but we're
+	 * not obligated to fill it in completely unless we're doing a
+	 * thorough update or this is the module we were asked for.  This
+	 * avoids unnecessary iteration and memory manipulation for data
+	 * we're not going to return for this request.
+	 */
+	if (data == NULL) {
+		uu_avl_index_t idx;
+
+		DEBUGMSGTL((MODNAME_STR, "found new fmd module %s\n",
+		    modinfo->ami_name));
+		if ((data = SNMP_MALLOC_TYPEDEF(sunFmModule_data_t)) == NULL) {
+			snmp_log(LOG_ERR, MODNAME_STR ": Out of memory for "
+			    "new module data at %s:%d\n", __FILE__, __LINE__);
+			return (1);
+		}
+		/*
+		 * We allocate indices sequentially and never reuse them.
+		 * This ensures we can always return valid GETNEXT responses
+		 * without having to reindex, and it provides the user a
+		 * more consistent view of the fault manager.
+		 */
+		data->d_index = ++max_index;
+		DEBUGMSGTL((MODNAME_STR, "index %lu is %s@%p\n", data->d_index,
+		    modinfo->ami_name, data));
+
+		strlcpy(data->d_ami_name, modinfo->ami_name,
+		    sizeof (data->d_ami_name));
+
+		uu_avl_node_init(data, &data->d_name_avl, mod_name_avl_pool);
+		(void) uu_avl_find(mod_name_avl, data, NULL, &idx);
+		uu_avl_insert(mod_name_avl, data, idx);
+
+		uu_avl_node_init(data, &data->d_index_avl, mod_index_avl_pool);
+		(void) uu_avl_find(mod_index_avl, data, NULL, &idx);
+		uu_avl_insert(mod_index_avl, data, idx);
+
+		DEBUGMSGTL((MODNAME_STR, "completed new module %lu/%s@%p\n",
+		    data->d_index, data->d_ami_name, data));
+	}
+
+	data->d_valid = valid_stamp;
+
+	DEBUGMSGTL((MODNAME_STR, "timestamp updated for %lu/%s@%p: %lu\n",
+	    data->d_index, data->d_ami_name, data, data->d_valid));
+
+	if ((update_ctx->uc_type & UCT_ALL) ||
+	    update_ctx->uc_index == data->d_index) {
+		strlcpy(data->d_ami_vers, modinfo->ami_vers,
+		    sizeof (data->d_ami_vers));
+		strlcpy(data->d_ami_desc, modinfo->ami_desc,
+		    sizeof (data->d_ami_desc));
+		data->d_ami_flags = modinfo->ami_flags;
+	}
+
+	return (!(update_ctx->uc_type & UCT_ALL) &&
+	    update_ctx->uc_index == data->d_index);
+}
+
+/*
+ * Update some or all module data from fmd.  If thorough is set, all modules
+ * will be indexed and their data cached.  Otherwise, updates will stop once
+ * the module matching index has been updated.
+ *
+ * Returns appropriate SNMP error codes.
+ */
+static int
+modinfo_update(sunFmModule_update_ctx_t *update_ctx)
+{
+	fmd_adm_t *adm;
+
+	ASSERT(update_ctx != NULL);
+	ASSERT((update_ctx->uc_type & (UCT_INDEX|UCT_ALL)) !=
+	    (UCT_INDEX|UCT_ALL));
+	ASSERT((update_ctx->uc_type & ~UCT_FLAGS) == 0);
+	ASSERT(VALID_AVL_STATE);
+
+	if ((adm = fmd_adm_open(update_ctx->uc_host, update_ctx->uc_prog,
+	    update_ctx->uc_version)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": Communication with fmd "
+		    "failed: %s\n", strerror(errno));
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	++valid_stamp;
+	if (fmd_adm_module_iter(adm, modinfo_update_one, update_ctx) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": fmd module information update "
+		    "failed: %s\n", fmd_adm_errmsg(adm));
+		fmd_adm_close(adm);
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	DEBUGMSGTL((MODNAME_STR, "module iteration completed\n"));
+
+	fmd_adm_close(adm);
+	return (SNMP_ERR_NOERROR);
+}
+
+/*ARGSUSED*/
+static void
+update_thread(void *arg)
+{
+	/*
+	 * The current modinfo_update implementation offers minimal savings
+	 * for the use of index-only updates; therefore we always do a full
+	 * update.  If it becomes advantageous to limit updates to a single
+	 * index, the contexts can be queued by the handler instead.
+	 */
+	sunFmModule_update_ctx_t	uc;
+
+	uc.uc_host = NULL;
+	uc.uc_prog = FMD_ADM_PROGRAM;
+	uc.uc_version = FMD_ADM_VERSION;
+
+	uc.uc_index = 0;
+	uc.uc_type = UCT_ALL;
+
+	for (;;) {
+		(void) pthread_mutex_lock(&update_lock);
+		update_status = US_QUIET;
+		while (update_status == US_QUIET)
+			(void) pthread_cond_wait(&update_cv, &update_lock);
+		update_status = US_INPROGRESS;
+		(void) pthread_mutex_unlock(&update_lock);
+		(void) modinfo_update(&uc);
+	}
+}
+
+static void
+request_update(void)
+{
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+	update_status = US_NEEDED;
+	(void) pthread_cond_signal(&update_cv);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+/*ARGSUSED*/
+static int
+module_compare_name(const void *l, const void *r, void *private)
+{
+	sunFmModule_data_t	*l_data = (sunFmModule_data_t *)l;
+	sunFmModule_data_t	*r_data = (sunFmModule_data_t *)r;
+
+	ASSERT(l_data != NULL && r_data != NULL);
+
+	return (strcmp(l_data->d_ami_name, r_data->d_ami_name));
+}
+
+/*ARGSUSED*/
+static int
+module_compare_index(const void *l, const void *r, void *private)
+{
+	sunFmModule_data_t	*l_data = (sunFmModule_data_t *)l;
+	sunFmModule_data_t	*r_data = (sunFmModule_data_t *)r;
+
+	ASSERT(l_data != NULL && r_data != NULL);
+
+	return (l_data->d_index < r_data->d_index ? -1 :
+	    l_data->d_index > r_data->d_index ? 1 : 0);
+}
+
+int
+sunFmModuleTable_init(void)
+{
+	static oid sunFmModuleTable_oid[] = { SUNFMMODULETABLE_OID };
+	netsnmp_table_registration_info *table_info;
+	netsnmp_handler_registration *handler;
+	int err;
+
+	if ((err = pthread_mutex_init(&update_lock, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": mutex_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+	if ((err = pthread_cond_init(&update_cv, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": cond_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread,
+	    NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": error creating update "
+		    "thread: %s\n", strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((table_info =
+	    SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info)) == NULL)
+		return (MIB_REGISTRATION_FAILED);
+
+	if ((handler = netsnmp_create_handler_registration("sunFmModuleTable",
+	    sunFmModuleTable_handler, sunFmModuleTable_oid,
+	    OID_LENGTH(sunFmModuleTable_oid), HANDLER_CAN_RONLY)) == NULL) {
+		SNMP_FREE(table_info);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	/*
+	 * The Net-SNMP template uses add_indexes here, but that
+	 * function is unsafe because it does not check for failure.
+	 */
+	if (netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED) == NULL) {
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	table_info->min_column = SUNFMMODULE_COLMIN;
+	table_info->max_column = SUNFMMODULE_COLMAX;
+
+	if ((mod_name_avl_pool = uu_avl_pool_create("mod_name",
+	    sizeof (sunFmModule_data_t),
+	    offsetof(sunFmModule_data_t, d_name_avl), module_compare_name,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+	}
+
+	if ((mod_name_avl = uu_avl_create(mod_name_avl_pool, NULL,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": mod_name_avl creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_pool_destroy(mod_name_avl_pool);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((mod_index_avl_pool = uu_avl_pool_create("mod_index",
+	    sizeof (sunFmModule_data_t),
+	    offsetof(sunFmModule_data_t, d_index_avl),
+	    module_compare_index, UU_AVL_DEBUG)) == NULL) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(mod_name_avl);
+		uu_avl_pool_destroy(mod_name_avl_pool);
+	}
+
+	if ((mod_index_avl = uu_avl_create(mod_index_avl_pool, NULL,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": mod_index_avl creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(mod_name_avl);
+		uu_avl_pool_destroy(mod_name_avl_pool);
+		uu_avl_pool_destroy(mod_index_avl_pool);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = netsnmp_register_table(handler, table_info)) !=
+	    MIB_REGISTERED_OK) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(mod_name_avl);
+		uu_avl_pool_destroy(mod_name_avl_pool);
+		uu_avl_destroy(mod_index_avl);
+		uu_avl_pool_destroy(mod_index_avl_pool);
+		return (err);
+	}
+
+	return (MIB_REGISTERED_OK);
+}
+
+/*
+ * These two functions form the core of GET/GETNEXT/GETBULK handling (the
+ * only kind we do).  They perform two functions:
+ *
+ * - First, frob the request to set all the index variables to correspond
+ *   to the value that's going to be returned.  For GET, this is a nop;
+ *   for GETNEXT/GETBULK it always requires some work.
+ * - Second, find and return the fmd module information corresponding to
+ *   the (possibly updated) indices.
+ *
+ * These should be as fast as possible; they run in the agent thread.
+ */
+static sunFmModule_data_t *
+sunFmModuleTable_nextmod(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmModule_data_t	*data;
+	netsnmp_variable_list	*var;
+	ulong_t index;
+
+	/*
+	 * If we have no index, we must make one.
+	 */
+	if (table_info->number_indexes < 1) {
+		oid tmpoid[MAX_OID_LEN];
+		index = 1;
+
+		DEBUGMSGTL((MODNAME_STR, "nextmod: no indexes given\n"));
+		var = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
+		snmp_set_var_typed_value(var, ASN_UNSIGNED, (uchar_t *)&index,
+		    sizeof (index));
+		memcpy(tmpoid, reginfo->rootoid,
+		    reginfo->rootoid_len * sizeof (oid));
+		tmpoid[reginfo->rootoid_len] = 1;	/* Entry is .1 */
+		tmpoid[reginfo->rootoid_len + 1] = table_info->colnum;
+		if (build_oid(&var->name, &var->name_length, tmpoid,
+		    reginfo->rootoid_len + 2, var) != SNMPERR_SUCCESS)
+			return (NULL);
+		DEBUGMSGTL((MODNAME_STR, "nextmod: built fake index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, var));
+		DEBUGMSG((MODNAME_STR, "\n"));
+	} else {
+		var = table_info->indexes;
+		index = *var->val.integer;
+		DEBUGMSGTL((MODNAME_STR, "nextmod: received index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, var));
+		DEBUGMSG((MODNAME_STR, "\n"));
+		index++;
+	}
+
+	if ((data = module_lookup_index_nextvalid(index)) == NULL) {
+		DEBUGMSGTL((MODNAME_STR, "nextmod: exact match not found for "
+		    "index %lu; trying next column\n", index));
+		if (table_info->colnum >= SUNFMMODULE_COLMAX) {
+			snmp_free_varbind(var);
+			table_info->indexes = NULL;
+			table_info->number_indexes = 0;
+			DEBUGMSGTL((MODNAME_STR, "nextmod: out of columns\n"));
+			return (NULL);
+		}
+		table_info->colnum++;
+		index = 1;
+
+		data = module_lookup_index_nextvalid(index);
+	}
+
+	if (data == NULL) {
+		DEBUGMSGTL((MODNAME_STR, "nextmod: exact match not found for "
+		    "index %lu; stopping\n", index));
+		snmp_free_varbind(var);
+		table_info->indexes = NULL;
+		table_info->number_indexes = 0;
+		return (NULL);
+	}
+
+	*var->val.integer = index;
+	table_info->indexes = var;
+
+	DEBUGMSGTL((MODNAME_STR, "matching data is %lu/%s@%p\n", data->d_index,
+	    data->d_ami_name, data));
+
+	return (data);
+}
+
+/*ARGSUSED*/
+static sunFmModule_data_t *
+sunFmModuleTable_mod(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmModule_data_t	*data;
+	netsnmp_variable_list	*var;
+
+	ASSERT(table_info->number_indexes == 1);
+
+	return (module_lookup_index_exact(table_info->index_oid[0]));
+}
+
+static void
+sunFmModuleTable_return(unsigned int reg, void *arg)
+{
+	netsnmp_delegated_cache		*cache = (netsnmp_delegated_cache *)arg;
+	netsnmp_request_info		*request;
+	netsnmp_agent_request_info	*reqinfo;
+	netsnmp_handler_registration	*reginfo;
+	netsnmp_mib_handler		*handler;
+	netsnmp_table_request_info	*table_info;
+	netsnmp_variable_list		*var;
+	sunFmModule_data_t		*data;
+	ulong_t				modstate;
+
+	ASSERT(netsnmp_handler_check_cache(cache) != NULL);
+
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		struct timeval			tv;
+
+		tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+		tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+		(void) snmp_alarm_register_hr(tv, 0, sunFmModuleTable_return,
+		    cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	request = cache->requests;
+	reqinfo = cache->reqinfo;
+	reginfo = cache->reginfo;
+	handler = cache->handler;
+
+	var = request->requestvb;
+	table_info = netsnmp_extract_table_info(request);
+	request->delegated = 0;
+
+	ASSERT(table_info->colnum >= SUNFMMODULE_COLMIN);
+	ASSERT(table_info->colnum <= SUNFMMODULE_COLMAX);
+
+	/*
+	 * table_info->colnum contains the column number requested.
+	 * table_info->indexes contains a linked list of snmp variable
+	 * bindings for the indexes of the table.  Values in the list
+	 * have been set corresponding to the indexes of the
+	 * request.  We have other guarantees as well:
+	 *
+	 * - The column number is always within range.
+	 * - If we have no index data, table_info->index_oid_len is 0.
+	 * - We will never receive requests outside our table nor
+	 *   those with the first subid anything other than 1 (Entry)
+	 *   nor those without a column number.  This is true even
+	 *   for GETNEXT requests.
+	 */
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		if ((data = sunFmModuleTable_mod(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	case MODE_GETNEXT:
+	case MODE_GETBULK:
+		if ((data = sunFmModuleTable_nextmod(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	default:
+		snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request "
+		    "mode %d\n", reqinfo->mode);
+		netsnmp_free_delegated_cache(cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	switch (table_info->colnum) {
+	case SUNFMMODULE_COL_NAME:
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_ami_name,
+		    strlen(data->d_ami_name));
+		break;
+	case SUNFMMODULE_COL_VERSION:
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_ami_vers,
+		    strlen(data->d_ami_vers));
+		break;
+	case SUNFMMODULE_COL_STATUS:
+		modstate = (data->d_ami_flags & FMD_ADM_MOD_FAILED) ?
+		    SUNFMMODULE_STATE_FAILED : SUNFMMODULE_STATE_ACTIVE;
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_INTEGER, (uchar_t *)&modstate,
+		    sizeof (modstate));
+		break;
+	case SUNFMMODULE_COL_DESCRIPTION:
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_ami_desc,
+		    strlen(data->d_ami_desc));
+		break;
+	default:
+		break;
+	}
+	netsnmp_free_delegated_cache(cache);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+static int
+sunFmModuleTable_handler(netsnmp_mib_handler *handler,
+    netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo,
+    netsnmp_request_info *requests)
+{
+	netsnmp_request_info		*request;
+	struct timeval			tv;
+
+	tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+	tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+	request_update();
+
+	for (request = requests; request; request = request->next) {
+		if (request->processed != 0)
+			continue;
+
+		if (netsnmp_extract_table_info(request) == NULL)
+			continue;
+
+		request->delegated = 1;
+		(void) snmp_alarm_register_hr(tv, 0, sunFmModuleTable_return,
+		    (void *) netsnmp_create_delegated_cache(handler, reginfo,
+		    reqinfo, request, NULL));
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/module.h	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_MODULE_H
+#define	_MODULE_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <libuutil.h>
+
+typedef struct sunFmModule_data {
+	ulong_t		d_index;		/* MIB index */
+	int		d_valid;		/* iteration stamp */
+	uu_avl_node_t	d_name_avl;		/* by-name AVL node */
+	uu_avl_node_t	d_index_avl;		/* by-index AVL node */
+	char		d_ami_name[256];	/* fmd module name */
+	char		d_ami_vers[256];	/* fmd module version */
+	char		d_ami_desc[256];	/* fmd module description */
+	uint_t		d_ami_flags;		/* fmd module flags */
+} sunFmModule_data_t;
+
+typedef struct sunFmModule_update_ctx {
+	const char	*uc_host;
+	uint32_t	uc_prog;
+	int		uc_version;
+	ulong_t		uc_index;
+	int		uc_type;
+} sunFmModule_update_ctx_t;
+
+int sunFmModuleTable_init(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _MODULE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/problem.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,1015 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/fm/protocol.h>
+#include <fm/fmd_adm.h>
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <errno.h>
+#include <alloca.h>
+#include <locale.h>
+#include <libuutil.h>
+#include <libnvpair.h>
+#include "sunFM_impl.h"
+#include "problem.h"
+
+/*
+ * We assume that the number of suspect fault events associated with a
+ * particular case will generally be sufficiently small that the overhead
+ * associated with indexing them in a tree would exceed the gain from
+ * not traversing the fault list for each request.
+ */
+static uu_avl_pool_t	*problem_uuid_avl_pool;
+static uu_avl_t		*problem_uuid_avl;
+
+#define	VALID_AVL_STATE	(problem_uuid_avl_pool != NULL &&	\
+	problem_uuid_avl != NULL)
+
+#define	UPDATE_WAIT_MILLIS	10	/* poll interval in milliseconds */
+
+/*
+ * Update types.  Single-index and all are mutually exclusive.
+ */
+#define	UCT_INDEX	0x1
+#define	UCT_ALL		0x2
+#define	UCT_FLAGS	0x3
+
+#define	MODULE_DATA_VALID(d)	((d)->d_valid == valid_stamp)
+
+/*
+ * Locking strategy is described in module.c.
+ */
+static int		valid_stamp;
+static pthread_mutex_t	update_lock;
+static pthread_cond_t	update_cv;
+static volatile enum { US_QUIET, US_NEEDED, US_INPROGRESS } update_status;
+
+static const char SNMP_URL[] = SNMP_URL_MSG;
+#define	URL_BASE	"http://sun.com/msg/"
+
+static Netsnmp_Node_Handler	sunFmProblemTable_handler;
+static Netsnmp_Node_Handler	sunFmFaultEventTable_handler;
+
+static sunFmProblem_data_t *
+problem_key_build(const char *uuid)
+{
+	static sunFmProblem_data_t	key;
+
+	key.d_aci_uuid = uuid;
+
+	return (&key);
+}
+
+static sunFmProblem_data_t *
+problem_lookup_uuid_exact(const char *uuid)
+{
+	sunFmProblem_data_t	*key, *data;
+
+	key = problem_key_build(uuid);
+
+	DEBUGMSGTL((MODNAME_STR, "lookup_exact for uuid %s\n", uuid));
+	data = uu_avl_find(problem_uuid_avl, key, NULL, NULL);
+
+	return (data);
+}
+
+static sunFmProblem_data_t *
+problem_lookup_uuid_next(const char *uuid)
+{
+	sunFmProblem_data_t	*key, *data;
+	uu_avl_index_t		idx;
+
+	key = problem_key_build(uuid);
+
+	DEBUGMSGTL((MODNAME_STR, "lookup_next for uuid %s\n", uuid));
+	(void) uu_avl_find(problem_uuid_avl, key, NULL, &idx);
+
+	data = uu_avl_nearest_next(problem_uuid_avl, idx);
+
+	DEBUGMSGTL((MODNAME_STR, "lookup_next: entry is %p\n", data));
+
+	return (data);
+}
+
+static sunFmFaultEvent_data_t *
+faultevent_lookup_index_exact(sunFmProblem_data_t *data, ulong_t index)
+{
+	if (index > data->d_nsuspects)
+		return (NULL);
+
+	if (data->d_suspects == NULL)
+		return (NULL);
+
+	return (data->d_suspects[index - 1]);
+}
+
+static int
+problem_update_one(const fmd_adm_caseinfo_t *acp, void *arg)
+{
+	const sunFmProblem_update_ctx_t	*update_ctx =
+	    (sunFmProblem_update_ctx_t *)arg;
+	sunFmProblem_data_t		*data;
+	nvlist_t			*nvl;
+	int64_t				*diag_time;
+	uint_t				nelem;
+	uint32_t			nsusp;
+	int				err;
+
+	DEBUGMSGTL((MODNAME_STR, "update_one\n"));
+
+	ASSERT(acp->aci_uuid != NULL);
+
+	if ((data = problem_lookup_uuid_exact(acp->aci_uuid)) == NULL) {
+		uu_avl_index_t idx;
+
+		DEBUGMSGTL((MODNAME_STR, "found new problem %s\n",
+		    acp->aci_uuid));
+		if ((data = SNMP_MALLOC_TYPEDEF(sunFmProblem_data_t)) == NULL) {
+			snmp_log(LOG_ERR, MODNAME_STR ": Out of memory for "
+			    "new problem data at %s:%d\n", __FILE__, __LINE__);
+			return (0);
+		}
+		if ((err = nvlist_dup(acp->aci_event, &data->d_aci_event, 0))
+		    != 0) {
+			snmp_log(LOG_ERR, MODNAME_STR ": Problem data setup "
+			    "failed: %s\n", strerror(err));
+			SNMP_FREE(data);
+			return (0);
+		}
+
+		data->d_aci_uuid = data->d_aci_code = data->d_aci_url = "-";
+		(void) nvlist_lookup_string(data->d_aci_event, FM_SUSPECT_UUID,
+		    (char **)&data->d_aci_uuid);
+		(void) nvlist_lookup_string(data->d_aci_event,
+		    FM_SUSPECT_DIAG_CODE, (char **)&data->d_aci_code);
+		data->d_aci_url = strdup(acp->aci_url);
+
+		if (nvlist_lookup_nvlist(data->d_aci_event, FM_SUSPECT_DE,
+		    &nvl) == 0)
+			if ((data->d_diag_engine = sunFm_nvl2str(nvl)) == NULL)
+				data->d_diag_engine = "-";
+
+		if (nvlist_lookup_int64_array(data->d_aci_event,
+		    FM_SUSPECT_DIAG_TIME, &diag_time, &nelem) == 0 &&
+		    nelem >= 2) {
+			data->d_diag_time.tv_sec = (long)diag_time[0];
+			data->d_diag_time.tv_usec = (long)diag_time[1];
+		}
+
+		(void) nvlist_lookup_uint32(data->d_aci_event,
+		    FM_SUSPECT_FAULT_SZ, &nsusp);
+		data->d_nsuspects = (ulong_t)nsusp;
+
+		(void) nvlist_lookup_nvlist_array(data->d_aci_event,
+		    FM_SUSPECT_FAULT_LIST, &data->d_suspects, &nelem);
+
+		ASSERT(nelem == data->d_nsuspects);
+
+		uu_avl_node_init(data, &data->d_uuid_avl,
+		    problem_uuid_avl_pool);
+		(void) uu_avl_find(problem_uuid_avl, data, NULL, &idx);
+		uu_avl_insert(problem_uuid_avl, data, idx);
+
+		data->d_valid = valid_stamp;
+
+		DEBUGMSGTL((MODNAME_STR, "completed new problem %s@%p\n",
+		    data->d_aci_uuid, data));
+	}
+
+	/*
+	 * We don't touch problems we've seen before; they shouldn't change
+	 * in any way we care about, since they've already been solved.  The
+	 * state, however, could change, and if we later expose that to the
+	 * client we need to update it here.
+	 */
+
+	return (0);
+}
+
+static int
+problem_update(sunFmProblem_update_ctx_t *update_ctx)
+{
+	fmd_adm_t *adm;
+
+	ASSERT(update_ctx != NULL);
+	ASSERT((update_ctx->uc_type & (UCT_INDEX|UCT_ALL)) !=
+	    (UCT_INDEX|UCT_ALL));
+	ASSERT((update_ctx->uc_type & ~UCT_FLAGS) == 0);
+	ASSERT(VALID_AVL_STATE);
+
+	if ((adm = fmd_adm_open(update_ctx->uc_host, update_ctx->uc_prog,
+	    update_ctx->uc_version)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": Communication with fmd "
+		    "failed: %s\n", strerror(errno));
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	++valid_stamp;
+	if (fmd_adm_case_iter(adm, SNMP_URL_MSG, problem_update_one,
+	    update_ctx) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": fmd case information update "
+		    "failed: %s\n", fmd_adm_errmsg(adm));
+		fmd_adm_close(adm);
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	DEBUGMSGTL((MODNAME_STR, "case iteration completed\n"));
+
+	fmd_adm_close(adm);
+	return (SNMP_ERR_NOERROR);
+}
+
+/*ARGSUSED*/
+static void
+update_thread(void *arg)
+{
+	/*
+	 * The current problem_update implementation offers minimal savings
+	 * for the use of index-only updates; therefore we always do a full
+	 * update.  If it becomes advantageous to limit updates to a single
+	 * index, the contexts can be queued by the handler instead.
+	 */
+	sunFmProblem_update_ctx_t	uc;
+
+	uc.uc_host = NULL;
+	uc.uc_prog = FMD_ADM_PROGRAM;
+	uc.uc_version = FMD_ADM_VERSION;
+
+	uc.uc_index = NULL;
+	uc.uc_type = UCT_ALL;
+
+	for (;;) {
+		(void) pthread_mutex_lock(&update_lock);
+		update_status = US_QUIET;
+		while (update_status == US_QUIET)
+			(void) pthread_cond_wait(&update_cv, &update_lock);
+		update_status = US_INPROGRESS;
+		(void) pthread_mutex_unlock(&update_lock);
+		(void) problem_update(&uc);
+	}
+}
+
+static void
+request_update(void)
+{
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+	update_status = US_NEEDED;
+	(void) pthread_cond_signal(&update_cv);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+/*ARGSUSED*/
+static int
+problem_compare_uuid(const void *l, const void *r, void *private)
+{
+	sunFmProblem_data_t	*l_data = (sunFmProblem_data_t *)l;
+	sunFmProblem_data_t	*r_data = (sunFmProblem_data_t *)r;
+
+	ASSERT(l_data != NULL && r_data != NULL);
+
+	return (strcmp(l_data->d_aci_uuid, r_data->d_aci_uuid));
+}
+
+int
+sunFmProblemTable_init(void)
+{
+	static oid sunFmProblemTable_oid[] = { SUNFMPROBLEMTABLE_OID };
+	netsnmp_table_registration_info *table_info;
+	netsnmp_handler_registration *handler;
+	int err;
+
+	if ((err = pthread_mutex_init(&update_lock, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": mutex_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+	if ((err = pthread_cond_init(&update_cv, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": cond_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread,
+	    NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": error creating update "
+		    "thread: %s\n", strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((table_info =
+	    SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info)) == NULL)
+		return (MIB_REGISTRATION_FAILED);
+
+	if ((handler = netsnmp_create_handler_registration("sunFmProblemTable",
+	    sunFmProblemTable_handler, sunFmProblemTable_oid,
+	    OID_LENGTH(sunFmProblemTable_oid), HANDLER_CAN_RONLY)) == NULL) {
+		SNMP_FREE(table_info);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	/*
+	 * The Net-SNMP template uses add_indexes here, but that
+	 * function is unsafe because it does not check for failure.
+	 */
+	if (netsnmp_table_helper_add_index(table_info, ASN_OCTET_STR) == NULL) {
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	table_info->min_column = SUNFMPROBLEM_COLMIN;
+	table_info->max_column = SUNFMPROBLEM_COLMAX;
+
+	if ((problem_uuid_avl_pool = uu_avl_pool_create("problem_uuid",
+	    sizeof (sunFmProblem_data_t),
+	    offsetof(sunFmProblem_data_t, d_uuid_avl), problem_compare_uuid,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": problem_uuid avl pool "
+		    "creation failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((problem_uuid_avl = uu_avl_create(problem_uuid_avl_pool, NULL,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": problem_uuid avl creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_pool_destroy(problem_uuid_avl_pool);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = netsnmp_register_table(handler, table_info)) !=
+	    MIB_REGISTERED_OK) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(problem_uuid_avl);
+		uu_avl_pool_destroy(problem_uuid_avl_pool);
+		return (err);
+	}
+
+	return (MIB_REGISTERED_OK);
+}
+
+int
+sunFmFaultEventTable_init(void)
+{
+	static oid sunFmFaultEventTable_oid[] = { SUNFMFAULTEVENTTABLE_OID };
+	netsnmp_table_registration_info *table_info;
+	netsnmp_handler_registration *handler;
+	int err;
+
+	if ((table_info =
+	    SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info)) == NULL)
+		return (MIB_REGISTRATION_FAILED);
+
+	if ((handler =
+	    netsnmp_create_handler_registration("sunFmFaultEventTable",
+	    sunFmFaultEventTable_handler, sunFmFaultEventTable_oid,
+	    OID_LENGTH(sunFmFaultEventTable_oid), HANDLER_CAN_RONLY)) == NULL) {
+		SNMP_FREE(table_info);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	/*
+	 * The Net-SNMP template uses add_indexes here, but that
+	 * function is unsafe because it does not check for failure.
+	 */
+	if (netsnmp_table_helper_add_index(table_info, ASN_OCTET_STR) == NULL) {
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+	if (netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED) == NULL) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	table_info->min_column = SUNFMFAULTEVENT_COLMIN;
+	table_info->max_column = SUNFMFAULTEVENT_COLMAX;
+
+	if ((err = netsnmp_register_table(handler, table_info)) !=
+	    MIB_REGISTERED_OK) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (err);
+	}
+
+	return (MIB_REGISTERED_OK);
+}
+
+/*
+ * Returns the problem data for the problem whose uuid is next according
+ * to ASN.1 lexical ordering after the request in table_info.  Indexes are
+ * updated to reflect the OID of the value being returned.  This allows
+ * us to implement GETNEXT.
+ */
+static sunFmProblem_data_t *
+sunFmProblemTable_nextpr(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmProblem_data_t	*data;
+	netsnmp_variable_list	*var;
+	char			*uuid = "";
+
+	if (table_info->number_indexes < 1) {
+		oid tmpoid[MAX_OID_LEN];
+
+		DEBUGMSGTL((MODNAME_STR, "nextpr: no indexes given\n"));
+
+		table_info->indexes =
+		    SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
+		snmp_set_var_typed_value(table_info->indexes, ASN_OCTET_STR,
+		    (const uchar_t *)uuid, 0);
+		memcpy(tmpoid, reginfo->rootoid,
+		    reginfo->rootoid_len * sizeof (oid));
+		tmpoid[reginfo->rootoid_len] = 1;
+		tmpoid[reginfo->rootoid_len + 1] = table_info->colnum;
+		if (build_oid_segment(table_info->indexes) != SNMPERR_SUCCESS) {
+			snmp_free_varbind(table_info->indexes);
+			return (NULL);
+		}
+		table_info->number_indexes = 1;
+		table_info->index_oid_len = table_info->indexes->name_length;
+		memcpy(table_info->index_oid, table_info->indexes->name,
+		    table_info->indexes->name_length);
+
+		DEBUGMSGTL((MODNAME_STR, "nextpr: built fake index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, table_info->indexes));
+		DEBUGMSG((MODNAME_STR, "\n"));
+	} else {
+		/*
+		 * Construct the next possible UUID to look for.  We can
+		 * simply increment the least significant byte of the last
+		 * UUID because (a) that preserves SNMP lex order and (b)
+		 * the characters that may appear in a UUID do not include
+		 * 127 nor 255.
+		 */
+		uuid = alloca(table_info->indexes->val_len + 1);
+		(void) strlcpy(uuid,
+		    (const char *)table_info->indexes->val.string,
+		    table_info->indexes->val_len + 1);
+		++uuid[table_info->indexes->val_len - 1];
+
+		DEBUGMSGTL((MODNAME_STR, "nextpr: received index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, table_info->indexes));
+		DEBUGMSG((MODNAME_STR, "\n"));
+	}
+
+	if ((data = problem_lookup_uuid_next(uuid)) == NULL) {
+		DEBUGMSGTL((MODNAME_STR, "nextpr: next match not found for "
+		    "%s; trying next column\n", uuid));
+		if (table_info->colnum >= SUNFMPROBLEM_COLMAX) {
+			snmp_free_varbind(table_info->indexes);
+			table_info->indexes = NULL;
+			table_info->number_indexes = 0;
+			DEBUGMSGTL((MODNAME_STR, "nextpr: out of columns\n"));
+			return (NULL);
+		}
+		table_info->colnum++;
+		DEBUGMSGTL((MODNAME_STR, "nextpr: search for col %u empty "
+		    "uuid\n", table_info->colnum, uuid));
+
+		if ((data = problem_lookup_uuid_next("")) == NULL) {
+			DEBUGMSGTL((MODNAME_STR, "nextpr: next match not found "
+			    "for empty uuid; stopping\n"));
+			snmp_free_varbind(table_info->indexes);
+			table_info->indexes = NULL;
+			table_info->number_indexes = 0;
+			return (NULL);
+		}
+	}
+
+	snmp_set_var_typed_value(table_info->indexes, ASN_OCTET_STR,
+	    (uchar_t *)data->d_aci_uuid, strlen(data->d_aci_uuid));
+	table_info->number_indexes = 1;
+
+	DEBUGMSGTL((MODNAME_STR, "matching data is %s@%p\n", data->d_aci_uuid,
+	    data));
+
+	return (data);
+}
+
+/*
+ * Returns the problem data corresponding to the request in table_info.
+ * All request parameters are unmodified.
+ */
+static sunFmProblem_data_t *
+sunFmProblemTable_pr(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmProblem_data_t	*data;
+	char			*uuid;
+
+	ASSERT(table_info->number_indexes >= 1);
+
+	uuid = alloca(table_info->indexes->val_len + 1);
+	(void) strlcpy(uuid, (const char *)table_info->indexes->val.string,
+	    table_info->indexes->val_len + 1);
+
+	return (problem_lookup_uuid_exact(uuid));
+}
+
+/*
+ * Returns the ASN.1 lexicographically first fault event after the one
+ * identified by table_info.  Indexes are updated to reflect the OID
+ * of the data returned.  This allows us to implement GETNEXT.
+ */
+static sunFmFaultEvent_data_t *
+sunFmFaultEventTable_nextfe(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmProblem_data_t	*data;
+	sunFmFaultEvent_data_t	*rv;
+	netsnmp_variable_list	*var;
+	char			*uuid;
+	ulong_t			index;
+
+	for (;;) {
+		switch (table_info->number_indexes) {
+		case 2:
+		default:
+			DEBUGMSGTL((MODNAME_STR, "nextfe: 2 indices:\n"));
+			DEBUGMSGVAR((MODNAME_STR, table_info->indexes));
+			DEBUGMSG((MODNAME_STR, "\n"));
+			DEBUGMSGVAR((MODNAME_STR,
+			    table_info->indexes->next_variable));
+			DEBUGMSG((MODNAME_STR, "\n"));
+			index = *(ulong_t *)
+			    table_info->indexes->next_variable->val.integer + 1;
+
+			if ((data = sunFmProblemTable_pr(reginfo,
+			    table_info)) != NULL &&
+			    (rv = faultevent_lookup_index_exact(data, index)) !=
+			    NULL) {
+				snmp_set_var_typed_value(
+				    table_info->indexes->next_variable,
+				    ASN_UNSIGNED, (uchar_t *)&index,
+				    sizeof (index));
+				return (rv);
+			}
+
+			if (sunFmProblemTable_nextpr(reginfo, table_info) ==
+			    NULL)
+				return (NULL);
+			break;
+		case 1:
+			if ((data = sunFmProblemTable_pr(reginfo,
+			    table_info)) != NULL) {
+				oid tmpoid[MAX_OID_LEN];
+				index = 0;
+
+				DEBUGMSGTL((MODNAME_STR, "nextfe: 1 index:\n"));
+				DEBUGMSGVAR((MODNAME_STR, table_info->indexes));
+				DEBUGMSG((MODNAME_STR, "\n"));
+				var =
+				    SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
+				snmp_set_var_typed_value(var, ASN_UNSIGNED,
+				    (uchar_t *)&index, sizeof (index));
+				memcpy(tmpoid, reginfo->rootoid,
+				    reginfo->rootoid_len * sizeof (oid));
+				tmpoid[reginfo->rootoid_len] = 1;
+				tmpoid[reginfo->rootoid_len + 1] =
+				    table_info->colnum;
+				if (build_oid_segment(var) != SNMPERR_SUCCESS) {
+					snmp_free_varbind(var);
+					return (NULL);
+				}
+				table_info->indexes->next_variable = var;
+				table_info->number_indexes = 2;
+				DEBUGMSGTL((MODNAME_STR, "nextfe: built fake "
+				    "index:\n"));
+				DEBUGMSGVAR((MODNAME_STR, table_info->indexes));
+				DEBUGMSG((MODNAME_STR, "\n"));
+				DEBUGMSGVAR((MODNAME_STR,
+				    table_info->indexes->next_variable));
+				DEBUGMSG((MODNAME_STR, "\n"));
+			} else {
+				if (sunFmProblemTable_nextpr(reginfo,
+				    table_info) == NULL)
+					return (NULL);
+			}
+			break;
+		case 0:
+			if (sunFmProblemTable_nextpr(reginfo, table_info) ==
+			    NULL)
+				return (NULL);
+			break;
+		}
+	}
+}
+
+static sunFmFaultEvent_data_t *
+sunFmFaultEventTable_fe(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmProblem_data_t	*data;
+
+	ASSERT(table_info->number_indexes == 2);
+
+	if ((data = sunFmProblemTable_pr(reginfo, table_info)) == NULL)
+		return (NULL);
+
+	return (faultevent_lookup_index_exact(data,
+	    *(ulong_t *)table_info->indexes->next_variable->val.integer));
+}
+
+static void
+sunFmProblemTable_return(unsigned int reg, void *arg)
+{
+	netsnmp_delegated_cache		*cache = (netsnmp_delegated_cache *)arg;
+	netsnmp_request_info		*request;
+	netsnmp_agent_request_info	*reqinfo;
+	netsnmp_handler_registration	*reginfo;
+	netsnmp_mib_handler		*handler;
+	netsnmp_table_request_info	*table_info;
+	netsnmp_variable_list		*var;
+	sunFmProblem_data_t		*data;
+
+	ASSERT(netsnmp_handler_check_cache(cache) != NULL);
+
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		struct timeval			tv;
+
+		tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+		tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+		(void) snmp_alarm_register_hr(tv, 0, sunFmProblemTable_return,
+		    cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	request = cache->requests;
+	reqinfo = cache->reqinfo;
+	reginfo = cache->reginfo;
+	handler = cache->handler;
+
+	var = request->requestvb;
+	table_info = netsnmp_extract_table_info(request);
+	request->delegated = 0;
+
+	ASSERT(table_info->colnum >= SUNFMPROBLEM_COLMIN);
+	ASSERT(table_info->colnum <= SUNFMPROBLEM_COLMAX);
+
+	/*
+	 * table_info->colnum contains the column number requested.
+	 * table_info->indexes contains a linked list of snmp variable
+	 * bindings for the indexes of the table.  Values in the list
+	 * have been set corresponding to the indexes of the
+	 * request.  We have other guarantees as well:
+	 *
+	 * - The column number is always within range.
+	 * - If we have no index data, table_info->index_oid_len is 0.
+	 * - We will never receive requests outside our table nor
+	 *   those with the first subid anything other than 1 (Entry)
+	 *   nor those without a column number.  This is true even
+	 *   for GETNEXT requests.
+	 */
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		if ((data = sunFmProblemTable_pr(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	case MODE_GETNEXT:
+	case MODE_GETBULK:
+		if ((data = sunFmProblemTable_nextpr(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	default:
+		snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request mode %d\n",
+		    reqinfo->mode);
+		netsnmp_free_delegated_cache(cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	switch (table_info->colnum) {
+	case SUNFMPROBLEM_COL_UUID:
+	{
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_aci_uuid,
+		    strlen(data->d_aci_uuid));
+		break;
+	}
+	case SUNFMPROBLEM_COL_CODE:
+	{
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_aci_code,
+		    strlen(data->d_aci_code));
+		break;
+	}
+	case SUNFMPROBLEM_COL_URL:
+	{
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_aci_url,
+		    strlen(data->d_aci_url));
+		break;
+	}
+	case SUNFMPROBLEM_COL_DIAGENGINE:
+	{
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_diag_engine,
+		    strlen(data->d_diag_engine));
+		break;
+	}
+	case SUNFMPROBLEM_COL_DIAGTIME:
+	{
+		/*
+		 * The date_n_time function is not Y2038-safe; this may
+		 * need to be updated when a suitable Y2038-safe Net-SNMP
+		 * API is available.
+		 */
+		size_t	dt_size;
+		time_t	dt_time = (time_t)data->d_diag_time.tv_sec;
+		uchar_t	*dt = date_n_time(&dt_time, &dt_size);
+
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, dt, dt_size);
+		break;
+	}
+	case SUNFMPROBLEM_COL_SUSPECTCOUNT:
+	{
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_UNSIGNED, (uchar_t *)&data->d_nsuspects,
+		    sizeof (data->d_nsuspects));
+		break;
+	}
+	default:
+		break;
+	}
+
+	netsnmp_free_delegated_cache(cache);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+static int
+sunFmProblemTable_handler(netsnmp_mib_handler *handler,
+    netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo,
+    netsnmp_request_info *requests)
+{
+	netsnmp_request_info		*request;
+	struct timeval			tv;
+
+	tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+	tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+	request_update();
+
+	for (request = requests; request; request = request->next) {
+		if (request->processed != 0)
+			continue;
+
+		if (netsnmp_extract_table_info(request) == NULL)
+			continue;
+
+		request->delegated = 1;
+		(void) snmp_alarm_register_hr(tv, 0,
+		    sunFmProblemTable_return,
+		    (void *) netsnmp_create_delegated_cache(handler, reginfo,
+		    reqinfo, request, NULL));
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
+
+static void
+sunFmFaultEventTable_return(unsigned int reg, void *arg)
+{
+	netsnmp_delegated_cache		*cache = (netsnmp_delegated_cache *)arg;
+	netsnmp_request_info		*request;
+	netsnmp_agent_request_info	*reqinfo;
+	netsnmp_handler_registration	*reginfo;
+	netsnmp_mib_handler		*handler;
+	netsnmp_table_request_info	*table_info;
+	netsnmp_variable_list		*var;
+	sunFmProblem_data_t		*pdata;
+	sunFmFaultEvent_data_t		*data;
+
+	ASSERT(netsnmp_handler_check_cache(cache) != NULL);
+
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		struct timeval			tv;
+
+		tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+		tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+		(void) snmp_alarm_register_hr(tv, 0,
+		    sunFmFaultEventTable_return, cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	request = cache->requests;
+	reqinfo = cache->reqinfo;
+	reginfo = cache->reginfo;
+	handler = cache->handler;
+
+	var = request->requestvb;
+	table_info = netsnmp_extract_table_info(request);
+	request->delegated = 0;
+
+	ASSERT(table_info->colnum >= SUNFMFAULTEVENT_COLMIN);
+	ASSERT(table_info->colnum <= SUNFMFAULTEVENT_COLMAX);
+
+	/*
+	 * table_info->colnum contains the column number requested.
+	 * table_info->indexes contains a linked list of snmp variable
+	 * bindings for the indexes of the table.  Values in the list
+	 * have been set corresponding to the indexes of the
+	 * request.  We have other guarantees as well:
+	 *
+	 * - The column number is always within range.
+	 * - If we have no index data, table_info->index_oid_len is 0.
+	 * - We will never receive requests outside our table nor
+	 *   those with the first subid anything other than 1 (Entry)
+	 *   nor those without a column number.  This is true even
+	 *   for GETNEXT requests.
+	 */
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		if ((data = sunFmFaultEventTable_fe(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	case MODE_GETNEXT:
+	case MODE_GETBULK:
+		if ((data = sunFmFaultEventTable_nextfe(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	default:
+		snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request mode %d\n",
+		    reqinfo->mode);
+		netsnmp_free_delegated_cache(cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	switch (table_info->colnum) {
+	case SUNFMFAULTEVENT_COL_PROBLEMUUID:
+	{
+		if ((pdata = sunFmProblemTable_pr(reginfo, table_info))
+		    == NULL) {
+			netsnmp_table_build_result(reginfo, request, table_info,
+			    ASN_OCTET_STR, NULL, 0);
+			break;
+		}
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)pdata->d_aci_uuid,
+		    strlen(pdata->d_aci_uuid));
+		break;
+	}
+	case SUNFMFAULTEVENT_COL_CLASS:
+	{
+		char	*class = "-";
+
+		(void) nvlist_lookup_string(data, FM_CLASS, &class);
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)class, strlen(class));
+		break;
+	}
+	case SUNFMFAULTEVENT_COL_CERTAINTY:
+	{
+		uint8_t	pct = 0;
+		ulong_t	pl;
+
+		(void) nvlist_lookup_uint8(data, FM_FAULT_CERTAINTY,
+		    &pct);
+		pl = (ulong_t)pct;
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_UNSIGNED, (uchar_t *)&pl, sizeof (pl));
+		break;
+	}
+	case SUNFMFAULTEVENT_COL_ASRU:
+	{
+		nvlist_t	*asru = NULL;
+		char		*fmri;
+
+		(void) nvlist_lookup_nvlist(data, FM_FAULT_ASRU, &asru);
+		if ((fmri = sunFm_nvl2str(asru)) == NULL)
+			fmri = "-";
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)fmri, strlen(fmri));
+		break;
+	}
+	case SUNFMFAULTEVENT_COL_FRU:
+	{
+		nvlist_t	*fru = NULL;
+		char		*fmri;
+
+		(void) nvlist_lookup_nvlist(data, FM_FAULT_FRU, &fru);
+		if ((fmri = sunFm_nvl2str(fru)) == NULL)
+			fmri = "-";
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)fmri, strlen(fmri));
+		break;
+	}
+	case SUNFMFAULTEVENT_COL_RESOURCE:
+	{
+		nvlist_t	*rsrc = NULL;
+		char		*fmri;
+
+		(void) nvlist_lookup_nvlist(data, FM_FAULT_ASRU, &rsrc);
+		if ((fmri = sunFm_nvl2str(rsrc)) == NULL)
+			fmri = "-";
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)fmri, strlen(fmri));
+		break;
+	}
+	default:
+		break;
+	}
+
+	netsnmp_free_delegated_cache(cache);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+static int
+sunFmFaultEventTable_handler(netsnmp_mib_handler *handler,
+    netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo,
+    netsnmp_request_info *requests)
+{
+	netsnmp_request_info		*request;
+	struct timeval			tv;
+
+	tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+	tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+	request_update();
+
+	for (request = requests; request; request = request->next) {
+		if (request->processed != 0)
+			continue;
+
+		if (netsnmp_extract_table_info(request) == NULL)
+			continue;
+
+		request->delegated = 1;
+		(void) snmp_alarm_register_hr(tv, 0,
+		    sunFmFaultEventTable_return,
+		    (void *) netsnmp_create_delegated_cache(handler, reginfo,
+		    reqinfo, request, NULL));
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/problem.h	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,70 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_PROBLEM_H
+#define	_PROBLEM_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <libuutil.h>
+#include <libnvpair.h>
+
+typedef struct sunFmProblem_data {
+	int		d_valid;
+	uu_avl_node_t	d_uuid_avl;
+	const char	*d_aci_uuid;
+	const char	*d_aci_code;
+	const char	*d_aci_url;
+	const char	*d_diag_engine;
+	struct timeval	d_diag_time;
+	ulong_t		d_nsuspects;
+	nvlist_t	**d_suspects;
+	nvlist_t	*d_aci_event;
+} sunFmProblem_data_t;
+
+typedef struct sunFmProblem_update_ctx {
+	const char	*uc_host;
+	uint32_t	uc_prog;
+	int		uc_version;
+	const char	*uc_index;
+	uint32_t	uc_type;
+} sunFmProblem_update_ctx_t;
+
+typedef nvlist_t sunFmFaultEvent_data_t;
+
+int sunFmProblemTable_init(void);
+int sunFmFaultEventTable_init(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _PROBLEM_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/resource.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,789 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <fm/fmd_adm.h>
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <pthread.h>
+#include <stddef.h>
+#include <errno.h>
+#include <libuutil.h>
+#include "sunFM_impl.h"
+#include "resource.h"
+
+static uu_avl_pool_t	*rsrc_fmri_avl_pool;
+static uu_avl_pool_t	*rsrc_index_avl_pool;
+static uu_avl_t		*rsrc_fmri_avl;
+static uu_avl_t		*rsrc_index_avl;
+
+#define	VALID_AVL_STATE	(rsrc_fmri_avl_pool != NULL &&		\
+	rsrc_index_avl_pool != NULL && rsrc_fmri_avl != NULL &&	\
+	rsrc_index_avl != NULL)
+
+#define	UPDATE_WAIT_MILLIS	10	/* poll interval in milliseconds */
+
+/*
+ * Update types: single-index and all are mutually exclusive; a count
+ * update is optional.
+ */
+#define	UCT_INDEX	0x1
+#define	UCT_ALL		0x2
+#define	UCT_COUNT	0x4
+#define	UCT_FLAGS	0x7
+
+#define	RESOURCE_DATA_VALID(d)	((d)->d_valid == valid_stamp)
+
+/*
+ * Locking strategy is described in module.c.
+ */
+static ulong_t		max_index;
+static int		valid_stamp;
+static uint32_t		rsrc_count;
+static pthread_mutex_t	update_lock;
+static pthread_cond_t	update_cv;
+static volatile enum { US_QUIET, US_NEEDED, US_INPROGRESS } update_status;
+
+static Netsnmp_Node_Handler	sunFmResourceTable_handler;
+static Netsnmp_Node_Handler	sunFmResourceCount_handler;
+
+static sunFmResource_data_t *
+key_build(const char *fmri, const ulong_t index)
+{
+	static sunFmResource_data_t	key;
+
+	key.d_index = index;
+	if (fmri)
+		strlcpy(key.d_ari_fmri, fmri, sizeof (key.d_ari_fmri));
+	else
+		key.d_ari_fmri[0] = '\0';
+
+	return (&key);
+}
+
+/*
+ * If fmri is the fmri of a resource we have previously seen and indexed, return
+ * data for it.  Otherwise, return NULL.  Note that the resource may not be
+ * valid; that is, it may have been removed from the fault manager since its
+ * information was last updated.
+ */
+static sunFmResource_data_t *
+resource_lookup_fmri(const char *fmri)
+{
+	sunFmResource_data_t	*key;
+
+	key = key_build(fmri, 0);
+	return (uu_avl_find(rsrc_fmri_avl, key, NULL, NULL));
+}
+
+/*
+ * If index corresponds to a resource we have previously seen and indexed,
+ * return data for it.  Otherwise, return NULL.  Note that the resource may
+ * not be valid; that is, it may have been expired from the fault manager
+ * since its information was last updated.
+ */
+static sunFmResource_data_t *
+resource_lookup_index_exact(const ulong_t index)
+{
+	sunFmResource_data_t	*key;
+
+	key = key_build(NULL, index);
+	return (uu_avl_find(rsrc_index_avl, key, NULL, NULL));
+}
+
+/*
+ * If index corresponds to a valid (that is, extant as of latest information
+ * from the fault manager) resource, return the data for that resource.
+ * Otherwise, return the data for the valid resource whose index is as close as
+ * possible to index but not lower.  This preserves the lexicographical
+ * ordering required for GETNEXT processing.
+ */
+static sunFmResource_data_t *
+resource_lookup_index_nextvalid(const ulong_t index)
+{
+	sunFmResource_data_t	*key, *data;
+	uu_avl_index_t		idx;
+
+	key = key_build(NULL, index);
+
+	if ((data = uu_avl_find(rsrc_index_avl, key, NULL, &idx)) != NULL &&
+	    RESOURCE_DATA_VALID(data))
+			return (data);
+
+	data = uu_avl_nearest_next(rsrc_index_avl, idx);
+
+	while (data != NULL && !RESOURCE_DATA_VALID(data)) {
+		(void) uu_avl_find(rsrc_index_avl, data, NULL, &idx);
+		data = uu_avl_nearest_next(rsrc_index_avl, idx);
+	}
+
+	return (data);
+}
+
+/*
+ * Possible update the contents of a single resource within the cache.  This
+ * is our callback from fmd_rsrc_iter.
+ */
+static int
+rsrcinfo_update_one(const fmd_adm_rsrcinfo_t *rsrcinfo, void *arg)
+{
+	const sunFmResource_update_ctx_t *update_ctx =
+	    (sunFmResource_update_ctx_t *)arg;
+	sunFmResource_data_t *data = resource_lookup_fmri(rsrcinfo->ari_fmri);
+
+	++rsrc_count;
+
+	/*
+	 * A resource we haven't seen before.  We're obligated to index
+	 * it and link it into our cache so that we can find it, but we're
+	 * not obligated to fill it in completely unless we're doing a
+	 * full update or this is the resource we were asked for.  This
+	 * avoids unnecessary iteration and memory manipulation for data
+	 * we're not going to return for this request.
+	 */
+	if (data == NULL) {
+		uu_avl_index_t idx;
+
+		DEBUGMSGTL((MODNAME_STR, "found new resource %s\n",
+		    rsrcinfo->ari_fmri));
+		if ((data = SNMP_MALLOC_TYPEDEF(sunFmResource_data_t)) ==
+		    NULL) {
+			snmp_log(LOG_ERR, MODNAME_STR ": Out of memory for "
+			    "new resource data at %s:%d\n", __FILE__, __LINE__);
+			return (1);
+		}
+		/*
+		 * We allocate indices sequentially and never reuse them.
+		 * This ensures we can always return valid GETNEXT responses
+		 * without having to reindex, and it provides the user a
+		 * more consistent view of the fault manager.
+		 */
+		data->d_index = ++max_index;
+		DEBUGMSGTL((MODNAME_STR, "index %lu is %s@%p\n", data->d_index,
+		    rsrcinfo->ari_fmri, data));
+
+		strlcpy(data->d_ari_fmri, rsrcinfo->ari_fmri,
+		    sizeof (data->d_ari_fmri));
+
+		uu_avl_node_init(data, &data->d_fmri_avl, rsrc_fmri_avl_pool);
+		(void) uu_avl_find(rsrc_fmri_avl, data, NULL, &idx);
+		uu_avl_insert(rsrc_fmri_avl, data, idx);
+
+		uu_avl_node_init(data, &data->d_index_avl, rsrc_index_avl_pool);
+		(void) uu_avl_find(rsrc_index_avl, data, NULL, &idx);
+		uu_avl_insert(rsrc_index_avl, data, idx);
+
+		DEBUGMSGTL((MODNAME_STR, "completed new resource %lu/%s@%p\n",
+		    data->d_index, data->d_ari_fmri, data));
+	}
+
+	data->d_valid = valid_stamp;
+
+	DEBUGMSGTL((MODNAME_STR, "timestamp updated for %lu/%s@%p: %lu\n",
+	    data->d_index, data->d_ari_fmri, data, data->d_valid));
+
+	if ((update_ctx->uc_type & UCT_ALL) ||
+	    update_ctx->uc_index == data->d_index) {
+		strlcpy(data->d_ari_case, rsrcinfo->ari_case,
+		    sizeof (data->d_ari_case));
+		data->d_ari_flags = rsrcinfo->ari_flags;
+	}
+
+	return (!(update_ctx->uc_type & UCT_ALL) &&
+	    update_ctx->uc_index == data->d_index);
+}
+
+/*
+ * Update some or all resource data from fmd.  If type includes UCT_ALL, all
+ * resources will be indexed and their data cached.  If type includes
+ * UCT_INDEX, updates will stop once the resource matching index has been
+ * updated.  If UCT_COUNT is set, the number of faulted resources will be
+ * set.
+ *
+ * Returns appropriate SNMP error codes.
+ */
+static int
+rsrcinfo_update(sunFmResource_update_ctx_t *update_ctx)
+{
+	fmd_adm_t *adm;
+	int err;
+
+	ASSERT(update_ctx != NULL);
+	ASSERT((update_ctx->uc_type & (UCT_ALL|UCT_INDEX)) !=
+	    (UCT_ALL|UCT_INDEX));
+	ASSERT((update_ctx->uc_type & ~UCT_FLAGS) == 0);
+	ASSERT(VALID_AVL_STATE);
+
+	if ((adm = fmd_adm_open(update_ctx->uc_host, update_ctx->uc_prog,
+	    update_ctx->uc_version)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": Communication with fmd "
+		    "failed: %s\n", strerror(errno));
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	if (update_ctx->uc_type == UCT_COUNT) {
+		err = fmd_adm_rsrc_count(adm, update_ctx->uc_all, &rsrc_count);
+	} else {
+		++valid_stamp;
+		rsrc_count = 0;
+		err = fmd_adm_rsrc_iter(adm, update_ctx->uc_all,
+		    rsrcinfo_update_one, update_ctx);
+		DEBUGMSGTL((MODNAME_STR, "resource iteration completed\n"));
+	}
+
+	fmd_adm_close(adm);
+
+	if (err != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": fmd resource information "
+		    "update failed: %s\n", fmd_adm_errmsg(adm));
+		return (SNMP_ERR_RESOURCEUNAVAILABLE);
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
+
+/*ARGSUSED*/
+static void
+update_thread(void *arg)
+{
+	/*
+	 * The current rsrcinfo_update implementation offers minimal savings
+	 * for the use of index-only updates; therefore we always do a full
+	 * update.  If it becomes advantageous to limit updates to a single
+	 * index, the contexts can be queued by the handler instead.
+	 */
+	sunFmResource_update_ctx_t	uc;
+
+	uc.uc_host = NULL;
+	uc.uc_prog = FMD_ADM_PROGRAM;
+	uc.uc_version = FMD_ADM_VERSION;
+
+	uc.uc_index = 0;
+	uc.uc_type = UCT_ALL;
+
+	for (;;) {
+		(void) pthread_mutex_lock(&update_lock);
+		update_status = US_QUIET;
+		while (update_status == US_QUIET)
+			(void) pthread_cond_wait(&update_cv, &update_lock);
+		update_status = US_INPROGRESS;
+		(void) pthread_mutex_unlock(&update_lock);
+		(void) rsrcinfo_update(&uc);
+	}
+}
+
+static void
+request_update(void)
+{
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+	update_status = US_NEEDED;
+	(void) pthread_cond_signal(&update_cv);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+/*ARGSUSED*/
+static int
+resource_compare_fmri(const void *l, const void *r, void *private)
+{
+	sunFmResource_data_t	*l_data = (sunFmResource_data_t *)l;
+	sunFmResource_data_t	*r_data = (sunFmResource_data_t *)r;
+
+	ASSERT(l_data != NULL && r_data != NULL);
+
+	return (strcmp(l_data->d_ari_fmri, r_data->d_ari_fmri));
+}
+
+/*ARGSUSED*/
+static int
+resource_compare_index(const void *l, const void *r, void *private)
+{
+	sunFmResource_data_t	*l_data = (sunFmResource_data_t *)l;
+	sunFmResource_data_t	*r_data = (sunFmResource_data_t *)r;
+
+	ASSERT(l_data != NULL && r_data != NULL);
+
+	return (l_data->d_index < r_data->d_index ? -1 :
+	    l_data->d_index > r_data->d_index ? 1 : 0);
+}
+
+int
+sunFmResourceTable_init(void)
+{
+	static oid sunFmResourceTable_oid[] = { SUNFMRESOURCETABLE_OID };
+	static oid sunFmResourceCount_oid[] = { SUNFMRESOURCECOUNT_OID, 0 };
+	netsnmp_table_registration_info *table_info;
+	netsnmp_handler_registration *handler;
+	int err;
+
+	if ((err = pthread_mutex_init(&update_lock, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": mutex_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+	if ((err = pthread_cond_init(&update_cv, NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": cond_init failure: %s\n",
+		    strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = pthread_create(NULL, NULL, (void *(*)(void *))update_thread,
+	    NULL)) != 0) {
+		snmp_log(LOG_ERR, MODNAME_STR ": error creating update "
+		    "thread: %s\n", strerror(err));
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((table_info =
+	    SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info)) == NULL)
+		return (MIB_REGISTRATION_FAILED);
+
+	if ((handler = netsnmp_create_handler_registration("sunFmResourceTable",
+	    sunFmResourceTable_handler, sunFmResourceTable_oid,
+	    OID_LENGTH(sunFmResourceTable_oid), HANDLER_CAN_RONLY)) == NULL) {
+		SNMP_FREE(table_info);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	/*
+	 * The Net-SNMP template uses add_indexes here, but that
+	 * function is unsafe because it does not check for failure.
+	 */
+	if (netsnmp_table_helper_add_index(table_info, ASN_UNSIGNED) == NULL) {
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	table_info->min_column = SUNFMRESOURCE_COLMIN;
+	table_info->max_column = SUNFMRESOURCE_COLMAX;
+
+	if ((rsrc_fmri_avl_pool = uu_avl_pool_create("rsrc_fmri",
+	    sizeof (sunFmResource_data_t),
+	    offsetof(sunFmResource_data_t, d_fmri_avl), resource_compare_fmri,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": rsrc_fmri avl pool creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+	}
+
+	if ((rsrc_fmri_avl = uu_avl_create(rsrc_fmri_avl_pool, NULL,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": rsrc_fmri avl creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_pool_destroy(rsrc_fmri_avl_pool);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((rsrc_index_avl_pool = uu_avl_pool_create("rsrc_index",
+	    sizeof (sunFmResource_data_t),
+	    offsetof(sunFmResource_data_t, d_index_avl),
+	    resource_compare_index, UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": rsrc_index avl pool creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(rsrc_fmri_avl);
+		uu_avl_pool_destroy(rsrc_fmri_avl_pool);
+	}
+
+	if ((rsrc_index_avl = uu_avl_create(rsrc_index_avl_pool, NULL,
+	    UU_AVL_DEBUG)) == NULL) {
+		snmp_log(LOG_ERR, MODNAME_STR ": rsrc_index avl creation "
+		    "failed: %s\n", uu_strerror(uu_error()));
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(rsrc_fmri_avl);
+		uu_avl_pool_destroy(rsrc_fmri_avl_pool);
+		uu_avl_pool_destroy(rsrc_index_avl_pool);
+		return (MIB_REGISTRATION_FAILED);
+	}
+
+	if ((err = netsnmp_register_table(handler, table_info)) !=
+	    MIB_REGISTERED_OK) {
+		snmp_free_varbind(table_info->indexes);
+		SNMP_FREE(table_info);
+		SNMP_FREE(handler);
+		uu_avl_destroy(rsrc_fmri_avl);
+		uu_avl_pool_destroy(rsrc_fmri_avl_pool);
+		uu_avl_destroy(rsrc_index_avl);
+		uu_avl_pool_destroy(rsrc_index_avl_pool);
+		return (err);
+	}
+
+	if ((err = netsnmp_register_read_only_instance(
+	    netsnmp_create_handler_registration("sunFmResourceCount",
+		sunFmResourceCount_handler, sunFmResourceCount_oid,
+		OID_LENGTH(sunFmResourceCount_oid), HANDLER_CAN_RONLY))) !=
+	    MIB_REGISTERED_OK) {
+		/*
+		 * There's no way to unregister the table handler, so we
+		 * can't free any of the data, either.
+		 */
+		return (err);
+	}
+
+	return (MIB_REGISTERED_OK);
+}
+
+/*
+ * These two functions form the core of GET/GETNEXT/GETBULK handling (the
+ * only kind we do).  They perform two functions:
+ *
+ * - First, frob the request to set all the index variables to correspond
+ *   to the value that's going to be returned.  For GET, this is a nop;
+ *   for GETNEXT/GETBULK it always requires some work.
+ * - Second, find and return the fmd resource information corresponding to
+ *   the (possibly updated) indices.
+ *
+ * These should be as fast as possible; they run in the agent thread.
+ */
+static sunFmResource_data_t *
+sunFmResourceTable_nextrsrc(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmResource_data_t	*data;
+	netsnmp_variable_list	*var;
+	ulong_t index;
+
+	/*
+	 * If we have no index, we must make one.
+	 */
+	if (table_info->number_indexes < 1) {
+		oid tmpoid[MAX_OID_LEN];
+		index = 1;
+
+		DEBUGMSGTL((MODNAME_STR, "nextrsrc: no indexes given\n"));
+		var = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
+		snmp_set_var_typed_value(var, ASN_UNSIGNED, (uchar_t *)&index,
+		    sizeof (index));
+		memcpy(tmpoid, reginfo->rootoid,
+		    reginfo->rootoid_len * sizeof (oid));
+		tmpoid[reginfo->rootoid_len] = 1;
+		tmpoid[reginfo->rootoid_len + 1] = table_info->colnum;
+		if (build_oid(&var->name, &var->name_length, tmpoid,
+		    reginfo->rootoid_len + 2, var) != SNMPERR_SUCCESS) {
+			snmp_free_varbind(var);
+			return (NULL);
+		}
+		DEBUGMSGTL((MODNAME_STR, "nextrsrc: built fake index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, var));
+		DEBUGMSG((MODNAME_STR, "\n"));
+	} else {
+		var = table_info->indexes;
+		index = *var->val.integer;
+		DEBUGMSGTL((MODNAME_STR, "nextrsrc: received index:\n"));
+		DEBUGMSGVAR((MODNAME_STR, var));
+		DEBUGMSG((MODNAME_STR, "\n"));
+		index++;
+	}
+
+	if ((data = resource_lookup_index_nextvalid(index)) == NULL) {
+		DEBUGMSGTL((MODNAME_STR, "nextrsrc: exact match not found for "
+		    "index %lu; trying next column\n", index));
+		if (table_info->colnum >= SUNFMRESOURCE_COLMAX) {
+			snmp_free_varbind(var);
+			table_info->indexes = NULL;
+			table_info->number_indexes = 0;
+			DEBUGMSGTL((MODNAME_STR, "nextrsrc: out of columns\n"));
+			return (NULL);
+		}
+		table_info->colnum++;
+		index = 1;
+
+		data = resource_lookup_index_nextvalid(index);
+	}
+
+	if (data == NULL) {
+		DEBUGMSGTL((MODNAME_STR, "nextrsrc: exact match not found for "
+		    "index %lu; stopping\n", index));
+		snmp_free_varbind(var);
+		table_info->indexes = NULL;
+		table_info->number_indexes = 0;
+		return (NULL);
+	}
+
+	*var->val.integer = index;
+	table_info->indexes = var;
+
+	DEBUGMSGTL((MODNAME_STR, "matching data is %lu/%s@%p\n", data->d_index,
+	    data->d_ari_fmri, data));
+
+	return (data);
+}
+
+/*ARGSUSED*/
+static sunFmResource_data_t *
+sunFmResourceTable_rsrc(netsnmp_handler_registration *reginfo,
+    netsnmp_table_request_info *table_info)
+{
+	sunFmResource_data_t	*data;
+	netsnmp_variable_list	*var;
+
+	ASSERT(table_info->number_indexes == 1);
+
+	return (resource_lookup_index_exact(table_info->index_oid[0]));
+}
+
+static void
+sunFmResourceTable_return(unsigned int reg, void *arg)
+{
+	netsnmp_delegated_cache		*cache = (netsnmp_delegated_cache *)arg;
+	netsnmp_request_info		*request;
+	netsnmp_agent_request_info	*reqinfo;
+	netsnmp_handler_registration	*reginfo;
+	netsnmp_mib_handler		*handler;
+	netsnmp_table_request_info	*table_info;
+	netsnmp_variable_list		*var;
+	sunFmResource_data_t		*data;
+	ulong_t				rsrcstate;
+
+	ASSERT(netsnmp_handler_check_cache(cache) != NULL);
+
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		struct timeval			tv;
+
+		tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+		tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+		(void) snmp_alarm_register_hr(tv, 0, sunFmResourceTable_return,
+		    cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	request = cache->requests;
+	reqinfo = cache->reqinfo;
+	reginfo = cache->reginfo;
+	handler = cache->handler;
+
+	var = request->requestvb;
+	table_info = netsnmp_extract_table_info(request);
+	request->delegated = 0;
+
+	ASSERT(table_info->colnum >= SUNFMRESOURCE_COLMIN);
+	ASSERT(table_info->colnum <= SUNFMRESOURCE_COLMAX);
+
+	/*
+	 * table_info->colnum contains the column number requested.
+	 * table_info->indexes contains a linked list of snmp variable
+	 * bindings for the indexes of the table.  Values in the list
+	 * have been set corresponding to the indexes of the
+	 * request.  We have other guarantees as well:
+	 *
+	 * - The column number is always within range.
+	 * - If we have no index data, table_info->index_oid_len is 0.
+	 * - We will never receive requests outside our table nor
+	 *   those with the first subid anything other than 1 (Entry)
+	 *   nor those without a column number.  This is true even
+	 *   for GETNEXT requests.
+	 */
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		if ((data = sunFmResourceTable_rsrc(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	case MODE_GETNEXT:
+	case MODE_GETBULK:
+		if ((data = sunFmResourceTable_nextrsrc(reginfo, table_info)) ==
+		    NULL) {
+			netsnmp_free_delegated_cache(cache);
+			(void) pthread_mutex_unlock(&update_lock);
+			return;
+		}
+		break;
+	default:
+		snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request mode %d\n",
+		    reqinfo->mode);
+		netsnmp_free_delegated_cache(cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	switch (table_info->colnum) {
+	case SUNFMRESOURCE_COL_FMRI:
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_ari_fmri,
+		    strlen(data->d_ari_fmri));
+		break;
+	case SUNFMRESOURCE_COL_STATUS:
+		switch (data->d_ari_flags &
+		    (FMD_ADM_RSRC_FAULTY|FMD_ADM_RSRC_UNUSABLE)) {
+		default:
+			rsrcstate = SUNFMRESOURCE_STATE_OK;
+			break;
+		case FMD_ADM_RSRC_FAULTY:
+			rsrcstate = SUNFMRESOURCE_STATE_DEGRADED;
+			break;
+		case FMD_ADM_RSRC_UNUSABLE:
+			rsrcstate = SUNFMRESOURCE_STATE_UNKNOWN;
+			break;
+		case FMD_ADM_RSRC_FAULTY | FMD_ADM_RSRC_UNUSABLE:
+			rsrcstate = SUNFMRESOURCE_STATE_FAULTED;
+			break;
+		}
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_INTEGER, (uchar_t *)&rsrcstate,
+		    sizeof (rsrcstate));
+		break;
+	case SUNFMRESOURCE_COL_DIAGNOSISUUID:
+		netsnmp_table_build_result(reginfo, request, table_info,
+		    ASN_OCTET_STR, (uchar_t *)data->d_ari_case,
+		    strlen(data->d_ari_case));
+		break;
+	default:
+		break;
+	}
+	netsnmp_free_delegated_cache(cache);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+static int
+sunFmResourceTable_handler(netsnmp_mib_handler *handler,
+    netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo,
+    netsnmp_request_info *requests)
+{
+	netsnmp_request_info		*request;
+	struct timeval			tv;
+
+	tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+	tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+	request_update();
+
+	for (request = requests; request; request = request->next) {
+		if (request->processed != 0)
+			continue;
+
+		if (netsnmp_extract_table_info(request) == NULL)
+			continue;
+
+		request->delegated = 1;
+		(void) snmp_alarm_register_hr(tv, 0, sunFmResourceTable_return,
+		    (void *) netsnmp_create_delegated_cache(handler, reginfo,
+		    reqinfo, request, NULL));
+	}
+
+	return (SNMP_ERR_NOERROR);
+}
+
+static void
+sunFmResourceCount_return(unsigned int reg, void *arg)
+{
+	netsnmp_delegated_cache		*cache = (netsnmp_delegated_cache *)arg;
+	netsnmp_request_info		*request;
+	netsnmp_agent_request_info	*reqinfo;
+	netsnmp_handler_registration	*reginfo;
+	netsnmp_mib_handler		*handler;
+	ulong_t				rsrc_count_long;
+	int				err;
+
+	ASSERT(netsnmp_handler_check_cache(cache) != NULL);
+
+	(void) pthread_mutex_lock(&update_lock);
+	if (update_status != US_QUIET) {
+		struct timeval	tv;
+
+		tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+		tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+		(void) snmp_alarm_register_hr(tv, 0, sunFmResourceCount_return,
+		    cache);
+		(void) pthread_mutex_unlock(&update_lock);
+		return;
+	}
+
+	request = cache->requests;
+	reqinfo = cache->reqinfo;
+	reginfo = cache->reginfo;
+	handler = cache->handler;
+
+	request->delegated = 0;
+
+	switch (reqinfo->mode) {
+	case MODE_GET:
+		DEBUGMSGTL((MODNAME_STR, "resource count is %u\n", rsrc_count));
+		rsrc_count_long = (ulong_t)rsrc_count;
+		snmp_set_var_typed_value(request->requestvb, ASN_GAUGE,
+		    (uchar_t *)&rsrc_count_long, sizeof (rsrc_count_long));
+		break;
+	default:
+		snmp_log(LOG_ERR, MODNAME_STR ": Unsupported request mode %d\n",
+		    reqinfo->mode);
+	}
+
+	netsnmp_free_delegated_cache(cache);
+	(void) pthread_mutex_unlock(&update_lock);
+}
+
+static int
+sunFmResourceCount_handler(netsnmp_mib_handler *handler,
+    netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo,
+    netsnmp_request_info *requests)
+{
+	struct timeval	tv;
+
+	tv.tv_sec = UPDATE_WAIT_MILLIS / 1000;
+	tv.tv_usec = (UPDATE_WAIT_MILLIS % 1000) * 1000;
+
+	request_update();
+
+	/*
+	 * We are never called for a GETNEXT when registered as an
+	 * instance; it's handled for us and converted to a GET.
+	 * Also, an instance handler is given only one request at a time, so
+	 * we don't need to loop over a list of requests.
+	 */
+
+	if (requests->processed != 0)
+		return (SNMP_ERR_NOERROR);
+
+	requests->delegated = 1;
+	(void) snmp_alarm_register_hr(tv, 0, sunFmResourceCount_return,
+	    (void *) netsnmp_create_delegated_cache(handler, reginfo,
+	    reqinfo, requests, NULL));
+
+	return (SNMP_ERR_NOERROR);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/resource.h	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,65 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_RESOURCE_H
+#define	_RESOURCE_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+#include <libuutil.h>
+
+typedef struct sunFmResource_data {
+	ulong_t		d_index;		/* MIB index */
+	int		d_valid;		/* iteration stamp */
+	uu_avl_node_t	d_fmri_avl;		/* by-FMRI AVL node */
+	uu_avl_node_t	d_index_avl;		/* by-index AVL node */
+	char		d_ari_fmri[256];	/* resource FMRI */
+	char		d_ari_case[256];	/* resource state case UUID */
+	uint_t		d_ari_flags;		/* resource flags */
+} sunFmResource_data_t;
+
+typedef struct sunFmResource_update_ctx {
+	const char	*uc_host;
+	uint32_t	uc_prog;
+	int		uc_version;
+	int		uc_all;
+	ulong_t		uc_index;
+	uint32_t	uc_type;
+} sunFmResource_update_ctx_t;
+
+int sunFmResourceTable_init(void);
+int sunFmResourceCount_init(void);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _RESOURCE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/scheme.c	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,297 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/fm/protocol.h>
+#include <sys/types.h>
+#include <sys/systeminfo.h>
+#include <fm/fmd_snmp.h>
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <libnvpair.h>
+#include <limits.h>
+#include <strings.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+#define	SCHEMEDIR_BASE	"/usr/lib/fm/fmd/schemes"
+
+#if defined(__sparcv9)
+#define	DEFAULTSCHEMEDIR	SCHEMEDIR_BASE "/sparcv9"
+#elif defined(__amd64)
+#define	DEFAULTSCHEMEDIR	SCHEMEDIR_BASE "/amd64"
+#else
+#define	DEFAULTSCHEMEDIR	SCHEMEDIR_BASE
+#endif
+
+typedef struct fmd_scheme_ops {
+	int (*sop_init)(void);
+	void (*sop_fini)(void);
+	ssize_t (*sop_nvl2str)(nvlist_t *, char *, size_t);
+} fmd_scheme_ops_t;
+
+typedef struct fmd_scheme_opd {
+	const char *opd_name;		/* symbol name of scheme function */
+	size_t opd_off;			/* offset within fmd_scheme_ops_t */
+} fmd_scheme_opd_t;
+
+typedef struct fmd_scheme {
+	struct fmd_scheme *sch_next;    /* next scheme on list of schemes */
+	char *sch_name;			/* name of this scheme (fmri prefix) */
+	void *sch_dlp;			/* libdl(3DL) shared library handle */
+	int sch_err;			/* if negative entry, errno to return */
+	fmd_scheme_ops_t sch_ops;	/* scheme function pointers */
+} fmd_scheme_t;
+
+static fmd_scheme_t *sch_list;		/* list of cached schemes */
+static char *g_root;			/* fmd root dir */
+
+static long
+fmd_scheme_notsup(void)
+{
+	errno = ENOTSUP;
+	return (-1);
+}
+
+static int
+fmd_scheme_nop(void)
+{
+	return (0);
+}
+
+/*
+ * Default values for the scheme ops.  If a scheme function is not defined in
+ * the module, then this operation is implemented using the default function.
+ */
+static const fmd_scheme_ops_t _fmd_scheme_default_ops = {
+	(int (*)())fmd_scheme_nop,		/* sop_init */
+	(void (*)())fmd_scheme_nop,		/* sop_fini */
+	(ssize_t (*)())fmd_scheme_notsup,	/* sop_nvl2str */
+};
+
+/*
+ * Scheme ops descriptions.  These names and offsets are used by the function
+ * fmd_scheme_rtld_init(), defined below, to load up a fmd_scheme_ops_t.
+ */
+static const fmd_scheme_opd_t _fmd_scheme_ops[] = {
+	{ "fmd_fmri_init", offsetof(fmd_scheme_ops_t, sop_init) },
+	{ "fmd_fmri_fini", offsetof(fmd_scheme_ops_t, sop_fini) },
+	{ "fmd_fmri_nvl2str", offsetof(fmd_scheme_ops_t, sop_nvl2str) },
+	{ NULL, 0 }
+};
+
+static fmd_scheme_t *
+fmd_scheme_create(const char *name)
+{
+	fmd_scheme_t *sp;
+
+	if ((sp = malloc(sizeof (fmd_scheme_t))) == NULL ||
+	    (sp->sch_name = strdup(name)) == NULL) {
+		free(sp);
+		return (NULL);
+	}
+
+	sp->sch_next = sch_list;
+	sp->sch_dlp = NULL;
+	sp->sch_err = 0;
+	sp->sch_ops = _fmd_scheme_default_ops;
+
+	sch_list = sp;
+	return (sp);
+}
+
+static int
+fmd_scheme_rtld_init(fmd_scheme_t *sp)
+{
+	const fmd_scheme_opd_t *opd;
+	void *p;
+
+	for (opd = _fmd_scheme_ops; opd->opd_name != NULL; opd++) {
+		if ((p = dlsym(sp->sch_dlp, opd->opd_name)) != NULL)
+			*(void **)((uintptr_t)&sp->sch_ops + opd->opd_off) = p;
+	}
+
+	return (sp->sch_ops.sop_init());
+}
+
+static fmd_scheme_t *
+fmd_scheme_lookup(const char *dir, const char *name)
+{
+	fmd_scheme_t *sp;
+	char path[PATH_MAX];
+
+	for (sp = sch_list; sp != NULL; sp = sp->sch_next) {
+		if (strcmp(name, sp->sch_name) == 0)
+			return (sp);
+	}
+
+	if ((sp = fmd_scheme_create(name)) == NULL)
+		return (NULL); /* errno is set for us */
+
+	(void) snprintf(path, sizeof (path), "%s%s/%s.so",
+	    g_root ? g_root : "", dir, name);
+
+	if (access(path, F_OK) != 0) {
+		sp->sch_err = errno;
+		return (sp);
+	}
+
+	if ((sp->sch_dlp = dlopen(path, RTLD_LOCAL | RTLD_NOW | RTLD_PARENT)) ==
+	    NULL) {
+		sp->sch_err = ELIBACC;
+		return (sp);
+	}
+
+	if (fmd_scheme_rtld_init(sp) != 0) {
+		sp->sch_err = errno;
+		(void) dlclose(sp->sch_dlp);
+		sp->sch_dlp = NULL;
+	}
+
+	return (sp);
+}
+
+char *
+sunFm_nvl2str(nvlist_t *nvl)
+{
+	fmd_scheme_t *sp;
+	char c, *name, *s = NULL;
+	ssize_t len;
+
+	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) {
+		DEBUGMSGTL((MODNAME_STR, "fmri does not contain required "
+		    "'%s' nvpair\n", FM_FMRI_SCHEME));
+		return (NULL);
+	}
+
+	if ((sp = fmd_scheme_lookup(DEFAULTSCHEMEDIR, name)) == NULL ||
+	    sp->sch_dlp == NULL || sp->sch_err != 0) {
+		const char *msg =
+		    sp->sch_err == ELIBACC ? dlerror() : strerror(sp->sch_err);
+		DEBUGMSGTL((MODNAME_STR, "cannot init '%s' scheme library to "
+		    "format fmri: %s\n", name, msg ? msg : "unknown error"));
+		return (NULL);
+	}
+
+	if ((len = sp->sch_ops.sop_nvl2str(nvl, &c, sizeof (c))) == -1 ||
+	    (s = malloc(len + 1)) == NULL ||
+	    sp->sch_ops.sop_nvl2str(nvl, s, len + 1) == -1) {
+		DEBUGMSGTL((MODNAME_STR, "cannot format fmri using scheme '%s'",
+		    name));
+		free(s);
+		return (NULL);
+	}
+
+	return (s);
+}
+
+void *
+fmd_fmri_alloc(size_t size)
+{
+	return (malloc(size));
+}
+
+void *
+fmd_fmri_zalloc(size_t size)
+{
+	void *data;
+
+	if ((data = malloc(size)) != NULL)
+		bzero(data, size);
+
+	return (data);
+}
+
+/*ARGSUSED*/
+void
+fmd_fmri_free(void *data, size_t size)
+{
+	free(data);
+}
+
+int
+fmd_fmri_error(int err)
+{
+	errno = err;
+	return (-1);
+}
+
+char *
+fmd_fmri_strescape(const char *s)
+{
+	return (strdup(s));
+}
+
+char *
+fmd_fmri_strdup(const char *s)
+{
+	return (strdup(s));
+}
+
+void
+fmd_fmri_strfree(char *s)
+{
+	free(s);
+}
+
+const char *
+fmd_fmri_get_rootdir(void)
+{
+	return (g_root ? g_root : "");
+}
+
+const char *
+fmd_fmri_get_platform(void)
+{
+	static char platform[MAXNAMELEN];
+
+	if (platform[0] == '\0')
+		(void) sysinfo(SI_PLATFORM, platform, sizeof (platform));
+
+	return (platform);
+}
+
+uint64_t
+fmd_fmri_get_drgen(void)
+{
+	return (0);
+}
+
+int
+fmd_fmri_set_errno(int err)
+{
+	errno = err;
+	return (-1);
+}
+
+void
+fmd_fmri_warn(const char *format, ...)
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/common/sunFM_impl.h	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,82 @@
+/*
+ * 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 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_SUNFM_IMPL_H
+#define	_SUNFM_IMPL_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <libnvpair.h>
+#include <stdarg.h>
+
+#ifdef DEBUG
+extern void sunFm_panic(const char *format, ...) __NORETURN;
+extern void sunFm_vpanic(const char *format, va_list ap) __NORETURN;
+extern int sunFm_assert(const char *, const char *, int);
+#define	ASSERT(x)	((void)((x) || sunFm_assert(#x, __FILE__, __LINE__)))
+#else
+extern void sunFm_panic(const char *format, ...);
+extern void sunFm_vpanic(const char *format, va_list ap);
+#define	ASSERT(x)
+#endif
+
+typedef int (*sunFm_table_init_func_t)(void);
+
+typedef struct sunFm_table {
+	const char		*t_name;
+	sunFm_table_init_func_t	t_init;
+} sunFm_table_t;
+
+#define	TABLE_INIT(__t)	__t##_init
+#define	TABLE_NAME(__t)	#__t
+#define	TABLE_REG(__t)	{ TABLE_NAME(__t), TABLE_INIT(__t) }
+#define	TABLE_NULL	{ NULL, NULL }
+
+/*
+ * The definition of netsnmp_table_helper_add_index in <net-snmp/agent/table.h>
+ * is defective; it includes a ; at the end.  We have to use our own.
+ */
+#ifdef	netsnmp_table_helper_add_index
+#undef	netsnmp_table_helper_add_index
+#define	netsnmp_table_helper_add_index(tinfo, type) \
+	snmp_varlist_add_variable(&tinfo->indexes, NULL, 0, (uchar_t)type, \
+	NULL, 0)
+#endif	/* netsnmp_table_helper_add_index */
+
+extern char *sunFm_nvl2str(nvlist_t *);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SUNFM_IMPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MAPDIR = ../spec/i386
+MACH_LDLIBS = -L$(ROOT)/usr/lib/fm
+
+include ../Makefile.com
+
+DYNFLAGS += -R/usr/lib/fm
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/mibs/SUN-FM-MIB.mib	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,514 @@
+--
+-- 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 2006 Sun Microsystems, Inc.  All rights reserved.
+-- Use is subject to license terms.
+--
+
+-- ident	"%Z%%M%	%I%	%E% SMI"
+
+SUN-FM-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+	products
+		FROM SUN-MIB
+	Gauge32, Unsigned32, OBJECT-TYPE, NOTIFICATION-TYPE, MODULE-IDENTITY
+		FROM SNMPv2-SMI
+	TEXTUAL-CONVENTION, DateAndTime, DisplayString
+		FROM SNMPv2-TC
+	OBJECT-GROUP, NOTIFICATION-GROUP
+		FROM SNMPv2-CONF
+	URLString
+		FROM NETWORK-SERVICES-MIB;
+
+sunFmMIB MODULE-IDENTITY
+	LAST-UPDATED	"200601130000Z"
+	ORGANIZATION	"Sun Microsystems, Inc."
+	CONTACT-INFO	"Sun Microsystems, Inc.
+			 4150 Network Circle
+			 Santa Clara, CA 95054
+
+			 1-800-555-9SUN or
+			 1-650-960-1300
+
+			 http://www.sun.com
+			 or contact your local support representative"
+	DESCRIPTION
+		"Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+		 Use is subject to license terms.
+
+		MIB providing access to Sun Fault Manager information"
+	REVISION	"200601130000Z"
+	DESCRIPTION	"Version: 1.0"
+	::= { fm 1 }
+
+fm OBJECT IDENTIFIER ::= { products 195 }
+
+SunFmUuidString ::= TEXTUAL-CONVENTION
+	STATUS	current
+	DESCRIPTION
+		"Represents a Universal Unique Identifier (UUID)."
+	SYNTAX	OCTET STRING (SIZE (0..64))
+
+SunFmModuleState ::= TEXTUAL-CONVENTION
+	STATUS	current
+	DESCRIPTION
+		"Represents the status of an fmd(1M) module."
+	SYNTAX	INTEGER {
+		other(1),	-- Unknown or unsupported
+		active(2),
+		failed(3)
+	}
+
+SunFmResourceState ::= TEXTUAL-CONVENTION
+	STATUS	current
+	DESCRIPTION
+		"Represents the status of a system resource as diagnosed
+		by the fault manager."
+	SYNTAX	INTEGER {
+		other(1),	-- Unknown or unsupported
+		ok(2),
+		degraded(3),
+		unknown(4),
+		faulted(5)
+	}
+
+--
+-- The problem table is analogous to the output of fmadm faulty organized
+-- by the UUID of the case in which the faulty diagnosis was made.  The
+-- list of events contributing to this diagnosis is in a separate table
+-- (fmFaultEventTable).  Because SNMP does not allow nested tables, we
+-- indicate here only the number of events contributing to the diagnosis.
+--
+
+sunFmProblemTable OBJECT-TYPE
+	SYNTAX		SEQUENCE OF SunFmProblemEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Table listing all of the known problems that have been
+		diagnosed by the fault manager associated with this managed
+		system element that are still present in that system."
+	::= { sunFmMIB 1 }
+
+sunFmProblemEntry OBJECT-TYPE
+	SYNTAX		SunFmProblemEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"A problem diagnosed by the fault manager and still
+		present in the system."
+	INDEX 		{ sunFmProblemUUIDIndex }
+	::= { sunFmProblemTable 1 }
+
+SunFmProblemEntry ::= SEQUENCE {
+	sunFmProblemUUIDIndex		SunFmUuidString,
+	sunFmProblemUUID		SunFmUuidString,
+	sunFmProblemCode		DisplayString,
+	sunFmProblemURL			URLString,
+	sunFmProblemDiagEngine		URLString,
+	sunFmProblemDiagTime		DateAndTime,
+	sunFmProblemSuspectCount	Gauge32
+}
+
+sunFmProblemUUIDIndex OBJECT-TYPE
+	SYNTAX		SunFmUuidString
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"The Universal Unique Identifier (UUID) for this problem, as
+		recorded by fmd(1M) and shown by fmadm(1M) or fmdump(1M).
+		This is the index into sunFmProblemTable."
+	::= { sunFmProblemEntry 1 }
+
+sunFmProblemUUID OBJECT-TYPE
+	SYNTAX		SunFmUuidString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The Universal Unique Identifier (UUID) for this problem, as
+		recorded by fmd(1M) and shown by fmadm(1M) or fmdump(1M)."
+	::= { sunFmProblemEntry 2 }
+
+sunFmProblemCode OBJECT-TYPE
+	SYNTAX		DisplayString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The SUNW-MSG-ID static message identifier for this class of
+		problem, as recorded by fmd(1M) and shown by fmdump(1M).  The
+		message identifier can be used as a key at http://sun.com/msg/"
+	::= { sunFmProblemEntry 3 }
+
+sunFmProblemURL OBJECT-TYPE
+	SYNTAX		URLString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The URL of an appropriate knowledge article providing more
+		detailed information about this problem."
+	::= { sunFmProblemEntry 4 }
+
+sunFmProblemDiagEngine OBJECT-TYPE
+	SYNTAX		URLString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The Sun FMRI of the Fault Manager diagnosis engine that
+		performed the diagnosis of this problem, including its version."
+	::= { sunFmProblemEntry 5 }
+
+sunFmProblemDiagTime OBJECT-TYPE
+	SYNTAX		DateAndTime
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The date and time at which the problem was diagnosed."
+	::= { sunFmProblemEntry 6 }
+
+sunFmProblemSuspectCount OBJECT-TYPE
+	SYNTAX		Gauge32
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The number of individual suspect defects or faults
+		associated with this problem diagnosis, as shown by
+		fmdump(1M) -v -u <UUID>."
+	::= { sunFmProblemEntry 7 }
+
+--
+-- Events are indexed by the associated problem UUID and an index ranging
+-- from 1 to sunFmProblemEntry.fmProblemSuspectCount.<UUID> for easy retrieval
+-- and reconstruction of the information available via fmdump -v.  A
+-- fault appears once for each diagnosis referencing it.
+--
+
+sunFmFaultEventTable OBJECT-TYPE
+	SYNTAX		SEQUENCE OF SunFmFaultEventEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"List of individual suspect defects or faults associated with
+		a problem diagnosis, as shown by fmdump(1M) -v -u <UUID>."
+	::= { sunFmMIB 2 }
+
+sunFmFaultEventEntry OBJECT-TYPE
+	SYNTAX		SunFmFaultEventEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Sun Fault Management fault or defect event containing a
+		suspect problem and the corresponding FRU and ASRU."
+	INDEX	{ sunFmFaultEventUUIDIndex, sunFmFaultEventIndex }
+	::= { sunFmFaultEventTable 1 }
+
+SunFmFaultEventEntry ::= SEQUENCE {
+	sunFmFaultEventUUIDIndex	SunFmUuidString,
+	sunFmFaultEventIndex		Unsigned32,
+	sunFmFaultEventProblemUUID	SunFmUuidString,
+	sunFmFaultEventClass		DisplayString,
+	sunFmFaultEventCertainty	Gauge32,
+	sunFmFaultEventASRU		URLString,
+	sunFmFaultEventFRU		URLString,
+	sunFmFaultEventResource		URLString
+}
+
+sunFmFaultEventUUIDIndex OBJECT-TYPE
+	SYNTAX		SunFmUuidString
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"UUID of a problem diagnosis with which this event is
+		associated.  An event may appear multiple times in association
+		with different diagnoses.  This is an index into
+		sunFmFaultEventTable."
+	::= { sunFmFaultEventEntry 1 }
+
+sunFmFaultEventIndex OBJECT-TYPE
+	SYNTAX		Unsigned32
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Index number of this event with respect to the problem
+		diagnosis."
+	::= { sunFmFaultEventEntry 2 }
+
+sunFmFaultEventProblemUUID OBJECT-TYPE
+	SYNTAX		SunFmUuidString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"UUID of a problem diagnosis with which this event is
+		associated.  An event may appear multiple times in association
+		with different diagnoses."
+	::= { sunFmFaultEventEntry 3 }
+
+sunFmFaultEventClass OBJECT-TYPE
+	SYNTAX		DisplayString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Sun Fault Management event class string."
+	::= { sunFmFaultEventEntry 4 }
+
+sunFmFaultEventCertainty OBJECT-TYPE
+	SYNTAX		Gauge32 (0..100)
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Percentage likelihood associated with this suspect for
+		this diagnosis."
+	::= { sunFmFaultEventEntry 5 }
+
+sunFmFaultEventASRU OBJECT-TYPE
+	SYNTAX		URLString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Sun FMRI of the Automated System Reconfiguration Unit (ASRU)
+		that is believed to contain the specified fault or defect."
+	::= { sunFmFaultEventEntry 6 }
+
+sunFmFaultEventFRU OBJECT-TYPE
+	SYNTAX		URLString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Sun FMRI of the Field Replaceable Unit (FRU) that should be
+		replaced in order to repair the specified fault or defect."
+	::= { sunFmFaultEventEntry 7 }
+
+sunFmFaultEventResource OBJECT-TYPE
+	SYNTAX		URLString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Sun FMRI of the resource responsible for the generation of
+		the telemetry leading to the diagnosis."
+	::= { sunFmFaultEventEntry 8 }
+
+--
+-- sunFmModuleTable provides fmd configuration information equivalent to
+-- the output of fmadm config.
+--
+
+sunFmModuleTable OBJECT-TYPE
+	SYNTAX		SEQUENCE OF SunFmModuleEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"List of modules configured in fmd(1M)."
+	::= { sunFmMIB 3 }
+
+sunFmModuleEntry OBJECT-TYPE
+	SYNTAX		SunFmModuleEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"A module which has been loaded into fmd(1M) to handle events.
+		The information provided is equivalent to the output of
+		fmadm(1) config'"
+	INDEX	{ sunFmModuleIndex }
+	::= { sunFmModuleTable 1 }
+
+SunFmModuleEntry ::= SEQUENCE {
+	sunFmModuleIndex		Unsigned32,
+	sunFmModuleName			DisplayString,
+	sunFmModuleVersion		DisplayString,
+	sunFmModuleStatus		SunFmModuleState,
+	sunFmModuleDescription		DisplayString
+}
+
+sunFmModuleIndex OBJECT-TYPE
+	SYNTAX		Unsigned32
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Unique integer index associated with this fault management
+		module's entry."
+	::= { sunFmModuleEntry 1 }
+
+sunFmModuleName OBJECT-TYPE
+	SYNTAX		DisplayString (SIZE(0..64))
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Name of the fault management module."
+	::= { sunFmModuleEntry 2 }
+
+sunFmModuleVersion OBJECT-TYPE
+	SYNTAX		DisplayString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Version string associated with the fault management module."
+	::= { sunFmModuleEntry 3 }
+
+sunFmModuleStatus OBJECT-TYPE
+	SYNTAX		SunFmModuleState
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Current status of the fault management module."
+	::= { sunFmModuleEntry 4 }
+
+sunFmModuleDescription OBJECT-TYPE
+	SYNTAX		DisplayString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"A text description of the fault management module."
+	::= { sunFmModuleEntry 5 }
+
+sunFmResourceCount OBJECT-TYPE
+	SYNTAX		Gauge32
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The number of managed elements currently believed by
+		the fault manager to be faulty."
+	::= { sunFmMIB 4 }
+
+sunFmResourceTable OBJECT-TYPE
+	SYNTAX		SEQUENCE OF SunFmResourceEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"A table containing information about all resources for which
+		the fault manager has received telemetry.  This is the same
+		information provided by the fmadm(1M) faulty command."
+	::= { sunFmMIB 5 }
+
+sunFmResourceEntry OBJECT-TYPE
+	SYNTAX		SunFmResourceEntry
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Information about the state of a resource the fault manager
+		believes to be faulty."
+	INDEX		{ sunFmResourceIndex }
+	::= { sunFmResourceTable 1 }
+
+SunFmResourceEntry ::= SEQUENCE {
+	sunFmResourceIndex		Unsigned32,
+	sunFmResourceFMRI		DisplayString,
+	sunFmResourceStatus		SunFmResourceState,
+	sunFmResourceDiagnosisUUID	SunFmUuidString
+}
+
+sunFmResourceIndex OBJECT-TYPE
+	SYNTAX		Unsigned32
+	MAX-ACCESS	not-accessible
+	STATUS		current
+	DESCRIPTION
+		"Index of the resource in the resource table."
+	::= { sunFmResourceEntry 1 }
+
+sunFmResourceFMRI OBJECT-TYPE
+	SYNTAX		DisplayString (SIZE(0..255))
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"Sun FMRI of the Automated System Reconfiguration Unit (ASRU)
+		which the fault manager believes to be faulty."
+	::= { sunFmResourceEntry 2 }
+
+sunFmResourceStatus OBJECT-TYPE
+	SYNTAX		SunFmResourceState
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The current status of the resource.  See fmadm(1M) faulty."
+	::= { sunFmResourceEntry 3 }
+
+sunFmResourceDiagnosisUUID OBJECT-TYPE
+	SYNTAX		SunFmUuidString
+	MAX-ACCESS	read-only
+	STATUS		current
+	DESCRIPTION
+		"The Universal Unique Identifier (UUID) for the problem
+		associated with the fault in this resource, as recorded by
+		fmd(1M) and shown by fmadm(1M)."
+	::= { sunFmResourceEntry 4 }
+
+sunFmObjectGroups OBJECT IDENTIFIER ::= { sunFmMIB 6 }
+
+sunFmObjectGroup OBJECT-GROUP OBJECTS {
+		sunFmProblemUUID,
+		sunFmProblemCode,
+		sunFmProblemURL,
+		sunFmProblemDiagEngine,
+		sunFmProblemDiagTime,
+		sunFmProblemSuspectCount,
+		sunFmFaultEventProblemUUID,
+		sunFmFaultEventClass,
+		sunFmFaultEventCertainty,
+		sunFmFaultEventASRU,
+		sunFmFaultEventFRU,
+		sunFmFaultEventResource,
+		sunFmModuleName,
+		sunFmModuleVersion,
+		sunFmModuleStatus,
+		sunFmModuleDescription,
+		sunFmResourceCount,
+		sunFmResourceFMRI,
+		sunFmResourceStatus,
+		sunFmResourceDiagnosisUUID
+	}
+	STATUS	current
+	DESCRIPTION
+		"A collection of objects providing access to Sun Fault
+		Manager operational data."
+	::= { sunFmObjectGroups 1 }
+	
+
+--
+-- RFC 3584 requires that the next-to-last sub-ID be zero to allow for
+-- mapping v2/v3 notifications to v1 traps.
+--
+
+sunFmTraps OBJECT IDENTIFIER ::= { sunFmMIB 7 0 }
+
+sunFmProblemTrap NOTIFICATION-TYPE
+	OBJECTS	{
+		sunFmProblemUUID,
+		sunFmProblemCode,
+		sunFmProblemURL
+	}
+	STATUS	current
+	DESCRIPTION
+		"Trap notification that a diagnosis has been made or the
+		fault manager fmd(1M) has restarted and the corresponding
+		problem is still believed to be present in the managed entity."
+	::= { sunFmTraps 1 }
+
+sunFmNotificationGroup NOTIFICATION-GROUP NOTIFICATIONS {
+		sunFmProblemTrap
+	}
+	STATUS	current
+	DESCRIPTION
+		"A collection of notifications provided by the Sun Fault
+		Manager."
+	::= { sunFmObjectGroups 2 }
+
+END
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MAPDIR = ../spec/sparc
+MACH_LDLIBS = -L$(ROOT)/usr/lib/fm
+
+include ../Makefile.com
+
+DYNFLAGS += -R/usr/lib/fm
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+MAPDIR = ../spec/sparcv9
+MACH_LDLIBS = -L$(ROOT)/usr/lib/fm/$(MACH64)
+
+include ../Makefile.com
+include ../../../Makefile.lib.64
+
+DYNFLAGS += -R/usr/lib/fm/$(MACH64)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,29 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include $(SRC)/lib/Makefile.spec.arch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/Makefile.targ	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,33 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+.KEEP_STATE:
+
+LIBRARY	= libfmd_snmp.a
+VERS	= .1 
+OBJECTS = fmd_snmp.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/amd64/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+# To enable apptrace, comment out the next line
+DISABLE_APPTRACE=	$(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/fmd_snmp.spec	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,80 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+function	init_sunFM
+version		SUNWprivate
+end
+
+function	fmd_fmri_alloc
+version		SUNWprivate
+end
+
+function	fmd_fmri_zalloc
+version		SUNWprivate
+end
+
+function	fmd_fmri_free
+version		SUNWprivate
+end
+
+function	fmd_fmri_error
+version		SUNWprivate
+end
+
+function	fmd_fmri_strescape
+version		SUNWprivate
+end
+
+function	fmd_fmri_strdup
+version		SUNWprivate
+end
+
+function	fmd_fmri_strfree
+version		SUNWprivate
+end
+
+function	fmd_fmri_get_rootdir
+version		SUNWprivate
+end
+
+function	fmd_fmri_get_platform
+version		SUNWprivate
+end
+
+function	fmd_fmri_get_drgen
+version		SUNWprivate
+end
+
+function	fmd_fmri_set_errno
+version		SUNWprivate
+end
+
+function	fmd_fmri_warn
+version		SUNWprivate
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/i386/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+# To enable apptrace, comment out the next line
+DISABLE_APPTRACE=	$(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/sparc/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,36 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+# To enable apptrace, comment out the next line
+DISABLE_APPTRACE=   $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/sparcv9/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,37 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+# To enable apptrace, comment out the next line
+DISABLE_APPTRACE=   $(POUND_SIGN)
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
+
+$(DISABLE_APPTRACE)install: $(ROOTABILIB64)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/fm/libfmd_snmp/spec/versions	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,43 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+i386 {
+	SUNWprivate;
+}
+
+amd64 {
+	SUNWprivate;
+}
+
+sparc {
+	SUNWprivate;
+}
+
+sparcv9 {
+	SUNWprivate;
+}
--- a/usr/src/pkgdefs/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -172,6 +172,7 @@
 	SUNWdtrp \
 	SUNWesu  \
 	SUNWfmd  \
+	SUNWfmdr  \
 	SUNWfss \
 	SUNWftdur \
 	SUNWftduu \
--- a/usr/src/pkgdefs/SUNWckr/prototype_com	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/SUNWckr/prototype_com	Fri Jan 20 16:06:55 2006 -0800
@@ -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,12 +18,15 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
+
+#
 # This required package information file contains a list of package contents.
 # The 'pkgmk' command uses this file to identify the contents of a package
 # and their location on the development machine when building the package.
@@ -55,8 +57,6 @@
 d none etc 755 root sys
 d none etc/crypto 755 root sys
 e kcfconfbase etc/crypto/kcf.conf 644 root sys
-d none etc/fm 755 root sys
-d none etc/fm/fmd 755 root sys
 e renameold etc/name_to_sysnum 644 root sys
 e etcsystem etc/system 644 root sys
 d none kernel 755 root sys
@@ -130,11 +130,6 @@
 f none lib/svc/method/svc-intrd 0555 root bin
 f none lib/svc/method/svc-scheduler 0555 root bin
 d none var 755 root sys
-d none var/fm 755 root sys
-d none var/fm/fmd 755 root sys
-d none var/fm/fmd/ckpt 700 root sys
-d none var/fm/fmd/rsrc 700 root sys
-d none var/fm/fmd/xprt 700 root sys
 d none var/svc 755 root sys
 d none var/svc/manifest 755 root sys
 d none var/svc/manifest/system 755 root sys
--- a/usr/src/pkgdefs/SUNWfmd/Makefile	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/SUNWfmd/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -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,16 +18,16 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 include ../Makefile.com
 
-DATAFILES += depend
-
 .KEEP_STATE:
 
 all: $(FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmd/depend	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,38 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWcakr	Core Solaris Kernel Architecture (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWckr	Core Solaris Kernel (Root)
+P SUNWcnetr	Core Solaris Network Infrastructure (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries
+P SUNWfmdr	Fault Management Daemon and Utilities (Root)
--- a/usr/src/pkgdefs/SUNWfmd/prototype_com	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_com	Fri Jan 20 16:06:55 2006 -0800
@@ -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,12 +18,14 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
 #
+
 i pkginfo
 i copyright
 i depend
@@ -39,6 +40,7 @@
 f none usr/include/fm/fmd_api.h 644 root bin
 f none usr/include/fm/fmd_fmri.h 644 root bin
 f none usr/include/fm/fmd_log.h 644 root bin
+f none usr/include/fm/fmd_snmp.h 644 root bin
 f none usr/include/fm/libtopo.h 644 root bin
 f none usr/include/fm/libtopo_enum.h 644 root bin
 d none usr/lib 755 root bin
@@ -64,6 +66,8 @@
 f none usr/lib/fm/fmd/plugins/io-retire.so 555 root bin
 f none usr/lib/fm/fmd/plugins/ip-transport.so 555 root bin
 f none usr/lib/fm/fmd/plugins/ip-transport.conf 644 root bin
+f none usr/lib/fm/fmd/plugins/snmp-trapgen.conf 644 root bin
+f none usr/lib/fm/fmd/plugins/snmp-trapgen.so 555 root bin
 f none usr/lib/fm/fmd/plugins/syslog-msgs.conf 644 root bin
 f none usr/lib/fm/fmd/plugins/syslog-msgs.so 555 root bin
 d none usr/lib/fm/fmd/schemes 755 root bin
@@ -86,6 +90,10 @@
 s none usr/lib/fm/libfmd_log.so=libfmd_log.so.1
 f none usr/lib/fm/llib-lfmd_log 644 root bin
 f none usr/lib/fm/llib-lfmd_log.ln 644 root bin
+f none usr/lib/fm/libfmd_snmp.so.1 755 root bin
+s none usr/lib/fm/libfmd_snmp.so=libfmd_snmp.so.1
+f none usr/lib/fm/llib-lfmd_snmp 644 root bin
+f none usr/lib/fm/llib-lfmd_snmp.ln 644 root bin
 f none usr/lib/fm/libtopo.so.1 755 root bin
 s none usr/lib/fm/libtopo.so=libtopo.so.1
 f none usr/lib/fm/llib-ltopo 644 root bin
--- a/usr/src/pkgdefs/SUNWfmd/prototype_i386	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_i386	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,13 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 #
 # Include ISA independent files (prototype_com)
@@ -44,9 +45,20 @@
 s none usr/lib/fm/amd64/libfmd_adm.so=./libfmd_adm.so.1
 f none usr/lib/fm/amd64/libfmd_log.so.1 755 root bin
 s none usr/lib/fm/amd64/libfmd_log.so=./libfmd_log.so.1
+f none usr/lib/fm/amd64/libfmd_snmp.so.1 755 root bin
+s none usr/lib/fm/amd64/libfmd_snmp.so=./libfmd_snmp.so.1
 f none usr/lib/fm/amd64/libtopo.so.1 755 root bin
 s none usr/lib/fm/amd64/libtopo.so=libtopo.so.1
 f none usr/lib/fm/amd64/llib-ldiagcode.ln 644 root bin
 f none usr/lib/fm/amd64/llib-lfmd_adm.ln 644 root bin
 f none usr/lib/fm/amd64/llib-lfmd_log.ln 644 root bin
+f none usr/lib/fm/amd64/llib-lfmd_snmp.ln 644 root bin
 f none usr/lib/fm/amd64/llib-ltopo.ln 644 root bin
+d none usr/lib/fm/fmd/schemes/amd64 755 root bin
+f none usr/lib/fm/fmd/schemes/amd64/cpu.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/dev.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/fmd.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/hc.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/legacy-hc.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/mod.so 555 root bin
+f none usr/lib/fm/fmd/schemes/amd64/pkg.so 555 root bin
--- a/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_sparc	Fri Jan 20 16:06:55 2006 -0800
@@ -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,11 +18,13 @@
 #
 # CDDL HEADER END
 #
+
 #
 # Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-#ident	"%Z%%M%	%I%	%E% SMI"
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
 
 !include prototype_com
 
@@ -35,6 +36,15 @@
 s none usr/lib/fm/libmdesc.so=libmdesc.so.1 755 root bin
 f none usr/lib/fm/llib-lmdesc 644 root bin
 f none usr/lib/fm/llib-lmdesc.ln 644 root bin
+d none usr/lib/fm/fmd/schemes/sparcv9 755 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/cpu.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/dev.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/fmd.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/hc.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/legacy-hc.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/mem.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/mod.so 555 root bin
+f none usr/lib/fm/fmd/schemes/sparcv9/pkg.so 555 root bin
 d none usr/lib/fm/sparcv9 755 root bin
 f none usr/lib/fm/sparcv9/libdiagcode.so.1 755 root bin
 s none usr/lib/fm/sparcv9/libdiagcode.so=libdiagcode.so.1
@@ -48,6 +58,9 @@
 f none usr/lib/fm/sparcv9/libmdesc.so.1 755 root bin
 s none usr/lib/fm/sparcv9/libmdesc.so=libmdesc.so.1 755 root bin
 f none usr/lib/fm/sparcv9/llib-lmdesc.ln 644 root bin
+f none usr/lib/fm/sparcv9/libfmd_snmp.so.1 755 root bin
+s none usr/lib/fm/sparcv9/libfmd_snmp.so=libfmd_snmp.so.1
+f none usr/lib/fm/sparcv9/llib-lfmd_snmp.ln 644 root bin
 f none usr/lib/fm/sparcv9/libtopo.so.1 755 root bin
 s none usr/lib/fm/sparcv9/libtopo.so=libtopo.so.1
 f none usr/lib/fm/sparcv9/llib-ltopo.ln 644 root bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmdr/Makefile	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,39 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES += depend
+
+.KEEP_STATE:
+
+all: $(FILES)
+
+install: all pkg
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmdr/pkginfo.tmpl	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,53 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+PKG="SUNWfmdr"
+NAME="Fault Management Daemon and Utilities (Root)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Fault Management Daemon and Utilities (Root)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmdr/prototype_com	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,47 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+i pkginfo
+i copyright
+i depend
+#
+# SUNWfmdr
+#
+d none etc 755 root sys
+d none etc/fm 755 root sys
+d none etc/fm/fmd 755 root sys
+d none etc/sma 755 root bin
+d none etc/sma/snmp 755 root bin
+f none etc/sma/snmp/fmd-trapgen.conf 600 root bin
+d none etc/sma/snmp/mibs 755 root bin
+f none etc/sma/snmp/mibs/SUN-FM-MIB.mib 644 root bin
+d none var/fm 755 root sys
+d none var/fm/fmd 755 root sys
+d none var/fm/fmd/ckpt 700 root sys
+d none var/fm/fmd/rsrc 700 root sys
+d none var/fm/fmd/xprt 700 root sys
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmdr/prototype_i386	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,40 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+# SUNWfmdr
+#
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWfmdr/prototype_sparc	Fri Jan 20 16:06:55 2006 -0800
@@ -0,0 +1,30 @@
+#
+# 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 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# ident	"%Z%%M%	%I%	%E% SMI"
+#
+
+!include prototype_com
+
--- a/usr/src/tools/scripts/check_rtime.pl	Fri Jan 20 11:54:53 2006 -0800
+++ b/usr/src/tools/scripts/check_rtime.pl	Fri Jan 20 16:06:55 2006 -0800
@@ -3,9 +3,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,15 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
+
+#
 # Check ELF information.
 #
 # This script descends a directory hierarchy inspecting ELF dynamic executables
@@ -210,7 +212,10 @@
 	libfrupicl\.so\.1;\ unused\ object=.*libdl\.so\.1 |
 	libmapmalloc\.so\.1;\ unused |
 	unused\ dependency\ of\ .*libstdc\+\+\.so\.6 |
-	unreferenced\ object=.*libstdc\+\+\.so\.6
+	unreferenced\ object=.*libstdc\+\+\.so\.6 |
+	unused\ dependency\ of\ .*libnetsnmphelpers\.so\.5 |
+	unused\ dependency\ of\ .*libnetsnmpmibs\.so\.5 |
+	unused\ dependency\ of\ .*libnetsnmpagent\.so\.5
 }x;
 
 # Define interpreters we should ignore.