Blame src/mpid/ch3/channels/nemesis/netmod/tcp/tcp_init.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2006 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#include "tcp_impl.h"
Packit Service c5cf8c
#ifdef HAVE_SYS_TYPES_H
Packit Service c5cf8c
#include <sys/types.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#ifdef HAVE_SYS_SOCKET_H
Packit Service c5cf8c
#include <sys/socket.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#ifdef HAVE_ARPA_INET_H
Packit Service c5cf8c
#include <arpa/inet.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#ifdef HAVE_NETDB_H
Packit Service c5cf8c
#include <netdb.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#ifdef HAVE_SIGNAL_H
Packit Service c5cf8c
#include <signal.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
=== BEGIN_MPI_T_CVAR_INFO_BLOCK ===
Packit Service c5cf8c
Packit Service c5cf8c
cvars:
Packit Service c5cf8c
    - name        : MPIR_CVAR_CH3_INTERFACE_HOSTNAME
Packit Service c5cf8c
      category    : CH3
Packit Service c5cf8c
      alt-env     : MPIR_CVAR_INTERFACE_HOSTNAME
Packit Service c5cf8c
      type        : string
Packit Service c5cf8c
      default     : NULL
Packit Service c5cf8c
      class       : none
Packit Service c5cf8c
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
Packit Service c5cf8c
      scope       : MPI_T_SCOPE_LOCAL
Packit Service c5cf8c
      description : >-
Packit Service c5cf8c
        If non-NULL, this cvar specifies the IP address that
Packit Service c5cf8c
        other processes should use when connecting to this process.
Packit Service c5cf8c
        This cvar is mutually exclusive with the
Packit Service c5cf8c
        MPIR_CVAR_CH3_NETWORK_IFACE cvar and it is an error to set them
Packit Service c5cf8c
        both.
Packit Service c5cf8c
Packit Service c5cf8c
    - name        : MPIR_CVAR_CH3_PORT_RANGE
Packit Service c5cf8c
      category    : CH3
Packit Service c5cf8c
      alt-env     : MPIR_CVAR_PORTRANGE, MPIR_CVAR_PORT_RANGE
Packit Service c5cf8c
      type        : range
Packit Service c5cf8c
      default     : "0:0"
Packit Service c5cf8c
      class       : none
Packit Service c5cf8c
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
Packit Service c5cf8c
      scope       : MPI_T_SCOPE_ALL_EQ
Packit Service c5cf8c
      description : >-
Packit Service c5cf8c
        The MPIR_CVAR_CH3_PORT_RANGE environment variable allows you to
Packit Service c5cf8c
        specify the range of TCP ports to be used by the process
Packit Service c5cf8c
        manager and the MPICH library. The format of this variable is
Packit Service c5cf8c
        <low>:<high>.  To specify any available port, use 0:0.
Packit Service c5cf8c
Packit Service c5cf8c
    - name        : MPIR_CVAR_NEMESIS_TCP_NETWORK_IFACE
Packit Service c5cf8c
      category    : NEMESIS
Packit Service c5cf8c
      alt-env     : MPIR_CVAR_NETWORK_IFACE
Packit Service c5cf8c
      type        : string
Packit Service c5cf8c
      default     : NULL
Packit Service c5cf8c
      class       : none
Packit Service c5cf8c
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
Packit Service c5cf8c
      scope       : MPI_T_SCOPE_ALL_EQ
Packit Service c5cf8c
      description : >-
Packit Service c5cf8c
        If non-NULL, this cvar specifies which pseudo-ethernet
Packit Service c5cf8c
        interface the tcp netmod should use (e.g., "eth1", "ib0").
Packit Service c5cf8c
        Note, this is a Linux-specific cvar.
Packit Service c5cf8c
        This cvar is mutually exclusive with the
Packit Service c5cf8c
        MPIR_CVAR_CH3_INTERFACE_HOSTNAME cvar and it is an error to set
Packit Service c5cf8c
        them both.
Packit Service c5cf8c
Packit Service c5cf8c
    - name        : MPIR_CVAR_NEMESIS_TCP_HOST_LOOKUP_RETRIES
Packit Service c5cf8c
      category    : NEMESIS
Packit Service c5cf8c
      type        : int
Packit Service c5cf8c
      default     : 10
Packit Service c5cf8c
      class       : none
Packit Service c5cf8c
      verbosity   : MPI_T_VERBOSITY_USER_BASIC
Packit Service c5cf8c
      scope       : MPI_T_SCOPE_ALL_EQ
Packit Service c5cf8c
      description : >-
Packit Service c5cf8c
        This cvar controls the number of times to retry the
