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]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <fm/libtopo.h>
26 #include <sys/fm/util.h>
27 #include <sys/types.h>
29 #include <sys/errno.h>
34 #include <libxml/xpathInternals.h>
36 #include "fabric-xlate.h"
38 #define XMLTOPOFILE "/var/run/fab-xlate-topo.xml"
40 fmd_xprt_t
*fab_fmd_xprt
; /* FMD transport layer handle */
41 char fab_buf
[FM_MAX_CLASS
];
43 /* Static FM Topo XML Format and XML XPath Context */
44 static xmlDocPtr fab_doc
= NULL
;
45 xmlXPathContextPtr fab_xpathCtx
= NULL
;
46 static int fab_valid_topo
= 0;
47 static pthread_mutex_t fab_lock
= PTHREAD_MUTEX_INITIALIZER
;
50 fab_update_topo(fmd_hdl_t
*hdl
)
52 topo_hdl_t
*thp
= NULL
;
57 /* Open the temporary file with proper ownership */
59 if ((unlink(XMLTOPOFILE
) == -1) && (errno
!= ENOENT
)) {
60 fmd_hdl_debug(hdl
, "Failed to remove XML topo file\n");
63 fd
= open(XMLTOPOFILE
, O_RDWR
| O_CREAT
| O_EXCL
, 0600);
64 if ((fd
== -1) && (errno
!= EEXIST
)) {
65 fmd_hdl_debug(hdl
, "Failed to create XML topo file\n");
70 /* Associate a stream with the temporary file */
71 if ((fp
= fdopen(fd
, "w")) == NULL
) {
72 fmd_hdl_debug(hdl
, "Failed to open XML topo file\n");
77 if ((thp
= fmd_hdl_topo_hold(hdl
, TOPO_VERSION
)) == NULL
) {
78 fmd_hdl_debug(hdl
, "Failed to hold topo\n");
82 /* Print topology to XML file */
83 if (topo_xml_print(thp
, fp
, FM_FMRI_SCHEME_HC
, &err
) < 0) {
84 fmd_hdl_debug(hdl
, "Failed to get XML topo\n");
85 fmd_hdl_topo_rele(hdl
, thp
);
89 /* Release topology */
90 fmd_hdl_topo_rele(hdl
, thp
);
92 /* Reload topology from XML file */
94 xmlXPathFreeContext(fab_xpathCtx
);
97 fab_doc
= xmlParseFile(XMLTOPOFILE
);
98 fab_xpathCtx
= xmlXPathNewContext(fab_doc
);
107 (void) unlink(XMLTOPOFILE
);
112 fab_recv(fmd_hdl_t
*hdl
, fmd_event_t
*ep
, nvlist_t
*nvl
, const char *class)
116 (void) pthread_mutex_lock(&fab_lock
);
118 fab_update_topo(hdl
);
119 (void) pthread_mutex_unlock(&fab_lock
);
121 if (nvlist_dup(nvl
, &new_nvl
, NV_UNIQUE_NAME
) != 0) {
122 fmd_hdl_error(hdl
, "failed to duplicate event");
126 if (fmd_nvl_class_match(hdl
, new_nvl
, "ereport.io.pci.fabric")) {
127 fab_xlate_fabric_erpts(hdl
, new_nvl
, class);
129 fab_pr(hdl
, ep
, new_nvl
);
130 if (fmd_nvl_class_match(hdl
, new_nvl
,
131 "ereport.io.pciex.rc.epkt")) {
132 fab_xlate_epkt_erpts(hdl
, new_nvl
, class);
134 fab_xlate_fire_erpts(hdl
, new_nvl
, class);
138 nvlist_free(new_nvl
);
143 fab_topo(fmd_hdl_t
*hdl
, topo_hdl_t
*topo
)
145 (void) pthread_mutex_lock(&fab_lock
);
147 (void) pthread_mutex_unlock(&fab_lock
);
150 static const fmd_hdl_ops_t fmd_ops
= {
151 fab_recv
, /* fmdo_recv */
152 NULL
, /* fmdo_timeout */
153 NULL
, /* fmdo_close */
154 NULL
, /* fmdo_stats */
156 NULL
, /* fmdo_send */
157 fab_topo
, /* fmdo_topo */
160 static const fmd_hdl_info_t fmd_info
= {
161 "Fabric Ereport Translater", "1.0", &fmd_ops
, NULL
165 _fmd_init(fmd_hdl_t
*hdl
)
167 if (fmd_hdl_register(hdl
, FMD_API_VERSION
, &fmd_info
) != 0)
173 fab_fmd_xprt
= fmd_xprt_open(hdl
, FMD_XPRT_RDONLY
, NULL
, NULL
);
174 fmd_hdl_debug(hdl
, "Fabric Translater Started\n");
176 fab_setup_master_table();
180 _fmd_fini(fmd_hdl_t
*hdl
)
184 xmlXPathFreeContext(fab_xpathCtx
);
185 /* Free xml document */
191 fmd_xprt_close(hdl
, fab_fmd_xprt
);