root/orte/util/dash_host/dash_host.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. orte_util_dash_host_compute_slots
  2. orte_util_add_dash_host_nodes
  3. parse_dash_host
  4. orte_util_filter_dash_host_nodes
  5. orte_util_get_ordered_dash_host_list

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2013      Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2014-2019 Intel, Inc.  All rights reserved.
  14  * Copyright (c) 2015      Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * Copyright (c) 2016      IBM Corporation.  All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #include "orte_config.h"
  25 
  26 #include <string.h>
  27 #include <ctype.h>
  28 
  29 #include "orte/constants.h"
  30 #include "orte/types.h"
  31 
  32 #include "orte/util/show_help.h"
  33 #include "opal/util/argv.h"
  34 #include "opal/util/if.h"
  35 #include "opal/util/net.h"
  36 
  37 #include "orte/mca/ras/base/base.h"
  38 #include "orte/mca/plm/plm_types.h"
  39 #include "orte/mca/errmgr/errmgr.h"
  40 #include "orte/util/proc_info.h"
  41 #include "orte/runtime/orte_globals.h"
  42 
  43 #include "dash_host.h"
  44 
  45 int orte_util_dash_host_compute_slots(orte_node_t *node, char *hosts)
  46 {
  47     char **specs, *cptr;
  48     int slots = 0;
  49     int n;
  50 
  51     specs = opal_argv_split(hosts, ',');
  52 
  53     /* see if this node appears in the list */
  54     for (n=0; NULL != specs[n]; n++) {
  55         if (0 == strncmp(node->name, specs[n], strlen(node->name)) ||
  56             (orte_ifislocal(node->name) && orte_ifislocal(specs[n]))) {
  57             /* check if the #slots was specified */
  58             if (NULL != (cptr = strchr(specs[n], ':'))) {
  59                 *cptr = '\0';
  60                 ++cptr;
  61                 if ('*' == *cptr || 0 == strcmp(cptr, "auto")) {
  62                     slots += node->slots - node->slots_inuse;
  63                 } else {
  64                     slots += strtol(cptr, NULL, 10);
  65                 }
  66             } else {
  67                 ++slots;
  68             }
  69 
  70         }
  71     }
  72     opal_argv_free(specs);
  73     return slots;
  74 }
  75 
  76 /* we can only enter this routine if no other allocation
  77  * was found, so we only need to know that finding any
  78  * relative node syntax should generate an immediate error
  79  */
  80 int orte_util_add_dash_host_nodes(opal_list_t *nodes,
  81                                   char *hosts, bool allocating)
  82 {
  83     opal_list_item_t *item, *itm;
  84     orte_std_cntr_t i, j, k;
  85     int rc, nodeidx;
  86     char **host_argv=NULL;
  87     char **mapped_nodes = NULL, **mini_map, *ndname;
  88     orte_node_t *node, *nd;
  89     opal_list_t adds;
  90     bool found;
  91     int slots=0;
  92     bool slots_given;
  93     char *cptr, *ptr;
  94 
  95     OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
  96                          "%s dashhost: parsing args %s",
  97                          ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hosts));
  98 
  99     OBJ_CONSTRUCT(&adds, opal_list_t);
 100     host_argv = opal_argv_split(hosts, ',');
 101 
 102     /* Accumulate all of the host name mappings */
 103     for (j = 0; j < opal_argv_count(host_argv); ++j) {
 104         mini_map = opal_argv_split(host_argv[j], ',');
 105 
 106         if (mapped_nodes == NULL) {
 107             mapped_nodes = mini_map;
 108         } else {
 109             for (k = 0; NULL != mini_map[k]; ++k) {
 110                 rc = opal_argv_append_nosize(&mapped_nodes,
 111                                              mini_map[k]);
 112                 if (OPAL_SUCCESS != rc) {
 113                     opal_argv_free(host_argv);
 114                     opal_argv_free(mini_map);
 115                     goto cleanup;
 116                 }
 117             }
 118             opal_argv_free(mini_map);
 119         }
 120     }
 121     opal_argv_free(host_argv);
 122     mini_map = NULL;
 123 
 124     /* Did we find anything? If not, then do nothing */
 125     if (NULL == mapped_nodes) {
 126         rc = ORTE_SUCCESS;
 127         goto cleanup;
 128     }
 129 
 130     for (i = 0; NULL != mapped_nodes[i]; ++i) {
 131         /* if the specified node contains a relative node syntax,
 132          * and we are allocating, then ignore it
 133          */
 134         if ('+' == mapped_nodes[i][0]) {
 135             if (!allocating) {
 136                 if ('e' == mapped_nodes[i][1] ||
 137                     'E' == mapped_nodes[i][1]) {
 138                     /* request for empty nodes - do they want
 139                      * all of them?
 140                      */
 141                     if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
 142                         /* the colon indicates a specific # are requested */
 143                         ++cptr;
 144                         j = strtoul(cptr, NULL, 10);
 145                     } else if ('\0' != mapped_nodes[0][2]) {
 146                         j = strtoul(&mapped_nodes[0][2], NULL, 10);
 147                     } else {
 148                         /* add them all */
 149                         j = orte_node_pool->size;
 150                     }
 151                     for (k=0; 0 < j && k < orte_node_pool->size; k++) {
 152                         if (NULL != (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, k))) {
 153                             if (0 == node->num_procs) {
 154                                 opal_argv_append_nosize(&mini_map, node->name);
 155                                 --j;
 156                             }
 157                         }
 158                     }
 159                 } else if ('n' == mapped_nodes[i][1] ||
 160                            'N' == mapped_nodes[i][1]) {
 161                     /* they want a specific relative node #, so
 162                      * look it up on global pool
 163                      */
 164                     if ('\0' == mapped_nodes[i][2]) {
 165                         /* they forgot to tell us the # */
 166                         orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
 167                                        true, mapped_nodes[i]);
 168                         rc = ORTE_ERR_SILENT;
 169                         goto cleanup;
 170                     }
 171                     nodeidx = strtol(&mapped_nodes[i][2], NULL, 10);
 172                     if (nodeidx < 0 ||
 173                         nodeidx > (int)orte_node_pool->size) {
 174                         /* this is an error */
 175                         orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
 176                                        true, nodeidx, mapped_nodes[i]);
 177                         rc = ORTE_ERR_SILENT;
 178                         goto cleanup;
 179                     }
 180                     /* if the HNP is not allocated, then we need to
 181                      * adjust the index as the node pool is offset
 182                      * by one
 183                      */
 184                     if (!orte_hnp_is_allocated) {
 185                         nodeidx++;
 186                     }
 187                     /* see if that location is filled */
 188 
 189                     if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
 190                         /* this is an error */
 191                         orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
 192                                        true, nodeidx, mapped_nodes[i]);
 193                         rc = ORTE_ERR_SILENT;
 194                         goto cleanup;
 195                     }
 196                     /* add this node to the list */
 197                     opal_argv_append_nosize(&mini_map, node->name);
 198                 } else {
 199                     /* invalid relative node syntax */
 200                     orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
 201                                    true, mapped_nodes[i]);
 202                     rc = ORTE_ERR_SILENT;
 203                     goto cleanup;
 204                 }
 205             }
 206         } else {
 207             /* just one node was given */
 208             opal_argv_append_nosize(&mini_map, mapped_nodes[i]);
 209         }
 210     }
 211     if (NULL == mini_map) {
 212         rc = ORTE_SUCCESS;
 213         goto cleanup;
 214     }
 215 
 216     /*  go through the names found and
 217         add them to the host list. If they're not unique, then
 218         bump the slots count for each duplicate */
 219     for (i=0; NULL != mini_map[i]; i++) {
 220         OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
 221                              "%s dashhost: working node %s",
 222                              ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), mini_map[i]));
 223 
 224         /* see if the node contains the number of slots */
 225         slots_given = false;
 226         if (NULL != (cptr = strchr(mini_map[i], ':'))) {
 227             *cptr = '\0';
 228             ++cptr;
 229             if ('*' == *cptr || 0 == strcmp(cptr, "auto")) {
 230                 /* auto-detect #slots */
 231                 slots = -1;
 232                 slots_given = false;
 233             } else {
 234                 slots = strtol(cptr, NULL, 10);
 235                 slots_given = true;
 236             }
 237         }
 238 
 239         /* check for local name */
 240         if (orte_ifislocal(mini_map[i])) {
 241             ndname = orte_process_info.nodename;
 242         } else {
 243             ndname = mini_map[i];
 244         }
 245 
 246         // Strip off the FQDN if present, ignore IP addresses
 247         if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(ndname) ) {
 248             if (NULL != (ptr = strchr(ndname, '.'))) {
 249                 *ptr = '\0';
 250             }
 251         }
 252         /* remove any modifier */
 253         if (NULL != (ptr = strchr(ndname, ':'))) {
 254             *ptr = '\0';
 255         }
 256         /* see if the node is already on the list */
 257         found = false;
 258         OPAL_LIST_FOREACH(node, &adds, orte_node_t) {
 259             if (0 == strcmp(node->name, ndname)) {
 260                 found = true;
 261                 if (slots_given) {
 262                     node->slots += slots;
 263                     if (0 < slots) {
 264                         ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 265                     }
 266                 } else {
 267                     ++node->slots;
 268                     ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 269                 }
 270                 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
 271                                      "%s dashhost: node %s already on list - slots %d",
 272                                      ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, node->slots));
 273                 break;
 274             }
 275         }
 276 
 277         /* If we didn't find it, add it to the list */
 278         if (!found) {
 279             node = OBJ_NEW(orte_node_t);
 280             if (NULL == node) {
 281                 opal_argv_free(mapped_nodes);
 282                 return ORTE_ERR_OUT_OF_RESOURCE;
 283             }
 284             node->name = strdup(ndname);
 285             OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
 286                                  "%s dashhost: added node %s to list - slots %d",
 287                                  ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, slots));
 288             node->state = ORTE_NODE_STATE_UP;
 289             node->slots_inuse = 0;
 290             node->slots_max = 0;
 291             if (slots_given) {
 292                 node->slots = slots;
 293                 if (0 < slots) {
 294                     ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 295                 }
 296             } else if (slots < 0) {
 297                 node->slots = 0;
 298                 ORTE_FLAG_UNSET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 299             } else {
 300                 node->slots = 1;
 301                 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 302             }
 303             opal_list_append(&adds, &node->super);
 304         }
 305     }
 306     opal_argv_free(mini_map);
 307 
 308     /* transfer across all unique nodes */
 309     while (NULL != (item = opal_list_remove_first(&adds))) {
 310         nd = (orte_node_t*)item;
 311         found = false;
 312         for (itm = opal_list_get_first(nodes);
 313              itm != opal_list_get_end(nodes);
 314              itm = opal_list_get_next(itm)) {
 315             node = (orte_node_t*)itm;
 316             if (0 == strcmp(nd->name, node->name)) {
 317                 found = true;
 318                 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
 319                                      "%s dashhost: found existing node %s on input list - adding slots",
 320                                      ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name));
 321                 if (ORTE_FLAG_TEST(nd, ORTE_NODE_FLAG_SLOTS_GIVEN)) {
 322                     /* transfer across the number of slots */
 323                     node->slots += nd->slots;
 324                     ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
 325                 }
 326                 break;
 327             }
 328         }
 329         if (!found) {
 330             OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
 331                                  "%s dashhost: adding node %s with %d slots to final list",
 332                                  ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), nd->name, nd->slots));
 333             opal_list_append(nodes, &nd->super);
 334         } else {
 335             OBJ_RELEASE(item);
 336         }
 337     }
 338 
 339     rc = ORTE_SUCCESS;
 340 
 341  cleanup:
 342     if (NULL != mapped_nodes) {
 343         opal_argv_free(mapped_nodes);
 344     }
 345     OPAL_LIST_DESTRUCT(&adds);
 346 
 347     return rc;
 348 }
 349 
 350 
 351 /* the -host option can always be used in both absolute
 352  * and relative mode, so we have to check for pre-existing
 353  * allocations if we are to use relative node syntax
 354  */
 355 static int parse_dash_host(char ***mapped_nodes, char *hosts)
 356 {
 357     orte_std_cntr_t j, k;
 358     int rc=ORTE_SUCCESS;
 359     char **mini_map=NULL, *cptr;
 360     int nodeidx;
 361     orte_node_t *node;
 362     char **host_argv=NULL;
 363 
 364     host_argv = opal_argv_split(hosts, ',');
 365 
 366     /* Accumulate all of the host name mappings */
 367     for (j = 0; j < opal_argv_count(host_argv); ++j) {
 368         mini_map = opal_argv_split(host_argv[j], ',');
 369 
 370         for (k = 0; NULL != mini_map[k]; ++k) {
 371             if ('+' == mini_map[k][0]) {
 372                 /* see if we specified empty nodes */
 373                 if ('e' == mini_map[k][1] ||
 374                     'E' == mini_map[k][1]) {
 375                     /* request for empty nodes - do they want
 376                      * all of them?
 377                      */
 378                     if (NULL != (cptr = strchr(mini_map[k], ':'))) {
 379                         /* the colon indicates a specific # are requested */
 380                         *cptr = '*';
 381                         opal_argv_append_nosize(mapped_nodes, cptr);
 382                     } else {
 383                         /* add a marker to the list */
 384                         opal_argv_append_nosize(mapped_nodes, "*");
 385                     }
 386                 } else if ('n' == mini_map[k][1] ||
 387                            'N' == mini_map[k][1]) {
 388                     /* they want a specific relative node #, so
 389                      * look it up on global pool
 390                      */
 391                     nodeidx = strtol(&mini_map[k][2], NULL, 10);
 392                     if (nodeidx < 0 ||
 393                         nodeidx > (int)orte_node_pool->size) {
 394                         /* this is an error */
 395                         orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
 396                                        true, nodeidx, mini_map[k]);
 397                         rc = ORTE_ERR_SILENT;
 398                         goto cleanup;
 399                     }
 400                     /* if the HNP is not allocated, then we need to
 401                      * adjust the index as the node pool is offset
 402                      * by one
 403                      */
 404                     if (!orte_hnp_is_allocated) {
 405                         nodeidx++;
 406                     }
 407                     /* see if that location is filled */
 408 
 409                     if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
 410                         /* this is an error */
 411                         orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
 412                                        true, nodeidx, mini_map[k]);
 413                         rc = ORTE_ERR_SILENT;
 414                         goto cleanup;
 415                     }
 416                     /* add this node to the list */
 417                     opal_argv_append_nosize(mapped_nodes, node->name);
 418                 } else {
 419                     /* invalid relative node syntax */
 420                     orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
 421                                    true, mini_map[k]);
 422                     rc = ORTE_ERR_SILENT;
 423                     goto cleanup;
 424                 }
 425             } else { /* non-relative syntax - add to list */
 426                 /* remove any modifier */
 427                 if (NULL != (cptr = strchr(mini_map[k], ':'))) {
 428                     *cptr = '\0';
 429                 }
 430                 /* check for local alias */
 431                 if (orte_ifislocal(mini_map[k])) {
 432                     opal_argv_append_nosize(mapped_nodes, orte_process_info.nodename);
 433                 } else {
 434                     opal_argv_append_nosize(mapped_nodes, mini_map[k]);
 435                 }
 436             }
 437         }
 438         opal_argv_free(mini_map);
 439         mini_map = NULL;
 440     }
 441 
 442 cleanup:
 443     if (NULL != host_argv) {
 444         opal_argv_free(host_argv);
 445     }
 446     if (NULL != mini_map) {
 447         opal_argv_free(mini_map);
 448     }
 449     return rc;
 450 }
 451 
 452 int orte_util_filter_dash_host_nodes(opal_list_t *nodes,
 453                                      char *hosts,
 454                                      bool remove)
 455 {
 456     opal_list_item_t* item;
 457     opal_list_item_t *next;
 458     orte_std_cntr_t i, j, len_mapped_node=0;
 459     int rc, test;
 460     char **mapped_nodes = NULL;
 461     orte_node_t *node;
 462     int num_empty=0;
 463     opal_list_t keep;
 464     bool want_all_empty=false;
 465     char *cptr;
 466     size_t lst, lmn;
 467 
 468     /* if the incoming node list is empty, then there
 469      * is nothing to filter!
 470      */
 471     if (opal_list_is_empty(nodes)) {
 472         return ORTE_SUCCESS;
 473     }
 474 
 475     if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
 476         ORTE_ERROR_LOG(rc);
 477         return rc;
 478     }
 479     /* Did we find anything? If not, then do nothing */
 480     if (NULL == mapped_nodes) {
 481         return ORTE_SUCCESS;
 482     }
 483 
 484     /* NOTE: The following logic is based on knowing that
 485      * any node can only be included on the incoming
 486      * nodes list ONCE.
 487      */
 488 
 489     len_mapped_node = opal_argv_count(mapped_nodes);
 490     /* setup a working list so we can put the final list
 491      * of nodes in order. This way, if the user specifies a
 492      * set of nodes, we will use them in the order in which
 493      * they were specifed. Note that empty node requests
 494      * will always be appended to the end
 495      */
 496     OBJ_CONSTRUCT(&keep, opal_list_t);
 497 
 498     for (i = 0; i < len_mapped_node; ++i) {
 499         /* check if we are supposed to add some number of empty
 500          * nodes here
 501          */
 502         if ('*' == mapped_nodes[i][0]) {
 503             /* if there is a number after the '*', then we are
 504              * to insert a specific # of nodes
 505              */
 506             if ('\0' == mapped_nodes[i][1]) {
 507                 /* take all empty nodes from the list */
 508                 num_empty = INT_MAX;
 509                 want_all_empty = true;
 510             } else {
 511                 /* extract number of nodes to take */
 512                 num_empty = strtol(&mapped_nodes[i][1], NULL, 10);
 513             }
 514             /* search for empty nodes and take them */
 515             item = opal_list_get_first(nodes);
 516             while (0 < num_empty && item != opal_list_get_end(nodes)) {
 517                 next = opal_list_get_next(item);  /* save this position */
 518                 node = (orte_node_t*)item;
 519                 /* see if this node is empty */
 520                 if (0 == node->slots_inuse) {
 521                     /* check to see if it is specified later */
 522                     for (j=i+1; j < len_mapped_node; j++) {
 523                         if (0 == strcmp(mapped_nodes[j], node->name)) {
 524                             /* specified later - skip this one */
 525                             goto skipnode;
 526                         }
 527                     }
 528                     if (remove) {
 529                         /* remove item from list */
 530                         opal_list_remove_item(nodes, item);
 531                         /* xfer to keep list */
 532                         opal_list_append(&keep, item);
 533                     } else {
 534                         /* mark the node as found */
 535                         ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
 536                     }
 537                     --num_empty;
 538                 }
 539             skipnode:
 540                 item = next;
 541             }
 542         } else {
 543             /* remove any modifier */
 544             if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
 545                 *cptr = '\0';
 546             }
 547             /* we are looking for a specific node on the list. The
 548              * parser will have substituted our local name for any
 549              * alias, so we only have to do a strcmp here. */
 550             cptr = NULL;
 551             lmn = strtoul(mapped_nodes[i], &cptr, 10);
 552             item = opal_list_get_first(nodes);
 553             while (item != opal_list_get_end(nodes)) {
 554                 next = opal_list_get_next(item);  /* save this position */
 555                 node = (orte_node_t*)item;
 556                 /* search -host list to see if this one is found */
 557                 if (orte_managed_allocation &&
 558                     (NULL == cptr || 0 == strlen(cptr))) {
 559                     /* if we are only given a number, then we test the
 560                      * value against the number in the node name. This allows support for
 561                      * launch_id-based environments. For example, a hostname
 562                      * of "nid0015" can be referenced by "--host 15" */
 563                     for (j=strlen(node->name)-1; 0 < j; j--) {
 564                         if (!isdigit(node->name[j])) {
 565                             j++;
 566                             break;
 567                         }
 568                     }
 569                     if (j >= (int)(strlen(node->name) - 1)) {
 570                         test = 0;
 571                     } else {
 572                         lst = strtoul(&node->name[j], NULL, 10);
 573                         test = (lmn == lst) ? 0 : 1;
 574                     }
 575                 } else {
 576                     test = strcmp(node->name, mapped_nodes[i]);
 577                 }
 578                 if (0 == test) {
 579                     if (remove) {
 580                         /* remove item from list */
 581                         opal_list_remove_item(nodes, item);
 582                         /* xfer to keep list */
 583                         opal_list_append(&keep, item);
 584                     } else {
 585                         /* mark the node as found */
 586                         ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
 587                     }
 588                     break;
 589                 }
 590                 item = next;
 591             }
 592         }
 593         /* done with the mapped entry */
 594         free(mapped_nodes[i]);
 595         mapped_nodes[i] = NULL;
 596     }
 597 
 598     /* was something specified that was -not- found? */
 599     for (i=0; i < len_mapped_node; i++) {
 600         if (NULL != mapped_nodes[i]) {
 601             orte_show_help("help-dash-host.txt", "not-all-mapped-alloc",
 602                            true, mapped_nodes[i]);
 603             rc = ORTE_ERR_SILENT;
 604             goto cleanup;
 605         }
 606     }
 607 
 608     if (!remove) {
 609         /* all done */
 610         rc = ORTE_SUCCESS;
 611         goto cleanup;
 612     }
 613 
 614     /* clear the rest of the nodes list */
 615     while (NULL != (item = opal_list_remove_first(nodes))) {
 616         OBJ_RELEASE(item);
 617     }
 618 
 619     /* the nodes list has been cleared - rebuild it in order */
 620     while (NULL != (item = opal_list_remove_first(&keep))) {
 621         opal_list_append(nodes, item);
 622     }
 623 
 624     /* did they ask for more than we could provide */
 625     if (!want_all_empty && 0 < num_empty) {
 626         orte_show_help("help-dash-host.txt", "dash-host:not-enough-empty",
 627                        true, num_empty);
 628         rc = ORTE_ERR_SILENT;
 629         goto cleanup;
 630     }
 631 
 632     rc = ORTE_SUCCESS;
 633     /* done filtering existing list */
 634 
 635 cleanup:
 636     for (i=0; i < len_mapped_node; i++) {
 637         if (NULL != mapped_nodes[i]) {
 638             free(mapped_nodes[i]);
 639             mapped_nodes[i] = NULL;
 640         }
 641     }
 642     if (NULL != mapped_nodes) {
 643         free(mapped_nodes);
 644     }
 645 
 646     return rc;
 647 }
 648 
 649 int orte_util_get_ordered_dash_host_list(opal_list_t *nodes,
 650                                          char *hosts)
 651 {
 652     int rc, i;
 653     char **mapped_nodes = NULL;
 654     orte_node_t *node;
 655 
 656     if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
 657         ORTE_ERROR_LOG(rc);
 658     }
 659 
 660     /* for each entry, create a node entry on the list */
 661     for (i=0; NULL != mapped_nodes[i]; i++) {
 662         node = OBJ_NEW(orte_node_t);
 663         node->name = strdup(mapped_nodes[i]);
 664         opal_list_append(nodes, &node->super);
 665     }
 666 
 667     /* cleanup */
 668     opal_argv_free(mapped_nodes);
 669     return rc;
 670 }

/* [<][>][^][v][top][bottom][index][help] */