Packit Service c5cf8c
        gethostbyname() function before giving up.
Packit Service c5cf8c
Packit Service c5cf8c
=== END_MPI_T_CVAR_INFO_BLOCK ===
Packit Service c5cf8c
*/
Packit Service c5cf8c
Packit Service c5cf8c
#define DBG_IFNAME 0
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef ENABLE_CHECKPOINTING
Packit Service c5cf8c
static int ckpt_restart(void);
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
MPID_nem_netmod_funcs_t MPIDI_nem_tcp_funcs = {
Packit Service c5cf8c
    MPID_nem_tcp_init,
Packit Service c5cf8c
    MPID_nem_tcp_finalize,
Packit Service c5cf8c
#ifdef ENABLE_CHECKPOINTING
Packit Service c5cf8c
    NULL, /* ckpt_precheck */
Packit Service c5cf8c
    ckpt_restart,
Packit Service c5cf8c
    NULL, /* ckpt_continue */
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    MPID_nem_tcp_connpoll,
Packit Service c5cf8c
    MPID_nem_tcp_get_business_card,
Packit Service c5cf8c
    MPID_nem_tcp_connect_to_root,
Packit Service c5cf8c
    MPID_nem_tcp_vc_init,
Packit Service c5cf8c
    MPID_nem_tcp_vc_destroy,
Packit Service c5cf8c
    MPID_nem_tcp_vc_terminate,
Packit Service c5cf8c
    NULL, /* anysource iprobe */
Packit Service c5cf8c
    NULL, /* anysource_improbe */
Packit Service c5cf8c
    MPID_nem_tcp_get_ordering
Packit Service c5cf8c
};
Packit Service c5cf8c
Packit Service c5cf8c
/* in case there are no packet types defined (e.g., they're ifdef'ed out) make sure the array is not zero length */
Packit Service c5cf8c
static MPIDI_CH3_PktHandler_Fcn *pkt_handlers[MPIDI_NEM_TCP_PKT_NUM_TYPES ? MPIDI_NEM_TCP_PKT_NUM_TYPES : 1];
Packit Service c5cf8c
Packit Service c5cf8c
MPL_dbg_class MPIDI_NEM_TCP_DBG_DET;
Packit Service c5cf8c
Packit Service c5cf8c
int MPID_nem_tcp_listen (int sockfd);
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME set_up_listener
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
static int set_up_listener(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_SET_UP_LISTENER);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_SET_UP_LISTENER);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_nem_tcp_g_lstn_plfd.fd = MPID_nem_tcp_g_lstn_sc.fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP2(MPID_nem_tcp_g_lstn_sc.fd == -1, mpi_errno, MPI_ERR_OTHER, "**sock_create", "**sock_create %s %d", MPIR_Strerror(errno), errno);
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_set_sockopts(MPID_nem_tcp_g_lstn_sc.fd);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_nem_tcp_g_lstn_plfd.events = POLLIN;
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_listen(MPID_nem_tcp_g_lstn_sc.fd);
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP2(mpi_errno, mpi_errno, MPI_ERR_OTHER, "**listen", "**listen %s %d", MPIR_Strerror(errno), errno);
Packit Service c5cf8c
    MPID_nem_tcp_g_lstn_sc.state.lstate = LISTEN_STATE_LISTENING;
Packit Service c5cf8c
    MPID_nem_tcp_g_lstn_sc.handler = MPID_nem_tcp_state_listening_handler;
Packit Service c5cf8c
Packit Service c5cf8c
fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_SET_UP_LISTENER);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
fn_fail:
Packit Service c5cf8c
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_init
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_init (MPIDI_PG_t *pg_p, int pg_rank, char **bc_val_p, int *val_max_sz_p)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_INIT);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_INIT);
Packit Service c5cf8c
Packit Service c5cf8c
    MPID_nem_net_module_vc_dbg_print_sendq = MPID_nem_tcp_vc_dbg_print_sendq;
Packit Service c5cf8c
Packit Service c5cf8c
    /* first make sure that our private fields in the vc fit into the area provided  */
Packit Service c5cf8c
    MPIR_Assert(sizeof(MPID_nem_tcp_vc_area) <= MPIDI_NEM_VC_NETMOD_AREA_LEN);
Packit Service c5cf8c
Packit Service c5cf8c
#if defined (MPL_USE_DBG_LOGGING)
Packit Service c5cf8c
    MPIDI_NEM_TCP_DBG_DET = MPL_dbg_class_alloc("MPIDI_NEM_TCP_DBG_DET", "nem_sock_det");
Packit Service c5cf8c
#endif /* MPL_USE_DBG_LOGGING */
Packit Service c5cf8c
Packit Service c5cf8c
    /* set up listener socket */
