blob: bf53ddb10457eaa20b2e1f98c3d130f553e8be5f [file] [log] [blame]
/*****************************************************************************\
* part_info.c - Functions related to partition display
* mode of sview.
*****************************************************************************
* Copyright (C) 2004-2006 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
*
* UCRL-CODE-226842.
*
* This file is part of SLURM, a resource management program.
* For details, see <http://www.llnl.gov/linux/slurm/>.
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
\*****************************************************************************/
#include "src/sview/sview.h"
#include "src/common/parse_time.h"
#define _DEBUG 0
typedef struct {
partition_info_t* part_ptr;
uint16_t node_state;
uint32_t node_cnt;
uint16_t min_cpus;
uint16_t max_cpus;
uint32_t min_disk;
uint32_t max_disk;
uint32_t min_mem;
uint32_t max_mem;
uint32_t min_weight;
uint32_t max_weight;
char *features;
char *reason;
hostlist_t hl;
List node_ptr_list;
} sview_part_sub_t;
/* Collection of data for printing reports. Like data is combined here */
typedef struct {
/* part_info contains partition, avail, max_time, job_size,
* root, share, groups */
partition_info_t* part_ptr;
char *color;
List sub_list;
} sview_part_info_t;
enum {
EDIT_AVAIL = 1,
EDIT_EDIT
};
/* These need to be in alpha order (except POS and CNT) */
enum {
SORTID_POS = POS_LOC,
SORTID_AVAIL,
#ifdef HAVE_BG
SORTID_NODELIST,
#endif
SORTID_CPUS,
SORTID_DEFAULT,
SORTID_FEATURES,
SORTID_GROUPS,
SORTID_HIDDEN,
SORTID_JOB_SIZE,
SORTID_MAX_NODES,
SORTID_MEM,
SORTID_MIN_NODES,
SORTID_NAME,
#ifndef HAVE_BG
SORTID_NODELIST,
#endif
SORTID_NODES,
SORTID_ONLY_LINE,
SORTID_REASON,
SORTID_ROOT,
SORTID_SHARE,
SORTID_STATE,
SORTID_STATE_NUM,
SORTID_TMP_DISK,
SORTID_TIMELIMIT,
SORTID_UPDATED,
SORTID_WEIGHT,
SORTID_CNT
};
static display_data_t display_data_part[] = {
{G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE, refresh_part},
{G_TYPE_STRING, SORTID_NAME, "Partition", TRUE,
EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_DEFAULT, "Default", TRUE,
EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_HIDDEN, "Hidden", FALSE,
EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_AVAIL, "Availablity", TRUE,
EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit",
TRUE, EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_NODES, "Nodes", TRUE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_STATE, "State", TRUE, EDIT_MODEL, refresh_part,
create_model_part, admin_edit_part},
#ifdef HAVE_BG
{G_TYPE_STRING, SORTID_NODELIST, "BP List", TRUE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
#else
{G_TYPE_STRING, SORTID_NODELIST, "NodeList", TRUE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
#endif
{G_TYPE_STRING, SORTID_JOB_SIZE, "Job Size", FALSE,
EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_MIN_NODES, "Min Nodes", FALSE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_MAX_NODES, "Max Nodes", FALSE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_ROOT, "Root", FALSE, EDIT_MODEL, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_SHARE, "Share", FALSE, EDIT_MODEL, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_GROUPS, "Groups", FALSE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_CPUS, "CPUs", FALSE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_TMP_DISK, "Temp Disk", FALSE,
EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_MEM, "Memory", FALSE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_WEIGHT, "Weight", FALSE,
EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_FEATURES, "Features", FALSE,
EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_STRING, SORTID_REASON, "Reason", FALSE,
EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
{G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_INT, SORTID_ONLY_LINE, NULL, FALSE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, EDIT_NONE, refresh_part,
create_model_part, admin_edit_part},
{G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
};
static display_data_t options_data_part[] = {
{G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE},
{G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, PART_PAGE},
#ifdef HAVE_BG
{G_TYPE_STRING, PART_PAGE, "Drain Base Partitions", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Resume Base Partitions", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Put Base Partitions Down",
TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Make Base Partitions Idle",
TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Update Base Partition Features",
TRUE, ADMIN_PAGE},
#else
{G_TYPE_STRING, PART_PAGE, "Drain Nodes", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Resume Nodes", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Put Nodes Down", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Make Nodes Idle", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Update Node Features", TRUE, ADMIN_PAGE},
#endif
{G_TYPE_STRING, PART_PAGE, "Change Availablity Up/Down",
TRUE, ADMIN_PAGE},
{G_TYPE_STRING, PART_PAGE, "Edit Part", TRUE, ADMIN_PAGE},
{G_TYPE_STRING, JOB_PAGE, "Jobs", TRUE, PART_PAGE},
#ifdef HAVE_BG
{G_TYPE_STRING, BLOCK_PAGE, "Blocks", TRUE, PART_PAGE},
{G_TYPE_STRING, NODE_PAGE, "Base Partitions", TRUE, PART_PAGE},
#else
{G_TYPE_STRING, NODE_PAGE, "Nodes", TRUE, PART_PAGE},
#endif
{G_TYPE_STRING, SUBMIT_PAGE, "Job Submit", FALSE, PART_PAGE},
{G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
};
#ifdef HAVE_BG
static void _update_nodes_for_bg(int node_scaling,
node_info_msg_t *node_msg,
bg_info_record_t *bg_info_record);
enum {
SVIEW_BG_IDLE_STATE,
SVIEW_BG_ERROR_STATE,
SVIEW_BG_ALLOC_STATE
};
#endif
static display_data_t *local_display_data = NULL;
static char *got_edit_signal = NULL;
static char *got_features_edit_signal = NULL;
static void _update_part_sub_record(sview_part_sub_t *sview_part_sub,
GtkTreeStore *treestore,
GtkTreeIter *iter);
static void _append_part_sub_record(sview_part_sub_t *sview_part_sub,
GtkTreeStore *treestore, GtkTreeIter *iter,
int line);
static node_info_t *_find_node(char *node_name, node_info_msg_t *node_msg);
#ifdef HAVE_BG
static void _update_nodes_for_bg(int node_scaling,
node_info_msg_t *node_msg,
bg_info_record_t *bg_info_record)
{
node_info_t *node_ptr = NULL;
hostlist_t hl;
char *node_name = NULL;
/* we are using less than one node */
if(bg_info_record->conn_type == SELECT_SMALL)
node_scaling = bg_info_record->node_cnt;
hl = hostlist_create(bg_info_record->nodes);
while (1) {
if (node_name)
free(node_name);
node_name = hostlist_shift(hl);
if (!node_name)
break;
node_ptr = _find_node(node_name, node_msg);
if (!node_ptr)
continue;
/* cores is overloaded to be the cnodes in an error
* state and used_cpus is overloaded to be the nodes in
* use. No block should be sent in here if it isn't
* in use (that doesn't mean in a free state, it means
* the user isn't slurm or the block is in an error state.
*/
if(bg_info_record->state == RM_PARTITION_ERROR)
node_ptr->cores += node_scaling;
else
node_ptr->used_cpus += node_scaling;
}
hostlist_destroy(hl);
}
#endif
static int
_build_min_max_16_string(char *buffer, int buf_size,
uint16_t min, uint16_t max, bool range)
{
char tmp_min[8];
char tmp_max[8];
convert_num_unit((float)min, tmp_min, sizeof(tmp_min), UNIT_NONE);
if(max != (uint16_t) INFINITE) {
convert_num_unit((float)max, tmp_max, sizeof(tmp_max),
UNIT_NONE);
}
if (max == min)
return snprintf(buffer, buf_size, "%s", tmp_max);
else if (range) {
if (max == (uint16_t) INFINITE)
return snprintf(buffer, buf_size, "%s-infinite",
tmp_min);
else
return snprintf(buffer, buf_size, "%s-%s",
tmp_min, tmp_max);
} else
return snprintf(buffer, buf_size, "%s+", tmp_min);
}
static int
_build_min_max_32_string(char *buffer, int buf_size,
uint32_t min, uint32_t max, bool range)
{
char tmp_min[8];
char tmp_max[8];
convert_num_unit((float)min, tmp_min, sizeof(tmp_min), UNIT_NONE);
convert_num_unit((float)max, tmp_max, sizeof(tmp_max), UNIT_NONE);
if (max == min)
return snprintf(buffer, buf_size, "%s", tmp_max);
else if (range) {
if (max == (uint32_t) INFINITE)
return snprintf(buffer, buf_size, "%s-infinite",
tmp_min);
else
return snprintf(buffer, buf_size, "%s-%s",
tmp_min, tmp_max);
} else
return snprintf(buffer, buf_size, "%s+", tmp_min);
}
static void _set_active_combo_part(GtkComboBox *combo,
GtkTreeModel *model, GtkTreeIter *iter,
int type)
{
char *temp_char = NULL;
int action = 0;
int i = 0, unknown_found = 0;
char *upper = NULL;
gtk_tree_model_get(model, iter, type, &temp_char, -1);
if(!temp_char)
goto end_it;
switch(type) {
case SORTID_DEFAULT:
case SORTID_HIDDEN:
case SORTID_ROOT:
if(!strcmp(temp_char, "yes"))
action = 0;
else if(!strcmp(temp_char, "no"))
action = 1;
else
action = 0;
break;
case SORTID_SHARE:
if(!strcmp(temp_char, "yes"))
action = 0;
else if(!strcmp(temp_char, "no"))
action = 1;
else if(!strcmp(temp_char, "force"))
action = 2;
else
action = 0;
break;
case SORTID_AVAIL:
if(!strcmp(temp_char, "up"))
action = 0;
else if(!strcmp(temp_char, "down"))
action = 1;
else
action = 0;
break;
case SORTID_STATE:
if(!strcasecmp(temp_char, "drain"))
action = 0;
else if(!strcasecmp(temp_char, "resume"))
action = 1;
else
for(i = 0; i < NODE_STATE_END; i++) {
upper = node_state_string(i);
if(!strcmp(upper, "UNKNOWN")) {
unknown_found++;
continue;
}
if(!strcasecmp(temp_char, upper)) {
action = i + 2 - unknown_found;
break;
}
}
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_part_msg(update_part_msg_t *part_msg,
const char *new_text,
int column)
{
char *type = NULL;
int temp_int = 0;
if(!part_msg)
return NULL;
switch(column) {
case SORTID_DEFAULT:
if (!strcasecmp(new_text, "yes"))
part_msg->default_part = 1;
else
part_msg->default_part = 0;
type = "default";
break;
case SORTID_HIDDEN:
if (!strcasecmp(new_text, "yes"))
part_msg->hidden = 1;
else
part_msg->hidden = 0;
type = "hidden";
break;
case SORTID_TIMELIMIT:
if ((strcasecmp(new_text,"infinite") == 0))
temp_int = INFINITE;
else
temp_int = time_str2mins((char *)new_text);
type = "timelimit";
if(temp_int <= 0 && temp_int != INFINITE)
goto return_error;
part_msg->max_time = (uint32_t)temp_int;
break;
case SORTID_MIN_NODES:
temp_int = strtol(new_text, (char **)NULL, 10);
type = "min_nodes";
if(temp_int <= 0)
goto return_error;
part_msg->min_nodes = (uint32_t)temp_int;
break;
case SORTID_MAX_NODES:
if (!strcasecmp(new_text, "infinite")) {
temp_int = INFINITE;
} else {
temp_int = strtol(new_text, (char **)NULL, 10);
}
type = "max_nodes";
if(temp_int <= 0 && temp_int != INFINITE)
goto return_error;
part_msg->max_nodes = (uint32_t)temp_int;
break;
case SORTID_ROOT:
if (!strcasecmp(new_text, "yes")) {
part_msg->root_only = 1;
} else {
part_msg->root_only = 0;
}
type = "root";
break;
case SORTID_SHARE:
if (!strcasecmp(new_text, "yes")) {
part_msg->shared = SHARED_YES;
} else if (!strcasecmp(new_text, "no")) {
part_msg->shared = SHARED_NO;
} else {
part_msg->shared = SHARED_FORCE;
}
type = "share";
break;
case SORTID_GROUPS:
type = "groups";
part_msg->allow_groups = xstrdup(new_text);
break;
case SORTID_NODELIST:
part_msg->nodes = xstrdup(new_text);
type = "nodelist";
break;
case SORTID_AVAIL:
if (!strcasecmp(new_text, "up"))
part_msg->state_up = 1;
else
part_msg->state_up = 0;
type = "availability";
break;
case SORTID_STATE:
type = (char *)new_text;
got_edit_signal = xstrdup(new_text);
break;
case SORTID_FEATURES:
type = "Update Features";
got_features_edit_signal = xstrdup(new_text);
break;
}
return type;
return_error:
errno = 1;
return type;
}
static void _admin_edit_combo_box_part(GtkComboBox *combo,
update_part_msg_t *part_msg)
{
GtkTreeModel *model = NULL;
GtkTreeIter iter;
int column = 0;
char *name = NULL;
if(!part_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_part_msg(part_msg, name, column);
g_free(name);
}
static gboolean _admin_focus_out_part(GtkEntry *entry,
GdkEventFocus *event,
update_part_msg_t *part_msg)
{
int type = gtk_entry_get_max_length(entry);
const char *name = gtk_entry_get_text(entry);
type -= DEFAULT_ENTRY_LENGTH;
_set_part_msg(part_msg, name, type);
return false;
}
static GtkWidget *_admin_full_edit_part(update_part_msg_t *part_msg,
GtkTreeModel *model, GtkTreeIter *iter)
{
GtkScrolledWindow *window = create_scrolled_window();
GtkBin *bin = NULL;
GtkViewport *view = NULL;
GtkTable *table = NULL;
GtkWidget *label = NULL;
GtkWidget *entry = NULL;
GtkTreeModel *model2 = NULL;
GtkCellRenderer *renderer = NULL;
int i = 0, row = 0;
char *temp_char = NULL;
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++) {
if(display_data_part[i].extra == EDIT_MODEL) {
/* edittable items that can only be known
values */
model2 = GTK_TREE_MODEL(
create_model_part(display_data_part[i].id));
if(!model2) {
g_print("no model set up for %d(%s)\n",
display_data_part[i].id,
display_data_part[i].name);
continue;
}
entry = gtk_combo_box_new_with_model(model2);
g_object_unref(model2);
_set_active_combo_part(GTK_COMBO_BOX(entry), model,
iter, display_data_part[i].id);
g_signal_connect(entry, "changed",
G_CALLBACK(
_admin_edit_combo_box_part),
part_msg);
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(entry),
renderer, TRUE);
gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(entry),
renderer, "text", 0);
} else if(display_data_part[i].extra == EDIT_TEXTBOX) {
/* other edittable items that are unknown */
entry = create_entry();
gtk_tree_model_get(model, iter,
display_data_part[i].id,
&temp_char, -1);
gtk_entry_set_max_length(GTK_ENTRY(entry),
(DEFAULT_ENTRY_LENGTH +
display_data_part[i].id));
if(temp_char) {
gtk_entry_set_text(GTK_ENTRY(entry),
temp_char);
g_free(temp_char);
}
g_signal_connect(entry, "focus-out-event",
G_CALLBACK(_admin_focus_out_part),
part_msg);
} else /* others can't be altered by the user */
continue;
label = gtk_label_new(display_data_part[i].name);
gtk_table_attach(table, label, 0, 1, row, row+1,
GTK_FILL | GTK_EXPAND, GTK_SHRINK,
0, 0);
gtk_table_attach(table, entry, 1, 2, row, row+1,
GTK_FILL, GTK_SHRINK,
0, 0);
row++;
}
gtk_table_resize(table, row, 2);
return GTK_WIDGET(window);
}
static void _subdivide_part(sview_part_info_t *sview_part_info,
GtkTreeModel *model,
GtkTreeIter *sub_iter,
GtkTreeIter *iter)
{
GtkTreeIter first_sub_iter;
ListIterator itr = NULL;
uint16_t state;
int i = 0, line = 0;
sview_part_sub_t *sview_part_sub = NULL;
int set = 0;
memset(&first_sub_iter, 0, sizeof(GtkTreeIter));
/* make sure all the steps are still here */
if (sub_iter) {
first_sub_iter = *sub_iter;
while(1) {
gtk_tree_store_set(GTK_TREE_STORE(model), sub_iter,
SORTID_UPDATED, 0, -1);
if(!gtk_tree_model_iter_next(model, sub_iter)) {
break;
}
}
memcpy(sub_iter, &first_sub_iter, sizeof(GtkTreeIter));
set = 1;
}
itr = list_iterator_create(sview_part_info->sub_list);
if(list_count(sview_part_info->sub_list) == 1) {
gtk_tree_store_set(GTK_TREE_STORE(model), iter,
SORTID_ONLY_LINE, 1, -1);
sview_part_sub = list_next(itr);
_update_part_sub_record(sview_part_sub,
GTK_TREE_STORE(model),
iter);
} else {
while((sview_part_sub = list_next(itr))) {
if (!sub_iter) {
i = NO_VAL;
goto adding;
} else {
memcpy(sub_iter, &first_sub_iter,
sizeof(GtkTreeIter));
}
while(1) {
/* search for the state number and
check to see if it is in the list */
gtk_tree_model_get(model, sub_iter,
SORTID_STATE_NUM,
&state, -1);
if(state == sview_part_sub->node_state) {
/* update with new info */
_update_part_sub_record(
sview_part_sub,
GTK_TREE_STORE(model),
sub_iter);
goto found;
}
/* see what line we were on to add the
next one to the list */
gtk_tree_model_get(model, sub_iter,
SORTID_POS,
&line, -1);
if(!gtk_tree_model_iter_next(model,
sub_iter)) {
line++;
break;
}
}
adding:
_append_part_sub_record(sview_part_sub,
GTK_TREE_STORE(model),
iter, line);
if(i == NO_VAL)
line++;
found:
;
}
}
list_iterator_destroy(itr);
if(set) {
sub_iter = &first_sub_iter;
/* clear all steps that aren't active */
while(1) {
gtk_tree_model_get(model, sub_iter,
SORTID_UPDATED, &i, -1);
if(!i) {
if(!gtk_tree_store_remove(
GTK_TREE_STORE(model),
sub_iter))
break;
else
continue;
}
if(!gtk_tree_model_iter_next(model, sub_iter)) {
break;
}
}
}
return;
}
static void _layout_part_record(GtkTreeView *treeview,
sview_part_info_t *sview_part_info,
int update)
{
GtkTreeIter iter;
ListIterator itr = NULL;
char time_buf[20];
char tmp_cnt[8];
char tmp_cnt1[8];
char tmp_cnt2[8];
partition_info_t *part_ptr = sview_part_info->part_ptr;
sview_part_sub_t *sview_part_sub = NULL;
sview_part_sub_t *temp_part_sub = NULL;
sview_part_sub_t alloc_part_sub;
sview_part_sub_t idle_part_sub;
sview_part_sub_t other_part_sub;
char tmp[1024];
char *temp_char = NULL;
int global_set = 0;
GtkTreeStore *treestore =
GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
memset(&alloc_part_sub, 0, sizeof(sview_part_sub_t));
memset(&idle_part_sub, 0, sizeof(sview_part_sub_t));
memset(&other_part_sub, 0, sizeof(sview_part_sub_t));
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_NAME),
part_ptr->name);
if(part_ptr->default_part)
temp_char = "yes";
else
temp_char = "no";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_DEFAULT),
temp_char);
if(part_ptr->hidden)
temp_char = "yes";
else
temp_char = "no";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_HIDDEN),
temp_char);
if (part_ptr->state_up)
temp_char = "up";
else
temp_char = "down";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_AVAIL),
temp_char);
if (part_ptr->max_time == INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
secs2time_str((part_ptr->max_time * 60),
time_buf, sizeof(time_buf));
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_TIMELIMIT),
time_buf);
_build_min_max_32_string(time_buf, sizeof(time_buf),
part_ptr->min_nodes,
part_ptr->max_nodes, true);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_JOB_SIZE),
time_buf);
if (part_ptr->min_nodes == (uint32_t) INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
convert_num_unit((float)part_ptr->min_nodes,
time_buf, sizeof(time_buf), UNIT_NONE);
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_MIN_NODES),
time_buf);
if (part_ptr->max_nodes == (uint32_t) INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
convert_num_unit((float)part_ptr->max_nodes,
time_buf, sizeof(time_buf), UNIT_NONE);
}
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_MAX_NODES),
time_buf);
if(part_ptr->root_only)
temp_char = "yes";
else
temp_char = "no";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_ROOT),
temp_char);
if(part_ptr->shared > 1)
temp_char = "force";
else if(part_ptr->shared)
temp_char = "yes";
else
temp_char = "no";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_SHARE),
temp_char);
if(part_ptr->allow_groups)
temp_char = part_ptr->allow_groups;
else
temp_char = "all";
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_GROUPS),
temp_char);
#ifdef HAVE_BG
convert_num_unit((float)part_ptr->total_nodes, tmp_cnt,
sizeof(tmp_cnt), UNIT_NONE);
#else
sprintf(tmp_cnt, "%u", part_ptr->total_nodes);
#endif
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_NODES),
tmp_cnt);
convert_num_unit((float)part_ptr->total_cpus, tmp_cnt, sizeof(tmp_cnt),
UNIT_NONE);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_CPUS),
tmp_cnt);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_NODELIST),
part_ptr->nodes);
itr = list_iterator_create(sview_part_info->sub_list);
while((sview_part_sub = list_next(itr))) {
if(sview_part_sub->node_state == NODE_STATE_IDLE)
temp_part_sub = &idle_part_sub;
else if(sview_part_sub->node_state == NODE_STATE_ALLOCATED)
temp_part_sub = &alloc_part_sub;
else
temp_part_sub = &other_part_sub;
temp_part_sub->node_cnt += sview_part_sub->node_cnt;
temp_part_sub->min_cpus += sview_part_sub->min_cpus;
temp_part_sub->max_cpus += sview_part_sub->max_cpus;
temp_part_sub->min_disk += sview_part_sub->min_disk;
temp_part_sub->max_disk += sview_part_sub->max_disk;
temp_part_sub->min_mem += sview_part_sub->min_mem;
temp_part_sub->max_mem += sview_part_sub->max_mem;
temp_part_sub->min_weight += sview_part_sub->min_weight;
temp_part_sub->max_weight += sview_part_sub->max_weight;
if(!global_set) {
global_set = 1;
/* store features and reasons in the others
group */
other_part_sub.features = temp_part_sub->features;
other_part_sub.reason = temp_part_sub->reason;
}
}
convert_num_unit((float)alloc_part_sub.node_cnt,
tmp_cnt, sizeof(tmp_cnt), UNIT_NONE);
convert_num_unit((float)idle_part_sub.node_cnt,
tmp_cnt1, sizeof(tmp_cnt1), UNIT_NONE);
convert_num_unit((float)other_part_sub.node_cnt,
tmp_cnt2, sizeof(tmp_cnt2), UNIT_NONE);
snprintf(tmp, sizeof(tmp), "%s/%s/%s",
tmp_cnt, tmp_cnt1, tmp_cnt2);
add_display_treestore_line(update, treestore, &iter,
"Nodes (Allocated/Idle/Other)",
tmp);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_FEATURES),
other_part_sub.features);
add_display_treestore_line(update, treestore, &iter,
find_col_name(display_data_part,
SORTID_REASON),
other_part_sub.reason);
}
static void _update_part_record(sview_part_info_t *sview_part_info,
GtkTreeStore *treestore,
GtkTreeIter *iter)
{
char time_buf[20];
char tmp_cnt[8];
char *temp_char = NULL;
partition_info_t *part_ptr = sview_part_info->part_ptr;
GtkTreeIter sub_iter;
int childern = 0;
gtk_tree_store_set(treestore, iter, SORTID_NAME, part_ptr->name, -1);
if(part_ptr->default_part)
temp_char = "yes";
else
temp_char = "no";
gtk_tree_store_set(treestore, iter, SORTID_DEFAULT, temp_char, -1);
if(part_ptr->hidden)
temp_char = "yes";
else
temp_char = "no";
gtk_tree_store_set(treestore, iter, SORTID_HIDDEN, temp_char, -1);
if (part_ptr->state_up)
temp_char = "up";
else
temp_char = "down";
gtk_tree_store_set(treestore, iter, SORTID_AVAIL, temp_char, -1);
if (part_ptr->max_time == INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
secs2time_str((part_ptr->max_time * 60),
time_buf, sizeof(time_buf));
}
gtk_tree_store_set(treestore, iter, SORTID_TIMELIMIT, time_buf, -1);
_build_min_max_32_string(time_buf, sizeof(time_buf),
part_ptr->min_nodes,
part_ptr->max_nodes, true);
gtk_tree_store_set(treestore, iter, SORTID_JOB_SIZE, time_buf, -1);
if (part_ptr->min_nodes == (uint32_t) INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
convert_num_unit((float)part_ptr->min_nodes,
time_buf, sizeof(time_buf), UNIT_NONE);
}
gtk_tree_store_set(treestore, iter, SORTID_MIN_NODES,
time_buf, -1);
if (part_ptr->max_nodes == (uint32_t) INFINITE)
snprintf(time_buf, sizeof(time_buf), "infinite");
else {
convert_num_unit((float)part_ptr->max_nodes,
time_buf, sizeof(time_buf), UNIT_NONE);
}
gtk_tree_store_set(treestore, iter, SORTID_MAX_NODES,
time_buf, -1);
if(part_ptr->root_only)
temp_char = "yes";
else
temp_char = "no";
gtk_tree_store_set(treestore, iter, SORTID_ROOT, temp_char, -1);
if(part_ptr->shared > 1)
temp_char = "force";
else if(part_ptr->shared)
temp_char = "yes";
else
temp_char = "no";
gtk_tree_store_set(treestore, iter, SORTID_SHARE, temp_char, -1);
if(part_ptr->allow_groups)
temp_char = part_ptr->allow_groups;
else
temp_char = "all";
gtk_tree_store_set(treestore, iter, SORTID_GROUPS, temp_char, -1);
#ifdef HAVE_BG
convert_num_unit((float)part_ptr->total_nodes, tmp_cnt,
sizeof(tmp_cnt), UNIT_NONE);
#else
sprintf(tmp_cnt, "%u", part_ptr->total_nodes);
#endif
gtk_tree_store_set(treestore, iter, SORTID_NODES, tmp_cnt, -1);
gtk_tree_store_set(treestore, iter, SORTID_NODELIST,
part_ptr->nodes, -1);
gtk_tree_store_set(treestore, iter, SORTID_ONLY_LINE, 0, -1);
/* clear out info for the main listing */
gtk_tree_store_set(treestore, iter, SORTID_STATE, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_STATE_NUM, -1, -1);
gtk_tree_store_set(treestore, iter, SORTID_CPUS, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_TMP_DISK, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_MEM, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_WEIGHT, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);
gtk_tree_store_set(treestore, iter, SORTID_FEATURES, "", -1);
gtk_tree_store_set(treestore, iter, SORTID_REASON, "", -1);
childern = gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
&sub_iter, iter);
if(gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
&sub_iter, iter))
_subdivide_part(sview_part_info,
GTK_TREE_MODEL(treestore), &sub_iter, iter);
else
_subdivide_part(sview_part_info,
GTK_TREE_MODEL(treestore), NULL, iter);
return;
}
static void _update_part_sub_record(sview_part_sub_t *sview_part_sub,
GtkTreeStore *treestore, GtkTreeIter *iter)
{
char time_buf[20];
char tmp_cnt[8];
partition_info_t *part_ptr = sview_part_sub->part_ptr;
char *upper = NULL, *lower = NULL;
char tmp[MAXHOSTRANGELEN];
gtk_tree_store_set(treestore, iter, SORTID_NAME, part_ptr->name, -1);
upper = node_state_string(sview_part_sub->node_state);
lower = str_tolower(upper);
gtk_tree_store_set(treestore, iter, SORTID_STATE,
lower, -1);
xfree(lower);
gtk_tree_store_set(treestore, iter, SORTID_STATE_NUM,
sview_part_sub->node_state, -1);
_build_min_max_16_string(time_buf, sizeof(time_buf),
sview_part_sub->min_cpus,
sview_part_sub->max_cpus, false);
gtk_tree_store_set(treestore, iter, SORTID_CPUS, time_buf, -1);
_build_min_max_32_string(time_buf, sizeof(time_buf),
sview_part_sub->min_disk,
sview_part_sub->max_disk, false);
gtk_tree_store_set(treestore, iter, SORTID_TMP_DISK, time_buf, -1);
_build_min_max_32_string(time_buf, sizeof(time_buf),
sview_part_sub->min_mem,
sview_part_sub->max_mem, false);
gtk_tree_store_set(treestore, iter, SORTID_MEM, time_buf, -1);
_build_min_max_32_string(time_buf, sizeof(time_buf),
sview_part_sub->min_weight,
sview_part_sub->max_weight, false);
gtk_tree_store_set(treestore, iter, SORTID_WEIGHT, time_buf, -1);
convert_num_unit((float)sview_part_sub->node_cnt, tmp_cnt,
sizeof(tmp_cnt), UNIT_NONE);
gtk_tree_store_set(treestore, iter, SORTID_NODES, tmp_cnt, -1);
hostlist_ranged_string(sview_part_sub->hl, sizeof(tmp), tmp);
gtk_tree_store_set(treestore, iter, SORTID_NODELIST,
tmp, -1);
gtk_tree_store_set(treestore, iter, SORTID_UPDATED, 1, -1);
gtk_tree_store_set(treestore, iter, SORTID_FEATURES,
sview_part_sub->features, -1);
gtk_tree_store_set(treestore, iter, SORTID_REASON,
sview_part_sub->reason, -1);
return;
}
static void _append_part_record(sview_part_info_t *sview_part_info,
GtkTreeStore *treestore, GtkTreeIter *iter,
int line)
{
gtk_tree_store_append(treestore, iter, NULL);
gtk_tree_store_set(treestore, iter, SORTID_POS, line, -1);
_update_part_record(sview_part_info, treestore, iter);
}
static void _append_part_sub_record(sview_part_sub_t *sview_part_sub,
GtkTreeStore *treestore, GtkTreeIter *iter,
int line)
{
GtkTreeIter sub_iter;
gtk_tree_store_append(treestore, &sub_iter, iter);
gtk_tree_store_set(treestore, &sub_iter, SORTID_POS, line, -1);
_update_part_sub_record(sview_part_sub, treestore, &sub_iter);
}
static void _update_info_part(List info_list,
GtkTreeView *tree_view)
{
GtkTreePath *path = gtk_tree_path_new_first();
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeIter iter;
partition_info_t *part_ptr = NULL;
int line = 0;
char *host = NULL, *part_name = NULL;
ListIterator itr = NULL;
sview_part_info_t *sview_part_info = NULL;
/* get the iter, or find out the list is empty goto add */
if (gtk_tree_model_get_iter(model, &iter, path)) {
/* make sure all the partitions are still here */
while(1) {
gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
SORTID_UPDATED, 0, -1);
if(!gtk_tree_model_iter_next(model, &iter)) {
break;
}
}
}
itr = list_iterator_create(info_list);
while ((sview_part_info = (sview_part_info_t*) list_next(itr))) {
part_ptr = sview_part_info->part_ptr;
/* get the iter, or find out the list is empty goto add */
if (!gtk_tree_model_get_iter(model, &iter, path)) {
goto adding;
}
while(1) {
/* search for the jobid and check to see if
it is in the list */
gtk_tree_model_get(model, &iter, SORTID_NAME,
&part_name, -1);
if(!strcmp(part_name, part_ptr->name)) {
/* update with new info */
g_free(part_name);
_update_part_record(sview_part_info,
GTK_TREE_STORE(model),
&iter);
goto found;
}
g_free(part_name);
/* see what line we were on to add the next one
to the list */
gtk_tree_model_get(model, &iter, SORTID_POS,
&line, -1);
if(!gtk_tree_model_iter_next(model, &iter)) {
line++;
break;
}
}
adding:
_append_part_record(sview_part_info, GTK_TREE_STORE(model),
&iter, line);
found:
;
}
list_iterator_destroy(itr);
if(host)
free(host);
gtk_tree_path_free(path);
/* remove all old partitions */
remove_old(model, SORTID_UPDATED);
return;
}
static void _part_info_list_del(void *object)
{
sview_part_info_t *sview_part_info = (sview_part_info_t *)object;
if (sview_part_info) {
if(sview_part_info->sub_list)
list_destroy(sview_part_info->sub_list);
xfree(sview_part_info);
}
}
static void _destroy_part_sub(void *object)
{
sview_part_sub_t *sview_part_sub = (sview_part_sub_t *)object;
if (sview_part_sub) {
xfree(sview_part_sub->features);
xfree(sview_part_sub->reason);
if(sview_part_sub->hl)
hostlist_destroy(sview_part_sub->hl);
if(sview_part_sub->node_ptr_list)
list_destroy(sview_part_sub->node_ptr_list);
xfree(sview_part_sub);
}
}
/* like strcmp, but works with NULL pointers */
static int _strcmp(char *data1, char *data2)
{
static char null_str[] = "(null)";
if (data1 == NULL)
data1 = null_str;
if (data2 == NULL)
data2 = null_str;
return strcmp(data1, data2);
}
/*
* _find_node - find a node by name
* node_name IN - name of node to locate
* node_msg IN - node information message from API
*/
static node_info_t *_find_node(char *node_name, node_info_msg_t *node_msg)
{
int i;
if (node_name == NULL)
return NULL;
for (i=0; i<node_msg->record_count; i++) {
if (_strcmp(node_name, node_msg->node_array[i].name))
continue;
return &(node_msg->node_array[i]);
}
/* not found */
return NULL;
}
static void _update_sview_part_sub(sview_part_sub_t *sview_part_sub,
node_info_t *node_ptr,
int node_scaling)
{
list_append(sview_part_sub->node_ptr_list, node_ptr);
#ifdef HAVE_BG
node_scaling = node_ptr->threads;
if(!node_scaling)
return;
#else
if(!node_scaling)
node_scaling = 1;
#endif
if (sview_part_sub->node_cnt == 0) { /* first node added */
sview_part_sub->node_state = node_ptr->node_state;
sview_part_sub->features = xstrdup(node_ptr->features);
sview_part_sub->reason = xstrdup(node_ptr->reason);
sview_part_sub->min_cpus = node_ptr->cpus;
sview_part_sub->max_cpus = node_ptr->cpus;
sview_part_sub->min_disk = node_ptr->tmp_disk;
sview_part_sub->max_disk = node_ptr->tmp_disk;
sview_part_sub->min_mem = node_ptr->real_memory;
sview_part_sub->max_mem = node_ptr->real_memory;
sview_part_sub->min_weight = node_ptr->weight;
sview_part_sub->max_weight = node_ptr->weight;
} else if (hostlist_find(sview_part_sub->hl,
node_ptr->name) != -1) {
/* we already have this node in this record,
* just return, don't duplicate */
return;
} else {
if (sview_part_sub->min_cpus > node_ptr->cpus)
sview_part_sub->min_cpus = node_ptr->cpus;
if (sview_part_sub->max_cpus < node_ptr->cpus)
sview_part_sub->max_cpus = node_ptr->cpus;
if (sview_part_sub->min_disk > node_ptr->tmp_disk)
sview_part_sub->min_disk = node_ptr->tmp_disk;
if (sview_part_sub->max_disk < node_ptr->tmp_disk)
sview_part_sub->max_disk = node_ptr->tmp_disk;
if (sview_part_sub->min_mem > node_ptr->real_memory)
sview_part_sub->min_mem = node_ptr->real_memory;
if (sview_part_sub->max_mem < node_ptr->real_memory)
sview_part_sub->max_mem = node_ptr->real_memory;
if (sview_part_sub->min_weight> node_ptr->weight)
sview_part_sub->min_weight = node_ptr->weight;
if (sview_part_sub->max_weight < node_ptr->weight)
sview_part_sub->max_weight = node_ptr->weight;
}
sview_part_sub->node_cnt += node_scaling;
hostlist_push(sview_part_sub->hl, node_ptr->name);
}
/*
* _create_sview_part_sub - create an sview_part_sub record for
* the given partition
* sview_part_sub OUT - ptr to an inited sview_part_sub_t
*/
static sview_part_sub_t *_create_sview_part_sub(partition_info_t *part_ptr,
node_info_t *node_ptr,
int node_scaling)
{
sview_part_sub_t *sview_part_sub_ptr =
xmalloc(sizeof(sview_part_sub_t));
#ifdef HAVE_BG
node_scaling = node_ptr->threads;
if(!node_scaling)
return NULL;
#else
if(!node_scaling)
node_scaling = 1;
#endif
if (!part_ptr) {
g_print("got no part_ptr!\n");
xfree(sview_part_sub_ptr);
return NULL;
}
if (!node_ptr) {
g_print("got no node_ptr!\n");
xfree(sview_part_sub_ptr);
return NULL;
}
sview_part_sub_ptr->part_ptr = part_ptr;
sview_part_sub_ptr->node_state = node_ptr->node_state;
sview_part_sub_ptr->node_cnt = node_scaling;
sview_part_sub_ptr->min_cpus = node_ptr->cpus;
sview_part_sub_ptr->max_cpus = node_ptr->cpus;
sview_part_sub_ptr->min_disk = node_ptr->tmp_disk;
sview_part_sub_ptr->max_disk = node_ptr->tmp_disk;
sview_part_sub_ptr->min_mem = node_ptr->real_memory;
sview_part_sub_ptr->max_mem = node_ptr->real_memory;
sview_part_sub_ptr->min_weight = node_ptr->weight;
sview_part_sub_ptr->max_weight = node_ptr->weight;
sview_part_sub_ptr->features = xstrdup(node_ptr->features);
sview_part_sub_ptr->reason = xstrdup(node_ptr->reason);
sview_part_sub_ptr->hl = hostlist_create(node_ptr->name);
sview_part_sub_ptr->node_ptr_list = list_create(NULL);
list_push(sview_part_sub_ptr->node_ptr_list, node_ptr);
return sview_part_sub_ptr;
}
/*
* _create_sview_part_info - create an sview_part_info record for
* the given partition
* part_ptr IN - pointer to partition record to add
* sview_part_info OUT - ptr to an inited sview_part_info_t
*/
static sview_part_info_t *_create_sview_part_info(partition_info_t* part_ptr)
{
sview_part_info_t *sview_part_info =
xmalloc(sizeof(sview_part_info_t));
sview_part_info->part_ptr = part_ptr;
sview_part_info->sub_list = list_create(_destroy_part_sub);
return sview_part_info;
}
static List _create_part_info_list(partition_info_msg_t *part_info_ptr,
node_info_msg_t *node_info_ptr,
node_select_info_msg_t *node_select_ptr,
int changed)
{
sview_part_info_t *sview_part_info = NULL;
sview_part_sub_t *sview_part_sub = NULL;
partition_info_t *part_ptr = NULL;
node_info_t *node_ptr = NULL;
static List info_list = NULL;
char *node_name = NULL;
int i, found = 0;
ListIterator itr = NULL;
hostlist_t hl;
#ifdef HAVE_BG
int j;
bg_info_record_t *bg_info_record = NULL;
int node_scaling = part_info_ptr->partition_array[0].node_scaling;
char *slurm_user = NULL;
#endif
if(!changed && info_list) {
return info_list;
}
if(info_list) {
list_destroy(info_list);
}
info_list = list_create(_part_info_list_del);
if (!info_list) {
g_print("malloc error\n");
return NULL;
}
#ifdef HAVE_BG
slurm_user = xstrdup(slurmctld_conf.slurm_user_name);
for (i=0; i<node_info_ptr->record_count; i++) {
node_ptr = &(node_info_ptr->node_array[i]);
/* in each node_ptr we overload the threads var
* with the number of cnodes in the used_cpus var
* will be used to tell how many cnodes are
* allocated and the cores will represent the cnodes
* in an error state. So we can get an idle count by
* subtracting those 2 numbers from the total possible
* cnodes (which are the idle cnodes).
*/
node_ptr->threads = node_scaling;
node_ptr->cores = 0;
node_ptr->used_cpus = 0;
}
for (i=0; i<node_select_ptr->record_count; i++) {
bg_info_record = &(node_select_ptr->bg_info_array[i]);
/* this block is idle we won't mark it */
if (bg_info_record->state != RM_PARTITION_ERROR
&& !strcmp(slurm_user, bg_info_record->owner_name))
continue;
_update_nodes_for_bg(node_scaling, node_info_ptr,
bg_info_record);
}
xfree(slurm_user);
#endif
for (i=0; i<part_info_ptr->record_count; i++) {
part_ptr = &(part_info_ptr->partition_array[i]);
if (!part_ptr->nodes || (part_ptr->nodes[0] == '\0'))
continue; /* empty partition */
sview_part_info = _create_sview_part_info(part_ptr);
hl = hostlist_create(part_ptr->nodes);
while((node_name = hostlist_shift(hl))) {
node_ptr = _find_node(node_name, node_info_ptr);
free(node_name);
#ifdef HAVE_BG
for(j=0; j<3; j++) {
int norm = 0;
switch(j) {
case SVIEW_BG_IDLE_STATE:
/* get the idle node count if
* we don't have any error or
* allocated nodes then we set
* the norm flag and add it
* as it's current state
*/
node_ptr->threads -=
(node_ptr->cores
+ node_ptr->used_cpus);
if(node_ptr->threads == node_scaling)
norm = 1;
else
node_ptr->node_state =
NODE_STATE_IDLE;
break;
case SVIEW_BG_ERROR_STATE:
/* get the error node count */
if(!node_ptr->cores)
continue;
node_ptr->node_state |=
NODE_STATE_DRAIN;
node_ptr->threads = node_ptr->cores;
break;
case SVIEW_BG_ALLOC_STATE:
/* get the allocated node count */
if(!node_ptr->used_cpus)
continue;
node_ptr->node_state =
NODE_STATE_ALLOCATED;
node_ptr->threads =
node_ptr->used_cpus;
break;
default:
error("unknown state");
break;
}
#endif
itr = list_iterator_create(sview_part_info->sub_list);
while((sview_part_sub = list_next(itr))) {
if(sview_part_sub->node_state
== node_ptr->node_state) {
_update_sview_part_sub(
sview_part_sub,
node_ptr,
part_ptr->node_scaling);
found = 1;
break;
}
}
list_iterator_destroy(itr);
if(!found) {
sview_part_sub =
_create_sview_part_sub(
part_ptr,
node_ptr,
part_ptr->node_scaling);
if(sview_part_sub)
list_push(sview_part_info->sub_list,
sview_part_sub);
}
found = 0;
#ifdef HAVE_BG
/* if we used the current state of
* the node then we just continue.
*/
if(norm)
break;
}
#endif
}
hostlist_destroy(hl);
list_append(info_list, sview_part_info);
}
return info_list;
}
void _display_info_part(List 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;
partition_info_t *part_ptr = NULL;
GtkTreeView *treeview = NULL;
ListIterator itr = NULL;
sview_part_info_t *sview_part_info = NULL;
int update = 0;
int i = -1, j = 0;
int first_time = 0;
if(!spec_info->search_info->gchar_data) {
//info = xstrdup("No pointer given!");
goto finished;
}
if(!list_count(popup_win->grid_button_list))
first_time = 1;
need_refresh:
if(!spec_info->display_widget) {
treeview = create_treeview_2cols_attach_to_table(
popup_win->table);
spec_info->display_widget =
gtk_widget_ref(GTK_WIDGET(treeview));
} else {
treeview = GTK_TREE_VIEW(spec_info->display_widget);
update = 1;
}
itr = list_iterator_create(info_list);
while ((sview_part_info = (sview_part_info_t*) list_next(itr))) {
part_ptr = sview_part_info->part_ptr;
i++;
if(!strcmp(part_ptr->name, name)) {
j=0;
while(part_ptr->node_inx[j] >= 0) {
if(!first_time)
change_grid_color(
popup_win->grid_button_list,
part_ptr->node_inx[j],
part_ptr->node_inx[j+1], i);
else
get_button_list_from_main(
&popup_win->grid_button_list,
part_ptr->node_inx[j],
part_ptr->node_inx[j+1],
i);
j += 2;
}
_layout_part_record(treeview, sview_part_info, update);
found = 1;
break;
}
}
list_iterator_destroy(itr);
if(!found) {
if(!popup_win->not_found) {
char *temp = "PARTITION DOESN'T EXSIST\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;
}
put_buttons_in_table(popup_win->grid_table,
popup_win->grid_button_list);
}
gtk_widget_show(spec_info->display_widget);
finished:
return;
}
extern void refresh_part(GtkAction *action, gpointer user_data)
{
popup_info_t *popup_win = (popup_info_t *)user_data;
xassert(popup_win != NULL);
xassert(popup_win->spec_info != NULL);
xassert(popup_win->spec_info->title != NULL);
popup_win->force_refresh = 1;
specific_info_part(popup_win);
}
extern int get_new_info_part(partition_info_msg_t **part_ptr, int force)
{
static partition_info_msg_t *part_info_ptr = NULL;
static partition_info_msg_t *new_part_ptr = NULL;
int error_code = SLURM_NO_CHANGE_IN_DATA;
time_t now = time(NULL);
static time_t last;
static bool changed = 0;
if(!force && ((now - last) < global_sleep_time)) {
*part_ptr = part_info_ptr;
if(changed)
return SLURM_SUCCESS;
return error_code;
}
last = now;
if (part_info_ptr) {
error_code = slurm_load_partitions(part_info_ptr->last_update,
&new_part_ptr, SHOW_ALL);
if (error_code == SLURM_SUCCESS) {
slurm_free_partition_info_msg(part_info_ptr);
changed = 1;
} else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
error_code = SLURM_NO_CHANGE_IN_DATA;
new_part_ptr = part_info_ptr;
changed = 0;
}
} else {
error_code = slurm_load_partitions((time_t) NULL,
&new_part_ptr, SHOW_ALL);
changed = 1;
}
part_info_ptr = new_part_ptr;
*part_ptr = new_part_ptr;
return error_code;
}
extern GtkListStore *create_model_part(int type)
{
GtkListStore *model = NULL;
GtkTreeIter iter;
char *upper = NULL, *lower = NULL;
int i=0;
switch(type) {
case SORTID_DEFAULT:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_DEFAULT,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_DEFAULT,
-1);
break;
case SORTID_HIDDEN:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_HIDDEN,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_HIDDEN,
-1);
break;
case SORTID_TIMELIMIT:
case SORTID_MIN_NODES:
case SORTID_MAX_NODES:
break;
case SORTID_ROOT:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_ROOT,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_ROOT,
-1);
break;
case SORTID_SHARE:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "yes",
1, SORTID_SHARE,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "no",
1, SORTID_SHARE,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "force",
1, SORTID_SHARE,
-1);
break;
case SORTID_GROUPS:
break;
case SORTID_NODELIST:
break;
case SORTID_AVAIL:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "up",
1, SORTID_AVAIL,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "down",
1, SORTID_AVAIL,
-1);
break;
case SORTID_STATE:
model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "drain",
1, SORTID_STATE,
-1);
gtk_list_store_append(model, &iter);
gtk_list_store_set(model, &iter,
0, "resume",
1, SORTID_STATE,
-1);
for(i = 0; i < NODE_STATE_END; i++) {
upper = node_state_string(i);
if(!strcmp(upper, "UNKNOWN"))
continue;
gtk_list_store_append(model, &iter);
lower = str_tolower(upper);
gtk_list_store_set(model, &iter,
0, lower,
1, SORTID_STATE,
-1);
xfree(lower);
}
break;
}
return model;
}
extern void admin_edit_part(GtkCellRendererText *cell,
const char *path_string,
const char *new_text,
gpointer data)
{
GtkTreeStore *treestore = GTK_TREE_STORE(data);
GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
GtkTreeIter iter;
update_part_msg_t *part_msg = xmalloc(sizeof(update_part_msg_t));
char *temp = NULL;
char *old_text = NULL;
const char *type = NULL;
int column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell),
"column"));
if(!new_text || !strcmp(new_text, ""))
goto no_input;
gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
if(column != SORTID_STATE) {
slurm_init_part_desc_msg(part_msg);
gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
SORTID_NAME, &temp,
column, &old_text,
-1);
part_msg->name = xstrdup(temp);
g_free(temp);
}
type = _set_part_msg(part_msg, new_text, column);
if(errno)
goto print_error;
if(got_edit_signal) {
temp = got_edit_signal;
got_edit_signal = NULL;
admin_part(GTK_TREE_MODEL(treestore), &iter, temp);
xfree(temp);
goto no_input;
}
if(got_features_edit_signal) {
admin_part(GTK_TREE_MODEL(treestore), &iter, (char *)type);
goto no_input;
}
if(column != SORTID_STATE && column != SORTID_FEATURES ) {
if(old_text && !strcmp(old_text, new_text)) {
temp = g_strdup_printf("No change in value.");
display_edit_note(temp);
g_free(temp);
} else if(slurm_update_partition(part_msg) == SLURM_SUCCESS) {
gtk_tree_store_set(treestore, &iter, column,
new_text, -1);
temp = g_strdup_printf("Partition %s %s changed to %s",
part_msg->name,
type,
new_text);
display_edit_note(temp);
g_free(temp);
} else {
print_error:
temp = g_strdup_printf("Partition %s %s can't be "
"set to %s",
part_msg->name,
type,
new_text);
display_edit_note(temp);
g_free(temp);
}
}
no_input:
slurm_free_update_part_msg(part_msg);
gtk_tree_path_free (path);
g_free(old_text);
g_static_mutex_unlock(&sview_mutex);
}
extern void get_info_part(GtkTable *table, display_data_t *display_data)
{
int part_error_code = SLURM_SUCCESS;
int node_error_code = SLURM_SUCCESS;
int block_error_code = SLURM_SUCCESS;
static int view = -1;
static partition_info_msg_t *part_info_ptr = NULL;
static node_info_msg_t *node_info_ptr = NULL;
static node_select_info_msg_t *node_select_ptr = NULL;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
static GtkWidget *display_widget = NULL;
List info_list = NULL;
int changed = 1;
int j=0, i=0;
sview_part_info_t *sview_part_info = NULL;
partition_info_t *part_ptr = NULL;
ListIterator itr = NULL;
if(display_data)
local_display_data = display_data;
if(!table) {
display_data_part->set_menu = local_display_data->set_menu;
return;
}
if(display_widget && toggled) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
goto display_it;
}
if((part_error_code = get_new_info_part(&part_info_ptr, force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
// just goto the new info node
} else if (part_error_code != SLURM_SUCCESS) {
if(view == ERROR_VIEW)
goto end_it;
if(display_widget)
gtk_widget_destroy(display_widget);
view = ERROR_VIEW;
snprintf(error_char, 100, "slurm_load_partitions: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
display_widget = gtk_widget_ref(GTK_WIDGET(label));
gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
gtk_widget_show(label);
goto end_it;
}
if((node_error_code = get_new_info_node(&node_info_ptr, force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
// just goto the new info node select
} else if (node_error_code != SLURM_SUCCESS) {
if(view == ERROR_VIEW)
goto end_it;
if(display_widget)
gtk_widget_destroy(display_widget);
view = ERROR_VIEW;
snprintf(error_char, 100, "slurm_load_node: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
display_widget = gtk_widget_ref(GTK_WIDGET(label));
gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
gtk_widget_show(label);
goto end_it;
}
if((block_error_code = get_new_info_node_select(&node_select_ptr,
force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
if((!display_widget || view == ERROR_VIEW)
|| (part_error_code != SLURM_NO_CHANGE_IN_DATA)
|| (node_error_code != SLURM_NO_CHANGE_IN_DATA)) {
goto display_it;
}
changed = 0;
} else if (block_error_code != SLURM_SUCCESS) {
if(view == ERROR_VIEW)
goto end_it;
view = ERROR_VIEW;
if(display_widget)
gtk_widget_destroy(display_widget);
sprintf(error_char, "slurm_load_node_select: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
gtk_table_attach_defaults(table,
label,
0, 1, 0, 1);
gtk_widget_show(label);
display_widget = gtk_widget_ref(label);
goto end_it;
}
display_it:
info_list = _create_part_info_list(part_info_ptr,
node_info_ptr,
node_select_ptr,
changed);
if(!info_list)
return;
/* set up the grid */
itr = list_iterator_create(info_list);
while ((sview_part_info = list_next(itr))) {
part_ptr = sview_part_info->part_ptr;
j=0;
while(part_ptr->node_inx[j] >= 0) {
sview_part_info->color =
change_grid_color(grid_button_list,
part_ptr->node_inx[j],
part_ptr->node_inx[j+1],
i);
j += 2;
}
i++;
}
list_iterator_destroy(itr);
if(view == ERROR_VIEW && display_widget) {
gtk_widget_destroy(display_widget);
display_widget = NULL;
}
if(!display_widget) {
tree_view = create_treeview(local_display_data);
display_widget = gtk_widget_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_part, SORTID_CNT);
}
view = INFO_VIEW;
_update_info_part(info_list, GTK_TREE_VIEW(display_widget));
end_it:
toggled = FALSE;
force_refresh = FALSE;
return;
}
extern void specific_info_part(popup_info_t *popup_win)
{
int part_error_code = SLURM_SUCCESS;
int node_error_code = SLURM_SUCCESS;
int block_error_code = SLURM_SUCCESS;
static partition_info_msg_t *part_info_ptr = NULL;
static node_info_msg_t *node_info_ptr = NULL;
static node_select_info_msg_t *node_select_ptr = NULL;
specific_info_t *spec_info = popup_win->spec_info;
char error_char[100];
GtkWidget *label = NULL;
GtkTreeView *tree_view = NULL;
List info_list = NULL;
List send_info_list = NULL;
int changed = 1;
int j=0, i=-1;
sview_part_info_t *sview_part_info_ptr = NULL;
partition_info_t *part_ptr = NULL;
ListIterator itr = NULL;
char *host = NULL, *host2 = NULL;
hostlist_t hostlist = NULL;
int found = 0;
if(!spec_info->display_widget)
setup_popup_info(popup_win, display_data_part, 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((part_error_code = get_new_info_part(&part_info_ptr,
popup_win->force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
} else if (part_error_code != SLURM_SUCCESS) {
if(spec_info->view == ERROR_VIEW)
goto end_it;
if(spec_info->display_widget) {
gtk_widget_destroy(spec_info->display_widget);
spec_info->display_widget = NULL;
}
spec_info->view = ERROR_VIEW;
snprintf(error_char, 100, "slurm_load_partitions: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(label));
gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1);
gtk_widget_show(label);
goto end_it;
}
if((node_error_code = get_new_info_node(&node_info_ptr,
popup_win->force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
} else if (node_error_code != SLURM_SUCCESS) {
if(spec_info->view == ERROR_VIEW)
goto end_it;
if(spec_info->display_widget)
gtk_widget_destroy(spec_info->display_widget);
spec_info->view = ERROR_VIEW;
snprintf(error_char, 100, "slurm_load_node: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
spec_info->display_widget = gtk_widget_ref(GTK_WIDGET(label));
gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1);
gtk_widget_show(label);
goto end_it;
}
if((block_error_code = get_new_info_node_select(&node_select_ptr,
force_refresh))
== SLURM_NO_CHANGE_IN_DATA) {
if((!spec_info->display_widget
|| spec_info->view == ERROR_VIEW)
|| (part_error_code != SLURM_NO_CHANGE_IN_DATA)
|| (node_error_code != SLURM_NO_CHANGE_IN_DATA))
goto display_it;
changed = 0;
} else if (block_error_code != SLURM_SUCCESS) {
if(spec_info->view == ERROR_VIEW)
goto end_it;
if(spec_info->display_widget)
gtk_widget_destroy(spec_info->display_widget);
spec_info->view = ERROR_VIEW;
sprintf(error_char, "slurm_load_node_select: %s",
slurm_strerror(slurm_get_errno()));
label = gtk_label_new(error_char);
spec_info->display_widget = gtk_widget_ref(label);
gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1);
gtk_widget_show(label);
goto end_it;
}
display_it:
info_list = _create_part_info_list(part_info_ptr,
node_info_ptr,
node_select_ptr,
changed);
if(!info_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);
spec_info->display_widget =
gtk_widget_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);
}
if(popup_win->grid_button_list) {
list_destroy(popup_win->grid_button_list);
}
#ifdef HAVE_BG
popup_win->grid_button_list = copy_main_button_list();
#else
popup_win->grid_button_list = list_create(destroy_grid_button);
#endif
spec_info->view = INFO_VIEW;
if(spec_info->type == INFO_PAGE) {
_display_info_part(info_list, popup_win);
goto end_it;
}
/* just linking to another list, don't free the inside, just
the list */
send_info_list = list_create(NULL);
itr = list_iterator_create(info_list);
while ((sview_part_info_ptr = list_next(itr))) {
i++;
part_ptr = sview_part_info_ptr->part_ptr;
switch(spec_info->type) {
case NODE_PAGE:
if(!part_ptr->nodes)
continue;
hostlist = hostlist_create(
spec_info->search_info->gchar_data);
host = hostlist_shift(hostlist);
hostlist_destroy(hostlist);
if(!host)
continue;
hostlist = hostlist_create(part_ptr->nodes);
found = 0;
while((host2 = hostlist_shift(hostlist))) {
if(!strcmp(host, host2)) {
free(host2);
found = 1;
break;
}
free(host2);
}
hostlist_destroy(hostlist);
if(!found)
continue;
break;
case PART_PAGE:
case BLOCK_PAGE:
case JOB_PAGE:
if(strcmp(part_ptr->name,
spec_info->search_info->gchar_data))
continue;
break;
default:
g_print("Unkown type %d\n", spec_info->type);
list_iterator_destroy(itr);
goto end_it;
}
list_push(send_info_list, sview_part_info_ptr);
j=0;
while(part_ptr->node_inx[j] >= 0) {
#ifdef HAVE_BG
change_grid_color(
popup_win->grid_button_list,
part_ptr->node_inx[j],
part_ptr->node_inx[j+1], i);
#else
get_button_list_from_main(
&popup_win->grid_button_list,
part_ptr->node_inx[j],
part_ptr->node_inx[j+1], i);
#endif
j += 2;
}
}
list_iterator_destroy(itr);
put_buttons_in_table(popup_win->grid_table,
popup_win->grid_button_list);
_update_info_part(send_info_list,
GTK_TREE_VIEW(spec_info->display_widget));
list_destroy(send_info_list);
end_it:
popup_win->toggled = 0;
popup_win->force_refresh = 0;
return;
}
extern void set_menus_part(void *arg, GtkTreePath *path,
GtkMenu *menu, int type)
{
GtkTreeView *tree_view = (GtkTreeView *)arg;
popup_info_t *popup_win = (popup_info_t *)arg;
switch(type) {
case TAB_CLICKED:
make_fields_menu(menu, display_data_part, SORTID_CNT);
break;
case ROW_CLICKED:
make_options_menu(tree_view, path, menu, options_data_part);
break;
case POPUP_CLICKED:
make_popup_fields_menu(popup_win, menu);
break;
default:
g_error("UNKNOWN type %d given to set_fields\n", type);
}
}
extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id)
{
char *name = NULL;
char *state = NULL;
char title[100];
int only_line = 0;
ListIterator itr = NULL;
popup_info_t *popup_win = NULL;
GError *error = NULL;
gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
switch(id) {
case JOB_PAGE:
snprintf(title, 100, "Job(s) in partition %s", name);
break;
case NODE_PAGE:
gtk_tree_model_get(model, iter, SORTID_ONLY_LINE,
&only_line, -1);
if(!only_line)
gtk_tree_model_get(model, iter,
SORTID_STATE, &state, -1);
#ifdef HAVE_BG
if(!state || !strlen(state))
snprintf(title, 100,
"Base partition(s) in partition %s",
name);
else
snprintf(title, 100,
"Base partition(s) in partition %s "
"that are in '%s' state",
name, state);
#else
if(!state || !strlen(state))
snprintf(title, 100, "Node(s) in partition %s ",
name);
else
snprintf(title, 100,
"Node(s) in partition %s that are in "
"'%s' state",
name, state);
#endif
break;
case BLOCK_PAGE:
snprintf(title, 100, "Block(s) in partition %s", name);
break;
case SUBMIT_PAGE:
snprintf(title, 100, "Submit job in partition %s", name);
break;
case INFO_PAGE:
snprintf(title, 100, "Full info for partition %s", name);
break;
default:
g_print("part got %d\n", id);
}
itr = list_iterator_create(popup_list);
while((popup_win = list_next(itr))) {
if(popup_win->spec_info)
if(!strcmp(popup_win->spec_info->title, title)) {
break;
}
}
list_iterator_destroy(itr);
if(!popup_win) {
if(id == INFO_PAGE)
popup_win = create_popup_info(id, PART_PAGE, title);
else
popup_win = create_popup_info(PART_PAGE, id, title);
} else {
g_free(name);
g_free(state);
gtk_window_present(GTK_WINDOW(popup_win->popup));
return;
}
switch(id) {
case JOB_PAGE:
case BLOCK_PAGE:
case INFO_PAGE:
popup_win->spec_info->search_info->gchar_data = name;
//specific_info_job(popup_win);
break;
case NODE_PAGE:
g_free(name);
gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1);
popup_win->spec_info->search_info->gchar_data = name;
if(state && strlen(state)) {
popup_win->spec_info->search_info->search_type =
SEARCH_NODE_STATE;
gtk_tree_model_get(
model, iter, SORTID_STATE_NUM,
&popup_win->spec_info->search_info->int_data,
-1);
} else {
popup_win->spec_info->search_info->search_type =
SEARCH_NODE_NAME;
}
g_free(state);
//specific_info_node(popup_win);
break;
case SUBMIT_PAGE:
break;
default:
g_print("part got unknown type %d\n", id);
}
if (!g_thread_create((gpointer)popup_thr, popup_win, FALSE, &error))
{
g_printerr ("Failed to create part popup thread: %s\n",
error->message);
return;
}
}
extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
{
update_part_msg_t *part_msg = xmalloc(sizeof(update_part_msg_t));
char *partid = NULL;
char *nodelist = NULL;
char *state = NULL;
char tmp_char[100];
char *temp = NULL;
int edit_type = 0;
int response = 0;
GtkWidget *label = NULL;
GtkWidget *entry = NULL;
GtkWidget *popup = gtk_dialog_new_with_buttons(
type,
GTK_WINDOW(main_window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
NULL);
gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
gtk_tree_model_get(model, iter, SORTID_NAME, &partid, -1);
gtk_tree_model_get(model, iter, SORTID_NODELIST, &nodelist, -1);
gtk_tree_model_get(model, iter, SORTID_AVAIL, &state, -1);
slurm_init_part_desc_msg(part_msg);
part_msg->name = xstrdup(partid);
if(!strcasecmp("Change Availablity Up/Down", type)) {
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);
if(!strcasecmp("down", type))
temp = "up";
else
temp = "down";
snprintf(tmp_char, sizeof(tmp_char),
"Are you sure you want to set partition %s %s?",
partid, temp);
label = gtk_label_new(tmp_char);
edit_type = EDIT_AVAIL;
} else if(!strcasecmp("Edit Part", type)) {
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 partition %s think before you type",
partid);
label = gtk_label_new(tmp_char);
edit_type = EDIT_EDIT;
entry = _admin_full_edit_part(part_msg, model, iter);
} else if(!strncasecmp("Update", type, 6)) {
char *old_features = NULL;
if(got_features_edit_signal)
old_features = got_features_edit_signal;
else
gtk_tree_model_get(model, iter, SORTID_FEATURES,
&old_features, -1);
update_features_node(GTK_DIALOG(popup),
nodelist, old_features);
if(got_features_edit_signal) {
got_features_edit_signal = NULL;
xfree(old_features);
} else
g_free(old_features);
goto end_it;
} else {
/* something that has to deal with a node state change */
update_state_node(GTK_DIALOG(popup), nodelist, type);
goto end_it;
}
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) {
if(slurm_update_partition(part_msg) == SLURM_SUCCESS) {
temp = g_strdup_printf(
"Partition %s updated successfully",
partid);
} else {
temp = g_strdup_printf(
"Problem updating partition %s.",
partid);
}
display_edit_note(temp);
g_free(temp);
}
end_it:
g_free(state);
g_free(partid);
g_free(nodelist);
slurm_free_update_part_msg(part_msg);
gtk_widget_destroy(popup);
if(got_edit_signal) {
type = got_edit_signal;
got_edit_signal = NULL;
admin_part(model, iter, type);
xfree(type);
}
if(got_features_edit_signal) {
type = "Update Features";
admin_part(model, iter, type);
}
return;
}