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 2009 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_valid_topo = 1; 76 } 77 78 /*ARGSUSED*/ 79 static void 80 fab_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) 81 { 82 nvlist_t *new_nvl; 83 84 if (!fab_valid_topo) 85 fab_update_topo(hdl); 86 87 if (nvlist_dup(nvl, &new_nvl, NV_UNIQUE_NAME) != 0) { 88 fmd_hdl_error(hdl, "failed to duplicate event"); 89 return; 90 } 91 92 if (fmd_nvl_class_match(hdl, new_nvl, "ereport.io.pci.fabric")) { 93 fab_xlate_fabric_erpts(hdl, new_nvl, class); 94 } else { 95 fab_pr(hdl, ep, new_nvl); 96 if (fmd_nvl_class_match(hdl, new_nvl, 97 "ereport.io.pciex.rc.epkt")) { 98 fab_xlate_epkt_erpts(hdl, new_nvl, class); 99 } else { 100 fab_xlate_fire_erpts(hdl, new_nvl, class); 101 } 102 } 103 104 nvlist_free(new_nvl); 105 } 106 107 /* ARGSUSED */ 108 static void 109 fab_topo(fmd_hdl_t *hdl, topo_hdl_t *topo) 110 { 111 fab_valid_topo = 0; 112 } 113 114 static const fmd_hdl_ops_t fmd_ops = { 115 fab_recv, /* fmdo_recv */ 116 NULL, /* fmdo_timeout */ 117 NULL, /* fmdo_close */ 118 NULL, /* fmdo_stats */ 119 NULL, /* fmdo_gc */ 120 NULL, /* fmdo_send */ 121 fab_topo, /* fmdo_topo */ 122 }; 123 124 static const fmd_hdl_info_t fmd_info = { 125 "Fabric Ereport Translater", "1.0", &fmd_ops, NULL 126 }; 127 128 void 129 _fmd_init(fmd_hdl_t *hdl) 130 { 131 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0) 132 return; 133 134 /* Init libxml */ 135 xmlInitParser(); 136 137 fab_fmd_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL); 138 fmd_hdl_debug(hdl, "Fabric Translater Started\n"); 139 140 fab_setup_master_table(); 141 } 142 143 void 144 _fmd_fini(fmd_hdl_t *hdl) 145 { 146 /* Fini xpath */ 147 if (fab_xpathCtx) 148 xmlXPathFreeContext(fab_xpathCtx); 149 /* Free xml document */ 150 if (fab_doc) 151 xmlFreeDoc(fab_doc); 152 /* Fini libxml */ 153 xmlCleanupParser(); 154 155 fmd_xprt_close(hdl, fab_fmd_xprt); 156 } 157