diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c index cf92038ead3d771880d679a8ec66e5326c3afd2d..2625d47a5ed6249f5478eed92b104e341f0bdb92 100644 --- a/src/slurmctld/reservation.c +++ b/src/slurmctld/reservation.c @@ -246,7 +246,7 @@ static slurmctld_resv_t *_copy_resv(slurmctld_resv_t *resv_orig_ptr) resv_copy_ptr->account_list = xmalloc(sizeof(char *) * resv_orig_ptr->account_cnt); resv_copy_ptr->account_not = resv_orig_ptr->account_not; - for (i=0; i<resv_copy_ptr->account_cnt; i++) { + for (i = 0; i < resv_copy_ptr->account_cnt; i++) { resv_copy_ptr->account_list[i] = xstrdup(resv_orig_ptr->account_list[i]); } @@ -269,7 +269,10 @@ static slurmctld_resv_t *_copy_resv(slurmctld_resv_t *resv_orig_ptr) resv_copy_ptr->magic = resv_orig_ptr->magic; resv_copy_ptr->flags_set_node = resv_orig_ptr->flags_set_node; resv_copy_ptr->name = xstrdup(resv_orig_ptr->name); - resv_copy_ptr->node_bitmap = bit_copy(resv_orig_ptr->node_bitmap); + if (resv_orig_ptr->node_bitmap) { + resv_copy_ptr->node_bitmap = + bit_copy(resv_orig_ptr->node_bitmap); + } resv_copy_ptr->node_cnt = resv_orig_ptr->node_cnt; resv_copy_ptr->node_list = xstrdup(resv_orig_ptr->node_list); resv_copy_ptr->partition = xstrdup(resv_orig_ptr->partition); @@ -286,7 +289,7 @@ static slurmctld_resv_t *_copy_resv(slurmctld_resv_t *resv_orig_ptr) resv_copy_ptr->user_list = xmalloc(sizeof(uid_t) * resv_orig_ptr->user_cnt); resv_copy_ptr->user_not = resv_orig_ptr->user_not; - for (i=0; i<resv_copy_ptr->user_cnt; i++) + for (i = 0; i < resv_copy_ptr->user_cnt; i++) resv_copy_ptr->user_list[i] = resv_orig_ptr->user_list[i]; return resv_copy_ptr; @@ -1770,11 +1773,11 @@ static void _set_tres_cnt(slurmctld_resv_t *resv_ptr, name2 = val2 = ""; info("sched: %s reservation=%s%s%s%s%s nodes=%s cores=%u " - "licenses=%s tres=%s start=%s end=%s", + "licenses=%s tres=%s watts=%u start=%s end=%s", old_resv_ptr ? "Updated" : "Created", resv_ptr->name, name1, val1, name2, val2, resv_ptr->node_list, resv_ptr->core_cnt, resv_ptr->licenses, - resv_ptr->tres_str, + resv_ptr->tres_str, resv_ptr->resv_watts, start_time, end_time); if (old_resv_ptr) _post_resv_update(resv_ptr, old_resv_ptr); diff --git a/src/sview/resv_info.c b/src/sview/resv_info.c index d4f5d0bc69bc6d20ff23c08c31e7cf7c399f031e..74368cd3255820cf0145e1cacc70d96fcb01f7aa 100644 --- a/src/sview/resv_info.c +++ b/src/sview/resv_info.c @@ -71,6 +71,7 @@ enum { SORTID_TIME_START, SORTID_UPDATED, SORTID_USERS, + SORTID_WATTS, SORTID_CNT }; @@ -79,9 +80,9 @@ enum { * known options) create it in function create_model_*. */ -/*these are the settings to apply for the user +/* these are the settings to apply for the user * on the first startup after a fresh slurm install. - * s/b a const probably*/ + * s/b a const probably */ static char *_initial_page_opts = "Name,Node_Count,Core_Count,NodeList," "Time_Start,Time_End"; @@ -141,6 +142,8 @@ static display_data_t display_data_resv[] = { refresh_resv, create_model_resv, admin_edit_resv}, {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, EDIT_NONE, refresh_resv, create_model_resv, admin_edit_resv}, + {G_TYPE_STRING, SORTID_WATTS, "Watts", FALSE, EDIT_TEXTBOX, + refresh_resv, create_model_resv, admin_edit_resv}, {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE} }; @@ -190,6 +193,8 @@ static display_data_t create_data_resv[] = { refresh_resv, create_model_resv, admin_edit_resv}, {G_TYPE_STRING, SORTID_FLAGS, "Flags", FALSE, EDIT_TEXTBOX, refresh_resv, create_model_resv, admin_edit_resv}, + {G_TYPE_STRING, SORTID_WATTS, "Watts", FALSE, EDIT_TEXTBOX, + refresh_resv, create_model_resv, admin_edit_resv}, {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE} }; @@ -248,6 +253,25 @@ end_it: } +static uint32_t _parse_watts(char * watts_str) +{ + uint32_t watts_num = 0; + char *end_ptr = NULL; + + if (!strcasecmp(watts_str, "n/a") || !strcasecmp(watts_str, "none")) + return watts_num; + watts_num = strtol(watts_str, &end_ptr, 10); + if ((end_ptr[0] == 'k') || (end_ptr[0] == 'K')) { + watts_num *= 1000; + } else if ((end_ptr[0] == 'm') || (end_ptr[0] == 'M')) { + watts_num *= 1000000; + } else if (end_ptr[0] != '\0') { + g_printerr("invalid watts value\n"); + watts_num = NO_VAL; + } + return watts_num; +} + /* don't free this char */ static const char *_set_resv_msg(resv_desc_msg_t *resv_msg, const char *new_text, @@ -349,6 +373,10 @@ static const char *_set_resv_msg(resv_desc_msg_t *resv_msg, resv_msg->users = xstrdup(new_text); type = "users"; break; + case SORTID_WATTS: + resv_msg->resv_watts = _parse_watts((char *) new_text); + type = "watts"; + break; default: type = "unknown"; break; @@ -457,7 +485,7 @@ static GtkWidget *_admin_full_edit_resv(resv_desc_msg_t *resv_msg, gtk_table_set_homogeneous(table, FALSE); - for(i = 0; i < SORTID_CNT; i++) { + for (i = 0; i < SORTID_CNT; i++) { while (display_data++) { if (display_data->id == -1) break; @@ -485,7 +513,7 @@ static void _layout_resv_record(GtkTreeView *treeview, int update) { GtkTreeIter iter; - char time_buf[20]; + char time_buf[20], power_buf[20]; reserve_info_t *resv_ptr = sview_resv_info->resv_ptr; char *temp_char = NULL; @@ -568,13 +596,30 @@ static void _layout_resv_record(GtkTreeView *treeview, find_col_name(display_data_resv, SORTID_USERS), resv_ptr->users); + + if ((resv_ptr->resv_watts == NO_VAL) || (resv_ptr->resv_watts == 0)) { + snprintf(power_buf, sizeof(power_buf), "0"); + } else if ((resv_ptr->resv_watts % 1000000) == 0) { + snprintf(power_buf, sizeof(power_buf), "%uM", + resv_ptr->resv_watts / 1000000); + } else if ((resv_ptr->resv_watts % 1000) == 0) { + snprintf(power_buf, sizeof(power_buf), "%uK", + resv_ptr->resv_watts / 1000); + } else { + snprintf(power_buf, sizeof(power_buf), "%u", + resv_ptr->resv_watts); + } + add_display_treestore_line(update, treestore, &iter, + find_col_name(display_data_resv, + SORTID_WATTS), + power_buf); } static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr, GtkTreeStore *treestore) { - char tmp_duration[40], tmp_end[40], tmp_nodes[40], tmp_start[40], - tmp_cores[40]; + char tmp_duration[40], tmp_end[40], tmp_nodes[40], tmp_start[40]; + char tmp_cores[40], power_buf[40]; char *tmp_flags; reserve_info_t *resv_ptr = sview_resv_info_ptr->resv_ptr; @@ -596,6 +641,19 @@ static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr, slurm_make_time_str((time_t *)&resv_ptr->start_time, tmp_start, sizeof(tmp_start)); + if ((resv_ptr->resv_watts == NO_VAL) || (resv_ptr->resv_watts == 0)) { + snprintf(power_buf, sizeof(power_buf), "0"); + } else if ((resv_ptr->resv_watts % 1000000) == 0) { + snprintf(power_buf, sizeof(power_buf), "%uM", + resv_ptr->resv_watts / 1000000); + } else if ((resv_ptr->resv_watts % 1000) == 0) { + snprintf(power_buf, sizeof(power_buf), "%uK", + resv_ptr->resv_watts / 1000); + } else { + snprintf(power_buf, sizeof(power_buf), "%u", + resv_ptr->resv_watts); + } + /* Combining these records provides a slight performance improvement */ gtk_tree_store_set(treestore, &sview_resv_info_ptr->iter_ptr, SORTID_ACCOUNTS, resv_ptr->accounts, @@ -617,6 +675,7 @@ static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr, SORTID_TIME_END, tmp_end, SORTID_UPDATED, 1, SORTID_USERS, resv_ptr->users, + SORTID_WATTS, power_buf, -1); xfree(tmp_flags);