This source file includes following definitions.
- hostfile_parse_error
- hostfile_parse_int
- hostfile_parse_string
- hostfile_lookup
- hostfile_parse_line
- hostfile_parse
- orte_util_add_hostfile_nodes
- orte_util_filter_hostfile_nodes
- orte_util_get_ordered_host_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "orte_config.h"
26 #include "orte/constants.h"
27
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include <errno.h>
32 #include <string.h>
33 #include <sys/stat.h>
34
35 #include "opal/class/opal_list.h"
36 #include "opal/util/argv.h"
37 #include "opal/util/output.h"
38 #include "opal/mca/mca.h"
39 #include "opal/mca/base/base.h"
40 #include "opal/util/if.h"
41 #include "opal/util/net.h"
42 #include "opal/mca/installdirs/installdirs.h"
43
44 #include "orte/util/show_help.h"
45 #include "orte/util/proc_info.h"
46 #include "orte/util/name_fns.h"
47 #include "orte/mca/errmgr/errmgr.h"
48 #include "orte/mca/ras/base/base.h"
49 #include "orte/runtime/orte_globals.h"
50
51 #include "orte/util/hostfile/hostfile_lex.h"
52 #include "orte/util/hostfile/hostfile.h"
53
54
55 static const char *cur_hostfile_name = NULL;
56
57 static void hostfile_parse_error(int token)
58 {
59 switch (token) {
60 case ORTE_HOSTFILE_STRING:
61 orte_show_help("help-hostfile.txt", "parse_error_string",
62 true,
63 cur_hostfile_name,
64 orte_util_hostfile_line,
65 token,
66 orte_util_hostfile_value.sval);
67 break;
68 case ORTE_HOSTFILE_IPV4:
69 case ORTE_HOSTFILE_IPV6:
70 case ORTE_HOSTFILE_INT:
71 orte_show_help("help-hostfile.txt", "parse_error_int",
72 true,
73 cur_hostfile_name,
74 orte_util_hostfile_line,
75 token,
76 orte_util_hostfile_value.ival);
77 break;
78 default:
79 orte_show_help("help-hostfile.txt", "parse_error",
80 true,
81 cur_hostfile_name,
82 orte_util_hostfile_line,
83 token );
84 break;
85 }
86 }
87
88
89
90
91 static int hostfile_parse_int(void)
92 {
93 if (ORTE_HOSTFILE_EQUAL != orte_util_hostfile_lex())
94 return -1;
95 if (ORTE_HOSTFILE_INT != orte_util_hostfile_lex())
96 return -1;
97 return orte_util_hostfile_value.ival;
98 }
99
100
101
102
103 static char *hostfile_parse_string(void)
104 {
105 int rc;
106 if (ORTE_HOSTFILE_EQUAL != orte_util_hostfile_lex()){
107 return NULL;
108 }
109 rc = orte_util_hostfile_lex();
110 if (ORTE_HOSTFILE_STRING != rc){
111 return NULL;
112 }
113 return strdup(orte_util_hostfile_value.sval);
114 }
115
116 static orte_node_t* hostfile_lookup(opal_list_t* nodes, const char* name)
117 {
118 opal_list_item_t* item;
119 for(item = opal_list_get_first(nodes);
120 item != opal_list_get_end(nodes);
121 item = opal_list_get_next(item)) {
122 orte_node_t* node = (orte_node_t*)item;
123 if (strcmp(node->name, name) == 0) {
124 return node;
125 }
126 }
127 return NULL;
128 }
129
130 static int hostfile_parse_line(int token, opal_list_t* updates,
131 opal_list_t* exclude, bool keep_all)
132 {
133 int rc;
134 orte_node_t* node;
135 bool got_max = false;
136 char* value;
137 char **argv;
138 char* node_name = NULL;
139 char* username = NULL;
140 int cnt;
141 int number_of_slots = 0;
142 char buff[64];
143
144 if (ORTE_HOSTFILE_STRING == token ||
145 ORTE_HOSTFILE_HOSTNAME == token ||
146 ORTE_HOSTFILE_INT == token ||
147 ORTE_HOSTFILE_IPV4 == token ||
148 ORTE_HOSTFILE_IPV6 == token) {
149
150 if(ORTE_HOSTFILE_INT == token) {
151 snprintf(buff, 64, "%d", orte_util_hostfile_value.ival);
152 value = buff;
153 } else {
154 value = orte_util_hostfile_value.sval;
155 }
156 argv = opal_argv_split (value, '@');
157
158 cnt = opal_argv_count (argv);
159 if (1 == cnt) {
160 node_name = strdup(argv[0]);
161 } else if (2 == cnt) {
162 username = strdup(argv[0]);
163 node_name = strdup(argv[1]);
164 } else {
165 opal_output(0, "WARNING: Unhandled user@host-combination\n");
166 }
167 opal_argv_free (argv);
168
169
170 if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(node_name) ) {
171 char *ptr;
172 if (NULL != (ptr = strchr(node_name, '.'))) {
173 *ptr = '\0';
174 }
175 }
176
177
178
179
180
181 if ('^' == node_name[0]) {
182 int i, len;
183 len = strlen(node_name);
184 for (i=1; i < len; i++) {
185 node_name[i-1] = node_name[i];
186 }
187 node_name[len-1] = '\0';
188
189 OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output,
190 "%s hostfile: node %s is being excluded",
191 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name));
192
193
194 if (orte_ifislocal(node_name)) {
195
196 free (node_name);
197 node_name = strdup(orte_process_info.nodename);
198 }
199
200
201
202 if (NULL == (node = hostfile_lookup(exclude, node_name))) {
203 node = OBJ_NEW(orte_node_t);
204 node->name = node_name;
205 if (NULL != username) {
206 orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING);
207 }
208 opal_list_append(exclude, &node->super);
209 } else {
210 free(node_name);
211 }
212 return ORTE_SUCCESS;
213 }
214
215
216
217
218 if (orte_ifislocal(node_name)) {
219
220 free (node_name);
221 node_name = strdup(orte_process_info.nodename);
222 }
223
224 OPAL_OUTPUT_VERBOSE((3, orte_ras_base_framework.framework_output,
225 "%s hostfile: node %s is being included - keep all is %s",
226 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node_name,
227 keep_all ? "TRUE" : "FALSE"));
228
229
230 if (keep_all || NULL == (node = hostfile_lookup(updates, node_name))) {
231 node = OBJ_NEW(orte_node_t);
232 node->name = node_name;
233 node->slots = 1;
234 if (NULL != username) {
235 orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING);
236 }
237 opal_list_append(updates, &node->super);
238 } else {
239
240 node->slots++;
241 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
242 free(node_name);
243 }
244 } else if (ORTE_HOSTFILE_RELATIVE == token) {
245
246 node = OBJ_NEW(orte_node_t);
247 node->name = strdup(orte_util_hostfile_value.sval);
248 opal_list_append(updates, &node->super);
249 } else if (ORTE_HOSTFILE_RANK == token) {
250
251
252
253
254 while (!orte_util_hostfile_done &&
255 ORTE_HOSTFILE_EQUAL != token) {
256 token = orte_util_hostfile_lex();
257 }
258 if (orte_util_hostfile_done) {
259
260 return ORTE_ERROR;
261 }
262
263 token = orte_util_hostfile_lex();
264 if(ORTE_HOSTFILE_INT == token) {
265 snprintf(buff, 64, "%d", orte_util_hostfile_value.ival);
266 value = buff;
267 } else {
268 value = orte_util_hostfile_value.sval;
269 }
270
271 argv = opal_argv_split (value, '@');
272
273 cnt = opal_argv_count (argv);
274 if (1 == cnt) {
275 node_name = strdup(argv[0]);
276 } else if (2 == cnt) {
277 username = strdup(argv[0]);
278 node_name = strdup(argv[1]);
279 } else {
280 opal_output(0, "WARNING: Unhandled user@host-combination\n");
281 }
282 opal_argv_free (argv);
283
284
285 if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(node_name) ) {
286 char *ptr;
287 if (NULL != (ptr = strchr(node_name, '.'))) {
288 *ptr = '\0';
289 }
290 }
291
292
293 if (NULL == (node = hostfile_lookup(updates, node_name))) {
294 node = OBJ_NEW(orte_node_t);
295 node->name = node_name;
296 node->slots = 1;
297 if (NULL != username) {
298 orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING);
299 }
300 opal_list_append(updates, &node->super);
301 } else {
302
303 node->slots++;
304 free(node_name);
305 }
306 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
307 "%s hostfile: node %s slots %d nodes-given %s",
308 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, node->slots,
309 ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN) ? "TRUE" : "FALSE"));
310
311
312
313 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
314
315 while (!orte_util_hostfile_done &&
316 ORTE_HOSTFILE_NEWLINE != token) {
317 token = orte_util_hostfile_lex();
318 }
319 return ORTE_SUCCESS;
320 } else {
321 hostfile_parse_error(token);
322 return ORTE_ERROR;
323 }
324 free(username);
325
326 while (!orte_util_hostfile_done) {
327 token = orte_util_hostfile_lex();
328
329 switch (token) {
330 case ORTE_HOSTFILE_DONE:
331 goto done;
332
333 case ORTE_HOSTFILE_NEWLINE:
334 goto done;
335
336 case ORTE_HOSTFILE_USERNAME:
337 username = hostfile_parse_string();
338 if (NULL != username) {
339 orte_set_attribute(&node->attributes, ORTE_NODE_USERNAME, ORTE_ATTR_LOCAL, username, OPAL_STRING);
340 free(username);
341 }
342 break;
343
344 case ORTE_HOSTFILE_PORT:
345 rc = hostfile_parse_int();
346 if (rc < 0) {
347 orte_show_help("help-hostfile.txt", "port",
348 true,
349 cur_hostfile_name, rc);
350 return ORTE_ERROR;
351 }
352 orte_set_attribute(&node->attributes, ORTE_NODE_PORT, ORTE_ATTR_LOCAL, &rc, OPAL_INT);
353 break;
354
355 case ORTE_HOSTFILE_COUNT:
356 case ORTE_HOSTFILE_CPU:
357 case ORTE_HOSTFILE_SLOTS:
358 rc = hostfile_parse_int();
359 if (rc < 0) {
360 orte_show_help("help-hostfile.txt", "slots",
361 true,
362 cur_hostfile_name, rc);
363 opal_list_remove_item(updates, &node->super);
364 OBJ_RELEASE(node);
365 return ORTE_ERROR;
366 }
367 if (ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN)) {
368
369
370
371 orte_show_help("help-hostfile.txt", "slots-given",
372 true,
373 cur_hostfile_name, node->name);
374 opal_list_remove_item(updates, &node->super);
375 OBJ_RELEASE(node);
376 return ORTE_ERROR;
377 }
378 node->slots = rc;
379 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
380
381
382 if (node->slots_max != 0 && node->slots_max < node->slots) {
383 node->slots_max = node->slots;
384 }
385 break;
386
387 case ORTE_HOSTFILE_SLOTS_MAX:
388 rc = hostfile_parse_int();
389 if (rc < 0) {
390 orte_show_help("help-hostfile.txt", "max_slots",
391 true,
392 cur_hostfile_name, ((size_t) rc));
393 opal_list_remove_item(updates, &node->super);
394 OBJ_RELEASE(node);
395 return ORTE_ERROR;
396 }
397
398 if (rc >= node->slots) {
399 if (node->slots_max != rc) {
400 node->slots_max = rc;
401 got_max = true;
402 }
403 } else {
404 orte_show_help("help-hostfile.txt", "max_slots_lt",
405 true,
406 cur_hostfile_name, node->slots, rc);
407 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
408 opal_list_remove_item(updates, &node->super);
409 OBJ_RELEASE(node);
410 return ORTE_ERROR;
411 }
412 break;
413
414 case ORTE_HOSTFILE_STRING:
415 case ORTE_HOSTFILE_INT:
416
417 break;
418
419 default:
420 hostfile_parse_error(token);
421 opal_list_remove_item(updates, &node->super);
422 OBJ_RELEASE(node);
423 return ORTE_ERROR;
424 }
425 if (number_of_slots > node->slots) {
426 ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM);
427 opal_list_remove_item(updates, &node->super);
428 OBJ_RELEASE(node);
429 return ORTE_ERROR;
430 }
431 }
432
433 done:
434 if (got_max && !ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_SLOTS_GIVEN)) {
435 node->slots = node->slots_max;
436 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
437 }
438
439 return ORTE_SUCCESS;
440 }
441
442
443
444
445
446
447 static int hostfile_parse(const char *hostfile, opal_list_t* updates,
448 opal_list_t* exclude, bool keep_all)
449 {
450 int token;
451 int rc = ORTE_SUCCESS;
452
453
454 cur_hostfile_name = hostfile;
455
456 orte_util_hostfile_done = false;
457 orte_util_hostfile_in = fopen(hostfile, "r");
458 if (NULL == orte_util_hostfile_in) {
459 if (NULL == orte_default_hostfile ||
460 0 != strcmp(orte_default_hostfile, hostfile)) {
461
462
463
464 orte_show_help("help-hostfile.txt", "no-hostfile", true, hostfile);
465 rc = ORTE_ERR_SILENT;
466 goto unlock;
467 }
468
469
470
471 if (orte_default_hostfile_given) {
472 orte_show_help("help-hostfile.txt", "no-hostfile", true, hostfile);
473 rc = ORTE_ERR_NOT_FOUND;
474 goto unlock;
475 }
476
477 rc = ORTE_SUCCESS;
478 goto unlock;
479 }
480
481 while (!orte_util_hostfile_done) {
482 token = orte_util_hostfile_lex();
483
484 switch (token) {
485 case ORTE_HOSTFILE_DONE:
486 orte_util_hostfile_done = true;
487 break;
488
489 case ORTE_HOSTFILE_NEWLINE:
490 break;
491
492
493
494
495
496
497
498 case ORTE_HOSTFILE_STRING:
499 case ORTE_HOSTFILE_INT:
500 case ORTE_HOSTFILE_HOSTNAME:
501 case ORTE_HOSTFILE_IPV4:
502 case ORTE_HOSTFILE_IPV6:
503 case ORTE_HOSTFILE_RELATIVE:
504 case ORTE_HOSTFILE_RANK:
505 rc = hostfile_parse_line(token, updates, exclude, keep_all);
506 if (ORTE_SUCCESS != rc) {
507 goto unlock;
508 }
509 break;
510
511 default:
512 hostfile_parse_error(token);
513 goto unlock;
514 }
515 }
516 fclose(orte_util_hostfile_in);
517 orte_util_hostfile_in = NULL;
518 orte_util_hostfile_lex_destroy();
519
520 unlock:
521 cur_hostfile_name = NULL;
522
523 return rc;
524 }
525
526
527
528
529
530
531 int orte_util_add_hostfile_nodes(opal_list_t *nodes,
532 char *hostfile)
533 {
534 opal_list_t exclude, adds;
535 opal_list_item_t *item, *itm;
536 int rc;
537 orte_node_t *nd, *node;
538 bool found;
539
540 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
541 "%s hostfile: checking hostfile %s for nodes",
542 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hostfile));
543
544 OBJ_CONSTRUCT(&exclude, opal_list_t);
545 OBJ_CONSTRUCT(&adds, opal_list_t);
546
547
548 if (ORTE_SUCCESS != (rc = hostfile_parse(hostfile, &adds, &exclude, false))) {
549 goto cleanup;
550 }
551
552
553 for (item = opal_list_get_first(&adds);
554 item != opal_list_get_end(&adds);
555 item = opal_list_get_next(item)) {
556 node=(orte_node_t*)item;
557
558 if ('+' == node->name[0]) {
559 orte_show_help("help-hostfile.txt", "hostfile:relative-syntax",
560 true, node->name);
561 rc = ORTE_ERR_SILENT;
562 goto cleanup;
563 }
564 }
565
566
567 while (NULL != (item = opal_list_remove_first(&exclude))) {
568 nd = (orte_node_t*)item;
569
570 for (itm = opal_list_get_first(&adds);
571 itm != opal_list_get_end(&adds);
572 itm = opal_list_get_next(itm)) {
573 node = (orte_node_t*)itm;
574 if (0 == strcmp(nd->name, node->name)) {
575
576 opal_list_remove_item(&adds, itm);
577 OBJ_RELEASE(itm);
578 break;
579 }
580 }
581 OBJ_RELEASE(item);
582 }
583
584
585 while (NULL != (item = opal_list_remove_first(&adds))) {
586 nd = (orte_node_t*)item;
587 found = false;
588 for (itm = opal_list_get_first(nodes);
589 itm != opal_list_get_end(nodes);
590 itm = opal_list_get_next(itm)) {
591 node = (orte_node_t*)itm;
592 if (0 == strcmp(nd->name, node->name)) {
593 found = true;
594 break;
595 }
596 }
597 if (!found) {
598 opal_list_append(nodes, &nd->super);
599 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
600 "%s hostfile: adding node %s slots %d",
601 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), nd->name, nd->slots));
602 } else {
603 OBJ_RELEASE(item);
604 }
605 }
606
607 cleanup:
608 OPAL_LIST_DESTRUCT(&exclude);
609 OPAL_LIST_DESTRUCT(&adds);
610
611 return rc;
612 }
613
614
615
616
617
618 int orte_util_filter_hostfile_nodes(opal_list_t *nodes,
619 char *hostfile,
620 bool remove)
621 {
622 opal_list_t newnodes, exclude;
623 opal_list_item_t *item1, *item2, *next, *item3;
624 orte_node_t *node_from_list, *node_from_file, *node_from_pool, *node3;
625 int rc = ORTE_SUCCESS;
626 char *cptr;
627 int num_empty, nodeidx;
628 bool want_all_empty = false;
629 opal_list_t keep;
630 bool found;
631
632 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
633 "%s hostfile: filtering nodes through hostfile %s",
634 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hostfile));
635
636
637 OBJ_CONSTRUCT(&newnodes, opal_list_t);
638 OBJ_CONSTRUCT(&exclude, opal_list_t);
639 if (ORTE_SUCCESS != (rc = hostfile_parse(hostfile, &newnodes, &exclude, false))) {
640 OBJ_DESTRUCT(&newnodes);
641 OBJ_DESTRUCT(&exclude);
642 return rc;
643 }
644
645
646 if (0 == opal_list_get_size(&newnodes)) {
647 OBJ_DESTRUCT(&newnodes);
648 OBJ_DESTRUCT(&exclude);
649
650 return ORTE_ERR_TAKE_NEXT_OPTION;
651 }
652
653
654
655 while (NULL != (item1 = opal_list_remove_first(&exclude))) {
656 node_from_file = (orte_node_t*)item1;
657
658 for (item2 = opal_list_get_first(&newnodes);
659 item2 != opal_list_get_end(&newnodes);
660 item2 = opal_list_get_next(item2)) {
661 orte_node_t *node = (orte_node_t*)item2;
662 if (0 == strcmp(node_from_file->name, node->name)) {
663
664 opal_list_remove_item(&newnodes, item2);
665 OBJ_RELEASE(item2);
666 break;
667 }
668 }
669 OBJ_RELEASE(item1);
670 }
671
672
673
674
675 OBJ_CONSTRUCT(&keep, opal_list_t);
676 while (NULL != (item2 = opal_list_remove_first(&newnodes))) {
677 node_from_file = (orte_node_t*)item2;
678
679 next = opal_list_get_next(item2);
680
681
682 if ('+' == node_from_file->name[0]) {
683
684 if ('e' == node_from_file->name[1] ||
685 'E' == node_from_file->name[1]) {
686
687
688
689 if (NULL != (cptr = strchr(node_from_file->name, ':'))) {
690
691 cptr++;
692 num_empty = strtol(cptr, NULL, 10);
693 } else {
694
695 num_empty = INT_MAX;
696 want_all_empty = true;
697 }
698
699
700
701 item1 = opal_list_get_first(nodes);
702 while (0 < num_empty && item1 != opal_list_get_end(nodes)) {
703 node_from_list = (orte_node_t*)item1;
704 next = opal_list_get_next(item1);
705 if (0 == node_from_list->slots_inuse) {
706
707
708
709 for (item3 = opal_list_get_first(&newnodes);
710 item3 != opal_list_get_end(&newnodes);
711 item3 = opal_list_get_next(item3)) {
712 node3 = (orte_node_t*)item3;
713 if (0 == strcmp(node3->name, node_from_list->name)) {
714
715 goto skipnode;
716 }
717 }
718 if (remove) {
719
720 opal_list_remove_item(nodes, item1);
721
722 opal_list_append(&keep, item1);
723 } else {
724
725 ORTE_FLAG_SET(node_from_list, ORTE_NODE_FLAG_MAPPED);
726 }
727 --num_empty;
728 }
729 skipnode:
730 item1 = next;
731 }
732
733 if (!want_all_empty && 0 < num_empty) {
734 orte_show_help("help-hostfile.txt", "hostfile:not-enough-empty",
735 true, num_empty);
736 rc = ORTE_ERR_SILENT;
737 goto cleanup;
738 }
739 } else if ('n' == node_from_file->name[1] ||
740 'N' == node_from_file->name[1]) {
741
742
743
744 nodeidx = strtol(&node_from_file->name[2], NULL, 10);
745 if (NULL == (node_from_pool = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
746
747 orte_show_help("help-hostfile.txt", "hostfile:relative-node-not-found",
748 true, nodeidx, node_from_file->name);
749 rc = ORTE_ERR_SILENT;
750 goto cleanup;
751 }
752
753 for (item1 = opal_list_get_first(nodes);
754 item1 != opal_list_get_end(nodes);
755 item1 = opal_list_get_next(nodes)) {
756 node_from_list = (orte_node_t*)item1;
757 if (0 == strcmp(node_from_list->name, node_from_pool->name)) {
758 if (remove) {
759
760 opal_list_remove_item(nodes, item1);
761
762 opal_list_append(&keep, item1);
763 } else {
764
765 ORTE_FLAG_SET(node_from_list, ORTE_NODE_FLAG_MAPPED);
766 }
767 break;
768 }
769 }
770 } else {
771
772 orte_show_help("help-hostfile.txt", "hostfile:invalid-relative-node-syntax",
773 true, node_from_file->name);
774 rc = ORTE_ERR_SILENT;
775 goto cleanup;
776 }
777 } else {
778
779
780
781
782 found = false;
783 for (item1 = opal_list_get_first(nodes);
784 item1 != opal_list_get_end(nodes);
785 item1 = opal_list_get_next(item1)) {
786 node_from_list = (orte_node_t*)item1;
787
788
789
790
791 if (0 == strcmp(node_from_file->name, node_from_list->name)) {
792
793
794
795
796
797 if (ORTE_FLAG_TEST(node_from_file, ORTE_NODE_FLAG_SLOTS_GIVEN) &&
798 node_from_file->slots < node_from_list->slots) {
799 node_from_list->slots = node_from_file->slots;
800 }
801 if (remove) {
802
803 opal_list_remove_item(nodes, item1);
804
805 opal_list_append(&keep, item1);
806 } else {
807
808 ORTE_FLAG_SET(node_from_list, ORTE_NODE_FLAG_MAPPED);
809 }
810 found = true;
811 break;
812 }
813 }
814
815
816
817
818 if (!found) {
819 orte_show_help("help-hostfile.txt", "hostfile:extra-node-not-found",
820 true, hostfile, node_from_file->name);
821 rc = ORTE_ERR_SILENT;
822 goto cleanup;
823 }
824 }
825
826 OBJ_RELEASE(item2);
827 }
828
829
830
831
832
833 if (0 != opal_list_get_size(&newnodes)) {
834 orte_show_help("help-hostfile.txt", "not-all-mapped-alloc",
835 true, hostfile);
836 while (NULL != (item1 = opal_list_remove_first(&newnodes))) {
837 OBJ_RELEASE(item1);
838 }
839 OBJ_DESTRUCT(&newnodes);
840 return ORTE_ERR_SILENT;
841 }
842
843 if (!remove) {
844
845 OBJ_DESTRUCT(&newnodes);
846 return ORTE_SUCCESS;
847 }
848
849
850 while (NULL != (item1 = opal_list_remove_first(nodes))) {
851 OBJ_RELEASE(item1);
852 }
853
854
855 while (NULL != (item1 = opal_list_remove_first(&keep))) {
856 opal_list_append(nodes, item1);
857 }
858
859 cleanup:
860 OBJ_DESTRUCT(&newnodes);
861
862 return rc;
863 }
864
865 int orte_util_get_ordered_host_list(opal_list_t *nodes,
866 char *hostfile)
867 {
868 opal_list_t exclude;
869 opal_list_item_t *item, *itm, *item2, *item1;
870 char *cptr;
871 int num_empty, i, nodeidx, startempty=0;
872 bool want_all_empty=false;
873 orte_node_t *node_from_pool, *newnode;
874 int rc;
875
876 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
877 "%s hostfile: creating ordered list of hosts from hostfile %s",
878 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hostfile));
879
880 OBJ_CONSTRUCT(&exclude, opal_list_t);
881
882
883 if (ORTE_SUCCESS != (rc = hostfile_parse(hostfile, nodes, &exclude, true))) {
884 goto cleanup;
885 }
886
887
888 item2 = opal_list_get_first(nodes);
889 while (item2 != opal_list_get_end(nodes)) {
890 orte_node_t *node=(orte_node_t*)item2;
891
892
893 item1 = opal_list_get_next(item2);
894
895 if ('+' != node->name[0]) {
896 item2 = item1;
897 continue;
898 }
899
900
901 if ('e' == node->name[1] ||
902 'E' == node->name[1]) {
903
904
905
906 if (NULL != (cptr = strchr(node->name, ':'))) {
907
908 cptr++;
909 num_empty = strtol(cptr, NULL, 10);
910 } else {
911
912 num_empty = INT_MAX;
913 want_all_empty = true;
914 }
915
916
917
918 if (!orte_hnp_is_allocated && 0 == startempty) {
919 startempty = 1;
920 }
921 for (i=startempty; 0 < num_empty && i < orte_node_pool->size; i++) {
922 if (NULL == (node_from_pool = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, i))) {
923 continue;
924 }
925 if (0 == node_from_pool->slots_inuse) {
926 newnode = OBJ_NEW(orte_node_t);
927 newnode->name = strdup(node_from_pool->name);
928
929
930
931
932
933 if (node->slots < node_from_pool->slots) {
934 newnode->slots = node->slots;
935 } else {
936 newnode->slots = node_from_pool->slots;
937 }
938 opal_list_insert_pos(nodes, item1, &newnode->super);
939
940 --num_empty;
941 }
942 }
943
944 startempty = i;
945
946 if (!want_all_empty && 0 < num_empty) {
947 orte_show_help("help-hostfile.txt", "hostfile:not-enough-empty",
948 true, num_empty);
949 rc = ORTE_ERR_SILENT;
950 goto cleanup;
951 }
952
953
954
955 opal_list_remove_item(nodes, item2);
956 OBJ_RELEASE(item2);
957 } else if ('n' == node->name[1] ||
958 'N' == node->name[1]) {
959
960
961
962 nodeidx = strtol(&node->name[2], NULL, 10);
963
964
965
966
967 if (!orte_hnp_is_allocated) {
968 nodeidx++;
969 }
970
971 if (NULL == (node_from_pool = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
972
973 orte_show_help("help-hostfile.txt", "hostfile:relative-node-not-found",
974 true, nodeidx, node->name);
975 rc = ORTE_ERR_SILENT;
976 goto cleanup;
977 }
978
979 newnode = OBJ_NEW(orte_node_t);
980 newnode->name = strdup(node_from_pool->name);
981
982
983
984
985
986 if (node->slots < node_from_pool->slots) {
987 newnode->slots = node->slots;
988 } else {
989 newnode->slots = node_from_pool->slots;
990 }
991
992 opal_list_insert_pos(nodes, item1, &newnode->super);
993
994
995
996 opal_list_remove_item(nodes, item2);
997 OBJ_RELEASE(item2);
998 } else {
999
1000 orte_show_help("help-hostfile.txt", "hostfile:invalid-relative-node-syntax",
1001 true, node->name);
1002 rc = ORTE_ERR_SILENT;
1003 goto cleanup;
1004 }
1005
1006
1007 item2 = item1;
1008 }
1009
1010
1011 while(NULL != (item = opal_list_remove_first(&exclude))) {
1012 orte_node_t *exnode = (orte_node_t*)item;
1013
1014 for (itm = opal_list_get_first(nodes);
1015 itm != opal_list_get_end(nodes);
1016 itm = opal_list_get_next(itm)) {
1017 orte_node_t *node=(orte_node_t*)itm;
1018 if (0 == strcmp(exnode->name, node->name)) {
1019
1020 opal_list_remove_item(nodes, itm);
1021 OBJ_RELEASE(itm);
1022
1023
1024
1025 }
1026 }
1027 OBJ_RELEASE(item);
1028 }
1029
1030 cleanup:
1031 OBJ_DESTRUCT(&exclude);
1032
1033 return rc;
1034 }