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 /*
236bc688afSScott 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>
276bc688afSScott M. Carter #include <sys/types.h>
286bc688afSScott M. Carter #include <sys/stat.h>
296bc688afSScott M. Carter #include <sys/errno.h>
306bc688afSScott M. Carter #include <fcntl.h>
316bc688afSScott M. Carter #include <unistd.h>
326bc688afSScott M. Carter #include <pthread.h>
33eae2e508Skrishnae
34*b0709259SAndy Fiddaman #include <libxml/tree.h>
35*b0709259SAndy Fiddaman #include <libxml/parser.h>
36eae2e508Skrishnae #include <libxml/xpathInternals.h>
37eae2e508Skrishnae
384df55fdeSJanie Lu #include "fabric-xlate.h"
39eae2e508Skrishnae
406bc688afSScott M. Carter #define XMLTOPOFILE "/var/run/fab-xlate-topo.xml"
41eae2e508Skrishnae
424df55fdeSJanie Lu fmd_xprt_t *fab_fmd_xprt; /* FMD transport layer handle */
434df55fdeSJanie Lu char fab_buf[FM_MAX_CLASS];
44eae2e508Skrishnae
45eae2e508Skrishnae /* Static FM Topo XML Format and XML XPath Context */
46eae2e508Skrishnae static xmlDocPtr fab_doc = NULL;
474df55fdeSJanie Lu xmlXPathContextPtr fab_xpathCtx = NULL;
48eae2e508Skrishnae static int fab_valid_topo = 0;
496bc688afSScott M. Carter static pthread_mutex_t fab_lock = PTHREAD_MUTEX_INITIALIZER;
50eae2e508Skrishnae
51eae2e508Skrishnae static void
fab_update_topo(fmd_hdl_t * hdl)52eae2e508Skrishnae fab_update_topo(fmd_hdl_t *hdl)
53eae2e508Skrishnae {
54eae2e508Skrishnae topo_hdl_t *thp = NULL;
556bc688afSScott M. Carter FILE *fp = NULL;
56eae2e508Skrishnae int err = 0;
576bc688afSScott M. Carter int fd = -1;
58eae2e508Skrishnae
596bc688afSScott M. Carter /* Open the temporary file with proper ownership */
606bc688afSScott M. Carter while (fd == -1) {
616bc688afSScott M. Carter if ((unlink(XMLTOPOFILE) == -1) && (errno != ENOENT)) {
626bc688afSScott M. Carter fmd_hdl_debug(hdl, "Failed to remove XML topo file\n");
636bc688afSScott M. Carter return;
646bc688afSScott M. Carter }
656bc688afSScott M. Carter fd = open(XMLTOPOFILE, O_RDWR | O_CREAT | O_EXCL, 0600);
666bc688afSScott M. Carter if ((fd == -1) && (errno != EEXIST)) {
676bc688afSScott M. Carter fmd_hdl_debug(hdl, "Failed to create XML topo file\n");
686bc688afSScott M. Carter return;
696bc688afSScott M. Carter }
706bc688afSScott M. Carter }
716bc688afSScott M. Carter
726bc688afSScott M. Carter /* Associate a stream with the temporary file */
736bc688afSScott M. Carter if ((fp = fdopen(fd, "w")) == NULL) {
746bc688afSScott M. Carter fmd_hdl_debug(hdl, "Failed to open XML topo file\n");
756bc688afSScott M. Carter goto cleanup;
766bc688afSScott M. Carter }
776bc688afSScott M. Carter
786bc688afSScott M. Carter /* Hold topology */
79eae2e508Skrishnae if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL) {
80eae2e508Skrishnae fmd_hdl_debug(hdl, "Failed to hold topo\n");
816bc688afSScott M. Carter goto cleanup;
82eae2e508Skrishnae }
83eae2e508Skrishnae
846bc688afSScott M. Carter /* Print topology to XML file */
85eae2e508Skrishnae if (topo_xml_print(thp, fp, FM_FMRI_SCHEME_HC, &err) < 0) {
86eae2e508Skrishnae fmd_hdl_debug(hdl, "Failed to get XML topo\n");
876bc688afSScott M. Carter fmd_hdl_topo_rele(hdl, thp);
886bc688afSScott M. Carter goto cleanup;
89eae2e508Skrishnae }
90eae2e508Skrishnae
916bc688afSScott M. Carter /* Release topology */
92eae2e508Skrishnae fmd_hdl_topo_rele(hdl, thp);
93eae2e508Skrishnae
946bc688afSScott M. Carter /* Reload topology from XML file */
95e8638579Skrishnae if (fab_xpathCtx)
96e8638579Skrishnae xmlXPathFreeContext(fab_xpathCtx);
97e8638579Skrishnae if (fab_doc)
98e8638579Skrishnae xmlFreeDoc(fab_doc);
99eae2e508Skrishnae fab_doc = xmlParseFile(XMLTOPOFILE);
100eae2e508Skrishnae fab_xpathCtx = xmlXPathNewContext(fab_doc);
101b344f6b3Sgongtian zhao - Sun Microsystems - Beijing China fab_set_fake_rp(hdl);
102eae2e508Skrishnae fab_valid_topo = 1;
1036bc688afSScott M. Carter
1046bc688afSScott M. Carter cleanup:
1056bc688afSScott M. Carter if (fp != NULL)
1066bc688afSScott M. Carter (void) fclose(fp);
1076bc688afSScott M. Carter else if (fd != -1)
1086bc688afSScott M. Carter (void) close(fd);
1096bc688afSScott M. Carter (void) unlink(XMLTOPOFILE);
110eae2e508Skrishnae }
111eae2e508Skrishnae
112eae2e508Skrishnae /*ARGSUSED*/
113eae2e508Skrishnae static void
fab_recv(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class)114eae2e508Skrishnae fab_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
115eae2e508Skrishnae {
1164df55fdeSJanie Lu nvlist_t *new_nvl;
117eae2e508Skrishnae
1186bc688afSScott M. Carter (void) pthread_mutex_lock(&fab_lock);
119eae2e508Skrishnae if (!fab_valid_topo)
120eae2e508Skrishnae fab_update_topo(hdl);
1216bc688afSScott M. Carter (void) pthread_mutex_unlock(&fab_lock);
122eae2e508Skrishnae
1234df55fdeSJanie Lu if (nvlist_dup(nvl, &new_nvl, NV_UNIQUE_NAME) != 0) {
1244df55fdeSJanie Lu fmd_hdl_error(hdl, "failed to duplicate event");
1254df55fdeSJanie Lu return;
126eae2e508Skrishnae }
1274df55fdeSJanie Lu
1284df55fdeSJanie Lu if (fmd_nvl_class_match(hdl, new_nvl, "ereport.io.pci.fabric")) {
1294df55fdeSJanie Lu fab_xlate_fabric_erpts(hdl, new_nvl, class);
1304df55fdeSJanie Lu } else {
1314df55fdeSJanie Lu fab_pr(hdl, ep, new_nvl);
1324df55fdeSJanie Lu if (fmd_nvl_class_match(hdl, new_nvl,
1334df55fdeSJanie Lu "ereport.io.pciex.rc.epkt")) {
1344df55fdeSJanie Lu fab_xlate_epkt_erpts(hdl, new_nvl, class);
1354df55fdeSJanie Lu } else {
1364df55fdeSJanie Lu fab_xlate_fire_erpts(hdl, new_nvl, class);
1374df55fdeSJanie Lu }
1384df55fdeSJanie Lu }
1394df55fdeSJanie Lu
1404df55fdeSJanie Lu nvlist_free(new_nvl);
141eae2e508Skrishnae }
142eae2e508Skrishnae
143eae2e508Skrishnae /* ARGSUSED */
144eae2e508Skrishnae static void
fab_topo(fmd_hdl_t * hdl,topo_hdl_t * topo)145eae2e508Skrishnae fab_topo(fmd_hdl_t *hdl, topo_hdl_t *topo)
146eae2e508Skrishnae {
1476bc688afSScott M. Carter (void) pthread_mutex_lock(&fab_lock);
148eae2e508Skrishnae fab_valid_topo = 0;
1496bc688afSScott M. Carter (void) pthread_mutex_unlock(&fab_lock);
150eae2e508Skrishnae }
151eae2e508Skrishnae
152eae2e508Skrishnae static const fmd_hdl_ops_t fmd_ops = {
153eae2e508Skrishnae fab_recv, /* fmdo_recv */
154eae2e508Skrishnae NULL, /* fmdo_timeout */
155eae2e508Skrishnae NULL, /* fmdo_close */
156eae2e508Skrishnae NULL, /* fmdo_stats */
157eae2e508Skrishnae NULL, /* fmdo_gc */
158eae2e508Skrishnae NULL, /* fmdo_send */
159eae2e508Skrishnae fab_topo, /* fmdo_topo */
160eae2e508Skrishnae };
161eae2e508Skrishnae
162eae2e508Skrishnae static const fmd_hdl_info_t fmd_info = {
163eae2e508Skrishnae "Fabric Ereport Translater", "1.0", &fmd_ops, NULL
164eae2e508Skrishnae };
165eae2e508Skrishnae
166eae2e508Skrishnae void
_fmd_init(fmd_hdl_t * hdl)167eae2e508Skrishnae _fmd_init(fmd_hdl_t *hdl)
168eae2e508Skrishnae {
169eae2e508Skrishnae if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
170eae2e508Skrishnae return;
171eae2e508Skrishnae
172eae2e508Skrishnae /* Init libxml */
173eae2e508Skrishnae xmlInitParser();
174eae2e508Skrishnae
175eae2e508Skrishnae fab_fmd_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL);
176eae2e508Skrishnae fmd_hdl_debug(hdl, "Fabric Translater Started\n");
177eae2e508Skrishnae
1784df55fdeSJanie Lu fab_setup_master_table();
179eae2e508Skrishnae }
180eae2e508Skrishnae
181eae2e508Skrishnae void
_fmd_fini(fmd_hdl_t * hdl)182eae2e508Skrishnae _fmd_fini(fmd_hdl_t *hdl)
183eae2e508Skrishnae {
184eae2e508Skrishnae /* Fini xpath */
185eae2e508Skrishnae if (fab_xpathCtx)
186eae2e508Skrishnae xmlXPathFreeContext(fab_xpathCtx);
187eae2e508Skrishnae /* Free xml document */
188eae2e508Skrishnae if (fab_doc)
189eae2e508Skrishnae xmlFreeDoc(fab_doc);
190eae2e508Skrishnae /* Fini libxml */
191eae2e508Skrishnae xmlCleanupParser();
192eae2e508Skrishnae
193eae2e508Skrishnae fmd_xprt_close(hdl, fab_fmd_xprt);
194eae2e508Skrishnae }
195