Packit Service c5cf8c
    mpi_errno = set_up_listener();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    
Packit Service c5cf8c
    /* create business card */
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_get_business_card(pg_rank, bc_val_p, val_max_sz_p);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_sm_init();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_send_init();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef HAVE_SIGNAL
Packit Service c5cf8c
    {
Packit Service c5cf8c
        /* In order to be able to handle socket errors on our own, we need
Packit Service c5cf8c
           to ignore SIGPIPE.  This may cause problems for programs that
Packit Service c5cf8c
           intend to handle SIGPIPE or count on being killed, but I expect
Packit Service c5cf8c
           such programs are very rare, and I'm not sure what the best
Packit Service c5cf8c
           solution would be anyway. */
Packit Service c5cf8c
        void *ret;
Packit Service c5cf8c
Packit Service c5cf8c
        ret = signal(SIGPIPE, SIG_IGN);
Packit Service c5cf8c
        MPIR_ERR_CHKANDJUMP1(ret == SIG_ERR, mpi_errno, MPI_ERR_OTHER, "**signal", "**signal %s", MPIR_Strerror(errno));
Packit Service c5cf8c
        if (ret != SIG_DFL && ret != SIG_IGN) {
Packit Service c5cf8c
            /* The app has set its own signal handler.  Replace the previous handler. */
Packit Service c5cf8c
            ret = signal(SIGPIPE, ret);
Packit Service c5cf8c
            MPIR_ERR_CHKANDJUMP1(ret == SIG_ERR, mpi_errno, MPI_ERR_OTHER, "**signal", "**signal %s", MPIR_Strerror(errno));
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_INIT);
Packit Service c5cf8c
/*     fprintf(stdout, FCNAME " Exit\n"); fflush(stdout); */
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
/*     fprintf(stdout, "failure. mpi_errno = %d\n", mpi_errno); */
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef ENABLE_CHECKPOINTING
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME ckpt_restart
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
static int ckpt_restart(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    char *publish_bc_orig = NULL;
Packit Service c5cf8c
    char *bc_val          = NULL;
Packit Service c5cf8c
    int val_max_sz;
Packit Service c5cf8c
    int i;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_CKPT_RESTART);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_CKPT_RESTART);
Packit Service c5cf8c
Packit Service c5cf8c
    /* First, clean up.  We didn't shut anything down before the
Packit Service c5cf8c
       checkpoint, so we need to go close and free any resources */
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_ckpt_cleanup();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_send_finalize();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_sm_finalize();
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Initialize the new business card */
Packit Service c5cf8c
    mpi_errno = MPIDI_CH3I_BCInit(&bc_val, &val_max_sz);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    publish_bc_orig = bc_val;
Packit Service c5cf8c
    
Packit Service c5cf8c
    /* Now we can restart */
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_init(MPIDI_Process.my_pg, MPIDI_Process.my_pg_rank, &bc_val, &val_max_sz);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    
Packit Service c5cf8c
    /* publish business card */
