1
1
openmpi/orte/mca/ras/bjs/ras_bjs.c
Josh Hursey 22c7f2b3e0 Quite a range of small changes.
ns_replica.c
 - Removed the error logging since I use this function in orte_init_stage1 to 
   check if we have created a cellid yet or not.

ras_types.h & rase_base_node.h
 - This was an empty file. moved the orte_ras_node_t from base/ras_base_node.h
   to this file.
 - Changed the name of orte_ras_base_node_t to orte_ras_node_t to match the 
   naming mechanisms in place.

ras.h
 - Exposed 2 functions:
   - node_insert:
     This takes a list of orte_ras_base_node_t's and places them in the Node 
     Segment of the GPR. This is to be used in orte_init_stage1 for singleton 
     processes, and the hostfile parsing (see rds_hostfile.c). This just puts 
     in the appropriate API interface to keep from calling the 
     orte_ras_base_node_insert function directly.
   - node_query:
     This is used in hostfile parsing. This just puts in the appropriate API 
     interface to keep from calling the orte_ras_base_node_query function 
     directly.
 - Touched all of the implemented components to add reference to these new 
   function pointers

ras_base_select.c & ras_base_open.c
 - Add and set the global module reference

rds.h
 - Exposed 1 function:
   - store_resource:
     This stores a list of rds_cell_desc_t's to the Resource Segment. 
     This is used in conjunction with the orte_ras.node_insert function in 
     both the orte_init_stage1 for singleton processes and rds_hostfile.c

rds_base_select.c & rds_base_open.c
 - Add and set the global module reference

rds_hostfile.c
 - Added functionality to create a new cellid for each hostfile, placing 
   each entry in the hostfile into the same cellid. Currently this is 
   commented out with the cellid hard coded to 0, with the intention of 
   taking this out once ORTE is able to handle multiple cellid's
 - Instead of just adding hosts to the Node Segment via a direct call to 
   the ras_base_node_insert() function. First add the hosts to the Resource 
   Segment of the GPR using the orte_rds.store_resource() function then use 
   the API version of orte_ras.node_insert() to store the hosts on the Node 
   Segment.
 - Add 1 new function pointer to module as required by the API.

rds_hostfile_component.c
 - Converted this to use the new MCA parameter registration

orte_init_stage1.c
 - It is possible that a cellid was not created yet for the current environment. 
   So I put in some logic to test if the cellid 0 existed. If it does then 
   continue, otherwise create the cellid so we can properly interact with the 
   GPR via the RDS.
 - For the singleton case we insert some 'dummy' data into the GPR. The RAS 
   matches this logic, so I took out the duplicate GPR put logic, and 
   replaced it with a call to the orte_ras.node_insert() function.
 - Further before calling orte_ras.node_insert() in the singleton case, 
   we also call orte_rds.store_resource() to add the singleton node to the 
   Resource Segment.

Console:
 - Added a bunch of new functions. Still experimenting with many aspects of the
   implementation. This is a checkpoint, and has very limited functionality.
 - Should not be considered stable at the moment.

This commit was SVN r6813.
2005-08-11 19:51:50 +00:00

