Bring in an updated launch system for the orteds. This commit restores the ability to execute singletons and singleton comm_spawn, both in single node and multi-node environments.
Short description: major changes include - 1. singletons now fork/exec a local daemon to manage their operations. 2. the orte daemon code now resides in libopen-rte 3. daemons no longer use the orte triggering system during startup. Instead, they directly call back to their parent pls component to report ready to operate. A base function to count the callbacks has been provided. I have modified all the pls components except xcpu and poe (don't understand either well enough to do it). Full functionality has been verified for rsh, SLURM, and TM systems. Compile has been verified for xgrid and gridengine. This commit was SVN r15390.
Этот коммит содержится в:
родитель
790bfd5b2a
Коммит
bd65f8ba88
@ -218,6 +218,7 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
size_t nprocs;
|
||||
char *error = NULL;
|
||||
bool compound_cmd = false;
|
||||
orte_buffer_t *cmd_buffer;
|
||||
bool timing = false;
|
||||
int param, value;
|
||||
struct timeval ompistart, ompistop;
|
||||
@ -261,7 +262,8 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
orte_debug_flag) {
|
||||
compound_cmd = false;
|
||||
} else {
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.begin_compound_cmd())) {
|
||||
cmd_buffer = OBJ_NEW(orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.begin_compound_cmd(cmd_buffer))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "ompi_mpi_init: orte_gpr.begin_compound_cmd failed";
|
||||
goto error;
|
||||
@ -532,11 +534,12 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
/* if the compound command is operative, execute it */
|
||||
|
||||
if (compound_cmd) {
|
||||
if (OMPI_SUCCESS != (ret = orte_gpr.exec_compound_cmd())) {
|
||||
if (OMPI_SUCCESS != (ret = orte_gpr.exec_compound_cmd(cmd_buffer))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "ompi_rte_init: orte_gpr.exec_compound_cmd failed";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(cmd_buffer);
|
||||
}
|
||||
|
||||
/* check for timing request - get stop time and report elapsed time if so */
|
||||
|
@ -62,3 +62,4 @@ include dss/Makefile.am
|
||||
include runtime/Makefile.am
|
||||
include util/Makefile.am
|
||||
include tools/Makefile.am
|
||||
include orted/Makefile.am
|
||||
|
@ -103,7 +103,9 @@ enum {
|
||||
ORTE_ERR_EXE_NOT_FOUND = (ORTE_ERR_BASE - 35),
|
||||
ORTE_ERR_PIPE_READ_FAILURE = (ORTE_ERR_BASE - 36),
|
||||
ORTE_ERR_EXE_NOT_ACCESSIBLE = (ORTE_ERR_BASE - 37),
|
||||
ORTE_ERR_FAILED_TO_START = (ORTE_ERR_BASE - 38)
|
||||
ORTE_ERR_FAILED_TO_START = (ORTE_ERR_BASE - 38),
|
||||
ORTE_ERR_FILE_NOT_EXECUTABLE = (ORTE_ERR_BASE - 39),
|
||||
ORTE_ERR_HNP_COULD_NOT_START = (ORTE_ERR_BASE - 40)
|
||||
};
|
||||
|
||||
#define ORTE_ERR_MAX (ORTE_ERR_BASE - 100)
|
||||
|
@ -109,6 +109,7 @@ extern "C" {
|
||||
#define ORTE_GPR_DUMP_A_TRIGGER_CMD (uint8_t) 23
|
||||
#define ORTE_GPR_DUMP_A_SUBSCRIPTION_CMD (uint8_t) 24
|
||||
#define ORTE_GPR_DUMP_SEGMENT_SIZE_CMD (uint8_t) 25
|
||||
#define ORTE_GPR_GET_NUMBER_ENTRIES_CMD (uint8_t) 26
|
||||
#define ORTE_GPR_ERROR (uint8_t)0xff
|
||||
|
||||
typedef uint8_t orte_gpr_cmd_flag_t;
|
||||
|
@ -89,7 +89,7 @@ typedef int (*orte_gpr_base_module_init_fn_t)(void);
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
typedef int (*orte_gpr_base_module_begin_compound_cmd_fn_t)(void);
|
||||
typedef int (*orte_gpr_base_module_begin_compound_cmd_fn_t)(orte_buffer_t *buffer);
|
||||
|
||||
/*
|
||||
* Stop recording a compound command
|
||||
@ -123,7 +123,13 @@ typedef int (*orte_gpr_base_module_stop_compound_cmd_fn_t)(void);
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
typedef int (*orte_gpr_base_module_exec_compound_cmd_fn_t)(void);
|
||||
typedef int (*orte_gpr_base_module_exec_compound_cmd_fn_t)(orte_buffer_t *buffer);
|
||||
|
||||
/*
|
||||
* Process a compound command buffer for a third-party (BLOCKING)
|
||||
*/
|
||||
typedef int (*orte_gpr_base_module_process_compound_cmd_fn_t)(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name);
|
||||
|
||||
|
||||
/*
|
||||
@ -188,6 +194,13 @@ typedef int (*orte_gpr_base_module_cleanup_proc_fn_t)(orte_process_name_t *proc)
|
||||
*/
|
||||
typedef int (*orte_gpr_base_module_preallocate_segment_fn_t)(char *name, orte_std_cntr_t num_slots);
|
||||
|
||||
/*
|
||||
* Get the number of entries on a segment or in a container
|
||||
* Returns the number of containers on a segment (if NULL tokens provided) or in a container
|
||||
* (if tokens provided - NULL terminated list)
|
||||
*/
|
||||
typedef int (*orte_gpr_base_module_get_number_entries_fn_t)(orte_std_cntr_t *n, char *segment, char **tokens);
|
||||
|
||||
/*
|
||||
* Delete a segment from the registry (BLOCKING)
|
||||
* This command removes an entire segment from the registry, including all data objects,
|
||||
@ -724,6 +737,7 @@ struct orte_gpr_base_module_1_0_0_t {
|
||||
orte_gpr_base_module_create_value_fn_t create_value;
|
||||
orte_gpr_base_module_create_keyval_fn_t create_keyval;
|
||||
orte_gpr_base_module_preallocate_segment_fn_t preallocate_segment;
|
||||
orte_gpr_base_module_get_number_entries_fn_t get_number_entries;
|
||||
orte_gpr_base_module_deliver_notify_msg_t deliver_notify_msg;
|
||||
/* ARITHMETIC OPERATIONS */
|
||||
orte_gpr_base_module_arith_fn_t arith;
|
||||
@ -741,6 +755,7 @@ struct orte_gpr_base_module_1_0_0_t {
|
||||
orte_gpr_base_module_begin_compound_cmd_fn_t begin_compound_cmd;
|
||||
orte_gpr_base_module_stop_compound_cmd_fn_t stop_compound_cmd;
|
||||
orte_gpr_base_module_exec_compound_cmd_fn_t exec_compound_cmd;
|
||||
orte_gpr_base_module_process_compound_cmd_fn_t process_compound_cmd;
|
||||
/* DIAGNOSTIC OPERATIONS */
|
||||
orte_gpr_base_module_dump_all_fn_t dump_all;
|
||||
orte_gpr_base_module_dump_segment_fn_t dump_segment;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "orte/orte_constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "orte/mca/gpr/base/base.h"
|
||||
#include "orte/dss/dss_types.h"
|
||||
|
||||
|
||||
static int
|
||||
@ -33,7 +34,7 @@ orte_gpr_null_module_init(void)
|
||||
|
||||
|
||||
static int
|
||||
orte_gpr_null_begin_compound_cmd(void)
|
||||
orte_gpr_null_begin_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
@ -45,11 +46,18 @@ orte_gpr_null_stop_compound_cmd(void)
|
||||
}
|
||||
|
||||
static int
|
||||
orte_gpr_null_exec_compound_cmd(void)
|
||||
orte_gpr_null_exec_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
orte_gpr_null_process_compound_cmd(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name)
|
||||
{
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
orte_gpr_null_cleanup_job(orte_jobid_t jobid)
|
||||
{
|
||||
@ -68,6 +76,13 @@ orte_gpr_null_preallocate_segment(char *name, orte_std_cntr_t num_slots)
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
orte_gpr_null_get_number_entries(orte_std_cntr_t *n, char *segment, char **tokens)
|
||||
{
|
||||
*n = 0;
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
orte_gpr_null_delete_segment(char *segment)
|
||||
{
|
||||
@ -379,6 +394,7 @@ orte_gpr_base_module_t orte_gpr_null_module = {
|
||||
orte_gpr_base_create_value,
|
||||
orte_gpr_base_create_keyval,
|
||||
orte_gpr_null_preallocate_segment,
|
||||
orte_gpr_null_get_number_entries,
|
||||
orte_gpr_null_deliver_notify_msg,
|
||||
/* ARITHMETIC OPERATIONS */
|
||||
orte_gpr_null_arith,
|
||||
@ -396,6 +412,7 @@ orte_gpr_base_module_t orte_gpr_null_module = {
|
||||
orte_gpr_null_begin_compound_cmd,
|
||||
orte_gpr_null_stop_compound_cmd,
|
||||
orte_gpr_null_exec_compound_cmd,
|
||||
orte_gpr_null_process_compound_cmd,
|
||||
/* DIAGNOSTIC OPERATIONS */
|
||||
orte_gpr_null_dump_all,
|
||||
orte_gpr_null_dump_segments,
|
||||
|
@ -103,11 +103,14 @@ extern orte_gpr_proxy_globals_t orte_gpr_proxy_globals;
|
||||
/*
|
||||
* Compound cmd functions
|
||||
*/
|
||||
int orte_gpr_proxy_begin_compound_cmd(void);
|
||||
int orte_gpr_proxy_begin_compound_cmd(orte_buffer_t *buffer);
|
||||
|
||||
int orte_gpr_proxy_stop_compound_cmd(void);
|
||||
|
||||
int orte_gpr_proxy_exec_compound_cmd(void);
|
||||
int orte_gpr_proxy_exec_compound_cmd(orte_buffer_t *buffer);
|
||||
|
||||
int orte_gpr_proxy_process_compound_cmd(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name);
|
||||
|
||||
/*
|
||||
* Arithmetic operations
|
||||
@ -222,6 +225,8 @@ int orte_gpr_proxy_dump_segment_size(char *segment);
|
||||
*/
|
||||
int orte_gpr_proxy_preallocate_segment(char *name, orte_std_cntr_t num_slots);
|
||||
|
||||
int orte_gpr_proxy_get_number_entries(orte_std_cntr_t *n, char *segment, char **tokens);
|
||||
|
||||
int orte_gpr_proxy_deliver_notify_msg(orte_gpr_notify_message_t *msg);
|
||||
|
||||
/*
|
||||
|
@ -89,6 +89,7 @@ static orte_gpr_base_module_t orte_gpr_proxy = {
|
||||
orte_gpr_base_create_value,
|
||||
orte_gpr_base_create_keyval,
|
||||
orte_gpr_proxy_preallocate_segment,
|
||||
orte_gpr_proxy_get_number_entries,
|
||||
orte_gpr_proxy_deliver_notify_msg,
|
||||
/* ARITHMETIC OPERATIONS */
|
||||
orte_gpr_proxy_arith,
|
||||
@ -106,6 +107,7 @@ static orte_gpr_base_module_t orte_gpr_proxy = {
|
||||
orte_gpr_proxy_begin_compound_cmd,
|
||||
orte_gpr_proxy_stop_compound_cmd,
|
||||
orte_gpr_proxy_exec_compound_cmd,
|
||||
orte_gpr_proxy_process_compound_cmd,
|
||||
/* DIAGNOSTIC OPERATIONS */
|
||||
orte_gpr_proxy_dump_all,
|
||||
orte_gpr_proxy_dump_segments,
|
||||
|
@ -41,7 +41,7 @@
|
||||
#include "gpr_proxy.h"
|
||||
|
||||
|
||||
int orte_gpr_proxy_begin_compound_cmd(void)
|
||||
int orte_gpr_proxy_begin_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
orte_gpr_cmd_flag_t command;
|
||||
int rc;
|
||||
@ -57,22 +57,12 @@ int orte_gpr_proxy_begin_compound_cmd(void)
|
||||
}
|
||||
|
||||
orte_gpr_proxy_globals.compound_cmd_mode = true;
|
||||
if (NULL != orte_gpr_proxy_globals.compound_cmd) {
|
||||
OBJ_RELEASE(orte_gpr_proxy_globals.compound_cmd);
|
||||
}
|
||||
|
||||
orte_gpr_proxy_globals.compound_cmd = OBJ_NEW(orte_buffer_t);
|
||||
if (NULL == orte_gpr_proxy_globals.compound_cmd) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
|
||||
orte_gpr_proxy_globals.compound_cmd_mode = false;
|
||||
return ORTE_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
orte_gpr_proxy_globals.compound_cmd = buffer;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(orte_gpr_proxy_globals.compound_cmd, &command,
|
||||
1, ORTE_GPR_CMD))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
orte_gpr_proxy_globals.compound_cmd_mode = false;
|
||||
OBJ_RELEASE(orte_gpr_proxy_globals.compound_cmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -86,10 +76,8 @@ int orte_gpr_proxy_stop_compound_cmd(void)
|
||||
OPAL_THREAD_LOCK(&orte_gpr_proxy_globals.wait_for_compound_mutex);
|
||||
|
||||
orte_gpr_proxy_globals.compound_cmd_mode = false;
|
||||
if (NULL != orte_gpr_proxy_globals.compound_cmd) {
|
||||
OBJ_RELEASE(orte_gpr_proxy_globals.compound_cmd);
|
||||
}
|
||||
|
||||
orte_gpr_proxy_globals.compound_cmd = NULL;
|
||||
|
||||
if (orte_gpr_proxy_globals.compound_cmd_waiting) {
|
||||
opal_condition_signal(&orte_gpr_proxy_globals.compound_cmd_condition);
|
||||
}
|
||||
@ -99,7 +87,7 @@ int orte_gpr_proxy_stop_compound_cmd(void)
|
||||
}
|
||||
|
||||
|
||||
int orte_gpr_proxy_exec_compound_cmd(void)
|
||||
int orte_gpr_proxy_exec_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
orte_buffer_t *answer;
|
||||
orte_gpr_cmd_flag_t command;
|
||||
@ -120,7 +108,6 @@ int orte_gpr_proxy_exec_compound_cmd(void)
|
||||
goto CLEANUP;
|
||||
}
|
||||
orte_gpr_proxy_globals.compound_cmd_mode = false;
|
||||
OBJ_RELEASE(orte_gpr_proxy_globals.compound_cmd);
|
||||
|
||||
answer = OBJ_NEW(orte_buffer_t);
|
||||
if (NULL == answer) {
|
||||
@ -154,6 +141,7 @@ int orte_gpr_proxy_exec_compound_cmd(void)
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.unpack(answer, &response, &n, ORTE_INT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_RELEASE(answer); /* done with this */
|
||||
|
||||
if (ORTE_SUCCESS == rc) {
|
||||
rc = (int)response;
|
||||
@ -169,4 +157,9 @@ int orte_gpr_proxy_exec_compound_cmd(void)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int orte_gpr_proxy_process_compound_cmd(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name)
|
||||
{
|
||||
return ORTE_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -45,3 +45,10 @@ int orte_gpr_proxy_preallocate_segment(char *name, orte_std_cntr_t num_slots)
|
||||
|
||||
return ORTE_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int orte_gpr_proxy_get_number_entries(orte_std_cntr_t *n, char *segment, char **tokens)
|
||||
{
|
||||
OPAL_TRACE(1);
|
||||
|
||||
return ORTE_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -52,11 +52,14 @@ extern "C" {
|
||||
/*
|
||||
* Compound cmd functions
|
||||
*/
|
||||
int orte_gpr_replica_begin_compound_cmd(void);
|
||||
int orte_gpr_replica_begin_compound_cmd(orte_buffer_t *buffer);
|
||||
|
||||
int orte_gpr_replica_stop_compound_cmd(void);
|
||||
|
||||
int orte_gpr_replica_exec_compound_cmd(void);
|
||||
int orte_gpr_replica_exec_compound_cmd(orte_buffer_t *buffer);
|
||||
|
||||
int orte_gpr_replica_process_compound_cmd(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name);
|
||||
|
||||
/*
|
||||
* Arithmetic operations
|
||||
@ -172,6 +175,8 @@ int orte_gpr_replica_dump_segment_size(char *segment);
|
||||
*/
|
||||
int orte_gpr_replica_preallocate_segment(char *name, orte_std_cntr_t num_slots);
|
||||
|
||||
int orte_gpr_replica_get_number_entries(orte_std_cntr_t *n, char *segment, char **tokens);
|
||||
|
||||
int orte_gpr_replica_deliver_notify_msg(orte_gpr_notify_message_t *msg);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
|
@ -27,13 +27,18 @@
|
||||
|
||||
#include "orte_config.h"
|
||||
|
||||
#include "orte/dss/dss_types.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
|
||||
#include "orte/mca/gpr/replica/communications/gpr_replica_comm.h"
|
||||
|
||||
#include "gpr_replica_api.h"
|
||||
|
||||
/* COMPOUND COMMANDS ARE NOT USED ON THE REPLICA
|
||||
* Any process co-located with the replica will "drive" the registry
|
||||
* directly
|
||||
*/
|
||||
int orte_gpr_replica_begin_compound_cmd(void)
|
||||
int orte_gpr_replica_begin_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
@ -45,7 +50,22 @@ int orte_gpr_replica_stop_compound_cmd(void)
|
||||
}
|
||||
|
||||
|
||||
int orte_gpr_replica_exec_compound_cmd(void)
|
||||
int orte_gpr_replica_exec_compound_cmd(orte_buffer_t *buffer)
|
||||
{
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
int orte_gpr_replica_process_compound_cmd(orte_buffer_t *buffer,
|
||||
orte_process_name_t *name)
|
||||
{
|
||||
orte_buffer_t *answer=NULL;
|
||||
int rc;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr_replica_process_command_buffer(buffer, name, &answer))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (NULL != answer) OBJ_RELEASE(answer); /* don't need this */
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "opal/util/trace.h"
|
||||
|
||||
#include "orte/class/orte_pointer_array.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
|
||||
#include "gpr_replica_api.h"
|
||||
|
||||
@ -45,6 +46,7 @@ int orte_gpr_replica_preallocate_segment(char *name, orte_std_cntr_t num_slots)
|
||||
|
||||
/* find the segment */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr_replica_find_seg(&seg, true, name))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OPAL_THREAD_UNLOCK(&orte_gpr_replica_globals.mutex);
|
||||
return rc;
|
||||
}
|
||||
@ -55,3 +57,63 @@ int orte_gpr_replica_preallocate_segment(char *name, orte_std_cntr_t num_slots)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int orte_gpr_replica_get_number_entries(orte_std_cntr_t *n, char *segment, char **tokens)
|
||||
{
|
||||
int rc;
|
||||
orte_gpr_replica_segment_t *seg=NULL;
|
||||
orte_std_cntr_t num_tokens=0;
|
||||
orte_gpr_replica_itag_t *itags=NULL;
|
||||
orte_gpr_replica_container_t **cptr;
|
||||
orte_std_cntr_t j, k, num_keyvals;
|
||||
|
||||
OPAL_TRACE(1);
|
||||
|
||||
OPAL_THREAD_LOCK(&orte_gpr_replica_globals.mutex);
|
||||
|
||||
/* find the segment */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr_replica_find_seg(&seg, true, segment))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OPAL_THREAD_UNLOCK(&orte_gpr_replica_globals.mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* if no tokens provided, just return the number of containers */
|
||||
if (NULL == tokens) {
|
||||
*n = seg->num_containers;
|
||||
OPAL_THREAD_UNLOCK(&orte_gpr_replica_globals.mutex);
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* otherwise, look up the container - convert tokens to array of itags */
|
||||
num_keyvals = 0;
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr_replica_get_itag_list(&itags, seg,
|
||||
tokens, &num_tokens))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* find the specified container(s) */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr_replica_find_containers(seg, ORTE_GPR_REPLICA_AND,
|
||||
itags, num_tokens))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* loop through any found containers and add up their keyvals */
|
||||
cptr = (orte_gpr_replica_container_t**)(orte_gpr_replica_globals.srch_cptr)->addr;
|
||||
for (j=0, k=0; k < orte_gpr_replica_globals.num_srch_cptr &&
|
||||
j < (orte_gpr_replica_globals.srch_cptr)->size; j++) {
|
||||
if (NULL != cptr[j]) {
|
||||
k++;
|
||||
num_keyvals += cptr[j]->num_itagvals;
|
||||
}
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
if (NULL != itags) free(itags);
|
||||
|
||||
*n = num_keyvals;
|
||||
OPAL_THREAD_UNLOCK(&orte_gpr_replica_globals.mutex);
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ static orte_gpr_base_module_t orte_gpr_replica_module = {
|
||||
orte_gpr_base_create_value,
|
||||
orte_gpr_base_create_keyval,
|
||||
orte_gpr_replica_preallocate_segment,
|
||||
orte_gpr_replica_get_number_entries,
|
||||
orte_gpr_replica_deliver_notify_msg,
|
||||
/* ARITHMETIC OPERATIONS */
|
||||
orte_gpr_replica_arith,
|
||||
@ -113,6 +114,7 @@ static orte_gpr_base_module_t orte_gpr_replica_module = {
|
||||
orte_gpr_replica_begin_compound_cmd,
|
||||
orte_gpr_replica_stop_compound_cmd,
|
||||
orte_gpr_replica_exec_compound_cmd,
|
||||
orte_gpr_replica_process_compound_cmd,
|
||||
/* DIAGNOSTIC OPERATIONS */
|
||||
orte_gpr_replica_dump_all,
|
||||
orte_gpr_replica_dump_segments,
|
||||
|
@ -489,12 +489,15 @@ int orte_iof_base_endpoint_delete(
|
||||
while(item != opal_list_get_end(&orte_iof_base.iof_endpoints)) {
|
||||
opal_list_item_t* next = opal_list_get_next(item);
|
||||
orte_iof_base_endpoint_t* endpoint = (orte_iof_base_endpoint_t*)item;
|
||||
if(orte_ns.compare_fields(mask,proc,&endpoint->ep_origin) == 0 &&
|
||||
endpoint->ep_tag == tag) {
|
||||
opal_list_remove_item(&orte_iof_base.iof_endpoints,&endpoint->super);
|
||||
OBJ_RELEASE(endpoint);
|
||||
OPAL_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
||||
return ORTE_SUCCESS;
|
||||
if (orte_ns.compare_fields(mask,proc,&endpoint->ep_origin) == 0) {
|
||||
if (endpoint->ep_tag == tag ||
|
||||
ORTE_IOF_ANY == endpoint->ep_tag ||
|
||||
ORTE_IOF_ANY == tag) {
|
||||
opal_list_remove_item(&orte_iof_base.iof_endpoints,&endpoint->super);
|
||||
OBJ_RELEASE(endpoint);
|
||||
OPAL_THREAD_UNLOCK(&orte_iof_base.iof_lock);
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
item = next;
|
||||
}
|
||||
|
@ -139,12 +139,21 @@ int orte_iof_proxy_unpublish(
|
||||
mask,
|
||||
tag);
|
||||
|
||||
/* delete local endpoint */
|
||||
/* delete local endpoint. Note that the endpoint may have already
|
||||
been deleted (e.g., if some entity noticed that the fd closed
|
||||
and called orte_iof_base_endpoint_delete on the corresopnding
|
||||
endpoint already). So if we get NOT_FOUND, ignore that error
|
||||
-- the end result is what we want: the endpoint is deleted when
|
||||
we return. */
|
||||
rc = orte_iof_base_endpoint_delete(
|
||||
origin,
|
||||
mask,
|
||||
tag);
|
||||
return rc;
|
||||
if (ORTE_ERR_NOT_FOUND == rc || ORTE_SUCCESS == rc) {
|
||||
return ORTE_SUCCESS;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,22 +106,36 @@ int orte_iof_svc_unpublish(
|
||||
orte_iof_base_tag_t tag)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Delete the corresponding publish. Note that it may have
|
||||
already been deleted by some other entity (e.g., message
|
||||
arriving saying to unpublish), so we may get a NOT_FOUND.
|
||||
That's ok/not an error -- the only end result that we want is
|
||||
that there is no corresponding publish. */
|
||||
rc = orte_iof_svc_pub_delete(
|
||||
origin,
|
||||
ORTE_PROC_MY_NAME,
|
||||
mask,
|
||||
tag);
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
if (ORTE_SUCCESS != rc && ORTE_ERR_NOT_FOUND != rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* setup a local endpoint to reflect registration */
|
||||
/* delete local endpoint. Note that the endpoint may have already
|
||||
been deleted (e.g., if some entity noticed that the fd closed
|
||||
and called orte_iof_base_endpoint_delete on the corresopnding
|
||||
endpoint already). So if we get NOT_FOUND, ignore that error
|
||||
-- the end result is what we want: the endpoint is deleted when
|
||||
we return. */
|
||||
rc = orte_iof_base_endpoint_delete(
|
||||
origin,
|
||||
mask,
|
||||
tag);
|
||||
|
||||
return rc;
|
||||
if (ORTE_ERR_NOT_FOUND == rc || ORTE_SUCCESS == rc) {
|
||||
return ORTE_SUCCESS;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,11 +130,9 @@ orte_iof_svc_exception_handler(const orte_process_name_t* peer, orte_rml_excepti
|
||||
(endpoint = orte_iof_base_endpoint_match(peer, ORTE_NS_CMP_ALL,
|
||||
ORTE_IOF_ANY))) {
|
||||
orte_iof_base_endpoint_closed(endpoint);
|
||||
};
|
||||
/* Then delete them */
|
||||
while (ORTE_SUCCESS ==
|
||||
orte_iof_base_endpoint_delete(peer, ORTE_NS_CMP_ALL, ORTE_IOF_ANY)) {
|
||||
continue;
|
||||
|
||||
/* Delete the endpoint that we just matched */
|
||||
orte_iof_base_endpoint_delete(peer, ORTE_NS_CMP_ALL, ORTE_IOF_ANY);
|
||||
}
|
||||
opal_output(orte_iof_base.iof_output, "done with exception handler\n");
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ libmca_odls_la_SOURCES += \
|
||||
base/odls_base_open.c \
|
||||
base/odls_base_select.c \
|
||||
base/odls_base_state.c \
|
||||
base/odls_base_purge_params.c \
|
||||
base/data_type_support/odls_compare_fns.c \
|
||||
base/data_type_support/odls_copy_fns.c \
|
||||
base/data_type_support/odls_packing_fns.c \
|
||||
|
50
orte/mca/odls/base/odls_base_purge_params.c
Обычный файл
50
orte/mca/odls/base/odls_base_purge_params.c
Обычный файл
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
#include "orte_config.h"
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#include "opal/util/opal_environ.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
|
||||
#include "orte/mca/odls/base/odls_private.h"
|
||||
|
||||
|
||||
/* Purge mca params not suitable for application procs */
|
||||
void orte_odls_base_purge_mca_params(char ***env)
|
||||
{
|
||||
char *var;
|
||||
|
||||
/* tell critical frameworks to only use their proxy components */
|
||||
var = mca_base_param_environ_variable("rds",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
var = mca_base_param_environ_variable("ras",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
var = mca_base_param_environ_variable("rmaps",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
var = mca_base_param_environ_variable("pls",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
var = mca_base_param_environ_variable("rmgr",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
}
|
@ -46,10 +46,13 @@ int orte_odls_base_report_spawn(opal_list_t *children)
|
||||
orte_std_cntr_t num_tokens;
|
||||
orte_gpr_addr_mode_t mode = ORTE_GPR_OVERWRITE | ORTE_GPR_TOKENS_AND | ORTE_GPR_KEYS_OR;
|
||||
orte_data_value_t dval = ORTE_DATA_VALUE_EMPTY;
|
||||
orte_buffer_t *buffer;
|
||||
int rc;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.begin_compound_cmd())) {
|
||||
buffer = OBJ_NEW(orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.begin_compound_cmd(buffer))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -66,23 +69,27 @@ int orte_odls_base_report_spawn(opal_list_t *children)
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_schema.get_proc_tokens(&tokens, &num_tokens, child->name))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_schema.get_job_segment_name(&segment, child->name->jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
opal_argv_free(tokens);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.set(&dval, (void*)&(child->pid), ORTE_PID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
opal_argv_free(tokens);
|
||||
free(segment);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.put_1(mode, segment, tokens, ORTE_PROC_LOCAL_PID_KEY, &dval))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
opal_argv_free(tokens);
|
||||
free(segment);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
dval.data = NULL;
|
||||
@ -92,20 +99,24 @@ int orte_odls_base_report_spawn(opal_list_t *children)
|
||||
/* now set the process state to LAUNCHED */
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_proc_state(child->name, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
} else if (ORTE_PROC_STATE_FAILED_TO_START == child->state) {
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_proc_state(child->name, ORTE_PROC_STATE_FAILED_TO_START, child->exit_code))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.exec_compound_cmd())) {
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.exec_compound_cmd(buffer))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
OBJ_RELEASE(buffer);
|
||||
|
||||
/* All done */
|
||||
return ORTE_SUCCESS;
|
||||
|
@ -73,6 +73,8 @@ ORTE_DECLSPEC extern orte_odls_globals_t orte_odls_globals;
|
||||
|
||||
ORTE_DECLSPEC int orte_odls_base_report_spawn(opal_list_t *children);
|
||||
|
||||
ORTE_DECLSPEC void orte_odls_base_purge_mca_params(char ***env);
|
||||
|
||||
/*
|
||||
* data type functions
|
||||
*/
|
||||
|
@ -503,12 +503,10 @@ GOTCHILD:
|
||||
}
|
||||
opal_output(orte_odls_globals.output, "orted sent IOF unpub message!\n");
|
||||
|
||||
#if 0
|
||||
/* Note that the svc IOF component will detect an exception on the
|
||||
oob because we're shutting it down, so it will take care of
|
||||
closing down any streams that it has open to us. */
|
||||
orte_iof.iof_flush();
|
||||
#endif
|
||||
|
||||
/* determine the state of this process */
|
||||
aborted = false;
|
||||
@ -746,10 +744,6 @@ static int odls_default_fork_local_proc(
|
||||
}
|
||||
}
|
||||
|
||||
param = mca_base_param_environ_variable("rmgr","bootproxy","jobid");
|
||||
opal_unsetenv(param, &environ_copy);
|
||||
free(param);
|
||||
|
||||
/* pass my contact info to the local proc so we can talk */
|
||||
uri = orte_rml.get_uri();
|
||||
param = mca_base_param_environ_variable("orte","local_daemon","uri");
|
||||
|
@ -558,6 +558,7 @@ static int mca_oob_xcast_direct(orte_jobid_t job,
|
||||
OPAL_THREAD_UNLOCK(&orte_oob_xcast_mutex);
|
||||
|
||||
for(i=0; i<n; i++) {
|
||||
opal_output(mca_oob_base_output, "oob_xcast: sending to [%ld,%ld,%ld]", ORTE_NAME_ARGS(peers+i));
|
||||
if (0 > (rc = mca_oob_send_packed_nb(peers+i, buffer, tag, 0, mca_oob_xcast_send_cb, NULL))) {
|
||||
if (ORTE_ERR_ADDRESSEE_UNKNOWN != rc) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
||||
|
@ -251,7 +251,13 @@ int mca_oob_tcp_send_nb(
|
||||
|
||||
if (ORTE_EQUAL == mca_oob_tcp_process_name_compare(name, orte_process_info.my_name)) { /* local delivery */
|
||||
rc = mca_oob_tcp_send_self(peer,msg,iov,count);
|
||||
return rc;
|
||||
if (rc < 0 ) {
|
||||
return rc;
|
||||
} else if (size == rc) {
|
||||
return ORTE_SUCCESS;
|
||||
} else {
|
||||
return ORTE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
MCA_OOB_TCP_HDR_HTON(&msg->msg_hdr);
|
||||
|
@ -28,6 +28,5 @@ libmca_pls_la_SOURCES += \
|
||||
base/pls_base_open.c \
|
||||
base/pls_base_receive.c \
|
||||
base/pls_base_select.c \
|
||||
base/pls_base_dmn_registry_fns.c \
|
||||
base/pls_base_reuse_daemon_launch.c \
|
||||
base/pls_base_orted_cmds.c
|
||||
|
@ -22,3 +22,20 @@ No available launching agents were found.
|
||||
This is an unusual error; it means that Open RTE was unable to find
|
||||
any mechanism to launch proceses, and therefore is unable to start the
|
||||
process(es) required by your application.
|
||||
#
|
||||
[daemon-died-no-signal]
|
||||
A daemon (pid %d) died unexpectedly while attempting to launch so we are aborting.
|
||||
|
||||
This may be because the daemon was unable to find all the needed shared
|
||||
libraries on the remote node. You may set your LD_LIBRARY_PATH to have the
|
||||
location of the shared libraries on the remote nodes and this will
|
||||
automatically be forwarded to the remote nodes.
|
||||
#
|
||||
[daemon-died-signal]
|
||||
A daemon (pid %d) died unexpectedly on signal %d while attempting to
|
||||
launch so we are aborting.
|
||||
|
||||
This may be because the daemon was unable to find all the needed shared
|
||||
libraries on the remote node. You may set your LD_LIBRARY_PATH to have the
|
||||
location of the shared libraries on the remote nodes and this will
|
||||
automatically be forwarded to the remote nodes.
|
||||
|
@ -35,39 +35,16 @@
|
||||
#include "orte/mca/pls/base/pls_private.h"
|
||||
|
||||
|
||||
static int lookup_set(char *a, char *b, char *c, int default_val,
|
||||
char *token, int *argc, char ***argv)
|
||||
{
|
||||
int id, rc;
|
||||
|
||||
id = mca_base_param_find(a, b, c);
|
||||
if (id < 0) {
|
||||
id = mca_base_param_register_int(a, b, c, NULL, default_val);
|
||||
}
|
||||
mca_base_param_lookup_int(id, &rc);
|
||||
if (rc) {
|
||||
opal_argv_append(argc, argv, token);
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int orte_pls_base_mca_argv(int *argc, char ***argv)
|
||||
{
|
||||
lookup_set("orted", "spin", NULL, 0, "--spin", argc, argv);
|
||||
lookup_set("orte", "no_daemonize", NULL, 0, "--no-daemonize", argc, argv);
|
||||
lookup_set("orte", "debug", NULL, 0, "--debug", argc, argv);
|
||||
lookup_set("orte", "debug", "daemons", 0, "--debug-daemons", argc, argv);
|
||||
lookup_set("orte", "debug", "daemons_file", 0, "--debug-daemons-file", argc, argv);
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
void orte_pls_base_purge_mca_params(char ***env)
|
||||
{
|
||||
char *var;
|
||||
|
||||
/* ensure we do not think we are an HNP */
|
||||
var = mca_base_param_environ_variable("seed",NULL,NULL);
|
||||
opal_setenv(var, "0", true, env);
|
||||
free(var);
|
||||
|
||||
/* tell critical frameworks to only use their proxy components */
|
||||
var = mca_base_param_environ_variable("rds",NULL,NULL);
|
||||
opal_setenv(var, "proxy", true, env);
|
||||
free(var);
|
||||
@ -97,8 +74,22 @@ int orte_pls_base_orted_append_basic_args(int *argc, char ***argv,
|
||||
char * tmp_force = NULL;
|
||||
|
||||
/* check for debug flags */
|
||||
orte_pls_base_mca_argv(argc, argv);
|
||||
|
||||
if (orte_debug_flag) {
|
||||
opal_argv_append(argc, argv, "--debug");
|
||||
}
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_argv_append(argc, argv, "--debug-daemons");
|
||||
}
|
||||
if (orte_debug_daemons_file_flag) {
|
||||
opal_argv_append(argc, argv, "--debug-daemons-file");
|
||||
}
|
||||
if (orted_spin_flag) {
|
||||
opal_argv_append(argc, argv, "--spin");
|
||||
}
|
||||
if (orte_no_daemonize_flag) {
|
||||
opal_argv_append(argc, argv, "--no-daemonize");
|
||||
}
|
||||
|
||||
/* Name */
|
||||
if( NULL != proc_name_index ) {
|
||||
opal_argv_append(argc, argv, "--name");
|
||||
|
@ -20,56 +20,129 @@
|
||||
#include "orte_config.h"
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#include "opal/util/show_help.h"
|
||||
|
||||
#include "orte/dss/dss.h"
|
||||
#include "orte/mca/rmaps/rmaps_types.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "orte/mca/rml/rml.h"
|
||||
#include "orte/mca/odls/odls.h"
|
||||
|
||||
#include "orte/mca/pls/base/pls_private.h"
|
||||
|
||||
/* Since we now send the "add_procs" command using xcast to all daemons
|
||||
* as our standard launch procedure, all we need do for launching on
|
||||
* existing daemons is correctly increment the launch counter so that
|
||||
* trigger will fire and the launch message will be sent
|
||||
*/
|
||||
int orte_pls_base_launch_on_existing_daemons(orte_job_map_t *map)
|
||||
int orte_pls_base_launch_apps(orte_job_map_t *map)
|
||||
{
|
||||
orte_std_cntr_t num_reused;
|
||||
orte_data_value_t dval = ORTE_DATA_VALUE_EMPTY;
|
||||
char *trig_tokens[] = {
|
||||
ORTE_JOB_GLOBALS,
|
||||
NULL
|
||||
};
|
||||
char *to_launch_keys[] = {
|
||||
ORTE_PROC_NUM_LAUNCHED,
|
||||
NULL
|
||||
};
|
||||
orte_daemon_cmd_flag_t command;
|
||||
orte_buffer_t *buffer;
|
||||
orte_gpr_notify_data_t *launch_data;
|
||||
int rc;
|
||||
|
||||
/* check the number of new daemons vs the number of nodes in the job
|
||||
* if num_new_daemons < num_nodes, then we are reusing some existing
|
||||
* daemons and we need to increment the launch counter
|
||||
*/
|
||||
if (map->num_nodes == map->num_new_daemons) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* compute the number of daemons that are being reused */
|
||||
num_reused = map->num_nodes - map->num_new_daemons;
|
||||
|
||||
/* setup the arithmetic operand */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.set(&dval, (void*)&num_reused, ORTE_STD_CNTR))) {
|
||||
|
||||
/* let the local launcher provide its required data */
|
||||
if (ORTE_SUCCESS != (rc = orte_odls.get_add_procs_data(&launch_data, map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* update the counter */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.arith(ORTE_GPR_TOKENS_AND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", trig_tokens, to_launch_keys,
|
||||
ORTE_DSS_ADD, &dval))) {
|
||||
/* setup the buffer */
|
||||
buffer = OBJ_NEW(orte_buffer_t);
|
||||
/* pack the add_local_procs command */
|
||||
command = ORTE_DAEMON_ADD_LOCAL_PROCS;
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(buffer, &command, 1, ORTE_DAEMON_CMD))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* pack the launch data */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(buffer, &launch_data, 1, ORTE_GPR_NOTIFY_DATA))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send the command to the daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_rml.xcast(0, buffer, ORTE_RML_TAG_DAEMON))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_RELEASE(buffer);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int orte_pls_base_daemon_callback(orte_std_cntr_t num_daemons)
|
||||
{
|
||||
orte_std_cntr_t i;
|
||||
orte_buffer_t ack, handoff;
|
||||
orte_process_name_t name;
|
||||
int src[4];
|
||||
int rc, idx;
|
||||
|
||||
for(i = 0; i < num_daemons; i++) {
|
||||
OBJ_CONSTRUCT(&ack, orte_buffer_t);
|
||||
rc = orte_rml.recv_buffer(ORTE_NAME_WILDCARD, &ack, ORTE_RML_TAG_ORTED_CALLBACK);
|
||||
if(0 > rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&ack);
|
||||
return rc;
|
||||
}
|
||||
/* a daemon actually only sends us back one int value. However, if
|
||||
* the daemon fails to launch, our local launcher may have additional
|
||||
* info it wants to pass back to us, so we allow up to four int
|
||||
* values to be returned. Fortunately, the DSS unpack routine
|
||||
* knows how to handle this situation - it will only unpack the
|
||||
* actual number of packed entries up to the number we specify here
|
||||
*/
|
||||
idx = 4;
|
||||
rc = orte_dss.unpack(&ack, &src, &idx, ORTE_INT);
|
||||
if(ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&ack);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if(-1 == src[0]) {
|
||||
/* one of the daemons has failed to properly launch. The error is sent
|
||||
* by orte_pls_bproc_waitpid_daemon_cb */
|
||||
if(-1 == src[1]) { /* did not die on a signal */
|
||||
opal_show_help("help-pls-base.txt", "daemon-died-no-signal", true, src[2]);
|
||||
} else { /* died on a signal */
|
||||
opal_show_help("help-pls-base.txt", "daemon-died-signal", true,
|
||||
src[2], src[1]);
|
||||
}
|
||||
rc = ORTE_ERR_FAILED_TO_START;
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&ack);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* okay, so the daemon says it started up okay - get the daemon's name */
|
||||
idx = 1;
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.unpack(&ack, &name, &idx, ORTE_NAME))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&ack);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* transfer the gpr compound command buffer it sent (if it did send one) and hand
|
||||
* it off for processing
|
||||
*/
|
||||
OBJ_CONSTRUCT(&handoff, orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.xfer_payload(&handoff, &ack))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&ack);
|
||||
OBJ_DESTRUCT(&handoff);
|
||||
return rc;
|
||||
}
|
||||
OBJ_DESTRUCT(&ack); /* done with this */
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.process_compound_cmd(&handoff, &name))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&handoff);
|
||||
return rc;
|
||||
}
|
||||
OBJ_DESTRUCT(&handoff); /* done with this */
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
@ -57,19 +57,6 @@ typedef uint8_t orte_pls_cmd_flag_t;
|
||||
#define ORTE_PLS_SIGNAL_PROC_CMD 5
|
||||
#define ORTE_PLS_TERMINATE_ORTEDS_CMD 6
|
||||
|
||||
/*
|
||||
* object for daemon information
|
||||
*/
|
||||
typedef struct orte_pls_daemon_info_t {
|
||||
opal_list_item_t super;
|
||||
orte_cellid_t cell;
|
||||
char *nodename;
|
||||
orte_process_name_t *name;
|
||||
orte_jobid_t active_job;
|
||||
} orte_pls_daemon_info_t;
|
||||
ORTE_DECLSPEC OBJ_CLASS_DECLARATION(orte_pls_daemon_info_t);
|
||||
|
||||
|
||||
/**
|
||||
* Utility routine to set progress engine schedule
|
||||
*/
|
||||
@ -79,18 +66,13 @@ typedef uint8_t orte_pls_cmd_flag_t;
|
||||
/**
|
||||
* Utilities for pls components that use proxy daemons
|
||||
*/
|
||||
ORTE_DECLSPEC int orte_pls_base_orted_cancel_operation(void);
|
||||
ORTE_DECLSPEC int orte_pls_base_orted_exit(struct timeval *timeout, opal_list_t *attrs);
|
||||
ORTE_DECLSPEC int orte_pls_base_orted_kill_local_procs(orte_jobid_t job, struct timeval *timeout, opal_list_t *attrs);
|
||||
ORTE_DECLSPEC int orte_pls_base_orted_signal_local_procs(orte_jobid_t job, int32_t signal, opal_list_t *attrs);
|
||||
ORTE_DECLSPEC int orte_pls_base_orted_add_local_procs(orte_gpr_notify_data_t *ndat);
|
||||
|
||||
ORTE_DECLSPEC int orte_pls_base_get_active_daemons(opal_list_t *daemons, orte_jobid_t job, opal_list_t *attrs);
|
||||
ORTE_DECLSPEC int orte_pls_base_store_active_daemons(opal_list_t *daemons);
|
||||
ORTE_DECLSPEC int orte_pls_base_remove_daemon(orte_pls_daemon_info_t *info);
|
||||
int orte_pls_base_check_avail_daemons(opal_list_t *daemons, orte_jobid_t job);
|
||||
ORTE_DECLSPEC int orte_pls_base_launch_apps(orte_job_map_t *map);
|
||||
|
||||
ORTE_DECLSPEC int orte_pls_base_launch_on_existing_daemons(orte_job_map_t *map);
|
||||
ORTE_DECLSPEC int orte_pls_base_daemon_callback(orte_std_cntr_t num_daemons);
|
||||
|
||||
/*
|
||||
* communications utilities
|
||||
@ -104,7 +86,6 @@ typedef uint8_t orte_pls_cmd_flag_t;
|
||||
/*
|
||||
* general utilities
|
||||
*/
|
||||
ORTE_DECLSPEC int orte_pls_base_mca_argv(int *argc, char ***argv);
|
||||
ORTE_DECLSPEC void orte_pls_base_purge_mca_params(char ***env);
|
||||
|
||||
/**
|
||||
|
@ -135,6 +135,8 @@ static int orte_pls_gridengine_fill_orted_path(char** orted_path)
|
||||
static void orte_pls_gridengine_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
{
|
||||
int rc;
|
||||
orte_buffer_t ack;
|
||||
int src[3] = {-1, -1};
|
||||
|
||||
if (! WIFEXITED(status) || ! WEXITSTATUS(status) == 0) {
|
||||
/* tell the user something went wrong. We need to do this BEFORE we
|
||||
@ -164,6 +166,23 @@ static void orte_pls_gridengine_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
opal_output(0, "No extra status information is available: %d.", status);
|
||||
}
|
||||
|
||||
/* need to fake a message to the daemon callback system so it can break out
|
||||
* of its receive loop
|
||||
*/
|
||||
src[2] = pid;
|
||||
if(WIFSIGNALED(status)) {
|
||||
src[1] = WTERMSIG(status);
|
||||
}
|
||||
OBJ_CONSTRUCT(&ack, orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(&ack, &src, 3, ORTE_INT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
rc = orte_rml.send_buffer(ORTE_PROC_MY_NAME, &ack, ORTE_RML_TAG_ORTED_CALLBACK, 0);
|
||||
if (0 > rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_DESTRUCT(&ack);
|
||||
|
||||
/* The usual reasons for qrsh to exit abnormally all are a pretty good
|
||||
indication that the child processes aren't going to start up properly.
|
||||
Set the job state to indicate we failed to launch so orterun's exit status
|
||||
@ -222,18 +241,13 @@ int orte_pls_gridengine_launch_job(orte_jobid_t jobid)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* account for any reuse of daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_on_existing_daemons(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = map->num_new_daemons;
|
||||
if (num_nodes == 0) {
|
||||
/* job must have been launched on existing daemons - just return */
|
||||
failed_launch = false;
|
||||
rc = ORTE_SUCCESS;
|
||||
goto cleanup;
|
||||
/* have all the daemons we need - launch app */
|
||||
if (mca_pls_gridengine_component.debug) {
|
||||
opal_output(0, "pls:rsh: no new daemons to launch");
|
||||
}
|
||||
goto launch_apps;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -252,8 +266,8 @@ int orte_pls_gridengine_launch_job(orte_jobid_t jobid)
|
||||
|
||||
node_name_index1 = argc;
|
||||
opal_argv_append(&argc, &argv, "<template>");
|
||||
|
||||
/* add the daemon command */
|
||||
|
||||
/* add the orted daemon in command */
|
||||
orted_index = argc;
|
||||
opal_argv_append(&argc, &argv, mca_pls_gridengine_component.orted);
|
||||
|
||||
@ -263,10 +277,15 @@ int orte_pls_gridengine_launch_job(orte_jobid_t jobid)
|
||||
* persistent for the whole duration of the task to the remote nodes,
|
||||
* which may not be ideal for large number of nodes */
|
||||
if (! mca_pls_gridengine_component.daemonize_orted) {
|
||||
opal_argv_append(&argc, &argv, "--no-daemonize");
|
||||
/* the actual orted option will be added when we
|
||||
* append_basic_args
|
||||
*/
|
||||
orte_no_daemonize_flag = true;
|
||||
}
|
||||
|
||||
/* Add basic orted command line options */
|
||||
/* Add basic orted command line options, including
|
||||
* all debug options
|
||||
*/
|
||||
orte_pls_base_orted_append_basic_args(&argc, &argv,
|
||||
&proc_name_index,
|
||||
&node_name_index2,
|
||||
@ -276,8 +295,6 @@ int orte_pls_gridengine_launch_job(orte_jobid_t jobid)
|
||||
* so we only need to do this once
|
||||
*/
|
||||
env = opal_argv_copy(environ);
|
||||
param = mca_base_param_environ_variable("seed",NULL,NULL);
|
||||
opal_setenv(param, "0", true, &env);
|
||||
|
||||
/* clean out any MCA component selection directives that
|
||||
* won't work on remote nodes
|
||||
@ -517,24 +534,31 @@ int orte_pls_gridengine_launch_job(orte_jobid_t jobid)
|
||||
opal_output(0, "pls:gridengine: parent");
|
||||
}
|
||||
|
||||
/* indicate this daemon has been launched in case anyone is sitting on that trigger */
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_proc_state(rmaps_node->daemon, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* setup callback on sigchild - wait until setup above is complete
|
||||
* as the callback can occur in the call to orte_wait_cb
|
||||
*/
|
||||
orte_wait_cb(pid, orte_pls_gridengine_wait_daemon, NULL);
|
||||
orte_wait_cb(pid, orte_pls_gridengine_wait_daemon, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
/* get here if launch went okay */
|
||||
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* get here if launch went okay */
|
||||
failed_launch = false;
|
||||
|
||||
|
||||
cleanup:
|
||||
cleanup:
|
||||
if (NULL != map) {
|
||||
OBJ_RELEASE(map);
|
||||
}
|
||||
|
@ -374,6 +374,8 @@ static void orte_pls_process_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
orte_pls_daemon_info_t *info = (orte_pls_daemon_info_t*) cbdata;
|
||||
int rc;
|
||||
unsigned long deltat;
|
||||
orte_buffer_t ack;
|
||||
int src[3] = {-1, -1};
|
||||
|
||||
if (! WIFEXITED(status) || ! WEXITSTATUS(status) == 0) {
|
||||
/* tell the user something went wrong */
|
||||
@ -398,6 +400,23 @@ static void orte_pls_process_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
} else {
|
||||
opal_output(0, "No extra status information is available: %d.", status);
|
||||
}
|
||||
/* need to fake a message to the daemon callback system so it can break out
|
||||
* of its receive loop
|
||||
*/
|
||||
src[2] = pid;
|
||||
if(WIFSIGNALED(status)) {
|
||||
src[1] = WTERMSIG(status);
|
||||
}
|
||||
OBJ_CONSTRUCT(&ack, orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(&ack, &src, 3, ORTE_INT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
rc = orte_rml.send_buffer(ORTE_PROC_MY_NAME, &ack, ORTE_RML_TAG_ORTED_CALLBACK, 0);
|
||||
if (0 > rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_DESTRUCT(&ack);
|
||||
|
||||
/* The usual reasons for ssh to exit abnormally all are a pretty good
|
||||
indication that the child processes aren't going to start up properly.
|
||||
Set the job state to indicate we failed to launch so orterun's exit status
|
||||
@ -482,18 +501,10 @@ int orte_pls_process_launch(orte_jobid_t jobid)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* account for any reuse of daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_on_existing_daemons(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = map->num_new_daemons;
|
||||
if (0 == num_nodes) {
|
||||
/* nothing to do - just return */
|
||||
failed_launch = false;
|
||||
OBJ_RELEASE(map);
|
||||
return ORTE_SUCCESS;
|
||||
/* have all the daemons we need - launch app */
|
||||
goto launch_apps;
|
||||
}
|
||||
|
||||
if (mca_pls_process_component.debug_daemons &&
|
||||
@ -820,6 +831,18 @@ int orte_pls_process_launch(orte_jobid_t jobid)
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get here if launch went okay */
|
||||
failed_launch = false;
|
||||
|
||||
|
@ -276,6 +276,8 @@ static void orte_pls_rsh_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
{
|
||||
int rc;
|
||||
unsigned long deltat;
|
||||
orte_buffer_t ack;
|
||||
int src[3] = {-1, -1};
|
||||
|
||||
if (! WIFEXITED(status) || ! WEXITSTATUS(status) == 0) {
|
||||
/* tell the user something went wrong */
|
||||
@ -300,6 +302,23 @@ static void orte_pls_rsh_wait_daemon(pid_t pid, int status, void* cbdata)
|
||||
} else {
|
||||
opal_output(0, "No extra status information is available: %d.", status);
|
||||
}
|
||||
/* need to fake a message to the daemon callback system so it can break out
|
||||
* of its receive loop
|
||||
*/
|
||||
src[2] = pid;
|
||||
if(WIFSIGNALED(status)) {
|
||||
src[1] = WTERMSIG(status);
|
||||
}
|
||||
OBJ_CONSTRUCT(&ack, orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(&ack, &src, 3, ORTE_INT))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
rc = orte_rml.send_buffer(ORTE_PROC_MY_NAME, &ack, ORTE_RML_TAG_ORTED_CALLBACK, 0);
|
||||
if (0 > rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_DESTRUCT(&ack);
|
||||
|
||||
/* The usual reasons for ssh to exit abnormally all are a pretty good
|
||||
indication that the child processes aren't going to start up properly.
|
||||
Set the job state to indicate we failed to launch so orterun's exit status
|
||||
@ -352,7 +371,6 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
orte_job_map_t *map=NULL;
|
||||
opal_list_item_t *n_item;
|
||||
orte_mapped_node_t *rmaps_node;
|
||||
orte_std_cntr_t num_nodes;
|
||||
int node_name_index1;
|
||||
int node_name_index2;
|
||||
int proc_name_index;
|
||||
@ -371,6 +389,10 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
bool failed_launch = true;
|
||||
orte_pls_rsh_shell_t shell;
|
||||
|
||||
if (mca_pls_rsh_component.debug) {
|
||||
opal_output(0, "pls:rsh: launching job %ld", (long)jobid);
|
||||
}
|
||||
|
||||
if (mca_pls_rsh_component.timing) {
|
||||
if (0 != gettimeofday(&joblaunchstart, NULL)) {
|
||||
opal_output(0, "pls_rsh: could not obtain start time");
|
||||
@ -394,22 +416,16 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* account for any reuse of daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_on_existing_daemons(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = map->num_new_daemons;
|
||||
if (0 == num_nodes) {
|
||||
/* nothing to do - just return */
|
||||
failed_launch = false;
|
||||
rc = ORTE_SUCCESS;
|
||||
goto cleanup;
|
||||
if (0 == map->num_new_daemons) {
|
||||
/* have all the daemons we need - launch app */
|
||||
if (mca_pls_rsh_component.debug) {
|
||||
opal_output(0, "pls:rsh: no new daemons to launch");
|
||||
}
|
||||
goto launch_apps;
|
||||
}
|
||||
|
||||
if (mca_pls_rsh_component.debug_daemons &&
|
||||
mca_pls_rsh_component.num_concurrent < num_nodes) {
|
||||
mca_pls_rsh_component.num_concurrent < map->num_new_daemons) {
|
||||
/**
|
||||
* If we are in '--debug-daemons' we keep the ssh connection
|
||||
* alive for the span of the run. If we use this option
|
||||
@ -424,7 +440,7 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
* and return an error code.
|
||||
*/
|
||||
opal_show_help("help-pls-rsh.txt", "deadlock-params",
|
||||
true, mca_pls_rsh_component.num_concurrent, num_nodes);
|
||||
true, mca_pls_rsh_component.num_concurrent, map->num_new_daemons);
|
||||
rc = ORTE_ERR_FATAL;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -535,7 +551,8 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
opal_argv_append(&argc, &argv, mca_pls_rsh_component.orted);
|
||||
|
||||
/*
|
||||
* Add the basic arguments to the orted command line
|
||||
* Add the basic arguments to the orted command line, including
|
||||
* all debug options
|
||||
*/
|
||||
orte_pls_base_orted_append_basic_args(&argc, &argv,
|
||||
&proc_name_index,
|
||||
@ -551,7 +568,7 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
free(param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Figure out the basenames for the libdir and bindir. This
|
||||
requires some explanation:
|
||||
|
||||
@ -634,6 +651,12 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
rmaps_node->nodename);
|
||||
}
|
||||
|
||||
/* setup environment */
|
||||
env = opal_argv_copy(environ);
|
||||
|
||||
/* clean any mca params that shouldn't go to the backend */
|
||||
orte_pls_base_purge_mca_params(&env);
|
||||
|
||||
/* We don't need to sense an oversubscribed condition and set the sched_yield
|
||||
* for the node as we are only launching the daemons at this time. The daemons
|
||||
* are now smart enough to set the oversubscribed condition themselves when
|
||||
@ -706,7 +729,7 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
free( newenv );
|
||||
newenv = temp;
|
||||
}
|
||||
opal_setenv("PATH", newenv, true, &environ);
|
||||
opal_setenv("PATH", newenv, true, &env);
|
||||
if (mca_pls_rsh_component.debug) {
|
||||
opal_output(0, "pls:rsh: reset PATH: %s", newenv);
|
||||
}
|
||||
@ -721,7 +744,7 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
free(newenv);
|
||||
newenv = temp;
|
||||
}
|
||||
opal_setenv("LD_LIBRARY_PATH", newenv, true, &environ);
|
||||
opal_setenv("LD_LIBRARY_PATH", newenv, true, &env);
|
||||
if (mca_pls_rsh_component.debug) {
|
||||
opal_output(0, "pls:rsh: reset LD_LIBRARY_PATH: %s",
|
||||
newenv);
|
||||
@ -859,11 +882,6 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
sigprocmask(0, 0, &sigs);
|
||||
sigprocmask(SIG_UNBLOCK, &sigs, 0);
|
||||
|
||||
/* setup environment */
|
||||
env = opal_argv_copy(environ);
|
||||
var = mca_base_param_environ_variable("seed",NULL,NULL);
|
||||
opal_setenv(var, "0", true, &env);
|
||||
|
||||
/* exec the daemon */
|
||||
if (mca_pls_rsh_component.debug) {
|
||||
param = opal_argv_join(exec_argv, ' ');
|
||||
@ -906,9 +924,23 @@ int orte_pls_rsh_launch(orte_jobid_t jobid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get here if launch went okay */
|
||||
failed_launch = false;
|
||||
|
||||
|
||||
|
||||
cleanup:
|
||||
if (NULL != map) {
|
||||
OBJ_RELEASE(map);
|
||||
|
@ -32,3 +32,10 @@ a fatal error for the SLURM process starter in Open MPI.
|
||||
The first two prefix values supplied were:
|
||||
%s
|
||||
and %s
|
||||
#
|
||||
[no-hosts-in-list]
|
||||
The SLURM process starter for Open MPI didn't find any hosts in
|
||||
the map for this application. This can be caused by a lack of
|
||||
an allocation, or by an error in the Open MPI code. Please check
|
||||
to ensure you have a SLURM allocation. If you do, then please pass
|
||||
the error to the Open MPI user's mailing list for assistance.
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "opal/util/basename.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
|
||||
#include "orte/runtime/params.h"
|
||||
#include "orte/runtime/runtime.h"
|
||||
#include "orte/runtime/orte_wakeup.h"
|
||||
#include "orte/runtime/orte_wait.h"
|
||||
@ -159,18 +160,10 @@ static int pls_slurm_launch_job(orte_jobid_t jobid)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* account for any reuse of daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_on_existing_daemons(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = map->num_new_daemons;
|
||||
if (num_nodes == 0) {
|
||||
/* nothing to do - just return */
|
||||
failed_launch = false;
|
||||
rc = ORTE_SUCCESS;
|
||||
goto cleanup;
|
||||
/* no new daemons required - just launch apps */
|
||||
goto launch_apps;
|
||||
}
|
||||
|
||||
/* need integer value for command line parameter */
|
||||
@ -228,6 +221,11 @@ static int pls_slurm_launch_job(orte_jobid_t jobid)
|
||||
*/
|
||||
opal_argv_append(&nodelist_argc, &nodelist_argv, node->nodename);
|
||||
}
|
||||
if (0 == opal_argv_count(nodelist_argv)) {
|
||||
opal_show_help("help-pls-slurm.txt", "no-hosts-in-list", true);
|
||||
rc = ORTE_ERR_FAILED_TO_START;
|
||||
goto cleanup;
|
||||
}
|
||||
nodelist_flat = opal_argv_join(nodelist_argv, ',');
|
||||
opal_argv_free(nodelist_argv);
|
||||
asprintf(&tmp, "--nodelist=%s", nodelist_flat);
|
||||
@ -241,14 +239,15 @@ static int pls_slurm_launch_job(orte_jobid_t jobid)
|
||||
|
||||
/* add the daemon command (as specified by user) */
|
||||
opal_argv_append(&argc, &argv, mca_pls_slurm_component.orted);
|
||||
opal_argv_append(&argc, &argv, "--no-daemonize");
|
||||
|
||||
/* ensure we don't lose contact */
|
||||
orte_no_daemonize_flag = true;
|
||||
|
||||
/* Add basic orted command line options */
|
||||
/* Add basic orted command line options, including debug flags */
|
||||
orte_pls_base_orted_append_basic_args(&argc, &argv,
|
||||
&proc_name_index,
|
||||
NULL,
|
||||
num_nodes
|
||||
);
|
||||
num_nodes);
|
||||
|
||||
/* force orted to use the slurm sds */
|
||||
opal_argv_append(&argc, &argv, "--ns-nds");
|
||||
@ -312,9 +311,11 @@ static int pls_slurm_launch_job(orte_jobid_t jobid)
|
||||
|
||||
/* setup environment */
|
||||
env = opal_argv_copy(environ);
|
||||
var = mca_base_param_environ_variable("seed", NULL, NULL);
|
||||
opal_setenv(var, "0", true, &env);
|
||||
free(var);
|
||||
|
||||
/* purge it of any params not for orteds */
|
||||
orte_pls_base_purge_mca_params(&env);
|
||||
|
||||
/* add the nodelist */
|
||||
var = mca_base_param_environ_variable("orte", "slurm", "nodelist");
|
||||
opal_setenv(var, nodelist_flat, true, &env);
|
||||
free(nodelist_flat);
|
||||
@ -333,11 +334,22 @@ static int pls_slurm_launch_job(orte_jobid_t jobid)
|
||||
}
|
||||
|
||||
/* do NOT wait for srun to complete. Srun only completes when the processes
|
||||
* it starts - in this case, the orteds - complete. We need to go ahead and
|
||||
* return so orterun can do the rest of its stuff. Instead, we'll catch
|
||||
* it starts - in this case, the orteds - complete. Instead, we'll catch
|
||||
* any srun failures and deal with them elsewhere
|
||||
*/
|
||||
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* declare the launch a success */
|
||||
failed_launch = false;
|
||||
|
||||
@ -516,7 +528,7 @@ static void srun_wait_cb(pid_t pid, int status, void* cbdata){
|
||||
static int pls_slurm_start_proc(int argc, char **argv, char **env,
|
||||
char *prefix)
|
||||
{
|
||||
int fd, id, debug_daemons;
|
||||
int fd;
|
||||
char *exec_argv = opal_path_findv(argv[0], 0, env, NULL);
|
||||
|
||||
if (NULL == exec_argv) {
|
||||
@ -575,12 +587,7 @@ static int pls_slurm_start_proc(int argc, char **argv, char **env,
|
||||
|
||||
/* When not in debug mode and --debug-daemons was not passed,
|
||||
* tie stdout/stderr to dev null so we don't see messages from orted */
|
||||
id = mca_base_param_find("orte", "debug", "daemons");
|
||||
if(id < 0) {
|
||||
id = mca_base_param_register_int("orte", "debug", "daemons", NULL, 0);
|
||||
}
|
||||
mca_base_param_lookup_int(id, &debug_daemons);
|
||||
if (0 == mca_pls_slurm_component.debug && 0 == debug_daemons) {
|
||||
if (0 == mca_pls_slurm_component.debug && !orte_debug_daemons_flag) {
|
||||
fd = open("/dev/null", O_CREAT|O_WRONLY|O_TRUNC, 0666);
|
||||
if (fd >= 0) {
|
||||
if (fd != 1) {
|
||||
|
@ -174,18 +174,10 @@ static int pls_tm_launch_job(orte_jobid_t jobid)
|
||||
}
|
||||
}
|
||||
|
||||
/* account for any reuse of daemons */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_on_existing_daemons(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = map->num_new_daemons;
|
||||
if (0 == num_nodes) {
|
||||
/* must have been launched on existing daemons - just return */
|
||||
failed_launch = false;
|
||||
rc = ORTE_SUCCESS;
|
||||
goto cleanup;
|
||||
/* have all the daemons we need - launch app */
|
||||
goto launch_apps;
|
||||
}
|
||||
|
||||
/* Allocate a bunch of TM events to use for tm_spawn()ing */
|
||||
@ -294,7 +286,7 @@ static int pls_tm_launch_job(orte_jobid_t jobid)
|
||||
if (node->daemon_preexists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* setup node name */
|
||||
free(argv[node_name_index]);
|
||||
argv[node_name_index] = strdup(node->nodename);
|
||||
@ -361,13 +353,7 @@ static int pls_tm_launch_job(orte_jobid_t jobid)
|
||||
}
|
||||
|
||||
launched++;
|
||||
|
||||
/* indicate this daemon has been launched in case anyone is sitting on that trigger */
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_proc_state(node->daemon, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* Allow some progress to occur */
|
||||
opal_event_loop(OPAL_EVLOOP_NONBLOCK);
|
||||
}
|
||||
@ -394,6 +380,18 @@ static int pls_tm_launch_job(orte_jobid_t jobid)
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* if we get here, then everything launched okay - record that fact */
|
||||
failed_launch = false;
|
||||
|
||||
|
@ -229,15 +229,12 @@ char **environ;
|
||||
|
||||
-(int) launchJob:(orte_jobid_t) jobid
|
||||
{
|
||||
orte_job_map_t *map;
|
||||
orte_job_map_t *map=NULL;
|
||||
opal_list_item_t *item;
|
||||
size_t num_nodes;
|
||||
orte_vpid_t vpid;
|
||||
int rc, i = 0;
|
||||
opal_list_t daemons;
|
||||
orte_pls_daemon_info_t *dmn;
|
||||
char *orted_path;
|
||||
char *nsuri = NULL, *gpruri = NULL;
|
||||
bool failed_launch = true;
|
||||
|
||||
/* Query the map for this job.
|
||||
* We need the entire mapping for a couple of reasons:
|
||||
@ -249,29 +246,10 @@ char **environ;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
num_nodes = opal_list_get_size(&map->nodes);
|
||||
|
||||
/*
|
||||
* Allocate a range of vpids for the daemons.
|
||||
*/
|
||||
if (0 == num_nodes) {
|
||||
return ORTE_ERR_BAD_PARAM;
|
||||
if (0 == map->num_new_daemons) {
|
||||
/* have all the daemons we need - launch app */
|
||||
goto launch_apps;
|
||||
}
|
||||
rc = orte_ns.reserve_range(0, num_nodes, &vpid);
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* setup the orted triggers for passing their launch info */
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.init_orted_stage_gates(jobid, num_nodes, NULL, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* setup a list that will contain the info for all the daemons
|
||||
* so we can store it on the registry when done
|
||||
*/
|
||||
OBJ_CONSTRUCT(&daemons, opal_list_t);
|
||||
|
||||
/* find orted */
|
||||
orted_path = opal_path_findv((char*) [orted cString], 0, environ, NULL);
|
||||
@ -303,26 +281,9 @@ char **environ;
|
||||
orte_process_name_t* name;
|
||||
char* name_string;
|
||||
|
||||
/* new daemon - setup to record its info */
|
||||
dmn = OBJ_NEW(orte_pls_daemon_info_t);
|
||||
dmn->active_job = jobid;
|
||||
opal_list_append(&daemons, &dmn->super);
|
||||
|
||||
/* record the node name in the daemon struct */
|
||||
dmn->cell = rmaps_node->cell;
|
||||
dmn->nodename = strdup(rmaps_node->nodename);
|
||||
|
||||
/* initialize daemons process name */
|
||||
rc = orte_ns.create_process_name(&name, rmaps_node->cell, 0, vpid);
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* save it in the daemon struct */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.copy((void**)&(dmn->name), name, ORTE_NAME))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
/* if this daemon already exists, don't launch it! */
|
||||
if (rmaps_node->daemon_preexists) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* setup per-node options */
|
||||
@ -331,7 +292,7 @@ char **environ;
|
||||
rmaps_node->nodename);
|
||||
|
||||
/* setup process name */
|
||||
rc = orte_ns.get_proc_name_string(&name_string, name);
|
||||
rc = orte_ns.get_proc_name_string(&name_string, rmaps_node->daemon);
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
opal_output(orte_pls_base.pls_output,
|
||||
"orte:pls:xgrid: unable to create process name");
|
||||
@ -343,7 +304,6 @@ char **environ;
|
||||
forKey: XGJobSpecificationCommandKey];
|
||||
NSArray *taskArguments =
|
||||
[NSArray arrayWithObjects: @"--no-daemonize",
|
||||
@"--bootproxy", [NSString stringWithFormat: @"%d", jobid],
|
||||
@"--name", [NSString stringWithCString: name_string],
|
||||
@"--num_procs", [NSString stringWithFormat: @"%d", 1],
|
||||
@"--nodename", [NSString stringWithCString: rmaps_node->nodename],
|
||||
@ -355,7 +315,7 @@ char **environ;
|
||||
[taskSpecifications setObject: task
|
||||
forKey: [NSString stringWithFormat: @"%d", i]];
|
||||
|
||||
vpid++; i++;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* job specification */
|
||||
@ -396,23 +356,39 @@ char **environ;
|
||||
[active_jobs setObject: [[actionMonitor results] objectForKey: @"jobIdentifier"]
|
||||
forKey: [NSString stringWithFormat: @"%d", jobid]];
|
||||
|
||||
/* all done, so store the daemon info on the registry */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_store_active_daemons(&daemons))) {
|
||||
/* wait for daemons to callback */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_daemon_callback(map->num_new_daemons))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
launch_apps:
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_launch_apps(map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get here if launch went okay */
|
||||
failed_launch = false;
|
||||
|
||||
cleanup:
|
||||
OBJ_RELEASE(map);
|
||||
if (NULL != map) OBJ_RELEASE(map);
|
||||
|
||||
if (NULL != nsuri) free(nsuri);
|
||||
if (NULL != gpruri) free(gpruri);
|
||||
|
||||
/* deconstruct the daemon list */
|
||||
while (NULL != (item = opal_list_remove_first(&daemons))) {
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&daemons);
|
||||
|
||||
/* check for failed launch - if so, force terminate */
|
||||
if (failed_launch) {
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_job_state(jobid, ORTE_JOB_STATE_FAILED_TO_START))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_wakeup(jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
}
|
||||
|
||||
opal_output_verbose(1, orte_pls_base.pls_output,
|
||||
"orte:pls:xgrid:launch: finished\n");
|
||||
|
||||
|
@ -53,7 +53,6 @@ int orte_pls_xgrid_terminate_orteds(orte_jobid_t jobid, struct timeval *timeout,
|
||||
int orte_pls_xgrid_terminate_proc(const orte_process_name_t* proc);
|
||||
int orte_pls_xgrid_signal_job(orte_jobid_t job, int32_t signal, opal_list_t *attrs);
|
||||
int orte_pls_xgrid_signal_proc(const orte_process_name_t* proc_name, int32_t signal);
|
||||
int orte_pls_xgrid_cancel_operation(void);
|
||||
int orte_pls_xgrid_finalize(void);
|
||||
|
||||
orte_pls_base_module_1_3_0_t orte_pls_xgrid_module = {
|
||||
@ -63,7 +62,6 @@ orte_pls_base_module_1_3_0_t orte_pls_xgrid_module = {
|
||||
orte_pls_xgrid_terminate_proc,
|
||||
orte_pls_xgrid_signal_job,
|
||||
orte_pls_xgrid_signal_proc,
|
||||
orte_pls_xgrid_cancel_operation,
|
||||
orte_pls_xgrid_finalize
|
||||
};
|
||||
|
||||
@ -88,28 +86,14 @@ int
|
||||
orte_pls_xgrid_terminate_job(orte_jobid_t jobid, struct timeval *timeout, opal_list_t *attrs)
|
||||
{
|
||||
int rc;
|
||||
opal_list_t daemons;
|
||||
opal_list_item_t *item;
|
||||
|
||||
/* construct the list of active daemons on this job */
|
||||
OBJ_CONSTRUCT(&daemons, opal_list_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_get_active_daemons(&daemons, jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* order them to kill their local procs for this job */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_kill_local_procs(&daemons, jobid, timeout))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_kill_local_procs(jobid, timeout, attrs))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
while (NULL != (item = opal_list_remove_first(&daemons))) {
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&daemons);
|
||||
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
rc = [mca_pls_xgrid_component.client terminateJob:jobid];
|
||||
}
|
||||
@ -125,27 +109,13 @@ int
|
||||
orte_pls_xgrid_terminate_orteds(orte_jobid_t jobid, struct timeval *timeout, opal_list_t *attrs)
|
||||
{
|
||||
int rc;
|
||||
opal_list_t daemons;
|
||||
opal_list_item_t *item;
|
||||
|
||||
/* construct the list of active daemons on this job */
|
||||
OBJ_CONSTRUCT(&daemons, opal_list_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_get_active_daemons(&daemons, jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* now tell them to die! */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_exit(&daemons, timeout))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_exit(timeout, attrs))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
while (NULL != (item = opal_list_remove_first(&daemons))) {
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&daemons);
|
||||
|
||||
if (ORTE_SUCCESS != rc) {
|
||||
rc = [mca_pls_xgrid_component.client terminateJob:jobid];
|
||||
}
|
||||
@ -168,27 +138,13 @@ int
|
||||
orte_pls_xgrid_signal_job(orte_jobid_t jobid, int32_t signal, opal_list_t *attrs)
|
||||
{
|
||||
int rc;
|
||||
opal_list_t daemons;
|
||||
opal_list_item_t *item;
|
||||
|
||||
/* construct the list of active daemons on this job */
|
||||
OBJ_CONSTRUCT(&daemons, opal_list_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_get_active_daemons(&daemons, jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&daemons);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* order them to pass this signal to their local procs */
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_signal_local_procs(&daemons, signal))) {
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_signal_local_procs(jobid, signal, attrs))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
|
||||
while (NULL != (item = opal_list_remove_first(&daemons))) {
|
||||
OBJ_RELEASE(item);
|
||||
}
|
||||
OBJ_DESTRUCT(&daemons);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -199,19 +155,6 @@ orte_pls_xgrid_signal_proc(const orte_process_name_t* proc, int32_t signal)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
orte_pls_xgrid_cancel_operation(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_pls_base_orted_cancel_operation())) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
orte_pls_xgrid_finalize(void)
|
||||
{
|
||||
|
@ -52,9 +52,10 @@ int orte_rmaps_base_print_map(char **output, char *prefix, orte_job_map_t *src,
|
||||
asprintf(&pfx2, "%s", prefix);
|
||||
}
|
||||
|
||||
asprintf(&tmp, "%sMap for job: %ld\tGenerated by mapping mode: %s\n%s\tStarting vpid: %ld\tVpid range: %ld\tNum app_contexts: %ld",
|
||||
asprintf(&tmp, "%sMap for job: %ld\tGenerated by mapping mode: %s\n%s\tStarting vpid: %ld\tVpid range: %ld\n%s\tNum app_contexts: %ld\tNum nodes: %ld",
|
||||
pfx2, (long)src->job, (NULL == src->mapping_mode) ? "NULL" : src->mapping_mode,
|
||||
pfx2, (long)src->vpid_start, (long)src->vpid_range, (long)src->num_apps);
|
||||
pfx2, (long)src->vpid_start, (long)src->vpid_range,
|
||||
pfx2, (long)src->num_apps, (long)src->num_nodes);
|
||||
|
||||
asprintf(&pfx, "%s\t", pfx2);
|
||||
free(pfx2);
|
||||
@ -71,9 +72,7 @@ int orte_rmaps_base_print_map(char **output, char *prefix, orte_job_map_t *src,
|
||||
free(tmp2);
|
||||
tmp = tmp3;
|
||||
}
|
||||
|
||||
asprintf(&tmp, "%s\n%sNum elements in nodes list: %ld", tmp3, pfx, (long)src->num_nodes);
|
||||
|
||||
|
||||
for (item = opal_list_get_first(&(src->nodes));
|
||||
item != opal_list_get_end(&(src->nodes));
|
||||
item = opal_list_get_next(item)) {
|
||||
|
@ -84,8 +84,11 @@ int orte_rmaps_base_get_job_map(orte_job_map_t **map, orte_jobid_t jobid)
|
||||
char* dkeys[] = {
|
||||
ORTE_PROC_NAME_KEY,
|
||||
ORTE_NODE_NAME_KEY,
|
||||
ORTE_PROC_RML_IP_ADDRESS_KEY,
|
||||
NULL
|
||||
};
|
||||
bool daemon_exists;
|
||||
|
||||
OPAL_TRACE(1);
|
||||
|
||||
/* define default answer */
|
||||
@ -318,6 +321,7 @@ int orte_rmaps_base_get_job_map(orte_job_map_t **map, orte_jobid_t jobid)
|
||||
for(v=0; v<num_dvalues; v++) {
|
||||
value = dvalues[v];
|
||||
node_name = NULL;
|
||||
daemon_exists = false;
|
||||
for(kv = 0; kv<value->cnt; kv++) {
|
||||
keyval = value->keyvals[kv];
|
||||
if(strcmp(keyval->key, ORTE_NODE_NAME_KEY) == 0) {
|
||||
@ -335,6 +339,13 @@ int orte_rmaps_base_get_job_map(orte_job_map_t **map, orte_jobid_t jobid)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strcmp(keyval->key, ORTE_PROC_RML_IP_ADDRESS_KEY) == 0) {
|
||||
/* we don't care about the value here - the existence of the key is
|
||||
* enough to indicate that this daemon must already exist, so flag it
|
||||
*/
|
||||
daemon_exists = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (NULL == node_name) continue;
|
||||
/* find this node on the map */
|
||||
@ -348,6 +359,10 @@ int orte_rmaps_base_get_job_map(orte_job_map_t **map, orte_jobid_t jobid)
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (daemon_exists) {
|
||||
/* set the pre-existing flag */
|
||||
node->daemon_preexists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,6 +513,7 @@ int orte_rmaps_base_define_daemons(orte_job_map_t *map)
|
||||
char* dkeys[] = {
|
||||
ORTE_PROC_NAME_KEY,
|
||||
ORTE_NODE_NAME_KEY,
|
||||
ORTE_PROC_RML_IP_ADDRESS_KEY,
|
||||
NULL
|
||||
};
|
||||
orte_gpr_value_t **dvalues=NULL, *value;
|
||||
@ -521,6 +522,7 @@ int orte_rmaps_base_define_daemons(orte_job_map_t *map)
|
||||
char *node_name;
|
||||
orte_process_name_t *pptr;
|
||||
int rc;
|
||||
bool daemon_exists;
|
||||
|
||||
/* save the default number of daemons we will need */
|
||||
num_daemons = map->num_nodes;
|
||||
@ -544,6 +546,7 @@ int orte_rmaps_base_define_daemons(orte_job_map_t *map)
|
||||
for(v=0; v<num_dvalues; v++) {
|
||||
value = dvalues[v];
|
||||
node_name = NULL;
|
||||
daemon_exists = false;
|
||||
for(kv = 0; kv<value->cnt; kv++) {
|
||||
keyval = value->keyvals[kv];
|
||||
if(strcmp(keyval->key, ORTE_NODE_NAME_KEY) == 0) {
|
||||
@ -561,6 +564,13 @@ int orte_rmaps_base_define_daemons(orte_job_map_t *map)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strcmp(keyval->key, ORTE_PROC_RML_IP_ADDRESS_KEY) == 0) {
|
||||
/* we don't care about the value here - the existence of the key is
|
||||
* enough to indicate that this daemon must already exist, so flag it
|
||||
*/
|
||||
daemon_exists = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (NULL == node_name) continue;
|
||||
/* find this node on the map */
|
||||
@ -574,10 +584,12 @@ int orte_rmaps_base_define_daemons(orte_job_map_t *map)
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* flag that this daemon already exists */
|
||||
node->daemon_preexists = true;
|
||||
/* decrease the number of daemons we will need to start */
|
||||
--num_daemons;
|
||||
/* flag that this daemon already exists, if it does */
|
||||
if (daemon_exists) {
|
||||
node->daemon_preexists = true;
|
||||
/* decrease the number of daemons we will need to start */
|
||||
--num_daemons;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "orte/orte_constants.h"
|
||||
#include "orte/orte_types.h"
|
||||
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/trace.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
@ -241,21 +240,6 @@ CLEANUP_SPAWN:
|
||||
}
|
||||
break;
|
||||
|
||||
case ORTE_RMGR_SETUP_ORTED_GATES_CMD:
|
||||
/* get the jobid */
|
||||
count = 1;
|
||||
if(ORTE_SUCCESS != (rc = orte_dss.unpack(buffer, &job, &count, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto SEND_ANSWER;
|
||||
}
|
||||
|
||||
/* setup the stage gates */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_base_orted_stage_gate_init(job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto SEND_ANSWER;
|
||||
}
|
||||
break;
|
||||
|
||||
case ORTE_RMGR_XCONNECT_CMD:
|
||||
/* get the child jobid */
|
||||
count = 1;
|
||||
|
@ -175,166 +175,3 @@ CLEANUP:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int orte_rmgr_base_orted_stage_gate_init(orte_jobid_t job)
|
||||
{
|
||||
orte_job_map_t *map;
|
||||
int rc;
|
||||
|
||||
/* get the map for this job */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmaps.get_job_map(&map, job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* setup the orted triggers for passing their launch info */
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.init_orted_stage_gates(map->job, map->num_new_daemons,
|
||||
orte_rmgr_base_orted_stage_gate_mgr, NULL))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int orte_rmgr_base_orted_stage_gate_mgr(orte_gpr_notify_message_t *msg)
|
||||
{
|
||||
int rc;
|
||||
orte_jobid_t job, *jptr;
|
||||
orte_job_map_t *map;
|
||||
orte_daemon_cmd_flag_t command;
|
||||
orte_buffer_t *buffer;
|
||||
orte_gpr_notify_data_t *launch_data;
|
||||
char* keys[] = {
|
||||
ORTE_JOB_BEING_LAUNCHED_KEY,
|
||||
NULL
|
||||
};
|
||||
char* tokens[] = {
|
||||
ORTE_JOB_GLOBALS,
|
||||
NULL
|
||||
};
|
||||
orte_gpr_value_t **values=NULL;
|
||||
orte_std_cntr_t num_values=0;
|
||||
|
||||
OPAL_TRACE(1);
|
||||
|
||||
/* set the job state to the appropriate level */
|
||||
if (orte_schema.check_std_trigger_name(msg->target, ORTE_STARTUP_TRIGGER)) {
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_job_state(0, ORTE_JOB_ORTE_STARTUP_COMPLETE))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
} else if (orte_schema.check_std_trigger_name(msg->target, ORTE_ALL_RUNNING_TRIGGER)) {
|
||||
if (ORTE_SUCCESS != (rc = orte_smr.set_job_state(0, ORTE_JOB_STATE_RUNNING))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* check to see if this came from a trigger that requires we send a message - if
|
||||
* so, then handle it as required
|
||||
*/
|
||||
if (orte_schema.check_std_trigger_name(msg->target, ORTE_STARTUP_TRIGGER)) {
|
||||
/* the startup trigger is intended for the sharing of contact info
|
||||
* across all orteds. The new orteds will be sitting at their startup
|
||||
* stage gate and need an xcast_barrier message to release them, so we
|
||||
* send the message to that RML tag. Orteds that have already started will
|
||||
* have posted a persistent RML receive on that tag so they can "catch"
|
||||
* this message as well - they use that mechanism to update their RML
|
||||
* contact info so they can talk to the other daemons since the xcast
|
||||
* goes to ALL members of the specified job.
|
||||
*/
|
||||
|
||||
/* set the message type to SUBSCRIPTION. When we give this to the processes, we want
|
||||
* them to break the message down and deliver it to the various subsystems.
|
||||
*/
|
||||
msg->msg_type = ORTE_GPR_SUBSCRIPTION_MSG;
|
||||
msg->id = ORTE_GPR_TRIGGER_ID_MAX;
|
||||
|
||||
/* setup the buffer */
|
||||
buffer = OBJ_NEW(orte_buffer_t);
|
||||
|
||||
/* pack the msg to be delivered */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(buffer, &msg, 1, ORTE_GPR_NOTIFY_MSG))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send the message to the xcast_barrier since the orte_startup trigger
|
||||
* is a blocking action
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_rml.xcast(0, buffer, ORTE_RML_TAG_XCAST_BARRIER))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_RELEASE(buffer);
|
||||
|
||||
} else if (orte_schema.check_std_trigger_name(msg->target, ORTE_ALL_RUNNING_TRIGGER)) {
|
||||
/* the running trigger indicates that we are ready to launch a job - get the
|
||||
* job being launched from the registry, get the launch data, and then send it out to
|
||||
* all the orteds
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.get(ORTE_GPR_KEYS_OR|ORTE_GPR_TOKENS_OR,
|
||||
"orte-job-0", tokens, keys,
|
||||
&num_values, &values))) {
|
||||
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (1 != num_values || 1 != values[0]->cnt) { /* can only be one value returned */
|
||||
ORTE_ERROR_LOG(ORTE_ERR_GPR_DATA_CORRUPT);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.get((void**)&jptr, values[0]->keyvals[0]->value, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
job = *jptr;
|
||||
OBJ_RELEASE(values[0]);
|
||||
|
||||
/* get the job map */
|
||||
if (ORTE_SUCCESS != (rc = orte_rmaps.get_job_map(&map, job))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* let the local launcher provide its required data */
|
||||
if (ORTE_SUCCESS != (rc = orte_odls.get_add_procs_data(&launch_data, map))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
OBJ_RELEASE(map); /* done with this */
|
||||
|
||||
/* setup the buffer */
|
||||
buffer = OBJ_NEW(orte_buffer_t);
|
||||
/* pack the add_local_procs command */
|
||||
command = ORTE_DAEMON_ADD_LOCAL_PROCS;
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(buffer, &command, 1, ORTE_DAEMON_CMD))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* pack the launch data */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(buffer, &launch_data, 1, ORTE_GPR_NOTIFY_DATA))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_RELEASE(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send the command to the daemon */
|
||||
if (ORTE_SUCCESS != (rc = orte_rml.xcast(0, buffer, ORTE_RML_TAG_DAEMON))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
OBJ_RELEASE(buffer);
|
||||
|
||||
cleanup:
|
||||
if (NULL != values) free(values);
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,6 @@ extern "C" {
|
||||
#define ORTE_RMGR_SPAWN_JOB_CMD 2
|
||||
#define ORTE_RMGR_SETUP_GATES_CMD 3
|
||||
#define ORTE_RMGR_XCONNECT_CMD 4
|
||||
#define ORTE_RMGR_SETUP_ORTED_GATES_CMD 5
|
||||
|
||||
#define ORTE_RMGR_CMD ORTE_UINT8
|
||||
typedef uint8_t orte_rmgr_cmd_t;
|
||||
@ -135,10 +134,6 @@ ORTE_DECLSPEC int orte_rmgr_base_proc_stage_gate_init(orte_jobid_t job);
|
||||
|
||||
ORTE_DECLSPEC int orte_rmgr_base_proc_stage_gate_mgr(orte_gpr_notify_message_t *msg);
|
||||
|
||||
ORTE_DECLSPEC int orte_rmgr_base_orted_stage_gate_init(orte_jobid_t job);
|
||||
|
||||
ORTE_DECLSPEC int orte_rmgr_base_orted_stage_gate_mgr(orte_gpr_notify_message_t *msg);
|
||||
|
||||
ORTE_DECLSPEC int orte_rmgr_base_xconnect(orte_jobid_t child, orte_jobid_t parent);
|
||||
|
||||
ORTE_DECLSPEC int orte_rmgr_base_comm_start(void);
|
||||
|
@ -49,8 +49,6 @@ static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
||||
|
||||
static int orte_rmgr_proxy_setup_stage_gates(orte_jobid_t jobid);
|
||||
|
||||
static int orte_rmgr_proxy_orted_stage_gate_init(orte_jobid_t jobid);
|
||||
|
||||
static int orte_rmgr_proxy_spawn_job(
|
||||
orte_app_context_t** app_context,
|
||||
orte_std_cntr_t num_context,
|
||||
@ -174,67 +172,6 @@ static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int orte_rmgr_proxy_orted_stage_gate_init(orte_jobid_t jobid)
|
||||
{
|
||||
orte_buffer_t cmd;
|
||||
orte_buffer_t rsp;
|
||||
orte_std_cntr_t count;
|
||||
orte_rmgr_cmd_t command=ORTE_RMGR_SETUP_ORTED_GATES_CMD;
|
||||
int rc;
|
||||
|
||||
OPAL_TRACE(1);
|
||||
|
||||
/* construct command */
|
||||
OBJ_CONSTRUCT(&cmd, orte_buffer_t);
|
||||
|
||||
/* pack the command */
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, &command, 1, ORTE_RMGR_CMD))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&cmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* pack the jobid */
|
||||
if(ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, &jobid, 1, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&cmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* send the command */
|
||||
if(0 > (rc = orte_rml.send_buffer(ORTE_PROC_MY_HNP, &cmd, ORTE_RML_TAG_RMGR, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&cmd);
|
||||
return rc;
|
||||
}
|
||||
OBJ_DESTRUCT(&cmd);
|
||||
|
||||
/* wait for response */
|
||||
OBJ_CONSTRUCT(&rsp, orte_buffer_t);
|
||||
if(0 > (rc = orte_rml.recv_buffer(ORTE_PROC_MY_HNP, &rsp, ORTE_RML_TAG_RMGR))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&rsp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* get the returned command */
|
||||
count = 1;
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.unpack(&rsp, &command, &count, ORTE_RMGR_CMD))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
OBJ_DESTRUCT(&rsp);
|
||||
return rc;
|
||||
}
|
||||
/* and check it to ensure valid comm */
|
||||
if (ORTE_RMGR_SETUP_ORTED_GATES_CMD != command) {
|
||||
OBJ_DESTRUCT(&rsp);
|
||||
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
||||
return ORTE_ERR_COMM_FAILURE;
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT(&rsp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int orte_rmgr_proxy_setup_stage_gates(orte_jobid_t jobid)
|
||||
{
|
||||
orte_buffer_t cmd;
|
||||
@ -571,7 +508,7 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
} else {
|
||||
flags = 0xff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup job and allocate resources
|
||||
*/
|
||||
@ -582,21 +519,21 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (flags & ORTE_RMGR_RES_DISC) {
|
||||
if (ORTE_SUCCESS != (rc = orte_rds.query(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (flags & ORTE_RMGR_ALLOC) {
|
||||
if (ORTE_SUCCESS != (rc = orte_ras.allocate_job(*jobid, attributes))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (flags & ORTE_RMGR_MAP) {
|
||||
if (ORTE_SUCCESS != (rc = orte_rmaps.map_job(*jobid, attributes))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
@ -667,7 +604,7 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* setup any user-provided callback
|
||||
*/
|
||||
@ -698,16 +635,7 @@ static int orte_rmgr_proxy_spawn_job(
|
||||
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* setup the orted's stage gate triggers - do this here as, if there are no
|
||||
* new orteds to launch, the trigger will fire immediately and launch
|
||||
* the procs
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_proxy_orted_stage_gate_init(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* launch the job
|
||||
*/
|
||||
|
@ -591,15 +591,6 @@ static int orte_rmgr_urm_spawn_job(
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup the orted's stage gate triggers - do this here as, if there are no
|
||||
* new orteds to launch, the trigger will fire immediately and launch
|
||||
* the procs
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_rmgr_base_orted_stage_gate_init(*jobid))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* launch the job
|
||||
*/
|
||||
|
@ -68,9 +68,10 @@ typedef uint32_t orte_rml_tag_t;
|
||||
#define ORTE_RML_TAG_SM_BACK_FILE_CREATED 18
|
||||
#define ORTE_RML_TAG_WIREUP 19
|
||||
#define ORTE_RML_TAG_RML 20
|
||||
#define ORTE_RML_TAG_ORTED_CALLBACK 21
|
||||
|
||||
#define ORTE_RML_TAG_FILEM 21
|
||||
#define ORTE_RML_TAG_CKPT 22
|
||||
#define ORTE_RML_TAG_FILEM 22
|
||||
#define ORTE_RML_TAG_CKPT 23
|
||||
/* For CRCP Coord Component */
|
||||
#define OMPI_CRCP_COORD_BOOKMARK_TAG 4242
|
||||
|
||||
|
@ -70,9 +70,8 @@ int orte_schema_base_get_std_subscription_name(char **name,
|
||||
char *subscription,
|
||||
orte_jobid_t jobid);
|
||||
|
||||
|
||||
/*
|
||||
* globals that might be needed inside the gpr
|
||||
* globals that might be needed inside the schema framework
|
||||
*/
|
||||
extern int orte_schema_base_output;
|
||||
extern bool orte_schema_base_selected;
|
||||
|
@ -313,3 +313,4 @@ int orte_schema_base_get_std_subscription_name(char **name,
|
||||
free(jobidstring);
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -71,21 +71,20 @@ typedef int (*orte_schema_get_std_subscription_name_fn_t)(char **name,
|
||||
char *subscription,
|
||||
orte_jobid_t jobid);
|
||||
|
||||
|
||||
/*
|
||||
* Ver 1.0.0
|
||||
*/
|
||||
struct orte_schema_base_module_1_0_0_t {
|
||||
orte_schema_get_proc_tokens_fn_t get_proc_tokens;
|
||||
orte_schema_get_node_tokens_fn_t get_node_tokens;
|
||||
orte_schema_get_job_tokens_fn_t get_job_tokens;
|
||||
orte_schema_get_cell_tokens_fn_t get_cell_tokens;
|
||||
orte_schema_get_job_segment_name_fn_t get_job_segment_name;
|
||||
orte_schema_extract_jobid_from_segment_name_fn_t extract_jobid_from_segment_name;
|
||||
orte_schema_get_std_trigger_name_fn_t get_std_trigger_name;
|
||||
orte_schema_check_std_trigger_name_fn_t check_std_trigger_name;
|
||||
orte_schema_extract_jobid_from_std_trigger_name_fn_t extract_jobid_from_std_trigger_name;
|
||||
orte_schema_get_std_subscription_name_fn_t get_std_subscription_name;
|
||||
orte_schema_get_proc_tokens_fn_t get_proc_tokens;
|
||||
orte_schema_get_node_tokens_fn_t get_node_tokens;
|
||||
orte_schema_get_job_tokens_fn_t get_job_tokens;
|
||||
orte_schema_get_cell_tokens_fn_t get_cell_tokens;
|
||||
orte_schema_get_job_segment_name_fn_t get_job_segment_name;
|
||||
orte_schema_extract_jobid_from_segment_name_fn_t extract_jobid_from_segment_name;
|
||||
orte_schema_get_std_trigger_name_fn_t get_std_trigger_name;
|
||||
orte_schema_check_std_trigger_name_fn_t check_std_trigger_name;
|
||||
orte_schema_extract_jobid_from_std_trigger_name_fn_t extract_jobid_from_std_trigger_name;
|
||||
orte_schema_get_std_subscription_name_fn_t get_std_subscription_name;
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,7 +157,8 @@
|
||||
* ORTED (ORTE DAEMON) TRIGGER DEFINITIONS
|
||||
*/
|
||||
#define ORTED_LAUNCH_STG_SUB "orted-launch-sub"
|
||||
|
||||
#define ORTED_LAUNCH_TRIGGER "orted-launch-trig"
|
||||
#define ORTED_LAUNCH_CNTR "orted-launch-cntr"
|
||||
|
||||
/*
|
||||
* BPROC-SPECIFIC SEGMENT FOR STORING CLUSTER-WIDE NODE STATES
|
||||
|
@ -24,6 +24,7 @@ libmca_sds_la_SOURCES =
|
||||
|
||||
# header setup
|
||||
nobase_orte_HEADERS =
|
||||
dist_pkgdata_DATA =
|
||||
|
||||
# local files
|
||||
headers = sds.h
|
||||
|
@ -16,6 +16,8 @@
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
dist_pkgdata_DATA += base/help-sds-base.txt
|
||||
|
||||
headers += \
|
||||
base/base.h
|
||||
|
||||
|
34
orte/mca/sds/base/help-sds-base.txt
Обычный файл
34
orte/mca/sds/base/help-sds-base.txt
Обычный файл
@ -0,0 +1,34 @@
|
||||
# -*- text -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
# This is the US/English general help file for the SDS base.
|
||||
#
|
||||
[sds-base:execv-error]
|
||||
The singleton application was not able to find the executable "orted" in
|
||||
your PATH or in the directory where Open MPI/OpenRTE was initially installed,
|
||||
and therefore cannot continue.
|
||||
|
||||
For reference, we tried the following command:
|
||||
|
||||
%s
|
||||
|
||||
and got the error %s.
|
||||
|
||||
This could mean that your PATH or executable name is wrong, or that you do not
|
||||
have the necessary permissions. Please ensure that the executable is able to be
|
||||
found and executed as it is required for singleton operations.
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "orte_config.h"
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
@ -24,21 +25,43 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "orte/orte_constants.h"
|
||||
#include "orte/mca/sds/base/base.h"
|
||||
#include "opal/util/path.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/installdirs/installdirs.h"
|
||||
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/runtime/runtime.h"
|
||||
#include "orte/mca/errmgr/base/base.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "orte/mca/ns/ns.h"
|
||||
#include "orte/mca/ns/base/base.h"
|
||||
#include "orte/mca/rml/rml.h"
|
||||
#include "orte/runtime/params.h"
|
||||
#include "orte/runtime/runtime.h"
|
||||
|
||||
#include "orte/mca/sds/base/base.h"
|
||||
|
||||
static int fork_hnp(void);
|
||||
|
||||
static void set_handler_default(int sig)
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
act.sa_handler = SIG_DFL;
|
||||
act.sa_flags = 0;
|
||||
sigemptyset(&act.sa_mask);
|
||||
|
||||
sigaction(sig, &act, (struct sigaction *)0);
|
||||
}
|
||||
|
||||
int
|
||||
orte_sds_base_basic_contact_universe(void)
|
||||
{
|
||||
int ret, rc, exit_if_not_exist;
|
||||
int rc=ORTE_SUCCESS, value;
|
||||
bool exit_if_not_exist;
|
||||
orte_universe_t univ;
|
||||
|
||||
OBJ_CONSTRUCT(&univ, orte_universe_t);
|
||||
@ -47,7 +70,7 @@ orte_sds_base_basic_contact_universe(void)
|
||||
* weren't told a universe contact point), check for some
|
||||
* existing universe to join */
|
||||
if (NULL == orte_process_info.ns_replica_uri || NULL == orte_process_info.gpr_replica_uri) {
|
||||
if (ORTE_SUCCESS == (ret = orte_universe_exists(&univ))) {
|
||||
if (ORTE_SUCCESS == (rc = orte_universe_exists(&univ))) {
|
||||
/* copy universe info into our universe structure */
|
||||
orte_universe_info.name = strdup(univ.name);
|
||||
orte_universe_info.host = strdup(univ.host);
|
||||
@ -70,51 +93,101 @@ orte_sds_base_basic_contact_universe(void)
|
||||
* relevant MCA parameter to see if the caller wants
|
||||
* us to abort in this situation
|
||||
*/
|
||||
if (0 > (rc = mca_base_param_register_int("orte", "univ", "exist", NULL, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = mca_base_param_lookup_int(rc, &exit_if_not_exist))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
mca_base_param_reg_int_name("orte", "univ_exist",
|
||||
"Exit if an existing universe cannot be detected or does not allow connection",
|
||||
false, false, (int)false, &value);
|
||||
exit_if_not_exist = OPAL_INT_TO_BOOL(value);
|
||||
|
||||
if (exit_if_not_exist) {
|
||||
/* cleanup the subsystems that were already opened */
|
||||
orte_system_finalize();
|
||||
return ORTE_ERR_UNREACH;
|
||||
/* tell orte_init to exit */
|
||||
rc = ORTE_ERR_UNREACH;
|
||||
goto CLEANUP;
|
||||
}
|
||||
if (ORTE_ERR_NOT_FOUND != ret) {
|
||||
|
||||
/* so the user didn't tell us to abort if it wasn't found - see
|
||||
* if the user specified a universe. if so, and we couldn't find
|
||||
* it, then we don't really want to continue
|
||||
*/
|
||||
if (ORTE_ERR_NOT_FOUND != rc) {
|
||||
/* user-specified name - abort */
|
||||
opal_output(0, "orte_init: could not contact the specified universe name %s",
|
||||
orte_universe_info.name);
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ORTE_ERR_UNREACH;
|
||||
goto CLEANUP;
|
||||
}
|
||||
orte_process_info.seed = true;
|
||||
/* since we are seed, ensure that all replica info is NULL'd */
|
||||
if (NULL != orte_process_info.ns_replica_uri) {
|
||||
free(orte_process_info.ns_replica_uri);
|
||||
orte_process_info.ns_replica_uri = NULL;
|
||||
}
|
||||
if (NULL != orte_process_info.ns_replica) {
|
||||
|
||||
/* so we could not find a universe to which we could connect, and we don't
|
||||
* want to just abort - let's see what we can do about starting one
|
||||
* of our very own! First, let's check if we are a singleton - if
|
||||
* we are infrastructure, then we are not a singleton and we will
|
||||
* simply declare ourselves to be an HNP to do the various good things
|
||||
*/
|
||||
if (orte_infrastructure) {
|
||||
orte_process_info.seed = true;
|
||||
/* since we are an HNP, ensure that all replica info is NULL'd */
|
||||
if (NULL != orte_process_info.ns_replica_uri) {
|
||||
free(orte_process_info.ns_replica_uri);
|
||||
orte_process_info.ns_replica_uri = NULL;
|
||||
}
|
||||
if (NULL != orte_process_info.ns_replica) {
|
||||
free(orte_process_info.ns_replica);
|
||||
orte_process_info.ns_replica = NULL;
|
||||
}
|
||||
|
||||
if (NULL != orte_process_info.gpr_replica_uri) {
|
||||
free(orte_process_info.gpr_replica_uri);
|
||||
orte_process_info.gpr_replica_uri = NULL;
|
||||
}
|
||||
if (NULL != orte_process_info.gpr_replica) {
|
||||
}
|
||||
|
||||
if (NULL != orte_process_info.gpr_replica_uri) {
|
||||
free(orte_process_info.gpr_replica_uri);
|
||||
orte_process_info.gpr_replica_uri = NULL;
|
||||
}
|
||||
if (NULL != orte_process_info.gpr_replica) {
|
||||
free(orte_process_info.gpr_replica);
|
||||
orte_process_info.gpr_replica = NULL;
|
||||
}
|
||||
rc = ORTE_SUCCESS;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
/* so we are not infrastructure, which means we *are* a singleton. In
|
||||
* this case, we need to start a daemon that can support our operation.
|
||||
* We must do this for two reasons:
|
||||
* (1) if we try to play the role of the HNP, then any child processes
|
||||
* we might start via comm_spawn will rely on us for all ORTE-level
|
||||
* support. However, we can only progress those requests when the
|
||||
* the application calls into the OMPI/ORTE library! Thus, if this
|
||||
* singleton just does computation, the other processes will "hang"
|
||||
* in any calls into the ORTE layer that communicate with the HNP -
|
||||
* and most calls on application procs *do*.
|
||||
*
|
||||
* (2) daemons are used to communicate messages for administrative
|
||||
* purposes in a broadcast-like manner. Thus, daemons are expected
|
||||
* to be able to interpret specific commands. Our application process
|
||||
* doesn't have any idea how to handle those commands, thus causing
|
||||
* the entire ORTE administrative system to break down.
|
||||
*
|
||||
* For those reasons, we choose to fork/exec a daemon at this time
|
||||
* and then reconnect ourselves to it. We could just "fork" and declare
|
||||
* the child to be a daemon, but that would require we place *all* of the
|
||||
* daemon command processing code in the ORTE library, do some strange
|
||||
* mojo in a few places, etc. This doesn't seem worth it, so we'll just
|
||||
* do the old fork/exec here
|
||||
*
|
||||
* Note that Windows-based systems have to do their own special trick as
|
||||
* they don't support fork/exec. So we have to use a giant "if" here to
|
||||
* protect the Windows world. To make the results more readable, we put
|
||||
* the whole mess in a separate function below
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc= fork_hnp())) {
|
||||
/* if this didn't work, then we cannot support operation any further.
|
||||
* Abort the system and tell orte_init to exit
|
||||
*/
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLEANUP:
|
||||
OBJ_DESTRUCT(&univ);
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -148,3 +221,188 @@ orte_sds_base_seed_set_name(void)
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int fork_hnp(void)
|
||||
{
|
||||
#if !defined(__WINDOWS__)
|
||||
int p[2], death_pipe[2];
|
||||
char *cmd;
|
||||
char **argv = NULL;
|
||||
int argc;
|
||||
char *param;
|
||||
sigset_t sigs;
|
||||
pid_t pid;
|
||||
char orted_uri[256];
|
||||
int rc;
|
||||
|
||||
/* A pipe is used to communicate between the parent and child to
|
||||
indicate whether the exec ultiimately succeeded or failed. The
|
||||
child sets the pipe to be close-on-exec; the child only ever
|
||||
writes anything to the pipe if there is an error (e.g.,
|
||||
executable not found, exec() fails, etc.). The parent does a
|
||||
blocking read on the pipe; if the pipe closed with no data,
|
||||
then the exec() succeeded. If the parent reads something from
|
||||
the pipe, then the child was letting us know that it failed.
|
||||
*/
|
||||
if (pipe(p) < 0) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
|
||||
return ORTE_ERR_SYS_LIMITS_PIPES;
|
||||
}
|
||||
|
||||
/* we also have to give the HNP a pipe it can watch to know when
|
||||
* we terminated. Since the HNP is going to be a child of us, it
|
||||
* can't just use waitpid to see when we leave - so it will watch
|
||||
* the pipe instead
|
||||
*/
|
||||
if (pipe(death_pipe) < 0) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_PIPES);
|
||||
return ORTE_ERR_SYS_LIMITS_PIPES;
|
||||
}
|
||||
|
||||
/* find the orted binary using the install_dirs support - this also
|
||||
* checks to ensure that we can see this executable and it *is* executable by us
|
||||
*/
|
||||
cmd = opal_path_access("orted", opal_install_dirs.bindir, X_OK);
|
||||
if (NULL == cmd) {
|
||||
/* guess we couldn't do it - best to abort */
|
||||
ORTE_ERROR_LOG(ORTE_ERR_FILE_NOT_EXECUTABLE);
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
return ORTE_ERR_FILE_NOT_EXECUTABLE;
|
||||
}
|
||||
|
||||
/* okay, setup an appropriate argv */
|
||||
opal_argv_append(&argc, &argv, "orted");
|
||||
|
||||
/* tell the daemon it is to be the seed */
|
||||
opal_argv_append(&argc, &argv, "--seed");
|
||||
|
||||
/* tell the daemon to get out of our process group */
|
||||
opal_argv_append(&argc, &argv, "--set-sid");
|
||||
|
||||
/* tell the daemon to not daemonize so we can see any output */
|
||||
opal_argv_append(&argc, &argv, "--no-daemonize");
|
||||
|
||||
/* tell the daemon to report back its uri so we can connect to it */
|
||||
opal_argv_append(&argc, &argv, "--report-uri");
|
||||
asprintf(¶m, "%d", p[1]);
|
||||
opal_argv_append(&argc, &argv, param);
|
||||
free(param);
|
||||
|
||||
/* give the daemon a pipe it can watch to tell when we have died */
|
||||
opal_argv_append(&argc, &argv, "--singleton-died-pipe");
|
||||
asprintf(¶m, "%d", death_pipe[0]);
|
||||
opal_argv_append(&argc, &argv, param);
|
||||
free(param);
|
||||
|
||||
/* add any debug flags */
|
||||
if (orte_debug_flag) {
|
||||
opal_argv_append(&argc, &argv, "--debug");
|
||||
}
|
||||
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_argv_append(&argc, &argv, "--debug-daemons");
|
||||
}
|
||||
|
||||
if (orte_debug_daemons_file_flag) {
|
||||
if (!orte_debug_daemons_flag) {
|
||||
opal_argv_append(&argc, &argv, "--debug-daemons");
|
||||
}
|
||||
opal_argv_append(&argc, &argv, "--debug-daemons-file");
|
||||
}
|
||||
|
||||
/* pass along the universe name so we match */
|
||||
opal_argv_append(&argc, &argv, "--universe");
|
||||
opal_argv_append(&argc, &argv, orte_universe_info.name);
|
||||
|
||||
/* Fork off the child */
|
||||
pid = fork();
|
||||
if(pid < 0) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_CHILDREN);
|
||||
close(p[0]);
|
||||
close(p[1]);
|
||||
close(death_pipe[0]);
|
||||
close(death_pipe[1]);
|
||||
free(cmd);
|
||||
return ORTE_ERR_SYS_LIMITS_CHILDREN;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
close(p[0]);
|
||||
close(death_pipe[1]);
|
||||
/* I am the child - exec me */
|
||||
|
||||
/* Set signal handlers back to the default. Do this close
|
||||
to the execve() because the event library may (and likely
|
||||
will) reset them. If we don't do this, the event
|
||||
library may have left some set that, at least on some
|
||||
OS's, don't get reset via fork() or exec(). Hence, the
|
||||
orted could be unkillable (for example). */
|
||||
set_handler_default(SIGTERM);
|
||||
set_handler_default(SIGINT);
|
||||
set_handler_default(SIGHUP);
|
||||
set_handler_default(SIGPIPE);
|
||||
set_handler_default(SIGCHLD);
|
||||
|
||||
/* Unblock all signals, for many of the same reasons that
|
||||
we set the default handlers, above. This is noticable
|
||||
on Linux where the event library blocks SIGTERM, but we
|
||||
don't want that blocked by the orted (or, more
|
||||
specifically, we don't want it to be blocked by the
|
||||
orted and then inherited by the ORTE processes that it
|
||||
forks, making them unkillable by SIGTERM). */
|
||||
sigprocmask(0, 0, &sigs);
|
||||
sigprocmask(SIG_UNBLOCK, &sigs, 0);
|
||||
|
||||
execv(cmd, argv);
|
||||
|
||||
/* if I get here, the execv failed! */
|
||||
opal_show_help("help-sds-base.txt", "sds-base:execv-error",
|
||||
true, cmd, strerror(errno));
|
||||
exit(1);
|
||||
|
||||
} else {
|
||||
/* I am the parent - wait to hear something back and
|
||||
* report results
|
||||
*/
|
||||
close(p[1]); /* parent closes the write - orted will write its contact info to it*/
|
||||
close(death_pipe[0]); /* parent closes the death_pipe's read */
|
||||
|
||||
while (1) {
|
||||
rc = read(p[0], orted_uri, 255);
|
||||
|
||||
if (rc <= 0) {
|
||||
/* we didn't get anything back - this is bad */
|
||||
ORTE_ERROR_LOG(ORTE_ERR_HNP_COULD_NOT_START);
|
||||
return ORTE_ERR_HNP_COULD_NOT_START;
|
||||
}
|
||||
/* we got something back - let's hope it was the uri.
|
||||
* Set the contact info into our RML - it will bark
|
||||
* if the returned info isn't a uri
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_rml.set_uri(orted_uri))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* okay, the HNP is now setup. We actually don't need to
|
||||
* restart ourselves as we haven't really done anything yet.
|
||||
* So set our name to be [0,1,0] since we know that's what
|
||||
* it should be, set the HNP info in our globals, and tell
|
||||
* orte_init that those things are done
|
||||
*/
|
||||
orte_universe_info.seed_uri = strdup(orted_uri);
|
||||
orte_process_info.ns_replica_uri = strdup(orted_uri);
|
||||
orte_process_info.gpr_replica_uri = strdup(orted_uri);
|
||||
/* indicate we are a singleton so orte_init knows what to do */
|
||||
orte_process_info.singleton = true;
|
||||
/* all done - report success */
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* someone will have to devise a Windows equivalent */
|
||||
#endif
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
@ -40,31 +40,20 @@ orte_sds_base_module_t orte_sds_singleton_module = {
|
||||
int
|
||||
orte_sds_singleton_set_name(void)
|
||||
{
|
||||
int rc, id, flag;
|
||||
orte_vpid_t vpid;
|
||||
int rc;
|
||||
|
||||
if (ORTE_SUCCESS != (rc = orte_ns.create_my_name())) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
vpid = ORTE_PROC_MY_NAME->vpid;
|
||||
|
||||
orte_process_info.num_procs = 1;
|
||||
orte_process_info.vpid_start = vpid;
|
||||
orte_process_info.vpid_start = ORTE_PROC_MY_NAME->vpid;
|
||||
/* since we are a singleton, then we must have a local_rank of 0
|
||||
* and only 1 local process
|
||||
*/
|
||||
orte_process_info.local_rank = 0;
|
||||
orte_process_info.num_local_procs = 1;
|
||||
|
||||
/* only set the singleton flag is we are NOT infrastructure,
|
||||
and it has not been previously set. */
|
||||
id = mca_base_param_find("orte", NULL, "infrastructure");
|
||||
mca_base_param_lookup_int(id, &flag);
|
||||
if (!flag) {
|
||||
orte_process_info.singleton = true;
|
||||
}
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ orte_smr_base_module_t orte_smr = {
|
||||
orte_smr_base_set_job_state,
|
||||
orte_smr_base_begin_monitoring_not_available,
|
||||
orte_smr_base_init_job_stage_gates,
|
||||
orte_smr_base_init_orted_stage_gates,
|
||||
orte_smr_base_define_alert_monitor,
|
||||
orte_smr_base_job_stage_gate_subscribe,
|
||||
orte_smr_base_module_finalize_not_available
|
||||
|
@ -188,192 +188,6 @@ int orte_smr_base_init_job_stage_gates(orte_jobid_t job,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup orted-specific stage gates
|
||||
* setup the orted trigger to fire when the specified number of orteds have been launched
|
||||
*/
|
||||
int orte_smr_base_init_orted_stage_gates(orte_jobid_t job,
|
||||
orte_std_cntr_t num_orteds,
|
||||
orte_gpr_trigger_cb_fn_t cbfunc,
|
||||
void *user_tag)
|
||||
{
|
||||
char *segment=NULL;
|
||||
char *trig_name=NULL;
|
||||
orte_gpr_value_t *value=NULL;
|
||||
orte_std_cntr_t zero=0;
|
||||
orte_std_cntr_t i, num_counters, num_named_trigs, num_start_routing;
|
||||
char *trig_tokens[] = {
|
||||
ORTE_JOB_GLOBALS,
|
||||
NULL
|
||||
};
|
||||
char *to_launch_keys[] = {
|
||||
ORTE_JOB_SLOTS_KEY,
|
||||
NULL
|
||||
};
|
||||
char* keys[] = {
|
||||
/* changes to this ordering need to be reflected in code below */
|
||||
/* We need to set up counters for defined ORTED process states, even though
|
||||
* a given launch system may not actually use them all. This must be done so that
|
||||
* callbacks can be generated - otherwise, they won't happen!
|
||||
*/
|
||||
ORTE_PROC_NUM_AT_INIT,
|
||||
ORTE_PROC_NUM_LAUNCHED,
|
||||
ORTE_PROC_NUM_FINALIZED,
|
||||
ORTE_PROC_NUM_TERMINATED,
|
||||
/* the following stage gates need data routed through them */
|
||||
ORTE_PROC_NUM_AT_ORTE_STARTUP,
|
||||
ORTE_PROC_NUM_RUNNING
|
||||
};
|
||||
char* trig_names[] = {
|
||||
/* this ordering needs to be identical to that in the array above! */
|
||||
ORTE_ALL_INIT_TRIGGER,
|
||||
ORTE_ALL_LAUNCHED_TRIGGER,
|
||||
ORTE_ALL_FINALIZED_TRIGGER,
|
||||
ORTE_ALL_TERMINATED_TRIGGER,
|
||||
/* the following triggers need data routed through them */
|
||||
ORTE_STARTUP_TRIGGER,
|
||||
ORTE_ALL_RUNNING_TRIGGER
|
||||
};
|
||||
char *trig_keys[] = {
|
||||
ORTE_JOB_SLOTS_KEY,
|
||||
NULL, /* placeholder */
|
||||
NULL
|
||||
};
|
||||
int rc;
|
||||
orte_gpr_trigger_id_t id;
|
||||
orte_gpr_trigger_action_t trig_mode, trig_mode_routed;
|
||||
orte_data_value_t dval = ORTE_DATA_VALUE_EMPTY;
|
||||
|
||||
num_counters = sizeof(keys)/sizeof(keys[0]);
|
||||
num_named_trigs= sizeof(trig_names)/sizeof(trig_names[0]);
|
||||
/* the index where the triggers that need data routed through them begin */
|
||||
num_start_routing = 4;
|
||||
|
||||
/* increment the total number of orteds in the system. This MUST be done first
|
||||
* or else the triggers will all immediately fire! Since there may be a pre-existing value here, we
|
||||
* will use the arith function and do an ADD - this will either (a) add to a pre-existing value, or
|
||||
* (b) initialize a location to the provided value
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.set(&dval, (void*)&num_orteds, ORTE_STD_CNTR))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.arith(ORTE_GPR_TOKENS_AND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", trig_tokens, to_launch_keys,
|
||||
ORTE_DSS_ADD, &dval))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
/* reset the data value so it can be reused */
|
||||
dval.type = ORTE_UNDEF;
|
||||
dval.data = NULL;
|
||||
|
||||
/* setup the counters - set initial values to 0. All reside on the "orte-job-0" segment. Since
|
||||
* the counters may pre-exist, we want to ensure we do NOT disturb their current value.
|
||||
* So, we just indicate that we do NOT want to overwrite them by not setting the
|
||||
* ORTE_GPR_OVERWRITE flag, and do NOT want duplicate entries on the registry by setting
|
||||
* the ORTE_GPR_NO_DUPLICATE flag. Thus, we will ONLY write the counters on the registry
|
||||
* if they do not previously exist.
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_value(&value,
|
||||
ORTE_GPR_NO_DUPLICATE | ORTE_GPR_TOKENS_XAND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", num_counters, 1))) {
|
||||
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
value->tokens[0] = strdup(ORTE_JOB_GLOBALS); /* put counters in the job's globals container */
|
||||
|
||||
/** initialize the counters to zero */
|
||||
for (i=0; i < num_counters; i++) {
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.create_keyval(&(value->keyvals[i]), keys[i], ORTE_STD_CNTR, &zero))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* store them on the registry */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.put(1, &value))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* record which job we are trying to launch so we can retrieve it later - this cannot
|
||||
* be included in the prior put as we must overwrite any pre-existing info
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_dss.set(&dval, (void*)&job, ORTE_JOBID))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.put_1(ORTE_GPR_OVERWRITE | ORTE_GPR_TOKENS_XAND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", trig_tokens, ORTE_JOB_BEING_LAUNCHED_KEY,
|
||||
&dval))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* now define the standard orted triggers. If these triggers already
|
||||
* exist, the registry will overwrite them with the new information.
|
||||
* The standard triggers will return the trigger counters so that we
|
||||
* can get required information for notifying processes. Other
|
||||
* subscriptions will then attach to them.
|
||||
*
|
||||
* NOTE: if a seed or a virtual machine is being setup, then the
|
||||
* jobid=0.
|
||||
*/
|
||||
trig_mode = ORTE_GPR_TRIG_INCLUDE_TRIG_CNTRS | ORTE_GPR_TRIG_ONE_SHOT |
|
||||
ORTE_GPR_TRIG_CMP_LEVELS;
|
||||
trig_mode_routed = trig_mode | ORTE_GPR_TRIG_ROUTE_DATA_THRU_ME;
|
||||
|
||||
for (i=0; i < num_named_trigs; i++) {
|
||||
trig_keys[1] = strdup(keys[i]);
|
||||
if (ORTE_SUCCESS != (rc = orte_schema.get_std_trigger_name(&trig_name,
|
||||
trig_names[i], 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (i < num_start_routing) {
|
||||
/* the first set of triggers do NOT have anything routed to them.
|
||||
* They are setup here strictly for users to attach to them.
|
||||
* Hence, we do not pass a trigger callback function and
|
||||
* set the trig actions to "not route data through me"
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.define_trigger(&id, trig_name, trig_mode,
|
||||
ORTE_GPR_TOKENS_XAND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", trig_tokens, 2, trig_keys,
|
||||
cbfunc, user_tag))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
/* these triggers do need data routed through them, so use
|
||||
* the appropriate trigger mode
|
||||
*/
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.define_trigger(&id, trig_name, trig_mode_routed,
|
||||
ORTE_GPR_TOKENS_XAND | ORTE_GPR_KEYS_OR,
|
||||
"orte-job-0", trig_tokens, 2, trig_keys,
|
||||
cbfunc, user_tag))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
free(trig_name);
|
||||
trig_name = NULL;
|
||||
free(trig_keys[1]);
|
||||
trig_keys[1] = NULL;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (NULL != segment) free(segment);
|
||||
if (NULL != trig_name) free(trig_name);
|
||||
if (NULL != value) OBJ_RELEASE(value);
|
||||
if (NULL != trig_keys[1]) free(trig_keys[1]);
|
||||
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup an alert monitor
|
||||
*/
|
||||
|
@ -80,11 +80,6 @@ int orte_smr_base_init_job_stage_gates(orte_jobid_t job,
|
||||
orte_gpr_trigger_cb_fn_t cbfunc,
|
||||
void *user_tag);
|
||||
|
||||
int orte_smr_base_init_orted_stage_gates(orte_jobid_t job,
|
||||
orte_std_cntr_t num_orteds,
|
||||
orte_gpr_trigger_cb_fn_t cbfunc,
|
||||
void *user_tag);
|
||||
|
||||
int orte_smr_base_define_alert_monitor(orte_jobid_t job,
|
||||
char *trigger_name,
|
||||
char *counter_key,
|
||||
|
@ -72,7 +72,6 @@ orte_smr_base_module_t orte_smr_bproc_module = {
|
||||
orte_smr_base_set_job_state,
|
||||
orte_smr_bproc_begin_monitoring,
|
||||
orte_smr_base_init_job_stage_gates,
|
||||
orte_smr_base_init_orted_stage_gates,
|
||||
orte_smr_base_define_alert_monitor,
|
||||
orte_smr_base_job_stage_gate_subscribe,
|
||||
orte_smr_bproc_finalize
|
||||
|
@ -94,15 +94,6 @@ typedef int (*orte_smr_base_module_job_stage_gate_init_fn_t)(orte_jobid_t job,
|
||||
orte_gpr_trigger_cb_fn_t cbfunc,
|
||||
void *user_tag);
|
||||
|
||||
/*
|
||||
* Define the orted standard stage gates
|
||||
* This function creates all of the orted-standard stage gates.
|
||||
*/
|
||||
typedef int (*orte_smr_base_module_orted_stage_gate_init_fn_t)(orte_jobid_t job,
|
||||
orte_std_cntr_t num_orteds,
|
||||
orte_gpr_trigger_cb_fn_t cbfunc,
|
||||
void *user_tag);
|
||||
|
||||
/*
|
||||
* Define an "alert" monitor
|
||||
* This function will establish an appropriate trigger to notify the specified
|
||||
@ -185,7 +176,6 @@ struct orte_smr_base_module_1_3_0_t {
|
||||
orte_smr_base_module_begin_monitoring_fn_t begin_monitoring;
|
||||
/* TRIGGER INIT FUNCTIONS */
|
||||
orte_smr_base_module_job_stage_gate_init_fn_t init_job_stage_gates;
|
||||
orte_smr_base_module_orted_stage_gate_init_fn_t init_orted_stage_gates;
|
||||
orte_smr_base_module_define_alert_monitor_fn_t define_alert_monitor;
|
||||
orte_smr_base_module_job_stage_gate_subscribe_fn_t job_stage_gate_subscribe;
|
||||
orte_smr_base_module_finalize_fn_t finalize;
|
||||
|
29
orte/orted/Makefile.am
Обычный файл
29
orte/orted/Makefile.am
Обычный файл
@ -0,0 +1,29 @@
|
||||
# -*- makefile -*-
|
||||
#
|
||||
# Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# This makefile.am does not stand on its own - it is included from orte/Makefile.am
|
||||
|
||||
dist_pkgdata_DATA += orted/help-orted.txt
|
||||
|
||||
headers += \
|
||||
orted/orted.h
|
||||
|
||||
libopen_rte_la_SOURCES += \
|
||||
orted/orted_main.c
|
||||
|
@ -20,37 +20,24 @@
|
||||
#define ORTED_H
|
||||
|
||||
#include "orte_config.h"
|
||||
#include "orte/orte_types.h"
|
||||
|
||||
#include "opal/threads/mutex.h"
|
||||
#include "opal/threads/condition.h"
|
||||
#
|
||||
#include "orte/dss/dss_types.h"
|
||||
#include "orte/mca/ns/ns_types.h"
|
||||
#include "orte/mca/rml/rml_types.h"
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
bool help;
|
||||
bool no_daemonize;
|
||||
bool debug;
|
||||
bool debug_daemons;
|
||||
bool debug_daemons_file;
|
||||
bool set_sid;
|
||||
char* ns_nds;
|
||||
char* name;
|
||||
char* vpid_start;
|
||||
char* num_procs;
|
||||
char* universe;
|
||||
char **saved_environ;
|
||||
int uri_pipe;
|
||||
opal_mutex_t mutex;
|
||||
opal_condition_t condition;
|
||||
bool exit_condition;
|
||||
bool spin;
|
||||
} orted_globals_t;
|
||||
|
||||
ORTE_DECLSPEC extern orted_globals_t orted_globals;
|
||||
/* main orted routine */
|
||||
int orte_daemon(int argc, char *argv[]);
|
||||
|
||||
/* setup routine - needed to instantiate the orted globals in libopenrte. To
|
||||
* make it at least be useful, will also start the necessary communication
|
||||
* receive calls for daemon comm
|
||||
*/
|
||||
int orte_daemon_setup(void);
|
||||
|
||||
/* orted communication functions */
|
||||
void orte_daemon_recv(int status, orte_process_name_t* sender,
|
||||
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
||||
@ -64,7 +51,7 @@ void orte_daemon_recv_gate(int status, orte_process_name_t* sender,
|
||||
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
||||
void* cbdata);
|
||||
|
||||
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
@ -9,6 +9,9 @@
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco, Inc. All rights reserved.
|
||||
* Copyright (c) 2007 Los Alamos National Security, LLC. All rights
|
||||
* reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -17,7 +20,6 @@
|
||||
*/
|
||||
|
||||
#include "orte_config.h"
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@ -34,31 +36,62 @@
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#include "opal/event/event.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/threads/mutex.h"
|
||||
#include "opal/threads/condition.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/bit_ops.h"
|
||||
#include "opal/util/cmd_line.h"
|
||||
#include "opal/util/daemon_init.h"
|
||||
#include "opal/util/opal_environ.h"
|
||||
#include "opal/util/os_path.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/printf.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/util/trace.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
|
||||
|
||||
#include "orte/dss/dss.h"
|
||||
#include "orte/class/orte_value_array.h"
|
||||
#include "orte/util/sys_info.h"
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/util/univ_info.h"
|
||||
#include "orte/util/session_dir.h"
|
||||
#include "orte/util/universe_setup_file_io.h"
|
||||
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/ns/ns.h"
|
||||
#include "orte/mca/ras/ras.h"
|
||||
#include "orte/mca/rds/rds.h"
|
||||
#include "orte/mca/rmaps/rmaps.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/rml/rml.h"
|
||||
#include "orte/mca/odls/odls.h"
|
||||
#include "orte/mca/smr/smr.h"
|
||||
#include "orte/mca/rmgr/rmgr.h"
|
||||
#include "orte/mca/rmgr/base/rmgr_private.h"
|
||||
#include "orte/mca/odls/odls.h"
|
||||
#include "orte/mca/pls/pls.h"
|
||||
|
||||
|
||||
#include "orte/runtime/runtime.h"
|
||||
#include "orte/runtime/params.h"
|
||||
|
||||
#include "orte/tools/orted/orted.h"
|
||||
#include "orte/orted/orted.h"
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
|
||||
static struct opal_event term_handler;
|
||||
static struct opal_event int_handler;
|
||||
static struct opal_event pipe_handler;
|
||||
|
||||
static void shutdown_callback(int fd, short flags, void *arg);
|
||||
static int binomial_route_msg(orte_process_name_t *sender,
|
||||
orte_buffer_t *buf,
|
||||
orte_rml_tag_t tag);
|
||||
@ -67,6 +100,491 @@ static int process_commands(orte_process_name_t* sender,
|
||||
orte_buffer_t *buffer,
|
||||
orte_rml_tag_t tag);
|
||||
|
||||
|
||||
static struct {
|
||||
bool help;
|
||||
bool set_sid;
|
||||
char* ns_nds;
|
||||
char* name;
|
||||
char* vpid_start;
|
||||
char* num_procs;
|
||||
char* universe;
|
||||
char **saved_environ;
|
||||
int uri_pipe;
|
||||
opal_mutex_t mutex;
|
||||
opal_condition_t condition;
|
||||
bool exit_condition;
|
||||
int singleton_died_pipe;
|
||||
} orted_globals;
|
||||
|
||||
/*
|
||||
* define the orted context table for obtaining parameters
|
||||
*/
|
||||
opal_cmd_line_init_t orte_cmd_line_opts[] = {
|
||||
/* Various "obvious" options */
|
||||
{ NULL, NULL, NULL, 'h', NULL, "help", 0,
|
||||
&orted_globals.help, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"This help message" },
|
||||
|
||||
{ "orted", "spin", NULL, 'd', NULL, "spin", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Have the orted spin until we can connect a debugger to it" },
|
||||
|
||||
{ "orte", "debug", NULL, 'd', NULL, "debug", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Debug the OpenRTE" },
|
||||
|
||||
{ "orte", "no_daemonize", NULL, '\0', NULL, "no-daemonize", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Don't daemonize into the background" },
|
||||
|
||||
{ "orte", "debug", "daemons", '\0', NULL, "debug-daemons", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Enable debugging of OpenRTE daemons" },
|
||||
|
||||
{ "orte", "debug", "daemons_file", '\0', NULL, "debug-daemons-file", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Enable debugging of OpenRTE daemons, storing output in files" },
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "set-sid", 0,
|
||||
&orted_globals.set_sid, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Direct the orted to separate from the current session"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "name", 1,
|
||||
&orted_globals.name, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the orte process name"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "vpid_start", 1,
|
||||
&orted_globals.vpid_start, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the starting vpid for this job"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "num_procs", 1,
|
||||
&orted_globals.num_procs, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the number of process in this job"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "ns-nds", 1,
|
||||
&orted_globals.ns_nds, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"set sds/nds component to use for daemon (normally not needed)"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "nsreplica", 1,
|
||||
&orte_process_info.ns_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Name service contact information."},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "gprreplica", 1,
|
||||
&orte_process_info.gpr_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Registry contact information."},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "nodename", 1,
|
||||
&orte_system_info.nodename, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Node name as specified by host/resource description." },
|
||||
|
||||
{ "universe", NULL, NULL, '\0', NULL, "universe", 1,
|
||||
&orted_globals.universe, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the universe name as username@hostname:universe_name for this application" },
|
||||
|
||||
{ "tmpdir", "base", NULL, '\0', NULL, "tmpdir", 1,
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the root for the session directory tree" },
|
||||
|
||||
{ "seed", NULL, NULL, '\0', NULL, "seed", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Host replicas for the core universe services"},
|
||||
|
||||
{ "universe", "persistence", NULL, '\0', NULL, "persistent", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Remain alive after the application process completes"},
|
||||
|
||||
{ "universe", "scope", NULL, '\0', NULL, "scope", 1,
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set restrictions on who can connect to this universe"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "report-uri", 1,
|
||||
&orted_globals.uri_pipe, OPAL_CMD_LINE_TYPE_INT,
|
||||
"Report this process' uri on indicated pipe"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "singleton-died-pipe", 1,
|
||||
&orted_globals.singleton_died_pipe, OPAL_CMD_LINE_TYPE_INT,
|
||||
"Watch on indicated pipe for singleton termination"},
|
||||
|
||||
/* End of list */
|
||||
{ NULL, NULL, NULL, '\0', NULL, NULL, 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_NULL, NULL }
|
||||
};
|
||||
|
||||
int orte_daemon(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int fd;
|
||||
opal_cmd_line_t *cmd_line = NULL;
|
||||
char *log_path = NULL;
|
||||
char log_file[PATH_MAX];
|
||||
char *jobidstring;
|
||||
int i;
|
||||
orte_buffer_t *buffer;
|
||||
int zero = 0;
|
||||
|
||||
/* initialize the globals */
|
||||
memset(&orted_globals, 0, sizeof(orted_globals));
|
||||
/* initialize the singleton died pipe to an illegal value so we can detect it was set */
|
||||
orted_globals.singleton_died_pipe = -1;
|
||||
|
||||
/* Ensure that enough of OPAL is setup for us to be able to run */
|
||||
if (OPAL_SUCCESS != opal_init_util()) {
|
||||
fprintf(stderr, "OPAL failed to initialize -- orted aborting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* save the environment for use when launching application processes */
|
||||
orted_globals.saved_environ = opal_argv_copy(environ);
|
||||
|
||||
/* setup to check common command line options that just report and die */
|
||||
cmd_line = OBJ_NEW(opal_cmd_line_t);
|
||||
opal_cmd_line_create(cmd_line, orte_cmd_line_opts);
|
||||
mca_base_cmd_line_setup(cmd_line);
|
||||
if (ORTE_SUCCESS != (ret = opal_cmd_line_parse(cmd_line, false,
|
||||
argc, argv))) {
|
||||
char *args = NULL;
|
||||
args = opal_cmd_line_get_usage_msg(cmd_line);
|
||||
opal_show_help("help-orted.txt", "orted:usage", false,
|
||||
argv[0], args);
|
||||
free(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since this process can now handle MCA/GMCA parameters, make sure to
|
||||
* process them.
|
||||
*/
|
||||
mca_base_cmd_line_process_args(cmd_line, &environ, &environ);
|
||||
|
||||
|
||||
/* register and process the orte params */
|
||||
if (ORTE_SUCCESS != (ret = orte_register_params(ORTE_INFRASTRUCTURE))) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* check for help request */
|
||||
if (orted_globals.help) {
|
||||
char *args = NULL;
|
||||
args = opal_cmd_line_get_usage_msg(cmd_line);
|
||||
opal_show_help("help-orted.txt", "orted:usage", false,
|
||||
argv[0], args);
|
||||
free(args);
|
||||
return 1;
|
||||
}
|
||||
#if !defined(__WINDOWS__)
|
||||
/* see if we were directed to separate from current session */
|
||||
if (orted_globals.set_sid) {
|
||||
setsid();
|
||||
}
|
||||
#endif /* !defined(__WINDOWS__) */
|
||||
/* see if they want us to spin until they can connect a debugger to us */
|
||||
i=0;
|
||||
/*orted_globals.spin = 1;*/
|
||||
while (orted_spin_flag) {
|
||||
i++;
|
||||
if (1000 < i) i=0;
|
||||
}
|
||||
|
||||
/* Okay, now on to serious business! */
|
||||
|
||||
/* Ensure the process info structure is instantiated and initialized
|
||||
* and set the daemon flag to true
|
||||
*/
|
||||
orte_process_info.daemon = true;
|
||||
|
||||
/*
|
||||
* If the daemon was given a name on the command line, need to set the
|
||||
* proper indicators in the environment so the name discovery service
|
||||
* can find it
|
||||
*/
|
||||
if (orted_globals.name) {
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
||||
"env", true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds", "env", ret);
|
||||
return ret;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_name",
|
||||
orted_globals.name, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_name", orted_globals.name, ret);
|
||||
return ret;
|
||||
}
|
||||
/* the following values are meaningless to the daemon, but may have
|
||||
* been passed in anyway. we set them here because the nds_env component
|
||||
* requires that they be set
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_vpid_start",
|
||||
orted_globals.vpid_start, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_vpid_start", orted_globals.vpid_start, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_num_procs",
|
||||
orted_globals.num_procs, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_num_procs", orted_globals.num_procs, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (orted_globals.ns_nds) {
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
||||
orted_globals.ns_nds, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds", "env", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* detach from controlling terminal
|
||||
* otherwise, remain attached so output can get to us
|
||||
*/
|
||||
if(orte_debug_flag == false &&
|
||||
orte_debug_daemons_flag == false &&
|
||||
orte_no_daemonize_flag == false) {
|
||||
opal_daemon_init(NULL);
|
||||
}
|
||||
|
||||
/* Intialize OPAL */
|
||||
if (ORTE_SUCCESS != (ret = opal_init())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the flag telling OpenRTE that I am NOT a
|
||||
* singleton, but am "infrastructure" - prevents setting
|
||||
* up incorrect infrastructure that only a singleton would
|
||||
* require.
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_init_stage1(ORTE_INFRASTRUCTURE))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* setup our receive functions - this will allow us to relay messages
|
||||
* during start for better scalability
|
||||
*/
|
||||
/* register the daemon main receive functions */
|
||||
/* setup to listen for broadcast commands via routed messaging algorithms */
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_ORTED_ROUTED,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_routed, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
/* setup to listen for commands sent specifically to me */
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_DAEMON, ORTE_RML_NON_PERSISTENT, orte_daemon_recv, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if we are not a seed, prep a return buffer to say we started okay */
|
||||
if (!orte_process_info.seed) {
|
||||
buffer = OBJ_NEW(orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (ret = orte_dss.pack(buffer, &zero, 1, ORTE_INT))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_dss.pack(buffer, ORTE_PROC_MY_NAME, 1, ORTE_NAME))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Begin recording registry actions */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.begin_compound_cmd(buffer))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* tell orte_init that we don't want any subscriptions registered by passing
|
||||
* a NULL trigger name
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_init_stage2(NULL))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if we aren't a seed, then we need to stop the compound_cmd mode here so
|
||||
* that other subsystems can use it
|
||||
*/
|
||||
if (!orte_process_info.seed) {
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.stop_compound_cmd())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set signal handlers to catch kill signals so we can properly clean up
|
||||
* after ourselves.
|
||||
*/
|
||||
opal_event_set(&term_handler, SIGTERM, OPAL_EV_SIGNAL,
|
||||
shutdown_callback, NULL);
|
||||
opal_event_add(&term_handler, NULL);
|
||||
opal_event_set(&int_handler, SIGINT, OPAL_EV_SIGNAL,
|
||||
shutdown_callback, NULL);
|
||||
opal_event_add(&int_handler, NULL);
|
||||
|
||||
/* if requested, report my uri to the indicated pipe */
|
||||
if (orted_globals.uri_pipe > 0) {
|
||||
write(orted_globals.uri_pipe, orte_universe_info.seed_uri,
|
||||
strlen(orte_universe_info.seed_uri)+1); /* need to add 1 to get the NULL */
|
||||
close(orted_globals.uri_pipe);
|
||||
}
|
||||
|
||||
/* setup stdout/stderr */
|
||||
if (orte_debug_daemons_file_flag) {
|
||||
/* if we are debugging to a file, then send stdout/stderr to
|
||||
* the orted log file
|
||||
*/
|
||||
|
||||
/* get my jobid */
|
||||
if (ORTE_SUCCESS != (ret = orte_ns.get_jobid_string(&jobidstring,
|
||||
orte_process_info.my_name))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* define a log file name in the session directory */
|
||||
sprintf(log_file, "output-orted-%s-%s.log",
|
||||
jobidstring, orte_system_info.nodename);
|
||||
log_path = opal_os_path(false,
|
||||
orte_process_info.tmpdir_base,
|
||||
orte_process_info.top_session_dir,
|
||||
log_file,
|
||||
NULL);
|
||||
|
||||
fd = open(log_path, O_RDWR|O_CREAT|O_TRUNC, 0640);
|
||||
if (fd < 0) {
|
||||
/* couldn't open the file for some reason, so
|
||||
* just connect everything to /dev/null
|
||||
*/
|
||||
fd = open("/dev/null", O_RDWR|O_CREAT|O_TRUNC, 0666);
|
||||
} else {
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if(fd != STDOUT_FILENO && fd != STDERR_FILENO) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* output a message indicating we are alive, our name, and our pid
|
||||
* for debugging purposes
|
||||
*/
|
||||
if (orte_debug_daemons_flag) {
|
||||
fprintf(stderr, "Daemon [%ld,%ld,%ld] checking in as pid %ld on host %s\n",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name), (long)orte_process_info.pid,
|
||||
orte_system_info.nodename);
|
||||
}
|
||||
|
||||
/* setup the thread lock and condition variables */
|
||||
OBJ_CONSTRUCT(&orted_globals.mutex, opal_mutex_t);
|
||||
OBJ_CONSTRUCT(&orted_globals.condition, opal_condition_t);
|
||||
|
||||
/* a daemon should *always* yield the processor when idle */
|
||||
opal_progress_set_yield_when_idle(true);
|
||||
|
||||
/* setup to listen for xcast stage gate commands. We need to do this because updates to the
|
||||
* contact info for dynamically spawned daemons will come to the gate RML-tag
|
||||
*/
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_XCAST_BARRIER,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_gate, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* if requested, report my uri to the indicated pipe */
|
||||
if (orted_globals.uri_pipe > 0) {
|
||||
write(orted_globals.uri_pipe, orte_universe_info.seed_uri,
|
||||
strlen(orte_universe_info.seed_uri)+1); /* need to add 1 to get the NULL */
|
||||
}
|
||||
|
||||
/* if we were given a pipe to monitor for singleton termination, set that up */
|
||||
if (orted_globals.singleton_died_pipe > 0) {
|
||||
/* register shutdown handler */
|
||||
opal_event_set(&pipe_handler,
|
||||
orted_globals.singleton_died_pipe,
|
||||
OPAL_EV_READ|OPAL_EV_PERSIST,
|
||||
shutdown_callback,
|
||||
&orted_globals.singleton_died_pipe);
|
||||
opal_event_add(&pipe_handler, NULL);
|
||||
}
|
||||
|
||||
/* setup and enter the event monitor */
|
||||
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
||||
|
||||
/* if we are not a seed... */
|
||||
if (!orte_process_info.seed) {
|
||||
/* send the information to the orted report-back point - this function
|
||||
* will kindly hand the gpr compound cmds contained in the buffer
|
||||
* over to the gpr for processing, but also counts the number of
|
||||
* orteds that reported back so the launch procedure can continue.
|
||||
* We need to do this at the last possible second as the HNP
|
||||
* can turn right around and begin issuing orders to us
|
||||
*/
|
||||
if (0 > (ret = orte_rml.send_buffer(ORTE_PROC_MY_HNP, buffer,
|
||||
ORTE_RML_TAG_ORTED_CALLBACK, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
OBJ_RELEASE(buffer); /* done with this */
|
||||
}
|
||||
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: up and running - waiting for commands!", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
while (false == orted_globals.exit_condition) {
|
||||
opal_condition_wait(&orted_globals.condition, &orted_globals.mutex);
|
||||
}
|
||||
|
||||
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
||||
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: mutex cleared - finalizing", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
if (NULL != log_path) {
|
||||
unlink(log_path);
|
||||
}
|
||||
|
||||
/* make sure our local procs are dead - but don't update their state
|
||||
* on the HNP as this may be redundant
|
||||
*/
|
||||
orte_odls.kill_local_procs(ORTE_JOBID_WILDCARD, false);
|
||||
|
||||
/* cleanup any lingering session directories */
|
||||
orte_session_dir_cleanup(ORTE_JOBID_WILDCARD);
|
||||
|
||||
/* Finalize and clean up ourselves */
|
||||
if (ORTE_SUCCESS != (ret = orte_finalize())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
}
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void shutdown_callback(int fd, short flags, void *arg)
|
||||
{
|
||||
OPAL_TRACE(1);
|
||||
if (NULL != arg) {
|
||||
/* it's the pipe... remove that handler */
|
||||
opal_event_del(&pipe_handler);
|
||||
}
|
||||
orted_globals.exit_condition = true;
|
||||
opal_condition_signal(&orted_globals.condition);
|
||||
}
|
||||
|
||||
void orte_daemon_recv_routed(int status, orte_process_name_t* sender,
|
||||
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
||||
void* cbdata)
|
||||
@ -79,7 +597,7 @@ void orte_daemon_recv_routed(int status, orte_process_name_t* sender,
|
||||
|
||||
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_recv_routed: received message from [%ld,%ld,%ld]",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name),
|
||||
ORTE_NAME_ARGS(sender));
|
||||
@ -126,7 +644,7 @@ void orte_daemon_recv(int status, orte_process_name_t* sender,
|
||||
|
||||
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_recv_cmd: received message from [%ld,%ld,%ld]",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name),
|
||||
ORTE_NAME_ARGS(sender));
|
||||
@ -229,7 +747,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
}
|
||||
|
||||
for (n=0; n < num_jobs; n++) {
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received kill_local_procs for job %ld",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name), (long)jobs[n]);
|
||||
}
|
||||
@ -243,7 +761,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
|
||||
/**** SIGNAL_LOCAL_PROCS ****/
|
||||
case ORTE_DAEMON_SIGNAL_LOCAL_PROCS:
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received signal_local_procs",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -278,7 +796,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
|
||||
/**** ADD_LOCAL_PROCS ****/
|
||||
case ORTE_DAEMON_ADD_LOCAL_PROCS:
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received add_local_procs",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -300,7 +818,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
|
||||
/**** DELIVER A MESSAGE TO THE LOCAL PROCS ****/
|
||||
case ORTE_DAEMON_MESSAGE_LOCAL_PROCS:
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received message_local_procs",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -403,7 +921,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
* exit if all our children are dead. For now, treat
|
||||
* the same as an exit_vm "hard kill" command
|
||||
*/
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received exit",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -419,7 +937,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
|
||||
/**** HALT VM COMMAND ****/
|
||||
case ORTE_DAEMON_HALT_VM_CMD:
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received halt vm",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -443,7 +961,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
|
||||
/**** CONTACT QUERY COMMAND ****/
|
||||
case ORTE_DAEMON_CONTACT_QUERY_CMD:
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_cmd: received contact query",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -492,7 +1010,7 @@ static int process_commands(orte_process_name_t* sender,
|
||||
/**** WARMUP CONNECTION TO LOCAL PROC ****/
|
||||
case ORTE_DAEMON_WARMUP_LOCAL_CONN:
|
||||
/* nothing to do here - just ignore it */
|
||||
if (orted_globals.debug_daemons) {
|
||||
if (orte_debug_daemons_flag) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted_recv: received connection from local proc",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
@ -579,7 +1097,6 @@ static int binomial_route_msg(orte_process_name_t *sender,
|
||||
peer = rank | mask;
|
||||
if (peer < size) {
|
||||
target.vpid = (orte_vpid_t)peer;
|
||||
opal_output(0, "[%ld,%ld,%ld] relaying to [%ld,%ld,%ld]", ORTE_NAME_ARGS(ORTE_PROC_MY_NAME), ORTE_NAME_ARGS(&target));
|
||||
if (0 > (ret = orte_rml.send_buffer(&target, relay, ORTE_RML_TAG_ORTED_ROUTED, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
goto CLEANUP;
|
@ -202,7 +202,10 @@ int orte_init_stage1(bool infrastructure)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize and select the Startup Discovery Service
|
||||
* Initialize and select the Startup Discovery Service. This must
|
||||
* be done here since some environments have different requirements
|
||||
* for detecting/connecting to a universe. Note that this does
|
||||
* *not* set our name - that will come later
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_sds_base_open())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
@ -214,8 +217,12 @@ int orte_init_stage1(bool infrastructure)
|
||||
error = "orte_sds_base_select";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Try to connect to the universe */
|
||||
|
||||
/* Try to connect to the universe. If we don't find one and are a
|
||||
* singleton, this will startup a new HNP and define our name
|
||||
* within it - in which case, we will skip the name discovery
|
||||
* process since we already have one
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_sds_base_contact_universe())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "orte_sds_base_contact_universe";
|
||||
@ -248,7 +255,7 @@ int orte_init_stage1(bool infrastructure)
|
||||
orte_rml.set_uri(orte_process_info.gpr_replica_uri);
|
||||
}
|
||||
|
||||
/* set my name and the names of the procs I was started with */
|
||||
/* Set my name */
|
||||
if (ORTE_SUCCESS != (ret = orte_sds_base_set_name())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "orte_sds_base_set_name";
|
||||
@ -429,16 +436,6 @@ int orte_init_stage1(bool infrastructure)
|
||||
|
||||
/* if i'm the seed, get my contact info and write my setup file for others to find */
|
||||
if (orte_process_info.seed) {
|
||||
if (NULL != orte_universe_info.seed_uri) {
|
||||
free(orte_universe_info.seed_uri);
|
||||
orte_universe_info.seed_uri = NULL;
|
||||
}
|
||||
if (NULL == (orte_universe_info.seed_uri = orte_rml.get_uri())) {
|
||||
ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND);
|
||||
error = "orte_rml_get_uri";
|
||||
ret = ORTE_ERR_NOT_FOUND;
|
||||
goto error;
|
||||
}
|
||||
contact_path = opal_os_path(false, orte_process_info.universe_session_dir,
|
||||
"universe-setup.txt", NULL);
|
||||
if (orte_debug_flag) {
|
||||
@ -485,96 +482,243 @@ int orte_init_stage1(bool infrastructure)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* if we are a singleton or the seed, setup an app_context for us.
|
||||
* Since we don't have access to the argv used to start this app,
|
||||
* we can only fake a name for the executable
|
||||
*/
|
||||
|
||||
if(orte_process_info.singleton || orte_process_info.seed) {
|
||||
if (orte_process_info.seed) {
|
||||
/* if we are an HNP, we have to setup an app_context for ourselves so
|
||||
* various frameworks can find their required info
|
||||
*/
|
||||
orte_app_context_t *app;
|
||||
orte_gpr_value_t *value;
|
||||
|
||||
app = OBJ_NEW(orte_app_context_t);
|
||||
app->app = strdup("unknown");
|
||||
app->app = strdup("orted");
|
||||
app->num_procs = 1;
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr_base_put_app_context(ORTE_PROC_MY_NAME->jobid, &app, 1))) {
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr.store_app_context(ORTE_PROC_MY_NAME->jobid, &app, 1))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "orte_rmgr_base_put_app_context for singleton/seed";
|
||||
error = "HNP store app context";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(app);
|
||||
|
||||
if (orte_process_info.singleton) {
|
||||
/* since all frameworks are now open and active, walk through
|
||||
* the spawn sequence to ensure that we collect info on all
|
||||
* available resources. Although we are a singleton and hence
|
||||
* don't need to be spawned, we may choose to dynamically spawn
|
||||
* additional processes. If we do that, then we need to know
|
||||
* about any resources that have been allocated to us - executing
|
||||
* the RDS and RAS frameworks is the only way to get that info.
|
||||
*
|
||||
* THIS ONLY SHOULD BE DONE FOR SINGLETONS - DO NOT DO IT
|
||||
* FOR ANY OTHER CASE
|
||||
*/
|
||||
opal_list_t attrs;
|
||||
opal_list_item_t *item;
|
||||
|
||||
OBJ_CONSTRUCT(&attrs, opal_list_t);
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_rds.query(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton rds query";
|
||||
goto error;
|
||||
}
|
||||
/* Note that, due to the way the RAS works, this might very well NOT result
|
||||
* in the localhost being on our allocation, even though we are executing
|
||||
* on it. This should be okay, though - if the localhost isn't included
|
||||
* in the official allocation, then we probably wouldn't want to launch
|
||||
* any dynamic processes on it anyway.
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_ras.allocate_job(ORTE_PROC_MY_NAME->jobid, &attrs))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton ras allocate job";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* even though the map in this case is trivial, we still
|
||||
* need to call the RMAPS framework so the proper data
|
||||
* structures get set into the registry
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr.add_attribute(&attrs, ORTE_RMAPS_NO_ALLOC_RANGE,
|
||||
ORTE_UNDEF, NULL, ORTE_RMGR_ATTR_OVERRIDE))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "could not create attribute for map";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_rmaps.map_job(ORTE_PROC_MY_NAME->jobid, &attrs))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "map for a singleton";
|
||||
goto error;
|
||||
}
|
||||
while (NULL != (item = opal_list_remove_first(&attrs))) OBJ_RELEASE(item);
|
||||
OBJ_DESTRUCT(&attrs);
|
||||
|
||||
/* need to define our stage gates and fire the LAUNCHED gate
|
||||
* to ensure that everything in the rest of the system runs smoothly
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr_base_proc_stage_gate_init(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton orte_rmgr_base_proc_stage_gate_init";
|
||||
goto error;
|
||||
}
|
||||
} else { /* if we an HNP, then we need to define the orted stage gates */
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr_base_orted_stage_gate_init(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "seed orte_rmgr_base_orted_stage_gate_init";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_value(&value,
|
||||
ORTE_GPR_OVERWRITE|ORTE_GPR_TOKENS_AND,
|
||||
"orte-job-0", 2,
|
||||
0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "HNP create value";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set our state to LAUNCHED */
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(orte_process_info.my_name, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
/* store the node name and the daemon's name */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(value->keyvals[0]), ORTE_NODE_NAME_KEY,
|
||||
ORTE_STRING, orte_system_info.nodename))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton/seed could not set launched state";
|
||||
error = "HNP create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(value->keyvals[1]), ORTE_PROC_NAME_KEY,
|
||||
ORTE_NAME, ORTE_PROC_MY_NAME))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "HNP create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set the tokens */
|
||||
if (ORTE_SUCCESS != (ret = orte_schema.get_proc_tokens(&(value->tokens), &(value->num_tokens), ORTE_PROC_MY_NAME))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "HNP get proc tokens";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* insert values */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.put(1, &value))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "HNP put values";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(value);
|
||||
|
||||
/* and set our state to LAUNCHED */
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(ORTE_PROC_MY_NAME, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "HNP could not set launched state";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (orte_process_info.singleton) {
|
||||
/* since all frameworks are now open and active, walk through
|
||||
* the spawn sequence to ensure that we collect info on all
|
||||
* available resources. Although we are a singleton and hence
|
||||
* don't need to be spawned, we may choose to dynamically spawn
|
||||
* additional processes. If we do that, then we need to know
|
||||
* about any resources that have been allocated to us - executing
|
||||
* the RDS and RAS frameworks is the only way to get that info.
|
||||
*
|
||||
* THIS ONLY SHOULD BE DONE FOR SINGLETONS - DO NOT DO IT
|
||||
* FOR ANY OTHER CASE
|
||||
*/
|
||||
orte_app_context_t *app;
|
||||
orte_gpr_value_t *values[2];
|
||||
orte_std_cntr_t one=1, zero=0;
|
||||
orte_proc_state_t init=ORTE_PROC_STATE_INIT;
|
||||
orte_vpid_t lrank=0, vone=1;
|
||||
char *segment;
|
||||
|
||||
app = OBJ_NEW(orte_app_context_t);
|
||||
app->app = strdup("singleton");
|
||||
app->num_procs = 1;
|
||||
|
||||
if (ORTE_SUCCESS !=
|
||||
(ret = orte_rmgr_base_put_app_context(ORTE_PROC_MY_NAME->jobid, &app, 1))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not store app context";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(app);
|
||||
|
||||
/* ensure we read the allocation, even if we are not sitting on a node that is within it */
|
||||
if (ORTE_SUCCESS != (ret = orte_ras.allocate_job(ORTE_PROC_MY_NAME->jobid, NULL))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not allocate job";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* setup the launch system's stage gate counters and subscriptions */
|
||||
if (ORTE_SUCCESS != (ret = orte_rmgr_base_proc_stage_gate_init(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not init triggers";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* let's deal with the procs first - start by getting their job segment name */
|
||||
if (ORTE_SUCCESS != (ret = orte_schema.get_job_segment_name(&segment, ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create job segment name";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_value(&(values[0]),
|
||||
ORTE_GPR_OVERWRITE|ORTE_GPR_TOKENS_AND,
|
||||
segment, 8, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create gpr value";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[0]), ORTE_PROC_RANK_KEY, ORTE_VPID, &(ORTE_PROC_MY_NAME->vpid)))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[1]), ORTE_PROC_NAME_KEY, ORTE_NAME, ORTE_PROC_MY_NAME))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[2]), ORTE_CELLID_KEY, ORTE_CELLID, &(ORTE_PROC_MY_NAME->cellid)))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[3]), ORTE_NODE_NAME_KEY, ORTE_STRING, orte_system_info.nodename))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[4]), ORTE_PROC_APP_CONTEXT_KEY, ORTE_STD_CNTR, &zero))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[5]), ORTE_PROC_STATE_KEY, ORTE_PROC_STATE, &init))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[6]), ORTE_PROC_LOCAL_RANK_KEY, ORTE_VPID, &lrank))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[0]->keyvals[7]), ORTE_NODE_NUM_PROCS_KEY, ORTE_STD_CNTR, &one))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_schema.get_proc_tokens(&(values[0]->tokens), &(values[0]->num_tokens), ORTE_PROC_MY_NAME))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not get gpr tokens";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_value(&values[1],
|
||||
ORTE_GPR_OVERWRITE|ORTE_GPR_TOKENS_AND,
|
||||
segment, 3, 1))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create gpr value";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[1]->keyvals[0]), ORTE_PROC_NUM_AT_INIT, ORTE_STD_CNTR, &one))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[1]->keyvals[1]), ORTE_JOB_VPID_START_KEY, ORTE_VPID, &(ORTE_PROC_MY_NAME->vpid)))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(values[1]->keyvals[2]), ORTE_JOB_VPID_RANGE_KEY, ORTE_VPID, &vone))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not create keyval";
|
||||
goto error;
|
||||
}
|
||||
values[1]->tokens[0] = strdup(ORTE_JOB_GLOBALS); /* counter is in the job's globals container */
|
||||
|
||||
/* insert all values in one call */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.put(2, values))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not put its launch data";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(values[0]);
|
||||
OBJ_RELEASE(values[1]);
|
||||
free(segment);
|
||||
|
||||
/* wireup our io */
|
||||
if (ORTE_SUCCESS != (ret = orte_iof.iof_pull(ORTE_PROC_MY_NAME, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not setup iof";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_iof.iof_pull(ORTE_PROC_MY_NAME, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not setup iof";
|
||||
goto error;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = orte_iof.iof_push(ORTE_PROC_MY_NAME, ORTE_NS_CMP_JOBID, ORTE_IOF_STDIN, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not setup iof";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* setup the errmgr, as required */
|
||||
if (ORTE_SUCCESS != (ret = orte_errmgr.register_job(ORTE_PROC_MY_NAME->jobid))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not setup errmgr callbacks";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* set our state to LAUNCHED */
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(ORTE_PROC_MY_NAME, ORTE_PROC_STATE_LAUNCHED, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error = "singleton could not set launched state";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
@ -61,10 +61,12 @@ int orte_init_stage2(char *trigger)
|
||||
* between all processes in this job when the provided
|
||||
* trigger fires
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_rml.register_subscription(ORTE_PROC_MY_NAME->jobid, trigger))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error_str = "orte_rml.register_subscription";
|
||||
goto return_error;
|
||||
if (NULL != trigger) {
|
||||
if (ORTE_SUCCESS != (ret = orte_rml.register_subscription(ORTE_PROC_MY_NAME->jobid, trigger))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error_str = "orte_rml.register_subscription";
|
||||
goto return_error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -81,13 +83,13 @@ int orte_init_stage2(char *trigger)
|
||||
/* Since we are now finished with init, change the state to running */
|
||||
orte_universe_info.state = ORTE_UNIVERSE_STATE_RUNNING;
|
||||
|
||||
/* for singleton or seed, need to fire the RUNNING gate
|
||||
/* for singleton, need to fire the RUNNING gate
|
||||
* to ensure that everything in the rest of the system runs smoothly
|
||||
*/
|
||||
if (orte_process_info.seed || orte_process_info.singleton) {
|
||||
if (orte_process_info.singleton) {
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(orte_process_info.my_name, ORTE_PROC_STATE_RUNNING, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
error_str = "singleton/seed could not set RUNNING state";
|
||||
error_str = "singleton could not set RUNNING state";
|
||||
goto return_error;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include "orte/runtime/params.h"
|
||||
|
||||
/* globals used by RTE */
|
||||
bool orte_debug_flag, orte_timing;
|
||||
bool orte_debug_flag, orte_timing, orte_infrastructure;
|
||||
bool orte_debug_daemons_flag, orte_debug_daemons_file_flag;
|
||||
bool orted_spin_flag, orte_no_daemonize_flag;
|
||||
struct timeval orte_abort_timeout;
|
||||
|
||||
|
||||
@ -40,10 +42,17 @@ struct timeval orte_abort_timeout;
|
||||
*/
|
||||
bool orte_initialized = false;
|
||||
|
||||
/* whether we have registered params or not */
|
||||
static bool params_set = false;
|
||||
|
||||
int orte_register_params(bool infrastructure)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (params_set) {
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
mca_base_param_reg_int_name("orte", "debug",
|
||||
"Top-level ORTE debug switch",
|
||||
false, false, (int)false, &value);
|
||||
@ -51,19 +60,26 @@ int orte_register_params(bool infrastructure)
|
||||
|
||||
mca_base_param_reg_int_name("orte", "debug_daemons_file",
|
||||
"Whether want stdout/stderr of daemons to go to a file or not",
|
||||
false, false, (int)false, NULL);
|
||||
false, false, (int)false, &value);
|
||||
orte_debug_daemons_file_flag = OPAL_INT_TO_BOOL(value);
|
||||
|
||||
mca_base_param_reg_int_name("orte", "no_daemonize",
|
||||
"Whether to properly daemonize the ORTE daemons or not",
|
||||
false, false, (int)false, NULL);
|
||||
orte_no_daemonize_flag = OPAL_INT_TO_BOOL(value);
|
||||
|
||||
mca_base_param_reg_int_name("orte", "debug_daemons",
|
||||
"Whether to debug the ORTE daemons or not",
|
||||
false, false, (int)false, NULL);
|
||||
false, false, (int)false, &value);
|
||||
orte_debug_daemons_flag = OPAL_INT_TO_BOOL(value);
|
||||
|
||||
mca_base_param_reg_int_name("orte", "infrastructure",
|
||||
"Whether we are ORTE infrastructure or an ORTE application",
|
||||
true, true, (int)infrastructure, NULL);
|
||||
mca_base_param_reg_int_name("orted", "spin",
|
||||
"Have any orteds spin until we can connect a debugger to them",
|
||||
false, false, (int)false, &value);
|
||||
orted_spin_flag = OPAL_INT_TO_BOOL(value);
|
||||
|
||||
/* save this in a global location as others will need to reference it */
|
||||
orte_infrastructure = infrastructure;
|
||||
|
||||
/* check for timing requests */
|
||||
mca_base_param_reg_int_name("orte", "timing",
|
||||
@ -85,6 +101,7 @@ int orte_register_params(bool infrastructure)
|
||||
orte_abort_timeout.tv_usec = 0;
|
||||
|
||||
/* All done */
|
||||
params_set = true;
|
||||
return ORTE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,12 @@ int orte_system_init(bool infrastructure, bool barrier)
|
||||
}
|
||||
|
||||
/* begin recording registry actions */
|
||||
#if 0
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.begin_compound_cmd())) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (ORTE_SUCCESS != (rc = orte_init_stage2(ORTE_STARTUP_TRIGGER))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
@ -64,13 +65,13 @@ int orte_system_init(bool infrastructure, bool barrier)
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* send the information */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.exec_compound_cmd())) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* if we want to wait for receipt of info and release, do so here */
|
||||
if (barrier) {
|
||||
if (ORTE_SUCCESS != (rc = orte_rml.xcast_gate(orte_gpr.deliver_notify_msg))) {
|
||||
|
@ -40,6 +40,8 @@ extern "C" {
|
||||
/* globals used by RTE - instanced in orte_params.c */
|
||||
|
||||
ORTE_DECLSPEC extern bool orte_debug_flag, orte_reuse_daemons, orte_timing;
|
||||
ORTE_DECLSPEC extern bool orte_debug_daemons_flag, orte_debug_daemons_file_flag;
|
||||
ORTE_DECLSPEC extern bool orte_infrastructure, orted_spin_flag, orte_no_daemonize_flag;
|
||||
|
||||
ORTE_DECLSPEC extern struct timeval orte_abort_timeout;
|
||||
|
||||
|
@ -135,6 +135,7 @@ int main(int argc, char* argv[])
|
||||
msg.iov_len = sizeof(i);
|
||||
for (i=0; i < range; i++) {
|
||||
name.vpid = i;
|
||||
fprintf(stderr, "Parent: sending message to child [%ld,%ld,%ld]\n", ORTE_NAME_ARGS(&name));
|
||||
if (0 > (rc = orte_rml.send(&name, &msg, 1, MY_TAG, 0))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ int main(int argc, char* argv[])
|
||||
bool timing = false;
|
||||
int param, value;
|
||||
struct timeval ortestart, ortestop;
|
||||
orte_buffer_t *buf;
|
||||
|
||||
/* setup the OPAL environment */
|
||||
if (ORTE_SUCCESS != (rc = opal_init())) {
|
||||
@ -52,7 +53,8 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
/* begin recording registry actions */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.begin_compound_cmd())) {
|
||||
buf = OBJ_NEW(orte_buffer_t);
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.begin_compound_cmd(buf))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
error = "begin compound cmd failed";
|
||||
goto error;
|
||||
@ -73,11 +75,12 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
/* send the information */
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.exec_compound_cmd())) {
|
||||
if (ORTE_SUCCESS != (rc = orte_gpr.exec_compound_cmd(buf))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
error = "exec compound cmd failed";
|
||||
goto error;
|
||||
}
|
||||
OBJ_RELEASE(buf);
|
||||
|
||||
/* check for timing request - get stop time and report elapsed time if so */
|
||||
if (timing) {
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/pls/base/base.h"
|
||||
#include "orte/runtime/orte_setup_hnp.h"
|
||||
#include "orte/tools/orted/orted.h"
|
||||
|
||||
#include "orte/tools/console/orteconsole.h"
|
||||
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
#include "orte/mca/odls/odls_types.h"
|
||||
|
||||
#include "orte/tools/orted/orted.h"
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
if OMPI_INSTALL_BINARIES
|
||||
|
||||
dist_pkgdata_DATA = help-orted.txt
|
||||
|
||||
bin_PROGRAMS = orted
|
||||
|
||||
endif
|
||||
@ -28,16 +26,11 @@ endif
|
||||
libs = \
|
||||
$(top_builddir)/orte/libopen-rte.la
|
||||
|
||||
headers = \
|
||||
orted.h
|
||||
|
||||
man_MANS = orted.1
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
orted_SOURCES = \
|
||||
$(headers) \
|
||||
orted_comm.c \
|
||||
orted.c
|
||||
|
||||
orted_LDADD = $(libs)
|
||||
@ -49,7 +42,6 @@ orted_DEPENDENCIES = $(libs)
|
||||
|
||||
if WANT_INSTALL_HEADERS
|
||||
ortedir = $(includedir)/openmpi/orte/tools/orted
|
||||
orte_HEADERS = $(headers)
|
||||
else
|
||||
ortedir = $(includedir)
|
||||
endif
|
||||
|
@ -19,495 +19,10 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "orte_config.h"
|
||||
#include "orte/orted/orted.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "orte/orte_constants.h"
|
||||
|
||||
#include "opal/event/event.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/threads/mutex.h"
|
||||
#include "opal/threads/condition.h"
|
||||
#include "opal/util/cmd_line.h"
|
||||
#include "opal/util/daemon_init.h"
|
||||
#include "opal/util/opal_environ.h"
|
||||
#include "opal/util/os_path.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/printf.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/util/trace.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
|
||||
|
||||
#include "orte/dss/dss.h"
|
||||
#include "orte/class/orte_value_array.h"
|
||||
#include "orte/util/sys_info.h"
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/util/univ_info.h"
|
||||
#include "orte/util/session_dir.h"
|
||||
#include "orte/util/universe_setup_file_io.h"
|
||||
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "orte/mca/ns/ns.h"
|
||||
#include "orte/mca/ns/base/base.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
#include "orte/mca/rml/rml.h"
|
||||
#include "orte/mca/smr/smr.h"
|
||||
#include "orte/mca/rmgr/rmgr.h"
|
||||
#include "orte/mca/rmgr/base/base.h"
|
||||
#include "orte/mca/odls/odls.h"
|
||||
#include "orte/mca/pls/pls.h"
|
||||
|
||||
|
||||
#include "orte/runtime/runtime.h"
|
||||
#include "orte/runtime/params.h"
|
||||
|
||||
#include "orte/tools/orted/orted.h"
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
orted_globals_t orted_globals;
|
||||
|
||||
static struct opal_event term_handler;
|
||||
static struct opal_event int_handler;
|
||||
|
||||
static void signal_callback(int fd, short flags, void *arg);
|
||||
|
||||
/*
|
||||
* define the orted context table for obtaining parameters
|
||||
*/
|
||||
opal_cmd_line_init_t orte_cmd_line_opts[] = {
|
||||
/* Various "obvious" options */
|
||||
{ NULL, NULL, NULL, 'h', NULL, "help", 0,
|
||||
&orted_globals.help, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"This help message" },
|
||||
|
||||
{ "orted", "spin", NULL, 'd', NULL, "spin", 0,
|
||||
&orted_globals.spin, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Have the orted spin until we can connect a debugger to it" },
|
||||
|
||||
{ "orte", "debug", NULL, 'd', NULL, "debug", 0,
|
||||
&orted_globals.debug, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Debug the OpenRTE" },
|
||||
|
||||
{ "orte", "no_daemonize", NULL, '\0', NULL, "no-daemonize", 0,
|
||||
&orted_globals.no_daemonize, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Don't daemonize into the background" },
|
||||
|
||||
{ "orte", "debug", "daemons", '\0', NULL, "debug-daemons", 0,
|
||||
&orted_globals.debug_daemons, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Enable debugging of OpenRTE daemons" },
|
||||
|
||||
{ "orte", "debug", "daemons_file", '\0', NULL, "debug-daemons-file", 0,
|
||||
&orted_globals.debug_daemons_file, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Enable debugging of OpenRTE daemons, storing output in files" },
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "set-sid", 0,
|
||||
&orted_globals.set_sid, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Direct the orted to separate from the current session"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "name", 1,
|
||||
&orted_globals.name, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the orte process name"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "vpid_start", 1,
|
||||
&orted_globals.vpid_start, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the starting vpid for this job"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "num_procs", 1,
|
||||
&orted_globals.num_procs, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the number of process in this job"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "ns-nds", 1,
|
||||
&orted_globals.ns_nds, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"set sds/nds component to use for daemon (normally not needed)"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "nsreplica", 1,
|
||||
&orte_process_info.ns_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Name service contact information."},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "gprreplica", 1,
|
||||
&orte_process_info.gpr_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Registry contact information."},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "nodename", 1,
|
||||
&orte_system_info.nodename, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Node name as specified by host/resource description." },
|
||||
|
||||
{ "universe", NULL, NULL, '\0', NULL, "universe", 1,
|
||||
&orted_globals.universe, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the universe name as username@hostname:universe_name for this application" },
|
||||
|
||||
{ "tmpdir", "base", NULL, '\0', NULL, "tmpdir", 1,
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set the root for the session directory tree" },
|
||||
|
||||
{ "seed", NULL, NULL, '\0', NULL, "seed", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Host replicas for the core universe services"},
|
||||
|
||||
{ "universe", "persistence", NULL, '\0', NULL, "persistent", 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
||||
"Remain alive after the application process completes"},
|
||||
|
||||
{ "universe", "scope", NULL, '\0', NULL, "scope", 1,
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Set restrictions on who can connect to this universe"},
|
||||
|
||||
{ NULL, NULL, NULL, '\0', NULL, "report-uri", 1,
|
||||
&orted_globals.uri_pipe, OPAL_CMD_LINE_TYPE_INT,
|
||||
"Report this process' uri on indicated pipe"},
|
||||
|
||||
/* End of list */
|
||||
{ NULL, NULL, NULL, '\0', NULL, NULL, 0,
|
||||
NULL, OPAL_CMD_LINE_TYPE_NULL, NULL }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
int fd;
|
||||
opal_cmd_line_t *cmd_line = NULL;
|
||||
char *log_path = NULL;
|
||||
char log_file[PATH_MAX];
|
||||
char *jobidstring;
|
||||
int i;
|
||||
|
||||
/* initialize the globals */
|
||||
memset(&orted_globals, 0, sizeof(orted_globals_t));
|
||||
|
||||
/* save the environment for use when launching application processes */
|
||||
orted_globals.saved_environ = opal_argv_copy(environ);
|
||||
|
||||
/* setup to check common command line options that just report and die */
|
||||
cmd_line = OBJ_NEW(opal_cmd_line_t);
|
||||
opal_cmd_line_create(cmd_line, orte_cmd_line_opts);
|
||||
mca_base_cmd_line_setup(cmd_line);
|
||||
if (ORTE_SUCCESS != (ret = opal_cmd_line_parse(cmd_line, false,
|
||||
argc, argv))) {
|
||||
char *args = NULL;
|
||||
args = opal_cmd_line_get_usage_msg(cmd_line);
|
||||
opal_show_help("help-orted.txt", "orted:usage", false,
|
||||
argv[0], args);
|
||||
free(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since this process can now handle MCA/GMCA parameters, make sure to
|
||||
* process them.
|
||||
*/
|
||||
mca_base_cmd_line_process_args(cmd_line, &environ, &environ);
|
||||
|
||||
/* Ensure that enough of OPAL is setup for us to be able to run */
|
||||
if (OPAL_SUCCESS != opal_init_util()) {
|
||||
fprintf(stderr, "OPAL failed to initialize -- orted aborting\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* check for help request */
|
||||
if (orted_globals.help) {
|
||||
char *args = NULL;
|
||||
args = opal_cmd_line_get_usage_msg(cmd_line);
|
||||
opal_show_help("help-orted.txt", "orted:usage", false,
|
||||
argv[0], args);
|
||||
free(args);
|
||||
return 1;
|
||||
}
|
||||
#if !defined(__WINDOWS__)
|
||||
/* see if we were directed to separate from current session */
|
||||
if (orted_globals.set_sid) {
|
||||
setsid();
|
||||
}
|
||||
#endif /* !defined(__WINDOWS__) */
|
||||
/* see if they want us to spin until they can connect a debugger to us */
|
||||
i=0;
|
||||
/*orted_globals.spin = 1;*/
|
||||
while (orted_globals.spin) {
|
||||
i++;
|
||||
if (1000 < i) i=0;
|
||||
}
|
||||
|
||||
/* Okay, now on to serious business! */
|
||||
|
||||
/* Ensure the process info structure is instantiated and initialized
|
||||
* and set the daemon flag to true
|
||||
*/
|
||||
orte_process_info.daemon = true;
|
||||
|
||||
/*
|
||||
* If the daemon was given a name on the command line, need to set the
|
||||
* proper indicators in the environment so the name discovery service
|
||||
* can find it
|
||||
*/
|
||||
if (orted_globals.name) {
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
||||
"env", true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds", "env", ret);
|
||||
return ret;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_name",
|
||||
orted_globals.name, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_name", orted_globals.name, ret);
|
||||
return ret;
|
||||
}
|
||||
/* the following values are meaningless to the daemon, but may have
|
||||
* been passed in anyway. we set them here because the nds_env component
|
||||
* requires that they be set
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_vpid_start",
|
||||
orted_globals.vpid_start, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_vpid_start", orted_globals.vpid_start, ret);
|
||||
return ret;
|
||||
}
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_num_procs",
|
||||
orted_globals.num_procs, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds_num_procs", orted_globals.num_procs, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (orted_globals.ns_nds) {
|
||||
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
||||
orted_globals.ns_nds, true, &environ))) {
|
||||
opal_show_help("help-orted.txt", "orted:environ", false,
|
||||
"OMPI_MCA_ns_nds", "env", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* turn on debug if debug_file is requested so output will be generated */
|
||||
if (orted_globals.debug_daemons_file) {
|
||||
orted_globals.debug_daemons = true;
|
||||
}
|
||||
|
||||
/* detach from controlling terminal
|
||||
* otherwise, remain attached so output can get to us
|
||||
*/
|
||||
if(orted_globals.debug == false &&
|
||||
orted_globals.debug_daemons == false &&
|
||||
orted_globals.no_daemonize == false) {
|
||||
opal_daemon_init(NULL);
|
||||
}
|
||||
|
||||
/* Intialize OPAL */
|
||||
if (ORTE_SUCCESS != (ret = opal_init())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the flag telling OpenRTE that I am NOT a
|
||||
* singleton, but am "infrastructure" - prevents setting
|
||||
* up incorrect infrastructure that only a singleton would
|
||||
* require.
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_init_stage1(ORTE_INFRASTRUCTURE))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* setup our receive functions - this will allow us to relay messages
|
||||
* during start for better scalability
|
||||
*/
|
||||
/* register the daemon main receive functions */
|
||||
/* setup to listen for broadcast commands via routed messaging algorithms */
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_ORTED_ROUTED,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_routed, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
/* setup to listen for commands sent specifically to me */
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_DAEMON, ORTE_RML_NON_PERSISTENT, orte_daemon_recv, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Complete initializing the rte - begin recording registry actions */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.begin_compound_cmd())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ORTE_SUCCESS != (ret = orte_init_stage2(ORTE_STARTUP_TRIGGER))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* indicate we are at the ORTE_STARTUP_COMPLETE state */
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(ORTE_PROC_MY_NAME,
|
||||
ORTE_PROC_ORTE_STARTUP_COMPLETE, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* send the information */
|
||||
if (ORTE_SUCCESS != (ret = orte_gpr.exec_compound_cmd())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Use the barrier capability to hold us
|
||||
* in orte_init until the orte_setup state is achieved. This
|
||||
* will allow us to obtain a complete set of contact info
|
||||
* for all of our fellow daemons
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_rml.xcast_gate(orte_gpr.deliver_notify_msg))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set signal handlers to catch kill signals so we can properly clean up
|
||||
* after ourselves.
|
||||
*/
|
||||
opal_event_set(&term_handler, SIGTERM, OPAL_EV_SIGNAL,
|
||||
signal_callback, NULL);
|
||||
opal_event_add(&term_handler, NULL);
|
||||
opal_event_set(&int_handler, SIGINT, OPAL_EV_SIGNAL,
|
||||
signal_callback, NULL);
|
||||
opal_event_add(&int_handler, NULL);
|
||||
|
||||
/* if requested, report my uri to the indicated pipe */
|
||||
if (orted_globals.uri_pipe > 0) {
|
||||
write(orted_globals.uri_pipe, orte_universe_info.seed_uri,
|
||||
strlen(orte_universe_info.seed_uri)+1); /* need to add 1 to get the NULL */
|
||||
close(orted_globals.uri_pipe);
|
||||
}
|
||||
|
||||
/* setup stdout/stderr */
|
||||
if (orted_globals.debug_daemons_file) {
|
||||
/* if we are debugging to a file, then send stdout/stderr to
|
||||
* the orted log file
|
||||
*/
|
||||
|
||||
/* get my jobid */
|
||||
if (ORTE_SUCCESS != (ret = orte_ns.get_jobid_string(&jobidstring,
|
||||
orte_process_info.my_name))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* define a log file name in the session directory */
|
||||
sprintf(log_file, "output-orted-%s-%s.log",
|
||||
jobidstring, orte_system_info.nodename);
|
||||
log_path = opal_os_path(false,
|
||||
orte_process_info.tmpdir_base,
|
||||
orte_process_info.top_session_dir,
|
||||
log_file,
|
||||
NULL);
|
||||
|
||||
fd = open(log_path, O_RDWR|O_CREAT|O_TRUNC, 0640);
|
||||
if (fd < 0) {
|
||||
/* couldn't open the file for some reason, so
|
||||
* just connect everything to /dev/null
|
||||
*/
|
||||
fd = open("/dev/null", O_RDWR|O_CREAT|O_TRUNC, 0666);
|
||||
} else {
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
if(fd != STDOUT_FILENO && fd != STDERR_FILENO) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* output a message indicating we are alive, our name, and our pid
|
||||
* for debugging purposes
|
||||
*/
|
||||
if (orted_globals.debug_daemons) {
|
||||
fprintf(stderr, "Daemon [%ld,%ld,%ld] checking in as pid %ld on host %s\n",
|
||||
ORTE_NAME_ARGS(orte_process_info.my_name), (long)orte_process_info.pid,
|
||||
orte_system_info.nodename);
|
||||
}
|
||||
|
||||
/* setup the thread lock and condition variables */
|
||||
OBJ_CONSTRUCT(&orted_globals.mutex, opal_mutex_t);
|
||||
OBJ_CONSTRUCT(&orted_globals.condition, opal_condition_t);
|
||||
|
||||
/* a daemon should *always* yield the processor when idle */
|
||||
opal_progress_set_yield_when_idle(true);
|
||||
|
||||
/* setup to listen for xcast stage gate commands. We need to do this because updates to the
|
||||
* contact info for dynamically spawned daemons will come to the gate RML-tag
|
||||
*/
|
||||
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_XCAST_BARRIER,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_gate, NULL);
|
||||
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set my process status to "running". Note that this must be done
|
||||
* after the rte init is completed.
|
||||
*/
|
||||
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(orte_process_info.my_name,
|
||||
ORTE_PROC_STATE_RUNNING, 0))) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: up and running - waiting for commands!", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
/* setup and enter the event monitor */
|
||||
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
||||
|
||||
while (false == orted_globals.exit_condition) {
|
||||
opal_condition_wait(&orted_globals.condition, &orted_globals.mutex);
|
||||
}
|
||||
|
||||
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
||||
|
||||
if (orted_globals.debug_daemons) {
|
||||
opal_output(0, "[%lu,%lu,%lu] orted: mutex cleared - finalizing", ORTE_NAME_ARGS(orte_process_info.my_name));
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
if (NULL != log_path) {
|
||||
unlink(log_path);
|
||||
}
|
||||
|
||||
/* make sure our local procs are dead - but don't update their state
|
||||
* on the HNP as this may be redundant
|
||||
*/
|
||||
orte_odls.kill_local_procs(ORTE_JOBID_WILDCARD, false);
|
||||
|
||||
/* cleanup any lingering session directories */
|
||||
orte_session_dir_cleanup(ORTE_JOBID_WILDCARD);
|
||||
|
||||
/* Finalize and clean up ourselves */
|
||||
if (ORTE_SUCCESS != (ret = orte_finalize())) {
|
||||
ORTE_ERROR_LOG(ret);
|
||||
}
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void signal_callback(int fd, short flags, void *arg)
|
||||
{
|
||||
OPAL_TRACE(1);
|
||||
orted_globals.exit_condition = true;
|
||||
opal_condition_signal(&orted_globals.condition);
|
||||
return orte_daemon(argc, argv);
|
||||
}
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "opal/util/cmd_line.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "orte/tools/orted/orted.h"
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include "orte/mca/pls/pls.h"
|
||||
#include "orte/mca/rmaps/rmaps_types.h"
|
||||
#include "orte/mca/rmgr/rmgr.h"
|
||||
#include "orte/mca/rml/rml.h"
|
||||
#include "orte/mca/schema/schema.h"
|
||||
#include "orte/mca/smr/smr.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
@ -84,6 +85,9 @@
|
||||
#include "orte/runtime/params.h"
|
||||
#include "orte/runtime/orte_wait.h"
|
||||
|
||||
/* ensure I can behave like a daemon */
|
||||
#include "orte/orted/orted.h"
|
||||
|
||||
#include "orterun.h"
|
||||
#include "totalview.h"
|
||||
|
||||
@ -332,7 +336,6 @@ int orterun(int argc, char *argv[])
|
||||
opal_init_util();
|
||||
|
||||
/* Setup MCA params */
|
||||
orte_register_params(false);
|
||||
|
||||
|
||||
/* Check for some "global" command line params */
|
||||
@ -384,6 +387,9 @@ int orterun(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
/* since we are a daemon, we should *always* yield the processor when idle */
|
||||
opal_progress_set_yield_when_idle(true);
|
||||
|
||||
/* pre-condition any network transports that require it */
|
||||
if (ORTE_SUCCESS != (rc = orte_pre_condition_transports(apps, num_apps))) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
@ -392,7 +398,38 @@ int orterun(int argc, char *argv[])
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* setup our receive functions so we can fully participate in daemon
|
||||
* communications - this will allow us to relay messages
|
||||
* during start for better scalability
|
||||
*/
|
||||
/* register the daemon main receive functions */
|
||||
/* setup to listen for broadcast commands via routed messaging algorithms */
|
||||
rc = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_ORTED_ROUTED,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_routed, NULL);
|
||||
if (rc != ORTE_SUCCESS && rc != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* setup to listen for commands sent specifically to me, even though I would probably
|
||||
* be the one sending them! Unfortunately, since I am a participating daemon,
|
||||
* there are times I need to send a command to "all daemons", and that means *I* have
|
||||
* to receive it too
|
||||
*/
|
||||
rc = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_DAEMON, ORTE_RML_NON_PERSISTENT, orte_daemon_recv, NULL);
|
||||
if (rc != ORTE_SUCCESS && rc != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
/* setup to listen for xcast stage gate commands. We need to do this because updates to the
|
||||
* contact info for dynamically spawned daemons will come to the gate RML-tag
|
||||
*/
|
||||
rc = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_XCAST_BARRIER,
|
||||
ORTE_RML_NON_PERSISTENT, orte_daemon_recv_gate, NULL);
|
||||
if (rc != ORTE_SUCCESS && rc != ORTE_ERR_NOT_IMPLEMENTED) {
|
||||
ORTE_ERROR_LOG(rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Prep to start the application */
|
||||
/* construct the list of attributes */
|
||||
OBJ_CONSTRUCT(&attributes, opal_list_t);
|
||||
@ -432,7 +469,7 @@ int orterun(int argc, char *argv[])
|
||||
/* we are done! */
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
|
||||
OPAL_THREAD_LOCK(&orterun_globals.lock);
|
||||
/* If the spawn was successful, wait for the app to complete */
|
||||
if (ORTE_SUCCESS == rc) {
|
||||
|
@ -142,6 +142,12 @@ orte_err2str(int errnum)
|
||||
case ORTE_ERR_FAILED_TO_START:
|
||||
retval = "The specified application failed to start";
|
||||
break;
|
||||
case ORTE_ERR_FILE_NOT_EXECUTABLE:
|
||||
retval = "A system-required executable either could not be found or was not executable by this user";
|
||||
break;
|
||||
case ORTE_ERR_HNP_COULD_NOT_START:
|
||||
retval = "Unable to start a daemon on the local node";
|
||||
break;
|
||||
default:
|
||||
retval = NULL;
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user