Packit Service c5cf8c
    mpi_errno = MPIDI_PG_SetConnInfo(MPIDI_Process.my_pg_rank, (const char *)publish_bc_orig);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    MPL_free(publish_bc_orig);
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < MPIDI_Process.my_pg->size; ++i) {
Packit Service c5cf8c
        MPIDI_VC_t *vc;
Packit Service c5cf8c
        MPIDI_CH3I_VC *vc_ch;
Packit Service c5cf8c
        if (i == MPIDI_Process.my_pg_rank)
Packit Service c5cf8c
            continue;
Packit Service c5cf8c
        MPIDI_PG_Get_vc(MPIDI_Process.my_pg, i, &vc);
Packit Service c5cf8c
        vc_ch = &vc->ch;
Packit Service c5cf8c
        if (!vc_ch->is_local) {
Packit Service c5cf8c
            mpi_errno = vc_ch->ckpt_restart_vc(vc);
Packit Service c5cf8c
            if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    
Packit Service c5cf8c
Packit Service c5cf8c
fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_CKPT_RESTART);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
fn_fail:
Packit Service c5cf8c
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * Get a description of the network interface to use for socket communication
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * Here are the steps.  This order of checks is used to provide the 
Packit Service c5cf8c
 * user control over the choice of interface and to avoid, where possible,
Packit Service c5cf8c
 * the use of non-scalable services, such as centeralized name servers.
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * MPICH_INTERFACE_HOSTNAME
Packit Service c5cf8c
 * MPICH_INTERFACE_HOSTNAME_R%d
Packit Service c5cf8c
 * a single (non-localhost) available IP address, if possible
Packit Service c5cf8c
 * gethostbyname(gethostname())
Packit Service c5cf8c
 *
Packit Service c5cf8c
 * We return the following items:
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *    ifname - hostname of the interface.  This may or may not be the same
Packit Service c5cf8c
 *             as the name returned by gethostname  (in Unix)
Packit Service c5cf8c
 *    ifaddr - This structure includes the interface IP address (as bytes),
Packit Service c5cf8c
 *             and the type (e.g., AF_INET or AF_INET6).  Only 
Packit Service c5cf8c
 *             ipv4 (AF_INET) is used so far.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
static int GetSockInterfaceAddr(int myRank, char *ifname, int maxIfname,
Packit Service c5cf8c
                                MPL_sockaddr_t *p_addr)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *ifname_string;
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int ifaddrFound = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_Assert(maxIfname);
Packit Service c5cf8c
    ifname[0] = '\0';
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP(MPIR_CVAR_CH3_INTERFACE_HOSTNAME && MPIR_CVAR_NEMESIS_TCP_NETWORK_IFACE, mpi_errno, MPI_ERR_OTHER, "**ifname_and_hostname");
Packit Service c5cf8c
    
Packit Service c5cf8c
    /* Check if user specified ethernet interface name, e.g., ib0, eth1 */
Packit Service c5cf8c
    if (MPIR_CVAR_NEMESIS_TCP_NETWORK_IFACE) {
Packit Service c5cf8c
        char s[100];
Packit Service c5cf8c
	int len;
Packit Service a56745
        int ret = MPL_get_sockaddr_iface(MPIR_CVAR_NEMESIS_TCP_NETWORK_IFACE, p_addr);
Packit Service a56745
        MPIR_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**iface_notfound",
Packit Service a56745
                             "**iface_notfound %s", MPIR_CVAR_NEMESIS_TCP_NETWORK_IFACE);
Packit Service c5cf8c
Packit Service c5cf8c
        MPL_sockaddr_to_str(p_addr, s, 100);
Packit Service c5cf8c
        MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CONNECT, VERBOSE, (MPL_DBG_FDEST,
Packit Service c5cf8c
                                                "ifaddrFound: %s", s));
Packit Service c5cf8c
Packit Service c5cf8c
        /* In this case, ifname is only used for debugging purposes */
Packit Service c5cf8c
	mpi_errno = MPID_Get_processor_name(ifname, maxIfname, &len );
Packit Service c5cf8c
        if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        goto fn_exit;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* Check for a host name supplied through an environment variable */
Packit Service c5cf8c
    ifname_string = MPIR_CVAR_CH3_INTERFACE_HOSTNAME;
Packit Service c5cf8c
    if (!ifname_string) {
Packit Service c5cf8c
	/* See if there is a per-process name for the interfaces (e.g.,
Packit Service c5cf8c
	   the process manager only delievers the same values for the 
Packit Service c5cf8c
	   environment to each process.  There's no way to do this with
Packit Service c5cf8c
           the param interface, so we need to use getenv() here. */
Packit Service c5cf8c
	char namebuf[1024];
Packit Service c5cf8c
	MPL_snprintf( namebuf, sizeof(namebuf), 
Packit Service c5cf8c
		       "MPICH_INTERFACE_HOSTNAME_R%d", myRank );
Packit Service c5cf8c
	ifname_string = getenv( namebuf );
Packit Service c5cf8c
Packit Service c5cf8c
	if (DBG_IFNAME && ifname_string) {
Packit Service c5cf8c
	    fprintf( stdout, "Found interface name %s from %s\n", 
Packit Service c5cf8c
		    ifname_string, namebuf );
Packit Service c5cf8c
	    fflush( stdout );
Packit Service c5cf8c
	}
Packit Service c5cf8c
    }
Packit Service c5cf8c
    else if (DBG_IFNAME) {
Packit Service c5cf8c
	fprintf( stdout, 
Packit Service c5cf8c
		 "Found interface name %s from MPICH_INTERFACE_HOSTNAME\n", 
Packit Service c5cf8c
		 ifname_string );
Packit Service c5cf8c
	fflush( stdout );
Packit Service c5cf8c
    }
Packit Service c5cf8c
	 
