2005-03-14 23:57:21 +03:00
|
|
|
/*
|
2007-03-17 02:11:45 +03:00
|
|
|
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
2005-11-05 22:57:48 +03:00
|
|
|
* University Research and Technology
|
|
|
|
* Corporation. All rights reserved.
|
2006-08-24 20:18:42 +04:00
|
|
|
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
2005-11-05 22:57:48 +03:00
|
|
|
* of Tennessee Research Foundation. All rights
|
|
|
|
* reserved.
|
2006-02-08 20:40:11 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
2005-03-14 23:57:21 +03:00
|
|
|
* University of Stuttgart. All rights reserved.
|
2005-03-24 15:43:37 +03:00
|
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
|
|
* All rights reserved.
|
2005-03-14 23:57:21 +03:00
|
|
|
* $COPYRIGHT$
|
2006-02-08 20:40:11 +03:00
|
|
|
*
|
2005-03-14 23:57:21 +03:00
|
|
|
* Additional copyrights may follow
|
2006-02-08 20:40:11 +03:00
|
|
|
*
|
2005-03-14 23:57:21 +03:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "orte_config.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>
|
2005-08-26 22:56:08 +04:00
|
|
|
#include <signal.h>
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2006-02-12 04:33:29 +03:00
|
|
|
#include "orte/orte_constants.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "opal/event/event.h"
|
|
|
|
#include "opal/mca/base/base.h"
|
2005-07-04 02:45:48 +04:00
|
|
|
#include "opal/threads/mutex.h"
|
|
|
|
#include "opal/threads/condition.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "opal/util/cmd_line.h"
|
|
|
|
#include "opal/util/daemon_init.h"
|
2005-07-04 05:36:20 +04:00
|
|
|
#include "opal/util/opal_environ.h"
|
2005-07-04 05:59:52 +04:00
|
|
|
#include "opal/util/os_path.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "opal/util/output.h"
|
2005-07-04 06:16:57 +04:00
|
|
|
#include "opal/util/printf.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "opal/util/show_help.h"
|
|
|
|
#include "opal/util/trace.h"
|
2006-10-11 19:18:57 +04:00
|
|
|
#include "opal/util/argv.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
|
2006-02-07 06:32:36 +03:00
|
|
|
#include "orte/dss/dss.h"
|
2006-09-15 01:29:51 +04:00
|
|
|
#include "orte/class/orte_value_array.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
#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"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-09-19 21:20:01 +04:00
|
|
|
#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"
|
2006-08-16 20:35:09 +04:00
|
|
|
#include "orte/mca/smr/smr.h"
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "orte/mca/rmgr/rmgr.h"
|
|
|
|
#include "orte/mca/rmgr/base/base.h"
|
2006-09-15 01:29:51 +04:00
|
|
|
#include "orte/mca/odls/odls.h"
|
2006-11-18 07:47:51 +03:00
|
|
|
#include "orte/mca/pls/pls.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "orte/runtime/runtime.h"
|
2007-01-25 17:17:44 +03:00
|
|
|
#include "orte/runtime/params.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-09-19 21:20:01 +04:00
|
|
|
#include "orte/tools/orted/orted.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2006-08-24 20:18:42 +04:00
|
|
|
#if !defined(__WINDOWS__)
|
|
|
|
extern char** environ;
|
|
|
|
#endif /* !defined(__WINDOWS__) */
|
2006-08-23 10:19:47 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/*
|
|
|
|
* Globals
|
|
|
|
*/
|
2005-03-14 23:57:21 +03:00
|
|
|
orted_globals_t orted_globals;
|
|
|
|
|
2005-08-26 22:56:08 +04:00
|
|
|
static struct opal_event term_handler;
|
|
|
|
static struct opal_event int_handler;
|
|
|
|
|
|
|
|
static void signal_callback(int fd, short flags, void *arg);
|
2005-03-14 23:57:21 +03:00
|
|
|
static void orte_daemon_recv(int status, orte_process_name_t* sender,
|
2006-09-15 01:29:51 +04:00
|
|
|
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
|
|
|
void* cbdata);
|
|
|
|
static void orte_daemon_recv_pls(int status, orte_process_name_t* sender,
|
|
|
|
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
|
|
|
void* cbdata);
|
|
|
|
static void orted_local_cb_launcher(orte_gpr_notify_data_t *data, void *user_tag);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* define the orted context table for obtaining parameters
|
|
|
|
*/
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_cmd_line_init_t orte_cmd_line_opts[] = {
|
2005-03-14 23:57:21 +03:00
|
|
|
/* Various "obvious" options */
|
2006-02-08 20:40:11 +03:00
|
|
|
{ NULL, NULL, NULL, 'h', NULL, "help", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.help, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-03-14 23:57:21 +03:00
|
|
|
"This help message" },
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
{ "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" },
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
{ "orte", "debug", NULL, 'd', NULL, "debug", 0,
|
|
|
|
&orted_globals.debug, OPAL_CMD_LINE_TYPE_BOOL,
|
|
|
|
"Debug the OpenRTE" },
|
|
|
|
|
2005-05-24 19:02:50 +04:00
|
|
|
{ "orte", "no_daemonize", NULL, '\0', NULL, "no-daemonize", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.no_daemonize, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-05-04 15:57:47 +04:00
|
|
|
"Don't daemonize into the background" },
|
2005-05-13 01:44:23 +04:00
|
|
|
|
|
|
|
{ "orte", "debug", "daemons", '\0', NULL, "debug-daemons", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.debug_daemons, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Enable debugging of OpenRTE daemons" },
|
|
|
|
|
|
|
|
{ "orte", "debug", "daemons_file", '\0', NULL, "debug-daemons-file", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.debug_daemons_file, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Enable debugging of OpenRTE daemons, storing output in files" },
|
|
|
|
|
2005-03-31 19:47:37 +04:00
|
|
|
{ "rmgr", "bootproxy", "jobid", '\0', NULL, "bootproxy", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.bootproxy, OPAL_CMD_LINE_TYPE_INT,
|
2005-03-14 23:57:21 +03:00
|
|
|
"Run as boot proxy for <job-id>" },
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2007-01-25 17:17:44 +03:00
|
|
|
{ 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"},
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "name", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.name, OPAL_CMD_LINE_TYPE_STRING,
|
2005-03-14 23:57:21 +03:00
|
|
|
"Set the orte process name"},
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2005-05-24 17:39:15 +04:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "vpid_start", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.vpid_start, OPAL_CMD_LINE_TYPE_STRING,
|
2005-05-24 17:39:15 +04:00
|
|
|
"Set the starting vpid for this job"},
|
|
|
|
|
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "num_procs", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.num_procs, OPAL_CMD_LINE_TYPE_STRING,
|
2005-05-24 17:39:15 +04:00
|
|
|
"Set the number of process in this job"},
|
|
|
|
|
2005-08-26 02:29:23 +04:00
|
|
|
{ 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)"},
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "nsreplica", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orte_process_info.ns_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
2005-03-14 23:57:21 +03:00
|
|
|
"Name service contact information."},
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "gprreplica", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orte_process_info.gpr_replica_uri, OPAL_CMD_LINE_TYPE_STRING,
|
2005-03-14 23:57:21 +03:00
|
|
|
"Registry contact information."},
|
2005-05-13 01:44:23 +04:00
|
|
|
|
2005-03-18 06:43:59 +03:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "nodename", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orte_system_info.nodename, OPAL_CMD_LINE_TYPE_STRING,
|
2005-03-18 06:43:59 +03:00
|
|
|
"Node name as specified by host/resource description." },
|
2005-05-13 01:44:23 +04:00
|
|
|
|
|
|
|
{ "universe", NULL, NULL, '\0', NULL, "universe", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.universe, OPAL_CMD_LINE_TYPE_STRING,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Set the universe name as username@hostname:universe_name for this application" },
|
|
|
|
|
|
|
|
{ "tmpdir", "base", NULL, '\0', NULL, "tmpdir", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Set the root for the session directory tree" },
|
|
|
|
|
2005-03-24 18:45:44 +03:00
|
|
|
{ "seed", NULL, NULL, '\0', NULL, "seed", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Host replicas for the core universe services"},
|
|
|
|
|
2005-03-24 18:45:44 +03:00
|
|
|
{ "universe", "persistence", NULL, '\0', NULL, "persistent", 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
NULL, OPAL_CMD_LINE_TYPE_BOOL,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Remain alive after the application process completes"},
|
|
|
|
|
2005-03-24 18:45:44 +03:00
|
|
|
{ "universe", "scope", NULL, '\0', NULL, "scope", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
2005-05-13 01:44:23 +04:00
|
|
|
"Set restrictions on who can connect to this universe"},
|
|
|
|
|
2005-05-18 21:56:51 +04:00
|
|
|
{ NULL, NULL, NULL, '\0', NULL, "report-uri", 1,
|
2005-07-04 04:13:44 +04:00
|
|
|
&orted_globals.uri_pipe, OPAL_CMD_LINE_TYPE_INT,
|
2005-05-18 21:56:51 +04:00
|
|
|
"Report this process' uri on indicated pipe"},
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/* End of list */
|
|
|
|
{ NULL, NULL, NULL, '\0', NULL, NULL, 0,
|
2005-07-04 04:13:44 +04:00
|
|
|
NULL, OPAL_CMD_LINE_TYPE_NULL, NULL }
|
2005-03-14 23:57:21 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2006-08-10 16:57:55 +04:00
|
|
|
int ret = 0;
|
2005-05-13 01:44:23 +04:00
|
|
|
int fd;
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_cmd_line_t *cmd_line = NULL;
|
2005-03-14 23:57:21 +03:00
|
|
|
char *log_path = NULL;
|
2005-05-13 01:44:23 +04:00
|
|
|
char log_file[PATH_MAX];
|
|
|
|
char *jobidstring;
|
2006-09-15 01:29:51 +04:00
|
|
|
orte_gpr_value_t *value;
|
|
|
|
char *segment;
|
|
|
|
int i;
|
2006-11-15 18:09:28 +03:00
|
|
|
orte_buffer_t answer;
|
2007-03-01 16:39:20 +03:00
|
|
|
char * orted_amca_param_path = NULL;
|
2005-09-14 01:14:34 +04:00
|
|
|
|
2006-10-11 19:18:57 +04:00
|
|
|
/* initialize the globals */
|
2005-05-13 01:44:23 +04:00
|
|
|
memset(&orted_globals, 0, sizeof(orted_globals_t));
|
2006-10-11 19:18:57 +04:00
|
|
|
|
|
|
|
/* save the environment for use when launching application processes */
|
|
|
|
orted_globals.saved_environ = opal_argv_copy(environ);
|
2006-10-20 00:35:55 +04:00
|
|
|
|
2007-03-01 16:39:20 +03:00
|
|
|
/* setup mca param system
|
|
|
|
* Do not parse the Aggregate Parameter Sets in this pass.
|
|
|
|
* we will get to them in a moment
|
|
|
|
*/
|
|
|
|
opal_mca_base_param_use_amca_sets = false;
|
2007-01-25 17:17:44 +03:00
|
|
|
mca_base_param_init();
|
|
|
|
|
2006-10-11 19:18:57 +04:00
|
|
|
/* setup to check common command line options that just report and die */
|
2005-07-04 04:13:44 +04:00
|
|
|
cmd_line = OBJ_NEW(opal_cmd_line_t);
|
|
|
|
opal_cmd_line_create(cmd_line, orte_cmd_line_opts);
|
2007-03-01 16:39:20 +03:00
|
|
|
mca_base_cmd_line_setup(cmd_line);
|
2006-02-12 04:33:29 +03:00
|
|
|
if (ORTE_SUCCESS != (ret = opal_cmd_line_parse(cmd_line, false,
|
2005-03-14 23:57:21 +03:00
|
|
|
argc, argv))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
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);
|
2005-03-14 23:57:21 +03:00
|
|
|
return ret;
|
|
|
|
}
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2007-03-01 16:39:20 +03:00
|
|
|
/*
|
|
|
|
* Since this process can now handle MCA/GMCA parameters, make sure to
|
|
|
|
* process them.
|
|
|
|
*/
|
|
|
|
mca_base_cmd_line_process_args(cmd_line, &environ, &environ);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* orterun may have given us an additional path to use when looking for
|
|
|
|
* Aggregate MCA parameter sets. Look it up, and prepend it to the
|
|
|
|
* search list.
|
|
|
|
*/
|
|
|
|
mca_base_param_reg_string_name("mca", "base_param_file_path_orted",
|
|
|
|
"[INTERNAL] Current working directory from MPIRUN to help in finding Aggregate MCA parameters",
|
|
|
|
true, false,
|
|
|
|
NULL,
|
|
|
|
&orted_amca_param_path);
|
|
|
|
|
|
|
|
if( NULL != orted_amca_param_path ) {
|
|
|
|
int loc_id;
|
|
|
|
char * amca_param_path = NULL;
|
|
|
|
char * tmp_str = NULL;
|
|
|
|
|
|
|
|
/* Lookup the current Aggregate MCA Parameter set path */
|
|
|
|
loc_id = mca_base_param_find("mca", NULL, "base_param_file_path");
|
|
|
|
mca_base_param_lookup_string(loc_id, &amca_param_path);
|
|
|
|
|
|
|
|
asprintf(&tmp_str, "%s%c%s", orted_amca_param_path, OPAL_ENV_SEP, amca_param_path);
|
|
|
|
|
|
|
|
mca_base_param_set_string(loc_id, tmp_str);
|
|
|
|
|
|
|
|
loc_id = mca_base_param_find("mca", NULL, "base_param_file_path");
|
|
|
|
mca_base_param_lookup_string(loc_id, &amca_param_path);
|
|
|
|
|
|
|
|
if( NULL != amca_param_path) {
|
|
|
|
free(amca_param_path);
|
|
|
|
amca_param_path = NULL;
|
|
|
|
}
|
|
|
|
if( NULL != orted_amca_param_path) {
|
|
|
|
free(orted_amca_param_path);
|
|
|
|
orted_amca_param_path = NULL;
|
|
|
|
}
|
|
|
|
if( NULL != tmp_str) {
|
|
|
|
free(tmp_str);
|
|
|
|
tmp_str = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Need to recache the files since the user might have given us
|
|
|
|
* Aggregate MCA parameters that need to be reinitalized.
|
|
|
|
*/
|
|
|
|
opal_mca_base_param_use_amca_sets = true;
|
|
|
|
mca_base_param_recache_files(true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
opal_mca_base_param_use_amca_sets = true;
|
|
|
|
mca_base_param_recache_files(false);
|
|
|
|
}
|
|
|
|
|
2005-07-29 00:49:17 +04:00
|
|
|
/* check for help request */
|
2005-03-14 23:57:21 +03:00
|
|
|
if (orted_globals.help) {
|
|
|
|
char *args = NULL;
|
2005-07-04 04:13:44 +04:00
|
|
|
args = opal_cmd_line_get_usage_msg(cmd_line);
|
2005-07-04 06:38:44 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:usage", false,
|
2005-03-14 23:57:21 +03:00
|
|
|
argv[0], args);
|
|
|
|
free(args);
|
|
|
|
return 1;
|
|
|
|
}
|
2007-04-01 20:16:54 +04:00
|
|
|
#if !defined(__WINDOWS__)
|
2007-01-25 17:17:44 +03:00
|
|
|
/* see if we were directed to separate from current session */
|
|
|
|
if (orted_globals.set_sid) {
|
|
|
|
setsid();
|
|
|
|
}
|
2007-04-01 20:16:54 +04:00
|
|
|
#endif /* !defined(__WINDOWS__) */
|
2006-09-15 01:29:51 +04:00
|
|
|
/* see if they want us to spin until they can connect a debugger to us */
|
2006-09-18 16:40:42 +04:00
|
|
|
i=0;
|
2007-04-01 20:16:54 +04:00
|
|
|
/*orted_globals.spin = 1;*/
|
2006-09-15 01:29:51 +04:00
|
|
|
while (orted_globals.spin) {
|
|
|
|
i++;
|
|
|
|
if (1000 < i) i=0;
|
|
|
|
}
|
|
|
|
|
2006-10-11 19:18:57 +04:00
|
|
|
/* Okay, now on to serious business! */
|
|
|
|
|
|
|
|
/* Ensure the process info structure in instantiated and initialized
|
2005-03-14 23:57:21 +03:00
|
|
|
* and set the daemon flag to true
|
|
|
|
*/
|
|
|
|
orte_process_info.daemon = true;
|
|
|
|
|
|
|
|
/*
|
2005-05-24 17:39:15 +04:00
|
|
|
* 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
|
2005-03-14 23:57:21 +03:00
|
|
|
*/
|
2006-02-08 20:40:11 +03:00
|
|
|
if (orted_globals.name) {
|
2005-07-04 05:36:20 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
2006-08-23 10:19:47 +04:00
|
|
|
"env", true, &environ))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:environ", false,
|
|
|
|
"OMPI_MCA_ns_nds", "env", ret);
|
2005-05-24 17:39:15 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2005-07-04 05:36:20 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_name",
|
2006-08-23 10:19:47 +04:00
|
|
|
orted_globals.name, true, &environ))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:environ", false,
|
|
|
|
"OMPI_MCA_ns_nds_name", orted_globals.name, ret);
|
2005-05-24 17:39:15 +04:00
|
|
|
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
|
|
|
|
*/
|
2005-07-04 05:36:20 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_vpid_start",
|
2006-08-23 10:19:47 +04:00
|
|
|
orted_globals.vpid_start, true, &environ))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:environ", false,
|
|
|
|
"OMPI_MCA_ns_nds_vpid_start", orted_globals.vpid_start, ret);
|
2005-05-24 17:39:15 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2005-07-04 05:36:20 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds_num_procs",
|
2006-08-23 10:19:47 +04:00
|
|
|
orted_globals.num_procs, true, &environ))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:environ", false,
|
|
|
|
"OMPI_MCA_ns_nds_num_procs", orted_globals.num_procs, ret);
|
2005-05-24 17:39:15 +04:00
|
|
|
return ret;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
}
|
2005-08-26 02:29:23 +04:00
|
|
|
if (orted_globals.ns_nds) {
|
|
|
|
if (ORTE_SUCCESS != (ret = opal_setenv("OMPI_MCA_ns_nds",
|
2006-08-23 10:19:47 +04:00
|
|
|
orted_globals.ns_nds, true, &environ))) {
|
2005-08-26 02:29:23 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:environ", false,
|
|
|
|
"OMPI_MCA_ns_nds", "env", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
/* turn on debug if debug_file is requested so output will be generated */
|
|
|
|
if (orted_globals.debug_daemons_file) {
|
|
|
|
orted_globals.debug_daemons = true;
|
|
|
|
}
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
/* detach from controlling terminal
|
|
|
|
* otherwise, remain attached so output can get to us
|
|
|
|
*/
|
2005-05-24 02:06:50 +04:00
|
|
|
if(orted_globals.debug == false &&
|
2006-02-08 20:40:11 +03:00
|
|
|
orted_globals.debug_daemons == false &&
|
2005-05-24 02:06:50 +04:00
|
|
|
orted_globals.no_daemonize == false) {
|
2005-07-04 04:13:44 +04:00
|
|
|
opal_daemon_init(NULL);
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Intialize the Open RTE */
|
2005-08-27 00:13:35 +04:00
|
|
|
/* Set the flag telling orte_init that I am NOT a
|
2005-06-30 20:32:02 +04:00
|
|
|
* singleton, but am "infrastructure" - prevents setting
|
|
|
|
* up incorrect infrastructure that only a singleton would
|
|
|
|
* require
|
|
|
|
*/
|
2005-08-27 00:13:35 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = orte_init(true))) {
|
2005-07-29 00:49:17 +04:00
|
|
|
opal_show_help("help-orted.txt", "orted:init-failure", false,
|
|
|
|
"orte_init()", ret);
|
2005-03-14 23:57:21 +03:00
|
|
|
return ret;
|
|
|
|
}
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2005-08-26 22:56:08 +04:00
|
|
|
/* Set signal handlers to catch kill signals so we can properly clean up
|
2006-02-16 19:19:37 +03:00
|
|
|
* after ourselves.
|
2005-08-26 22:56:08 +04:00
|
|
|
*/
|
|
|
|
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);
|
|
|
|
|
2005-05-18 21:56:51 +04:00
|
|
|
/* 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,
|
2005-05-18 22:24:14 +04:00
|
|
|
strlen(orte_universe_info.seed_uri)+1); /* need to add 1 to get the NULL */
|
2005-05-18 21:56:51 +04:00
|
|
|
close(orted_globals.uri_pipe);
|
|
|
|
}
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2005-06-06 17:36:41 +04:00
|
|
|
/* setup stdout/stderr */
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons_file) {
|
2005-06-06 17:36:41 +04:00
|
|
|
/* if we are debugging to a file, then send stdout/stderr to
|
|
|
|
* the orted log file
|
2005-05-13 01:44:23 +04:00
|
|
|
*/
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
/* get my jobid */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_ns.get_jobid_string(&jobidstring,
|
|
|
|
orte_process_info.my_name))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
/* define a log file name in the session directory */
|
2006-02-08 20:40:11 +03:00
|
|
|
sprintf(log_file, "output-orted-%s-%s.log",
|
2005-05-13 01:44:23 +04:00
|
|
|
jobidstring, orte_system_info.nodename);
|
2006-02-08 20:40:11 +03:00
|
|
|
log_path = opal_os_path(false,
|
|
|
|
orte_process_info.tmpdir_base,
|
|
|
|
orte_process_info.top_session_dir,
|
|
|
|
log_file,
|
2005-05-01 12:27:14 +04:00
|
|
|
NULL);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-06-06 17:36:41 +04:00
|
|
|
fd = open(log_path, O_RDWR|O_CREAT|O_TRUNC, 0640);
|
2005-05-13 01:44:23 +04:00
|
|
|
if (fd < 0) {
|
|
|
|
/* couldn't open the file for some reason, so
|
|
|
|
* just connect everything to /dev/null
|
|
|
|
*/
|
2005-03-31 19:47:37 +04:00
|
|
|
fd = open("/dev/null", O_RDWR|O_CREAT|O_TRUNC, 0666);
|
2005-05-13 01:44:23 +04:00
|
|
|
} else {
|
2005-03-14 23:57:21 +03:00
|
|
|
dup2(fd, STDOUT_FILENO);
|
|
|
|
dup2(fd, STDERR_FILENO);
|
|
|
|
if(fd != STDOUT_FILENO && fd != STDERR_FILENO) {
|
|
|
|
close(fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-20 22:05:16 +04:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* setup the thread lock and condition variables */
|
2006-02-08 20:40:11 +03:00
|
|
|
OBJ_CONSTRUCT(&orted_globals.mutex, opal_mutex_t);
|
|
|
|
OBJ_CONSTRUCT(&orted_globals.condition, opal_condition_t);
|
2005-09-19 20:01:29 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* register the daemon main receive functions */
|
Bring over the update to terminate orteds that are generated by a dynamic spawn such as comm_spawn. This introduces the concept of a job "family" - i.e., jobs that have a parent/child relationship. Comm_spawn'ed jobs have a parent (the one that spawned them). We track that relationship throughout the lineage - i.e., if a comm_spawned job in turn calls comm_spawn, then it has a parent (the one that spawned it) and a "root" job (the original job that started things).
Accordingly, there are new APIs to the name service to support the ability to get a job's parent, root, immediate children, and all its descendants. In addition, the terminate_job, terminate_orted, and signal_job APIs for the PLS have been modified to accept attributes that define the extent of their actions. For example, doing a "terminate_job" with an attribute of ORTE_NS_INCLUDE_DESCENDANTS will terminate the given jobid AND all jobs that descended from it.
I have tested this capability on a MacBook under rsh, Odin under SLURM, and LANL's Flash (bproc). It worked successfully on non-MPI jobs (both simple and including a spawn), and MPI jobs (again, both simple and with a spawn).
This commit was SVN r12597.
2006-11-14 22:34:59 +03:00
|
|
|
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_PLS_ORTED, ORTE_RML_NON_PERSISTENT, orte_daemon_recv_pls, NULL);
|
2006-09-15 01:29:51 +04:00
|
|
|
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
Bring over the update to terminate orteds that are generated by a dynamic spawn such as comm_spawn. This introduces the concept of a job "family" - i.e., jobs that have a parent/child relationship. Comm_spawn'ed jobs have a parent (the one that spawned them). We track that relationship throughout the lineage - i.e., if a comm_spawned job in turn calls comm_spawn, then it has a parent (the one that spawned it) and a "root" job (the original job that started things).
Accordingly, there are new APIs to the name service to support the ability to get a job's parent, root, immediate children, and all its descendants. In addition, the terminate_job, terminate_orted, and signal_job APIs for the PLS have been modified to accept attributes that define the extent of their actions. For example, doing a "terminate_job" with an attribute of ORTE_NS_INCLUDE_DESCENDANTS will terminate the given jobid AND all jobs that descended from it.
I have tested this capability on a MacBook under rsh, Odin under SLURM, and LANL's Flash (bproc). It worked successfully on non-MPI jobs (both simple and including a spawn), and MPI jobs (again, both simple and with a spawn).
This commit was SVN r12597.
2006-11-14 22:34:59 +03:00
|
|
|
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_DAEMON, ORTE_RML_NON_PERSISTENT, orte_daemon_recv, NULL);
|
2006-09-15 01:29:51 +04:00
|
|
|
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/* check to see if I'm a bootproxy */
|
|
|
|
if (orted_globals.bootproxy) { /* perform bootproxy-specific things */
|
2007-02-01 22:31:44 +03:00
|
|
|
/* a daemon should *always* yield the processor when idle */
|
|
|
|
opal_progress_set_yield_when_idle(true);
|
2005-08-19 22:56:44 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* attach a subscription to the orted standard trigger so I can get
|
|
|
|
* information on the processes I am to locally launch as soon as all
|
|
|
|
* the orteds for this job are started.
|
|
|
|
*
|
|
|
|
* Once the registry gets to 2.0, we will be able to setup the
|
|
|
|
* subscription so we only get our own launch info back. In the interim,
|
|
|
|
* we setup the subscription so that ALL launch info for this job
|
|
|
|
* is returned. We will then have to parse that message to get our
|
|
|
|
* own local launch info.
|
|
|
|
*
|
|
|
|
* Since we have chosen this approach, we can take advantage of the
|
|
|
|
* fact that the callback function will directly receive this data.
|
|
|
|
* By setting up that callback function to actually perform the launch
|
|
|
|
* based on the received data, all we have to do here is go into our
|
|
|
|
* conditioned wait until the job completes!
|
|
|
|
*
|
|
|
|
* Sometimes, life can be good! :-)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** put all this registry stuff in a compound command to limit communications */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_gpr.begin_compound_cmd())) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* let the local launcher setup a subscription for its required data. We
|
|
|
|
* pass the local_cb_launcher function so that this gets called back - this
|
|
|
|
* allows us to wakeup the orted so it can exit cleanly if the callback
|
|
|
|
* generates an error
|
|
|
|
*/
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_odls.subscribe_launch_data(orted_globals.bootproxy, orted_local_cb_launcher))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the job segment name */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_schema.get_job_segment_name(&segment, orted_globals.bootproxy))) {
|
2005-09-13 06:37:34 +04:00
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2005-09-13 06:37:34 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/** increment the orted stage gate counter */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_gpr.create_value(&value, ORTE_GPR_KEYS_OR|ORTE_GPR_TOKENS_AND,
|
|
|
|
segment, 1, 1))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
free(segment); /* done with this now */
|
|
|
|
|
|
|
|
value->tokens[0] = strdup(ORTE_JOB_GLOBALS);
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_gpr.create_keyval(&(value->keyvals[0]), ORTED_LAUNCH_STAGE_GATE_CNTR, ORTE_UNDEF, NULL))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
2005-09-17 00:45:25 +04:00
|
|
|
}
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* do the increment */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_gpr.increment_value(value))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
OBJ_RELEASE(value); /* done with this now */
|
|
|
|
|
|
|
|
/** send the compound command */
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_gpr.exec_compound_cmd())) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup and enter the event monitor to wait for a wakeup call */
|
2005-09-13 06:37:34 +04:00
|
|
|
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);
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2006-11-11 07:03:45 +03:00
|
|
|
/* make sure our local procs are dead - but don't update their state
|
|
|
|
* on the HNP as this may be redundant
|
|
|
|
*/
|
2006-11-17 00:15:25 +03:00
|
|
|
orte_odls.kill_local_procs(ORTE_JOBID_WILDCARD, false);
|
2006-11-11 07:03:45 +03:00
|
|
|
|
2006-11-15 18:09:28 +03:00
|
|
|
/* cleanup their session directory */
|
2006-02-16 03:16:22 +03:00
|
|
|
orte_session_dir_cleanup(orted_globals.bootproxy);
|
|
|
|
|
2006-11-15 18:09:28 +03:00
|
|
|
/* send an ack - we are as close to done as we can be while
|
|
|
|
* still able to communicate
|
|
|
|
*/
|
|
|
|
OBJ_CONSTRUCT(&answer, orte_buffer_t);
|
|
|
|
if (0 > orte_rml.send_buffer(ORTE_PROC_MY_HNP, &answer, ORTE_RML_TAG_PLS_ORTED_ACK, 0)) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&answer);
|
|
|
|
|
|
|
|
|
|
|
|
/* Finalize and clean up ourselves */
|
2005-03-14 23:57:21 +03:00
|
|
|
if (ORTE_SUCCESS != (ret = orte_finalize())) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
|
|
|
exit(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2006-09-15 01:29:51 +04:00
|
|
|
* Set my process status to "running". Note that this must be done
|
2005-03-14 23:57:21 +03:00
|
|
|
* after the rte init is completed.
|
|
|
|
*/
|
2006-08-16 20:35:09 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = orte_smr.set_proc_state(orte_process_info.my_name,
|
2005-03-14 23:57:21 +03:00
|
|
|
ORTE_PROC_STATE_RUNNING, 0))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
2006-02-08 20:40:11 +03:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] ompid: issuing callback", ORTE_NAME_ARGS(orte_process_info.my_name));
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* go through the universe fields and see what else I need to do
|
|
|
|
* - could be setup a virtual machine, spawn a console, etc.
|
|
|
|
*/
|
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
2006-02-08 20:40:11 +03:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] ompid: setting up event monitor", ORTE_NAME_ARGS(orte_process_info.my_name));
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* setup and enter the event monitor */
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
while (false == orted_globals.exit_condition) {
|
2006-02-08 20:40:11 +03:00
|
|
|
opal_condition_wait(&orted_globals.condition, &orted_globals.mutex);
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
2006-11-13 21:51:18 +03:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted: mutex cleared - finalizing", ORTE_NAME_ARGS(orte_process_info.my_name));
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
if (NULL != log_path) {
|
|
|
|
unlink(log_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* finalize the system */
|
|
|
|
orte_finalize();
|
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
2006-11-13 21:51:18 +03:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted: done - exiting", ORTE_NAME_ARGS(orte_process_info.my_name));
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* this function receives the trigger callback from the orted launch stage gate
|
|
|
|
* and passes it to the orted local launcher for processing. We do this intermediate
|
|
|
|
* step so that we can get an error code if anything went wrong and, if so, wakeup the
|
|
|
|
* orted so we can gracefully die
|
|
|
|
*/
|
|
|
|
static void orted_local_cb_launcher(orte_gpr_notify_data_t *data, void *user_tag)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
2006-11-13 21:51:18 +03:00
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted: received launch callback", ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* pass the data to the orted_local_launcher and get a report on
|
|
|
|
* success or failure of the launch
|
|
|
|
*/
|
2006-10-11 19:18:57 +04:00
|
|
|
if (ORTE_SUCCESS != (rc = orte_odls.launch_local_procs(data, orted_globals.saved_environ))) {
|
2006-10-23 17:27:31 +04:00
|
|
|
/* if there was an error, report it.
|
|
|
|
* NOTE: it is absolutely imperative that we do not cause the orted to EXIT when
|
|
|
|
* this happens!!! If we do, then the HNP will "hang" as the orted will no longer
|
|
|
|
* be around to receive messages telling it what to do in response to the failure
|
|
|
|
*/
|
2006-09-15 01:29:51 +04:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* all done - return and let the orted sleep until something happens */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-26 22:56:08 +04:00
|
|
|
static void signal_callback(int fd, short flags, void *arg)
|
|
|
|
{
|
2005-09-19 21:20:01 +04:00
|
|
|
OPAL_TRACE(1);
|
2005-08-26 22:56:08 +04:00
|
|
|
orted_globals.exit_condition = true;
|
|
|
|
opal_condition_signal(&orted_globals.condition);
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
static void orte_daemon_recv_pls(int status, orte_process_name_t* sender,
|
2006-02-08 20:40:11 +03:00
|
|
|
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
|
|
|
void* cbdata)
|
2005-03-14 23:57:21 +03:00
|
|
|
{
|
|
|
|
orte_daemon_cmd_flag_t command;
|
2006-11-15 18:09:28 +03:00
|
|
|
orte_buffer_t answer;
|
2005-03-14 23:57:21 +03:00
|
|
|
int ret;
|
2006-08-15 23:54:10 +04:00
|
|
|
orte_std_cntr_t n;
|
2006-09-15 01:29:51 +04:00
|
|
|
int32_t signal;
|
|
|
|
orte_gpr_notify_data_t *ndat;
|
|
|
|
orte_jobid_t job;
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-09-19 21:20:01 +04:00
|
|
|
OPAL_TRACE(1);
|
2006-02-08 20:40:11 +03:00
|
|
|
|
2005-07-04 02:45:48 +04:00
|
|
|
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-05-13 01:44:23 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
2006-10-21 06:53:19 +04:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv_pls: received message from [%ld,%ld,%ld]",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name),
|
|
|
|
ORTE_NAME_ARGS(sender));
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/* unpack the command */
|
|
|
|
n = 1;
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.unpack(buffer, &command, &n, ORTE_DAEMON_CMD))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
2006-09-19 17:05:40 +04:00
|
|
|
goto CLEANUP;
|
2006-09-15 01:29:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(command) {
|
|
|
|
|
|
|
|
/**** KILL_LOCAL_PROCS ****/
|
|
|
|
case ORTE_DAEMON_KILL_LOCAL_PROCS:
|
2006-10-21 06:53:19 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv_pls: received kill_local_procs",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
2006-09-15 01:29:51 +04:00
|
|
|
/* unpack the jobid - could be JOBID_WILDCARD, which would indicatge
|
|
|
|
* we should kill all local procs. Otherwise, only kill those within
|
|
|
|
* the specified jobid
|
|
|
|
*/
|
|
|
|
n = 1;
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.unpack(buffer, &job, &n, ORTE_JOBID))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
2006-11-14 01:08:47 +03:00
|
|
|
goto CLEANUP;
|
2006-09-15 01:29:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_odls.kill_local_procs(job, true))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
/**** SIGNAL_LOCAL_PROCS ****/
|
|
|
|
case ORTE_DAEMON_SIGNAL_LOCAL_PROCS:
|
2006-10-21 06:53:19 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv_pls: received signal_local_procs",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
2006-09-15 01:29:51 +04:00
|
|
|
/* get the signal */
|
|
|
|
n = 1;
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.unpack(buffer, &signal, &n, ORTE_INT32))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
2006-11-14 01:08:47 +03:00
|
|
|
goto CLEANUP;
|
2006-09-15 01:29:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* see if they specified a process to signal, or if we
|
|
|
|
* should just signal them all
|
|
|
|
*
|
|
|
|
* NOTE: FOR NOW, WE JUST SIGNAL ALL CHILDREN
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_odls.signal_local_procs(NULL, signal))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
/**** ADD_LOCAL_PROCS ****/
|
|
|
|
case ORTE_DAEMON_ADD_LOCAL_PROCS:
|
2006-10-21 06:53:19 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv_pls: received add_local_procs",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
2006-09-15 01:29:51 +04:00
|
|
|
/* unpack the notify data object */
|
2006-11-16 00:12:27 +03:00
|
|
|
n = 1;
|
2006-09-15 01:29:51 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.unpack(buffer, &ndat, &n, ORTE_GPR_NOTIFY_DATA))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
2006-11-14 01:08:47 +03:00
|
|
|
goto CLEANUP;
|
2006-09-15 01:29:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* launch the processes */
|
2006-10-11 19:18:57 +04:00
|
|
|
if (ORTE_SUCCESS != (ret = orte_odls.launch_local_procs(ndat, orted_globals.saved_environ))) {
|
2006-09-15 01:29:51 +04:00
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup the memory */
|
|
|
|
OBJ_RELEASE(ndat);
|
|
|
|
break;
|
|
|
|
|
|
|
|
/**** EXIT COMMAND ****/
|
|
|
|
case ORTE_DAEMON_EXIT_CMD:
|
2006-10-21 06:53:19 +04:00
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv_pls: received exit",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
2006-11-15 18:09:28 +03:00
|
|
|
/* no response to send here - we'll send it when nearly exit'd */
|
2006-09-15 01:29:51 +04:00
|
|
|
orted_globals.exit_condition = true;
|
|
|
|
opal_condition_signal(&orted_globals.condition);
|
2006-11-15 18:09:28 +03:00
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
|
|
|
return;
|
2006-09-15 01:29:51 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CLEANUP:
|
2006-11-15 18:09:28 +03:00
|
|
|
/* send an ack that command is done */
|
|
|
|
OBJ_CONSTRUCT(&answer, orte_buffer_t);
|
|
|
|
if (0 > orte_rml.send_buffer(sender, &answer, ORTE_RML_TAG_PLS_ORTED_ACK, 0)) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&answer);
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
|
|
|
|
|
|
|
/* reissue the non-blocking receive */
|
Bring over the update to terminate orteds that are generated by a dynamic spawn such as comm_spawn. This introduces the concept of a job "family" - i.e., jobs that have a parent/child relationship. Comm_spawn'ed jobs have a parent (the one that spawned them). We track that relationship throughout the lineage - i.e., if a comm_spawned job in turn calls comm_spawn, then it has a parent (the one that spawned it) and a "root" job (the original job that started things).
Accordingly, there are new APIs to the name service to support the ability to get a job's parent, root, immediate children, and all its descendants. In addition, the terminate_job, terminate_orted, and signal_job APIs for the PLS have been modified to accept attributes that define the extent of their actions. For example, doing a "terminate_job" with an attribute of ORTE_NS_INCLUDE_DESCENDANTS will terminate the given jobid AND all jobs that descended from it.
I have tested this capability on a MacBook under rsh, Odin under SLURM, and LANL's Flash (bproc). It worked successfully on non-MPI jobs (both simple and including a spawn), and MPI jobs (again, both simple and with a spawn).
This commit was SVN r12597.
2006-11-14 22:34:59 +03:00
|
|
|
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_PLS_ORTED, ORTE_RML_NON_PERSISTENT, orte_daemon_recv_pls, NULL);
|
2006-09-15 01:29:51 +04:00
|
|
|
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-11-18 07:47:51 +03:00
|
|
|
static void exit_callback(int fd, short event, void *arg)
|
|
|
|
{
|
|
|
|
/* Trigger the normal exit conditions */
|
|
|
|
orted_globals.exit_condition = true;
|
|
|
|
opal_condition_signal(&orted_globals.condition);
|
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void halt_vm(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct timeval tv = { 1, 0 };
|
|
|
|
opal_event_t* event;
|
|
|
|
opal_list_t attrs;
|
|
|
|
opal_list_item_t *item;
|
|
|
|
|
|
|
|
/* terminate the vm - this will also wake us up so we can exit */
|
|
|
|
OBJ_CONSTRUCT(&attrs, opal_list_t);
|
|
|
|
orte_rmgr.add_attribute(&attrs, ORTE_NS_INCLUDE_DESCENDANTS, ORTE_UNDEF, NULL, ORTE_RMGR_ATTR_OVERRIDE);
|
2007-01-25 17:17:44 +03:00
|
|
|
ret = orte_pls.terminate_orteds(0, &orte_abort_timeout, &attrs);
|
2006-11-18 07:47:51 +03:00
|
|
|
while (NULL != (item = opal_list_remove_first(&attrs))) OBJ_RELEASE(item);
|
|
|
|
OBJ_DESTRUCT(&attrs);
|
|
|
|
|
|
|
|
/* setup a delay to give the orteds time to complete their departure */
|
|
|
|
if (NULL != (event = (opal_event_t*)malloc(sizeof(opal_event_t)))) {
|
|
|
|
opal_evtimer_set(event, exit_callback, NULL);
|
|
|
|
opal_evtimer_add(event, &tv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
static void orte_daemon_recv(int status, orte_process_name_t* sender,
|
|
|
|
orte_buffer_t *buffer, orte_rml_tag_t tag,
|
|
|
|
void* cbdata)
|
|
|
|
{
|
|
|
|
orte_buffer_t *answer;
|
|
|
|
orte_daemon_cmd_flag_t command;
|
|
|
|
int ret;
|
|
|
|
orte_std_cntr_t n;
|
|
|
|
char *contact_info;
|
|
|
|
|
|
|
|
OPAL_TRACE(1);
|
|
|
|
|
|
|
|
OPAL_THREAD_LOCK(&orted_globals.mutex);
|
|
|
|
|
|
|
|
if (orted_globals.debug_daemons) {
|
2006-10-21 06:53:19 +04:00
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv: received message from [%ld,%ld,%ld]",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name),
|
|
|
|
ORTE_NAME_ARGS(sender));
|
2006-09-15 01:29:51 +04:00
|
|
|
}
|
|
|
|
|
2006-11-18 07:47:51 +03:00
|
|
|
n = 1;
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.unpack(buffer, &command, &n, ORTE_DAEMON_CMD))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
answer = OBJ_NEW(orte_buffer_t);
|
|
|
|
if (NULL == answer) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE);
|
|
|
|
goto DONE;
|
|
|
|
}
|
|
|
|
|
2006-11-18 07:47:51 +03:00
|
|
|
switch(command) {
|
|
|
|
/**** EXIT COMMAND ****/
|
|
|
|
case ORTE_DAEMON_EXIT_CMD:
|
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv: received exit",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
|
|
|
|
|
|
|
orted_globals.exit_condition = true;
|
|
|
|
opal_condition_signal(&orted_globals.condition);
|
|
|
|
break;
|
|
|
|
|
|
|
|
/**** HALT VM COMMAND ****/
|
|
|
|
case ORTE_DAEMON_HALT_VM_CMD:
|
|
|
|
if (orted_globals.debug_daemons) {
|
|
|
|
opal_output(0, "[%lu,%lu,%lu] orted_recv: received halt vm",
|
|
|
|
ORTE_NAME_ARGS(orte_process_info.my_name));
|
|
|
|
}
|
|
|
|
halt_vm();
|
|
|
|
break;
|
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
/**** CONTACT QUERY COMMAND ****/
|
2006-11-18 07:47:51 +03:00
|
|
|
case ORTE_DAEMON_CONTACT_QUERY_CMD:
|
|
|
|
/* send back contact info */
|
|
|
|
contact_info = orte_rml.get_uri();
|
|
|
|
|
|
|
|
if (NULL == contact_info) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERROR);
|
|
|
|
goto CLEANUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ORTE_SUCCESS != (ret = orte_dss.pack(answer, &contact_info, 1, ORTE_STRING))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
goto CLEANUP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0 > orte_rml.send_buffer(sender, answer, tag, 0)) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
|
|
|
}
|
|
|
|
break;
|
2006-09-15 01:29:51 +04:00
|
|
|
|
|
|
|
/**** HOSTFILE COMMAND ****/
|
2006-11-18 07:47:51 +03:00
|
|
|
case ORTE_DAEMON_HOSTFILE_CMD:
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_NOT_IMPLEMENTED);
|
|
|
|
break;
|
2006-09-15 01:29:51 +04:00
|
|
|
|
|
|
|
/**** SCRIPTFILE COMMAND ****/
|
2006-11-18 07:47:51 +03:00
|
|
|
case ORTE_DAEMON_SCRIPTFILE_CMD:
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_NOT_IMPLEMENTED);
|
|
|
|
break;
|
2006-09-15 01:29:51 +04:00
|
|
|
|
|
|
|
/**** HEARTBEAT COMMAND ****/
|
2006-11-18 07:47:51 +03:00
|
|
|
case ORTE_DAEMON_HEARTBEAT_CMD:
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_NOT_IMPLEMENTED);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
|
2005-08-11 20:57:06 +04:00
|
|
|
}
|
2006-09-15 01:29:51 +04:00
|
|
|
|
|
|
|
CLEANUP:
|
2006-11-18 07:47:51 +03:00
|
|
|
OBJ_RELEASE(answer);
|
2006-09-15 01:29:51 +04:00
|
|
|
|
|
|
|
DONE:
|
2006-11-18 07:47:51 +03:00
|
|
|
OPAL_THREAD_UNLOCK(&orted_globals.mutex);
|
2006-09-15 01:29:51 +04:00
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/* reissue the non-blocking receive */
|
Bring over the update to terminate orteds that are generated by a dynamic spawn such as comm_spawn. This introduces the concept of a job "family" - i.e., jobs that have a parent/child relationship. Comm_spawn'ed jobs have a parent (the one that spawned them). We track that relationship throughout the lineage - i.e., if a comm_spawned job in turn calls comm_spawn, then it has a parent (the one that spawned it) and a "root" job (the original job that started things).
Accordingly, there are new APIs to the name service to support the ability to get a job's parent, root, immediate children, and all its descendants. In addition, the terminate_job, terminate_orted, and signal_job APIs for the PLS have been modified to accept attributes that define the extent of their actions. For example, doing a "terminate_job" with an attribute of ORTE_NS_INCLUDE_DESCENDANTS will terminate the given jobid AND all jobs that descended from it.
I have tested this capability on a MacBook under rsh, Odin under SLURM, and LANL's Flash (bproc). It worked successfully on non-MPI jobs (both simple and including a spawn), and MPI jobs (again, both simple and with a spawn).
This commit was SVN r12597.
2006-11-14 22:34:59 +03:00
|
|
|
ret = orte_rml.recv_buffer_nb(ORTE_NAME_WILDCARD, ORTE_RML_TAG_DAEMON, ORTE_RML_NON_PERSISTENT, orte_daemon_recv, NULL);
|
2005-03-14 23:57:21 +03:00
|
|
|
if (ret != ORTE_SUCCESS && ret != ORTE_ERR_NOT_IMPLEMENTED) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
|
|
|
}
|
2006-09-15 01:29:51 +04:00
|
|
|
|
2005-09-13 06:37:34 +04:00
|
|
|
return;
|
|
|
|
}
|