/** * Return the integer following an = (actually may only return positive ints) */ static int hostfile_parse_int(void) { if (ORTE_HOSTFILE_EQUAL != orte_util_hostfile_lex()) return -1; if (ORTE_HOSTFILE_INT != orte_util_hostfile_lex()) return -1; return orte_util_hostfile_value.ival; }
/** * Return the string following an = (option to a keyword) */ static char *hostfile_parse_string(void) { int rc; if (ORTE_HOSTFILE_EQUAL != orte_util_hostfile_lex()){ return NULL; } rc = orte_util_hostfile_lex(); if (ORTE_HOSTFILE_STRING != rc){ return NULL; } return strdup(orte_util_hostfile_value.sval); }
static int hostfile_parse(const char *hostfile, opal_list_t* updates, opal_list_t* exclude, bool keep_all) { int token; int rc = ORTE_SUCCESS; cur_hostfile_name = hostfile; orte_util_hostfile_done = false; orte_util_hostfile_in = fopen(hostfile, "r"); if (NULL == orte_util_hostfile_in) { orte_show_help("help-hostfile.txt", "no-hostfile", true, hostfile); rc = ORTE_ERR_NOT_FOUND; goto unlock; } while (!orte_util_hostfile_done) { token = orte_util_hostfile_lex(); switch (token) { case ORTE_HOSTFILE_DONE: orte_util_hostfile_done = true; break; case ORTE_HOSTFILE_NEWLINE: break; /* * This looks odd, since we have several forms of host-definitions: * hostname just plain as it is, being a ORTE_HOSTFILE_STRING * IP4s and user@IPv4s * hostname.domain and [email protected] */ case ORTE_HOSTFILE_STRING: case ORTE_HOSTFILE_INT: case ORTE_HOSTFILE_HOSTNAME: case ORTE_HOSTFILE_IPV4: case ORTE_HOSTFILE_IPV6: case ORTE_HOSTFILE_RELATIVE: case ORTE_HOSTFILE_RANK: rc = hostfile_parse_line(token, updates, exclude, keep_all); if (ORTE_SUCCESS != rc) { goto unlock; } break; default: hostfile_parse_error(token); goto unlock; } } fclose(orte_util_hostfile_in); orte_util_hostfile_in = NULL; unlock: cur_hostfile_name = NULL; return rc; }
static int hostfile_parse_line(int token, opal_list_t* updates, opal_list_t* exclude, bool keep_all) { int rc; orte_node_t* node; bool got_count = false; bool got_max = false; char* value; char** argv; char* node_name = NULL; char* node_alias = NULL; char* username = NULL; int cnt; int number_of_slots = 0; char buff[64]; if (ORTE_HOSTFILE_STRING == token || ORTE_HOSTFILE_HOSTNAME == token || ORTE_HOSTFILE_INT == token || ORTE_HOSTFILE_IPV4 == token || ORTE_HOSTFILE_IPV6 == token) { if(ORTE_HOSTFILE_INT == token) { snprintf(buff, 64, "%d", orte_util_hostfile_value.ival); value = buff; } else { value = orte_util_hostfile_value.sval; } argv = opal_argv_split (value, '@'); 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: Unhandled user@host-combination\n"); /* XXX */ } opal_argv_free (argv); /* if the first letter of the name is '^', then this is a node * to be excluded. Remove the ^ character so the nodename is * usable, and put it on the exclude list */ if ('^' == node_name[0]) { int i, len; len = strlen(node_name); for (i=1; i < len; i++) { node_name[i-1] = node_name[i]; } node_name[len-1] = '\0'; /* truncate */ OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output, "%s hostfile: node %s is being excluded", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name)); /* convert this into something globally unique */ if (strcmp(node_name, "localhost") == 0 || opal_ifislocal(node_name)) { /* Nodename has been allocated, that is for sure */ if (orte_show_resolved_nodenames && 0 != strcmp(node_name, orte_process_info.nodename)) { node_alias = strdup(node_name); } free (node_name); node_name = strdup(orte_process_info.nodename); } /* Do we need to make a new node object? First check to see if it's already in the exclude list */ if (NULL == (node = hostfile_lookup(exclude, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; if (NULL != username) { node->username = strdup(username); } } /* Note that we need to add this back to the exclude list. If it was found, we just removed it (in hostfile_lookup()), so this puts it back. If it was not found, then we have to add it to the exclude list anyway. */ opal_list_append(exclude, &node->super); return ORTE_SUCCESS; } /* this is not a node to be excluded, so we need to process it and * add it to the "include" list. See if this host is actually us. */ if (strcmp(node_name, "localhost") == 0 || opal_ifislocal(node_name)) { /* Nodename has been allocated, that is for sure */ if (orte_show_resolved_nodenames && 0 != strcmp(node_name, orte_process_info.nodename)) { node_alias = strdup(node_name); } free (node_name); node_name = strdup(orte_process_info.nodename); } OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output, "%s hostfile: node %s is being included - keep all is %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name, keep_all ? "TRUE" : "FALSE")); /* Do we need to make a new node object? First check to see * if we are keeping everything or if it's already in the updates * list. Because we check keep_all first, if that is set we will * not do the hostfile_lookup call, and thus won't remove the * pre-existing node from the updates list */ if (keep_all || NULL == (node = hostfile_lookup(updates, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; if (NULL != username) { node->username = strdup(username); } } /* do we need to record an alias for this node? */ if (NULL != node_alias) { /* add to list of aliases for this node - only add if unique */ opal_argv_append_unique_nosize(&node->alias, node_alias, false); free(node_alias); } } else if (ORTE_HOSTFILE_RELATIVE == token) { /* store this for later processing */ node = OBJ_NEW(orte_node_t); node->name = strdup(orte_util_hostfile_value.sval); if (NULL != username) { node->username = strdup(username); } } else if (ORTE_HOSTFILE_RANK == token) { /* we can ignore the rank, but we need to extract the node name. we * first need to shift over to the other side of the equal sign as * this is where the node name will be */ while (!orte_util_hostfile_done && ORTE_HOSTFILE_EQUAL != token) { token = orte_util_hostfile_lex(); } if (orte_util_hostfile_done) { /* bad syntax somewhere */ return ORTE_ERROR; } /* next position should be the node name */ token = orte_util_hostfile_lex(); if(ORTE_HOSTFILE_INT == token) { snprintf(buff, 64, "%d", orte_util_hostfile_value.ival); value = buff; } else { value = orte_util_hostfile_value.sval; } argv = opal_argv_split (value, '@'); 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: Unhandled user@host-combination\n"); /* XXX */ } opal_argv_free (argv); /* Do we need to make a new node object? First check to see * if we are keeping everything or if it's already in the updates * list. Because we check keep_all first, if that is set we will * not do the hostfile_lookup call, and thus won't remove the * pre-existing node from the updates list */ if (keep_all || NULL == (node = hostfile_lookup(updates, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; if (NULL != username) { node->username = strdup(username); } } /* add a slot */ node->slots++; /* do we need to record an alias for this node? */ if (NULL != node_alias) { /* add to list of aliases for this node - only add if unique */ opal_argv_append_unique_nosize(&node->alias, node_alias, false); free(node_alias); } /* skip to end of line */ while (!orte_util_hostfile_done && ORTE_HOSTFILE_NEWLINE != token) { token = orte_util_hostfile_lex(); } opal_list_append(updates, &node->super); return ORTE_SUCCESS; } else { hostfile_parse_error(token); return ORTE_ERROR; } got_count = false; while (!orte_util_hostfile_done) { token = orte_util_hostfile_lex(); switch (token) { case ORTE_HOSTFILE_DONE: goto done; case ORTE_HOSTFILE_NEWLINE: goto done; case ORTE_HOSTFILE_USERNAME: node->username = hostfile_parse_string(); break; case ORTE_HOSTFILE_COUNT: case ORTE_HOSTFILE_CPU: case ORTE_HOSTFILE_SLOTS: rc = hostfile_parse_int(); if (rc < 0) { orte_show_help("help-hostfile.txt", "slots", true, cur_hostfile_name, rc); OBJ_RELEASE(node); return ORTE_ERROR; } node->slots += rc; got_count = true; /* Ensure that slots_max >= slots */ if (node->slots_max != 0 && node->slots_max < node->slots) { node->slots_max = node->slots; } break; case ORTE_HOSTFILE_SLOTS_MAX: rc = hostfile_parse_int(); if (rc < 0) { orte_show_help("help-hostfile.txt", "max_slots", true, cur_hostfile_name, ((size_t) rc)); OBJ_RELEASE(node); return ORTE_ERROR; } /* Only take this update if it puts us >= node_slots */ if (rc >= node->slots) { if (node->slots_max != rc) { node->slots_max = rc; got_max = true; } } else { orte_show_help("help-hostfile.txt", "max_slots_lt", true, cur_hostfile_name, node->slots, rc); ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM); OBJ_RELEASE(node); return ORTE_ERROR; } break; default: hostfile_parse_error(token); OBJ_RELEASE(node); return ORTE_ERROR; } if (number_of_slots > node->slots) { ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM); OBJ_RELEASE(node); return ORTE_ERROR; } } done: if (got_count) { node->slots_given = true; } else if (got_max) { node->slots = node->slots_max; node->slots_given = true; } else { /* should be set by obj_new, but just to be clear */ node->slots_given = false; /* if we weren't give a count or a max, then * just increment by one to support RMs that * count slots by listing the node multiple * times in the file */ ++node->slots; } opal_list_append(updates, &node->super); return ORTE_SUCCESS; }
static int hostfile_parse_line(int token, opal_list_t* updates, opal_list_t* exclude, bool keep_all) { int rc; orte_node_t* node; bool got_max = false; char* value; char **argv; char* node_name = NULL; char* username = NULL; int cnt; int number_of_slots = 0; char buff[64]; if (ORTE_HOSTFILE_STRING == token || ORTE_HOSTFILE_HOSTNAME == token || ORTE_HOSTFILE_INT == token || ORTE_HOSTFILE_IPV4 == token || ORTE_HOSTFILE_IPV6 == token) { if(ORTE_HOSTFILE_INT == token) { snprintf(buff, 64, "%d", orte_util_hostfile_value.ival); value = buff; } else { value = orte_util_hostfile_value.sval; } argv = opal_argv_split (value, '@'); cnt = opal_argv_count (argv); if (1 == cnt) { node_name = strdup(argv[0]); } else if (2 == cnt) { username = argv[0]; node_name = strdup(argv[1]); } else { opal_output(0, "WARNING: Unhandled user@host-combination\n"); /* XXX */ } opal_argv_free (argv); // Strip off the FQDN if present, ignore IP addresses if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(node_name) ) { char *ptr; if (NULL != (ptr = strchr(node_name, '.'))) { *ptr = '\0'; } } /* if the first letter of the name is '^', then this is a node * to be excluded. Remove the ^ character so the nodename is * usable, and put it on the exclude list */ if ('^' == node_name[0]) { int i, len; len = strlen(node_name); for (i=1; i < len; i++) { node_name[i-1] = node_name[i]; } node_name[len-1] = '\0'; /* truncate */ OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output, "%s hostfile: node %s is being excluded", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name)); /* see if this is another name for us */ if (orte_ifislocal(node_name)) { /* Nodename has been allocated, that is for sure */ free (node_name); node_name = strdup(orte_process_info.nodename); } /* Do we need to make a new node object? First check to see if it's already in the exclude list */ if (NULL == (node = hostfile_lookup(exclude, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; if (NULL != username) { orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING); } opal_list_append(exclude, &node->super); } else { free(node_name); } return ORTE_SUCCESS; } /* this is not a node to be excluded, so we need to process it and * add it to the "include" list. See if this host is actually us. */ if (orte_ifislocal(node_name)) { /* Nodename has been allocated, that is for sure */ free (node_name); node_name = strdup(orte_process_info.nodename); } OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output, "%s hostfile: node %s is being included - keep all is %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name, keep_all ? "TRUE" : "FALSE")); /* Do we need to make a new node object? */ if (keep_all || NULL == (node = hostfile_lookup(updates, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; node->slots = 1; if (NULL != username) { orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING); } opal_list_append(updates, &node->super); } else { /* this node was already found once - add a slot and mark slots as "given" */ node->slots++; ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN); free(node_name); } } else if (ORTE_HOSTFILE_RELATIVE == token) { /* store this for later processing */ node = OBJ_NEW(orte_node_t); node->name = strdup(orte_util_hostfile_value.sval); opal_list_append(updates, &node->super); } else if (ORTE_HOSTFILE_RANK == token) { /* we can ignore the rank, but we need to extract the node name. we * first need to shift over to the other side of the equal sign as * this is where the node name will be */ while (!orte_util_hostfile_done && ORTE_HOSTFILE_EQUAL != token) { token = orte_util_hostfile_lex(); } if (orte_util_hostfile_done) { /* bad syntax somewhere */ return ORTE_ERROR; } /* next position should be the node name */ token = orte_util_hostfile_lex(); if(ORTE_HOSTFILE_INT == token) { snprintf(buff, 64, "%d", orte_util_hostfile_value.ival); value = buff; } else { value = orte_util_hostfile_value.sval; } argv = opal_argv_split (value, '@'); cnt = opal_argv_count (argv); if (1 == cnt) { node_name = strdup(argv[0]); } else if (2 == cnt) { username = argv[0]; node_name = strdup(argv[1]); } else { opal_output(0, "WARNING: Unhandled user@host-combination\n"); /* XXX */ } opal_argv_free (argv); // Strip off the FQDN if present, ignore IP addresses if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(node_name) ) { char *ptr; if (NULL != (ptr = strchr(node_name, '.'))) { *ptr = '\0'; } } /* Do we need to make a new node object? */ if (NULL == (node = hostfile_lookup(updates, node_name))) { node = OBJ_NEW(orte_node_t); node->name = node_name; node->slots = 1; if (NULL != username) { orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING); } opal_list_append(updates, &node->super); } else { /* add a slot */ node->slots++; free(node_name); } OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output, "%s hostfile: node %s slots %d nodes-given %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, node->slots, ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN) ? "TRUE" : "FALSE")); /* mark the slots as "given" since we take them as being the * number specified via the rankfile */ ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN); /* skip to end of line */ while (!orte_util_hostfile_done && ORTE_HOSTFILE_NEWLINE != token) { token = orte_util_hostfile_lex(); } return ORTE_SUCCESS; } else { hostfile_parse_error(token); return ORTE_ERROR; } free(username); while (!orte_util_hostfile_done) { token = orte_util_hostfile_lex(); switch (token) { case ORTE_HOSTFILE_DONE: goto done; case ORTE_HOSTFILE_NEWLINE: goto done; case ORTE_HOSTFILE_USERNAME: username = hostfile_parse_string(); if (NULL != username) { orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING); free(username); } break; case ORTE_HOSTFILE_PORT: rc = hostfile_parse_int(); if (rc < 0) { orte_show_help("help-hostfile.txt", "port", true, cur_hostfile_name, rc); return ORTE_ERROR; } orte_set_attribute(&node->attributes, ORTE_NODE_PORT, ORTE_ATTR_LOCAL, &rc, OPAL_INT); break; case ORTE_HOSTFILE_COUNT: case ORTE_HOSTFILE_CPU: case ORTE_HOSTFILE_SLOTS: rc = hostfile_parse_int(); if (rc < 0) { orte_show_help("help-hostfile.txt", "slots", true, cur_hostfile_name, rc); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } if (ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN)) { /* multiple definitions were given for the * slot count - this is not allowed */ orte_show_help("help-hostfile.txt", "slots-given", true, cur_hostfile_name, node->name); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } node->slots = rc; ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN); /* Ensure that slots_max >= slots */ if (node->slots_max != 0 && node->slots_max < node->slots) { node->slots_max = node->slots; } break; case ORTE_HOSTFILE_SLOTS_MAX: rc = hostfile_parse_int(); if (rc < 0) { orte_show_help("help-hostfile.txt", "max_slots", true, cur_hostfile_name, ((size_t) rc)); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } /* Only take this update if it puts us >= node_slots */ if (rc >= node->slots) { if (node->slots_max != rc) { node->slots_max = rc; got_max = true; } } else { orte_show_help("help-hostfile.txt", "max_slots_lt", true, cur_hostfile_name, node->slots, rc); ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } break; case ORTE_HOSTFILE_STRING: case ORTE_HOSTFILE_INT: /* just ignore it */ break; default: hostfile_parse_error(token); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } if (number_of_slots > node->slots) { ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM); opal_list_remove_item(updates, &node->super); OBJ_RELEASE(node); return ORTE_ERROR; } } done: if (got_max && !ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN)) { node->slots = node->slots_max; ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN); } return ORTE_SUCCESS; }