733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * CDDL HEADER START
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * The contents of this file are subject to the terms of the
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * Common Development and Distribution License (the "License").
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * You may not use this file except in compliance with the License.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or http://www.opensolaris.org/os/licensing.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * See the License for the specific language governing permissions
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * and limitations under the License.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * When distributing Covered Code, include this CDDL HEADER in each
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * If applicable, add the following below this CDDL HEADER, with the
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * fields enclosed by brackets "[]" replaced with your own identifying
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * information: Portions Copyright [yyyy] [name of copyright owner]
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * CDDL HEADER END
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
20ae46ebaff1237662e05edf9db61538aa85d448ha * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Use is subject to license terms.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_api_dd.c FMA ETM-to-Transport API implementation
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * for sun4v/Ontario
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * library for establishing connections and transporting FMA events
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * between ETMs (event transport modules) in separate fault domain,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * ie, between domain and service processor in same chassis, using
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * a character device driver based transport
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#pragma ident "%Z%%M% %I% %E% SMI"
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * --------------------------------- includes --------------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <sys/types.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <sys/stat.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <sys/fm/protocol.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <fm/fmd_api.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <pthread.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <stdio.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <stropts.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <locale.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <strings.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <stdlib.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <unistd.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <limits.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <alloca.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <errno.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <fcntl.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include <time.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <poll.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <sys/ldc.h>
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#include <sys/vldc.h>
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include "etm_xport_api.h"
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include "etm_etm_proto.h"
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#include "etm_impl.h"
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * ----------------------- private consts and defns --------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/* magic numbers (32 bits) for transport address and connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#define ETM_XPORT_DD_MAGIC_ADDR (0x45544D41)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#define ETM_XPORT_DD_MAGIC_CONN (0x45544D43)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/* flags to use in opening transport device */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#define ETM_XPORT_OPEN_FLAGS (O_RDWR | O_NOCTTY)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * transport address and connection handle structures overload fn and fd
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * fields to include state information:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * fn file name NULL means unused or closed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * fd file descriptor -1 means unused or closed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbtypedef struct _etm_xport_addr {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb uint32_t magic_num; /* magic number */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb char *fn; /* fullpath to device node */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} _etm_xport_addr_t;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbtypedef struct _etm_xport_conn {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb uint32_t magic_num; /* magic number */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int fd; /* open dev file descriptor */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *addr; /* associated transport addr */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} _etm_xport_conn_t;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * filename of device node to reach SP from domain. one of these two
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * device nodes will be used:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ETM_XPORT_DEV_FN_SP - the Ontario glvc
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * ETM_XPORT_DEV_VLDC - the more recent LDOMS 1.0 (a.k.a. Ontario+) vldc
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * When the latter is in use, use_vldc is set to 1.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * filenames of device nodes to reach domains from SP
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * are NA because SP runs ALOM vs Solaris or Linux
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * and ETM is for Unix based OSes
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb#define ETM_XPORT_DEV_FN_SP "/dev/spfma"
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn#define ETM_XPORT_DEV_VLDC \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn "/devices/virtual-devices@100/channel-devices@200" \
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn "/virtual-channel-client@2:spfma"
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * -------------------------- global variables -------------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic int use_vldc = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic struct stats {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* address handle failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_addr_magicnum_bad;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_addr_fn_bad;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* connection handle failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_conn_magicnum_bad;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_conn_fd_bad;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* internal read/peek failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_buffread_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_rawpeek_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* xport API failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_accept_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_get_addr_conn_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_free_addr_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_free_addrv_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_get_any_lcc_badargs;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* system and library failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_open_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_close_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_read_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_write_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_peek_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_stat_t xport_os_ioctl_fail;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} etm_xport_stats = {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* address handle failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_addr_magicnum_bad", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "invalid address handle magic number" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_addr_fn_bad", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "invalid address handle file name" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* connection handle failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_conn_magicnum_bad", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "invalid connection handle magic number" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_conn_fd_bad", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "invalid connection handle file descriptor" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* internal read/peek failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_buffread_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_buffered_read" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_rawpeek_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_raw_peek" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* xport API failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_accept_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_accept" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_get_addr_conn_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_get_addr_conn" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_free_addr_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_free_addr" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_free_addrv_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_free_addrv" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_get_any_lcc_badargs", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "bad arguments in etm_xport_get_any_lcc" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* system and library failures */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_open_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "open system call failures" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_close_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "close system call failures" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_read_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "read system call failures" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_write_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "write system call failures" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_peek_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "peek (ioctl) failures" },
733a5356058ae0150a67d61f0ad8e5260d2acae3rb { "xport_os_ioctl_fail", FMD_TYPE_UINT64,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb "ioctl system call failures" }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb};
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/* intermediate read buffer to [partially] emulate byte stream semantics */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic uint8_t *etm_xport_irb_area = NULL; /* buffered read area */
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic uint8_t *etm_xport_irb_head = NULL; /* read head (dequeue) */
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic uint8_t *etm_xport_irb_tail = NULL; /* read tail (enqueue) */
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic size_t etm_xport_irb_mtu_sz = 0; /* MTU size (in bytes) */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * -------------------------- private variables ------------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic _etm_xport_conn_t *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnetm_xport_vldc_conn = NULL; /* single connection handle for VLDC */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnstatic pthread_mutex_t
31e37bb439502e3f7c4c0a9a77d655ea5d56887avnetm_xport_vldc_lock = PTHREAD_MUTEX_INITIALIZER;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /* lock for open()/close() VLDC */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic int
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_debug_lvl = 0; /* debug level: 0 off, 1 on, 2 more, ... */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic char *
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_addrs = ""; /* spec str for transport addrs to use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic int
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_should_fake_dd = 0; /* bool for whether to fake device driver */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * -------------------------- private functions ------------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_fake_ioctl - fake/simulate transport driver's ioctl() behavior
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * [for unit testing with device driver absent or
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * for alternative directory entry based transports],
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return 0 for success
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -1 and set errno
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * caveats:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * simulation may be incomplete, especially wrt peek()
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Design_Note: To avoid interfering with FMD's signal mask (SIGALRM)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * do not use [Solaris] sleep(3C) and instead use
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * pthread_cond_wait() or nanosleep(), both of which
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * are POSIX spec-ed to leave signal masks alone.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * This is needed for Solaris and Linux (domain and SP).
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic int
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_fake_ioctl(int fd, int op, void *buf)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_opt_op_t *op_ctl_ptr; /* ptr for option ops */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_msg_peek_t *peek_ctl_ptr; /* ptr for peeking */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb struct stat stat_buf; /* file stat struct */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb struct timespec tms; /* for nanosleep() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb tms.tv_sec = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb tms.tv_nsec = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = 0; /* default is success */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (op == ETM_XPORT_IOCTL_DATA_PEEK) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl_ptr = buf;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* sleep until some data avail, potentially forever */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb for (;;) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (fstat(fd, &stat_buf) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = -1;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (stat_buf.st_size > 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = MIN(peek_ctl_ptr->pk_buflen,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb stat_buf.st_size);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl_ptr->pk_buflen = n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* return bogus data assuming content unused */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) memset(peek_ctl_ptr->pk_buf, 0xA5, n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb tms.tv_sec = ETM_SLEEP_QUIK;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb tms.tv_nsec = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = nanosleep(&tms, NULL)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = -1;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* forever awaiting data */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else if (op == ETM_XPORT_IOCTL_OPT_OP) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb op_ctl_ptr = buf;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* default near MTU_SZ gets and agree with everything else */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((op_ctl_ptr->oo_op == ETM_XPORT_OPT_GET) &&
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (op_ctl_ptr->oo_opt == ETM_XPORT_OPT_MTU_SZ)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb op_ctl_ptr->oo_val = 7 * ETM_XPORT_MTU_SZ_DEF / 8;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* whether ioctl op is handled */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = -1;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = EINVAL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbfunc_ret:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_fake_ioctl() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_get_fn - return a cached read-only copy
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * of the device node name to use
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * for the given I/O operation
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic char *
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_get_fn(fmd_hdl_t *hdl, int io_op)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb static char fn_wr[PATH_MAX] = {0}; /* fn for write */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb static char fn_rd[PATH_MAX] = {0}; /* fn for read/peek */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb char *rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb char *prop_str; /* property string */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb char *cp; /* char ptr */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* use cached copies if avail */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((io_op == ETM_IO_OP_WR) && (fn_wr[0] != '\0')) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (fn_wr);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (((io_op == ETM_IO_OP_RD) || (io_op == ETM_IO_OP_PK)) &&
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (fn_rd[0] != '\0')) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (fn_rd);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* create cached copies if empty "" property string */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb prop_str = fmd_prop_get_string(hdl, ETM_PROP_NM_XPORT_ADDRS);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 2) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: etm_xport_get_fn prop_str %s\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb prop_str);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (strlen(prop_str) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn struct stat buf;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn char *fname;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (stat(ETM_XPORT_DEV_VLDC, &buf) == 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn use_vldc = 1;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fname = ETM_XPORT_DEV_VLDC;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn use_vldc = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fname = ETM_XPORT_DEV_FN_SP;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) strncpy(fn_wr, fname, PATH_MAX - 1);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) strncpy(fn_rd, fname, PATH_MAX - 1);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = fn_rd;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (io_op == ETM_IO_OP_WR) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = fn_wr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* if no/empty property set */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* create cached copies if "write[|read]" property string */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (io_op == ETM_IO_OP_WR) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) strncpy(fn_wr, prop_str, PATH_MAX - 1);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((cp = strchr(fn_wr, '|')) != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *cp = '\0';
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = fn_wr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((cp = strchr(prop_str, '|')) != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb cp++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb cp = prop_str;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) strncpy(fn_rd, cp, PATH_MAX - 1);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = fn_rd;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* whether io op is write/read/peek */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbfunc_ret:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 2) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: etm_xport_get_fn fn_wr %s fn_rd %s\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb fn_wr, fn_rd);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_prop_free_string(hdl, prop_str);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_get_fn() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_valid_addr - validate the given transport address,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return 0 if valid
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value if not
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic int
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_valid_addr(etm_xport_addr_t addr)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *_addr; /* transport address */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb struct stat stat_buf; /* buffer for stat() results */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = addr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addr == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addr->magic_num != ETM_XPORT_DD_MAGIC_ADDR) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_addr_magicnum_bad.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EFAULT);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (stat(_addr->fn, &stat_buf) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_addr_fn_bad.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (0);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_valid_addr() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_valid_conn - validate the given connection handle,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return 0 if valid
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value if not
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic int
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_valid_conn(etm_xport_conn_t conn)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = conn;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_conn == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_conn->magic_num != ETM_XPORT_DD_MAGIC_CONN) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_conn_magicnum_bad.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EFAULT);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_conn->fd <= -1) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_conn_fd_bad.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EBADF);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (0);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_valid_conn() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_free_addr - free the given transport address
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic void
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_free_addr(fmd_hdl_t *hdl, etm_xport_addr_t addr)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (addr == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_free_addr_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_free(hdl, addr, sizeof (_etm_xport_addr_t));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_free_addr() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_dup_addr - duplicate the given transport address,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * which is to be freed separately,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the newly allocated transport address
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * pending until possible to do so
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic etm_xport_addr_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_dup_addr(fmd_hdl_t *hdl, etm_xport_addr_t addr)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_addr_t new_addr; /* new transport address */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb new_addr = fmd_hdl_zalloc(hdl, sizeof (_etm_xport_addr_t), FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) memcpy(new_addr, addr, sizeof (_etm_xport_addr_t));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (new_addr);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_dup_addr() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_raw_peek - try to peek N <= MTU bytes from the connection
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * into the caller's given buffer,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return how many bytes actually peeked
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * caveats:
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * peeked data is NOT guaranteed by all platform transports
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * to remain enqueued if this process/thread crashes;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * this casts some doubt on the utility of this func
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn *
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * transport does NOT support peek sizes > MTU
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic ssize_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_raw_peek(fmd_hdl_t *hdl, _etm_xport_conn_t *_conn,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb void *buf, size_t byte_cnt)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_msg_peek_t peek_ctl; /* struct for peeking */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* sanity check args */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((hdl == NULL) || (_conn == NULL) || (buf == NULL)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_rawpeek_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((etm_xport_irb_mtu_sz > 0) && (byte_cnt > etm_xport_irb_mtu_sz)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_rawpeek_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* try to peek requested amt of data */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl.pk_buf = buf;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl.pk_buflen = byte_cnt;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl.pk_flags = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb peek_ctl.pk_rsvd = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_should_fake_dd) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = etm_fake_ioctl(_conn->fd, ETM_XPORT_IOCTL_DATA_PEEK,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb &peek_ctl);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = ioctl(_conn->fd, ETM_XPORT_IOCTL_DATA_PEEK, &peek_ctl);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (n < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_os_peek_fail.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = peek_ctl.pk_buflen;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 3) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: [fake] ioctl(_PEEK) ~= %d bytes\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_raw_peek() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Design_Note:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * The transport device driver did not implement byte stream semantics
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * per the spec; its behavior is closer to that of a block device.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Consequently, ETM within its Transport API attempts to make the device
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * look like a byte stream by using an intermediate buffer in user space
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * and maintaining progress pointers within that buffer which is populated
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * in near-MTU sized reads. We think it's OK to leave the write side
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * implementation as it was originally written for byte stream semantics
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * because we were told subsequent write()s will pend until the earlier
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * content is read() at the remote end -- essentially each write() must be
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * paired with a single read() -- the device driver does not buffer any I/O.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * The early driver bugs of returning more data than requested (thus
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * causing buffer overrun corruptions/crashes) and requiring user buffers
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * to be stack based vs heap based, have both been corrected.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_buffered_read - try to read N <= MTU bytes from the connection
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or from an privately maintained intermediate buffer,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * into the caller's given buffer,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return how many bytes actually read
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * caveats:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * simple buffer scheme consumes 2x MTU bytes of memory and
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * may do unnecesssary memory copies for ease of coding
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbstatic ssize_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_buffered_read(fmd_hdl_t *hdl, _etm_xport_conn_t *_conn,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb void *buf, size_t byte_cnt)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t i, n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* perform one-time initializations */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Design_Note:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * These initializations are not done in etm_xport_init() because
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * the connection/device is not yet open and hence the MTU size
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * is not yet known. However, the corresponding cleanup is done
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * in etm_xport_fini(). The buffering for byte stream semantics
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * should be done on a per device vs per connection basis; the
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * MTU size is assumed to remain constant across all connections.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_irb_mtu_sz == 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = etm_xport_get_opt(hdl, _conn,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb ETM_XPORT_OPT_MTU_SZ)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_mtu_sz = ETM_XPORT_MTU_SZ_DEF;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_mtu_sz = n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_irb_area == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_area = fmd_hdl_zalloc(hdl,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb 2 * etm_xport_irb_mtu_sz, FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_head = etm_xport_irb_area;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_tail = etm_xport_irb_head;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* sanity check the byte count after have MTU */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (byte_cnt > etm_xport_irb_mtu_sz) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_buffread_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* if intermediate buffer can satisfy request do so w/out xport read */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (byte_cnt <= (etm_xport_irb_tail - etm_xport_irb_head)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) memcpy(buf, etm_xport_irb_head, byte_cnt);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_head += byte_cnt;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 2) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: quik buffered read == %d\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb byte_cnt);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (byte_cnt);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* slide buffer contents to front to make room for [MTU] more bytes */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = etm_xport_irb_tail - etm_xport_irb_head;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) memmove(etm_xport_irb_area, etm_xport_irb_head, n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_head = etm_xport_irb_area;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_tail = etm_xport_irb_head + n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * peek to see how much data is avail and read all of it;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * there is no race condition between peeking and reading
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * due to unbuffered design of the device driver
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd_t pollfd;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.events = POLLIN;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.revents = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.fd = _conn->fd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb if ((n = poll(&pollfd, 1, -1)) < 1) {
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb if (n == 0)
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb return (-EIO);
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb else
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb return (-errno);
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /*
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * set i to the maximum size --- read(..., i) below will
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn * pull in n bytes (n <= i) anyway
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn i = etm_xport_irb_mtu_sz;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((i = etm_xport_raw_peek(hdl, _conn, etm_xport_irb_tail,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb etm_xport_irb_mtu_sz)) < 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (i);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = read(_conn->fd, etm_xport_irb_tail, i)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_os_read_fail.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_tail += n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* satisfy request as best we can with what we now have */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = MIN(byte_cnt, (etm_xport_irb_tail - etm_xport_irb_head));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) memcpy(buf, etm_xport_irb_head, n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_head += n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 2) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: slow buffered read == %d\n", n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_buffered_read() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * ------------------ connection establishment functions ---------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_init - initialize/setup any transport infrastructure
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * before any connections are opened,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return 0 or -errno value if initialization failed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbint
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_init(fmd_hdl_t *hdl)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t **_addrv; /* address vector */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int i; /* vector index */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb struct stat stat_buf; /* file stat struct */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb char *fn; /* filename of dev node */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = 0; /* assume good */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (hdl == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: xport initializing\n");
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* setup statistics and properties from FMD */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb sizeof (etm_xport_stats) / sizeof (fmd_stat_t),
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (fmd_stat_t *)&etm_xport_stats);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_debug_lvl = fmd_prop_get_int32(hdl, ETM_PROP_NM_DEBUG_LVL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_addrs = fmd_prop_get_string(hdl, ETM_PROP_NM_XPORT_ADDRS);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: etm_xport_debug_lvl %d\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb etm_xport_debug_lvl);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: etm_xport_addrs %s\n", etm_xport_addrs);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* decide whether to fake [some of] the device driver behavior */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_should_fake_dd = 0; /* default to false */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fn = etm_xport_get_fn(hdl, ETM_IO_OP_RD);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (stat(fn, &stat_buf) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_error(hdl, "error: bad device node %s errno %d\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb fn, errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (!S_ISCHR(stat_buf.st_mode) && use_vldc == 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_should_fake_dd = 1; /* not a char driver */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: etm_xport_should_fake_dd %d\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb etm_xport_should_fake_dd);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* validate each default dst transport address */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((_addrv = (void *)etm_xport_get_ev_addrv(hdl, NULL)) == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb for (i = 0; _addrv[i] != NULL; i++) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = etm_xport_valid_addr(_addrv[i])) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_error(hdl, "error: bad xport addr %p\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb _addrv[i]);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = n;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* foreach dst addr */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_vldc_conn = etm_xport_open(hdl, _addrv[0]);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (etm_xport_vldc_conn == NULL) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fmd_hdl_debug(hdl, "info: etm_xport_open() failed\n");
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rbfunc_ret:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addrv != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_free_addrv(hdl, (void *)_addrv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (rv >= 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: xport initialized ok\n");
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_init() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_open - open a connection with the given endpoint,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the connection handle,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno if open failed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * Design_Note: The current transport device driver's open()
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * call will succeed even if the SP is down;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * hence there's currently no need for a retry
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * mechanism.
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_conn_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_open(fmd_hdl_t *hdl, etm_xport_addr_t addr)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *_addr; /* address handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = etm_xport_valid_addr(addr)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = (-n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (NULL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = etm_xport_dup_addr(hdl, addr);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* allocate a connection handle and start populating it */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = fmd_hdl_zalloc(hdl, sizeof (_etm_xport_conn_t), FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc == 0 || etm_xport_vldc_conn == NULL) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((_conn->fd = open(_addr->fn,
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb ETM_XPORT_OPEN_FLAGS, 0)) == -1) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /* errno assumed set by above call */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_free_addr(hdl, _addr);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fmd_hdl_free(hdl, _conn, sizeof (_etm_xport_conn_t));
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_stats.xport_os_open_fail.fmds_value.ui64++;
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (void) pthread_mutex_unlock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc && etm_xport_vldc_conn == NULL) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn vldc_opt_op_t op;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /* Set the channel to reliable mode */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn op.op_sel = VLDC_OP_SET;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn op.opt_sel = VLDC_OPT_MODE;
20ae46ebaff1237662e05edf9db61538aa85d448ha op.opt_val = LDC_MODE_RELIABLE;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (ioctl(_conn->fd, VLDC_IOCTL_OPT_OP, &op) != 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn /* errno assumed set by above call */
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) close(_conn->fd);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_free_addr(hdl, _addr);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn fmd_hdl_free(hdl, _conn, sizeof (_etm_xport_conn_t));
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb etm_xport_stats.xport_os_ioctl_fail.fmds_value.ui64++;
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (void) pthread_mutex_unlock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (NULL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_vldc_conn = _conn;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (use_vldc && etm_xport_vldc_conn != NULL) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn _conn->fd = dup(etm_xport_vldc_conn->fd);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* return the fully formed connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn->magic_num = ETM_XPORT_DD_MAGIC_CONN;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn->addr = _addr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (_conn);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_open() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_accept - accept a request to open a connection,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * pending until a remote endpoint opens a
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * a new connection to us [and sends an ETM msg],
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * per non-NULL addrp optionally indicate the
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * remote address if known/avail (NULL if not),
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the connection handle,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno on failure
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * caveats:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * any returned transport address is valid only for
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * as long as the associated connection remains open;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * callers should not try to free the transport address
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * if new connections are rapid relative to how
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * frequently this function is called, fairness will
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * be provided among which connections are accepted
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * this function may maintain state to recognize [new]
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * connections and/or to provide fairness
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_conn_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_accept(fmd_hdl_t *hdl, etm_xport_addr_t *addrp)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *_addr; /* address handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t **_addrv; /* vector of addresses */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb uint8_t buf[4]; /* buffer for peeking */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int n; /* byte cnt */
e2ff4ac63d83b80a04de28e4d3d6068fe781fa12rb struct timespec tms; /* for nanosleep() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = NULL; /* default is failure */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
e2ff4ac63d83b80a04de28e4d3d6068fe781fa12rb tms.tv_sec = ETM_SLEEP_QUIK;
e2ff4ac63d83b80a04de28e4d3d6068fe781fa12rb tms.tv_nsec = 0;
e2ff4ac63d83b80a04de28e4d3d6068fe781fa12rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * get the default dst transport address and open a connection to it;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * there is only 1 default addr
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((_addrv = (void*)etm_xport_get_ev_addrv(hdl, NULL)) == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addrv[0] == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = ENXIO; /* missing addr */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_accept_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addrv[1] != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = E2BIG; /* too many addrs */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_accept_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = _addrv[0];
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr->fn = etm_xport_get_fn(hdl, ETM_IO_OP_RD);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((_conn = etm_xport_open(hdl, _addr)) == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_should_fake_dd) {
e2ff4ac63d83b80a04de28e4d3d6068fe781fa12rb (void) nanosleep(&tms, NULL); /* delay [for resp capture] */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) ftruncate(_conn->fd, 0); /* act like socket/queue/pipe */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * peek from the connection to simulate an accept() system call
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * behavior; this will pend until some ETM message is written
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * from the other end
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd_t pollfd;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.events = POLLIN;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.revents = 0;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn pollfd.fd = _conn->fd;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb if ((n = poll(&pollfd, 1, -1)) < 1) {
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb if (n == 0) {
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb errno = EIO;
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn goto func_ret;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if ((n = etm_xport_raw_peek(hdl, _conn, buf, 1)) < 0) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn errno = (-n);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn goto func_ret;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = _conn; /* success, return the open connection */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbfunc_ret:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* cleanup the connection if failed */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (rv == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_conn != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb (void) etm_xport_close(hdl, _conn);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (addrp != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *addrp = _conn->addr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* free _addrv and all its transport addresses */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_addrv != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_free_addrv(hdl, (void *)_addrv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_debug_lvl >= 2) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: accept conn %p w/ *addrp %p\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb rv, (addrp != NULL ? *addrp : NULL));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_accept() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_close - close a connection from either endpoint,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the original connection handle,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno if close failed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_conn_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_close(fmd_hdl_t *hdl, etm_xport_conn_t conn)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_conn_t rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int nev; /* -errno val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = conn;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = _conn; /* assume success */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((nev = etm_xport_valid_conn(_conn)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb goto func_ret;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* close the device node */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_lock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (close(_conn->fd) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_os_close_fail.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb nev = (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc && (_conn == etm_xport_vldc_conn)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_vldc_conn = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) pthread_mutex_unlock(&etm_xport_vldc_lock);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rbfunc_ret:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* cleanup the connection */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (_conn != NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_free_addr(hdl, _conn->addr);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn->addr = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn->magic_num = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn->fd = -1;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_free(hdl, _conn, sizeof (_etm_xport_conn_t));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (rv == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = (-nev);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_close() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_get_ev_addrv - indicate which transport addresses
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * are implied as destinations by the
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * given FMA event, if given no FMA event
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * (NULL) indicate default or policy
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * driven dst transport addresses,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return an allocated NULL terminated
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * vector of allocated transport addresses,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno if none
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * caveats:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * callers should never try to individually free an addr
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * within the returned vector
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_addr_t *
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_get_ev_addrv(fmd_hdl_t *hdl, nvlist_t *evp)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *_addr; /* address handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t **_addrv; /* vector of addresses */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (evp == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * allocate address handles for default/policy destinations
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * in reality we have just 1 dst transport addr
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = fmd_hdl_zalloc(hdl, sizeof (_etm_xport_addr_t),
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * allocate address handles per FMA event content
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * in reality we have just 1 dst transport addr
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = fmd_hdl_zalloc(hdl, sizeof (_etm_xport_addr_t),
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* whether caller passed in a FMA event */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* allocate vector with 1 non-NULL transport addr */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv = fmd_hdl_zalloc(hdl, 2 * sizeof (_etm_xport_addr_t *),
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr->fn = etm_xport_get_fn(hdl, ETM_IO_OP_WR);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr->magic_num = ETM_XPORT_DD_MAGIC_ADDR;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv[0] = _addr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv[1] = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return ((void *) _addrv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_get_ev_addrv() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_free_addrv - free the given vector of transport addresses,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * including each transport address
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbvoid
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_free_addrv(fmd_hdl_t *hdl, etm_xport_addr_t *addrv)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t **_addrv; /* vector of addrs */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int i; /* vector index */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (addrv == NULL) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_free_addrv_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv = (void*)addrv;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb for (i = 0; _addrv[i] != NULL; i++) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_free_addr(hdl, _addrv[i]);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addrv[i] = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_free(hdl, _addrv, (i + 1) * sizeof (_etm_xport_addr_t *));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_free_addrv() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_get_addr_conn - indicate which connections in a NULL
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * terminated vector of connection
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * handles are associated with the
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * given transport address,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return an allocated NULL terminated
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * vector of those connection handles,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno if none
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_conn_t *
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_get_addr_conn(fmd_hdl_t *hdl, etm_xport_conn_t *connv,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_addr_t addr)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t **_connv; /* vector of connections */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t **_mcv; /* matching connections vector */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_addr_t *_addr; /* transport addr to match */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int n; /* matching transport addr cnt */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int i; /* vector index */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((connv == NULL) || (addr == NULL)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = EINVAL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_get_addr_conn_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (NULL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _connv = (void*)connv;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _addr = (void*)addr;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* count, allocate space for, and copy, all matching addrs */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb for (i = 0; _connv[i] != NULL; i++) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((_connv[i]->addr == _addr) ||
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb ((_connv[i]->addr != NULL) &&
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (_connv[i]->addr->fn == _addr->fn))) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* for counting how many addresses match */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _mcv = fmd_hdl_zalloc(hdl, (n + 1) * sizeof (_etm_xport_conn_t *),
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb FMD_SLEEP);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb for (i = 0; _connv[i] != NULL; i++) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((_connv[i]->addr == _addr) ||
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb ((_connv[i]->addr != NULL) &&
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (_connv[i]->addr->fn == _addr->fn))) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _mcv[n] = _connv[i];
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } /* for copying matching address pointers */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _mcv[n] = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return ((void *) _mcv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_get_addr_conn() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_get_any_lcc - indicate which endpoint has undergone
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * a life cycle change and what that change
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * was (ex: came up), pending until a change
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * has occured for some/any endpoint,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the appropriate address handle,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or NULL and set errno if problem
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * caveats:
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * this function maintains or accesses state/history
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * regarding life cycle changes of endpoints
733a5356058ae0150a67d61f0ad8e5260d2acae3rb *
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * if life cycle changes are rapid relative to how
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * frequently this function is called, fairness will
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * be provided among which endpoints are reported
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_addr_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_get_any_lcc(fmd_hdl_t *hdl, etm_xport_lcc_t *lccp)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((hdl == NULL) || (lccp == NULL)) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_get_any_lcc_badargs.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = EINVAL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (NULL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * function not needed in FMA Phase 1 for sun4v/Ontario
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb errno = ENOTSUP;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (NULL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_get_any_lcc() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_fini - finish/teardown any transport infrastructure
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * after all connections are closed,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return 0 or -errno value if teardown failed
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbint
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_fini(fmd_hdl_t *hdl)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: xport finalizing\n");
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (use_vldc && (etm_xport_vldc_conn != NULL)) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn (void) etm_xport_close(hdl, etm_xport_vldc_conn);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn etm_xport_vldc_conn = NULL;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* free any long standing properties from FMD */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_prop_free_string(hdl, etm_xport_addrs);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* cleanup the intermediate read buffer */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_irb_tail != etm_xport_irb_head) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "warning: xport %d bytes stale data\n",
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb (int)(etm_xport_irb_tail - etm_xport_irb_head));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_free(hdl, etm_xport_irb_area, 2 * etm_xport_irb_mtu_sz);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_area = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_head = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_tail = NULL;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_irb_mtu_sz = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb /* cleanup statistics from FMD */
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb (void) fmd_stat_destroy(hdl,
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb sizeof (etm_xport_stats) / sizeof (fmd_stat_t),
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb (fmd_stat_t *)&etm_xport_stats);
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb fmd_hdl_debug(hdl, "info: xport finalized ok\n");
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (0);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_fini() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * ------------------------ input/output functions ---------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_read - try to read N bytes from the connection
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * into the given buffer,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return how many bytes actually read
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbssize_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_read(fmd_hdl_t *hdl, etm_xport_conn_t conn, void *buf,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb size_t byte_cnt)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (etm_xport_buffered_read(hdl, conn, buf, byte_cnt));
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_read() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_write - try to write N bytes to the connection
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * from the given buffer,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return how many bytes actually written
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbssize_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_write(fmd_hdl_t *hdl, etm_xport_conn_t conn, void *buf,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb size_t byte_cnt)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb int n; /* byte cnt */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = conn;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (hdl == NULL) { /* appease lint */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = etm_xport_valid_conn(_conn)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* write to the connection device's open file descriptor */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = write(_conn->fd, buf, byte_cnt)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_stats.xport_os_write_fail.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = (-errno);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_write() */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * ------------------------ miscellaneous functions --------------------------
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb/*
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * etm_xport_get_opt - get a connection's transport option value,
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * return the current value
733a5356058ae0150a67d61f0ad8e5260d2acae3rb * or -errno value (ex: -ENOTSUP)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rbssize_t
733a5356058ae0150a67d61f0ad8e5260d2acae3rbetm_xport_get_opt(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_xport_opt_t opt)
733a5356058ae0150a67d61f0ad8e5260d2acae3rb{
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t rv; /* ret val */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _etm_xport_conn_t *_conn; /* connection handle */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb etm_xport_opt_op_t op_ctl; /* struct for option ops */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb ssize_t n; /* gen use */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = 0;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb _conn = conn;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (hdl == NULL) { /* appease lint */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (-EINVAL);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if ((n = etm_xport_valid_conn(_conn)) < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (n);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb op_ctl.oo_op = ETM_XPORT_OPT_GET;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb op_ctl.oo_opt = opt;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (etm_xport_should_fake_dd) {
b8677b7267ab10505b6cad6e53eef7ca24ba2eaarb n = etm_fake_ioctl(_conn->fd, ETM_XPORT_IOCTL_OPT_OP, &op_ctl);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else if (use_vldc) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn if (opt == ETM_XPORT_OPT_MTU_SZ) {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn vldc_opt_op_t operation;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn operation.op_sel = VLDC_OP_GET;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn operation.opt_sel = VLDC_OPT_MTU_SZ;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn n = ioctl(_conn->fd, VLDC_IOCTL_OPT_OP, &operation);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn op_ctl.oo_val = operation.opt_val;
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn } else {
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn return (-EINVAL);
31e37bb439502e3f7c4c0a9a77d655ea5d56887avn }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb n = ioctl(_conn->fd, ETM_XPORT_IOCTL_OPT_OP, &op_ctl);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb if (n < 0) {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb /* errno assumed set by above call */
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (-errno);
2ca9f232d5e039a8f2de8723786dbf6248bf9e1erb etm_xport_stats.xport_os_ioctl_fail.fmds_value.ui64++;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb } else {
733a5356058ae0150a67d61f0ad8e5260d2acae3rb rv = (int)op_ctl.oo_val;
733a5356058ae0150a67d61f0ad8e5260d2acae3rb }
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb return (rv);
733a5356058ae0150a67d61f0ad8e5260d2acae3rb
733a5356058ae0150a67d61f0ad8e5260d2acae3rb} /* etm_xport_get_opt() */