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