1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #include <fm/libtopo.h> 27 #include <sys/fm/util.h> 28 29 #include <libxml/xpathInternals.h> 30 31 #include "fabric-xlate.h" 32 33 #define XMLTOPOFILE "/tmp/fab-xlate-topo.xml" 34 35 fmd_xprt_t *fab_fmd_xprt; /* FMD transport layer handle */ 36 char fab_buf[FM_MAX_CLASS]; 37 38 /* Static FM Topo XML Format and XML XPath Context */ 39 static xmlDocPtr fab_doc = NULL; 40 xmlXPathContextPtr fab_xpathCtx = NULL; 41 static int fab_valid_topo = 0; 42 43 static void 44 fab_update_topo(fmd_hdl_t *hdl) 45 { 46 topo_hdl_t *thp = NULL; 47 FILE *fp; 48 int err = 0; 49 50 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL) { 51 fmd_hdl_debug(hdl, "Failed to hold topo\n"); 52 } 53 54 fp = fopen(XMLTOPOFILE, "w"); 55 56 if (topo_xml_print(thp, fp, FM_FMRI_SCHEME_HC, &err) < 0) { 57 fmd_hdl_debug(hdl, "Failed to get XML topo\n"); 58 } 59 60 (void) fclose(fp); 61 62 fmd_hdl_topo_rele(hdl, thp); 63 64 if (fab_xpathCtx) 65 xmlXPathFreeContext(fab_xpathCtx); 66 if (fab_doc) 67 xmlFreeDoc(fab_doc); 68 69 /* Load xml document */ 70 fab_doc = xmlParseFile(XMLTOPOFILE); 71 72 /* Init xpath */ 73 fab_xpathCtx = xmlXPathNewContext(fab_doc); 74 75 fab_set_fake_rp(hdl); 76 77 fab_valid_topo = 1; 78 } 79 80 /*ARGSUSED*/ 81 static void 82 fab_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) 83 { 84 nvlist_t *new_nvl; 85 86 if (!fab_valid_topo) 87 fab_update_topo(hdl); 88 89 if (nvlist_dup(nvl, &new_nvl, NV_UNIQUE_NAME) != 0) { 90 fmd_hdl_error(hdl, "failed to duplicate event"); 91 return; 92 } 93 94 if (fmd_nvl_class_match(hdl, new_nvl, "ereport.io.pci.fabric")) { 95 fab_xlate_fabric_erpts(hdl, new_nvl, class); 96 } else { 97 fab_pr(hdl, ep, new_nvl); 98 if (fmd_nvl_class_match(hdl, new_nvl, 99 "ereport.io.pciex.rc.epkt")) { 100 fab_xlate_epkt_erpts(hdl, new_nvl, class); 101 } else { 102 fab_xlate_fire_erpts(hdl, new_nvl, class); 103 } 104 } 105 106 nvlist_free(new_nvl); 107 } 108 109 /* ARGSUSED */ 110 static void 111 fab_topo(fmd_hdl_t *hdl, topo_hdl_t *topo) 112 { 113 fab_valid_topo = 0; 114 } 115 116 static const fmd_hdl_ops_t fmd_ops = { 117 fab_recv, /* fmdo_recv */ 118 NULL, /* fmdo_timeout */ 119 NULL, /* fmdo_close */ 120 NULL, /* fmdo_stats */ 121 NULL, /* fmdo_gc */ 122 NULL, /* fmdo_send */ 123 fab_topo, /* fmdo_topo */ 124 }; 125 126 static const fmd_hdl_info_t fmd_info = { 127 "Fabric Ereport Translater", "1.0", &fmd_ops, NULL 128 }; 129 130 void 131 _fmd_init(fmd_hdl_t *hdl) 132 { 133 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) 134 return; 135 136 /* Init libxml */ 137 xmlInitParser(); 138 139 fab_fmd_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL); 140 fmd_hdl_debug(hdl, "Fabric Translater Started\n"); 141 142 fab_setup_master_table(); 143 } 144 145 void 146 _fmd_fini(fmd_hdl_t *hdl) 147 { 148 /* Fini xpath */ 149 if (fab_xpathCtx) 150 xmlXPathFreeContext(fab_xpathCtx); 151 /* Free xml document */ 152 if (fab_doc) 153 xmlFreeDoc(fab_doc); 154 /* Fini libxml */ 155 xmlCleanupParser(); 156 157 fmd_xprt_close(hdl, fab_fmd_xprt); 158 } 159