2005-03-14 23:57:21 +03:00
|
|
|
/*
|
2005-11-05 22:57:48 +03:00
|
|
|
* 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.
|
2005-03-14 23:57:21 +03:00
|
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
|
|
* 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.
|
2006-07-05 00:12:35 +04:00
|
|
|
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
2005-03-14 23:57:21 +03:00
|
|
|
* $COPYRIGHT$
|
|
|
|
*
|
|
|
|
* Additional copyrights may follow
|
|
|
|
*
|
|
|
|
* $HEADER$
|
|
|
|
*/
|
|
|
|
#include "orte_config.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "orte/constants.h"
|
|
|
|
#include "orte/types.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
2006-11-06 23:56:18 +03:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif /* HAVE_SYS_TIME_H */
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2005-07-04 04:13:44 +04:00
|
|
|
#include "opal/util/argv.h"
|
2005-07-04 03:31:27 +04:00
|
|
|
#include "opal/util/output.h"
|
2007-02-09 18:06:45 +03:00
|
|
|
#include "opal/util/os_path.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "opal/util/show_help.h"
|
2006-10-17 20:06:17 +04:00
|
|
|
|
2006-10-17 21:28:02 +04:00
|
|
|
#include "orte/mca/errmgr/errmgr.h"
|
2008-02-28 04:57:57 +03:00
|
|
|
#include "orte/runtime/orte_globals.h"
|
|
|
|
#include "orte/util/name_fns.h"
|
2006-10-17 20:06:17 +04:00
|
|
|
|
2006-09-15 01:29:51 +04:00
|
|
|
#include "orte/mca/ras/base/ras_private.h"
|
2005-03-14 23:57:21 +03:00
|
|
|
#include "ras_tm.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local functions
|
|
|
|
*/
|
2008-02-28 04:57:57 +03:00
|
|
|
static int allocate(opal_list_t *nodes);
|
2005-03-14 23:57:21 +03:00
|
|
|
static int finalize(void);
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
static int discover(opal_list_t* nodelist, char *pbs_jobid);
|
|
|
|
static char *tm_getline(FILE *fp);
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
#define TM_FILE_MAX_LINE_LENGTH 512
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
static char *filename;
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/*
|
|
|
|
* Global variable
|
|
|
|
*/
|
|
|
|
orte_ras_base_module_t orte_ras_tm_module = {
|
|
|
|
allocate,
|
|
|
|
finalize
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2008-02-28 04:57:57 +03:00
|
|
|
* Discover available (pre-allocated) nodes and report
|
|
|
|
* them back to the caller.
|
2005-03-14 23:57:21 +03:00
|
|
|
*
|
|
|
|
*/
|
2008-02-28 04:57:57 +03:00
|
|
|
static int allocate(opal_list_t *nodes)
|
2005-03-14 23:57:21 +03:00
|
|
|
{
|
|
|
|
int ret;
|
2007-02-09 18:06:45 +03:00
|
|
|
char *pbs_jobid;
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
/* get our PBS jobid from the environment */
|
|
|
|
if (NULL == (pbs_jobid = getenv("PBS_JOBID"))) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND);
|
|
|
|
return ORTE_ERR_NOT_FOUND;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2007-02-09 18:06:45 +03:00
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
if (ORTE_SUCCESS != (ret = discover(nodes, pbs_jobid))) {
|
|
|
|
ORTE_ERROR_LOG(ret);
|
2005-03-14 23:57:21 +03:00
|
|
|
return ret;
|
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
/* in the TM world, if we didn't find anything, then this
|
|
|
|
* is an unrecoverable error - report it
|
|
|
|
*/
|
|
|
|
if (opal_list_is_empty(nodes)) {
|
|
|
|
opal_show_help("help-ras-tm.txt", "no-nodes-found", true, filename);
|
|
|
|
return ORTE_ERR_NOT_FOUND;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2008-02-28 04:57:57 +03:00
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/* All done */
|
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* There's really nothing to do here
|
|
|
|
*/
|
|
|
|
static int finalize(void)
|
|
|
|
{
|
2008-02-28 04:57:57 +03:00
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
|
|
|
"%s ras:tm:finalize: success (nothing to do)",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
2005-03-14 23:57:21 +03:00
|
|
|
return ORTE_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Discover the available resources. Obtain directly from TM (and
|
|
|
|
* therefore have no need to validate) -- ignore hostfile or any other
|
|
|
|
* user-specified parameters.
|
|
|
|
*
|
|
|
|
* - validate any nodes specified via hostfile/commandline
|
|
|
|
* - check for additional nodes that have already been allocated
|
|
|
|
*/
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
static int discover(opal_list_t* nodelist, char *pbs_jobid)
|
2005-03-14 23:57:21 +03:00
|
|
|
{
|
2007-02-09 18:06:45 +03:00
|
|
|
int32_t nodeid;
|
2008-02-28 04:57:57 +03:00
|
|
|
orte_node_t *node;
|
2005-07-03 20:22:16 +04:00
|
|
|
opal_list_item_t* item;
|
2007-02-09 18:06:45 +03:00
|
|
|
FILE *fp;
|
2008-02-28 04:57:57 +03:00
|
|
|
char *hostname;
|
2006-11-06 21:41:22 +03:00
|
|
|
struct timeval start, stop;
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2006-11-06 21:41:22 +03:00
|
|
|
/* check for timing request - get start time if so */
|
2008-02-28 04:57:57 +03:00
|
|
|
if (orte_timing) {
|
2006-11-06 21:41:22 +03:00
|
|
|
gettimeofday(&start, NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
/* Ignore anything that the user already specified -- we're
|
|
|
|
getting nodes only from TM. */
|
|
|
|
|
|
|
|
/* TM "nodes" may actually correspond to PBS "VCPUs", which means
|
|
|
|
there may be multiple "TM nodes" that correspond to the same
|
|
|
|
physical node. This doesn't really affect what we're doing
|
|
|
|
here (we actually ignore the fact that they're duplicates --
|
|
|
|
slightly inefficient, but no big deal); just mentioned for
|
|
|
|
completeness... */
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
/* setup the full path to the PBS file */
|
|
|
|
filename = opal_os_path(false, mca_ras_tm_component.nodefile_dir,
|
|
|
|
pbs_jobid, NULL);
|
|
|
|
fp = fopen(filename, "r");
|
|
|
|
if (NULL == fp) {
|
|
|
|
ORTE_ERROR_LOG(ORTE_ERR_FILE_OPEN_FAILURE);
|
|
|
|
free(filename);
|
|
|
|
return ORTE_ERR_FILE_OPEN_FAILURE;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
2006-07-05 00:12:35 +04:00
|
|
|
/* Iterate through all the nodes and make an entry for each. TM
|
|
|
|
node ID's will never be duplicated, but they may end up
|
|
|
|
resolving to the same hostname (i.e., vcpu's on a single
|
|
|
|
host). */
|
2005-03-14 23:57:21 +03:00
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
nodeid=0;
|
|
|
|
while (NULL != (hostname = tm_getline(fp))) {
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
|
|
|
"%s ras:tm:allocate:discover: got hostname %s",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hostname));
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
/* Remember that TM may list the same node more than once. So
|
|
|
|
we have to check for duplicates. */
|
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
for (item = opal_list_get_first(nodelist);
|
|
|
|
opal_list_get_end(nodelist) != item;
|
2005-07-03 20:22:16 +04:00
|
|
|
item = opal_list_get_next(item)) {
|
2008-02-28 04:57:57 +03:00
|
|
|
node = (orte_node_t*) item;
|
|
|
|
if (0 == strcmp(node->name, hostname)) {
|
|
|
|
++node->slots;
|
|
|
|
|
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
|
|
|
"%s ras:tm:allocate:discover: found -- bumped slots to %d",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->slots));
|
|
|
|
|
2005-03-14 23:57:21 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Did we find it? */
|
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
if (opal_list_get_end(nodelist) == item) {
|
2005-03-14 23:57:21 +03:00
|
|
|
|
|
|
|
/* Nope -- didn't find it, so add a new item to the list */
|
2008-02-28 04:57:57 +03:00
|
|
|
|
|
|
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
|
|
|
"%s ras:tm:allocate:discover: not found -- added to list",
|
|
|
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
|
|
|
|
|
|
|
node = OBJ_NEW(orte_node_t);
|
|
|
|
node->name = hostname;
|
2007-02-09 18:06:45 +03:00
|
|
|
node->launch_id = nodeid;
|
2008-02-28 04:57:57 +03:00
|
|
|
node->slots_inuse = 0;
|
|
|
|
node->slots_max = 0;
|
|
|
|
node->slots = 1;
|
|
|
|
opal_list_append(nodelist, &node->super);
|
2005-03-14 23:57:21 +03:00
|
|
|
} else {
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
/* Yes, so we need to free the hostname that came back */
|
2005-03-14 23:57:21 +03:00
|
|
|
free(hostname);
|
|
|
|
}
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
/* up the nodeid */
|
|
|
|
nodeid++;
|
2006-11-06 21:41:22 +03:00
|
|
|
}
|
2007-02-09 18:06:45 +03:00
|
|
|
|
|
|
|
/* check for timing request - get stop time and report elapsed time if so */
|
2008-02-28 04:57:57 +03:00
|
|
|
if (orte_timing) {
|
2007-02-09 18:06:45 +03:00
|
|
|
gettimeofday(&stop, NULL);
|
|
|
|
opal_output(0, "ras_tm: time to allocate is %ld usec",
|
|
|
|
(long int)((stop.tv_sec - start.tv_sec)*1000000 +
|
|
|
|
(stop.tv_usec - start.tv_usec)));
|
|
|
|
gettimeofday(&start, NULL);
|
|
|
|
}
|
|
|
|
|
2008-02-28 04:57:57 +03:00
|
|
|
return ORTE_SUCCESS;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
|
|
|
|
2007-02-09 18:06:45 +03:00
|
|
|
static char *tm_getline(FILE *fp)
|
2005-03-14 23:57:21 +03:00
|
|
|
{
|
2007-02-09 18:06:45 +03:00
|
|
|
char *ret, *buff;
|
|
|
|
char input[TM_FILE_MAX_LINE_LENGTH];
|
|
|
|
|
|
|
|
ret = fgets(input, TM_FILE_MAX_LINE_LENGTH, fp);
|
|
|
|
if (NULL != ret) {
|
|
|
|
input[strlen(input)-1] = '\0'; /* remove newline */
|
|
|
|
buff = strdup(input);
|
|
|
|
return buff;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2007-02-09 18:06:45 +03:00
|
|
|
|
|
|
|
return NULL;
|
2005-03-14 23:57:21 +03:00
|
|
|
}
|
2007-02-09 18:06:45 +03:00
|
|
|
|