2004-01-15 02:24:15 +03:00
|
|
|
/*
|
2004-11-22 04:38:40 +03:00
|
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University.
|
|
|
|
* All rights reserved.
|
|
|
|
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
|
|
|
|
* All rights reserved.
|
2004-11-28 23:09:25 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2004-11-22 04:38:40 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
2004-01-15 02:24:15 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
2004-10-20 05:03:09 +04:00
|
|
|
#include "ompi_config.h"
|
2005-01-20 03:03:23 +03:00
|
|
|
#include "include/ompi_socket_errno.h"
|
2004-10-22 20:06:05 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2004-01-29 01:52:51 +03:00
|
|
|
#include <unistd.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
2004-03-26 17:15:20 +03:00
|
|
|
#include <string.h>
|
2004-03-12 01:02:01 +03:00
|
|
|
#include <fcntl.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
2004-03-12 01:02:01 +03:00
|
|
|
#include <sys/types.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
2004-03-12 01:02:01 +03:00
|
|
|
#include <sys/socket.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
2004-03-12 01:02:01 +03:00
|
|
|
#include <netinet/in.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_ARPA_INET_H
|
2004-03-12 01:02:01 +03:00
|
|
|
#include <arpa/inet.h>
|
2004-10-22 20:06:05 +04:00
|
|
|
#endif
|
2004-01-16 00:47:51 +03:00
|
|
|
|
2004-06-18 01:48:33 +04:00
|
|
|
#include "include/constants.h"
|
2005-07-04 03:09:55 +04:00
|
|
|
#include "opal/event/event.h"
|
2005-07-04 05:36:20 +04:00
|
|
|
#include "opal/util/if.h"
|
2005-07-04 04:13:44 +04:00
|
|
|
#include "opal/util/argv.h"
|
2005-07-04 03:31:27 +04:00
|
|
|
#include "opal/util/output.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "mca/pml/pml.h"
|
|
|
|
#include "mca/ptl/ptl.h"
|
2004-06-24 23:28:30 +04:00
|
|
|
#include "mca/pml/base/pml_base_sendreq.h"
|
2004-03-17 21:45:16 +03:00
|
|
|
#include "mca/base/mca_base_param.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
#include "mca/ns/ns_types.h"
|
|
|
|
|
2004-09-16 17:01:32 +04:00
|
|
|
#include "mca/oob/base/base.h"
|
2004-01-14 18:15:17 +03:00
|
|
|
#include "ptl_tcp.h"
|
2004-01-29 01:52:51 +03:00
|
|
|
#include "ptl_tcp_addr.h"
|
|
|
|
#include "ptl_tcp_proc.h"
|
|
|
|
#include "ptl_tcp_recvfrag.h"
|
|
|
|
#include "ptl_tcp_sendfrag.h"
|
2004-02-04 00:33:29 +03:00
|
|
|
#include "ptl_tcp_sendreq.h"
|
2004-01-29 01:52:51 +03:00
|
|
|
|
2005-01-20 07:44:07 +03:00
|
|
|
#define IMPORTANT_WINDOWS_COMMENT() \
|
2005-01-20 03:03:23 +03:00
|
|
|
/* In windows, many of the socket functions return an EWOULDBLOCK instead of \
|
|
|
|
things like EAGAIN, EINPROGRESS, etc. It has been verified that this will \
|
|
|
|
not conflict with other error codes that are returned by these functions \
|
|
|
|
under UNIX/Linux environments */
|
2004-01-14 18:15:17 +03:00
|
|
|
|
2004-09-30 19:09:29 +04:00
|
|
|
/*
|
|
|
|
* Data structure for accepting connections.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct mca_ptl_tcp_event_t {
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t item;
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_t event;
|
2004-09-30 19:09:29 +04:00
|
|
|
};
|
|
|
|
typedef struct mca_ptl_tcp_event_t mca_ptl_tcp_event_t;
|
|
|
|
|
|
|
|
static void mca_ptl_tcp_event_construct(mca_ptl_tcp_event_t* event)
|
|
|
|
{
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&mca_ptl_tcp_component.tcp_lock);
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_append(&mca_ptl_tcp_component.tcp_events, &event->item);
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-09-30 19:09:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mca_ptl_tcp_event_destruct(mca_ptl_tcp_event_t* event)
|
|
|
|
{
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&mca_ptl_tcp_component.tcp_lock);
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_remove_item(&mca_ptl_tcp_component.tcp_events, &event->item);
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-09-30 19:09:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_CLASS_INSTANCE(
|
|
|
|
mca_ptl_tcp_event_t,
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t,
|
2004-09-30 19:09:29 +04:00
|
|
|
mca_ptl_tcp_event_construct,
|
|
|
|
mca_ptl_tcp_event_destruct);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The PTL TCP component
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component_t mca_ptl_tcp_component = {
|
2004-01-14 18:15:17 +03:00
|
|
|
{
|
2004-08-02 04:24:22 +04:00
|
|
|
/* First, the mca_base_module_t struct containing meta
|
|
|
|
information about the module itself */
|
|
|
|
{
|
|
|
|
/* Indicate that we are a pml v1.0.0 module (which also
|
|
|
|
implies a specific MCA version) */
|
|
|
|
|
|
|
|
MCA_PTL_BASE_VERSION_1_0_0,
|
|
|
|
|
|
|
|
"tcp", /* MCA module name */
|
Major simplifications to component versioning:
- After long discussions and ruminations on how we run components in
LAM/MPI, made the decision that, by default, all components included
in Open MPI will use the version number of their parent project
(i.e., OMPI or ORTE). They are certaint free to use a different
number, but this simplification makes the common cases easy:
- components are only released when the parent project is released
- it is easy (trivial?) to distinguish which version component goes
with with version of the parent project
- removed all autogen/configure code for templating the version .h
file in components
- made all ORTE components use ORTE_*_VERSION for version numbers
- made all OMPI components use OMPI_*_VERSION for version numbers
- removed all VERSION files from components
- configure now displays OPAL, ORTE, and OMPI version numbers
- ditto for ompi_info
- right now, faking it -- OPAL and ORTE and OMPI will always have the
same version number (i.e., they all come from the same top-level
VERSION file). But this paves the way for the Great Configure
Reorganization, where, among other things, each project will have
its own version number.
So all in all, we went from a boatload of version numbers to
[effectively] three. That's pretty good. :-)
This commit was SVN r6344.
2005-07-05 00:12:36 +04:00
|
|
|
OMPI_MAJOR_VERSION, /* MCA module major version */
|
|
|
|
OMPI_MINOR_VERSION, /* MCA module minor version */
|
|
|
|
OMPI_RELEASE_VERSION, /* MCA module release version */
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component_open, /* module open */
|
|
|
|
mca_ptl_tcp_component_close /* module close */
|
|
|
|
},
|
|
|
|
|
|
|
|
/* Next the MCA v1.0.0 module meta data */
|
|
|
|
|
|
|
|
{
|
|
|
|
/* Whether the module is checkpointable or not */
|
|
|
|
|
|
|
|
false
|
|
|
|
},
|
|
|
|
|
|
|
|
mca_ptl_tcp_component_init,
|
|
|
|
mca_ptl_tcp_component_control,
|
2005-04-10 04:26:35 +04:00
|
|
|
NULL /*mca_ptl_tcp_component_progress*/,
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
};
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
/*
|
2004-02-12 23:55:10 +03:00
|
|
|
* functions for receiving event callbacks
|
2004-01-15 03:58:54 +03:00
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
static void mca_ptl_tcp_component_recv_handler(int, short, void*);
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* utility routines for parameter registration
|
|
|
|
*/
|
|
|
|
|
|
|
|
static inline char* mca_ptl_tcp_param_register_string(
|
|
|
|
const char* param_name,
|
|
|
|
const char* default_value)
|
|
|
|
{
|
|
|
|
char *param_value;
|
|
|
|
int id = mca_base_param_register_string("ptl","tcp",param_name,NULL,default_value);
|
|
|
|
mca_base_param_lookup_string(id, ¶m_value);
|
|
|
|
return param_value;
|
|
|
|
}
|
2004-01-14 18:15:17 +03:00
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
static inline int mca_ptl_tcp_param_register_int(
|
|
|
|
const char* param_name,
|
|
|
|
int default_value)
|
|
|
|
{
|
2004-01-15 20:43:54 +03:00
|
|
|
int id = mca_base_param_register_int("ptl","tcp",param_name,NULL,default_value);
|
|
|
|
int param_value = default_value;
|
|
|
|
mca_base_param_lookup_int(id,¶m_value);
|
|
|
|
return param_value;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
/*
|
|
|
|
* Called by MCA framework to open the module, registers
|
|
|
|
* module parameters.
|
2004-01-14 18:15:17 +03:00
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_component_open(void)
|
2004-01-14 18:15:17 +03:00
|
|
|
{
|
2004-11-02 16:14:34 +03:00
|
|
|
#ifdef WIN32
|
|
|
|
WSADATA win_sock_data;
|
|
|
|
if (WSAStartup(MAKEWORD(2,2), &win_sock_data) != 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output (0, "mca_ptl_tcp_component_init: failed to initialise windows sockets:%d\n", WSAGetLastError());
|
2004-11-02 16:14:34 +03:00
|
|
|
return OMPI_ERROR;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-02-13 18:12:46 +03:00
|
|
|
/* initialize state */
|
2004-08-03 02:16:35 +04:00
|
|
|
mca_ptl_tcp_component.tcp_listen_sd = -1;
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_ptl_modules = NULL;
|
|
|
|
mca_ptl_tcp_component.tcp_num_ptl_modules = 0;
|
2004-02-13 18:12:46 +03:00
|
|
|
|
|
|
|
/* initialize objects */
|
2005-07-04 02:45:48 +04:00
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_lock, opal_mutex_t);
|
2005-07-03 20:52:32 +04:00
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_procs, opal_hash_table_t);
|
2005-07-03 20:22:16 +04:00
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_pending_acks, opal_list_t);
|
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_events, opal_list_t);
|
2004-08-02 04:24:22 +04:00
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_send_frags, ompi_free_list_t);
|
|
|
|
OBJ_CONSTRUCT(&mca_ptl_tcp_component.tcp_recv_frags, ompi_free_list_t);
|
2005-07-03 20:52:32 +04:00
|
|
|
opal_hash_table_init(&mca_ptl_tcp_component.tcp_procs, 256);
|
2004-02-05 20:45:54 +03:00
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
/* register TCP module parameters */
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_if_include =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_string("if_include", "");
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_if_exclude =
|
2004-08-28 03:44:21 +04:00
|
|
|
mca_ptl_tcp_param_register_string("if_exclude", "lo");
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_free_list_num =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_int("free_list_num", 256);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_free_list_max =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_int("free_list_max", -1);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_free_list_inc =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_int("free_list_inc", 256);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_sndbuf =
|
2004-04-23 05:38:41 +04:00
|
|
|
mca_ptl_tcp_param_register_int("sndbuf", 128*1024);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_rcvbuf =
|
2004-04-23 05:38:41 +04:00
|
|
|
mca_ptl_tcp_param_register_int("rcvbuf", 128*1024);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_module.super.ptl_exclusivity =
|
2004-01-16 00:31:41 +03:00
|
|
|
mca_ptl_tcp_param_register_int("exclusivity", 0);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_module.super.ptl_first_frag_size =
|
2004-03-26 17:15:20 +03:00
|
|
|
mca_ptl_tcp_param_register_int("first_frag_size", 64*1024);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_module.super.ptl_min_frag_size =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_int("min_frag_size", 64*1024);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_module.super.ptl_max_frag_size =
|
2004-01-30 02:50:31 +03:00
|
|
|
mca_ptl_tcp_param_register_int("max_frag_size", -1);
|
2004-10-28 21:44:14 +04:00
|
|
|
/* the tcp allocator will never allocate buffers with more than this size */
|
|
|
|
mca_ptl_tcp_component.tcp_frag_size =
|
2004-11-05 10:52:30 +03:00
|
|
|
mca_ptl_tcp_param_register_int("frag_size", 64*1024);
|
2004-10-28 21:44:14 +04:00
|
|
|
/* adapt the first fragment size to fit with the allowed fragment size */
|
|
|
|
if( (mca_ptl_tcp_component.tcp_frag_size != 0) &&
|
|
|
|
(mca_ptl_tcp_module.super.ptl_first_frag_size > mca_ptl_tcp_component.tcp_frag_size) ) {
|
|
|
|
mca_ptl_tcp_module.super.ptl_first_frag_size = mca_ptl_tcp_component.tcp_frag_size;
|
|
|
|
}
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
|
2004-06-04 02:13:01 +04:00
|
|
|
/*
|
|
|
|
* module cleanup - sanity checking of queue lengths
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_component_close(void)
|
2004-01-14 18:15:17 +03:00
|
|
|
{
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t* item;
|
2004-11-02 16:14:34 +03:00
|
|
|
#ifdef WIN32
|
|
|
|
WSACleanup();
|
|
|
|
#endif
|
2004-11-18 01:47:08 +03:00
|
|
|
#if OMPI_ENABLE_DEBUG
|
2004-08-02 04:24:22 +04:00
|
|
|
if (mca_ptl_tcp_component.tcp_send_frags.fl_num_allocated !=
|
2005-07-03 20:22:16 +04:00
|
|
|
mca_ptl_tcp_component.tcp_send_frags.super.opal_list_length) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "tcp send frags: %d allocated %d returned\n",
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_send_frags.fl_num_allocated,
|
2005-07-03 20:22:16 +04:00
|
|
|
mca_ptl_tcp_component.tcp_send_frags.super.opal_list_length);
|
2004-04-12 19:39:15 +04:00
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
if (mca_ptl_tcp_component.tcp_recv_frags.fl_num_allocated !=
|
2005-07-03 20:22:16 +04:00
|
|
|
mca_ptl_tcp_component.tcp_recv_frags.super.opal_list_length) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "tcp recv frags: %d allocated %d returned\n",
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_recv_frags.fl_num_allocated,
|
2005-07-03 20:22:16 +04:00
|
|
|
mca_ptl_tcp_component.tcp_recv_frags.super.opal_list_length);
|
2004-04-12 19:39:15 +04:00
|
|
|
}
|
2004-11-18 01:47:08 +03:00
|
|
|
#endif
|
2004-04-12 19:39:15 +04:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
if(NULL != mca_ptl_tcp_component.tcp_if_include)
|
|
|
|
free(mca_ptl_tcp_component.tcp_if_include);
|
|
|
|
if(NULL != mca_ptl_tcp_component.tcp_if_exclude)
|
|
|
|
free(mca_ptl_tcp_component.tcp_if_exclude);
|
|
|
|
if (NULL != mca_ptl_tcp_component.tcp_ptl_modules)
|
|
|
|
free(mca_ptl_tcp_component.tcp_ptl_modules);
|
2004-02-05 20:12:59 +03:00
|
|
|
|
2004-08-11 20:56:45 +04:00
|
|
|
if (mca_ptl_tcp_component.tcp_listen_sd >= 0) {
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_del(&mca_ptl_tcp_component.tcp_recv_event);
|
2004-08-03 02:16:35 +04:00
|
|
|
close(mca_ptl_tcp_component.tcp_listen_sd);
|
2004-09-16 17:01:32 +04:00
|
|
|
mca_ptl_tcp_component.tcp_listen_sd = -1;
|
2004-08-11 20:56:45 +04:00
|
|
|
}
|
2004-09-30 19:09:29 +04:00
|
|
|
|
|
|
|
/* cleanup any pending events */
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&mca_ptl_tcp_component.tcp_lock);
|
2005-07-03 20:22:16 +04:00
|
|
|
for(item = opal_list_remove_first(&mca_ptl_tcp_component.tcp_events);
|
2004-09-30 19:09:29 +04:00
|
|
|
item != NULL;
|
2005-07-03 20:22:16 +04:00
|
|
|
item = opal_list_remove_first(&mca_ptl_tcp_component.tcp_events)) {
|
2004-09-30 19:09:29 +04:00
|
|
|
mca_ptl_tcp_event_t* event = (mca_ptl_tcp_event_t*)item;
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_del(&event->event);
|
2004-09-30 19:09:29 +04:00
|
|
|
OBJ_RELEASE(event);
|
|
|
|
}
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&mca_ptl_tcp_component.tcp_lock);
|
2004-09-30 19:09:29 +04:00
|
|
|
|
|
|
|
/* release resources */
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_procs);
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_pending_acks);
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_events);
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_send_frags);
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_recv_frags);
|
|
|
|
OBJ_DESTRUCT(&mca_ptl_tcp_component.tcp_lock);
|
2004-09-03 04:06:57 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/*
|
|
|
|
* Create a ptl instance and add to modules list.
|
|
|
|
*/
|
|
|
|
|
2004-05-19 01:06:11 +04:00
|
|
|
static int mca_ptl_tcp_create(int if_index, const char* if_name)
|
2004-03-26 17:15:20 +03:00
|
|
|
{
|
2004-10-28 22:13:43 +04:00
|
|
|
mca_ptl_tcp_module_t* ptl = (mca_ptl_tcp_module_t *)malloc(sizeof(mca_ptl_tcp_module_t));
|
2004-05-19 01:06:11 +04:00
|
|
|
char param[256];
|
2004-03-26 17:15:20 +03:00
|
|
|
if(NULL == ptl)
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
2004-08-02 04:24:22 +04:00
|
|
|
memcpy(ptl, &mca_ptl_tcp_module, sizeof(mca_ptl_tcp_module));
|
2005-07-03 20:22:16 +04:00
|
|
|
OBJ_CONSTRUCT(&ptl->ptl_peers, opal_list_t);
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_ptl_modules[mca_ptl_tcp_component.tcp_num_ptl_modules++] = ptl;
|
2004-05-19 01:06:11 +04:00
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/* initialize the ptl */
|
|
|
|
ptl->ptl_ifindex = if_index;
|
2004-04-23 05:38:41 +04:00
|
|
|
#if MCA_PTL_TCP_STATISTICS
|
|
|
|
ptl->ptl_bytes_recv = 0;
|
|
|
|
ptl->ptl_bytes_sent = 0;
|
|
|
|
ptl->ptl_send_handler = 0;
|
|
|
|
#endif
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_ifindextoaddr(if_index, (struct sockaddr*)&ptl->ptl_ifaddr, sizeof(ptl->ptl_ifaddr));
|
|
|
|
opal_ifindextomask(if_index, (struct sockaddr*)&ptl->ptl_ifmask, sizeof(ptl->ptl_ifmask));
|
2004-05-19 01:06:11 +04:00
|
|
|
|
|
|
|
/* allow user to specify interface bandwidth */
|
|
|
|
sprintf(param, "bandwidth_%s", if_name);
|
|
|
|
ptl->super.ptl_bandwidth = mca_ptl_tcp_param_register_int(param, 0);
|
|
|
|
|
|
|
|
/* allow user to override/specify latency ranking */
|
|
|
|
sprintf(param, "latency_%s", if_name);
|
|
|
|
ptl->super.ptl_latency = mca_ptl_tcp_param_register_int(param, 0);
|
|
|
|
|
2004-08-28 03:44:21 +04:00
|
|
|
#if OMPI_ENABLE_DEBUG && 0
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,"interface: %s bandwidth %d latency %d\n",
|
2004-05-19 01:06:11 +04:00
|
|
|
if_name, ptl->super.ptl_bandwidth, ptl->super.ptl_latency);
|
|
|
|
#endif
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-03-26 17:15:20 +03:00
|
|
|
}
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
/*
|
|
|
|
* Create a TCP PTL instance for either:
|
|
|
|
* (1) all interfaces specified by the user
|
|
|
|
* (2) all available interfaces
|
|
|
|
* (3) all available interfaces except for those excluded by the user
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
static int mca_ptl_tcp_component_create_instances(void)
|
2004-01-15 03:58:54 +03:00
|
|
|
{
|
2005-07-04 05:36:20 +04:00
|
|
|
int if_count = opal_ifcount();
|
2004-01-15 03:58:54 +03:00
|
|
|
int if_index;
|
|
|
|
char **include;
|
|
|
|
char **exclude;
|
|
|
|
char **argv;
|
|
|
|
|
|
|
|
if(if_count <= 0)
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
/* allocate memory for ptls */
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_max_ptl_modules = if_count;
|
2004-10-28 22:13:43 +04:00
|
|
|
mca_ptl_tcp_component.tcp_ptl_modules = (mca_ptl_tcp_module_t **)malloc(if_count * sizeof(mca_ptl_tcp_module_t*));
|
2004-08-02 04:24:22 +04:00
|
|
|
if(NULL == mca_ptl_tcp_component.tcp_ptl_modules)
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERR_OUT_OF_RESOURCE;
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/* if the user specified an interface list - use these exclusively */
|
2005-07-04 04:13:44 +04:00
|
|
|
argv = include = opal_argv_split(mca_ptl_tcp_component.tcp_if_include,',');
|
2004-01-15 03:58:54 +03:00
|
|
|
while(argv && *argv) {
|
|
|
|
char* if_name = *argv;
|
2005-07-04 05:36:20 +04:00
|
|
|
int if_index = opal_ifnametoindex(if_name);
|
2004-01-15 03:58:54 +03:00
|
|
|
if(if_index < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,"mca_ptl_tcp_component_init: invalid interface \"%s\"", if_name);
|
2004-01-15 03:58:54 +03:00
|
|
|
} else {
|
2004-05-19 01:06:11 +04:00
|
|
|
mca_ptl_tcp_create(if_index, if_name);
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
argv++;
|
|
|
|
}
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_free(include);
|
2004-08-02 04:24:22 +04:00
|
|
|
if(mca_ptl_tcp_component.tcp_num_ptl_modules)
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
/* if the interface list was not specified by the user, create
|
|
|
|
* a PTL for each interface that was not excluded.
|
|
|
|
*/
|
2005-07-04 04:13:44 +04:00
|
|
|
exclude = opal_argv_split(mca_ptl_tcp_component.tcp_if_exclude,',');
|
2005-07-04 05:36:20 +04:00
|
|
|
for(if_index = opal_ifbegin(); if_index >= 0; if_index = opal_ifnext(if_index)) {
|
2004-01-15 03:58:54 +03:00
|
|
|
char if_name[32];
|
2005-07-04 05:36:20 +04:00
|
|
|
opal_ifindextoname(if_index, if_name, sizeof(if_name));
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
/* check to see if this interface exists in the exclude list */
|
2005-07-04 05:36:20 +04:00
|
|
|
if(opal_ifcount() > 1) {
|
2004-10-01 01:23:10 +04:00
|
|
|
argv = exclude;
|
|
|
|
while(argv && *argv) {
|
|
|
|
if(strncmp(*argv,if_name,strlen(*argv)) == 0)
|
|
|
|
break;
|
|
|
|
argv++;
|
|
|
|
}
|
|
|
|
/* if this interface was not found in the excluded list - create a PTL */
|
|
|
|
if(argv == 0 || *argv == 0) {
|
|
|
|
mca_ptl_tcp_create(if_index, if_name);
|
|
|
|
}
|
|
|
|
} else {
|
2004-05-19 01:06:11 +04:00
|
|
|
mca_ptl_tcp_create(if_index, if_name);
|
2004-04-12 19:39:15 +04:00
|
|
|
}
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_argv_free(exclude);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a listen socket and bind to all interfaces
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
static int mca_ptl_tcp_component_create_listen(void)
|
2004-01-14 18:15:17 +03:00
|
|
|
{
|
2004-03-12 01:02:01 +03:00
|
|
|
int flags;
|
2004-03-26 17:15:20 +03:00
|
|
|
struct sockaddr_in inaddr;
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_socklen_t addrlen;
|
2004-03-12 01:02:01 +03:00
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
/* create a listen socket for incoming connections */
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_listen_sd = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if(mca_ptl_tcp_component.tcp_listen_sd < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,"mca_ptl_tcp_component_init: socket() failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_set_socket_options(mca_ptl_tcp_component.tcp_listen_sd);
|
2004-01-15 03:58:54 +03:00
|
|
|
|
|
|
|
/* bind to all addresses and dynamically assigned port */
|
2004-03-12 01:02:01 +03:00
|
|
|
memset(&inaddr, 0, sizeof(inaddr));
|
2004-01-15 03:58:54 +03:00
|
|
|
inaddr.sin_family = AF_INET;
|
|
|
|
inaddr.sin_addr.s_addr = INADDR_ANY;
|
|
|
|
inaddr.sin_port = 0;
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
if(bind(mca_ptl_tcp_component.tcp_listen_sd, (struct sockaddr*)&inaddr, sizeof(inaddr)) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0,"mca_ptl_tcp_component_init: bind() failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* resolve system assignend port */
|
2004-03-26 17:15:20 +03:00
|
|
|
addrlen = sizeof(struct sockaddr_in);
|
2004-08-02 04:24:22 +04:00
|
|
|
if(getsockname(mca_ptl_tcp_component.tcp_listen_sd, (struct sockaddr*)&inaddr, &addrlen) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_init: getsockname() failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_listen_port = inaddr.sin_port;
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-03-12 01:02:01 +03:00
|
|
|
/* setup listen backlog to maximum allowed by kernel */
|
2004-08-02 04:24:22 +04:00
|
|
|
if(listen(mca_ptl_tcp_component.tcp_listen_sd, SOMAXCONN) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_init: listen() failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-03-12 01:02:01 +03:00
|
|
|
}
|
2004-05-19 01:06:11 +04:00
|
|
|
|
2004-03-12 01:02:01 +03:00
|
|
|
/* set socket up to be non-blocking, otherwise accept could block */
|
2004-08-02 04:24:22 +04:00
|
|
|
if((flags = fcntl(mca_ptl_tcp_component.tcp_listen_sd, F_GETFL, 0)) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_init: fcntl(F_GETFL) failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-03-12 01:02:01 +03:00
|
|
|
} else {
|
|
|
|
flags |= O_NONBLOCK;
|
2004-08-02 04:24:22 +04:00
|
|
|
if(fcntl(mca_ptl_tcp_component.tcp_listen_sd, F_SETFL, flags) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_init: fcntl(F_SETFL) failed with errno=%d", ompi_socket_errno);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_ERROR;
|
2004-03-12 01:02:01 +03:00
|
|
|
}
|
|
|
|
}
|
2005-04-10 04:26:35 +04:00
|
|
|
|
2004-01-29 01:52:51 +03:00
|
|
|
/* register listen port */
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_set(
|
2004-08-02 04:24:22 +04:00
|
|
|
&mca_ptl_tcp_component.tcp_recv_event,
|
|
|
|
mca_ptl_tcp_component.tcp_listen_sd,
|
2005-07-04 03:09:55 +04:00
|
|
|
OPAL_EV_READ|OPAL_EV_PERSIST,
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component_recv_handler,
|
2004-02-13 16:56:55 +03:00
|
|
|
0);
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Register TCP module addressing information. The MCA framework
|
|
|
|
* will make this available to all peers.
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
static int mca_ptl_tcp_component_exchange(void)
|
2004-01-15 03:58:54 +03:00
|
|
|
{
|
2004-12-06 05:15:34 +03:00
|
|
|
int rc=0;
|
|
|
|
size_t i=0;
|
2004-08-02 04:24:22 +04:00
|
|
|
size_t size = mca_ptl_tcp_component.tcp_num_ptl_modules * sizeof(mca_ptl_tcp_addr_t);
|
2004-08-28 03:44:21 +04:00
|
|
|
if(mca_ptl_tcp_component.tcp_num_ptl_modules != 0) {
|
2004-10-28 22:13:43 +04:00
|
|
|
mca_ptl_tcp_addr_t *addrs = (mca_ptl_tcp_addr_t *)malloc(size);
|
2004-08-28 03:44:21 +04:00
|
|
|
for(i=0; i<mca_ptl_tcp_component.tcp_num_ptl_modules; i++) {
|
|
|
|
mca_ptl_tcp_module_t* ptl = mca_ptl_tcp_component.tcp_ptl_modules[i];
|
2005-04-10 04:26:35 +04:00
|
|
|
addrs[i].addr_inet = ptl->ptl_ifaddr.sin_addr;
|
|
|
|
addrs[i].addr_port = mca_ptl_tcp_component.tcp_listen_port;
|
|
|
|
addrs[i].addr_inuse = 0;
|
2004-08-28 03:44:21 +04:00
|
|
|
}
|
2005-08-05 22:03:30 +04:00
|
|
|
rc = mca_pml_base_modex_send(&mca_ptl_tcp_component.super.ptlm_version, addrs, size);
|
2004-08-28 03:44:21 +04:00
|
|
|
free(addrs);
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
2004-02-03 01:58:24 +03:00
|
|
|
return rc;
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TCP module initialization:
|
|
|
|
* (1) read interface list from kernel and compare against module parameters
|
|
|
|
* then create a PTL instance for selected interfaces
|
|
|
|
* (2) setup TCP listen socket for incoming connection attempts
|
|
|
|
* (3) register PTL parameters with the MCA
|
|
|
|
*/
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_base_module_t** mca_ptl_tcp_component_init(int *num_ptl_modules,
|
2005-03-27 17:05:23 +04:00
|
|
|
bool enable_progress_threads,
|
|
|
|
bool enable_mpi_threads)
|
2004-01-15 03:58:54 +03:00
|
|
|
{
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_base_module_t **ptls;
|
|
|
|
*num_ptl_modules = 0;
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
ompi_free_list_init(&mca_ptl_tcp_component.tcp_send_frags,
|
2004-01-29 01:52:51 +03:00
|
|
|
sizeof(mca_ptl_tcp_send_frag_t),
|
2004-02-13 01:42:39 +03:00
|
|
|
OBJ_CLASS(mca_ptl_tcp_send_frag_t),
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_free_list_num,
|
|
|
|
mca_ptl_tcp_component.tcp_free_list_max,
|
|
|
|
mca_ptl_tcp_component.tcp_free_list_inc,
|
2004-01-29 01:52:51 +03:00
|
|
|
NULL); /* use default allocator */
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
ompi_free_list_init(&mca_ptl_tcp_component.tcp_recv_frags,
|
2004-01-29 01:52:51 +03:00
|
|
|
sizeof(mca_ptl_tcp_recv_frag_t),
|
2004-02-13 01:42:39 +03:00
|
|
|
OBJ_CLASS(mca_ptl_tcp_recv_frag_t),
|
2004-08-02 04:24:22 +04:00
|
|
|
mca_ptl_tcp_component.tcp_free_list_num,
|
|
|
|
mca_ptl_tcp_component.tcp_free_list_max,
|
|
|
|
mca_ptl_tcp_component.tcp_free_list_inc,
|
2004-01-29 01:52:51 +03:00
|
|
|
NULL); /* use default allocator */
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
/* create a PTL TCP module for selected interfaces */
|
2004-08-02 04:24:22 +04:00
|
|
|
if(mca_ptl_tcp_component_create_instances() != OMPI_SUCCESS)
|
2004-01-15 03:58:54 +03:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* create a TCP listen socket for incoming connection attempts */
|
2004-08-02 04:24:22 +04:00
|
|
|
if(mca_ptl_tcp_component_create_listen() != OMPI_SUCCESS)
|
2004-01-15 03:58:54 +03:00
|
|
|
return 0;
|
|
|
|
|
2004-03-26 17:15:20 +03:00
|
|
|
/* publish TCP parameters with the MCA framework */
|
2004-08-02 04:24:22 +04:00
|
|
|
if(mca_ptl_tcp_component_exchange() != OMPI_SUCCESS)
|
2004-01-15 03:58:54 +03:00
|
|
|
return 0;
|
|
|
|
|
2004-10-28 22:13:43 +04:00
|
|
|
ptls = (mca_ptl_base_module_t **)malloc(mca_ptl_tcp_component.tcp_num_ptl_modules *
|
2004-08-02 04:24:22 +04:00
|
|
|
sizeof(mca_ptl_base_module_t*));
|
2004-02-13 18:12:46 +03:00
|
|
|
if(NULL == ptls)
|
|
|
|
return NULL;
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
memcpy(ptls, mca_ptl_tcp_component.tcp_ptl_modules, mca_ptl_tcp_component.tcp_num_ptl_modules*sizeof(mca_ptl_tcp_module_t*));
|
|
|
|
*num_ptl_modules = mca_ptl_tcp_component.tcp_num_ptl_modules;
|
2004-11-18 01:47:08 +03:00
|
|
|
|
2004-02-13 18:12:46 +03:00
|
|
|
return ptls;
|
2004-01-14 18:15:17 +03:00
|
|
|
}
|
|
|
|
|
2004-04-12 19:39:15 +04:00
|
|
|
/*
|
|
|
|
* TCP module control
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_component_control(int param, void* value, size_t size)
|
2004-04-12 19:39:15 +04:00
|
|
|
{
|
|
|
|
switch(param) {
|
|
|
|
case MCA_PTL_ENABLE:
|
2004-11-18 01:47:08 +03:00
|
|
|
if(*(int*)value) {
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_add(&mca_ptl_tcp_component.tcp_recv_event, 0);
|
2005-07-03 20:52:32 +04:00
|
|
|
if(opal_hash_table_get_size(&mca_ptl_tcp_component.tcp_procs) > 0) {
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_progress_events(OPAL_EVLOOP_NONBLOCK);
|
2004-11-18 01:47:08 +03:00
|
|
|
}
|
|
|
|
} else {
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_del(&mca_ptl_tcp_component.tcp_recv_event);
|
2004-11-18 01:47:08 +03:00
|
|
|
}
|
2004-04-12 19:39:15 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-04-12 19:39:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TCP module progress.
|
|
|
|
*/
|
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
int mca_ptl_tcp_component_progress(mca_ptl_tstamp_t tstamp)
|
2004-04-12 19:39:15 +04:00
|
|
|
{
|
2004-06-07 19:33:53 +04:00
|
|
|
return OMPI_SUCCESS;
|
2004-04-12 19:39:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-15 20:43:54 +03:00
|
|
|
/*
|
2004-08-02 04:24:22 +04:00
|
|
|
* Called by mca_ptl_tcp_component_recv() when the TCP listen
|
2004-01-15 20:43:54 +03:00
|
|
|
* socket has pending connection requests. Accept incoming
|
|
|
|
* requests and queue for completion of the connection handshake.
|
|
|
|
*/
|
|
|
|
|
2004-09-16 17:01:32 +04:00
|
|
|
|
2004-08-02 04:24:22 +04:00
|
|
|
static void mca_ptl_tcp_component_accept(void)
|
2004-01-15 20:43:54 +03:00
|
|
|
{
|
|
|
|
while(true) {
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_socklen_t addrlen = sizeof(struct sockaddr_in);
|
2004-01-15 20:43:54 +03:00
|
|
|
struct sockaddr_in addr;
|
2004-09-30 19:09:29 +04:00
|
|
|
mca_ptl_tcp_event_t *event;
|
2004-08-02 04:24:22 +04:00
|
|
|
int sd = accept(mca_ptl_tcp_component.tcp_listen_sd, (struct sockaddr*)&addr, &addrlen);
|
2004-01-15 20:43:54 +03:00
|
|
|
if(sd < 0) {
|
2005-01-20 07:44:07 +03:00
|
|
|
IMPORTANT_WINDOWS_COMMENT();
|
2005-01-20 03:03:23 +03:00
|
|
|
if(ompi_socket_errno == EINTR)
|
2004-01-15 20:43:54 +03:00
|
|
|
continue;
|
2005-01-20 03:03:23 +03:00
|
|
|
if(ompi_socket_errno != EAGAIN || ompi_socket_errno != EWOULDBLOCK)
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_accept: accept() failed with errno %d.", ompi_socket_errno);
|
2004-01-15 20:43:54 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-04-23 05:38:41 +04:00
|
|
|
mca_ptl_tcp_set_socket_options(sd);
|
2004-01-29 01:52:51 +03:00
|
|
|
|
|
|
|
/* wait for receipt of peers process identifier to complete this connection */
|
2004-09-30 19:09:29 +04:00
|
|
|
|
|
|
|
event = OBJ_NEW(mca_ptl_tcp_event_t);
|
2005-07-04 03:09:55 +04:00
|
|
|
opal_event_set(&event->event, sd, OPAL_EV_READ, mca_ptl_tcp_component_recv_handler, event);
|
|
|
|
opal_event_add(&event->event, 0);
|
2004-01-15 20:43:54 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-15 03:58:54 +03:00
|
|
|
|
2004-01-15 20:43:54 +03:00
|
|
|
/*
|
2004-02-12 23:55:10 +03:00
|
|
|
* Event callback when there is data available on the registered
|
2004-01-29 01:52:51 +03:00
|
|
|
* socket to recv.
|
2004-01-15 20:43:54 +03:00
|
|
|
*/
|
2004-08-02 04:24:22 +04:00
|
|
|
static void mca_ptl_tcp_component_recv_handler(int sd, short flags, void* user)
|
2004-01-15 03:58:54 +03:00
|
|
|
{
|
2005-03-14 23:57:21 +03:00
|
|
|
orte_process_name_t guid;
|
2004-01-29 01:52:51 +03:00
|
|
|
struct sockaddr_in addr;
|
2004-03-25 22:18:13 +03:00
|
|
|
int retval;
|
|
|
|
mca_ptl_tcp_proc_t* ptl_proc;
|
2004-06-07 19:33:53 +04:00
|
|
|
ompi_socklen_t addr_len = sizeof(addr);
|
2004-10-28 22:13:43 +04:00
|
|
|
mca_ptl_tcp_event_t *event = (mca_ptl_tcp_event_t *)user;
|
2004-01-29 01:52:51 +03:00
|
|
|
|
2004-01-15 20:43:54 +03:00
|
|
|
/* accept new connections on the listen socket */
|
2004-08-02 04:24:22 +04:00
|
|
|
if(mca_ptl_tcp_component.tcp_listen_sd == sd) {
|
|
|
|
mca_ptl_tcp_component_accept();
|
2004-01-15 20:43:54 +03:00
|
|
|
return;
|
|
|
|
}
|
2004-09-30 19:09:29 +04:00
|
|
|
OBJ_RELEASE(event);
|
2004-01-29 01:52:51 +03:00
|
|
|
|
2004-07-01 18:49:54 +04:00
|
|
|
/* recv the process identifier */
|
2004-10-28 22:13:43 +04:00
|
|
|
retval = recv(sd, (char *)&guid, sizeof(guid), 0);
|
2004-07-01 18:49:54 +04:00
|
|
|
if(retval != sizeof(guid)) {
|
2004-01-29 01:52:51 +03:00
|
|
|
close(sd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-04-23 05:38:41 +04:00
|
|
|
/* now set socket up to be non-blocking */
|
|
|
|
if((flags = fcntl(sd, F_GETFL, 0)) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_recv_handler: fcntl(F_GETFL) failed with errno=%d", ompi_socket_errno);
|
2004-04-23 05:38:41 +04:00
|
|
|
} else {
|
|
|
|
flags |= O_NONBLOCK;
|
|
|
|
if(fcntl(sd, F_SETFL, flags) < 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_recv_handler: fcntl(F_SETFL) failed with errno=%d", ompi_socket_errno);
|
2004-04-23 05:38:41 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-29 01:52:51 +03:00
|
|
|
/* lookup the corresponding process */
|
2004-07-01 18:49:54 +04:00
|
|
|
ptl_proc = mca_ptl_tcp_proc_lookup(&guid);
|
2004-01-29 01:52:51 +03:00
|
|
|
if(NULL == ptl_proc) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_recv_handler: unable to locate process");
|
2004-01-29 01:52:51 +03:00
|
|
|
close(sd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* lookup peer address */
|
|
|
|
if(getpeername(sd, (struct sockaddr*)&addr, &addr_len) != 0) {
|
2005-07-04 03:31:27 +04:00
|
|
|
opal_output(0, "mca_ptl_tcp_component_recv_handler: getpeername() failed with errno=%d", ompi_socket_errno);
|
2004-01-29 01:52:51 +03:00
|
|
|
close(sd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* are there any existing peer instances will to accept this connection */
|
|
|
|
if(mca_ptl_tcp_proc_accept(ptl_proc, &addr, sd) == false) {
|
|
|
|
close(sd);
|
|
|
|
return;
|
|
|
|
}
|
2004-01-15 03:58:54 +03:00
|
|
|
}
|
|
|
|
|