Packit Service c5cf8c
    if (!ifname_string) {
Packit Service c5cf8c
	int len;
Packit Service c5cf8c
Packit Service c5cf8c
	/* User did not specify a hostname.  Look it up. */
Packit Service c5cf8c
	mpi_errno = MPID_Get_processor_name(ifname, maxIfname, &len );
Packit Service c5cf8c
        if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
	ifname_string = ifname;
Packit Service c5cf8c
Packit Service a56745
        /* If we didn't find a specific name, then try to get an IP address
Packit Service a56745
         * directly from the available interfaces, if that is supported on
Packit Service a56745
         * this platform.  Otherwise, we'll drop into the next step that uses
Packit Service a56745
         * the ifname */
Packit Service a56745
        int ret = MPL_get_sockaddr_iface(NULL, p_addr);
Packit Service a56745
        MPIR_ERR_CHKANDJUMP1(ret != 0, mpi_errno, MPI_ERR_OTHER, "**iface_notfound",
Packit Service a56745
                             "**iface_notfound %s", NULL);
Packit Service c5cf8c
        ifaddrFound = 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    else {
Packit Service c5cf8c
	/* Copy this name into the output name */
Packit Service c5cf8c
	MPL_strncpy( ifname, ifname_string, maxIfname );
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* If we don't have an IP address, try to get it from the name */
Packit Service c5cf8c
    if (!ifaddrFound) {
Packit Service a56745
        int ret = MPL_get_sockaddr(ifname_string, p_addr);
Packit Service a56745
        MPIR_ERR_CHKANDJUMP2(ret != 0, mpi_errno, MPI_ERR_OTHER, "**gethostbyname",
Packit Service a56745
                             "**gethostbyname %s %d", ifname_string, h_errno);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
fn_exit:
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_get_business_card
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_get_business_card (int my_rank, char **bc_val_p, int *val_max_sz_p)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int str_errno = MPL_STR_SUCCESS;
Packit Service c5cf8c
    MPL_sockaddr_t addr;
Packit Service c5cf8c
    char ifname[MAX_HOST_DESCRIPTION_LEN];
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
    MPL_sockaddr_t sock_id;
Packit Service c5cf8c
    socklen_t len;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_GET_BUSINESS_CARD);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_GET_BUSINESS_CARD);
Packit Service c5cf8c
    
Packit Service c5cf8c
    mpi_errno = GetSockInterfaceAddr(my_rank, ifname, sizeof(ifname), &addr);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    
Packit Service c5cf8c
    
Packit Service c5cf8c
    str_errno = MPL_str_add_string_arg(bc_val_p, val_max_sz_p, MPIDI_CH3I_HOST_DESCRIPTION_KEY, ifname);
Packit Service c5cf8c
    if (str_errno) {
Packit Service c5cf8c
        MPIR_ERR_CHKANDJUMP(str_errno == MPL_STR_NOMEM, mpi_errno, MPI_ERR_OTHER, "**buscard_len");
Packit Service c5cf8c
        MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**buscard");
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    len = sizeof(sock_id);
Packit Service c5cf8c
    ret = getsockname (MPID_nem_tcp_g_lstn_sc.fd, (struct sockaddr *)&sock_id, &len;;
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP1 (ret == -1, mpi_errno, MPI_ERR_OTHER, "**getsockname", "**getsockname %s", MPIR_Strerror (errno));
Packit Service c5cf8c
Packit Service c5cf8c
    str_errno = MPL_str_add_int_arg (bc_val_p, val_max_sz_p, MPIDI_CH3I_PORT_KEY, MPL_sockaddr_port(&sock_id));
Packit Service c5cf8c
    if (str_errno) {
Packit Service c5cf8c
        MPIR_ERR_CHKANDJUMP(str_errno == MPL_STR_NOMEM, mpi_errno, MPI_ERR_OTHER, "**buscard_len");
Packit Service c5cf8c
        MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**buscard");
Packit Service c5cf8c
    }
Packit Service c5cf8c
    
Packit Service c5cf8c
    if (addr.ss_family == AF_INET)
Packit Service c5cf8c
    {
Packit Service c5cf8c
        MPL_sockaddr_to_str(&addr, ifname, MAX_HOST_DESCRIPTION_LEN);
Packit Service c5cf8c
        MPL_DBG_MSG_S(MPIDI_CH3_DBG_CONNECT,VERBOSE,"ifname = %s",ifname );
Packit Service c5cf8c
        str_errno = MPL_str_add_string_arg(bc_val_p, val_max_sz_p, MPIDI_CH3I_IFNAME_KEY, ifname);
Packit Service c5cf8c
        if (str_errno) {
Packit Service c5cf8c
            MPIR_ERR_CHKANDJUMP(str_errno == MPL_STR_NOMEM, mpi_errno, MPI_ERR_OTHER, "**buscard_len");
Packit Service c5cf8c
            MPIR_ERR_SETANDJUMP(mpi_errno, MPI_ERR_OTHER, "**buscard");
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    
Packit Service c5cf8c
Packit Service c5cf8c
    /*     printf("MPID_nem_tcp_get_business_card. port=%d\n", sock_id.sin_port); */
Packit Service c5cf8c
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
/*     fprintf(stdout, "MPID_nem_tcp_get_business_card Exit, mpi_errno=%d\n", mpi_errno); fflush(stdout); */
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_GET_BUSINESS_CARD);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_connect_to_root
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_connect_to_root (const char *business_card, MPIDI_VC_t *new_vc)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    struct in_addr addr;
Packit Service c5cf8c
    MPID_nem_tcp_vc_area *vc_tcp = VC_TCP(new_vc);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_CONNECT_TO_ROOT);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_CONNECT_TO_ROOT);
Packit Service c5cf8c
Packit Service c5cf8c
    /* vc is already allocated before reaching this point */
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_get_addr_port_from_bc(business_card, &addr, &vc_tcp->sock_id.sin_port);
Packit Service c5cf8c
    vc_tcp->sock_id.sin_addr.s_addr = addr.s_addr;
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPIDI_GetTagFromPort(business_card, &new_vc->port_name_tag);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_connect(new_vc);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_CONNECT_TO_ROOT);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_vc_init
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_vc_init (MPIDI_VC_t *vc)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIDI_CH3I_VC *vc_ch = &vc->ch;
Packit Service c5cf8c
    MPID_nem_tcp_vc_area *vc_tcp = VC_TCP(vc);
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_VC_INIT);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_VC_INIT);
Packit Service c5cf8c
Packit Service c5cf8c
    vc_tcp->state = MPID_NEM_TCP_VC_STATE_DISCONNECTED;
