f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae/*
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * CDDL HEADER START
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae *
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * The contents of this file are subject to the terms of the
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * Common Development and Distribution License (the "License").
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * You may not use this file except in compliance with the License.
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae *
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * or http://www.opensolaris.org/os/licensing.
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * See the License for the specific language governing permissions
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * and limitations under the License.
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae *
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * When distributing Covered Code, include this CDDL HEADER in each
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * If applicable, add the following below this CDDL HEADER, with the
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * fields enclosed by brackets "[]" replaced with your own identifying
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * information: Portions Copyright [yyyy] [name of copyright owner]
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae *
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae * CDDL HEADER END
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae/*
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae#include <fm/libtopo.h>
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae#include <sys/fm/util.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <sys/types.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <sys/stat.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <sys/errno.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <fcntl.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <unistd.h>
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#include <pthread.h>
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae#include <libxml/xpathInternals.h>
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu#include "fabric-xlate.h"
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter#define XMLTOPOFILE "/var/run/fab-xlate-topo.xml"
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
4df55fde49134f9735f84011f23a767c75e393c7Janie Lufmd_xprt_t *fab_fmd_xprt; /* FMD transport layer handle */
4df55fde49134f9735f84011f23a767c75e393c7Janie Luchar fab_buf[FM_MAX_CLASS];
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu/* Static FM Topo XML Format and XML XPath Context */
4df55fde49134f9735f84011f23a767c75e393c7Janie Lustatic xmlDocPtr fab_doc = NULL;
4df55fde49134f9735f84011f23a767c75e393c7Janie LuxmlXPathContextPtr fab_xpathCtx = NULL;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lustatic int fab_valid_topo = 0;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carterstatic pthread_mutex_t fab_lock = PTHREAD_MUTEX_INITIALIZER;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaestatic void
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaefab_update_topo(fmd_hdl_t *hdl)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae{
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae topo_hdl_t *thp = NULL;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter FILE *fp = NULL;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae int err = 0;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter int fd = -1;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Open the temporary file with proper ownership */
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter while (fd == -1) {
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter if ((unlink(XMLTOPOFILE) == -1) && (errno != ENOENT)) {
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter fmd_hdl_debug(hdl, "Failed to remove XML topo file\n");
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter return;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter }
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter fd = open(XMLTOPOFILE, O_RDWR | O_CREAT | O_EXCL, 0600);
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter if ((fd == -1) && (errno != EEXIST)) {
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter fmd_hdl_debug(hdl, "Failed to create XML topo file\n");
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter return;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter }
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter }
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Associate a stream with the temporary file */
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter if ((fp = fdopen(fd, "w")) == NULL) {
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter fmd_hdl_debug(hdl, "Failed to open XML topo file\n");
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter goto cleanup;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter }
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Hold topology */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL) {
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fmd_hdl_debug(hdl, "Failed to hold topo\n");
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter goto cleanup;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae }
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Print topology to XML file */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if (topo_xml_print(thp, fp, FM_FMRI_SCHEME_HC, &err) < 0) {
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fmd_hdl_debug(hdl, "Failed to get XML topo\n");
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter fmd_hdl_topo_rele(hdl, thp);
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter goto cleanup;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae }
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Release topology */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fmd_hdl_topo_rele(hdl, thp);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter /* Reload topology from XML file */
e86385799016fd6009b4330d289dfc892378cf28krishnae if (fab_xpathCtx)
e86385799016fd6009b4330d289dfc892378cf28krishnae xmlXPathFreeContext(fab_xpathCtx);
e86385799016fd6009b4330d289dfc892378cf28krishnae if (fab_doc)
e86385799016fd6009b4330d289dfc892378cf28krishnae xmlFreeDoc(fab_doc);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_doc = xmlParseFile(XMLTOPOFILE);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_xpathCtx = xmlXPathNewContext(fab_doc);
b344f6b3aaff135e766e22b3d18489fe22a74198gongtian zhao - Sun Microsystems - Beijing China fab_set_fake_rp(hdl);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_valid_topo = 1;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Cartercleanup:
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter if (fp != NULL)
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) fclose(fp);
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter else if (fd != -1)
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) close(fd);
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) unlink(XMLTOPOFILE);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae}
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae/*ARGSUSED*/
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaestatic void
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaefab_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae{
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu nvlist_t *new_nvl;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) pthread_mutex_lock(&fab_lock);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if (!fab_valid_topo)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_update_topo(hdl);
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) pthread_mutex_unlock(&fab_lock);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (nvlist_dup(nvl, &new_nvl, NV_UNIQUE_NAME) != 0) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fmd_hdl_error(hdl, "failed to duplicate event");
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu return;
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (fmd_nvl_class_match(hdl, new_nvl, "ereport.io.pci.fabric")) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_xlate_fabric_erpts(hdl, new_nvl, class);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae } else {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_pr(hdl, ep, new_nvl);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu if (fmd_nvl_class_match(hdl, new_nvl,
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu "ereport.io.pciex.rc.epkt")) {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_xlate_epkt_erpts(hdl, new_nvl, class);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu } else {
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_xlate_fire_erpts(hdl, new_nvl, class);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu }
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae }
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu nvlist_free(new_nvl);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae}
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae/* ARGSUSED */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaestatic void
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaefab_topo(fmd_hdl_t *hdl, topo_hdl_t *topo)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae{
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) pthread_mutex_lock(&fab_lock);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_valid_topo = 0;
6bc688af4fb132e30e3dcc0243a24d232b5a3ebaScott M. Carter (void) pthread_mutex_unlock(&fab_lock);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae}
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaestatic const fmd_hdl_ops_t fmd_ops = {
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_recv, /* fmdo_recv */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae NULL, /* fmdo_timeout */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae NULL, /* fmdo_close */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae NULL, /* fmdo_stats */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae NULL, /* fmdo_gc */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae NULL, /* fmdo_send */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_topo, /* fmdo_topo */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae};
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaestatic const fmd_hdl_info_t fmd_info = {
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae "Fabric Ereport Translater", "1.0", &fmd_ops, NULL
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae};
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaevoid
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae_fmd_init(fmd_hdl_t *hdl)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae{
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae return;
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae /* Init libxml */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae xmlInitParser();
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fab_fmd_xprt = fmd_xprt_open(hdl, FMD_XPRT_RDONLY, NULL, NULL);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fmd_hdl_debug(hdl, "Fabric Translater Started\n");
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu fab_setup_master_table();
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae}
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnaevoid
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae_fmd_fini(fmd_hdl_t *hdl)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae{
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae /* Fini xpath */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if (fab_xpathCtx)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae xmlXPathFreeContext(fab_xpathCtx);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae /* Free xml document */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae if (fab_doc)
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae xmlFreeDoc(fab_doc);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae /* Fini libxml */
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae xmlCleanupParser();
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae fmd_xprt_close(hdl, fab_fmd_xprt);
f41150baf74bdaf964ddfe42d865d3c2380b3623krishnae}