2005-03-31 15:47:37 +00:00
|
|
|
/*
|
2007-03-16 23:11:45 +00:00
|
|
|
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
2005-11-05 19:57:48 +00:00
|
|
|
* 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.
|
2006-02-08 17:40:11 +00:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
2005-03-31 15:47:37 +00:00
|
|
|
* University of Stuttgart. All rights reserved.
|
|
|
|
* $COPYRIGHT$
|
2006-02-08 17:40:11 +00:00
|
|
|
*
|
2005-03-31 15:47:37 +00:00
|
|
|
* Additional copyrights may follow
|
2006-02-08 17:40:11 +00:00
|
|
|
*
|
2005-03-31 15:47:37 +00:00
|
|
|
* $HEADER$
|
|
|
|
*/
|
2005-09-19 15:29:14 +00:00
|
|
|
#include "orte_config.h"
|
2005-03-31 15:47:37 +00:00
|
|
|
#include <errno.h>
|
2005-12-12 20:04:00 +00:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2005-03-31 15:47:37 +00:00
|
|
|
#include <unistd.h>
|
2005-12-12 20:04:00 +00:00
|
|
|
#endif /* HAVE_UNISTD_H */
|
|
|
|
#ifdef HAVE_STRING_H
|
2005-03-31 15:47:37 +00:00
|
|
|
#include <string.h>
|
2005-12-12 20:04:00 +00:00
|
|
|
#endif /* HAVE_STRING_H */
|
2005-03-31 15:47:37 +00:00
|
|
|
|
2006-02-12 01:33:29 +00:00
|
|
|
#include "orte/orte_constants.h"
|
2006-10-17 16:06:17 +00:00
|
|
|
|
|
|
|
#include "opal/class/opal_list.h"
|
2005-07-03 23:31:27 +00:00
|
|
|
#include "opal/util/output.h"
|
2005-09-19 15:29:14 +00:00
|
|
|
#include "opal/util/trace.h"
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
#include "orte/mca/rds/rds.h"
|
|
|
|
#include "orte/mca/ras/ras.h"
|
|
|
|
#include "orte/mca/rmaps/rmaps.h"
|
|
|
|
#include "orte/mca/pls/pls.h"
|
2005-09-19 15:29:14 +00:00
|
|
|
#include "orte/mca/errmgr/errmgr.h"
|
|
|
|
#include "orte/mca/rml/rml.h"
|
|
|
|
#include "orte/mca/iof/iof.h"
|
2006-09-14 21:29:51 +00:00
|
|
|
#include "orte/mca/smr/smr.h"
|
2005-09-19 15:29:14 +00:00
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
#include "orte/mca/rmgr/base/rmgr_private.h"
|
2005-09-19 15:29:14 +00:00
|
|
|
#include "orte/mca/rmgr/proxy/rmgr_proxy.h"
|
2005-03-31 15:47:37 +00:00
|
|
|
|
|
|
|
|
2006-11-13 18:51:18 +00:00
|
|
|
static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
|
|
|
orte_std_cntr_t num_context,
|
|
|
|
orte_jobid_t* jobid,
|
|
|
|
opal_list_t *attributes);
|
2005-03-31 15:47:37 +00:00
|
|
|
|
2006-10-03 02:07:58 +00:00
|
|
|
static int orte_rmgr_proxy_setup_stage_gates(orte_jobid_t jobid);
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
static int orte_rmgr_proxy_spawn_job(
|
2005-03-31 15:47:37 +00:00
|
|
|
orte_app_context_t** app_context,
|
2006-08-15 19:54:10 +00:00
|
|
|
orte_std_cntr_t num_context,
|
2005-03-31 15:47:37 +00:00
|
|
|
orte_jobid_t* jobid,
|
2006-09-19 01:45:05 +00:00
|
|
|
orte_std_cntr_t num_connect,
|
|
|
|
orte_process_name_t *connect,
|
2006-02-08 17:40:11 +00:00
|
|
|
orte_rmgr_cb_fn_t cbfn,
|
2006-10-17 16:06:17 +00:00
|
|
|
orte_proc_state_t cb_conditions,
|
|
|
|
opal_list_t *attributes);
|
2005-03-31 15:47:37 +00:00
|
|
|
|
|
|
|
orte_rmgr_base_module_t orte_rmgr_proxy_module = {
|
2006-09-14 21:29:51 +00:00
|
|
|
NULL, /* don't need special init */
|
|
|
|
orte_rmgr_proxy_setup_job,
|
|
|
|
orte_rmgr_proxy_spawn_job,
|
2006-09-19 01:45:05 +00:00
|
|
|
orte_rmgr_base_connect,
|
|
|
|
orte_rmgr_base_disconnect,
|
2005-03-31 15:47:37 +00:00
|
|
|
NULL, /* finalize */
|
2006-09-14 21:29:51 +00:00
|
|
|
/** SUPPORT FUNCTIONS ***/
|
2006-10-17 16:06:17 +00:00
|
|
|
orte_rmgr_base_find_attribute,
|
|
|
|
orte_rmgr_base_add_attribute,
|
2006-10-18 20:02:16 +00:00
|
|
|
orte_rmgr_base_merge_attributes,
|
2006-10-17 16:06:17 +00:00
|
|
|
orte_rmgr_base_delete_attribute,
|
2006-09-14 21:29:51 +00:00
|
|
|
orte_rmgr_base_get_app_context,
|
|
|
|
orte_rmgr_base_put_app_context,
|
|
|
|
orte_rmgr_base_check_context_cwd,
|
|
|
|
orte_rmgr_base_check_context_app,
|
2007-03-16 23:11:45 +00:00
|
|
|
orte_rmgr_base_set_proc_info,
|
|
|
|
orte_rmgr_base_get_proc_info
|
2005-03-31 15:47:37 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2006-09-14 21:29:51 +00:00
|
|
|
* Setup the job segment and initialize the application context. Could
|
|
|
|
* do this in the proxy - but allowing the HNP to do this moves the registry
|
|
|
|
* and name service actions to the HNP for efficiency.
|
2005-03-31 15:47:37 +00:00
|
|
|
*/
|
|
|
|
|
2006-11-13 18:51:18 +00:00
|
|
|
static int orte_rmgr_proxy_setup_job(orte_app_context_t** app_context,
|
|
|
|
orte_std_cntr_t num_context,
|
|
|
|
orte_jobid_t* jobid,
|
|
|
|
opal_list_t *attrs)
|
2005-03-31 15:47:37 +00:00
|
|
|
{
|
|
|
|
orte_buffer_t cmd;
|
|
|
|
orte_buffer_t rsp;
|
2006-09-14 21:29:51 +00:00
|
|
|
orte_std_cntr_t count;
|
2006-09-29 21:44:11 +00:00
|
|
|
orte_rmgr_cmd_t command=ORTE_RMGR_SETUP_JOB_CMD;
|
2005-03-31 15:47:37 +00:00
|
|
|
int rc;
|
|
|
|
|
2005-09-19 15:29:14 +00:00
|
|
|
OPAL_TRACE(1);
|
2006-02-08 17:40:11 +00:00
|
|
|
|
2005-03-31 15:47:37 +00:00
|
|
|
/* construct command */
|
|
|
|
OBJ_CONSTRUCT(&cmd, orte_buffer_t);
|
2006-09-29 21:10:48 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
/* pack the number of app_contexts */
|
|
|
|
if(ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, &num_context, 1, ORTE_STD_CNTR))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-09-14 21:29:51 +00:00
|
|
|
|
|
|
|
/* and pack them */
|
|
|
|
if(ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, app_context, num_context, ORTE_APP_CONTEXT))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
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 19:34:59 +00:00
|
|
|
/* pack the attributes */
|
2006-11-13 18:51:18 +00:00
|
|
|
if (ORTE_SUCCESS != (rc = orte_dss.pack(&cmd, attrs, 1, ORTE_ATTR_LIST))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
/* send the command */
|
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 19:34:59 +00:00
|
|
|
if(0 > (rc = orte_rml.send_buffer(ORTE_PROC_MY_HNP, &cmd, ORTE_RML_TAG_RMGR, 0))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
|
|
|
|
/* wait for response */
|
|
|
|
OBJ_CONSTRUCT(&rsp, orte_buffer_t);
|
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 19:34:59 +00:00
|
|
|
if(0 > (rc = orte_rml.recv_buffer(ORTE_PROC_MY_HNP, &rsp, ORTE_RML_TAG_RMGR))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&rsp);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
/* get the returned command */
|
|
|
|
count = 1;
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_dss.unpack(&rsp, &command, &count, ORTE_RMGR_CMD))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&rsp);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-09-14 21:29:51 +00:00
|
|
|
/* and check it to ensure valid comm */
|
|
|
|
if (ORTE_RMGR_SETUP_JOB_CMD != command) {
|
2006-06-08 18:27:17 +00:00
|
|
|
OBJ_DESTRUCT(&rsp);
|
2006-09-14 21:29:51 +00:00
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
|
|
|
return ORTE_ERR_COMM_FAILURE;
|
2006-06-08 18:27:17 +00:00
|
|
|
}
|
2006-09-14 21:29:51 +00:00
|
|
|
|
|
|
|
/* get the jobid */
|
|
|
|
count = 1;
|
|
|
|
if(ORTE_SUCCESS != (rc = orte_dss.unpack(&rsp, jobid, &count, ORTE_JOBID))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
}
|
2006-09-14 21:29:51 +00:00
|
|
|
|
2005-03-31 15:47:37 +00:00
|
|
|
OBJ_DESTRUCT(&rsp);
|
2006-09-14 21:29:51 +00:00
|
|
|
return rc;
|
2005-03-31 15:47:37 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 02:07:58 +00:00
|
|
|
static int orte_rmgr_proxy_setup_stage_gates(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_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 */
|
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 19:34:59 +00:00
|
|
|
if(0 > (rc = orte_rml.send_buffer(ORTE_PROC_MY_HNP, &cmd, ORTE_RML_TAG_RMGR, 0))) {
|
2006-10-03 02:07:58 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
OBJ_DESTRUCT(&cmd);
|
|
|
|
|
|
|
|
/* wait for response */
|
|
|
|
OBJ_CONSTRUCT(&rsp, orte_buffer_t);
|
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 19:34:59 +00:00
|
|
|
if(0 > (rc = orte_rml.recv_buffer(ORTE_PROC_MY_HNP, &rsp, ORTE_RML_TAG_RMGR))) {
|
2006-10-03 02:07:58 +00:00
|
|
|
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_GATES_CMD != command) {
|
|
|
|
OBJ_DESTRUCT(&rsp);
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE);
|
|
|
|
return ORTE_ERR_COMM_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
OBJ_DESTRUCT(&rsp);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-30 19:44:28 +00:00
|
|
|
static void orte_rmgr_proxy_wireup_stdin(orte_jobid_t jobid)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
orte_process_name_t* name;
|
|
|
|
|
|
|
|
OPAL_TRACE(1);
|
|
|
|
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_ns.create_process_name(&name, 0, jobid, 0))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_iof.iof_push(name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDIN, 0))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-03-31 15:47:37 +00:00
|
|
|
static void orte_rmgr_proxy_callback(orte_gpr_notify_data_t *data, void *cbdata)
|
|
|
|
{
|
2006-03-29 01:26:16 +00:00
|
|
|
orte_rmgr_cb_fn_t cbfunc;
|
|
|
|
union {
|
|
|
|
orte_rmgr_cb_fn_t func;
|
|
|
|
void * ptr;
|
|
|
|
} cbfunc_union;
|
2005-07-18 18:49:00 +00:00
|
|
|
orte_gpr_value_t **values, *value;
|
2005-03-31 15:47:37 +00:00
|
|
|
orte_gpr_keyval_t** keyvals;
|
|
|
|
orte_jobid_t jobid;
|
2006-08-15 19:54:10 +00:00
|
|
|
orte_std_cntr_t i, j, k;
|
2005-05-01 00:47:35 +00:00
|
|
|
int rc;
|
2005-03-31 15:47:37 +00:00
|
|
|
|
2005-09-19 15:29:14 +00:00
|
|
|
OPAL_TRACE(1);
|
2006-02-08 17:40:11 +00:00
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
/* ISO C forbids conversion of object pointer to function
|
2006-03-29 01:26:16 +00:00
|
|
|
pointer. So we do this, which is the same thing, but without
|
|
|
|
the warning from GCC */
|
|
|
|
cbfunc_union.ptr = cbdata;
|
|
|
|
cbfunc = cbfunc_union.func;
|
|
|
|
|
2005-06-24 16:59:37 +00:00
|
|
|
/* we made sure in the subscriptions that at least one
|
|
|
|
* value is always returned
|
|
|
|
* get the jobid from the segment name in the first value
|
|
|
|
*/
|
2005-07-18 18:49:00 +00:00
|
|
|
values = (orte_gpr_value_t**)(data->values)->addr;
|
2005-06-24 16:59:37 +00:00
|
|
|
if (ORTE_SUCCESS != (rc =
|
|
|
|
orte_schema.extract_jobid_from_segment_name(&jobid,
|
|
|
|
values[0]->segment))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-07-18 18:49:00 +00:00
|
|
|
for(i = 0, k=0; k < data->cnt &&
|
|
|
|
i < (data->values)->size; i++) {
|
|
|
|
if (NULL != values[i]) {
|
|
|
|
k++;
|
|
|
|
value = values[i];
|
|
|
|
/* determine the state change */
|
|
|
|
keyvals = value->keyvals;
|
|
|
|
for(j=0; j<value->cnt; j++) {
|
|
|
|
orte_gpr_keyval_t* keyval = keyvals[j];
|
2006-02-08 17:40:11 +00:00
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_AT_INIT) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_INIT);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_LAUNCHED) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_LAUNCHED);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_RUNNING) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_RUNNING);
|
|
|
|
continue;
|
|
|
|
}
|
2005-07-18 18:49:00 +00:00
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_AT_STG1) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_AT_STG1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_AT_STG2) == 0) {
|
2005-11-10 15:29:52 +00:00
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_AT_STG2);
|
2005-07-18 18:49:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_AT_STG3) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_AT_STG3);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_FINALIZED) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_FINALIZED);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if(strcmp(keyval->key, ORTE_PROC_NUM_TERMINATED) == 0) {
|
|
|
|
(*cbfunc)(jobid,ORTE_PROC_STATE_TERMINATED);
|
|
|
|
continue;
|
|
|
|
}
|
2005-03-31 15:47:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-30 19:44:28 +00:00
|
|
|
/**
|
|
|
|
* define a callback point for completing the wireup of the stdin for io forwarding
|
|
|
|
*/
|
|
|
|
static void orte_rmgr_proxy_wireup_callback(orte_gpr_notify_data_t *data, void *cbdata)
|
|
|
|
{
|
|
|
|
orte_gpr_value_t **values;
|
|
|
|
orte_jobid_t jobid;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
OPAL_TRACE(1);
|
|
|
|
|
|
|
|
/* we made sure in the subscriptions that at least one
|
|
|
|
* value is always returned
|
|
|
|
* get the jobid from the segment name in the first value
|
|
|
|
*/
|
|
|
|
values = (orte_gpr_value_t**)(data->values)->addr;
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_schema.extract_jobid_from_segment_name(&jobid, values[0]->segment))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
orte_rmgr_proxy_wireup_stdin(jobid);
|
|
|
|
}
|
2005-03-31 15:47:37 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Shortcut for the multiple steps involved in spawning a new job.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2006-09-14 21:29:51 +00:00
|
|
|
static int orte_rmgr_proxy_spawn_job(
|
2005-03-31 15:47:37 +00:00
|
|
|
orte_app_context_t** app_context,
|
2006-08-15 19:54:10 +00:00
|
|
|
orte_std_cntr_t num_context,
|
2005-03-31 15:47:37 +00:00
|
|
|
orte_jobid_t* jobid,
|
2006-09-19 01:45:05 +00:00
|
|
|
orte_std_cntr_t num_connect,
|
|
|
|
orte_process_name_t *connect,
|
2006-02-08 17:40:11 +00:00
|
|
|
orte_rmgr_cb_fn_t cbfunc,
|
2006-10-17 16:06:17 +00:00
|
|
|
orte_proc_state_t cb_conditions,
|
|
|
|
opal_list_t *attributes)
|
2005-03-31 15:47:37 +00:00
|
|
|
{
|
|
|
|
int rc;
|
2006-10-02 14:58:22 +00:00
|
|
|
orte_process_name_t name = {0, ORTE_JOBID_INVALID, 0};
|
2006-11-02 05:15:24 +00:00
|
|
|
orte_attribute_t *flow;
|
|
|
|
uint8_t flags, *fptr;
|
2006-02-08 17:40:11 +00:00
|
|
|
|
2005-09-19 15:29:14 +00:00
|
|
|
OPAL_TRACE(1);
|
2006-11-02 05:15:24 +00:00
|
|
|
|
|
|
|
/* check for any flow directives to control what we do */
|
|
|
|
if (NULL != (flow = orte_rmgr.find_attribute(attributes, ORTE_RMGR_SPAWN_FLOW))) {
|
|
|
|
/* something was specified - get the value */
|
2006-11-03 20:45:22 +00:00
|
|
|
if (ORTE_SUCCESS != (rc = orte_dss.get((void**)&fptr, flow->value, ORTE_UINT8))) {
|
2006-11-02 05:15:24 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
flags = *fptr;
|
|
|
|
} else {
|
|
|
|
flags = 0xff;
|
|
|
|
}
|
|
|
|
|
2005-03-31 15:47:37 +00:00
|
|
|
/*
|
2006-09-14 21:29:51 +00:00
|
|
|
* Setup job and allocate resources
|
2005-03-31 15:47:37 +00:00
|
|
|
*/
|
2006-11-02 05:15:24 +00:00
|
|
|
if (flags & ORTE_RMGR_SETUP) {
|
|
|
|
if (ORTE_SUCCESS !=
|
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 19:34:59 +00:00
|
|
|
(rc = orte_rmgr_proxy_setup_job(app_context, num_context, jobid, attributes))) {
|
2006-11-02 05:15:24 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-10-31 23:52:25 +00:00
|
|
|
}
|
|
|
|
|
2006-12-06 15:59:34 +00:00
|
|
|
if (flags & ORTE_RMGR_RES_DISC) {
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_rds.query(*jobid))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-02 05:15:24 +00:00
|
|
|
if (flags & ORTE_RMGR_ALLOC) {
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_ras.allocate_job(*jobid, attributes))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-10-31 23:52:25 +00:00
|
|
|
}
|
|
|
|
|
2006-11-02 05:15:24 +00:00
|
|
|
if (flags & ORTE_RMGR_MAP) {
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_rmaps.map_job(*jobid, attributes))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-10-31 23:52:25 +00:00
|
|
|
}
|
|
|
|
|
2006-11-13 18:51:18 +00:00
|
|
|
if (flags & ORTE_RMGR_SETUP_TRIGS) {
|
|
|
|
/*
|
|
|
|
* setup I/O forwarding
|
|
|
|
*/
|
|
|
|
|
|
|
|
name.jobid = *jobid;
|
|
|
|
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDOUT, 1))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_iof.iof_pull(&name, ORTE_NS_CMP_JOBID, ORTE_IOF_STDERR, 2))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
2006-03-29 01:26:16 +00:00
|
|
|
|
2006-11-13 18:51:18 +00:00
|
|
|
/* setup the launch system's stage gate counters and subscriptions */
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_rmgr_proxy_setup_stage_gates(*jobid))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** setup the subscription so we can complete the wireup when all processes reach LAUNCHED */
|
|
|
|
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_wireup_callback, NULL, ORTE_PROC_STATE_LAUNCHED);
|
2005-03-31 15:47:37 +00:00
|
|
|
if(ORTE_SUCCESS != rc) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2006-11-13 18:51:18 +00:00
|
|
|
/*
|
|
|
|
* Define the ERRMGR's callbacks as required
|
|
|
|
*/
|
|
|
|
if (ORTE_SUCCESS != (rc = orte_errmgr.register_job(*jobid))) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* setup callback
|
|
|
|
*/
|
|
|
|
|
|
|
|
if(NULL != cbfunc) {
|
|
|
|
union {
|
|
|
|
orte_rmgr_cb_fn_t func;
|
|
|
|
void * ptr;
|
|
|
|
} cbfunc_union;
|
|
|
|
void *cbdata;
|
|
|
|
|
|
|
|
/* ISO C forbids conversion of object pointer to function
|
|
|
|
pointer. So we do this, which is the same thing, but without
|
|
|
|
the warning from GCC */
|
|
|
|
cbfunc_union.func = cbfunc;
|
|
|
|
cbdata = cbfunc_union.ptr;
|
|
|
|
|
|
|
|
rc = orte_smr.job_stage_gate_subscribe(*jobid, orte_rmgr_proxy_callback, cbdata, cb_conditions);
|
|
|
|
if(ORTE_SUCCESS != rc) {
|
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we don't want to launch, then just return here */
|
|
|
|
if (!(flags & ORTE_RMGR_LAUNCH)) {
|
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-03-31 15:47:37 +00:00
|
|
|
/*
|
|
|
|
* launch the job
|
|
|
|
*/
|
2006-09-14 21:29:51 +00:00
|
|
|
if (ORTE_SUCCESS != (rc = orte_pls.launch_job(*jobid))) {
|
2005-03-31 15:47:37 +00:00
|
|
|
ORTE_ERROR_LOG(rc);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|