Packit Service c5cf8c
    
Packit Service c5cf8c
    vc->sendNoncontig_fn   = MPID_nem_tcp_SendNoncontig;
Packit Service c5cf8c
    vc_ch->iStartContigMsg = MPID_nem_tcp_iStartContigMsg;
Packit Service c5cf8c
    vc_ch->iSendContig     = MPID_nem_tcp_iSendContig;
Packit Service c5cf8c
#ifdef ENABLE_CHECKPOINTING
Packit Service c5cf8c
    vc_ch->ckpt_pause_send_vc = MPID_nem_tcp_ckpt_pause_send_vc;
Packit Service c5cf8c
    vc_ch->ckpt_continue_vc   = MPID_nem_tcp_ckpt_continue_vc;
Packit Service c5cf8c
    vc_ch->ckpt_restart_vc    = MPID_nem_tcp_ckpt_restart_vc;
Packit Service c5cf8c
Packit Service c5cf8c
    pkt_handlers[MPIDI_NEM_TCP_PKT_UNPAUSE] = MPID_nem_tcp_pkt_unpause_handler;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
    vc_ch->pkt_handler = pkt_handlers;
Packit Service c5cf8c
    vc_ch->num_pkt_handlers = MPIDI_NEM_TCP_PKT_NUM_TYPES;
Packit Service c5cf8c
Packit Service c5cf8c
    memset(&vc_tcp->sock_id, 0, sizeof(vc_tcp->sock_id));
Packit Service c5cf8c
    vc_tcp->sock_id.sin_family = AF_INET;
Packit Service c5cf8c
Packit Service c5cf8c
    vc_ch->next = NULL;
Packit Service c5cf8c
    vc_ch->prev = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
    ASSIGN_SC_TO_VC(vc_tcp, NULL);
Packit Service c5cf8c
    vc_tcp->send_queue.head = vc_tcp->send_queue.tail = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
    vc_tcp->send_paused = FALSE;
Packit Service c5cf8c
    vc_tcp->paused_send_queue.head = vc_tcp->paused_send_queue.tail = NULL;
Packit Service c5cf8c
Packit Service c5cf8c
    vc_tcp->sc_ref_count = 0;
Packit Service c5cf8c
    
Packit Service c5cf8c
    vc_tcp->connect_retry_count = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_VC_INIT);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_vc_destroy
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_vc_destroy(MPIDI_VC_t *vc)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
Packit Service c5cf8c
    /* currently do nothing */
Packit Service c5cf8c
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/* 
Packit Service c5cf8c
   FIXME: this is the same function as in socksm.c 
Packit Service c5cf8c
   This should be removed and use only one function eventually.
Packit Service c5cf8c
*/
Packit Service c5cf8c
   
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_get_addr_port_from_bc
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_get_addr_port_from_bc(const char *business_card, struct in_addr *addr, in_port_t *port)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
    int port_int;
Packit Service c5cf8c
    /*char desc_str[256];*/
Packit Service c5cf8c
    char ifname[256];
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_GET_ADDR_PORT_FROM_BC);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_GET_ADDR_PORT_FROM_BC);
Packit Service c5cf8c
    
