4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
26 * FMD Topology Handling
28 * Fault manager scheme and module plug-ins may need access to the latest
29 * libtopo snapshot. Upon fmd initialization, a snapshot is taken and
30 * made available via fmd_fmri_topology() and fmd_hdl_topology(). Each
31 * of these routines returns a libtopo snapshot handle back to the caller.
32 * New snapshots are taken if and when a DR event causes the DR generation
33 * number to increase. The current snapshot is retained to assure consistency
34 * for modules still using older snapshots and the latest snapshot handle is
35 * returned to the caller.
38 #include <fmd_alloc.h>
39 #include <fmd_error.h>
46 #include <sys/types.h>
47 #include <fm/fmd_fmri.h>
48 #include <fm/libtopo.h>
51 fmd_topo_rele_locked(fmd_topo_t
*ftp
)
53 ASSERT(MUTEX_HELD(&fmd
.d_topo_lock
));
55 if (--ftp
->ft_refcount
== 0) {
56 fmd_list_delete(&fmd
.d_topo_list
, ftp
);
57 topo_close(ftp
->ft_hdl
);
58 fmd_free(ftp
, sizeof (fmd_topo_t
));
67 fmd_topo_t
*ftp
, *prev
;
71 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
73 fmd
.d_stats
->ds_topo_drgen
.fmds_value
.ui64
= fmd_fmri_get_drgen();
75 name
= fmd
.d_rootdir
!= NULL
&&
76 *fmd
.d_rootdir
!= '\0' ? fmd
.d_rootdir
: NULL
;
79 * Update the topology snapshot.
81 if ((tp
= topo_open(TOPO_VERSION
, name
, &err
)) == NULL
)
82 fmd_panic("failed to open topology library: %s",
85 ftp
= fmd_alloc(sizeof (fmd_topo_t
), FMD_SLEEP
);
87 ftp
->ft_time_begin
= fmd_time_gethrtime();
89 if ((id
= topo_snap_hold(tp
, NULL
, &err
)) == NULL
)
90 fmd_panic("failed to get topology snapshot: %s",
93 topo_hdl_strfree(tp
, id
);
95 ftp
->ft_time_end
= fmd_time_gethrtime();
96 fmd
.d_stats
->ds_topo_gen
.fmds_value
.ui64
++;
99 * We always keep a reference count on the last topo snapshot taken.
100 * Release the previous snapshot (if present), and set the current
101 * reference count to 1.
103 if ((prev
= fmd_list_next(&fmd
.d_topo_list
)) != NULL
)
104 fmd_topo_rele_locked(prev
);
105 ftp
->ft_refcount
= 1;
106 fmd_list_prepend(&fmd
.d_topo_list
, ftp
);
108 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);
116 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
117 ftp
= fmd_list_next(&fmd
.d_topo_list
);
119 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);
125 fmd_topo_addref(fmd_topo_t
*ftp
)
127 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
129 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);
133 fmd_topo_rele(fmd_topo_t
*ftp
)
135 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
137 fmd_topo_rele_locked(ftp
);
139 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);
143 fmd_topo_rele_hdl(topo_hdl_t
*thp
)
147 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
148 for (ftp
= fmd_list_next(&fmd
.d_topo_list
); ftp
!= NULL
;
149 ftp
= fmd_list_next(ftp
)) {
150 if (ftp
->ft_hdl
== thp
)
155 fmd_topo_rele_locked(ftp
);
156 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);
170 (void) pthread_mutex_lock(&fmd
.d_topo_lock
);
171 while ((ftp
= fmd_list_next(&fmd
.d_topo_list
)) != NULL
) {
172 fmd_list_delete(&fmd
.d_topo_list
, ftp
);
173 topo_close(ftp
->ft_hdl
);
174 fmd_free(ftp
, sizeof (fmd_topo_t
));
176 (void) pthread_mutex_unlock(&fmd
.d_topo_lock
);