diff --git a/orte/mca/pls/rsh/pls_rsh_module.c b/orte/mca/pls/rsh/pls_rsh_module.c index 1eaede307a..56c6a4a7cc 100644 --- a/orte/mca/pls/rsh/pls_rsh_module.c +++ b/orte/mca/pls/rsh/pls_rsh_module.c @@ -630,7 +630,13 @@ int orte_pls_rsh_launch(orte_jobid_t jobid) /* setup node name */ free(argv[node_name_index1]); - argv[node_name_index1] = strdup(node->node_name); + if (NULL != node->node_username && + 0 != strlen (node->node_username)) { + asprintf (&argv[node_name_index1], "%s@%s", + node->node_username, node->node_name); + } else { + argv[node_name_index1] = strdup(node->node_name); + } free(argv[node_name_index2]); argv[node_name_index2] = strdup(node->node_name); diff --git a/orte/mca/ras/base/ras_base_node.c b/orte/mca/ras/base/ras_base_node.c index 654d691792..e1d1a5e4f5 100644 --- a/orte/mca/ras/base/ras_base_node.c +++ b/orte/mca/ras/base/ras_base_node.c @@ -37,6 +37,7 @@ static void orte_ras_base_node_construct(orte_ras_node_t* node) node->node_slots_inuse = 0; node->node_slots_alloc = 0; node->node_slots_max = 0; + node->node_username = NULL; } static void orte_ras_base_node_destruct(orte_ras_node_t* node) @@ -47,6 +48,9 @@ static void orte_ras_base_node_destruct(orte_ras_node_t* node) if (NULL != node->node_arch) { free(node->node_arch); } + if (NULL != node->node_username) { + free(node->node_username); + } } @@ -112,6 +116,10 @@ int orte_ras_base_node_query(opal_list_t* nodes) node->node_slots_max = keyval->value.size; continue; } + if(strcmp(keyval->key, ORTE_NODE_USERNAME_KEY) == 0) { + node->node_username = strdup(keyval->value.strptr); + continue; + } if(strcmp(keyval->key, ORTE_CELLID_KEY) == 0) { node->node_cellid = keyval->value.cellid; continue; @@ -137,6 +145,7 @@ int orte_ras_base_node_query_alloc(opal_list_t* nodes, orte_jobid_t jobid) ORTE_NODE_SLOTS_KEY, ORTE_NODE_SLOTS_ALLOC_KEY, ORTE_NODE_SLOTS_MAX_KEY, + ORTE_NODE_USERNAME_KEY, ORTE_CELLID_KEY, NULL }; @@ -215,6 +224,10 @@ int orte_ras_base_node_query_alloc(opal_list_t* nodes, orte_jobid_t jobid) node->node_slots_max = keyval->value.size; continue; } + if(strcmp(keyval->key, ORTE_NODE_USERNAME_KEY) == 0) { + node->node_username = strdup(keyval->value.strptr); + continue; + } if(strcmp(keyval->key, ORTE_CELLID_KEY) == 0) { node->node_cellid = keyval->value.cellid; continue; @@ -270,7 +283,7 @@ int orte_ras_base_node_insert(opal_list_t* nodes) value->addr_mode = ORTE_GPR_OVERWRITE | ORTE_GPR_TOKENS_AND; value->segment = strdup(ORTE_NODE_SEGMENT); - value->cnt = 6; + value->cnt = 7; /* Seven, at max (including node_username) */ value->keyvals = (orte_gpr_keyval_t**)malloc(value->cnt*sizeof(orte_gpr_keyval_t*)); if (NULL == value->keyvals) { for (j=0; j < i; j++) { @@ -334,6 +347,15 @@ int orte_ras_base_node_insert(opal_list_t* nodes) (value->keyvals[j])->type = ORTE_SIZE; (value->keyvals[j])->value.size = node->node_slots_max; + ++j; + (value->keyvals[j])->key = strdup(ORTE_NODE_USERNAME_KEY); + (value->keyvals[j])->type = ORTE_STRING; + if (NULL != node->node_username) { + (value->keyvals[j])->value.strptr = strdup(node->node_username); + } else { + (value->keyvals[j])->value.strptr = strdup(""); + } + /* setup index/keys for this node */ rc = orte_schema.get_node_tokens(&value->tokens, &value->num_tokens, node->node_cellid, node->node_name); if (ORTE_SUCCESS != rc) { diff --git a/orte/mca/ras/ras_types.h b/orte/mca/ras/ras_types.h index bdb62004ea..16389e34bb 100644 --- a/orte/mca/ras/ras_types.h +++ b/orte/mca/ras/ras_types.h @@ -62,6 +62,8 @@ struct orte_ras_node_t { specified limit. For example, if we have two processors, we may want to allow up to four processes but no more. */ size_t node_slots_max; + /** Username on this node, if specified */ + char * node_username; }; /** diff --git a/orte/mca/rds/hostfile/rds_hostfile.c b/orte/mca/rds/hostfile/rds_hostfile.c index f54ad56c70..5d2774c4ff 100644 --- a/orte/mca/rds/hostfile/rds_hostfile.c +++ b/orte/mca/rds/hostfile/rds_hostfile.c @@ -23,6 +23,7 @@ #include "include/orte_constants.h" #include "opal/class/opal_list.h" #include "opal/util/output.h" +#include "opal/util/argv.h" #include "util/sys_info.h" #include "mca/mca.h" #include "mca/base/base.h" @@ -39,13 +40,28 @@ static orte_cellid_t local_cellid; static bool need_cellid = true; -static void orte_rds_hostfile_parse_error(void) +static void orte_rds_hostfile_parse_error(int token) { - opal_output(0, "Error reading hostfile at line %d: %s\n", - orte_rds_hostfile_line, orte_rds_hostfile_value.sval); + switch (token) { + case ORTE_RDS_HOSTFILE_STRING: + opal_output(0, "Error reading hostfile at line %d: token:%d %s\n", + orte_rds_hostfile_line, token, orte_rds_hostfile_value.sval); + break; + case ORTE_RDS_HOSTFILE_IPV4: + case ORTE_RDS_HOSTFILE_INT: + opal_output(0, "Error reading hostfile at line %d: token:%d %d\n", + orte_rds_hostfile_line, token, orte_rds_hostfile_value.ival); + break; + default: + opal_output(0, "Error reading hostfile at line %d token:%d\n", + orte_rds_hostfile_line, token); + break; + } } - + /** + * Return the integer following an = (actually may only return positive ints) + */ static int orte_rds_hostfile_parse_int(void) { if (ORTE_RDS_HOSTFILE_EQUAL != orte_rds_hostfile_lex()) @@ -55,6 +71,20 @@ static int orte_rds_hostfile_parse_int(void) return orte_rds_hostfile_value.ival; } +/** + * Return the string following an = (option to a keyword) + */ +static char * orte_rds_hostfile_parse_string(void) +{ + int rc; + if (ORTE_RDS_HOSTFILE_EQUAL != orte_rds_hostfile_lex()) + return NULL; + rc = orte_rds_hostfile_lex(); + if (ORTE_RDS_HOSTFILE_STRING != rc) + return NULL; + return strdup(orte_rds_hostfile_value.sval); +} + static orte_ras_node_t* orte_rds_hostfile_lookup(opal_list_t* nodes, const char* name) { @@ -78,12 +108,31 @@ static int orte_rds_hostfile_parse_line(int token, opal_list_t* existing, opal_l bool update = false; bool got_count = false; - if (ORTE_RDS_HOSTFILE_STRING == token) { - char* node_name = orte_rds_hostfile_value.sval; + if (ORTE_RDS_HOSTFILE_STRING == token || + ORTE_RDS_HOSTFILE_HOSTNAME == token || + ORTE_RDS_HOSTFILE_IPV4 == token) { + char* value = orte_rds_hostfile_value.sval; + char** argv = opal_argv_split (value, '@'); + char* node_name = NULL; + char* username = NULL; + int cnt; + + cnt = opal_argv_count (argv); + if (1 == cnt) { + node_name = strdup(argv[0]); + } else if (2 == cnt) { + username = strdup(argv[0]); + node_name = strdup(argv[1]); + } else { + opal_output(0, "WARNING: Unhandeled user@host-combination\n"); /* XXX */ + } + opal_argv_free (argv); /* convert this into something globally unique */ if(strcmp(node_name, "localhost") == 0) { - node_name = orte_system_info.nodename; + /* Nodename has been allocated, that is for sure */ + free (node_name); + node_name = strdup(orte_system_info.nodename); } /* Do we need to make a new node object? First check to see @@ -96,7 +145,8 @@ static int orte_rds_hostfile_parse_line(int token, opal_list_t* existing, opal_l if (NULL == (node = orte_rds_hostfile_lookup(updates, node_name))) { node = OBJ_NEW(orte_ras_node_t); - node->node_name = strdup(node_name); + node->node_name = node_name; + node->node_username = username; node->node_slots = 0; #if 0 @@ -133,13 +183,14 @@ static int orte_rds_hostfile_parse_line(int token, opal_list_t* existing, opal_l need_cellid = false; } } else { - orte_rds_hostfile_parse_error(); + orte_rds_hostfile_parse_error(token); return OMPI_ERROR; } got_count = false; while (!orte_rds_hostfile_done) { token = orte_rds_hostfile_lex(); + switch (token) { case ORTE_RDS_HOSTFILE_DONE: goto done; @@ -147,6 +198,10 @@ static int orte_rds_hostfile_parse_line(int token, opal_list_t* existing, opal_l case ORTE_RDS_HOSTFILE_NEWLINE: goto done; + case ORTE_RDS_HOSTFILE_USERNAME: + node->node_username = orte_rds_hostfile_parse_string(); + break; + case ORTE_RDS_HOSTFILE_COUNT: case ORTE_RDS_HOSTFILE_CPU: case ORTE_RDS_HOSTFILE_SLOTS: @@ -185,7 +240,7 @@ static int orte_rds_hostfile_parse_line(int token, opal_list_t* existing, opal_l break; default: - orte_rds_hostfile_parse_error(); + orte_rds_hostfile_parse_error(token); OBJ_RELEASE(node); return OMPI_ERROR; } @@ -224,6 +279,7 @@ static int orte_rds_hostfile_parse(const char *hostfile, opal_list_t* existing, while (!orte_rds_hostfile_done) { token = orte_rds_hostfile_lex(); + switch (token) { case ORTE_RDS_HOSTFILE_DONE: orte_rds_hostfile_done = true; @@ -232,7 +288,15 @@ static int orte_rds_hostfile_parse(const char *hostfile, opal_list_t* existing, case ORTE_RDS_HOSTFILE_NEWLINE: break; + /* + * This looks odd, since we have several forms of host-definitions: + * hostname just plain as it is, being a ORTE_RDS_HOSTFILE_STRING + * IP4s and user@IPv4s + * hostname.domain and user@hostname.domain + */ case ORTE_RDS_HOSTFILE_STRING: + case ORTE_RDS_HOSTFILE_HOSTNAME: + case ORTE_RDS_HOSTFILE_IPV4: rc = orte_rds_hostfile_parse_line(token, existing, updates); if (ORTE_SUCCESS != rc) { goto unlock; @@ -240,7 +304,7 @@ static int orte_rds_hostfile_parse(const char *hostfile, opal_list_t* existing, break; default: - orte_rds_hostfile_parse_error(); + orte_rds_hostfile_parse_error(token); goto unlock; } } @@ -400,4 +464,3 @@ orte_rds_base_module_t orte_rds_hostfile_module = { orte_rds_base_store_resource, orte_rds_hostfile_finalize }; - diff --git a/orte/mca/rds/hostfile/rds_hostfile_lex.h b/orte/mca/rds/hostfile/rds_hostfile_lex.h index ebb899a59e..6193ffc32d 100644 --- a/orte/mca/rds/hostfile/rds_hostfile_lex.h +++ b/orte/mca/rds/hostfile/rds_hostfile_lex.h @@ -62,6 +62,9 @@ extern orte_rds_value_t orte_rds_hostfile_value; #define ORTE_RDS_HOSTFILE_COUNT 7 #define ORTE_RDS_HOSTFILE_SLOTS 8 #define ORTE_RDS_HOSTFILE_SLOTS_MAX 9 -#define ORTE_RDS_HOSTFILE_NEWLINE 10 +#define ORTE_RDS_HOSTFILE_USERNAME 10 +#define ORTE_RDS_HOSTFILE_IPV4 11 +#define ORTE_RDS_HOSTFILE_HOSTNAME 12 +#define ORTE_RDS_HOSTFILE_NEWLINE 13 #endif diff --git a/orte/mca/rds/hostfile/rds_hostfile_lex.l b/orte/mca/rds/hostfile/rds_hostfile_lex.l index 02d85b302c..0829c79b20 100644 --- a/orte/mca/rds/hostfile/rds_hostfile_lex.l +++ b/orte/mca/rds/hostfile/rds_hostfile_lex.l @@ -98,12 +98,31 @@ count_max { orte_rds_hostfile_value.sval = yytext; max_count { orte_rds_hostfile_value.sval = yytext; return ORTE_RDS_HOSTFILE_SLOTS_MAX; } +username { orte_rds_hostfile_value.sval = yytext; + return ORTE_RDS_HOSTFILE_USERNAME; } +"user-name" { orte_rds_hostfile_value.sval = yytext; + return ORTE_RDS_HOSTFILE_USERNAME; } +"user_name" { orte_rds_hostfile_value.sval = yytext; + return ORTE_RDS_HOSTFILE_USERNAME; } + [0-9]+ { orte_rds_hostfile_value.ival = atol(yytext); return ORTE_RDS_HOSTFILE_INT; } +%{ /* First detect hosts as standard Strings (but without ".") + * then username@IPv4 or IPV4, then username@hostname or hostname + */ +%} -[A-Za-z0-9_\-\.]* { orte_rds_hostfile_value.sval = yytext; +[A-za-z0-9_\-]* { orte_rds_hostfile_value.sval = yytext; return ORTE_RDS_HOSTFILE_STRING; } +([A-Za-z0-9][A-Za-z0-9_\-]*"@")?([0-9]{1,3}"."){3}[0-9]{1,3} { + orte_rds_hostfile_value.sval = yytext; + return ORTE_RDS_HOSTFILE_IPV4; } + +([A-Za-z0-9][A-Za-z0-9_\-]*"@")?[A-Za-z][A-Za-z0-9_\-\.]* { + orte_rds_hostfile_value.sval = yytext; + return ORTE_RDS_HOSTFILE_HOSTNAME; } + . { orte_rds_hostfile_value.sval = yytext; return ORTE_RDS_HOSTFILE_ERROR; } diff --git a/orte/mca/schema/schema_types.h b/orte/mca/schema/schema_types.h index 17c38b75a8..bb91bd01c7 100644 --- a/orte/mca/schema/schema_types.h +++ b/orte/mca/schema/schema_types.h @@ -65,6 +65,7 @@ #define ORTE_NODE_SLOTS_MAX_KEY "orte-node-slots-max" #define ORTE_NODE_ALLOC_KEY "orte-node-alloc" #define ORTE_NODE_BOOTPROXY_KEY "orte-node-bootproxy" +#define ORTE_NODE_USERNAME_KEY "orte-node-username" #define ORTE_JOB_APP_CONTEXT_KEY "orte-job-app-context" #define ORTE_JOB_SLOTS_KEY "orte-job-slots" /**< number of procs in job */ #define ORTE_JOB_VPID_START_KEY "orte-job-vpid-start"