From 0340107179c024ade87e626e737ba4dba934f366 Mon Sep 17 00:00:00 2001 From: Danny Auble <da@llnl.gov> Date: Thu, 30 Apr 2009 21:13:28 +0000 Subject: [PATCH] fix for reservations to create new entries in the database when something about nodes or cpus or flags change --- .../mysql/accounting_storage_mysql.c | 12 ++-- src/slurmctld/reservation.c | 49 ++++++++++----- src/slurmctld/slurmctld.h | 1 + src/sview/common.c | 63 ++++++++++++++++++- 4 files changed, 104 insertions(+), 21 deletions(-) diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c index ceb404d4ab6..633a4549a20 100644 --- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c +++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c @@ -2890,6 +2890,7 @@ static int _mysql_acct_check_tables(MYSQL *db_conn) { "control_host", "tinytext not null default ''" }, { "control_port", "mediumint not null default 0" }, { "rpc_version", "mediumint not null default 0" }, + { "classification", "tinyint unsigned default 0" }, { NULL, NULL} }; @@ -6225,7 +6226,7 @@ try_again: resv->cpus = atoi(row[RESV_CPU]); - if(resv->flags == (uint16_t)NO_VAL) + if(resv->flags != (uint16_t)NO_VAL) set = 1; else resv->flags = atoi(row[RESV_FLAGS]); @@ -6243,13 +6244,12 @@ try_again: mysql_free_result(result); - _setup_resv_limits(resv, &cols, &vals, &extra); /* use start below instead of resv->time_start_prev * just incase we have a different one from being out * of sync */ - - if((start < now) || !set) { + if((start > now) || !set) { + _setup_resv_limits(resv, &cols, &vals, &extra); /* we haven't started the reservation yet, or we are changing the associations or end time which we can just update it */ @@ -6260,6 +6260,10 @@ try_again: start, resv->cluster); } else { + /* since we change the start time here to now we can't + run the setup before here */ +/* resv->time_start = now; */ + _setup_resv_limits(resv, &cols, &vals, &extra); /* time_start is already done above and we * changed something that is in need on a new * entry. */ diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c index 5c662664f05..558526c3ab1 100644 --- a/src/slurmctld/reservation.c +++ b/src/slurmctld/reservation.c @@ -157,6 +157,7 @@ static slurmctld_resv_t *_copy_resv(slurmctld_resv_t *resv_orig_ptr) resv_copy_ptr->part_ptr = resv_orig_ptr->part_ptr; resv_copy_ptr->resv_id = resv_orig_ptr->resv_id; resv_copy_ptr->start_time = resv_orig_ptr->start_time; + resv_copy_ptr->start_time_first = resv_orig_ptr->start_time_first; resv_copy_ptr->start_time_prev = resv_orig_ptr->start_time_prev; resv_copy_ptr->users = xstrdup(resv_orig_ptr->users); resv_copy_ptr->user_cnt = resv_orig_ptr->user_cnt; @@ -481,8 +482,6 @@ static int _post_resv_update(slurmctld_resv_t *resv_ptr, resv.cluster = slurmctld_cluster_name; resv.id = resv_ptr->resv_id; resv.time_end = resv_ptr->end_time; - resv.time_start = resv_ptr->start_time; - resv.time_start_prev = resv_ptr->start_time_prev; if(!old_resv_ptr) { resv.assocs = resv_ptr->assoc_list; @@ -490,9 +489,11 @@ static int _post_resv_update(slurmctld_resv_t *resv_ptr, resv.flags = resv_ptr->flags; resv.nodes = resv_ptr->node_list; } else { + time_t now = time(NULL); + if(old_resv_ptr->assoc_list && resv_ptr->assoc_list) { if(strcmp(old_resv_ptr->assoc_list, - resv_ptr->assoc_list)) + resv_ptr->assoc_list)) resv.assocs = resv_ptr->assoc_list; } else if(resv_ptr->assoc_list) resv.assocs = resv_ptr->assoc_list; @@ -513,7 +514,23 @@ static int _post_resv_update(slurmctld_resv_t *resv_ptr, resv.nodes = resv_ptr->node_list; } else if(resv_ptr->node_list) resv.nodes = resv_ptr->node_list; + + /* Here if the reservation has started already we need + to mark a new start time for it if certain + variables are needed in accounting. Right now if + the flags, nodes, or cpu count changes we need a + new start time of now. */ + if((resv_ptr->start_time < now) + && (resv.nodes + || (resv.flags != (uint16_t)NO_VAL) + || (resv.cpus != (uint32_t)NO_VAL))) { + resv_ptr->start_time_prev = resv_ptr->start_time; + resv_ptr->start_time = now; + } } + /* now set the (maybe new) start_times */ + resv.time_start = resv_ptr->start_time; + resv.time_start_prev = resv_ptr->start_time_prev; if(resv.nodes && resv_ptr->node_bitmap) resv.node_inx = bit_fmt(temp_bit, sizeof(temp_bit), @@ -929,7 +946,7 @@ static void _pack_resv(slurmctld_resv_t *resv_ptr, Buf buffer, pack32(resv_ptr->node_cnt, buffer); packstr(resv_ptr->node_list, buffer); packstr(resv_ptr->partition, buffer); - pack_time(resv_ptr->start_time, buffer); + pack_time(resv_ptr->start_time_first, buffer); pack16(resv_ptr->flags, buffer); packstr(resv_ptr->users, buffer); @@ -938,13 +955,9 @@ static void _pack_resv(slurmctld_resv_t *resv_ptr, Buf buffer, pack32(resv_ptr->cpu_cnt, buffer); pack32(resv_ptr->resv_id, buffer); pack_time(resv_ptr->start_time_prev, buffer); + pack_time(resv_ptr->start_time, buffer); } else { - time_t now = time(NULL); - /* only send the bitmap if it is valid now. */ - if(resv_ptr->start_time > now || resv_ptr->end_time < now) - pack_bit_fmt(NULL, buffer); - else - pack_bit_fmt(resv_ptr->node_bitmap, buffer); + pack_bit_fmt(resv_ptr->node_bitmap, buffer); } } @@ -1051,9 +1064,9 @@ extern int create_resv(resv_desc_msg_t *resv_desc_ptr) rc = ESLURM_INVALID_TIME_VALUE; goto bad_parse; } - } else + } else resv_desc_ptr->start_time = now; - + 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"); @@ -1172,6 +1185,7 @@ extern int create_resv(resv_desc_msg_t *resv_desc_ptr) resv_desc_ptr->partition = NULL; /* Nothing left to free */ resv_ptr->part_ptr = part_ptr; resv_ptr->start_time = resv_desc_ptr->start_time; + resv_ptr->start_time_first = resv_ptr->start_time; resv_ptr->start_time_prev = resv_ptr->start_time; resv_ptr->flags = resv_desc_ptr->flags; resv_ptr->users = resv_desc_ptr->users; @@ -1322,7 +1336,7 @@ extern int update_resv(resv_desc_msg_t *resv_desc_ptr) 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_ptr->end_time = resv_ptr->start_time_first + (resv_desc_ptr->duration * 60); } if (resv_ptr->start_time >= resv_ptr->end_time) { @@ -1887,7 +1901,7 @@ extern int load_all_resv_state(int recover) &uint32_tmp, buffer); safe_unpackstr_xmalloc(&resv_ptr->partition, &uint32_tmp, buffer); - safe_unpack_time(&resv_ptr->start_time, buffer); + safe_unpack_time(&resv_ptr->start_time_first, buffer); safe_unpack16(&resv_ptr->flags, buffer); safe_unpackstr_xmalloc(&resv_ptr->users,&uint32_tmp, buffer); @@ -1897,6 +1911,7 @@ extern int load_all_resv_state(int recover) safe_unpack32(&resv_ptr->cpu_cnt, buffer); safe_unpack32(&resv_ptr->resv_id, buffer); safe_unpack_time(&resv_ptr->start_time_prev, buffer); + safe_unpack_time(&resv_ptr->start_time, buffer); list_append(resv_list, resv_ptr); info("Recovered state of reservation %s", resv_ptr->name); @@ -2391,8 +2406,9 @@ extern void fini_job_resv_check(void) (resv_ptr->flags & RESERVE_FLAG_DAILY)) { verbose("Advance reservation %s one day", resv_ptr->name); - resv_ptr->start_time_prev = resv_ptr->start_time; resv_ptr->start_time += 24 * 60 * 60; + resv_ptr->start_time_prev = resv_ptr->start_time; + resv_ptr->start_time_first = resv_ptr->start_time; resv_ptr->end_time += 24 * 60 * 60; _post_resv_update(resv_ptr, NULL); last_resv_update = now; @@ -2403,8 +2419,9 @@ extern void fini_job_resv_check(void) (resv_ptr->flags & RESERVE_FLAG_WEEKLY)) { verbose("Advance reservation %s one week", resv_ptr->name); - resv_ptr->start_time_prev = resv_ptr->start_time; resv_ptr->start_time += 7 * 24 * 60 * 60; + resv_ptr->start_time_prev = resv_ptr->start_time; + resv_ptr->start_time_first = resv_ptr->start_time; resv_ptr->end_time += 7 * 24 * 60 * 60; _post_resv_update(resv_ptr, NULL); last_resv_update = now; diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h index ef96cef664d..c39b9796f4b 100644 --- a/src/slurmctld/slurmctld.h +++ b/src/slurmctld/slurmctld.h @@ -349,6 +349,7 @@ typedef struct slurmctld_resv { struct part_record *part_ptr; /* pointer to partition used */ uint32_t resv_id; /* unique reservation ID, internal use */ time_t start_time; /* start time of reservation */ + time_t start_time_first;/* when the reservation first started */ time_t start_time_prev; /* If start time was changed this is * the pervious start time. Needed * for accounting */ diff --git a/src/sview/common.c b/src/sview/common.c index c30902a39d0..f6b6ea6efb6 100644 --- a/src/sview/common.c +++ b/src/sview/common.c @@ -166,6 +166,56 @@ cleanup: return ret; } +static int _sort_iter_compare_func_bp_list(GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer userdata) +{ + int sortcol = GPOINTER_TO_INT(userdata); + int ret = 0; + int len1 = 0, len2 = 0; + gchar *name1 = NULL, *name2 = NULL; + + gtk_tree_model_get(model, a, sortcol, &name1, -1); + gtk_tree_model_get(model, b, sortcol, &name2, -1); + + if (name1 == NULL || name2 == NULL) { + if (name1 == NULL && name2 == NULL) + goto cleanup; /* both equal => ret = 0 */ + + ret = (name1 == NULL) ? -1 : 1; + } else { + /* sort like a human would + meaning snowflake2 would be greater than + snowflake12 */ + len1 = strlen(name1); + len2 = strlen(name2); + while((ret < len1) && (!g_ascii_isdigit(name1[ret]))) + ret++; + if(ret < len1) { + if(!g_ascii_strncasecmp(name1, name2, ret)) { + if(len1 > len2) + ret = 1; + else if(len1 < len2) + ret = -1; + else { + ret = g_ascii_strcasecmp(name1, name2); + } + } else { + ret = g_ascii_strcasecmp(name1, name2); + } + + } else { + ret = g_ascii_strcasecmp(name1, name2); + } + } +cleanup: + g_free(name1); + g_free(name2); + + return ret; +} + static void _editing_started(GtkCellRenderer *cell, GtkCellEditable *editable, const gchar *path, @@ -621,7 +671,9 @@ extern GtkTreeStore *create_treestore(GtkTreeView *tree_view, break; case G_TYPE_STRING: - if(!strcasecmp(display_data[i].name, "Nodes")) { + if(!strcasecmp(display_data[i].name, "Nodes") + || !strcasecmp(display_data[i].name, "Real Memory") + || !strcasecmp(display_data[i].name, "Tmp Disk")) { gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE(treestore), display_data[i].id, @@ -629,6 +681,15 @@ extern GtkTreeStore *create_treestore(GtkTreeView *tree_view, GINT_TO_POINTER(display_data[i].id), NULL); break; + } else if(!strcasecmp(display_data[i].name, + "BP List")) { + gtk_tree_sortable_set_sort_func( + GTK_TREE_SORTABLE(treestore), + display_data[i].id, + _sort_iter_compare_func_bp_list, + GINT_TO_POINTER(display_data[i].id), + NULL); + break; } else { gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE(treestore), -- GitLab