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
* CODE-OCEC-09-009. All rights reserved.
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.
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"
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"
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 */
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;
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;
235
240
if (default_part.allow_groups)
238
243
part_ptr->allow_groups = NULL;
245
if (default_part.allow_alloc_nodes)
246
part_ptr->allow_alloc_nodes = xstrdup(default_part.
249
part_ptr->allow_alloc_nodes = NULL;
240
251
if (default_part.nodes)
241
252
part_ptr->nodes = xstrdup(default_part.nodes);
278
289
/* dump_all_part_state - save the state of all partitions to file */
279
290
int dump_all_part_state(void)
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);
296
309
/* write partition records to buffer */
297
310
lock_slurmctld(part_read_lock);
298
311
part_iterator = list_iterator_create(part_list);
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);
322
337
int pos = 0, nwrite = get_buf_offset(buffer), amount;
323
338
char *data = (char *)get_buf_data(buffer);
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",
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",
345
364
(void) unlink(new_file);
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);
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);
395
416
int load_all_part_state(void)
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;
400
421
uint16_t def_part_flag, hidden, root_only;
401
422
uint16_t max_share, priority, state_up;
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);
467
490
safe_unpack16(&max_share, buffer);
468
491
safe_unpack16(&priority, buffer);
493
if(priority > part_max_priority)
494
part_max_priority = priority;
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);
474
501
/* validity test as possible */
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;
538
if(part_max_priority)
539
part_ptr->norm_priority =
540
(double)part_ptr->priority
541
/ (double)part_max_priority;
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;
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);
577
616
if (part_list) /* delete defunct partitions */
702
742
buffer = init_buf(BUF_SIZE);
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)))
755
|| (validate_group (part_ptr, uid) == 0)))
716
757
pack_part(part_ptr, buffer);
736
777
* IN/OUT buffer - buffer in which data is placed, pointers automatically
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
742
783
void pack_part(struct part_record *part_ptr, Buf buffer)
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;
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,
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
791
int update_part(update_part_msg_t * part_desc)
835
extern int update_part (update_part_msg_t * part_desc, bool create_flag)
794
838
struct part_record *part_ptr;
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;
801
845
error_code = SLURM_SUCCESS;
802
846
part_ptr = list_find_first(part_list, &list_find_part,
805
if (part_ptr == NULL) {
806
info("update_part: partition %s does not exist, "
807
"being created", part_desc->name);
851
verbose("Duplicate partition name for create (%s)",
853
return ESLURM_INVALID_PARTITION_NAME;
855
info("update_part: partition %s being created",
808
857
part_ptr = create_part_record();
809
858
xfree(part_ptr->name);
810
859
part_ptr->name = xstrdup(part_desc->name);
862
verbose("Update for partition not found (%s)",
864
return ESLURM_INVALID_PARTITION_NAME;
813
868
last_part_update = time(NULL);
824
879
part_ptr->max_time = part_desc->max_time;
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 "
889
part_desc->default_time, part_desc->name);
890
part_ptr->default_time = part_desc->default_time;
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;
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.
949
if(part_ptr->priority > part_max_priority) {
950
ListIterator itr = list_iterator_create(part_list);
951
struct part_record *part2 = NULL;
953
part_max_priority = part_ptr->priority;
955
while((part2 = list_next(itr))) {
956
part2->norm_priority = (double)part2->priority
957
/ (double)part_max_priority;
959
list_iterator_destroy(itr);
961
part_ptr->norm_priority = (double)part_ptr->priority
962
/ (double)part_max_priority;
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);
888
975
xfree(default_part_name);
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);
1008
part_ptr->allow_alloc_nodes = part_desc->
1010
part_desc->allow_alloc_nodes = NULL;
1011
info("update_part: setting allow_alloc_nodes to %s for "
1013
part_ptr->allow_alloc_nodes, part_desc->name);
912
1017
if (part_desc->nodes != NULL) {
913
1018
char *backup_node_list = part_ptr->nodes;
928
1033
xfree(part_ptr->nodes);
929
1034
part_ptr->nodes = backup_node_list;
931
info("update_part: setting nodes to %s for partition %s",
1036
info("update_part: setting nodes to %s "
932
1038
part_ptr->nodes, part_desc->name);
933
1039
xfree(backup_node_list);
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);
937
1046
if (error_code == SLURM_SUCCESS) {
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
1093
extern int validate_alloc_node(struct part_record *part_ptr, char* alloc_node)
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
1103
hostlist_t hl = hostlist_create(part_ptr->allow_alloc_nodes);
1104
status=hostlist_find(hl,alloc_node);
1105
hostlist_destroy(hl);
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
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) {
1092
1229
group_uids[j++] = my_uid;
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);
1331
slurm_sched_partition_change(); /* notify sched plugin */
1332
select_g_reconfigure(); /* notify select plugin too */
1333
reset_job_priority(); /* free jobs */
1195
1335
return SLURM_SUCCESS;