summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fm/fmd/common/fmd_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/fm/fmd/common/fmd_module.c')
-rw-r--r--usr/src/cmd/fm/fmd/common/fmd_module.c64
1 files changed, 60 insertions, 4 deletions
diff --git a/usr/src/cmd/fm/fmd/common/fmd_module.c b/usr/src/cmd/fm/fmd/common/fmd_module.c
index c0e52a4b59..ad72e3c9ce 100644
--- a/usr/src/cmd/fm/fmd/common/fmd_module.c
+++ b/usr/src/cmd/fm/fmd/common/fmd_module.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,6 +49,7 @@
#include <fmd_buf.h>
#include <fmd_ckpt.h>
#include <fmd_xprt.h>
+#include <fmd_topo.h>
#include <fmd.h>
@@ -208,6 +208,8 @@ fmd_module_create(const char *path, const fmd_modops_t *ops)
fmd_buf_hash_create(&mp->mod_bufs);
fmd_serd_hash_create(&mp->mod_serds);
+ mp->mod_topo_current = fmd_topo_hold();
+
(void) pthread_mutex_lock(&fmd.d_mod_lock);
fmd_list_append(&fmd.d_mod_list, mp);
(void) pthread_mutex_unlock(&fmd.d_mod_lock);
@@ -337,6 +339,8 @@ fmd_module_untimeout(fmd_idspace_t *ids, id_t id, fmd_module_t *mp)
void
fmd_module_unload(fmd_module_t *mp)
{
+ fmd_modtopo_t *mtp;
+
(void) pthread_mutex_lock(&mp->mod_lock);
if (mp->mod_flags & FMD_MOD_QUIT) {
@@ -386,6 +390,12 @@ fmd_module_unload(fmd_module_t *mp)
(void) fmd_buf_hash_destroy(&mp->mod_bufs);
fmd_serd_hash_destroy(&mp->mod_serds);
+ while ((mtp = fmd_list_next(&mp->mod_topolist)) != NULL) {
+ fmd_list_delete(&mp->mod_topolist, mtp);
+ fmd_topo_rele(mtp->mt_topo);
+ fmd_free(mtp, sizeof (fmd_modtopo_t));
+ }
+
fmd_module_unlock(mp);
fmd_dprintf(FMD_DBG_MOD, "unloaded module %s\n", mp->mod_name);
}
@@ -416,6 +426,9 @@ fmd_module_destroy(fmd_module_t *mp)
fmd_list_delete(&fmd.d_mod_list, mp);
(void) pthread_mutex_unlock(&fmd.d_mod_lock);
+ if (mp->mod_topo_current != NULL)
+ fmd_topo_rele(mp->mod_topo_current);
+
/*
* Once the module is no longer processing events and no longer visible
* through any program data structures, we can free all of its content.
@@ -548,6 +561,12 @@ fmd_module_dispatch(fmd_module_t *mp, fmd_event_t *e)
case FMD_EVT_PUBLISH:
fmd_case_publish(ep->ev_data, FMD_CASE_CURRENT);
break;
+ case FMD_EVT_TOPO:
+ fmd_topo_rele(mp->mod_topo_current);
+ mp->mod_topo_current = (fmd_topo_t *)ep->ev_data;
+ fmd_topo_addref(mp->mod_topo_current);
+ ops->fmdo_topo(hdl, mp->mod_topo_current->ft_hdl);
+ break;
}
}
@@ -1311,3 +1330,40 @@ fmd_modstat_snapshot(fmd_module_t *mp, fmd_ustat_snap_t *uss)
return (err);
}
+
+struct topo_hdl *
+fmd_module_topo_hold(fmd_module_t *mp)
+{
+ fmd_modtopo_t *mtp;
+
+ ASSERT(fmd_module_locked(mp));
+
+ mtp = fmd_zalloc(sizeof (fmd_modtopo_t), FMD_SLEEP);
+ mtp->mt_topo = mp->mod_topo_current;
+ fmd_topo_addref(mtp->mt_topo);
+ fmd_list_prepend(&mp->mod_topolist, mtp);
+
+ return (mtp->mt_topo->ft_hdl);
+}
+
+int
+fmd_module_topo_rele(fmd_module_t *mp, struct topo_hdl *hdl)
+{
+ fmd_modtopo_t *mtp;
+
+ ASSERT(fmd_module_locked(mp));
+
+ for (mtp = fmd_list_next(&mp->mod_topolist); mtp != NULL;
+ mtp = fmd_list_next(mtp)) {
+ if (mtp->mt_topo->ft_hdl == hdl)
+ break;
+ }
+
+ if (mtp == NULL)
+ return (-1);
+
+ fmd_list_delete(&mp->mod_topolist, mtp);
+ fmd_topo_rele(mtp->mt_topo);
+ fmd_free(mtp, sizeof (fmd_modtopo_t));
+ return (0);
+}