blob: 1d180fb6c40ee9f07e28a41efa51b6fda9098be4 [file] [log] [blame]
/*****************************************************************************\
* bb_info.c - Functions related to Burst Buffer display mode of sview.
*****************************************************************************
* Copyright (C) SchedMD LLC.
* Written by Nathan Yee <nyee32@shedmd.com>
*
* 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/strlcpy.h"
#define _DEBUG 0
/* Collection of data for printing reports. Like data is combined here */
typedef struct {
char * bb_name;
burst_buffer_resv_t *bb_ptr;
int color_inx;
GtkTreeIter iter_ptr;
bool iter_set;
char * plugin;
int pos;
} sview_bb_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_ACCOUNT,
SORTID_COLOR,
SORTID_COLOR_INX,
SORTID_CREATE_TIME,
SORTID_NAME,
SORTID_PARTITION,
SORTID_PLUGIN,
SORTID_POOL,
SORTID_QOS,
SORTID_SIZE,
SORTID_STATE,
SORTID_UPDATED,
SORTID_USERID,
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/JobID,Pool,Size,State,StateTime,UserID";
static display_data_t display_data_bb[] = {
{G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_PLUGIN, "Plugin", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_NAME, "Name/JobID", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_COLOR, NULL, true, EDIT_COLOR,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_INT, SORTID_COLOR_INX, NULL, false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_ACCOUNT, "Account", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_CREATE_TIME, "CreateTime", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_PARTITION, "Partition", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_POOL, "Pool", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_QOS, "QOS", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_SIZE, "Size", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_STATE, "State", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_INT, SORTID_UPDATED, NULL, false, EDIT_NONE, refresh_bb,
create_model_bb, admin_edit_bb},
{G_TYPE_STRING, SORTID_USERID, "UserID", false, EDIT_NONE,
refresh_bb, create_model_bb, admin_edit_bb},
{G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
};
/*Burst buffer options list*/
static display_data_t options_data_bb[] = {
{G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE},
{G_TYPE_STRING, INFO_PAGE, "Full Info", true, BB_PAGE},
{G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
};
static display_data_t *local_display_data = NULL;
//Variable for Admin edit if needed
/* static char *got_edit_signal = NULL; */
static GtkTreeModel *last_model = NULL;
static void _get_size_str(char *buf, size_t buf_size, uint64_t num);
/*Functions for admin edit*/
/* static void _admin_bb(GtkTreeModel *model, GtkTreeIter *iter, char *type); */
/* static void _process_each_bb(GtkTreeModel *model, GtkTreePath *path, */
/* GtkTreeIter*iter, gpointer userdata); */
/* static void _set_active_combo_bb(GtkComboBox *combo, */
/* GtkTreeModel *model, GtkTreeIter *iter, */
/* int type) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
// Function for admin edit
//don't free this char
/* static const char *_set_bb_msg(burst_buffer_info_msg_t *bb_msg, */
/* const char *new_text, */
/* int column) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
/* Free the burst buffer information */
static void _bb_info_free(sview_bb_info_t *sview_bb_info)
{
if (sview_bb_info) {
xfree(sview_bb_info->bb_name);
xfree(sview_bb_info->plugin);
}
}
/* Free the Burst Buffer information list */
static void _bb_info_list_del(void *object)
{
sview_bb_info_t *sview_bb_info = (sview_bb_info_t *)object;
if (sview_bb_info) {
_bb_info_free(sview_bb_info);
xfree(sview_bb_info);
}
}
/* static void _admin_edit_combo_box_bb(GtkComboBox *combo, */
/* resv_desc_msg_t *resv_msg) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
/* static gboolean _admin_focus_out_bb(GtkEntry *entry, */
/* GdkEventFocus *event, */
/* resv_desc_msg_t *resv_msg) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
/* static GtkWidget *_admin_full_edit_bb(resv_desc_msg_t *resv_msg, */
/* GtkTreeModel *model, GtkTreeIter *iter) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
/* Function creates the record menu when you double click on a record */
static void _layout_bb_record(GtkTreeView *treeview,
sview_bb_info_t *sview_bb_info, int update)
{
GtkTreeIter iter;
char time_buf[256], tmp_user_id[60], tmp_size[20];
char bb_name_id[32];
char *tmp_state, *tmp_user_name;
burst_buffer_resv_t *bb_ptr = sview_bb_info->bb_ptr;
GtkTreeStore *treestore;
treestore = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
if (bb_ptr->name) {
strlcpy(bb_name_id, bb_ptr->name, sizeof(bb_name_id));
} else if (bb_ptr->array_task_id == NO_VAL) {
convert_num_unit(bb_ptr->job_id, bb_name_id, sizeof(bb_name_id),
UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
} else {
snprintf(bb_name_id, sizeof(bb_name_id),
"%u_%u(%u)",
bb_ptr->array_job_id,
bb_ptr->array_task_id,
bb_ptr->job_id);
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_NAME),
bb_name_id);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_PLUGIN),
sview_bb_info->plugin);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_ACCOUNT),
bb_ptr->account);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_PARTITION),
bb_ptr->partition);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_POOL),
bb_ptr->pool);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_QOS),
bb_ptr->qos);
tmp_state = bb_state_string(bb_ptr->state);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_STATE),
tmp_state);
_get_size_str(tmp_size, sizeof(tmp_size), bb_ptr->size);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_SIZE),
tmp_size);
if (bb_ptr->create_time) {
slurm_make_time_str((time_t *)&bb_ptr->create_time, time_buf,
sizeof(time_buf));
} else {
time_t now = time(NULL);
slurm_make_time_str(&now, time_buf, sizeof(time_buf));
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_CREATE_TIME),
time_buf);
tmp_user_name = uid_to_string(bb_ptr->user_id);
snprintf(tmp_user_id, sizeof(tmp_user_id), "%s(%u)", tmp_user_name,
bb_ptr->user_id);
xfree(tmp_user_name);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_bb,
SORTID_USERID),
tmp_user_id);
}
/* Reformat a numeric value with an appropriate suffix.
* The input units are GB */
static void _get_size_str(char *buf, size_t buf_size, uint64_t num)
{
uint64_t tmp64;
if ((num == NO_VAL64) || (num == INFINITE64)) {
snprintf(buf, buf_size, "INFINITE");
} else if (num == 0) {
snprintf(buf, buf_size, "0GB");
} else if ((num % ((uint64_t) 1024 * 1024 * 1024 * 1024 * 1024)) == 0) {
tmp64 = num / ((uint64_t) 1024 * 1024 * 1024 * 1024 * 1024);
snprintf(buf, buf_size, "%"PRIu64"PB", tmp64);
} else if ((num % ((uint64_t) 1024 * 1024 * 1024 * 1024)) == 0) {
tmp64 = num / ((uint64_t) 1024 * 1024 * 1024 * 1024);
snprintf(buf, buf_size, "%"PRIu64"TB", tmp64);
} else if ((num % ((uint64_t) 1024 * 1024 * 1024)) == 0) {
tmp64 = num / ((uint64_t) 1024 * 1024 * 1024);
snprintf(buf, buf_size, "%"PRIu64"GB", tmp64);
} else if ((num % ((uint64_t) 1024 * 1024)) == 0) {
tmp64 = num / ((uint64_t) 1024 * 1024);
snprintf(buf, buf_size, "%"PRIu64"MB", tmp64);
} else if ((num % 1024) == 0) {
tmp64 = num / 1024;
snprintf(buf, buf_size, "%"PRIu64"KB", tmp64);
} else {
tmp64 = num;
snprintf(buf, buf_size, "%"PRIu64"B", tmp64);
}
}
/* updates the burst buffer record on sview */
static void _update_bb_record(sview_bb_info_t *sview_bb_info_ptr,
GtkTreeStore *treestore)
{
char tmp_create_time[256];
char tmp_size[20], tmp_user_id[60], bb_name_id[32];
char *tmp_state, *tmp_user_name;
burst_buffer_resv_t *bb_ptr = sview_bb_info_ptr->bb_ptr;
if (bb_ptr->name) {
strlcpy(bb_name_id, bb_ptr->name, sizeof(bb_name_id));
} else if (bb_ptr->array_task_id == NO_VAL) {
convert_num_unit(bb_ptr->job_id, bb_name_id, sizeof(bb_name_id),
UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
} else {
snprintf(bb_name_id, sizeof(bb_name_id),
"%u_%u(%u)",
bb_ptr->array_job_id,
bb_ptr->array_task_id,
bb_ptr->job_id);
}
if (bb_ptr->create_time) {
slurm_make_time_str((time_t *)&bb_ptr->create_time,
tmp_create_time, sizeof(tmp_create_time));
} else {
time_t now = time(NULL);
slurm_make_time_str(&now, tmp_create_time,
sizeof(tmp_create_time));
}
_get_size_str(tmp_size, sizeof(tmp_size), bb_ptr->size);
tmp_state = bb_state_string(bb_ptr->state);
tmp_user_name = uid_to_string(bb_ptr->user_id);
snprintf(tmp_user_id, sizeof(tmp_user_id), "%s(%u)", tmp_user_name,
bb_ptr->user_id);
xfree(tmp_user_name);
/* Combining these records provides a slight performance improvement */
gtk_tree_store_set(treestore, &sview_bb_info_ptr->iter_ptr,
SORTID_COLOR,
sview_colors[sview_bb_info_ptr->color_inx],
SORTID_COLOR_INX, sview_bb_info_ptr->color_inx,
SORTID_PLUGIN, sview_bb_info_ptr->plugin,
SORTID_ACCOUNT, bb_ptr->account,
SORTID_CREATE_TIME, tmp_create_time,
SORTID_NAME, bb_name_id,
SORTID_PARTITION, bb_ptr->partition,
SORTID_POOL, bb_ptr->pool,
SORTID_QOS, bb_ptr->qos,
SORTID_SIZE, tmp_size,
SORTID_STATE, tmp_state,
SORTID_UPDATED, 1,
SORTID_USERID, tmp_user_id,
-1);
return;
}
/* Append the give Burst Record to the list */
static void _append_bb_record(sview_bb_info_t *sview_bb_info_ptr,
GtkTreeStore *treestore)
{
gtk_tree_store_append(treestore, &sview_bb_info_ptr->iter_ptr, NULL);
gtk_tree_store_set(treestore, &sview_bb_info_ptr->iter_ptr,
SORTID_POS, sview_bb_info_ptr->pos, -1);
_update_bb_record(sview_bb_info_ptr, treestore);
}
/* Update the Burst Buffer information record */
static void _update_info_bb(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_bb_info_t *sview_bb_info = NULL;
set_for_update(model, SORTID_UPDATED);
itr = list_iterator_create(info_list);
while ((sview_bb_info = list_next(itr))) {
/* This means the tree_store changed (added new column
* or something). */
if (last_model != model)
sview_bb_info->iter_set = false;
if (sview_bb_info->iter_set) {
gtk_tree_model_get(model, &sview_bb_info->iter_ptr,
SORTID_NAME, &name, -1);
if (xstrcmp(name, sview_bb_info->bb_name)) {
/* Bad pointer */
sview_bb_info->iter_set = false;
//g_print("bad resv iter pointer\n");
}
g_free(name);
}
if (sview_bb_info->iter_set) {
_update_bb_record(sview_bb_info,
GTK_TREE_STORE(model));
} else {
_append_bb_record(sview_bb_info,
GTK_TREE_STORE(model));
sview_bb_info->iter_set = true;
}
}
list_iterator_destroy(itr);
/* remove all old bb */
remove_old(model, SORTID_UPDATED);
last_model = model;
}
static list_t *_create_bb_info_list(burst_buffer_info_msg_t *bb_info_ptr)
{
static list_t *info_list = NULL;
list_t *last_list = NULL;
list_itr_t *last_list_itr = NULL;
int i, j, pos = 0;
static burst_buffer_info_msg_t *last_bb_info_ptr = NULL;
sview_bb_info_t *sview_bb_info_ptr = NULL;
burst_buffer_info_t *bb_ptr;
burst_buffer_resv_t *bb_resv_ptr = NULL;
char bb_name_id[32] = "";
if (info_list && (bb_info_ptr == last_bb_info_ptr))
return info_list;
last_bb_info_ptr = bb_info_ptr;
if (info_list)
last_list = info_list;
info_list = list_create(_bb_info_list_del);
for (i = 0, bb_ptr = bb_info_ptr->burst_buffer_array;
i < bb_info_ptr->record_count; i++, bb_ptr++) {
for (j = 0, bb_resv_ptr = bb_ptr->burst_buffer_resv_ptr;
j < bb_ptr->buffer_count; j++, bb_resv_ptr++) {
/* Find any existing record for this burst buffer */
if (last_list) {
last_list_itr = list_iterator_create(last_list);
while ((sview_bb_info_ptr =
list_next(last_list_itr))) {
if (bb_resv_ptr->job_id &&
(bb_resv_ptr->job_id !=
sview_bb_info_ptr->bb_ptr->job_id))
continue;
if (bb_resv_ptr->name &&
xstrcmp(sview_bb_info_ptr->bb_name,
bb_resv_ptr->name))
continue;
if (xstrcmp(sview_bb_info_ptr->plugin,
bb_ptr->name))
continue;
list_remove(last_list_itr);
_bb_info_free(sview_bb_info_ptr);
break;
}
list_iterator_destroy(last_list_itr);
} else {
sview_bb_info_ptr = NULL;
}
if (bb_resv_ptr->name) {
strlcpy(bb_name_id, bb_resv_ptr->name,
sizeof(bb_name_id));
} else if (bb_resv_ptr->array_task_id == NO_VAL) {
convert_num_unit(bb_resv_ptr->job_id,
bb_name_id,
sizeof(bb_name_id),
UNIT_NONE, NO_VAL,
working_sview_config.
convert_flags);
} else {
snprintf(bb_name_id, sizeof(bb_name_id),
"%u_%u(%u)",
bb_resv_ptr->array_job_id,
bb_resv_ptr->array_task_id,
bb_resv_ptr->job_id);
}
if (!sview_bb_info_ptr) { /* Need new record */
sview_bb_info_ptr =
xmalloc(sizeof(sview_bb_info_t));
}
sview_bb_info_ptr->bb_ptr = bb_resv_ptr;
sview_bb_info_ptr->bb_name = xstrdup(bb_name_id);
bb_name_id[0] = '\0'; /* Clear bb_name_id */
sview_bb_info_ptr->color_inx = pos % sview_colors_cnt;
sview_bb_info_ptr->plugin = xstrdup(bb_ptr->name);
sview_bb_info_ptr->pos = pos++;
list_append(info_list, sview_bb_info_ptr);
}
}
FREE_NULL_LIST(last_list);
return info_list;
}
static void _display_info_bb(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;
burst_buffer_resv_t *bb_ptr = NULL;
GtkTreeView *treeview = NULL;
list_itr_t *itr = NULL;
sview_bb_info_t *sview_bb_info = NULL;
int update = 0;
char bb_name_id[32];
if (!spec_info->search_info->gchar_data) {
//info = xstrdup("No pointer given!");
goto finished;
}
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_bb_info = list_next(itr))) {
bb_ptr = sview_bb_info->bb_ptr;
if (bb_ptr->name) {
strlcpy(bb_name_id, bb_ptr->name, sizeof(bb_name_id));
} else if (bb_ptr->array_task_id == NO_VAL) {
convert_num_unit(bb_ptr->job_id,
bb_name_id,
sizeof(bb_name_id),
UNIT_NONE, NO_VAL,
working_sview_config.convert_flags);
} else {
snprintf(bb_name_id, sizeof(bb_name_id),
"%u_%u(%u)",
bb_ptr->array_job_id,
bb_ptr->array_task_id,
bb_ptr->job_id);
}
if (!xstrcmp(bb_name_id, name)) {
_layout_bb_record(treeview, sview_bb_info, update);
break;
}
}
list_iterator_destroy(itr);
gtk_widget_show(spec_info->display_widget);
finished:
return;
}
/* extern GtkWidget *create_bb_entry(resv_desc_msg_t *resv_msg, */
/* GtkTreeModel *model, GtkTreeIter *iter) */
/* { */
/* NOP */
/* Function to add new burst buffer */
/* Admin edit function */
/* } */
/* Fresh the Burst Buffer information */
extern void refresh_bb(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_bb(popup_win);
}
/* Get the Burst buffer information */
extern int get_new_info_bb(burst_buffer_info_msg_t **info_ptr, int force)
{
static burst_buffer_info_msg_t *new_bb_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_bb_info_ptr && !force
&& ((now - last) < working_sview_config.refresh_delay)) {
if (*info_ptr != g_bb_info_ptr)
error_code = SLURM_SUCCESS;
*info_ptr = g_bb_info_ptr;
if (changed)
error_code = SLURM_SUCCESS;
goto end_it;
}
last = now;
if (g_bb_info_ptr) {
error_code = slurm_load_burst_buffer_info(&new_bb_ptr);
if (error_code == SLURM_SUCCESS) {
slurm_free_burst_buffer_info_msg(g_bb_info_ptr);
changed = 1;
} else if (errno == SLURM_NO_CHANGE_IN_DATA) {
error_code = SLURM_NO_CHANGE_IN_DATA;
new_bb_ptr = g_bb_info_ptr;
changed = 0;
}
} else {
new_bb_ptr = NULL;
error_code = slurm_load_burst_buffer_info(&new_bb_ptr);
changed = 1;
}
g_bb_info_ptr = new_bb_ptr;
if (g_bb_info_ptr && (*info_ptr != g_bb_info_ptr))
error_code = SLURM_SUCCESS;
*info_ptr = g_bb_info_ptr;
end_it:
return error_code;
}
/* Create the model with types with known values */
extern GtkListStore *create_model_bb(int type)
{
/* Since none of the values can be edited this is left blank */
/* NOP */
return NULL;
}
/* If Burst buffer wants to be edited it goes here */
extern void admin_edit_bb(GtkCellRendererText *cell,
const char *path_string,
const char *new_text,
gpointer data)
{
/* NOP */
}
extern void get_info_bb(GtkTable *table, display_data_t *display_data)
{
int error_code = SLURM_SUCCESS;
list_t *info_list = NULL;
static int view = -1;
static burst_buffer_info_msg_t *bb_info_ptr = NULL;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
static GtkWidget *display_widget = NULL;
GtkTreePath *path = NULL;
static bool set_opts = false;
if (!set_opts) {
set_page_opts(BB_PAGE, display_data_bb,
SORTID_CNT, _initial_page_opts);
}
set_opts = true;
/* reset */
if (!table && !display_data) {
if (display_widget)
gtk_widget_destroy(display_widget);
display_widget = NULL;
bb_info_ptr = NULL;
goto reset_curs;
}
if (display_data)
local_display_data = display_data;
if (!table) {
display_data_bb->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_bb(&bb_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_bb_info_list(bb_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);
}
change_grid_color(grid_button_list, -1, -1,
MAKE_WHITE, true, 0);
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_bb,
SORTID_CNT, SORTID_NAME, SORTID_COLOR);
}
view = INFO_VIEW;
_update_info_bb(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;
}
/* Function for full information about a Burst Buffer */
extern void specific_info_bb(popup_info_t *popup_win)
{
int bb_error_code = SLURM_SUCCESS;
static burst_buffer_info_msg_t *bb_info_ptr = NULL;
specific_info_t *spec_info = popup_win->spec_info;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
list_t *bb_list = NULL;
list_t *send_bb_list = NULL;
sview_bb_info_t *sview_bb_info_ptr = NULL;
list_itr_t *itr = NULL;
if (!spec_info->display_widget) {
setup_popup_info(popup_win, display_data_bb, 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 ((bb_error_code =
get_new_info_bb(&bb_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 (bb_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_bb: %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:
bb_list = _create_bb_info_list(bb_info_ptr);
if (!bb_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_NAME, SORTID_COLOR);
}
setup_popup_grid_list(popup_win);
spec_info->view = INFO_VIEW;
if (spec_info->type == INFO_PAGE) {
_display_info_bb(bb_list, popup_win);
goto end_it;
}
/*
* just linking to another list, don't free the inside, just the list
*/
send_bb_list = list_create(NULL);
itr = list_iterator_create(bb_list);
/*
* Set up additional menu options(ie the right click menu stuff)
*/
while ((sview_bb_info_ptr = list_next(itr))) {
switch (spec_info->type) {
case BB_PAGE:
list_push(send_bb_list, sview_bb_info_ptr);
break;
case JOB_PAGE:
case NODE_PAGE:
case PART_PAGE:
case RESV_PAGE:
default:
/*
* Since we will not use any of these pages we will
* leave them blank
*/
g_print("Unknown type %d\n", spec_info->type);
break;
}
}
list_iterator_destroy(itr);
post_setup_popup_grid_list(popup_win);
_update_info_bb(send_bb_list,
GTK_TREE_VIEW(spec_info->display_widget));
FREE_NULL_LIST(send_bb_list);
end_it:
popup_win->toggled = 0;
popup_win->force_refresh = 0;
return;
}
/* creates a popup window depending on what is clicked */
extern void set_menus_bb(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;
switch (type) {
case TAB_CLICKED:
make_fields_menu(NULL, menu, display_data_bb, SORTID_CNT);
break;
case ROW_CLICKED:
make_options_menu(tree_view, path, menu, options_data_bb);
break;
case ROW_LEFT_CLICKED:
/* Highlights the node in th node grid */
/* since we are not using this we will keep it empty */
/* NOP */
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_bb(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);
}
}
/* Function to setup popup windows for Burst Buffer */
extern void popup_all_bb(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 INFO_PAGE:
snprintf(title, 100, "Full info for Burst Buffer %s", name);
break;
default:
g_print("Burst Buffer 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, BB_PAGE, title);
} else {
popup_win = create_popup_info(BB_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;
/* Sets up right click information */
switch (id) {
case JOB_PAGE:
case INFO_PAGE:
popup_win->spec_info->search_info->gchar_data = name;
specific_info_bb(popup_win);
break;
case NODE_PAGE:
case PART_PAGE:
case SUBMIT_PAGE:
break;
default:
g_print("Burst Buffer got unknown type %d\n", id);
}
if (!sview_thread_new((gpointer)popup_thr, popup_win, &error)) {
g_printerr ("Failed to create burst buffer popup thread: %s\n",
error->message);
return;
}
}
/* static void _process_each_bb(GtkTreeModel *model, GtkTreePath *path, */
/* GtkTreeIter*iter, gpointer userdata) */
/* { */
/* Function for admin edit */
/* NOP */
/* } */
extern void select_admin_bb(GtkTreeModel *model, GtkTreeIter *iter,
display_data_t *display_data,
GtkTreeView *treeview)
{
/* NOP */
/* Function for admin edit */
}
/* static void _admin_bb(GtkTreeModel *model, GtkTreeIter *iter, char *type) */
/* { */
/* NOP */
/* Function for admin edit */
/* } */
extern void cluster_change_bb(void)
{
get_info_bb(NULL, NULL);
}