Packit Service c5cf8c
    /*     fprintf(stdout, FCNAME " Enter\n"); fflush(stdout); */
Packit Service c5cf8c
    /* desc_str is only used for debugging
Packit Service c5cf8c
    ret = MPL_str_get_string_arg (business_card, MPIDI_CH3I_HOST_DESCRIPTION_KEY, desc_str, sizeof(desc_str));
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP (ret != MPL_STR_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**argstr_missinghost");
Packit Service c5cf8c
    */
Packit Service c5cf8c
Packit Service c5cf8c
    /* sizeof(in_port_t) != sizeof(int) on most platforms, so we need to use
Packit Service c5cf8c
     * port_int as the arg to MPL_str_get_int_arg. */
Packit Service c5cf8c
    ret = MPL_str_get_int_arg (business_card, MPIDI_CH3I_PORT_KEY, &port_int);
Packit Service c5cf8c
    /* MPL_STR_FAIL is not a valid MPI error code so we store the result in ret
Packit Service c5cf8c
     * instead of mpi_errno. */
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP (ret != MPL_STR_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**argstr_missingport");
Packit Service c5cf8c
    MPIR_Assert((port_int >> (8*sizeof(*port))) == 0); /* ensure port_int isn't too large for *port */
Packit Service c5cf8c
    *port = htons((in_port_t)port_int);
Packit Service c5cf8c
Packit Service c5cf8c
    ret = MPL_str_get_string_arg(business_card, MPIDI_CH3I_IFNAME_KEY, ifname, sizeof(ifname));
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP (ret != MPL_STR_SUCCESS, mpi_errno, MPI_ERR_OTHER, "**argstr_missingifname");
Packit Service c5cf8c
Packit Service c5cf8c
    ret = inet_pton (AF_INET, (const char *)ifname, addr);
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP(ret == 0, mpi_errno,MPI_ERR_OTHER,"**ifnameinvalid");
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP(ret < 0, mpi_errno, MPI_ERR_OTHER, "**afinetinvalid");
Packit Service c5cf8c
    
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
/*     fprintf(stdout, FCNAME " Exit\n"); fflush(stdout); */
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_GET_ADDR_PORT_FROM_BC);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
/*     fprintf(stdout, "failure. mpi_errno = %d\n", mpi_errno); */
Packit Service c5cf8c
    MPL_DBG_MSG_FMT(MPIDI_NEM_TCP_DBG_DET, VERBOSE, (MPL_DBG_FDEST, "failure. mpi_errno = %d", mpi_errno));
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* MPID_nem_tcp_listen -- if MPICH_PORT_RANGE is set, this
Packit Service c5cf8c
   binds the socket to an available port number in the range.
Packit Service c5cf8c
   Otherwise, it binds it to any addr and any port */
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_listen
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_listen (int sockfd)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int ret;
Packit Service c5cf8c
    unsigned short port;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_BIND);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_BIND);
Packit Service c5cf8c
   
Packit Service c5cf8c
    MPIR_ERR_CHKANDJUMP(MPIR_CVAR_CH3_PORT_RANGE.low < 0 || MPIR_CVAR_CH3_PORT_RANGE.low > MPIR_CVAR_CH3_PORT_RANGE.high, mpi_errno, MPI_ERR_OTHER, "**badportrange");
Packit Service c5cf8c
Packit Service c5cf8c
    /* default MPICH_PORT_RANGE is {0,0} so bind will use any available port */
Packit Service c5cf8c
    ret = 0;
