Home | History | Annotate | Download | only in fabric-xlate
      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