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

« back to all changes in this revision

Viewing changes to src/slurmctld/partition_mgr.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:
2
2
 *  partition_mgr.c - manage the partition information of slurm
3
3
 *      Note: there is a global partition list (part_list) and
4
4
 *      time stamp (last_part_update)
5
 
 *  $Id: partition_mgr.c 15121 2008-09-19 18:31:06Z da $
 
5
 *  $Id: partition_mgr.c 18102 2009-07-09 20:45:13Z jette $
6
6
 *****************************************************************************
7
7
 *  Copyright (C) 2002-2007 The Regents of the University of California.
8
8
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
9
9
 *  Written by Morris Jette <jette@llnl.gov> et. al.
10
 
 *  LLNL-CODE-402394.
 
10
 *  CODE-OCEC-09-009. All rights reserved.
11
11
 *  
12
12
 *  This file is part of SLURM, a resource management program.
13
 
 *  For details, see <http://www.llnl.gov/linux/slurm/>.
 
13
 *  For details, see <https://computing.llnl.gov/linux/slurm/>.
 
14
 *  Please also read the included file: DISCLAIMER.
14
15
 *  
15
16
 *  SLURM is free software; you can redistribute it and/or modify it under
16
17
 *  the terms of the GNU General Public License as published by the Free
67
68
#include "src/slurmctld/slurmctld.h"
68
69
 
69
70
/* Change PART_STATE_VERSION value when changing the state save format */
70
 
#define PART_STATE_VERSION      "VER001"
 
71
#define PART_STATE_VERSION      "VER002"
71
72
 
72
73
/* Global variables */
73
74
struct part_record default_part;        /* default configuration values */
75
76
char *default_part_name = NULL;         /* name of default partition */
76
77
struct part_record *default_part_loc = NULL; /* default partition location */
77
78
time_t last_part_update;        /* time of last update to partition records */
 
79
uint16_t part_max_priority = 0;         /* max priority in all partitions */
78
80
 
79
81
static int    _build_part_bitmap(struct part_record *part_ptr);
80
82
static int    _delete_part_record(char *name);
109
111
        part_ptr->total_nodes = 0;
110
112
 