285 строки
7.6 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* All rights reserved.
* 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 <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/bproc.h>
#include "include/orte_constants.h"
#include "include/orte_types.h"
#include "opal/util/argv.h"
#include "opal/util/output.h"
#include "mca/ras/base/base.h"
#include "mca/ras/base/ras_base_node.h"
#include "mca/errmgr/errmgr.h"
#include "ras_bjs.h"
/**
* Query the bproc node status
*/
static int orte_ras_bjs_node_state(int node)
{
#if defined BPROC_API_VERSION && BPROC_API_VERSION >= 4
char nodestatus[BPROC_STATE_LEN + 1];
bproc_nodestatus(node, nodestatus, sizeof(nodestatus));
if (strcmp(nodestatus, "up") == 0)
return ORTE_NODE_STATE_UP;
if (strcmp(nodestatus, "down") == 0)
return ORTE_NODE_STATE_DOWN;
if (strcmp(nodestatus, "boot") == 0)
return ORTE_NODE_STATE_REBOOT;
return ORTE_NODE_STATE_UNKNOWN;
#else
switch(bproc_nodestatus(node)) {
case bproc_node_up:
return ORTE_NODE_STATE_UP;
case bproc_node_down:
return ORTE_NODE_STATE_DOWN;
case bproc_node_boot:
return ORTE_NODE_STATE_REBOOT;
default:
return ORTE_NODE_STATE_UNKNOWN;
}
#endif
}
/**
* Parse the NODELIST to determine the number of process
* slots/processors available on the node.
*/
static size_t orte_ras_bjs_node_slots(char* node_name)
{
static char** nodelist = NULL;
char** ptr;
size_t count = 0;
if(nodelist == NULL)
nodelist = opal_argv_split(getenv("NODELIST"), ',');
ptr = nodelist;
while(ptr && *ptr) {
if(strcmp(*ptr, node_name) == 0)
count++;
ptr++;
}
return count;
}
/**
* Resolve the node name to node number.
*/
static int orte_ras_bjs_node_resolve(char* node_name, int* node_num)
{
/* for now we expect this to be the node number */
if(NULL == node_name || sscanf(node_name, "%d", node_num) != 1)
return ORTE_NODE_ERROR;
return ORTE_SUCCESS;
}
/**
* Discover the available resources.
* - validate any nodes specified via hostfile/commandline
* - check for additional nodes that have already been allocated
*/
static int orte_ras_bjs_discover(opal_list_t* nodelist)
{
char* nodes;
char* ptr;
opal_list_item_t* item;
opal_list_t new_nodes;
int rc;
/* query the nodelist from the registry */
OBJ_CONSTRUCT(&new_nodes, opal_list_t);
if(ORTE_SUCCESS != (rc = orte_ras_base_node_query(nodelist))) {
ORTE_ERROR_LOG(rc);
return rc;
}
/* validate that any user supplied nodes actually exist, etc. */
item = opal_list_get_first(nodelist);
while(item != opal_list_get_end(nodelist)) {
opal_list_item_t* next = opal_list_get_next(item);
int node_num;
orte_ras_node_t* node = (orte_ras_node_t*)item;
if(ORTE_SUCCESS != orte_ras_bjs_node_resolve(node->node_name, &node_num)) {
opal_list_remove_item(nodelist,item);
OBJ_DESTRUCT(item);
item = next;
continue;
}
if(orte_ras_bjs_node_state(node_num) != ORTE_NODE_STATE_UP) {
opal_list_remove_item(nodelist,item);
OBJ_DESTRUCT(item);
item = next;
continue;
}
if(bproc_access(node_num, BPROC_X_OK) != 0) {
opal_list_remove_item(nodelist,item);
OBJ_DESTRUCT(item);
item = next;
continue;
}
/* try and determine the number of available slots */
if(node->node_slots == 0) {
node->node_slots_inuse = 0;
node->node_slots_max = 0;
node->node_slots = orte_ras_bjs_node_slots(node->node_name);
}
item = next;
}
/* parse the node list and check node status/access */
nodes = getenv("NODES");
if(NULL == nodes) {
return opal_list_get_size(nodelist) ? ORTE_SUCCESS : ORTE_ERR_NOT_AVAILABLE;
}
OBJ_CONSTRUCT(&new_nodes, opal_list_t);
while(NULL != (ptr = strsep(&nodes,","))) {
orte_ras_node_t *node;
orte_node_state_t node_state;
int node_num;
/* is this node already in the list */
for(item = opal_list_get_first(nodelist);
item != opal_list_get_end(nodelist);
item = opal_list_get_next(item)) {
node = (orte_ras_node_t*)item;
if(strcmp(node->node_name, ptr) == 0)
break;
}
if(item != opal_list_get_end(nodelist))
continue;
if(sscanf(ptr, "%d", &node_num) != 1) {
continue;
}
if(ORTE_NODE_STATE_UP != (node_state = orte_ras_bjs_node_state(node_num))) {
opal_output(0, "error: a specified node (%d) is not up.\n", node_num);
rc = ORTE_NODE_DOWN;
goto cleanup;
}
if(bproc_access(node_num, BPROC_X_OK) != 0) {
opal_output(0, "error: a specified node (%d) is not accessible.\n", node_num);
rc = ORTE_NODE_ERROR;
goto cleanup;
}
/* create a new node entry */
node = OBJ_NEW(orte_ras_node_t);
node->node_name = strdup(ptr);
node->node_state = node_state;
node->node_cellid = 0;
node->node_slots_inuse = 0;
node->node_slots_max = 0;
node->node_slots = orte_ras_bjs_node_slots(node->node_name);
opal_list_append(&new_nodes, &node->super);
}
/* add any newly discovered nodes to the registry */
if(opal_list_get_size(&new_nodes)) {
rc = orte_ras_base_node_insert(&new_nodes);
if(ORTE_SUCCESS != rc) {
ORTE_ERROR_LOG(rc);
}
}
/* append them to the nodelist */
while(NULL != (item = opal_list_remove_first(&new_nodes)))
opal_list_append(nodelist, item);
cleanup:
OBJ_DESTRUCT(&new_nodes);
return rc;
}
/**
* Discover available (pre-allocated) nodes. Allocate the
* requested number of nodes/process slots to the job.
*
*/
static int orte_ras_bjs_allocate(orte_jobid_t jobid)
{
opal_list_t nodes;
opal_list_item_t* item;
int rc;
OBJ_CONSTRUCT(&nodes, opal_list_t);
if(ORTE_SUCCESS != (rc = orte_ras_bjs_discover(&nodes))) {
ORTE_ERROR_LOG(rc);
return rc;
}
if (0 == strcmp(mca_ras_bjs_component.schedule_policy, "node")) {
rc = orte_ras_base_allocate_nodes_by_node(jobid, &nodes);
} else {
rc = orte_ras_base_allocate_nodes_by_slot(jobid, &nodes);
}
if(ORTE_SUCCESS != rc) {
ORTE_ERROR_LOG(rc);
}
while(NULL != (item = opal_list_remove_first(&nodes)))
OBJ_RELEASE(item);
OBJ_DESTRUCT(&nodes);
return rc;
}
static int orte_ras_bjs_node_insert(opal_list_t *nodes)
{
return orte_ras_base_node_insert(nodes);
}
static int orte_ras_bjs_node_query(opal_list_t *nodes)
{
return orte_ras_base_node_query(nodes);
}
static int orte_ras_bjs_deallocate(orte_jobid_t jobid)
{
return ORTE_SUCCESS;
}
static int orte_ras_bjs_finalize(void)
{
return ORTE_SUCCESS;
}
orte_ras_base_module_t orte_ras_bjs_module = {
orte_ras_bjs_allocate,
orte_ras_bjs_node_insert,
orte_ras_bjs_node_query,
orte_ras_bjs_deallocate,
orte_ras_bjs_finalize
};