Packit Service c5cf8c
    if (MPIR_CVAR_CH3_PORT_RANGE.low==0){
Packit Service c5cf8c
        ret = MPL_listen_anyport(sockfd, &port);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    else {
Packit Service c5cf8c
        ret = MPL_listen_portrange(sockfd, &port, MPIR_CVAR_CH3_PORT_RANGE.low, MPIR_CVAR_CH3_PORT_RANGE.high);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (ret == -2) {
Packit Service c5cf8c
        /* check if an available port was found */
Packit Service c5cf8c
        MPIR_ERR_CHKANDJUMP3 (1, mpi_errno, MPI_ERR_OTHER, "**sock|poll|bind", "**sock|poll|bind %d %d %s", port-1, errno, MPIR_Strerror (errno));
Packit Service c5cf8c
    }
Packit Service c5cf8c
    else if (ret) {
Packit Service c5cf8c
        /* check for real error */
Packit Service c5cf8c
        MPIR_ERR_CHKANDJUMP3 (errno != EADDRINUSE && errno != EADDRNOTAVAIL, mpi_errno, MPI_ERR_OTHER, "**sock|poll|bind", "**sock|poll|bind %d %d %s", port, errno, MPIR_Strerror (errno));
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
/*     if (ret == 0) */
Packit Service c5cf8c
/*         fprintf(stdout, "sockfd=%d  port=%d bound\n", sockfd, port); */
Packit Service c5cf8c
/*     fprintf(stdout, FCNAME " Exit\n"); fflush(stdout); */
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_BIND);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
/*     fprintf(stdout, "failure. mpi_errno = %d\n", mpi_errno); */
Packit Service c5cf8c
    MPL_DBG_MSG_FMT(MPIDI_NEM_TCP_DBG_DET, VERBOSE, (MPL_DBG_FDEST, "failure. mpi_errno = %d", mpi_errno));
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_vc_terminate
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_vc_terminate(MPIDI_VC_t *vc)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    int req_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_VC_TERMINATE);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_VC_TERMINATE);
Packit Service c5cf8c
Packit Service c5cf8c
    if (vc->state != MPIDI_VC_STATE_CLOSED) {
Packit Service c5cf8c
        /* VC is terminated as a result of a fault.  Complete
Packit Service c5cf8c
           outstanding sends with an error and terminate
Packit Service c5cf8c
           connection immediately. */
Packit Service c5cf8c
        MPIR_ERR_SET1(req_errno, MPIX_ERR_PROC_FAILED, "**comm_fail", "**comm_fail %d", vc->pg_rank);
Packit Service c5cf8c
        mpi_errno = MPID_nem_tcp_error_out_send_queue(vc, req_errno);
Packit Service c5cf8c
        if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        mpi_errno = MPID_nem_tcp_vc_terminated(vc);
Packit Service c5cf8c
        if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        MPID_nem_tcp_vc_area *vc_tcp = VC_TCP(vc);
Packit Service c5cf8c
        /* VC is terminated as a result of the close protocol.
Packit Service c5cf8c
           Wait for sends to complete, then terminate. */
Packit Service c5cf8c
Packit Service c5cf8c
        if (MPIDI_CH3I_Sendq_empty(vc_tcp->send_queue)) {
Packit Service c5cf8c
            /* The sendq is empty, so we can immediately terminate
Packit Service c5cf8c
               the connection. */
Packit Service c5cf8c
            mpi_errno = MPID_nem_tcp_vc_terminated(vc);
Packit Service c5cf8c
            if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* else: just return.  We'll call vc_terminated() from the
Packit Service c5cf8c
           commrdy_handler once the sendq is empty. */
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_VC_TERMINATE);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_vc_terminated
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_vc_terminated(MPIDI_VC_t *vc)
Packit Service c5cf8c
{
Packit Service c5cf8c
    /* This is called when the VC is to be terminated once all queued
Packit Service c5cf8c
       sends have been sent. */
Packit Service c5cf8c
    int mpi_errno = MPI_SUCCESS;
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_STATE_DECL(MPID_NEM_TCP_VC_TERMINATED);
Packit Service c5cf8c
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_ENTER(MPID_NEM_TCP_VC_TERMINATED);
Packit Service c5cf8c
Packit Service c5cf8c
    mpi_errno = MPID_nem_tcp_cleanup(vc);
Packit Service c5cf8c
    if (mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
    
Packit Service c5cf8c
    mpi_errno = MPIDI_CH3U_Handle_connection(vc, MPIDI_VC_EVENT_TERMINATED);
Packit Service c5cf8c
    if(mpi_errno) MPIR_ERR_POP(mpi_errno);
Packit Service c5cf8c
Packit Service c5cf8c
 fn_exit:
Packit Service c5cf8c
    MPIR_FUNC_VERBOSE_EXIT(MPID_NEM_TCP_VC_TERMINATED);
Packit Service c5cf8c
    return mpi_errno;
Packit Service c5cf8c
 fn_fail:
Packit Service c5cf8c
    MPL_DBG_MSG_FMT(MPIDI_NEM_TCP_DBG_DET, VERBOSE, (MPL_DBG_FDEST, "failure. mpi_errno = %d", mpi_errno));
Packit Service c5cf8c
    goto fn_exit;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
#undef FUNCNAME
Packit Service c5cf8c
#define FUNCNAME MPID_nem_tcp_get_ordering
Packit Service c5cf8c
#undef FCNAME
Packit Service c5cf8c
#define FCNAME MPL_QUOTE(FUNCNAME)
Packit Service c5cf8c
int MPID_nem_tcp_get_ordering(int *ordering)
Packit Service c5cf8c
{
Packit Service c5cf8c
    (*ordering) = 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}