From 27768b0b2889af1b879cb8e7cf605046db7e44cf Mon Sep 17 00:00:00 2001 From: Moe Jette <jette1@llnl.gov> Date: Fri, 23 Jan 2009 20:55:54 +0000 Subject: [PATCH] Add logic to test for overlapping partitions --- src/slurmctld/reservation.c | 112 +++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c index 9fdd2b5feb4..32a16d9de07 100644 --- a/src/slurmctld/reservation.c +++ b/src/slurmctld/reservation.c @@ -114,6 +114,8 @@ static void _generate_resv_name(reserve_request_msg_t *resv_ptr); static bool _is_account_valid(char *account); static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer, bool internal); +static bool _resv_overlap(time_t start_time, time_t end_time, + bitstr_t *node_bitmap); static void _set_assoc_list(struct slurmctld_resv *resv_ptr); static void _set_resv_id(struct slurmctld_resv *resv_ptr); static int _update_account_list(struct slurmctld_resv *resv_ptr, @@ -660,6 +662,39 @@ static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer, } } +/* + * Test if a new/updated reservation request overlaps an existing + * reservation + * RET true if overlap + */ +static bool _resv_overlap(time_t start_time, time_t end_time, + bitstr_t *node_bitmap) +{ + ListIterator iter; + slurmctld_resv_t *resv_ptr; + bool rc = false; + + if (!node_bitmap) + return rc; + + iter = list_iterator_create(resv_list); + if (!iter) + fatal("malloc: list_iterator_create"); + while ((resv_ptr = (slurmctld_resv_t *) list_next(iter))) { + if ((resv_ptr->end_time <= start_time) || + (resv_ptr->start_time >= end_time) || + (resv_ptr->node_bitmap == NULL) || + (bit_overlap(resv_ptr->node_bitmap, node_bitmap) == 0)) + continue; + verbose("Reservation overlap with %s", resv_ptr->name); + rc = true; + break; + } + list_iterator_destroy(iter); + + return rc; +} + /* Create a resource reservation */ extern int create_resv(reserve_request_msg_t *resv_desc_ptr) { @@ -761,6 +796,12 @@ 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)) { + info("Reservation requestion overlaps another"); + rc = ESLURM_INVALID_TIME_VALUE; + goto bad_parse; + } } else if (resv_desc_ptr->node_cnt == NO_VAL) { info("Reservation request lacks node specification"); rc = ESLURM_INVALID_NODE_NAME; @@ -816,6 +857,9 @@ extern int create_resv(reserve_request_msg_t *resv_desc_ptr) extern int update_resv(reserve_request_msg_t *resv_desc_ptr) { time_t now = time(NULL); + time_t old_start_time, old_end_time; + bitstr_t *old_node_bitmap = (bitstr_t *) NULL; + char *old_node_list = NULL; slurmctld_resv_t *resv_ptr; int error_code = SLURM_SUCCESS; @@ -833,26 +877,6 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr) /* Process the request */ last_resv_update = now; - if (resv_desc_ptr->start_time != (time_t) NO_VAL) { - if (resv_desc_ptr->start_time < (now - 60)) { - info("Reservation requestion has invalid start time"); - error_code = ESLURM_INVALID_TIME_VALUE; - goto fini; - } - resv_ptr->start_time = resv_desc_ptr->start_time; - } - if (resv_desc_ptr->end_time != (time_t) NO_VAL) { - if (resv_desc_ptr->end_time < (now - 60)) { - info("Reservation requestion has invalid end time"); - error_code = ESLURM_INVALID_TIME_VALUE; - goto fini; - } - resv_ptr->end_time = resv_desc_ptr->end_time; - } - if (resv_desc_ptr->duration != NO_VAL) { - resv_ptr->end_time = resv_ptr->start_time + - (resv_desc_ptr->duration * 60); - } if (resv_desc_ptr->type != (uint16_t) NO_VAL) { if (resv_desc_ptr->type > RESERVE_TYPE_MAINT) { error("Invalid reservation type %u ignored", @@ -897,6 +921,29 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr) goto fini; } } + + old_start_time = resv_ptr->start_time; + old_end_time = resv_ptr->end_time; + if (resv_desc_ptr->start_time != (time_t) NO_VAL) { + if (resv_desc_ptr->start_time < (now - 60)) { + info("Reservation requestion has invalid start time"); + error_code = ESLURM_INVALID_TIME_VALUE; + goto fini; + } + resv_ptr->start_time = resv_desc_ptr->start_time; + } + if (resv_desc_ptr->end_time != (time_t) NO_VAL) { + if (resv_desc_ptr->end_time < (now - 60)) { + info("Reservation requestion has invalid end time"); + error_code = ESLURM_INVALID_TIME_VALUE; + goto fini; + } + resv_ptr->end_time = resv_desc_ptr->end_time; + } + if (resv_desc_ptr->duration != NO_VAL) { + resv_ptr->end_time = resv_ptr->start_time + + (resv_desc_ptr->duration * 60); + } if (resv_desc_ptr->node_list) { /* Change bitmap last */ bitstr_t *node_bitmap; if (strcmp(resv_desc_ptr->node_list, "ALL") == 0) { @@ -905,14 +952,35 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr) } else if (node_name2bitmap(resv_desc_ptr->node_list, false, &node_bitmap)) { error_code = ESLURM_INVALID_NODE_NAME; + /* Restore state with respect to time and nodes */ + resv_ptr->start_time = old_start_time; + resv_ptr->end_time = old_start_time; goto fini; } - xfree(resv_ptr->node_list); + old_node_list = resv_ptr->node_list; resv_ptr->node_list = resv_desc_ptr->node_list; resv_desc_ptr->node_list = NULL; /* Nothing left to free */ - FREE_NULL_BITMAP(resv_ptr->node_bitmap); + old_node_bitmap = resv_ptr->node_bitmap; resv_ptr->node_bitmap = node_bitmap; } + if (_resv_overlap(resv_ptr->start_time, resv_ptr->end_time, + resv_ptr->node_bitmap)) { + info("Reservation requestion overlaps another"); + error_code = ESLURM_INVALID_TIME_VALUE; + /* Restore state with respect to time and nodes */ + resv_ptr->start_time = old_start_time; + resv_ptr->end_time = old_end_time; + if (old_node_list) { + xfree(resv_ptr->node_list); + resv_ptr->node_list = old_node_list; + FREE_NULL_BITMAP(resv_ptr->node_bitmap); + resv_ptr->node_bitmap = old_node_bitmap; + } + } else if (old_node_list) { + /* Free temporarily saved state */ + xfree(old_node_list); + FREE_NULL_BITMAP(old_node_bitmap); + } fini: last_resv_update = now; _set_assoc_list(resv_ptr); -- GitLab