|  | /*****************************************************************************\ | 
|  | *  resv_info.c - Functions related to advanced reservation display | 
|  | *  mode of sview. | 
|  | ***************************************************************************** | 
|  | *  Copyright (C) 2009-2011 Lawrence Livermore National Security. | 
|  | *  Copyright (C) SchedMD LLC. | 
|  | *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). | 
|  | *  Written by Morris Jette <jette@llnl.gov> | 
|  | *  CODE-OCEC-09-009. All rights reserved. | 
|  | * | 
|  | *  This file is part of Slurm, a resource management program. | 
|  | *  For details, see <https://slurm.schedmd.com/>. | 
|  | *  Please also read the included file: DISCLAIMER. | 
|  | * | 
|  | *  Slurm is free software; you can redistribute it and/or modify it under | 
|  | *  the terms of the GNU General Public License as published by the Free | 
|  | *  Software Foundation; either version 2 of the License, or (at your option) | 
|  | *  any later version. | 
|  | * | 
|  | *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY | 
|  | *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
|  | *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more | 
|  | *  details. | 
|  | * | 
|  | *  You should have received a copy of the GNU General Public License along | 
|  | *  with Slurm; if not, write to the Free Software Foundation, Inc., | 
|  | *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA. | 
|  | \*****************************************************************************/ | 
|  |  | 
|  | #include "src/common/uid.h" | 
|  | #include "src/sview/sview.h" | 
|  | #include "src/common/parse_time.h" | 
|  | #include "src/common/proc_args.h" | 
|  | #include "src/common/xstring.h" | 
|  |  | 
|  | #define _DEBUG 0 | 
|  |  | 
|  | /* Collection of data for printing reports. Like data is combined here */ | 
|  | typedef struct { | 
|  | int color_inx; | 
|  | GtkTreeIter iter_ptr; | 
|  | bool iter_set; | 
|  | int pos; | 
|  | char *resv_name; | 
|  | reserve_info_t *resv_ptr; | 
|  | } sview_resv_info_t; | 
|  |  | 
|  | enum { | 
|  | EDIT_REMOVE = 1, | 
|  | EDIT_EDIT | 
|  | }; | 
|  |  | 
|  | /* These need to be in alpha order (except POS and CNT) */ | 
|  | enum { | 
|  | SORTID_POS = POS_LOC, | 
|  | SORTID_ACCOUNTS, | 
|  | SORTID_ACTION, | 
|  | SORTID_BURST_BUFFER, | 
|  | SORTID_COLOR, | 
|  | SORTID_COLOR_INX, | 
|  | SORTID_CORE_CNT, | 
|  | SORTID_DURATION, | 
|  | SORTID_FEATURES, | 
|  | SORTID_FLAGS, | 
|  | SORTID_GROUPS, | 
|  | SORTID_LICENSES, | 
|  | SORTID_MSD, | 
|  | SORTID_NAME, | 
|  | SORTID_NODE_CNT, | 
|  | SORTID_NODELIST, | 
|  | SORTID_NODE_INX, | 
|  | SORTID_PARTITION, | 
|  | SORTID_TIME_END, | 
|  | SORTID_TIME_START, | 
|  | SORTID_TRES, | 
|  | SORTID_UPDATED, | 
|  | SORTID_USERS, | 
|  | SORTID_WATTS, | 
|  | SORTID_CNT | 
|  | }; | 
|  |  | 
|  | /* extra field here is for choosing the type of edit you that will | 
|  | * take place.  If you choose EDIT_MODEL (means only display a set of | 
|  | * known options) create it in function create_model_*. | 
|  | */ | 
|  |  | 
|  | /* these are the settings to apply for the user | 
|  | * on the first startup after a fresh slurm install. | 
|  | * s/b a const probably */ | 
|  | static char *_initial_page_opts = "Name,Node_Count,Core_Count,NodeList," | 
|  | "Time_Start,Time_End"; | 
|  |  | 
|  | static display_data_t display_data_resv[] = { | 
|  | {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NAME, "Name", false, EDIT_NONE, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_COLOR, NULL, true, EDIT_COLOR, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_ACTION, "Action", false, EDIT_MODEL, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NODE_CNT, "Node Count", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_CORE_CNT, "Core Count", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NODELIST, "Node List", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_TIME_START, "Time Start", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_TIME_END, "Time End", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_DURATION, "Duration", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_ACCOUNTS, "Accounts", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_BURST_BUFFER, "BurstBuffer", false, | 
|  | EDIT_TEXTBOX, refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_LICENSES, "Licenses", true, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_USERS, "Users", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_GROUPS, "Groups", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_PARTITION, "Partition", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_FEATURES, "Features", false, EDIT_TEXTBOX, | 
|  | 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_POINTER, SORTID_NODE_INX, NULL, false, EDIT_NONE, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_INT, SORTID_COLOR_INX, NULL, false, EDIT_NONE, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_TRES, "TRES", false, EDIT_TEXTBOX, | 
|  | 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_STRING, SORTID_MSD, "MaxStartDelay", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_NONE, -1, NULL, false, EDIT_NONE} | 
|  | }; | 
|  |  | 
|  | static display_data_t create_data_resv[] = { | 
|  | {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NAME, "Name", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NODE_CNT, "Node_Count", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_CORE_CNT, "Core_Count", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_NODELIST, "Node_List", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_TIME_START, "Time_Start", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_TIME_END, "Time_End", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_DURATION, "Duration", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_ACCOUNTS, "Accounts", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_BURST_BUFFER, "BurstBuffer", false, | 
|  | EDIT_TEXTBOX, refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_USERS, "Users", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_GROUPS, "Groups", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_PARTITION, "Partition", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_STRING, SORTID_FEATURES, "Features", false, EDIT_TEXTBOX, | 
|  | 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_TRES, "TRES", 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_STRING, SORTID_MSD, "MaxStartDelay", false, EDIT_TEXTBOX, | 
|  | refresh_resv, create_model_resv, admin_edit_resv}, | 
|  | {G_TYPE_NONE, -1, NULL, false, EDIT_NONE} | 
|  | }; | 
|  |  | 
|  | static display_data_t options_data_resv[] = { | 
|  | {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE}, | 
|  | {G_TYPE_STRING, INFO_PAGE, "Full Info", true, RESV_PAGE}, | 
|  | {G_TYPE_STRING, RESV_PAGE, "Remove Reservation", true, ADMIN_PAGE}, | 
|  | {G_TYPE_STRING, RESV_PAGE, "Edit Reservation", true, ADMIN_PAGE}, | 
|  | {G_TYPE_STRING, JOB_PAGE, "Jobs", true, RESV_PAGE}, | 
|  | {G_TYPE_STRING, PART_PAGE, "Partitions", true, RESV_PAGE}, | 
|  | {G_TYPE_STRING, NODE_PAGE, "Nodes", true, RESV_PAGE}, | 
|  | {G_TYPE_NONE, -1, NULL, false, EDIT_NONE} | 
|  | }; | 
|  |  | 
|  | static display_data_t *local_display_data = NULL; | 
|  | static char *got_edit_signal = NULL; | 
|  | static GtkTreeModel *last_model = NULL; | 
|  |  | 
|  | static void _admin_resv(GtkTreeModel *model, GtkTreeIter *iter, char *type); | 
|  | static void _process_each_resv(GtkTreeModel *model, GtkTreePath *path, | 
|  | GtkTreeIter*iter, gpointer userdata); | 
|  |  | 
|  | static void _set_active_combo_resv(GtkComboBox *combo, | 
|  | GtkTreeModel *model, GtkTreeIter *iter, | 
|  | int type) | 
|  | { | 
|  | char *temp_char = NULL; | 
|  | int action = 0; | 
|  |  | 
|  | gtk_tree_model_get(model, iter, type, &temp_char, -1); | 
|  | if (!temp_char) | 
|  | goto end_it; | 
|  | switch (type) { | 
|  | case SORTID_ACTION: | 
|  | if (!xstrcmp(temp_char, "none")) | 
|  | action = 0; | 
|  | else if (!xstrcmp(temp_char, "remove")) | 
|  | action = 1; | 
|  | else | 
|  | action = 0; | 
|  |  | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | g_free(temp_char); | 
|  | end_it: | 
|  | gtk_combo_box_set_active(combo, action); | 
|  |  | 
|  | } | 
|  |  | 
|  | /* don't free this char */ | 
|  | static const char *_set_resv_msg(resv_desc_msg_t *resv_msg, | 
|  | const char *new_text, | 
|  | int column) | 
|  | { | 
|  | char *type = ""; | 
|  | uint32_t res_free_flags = 0; | 
|  | int temp_int = 0; | 
|  | uint64_t f; | 
|  |  | 
|  | /* need to clear global_edit_error here (just in case) */ | 
|  | global_edit_error = 0; | 
|  |  | 
|  | if (!resv_msg) | 
|  | return NULL; | 
|  |  | 
|  | switch (column) { | 
|  | case SORTID_ACCOUNTS: | 
|  | resv_msg->accounts = xstrdup(new_text); | 
|  | type = "accounts"; | 
|  | break; | 
|  | case SORTID_ACTION: | 
|  | xfree(got_edit_signal); | 
|  | if (!xstrcasecmp(new_text, "None")) | 
|  | got_edit_signal = NULL; | 
|  | else | 
|  | got_edit_signal = xstrdup(new_text); | 
|  | break; | 
|  | case SORTID_BURST_BUFFER: | 
|  | resv_msg->burst_buffer = xstrdup(new_text); | 
|  | type = "burst_buffer"; | 
|  | break; | 
|  | case SORTID_CORE_CNT: | 
|  | if (strtok_r((char *)new_text, ",", &type)) { | 
|  | type = NULL; | 
|  | if (global_edit_error_msg) | 
|  | g_free(global_edit_error_msg); | 
|  | global_edit_error_msg = g_strdup("Using a comma separated array for CoreCnt is no longer valid."); | 
|  | goto return_error; | 
|  | } | 
|  |  | 
|  | type = "Core Count"; | 
|  | resv_msg->core_cnt = slurm_atoul((char *)new_text); | 
|  | break; | 
|  | case SORTID_DURATION: | 
|  | type = "duration"; | 
|  | temp_int = time_str2mins((char *)new_text); | 
|  | if (temp_int <= 0) | 
|  | goto return_error; | 
|  | resv_msg->duration = temp_int; | 
|  | break; | 
|  | case SORTID_TIME_END: | 
|  | resv_msg->end_time = parse_time((char *)new_text, 0); | 
|  | type = "end time"; | 
|  | break; | 
|  | case SORTID_FEATURES: | 
|  | resv_msg->features = xstrdup(new_text); | 
|  | type = "features"; | 
|  | break; | 
|  | case SORTID_FLAGS: | 
|  | f = parse_resv_flags(new_text, __func__, resv_msg); | 
|  | type = "flags"; | 
|  | if (f == INFINITE64) | 
|  | goto return_error; | 
|  | break; | 
|  | case SORTID_GROUPS: | 
|  | resv_msg->groups = xstrdup(new_text); | 
|  | type = "groups"; | 
|  | break; | 
|  | case SORTID_LICENSES: | 
|  | resv_msg->licenses = xstrdup(new_text); | 
|  | type = "licenses"; | 
|  | break; | 
|  | case SORTID_MSD: | 
|  | type = "MaxStartDelay"; | 
|  | temp_int = time_str2secs((char *)new_text); | 
|  | if (temp_int < 0) | 
|  | goto return_error; | 
|  | resv_msg->max_start_delay = temp_int; | 
|  | break; | 
|  | case SORTID_NAME: | 
|  | resv_msg->name = xstrdup(new_text); | 
|  | type = "name"; | 
|  | break; | 
|  | case SORTID_NODE_CNT: | 
|  | if (strtok_r((char *)new_text, ",", &type)) { | 
|  | type = NULL; | 
|  | if (global_edit_error_msg) | 
|  | g_free(global_edit_error_msg); | 
|  | global_edit_error_msg = g_strdup("Using a comma separated array for NodeCnt is no longer valid."); | 
|  | goto return_error; | 
|  | } | 
|  |  | 
|  | type = "Node Count"; | 
|  | resv_msg->node_cnt = slurm_atoul((char *)new_text); | 
|  | break; | 
|  | case SORTID_NODELIST: | 
|  | resv_msg->node_list = xstrdup(new_text); | 
|  | type = "Node List"; | 
|  | break; | 
|  | case SORTID_PARTITION: | 
|  | resv_msg->partition = xstrdup(new_text); | 
|  | type = "partition"; | 
|  | break; | 
|  | case SORTID_TIME_START: | 
|  | resv_msg->start_time = parse_time((char *)new_text, 0); | 
|  | type = "start time"; | 
|  | break; | 
|  | case SORTID_USERS: | 
|  | resv_msg->users = xstrdup(new_text); | 
|  | type = "users"; | 
|  | break; | 
|  | case SORTID_TRES: | 
|  | resv_msg->tres_str = xstrdup(new_text); | 
|  | type = "TRES"; | 
|  | break; | 
|  | default: | 
|  | type = "unknown"; | 
|  | break; | 
|  | } | 
|  |  | 
|  | if (xstrcmp(type, "unknown")) | 
|  | global_send_update_msg = 1; | 
|  |  | 
|  | slurm_free_resv_desc_msg_part(resv_msg, res_free_flags); | 
|  | return type; | 
|  |  | 
|  | return_error: | 
|  | slurm_free_resv_desc_msg_part(resv_msg, res_free_flags); | 
|  | global_edit_error = 1; | 
|  | return type; | 
|  | } | 
|  |  | 
|  | static void _resv_info_free(sview_resv_info_t *sview_resv_info) | 
|  | { | 
|  | if (sview_resv_info) { | 
|  | xfree(sview_resv_info->resv_name); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void _resv_info_list_del(void *object) | 
|  | { | 
|  | sview_resv_info_t *sview_resv_info = (sview_resv_info_t *)object; | 
|  |  | 
|  | if (sview_resv_info) { | 
|  | _resv_info_free(sview_resv_info); | 
|  | xfree(sview_resv_info); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void _admin_edit_combo_box_resv(GtkComboBox *combo, | 
|  | resv_desc_msg_t *resv_msg) | 
|  | { | 
|  | GtkTreeModel *model = NULL; | 
|  | GtkTreeIter iter; | 
|  | int column = 0; | 
|  | char *name = NULL; | 
|  |  | 
|  | if (!resv_msg) | 
|  | return; | 
|  |  | 
|  | if (!gtk_combo_box_get_active_iter(combo, &iter)) { | 
|  | g_print("nothing selected\n"); | 
|  | return; | 
|  | } | 
|  | model = gtk_combo_box_get_model(combo); | 
|  | if (!model) { | 
|  | g_print("nothing selected\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | gtk_tree_model_get(model, &iter, 0, &name, -1); | 
|  | gtk_tree_model_get(model, &iter, 1, &column, -1); | 
|  |  | 
|  | _set_resv_msg(resv_msg, name, column); | 
|  |  | 
|  | g_free(name); | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  | static gboolean _admin_focus_out_resv(GtkEntry *entry, | 
|  | GdkEventFocus *event, | 
|  | resv_desc_msg_t *resv_msg) | 
|  | { | 
|  | if (global_entry_changed) { | 
|  | const char *col_name = NULL; | 
|  | int type = gtk_entry_get_max_length(entry); | 
|  | const char *name = gtk_entry_get_text(entry); | 
|  | type -= DEFAULT_ENTRY_LENGTH; | 
|  | col_name = _set_resv_msg(resv_msg, name, type); | 
|  | if (global_edit_error && !global_edit_error_msg) { | 
|  | global_edit_error_msg = g_strdup_printf( | 
|  | "Reservation %s %s can't be set to %s", | 
|  | resv_msg->name, | 
|  | col_name, | 
|  | name); | 
|  | } | 
|  | global_entry_changed = 0; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | static GtkWidget *_admin_full_edit_resv(resv_desc_msg_t *resv_msg, | 
|  | GtkTreeModel *model, GtkTreeIter *iter) | 
|  | { | 
|  | GtkScrolledWindow *window = create_scrolled_window(); | 
|  | GtkBin *bin = NULL; | 
|  | GtkViewport *view = NULL; | 
|  | GtkTable *table = NULL; | 
|  | int i = 0, row = 0; | 
|  | display_data_t *display_data = display_data_resv; | 
|  |  | 
|  | gtk_scrolled_window_set_policy(window, | 
|  | GTK_POLICY_NEVER, | 
|  | GTK_POLICY_AUTOMATIC); | 
|  | bin = GTK_BIN(&window->container); | 
|  | view = GTK_VIEWPORT(bin->child); | 
|  | bin = GTK_BIN(&view->bin); | 
|  | table = GTK_TABLE(bin->child); | 
|  | gtk_table_resize(table, SORTID_CNT, 2); | 
|  |  | 
|  | gtk_table_set_homogeneous(table, false); | 
|  |  | 
|  | for (i = 0; i < SORTID_CNT; i++) { | 
|  | while (display_data++) { | 
|  | if (display_data->id == -1) | 
|  | break; | 
|  | if (!display_data->name) | 
|  | continue; | 
|  | if (display_data->id != i) | 
|  | continue; | 
|  | display_admin_edit( | 
|  | table, resv_msg, &row, model, iter, | 
|  | display_data, | 
|  | G_CALLBACK(_admin_edit_combo_box_resv), | 
|  | G_CALLBACK(_admin_focus_out_resv), | 
|  | _set_active_combo_resv); | 
|  | break; | 
|  | } | 
|  | display_data = display_data_resv; | 
|  | } | 
|  | gtk_table_resize(table, row, 2); | 
|  |  | 
|  | return GTK_WIDGET(window); | 
|  | } | 
|  |  | 
|  | static void _layout_resv_record(GtkTreeView *treeview, | 
|  | sview_resv_info_t *sview_resv_info, | 
|  | int update) | 
|  | { | 
|  | GtkTreeIter iter; | 
|  | char time_buf[256]; | 
|  | reserve_info_t *resv_ptr = sview_resv_info->resv_ptr; | 
|  | char *temp_char = NULL; | 
|  |  | 
|  | GtkTreeStore *treestore = | 
|  | GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_ACCOUNTS), | 
|  | resv_ptr->accounts); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_BURST_BUFFER), | 
|  | resv_ptr->burst_buffer); | 
|  |  | 
|  | convert_num_unit((float)resv_ptr->core_cnt, | 
|  | time_buf, sizeof(time_buf), UNIT_NONE, NO_VAL, | 
|  | working_sview_config.convert_flags); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_CORE_CNT), | 
|  | time_buf); | 
|  | secs2time_str((uint32_t)difftime(resv_ptr->end_time, | 
|  | resv_ptr->start_time), | 
|  | time_buf, sizeof(time_buf)); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_DURATION), | 
|  | time_buf); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_FEATURES), | 
|  | resv_ptr->features); | 
|  |  | 
|  | temp_char = reservation_flags_string(resv_ptr); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_FLAGS), | 
|  | temp_char); | 
|  | xfree(temp_char); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_GROUPS), | 
|  | resv_ptr->groups); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_LICENSES), | 
|  | resv_ptr->licenses); | 
|  |  | 
|  | if (resv_ptr->max_start_delay) | 
|  | secs2time_str(resv_ptr->max_start_delay, | 
|  | time_buf, sizeof(time_buf)); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_MSD), | 
|  | resv_ptr->max_start_delay ? | 
|  | time_buf : NULL); | 
|  |  | 
|  | /* NOTE: node_cnt in reservation info from slurmctld ONE number */ | 
|  | convert_num_unit((float)resv_ptr->node_cnt, | 
|  | time_buf, sizeof(time_buf), UNIT_NONE, NO_VAL, | 
|  | working_sview_config.convert_flags); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_NODE_CNT), | 
|  | time_buf); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_NODELIST), | 
|  | resv_ptr->node_list); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_PARTITION), | 
|  | resv_ptr->partition); | 
|  |  | 
|  | slurm_make_time_str((time_t *)&resv_ptr->end_time, time_buf, | 
|  | sizeof(time_buf)); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_TIME_END), | 
|  | time_buf); | 
|  | slurm_make_time_str((time_t *)&resv_ptr->start_time, time_buf, | 
|  | sizeof(time_buf)); | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_TIME_START), | 
|  | time_buf); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_TRES), | 
|  | resv_ptr->tres_str); | 
|  |  | 
|  | add_display_treestore_line(update, treestore, &iter, | 
|  | find_col_name(display_data_resv, | 
|  | SORTID_USERS), | 
|  | resv_ptr->users); | 
|  | } | 
|  |  | 
|  | static void _update_resv_record(sview_resv_info_t *sview_resv_info_ptr, | 
|  | GtkTreeStore *treestore) | 
|  | { | 
|  | char tmp_duration[40], tmp_end[256], tmp_nodes[40], tmp_start[256]; | 
|  | char tmp_cores[40], tmp_msd[40]; | 
|  | char *tmp_flags; | 
|  | reserve_info_t *resv_ptr = sview_resv_info_ptr->resv_ptr; | 
|  |  | 
|  | secs2time_str((uint32_t)difftime(resv_ptr->end_time, | 
|  | resv_ptr->start_time), | 
|  | tmp_duration, sizeof(tmp_duration)); | 
|  |  | 
|  | slurm_make_time_str((time_t *)&resv_ptr->end_time, tmp_end, | 
|  | sizeof(tmp_end)); | 
|  |  | 
|  | tmp_flags = reservation_flags_string(resv_ptr); | 
|  |  | 
|  | convert_num_unit((float)resv_ptr->core_cnt, | 
|  | tmp_cores, sizeof(tmp_cores), UNIT_NONE, NO_VAL, | 
|  | working_sview_config.convert_flags); | 
|  |  | 
|  | convert_num_unit((float)resv_ptr->node_cnt, | 
|  | tmp_nodes, sizeof(tmp_nodes), UNIT_NONE, NO_VAL, | 
|  | working_sview_config.convert_flags); | 
|  |  | 
|  | slurm_make_time_str((time_t *)&resv_ptr->start_time, tmp_start, | 
|  | sizeof(tmp_start)); | 
|  |  | 
|  | if (resv_ptr->max_start_delay) | 
|  | secs2time_str(resv_ptr->max_start_delay, | 
|  | tmp_msd, sizeof(tmp_msd)); | 
|  |  | 
|  | /* Combining these records provides a slight performance improvement */ | 
|  | gtk_tree_store_set(treestore, &sview_resv_info_ptr->iter_ptr, | 
|  | SORTID_ACCOUNTS,   resv_ptr->accounts, | 
|  | SORTID_BURST_BUFFER, resv_ptr->burst_buffer, | 
|  | SORTID_COLOR, | 
|  | sview_colors[sview_resv_info_ptr->color_inx], | 
|  | SORTID_COLOR_INX,  sview_resv_info_ptr->color_inx, | 
|  | SORTID_CORE_CNT,   tmp_cores, | 
|  | SORTID_DURATION,   tmp_duration, | 
|  | SORTID_FEATURES,   resv_ptr->features, | 
|  | SORTID_FLAGS,      tmp_flags, | 
|  | SORTID_GROUPS,     resv_ptr->groups, | 
|  | SORTID_LICENSES,   resv_ptr->licenses, | 
|  | SORTID_MSD,        resv_ptr->max_start_delay ? | 
|  | tmp_msd : NULL, | 
|  | SORTID_NAME,       resv_ptr->name, | 
|  | SORTID_NODE_CNT,   tmp_nodes, | 
|  | SORTID_NODE_INX,   resv_ptr->node_inx, | 
|  | SORTID_NODELIST,   resv_ptr->node_list, | 
|  | SORTID_PARTITION,  resv_ptr->partition, | 
|  | SORTID_TIME_START, tmp_start, | 
|  | SORTID_TIME_END,   tmp_end, | 
|  | SORTID_TRES,       resv_ptr->tres_str, | 
|  | SORTID_UPDATED,    1, | 
|  | SORTID_USERS,      resv_ptr->users, | 
|  | -1); | 
|  |  | 
|  | xfree(tmp_flags); | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | static void _append_resv_record(sview_resv_info_t *sview_resv_info_ptr, | 
|  | GtkTreeStore *treestore) | 
|  | { | 
|  | gtk_tree_store_append(treestore, &sview_resv_info_ptr->iter_ptr, NULL); | 
|  | gtk_tree_store_set(treestore, &sview_resv_info_ptr->iter_ptr, | 
|  | SORTID_POS, sview_resv_info_ptr->pos, -1); | 
|  | _update_resv_record(sview_resv_info_ptr, treestore); | 
|  | } | 
|  |  | 
|  | static void _update_info_resv(list_t *info_list, GtkTreeView *tree_view) | 
|  | { | 
|  | GtkTreeModel *model = gtk_tree_view_get_model(tree_view); | 
|  | char *name = NULL; | 
|  | list_itr_t *itr = NULL; | 
|  | sview_resv_info_t *sview_resv_info = NULL; | 
|  |  | 
|  | set_for_update(model, SORTID_UPDATED); | 
|  |  | 
|  | itr = list_iterator_create(info_list); | 
|  | while ((sview_resv_info = list_next(itr))) { | 
|  | /* This means the tree_store changed (added new column | 
|  | or something). */ | 
|  | if (last_model != model) | 
|  | sview_resv_info->iter_set = false; | 
|  |  | 
|  | if (sview_resv_info->iter_set) { | 
|  | gtk_tree_model_get(model, &sview_resv_info->iter_ptr, | 
|  | SORTID_NAME, &name, -1); | 
|  | if (xstrcmp(name, sview_resv_info->resv_name)) { | 
|  | /* Bad pointer */ | 
|  | sview_resv_info->iter_set = false; | 
|  | //g_print("bad resv iter pointer\n"); | 
|  | } | 
|  | g_free(name); | 
|  | } | 
|  | if (sview_resv_info->iter_set) { | 
|  | _update_resv_record(sview_resv_info, | 
|  | GTK_TREE_STORE(model)); | 
|  | } else { | 
|  | _append_resv_record(sview_resv_info, | 
|  | GTK_TREE_STORE(model)); | 
|  | sview_resv_info->iter_set = true; | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  |  | 
|  | /* remove all old reservations */ | 
|  | remove_old(model, SORTID_UPDATED); | 
|  | last_model = model; | 
|  | } | 
|  |  | 
|  | static int _sview_resv_sort_aval_dec(void *s1, void *s2) | 
|  | { | 
|  | sview_resv_info_t *rec_a = *(sview_resv_info_t **)s1; | 
|  | sview_resv_info_t *rec_b = *(sview_resv_info_t **)s2; | 
|  | int size_a; | 
|  | int size_b; | 
|  |  | 
|  | size_a = rec_a->resv_ptr->node_cnt; | 
|  | size_b = rec_b->resv_ptr->node_cnt; | 
|  |  | 
|  | if (size_a < size_b) | 
|  | return -1; | 
|  | else if (size_a > size_b) | 
|  | return 1; | 
|  |  | 
|  | if (rec_a->resv_ptr->node_list && rec_b->resv_ptr->node_list) { | 
|  | size_a = xstrcmp(rec_a->resv_ptr->node_list, | 
|  | rec_b->resv_ptr->node_list); | 
|  | if (size_a < 0) | 
|  | return -1; | 
|  | else if (size_a > 0) | 
|  | return 1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static list_t *_create_resv_info_list(reserve_info_msg_t *resv_info_ptr) | 
|  | { | 
|  | static list_t *info_list = NULL; | 
|  | list_t *last_list = NULL; | 
|  | list_itr_t *last_list_itr = NULL; | 
|  | int i = 0; | 
|  | static reserve_info_msg_t *last_resv_info_ptr = NULL; | 
|  | sview_resv_info_t *sview_resv_info_ptr = NULL; | 
|  | reserve_info_t *resv_ptr = NULL; | 
|  |  | 
|  | if (info_list && (resv_info_ptr == last_resv_info_ptr)) | 
|  | goto update_color; | 
|  |  | 
|  | last_resv_info_ptr = resv_info_ptr; | 
|  |  | 
|  | if (info_list) | 
|  | last_list = info_list; | 
|  |  | 
|  | info_list = list_create(_resv_info_list_del); | 
|  |  | 
|  | if (last_list) | 
|  | last_list_itr = list_iterator_create(last_list); | 
|  | for(i=0; i<resv_info_ptr->record_count; i++) { | 
|  | resv_ptr = &(resv_info_ptr->reservation_array[i]); | 
|  |  | 
|  | sview_resv_info_ptr = NULL; | 
|  |  | 
|  | if (last_list_itr) { | 
|  | while ((sview_resv_info_ptr = | 
|  | list_next(last_list_itr))) { | 
|  | if (!xstrcmp(sview_resv_info_ptr->resv_name, | 
|  | resv_ptr->name)) { | 
|  | list_remove(last_list_itr); | 
|  | _resv_info_free(sview_resv_info_ptr); | 
|  | break; | 
|  | } | 
|  | } | 
|  | list_iterator_reset(last_list_itr); | 
|  | } | 
|  | if (!sview_resv_info_ptr) | 
|  | sview_resv_info_ptr = | 
|  | xmalloc(sizeof(sview_resv_info_t)); | 
|  | sview_resv_info_ptr->resv_name = xstrdup(resv_ptr->name); | 
|  | sview_resv_info_ptr->pos = i; | 
|  | sview_resv_info_ptr->resv_ptr = resv_ptr; | 
|  | sview_resv_info_ptr->color_inx = i % sview_colors_cnt; | 
|  | list_append(info_list, sview_resv_info_ptr); | 
|  | } | 
|  |  | 
|  | list_sort(info_list, | 
|  | (ListCmpF)_sview_resv_sort_aval_dec); | 
|  |  | 
|  | if (last_list) { | 
|  | list_iterator_destroy(last_list_itr); | 
|  | FREE_NULL_LIST(last_list); | 
|  | } | 
|  |  | 
|  | update_color: | 
|  | return info_list; | 
|  | } | 
|  |  | 
|  | static void _display_info_resv(list_t *info_list, popup_info_t *popup_win) | 
|  | { | 
|  | specific_info_t *spec_info = popup_win->spec_info; | 
|  | char *name = (char *)spec_info->search_info->gchar_data; | 
|  | int found = 0; | 
|  | reserve_info_t *resv_ptr = NULL; | 
|  | GtkTreeView *treeview = NULL; | 
|  | list_itr_t *itr = NULL; | 
|  | sview_resv_info_t *sview_resv_info = NULL; | 
|  | int update = 0; | 
|  | int j = 0; | 
|  |  | 
|  | if (!spec_info->search_info->gchar_data) { | 
|  | //info = xstrdup("No pointer given!"); | 
|  | goto finished; | 
|  | } | 
|  |  | 
|  | need_refresh: | 
|  | if (!spec_info->display_widget) { | 
|  | treeview = create_treeview_2cols_attach_to_table( | 
|  | popup_win->table); | 
|  | spec_info->display_widget = | 
|  | g_object_ref(GTK_WIDGET(treeview)); | 
|  | } else { | 
|  | treeview = GTK_TREE_VIEW(spec_info->display_widget); | 
|  | update = 1; | 
|  | } | 
|  |  | 
|  | itr = list_iterator_create(info_list); | 
|  | while ((sview_resv_info = list_next(itr))) { | 
|  | resv_ptr = sview_resv_info->resv_ptr; | 
|  | if (!xstrcmp(resv_ptr->name, name)) { | 
|  | j=0; | 
|  | while (resv_ptr->node_inx[j] >= 0) { | 
|  | change_grid_color( | 
|  | popup_win->grid_button_list, | 
|  | resv_ptr->node_inx[j], | 
|  | resv_ptr->node_inx[j+1], | 
|  | sview_resv_info->color_inx, | 
|  | true, 0); | 
|  | j += 2; | 
|  | } | 
|  | _layout_resv_record(treeview, sview_resv_info, update); | 
|  | found = 1; | 
|  | break; | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | post_setup_popup_grid_list(popup_win); | 
|  |  | 
|  | if (!found) { | 
|  | if (!popup_win->not_found) { | 
|  | char *temp = "RESERVATION DOESN'T EXIST\n"; | 
|  | GtkTreeIter iter; | 
|  | GtkTreeModel *model = NULL; | 
|  |  | 
|  | /* only time this will be run so no update */ | 
|  | model = gtk_tree_view_get_model(treeview); | 
|  | add_display_treestore_line(0, | 
|  | GTK_TREE_STORE(model), | 
|  | &iter, | 
|  | temp, ""); | 
|  | } | 
|  | popup_win->not_found = true; | 
|  | } else { | 
|  | if (popup_win->not_found) { | 
|  | popup_win->not_found = false; | 
|  | gtk_widget_destroy(spec_info->display_widget); | 
|  |  | 
|  | goto need_refresh; | 
|  | } | 
|  | } | 
|  | gtk_widget_show(spec_info->display_widget); | 
|  |  | 
|  | finished: | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | extern GtkWidget *create_resv_entry(resv_desc_msg_t *resv_msg, | 
|  | GtkTreeModel *model, GtkTreeIter *iter) | 
|  | { | 
|  | GtkScrolledWindow *window = create_scrolled_window(); | 
|  | GtkBin *bin = NULL; | 
|  | GtkViewport *view = NULL; | 
|  | GtkTable *table = NULL; | 
|  | int i = 0, row = 0; | 
|  | display_data_t *display_data = create_data_resv; | 
|  |  | 
|  | gtk_scrolled_window_set_policy(window, | 
|  | GTK_POLICY_NEVER, | 
|  | GTK_POLICY_AUTOMATIC); | 
|  | bin = GTK_BIN(&window->container); | 
|  | view = GTK_VIEWPORT(bin->child); | 
|  | bin = GTK_BIN(&view->bin); | 
|  | table = GTK_TABLE(bin->child); | 
|  | gtk_table_resize(table, SORTID_CNT, 2); | 
|  |  | 
|  | gtk_table_set_homogeneous(table, false); | 
|  |  | 
|  | for (i = 0; i < SORTID_CNT; i++) { | 
|  | while (display_data++) { | 
|  | if (display_data->id == -1) | 
|  | break; | 
|  | if (!display_data->name) | 
|  | continue; | 
|  | if (display_data->id != i) | 
|  | continue; | 
|  | display_admin_edit( | 
|  | table, resv_msg, &row, model, iter, | 
|  | display_data, | 
|  | G_CALLBACK(_admin_edit_combo_box_resv), | 
|  | G_CALLBACK(_admin_focus_out_resv), | 
|  | _set_active_combo_resv); | 
|  | break; | 
|  | } | 
|  | display_data = create_data_resv; | 
|  | } | 
|  | gtk_table_resize(table, row, 2); | 
|  |  | 
|  | return GTK_WIDGET(window); | 
|  | } | 
|  |  | 
|  | extern void refresh_resv(GtkAction *action, gpointer user_data) | 
|  | { | 
|  | popup_info_t *popup_win = (popup_info_t *)user_data; | 
|  | xassert(popup_win); | 
|  | xassert(popup_win->spec_info); | 
|  | xassert(popup_win->spec_info->title); | 
|  | popup_win->force_refresh = 1; | 
|  | specific_info_resv(popup_win); | 
|  | } | 
|  |  | 
|  | extern int get_new_info_resv(reserve_info_msg_t **info_ptr, | 
|  | int force) | 
|  | { | 
|  | static reserve_info_msg_t *new_resv_ptr = NULL; | 
|  | int error_code = SLURM_NO_CHANGE_IN_DATA; | 
|  | time_t now = time(NULL); | 
|  | static time_t last; | 
|  | static bool changed = 0; | 
|  |  | 
|  | if (g_resv_info_ptr && !force | 
|  | && ((now - last) < working_sview_config.refresh_delay)) { | 
|  | if (*info_ptr != g_resv_info_ptr) | 
|  | error_code = SLURM_SUCCESS; | 
|  | *info_ptr = g_resv_info_ptr; | 
|  | if (changed) | 
|  | error_code = SLURM_SUCCESS; | 
|  | goto end_it; | 
|  | } | 
|  | last = now; | 
|  | if (g_resv_info_ptr) { | 
|  | error_code = slurm_load_reservations( | 
|  | g_resv_info_ptr->last_update, &new_resv_ptr); | 
|  | if (error_code == SLURM_SUCCESS) { | 
|  | slurm_free_reservation_info_msg(g_resv_info_ptr); | 
|  | changed = 1; | 
|  | } else if (errno == SLURM_NO_CHANGE_IN_DATA) { | 
|  | error_code = SLURM_NO_CHANGE_IN_DATA; | 
|  | new_resv_ptr = g_resv_info_ptr; | 
|  | changed = 0; | 
|  | } | 
|  | } else { | 
|  | new_resv_ptr = NULL; | 
|  | error_code = slurm_load_reservations((time_t) NULL, | 
|  | &new_resv_ptr); | 
|  | changed = 1; | 
|  | } | 
|  |  | 
|  | g_resv_info_ptr = new_resv_ptr; | 
|  |  | 
|  | if (g_resv_info_ptr && (*info_ptr != g_resv_info_ptr)) | 
|  | error_code = SLURM_SUCCESS; | 
|  |  | 
|  | *info_ptr = g_resv_info_ptr; | 
|  | end_it: | 
|  | return error_code; | 
|  | } | 
|  |  | 
|  | extern GtkListStore *create_model_resv(int type) | 
|  | { | 
|  | GtkListStore *model = NULL; | 
|  | GtkTreeIter iter; | 
|  |  | 
|  | last_model = NULL;	/* Reformat display */ | 
|  | switch(type) { | 
|  | case SORTID_ACTION: | 
|  | model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); | 
|  | gtk_list_store_append(model, &iter); | 
|  | gtk_list_store_set(model, &iter, | 
|  | 1, SORTID_ACTION, | 
|  | 0, "None", | 
|  | -1); | 
|  | gtk_list_store_append(model, &iter); | 
|  | gtk_list_store_set(model, &iter, | 
|  | 1, SORTID_ACTION, | 
|  | 0, "Remove Reservation", | 
|  | -1); | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return model; | 
|  | } | 
|  |  | 
|  | extern void admin_edit_resv(GtkCellRendererText *cell, | 
|  | const char *path_string, | 
|  | const char *new_text, | 
|  | gpointer data) | 
|  | { | 
|  | GtkTreeStore *treestore = NULL; | 
|  | GtkTreePath *path = NULL; | 
|  | GtkTreeIter iter; | 
|  | resv_desc_msg_t *resv_msg = NULL; | 
|  |  | 
|  | char *temp = NULL; | 
|  | char *old_text = NULL; | 
|  | const char *type = NULL; | 
|  |  | 
|  | int column; | 
|  |  | 
|  | if (!new_text || !xstrcmp(new_text, "")) | 
|  | goto no_input; | 
|  |  | 
|  | if (cluster_flags & CLUSTER_FLAG_FED) { | 
|  | display_fed_disabled_popup(type); | 
|  | goto no_input; | 
|  | } | 
|  |  | 
|  | column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column")); | 
|  | path = gtk_tree_path_new_from_string(path_string); | 
|  | treestore = GTK_TREE_STORE(data); | 
|  | gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path); | 
|  |  | 
|  | gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter, | 
|  | SORTID_NAME, &temp, | 
|  | column, &old_text, | 
|  | -1); | 
|  |  | 
|  | resv_msg = xmalloc(sizeof(resv_desc_msg_t)); | 
|  | slurm_init_resv_desc_msg(resv_msg); | 
|  | resv_msg->name = xstrdup(temp); | 
|  | g_free(temp); | 
|  |  | 
|  | type = _set_resv_msg(resv_msg, new_text, column); | 
|  | if (global_edit_error) | 
|  | goto print_error; | 
|  |  | 
|  | if (got_edit_signal) { | 
|  | temp = got_edit_signal; | 
|  | got_edit_signal = NULL; | 
|  | _admin_resv(GTK_TREE_MODEL(treestore), &iter, temp); | 
|  | xfree(temp); | 
|  | goto no_input; | 
|  | } | 
|  |  | 
|  | if (old_text && !xstrcmp(old_text, new_text)) { | 
|  | temp = g_strdup_printf("No change in value."); | 
|  | } else if (slurm_update_reservation(resv_msg) | 
|  | == SLURM_SUCCESS) { | 
|  | gtk_tree_store_set(treestore, &iter, column, new_text, -1); | 
|  | temp = g_strdup_printf("Reservation %s %s changed to %s", | 
|  | resv_msg->name, | 
|  | type, | 
|  | new_text); | 
|  | } else if (errno == ESLURM_DISABLED) { | 
|  | temp = g_strdup_printf( | 
|  | "Can only edit %s on reservations not yet started.", | 
|  | type); | 
|  | } else { | 
|  | print_error: | 
|  | temp = g_strdup_printf("Reservation %s %s can't be " | 
|  | "set to %s", | 
|  | resv_msg->name, | 
|  | type, | 
|  | new_text); | 
|  | } | 
|  |  | 
|  | display_edit_note(temp); | 
|  | g_free(temp); | 
|  |  | 
|  | no_input: | 
|  | slurm_free_resv_desc_msg(resv_msg); | 
|  |  | 
|  | gtk_tree_path_free(path); | 
|  | g_free(old_text); | 
|  | g_mutex_unlock(sview_mutex); | 
|  | } | 
|  |  | 
|  | extern void get_info_resv(GtkTable *table, display_data_t *display_data) | 
|  | { | 
|  | int error_code = SLURM_SUCCESS; | 
|  | list_t *info_list = NULL; | 
|  | static int view = -1; | 
|  | static reserve_info_msg_t *resv_info_ptr = NULL; | 
|  | char error_char[100]; | 
|  | GtkWidget *label = NULL; | 
|  | GtkTreeView *tree_view = NULL; | 
|  | static GtkWidget *display_widget = NULL; | 
|  | int j=0; | 
|  | list_itr_t *itr = NULL; | 
|  | sview_resv_info_t *sview_resv_info_ptr = NULL; | 
|  | reserve_info_t *resv_ptr = NULL; | 
|  | time_t now = time(NULL); | 
|  | GtkTreePath *path = NULL; | 
|  | static bool set_opts = false; | 
|  |  | 
|  | if (!set_opts) | 
|  | set_page_opts(RESV_PAGE, display_data_resv, | 
|  | SORTID_CNT, _initial_page_opts); | 
|  | set_opts = true; | 
|  |  | 
|  | /* reset */ | 
|  | if (!table && !display_data) { | 
|  | if (display_widget) | 
|  | gtk_widget_destroy(display_widget); | 
|  | display_widget = NULL; | 
|  | resv_info_ptr = NULL; | 
|  | goto reset_curs; | 
|  | } | 
|  |  | 
|  | if (display_data) | 
|  | local_display_data = display_data; | 
|  | if (!table) { | 
|  | display_data_resv->set_menu = local_display_data->set_menu; | 
|  | goto reset_curs; | 
|  | } | 
|  |  | 
|  | if (cluster_flags & CLUSTER_FLAG_FED) { | 
|  | view = ERROR_VIEW; | 
|  | if (display_widget) | 
|  | gtk_widget_destroy(display_widget); | 
|  | label = gtk_label_new("Not available in a federated view"); | 
|  | gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); | 
|  | gtk_widget_show(label); | 
|  | display_widget = g_object_ref(label); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | if (display_widget && toggled) { | 
|  | gtk_widget_destroy(display_widget); | 
|  | display_widget = NULL; | 
|  | goto display_it; | 
|  | } | 
|  |  | 
|  | error_code = get_new_info_resv(&resv_info_ptr, force_refresh); | 
|  | if (error_code == SLURM_NO_CHANGE_IN_DATA) { | 
|  | } else if (error_code != SLURM_SUCCESS) { | 
|  | if (view == ERROR_VIEW) | 
|  | goto end_it; | 
|  | if (display_widget) | 
|  | gtk_widget_destroy(display_widget); | 
|  | view = ERROR_VIEW; | 
|  | sprintf(error_char, "slurm_load_reservations: %s", | 
|  | slurm_strerror(errno)); | 
|  | label = gtk_label_new(error_char); | 
|  | gtk_table_attach_defaults(table, label, 0, 1, 0, 1); | 
|  | gtk_widget_show(label); | 
|  | display_widget = g_object_ref(GTK_WIDGET(label)); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | display_it: | 
|  | info_list = _create_resv_info_list(resv_info_ptr); | 
|  | if (!info_list) | 
|  | goto reset_curs; | 
|  | /* set up the grid */ | 
|  | if (display_widget && GTK_IS_TREE_VIEW(display_widget) | 
|  | && gtk_tree_selection_count_selected_rows( | 
|  | gtk_tree_view_get_selection( | 
|  | GTK_TREE_VIEW(display_widget)))) { | 
|  | GtkTreeViewColumn *focus_column = NULL; | 
|  | /* highlight the correct nodes from the last selection */ | 
|  | gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget), | 
|  | &path, &focus_column); | 
|  | } | 
|  | if (!path) { | 
|  | itr = list_iterator_create(info_list); | 
|  | while ((sview_resv_info_ptr = list_next(itr))) { | 
|  | resv_ptr = sview_resv_info_ptr->resv_ptr; | 
|  | if ((resv_ptr->start_time > now) || | 
|  | (resv_ptr->end_time   < now)) | 
|  | continue;/* only map current reservations */ | 
|  | j=0; | 
|  | while (resv_ptr->node_inx[j] >= 0) { | 
|  | change_grid_color(grid_button_list, | 
|  | resv_ptr->node_inx[j], | 
|  | resv_ptr->node_inx[j+1], | 
|  | sview_resv_info_ptr-> | 
|  | color_inx, | 
|  | true, 0); | 
|  | j += 2; | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | change_grid_color(grid_button_list, -1, -1, | 
|  | MAKE_WHITE, true, 0); | 
|  | } else { | 
|  | highlight_grid(GTK_TREE_VIEW(display_widget), | 
|  | SORTID_NODE_INX, SORTID_COLOR_INX, | 
|  | grid_button_list); | 
|  | gtk_tree_path_free(path); | 
|  | } | 
|  |  | 
|  | if (view == ERROR_VIEW && display_widget) { | 
|  | gtk_widget_destroy(display_widget); | 
|  | display_widget = NULL; | 
|  | } | 
|  | if (!display_widget) { | 
|  | tree_view = create_treeview(local_display_data, | 
|  | &grid_button_list); | 
|  | gtk_tree_selection_set_mode( | 
|  | gtk_tree_view_get_selection(tree_view), | 
|  | GTK_SELECTION_MULTIPLE); | 
|  | display_widget = g_object_ref(GTK_WIDGET(tree_view)); | 
|  | gtk_table_attach_defaults(table, | 
|  | GTK_WIDGET(tree_view), | 
|  | 0, 1, 0, 1); | 
|  | /* since this function sets the model of the tree_view | 
|  | to the treestore we don't really care about | 
|  | the return value */ | 
|  | create_treestore(tree_view, display_data_resv, | 
|  | SORTID_CNT, SORTID_TIME_START, SORTID_COLOR); | 
|  |  | 
|  | set_column_width_fixed(tree_view, SORTID_NODELIST, 100); | 
|  | } | 
|  |  | 
|  | view = INFO_VIEW; | 
|  | _update_info_resv(info_list, GTK_TREE_VIEW(display_widget)); | 
|  | end_it: | 
|  | toggled = false; | 
|  | force_refresh = false; | 
|  | reset_curs: | 
|  | if (main_window && main_window->window) | 
|  | gdk_window_set_cursor(main_window->window, NULL); | 
|  | return; | 
|  | } | 
|  |  | 
|  | extern void specific_info_resv(popup_info_t *popup_win) | 
|  | { | 
|  | int resv_error_code = SLURM_SUCCESS; | 
|  | static reserve_info_msg_t *resv_info_ptr = NULL; | 
|  | static reserve_info_t *resv_ptr = NULL; | 
|  | specific_info_t *spec_info = popup_win->spec_info; | 
|  | sview_search_info_t *search_info = spec_info->search_info; | 
|  | char error_char[100]; | 
|  | GtkWidget *label = NULL; | 
|  | GtkTreeView *tree_view = NULL; | 
|  | list_t *resv_list = NULL; | 
|  | list_t *send_resv_list = NULL; | 
|  | sview_resv_info_t *sview_resv_info_ptr = NULL; | 
|  | int j=0; | 
|  | hostset_t *hostset = NULL; | 
|  | list_itr_t *itr = NULL; | 
|  |  | 
|  | if (!spec_info->display_widget) { | 
|  | setup_popup_info(popup_win, display_data_resv, SORTID_CNT); | 
|  | } | 
|  |  | 
|  | if (spec_info->display_widget && popup_win->toggled) { | 
|  | gtk_widget_destroy(spec_info->display_widget); | 
|  | spec_info->display_widget = NULL; | 
|  | goto display_it; | 
|  | } | 
|  |  | 
|  | if ((resv_error_code = | 
|  | get_new_info_resv(&resv_info_ptr, popup_win->force_refresh)) | 
|  | == SLURM_NO_CHANGE_IN_DATA) { | 
|  | if (!spec_info->display_widget || spec_info->view == ERROR_VIEW) | 
|  | goto display_it; | 
|  | } else if (resv_error_code != SLURM_SUCCESS) { | 
|  | if (spec_info->view == ERROR_VIEW) | 
|  | goto end_it; | 
|  | spec_info->view = ERROR_VIEW; | 
|  | if (spec_info->display_widget) | 
|  | gtk_widget_destroy(spec_info->display_widget); | 
|  | sprintf(error_char, "get_new_info_resv: %s", | 
|  | slurm_strerror(errno)); | 
|  | label = gtk_label_new(error_char); | 
|  | gtk_table_attach_defaults(popup_win->table, | 
|  | label, | 
|  | 0, 1, 0, 1); | 
|  | gtk_widget_show(label); | 
|  | spec_info->display_widget = g_object_ref(label); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | display_it: | 
|  |  | 
|  | resv_list = _create_resv_info_list(resv_info_ptr); | 
|  |  | 
|  | if (!resv_list) | 
|  | return; | 
|  |  | 
|  | if (spec_info->view == ERROR_VIEW && spec_info->display_widget) { | 
|  | gtk_widget_destroy(spec_info->display_widget); | 
|  | spec_info->display_widget = NULL; | 
|  | } | 
|  | if (spec_info->type != INFO_PAGE && !spec_info->display_widget) { | 
|  | tree_view = create_treeview(local_display_data, | 
|  | &popup_win->grid_button_list); | 
|  | gtk_tree_selection_set_mode( | 
|  | gtk_tree_view_get_selection(tree_view), | 
|  | GTK_SELECTION_MULTIPLE); | 
|  | spec_info->display_widget = | 
|  | g_object_ref(GTK_WIDGET(tree_view)); | 
|  | gtk_table_attach_defaults(popup_win->table, | 
|  | GTK_WIDGET(tree_view), | 
|  | 0, 1, 0, 1); | 
|  | /* since this function sets the model of the tree_view | 
|  | to the treestore we don't really care about | 
|  | the return value */ | 
|  | create_treestore(tree_view, popup_win->display_data, | 
|  | SORTID_CNT, SORTID_TIME_START, SORTID_COLOR); | 
|  | } | 
|  |  | 
|  | setup_popup_grid_list(popup_win); | 
|  |  | 
|  | spec_info->view = INFO_VIEW; | 
|  | if (spec_info->type == INFO_PAGE) { | 
|  | _display_info_resv(resv_list, popup_win); | 
|  | goto end_it; | 
|  | } | 
|  |  | 
|  | /* just linking to another list, don't free the inside, just | 
|  | the list */ | 
|  | send_resv_list = list_create(NULL); | 
|  | itr = list_iterator_create(resv_list); | 
|  | while ((sview_resv_info_ptr = list_next(itr))) { | 
|  | resv_ptr = sview_resv_info_ptr->resv_ptr; | 
|  | switch(spec_info->type) { | 
|  | case PART_PAGE: | 
|  | case NODE_PAGE: | 
|  | if (!resv_ptr->node_list) | 
|  | continue; | 
|  |  | 
|  | if (!(hostset = hostset_create( | 
|  | search_info->gchar_data))) | 
|  | continue; | 
|  | if (!hostset_intersects(hostset, resv_ptr->node_list)) { | 
|  | hostset_destroy(hostset); | 
|  | continue; | 
|  | } | 
|  | hostset_destroy(hostset); | 
|  | break; | 
|  | case JOB_PAGE: | 
|  | if (xstrcmp(resv_ptr->name, search_info->gchar_data)) | 
|  | continue; | 
|  | break; | 
|  | case RESV_PAGE: | 
|  | switch(search_info->search_type) { | 
|  | case SEARCH_RESERVATION_NAME: | 
|  | if (!search_info->gchar_data) | 
|  | continue; | 
|  |  | 
|  | if (xstrcmp(resv_ptr->name, | 
|  | search_info->gchar_data)) | 
|  | continue; | 
|  | break; | 
|  | default: | 
|  | continue; | 
|  | } | 
|  | break; | 
|  | default: | 
|  | g_print("Unknown type %d\n", spec_info->type); | 
|  | continue; | 
|  | } | 
|  | list_push(send_resv_list, sview_resv_info_ptr); | 
|  | j=0; | 
|  | while (resv_ptr->node_inx[j] >= 0) { | 
|  | change_grid_color( | 
|  | popup_win->grid_button_list, | 
|  | resv_ptr->node_inx[j], | 
|  | resv_ptr->node_inx[j+1], | 
|  | sview_resv_info_ptr->color_inx, | 
|  | true, 0); | 
|  | j += 2; | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  | post_setup_popup_grid_list(popup_win); | 
|  |  | 
|  | _update_info_resv(send_resv_list, | 
|  | GTK_TREE_VIEW(spec_info->display_widget)); | 
|  | FREE_NULL_LIST(send_resv_list); | 
|  | end_it: | 
|  | popup_win->toggled = 0; | 
|  | popup_win->force_refresh = 0; | 
|  |  | 
|  | return; | 
|  | } | 
|  |  | 
|  | extern void set_menus_resv(void *arg, void *arg2, GtkTreePath *path, int type) | 
|  | { | 
|  | GtkTreeView *tree_view = (GtkTreeView *)arg; | 
|  | popup_info_t *popup_win = (popup_info_t *)arg; | 
|  | GtkMenu *menu = (GtkMenu *)arg2; | 
|  | list_t *button_list = arg2; | 
|  |  | 
|  | switch(type) { | 
|  | case TAB_CLICKED: | 
|  | make_fields_menu(NULL, menu, display_data_resv, SORTID_CNT); | 
|  | break; | 
|  | case ROW_CLICKED: | 
|  | make_options_menu(tree_view, path, menu, options_data_resv); | 
|  | break; | 
|  | case ROW_LEFT_CLICKED: | 
|  | highlight_grid(tree_view, SORTID_NODE_INX, | 
|  | SORTID_COLOR_INX, button_list); | 
|  | break; | 
|  | case FULL_CLICKED: | 
|  | { | 
|  | GtkTreeModel *model = gtk_tree_view_get_model(tree_view); | 
|  | GtkTreeIter iter; | 
|  | if (!gtk_tree_model_get_iter(model, &iter, path)) { | 
|  | g_error("error getting iter from model\n"); | 
|  | break; | 
|  | } | 
|  |  | 
|  | popup_all_resv(model, &iter, INFO_PAGE); | 
|  |  | 
|  | break; | 
|  | } | 
|  | case POPUP_CLICKED: | 
|  | make_fields_menu(popup_win, menu, | 
|  | popup_win->display_data, SORTID_CNT); | 
|  | break; | 
|  | default: | 
|  | g_error("UNKNOWN type %d given to set_fields\n", type); | 
|  | } | 
|  | } | 
|  |  | 
|  | extern void popup_all_resv(GtkTreeModel *model, GtkTreeIter *iter, int id) | 
|  | { | 
|  | char *name = NULL; | 
|  | char title[100] = {0}; | 
|  | list_itr_t *itr = NULL; | 
|  | popup_info_t *popup_win = NULL; | 
|  | GError *error = NULL; | 
|  |  | 
|  | gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1); | 
|  |  | 
|  | switch(id) { | 
|  | case PART_PAGE: | 
|  | snprintf(title, 100, "Partition(s) with reservation %s", name); | 
|  | break; | 
|  | case JOB_PAGE: | 
|  | snprintf(title, 100, "Job(s) in reservation %s", name); | 
|  | break; | 
|  | case NODE_PAGE: | 
|  | snprintf(title, 100, "Node(s) in reservation %s ", name); | 
|  | break; | 
|  | case SUBMIT_PAGE: | 
|  | snprintf(title, 100, "Submit job in reservation %s", name); | 
|  | break; | 
|  | case INFO_PAGE: | 
|  | snprintf(title, 100, "Full info for reservation %s", name); | 
|  | break; | 
|  | default: | 
|  | g_print("resv got %d\n", id); | 
|  | } | 
|  |  | 
|  | itr = list_iterator_create(popup_list); | 
|  | while ((popup_win = list_next(itr))) { | 
|  | if (popup_win->spec_info) | 
|  | if (!xstrcmp(popup_win->spec_info->title, title)) { | 
|  | break; | 
|  | } | 
|  | } | 
|  | list_iterator_destroy(itr); | 
|  |  | 
|  | if (!popup_win) { | 
|  | if (id == INFO_PAGE) | 
|  | popup_win = create_popup_info(id, RESV_PAGE, title); | 
|  | else | 
|  | popup_win = create_popup_info(RESV_PAGE, id, title); | 
|  | } else { | 
|  | g_free(name); | 
|  | gtk_window_present(GTK_WINDOW(popup_win->popup)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | /* Pass the model and the structs from the iter so we can always get | 
|  | the current node_inx. | 
|  | */ | 
|  | popup_win->model = model; | 
|  | popup_win->iter = *iter; | 
|  | popup_win->node_inx_id = SORTID_NODE_INX; | 
|  |  | 
|  | switch(id) { | 
|  | case JOB_PAGE: | 
|  | case INFO_PAGE: | 
|  | popup_win->spec_info->search_info->gchar_data = name; | 
|  | //specific_info_job(popup_win); | 
|  | break; | 
|  | case NODE_PAGE: | 
|  | case PART_PAGE: | 
|  | g_free(name); | 
|  | gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1); | 
|  | popup_win->spec_info->search_info->gchar_data = name; | 
|  | popup_win->spec_info->search_info->search_type = | 
|  | SEARCH_NODE_NAME; | 
|  | //specific_info_node(popup_win); | 
|  | break; | 
|  | case SUBMIT_PAGE: | 
|  | break; | 
|  | default: | 
|  | g_print("resv got unknown type %d\n", id); | 
|  | } | 
|  | if (!sview_thread_new((gpointer)popup_thr, popup_win, &error)) { | 
|  | g_printerr ("Failed to create resv popup thread: %s\n", | 
|  | error->message); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | static void _process_each_resv(GtkTreeModel *model, GtkTreePath *path, | 
|  | GtkTreeIter*iter, gpointer userdata) | 
|  | { | 
|  | char *type = userdata; | 
|  | if (_DEBUG) | 
|  | g_print("process_each_resv: global_multi_error = %d\n", | 
|  | global_multi_error); | 
|  |  | 
|  | if (!global_multi_error) { | 
|  | _admin_resv(model, iter, type); | 
|  | } | 
|  | } | 
|  |  | 
|  | extern void select_admin_resv(GtkTreeModel *model, GtkTreeIter *iter, | 
|  | display_data_t *display_data, | 
|  | GtkTreeView *treeview) | 
|  | { | 
|  | select_admin_common(model, iter, display_data, treeview, | 
|  | SORTID_NODELIST, _process_each_resv); | 
|  | } | 
|  |  | 
|  | static void _admin_resv(GtkTreeModel *model, GtkTreeIter *iter, char *type) | 
|  | { | 
|  | resv_desc_msg_t *resv_msg = NULL; | 
|  | reservation_name_msg_t resv_name_msg; | 
|  | char *resvid = NULL; | 
|  | char tmp_char[100]; | 
|  | char *temp = NULL; | 
|  | int edit_type = 0; | 
|  | int response = 0; | 
|  | GtkWidget *label = NULL; | 
|  | GtkWidget *entry = NULL; | 
|  | GtkWidget *popup = NULL; | 
|  |  | 
|  | if (cluster_flags & CLUSTER_FLAG_FED) { | 
|  | display_fed_disabled_popup(type); | 
|  | global_entry_changed = 0; | 
|  | return; | 
|  | } | 
|  |  | 
|  | popup = gtk_dialog_new_with_buttons( | 
|  | type, | 
|  | GTK_WINDOW(main_window), | 
|  | GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, | 
|  | NULL); | 
|  | gtk_window_set_type_hint(GTK_WINDOW(popup), | 
|  | GDK_WINDOW_TYPE_HINT_NORMAL); | 
|  |  | 
|  | gtk_window_set_transient_for(GTK_WINDOW(popup), NULL); | 
|  |  | 
|  | gtk_tree_model_get(model, iter, SORTID_NAME, &resvid, -1); | 
|  |  | 
|  | resv_msg = xmalloc(sizeof(resv_desc_msg_t)); | 
|  | slurm_init_resv_desc_msg(resv_msg); | 
|  | memset(&resv_name_msg, 0, sizeof(reservation_name_msg_t)); | 
|  |  | 
|  | resv_msg->name = xstrdup(resvid); | 
|  |  | 
|  | if (!xstrcasecmp("Remove Reservation", type)) { | 
|  | resv_name_msg.name = resvid; | 
|  |  | 
|  | label = gtk_dialog_add_button(GTK_DIALOG(popup), | 
|  | GTK_STOCK_YES, GTK_RESPONSE_OK); | 
|  | gtk_window_set_default(GTK_WINDOW(popup), label); | 
|  | gtk_dialog_add_button(GTK_DIALOG(popup), | 
|  | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); | 
|  |  | 
|  | snprintf(tmp_char, sizeof(tmp_char), | 
|  | "Are you sure you want to remove " | 
|  | "reservation %s?", | 
|  | resvid); | 
|  | label = gtk_label_new(tmp_char); | 
|  | edit_type = EDIT_REMOVE; | 
|  | } else { | 
|  | label = gtk_dialog_add_button(GTK_DIALOG(popup), | 
|  | GTK_STOCK_OK, GTK_RESPONSE_OK); | 
|  | gtk_window_set_default(GTK_WINDOW(popup), label); | 
|  | gtk_dialog_add_button(GTK_DIALOG(popup), | 
|  | GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); | 
|  |  | 
|  | gtk_window_set_default_size(GTK_WINDOW(popup), 200, 400); | 
|  | snprintf(tmp_char, sizeof(tmp_char), | 
|  | "Editing reservation %s think before you type", | 
|  | resvid); | 
|  | label = gtk_label_new(tmp_char); | 
|  | edit_type = EDIT_EDIT; | 
|  | entry = _admin_full_edit_resv(resv_msg, model, iter); | 
|  | } | 
|  |  | 
|  | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox), | 
|  | label, false, false, 0); | 
|  | if (entry) | 
|  | gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox), | 
|  | entry, true, true, 0); | 
|  | gtk_widget_show_all(popup); | 
|  | response = gtk_dialog_run (GTK_DIALOG(popup)); | 
|  |  | 
|  | if (response == GTK_RESPONSE_OK) { | 
|  | switch(edit_type) { | 
|  | case EDIT_REMOVE: | 
|  | if (slurm_delete_reservation(&resv_name_msg) | 
|  | == SLURM_SUCCESS) { | 
|  | temp = g_strdup_printf( | 
|  | "Reservation %s removed successfully", | 
|  | resvid); | 
|  | } else { | 
|  | temp = g_strdup_printf( | 
|  | "Problem removing reservation %s.", | 
|  | resvid); | 
|  | } | 
|  | display_edit_note(temp); | 
|  | g_free(temp); | 
|  | break; | 
|  | case EDIT_EDIT: | 
|  | if (got_edit_signal) | 
|  | goto end_it; | 
|  |  | 
|  | if (global_edit_error) { | 
|  | temp = g_strdup_printf( | 
|  | "Something was wrong with the " | 
|  | "values you wanted to change: %s", | 
|  | global_edit_error_msg ? | 
|  | global_edit_error_msg : "unknown"); | 
|  | if (global_edit_error_msg) | 
|  | g_free(global_edit_error_msg); | 
|  | } else if (!global_send_update_msg) { | 
|  | temp = g_strdup_printf("No change detected."); | 
|  | } else if (slurm_update_reservation(resv_msg) | 
|  | == SLURM_SUCCESS) { | 
|  | temp = g_strdup_printf( | 
|  | "Reservation %s updated successfully", | 
|  | resvid); | 
|  | } else { | 
|  | temp = g_strdup_printf( | 
|  | "Problem updating reservation %s.", | 
|  | resvid); | 
|  | } | 
|  | display_edit_note(temp); | 
|  | g_free(temp); | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | } | 
|  | end_it: | 
|  |  | 
|  | g_free(resvid); | 
|  | global_entry_changed = 0; | 
|  | slurm_free_resv_desc_msg(resv_msg); | 
|  | gtk_widget_destroy(popup); | 
|  | if (got_edit_signal) { | 
|  | type = got_edit_signal; | 
|  | got_edit_signal = NULL; | 
|  | _admin_resv(model, iter, type); | 
|  | xfree(type); | 
|  | } | 
|  | return; | 
|  | } | 
|  |  | 
|  | extern void cluster_change_resv(void) | 
|  | { | 
|  | get_info_resv(NULL, NULL); | 
|  | } |