xref: /titanic_52/usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.c (revision 6bc688af4fb132e30e3dcc0243a24d232b5a3eba)
1eae2e508Skrishnae /*
2eae2e508Skrishnae  * CDDL HEADER START
3eae2e508Skrishnae  *
4eae2e508Skrishnae  * The contents of this file are subject to the terms of the
5eae2e508Skrishnae  * Common Development and Distribution License (the "License").
6eae2e508Skrishnae  * You may not use this file except in compliance with the License.
7eae2e508Skrishnae  *
8eae2e508Skrishnae  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9eae2e508Skrishnae  * or http://www.opensolaris.org/os/licensing.
10eae2e508Skrishnae  * See the License for the specific language governing permissions
11eae2e508Skrishnae  * and limitations under the License.
12eae2e508Skrishnae  *
13eae2e508Skrishnae  * When distributing Covered Code, include this CDDL HEADER in each
14eae2e508Skrishnae  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eae2e508Skrishnae  * If applicable, add the following below this CDDL HEADER, with the
16eae2e508Skrishnae  * fields enclosed by brackets "[]" replaced with your own identifying
17eae2e508Skrishnae  * information: Portions Copyright [yyyy] [name of copyright owner]
18eae2e508Skrishnae  *
19eae2e508Skrishnae  * CDDL HEADER END
20eae2e508Skrishnae  */
21eae2e508Skrishnae 
22eae2e508Skrishnae /*
23*6bc688afSScott M. Carter  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24eae2e508Skrishnae  */
25eae2e508Skrishnae #include <fm/libtopo.h>
26eae2e508Skrishnae #include <sys/fm/util.h>
27*6bc688afSScott M. Carter #include <sys/types.h>
28*6bc688afSScott M. Carter #include <sys/stat.h>
29*6bc688afSScott M. Carter #include <sys/errno.h>
30*6bc688afSScott M. Carter #include <fcntl.h>
31*6bc688afSScott M. Carter #include <unistd.h>
32*6bc688afSScott M. Carter #include <pthread.h>
33eae2e508Skrishnae 
34eae2e508Skrishnae #include <libxml/xpathInternals.h>
35eae2e508Skrishnae 
364df55fdeSJanie Lu #include "fabric-xlate.h"
37eae2e508Skrishnae 
38*6bc688afSScott M. Carter #define	XMLTOPOFILE "/var/run/fab-xlate-topo.xml"
39eae2e508Skrishnae 
404df55fdeSJanie Lu fmd_xprt_t *fab_fmd_xprt;	/* FMD transport layer handle */
414df55fdeSJanie Lu char fab_buf[FM_MAX_CLASS];
42eae2e508Skrishnae 
43eae2e508Skrishnae /* Static FM Topo XML Format and XML XPath Context  */
44eae2e508Skrishnae static xmlDocPtr	fab_doc = NULL;
454df55fdeSJanie Lu xmlXPathContextPtr	fab_xpathCtx = NULL;
46eae2e508Skrishnae static int		fab_valid_topo = 0;
47*6bc688afSScott M. Carter static pthread_mutex_t	fab_lock = PTHREAD_MUTEX_INITIALIZER;
48eae2e508Skrishnae 
49eae2e508Skrishnae static void
50eae2e508Skrishnae fab_update_topo(fmd_hdl_t *hdl)
51eae2e508Skrishnae {
52eae2e508Skrishnae 	topo_hdl_t	*thp = NULL;
53*6bc688afSScott M. Carter 	FILE		*fp = NULL;
54eae2e508Skrishnae 	int		err = 0;
55*6bc688afSScott M. Carter 	int		fd = -1;
56eae2e508Skrishnae 
57*6bc688afSScott M. Carter 	/* Open the temporary file with proper ownership */
58*6bc688afSScott M. Carter 	while (fd == -1) {
59*6bc688afSScott M. Carter 		if ((unlink(XMLTOPOFILE) == -1) && (errno != ENOENT)) {
60*6bc688afSScott M. Carter 			fmd_hdl_debug(hdl, "Failed to remove XML topo file\n");
61*6bc688afSScott M. Carter 			return;
62*6bc688afSScott M. Carter 		}
63*6bc688afSScott M. Carter 		fd = open(XMLTOPOFILE, O_RDWR | O_CREAT | O_EXCL, 0600);
64*6bc688afSScott M. Carter 		if ((fd == -1) && (errno != EEXIST)) {
65*6bc688afSScott M. Carter 			fmd_hdl_debug(hdl, "Failed to create XML topo file\n");
66*6bc688afSScott M. Carter 			return;
67*6bc688afSScott M. Carter 		}
68*6bc688afSScott M. Carter 	}
69*6bc688afSScott M. Carter 
70*6bc688afSScott M. Carter 	/* Associate a stream with the temporary file */
71*6bc688afSScott M. Carter 	if ((fp = fdopen(fd, "w")) == NULL) {
72*6bc688afSScott M. Carter 		fmd_hdl_debug(hdl, "Failed to open XML topo file\n");
73*6bc688afSScott M. Carter 		goto cleanup;
74*6bc688afSScott M. Carter 	}
75*6bc688afSScott M. Carter 
76*6bc688afSScott M. Carter 	/* Hold topology */
77eae2e508Skrishnae 	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL) {
78eae2e508Skrishnae 		fmd_hdl_debug(hdl, "Failed to hold topo\n");
79*6bc688afSScott M. Carter 		goto cleanup;
80eae2e508Skrishnae 	}
81eae2e508Skrishnae 
82*6bc688afSScott M. Carter 	/* Print topology to XML file */
83eae2e508Skrishnae 	if (topo_xml_print(thp, fp, FM_FMRI_SCHEME_HC, &err) < 0) {
84eae2e508Skrishnae 		fmd_hdl_debug(hdl, "Failed to get XML topo\n");
85*6bc688afSScott M. Carter 		fmd_hdl_topo_rele(hdl, thp);
86*6bc688afSScott M. Carter 		goto cleanup;
87eae2e508Skrishnae 	}
88eae2e508Skrishnae 
89*6bc688afSScott M. Carter 	/* Release topology */
90eae2e508Skrishnae 	fmd_hdl_topo_rele(hdl, thp);
91eae2e508Skrishnae 
92*6bc688afSScott M. Carter 	/* Reload topology from XML file */
93e8638579Skrishnae 	if (fab_xpathCtx)
94e8638579Skrishnae 		xmlXPathFreeContext(fab_xpathCtx);
95e8638579Skrishnae 	if (fab_doc)
96e8638579Skrishnae 		xmlFreeDoc(fab_doc);
97eae2e508Skrishnae 	fab_doc = xmlParseFile(XMLTOPOFILE);
98eae2e508Skrishnae 	fab_xpathCtx = xmlXPathNewContext(fab_doc);
99b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China 	fab_set_fake_rp(hdl);
100eae2e508Skrishnae 	fab_valid_topo = 1;
101*6bc688afSScott M. Carter 
102*6bc688afSScott M. Carter cleanup:
103*6bc688afSScott M. Carter 	if (fp != NULL)
104*6bc688afSScott M. Carter 		(void) fclose(fp);
105*6bc688afSScott M. Carter 	else if (fd != -1)
106*6bc688afSScott M. Carter 		(void) close(fd);
107*6bc688afSScott M. Carter 	(void) unlink(XMLTOPOFILE);
108eae2e508Skrishnae }
109eae2e508Skrishnae 
110eae2e508Skrishnae /*ARGSUSED*/
111eae2e508Skrishnae static void
112eae2e508Skrishnae fab_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
113eae2e508Skrishnae {
1144df55fdeSJanie Lu 	nvlist_t *new_nvl;
115eae2e508Skrishnae 
116*6bc688afSScott M. Carter 	(void) pthread_mutex_lock(&fab_lock);
117eae2e508Skrishnae 	if (!fab_valid_topo)
118eae2e508Skrishnae 		fab_update_topo(hdl);
119*6bc688afSScott M. Carter 	(void) pthread_mutex_unlock(&fab_lock);
120eae2e508Skrishnae 
1214df55fdeSJanie Lu 	if (nvlist_dup(nvl, &new_nvl, NV_UNIQUE_NAME) != 0) {
1224df55fdeSJanie Lu 		fmd_hdl_error(hdl, "failed to duplicate event");
1234df55fdeSJanie Lu 		return;
124eae2e508Skrishnae 	}
1254df55fdeSJanie Lu 
1264df55fdeSJanie Lu 	if (fmd_nvl_class_match(hdl, new_nvl, "ereport.io.pci.fabric")) {
1274df55fdeSJanie Lu 		fab_xlate_fabric_erpts(hdl, new_nvl, class);
1284df55fdeSJanie Lu 	} else {
1294df55fdeSJanie Lu 		fab_pr(hdl, ep, new_nvl);
1304df55fdeSJanie Lu 		if (fmd_nvl_class_match(hdl, new_nvl,
1314df55fdeSJanie Lu 		    "ereport.io.pciex.rc.epkt")) {
1324df55fdeSJanie Lu 			fab_xlate_epkt_erpts(hdl, new_nvl, class);
1334df55fdeSJanie Lu 		} else {
1344df55fdeSJanie Lu 			fab_xlate_fire_erpts(hdl, new_nvl, class);
1354df55fdeSJanie Lu 		}
1364df55fdeSJanie Lu 	}
1374df55fdeSJanie Lu 
1384df55fdeSJanie Lu 	nvlist_free(new_nvl);
139eae2e508Skrishnae }
140eae2e508Skrishnae 
141eae2e508Skrishnae /* ARGSUSED */
142eae2e508Skrishnae static void
143eae2e508Skrishnae fab_topo(fmd_hdl_t *hdl, topo_hdl_t *topo)
144eae2e508Skrishnae {
145*6bc688afSScott M. Carter 	(void) pthread_mutex_lock(&fab_lock);
146eae2e508Skrishnae 	fab_valid_topo = 0;
147*6bc688afSScott M. Carter 	(void) pthread_mutex_unlock(&fab_lock);
148eae2e508Skrishnae }
149eae2e508Skrishnae 
150eae2e508Skrishnae static const fmd_hdl_ops_t fmd_ops = {
151eae2e508Skrishnae 	fab_recv,	/* fmdo_recv */
152eae2e508Skrishnae 	NULL,		/* fmdo_timeout */
153eae2e508Skrishnae 	NULL,		/* fmdo_close */
154eae2e508Skrishnae 	NULL,		/* fmdo_stats */
155eae2e508Skrishnae 	NULL,		/* fmdo_gc */
156eae2e508Skrishnae 	NULL,		/* fmdo_send */
157eae2e508Skrishnae 	fab_topo,	/* fmdo_topo */
158eae2e508Skrishnae };
159eae2e508Skrishnae 
160eae2e508Skrishnae static const fmd_hdl_info_t fmd_info = {
161eae2e508Skrishnae 	"Fabric Ereport Translater", "1.0", &fmd_ops, NULL
162eae2e508Skrishnae };
163eae2e508Skrishnae 
164eae2e508Skrishnae void
165eae2e508Skrishnae _fmd_init(fmd_hdl_t *hdl)
166eae2e508Skrishnae {
167eae2e508Skrishnae 	if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
168eae2e508Skrishnae 		return;
169eae2e508Skrishnae 
170eae2e508Skrishnae 	/* Init libxml */
171eae2e508Skrishnae 	xmlInitParser();
172eae2e508Skrishnae 
173eae2e508Skrishnae 	fab_fmd_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL);
174eae2e508Skrishnae 	fmd_hdl_debug(hdl, "Fabric Translater Started\n");
175eae2e508Skrishnae 
1764df55fdeSJanie Lu 	fab_setup_master_table();
177eae2e508Skrishnae }
178eae2e508Skrishnae 
179eae2e508Skrishnae void
180eae2e508Skrishnae _fmd_fini(fmd_hdl_t *hdl)
181eae2e508Skrishnae {
182eae2e508Skrishnae 	/* Fini xpath */
183eae2e508Skrishnae 	if (fab_xpathCtx)
184eae2e508Skrishnae 		xmlXPathFreeContext(fab_xpathCtx);
185eae2e508Skrishnae 	/* Free xml document */
186eae2e508Skrishnae 	if (fab_doc)
187eae2e508Skrishnae 		xmlFreeDoc(fab_doc);
188eae2e508Skrishnae 	/* Fini libxml */
189eae2e508Skrishnae 	xmlCleanupParser();
190eae2e508Skrishnae 
191eae2e508Skrishnae 	fmd_xprt_close(hdl, fab_fmd_xprt);
192eae2e508Skrishnae }
193