diff --git a/doc/man/man1/scontrol.1 b/doc/man/man1/scontrol.1 index 47756d87cb9e9887631e7e515edec954ba7333c7..7195057141f5b35db52a36f4be15fa46d2c08b1f 100644 --- a/doc/man/man1/scontrol.1 +++ b/doc/man/man1/scontrol.1 @@ -1,4 +1,4 @@ -.TH SCONTROL "1" "December 2008" "scontrol 1.4" "Slurm components" +.TH SCONTROL "1" "February 2009" "scontrol 1.4" "Slurm components" .SH "NAME" scontrol \- Used view and modify Slurm configuration and state. @@ -576,7 +576,13 @@ Identify the partition to be reserved. .TP \fIFlags\fP=<flags> Flags associated with the reservation. -Currently "Maintenance" is supported. +Currently "MAINT" (maintenance mode, receives special accounting treatment), +"DAILY" (repeat the reservation every day), +"WEEKLY" (repeat the reservation every week) and +"SPEC_NODES" (reservation is for specific nodes, output only) is supported. +In order to remove the "MAINT", "DAILY" or "WEEKLY" flag with the update +option, preceed the name with a minus sign. For example: +Flags=\-MAINT. .TP \fIFeatures\fP=<features> diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in index 2b287009168fa34779dd22e06f26bd8b8c0afbdd..463bc5fd5fbbe87ac4a0035b9eef09c0515bdff3 100644 --- a/slurm/slurm.h.in +++ b/slurm/slurm.h.in @@ -969,6 +969,7 @@ typedef struct partition_info_msg { #define RESERVE_FLAG_NO_DAILY 0x0008 /* Clear DAILY flag */ #define RESERVE_FLAG_WEEKLY 0x0010 /* Set WEEKLY flag */ #define RESERVE_FLAG_NO_WEEKLY 0x0020 /* Clear WEEKLY flag */ +#define RESERVE_FLAG_SPEC_NODES 0x8000 /* Contains specific nodes */ typedef struct reserve_info { char *accounts; /* names of accounts permitted to use */ diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c index 15ffe2737538a77af29c5678c1b0ed33793ee2aa..89b2ec8896701e696a6c13820229bbf7bfe5a30a 100644 --- a/src/common/slurm_protocol_defs.c +++ b/src/common/slurm_protocol_defs.c @@ -908,6 +908,11 @@ extern char *reservation_flags_string(uint16_t flags) xstrcat(flag_str, ","); xstrcat(flag_str, "NO_WEEKLY"); } + if (flags & RESERVE_FLAG_SPEC_NODES) { + if (flag_str[0]) + xstrcat(flag_str, ","); + xstrcat(flag_str, "SPEC_NODES"); + } return flag_str; } diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c index 407506548f903ec0ee1a6f538199a7664fbec16a..3706c7260a9962455ca52ef1c7e9d7643e8e44fa 100644 --- a/src/slurmctld/reservation.c +++ b/src/slurmctld/reservation.c @@ -95,7 +95,7 @@ static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer, bool internal); static int _resize_resv(slurmctld_resv_t *resv_ptr, uint32_t node_cnt); static bool _resv_overlap(time_t start_time, time_t end_time, - bitstr_t *node_bitmap, + uint16_t flags, bitstr_t *node_bitmap, struct slurmctld_resv *this_resv_ptr); static int _select_nodes(reserve_request_msg_t *resv_desc_ptr, struct part_record **part_ptr, @@ -737,13 +737,14 @@ static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer, * RET true if overlap */ static bool _resv_overlap(time_t start_time, time_t end_time, - bitstr_t *node_bitmap, + uint16_t flags, bitstr_t *node_bitmap, struct slurmctld_resv *this_resv_ptr) { ListIterator iter; slurmctld_resv_t *resv_ptr; bool rc = false; - uint32_t delta_t, i; + uint32_t delta_t, i, j; + time_t s_time1, s_time2, e_time1, e_time2; if (!node_bitmap) return rc; @@ -755,19 +756,30 @@ static bool _resv_overlap(time_t start_time, time_t end_time, while ((resv_ptr = (slurmctld_resv_t *) list_next(iter))) { if (resv_ptr == this_resv_ptr) continue; /* skip self */ + if (resv_ptr->node_bitmap == NULL) + continue; /* no specific nodes in reservation */ + if (!bit_overlap(resv_ptr->node_bitmap, node_bitmap)) + continue; /* no overlap */ - for (i=0; i<7; i++) { /* look forward one week */ + for (i=0; ((i<7) && (!rc)); i++) { /* look forward one week */ delta_t = i * (24 * 60 * 60); - if ((start_time < (resv_ptr->end_time + delta_t)) && - (end_time > (resv_ptr->start_time + delta_t)) && - resv_ptr->node_bitmap && - bit_overlap(resv_ptr->node_bitmap, node_bitmap)) { - verbose("Reservation overlap with %s", - resv_ptr->name); - rc = true; - break; + s_time1 = start_time + delta_t; + e_time1 = end_time + delta_t; + for (j=0; ((j<7) && (!rc)); j++) { + delta_t = j * (24 * 60 * 60); + s_time2 = resv_ptr->start_time + delta_t; + e_time2 = resv_ptr->end_time + delta_t; + if ((s_time1 < e_time2) && + (e_time1 > s_time2)) { + verbose("Reservation overlap with %s", + resv_ptr->name); + rc = true; + break; + } + if (!(resv_ptr->flags & RESERVE_FLAG_DAILY)) + break; } - if ((resv_ptr->flags & RESERVE_FLAG_DAILY) == 0) + if ((flags & RESERVE_FLAG_DAILY) == 0) break; } } @@ -838,6 +850,11 @@ extern int create_resv(reserve_request_msg_t *resv_desc_ptr) resv_desc_ptr->end_time = INFINITE; if (resv_desc_ptr->flags == (uint16_t) NO_VAL) resv_desc_ptr->flags = 0; + else { + resv_desc_ptr->flags &= RESERVE_FLAG_MAINT | + RESERVE_FLAG_DAILY | + RESERVE_FLAG_WEEKLY; + } if (resv_desc_ptr->partition) { part_ptr = find_part_record(resv_desc_ptr->partition); if (!part_ptr) { @@ -866,6 +883,7 @@ extern int create_resv(reserve_request_msg_t *resv_desc_ptr) goto bad_parse; } if (resv_desc_ptr->node_list) { + resv_desc_ptr->flags |= RESERVE_FLAG_SPEC_NODES; if (strcmp(resv_desc_ptr->node_list, "ALL") == 0) { node_bitmap = bit_alloc(node_record_count); bit_nset(node_bitmap, 0, (node_record_count - 1)); @@ -877,7 +895,8 @@ extern int create_resv(reserve_request_msg_t *resv_desc_ptr) if (resv_desc_ptr->node_cnt == NO_VAL) resv_desc_ptr->node_cnt = 0; if (_resv_overlap(resv_desc_ptr->start_time, - resv_desc_ptr->end_time, node_bitmap, + resv_desc_ptr->end_time, + resv_desc_ptr->flags, node_bitmap, NULL)) { info("Reservation requestion overlaps another"); rc = ESLURM_INVALID_TIME_VALUE; @@ -1074,8 +1093,18 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr) resv_ptr->end_time = resv_ptr->start_time + (resv_desc_ptr->duration * 60); } + if (resv_desc_ptr->node_list && + (resv_desc_ptr->node_list[0] == '\0')) { /* Clear bitmap */ + resv_ptr->flags &= (~RESERVE_FLAG_SPEC_NODES); + xfree(resv_desc_ptr->node_list); + xfree(resv_ptr->node_list); + FREE_NULL_BITMAP(resv_ptr->node_bitmap); + if (resv_desc_ptr->node_cnt == NO_VAL) + resv_desc_ptr->node_cnt = resv_ptr->node_cnt; + } if (resv_desc_ptr->node_list) { /* Change bitmap last */ bitstr_t *node_bitmap; + resv_ptr->flags |= RESERVE_FLAG_SPEC_NODES; if (strcmp(resv_desc_ptr->node_list, "ALL") == 0) { node_bitmap = bit_alloc(node_record_count); bit_nset(node_bitmap, 0, (node_record_count - 1)); @@ -1100,7 +1129,7 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr) resv_ptr->node_cnt = bit_set_count(resv_ptr->node_bitmap); } if (_resv_overlap(resv_ptr->start_time, resv_ptr->end_time, - resv_ptr->node_bitmap, resv_ptr)) { + resv_ptr->flags, resv_ptr->node_bitmap, resv_ptr)) { info("Reservation requestion overlaps another"); error_code = ESLURM_INVALID_TIME_VALUE; goto update_failure;