Update the multicast framework to allow specification of different message scopes per various RFCs. Redefine the API a little to utilize channel numbers without worrying about the specifics of their addressing
This commit was SVN r22037.
Этот коммит содержится в:
родитель
84a45fea0a
Коммит
1d7ab97c84
@ -484,8 +484,7 @@ checkin:
|
||||
opal_dss.pack(&buf, &orte_process_info.nodename, 1, OPAL_STRING);
|
||||
|
||||
/* set the recv to get the answer */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmcast.recv_nb(ORTE_RMCAST_SYS_ADDR,
|
||||
ORTE_RMCAST_NON_PERSISTENT,
|
||||
if (ORTE_SUCCESS != (rc = orte_rmcast.recv_nb(0, ORTE_RMCAST_NON_PERSISTENT,
|
||||
ORTE_RMCAST_TAG_BOOTSTRAP,
|
||||
cbfunc, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
@ -494,8 +493,7 @@ checkin:
|
||||
}
|
||||
|
||||
/* send the request */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmcast.send(ORTE_RMCAST_SYS_ADDR,
|
||||
ORTE_RMCAST_TAG_BOOTSTRAP,
|
||||
if (ORTE_SUCCESS != (rc = orte_rmcast.send(0, ORTE_RMCAST_TAG_BOOTSTRAP,
|
||||
&buf))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&buf);
|
||||
|
@ -24,6 +24,7 @@ libmca_rmcast_la_SOURCES =
|
||||
|
||||
# header setup
|
||||
nobase_orte_HEADERS =
|
||||
dist_pkgdata_DATA =
|
||||
|
||||
# local files
|
||||
headers = rmcast.h rmcast_types.h
|
||||
|
@ -7,6 +7,8 @@
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
dist_pkgdata_DATA += base/help-rmcast-base.txt
|
||||
|
||||
headers += \
|
||||
base/base.h
|
||||
|
||||
|
@ -31,10 +31,10 @@ ORTE_DECLSPEC int orte_rmcast_base_open(void);
|
||||
typedef struct {
|
||||
int rmcast_output;
|
||||
opal_list_t rmcast_opened;
|
||||
uint8_t subnet;
|
||||
uint8_t scope;
|
||||
uint16_t af_family;
|
||||
uint32_t base_ip_addr;
|
||||
uint8_t octet1[2];
|
||||
uint8_t octet2[2];
|
||||
uint8_t octet3[2];
|
||||
uint8_t channel_offset;
|
||||
uint16_t ports[256];
|
||||
} orte_rmcast_base_t;
|
||||
|
||||
|
30
orte/mca/rmcast/base/help-rmcast-base.txt
Обычный файл
30
orte/mca/rmcast/base/help-rmcast-base.txt
Обычный файл
@ -0,0 +1,30 @@
|
||||
# -*- text -*-
|
||||
#
|
||||
# Copyright (c) 2009 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
# This is the US/English general help file for Open RTE.
|
||||
#
|
||||
[unrecognized-scope]
|
||||
An out-of-range value for the scope of the multicast address range was specified:
|
||||
|
||||
Scope: %s
|
||||
|
||||
Please specify a valid scope - as a reminder, you can use
|
||||
|
||||
ompi_info -param rmcast all
|
||||
|
||||
to see the allowed values.
|
||||
#
|
||||
[value-range]
|
||||
The specified parameter is outside of valid range:
|
||||
|
||||
Parameter: %s
|
||||
Value given: %d
|
||||
Valid range: %s
|
||||
|
||||
Please adjust the value and try again.
|
@ -26,6 +26,8 @@
|
||||
#include "opal/util/argv.h"
|
||||
|
||||
#include "orte/util/parse_options.h"
|
||||
#include "orte/util/show_help.h"
|
||||
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
|
||||
#endif
|
||||
@ -79,20 +81,55 @@ int orte_rmcast_base_open(void)
|
||||
char *tmp, **ports=NULL;
|
||||
|
||||
/* public multicast channel for this job */
|
||||
mca_base_param_reg_int_name("rmcast", "base_multicast_subnet",
|
||||
"Multicast subnet for the ORTE system (default: 239)",
|
||||
false, false, (int)ORTE_RMCAST_DEFAULT_SUBNET, &value);
|
||||
mca_base_param_reg_string_name("rmcast", "base_scope",
|
||||
"Scope of the multicast system [link (default) | site | org | global]",
|
||||
false, false, "link", &tmp);
|
||||
if (0 == strcasecmp(tmp, "site")) {
|
||||
orte_rmcast_base.octet1[0] = 239;
|
||||
orte_rmcast_base.octet1[1] = 239;
|
||||
orte_rmcast_base.octet2[0] = 255;
|
||||
orte_rmcast_base.octet2[1] = 255;
|
||||
orte_rmcast_base.octet3[0] = 0;
|
||||
orte_rmcast_base.octet3[1] = 255;
|
||||
} else if (0 == strcasecmp(tmp, "org")) {
|
||||
orte_rmcast_base.octet1[0] = 239;
|
||||
orte_rmcast_base.octet1[1] = 239;
|
||||
orte_rmcast_base.octet2[0] = 192;
|
||||
orte_rmcast_base.octet2[1] = 195;
|
||||
orte_rmcast_base.octet3[0] = 0;
|
||||
orte_rmcast_base.octet3[1] = 255;
|
||||
} else if (0 == strcasecmp(tmp, "global")) {
|
||||
orte_rmcast_base.octet1[0] = 224;
|
||||
orte_rmcast_base.octet1[1] = 238;
|
||||
orte_rmcast_base.octet2[0] = 0;
|
||||
orte_rmcast_base.octet2[1] = 255;
|
||||
orte_rmcast_base.octet3[0] = 1;
|
||||
orte_rmcast_base.octet3[1] = 255;
|
||||
} else if (0 == strcasecmp(tmp, "link")) {
|
||||
/* default to link */
|
||||
orte_rmcast_base.octet1[0] = 224;
|
||||
orte_rmcast_base.octet1[1] = 224;
|
||||
orte_rmcast_base.octet2[0] = 0;
|
||||
orte_rmcast_base.octet2[1] = 0;
|
||||
orte_rmcast_base.octet3[0] = 0;
|
||||
orte_rmcast_base.octet3[1] = 0;
|
||||
} else {
|
||||
orte_show_help("help-rmcast-base.txt", "unrecognized-scope", true, tmp);
|
||||
return ORTE_ERR_SILENT;
|
||||
}
|
||||
|
||||
/* channel offset */
|
||||
mca_base_param_reg_int_name("rmcast", "base_starting_channel",
|
||||
"Offset to use within each network when computing channel (default: 0)",
|
||||
false, false, 0, &value);
|
||||
/* check for correctness of value */
|
||||
orte_rmcast_base.subnet = (uint8_t)value;
|
||||
|
||||
/* scope of the public channel */
|
||||
mca_base_param_reg_int_name("rmcast", "base_multicast_scope",
|
||||
"Scope of the multicast channel (default: 255)",
|
||||
false, false, (int)ORTE_RMCAST_DEFAULT_SCOPE, &value);
|
||||
/* check for correctness of value */
|
||||
orte_rmcast_base.scope = (uint8_t)value;
|
||||
|
||||
|
||||
if (value < 0 || value > 255) {
|
||||
orte_show_help("help-rmcast-base.txt", "value-range", true,
|
||||
"starting channel", value, "0-255");
|
||||
return ORTE_ERR_SILENT;
|
||||
}
|
||||
orte_rmcast_base.channel_offset = (uint8_t)value;
|
||||
|
||||
/* range of available ports */
|
||||
mca_base_param_reg_string_name("rmcast", "base_multicast_ports",
|
||||
"Ports available for multicast channels (default: 6900-7155)",
|
||||
@ -107,11 +144,6 @@ int orte_rmcast_base_open(void)
|
||||
orte_rmcast_base.ports[i] = pval;
|
||||
}
|
||||
|
||||
/* create the base IP multicase addr */
|
||||
orte_rmcast_base.af_family = AF_INET;
|
||||
orte_rmcast_base.base_ip_addr = ((orte_rmcast_base.subnet << 24) & 0xFF000000) |
|
||||
((orte_rmcast_base.scope << 16) & 0x00FF0000);
|
||||
|
||||
/* Debugging / verbose output. Always have stream open, with
|
||||
verbose set by the mca open system... */
|
||||
orte_rmcast_base.rmcast_output = opal_output_open(NULL);
|
||||
|
@ -40,8 +40,12 @@
|
||||
static opal_mutex_t lock;
|
||||
static opal_list_t recvs;
|
||||
static opal_list_t channels;
|
||||
static unsigned int next_channel;
|
||||
static opal_list_t networks;
|
||||
static bool init_completed = false;
|
||||
static uint8_t next_octet1 = 0;
|
||||
static uint8_t next_octet2 = 0;
|
||||
static uint8_t next_octet3 = 0;
|
||||
static unsigned int next_channel = 0;
|
||||
|
||||
/* LOCAL FUNCTIONS */
|
||||
#define CLOSE_THE_SOCKET(socket) \
|
||||
@ -52,17 +56,40 @@ static bool init_completed = false;
|
||||
|
||||
static void recv_handler(int sd, short flags, void* user);
|
||||
|
||||
static int setup_socket(int *sd, int channel, bool bindsocket);
|
||||
static int setup_socket(int *sd, uint32_t chan, uint16_t port, bool bindsocket);
|
||||
|
||||
static void xmit_data(int sd, short flags, void* send_req);
|
||||
|
||||
static uint32_t parse_network(char *network);
|
||||
|
||||
/*
|
||||
* Data structure for tracking networks and their channels
|
||||
*/
|
||||
typedef struct {
|
||||
opal_list_item_t item;
|
||||
uint32_t network;
|
||||
uint8_t next_freq;
|
||||
} rmcast_basic_network_t;
|
||||
static void newtork_construct(rmcast_basic_network_t *ptr)
|
||||
{
|
||||
ptr->network = 0;
|
||||
ptr->next_freq = 0;
|
||||
}
|
||||
OBJ_CLASS_INSTANCE(rmcast_basic_network_t,
|
||||
opal_list_item_t,
|
||||
newtork_construct,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* Data structure for tracking assigned channels
|
||||
*/
|
||||
typedef struct {
|
||||
opal_list_item_t item;
|
||||
char *name;
|
||||
uint32_t channel;
|
||||
unsigned int channel;
|
||||
uint32_t full_addr;
|
||||
uint16_t port;
|
||||
uint8_t freq;
|
||||
int xmit;
|
||||
int recv;
|
||||
struct sockaddr_in addr;
|
||||
@ -79,6 +106,9 @@ static void channel_construct(rmcast_basic_channel_t *ptr)
|
||||
{
|
||||
ptr->name = NULL;
|
||||
ptr->channel = 0;
|
||||
ptr->full_addr = 0;
|
||||
ptr->port = 0;
|
||||
ptr->freq = 0;
|
||||
ptr->xmit = -1;
|
||||
ptr->recv = -1;
|
||||
memset(&ptr->addr, 0, sizeof(ptr->addr));
|
||||
@ -126,9 +156,9 @@ OBJ_CLASS_INSTANCE(rmcast_basic_channel_t,
|
||||
*/
|
||||
typedef struct {
|
||||
opal_list_item_t item;
|
||||
uint32_t channel;
|
||||
bool recvd;
|
||||
opal_buffer_t *data;
|
||||
uint32_t channel;
|
||||
orte_rmcast_tag_t tag;
|
||||
orte_rmcast_flag_t flags;
|
||||
orte_rmcast_callback_fn_t cbfunc;
|
||||
@ -137,6 +167,7 @@ typedef struct {
|
||||
|
||||
static void recv_construct(rmcast_basic_recv_t *ptr)
|
||||
{
|
||||
ptr->channel = 0;
|
||||
ptr->recvd = false;
|
||||
ptr->data = NULL;
|
||||
ptr->tag = ORTE_RMCAST_TAG_INVALID;
|
||||
@ -211,7 +242,7 @@ static int basic_recv_nb(unsigned int channel,
|
||||
static void cancel_recv(unsigned int channel,
|
||||
orte_rmcast_tag_t tag);
|
||||
|
||||
static unsigned int get_channel(char *name, uint8_t direction);
|
||||
static unsigned int open_channel(char *name, char *network, uint8_t direction);
|
||||
|
||||
/* The API's in this module are solely used to support LOCAL
|
||||
* procs - i.e., procs that are co-located to the HNP. Remote
|
||||
@ -227,15 +258,18 @@ orte_rmcast_module_t orte_rmcast_basic_module = {
|
||||
basic_recv,
|
||||
basic_recv_nb,
|
||||
cancel_recv,
|
||||
get_channel
|
||||
open_channel
|
||||
};
|
||||
|
||||
static int init(void)
|
||||
{
|
||||
int xmitsd, recvsd;
|
||||
rmcast_basic_channel_t *chan;
|
||||
int channel;
|
||||
rmcast_basic_network_t *net;
|
||||
uint8_t freq;
|
||||
char *name;
|
||||
int rc;
|
||||
uint16_t port;
|
||||
|
||||
if (init_completed) {
|
||||
return ORTE_SUCCESS;
|
||||
@ -249,39 +283,68 @@ static int init(void)
|
||||
OBJ_CONSTRUCT(&lock, opal_mutex_t);
|
||||
OBJ_CONSTRUCT(&recvs, opal_list_t);
|
||||
OBJ_CONSTRUCT(&channels, opal_list_t);
|
||||
OBJ_CONSTRUCT(&networks, opal_list_t);
|
||||
|
||||
/* define the starting point for new channels */
|
||||
next_channel = ORTE_RMCAST_DYNAMIC_CHANNELS;
|
||||
/* set the last octets to point at the beginning of the
|
||||
* specified octet ranges
|
||||
*/
|
||||
next_octet1 = orte_rmcast_base.octet1[0];
|
||||
next_octet2 = orte_rmcast_base.octet2[0];
|
||||
next_octet3 = orte_rmcast_base.octet3[0];
|
||||
|
||||
/* form our base-level network */
|
||||
net = OBJ_NEW(rmcast_basic_network_t);
|
||||
net->network = OPAL_IF_ASSEMBLE_NETWORK(next_octet1, next_octet2, next_octet3);
|
||||
|
||||
/* select our frequency and port */
|
||||
if (ORTE_PROC_IS_HNP || ORTE_PROC_IS_DAEMON || ORTE_PROC_IS_TOOL) {
|
||||
channel = ORTE_RMCAST_SYS_ADDR;
|
||||
freq = ORTE_RMCAST_SYS_ADDR + orte_rmcast_base.channel_offset;
|
||||
name = "system";
|
||||
} else if (ORTE_PROC_IS_APP) {
|
||||
channel = ORTE_RMCAST_APP_PUBLIC_ADDR;
|
||||
freq = ORTE_RMCAST_APP_PUBLIC_ADDR + orte_rmcast_base.channel_offset;
|
||||
name = "app-public";
|
||||
} else {
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
port = orte_rmcast_base.ports[freq-orte_rmcast_base.channel_offset-1];
|
||||
|
||||
/* create a xmit socket */
|
||||
setup_socket(&xmitsd, channel, false);
|
||||
/* setup the next freq for this network */
|
||||
net->next_freq = freq + 1;
|
||||
|
||||
/* create a recv socket */
|
||||
setup_socket(&recvsd, channel, true);
|
||||
|
||||
|
||||
/* this channel is available for use, so add it to our list */
|
||||
/* add this channel to our list */
|
||||
chan = OBJ_NEW(rmcast_basic_channel_t);
|
||||
chan->name = strdup(name);
|
||||
chan->channel = channel;
|
||||
chan->full_addr = net->network + freq;
|
||||
chan->port = port;
|
||||
chan->channel = next_channel++;
|
||||
|
||||
/* setup the IPv4 addr info */
|
||||
chan->addr.sin_family = AF_INET;
|
||||
chan->addr.sin_addr.s_addr = htonl(chan->full_addr);
|
||||
chan->addr.sin_port = htons(chan->port);
|
||||
|
||||
OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output,
|
||||
"addr %03d.%03d.%03d.%03d port %d freq %d offset %d ports %d",
|
||||
OPAL_IF_FORMAT_ADDR(chan->full_addr), (int)port,
|
||||
(int)freq, (int)orte_rmcast_base.channel_offset,
|
||||
(int)orte_rmcast_base.ports[0]));
|
||||
|
||||
/* create a xmit socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&xmitsd, chan->full_addr, port, false))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
chan->xmit = xmitsd;
|
||||
chan->send_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
|
||||
/* create a recv socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&recvsd, chan->full_addr, port, true))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
chan->recv = recvsd;
|
||||
chan->recvd_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
chan->addr.sin_family = AF_INET;
|
||||
chan->addr.sin_addr.s_addr = htonl(orte_rmcast_base.base_ip_addr + channel);
|
||||
chan->addr.sin_port = htons(orte_rmcast_base.ports[channel-1]);
|
||||
|
||||
|
||||
/* setup an event to catch messages */
|
||||
opal_event_set(&chan->recv_ev, chan->recv, OPAL_EV_READ|OPAL_EV_PERSIST, recv_handler, chan);
|
||||
opal_event_add(&chan->recv_ev, 0);
|
||||
@ -309,6 +372,10 @@ static void finalize(void)
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&channels);
|
||||
while (NULL != (item = opal_list_remove_first(&networks))) {
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&networks);
|
||||
OPAL_THREAD_UNLOCK(&lock);
|
||||
|
||||
OBJ_DESTRUCT(&lock);
|
||||
@ -328,30 +395,11 @@ static int basic_send(unsigned int channel,
|
||||
orte_rmcast_tag_t tag,
|
||||
opal_buffer_t *buf)
|
||||
{
|
||||
uint32_t chan;
|
||||
opal_list_item_t *item;
|
||||
rmcast_basic_channel_t *chptr, *ch;
|
||||
rmcast_basic_send_t *snd;
|
||||
|
||||
chan = orte_rmcast_base.base_ip_addr + channel;
|
||||
OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: send of %lu bytes"
|
||||
" called on multicast channel %03d.%03d.%03d.%03d %0x",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
(unsigned long)buf->bytes_used, OPAL_IF_FORMAT_ADDR(chan), chan));
|
||||
|
||||
/* check the msg size to ensure it isn't too big */
|
||||
if (buf->bytes_used > (ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10)) {
|
||||
orte_show_help("help-orte-rmcast-basic.txt",
|
||||
"orte-rmcast-basic:msg-too-large", true,
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
OPAL_IF_FORMAT_ADDR(chan), tag,
|
||||
buf->bytes_used,
|
||||
ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10);
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* do we already have this channel open? */
|
||||
/* find the channel */
|
||||
ch = NULL;
|
||||
for (item = opal_list_get_first(&channels);
|
||||
item != opal_list_get_end(&channels);
|
||||
@ -363,8 +411,26 @@ static int basic_send(unsigned int channel,
|
||||
}
|
||||
}
|
||||
if (NULL == ch) {
|
||||
/* didn't find it - open the channel */
|
||||
return ORTE_ERR_NOT_IMPLEMENTED;
|
||||
/* didn't find it */
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: send of %lu bytes"
|
||||
" called on multicast channel %03d.%03d.%03d.%03d %0x",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
(unsigned long)buf->bytes_used,
|
||||
OPAL_IF_FORMAT_ADDR(ch->full_addr), ch->full_addr));
|
||||
|
||||
/* check the msg size to ensure it isn't too big */
|
||||
if (buf->bytes_used > (ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10)) {
|
||||
orte_show_help("help-orte-rmcast-basic.txt",
|
||||
"orte-rmcast-basic:msg-too-large", true,
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
OPAL_IF_FORMAT_ADDR(ch->full_addr), tag,
|
||||
buf->bytes_used,
|
||||
ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10);
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* queue it to be sent - preserves order! */
|
||||
@ -397,29 +463,11 @@ static int basic_send_nb(unsigned int channel,
|
||||
orte_rmcast_callback_fn_t cbfunc,
|
||||
void *cbdata)
|
||||
{
|
||||
uint32_t chan;
|
||||
opal_list_item_t *item;
|
||||
rmcast_basic_channel_t *chptr, *ch;
|
||||
rmcast_basic_send_t *snd;
|
||||
|
||||
chan = orte_rmcast_base.base_ip_addr + channel;
|
||||
OPAL_OUTPUT_VERBOSE((0, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: send_nb of %lu bytes"
|
||||
" called on multicast channel %03d.%03d.%03d.%03d %0x",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
(unsigned long)buf->bytes_used, OPAL_IF_FORMAT_ADDR(chan), chan));
|
||||
|
||||
if (buf->bytes_used > (ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10)) {
|
||||
orte_show_help("help-orte-rmcast-basic.txt",
|
||||
"orte-rmcast-basic:msg-too-large", true,
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
OPAL_IF_FORMAT_ADDR(chan), tag,
|
||||
buf->bytes_used,
|
||||
ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10);
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* do we already have this channel open? */
|
||||
/* find the channel */
|
||||
ch = NULL;
|
||||
for (item = opal_list_get_first(&channels);
|
||||
item != opal_list_get_end(&channels);
|
||||
@ -431,10 +479,27 @@ static int basic_send_nb(unsigned int channel,
|
||||
}
|
||||
}
|
||||
if (NULL == ch) {
|
||||
/* didn't find it - open the channel */
|
||||
return ORTE_ERR_NOT_IMPLEMENTED;
|
||||
/* didn't find it */
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
OPAL_OUTPUT_VERBOSE((0, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: send_nb of %lu bytes"
|
||||
" called on multicast channel %03d.%03d.%03d.%03d %0x",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
(unsigned long)buf->bytes_used,
|
||||
OPAL_IF_FORMAT_ADDR(ch->full_addr), ch->full_addr));
|
||||
|
||||
if (buf->bytes_used > (ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10)) {
|
||||
orte_show_help("help-orte-rmcast-basic.txt",
|
||||
"orte-rmcast-basic:msg-too-large", true,
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||
OPAL_IF_FORMAT_ADDR(ch->full_addr), tag,
|
||||
buf->bytes_used,
|
||||
ORTE_RMCAST_BASIC_MAX_MSG_SIZE-10);
|
||||
return ORTE_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* queue it to be sent - preserves order! */
|
||||
snd = OBJ_NEW(rmcast_basic_send_t);
|
||||
snd->data = buf;
|
||||
@ -460,13 +525,29 @@ static int basic_recv(unsigned int channel,
|
||||
orte_rmcast_tag_t tag,
|
||||
opal_buffer_t *buf)
|
||||
{
|
||||
int32_t chan;
|
||||
opal_list_item_t *item;
|
||||
rmcast_basic_recv_t *recvptr;
|
||||
|
||||
chan = orte_rmcast_base.base_ip_addr + channel;
|
||||
rmcast_basic_channel_t *ch, *chptr;
|
||||
|
||||
/* find the channel */
|
||||
ch = NULL;
|
||||
for (item = opal_list_get_first(&channels);
|
||||
item != opal_list_get_end(&channels);
|
||||
item = opal_list_get_next(item)) {
|
||||
chptr = (rmcast_basic_channel_t*)item;
|
||||
if (channel == chptr->channel) {
|
||||
ch = chptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == ch) {
|
||||
/* didn't find it */
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: recv called on multicast channel %03d.%03d.%03d.%03d",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), OPAL_IF_FORMAT_ADDR(chan)));
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), OPAL_IF_FORMAT_ADDR(ch->full_addr)));
|
||||
|
||||
recvptr = OBJ_NEW(rmcast_basic_recv_t);
|
||||
recvptr->channel = channel;
|
||||
@ -488,13 +569,29 @@ static int basic_recv_nb(unsigned int channel,
|
||||
orte_rmcast_tag_t tag,
|
||||
orte_rmcast_callback_fn_t cbfunc, void *cbdata)
|
||||
{
|
||||
int32_t chan;
|
||||
opal_list_item_t *item;
|
||||
rmcast_basic_recv_t *recvptr;
|
||||
rmcast_basic_channel_t *ch, *chptr;
|
||||
|
||||
chan = orte_rmcast_base.base_ip_addr + channel;
|
||||
/* find the channel */
|
||||
ch = NULL;
|
||||
for (item = opal_list_get_first(&channels);
|
||||
item != opal_list_get_end(&channels);
|
||||
item = opal_list_get_next(item)) {
|
||||
chptr = (rmcast_basic_channel_t*)item;
|
||||
if (channel == chptr->channel) {
|
||||
ch = chptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == ch) {
|
||||
/* didn't find it */
|
||||
return ORTE_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
OPAL_OUTPUT_VERBOSE((2, orte_rmcast_base.rmcast_output,
|
||||
"%s rmcast:basic: recv_nb called on multicast channel %03d.%03d.%03d.%03d",
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), OPAL_IF_FORMAT_ADDR(chan)));
|
||||
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), OPAL_IF_FORMAT_ADDR(ch->full_addr)));
|
||||
|
||||
recvptr = OBJ_NEW(rmcast_basic_recv_t);
|
||||
recvptr->channel = channel;
|
||||
@ -529,10 +626,14 @@ static void cancel_recv(unsigned int channel,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int get_channel(char *name, uint8_t direction)
|
||||
static unsigned int open_channel(char *name, char *network, uint8_t direction)
|
||||
{
|
||||
opal_list_item_t *item;
|
||||
rmcast_basic_channel_t *nchan, *chan;
|
||||
rmcast_basic_network_t *net, *netitem;
|
||||
uint32_t netaddr;
|
||||
int rc;
|
||||
int xmitsd, recvsd;
|
||||
|
||||
/* see if this name has already been assigned a channel */
|
||||
chan = NULL;
|
||||
@ -541,7 +642,7 @@ static unsigned int get_channel(char *name, uint8_t direction)
|
||||
item = opal_list_get_next(item)) {
|
||||
nchan = (rmcast_basic_channel_t*)item;
|
||||
|
||||
if (0 == strcmp(nchan->name, name)) {
|
||||
if (0 == strcasecmp(nchan->name, name)) {
|
||||
chan = nchan;
|
||||
break;
|
||||
}
|
||||
@ -552,10 +653,10 @@ static unsigned int get_channel(char *name, uint8_t direction)
|
||||
* socket is setup
|
||||
*/
|
||||
if (0 > chan->xmit && ORTE_RMCAST_XMIT & direction) {
|
||||
setup_socket(&chan->xmit, chan->channel, false);
|
||||
setup_socket(&chan->xmit, chan->full_addr, chan->port, false);
|
||||
}
|
||||
if (0 > chan->recv && ORTE_RMCAST_RECV & direction) {
|
||||
setup_socket(&chan->recv, chan->channel, true);
|
||||
setup_socket(&chan->recv, chan->full_addr, chan->port, true);
|
||||
/* setup an event to catch messages */
|
||||
opal_event_set(&chan->recv_ev, chan->recv, OPAL_EV_READ, recv_handler, chan);
|
||||
opal_event_add(&chan->recv_ev, 0);
|
||||
@ -563,22 +664,118 @@ static unsigned int get_channel(char *name, uint8_t direction)
|
||||
return chan->channel;
|
||||
}
|
||||
|
||||
/* doesn't exist - create it */
|
||||
/* the named channel doesn't exist - did they give
|
||||
* us a specific network to use?
|
||||
*/
|
||||
if (NULL != network) {
|
||||
net = NULL;
|
||||
netaddr = parse_network(network);
|
||||
for (item = opal_list_get_first(&networks);
|
||||
item != opal_list_get_end(&networks);
|
||||
item = opal_list_get_next(item)) {
|
||||
netitem = (rmcast_basic_network_t*)item;
|
||||
|
||||
if (netaddr == netitem->network) {
|
||||
net = netitem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == net) {
|
||||
/* new network - create it */
|
||||
net = OBJ_NEW(rmcast_basic_network_t);
|
||||
net->network = OPAL_IF_ASSEMBLE_NETWORK(next_octet1, next_octet2, next_octet3);
|
||||
net->next_freq = orte_rmcast_base.channel_offset + 1;
|
||||
}
|
||||
/* assign next freq to the next available channel */
|
||||
chan = OBJ_NEW(rmcast_basic_channel_t);
|
||||
chan->name = strdup(name);
|
||||
chan->full_addr = net->network + net->next_freq;
|
||||
chan->port = orte_rmcast_base.ports[net->next_freq-orte_rmcast_base.channel_offset-1];
|
||||
chan->channel = next_channel++;
|
||||
/* setup the IPv4 addr info */
|
||||
chan->addr.sin_family = AF_INET;
|
||||
chan->addr.sin_addr.s_addr = htonl(chan->full_addr);
|
||||
chan->addr.sin_port = htons(chan->port);
|
||||
if (ORTE_RMCAST_XMIT & direction) {
|
||||
/* create a xmit socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&xmitsd, chan->full_addr, chan->port, false))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return 0;
|
||||
}
|
||||
chan->xmit = xmitsd;
|
||||
chan->send_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
}
|
||||
if (ORTE_RMCAST_RECV & direction) {
|
||||
/* create a recv socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&recvsd, chan->full_addr, chan->port, true))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return 0;
|
||||
}
|
||||
chan->recv = recvsd;
|
||||
chan->recvd_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
}
|
||||
/* change to the next freq */
|
||||
net->next_freq++;
|
||||
return chan->channel;
|
||||
}
|
||||
|
||||
/* if we get here, then we couldn't find a channel of the given name
|
||||
* AND we were not given a network address to use. In this case, use
|
||||
* the next available network/freq
|
||||
*
|
||||
* RHC: for now, we are not going to worry about balancing loads
|
||||
* across available networks. We are just going to use the next
|
||||
* network with an available freq
|
||||
*/
|
||||
|
||||
net = NULL;
|
||||
for (item = opal_list_get_first(&networks);
|
||||
item != opal_list_get_end(&networks);
|
||||
item = opal_list_get_next(item)) {
|
||||
netitem = (rmcast_basic_network_t*)item;
|
||||
|
||||
if (netitem->next_freq < 255) {
|
||||
net = netitem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == net) {
|
||||
/* we are hosed */
|
||||
ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
|
||||
return 255;
|
||||
}
|
||||
|
||||
chan = OBJ_NEW(rmcast_basic_channel_t); /* puts it on list */
|
||||
chan->name = strdup(name);
|
||||
chan->full_addr = net->network + net->next_freq;
|
||||
chan->port = orte_rmcast_base.ports[net->next_freq-orte_rmcast_base.channel_offset-1];
|
||||
chan->channel = next_channel++;
|
||||
|
||||
/* open requested sockets */
|
||||
/* setup the IPv4 addr info */
|
||||
chan->addr.sin_family = AF_INET;
|
||||
chan->addr.sin_addr.s_addr = htonl(chan->full_addr);
|
||||
chan->addr.sin_port = htons(chan->port);
|
||||
if (ORTE_RMCAST_XMIT & direction) {
|
||||
setup_socket(&chan->xmit, chan->channel, false);
|
||||
/* create a xmit socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&xmitsd, chan->full_addr, chan->port, false))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return 255;
|
||||
}
|
||||
chan->xmit = xmitsd;
|
||||
chan->send_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
}
|
||||
if (ORTE_RMCAST_RECV & direction) {
|
||||
setup_socket(&chan->recv, chan->channel, true);
|
||||
/* setup an event to catch messages */
|
||||
opal_event_set(&chan->recv_ev, chan->recv, OPAL_EV_READ, recv_handler, chan);
|
||||
opal_event_add(&chan->recv_ev, 0);
|
||||
/* create a recv socket */
|
||||
if (ORTE_SUCCESS != (rc = setup_socket(&recvsd, chan->full_addr, chan->port, true))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return 255;
|
||||
}
|
||||
chan->recv = recvsd;
|
||||
chan->recvd_data = (uint8_t*)malloc(mca_rmcast_basic_component.max_msg_size);
|
||||
}
|
||||
|
||||
/* change to the next freq */
|
||||
net->next_freq++;
|
||||
|
||||
return chan->channel;
|
||||
}
|
||||
|
||||
@ -674,7 +871,7 @@ static void recv_handler(int sd, short flags, void* cbdata)
|
||||
return;
|
||||
}
|
||||
|
||||
static int setup_socket(int *sd, int channel, bool bindsocket)
|
||||
static int setup_socket(int *sd, uint32_t chan, uint16_t port, bool bindsocket)
|
||||
{
|
||||
uint8_t ttl = 1;
|
||||
struct sockaddr_in inaddr;
|
||||
@ -682,7 +879,6 @@ static int setup_socket(int *sd, int channel, bool bindsocket)
|
||||
int addrlen;
|
||||
int target_sd;
|
||||
int flags;
|
||||
uint32_t chan;
|
||||
|
||||
target_sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(target_sd < 0) {
|
||||
@ -710,18 +906,13 @@ static int setup_socket(int *sd, int channel, bool bindsocket)
|
||||
CLOSE_THE_SOCKET(target_sd);
|
||||
return ORTE_ERROR;
|
||||
}
|
||||
|
||||
chan = orte_rmcast_base.base_ip_addr + channel;
|
||||
|
||||
|
||||
/* Bind the socket if requested */
|
||||
if (bindsocket) {
|
||||
if (AF_INET != orte_rmcast_base.af_family) {
|
||||
return ORTE_ERROR;
|
||||
}
|
||||
memset(&inaddr, 0, sizeof(inaddr));
|
||||
inaddr.sin_family = AF_INET;
|
||||
inaddr.sin_addr.s_addr = htonl(chan);
|
||||
inaddr.sin_port = htons(orte_rmcast_base.ports[channel-1]);
|
||||
inaddr.sin_port = htons(port);
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
/* bind the socket */
|
||||
@ -834,3 +1025,22 @@ static void xmit_data(int sd, short flags, void* send_req)
|
||||
|
||||
OPAL_THREAD_UNLOCK(&chan->send_lock);
|
||||
}
|
||||
|
||||
static uint32_t parse_network(char *network)
|
||||
{
|
||||
char **octets=NULL;
|
||||
uint32_t net, oct1, oct2, oct3;
|
||||
|
||||
/* the network will be provided as a set of dot-separated
|
||||
* octets, so split at those points
|
||||
*/
|
||||
octets = opal_argv_split(network, '.');
|
||||
oct1 = strtoul(octets[0], NULL, 10);
|
||||
oct2 = strtoul(octets[1], NULL, 10);
|
||||
oct3 = strtoul(octets[2], NULL, 10);
|
||||
net = ((oct1 >> 24) & 0x000000FF) |
|
||||
((oct2 >> 16) & 0x000000FF) |
|
||||
((oct3 >> 8) & 0x000000FF);
|
||||
opal_argv_free(octets);
|
||||
return net;
|
||||
}
|
||||
|
@ -73,8 +73,8 @@ typedef int (*orte_rmcast_base_module_recv_fn_t)(unsigned int channel,
|
||||
typedef void (*orte_rmcast_base_module_cancel_recv_fn_t)(unsigned int channel,
|
||||
orte_rmcast_tag_t tag);
|
||||
|
||||
/* get the next available channel */
|
||||
typedef unsigned int (*orte_rmcast_base_module_get_rmcast_channel_fn_t)(char *name, uint8_t direction);
|
||||
/* open the next available channel */
|
||||
typedef unsigned int (*orte_rmcast_base_module_open_rmcast_channel_fn_t)(char *name, char *network, uint8_t direction);
|
||||
|
||||
/*
|
||||
* rmcast component
|
||||
@ -101,7 +101,7 @@ struct orte_rmcast_base_module_t {
|
||||
orte_rmcast_base_module_recv_fn_t recv;
|
||||
orte_rmcast_base_module_recv_nb_fn_t recv_nb;
|
||||
orte_rmcast_base_module_cancel_recv_fn_t cancel_recv;
|
||||
orte_rmcast_base_module_get_rmcast_channel_fn_t get_channel;
|
||||
orte_rmcast_base_module_open_rmcast_channel_fn_t open_channel;
|
||||
};
|
||||
/** Convienence typedef */
|
||||
typedef struct orte_rmcast_base_module_t orte_rmcast_module_t;
|
||||
|
@ -21,12 +21,6 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/* define the default ORTE multicast subnet */
|
||||
#define ORTE_RMCAST_DEFAULT_SUBNET 239
|
||||
|
||||
/* default IP multicast scope - site-local, per IANA 2009-03-17 */
|
||||
#define ORTE_RMCAST_DEFAULT_SCOPE 255
|
||||
|
||||
/* ORTE IP multicast channels */
|
||||
#define ORTE_RMCAST_SYS_ADDR 1
|
||||
#define ORTE_RMCAST_APP_PUBLIC_ADDR 2
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user