111
113
        if (part_ptr->node_bitmap == NULL) {
112
 
                part_ptr->node_bitmap = 
113
 
                        (bitstr_t *) bit_alloc(node_record_count);
 
114
                part_ptr->node_bitmap = bit_alloc(node_record_count);
114
115
                if (part_ptr->node_bitmap == NULL)
115
116
                        fatal("bit_alloc malloc failure");
116
117
                old_bitmap = NULL;
222
223
        part_ptr->disable_root_jobs = default_part.disable_root_jobs;
223
224
        part_ptr->hidden            = default_part.hidden;
224
225
        part_ptr->max_time          = default_part.max_time;
 
226
        part_ptr->default_time      = default_part.default_time;
225
227
        part_ptr->max_nodes         = default_part.max_nodes;
226
228
        part_ptr->max_nodes_orig    = default_part.max_nodes;
227
229
        part_ptr->min_nodes         = default_part.min_nodes;
230
232
        part_ptr->state_up          = default_part.state_up;
231
233
        part_ptr->max_share         = default_part.max_share;
232
234
        part_ptr->priority          = default_part.priority;
 
235
        if(part_max_priority)
 
236
                part_ptr->norm_priority = (double)default_part.priority 
 
237
                        / (double)part_max_priority;
233
238
        part_ptr->node_bitmap       = NULL;
234
239
 
235
240
        if (default_part.allow_groups)
237
242
        else
238
243
                part_ptr->allow_groups = NULL;
239
244
 
 
245
        if (default_part.allow_alloc_nodes)
 
246
                part_ptr->allow_alloc_nodes = xstrdup(default_part.
 
247
                                                      allow_alloc_nodes);
 
248
        else
 
249
                part_ptr->allow_alloc_nodes = NULL;
 
250
 
240
251
        if (default_part.nodes)
241
252
                part_ptr->nodes = xstrdup(default_part.nodes);
242
253
        else
278
289
/* dump_all_part_state - save the state of all partitions to file */
279
290
int dump_all_part_state(void)
280
291
{
 
292
        /* Save high-water mark to avoid buffer growth with copies */
 
293
        static int high_buffer_size = BUF_SIZE;
281
294
        ListIterator part_iterator;
282
295
        struct part_record *part_ptr;
283
296
        int error_code = 0, log_fd;
285
298
        /* Locks: Read partition */
286
299
        slurmctld_lock_t part_read_lock =
287
300
            { READ_LOCK, NO_LOCK, NO_LOCK, READ_LOCK };
288
 
        Buf buffer = init_buf(BUF_SIZE);
 
301
        Buf buffer = init_buf(high_buffer_size);
289
302
        DEF_TIMERS;
290
303
 
291
304
        START_TIMER;
296
309
        /* write partition records to buffer */
297
310
        lock_slurmctld(part_read_lock);
298
311
        part_iterator = list_iterator_create(part_list);
 
312
        if (!part_iterator)
 
313
                fatal("list_iterator_create malloc");
299
314
        while ((part_ptr = (struct part_record *) list_next(part_iterator))) {
300
315
                xassert (part_ptr->magic == PART_MAGIC);
301
316
                _dump_part_state(part_ptr, buffer);
321
336
        } else {
322
337
                int pos = 0, nwrite = get_buf_offset(buffer), amount;
323
338
                char *data = (char *)get_buf_data(buffer);
324
 
 
 
339
                high_buffer_size = MAX(nwrite, high_buffer_size);
325
340
                while (nwrite > 0) {
326
341
                        amount = write(log_fd, &data[pos], nwrite);
327
342
                        if ((amount < 0) && (errno != EINTR)) {
339
354
                (void) unlink(new_file);
340
355
        else {                  /* file shuffle */
341
356
                (void) unlink(old_file);
342
 
                (void) link(reg_file, old_file);
 
357
                if(link(reg_file, old_file))
 
358
                        debug4("unable to create link for %s -> %s: %m",
 
359
                               reg_file, old_file);
343
360
                (void) unlink(reg_file);
344
 
                (void) link(new_file, reg_file);
 
361
                if(link(new_file, reg_file))
 
362
                        debug4("unable to create link for %s -> %s: %m",
 
363
                               new_file, reg_file);
345
364
                (void) unlink(new_file);
346
365
        }
347
366
        xfree(old_file);
372
391
 
373
392
        packstr(part_ptr->name,          buffer);
374
393
        pack32(part_ptr->max_time,       buffer);
 
394
        pack32(part_ptr->default_time,   buffer);
375
395
        pack32(part_ptr->max_nodes_orig, buffer);
376
396
        pack32(part_ptr->min_nodes_orig, buffer);
377
397
 
383
403
 
384
404
        pack16(part_ptr->state_up,       buffer);
385
405
        packstr(part_ptr->allow_groups,  buffer);
 
406
        packstr(part_ptr->allow_alloc_nodes, buffer);
386
407
        packstr(part_ptr->nodes,         buffer);
387
408
}
388
409
 
395
416
int load_all_part_state(void)
396
417
{
397
418
        char *part_name, *allow_groups, *nodes, *state_file, *data = NULL;
398
 
        uint32_t max_time, max_nodes, min_nodes;
 
419
        uint32_t max_time, default_time, max_nodes, min_nodes;
399
420
        time_t time;
400
421
        uint16_t def_part_flag, hidden, root_only;
401
422
        uint16_t max_share, priority, state_up;
405
426
        int state_fd;
406
427
        Buf buffer;
407
428
        char *ver_str = NULL;
 
429
        char* allow_alloc_nodes = NULL;
408
430
 
409
431
        /* read the file */
410
432
        state_file = xstrdup(slurmctld_conf.state_save_location);
458
480
        while (remaining_buf(buffer) > 0) {
459
481
                safe_unpackstr_xmalloc(&part_name, &name_len, buffer);
460
482
                safe_unpack32(&max_time, buffer);
 
483
                safe_unpack32(&default_time, buffer);
461
484
                safe_unpack32(&max_nodes, buffer);
462
485
                safe_unpack32(&min_nodes, buffer);
463
486
 
467
490
                safe_unpack16(&max_share, buffer);
468
491
                safe_unpack16(&priority,  buffer);
469
492
 
 
493
                if(priority > part_max_priority) 
 
494
                        part_max_priority = priority;
 
495
 
470
496
                safe_unpack16(&state_up, buffer);
471
497
                safe_unpackstr_xmalloc(&allow_groups, &name_len, buffer);
 
498
                safe_unpackstr_xmalloc(&allow_alloc_nodes, &name_len, buffer);
472
499
                safe_unpackstr_xmalloc(&nodes, &name_len, buffer);
473
500
 
474
501
                /* validity test as possible */
494
521
                        part_cnt++;
495
522
                        part_ptr->hidden         = hidden;
496
523
                        part_ptr->max_time       = max_time;
 
524
                        part_ptr->default_time   = default_time;
497
525
                        part_ptr->max_nodes      = max_nodes;
498
526
                        part_ptr->max_nodes_orig = max_nodes;
499
527
                        part_ptr->min_nodes      = min_nodes;
506
534
                        part_ptr->root_only      = root_only;
507
535
                        part_ptr->max_share      = max_share;
508
536
                        part_ptr->priority       = priority;
 
537
 
 
538
                        if(part_max_priority) 
 
539
                                part_ptr->norm_priority = 
 
540
                                        (double)part_ptr->priority 
 
541
                                        / (double)part_max_priority;
 
542
 
509
543
                        part_ptr->state_up       = state_up;
510
544
                        xfree(part_ptr->allow_groups);
511
545
                        part_ptr->allow_groups   = allow_groups;
 
546
                        xfree(part_ptr->allow_alloc_nodes);
 
547
                        part_ptr->allow_alloc_nodes   = allow_alloc_nodes;
512
548
                        xfree(part_ptr->nodes);
513
549
                        part_ptr->nodes = nodes;
514
550
                } else {
559
595
        default_part.disable_root_jobs = slurmctld_conf.disable_root_jobs;
560
596
        default_part.hidden         = 0;
561
597
        default_part.max_time       = INFINITE;
 
598
        default_part.default_time   = NO_VAL;
562
599
        default_part.max_nodes      = INFINITE;
563
600
        default_part.max_nodes_orig = INFINITE;
564
601
        default_part.min_nodes      = 1;
567
604
        default_part.state_up       = 1;
568
605
        default_part.max_share      = 1;
569
606
        default_part.priority       = 1;
 
607
        default_part.norm_priority  = 0;
570
608
        default_part.total_nodes    = 0;
571
609
        default_part.total_cpus     = 0;
572
610
        xfree(default_part.nodes);
573
611
        xfree(default_part.allow_groups);
574
612
        xfree(default_part.allow_uids);
 
613
        xfree(default_part.allow_alloc_nodes);
575
614
        FREE_NULL_BITMAP(default_part.node_bitmap);
576
615
 
577
616
        if (part_list)          /* delete defunct partitions */
617
656
        xfree(part_ptr->name);
618
657
        xfree(part_ptr->allow_groups);
619
658
        xfree(part_ptr->allow_uids);
 
659
        xfree(part_ptr->allow_alloc_nodes);
620
660
        xfree(part_ptr->nodes);
621
661
        FREE_NULL_BITMAP(part_ptr->node_bitmap);
622
662
        xfree(part_entry);
701
741
 
702
742
        buffer = init_buf(BUF_SIZE);
703
743
 
704
 
        /* write haeader: version and time */
 
744
        /* write header: version and time */
705
745
        parts_packed = 0;
706
746
        pack32(parts_packed, buffer);
707
747
        pack_time(now, buffer);
711
751
        while ((part_ptr = (struct part_record *) list_next(part_iterator))) {
712
752
                xassert (part_ptr->magic == PART_MAGIC);
713
753
                if (((show_flags & SHOW_ALL) == 0) && (uid != 0) &&
714
 
                    ((part_ptr->hidden) || (validate_group (part_ptr, uid) == 0)))
 
754
                    ((part_ptr->hidden) 
 
755
                     || (validate_group (part_ptr, uid) == 0)))
715
756
                        continue;
716
757
                pack_part(part_ptr, buffer);
717
758
                parts_packed++;
736
777
 * IN/OUT buffer - buffer in which data is placed, pointers automatically 
737
778
 *      updated
738
779
 * global: default_part_loc - pointer to the default partition
739
 
 * NOTE: if you make any changes here be sure to make the corresponding 
740
 
 *      changes to load_part_config in api/partition_info.c
 
780
 * NOTE: if you make any changes here be sure to make the corresponding changes
 
781
 *      to _unpack_partition_info_members() in common/slurm_protocol_pack.c
741
782
 */
742
783
void pack_part(struct part_record *part_ptr, Buf buffer)
743
784
{
752
793
 
753
794
        packstr(part_ptr->name, buffer);
754
795
        pack32(part_ptr->max_time, buffer);
 
796
        pack32(part_ptr->default_time, buffer);
755
797
        pack32(part_ptr->max_nodes_orig, buffer);
756
798
        pack32(part_ptr->min_nodes_orig, buffer);
757
799
        altered = part_ptr->total_nodes;
771
813
 
772
814
        pack16(part_ptr->state_up, buffer);
773
815
        packstr(part_ptr->allow_groups, buffer);
 
816
        packstr(part_ptr->allow_alloc_nodes, buffer);
774
817
        packstr(part_ptr->nodes, buffer);
775
818
        if (part_ptr->node_bitmap) {
776
819
                bit_fmt(node_inx_ptr, BUF_SIZE,
782
825
 
783
826
 
784
827
/* 
785
 
 * update_part - update a partition's configuration data
 
828
 * update_part - create or update a partition's configuration data
786
829
 * IN part_desc - description of partition changes
 
830
 * IN create_flag - create a new partition
787
831
 * RET 0 or an error code
788
832
 * global: part_list - list of partition entries
789
833
 *      last_part_update - update time of partition records
790
834
 */
791
 
int update_part(update_part_msg_t * part_desc)
 
835
extern int update_part (update_part_msg_t * part_desc, bool create_flag)
792
836
{
793
837
        int error_code;
794
838
        struct part_record *part_ptr;
795
839
 
796
840
        if (part_desc->name == NULL) {
797
 
                error("update_part: invalid partition name, NULL");
 
841
                info("update_part: invalid partition name, NULL");
798
842
                return ESLURM_INVALID_PARTITION_NAME;
799
843
        }
800
844
 
801
845
        error_code = SLURM_SUCCESS;
802
846
        part_ptr = list_find_first(part_list, &list_find_part, 
803
 
                                        part_desc->name);
 
847
                                   part_desc->name);
804
848
 
805
 
        if (part_ptr == NULL) {
806
 
                info("update_part: partition %s does not exist, "
807
 
                        "being created", part_desc->name);
 
849
        if (create_flag) {
 
850
                if (part_ptr) {
 
851
                        verbose("Duplicate partition name for create (%s)",
 
852
                                part_desc->name);
 
853
                        return ESLURM_INVALID_PARTITION_NAME;
 
854
                }
 
855
                info("update_part: partition %s being created",
 
856
                     part_desc->name);
808
857
                part_ptr = create_part_record();
809
858
                xfree(part_ptr->name);
810
859
                part_ptr->name = xstrdup(part_desc->name);
 
860
        } else {
 
861
                if (!part_ptr) {
 
862
                        verbose("Update for partition not found (%s)",
 
863
                                part_desc->name);
 
864
                        return ESLURM_INVALID_PARTITION_NAME;
 
865
                }
811
866
        }
812
867
 
813
868
        last_part_update = time(NULL);
824
879
                part_ptr->max_time = part_desc->max_time;
825
880
        }
826
881
 
 
882
        if ((part_desc->default_time != NO_VAL) && 
 
883
            (part_desc->default_time > part_ptr->max_time)) {
 
884
                info("update_part: DefaultTime would exceed MaxTime for "
 
885
                     "partition %s", part_desc->name);
 
886
        } else if (part_desc->default_time != NO_VAL) {
 
887
                info("update_part: setting default_time to %u "
 
888
                     "for partition %s", 
 
889
                     part_desc->default_time, part_desc->name);
 
890
                part_ptr->default_time = part_desc->default_time;
 
891
        }
 
892
 
827
893
        if (part_desc->max_nodes != NO_VAL) {
828
894
                info("update_part: setting max_nodes to %u for partition %s", 
829
895
                     part_desc->max_nodes, part_desc->name);
875
941
                info("update_part: setting priority to %u for partition %s",
876
942
                     part_desc->priority, part_desc->name);
877
943
                part_ptr->priority = part_desc->priority;
 
944
                
 
945
                /* If the max_priority changes we need to change all
 
946
                   the normalized priorities of all the other
 
947
                   partitions.  If not then just set this partitions.
 
948
                */
 
949
                if(part_ptr->priority > part_max_priority) {
 
950
                        ListIterator itr = list_iterator_create(part_list);
 
951
                        struct part_record *part2 = NULL;
 
952
 
 
953
                        part_max_priority = part_ptr->priority;
 
954
 
 
955
                        while((part2 = list_next(itr))) {
 
956
                                part2->norm_priority = (double)part2->priority 
 
957
                                        / (double)part_max_priority;
 
958
                        }
 
959
                        list_iterator_destroy(itr);
 
960
                } else {
 
961
                        part_ptr->norm_priority = (double)part_ptr->priority 
 
962
                                / (double)part_max_priority;
 
963
                }
878
964
        }
879
965
 
880
966
        if (part_desc->default_part == 1) {
882
968
                        info("update_part: setting default partition to %s", 
883
969
                             part_desc->name);
884
970
                } else if (strcmp(default_part_name, part_desc->name) != 0) {
885
 
                        info("update_part: changing default partition from %s to %s", 
 
971
                        info("update_part: changing default "
 
972
                             "partition from %s to %s", 
886
973
                             default_part_name, part_desc->name);
887
974
                }
888
975
                xfree(default_part_name);
909
996
                }
910
997
        }
911
998
 
 
999
        if (part_desc->allow_alloc_nodes != NULL) {
 
1000
                xfree(part_ptr->allow_alloc_nodes);
 
1001
                if ((part_desc->allow_alloc_nodes[0] == '\0') ||
 
1002
                    (strcasecmp(part_desc->allow_alloc_nodes, "ALL") == 0)) {
 
1003
                        part_ptr->allow_alloc_nodes = NULL;
 
1004
                        info("update_part: setting allow_alloc_nodes to ALL"
 
1005
                             " for partition %s",part_desc->name);
 
1006
                }
 
1007
                else {
 
1008
                        part_ptr->allow_alloc_nodes = part_desc->
 
1009
                                                      allow_alloc_nodes;
 
1010
                        part_desc->allow_alloc_nodes = NULL;
 
1011
                        info("update_part: setting allow_alloc_nodes to %s for "
 
1012
                             "partition %s", 
 
1013
                             part_ptr->allow_alloc_nodes, part_desc->name);
 
1014
                }
 
1015
        }
 
1016
 
912
1017
        if (part_desc->nodes != NULL) {
913
1018
                char *backup_node_list = part_ptr->nodes;
914
1019
 
928
1033
                        xfree(part_ptr->nodes);
929
1034
                        part_ptr->nodes = backup_node_list;
930
1035
                } else {
931
 
                        info("update_part: setting nodes to %s for partition %s", 
 
1036
                        info("update_part: setting nodes to %s "
 
1037
                             "for partition %s", 
932
1038
                             part_ptr->nodes, part_desc->name);
933
1039
                        xfree(backup_node_list);
934
1040
                }
 
1041
        } else if (part_ptr->node_bitmap == NULL) {
 
1042
                /* Newly created partition needs a bitmap, even if empty */
 
1043
                part_ptr->node_bitmap = bit_alloc(node_record_count);
935
1044
        }
936
1045
 
937
1046
        if (error_code == SLURM_SUCCESS) {
975
1084
}
976
1085
 
977
1086
/*
 
1087
 * validate_alloc_node - validate that the allocating node
 
1088
 * is allowed to use this partition
 
1089
 * IN part_ptr - pointer to a partition
 
1090
 * IN alloc_node - allocting node of the request
 
1091
 * RET 1 if permitted to run, 0 otherwise
 
1092
 */
 
1093
extern int validate_alloc_node(struct part_record *part_ptr, char* alloc_node)
 
1094
{
 
1095
        int status;
 
1096
        
 
1097
        if (part_ptr->allow_alloc_nodes == NULL)
 
1098
                return 1;       /* all allocating nodes allowed */
 
1099
        if (alloc_node == NULL)
 
1100
                return 1;       /* if no allocating node defined
 
1101
                                 * let it go */
 
1102
 
 
1103
        hostlist_t hl = hostlist_create(part_ptr->allow_alloc_nodes);
 
1104
        status=hostlist_find(hl,alloc_node);
 
1105
        hostlist_destroy(hl);
 
1106
        
 
1107
        if(status==-1)
 
1108
                status=0;
 
1109
        else
 
1110
                status=1;
 
1111
        
 
1112
        return status;
 
1113
}
 
1114
 
 
1115
/*
978
1116
 * load_part_uid_allow_list - reload the allow_uid list of partitions
979
1117
 *      if required (updated group file or force set)
980
1118
 * IN force - if set then always reload the allow_uid list
1084
1222
 
1085
1223
        j = 0;
1086
1224
        for (i=0; i<uid_cnt; i++) {
1087
 
                my_uid = uid_from_string(grp_result->gr_mem[i]);
1088
 
                if (my_uid == (uid_t) -1) {
 
1225
                if (uid_from_string (grp_result->gr_mem[i], &my_uid) < 0)
1089
1226
                        error("Could not find user %s in configured group %s",
1090
1227
                              grp_result->gr_mem[i], group_name);
1091
 
                } else if (my_uid) {
 
1228
                else if (my_uid)
1092
1229
                        group_uids[j++] = my_uid;
1093
 
                }
1094
1230
        }
1095
1231
 
1096
1232
#ifdef HAVE_AIX
1192
1328
        list_delete_all(part_list, list_find_part, part_desc_ptr->name);
1193
1329
        last_part_update = time(NULL);
1194
1330
 
 
1331
        slurm_sched_partition_change(); /* notify sched plugin */
 
1332
        select_g_reconfigure();         /* notify select plugin too */
 
1333
        reset_job_priority();           /* free jobs */
 
1334
 
1195
1335
        return SLURM_SUCCESS;
1196
1336
}