25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#pragma ident "%Z%%M% %I% %E% SMI"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMA Event Transport Module
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Plugin for sending/receiving FMA events to/from a remote endoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <netinet/in.h>
77a7fd96f77f04bbd7634db14755686062589ecajrutt#include <errno.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/fm/protocol.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/sysmacros.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <pthread.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <strings.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <ctype.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <link.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <libnvpair.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include "etm_xport_api.h"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include "etm_proto.h"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM declarations
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef enum etm_connection_status {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl C_UNINITIALIZED = 0,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl C_OPEN, /* Connection is open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl C_CLOSED, /* Connection is closed */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl C_LIMBO, /* Bad value in header from peer */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl C_TIMED_OUT /* Reconnection to peer timed out */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} etm_connstat_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef enum etm_fmd_queue_status {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Q_UNINITIALIZED = 100,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Q_INIT_PENDING, /* Queue initialization in progress */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Q_OPEN, /* Queue is open */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Q_SUSPENDED /* Queue is suspended */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} etm_qstat_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Per endpoint data */
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef struct etm_endpoint_map {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl uint8_t epm_ver; /* Protocol version being used */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *epm_ep_str; /* Endpoint ID string */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int epm_xprtflags; /* FMD transport open flags */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_xport_hdl_t epm_tlhdl; /* Transport Layer instance handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl pthread_mutex_t epm_lock; /* Protects remainder of struct */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl pthread_cond_t epm_tx_cv; /* Cond var for send/transmit */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int epm_txbusy; /* Busy doing send/transmit */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_t *epm_xprthdl; /* FMD transport handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_qstat_t epm_qstat; /* Status of fmd xprt queue */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_t *epm_ep_nvl; /* Endpoint ID nv_list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_xport_conn_t epm_oconn; /* Connection for outgoing events */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_connstat_t epm_cstat; /* Status of connection */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl id_t epm_timer_id; /* Timer id */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int epm_timer_in_use; /* Indicates if timer is in use */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hrtime_t epm_reconn_end; /* Reconnection end time */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct etm_endpoint_map *epm_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} etm_epmap_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_HDR_INVALID (ETM_HDR_TYPE_TOO_HIGH + 1)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_HDR_BADVERSION (ETM_HDR_TYPE_TOO_HIGH + 2)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_HDR_BADTYPE (ETM_HDR_TYPE_TOO_HIGH + 3)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_EP_INST_MAX 4 /* Max chars in endpt instance */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_CLIENT_XPRT_FLAGS FMD_XPRT_RDWR
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ETM_SERVER_XPRT_FLAGS (FMD_XPRT_RDWR | FMD_XPRT_ACCEPT)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ALLOC_BUF(hdl, buf, size) \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl buf = fmd_hdl_zalloc((hdl), (size), FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define FREE_BUF(hdl, buf, size) fmd_hdl_free((hdl), (buf), (size));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define IS_CLIENT(mp) (((mp)->epm_xprtflags & FMD_XPRT_ACCEPT) ? 0 : 1)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define INCRSTAT(x) { (void) pthread_mutex_lock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (x)++; \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define DECRSTAT(x) { (void) pthread_mutex_lock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (x)--; \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define ADDSTAT(x, y) { (void) pthread_mutex_lock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (x) += (y); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock); \
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Global variables
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic pthread_mutex_t Etm_mod_lock = PTHREAD_MUTEX_INITIALIZER;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Protects globals */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic hrtime_t Reconn_interval; /* Time between reconnection attempts */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic hrtime_t Reconn_timeout; /* Time allowed for reconnection */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic hrtime_t Rw_timeout; /* Time allowed for I/O operation */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int Etm_dump = 0; /* Enables hex dump for debug */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int Etm_exit = 0; /* Flag for exit */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic etm_epmap_t *Epmap_head = NULL; /* Head of list of epmap structs */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Module statistics */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic struct etm_stats {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* read counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t read_ack;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t read_bytes;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t read_msg;
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_stat_t post_filter;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* write counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t write_ack;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t write_bytes;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t write_msg;
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_stat_t send_filter;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* error counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t error_protocol;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t error_drop_read;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t error_read;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t error_read_badhdr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t error_write;
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_stat_t error_send_filter;
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_stat_t error_post_filter;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* misc */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_stat_t peer_count;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} Etm_stats = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* read counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "read_ack", FMD_TYPE_UINT64, "ACKs read" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "read_bytes", FMD_TYPE_UINT64, "Bytes read" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "read_msg", FMD_TYPE_UINT64, "Messages read" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "post_filter", FMD_TYPE_UINT64, "Drops by post_filter" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* write counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "write_ack", FMD_TYPE_UINT64, "ACKs sent" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "write_bytes", FMD_TYPE_UINT64, "Bytes sent" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "write_msg", FMD_TYPE_UINT64, "Messages sent" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "send_filter", FMD_TYPE_UINT64, "Drops by send_filter" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* ETM error counters */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "error_protocol", FMD_TYPE_UINT64, "ETM protocol errors" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "error_drop_read", FMD_TYPE_UINT64, "Dropped read messages" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "error_read", FMD_TYPE_UINT64, "Read I/O errors" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "error_read_badhdr", FMD_TYPE_UINT64, "Bad headers read" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "error_write", FMD_TYPE_UINT64, "Write I/O errors" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "error_send_filter", FMD_TYPE_UINT64, "Send filter errors" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "error_post_filter", FMD_TYPE_UINT64, "Post filter errors" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* ETM Misc */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "peer_count", FMD_TYPE_UINT64, "Number of peers initialized" },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM Private functions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Hex dump for debug.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_hex_dump(fmd_hdl_t *hdl, void *buf, size_t buflen, int direction)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int i, j, k;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int16_t *c;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Etm_dump == 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl j = buflen / 16; /* Number of complete 8-column rows */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl k = buflen % 16; /* Is there a last (non-8-column) row? */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (direction)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "--- WRITE Message Dump ---");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "--- READ Message Dump ---");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, " Displaying %d bytes", buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Dump the complete 8-column rows */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = 0; i < j; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl c = (int16_t *)buf + (i * 8);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "%3d: %4x %4x %4x %4x %4x %4x %4x %4x", i,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *(c+0), *(c+1), *(c+2), *(c+3),
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *(c+4), *(c+5), *(c+6), *(c+7));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Dump the last (incomplete) row */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl c = (int16_t *)buf + (i * 8);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (k) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case 4:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "%3d: %4x %4x", i, *(c+0), *(c+1));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case 8:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "%3d: %4x %4x %4x %4x", i, *(c+0), *(c+1),
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *(c+2), *(c+3));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case 12:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "%3d: %4x %4x %4x %4x %4x %4x", i, *(c+0),
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *(c+1), *(c+2), *(c+3), *(c+4), *(c+5));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "--- End Dump ---");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Provide the length of a message based on the data in the given ETM header.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic size_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_get_msglen(void *buf)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_proto_hdr_t *hp = (etm_proto_hdr_t *)buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ntohl(hp->hdr_msglen));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Check the contents of the ETM header for errors.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return the header type (hdr_type).
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_check_hdr(fmd_hdl_t *hdl, etm_epmap_t *mp, void *buf)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_proto_hdr_t *hp = (etm_proto_hdr_t *)buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (bcmp(hp->hdr_delim, ETM_DELIM, ETM_DELIMLEN) != 0) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "Bad delimiter in ETM header from %s "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ": 0x%x\n", mp->epm_ep_str, hp->hdr_delim);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ETM_HDR_INVALID);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->hdr_type == ETM_HDR_C_HELLO) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (hp->hdr_type == ETM_HDR_S_HELLO)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Until version is negotiated, other fields may be wrong */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (hp->hdr_type);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->hdr_ver != mp->epm_ver) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "Bad version in ETM header from %s : 0x%x\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str, hp->hdr_ver);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ETM_HDR_BADVERSION);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->hdr_type == ETM_HDR_TYPE_TOO_LOW) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (hp->hdr_type >= ETM_HDR_TYPE_TOO_HIGH)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "Bad type in ETM header from %s : 0x%x\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str, hp->hdr_type);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ETM_HDR_BADTYPE);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (hp->hdr_type);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Create an ETM header of a given type in the given buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return length of header.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic size_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_create_hdr(void *buf, uint8_t ver, uint8_t type, uint32_t msglen)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_proto_hdr_t *hp = (etm_proto_hdr_t *)buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl bcopy(ETM_DELIM, hp->hdr_delim, ETM_DELIMLEN);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->hdr_ver = ver;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->hdr_type = type;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->hdr_msglen = htonl(msglen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ETM_HDRLEN);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Convert message bytes to nvlist and post to fmd.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return zero for success, non-zero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Note : nvl is free'd by fmd.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_post_msg(fmd_hdl_t *hdl, etm_epmap_t *mp, void *buf, size_t buflen)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_t *nvl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nvlist_unpack((char *)buf, buflen, &nvl, 0)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "failed to unpack message");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt rv = etm_xport_post_filter(hdl, nvl, mp->epm_ep_str);
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (rv == ETM_XPORT_FILTER_DROP) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "post_filter dropped event");
77a7fd96f77f04bbd7634db14755686062589ecajrutt INCRSTAT(Etm_stats.post_filter.fmds_value.ui64);
77a7fd96f77f04bbd7634db14755686062589ecajrutt nvlist_free(nvl);
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (0);
77a7fd96f77f04bbd7634db14755686062589ecajrutt } else if (rv == ETM_XPORT_FILTER_ERROR) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "post_filter error : %s", strerror(errno));
77a7fd96f77f04bbd7634db14755686062589ecajrutt INCRSTAT(Etm_stats.error_post_filter.fmds_value.ui64);
77a7fd96f77f04bbd7634db14755686062589ecajrutt /* Still post event */
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (!Etm_exit) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_qstat == Q_OPEN) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_post(hdl, mp->epm_xprthdl, nvl, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (mp->epm_qstat == Q_SUSPENDED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_resume(hdl, mp->epm_xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_timer_in_use) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_timer_remove(hdl, mp->epm_timer_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue resumed for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_post(hdl, mp->epm_xprthdl, nvl, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "unable to post message, qstat = %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt nvlist_free(nvl);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /* Remote peer will attempt to resend event */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 2;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "unable to post message, module exiting");
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt nvlist_free(nvl);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /* Remote peer will attempt to resend event */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 3;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Handle the startup handshake to the server. The client always initiates
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the startup handshake. In the following sequence, we are the client and
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the remote endpoint is the server.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Client sends C_HELLO and transitions to Q_INIT_PENDING state.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Server sends S_HELLO and transitions to Q_INIT_PENDING state.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Client sends ACK and transitions to Q_OPEN state.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Server receives ACK and transitions to Q_OPEN state.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_handle_startup(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_proto_hdr_t *hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size_t hdrlen = ETM_HDRLEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int hdrstat;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char hbuf[ETM_HDRLEN];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_oconn = etm_xport_open(hdl, mp->epm_tlhdl)) == NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_C_HELLO, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, mp->epm_oconn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Failed to write C_HELLO to %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (2);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_INIT_PENDING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_read(hdl, mp->epm_oconn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Failed to read S_HELLO from %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (3);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrstat = etm_check_hdr(hdl, mp, hbuf);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hdrstat != ETM_HDR_S_HELLO) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Protocol error, did not receive S_HELLO "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "from %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (4);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Get version from the server.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Currently, only one version is supported.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp = (etm_proto_hdr_t *)(void *)hbuf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->hdr_ver != ETM_PROTO_V1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Unable to use same version as %s : %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str, hp->hdr_ver);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (5);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ver = hp->hdr_ver;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_ACK, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, mp->epm_oconn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Failed to write ACK for S_HELLO to %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (6);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Call fmd_xprt_open and fmd_xprt_setspecific with
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Etm_mod_lock held to avoid race with etm_send thread.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_xprthdl = fmd_xprt_open(hdl, mp->epm_xprtflags,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_nvl, NULL)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_abort(hdl, "Failed to init xprthdl for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_setspecific(hdl, mp->epm_xprthdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue open for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt/*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Open a connection to the peer, send a SHUTDOWN message,
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * and close the connection.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt */
ac92251dc182f030faf6a5f76981d551b0b16072jruttstatic void
ac92251dc182f030faf6a5f76981d551b0b16072jruttetm_send_shutdown(fmd_hdl_t *hdl, etm_epmap_t *mp)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt{
ac92251dc182f030faf6a5f76981d551b0b16072jrutt size_t hdrlen = ETM_HDRLEN;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt char hbuf[ETM_HDRLEN];
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((mp->epm_oconn = etm_xport_open(hdl, mp->epm_tlhdl)) == NULL)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_SHUTDOWN, 0);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) etm_xport_write(hdl, mp->epm_oconn, Rw_timeout, hbuf, hdrlen);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) etm_xport_close(hdl, mp->epm_oconn);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt mp->epm_oconn = NULL;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt}
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Alloc a nvlist and add a string for the endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return zero for success, non-zero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_get_ep_nvl(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Cannot use nvlist_xalloc(3NVPAIR) due to a recursive mutex situation
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * in fmd when this nvlist_t is free'd.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) nvlist_alloc(&mp->epm_ep_nvl, NV_UNIQUE_NAME, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nvlist_add_string(mp->epm_ep_nvl, "domain-id", mp->epm_ep_str)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "failed to add domain-id string to nvlist "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_free(mp->epm_ep_nvl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Free the nvlist for the endpoint_id string.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_free_ep_nvl(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_free(mp->epm_ep_nvl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Check for a duplicate endpoint/peer string.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_check_dup_ep_str(fmd_hdl_t *hdl, char *epname)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *mp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (mp = Epmap_head; mp != NULL; mp = mp->epm_next)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (strcmp(epname, mp->epm_ep_str) == 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Attempt to re-open a connection with the remote endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_reconnect(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_reconn_end > 0) && (mp->epm_cstat == C_UNINITIALIZED)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (gethrtime() < mp->epm_reconn_end) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_oconn = etm_xport_open(hdl,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_tlhdl)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "reconnect failed for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_id = fmd_timer_install(hdl, mp,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, Reconn_interval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "reconnect success for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_reconn_end = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Reconnect timed out for %s\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_reconn_end = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_TIMED_OUT;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_cstat == C_OPEN) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_resume(hdl, mp->epm_xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue resumed for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Suspend a given connection and setup for reconnection retries.
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * Assume caller holds lock on epm_lock.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_suspend_reconnect(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Etm_exit) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_reconn_end = gethrtime() + Reconn_timeout;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_xprthdl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_suspend(hdl, mp->epm_xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_SUSPENDED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue suspended for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_timer_in_use == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_id = fmd_timer_install(hdl, mp, NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Reconn_interval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Reinitialize the connection. The old fmd_xprt_t handle must be
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * removed/closed first.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Assume caller holds lock on epm_lock.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_reinit(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * To avoid a deadlock, wait for etm_send to finish before
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * calling fmd_xprt_close()
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp->epm_txbusy)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_wait(&mp->epm_tx_cv, &mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_xprthdl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_close(hdl, mp->epm_xprthdl);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "queue closed for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_xprthdl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* mp->epm_ep_nvl is free'd in fmd_xprt_close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_nvl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_timer_in_use) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_timer_remove(hdl, mp->epm_timer_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Receive data from ETM transport layer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Note : This is not the fmdo_recv entry point.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_recv(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size_t buflen, hdrlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char hbuf[ETM_HDRLEN];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int hdrstat, rv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = ETM_HDRLEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_read(hdl, conn, Rw_timeout, hbuf, hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to read header from %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrstat = etm_check_hdr(hdl, mp, hbuf);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (hdrstat) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_INVALID:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_cstat == C_OPEN)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_CLOSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read_badhdr.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = ECANCELED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_BADTYPE:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_BADVERSION:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_NAK, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, conn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to write NAK to %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_write.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_LIMBO;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read_badhdr.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = ENOTSUP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_C_HELLO:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Client is initiating a startup handshake */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_reinit(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_INIT_PENDING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_S_HELLO, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, conn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to write S_HELLO to %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_write.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_ACK:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_qstat == Q_INIT_PENDING) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* This is client's ACK from startup handshake */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* mp->epm_ep_nvl is free'd in fmd_xprt_close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_ep_nvl == NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_get_ep_nvl(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Call fmd_xprt_open and fmd_xprt_setspecific with
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Etm_mod_lock held to avoid race with etm_send thread.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_xprthdl = fmd_xprt_open(hdl,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_xprtflags, mp->epm_ep_nvl, NULL)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_abort(hdl, "Failed to init xprthdl "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_setspecific(hdl, mp->epm_xprthdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue open for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "protocol error, not expecting ACK "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "from %s\n", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_protocol.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_SHUTDOWN:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "received shutdown from %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_reinit(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (IS_CLIENT(mp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A server shutdown is considered to be temporary.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare for reconnection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_id = fmd_timer_install(hdl, mp, NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Reconn_interval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = ECANCELED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_HDR_MSG:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_qstat == Q_UNINITIALIZED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Peer (client) is unaware that we've restarted */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ETM_HDR_S_RESTART, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, conn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to write S_RESTART "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "to %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_write.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ECANCELED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl buflen = etm_get_msglen(hbuf);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ALLOC_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_xport_read(hdl, conn, Rw_timeout, buf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl buflen) != buflen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to read message from %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.read_msg.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ADDSTAT(Etm_stats.read_bytes.fmds_value.ui64, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_hex_dump(hdl, buf, buflen, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_post_msg(hdl, mp, buf, buflen)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_drop_read.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver, ETM_HDR_ACK, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((etm_xport_write(hdl, conn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen)) != hdrlen) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to write ACK to %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_write.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (EIO);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.write_ack.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If we got this far and the current state of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * outbound/sending connection is TIMED_OUT or
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * LIMBO, then we should reinitialize it.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_cstat == C_TIMED_OUT ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat == C_LIMBO) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_resume(hdl, mp->epm_xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_timer_in_use) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_timer_remove(hdl, mp->epm_timer_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue resumed for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "protocol error, unexpected header "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "from %s : %d", mp->epm_ep_str, hdrstat);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_protocol.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM transport layer callback function.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The transport layer calls this function to :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (a) pass an incoming message (flag == ETM_CBFLAG_RECV)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (b) tell us to reinitialize the connection (flag == ETM_CBFLAG_REINIT)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_cb_func(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *mp = (etm_epmap_t *)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rv = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Etm_exit) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (ECANCELED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl switch (flag) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_CBFLAG_RECV:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = etm_recv(hdl, conn, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl case ETM_CBFLAG_REINIT:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_reinit(hdl, mp);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt etm_send_shutdown(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return ECANCELED so the transport layer will close the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * server connection. The transport layer is responsible for
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * reestablishing this connection (should a connection request
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * arrive from the peer).
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = ECANCELED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl default:
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "Unknown callback flag : 0x%x", flag);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = ENOTSUP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Allocate and initialize an etm_epmap_t struct for the given endpoint
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * name string.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_init_epmap(fmd_hdl_t *hdl, char *epname, int flags)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *newmap;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_check_dup_ep_str(hdl, epname)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "skipping duplicate peer : %s", epname);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap = fmd_hdl_zalloc(hdl, sizeof (etm_epmap_t), FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_ep_str = fmd_hdl_strdup(hdl, epname, FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_xprtflags = flags;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_cstat = C_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_qstat = Q_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_ver = ETM_PROTO_V1; /* Currently support one proto ver */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_txbusy = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_init(&newmap->epm_lock, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_init(&newmap->epm_tx_cv, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_get_ep_nvl(hdl, newmap)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, newmap->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, newmap, sizeof (etm_epmap_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_lock(&newmap->epm_lock);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((newmap->epm_tlhdl = etm_xport_init(hdl, newmap->epm_ep_str,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_cb_func, newmap)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "failed to init tlhdl for %s\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_free_ep_nvl(hdl, newmap);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_unlock(&newmap->epm_lock);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_destroy(&newmap->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, newmap->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, newmap, sizeof (etm_epmap_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (IS_CLIENT(newmap)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_handle_startup(hdl, newmap)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /*
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * For whatever reason, we could not complete the
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * startup handshake with the server. Set the timer
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * and try again.
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (newmap->epm_oconn != NULL) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) etm_xport_close(hdl, newmap->epm_oconn);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt newmap->epm_oconn = NULL;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt }
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt newmap->epm_cstat = C_UNINITIALIZED;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt newmap->epm_qstat = Q_UNINITIALIZED;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt newmap->epm_timer_id = fmd_timer_install(hdl, newmap,
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt NULL, Reconn_interval);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt newmap->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt } else {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * We may be restarting after a crash. If so, the client
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * may be unaware of this.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt etm_send_shutdown(hdl, newmap);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Add this transport instance handle to the list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl newmap->epm_next = Epmap_head;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Epmap_head = newmap;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_unlock(&newmap->epm_lock);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.peer_count.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Parse the given property list string and call etm_init_epmap
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * for each endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_create_epmaps(fmd_hdl_t *hdl, char *eplist, int flags)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *epstr, *ep, *prefix, *lasts, *numstr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char epname[MAXPATHLEN];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size_t slen, nlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int beg, end, i;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (eplist == NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Create a copy of eplist for parsing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * strtok/strtok_r(3C) will insert null chars to the string.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Therefore, fmd_hdl_strdup/fmd_hdl_strfree cannot be used.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl slen = strlen(eplist);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl epstr = fmd_hdl_zalloc(hdl, slen + 1, FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) strcpy(epstr, eplist);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The following are supported for the "client_list" and
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * "server_list" properties :
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A space-separated list of endpoints.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * "dev:///dom0 dev:///dom1 dev:///dom2"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * An array syntax for a range of instances.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * "dev:///dom[0:2]"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * A combination of both.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * "dev:///dom0 dev:///dom[1:2]"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(epstr, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (ep != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (strchr(ep, '[') != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * This string is using array syntax.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Check the string for correct syntax.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((strchr(ep, ':') == NULL) ||
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (strchr(ep, ']') == NULL)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Syntax error in property "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "that includes : %s\n", ep);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(NULL, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* expand the array syntax */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl prefix = strtok(ep, "[");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl numstr = strtok(NULL, ":");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((numstr == NULL) || (!isdigit(*numstr))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Syntax error in property "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "that includes : %s[\n", prefix);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(NULL, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl beg = atoi(numstr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl numstr = strtok(NULL, "]");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((numstr == NULL) || (!isdigit(*numstr))) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Syntax error in property "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "that includes : %s[\n", prefix);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(NULL, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl end = atoi(numstr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nlen = strlen(prefix) + ETM_EP_INST_MAX;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nlen > MAXPATHLEN) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Endpoint prop string "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "exceeds MAXPATHLEN\n");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(NULL, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (i = beg; i <= end; i++) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl bzero(epname, MAXPATHLEN);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) snprintf(epname, nlen, "%s%d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl prefix, i);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_init_epmap(hdl, epname, flags);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_init_epmap(hdl, ep, flags);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ep = strtok_r(NULL, " ", &lasts);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, epstr, slen + 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Free the transport infrastructure for an endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_free_epmap(fmd_hdl_t *hdl, etm_epmap_t *mp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size_t hdrlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char hbuf[ETM_HDRLEN];
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If an etm_send thread is in progress, wait for it to finish.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The etm_recv thread is managed by the transport layer and will
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * be destroyed with etm_xport_fini().
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp->epm_txbusy)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_wait(&mp->epm_tx_cv, &mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_timer_in_use)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_timer_remove(hdl, mp->epm_timer_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = etm_create_hdr(hbuf, mp->epm_ver,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ETM_HDR_SHUTDOWN, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_write(hdl, mp->epm_oconn, Rw_timeout, hbuf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_xprthdl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_close(hdl, mp->epm_xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* mp->epm_ep_nvl is free'd in fmd_xprt_close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_ep_nvl = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_ep_nvl != NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_free_ep_nvl(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_tlhdl != NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_fini(hdl, mp->epm_tlhdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_destroy(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, mp, sizeof (etm_epmap_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl DECRSTAT(Etm_stats.peer_count.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMD entry points
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMD fmdo_send entry point.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Send an event to the remote endpoint and receive an ACK.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_send(fmd_hdl_t *hdl, fmd_xprt_t *xprthdl, fmd_event_t *ep, nvlist_t *nvl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *mp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_t *msgnvl;
77a7fd96f77f04bbd7634db14755686062589ecajrutt int hdrstat, rv, cnt = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *buf, *nvbuf, *class;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl size_t nvsize, buflen, hdrlen;
77a7fd96f77f04bbd7634db14755686062589ecajrutt struct timespec tms;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Etm_exit) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp = fmd_xprt_getspecific(hdl, xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt for (;;) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (pthread_mutex_trylock(&mp->epm_lock) == 0) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt break;
77a7fd96f77f04bbd7634db14755686062589ecajrutt } else {
77a7fd96f77f04bbd7634db14755686062589ecajrutt /*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * Another thread may be (1) trying to close this
77a7fd96f77f04bbd7634db14755686062589ecajrutt * fmd_xprt_t, or (2) posting an event to it.
77a7fd96f77f04bbd7634db14755686062589ecajrutt * If (1), don't want to spend too much time here.
77a7fd96f77f04bbd7634db14755686062589ecajrutt * If (2), allow it to finish and release epm_lock.
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (cnt++ < 10) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt tms.tv_sec = 0;
77a7fd96f77f04bbd7634db14755686062589ecajrutt tms.tv_nsec = (cnt * 10000);
77a7fd96f77f04bbd7634db14755686062589ecajrutt (void) nanosleep(&tms, NULL);
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt } else {
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (FMD_SEND_RETRY);
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy++;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (mp->epm_qstat == Q_UNINITIALIZED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt return (FMD_SEND_FAILED);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt }
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (mp->epm_cstat == C_CLOSED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_suspend_reconnect(hdl, mp);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_txbusy--;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_cstat == C_LIMBO) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_suspend(hdl, xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_SUSPENDED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "queue suspended for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_oconn == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((mp->epm_oconn = etm_xport_open(hdl, mp->epm_tlhdl))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl == NULL) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt etm_suspend_reconnect(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_OPEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nvlist_lookup_string(nvl, FM_CLASS, &class) != 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_abort(hdl, "No class string in nvlist");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl msgnvl = fmd_xprt_translate(hdl, xprthdl, ep);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (msgnvl == NULL) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_txbusy--;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Failed to translate event %p\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void *) ep);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_FAILED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt rv = etm_xport_send_filter(hdl, msgnvl, mp->epm_ep_str);
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (rv == ETM_XPORT_FILTER_DROP) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt mp->epm_txbusy--;
77a7fd96f77f04bbd7634db14755686062589ecajrutt (void) pthread_cond_broadcast(&mp->epm_tx_cv);
77a7fd96f77f04bbd7634db14755686062589ecajrutt (void) pthread_mutex_unlock(&mp->epm_lock);
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "send_filter dropped event");
77a7fd96f77f04bbd7634db14755686062589ecajrutt nvlist_free(msgnvl);
77a7fd96f77f04bbd7634db14755686062589ecajrutt INCRSTAT(Etm_stats.send_filter.fmds_value.ui64);
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (FMD_SEND_SUCCESS);
77a7fd96f77f04bbd7634db14755686062589ecajrutt } else if (rv == ETM_XPORT_FILTER_ERROR) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "send_filter error : %s", strerror(errno));
77a7fd96f77f04bbd7634db14755686062589ecajrutt INCRSTAT(Etm_stats.error_send_filter.fmds_value.ui64);
77a7fd96f77f04bbd7634db14755686062589ecajrutt /* Still send event */
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) nvlist_size(msgnvl, &nvsize, NV_ENCODE_XDR);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen = ETM_HDRLEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl buflen = nvsize + hdrlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ALLOC_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvbuf = buf + hdrlen;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_create_hdr(buf, mp->epm_ver, ETM_HDR_MSG, nvsize);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (rv = nvlist_pack(msgnvl, &nvbuf, &nvsize, NV_ENCODE_XDR, 0)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) pthread_mutex_lock(&mp->epm_lock);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_txbusy--;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_error(hdl, "Failed to pack event : %s\n", strerror(rv));
77a7fd96f77f04bbd7634db14755686062589ecajrutt nvlist_free(msgnvl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_FAILED);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nvlist_free(msgnvl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_xport_write(hdl, mp->epm_oconn, Rw_timeout, buf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl buflen) != buflen) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "failed to send message to %s",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt etm_suspend_reconnect(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_write.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.write_msg.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ADDSTAT(Etm_stats.write_bytes.fmds_value.ui64, nvsize);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_hex_dump(hdl, nvbuf, nvsize, 1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_xport_read(hdl, mp->epm_oconn, Rw_timeout, buf,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrlen) != hdrlen) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "failed to read ACK from %s",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt etm_suspend_reconnect(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_RETRY);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hdrstat = etm_check_hdr(hdl, mp, buf);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FREE_BUF(hdl, buf, buflen);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hdrstat == ETM_HDR_ACK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.read_ack.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_xport_close(hdl, mp->epm_oconn);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_oconn = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hdrstat == ETM_HDR_NAK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Peer received a bad value in the header */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_xprthdl != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_LIMBO;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_xprt_suspend(hdl, xprthdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_SUSPENDED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "received NAK, queue "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "suspended for %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = FMD_SEND_RETRY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (hdrstat == ETM_HDR_S_RESTART) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Server has restarted */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_cstat = C_CLOSED;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_qstat = Q_UNINITIALIZED;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "server %s restarted",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_ep_str);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /*
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * Cannot call fmd_xprt_close here, so we'll do it
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt * on the timeout thread.
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (mp->epm_timer_in_use == 0) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_timer_id = fmd_timer_install(
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt hdl, mp, NULL, 0);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fault.* or list.* events will be replayed if a
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * transport is opened with the same auth.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Other events will be discarded.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = FMD_SEND_FAILED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_cstat = C_CLOSED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "bad ACK from %s", mp->epm_ep_str);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv = FMD_SEND_RETRY;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl INCRSTAT(Etm_stats.error_read_badhdr.fmds_value.ui64);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_txbusy--;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_cond_broadcast(&mp->epm_tx_cv);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (FMD_SEND_SUCCESS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMD fmdo_timeout entry point..
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_timeout(fmd_hdl_t *hdl, id_t id, void *data)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *mp = (etm_epmap_t *)data;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_qstat == Q_UNINITIALIZED) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Server has shutdown and we (client) need to reconnect */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (mp->epm_xprthdl != NULL) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_xprt_close(hdl, mp->epm_xprthdl);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "queue closed for %s",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_ep_str);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_xprthdl = NULL;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /* mp->epm_ep_nvl is free'd in fmd_xprt_close */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_ep_nvl = NULL;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt }
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (mp->epm_ep_nvl == NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) etm_get_ep_nvl(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (etm_handle_startup(hdl, mp)) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (mp->epm_oconn != NULL) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) etm_xport_close(hdl, mp->epm_oconn);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_oconn = NULL;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt }
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt mp->epm_cstat = C_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_qstat = Q_UNINITIALIZED;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_id = fmd_timer_install(hdl, mp, NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Reconn_interval);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp->epm_timer_in_use = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_reconnect(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&mp->epm_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMD Module declarations
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic const fmd_hdl_ops_t etm_ops = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* fmdo_recv */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_timeout, /* fmdo_timeout */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* fmdo_close */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* fmdo_stats */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL, /* fmdo_gc */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_send, /* fmdo_send */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic const fmd_prop_t etm_props[] = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "client_list", FMD_TYPE_STRING, NULL },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "server_list", FMD_TYPE_STRING, NULL },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { "reconnect_interval", FMD_TYPE_UINT64, "10000000000" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "reconnect_timeout", FMD_TYPE_UINT64, "300000000000" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "rw_timeout", FMD_TYPE_UINT64, "2000000000" },
77a7fd96f77f04bbd7634db14755686062589ecajrutt { "filter_path", FMD_TYPE_STRING, NULL },
25cf1a301a396c38e8adf52c15f537b80d2483f7jl { NULL, 0, NULL }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic const fmd_hdl_info_t etm_info = {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "Event Transport Module", "2.0", &etm_ops, etm_props
25cf1a301a396c38e8adf52c15f537b80d2483f7jl};
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize the transport for use by ETM.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_fmd_init(fmd_hdl_t *hdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *propstr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (fmd_hdl_register(hdl, FMD_API_VERSION, &etm_info) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return; /* invalid data in configuration file */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create global stats */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sizeof (Etm_stats) / sizeof (fmd_stat_t), (fmd_stat_t *)&Etm_stats);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Get module properties */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Reconn_timeout = fmd_prop_get_int64(hdl, "reconnect_timeout");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Reconn_interval = fmd_prop_get_int64(hdl, "reconnect_interval");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Rw_timeout = fmd_prop_get_int64(hdl, "rw_timeout");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl propstr = fmd_prop_get_string(hdl, "client_list");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_create_epmaps(hdl, propstr, ETM_SERVER_XPRT_FLAGS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_prop_free_string(hdl, propstr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl propstr = fmd_prop_get_string(hdl, "server_list");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_create_epmaps(hdl, propstr, ETM_CLIENT_XPRT_FLAGS);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_prop_free_string(hdl, propstr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Etm_stats.peer_count.fmds_value.ui64 == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "Failed to init any endpoint\n");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_unregister(hdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Teardown the transport
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlvoid
25cf1a301a396c38e8adf52c15f537b80d2483f7jl_fmd_fini(fmd_hdl_t *hdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_epmap_t *mp, *next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Etm_exit = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Etm_mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp = Epmap_head;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (mp) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl next = mp->epm_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl etm_free_epmap(hdl, mp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl mp = next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_unregister(hdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}