~ubuntu-branches/ubuntu/vivid/slurm-llnl/vivid

« back to all changes in this revision

Viewing changes to src/slurmctld/node_scheduler.c

  • Committer: Bazaar Package Importer
  • Author(s): Gennaro Oliva
  • Date: 2009-09-24 23:28:15 UTC
  • mfrom: (1.1.11 upstream) (3.2.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090924232815-enh65jn32q1ebg07
Tags: 2.0.5-1
* New upstream release 
* Changed dependecy from lib-mysqlclient15 to lib-mysqlclient 
* Added Default-Start for runlevel 2 and 4 and $remote_fs requirement in
  init.d scripts (Closes: #541252)
* Postinst checks for wrong runlevels 2 and 4 links
* Upgraded to standard version 3.8.3
* Add lintian overrides for missing slurm-llnl-configurator.html in doc
  base registration
* modified postrm scripts to ignore pkill return value in order to avoid
  postrm failure when no slurm process is running
* Checking for slurmctld.pid before cancelling running and pending
  jobs during package removal 

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *      Note: there is a global node table (node_record_table_ptr) 
4
4
 *****************************************************************************
5
5
 *  Copyright (C) 2002-2007 The Regents of the University of California.
6
 
 *  Copyright (C) 2008 Lawrence Livermore National Security.
 
6
 *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
7
7
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
8
8
 *  Written by Morris Jette <jette1@llnl.gov>
9
 
 *  LLNL-CODE-402394.
 
9
 *  CODE-OCEC-09-009. All rights reserved.
10
10
 *  
11
11
 *  This file is part of SLURM, a resource management program.
12
 
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 
12
 *  For details, see <https://computing.llnl.gov/linux/slurm/>.
 
13
 *  Please also read the included file: DISCLAIMER.
13
14
 *  
14
15
 *  SLURM is free software; you can redistribute it and/or modify it under
15
16
 *  the terms of the GNU General Public License as published by the Free
65
66
 
66
67
#include "src/slurmctld/acct_policy.h"
67
68
#include "src/slurmctld/agent.h"
 
69
#include "src/slurmctld/basil_interface.h"
 
70
#include "src/slurmctld/job_scheduler.h"
68
71
#include "src/slurmctld/licenses.h"
69
72
#include "src/slurmctld/node_scheduler.h"
 
73
#include "src/slurmctld/reservation.h"
70
74
#include "src/slurmctld/sched_plugin.h"
71
75
#include "src/slurmctld/slurmctld.h"
72
76
 
74
78
#define MAX_RETRIES   10
75
79
 
76
80
struct node_set {               /* set of nodes with same configuration */
77
 
        uint32_t cpus_per_node; /* NOTE: This is the minimum count,
 
81
        uint16_t cpus_per_node; /* NOTE: This is the minimum count,
78
82
                                 * if FastSchedule==0 then individual 
79
83
                                 * nodes within the same configuration 
80
84
                                 * line (in slurm.conf) can actually 
103
107
                            struct part_record *part_ptr,
104
108
                            uint32_t min_nodes, uint32_t max_nodes,
105
109
                            uint32_t req_nodes, bool test_only);
 
110
static void _reset_feature_counts(struct job_details *details_ptr);
 
111
static bool _valid_feature_counts(struct job_details *details_ptr);
106
112
static bitstr_t *_valid_features(struct job_details *detail_ptr, 
107
 
                                 struct config_record *config_ptr);
 
113
                                 struct config_record *config_ptr,
 
114
                                 bool update_count);
108
115
 
109
116
 
110
117
/*
157
164
                error("slurm_sched_freealloc(%u): %m", job_ptr->job_id);
158
165
        if (select_g_job_fini(job_ptr) != SLURM_SUCCESS)
159
166
                error("select_g_job_fini(%u): %m", job_ptr->job_id);
160
 
        
 
167
        (void) epilog_slurmctld(job_ptr);
 
168
 
 
169
#ifdef HAVE_CRAY_XT
 
170
        basil_release(job_ptr);
 
171
#endif /* HAVE_CRAY_XT */
 
172
 
161
173
        agent_args = xmalloc(sizeof(agent_arg_t));
162
174
        if (timeout)
163
175
                agent_args->msg_type = REQUEST_KILL_TIMELIMIT;
277
289
 *      (uint16_t)NO_VAL        = default
278
290
 *      0                       = exclusive
279
291
 *      1                       = share=yes
 
292
 *
 
293
 * Return values:
 
294
 *      0 = no sharing
 
295
 *      1 = user requested sharing
 
296
 *      2 = sharing enforced (either by partition or cons_res)
 
297
 * (cons_res plugin needs to distinguish between "enforced" and
 
298
 *  "requested" sharing)
280
299
 */
281
300
static int
282
301
_resolve_shared_status(uint16_t user_flag, uint16_t part_max_share,
287
306
                return 0;
288
307
        /* sharing if part=FORCE */
289
308
        if (part_max_share & SHARED_FORCE)
290
 
                return 1;
 
309
                return 2;
291
310
 
292
311
        if (cons_res_flag) {
293
312
                /* sharing unless user requested exclusive */
294
313
                if (user_flag == 0)
295
314
                        return 0;
296
 
                return 1;
 
315
                if (user_flag == 1)
 
316
                        return 1;
 
317
                return 2;
297
318
        } else {
298
319
                /* no sharing if part=NO */
299
320
                if (part_max_share == 1)
323
344
        uint32_t saved_min_nodes, saved_job_min_nodes;
324
345
        bitstr_t *saved_req_node_bitmap = NULL;
325
346
        uint32_t saved_num_procs, saved_req_nodes;
326
 
        int tmp_node_set_size;
 
347
        int rc, tmp_node_set_size;
327
348
        struct node_set *tmp_node_set_ptr;
328
349
        int error_code = SLURM_SUCCESS, i;
329
350
        bitstr_t *feature_bitmap, *accumulate_bitmap = NULL;
 
351
        bitstr_t *save_avail_node_bitmap = NULL, *resv_bitmap;
 
352
        time_t start_res = time(NULL);
 
353
 
 
354
        /* Mark nodes reserved for other jobs as off limit for this job */
 
355
        rc = job_test_resv(job_ptr, &start_res, false, &resv_bitmap);
 
356
        if ((rc != SLURM_SUCCESS) ||
 
357
            (bit_set_count(resv_bitmap) < min_nodes) ||
 
358
            (job_ptr->details->req_node_bitmap &&
 
359
             (!bit_super_set(job_ptr->details->req_node_bitmap,
 
360
                             resv_bitmap)))) {
 
361
                FREE_NULL_BITMAP(resv_bitmap);
 
362
                return ESLURM_NODES_BUSY;       /* reserved */
 
363
        }
 
364
        if (resv_bitmap &&
 
365
            (!bit_equal(resv_bitmap, avail_node_bitmap))) {
 
366
                bit_and(resv_bitmap, avail_node_bitmap);
 
367
                save_avail_node_bitmap = avail_node_bitmap;
 
368
                avail_node_bitmap = resv_bitmap;
 
369
        } else
 
370
                FREE_NULL_BITMAP(resv_bitmap);
330
371
 
331
372
        /* save job and request state */
332
373
        saved_min_nodes = min_nodes;
348
389
            (job_ptr->details->req_node_layout == NULL)) {
349
390
                ListIterator feat_iter;
350
391
                struct feature_record *feat_ptr;
351
 
                feat_iter = list_iterator_create(job_ptr->details->feature_list);
 
392
                feat_iter = list_iterator_create(
 
393
                                job_ptr->details->feature_list);
352
394
                while ((feat_ptr = (struct feature_record *)
353
395
                                list_next(feat_iter))) {
354
396
                        if (feat_ptr->count == 0)
361
403
                                if (!_match_feature(feat_ptr->name, 
362
404
                                                    node_set_ptr+i))
363
405
                                        continue;
364
 
                                tmp_node_set_ptr[tmp_node_set_size].cpus_per_node =
 
406
                                tmp_node_set_ptr[tmp_node_set_size].
 
407
                                        cpus_per_node =
365
408
                                        node_set_ptr[i].cpus_per_node;
366
 
                                tmp_node_set_ptr[tmp_node_set_size].real_memory =
 
409
                                tmp_node_set_ptr[tmp_node_set_size].
 
410
                                        real_memory =
367
411
                                        node_set_ptr[i].real_memory;
368
412
                                tmp_node_set_ptr[tmp_node_set_size].nodes =
369
413
                                        node_set_ptr[i].nodes;
371
415
                                        node_set_ptr[i].weight;
372
416
                                tmp_node_set_ptr[tmp_node_set_size].features = 
373
417
                                        xstrdup(node_set_ptr[i].features);
374
 
                                tmp_node_set_ptr[tmp_node_set_size].feature_array =
 
418
                                tmp_node_set_ptr[tmp_node_set_size].
 
419
                                        feature_array =
375
420
                                        node_set_ptr[i].feature_array;
376
 
                                tmp_node_set_ptr[tmp_node_set_size].feature_bits = 
 
421
                                tmp_node_set_ptr[tmp_node_set_size].
 
422
                                        feature_bits = 
377
423
                                        bit_copy(node_set_ptr[i].feature_bits);
378
 
                                tmp_node_set_ptr[tmp_node_set_size].my_bitmap = 
 
424
                                tmp_node_set_ptr[tmp_node_set_size].my_bitmap =
379
425
                                        bit_copy(node_set_ptr[i].my_bitmap);
380
426
                                tmp_node_set_size++;
381
427
                        }
391
437
#if 0
392
438
{
393
439
                        char *tmp_str = bitmap2node_name(feature_bitmap);
394
 
                        info("job %u needs %u nodes with feature %s, using %s", 
395
 
                                job_ptr->job_id, feat_ptr->count, 
396
 
                                feat_ptr->name, tmp_str);
 
440
                        info("job %u needs %u nodes with feature %s, "
 
441
                             "using %s, error_code=%d", 
 
442
                             job_ptr->job_id, feat_ptr->count, 
 
443
                             feat_ptr->name, tmp_str, error_code);
397
444
                        xfree(tmp_str);
398
445
}
399
446
#endif
400
447
                        for (i=0; i<tmp_node_set_size; i++) {
401
448
                                xfree(tmp_node_set_ptr[i].features);
402
 
                                FREE_NULL_BITMAP(tmp_node_set_ptr[i].feature_bits);
403
 
                                FREE_NULL_BITMAP(tmp_node_set_ptr[i].my_bitmap);
 
449
                                FREE_NULL_BITMAP(tmp_node_set_ptr[i].
 
450
                                                 feature_bits);
 
451
                                FREE_NULL_BITMAP(tmp_node_set_ptr[i].
 
452
                                                 my_bitmap);
404
453
                        }
405
454
                        if (error_code != SLURM_SUCCESS)
406
455
                                break;
407
456
                        if (feature_bitmap) {
408
457
                                if (job_ptr->details->req_node_bitmap) {
409
 
                                        bit_or(job_ptr->details->req_node_bitmap,
 
458
                                        bit_or(job_ptr->details->
 
459
                                               req_node_bitmap,
410
460
                                               feature_bitmap);
411
461
                                } else {
412
462
                                        job_ptr->details->req_node_bitmap =
413
463
                                                bit_copy(feature_bitmap);
414
464
                                }
415
465
                                if (accumulate_bitmap) {
416
 
                                        bit_or(accumulate_bitmap, feature_bitmap);
 
466
                                        bit_or(accumulate_bitmap, 
 
467
                                               feature_bitmap);
417
468
                                        bit_free(feature_bitmap);
418
469
                                } else
419
470
                                        accumulate_bitmap = feature_bitmap;
479
530
        job_ptr->num_procs = saved_num_procs;
480
531
        job_ptr->details->min_nodes = saved_job_min_nodes;
481
532
 
 
533
        /* Restore available node bitmap, ignoring reservations */
 
534
        if (save_avail_node_bitmap) {
 
535
                bit_free(avail_node_bitmap);
 
536
                avail_node_bitmap = save_avail_node_bitmap;
 
537
        }
 
538
 
482
539
        return error_code;
483
540
}
484
541
 
534
591
        bool runable_avail = false;     /* Job can run with available nodes */
535
592
        bool tried_sched = false;       /* Tried to schedule with avail nodes */
536
593
        static uint32_t cr_enabled = NO_VAL;
 
594
        static bool sched_gang_test = false;
 
595
        static bool sched_gang = false;
537
596
        select_type_plugin_info_t cr_type = SELECT_TYPE_INFO_NONE; 
538
597
        int shared = 0, select_mode;
539
598
 
551
610
        if (cr_enabled == NO_VAL) {
552
611
                cr_enabled = 0; /* select/linear and bluegene are no-ops */
553
612
                error_code = select_g_get_info_from_plugin (SELECT_CR_PLUGIN, 
554
 
                                                            &cr_enabled);
 
613
                                                            NULL, &cr_enabled);
555
614
                if (error_code != SLURM_SUCCESS) {
556
615
                        cr_enabled = NO_VAL;
557
616
                        return error_code;
569
628
 
570
629
                cr_type = (select_type_plugin_info_t) slurmctld_conf.
571
630
                                                        select_type_param;
572
 
                debug3("Job %u shared %d cr_enabled %d CR type %d num_procs %d", 
 
631
 
 
632
                /* Set the partially_idle_node_bitmap to reflect the
 
633
                 * idle and partially idle nodes */
 
634
                error_code = select_g_get_info_from_plugin (SELECT_BITMAP,
 
635
                                        job_ptr, &partially_idle_node_bitmap);
 
636
                if (error_code != SLURM_SUCCESS) {
 
637
                        FREE_NULL_BITMAP(partially_idle_node_bitmap);
 
638
                        return error_code;
 
639
                }
 
640
                debug3("Job %u shared %d CR type %d num_procs %d nbits %d", 
573
641
                     job_ptr->job_id, shared, cr_enabled, cr_type, 
574
 
                     job_ptr->num_procs);
575
 
 
576
 
                if (shared == 0) {
577
 
                        partially_idle_node_bitmap = bit_copy(idle_node_bitmap);
578
 
                } else {
579
 
                        /* Update partially_idle_node_bitmap to reflect the
580
 
                         * idle and partially idle nodes */
581
 
                        error_code = select_g_get_info_from_plugin (
582
 
                                        SELECT_BITMAP, 
583
 
                                        &partially_idle_node_bitmap);
584
 
                        if (error_code != SLURM_SUCCESS) {
585
 
                                FREE_NULL_BITMAP(partially_idle_node_bitmap);
586
 
                                return error_code;
587
 
                        }
588
 
                }
 
642
                     job_ptr->num_procs,
 
643
                     bit_set_count(partially_idle_node_bitmap));
589
644
        }
590
645
 
591
646
        if (job_ptr->details->req_node_bitmap) {  /* specific nodes required */
616
671
                                return ESLURM_NODES_BUSY;
617
672
                        }
618
673
                }
619
 
                if (shared) {
620
 
                        if (!bit_super_set(job_ptr->details->req_node_bitmap, 
621
 
                                           share_node_bitmap)) {
622
 
                                FREE_NULL_BITMAP(partially_idle_node_bitmap);
623
 
                                return ESLURM_NODES_BUSY;
624
 
                        }
625
 
                } else {
626
 
                        if (!bit_super_set(job_ptr->details->req_node_bitmap, 
627
 
                                           idle_node_bitmap)) {
628
 
                                FREE_NULL_BITMAP(partially_idle_node_bitmap);
629
 
                                return ESLURM_NODES_BUSY;
 
674
                /* If preemption is available via sched/gang, then
 
675
                 * do NOT limit the set of available nodes by their
 
676
                 * current 'sharable' or 'idle' setting */
 
677
                if (!sched_gang_test) {
 
678
                        char *sched_type = slurm_get_sched_type();
 
679
                        if (strcmp(sched_type, "sched/gang") == 0)
 
680
                                sched_gang = true;
 
681
                        xfree(sched_type);
 
682
                        sched_gang_test = true;
 
683
                }
 
684
                if (!sched_gang) {
 
685
                        if (shared) {
 
686
                                if (!bit_super_set(job_ptr->details->
 
687
                                                   req_node_bitmap, 
 
688
                                                   share_node_bitmap)) {
 
689
                                        FREE_NULL_BITMAP(
 
690
                                                partially_idle_node_bitmap);
 
691
                                        return ESLURM_NODES_BUSY;
 
692
                                }
 
693
                        } else {
 
694
                                if (!bit_super_set(job_ptr->details->
 
695
                                                   req_node_bitmap, 
 
696
                                                   idle_node_bitmap)) {
 
697
                                        FREE_NULL_BITMAP(
 
698
                                                partially_idle_node_bitmap);
 
699
                                        return ESLURM_NODES_BUSY;
 
700
                                }
630
701
                        }
631
702
                }
632
703
 
648
719
                        max_feature = j;
649
720
        }
650
721
 
 
722
        debug3("_pick_best_nodes: job %u idle_nodes %u share_nodes %u",
 
723
                job_ptr->job_id, bit_set_count(idle_node_bitmap),
 
724
                bit_set_count(share_node_bitmap));
651
725
        /* Accumulate resources for this job based upon its required 
652
726
         * features (possibly with node counts). */
653
727
        for (j = min_feature; j <= max_feature; j++) {
655
729
                        if (!bit_test(node_set_ptr[i].feature_bits, j))
656
730
                                continue;
657
731
 
658
 
                        if (total_bitmap)
659
 
                                bit_or(total_bitmap, node_set_ptr[i].my_bitmap);
660
 
                        else {
 
732
                        if (total_bitmap) {
 
733
                                bit_or(total_bitmap, 
 
734
                                       node_set_ptr[i].my_bitmap);
 
735
                        } else {
661
736
                                total_bitmap = bit_copy(
662
737
                                                node_set_ptr[i].my_bitmap);
663
738
                                if (total_bitmap == NULL)
669
744
                                bit_and(node_set_ptr[i].my_bitmap,
670
745
                                        partially_idle_node_bitmap);
671
746
                        }
672
 
                        if (shared) {
673
 
                                bit_and(node_set_ptr[i].my_bitmap,
674
 
                                        share_node_bitmap);
 
747
                        /* If preemption is available via sched/gang, then
 
748
                         * do NOT limit the set of available nodes by their
 
749
                         * current 'sharable' or 'idle' setting */
 
750
                        if (!sched_gang_test) {
 
751
                                char *sched_type = slurm_get_sched_type();
 
752
                                if (strcmp(sched_type, "sched/gang") == 0)
 
753
                                        sched_gang = true;
 
754
                                xfree(sched_type);
 
755
                                sched_gang_test = true;
 
756
                        }
 
757
                        if (!sched_gang) {
 
758
                                if (shared) {
 
759
                                        bit_and(node_set_ptr[i].my_bitmap,
 
760
                                                share_node_bitmap);
 
761
                                } else {
 
762
                                        bit_and(node_set_ptr[i].my_bitmap,
 
763
                                                idle_node_bitmap);
 
764
                                }
 
765
                        }
 
766
                        if (avail_bitmap) {
 
767
                                bit_or(avail_bitmap, 
 
768
                                       node_set_ptr[i].my_bitmap);
675
769
                        } else {
676
 
                                bit_and(node_set_ptr[i].my_bitmap,
677
 
                                        idle_node_bitmap);
678
 
                        }
679
 
                        if (avail_bitmap)
680
 
                                bit_or(avail_bitmap, node_set_ptr[i].my_bitmap);
681
 
                        else {
682
770
                                avail_bitmap = bit_copy(
683
771
                                        node_set_ptr[i].my_bitmap);
684
772
                                if (avail_bitmap == NULL)
688
776
                        tried_sched = false;    /* need to test these nodes */
689
777
 
690
778
                        if (shared && ((i+1) < node_set_size) && 
691
 
                            (node_set_ptr[i].weight == node_set_ptr[i+1].weight)) {
 
779
                            (node_set_ptr[i].weight == 
 
780
                             node_set_ptr[i+1].weight)) {
692
781
                                /* Keep accumulating so we can pick the
693
782
                                 * most lightly loaded nodes */
694
783
                                continue;
782
871
                                        fatal("bit_copy malloc failure");
783
872
                                bit_and(avail_bitmap, avail_node_bitmap);
784
873
                                pick_code = select_g_job_test(job_ptr, 
785
 
                                                              avail_bitmap, 
786
 
                                                              min_nodes, 
787
 
                                                              max_nodes,
788
 
                                                              req_nodes,
789
 
                                                              SELECT_MODE_TEST_ONLY);
 
874
                                                avail_bitmap, 
 
875
                                                min_nodes, 
 
876
                                                max_nodes,
 
877
                                                req_nodes,
 
878
                                                SELECT_MODE_TEST_ONLY);
790
879
                                if (pick_code == SLURM_SUCCESS) {
791
880
                                        runable_ever  = true;
792
881
                                        if (bit_set_count(avail_bitmap) <=
799
888
                        }
800
889
                        if (!runable_ever) {
801
890
                                pick_code = select_g_job_test(job_ptr, 
802
 
                                                              total_bitmap, 
803
 
                                                              min_nodes, 
804
 
                                                              max_nodes,
805
 
                                                              req_nodes, 
806
 
                                                              SELECT_MODE_TEST_ONLY);
 
891
                                                total_bitmap, 
 
892
                                                min_nodes, 
 
893
                                                max_nodes,
 
894
                                                req_nodes, 
 
895
                                                SELECT_MODE_TEST_ONLY);
807
896
                                if (pick_code == SLURM_SUCCESS) {
808
897
                                        FREE_NULL_BITMAP(possible_bitmap);
809
898
                                        possible_bitmap = total_bitmap;
824
913
                error_code = ESLURM_REQUESTED_PART_CONFIG_UNAVAILABLE;
825
914
        if (!runable_ever) {
826
915
                error_code = ESLURM_REQUESTED_NODE_CONFIG_UNAVAILABLE;
827
 
                info("_pick_best_nodes: job %u never runnable", job_ptr->job_id);
 
916
                info("_pick_best_nodes: job %u never runnable", 
 
917
                     job_ptr->job_id);
828
918
        }
829
919
 
830
920
        if (error_code == SLURM_SUCCESS) {
898
988
                 fail_reason = WAIT_PART_NODE_LIMIT;
899
989
        if (fail_reason != WAIT_NO_REASON) {
900
990
                job_ptr->state_reason = fail_reason;
 
991
                xfree(job_ptr->state_desc);
901
992
                last_job_update = now;
902
993
                if (job_ptr->priority == 0)     /* user/admin hold */
903
994
                        return ESLURM_JOB_HELD;
955
1046
                        debug3("JobId=%u not runnable with present config",
956
1047
                               job_ptr->job_id);
957
1048
                        job_ptr->state_reason = WAIT_PART_NODE_LIMIT;
 
1049
                        xfree(job_ptr->state_desc);
958
1050
                        if (job_ptr->priority != 0)  /* Move to end of queue */
959
1051
                                job_ptr->priority = 1;
960
1052
                        last_job_update = now;
 
1053
                } else if (error_code == ESLURM_RESERVATION_NOT_USABLE) {
 
1054
                        job_ptr->state_reason = WAIT_RESERVATION;
 
1055
                        xfree(job_ptr->state_desc);
961
1056
                } else {
962
1057
                        job_ptr->state_reason = WAIT_RESOURCES;
 
1058
                        xfree(job_ptr->state_desc);
963
1059
                        if (error_code == ESLURM_NODES_BUSY)
964
1060
                                slurm_sched_job_is_pending();
965
1061
                }
971
1067
                goto cleanup;
972
1068
        }
973
1069
 
 
1070
#ifdef HAVE_CRAY_XT
 
1071
        if (basil_reserve(job_ptr) != SLURM_SUCCESS) {
 
1072
                job_ptr->state_reason = WAIT_RESOURCES;
 
1073
                xfree(job_ptr->state_desc);
 
1074
                error_code = ESLURM_NODES_BUSY;
 
1075
                goto cleanup;
 
1076
        }
 
1077
#endif  /* HAVE_CRAY_XT */
 
1078
 
974
1079
        /* This job may be getting requeued, clear vestigial 
975
1080
         * state information before over-writting and leaking 
976
1081
         * memory. */
990
1095
                                    (365 * 24 * 60 * 60); /* secs in year */
991
1096
        else
992
1097
                job_ptr->end_time = job_ptr->start_time + 
993
 
                                    (job_ptr->time_limit * 60);   /* secs */
994
 
 
 
1098
                        (job_ptr->time_limit * 60);   /* secs */
 
1099
        
995
1100
        if (select_g_job_begin(job_ptr) != SLURM_SUCCESS) {
996
1101
                /* Leave job queued, something is hosed */
997
1102
                error("select_g_job_begin(%u): %m", job_ptr->job_id);
999
1104
                job_ptr->start_time = 0;
1000
1105
                job_ptr->time_last_active = 0;
1001
1106
                job_ptr->end_time = 0;
 
1107
                job_ptr->node_bitmap = NULL;
1002
1108
                goto cleanup;
1003
1109
        }
1004
1110
 
1005
1111
        /* assign the nodes and stage_in the job */
1006
1112
        job_ptr->state_reason = WAIT_NO_REASON;
 
1113
        xfree(job_ptr->state_desc);
1007
1114
        job_ptr->nodes = bitmap2node_name(select_bitmap);
1008
1115
        select_bitmap = NULL;   /* nothing left to free */
1009
1116
        allocate_nodes(job_ptr);
1018
1125
 
1019
1126
        acct_policy_job_begin(job_ptr);
1020
1127
 
1021
 
        jobacct_storage_g_job_start(
1022
 
                acct_db_conn, slurmctld_cluster_name, job_ptr);
1023
 
 
 
1128
        jobacct_storage_g_job_start(acct_db_conn, slurmctld_cluster_name, 
 
1129
                                    job_ptr);
 
1130
        prolog_slurmctld(job_ptr);
1024
1131
        slurm_sched_newalloc(job_ptr);
1025
1132
 
1026
1133
      cleanup:
1039
1146
        return error_code;
1040
1147
}
1041
1148
 
 
1149
/* Clear tmp_cnt for all features of given job */
 
1150
static void _reset_feature_counts(struct job_details *details_ptr)
 
1151
{
 
1152
        ListIterator feat_iter;
 
1153
        struct feature_record *feat_ptr;
 
1154
 
 
1155
        if (details_ptr->feature_list == NULL)  /* no constraints */
 
1156
                return;
 
1157
 
 
1158
        feat_iter = list_iterator_create(details_ptr->feature_list);
 
1159
        while ((feat_ptr = (struct feature_record *) list_next(feat_iter))) {
 
1160
                feat_ptr->tmp_cnt = 0;
 
1161
        }
 
1162
        list_iterator_destroy(feat_iter);
 
1163
}
 
1164
 
 
1165
/* Verify that tmp_cnt >= count for all features of given job */
 
1166
static bool _valid_feature_counts(struct job_details *details_ptr)
 
1167
{
 
1168
        ListIterator feat_iter;
 
1169
        struct feature_record *feat_ptr;
 
1170
        bool result = true;
 
1171
 
 
1172
        if (details_ptr->feature_list == NULL)  /* no constraints */
 
1173
                return result;
 
1174
 
 
1175
        feat_iter = list_iterator_create(details_ptr->feature_list);
 
1176
        while ((feat_ptr = (struct feature_record *) list_next(feat_iter))) {
 
1177
                if (feat_ptr->tmp_cnt >= feat_ptr->count)
 
1178
                        continue;
 
1179
                result = false;
 
1180
                break;
 
1181
        }
 
1182
        list_iterator_destroy(feat_iter);
 
1183
        return result;
 
1184
}
 
1185
 
1042
1186
/*
1043
1187
 * job_req_node_filter - job reqeust node filter.
1044
1188
 *      clear from a bitmap the nodes which can not be used for a job
1045
1189
 *      test memory size, required features, processor count, etc.
1046
 
 * NOTE: Does not support exclusive OR of features or feature counts.
 
1190
 * NOTE: Does not support exclusive OR of features.
1047
1191
 *      It just matches first element of XOR and ignores count.
1048
1192
 * IN job_ptr - pointer to node to be scheduled
1049
1193
 * IN/OUT bitmap - set of nodes being considered for use
1065
1209
                return EINVAL;
1066
1210
        }
1067
1211
 
 
1212
        _reset_feature_counts(detail_ptr);
1068
1213
        mc_ptr = detail_ptr->mc_ptr;
1069
1214
        for (i=0; i< node_record_count; i++) {
1070
1215
                if (!bit_test(avail_bitmap, i))
1071
1216
                        continue;
1072
1217
                node_ptr = node_record_table_ptr + i;
1073
1218
                config_ptr = node_ptr->config_ptr;
1074
 
                feature_bitmap = _valid_features(detail_ptr, config_ptr);
1075
 
                if ((feature_bitmap == NULL) || (!bit_test(feature_bitmap, 0))) {
 
1219
                feature_bitmap = _valid_features(detail_ptr, config_ptr, true);
 
1220
                if ((feature_bitmap == NULL) || 
 
1221
                    (!bit_test(feature_bitmap, 0))) {
1076
1222
                        bit_clear(avail_bitmap, i);
1077
1223
                        continue;
1078
1224
                }
1079
1225
                FREE_NULL_BITMAP(feature_bitmap);
1080
1226
                if (slurmctld_conf.fast_schedule) {
1081
 
                        if ((detail_ptr->job_min_procs    > config_ptr->cpus       )
 
1227
                        if ((detail_ptr->job_min_procs    > 
 
1228
                             config_ptr->cpus       )
1082
1229
                        ||  ((detail_ptr->job_min_memory & (~MEM_PER_CPU)) > 
1083
1230
                              config_ptr->real_memory) 
1084
 
                        ||  (detail_ptr->job_min_tmp_disk > config_ptr->tmp_disk)) {
 
1231
                        ||  (detail_ptr->job_min_tmp_disk > 
 
1232
                             config_ptr->tmp_disk)) {
1085
1233
                                bit_clear(avail_bitmap, i);
1086
1234
                                continue;
1087
1235
                        }
1091
1239
                        ||   (mc_ptr->min_threads     > config_ptr->threads  )
1092
1240
                        ||   (mc_ptr->job_min_sockets > config_ptr->sockets  )
1093
1241
                        ||   (mc_ptr->job_min_cores   > config_ptr->cores    )
1094
 
                        ||   (mc_ptr->job_min_threads > config_ptr->threads  ))) {
 
1242
                        ||   (mc_ptr->job_min_threads > 
 
1243
                              config_ptr->threads  ))) {
1095
1244
                                bit_clear(avail_bitmap, i);
1096
1245
                                continue;
1097
1246
                        }
1098
1247
                } else {
1099
 
                        if ((detail_ptr->job_min_procs    > node_ptr->cpus       )
 
1248
                        if ((detail_ptr->job_min_procs    > 
 
1249
                             node_ptr->cpus       )
1100
1250
                        ||  ((detail_ptr->job_min_memory & (~MEM_PER_CPU)) >
1101
1251
                              node_ptr->real_memory) 
1102
 
                        ||  (detail_ptr->job_min_tmp_disk > node_ptr->tmp_disk)) {
 
1252
                        ||  (detail_ptr->job_min_tmp_disk > 
 
1253
                             node_ptr->tmp_disk)) {
1103
1254
                                bit_clear(avail_bitmap, i);
1104
1255
                                continue;
1105
1256
                        }
1116
1267
                }
1117
1268
        }
1118
1269
        FREE_NULL_BITMAP(feature_bitmap);
 
1270
 
 
1271
        if (!_valid_feature_counts(detail_ptr))
 
1272
                return EINVAL;
 
1273
 
1119
1274
        return SLURM_SUCCESS;
1120
1275
}
1121
1276
 
1133
1288
                            struct node_set **node_set_pptr,
1134
1289
                            int *node_set_size)
1135
1290
{
1136
 
        int node_set_inx;
 
1291
        int i, node_set_inx, power_cnt, rc;
1137
1292
        struct node_set *node_set_ptr;
1138
1293
        struct config_record *config_ptr;
1139
1294
        struct part_record *part_ptr = job_ptr->part_ptr;
1140
1295
        ListIterator config_iterator;
1141
1296
        int check_node_config, config_filter = 0;
1142
1297
        struct job_details *detail_ptr = job_ptr->details;
1143
 
        bitstr_t *exc_node_mask = NULL;
 
1298
        bitstr_t *power_up_bitmap = NULL, *usable_node_mask = NULL;
1144
1299
        multi_core_data_t *mc_ptr = detail_ptr->mc_ptr;
1145
1300
        bitstr_t *tmp_feature;
 
1301
        uint32_t max_weight = 0;
 
1302
 
 
1303
        if (job_ptr->resv_name) {
 
1304
                /* Limit node selection to those in selected reservation */
 
1305
                time_t start_res = time(NULL);
 
1306
                rc = job_test_resv(job_ptr, &start_res, false, 
 
1307
                                   &usable_node_mask);
 
1308
                if (rc != SLURM_SUCCESS) {
 
1309
                        job_ptr->state_reason = WAIT_RESERVATION;
 
1310
                        xfree(job_ptr->state_desc);
 
1311
                        if (rc == ESLURM_INVALID_TIME_VALUE)
 
1312
                                return ESLURM_RESERVATION_NOT_USABLE;
 
1313
                        /* Defunct reservation or accesss denied */
 
1314
                        return ESLURM_REQUESTED_NODE_CONFIG_UNAVAILABLE;
 
1315
                }
 
1316
                if ((detail_ptr->req_node_bitmap) &&
 
1317
                    (!bit_super_set(detail_ptr->req_node_bitmap, 
 
1318
                                    usable_node_mask))) {
 
1319
                        job_ptr->state_reason = WAIT_RESERVATION;
 
1320
                        xfree(job_ptr->state_desc);
 
1321
                        FREE_NULL_BITMAP(usable_node_mask);
 
1322
                        /* Required nodes outside of the reservation */
 
1323
                        return ESLURM_REQUESTED_NODE_CONFIG_UNAVAILABLE;
 
1324
                }
 
1325
        }
1146
1326
 
1147
1327
        node_set_inx = 0;
1148
1328
        node_set_ptr = (struct node_set *) 
1149
1329
                        xmalloc(sizeof(struct node_set) * 2);
1150
1330
        node_set_ptr[node_set_inx+1].my_bitmap = NULL;
1151
1331
        if (detail_ptr->exc_node_bitmap) {
1152
 
                exc_node_mask = bit_copy(detail_ptr->exc_node_bitmap);
1153
 
                if (exc_node_mask == NULL)
1154
 
                        fatal("bit_copy malloc failure");
1155
 
                bit_not(exc_node_mask);
 
1332
                if (usable_node_mask) {
 
1333
                        bit_not(detail_ptr->exc_node_bitmap);
 
1334
                        bit_and(usable_node_mask, detail_ptr->exc_node_bitmap);
 
1335
                        bit_not(detail_ptr->exc_node_bitmap);
 
1336
                } else {
 
1337
                        usable_node_mask = 
 
1338
                                bit_copy(detail_ptr->exc_node_bitmap);
 
1339
                        if (usable_node_mask == NULL)
 
1340
                                fatal("bit_copy malloc failure");
 
1341
                        bit_not(usable_node_mask);
 
1342
                }
1156
1343
        }
1157
1344
 
1158
1345
        config_iterator = list_iterator_create(config_list);
1195
1382
                        fatal("bit_copy malloc failure");
1196
1383
                bit_and(node_set_ptr[node_set_inx].my_bitmap,
1197
1384
                        part_ptr->node_bitmap);
1198
 
                if (exc_node_mask) {
 
1385
                if (usable_node_mask) {
1199
1386
                        bit_and(node_set_ptr[node_set_inx].my_bitmap,
1200
 
                                exc_node_mask);
 
1387
                                usable_node_mask);
1201
1388
                }
1202
1389
                node_set_ptr[node_set_inx].nodes =
1203
1390
                        bit_set_count(node_set_ptr[node_set_inx].my_bitmap);
1211
1398
                        continue;
1212
1399
                }
1213
1400
 
1214
 
                tmp_feature = _valid_features(job_ptr->details, config_ptr);
 
1401
                tmp_feature = _valid_features(job_ptr->details, config_ptr, 
 
1402
                                              false);
1215
1403
                if (tmp_feature == NULL) {
1216
1404
                        FREE_NULL_BITMAP(node_set_ptr[node_set_inx].my_bitmap);
1217
1405
                        continue;
1221
1409
                node_set_ptr[node_set_inx].cpus_per_node =
1222
1410
                        config_ptr->cpus;
1223
1411
                node_set_ptr[node_set_inx].real_memory =
1224
 
                        config_ptr->real_memory;                
 
1412
                        config_ptr->real_memory;
1225
1413
                node_set_ptr[node_set_inx].weight =
1226
1414
                        config_ptr->weight;
 
1415
                max_weight = MAX(max_weight, config_ptr->weight);
1227
1416
                node_set_ptr[node_set_inx].features = 
1228
1417
                        xstrdup(config_ptr->feature);
1229
1418
                node_set_ptr[node_set_inx].feature_array = 
1242
1431
        xfree(node_set_ptr[node_set_inx].features);
1243
1432
        FREE_NULL_BITMAP(node_set_ptr[node_set_inx].my_bitmap);
1244
1433
        FREE_NULL_BITMAP(node_set_ptr[node_set_inx].feature_bits);
1245
 
        FREE_NULL_BITMAP(exc_node_mask);
 
1434
        FREE_NULL_BITMAP(usable_node_mask);
1246
1435
 
1247
1436
        if (node_set_inx == 0) {
1248
1437
                info("No nodes satisfy job %u requirements", 
1251
1440
                return ESLURM_REQUESTED_NODE_CONFIG_UNAVAILABLE;
1252
1441
        }
1253
1442
 
 
1443
        /* If any nodes are powered down, put them into a new node_set
 
1444
         * record with a higher scheduling weight . This means we avoid
 
1445
         * scheduling jobs on powered down nodes where possible. */
 
1446
        for (i = (node_set_inx-1); i >= 0; i--) {
 
1447
                power_cnt = bit_overlap(node_set_ptr[i].my_bitmap,
 
1448
                                        power_node_bitmap);
 
1449
                if (power_cnt == 0)
 
1450
                        continue;       /* no nodes powered down */
 
1451
                if (power_cnt == node_set_ptr[i].nodes) {
 
1452
                        node_set_ptr[i].weight += max_weight;   /* avoid all */
 
1453
                        continue;       /* all nodes powered down */
 
1454
                }
 
1455
 
 
1456
                /* Some nodes powered down, others up, split record */
 
1457
                node_set_ptr[node_set_inx].cpus_per_node =
 
1458
                        node_set_ptr[i].cpus_per_node;
 
1459
                node_set_ptr[node_set_inx].real_memory =
 
1460
                        node_set_ptr[i].real_memory;
 
1461
                node_set_ptr[node_set_inx].nodes = power_cnt;
 
1462
                node_set_ptr[i].nodes -= power_cnt;
 
1463
                node_set_ptr[node_set_inx].weight =
 
1464
                        node_set_ptr[i].weight + max_weight;
 
1465
                node_set_ptr[node_set_inx].features =
 
1466
                        xstrdup(node_set_ptr[i].features);
 
1467
                node_set_ptr[node_set_inx].feature_array =
 
1468
                        node_set_ptr[i].feature_array;
 
1469
                node_set_ptr[node_set_inx].feature_bits =
 
1470
                        bit_copy(node_set_ptr[i].feature_bits);
 
1471
                node_set_ptr[node_set_inx].my_bitmap = 
 
1472
                        bit_copy(node_set_ptr[i].my_bitmap);
 
1473
                bit_and(node_set_ptr[node_set_inx].my_bitmap,
 
1474
                        power_node_bitmap);
 
1475
                if (power_up_bitmap == NULL) {
 
1476
                        power_up_bitmap = bit_copy(power_node_bitmap);
 
1477
                        bit_not(power_up_bitmap);
 
1478
                }
 
1479
                bit_and(node_set_ptr[i].my_bitmap, power_up_bitmap);
 
1480
 
 
1481
                node_set_inx++;
 
1482
                xrealloc(node_set_ptr,
 
1483
                         sizeof(struct node_set) * (node_set_inx + 2));
 
1484
                node_set_ptr[node_set_inx + 1].my_bitmap = NULL;
 
1485
        }
 
1486
        FREE_NULL_BITMAP(power_up_bitmap);
 
1487
 
1254
1488
        *node_set_size = node_set_inx;
1255
1489
        *node_set_pptr = node_set_ptr;
1256
1490
        return SLURM_SUCCESS;
1358
1592
        return error_code;
1359
1593
}
1360
1594
 
1361
 
/* Update record of a job's allocated processors for each step */
1362
 
static void _alloc_step_cpus(struct job_record *job_ptr)
1363
 
{
1364
 
        ListIterator step_iterator;
1365
 
        struct step_record *step_ptr;
1366
 
 
1367
 
        if (job_ptr->step_list == NULL)
1368
 
                return;
1369
 
 
1370
 
        step_iterator = list_iterator_create(job_ptr->step_list);
1371
 
        while ((step_ptr = (struct step_record *) list_next(step_iterator))) {
1372
 
                step_alloc_lps(step_ptr);
1373
 
        }
1374
 
        list_iterator_destroy(step_iterator);
1375
 
}
1376
 
 
1377
1595
/*
1378
 
 * build_node_details - set cpu counts and addresses for allocated nodes:
1379
 
 *      cpu_count_reps, cpus_per_node, node_addr, node_cnt, num_cpu_groups
 
1596
 * build_node_details - sets addresses for allocated nodes
1380
1597
 * IN job_ptr - pointer to a job record
1381
1598
 */
1382
1599
extern void build_node_details(struct job_record *job_ptr)
1384
1601
        hostlist_t host_list = NULL;
1385
1602
        struct node_record *node_ptr;
1386
1603
        char *this_node_name;
1387
 
        int error_code = SLURM_SUCCESS;
1388
 
        int node_inx = 0, cpu_inx = -1;
1389
 
        int cr_count = 0;
1390
 
        uint32_t total_procs = 0;
 
1604
        int node_inx = 0;
1391
1605
 
1392
1606
        if ((job_ptr->node_bitmap == NULL) || (job_ptr->nodes == NULL)) {
1393
1607
                /* No nodes allocated, we're done... */
1394
 
                job_ptr->num_cpu_groups = 0;
1395
1608
                job_ptr->node_cnt = 0;
1396
 
                job_ptr->cpus_per_node = NULL;
1397
 
                job_ptr->cpu_count_reps = NULL;
1398
1609
                job_ptr->node_addr = NULL;
1399
 
                job_ptr->alloc_lps_cnt = 0;
1400
 
                xfree(job_ptr->alloc_lps);
1401
 
                xfree(job_ptr->used_lps);
1402
1610
                return;
1403
1611
        }
1404
 
 
1405
 
        job_ptr->num_cpu_groups = 0;
1406
1612
        
1407
1613
        /* Use hostlist here to insure ordering of info matches that of srun */
1408
1614
        if ((host_list = hostlist_create(job_ptr->nodes)) == NULL)
1409
1615
                fatal("hostlist_create error for %s: %m", job_ptr->nodes);
1410
 
 
1411
1616
        job_ptr->node_cnt = hostlist_count(host_list);  
1412
 
 
1413
 
        xrealloc(job_ptr->cpus_per_node, 
1414
 
                 (sizeof(uint32_t) * job_ptr->node_cnt));
1415
 
        xrealloc(job_ptr->cpu_count_reps, 
1416
 
                 (sizeof(uint32_t) * job_ptr->node_cnt));
1417
1617
        xrealloc(job_ptr->node_addr, 
1418
1618
                 (sizeof(slurm_addr) * job_ptr->node_cnt));     
1419
1619
 
1420
 
        job_ptr->alloc_lps_cnt = job_ptr->node_cnt;
1421
 
        xrealloc(job_ptr->alloc_lps,
1422
 
                 (sizeof(uint32_t) * job_ptr->node_cnt));
1423
 
        xrealloc(job_ptr->used_lps,
1424
 
                 (sizeof(uint32_t) * job_ptr->node_cnt));
1425
 
 
1426
1620
        while ((this_node_name = hostlist_shift(host_list))) {
1427
 
                node_ptr = find_node_record(this_node_name);
1428
 
                                
1429
 
                if (node_ptr) {
1430
 
                        uint16_t usable_lps = 0;
1431
 
#ifdef HAVE_BG
1432
 
                        if(job_ptr->node_cnt == 1) {
1433
 
                                memcpy(&job_ptr->node_addr[node_inx++],
1434
 
                                       &node_ptr->slurm_addr, 
1435
 
                                       sizeof(slurm_addr));
1436
 
                                cpu_inx++;
1437
 
                                
1438
 
                                job_ptr->cpus_per_node[cpu_inx] =
1439
 
                                        job_ptr->num_procs;
1440
 
                                total_procs += job_ptr->num_procs;
1441
 
                                job_ptr->cpu_count_reps[cpu_inx] = 1;
1442
 
                                job_ptr->alloc_lps[0] = job_ptr->num_procs;
1443
 
                                job_ptr->used_lps[0]  = 0;
1444
 
                                goto cleanup;
1445
 
                        }
1446
 
#endif
1447
 
                        error_code = select_g_get_extra_jobinfo( 
1448
 
                                node_ptr, job_ptr, SELECT_AVAIL_CPUS, 
1449
 
                                &usable_lps);
1450
 
                        if (error_code == SLURM_SUCCESS) {
1451
 
                                if (job_ptr->alloc_lps) {
1452
 
                                        job_ptr->used_lps[cr_count] = 0;
1453
 
                                        job_ptr->alloc_lps[cr_count++] =
1454
 
                                                                usable_lps;
1455
 
                                }
1456
 
                        } else {
1457
 
                                error("Unable to get extra jobinfo "
1458
 
                                      "from JobId=%u", job_ptr->job_id);
1459
 
                                /* Job is likely completed according to 
1460
 
                                 * select plugin */
1461
 
                                if (job_ptr->alloc_lps) {
1462
 
                                        job_ptr->used_lps[cr_count] = 0;
1463
 
                                        job_ptr->alloc_lps[cr_count++] = 0;
1464
 
                                }
1465
 
                        }
1466
 
                        
 
1621
                if ((node_ptr = find_node_record(this_node_name))) {
1467
1622
                        memcpy(&job_ptr->node_addr[node_inx++],
1468
1623
                               &node_ptr->slurm_addr, sizeof(slurm_addr));
1469
 
 
1470
 
                        if ((cpu_inx == -1) ||
1471
 
                            (job_ptr->cpus_per_node[cpu_inx] !=
1472
 
                             usable_lps)) {
1473
 
                                cpu_inx++;
1474
 
                                job_ptr->cpus_per_node[cpu_inx] =
1475
 
                                        usable_lps;
1476
 
                                job_ptr->cpu_count_reps[cpu_inx] = 1;
1477
 
                        } else
1478
 
                                job_ptr->cpu_count_reps[cpu_inx]++;
1479
 
                        total_procs +=  usable_lps;
1480
 
 
1481
1624
                } else {
1482
1625
                        error("Invalid node %s in JobId=%u",
1483
1626
                              this_node_name, job_ptr->job_id);
1484
1627
                }
1485
 
#ifdef HAVE_BG
1486
 
 cleanup:       
1487
 
#endif
1488
1628
                free(this_node_name);
1489
1629
        }
1490
1630
        hostlist_destroy(host_list);
1492
1632
                error("Node count mismatch for JobId=%u (%u,%u)",
1493
1633
                      job_ptr->job_id, job_ptr->node_cnt, node_inx);
1494
1634
        }
1495
 
        job_ptr->num_cpu_groups = cpu_inx + 1;
1496
 
        job_ptr->total_procs = total_procs;
1497
 
        _alloc_step_cpus(job_ptr);      /* reset counters */
1498
1635
}
1499
1636
 
1500
1637
/*
1502
1639
 *      the available nodes
1503
1640
 * IN details_ptr - job requirement details, includes requested features
1504
1641
 * IN config_ptr - node's configuration record
 
1642
 * IN update_count - if set, then increment tmp_cnt (temporary counter)
 
1643
 *      for matched features
1505
1644
 * RET NULL if request is not satisfied, otherwise a bitmap indicating 
1506
1645
 *      which mutually exclusive features are satisfied. For example
1507
1646
 *      _valid_features("[fs1|fs2|fs3|fs4]", "fs3") returns a bitmap with
1512
1651
 *      mutually exclusive feature list.
1513
1652
 */
1514
1653
static bitstr_t *_valid_features(struct job_details *details_ptr, 
1515
 
                                 struct config_record *config_ptr)
 
1654
                                 struct config_record *config_ptr,
 
1655
                                 bool update_count)
1516
1656
{
1517
1657
        bitstr_t *result_bits = (bitstr_t *) NULL;
1518
1658
        ListIterator feat_iter;
1519
1659
        struct feature_record *feat_ptr;
1520
 
        int found, last_op, position = 0, result;
1521
 
        int save_op = FEATURE_OP_AND, save_result=1;
 
1660
        bool found, test_names, result;
 
1661
        int last_op, position = 0;
 
1662
        int save_op = FEATURE_OP_AND, save_result = 1;
1522
1663
 
1523
 
        if (details_ptr->feature_list == NULL) {/* no constraints */
 
1664
        if (details_ptr->feature_list == NULL) {        /* no constraints */
1524
1665
                result_bits = bit_alloc(MAX_FEATURES);
1525
1666
                bit_set(result_bits, 0);
1526
1667
                return result_bits;
1527
1668
        }
1528
1669
 
1529
 
        result = 1;                             /* assume good for now */
 
1670
        result = true;                          /* assume good for now */
1530
1671
        last_op = FEATURE_OP_AND;
1531
1672
        feat_iter = list_iterator_create(details_ptr->feature_list);
1532
1673
        while ((feat_ptr = (struct feature_record *) list_next(feat_iter))) {
1533
 
                found = 0;
1534
 
                if (feat_ptr->count)
1535
 
                        found = 1;
1536
 
                else if (config_ptr->feature_array) {
 
1674
                test_names = false;
 
1675
                found = false;
 
1676
                if (feat_ptr->count) {
 
1677
                        found = true;
 
1678
                        if (update_count)
 
1679
                                test_names = true;
 
1680
                } else  
 
1681
                        test_names = true;
 
1682
 
 
1683
                if (test_names && config_ptr->feature_array) {
1537
1684
                        int i;
1538
1685
                        for (i=0; config_ptr->feature_array[i]; i++) {
1539
1686
                                if (strcmp(feat_ptr->name, 
1540
1687
                                           config_ptr->feature_array[i]))
1541
1688
                                        continue;
1542
 
                                found = 1;
 
1689
                                found = true;
 
1690
                                if (update_count && feat_ptr->count)
 
1691
                                        feat_ptr->tmp_cnt++;
1543
1692
                                break;
1544
1693
                        }
1545
1694
                }
1654
1803
 
1655
1804
        if (agent_args->node_count == 0) {
1656
1805
                xfree(kill_job);
 
1806
                if(agent_args->hostlist)
 
1807
                        hostlist_destroy(agent_args->hostlist);
1657
1808
                xfree(agent_args);
1658
1809
                hostlist_destroy(kill_hostlist);
1659
1810
                return;