1 /*****************************************************************************\
2 * part_info.c - Functions related to partition display
3 * mode of sview.
4 *****************************************************************************
5 * Copyright (C) 2004-2007 The Regents of the University of California.
6 * Copyright (C) 2008-2010 Lawrence Livermore National Security.
7 * Portions Copyright (C) 2010-2016 SchedMD <https://www.schedmd.com>.
8 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
9 * Written by Danny Auble <da@llnl.gov>
10 *
11 * CODE-OCEC-09-009. All rights reserved.
12 *
13 * This file is part of Slurm, a resource management program.
14 * For details, see <https://slurm.schedmd.com/>.
15 * Please also read the included file: DISCLAIMER.
16 *
17 * Slurm is free software; you can redistribute it and/or modify it under
18 * the terms of the GNU General Public License as published by the Free
19 * Software Foundation; either version 2 of the License, or (at your option)
20 * any later version.
21 *
22 * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
23 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
25 * details.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with Slurm; if not, write to the Free Software Foundation, Inc.,
29 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 \*****************************************************************************/
31
32 #include "src/sview/sview.h"
33 #include "src/common/parse_time.h"
34 #include <grp.h>
35
36 #define _DEBUG 0
37
38 static GtkListStore *_create_model_part2(int type);
39
40 typedef struct {
41 uint32_t cpu_cnt;
42 uint32_t cpu_alloc_cnt;
43 uint32_t cpu_idle_cnt;
44 uint32_t disk_total;
45 char *features;
46 char *features_act;
47 hostlist_t hl;
48 uint64_t mem_total;
49 uint32_t node_cnt;
50 uint32_t node_alloc_cnt;
51 uint32_t node_error_cnt;
52 uint32_t node_idle_cnt;
53 List node_ptr_list;
54 uint32_t node_state;
55 partition_info_t* part_ptr;
56 char *reason;
57 } sview_part_sub_t;
58
59 /* Collection of data for printing reports. Like data is combined here */
60 typedef struct {
61 int color_inx;
62 GtkTreeIter iter_ptr;
63 bool iter_set;
64 char *part_name;
65 char *cluster_name;
66 /* part_info contains partition, avail, max_time, job_size,
67 * root, share, groups */
68 partition_info_t* part_ptr;
69 int pos;
70 List sub_list;
71 sview_part_sub_t sub_part_total;
72 } sview_part_info_t;
73
74 enum {
75 EDIT_PART_STATE = 1,
76 EDIT_REMOVE_PART,
77 EDIT_EDIT
78 };
79
80 /* These need to be in alpha order (except POS and CNT) */
81 enum {
82 SORTID_POS = POS_LOC,
83 SORTID_ALLOW_ACCOUNTS,
84 SORTID_ALLOW_GROUPS,
85 SORTID_ALLOW_QOS,
86 SORTID_ALTERNATE,
87 SORTID_CLUSTER_NAME,
88 SORTID_COLOR,
89 SORTID_COLOR_INX,
90 SORTID_CPUS,
91 SORTID_DEFAULT,
92 SORTID_DENY_ACCOUNTS,
93 SORTID_DENY_QOS,
94 SORTID_EXCLUSIVE_USER,
95 SORTID_FEATURES,
96 SORTID_FEATURES_ACT,
97 SORTID_GRACE_TIME,
98 SORTID_HIDDEN,
99 SORTID_JOB_DEFAULTS,
100 SORTID_JOB_SIZE,
101 SORTID_MAX_CPUS_PER_NODE,
102 SORTID_MEM,
103 SORTID_NAME,
104 SORTID_NODELIST,
105 SORTID_NODES_ALLOWED,
106 SORTID_NODE_INX,
107 SORTID_NODE_STATE,
108 SORTID_NODE_STATE_NUM,
109 SORTID_NODES,
110 SORTID_NODES_MAX,
111 SORTID_NODES_MIN,
112 SORTID_ONLY_LINE,
113 SORTID_OVER_SUBSCRIBE,
114 SORTID_OVER_TIME_LIMIT,
115 SORTID_PART_STATE,
116 SORTID_PREEMPT_MODE,
117 SORTID_PRIORITY_JOB_FACTOR,
118 SORTID_PRIORITY_TIER,
119 SORTID_QOS_CHAR,
120 SORTID_REASON,
121 SORTID_ROOT,
122 SORTID_TMP_DISK,
123 SORTID_TIMELIMIT,
124 SORTID_UPDATED,
125 SORTID_CNT
126 };
127
128 /*
129 * These are the settings to apply for the user
130 * on the first startup after a fresh slurm install.
131 */
132 static char *_initial_page_opts = "Partition,Default,Part_State,Time_Limit,"
133 "Node_Count,Node_State,NodeList";
134
135 static display_data_t display_data_part[] = {
136 {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE, refresh_part},
137 {G_TYPE_STRING, SORTID_CLUSTER_NAME, "ClusterName", false,
138 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
139 {G_TYPE_STRING, SORTID_NAME, "Partition", false,
140 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
141 {G_TYPE_STRING, SORTID_COLOR, NULL, true, EDIT_COLOR, refresh_part,
142 create_model_part, admin_edit_part},
143 {G_TYPE_STRING, SORTID_ALTERNATE, "Alternate", false,
144 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
145 {G_TYPE_STRING, SORTID_DEFAULT, "Default", false,
146 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
147 {G_TYPE_STRING, SORTID_EXCLUSIVE_USER, "ExclusiveUser", false,
148 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
149 {G_TYPE_STRING, SORTID_GRACE_TIME, "GraceTime", false,
150 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
151 {G_TYPE_STRING, SORTID_HIDDEN, "Hidden", false,
152 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
153 {G_TYPE_STRING, SORTID_PART_STATE, "Part State", false,
154 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
155 {G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", false,
156 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
157 {G_TYPE_STRING, SORTID_NODES, "Node Count", false,
158 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
159 {G_TYPE_STRING, SORTID_CPUS, "CPU Count", false,
160 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
161 {G_TYPE_STRING, SORTID_NODE_STATE, "Node State", false,
162 EDIT_MODEL, refresh_part,
163 create_model_part, admin_edit_part},
164 {G_TYPE_STRING, SORTID_JOB_DEFAULTS, "Job Defaults", false,
165 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
166 {G_TYPE_STRING, SORTID_JOB_SIZE, "Job Size", false,
167 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
168 {G_TYPE_STRING, SORTID_PREEMPT_MODE, "PreemptMode", false,
169 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
170 {G_TYPE_STRING, SORTID_PRIORITY_JOB_FACTOR, "PriorityJobFactor", false,
171 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
172 {G_TYPE_STRING, SORTID_PRIORITY_TIER, "PriorityTier", false,
173 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
174 {G_TYPE_STRING, SORTID_NODES_MIN, "Nodes (minimum)", false,
175 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
176 {G_TYPE_STRING, SORTID_NODES_MAX, "Nodes Max", false,
177 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
178 {G_TYPE_STRING, SORTID_MAX_CPUS_PER_NODE, "Max CPUs Per Node", false,
179 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
180 {G_TYPE_STRING, SORTID_OVER_SUBSCRIBE, "OverSubscribe", false,
181 EDIT_MODEL, refresh_part, create_model_part, admin_edit_part},
182 {G_TYPE_STRING, SORTID_OVER_TIME_LIMIT, "OverTimeLimit", false,
183 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
184 {G_TYPE_STRING, SORTID_ROOT, "Root", false, EDIT_MODEL, refresh_part,
185 create_model_part, admin_edit_part},
186 {G_TYPE_STRING, SORTID_QOS_CHAR, "Qos", false,
187 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
188 {G_TYPE_STRING, SORTID_ALLOW_ACCOUNTS, "Allowed Accounts", false,
189 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
190 {G_TYPE_STRING, SORTID_ALLOW_GROUPS, "Allowed Groups", false,
191 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
192 {G_TYPE_STRING, SORTID_ALLOW_QOS, "Allowed Qos", false,
193 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
194 {G_TYPE_STRING, SORTID_DENY_ACCOUNTS, "Denied Accounts", false,
195 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
196 {G_TYPE_STRING, SORTID_DENY_QOS, "Denied Qos", false,
197 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
198 {G_TYPE_STRING, SORTID_NODES_ALLOWED, "Nodes Allowed Allocating", false,
199 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
200 {G_TYPE_STRING, SORTID_TMP_DISK, "Temp Disk", false,
201 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
202 {G_TYPE_STRING, SORTID_MEM, "Memory", false, EDIT_NONE, refresh_part,
203 create_model_part, admin_edit_part},
204 {G_TYPE_STRING, SORTID_FEATURES, "Available Features", false,
205 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
206 {G_TYPE_STRING, SORTID_FEATURES_ACT, "Active Features", false,
207 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
208 {G_TYPE_STRING, SORTID_REASON, "Reason", false,
209 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
210 {G_TYPE_STRING, SORTID_NODELIST, "NodeList", false,
211 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
212 {G_TYPE_INT, SORTID_NODE_STATE_NUM, NULL, false,
213 EDIT_NONE, refresh_part, create_model_part, admin_edit_part},
214 {G_TYPE_INT, SORTID_ONLY_LINE, NULL, false, EDIT_NONE, refresh_part,
215 create_model_part, admin_edit_part},
216 {G_TYPE_INT, SORTID_COLOR_INX, NULL, false, EDIT_NONE, refresh_part,
217 create_model_part, admin_edit_part},
218 {G_TYPE_POINTER, SORTID_NODE_INX, NULL, false, EDIT_NONE,
219 refresh_part, create_model_part, admin_edit_part},
220 {G_TYPE_INT, SORTID_UPDATED, NULL, false, EDIT_NONE, refresh_part,
221 create_model_part, admin_edit_part},
222 {G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
223 };
224
225 static display_data_t create_data_part[] = {
226 {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE, refresh_part},
227 {G_TYPE_STRING, SORTID_CLUSTER_NAME, "ClusterName", false,
228 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
229 {G_TYPE_STRING, SORTID_NAME, "Name", false,
230 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
231 {G_TYPE_STRING, SORTID_ALTERNATE, "Alternate", false,
232 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
233 {G_TYPE_STRING, SORTID_DEFAULT, "Default", false,
234 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
235 {G_TYPE_STRING, SORTID_EXCLUSIVE_USER, "ExclusiveUser", false,
236 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
237 {G_TYPE_STRING, SORTID_GRACE_TIME, "GraceTime", false,
238 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
239 {G_TYPE_STRING, SORTID_HIDDEN, "Hidden", false,
240 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
241 {G_TYPE_STRING, SORTID_JOB_DEFAULTS, "Job Defaults", false,
242 EDIT_TEXTBOX, refresh_part, create_model_part, admin_edit_part},
243 {G_TYPE_STRING, SORTID_PART_STATE, "State", false,
244 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
245 {G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", false,
246 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
247 {G_TYPE_STRING, SORTID_PREEMPT_MODE, "PreemptMode", false,
248 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
249 {G_TYPE_STRING, SORTID_PRIORITY_JOB_FACTOR, "PriorityJobFactor", false,
250 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
251 {G_TYPE_STRING, SORTID_PRIORITY_TIER, "PriorityTier", false,
252 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
253 {G_TYPE_STRING, SORTID_NODES_MIN, "Nodes (minimum)", false,
254 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
255 {G_TYPE_STRING, SORTID_NODES_MAX, "Nodes Max", false,
256 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
257 {G_TYPE_STRING, SORTID_MAX_CPUS_PER_NODE, "Max CPUs Per Node", false,
258 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
259 {G_TYPE_STRING, SORTID_ROOT, "Root", false,
260 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
261 {G_TYPE_STRING, SORTID_OVER_SUBSCRIBE, "OverSubscribe", false,
262 EDIT_MODEL, refresh_part, _create_model_part2, admin_edit_part},
263 {G_TYPE_STRING, SORTID_OVER_TIME_LIMIT, "OverTimeLimit", false,
264 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
265 {G_TYPE_STRING, SORTID_ALLOW_ACCOUNTS, "Accounts Allowed", false,
266 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
267 {G_TYPE_STRING, SORTID_ALLOW_GROUPS, "Groups Allowed", false,
268 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
269 {G_TYPE_STRING, SORTID_ALLOW_QOS, "Qos Allowed", false,
270 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
271 {G_TYPE_STRING, SORTID_DENY_ACCOUNTS, "Accounts Denied", false,
272 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
273 {G_TYPE_STRING, SORTID_DENY_QOS, "Qos Denied", false,
274 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
275 {G_TYPE_STRING, SORTID_NODES_ALLOWED, "Nodes Allowed Allocating", false,
276 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
277 {G_TYPE_STRING, SORTID_FEATURES, "Available Features", false,
278 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
279 {G_TYPE_STRING, SORTID_FEATURES_ACT, "Active Features", false,
280 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
281 {G_TYPE_NONE, SORTID_REASON, "Reason", false,
282 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
283 {G_TYPE_STRING, SORTID_NODELIST, "NodeList", false,
284 EDIT_TEXTBOX, refresh_part, _create_model_part2, admin_edit_part},
285 {G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
286 };
287
288 static display_data_t options_data_part[] = {
289 {G_TYPE_INT, SORTID_POS, NULL, false, EDIT_NONE},
290 {G_TYPE_STRING, INFO_PAGE, "Full Info", true, PART_PAGE},
291 {G_TYPE_STRING, PART_PAGE, "Edit Partition", true, ADMIN_PAGE},
292 {G_TYPE_STRING, PART_PAGE, "Remove Partition", true, ADMIN_PAGE},
293 {G_TYPE_STRING, PART_PAGE, "Drain Nodes",
294 true, ADMIN_PAGE | EXTRA_NODES},
295 {G_TYPE_STRING, PART_PAGE, "Resume Nodes",
296 true, ADMIN_PAGE | EXTRA_NODES},
297 {G_TYPE_STRING, PART_PAGE, "Put Nodes Down",
298 true, ADMIN_PAGE | EXTRA_NODES},
299 {G_TYPE_STRING, PART_PAGE, "Make Nodes Idle",
300 true, ADMIN_PAGE | EXTRA_NODES},
301 {G_TYPE_STRING, PART_PAGE, "Update Node Features",
302 true, ADMIN_PAGE | EXTRA_NODES},
303 {G_TYPE_STRING, PART_PAGE, "Change Partition State",
304 true, ADMIN_PAGE},
305 {G_TYPE_STRING, JOB_PAGE, "Jobs", true, PART_PAGE},
306 {G_TYPE_STRING, NODE_PAGE, "Nodes", true, PART_PAGE},
307 //{G_TYPE_STRING, SUBMIT_PAGE, "Job Submit", false, PART_PAGE},
308 {G_TYPE_STRING, RESV_PAGE, "Reservations", true, PART_PAGE},
309 {G_TYPE_NONE, -1, NULL, false, EDIT_NONE}
310 };
311
312 static display_data_t *local_display_data = NULL;
313 static char *got_edit_signal = NULL;
314 static char *got_features_edit_signal = NULL;
315 static GtkTreeModel *last_model = NULL;
316
317 static void _append_part_sub_record(sview_part_sub_t *sview_part_sub,
318 GtkTreeStore *treestore, GtkTreeIter *iter,
319 int line);
320 static void _update_part_sub_record(sview_part_sub_t *sview_part_sub,
321 GtkTreeStore *treestore,
322 GtkTreeIter *iter);
323
_build_min_max_32_string(char * buffer,int buf_size,uint32_t min,uint32_t max,bool range)324 static int _build_min_max_32_string(char *buffer, int buf_size,
325 uint32_t min, uint32_t max, bool range)
326 {
327 char tmp_min[8];
328 char tmp_max[8];
329 convert_num_unit((float)min, tmp_min, sizeof(tmp_min), UNIT_NONE,
330 NO_VAL, working_sview_config.convert_flags);
331 convert_num_unit((float)max, tmp_max, sizeof(tmp_max), UNIT_NONE,
332 NO_VAL, working_sview_config.convert_flags);
333
334 if (max == min)
335 return snprintf(buffer, buf_size, "%s", tmp_max);
336 else if (range) {
337 if (max == INFINITE)
338 return snprintf(buffer, buf_size, "%s-infinite",
339 tmp_min);
340 else
341 return snprintf(buffer, buf_size, "%s-%s",
342 tmp_min, tmp_max);
343 } else
344 return snprintf(buffer, buf_size, "%s+", tmp_min);
345 }
346
_set_active_combo_part(GtkComboBox * combo,GtkTreeModel * model,GtkTreeIter * iter,int type)347 static void _set_active_combo_part(GtkComboBox *combo,
348 GtkTreeModel *model, GtkTreeIter *iter,
349 int type)
350 {
351 char *temp_char = NULL;
352 int action = 0;
353 int i = 0, unknown_found = 0;
354 char *upper = NULL;
355
356 if (model)
357 gtk_tree_model_get(model, iter, type, &temp_char, -1);
358 if (!temp_char)
359 goto end_it;
360 switch(type) {
361 case SORTID_DEFAULT:
362 case SORTID_EXCLUSIVE_USER:
363 case SORTID_HIDDEN:
364 case SORTID_ROOT:
365 if (!xstrcmp(temp_char, "yes"))
366 action = 0;
367 else if (!xstrcmp(temp_char, "no"))
368 action = 1;
369 else
370 action = 0;
371
372 break;
373 case SORTID_OVER_SUBSCRIBE:
374 if (!xstrncmp(temp_char, "force", 5))
375 action = 0;
376 else if (!xstrcmp(temp_char, "no"))
377 action = 1;
378 else if (!xstrncmp(temp_char, "yes", 3))
379 action = 2;
380 else if (!xstrcmp(temp_char, "exclusive"))
381 action = 3;
382 else
383 action = 0;
384 break;
385 case SORTID_PART_STATE:
386 if (!xstrcmp(temp_char, "up"))
387 action = 0;
388 else if (!xstrcmp(temp_char, "down"))
389 action = 1;
390 else if (!xstrcmp(temp_char, "inactive"))
391 action = 2;
392 else if (!xstrcmp(temp_char, "drain"))
393 action = 3;
394 else
395 action = 0;
396 break;
397 case SORTID_NODE_STATE:
398 if (!xstrcasecmp(temp_char, "drain"))
399 action = 0;
400 else if (!xstrcasecmp(temp_char, "resume"))
401 action = 1;
402 else
403 for(i = 0; i < NODE_STATE_END; i++) {
404 upper = node_state_string(i);
405 if (!xstrcmp(upper, "UNKNOWN")) {
406 unknown_found++;
407 continue;
408 }
409
410 if (!xstrcasecmp(temp_char, upper)) {
411 action = i + 2 - unknown_found;
412 break;
413 }
414 }
415
416 break;
417 case SORTID_PREEMPT_MODE:
418 if (!xstrcasecmp(temp_char, "cancel"))
419 action = 0;
420 else if (!xstrcasecmp(temp_char, "off"))
421 action = 2;
422 else if (!xstrcasecmp(temp_char, "requeue"))
423 action = 3;
424 else if (!xstrcasecmp(temp_char, "suspend"))
425 action = 4;
426 else
427 action = 2; /* off */
428 break;
429 default:
430 break;
431 }
432 g_free(temp_char);
433 end_it:
434 gtk_combo_box_set_active(combo, action);
435
436 }
437
_set_part_over_subscribe_popup(void)438 static uint16_t _set_part_over_subscribe_popup(void)
439 {
440 GtkWidget *table = gtk_table_new(1, 2, false);
441 GtkWidget *label = NULL;
442 GtkObject *adjustment = gtk_adjustment_new(4,
443 1, 1000,
444 1, 60,
445 0);
446 GtkWidget *spin_button =
447 gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
448 GtkWidget *popup = gtk_dialog_new_with_buttons(
449 "Count",
450 GTK_WINDOW (main_window),
451 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
452 NULL);
453 int response = 0;
454 uint16_t count = 4;
455
456 gtk_window_set_type_hint(GTK_WINDOW(popup),
457 GDK_WINDOW_TYPE_HINT_NORMAL);
458
459 label = gtk_dialog_add_button(GTK_DIALOG(popup),
460 GTK_STOCK_OK, GTK_RESPONSE_OK);
461 gtk_window_set_default(GTK_WINDOW(popup), label);
462
463 label = gtk_label_new("OverSubscribe Job Count ");
464
465 gtk_container_set_border_width(GTK_CONTAINER(table), 10);
466
467 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
468 table, false, false, 0);
469
470 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
471 gtk_table_attach_defaults(GTK_TABLE(table), spin_button, 1, 2, 0, 1);
472
473 gtk_widget_show_all(popup);
474 response = gtk_dialog_run (GTK_DIALOG(popup));
475
476 if (response == GTK_RESPONSE_OK) {
477 count = gtk_spin_button_get_value_as_int(
478 GTK_SPIN_BUTTON(spin_button));
479 }
480
481 gtk_widget_destroy(popup);
482
483 return count;
484 }
485
486 /* don't free this char */
_set_part_msg(update_part_msg_t * part_msg,const char * new_text,int column)487 static const char *_set_part_msg(update_part_msg_t *part_msg,
488 const char *new_text,
489 int column)
490 {
491 char *type = "", *temp_char;
492 int temp_int = 0;
493
494 global_edit_error = 0;
495
496 if (!part_msg)
497 return NULL;
498
499 switch(column) {
500 case SORTID_ALTERNATE:
501 type = "alternate";
502 part_msg->alternate = xstrdup(new_text);
503 break;
504 case SORTID_DEFAULT:
505 if (!xstrcasecmp(new_text, "yes")) {
506 part_msg->flags |= PART_FLAG_DEFAULT;
507 part_msg->flags &= (~PART_FLAG_DEFAULT_CLR);
508 } else if (!xstrcasecmp(new_text, "no")) {
509 part_msg->flags &= (~PART_FLAG_DEFAULT);
510 part_msg->flags |= PART_FLAG_DEFAULT_CLR;
511 }
512 type = "default";
513 break;
514 case SORTID_EXCLUSIVE_USER:
515 if (!xstrcasecmp(new_text, "yes")) {
516 part_msg->flags |= PART_FLAG_EXCLUSIVE_USER;
517 part_msg->flags &= (~PART_FLAG_EXC_USER_CLR);
518 } else if (!xstrcasecmp(new_text, "no")) {
519 part_msg->flags &= (~PART_FLAG_EXCLUSIVE_USER);
520 part_msg->flags |= PART_FLAG_EXC_USER_CLR;
521 }
522 type = "hidden";
523 break;
524 case SORTID_GRACE_TIME:
525 temp_int = time_str2mins((char *)new_text);
526 type = "grace_time";
527 if (temp_int <= 0)
528 goto return_error;
529 /* convert to seconds */
530 part_msg->grace_time = (uint32_t)(temp_int * 60);
531 break;
532 case SORTID_HIDDEN:
533 if (!xstrcasecmp(new_text, "yes")) {
534 part_msg->flags |= PART_FLAG_HIDDEN;
535 part_msg->flags &= (~PART_FLAG_HIDDEN_CLR);
536 } else if (!xstrcasecmp(new_text, "no")) {
537 part_msg->flags &= (~PART_FLAG_HIDDEN);
538 part_msg->flags |= PART_FLAG_HIDDEN_CLR;
539 }
540 type = "hidden";
541 break;
542 case SORTID_JOB_DEFAULTS:
543 type = "job_defaults";
544 part_msg->job_defaults_str = xstrdup(new_text);
545 break;
546 case SORTID_TIMELIMIT:
547 if ((xstrcasecmp(new_text, "infinite") == 0))
548 temp_int = INFINITE;
549 else
550 temp_int = time_str2mins((char *)new_text);
551
552 type = "timelimit";
553 if ((temp_int <= 0) && (temp_int != INFINITE))
554 goto return_error;
555 part_msg->max_time = (uint32_t)temp_int;
556 break;
557 case SORTID_PREEMPT_MODE:
558 if (!xstrcasecmp(new_text, "cancel"))
559 part_msg->preempt_mode = PREEMPT_MODE_CANCEL;
560 else if (!xstrcasecmp(new_text, "off"))
561 part_msg->preempt_mode = PREEMPT_MODE_OFF;
562 else if (!xstrcasecmp(new_text, "requeue"))
563 part_msg->preempt_mode = PREEMPT_MODE_REQUEUE;
564 else if (!xstrcasecmp(new_text, "suspend"))
565 part_msg->preempt_mode = PREEMPT_MODE_SUSPEND;
566 type = "preempt_mode";
567 break;
568 case SORTID_PRIORITY_JOB_FACTOR:
569 temp_int = strtol(new_text, (char **)NULL, 10);
570 type = "priority_job_factor";
571 part_msg->priority_job_factor = (uint16_t)temp_int;
572 break;
573 case SORTID_PRIORITY_TIER:
574 temp_int = strtol(new_text, (char **)NULL, 10);
575 type = "priority_tier";
576 part_msg->priority_tier = (uint16_t)temp_int;
577 break;
578 case SORTID_NAME:
579 type = "name";
580 part_msg->name = xstrdup(new_text);
581 break;
582 case SORTID_MAX_CPUS_PER_NODE:
583 temp_int = strtol(new_text, (char **)NULL, 10);
584 type = "max_cpus_per_node";
585
586 if (temp_int <= 0)
587 goto return_error;
588 part_msg->max_cpus_per_node = temp_int;
589 break;
590 case SORTID_NODES_MIN:
591 temp_int = strtol(new_text, (char **)NULL, 10);
592 type = "min_nodes";
593
594 if (temp_int <= 0)
595 goto return_error;
596 part_msg->min_nodes = (uint32_t)temp_int;
597 break;
598 case SORTID_NODES_MAX:
599 if (!xstrcasecmp(new_text, "infinite")) {
600 temp_int = INFINITE;
601 } else {
602 temp_int = strtol(new_text, &temp_char, 10);
603 if ((temp_char[0] == 'k') || (temp_char[0] == 'K'))
604 temp_int *= 1024;
605 if ((temp_char[0] == 'm') || (temp_char[0] == 'M'))
606 temp_int *= (1024 * 1024);
607 }
608
609 type = "max_nodes";
610 if ((temp_int <= 0) && (temp_int != INFINITE))
611 goto return_error;
612 part_msg->max_nodes = (uint32_t)temp_int;
613 break;
614 case SORTID_ROOT:
615 if (!xstrcasecmp(new_text, "yes")) {
616 part_msg->flags |= PART_FLAG_ROOT_ONLY;
617 part_msg->flags &= (~PART_FLAG_ROOT_ONLY_CLR);
618 } else if (!xstrcasecmp(new_text, "no")) {
619 part_msg->flags &= (~PART_FLAG_ROOT_ONLY);
620 part_msg->flags |= PART_FLAG_ROOT_ONLY_CLR;
621 }
622
623 type = "root";
624 break;
625 case SORTID_OVER_SUBSCRIBE:
626 if (!xstrcasecmp(new_text, "yes")) {
627 part_msg->max_share = _set_part_over_subscribe_popup();
628 } else if (!xstrcasecmp(new_text, "exclusive")) {
629 part_msg->max_share = 0;
630 } else if (!xstrcasecmp(new_text, "force")) {
631 part_msg->max_share = _set_part_over_subscribe_popup()
632 | SHARED_FORCE;
633 } else if (!xstrcasecmp(new_text, "no"))
634 part_msg->max_share = 1;
635 else
636 goto return_error;
637 type = "oversubscribe";
638 break;
639 case SORTID_OVER_TIME_LIMIT:
640 if (!xstrcasecmp(new_text, "INFINITE") ||
641 !xstrcasecmp(new_text, "UNLIMITED")) {
642 part_msg->over_time_limit = INFINITE16;
643 } else if (new_text[0] >= '0' && new_text[0] <= '9')
644 part_msg->over_time_limit = atoi(new_text);
645 else
646 goto return_error;
647 type = "overtimelimit";
648 break;
649 case SORTID_ALLOW_ACCOUNTS:
650 type = "accounts";
651 part_msg->allow_accounts = xstrdup(new_text);
652 break;
653 case SORTID_ALLOW_GROUPS:
654 type = "groups";
655 part_msg->allow_groups = xstrdup(new_text);
656 break;
657 case SORTID_ALLOW_QOS:
658 type = "qos";
659 part_msg->allow_qos = xstrdup(new_text);
660 break;
661 case SORTID_DENY_ACCOUNTS:
662 type = "deny account";
663 part_msg->deny_accounts = xstrdup(new_text);
664 break;
665 case SORTID_DENY_QOS:
666 type = "deny qos";
667 part_msg->deny_qos = xstrdup(new_text);
668 break;
669 case SORTID_NODES_ALLOWED:
670 type = "allowed alloc nodes";
671 part_msg->allow_alloc_nodes = xstrdup(new_text);
672 break;
673 case SORTID_NODELIST:
674 part_msg->nodes = xstrdup(new_text);
675 type = "nodelist";
676 break;
677 case SORTID_PART_STATE:
678 if (!xstrcasecmp(new_text, "up"))
679 part_msg->state_up = PARTITION_UP;
680 else if (!xstrcasecmp(new_text, "down"))
681 part_msg->state_up = PARTITION_DOWN;
682 else if (!xstrcasecmp(new_text, "inactive"))
683 part_msg->state_up = PARTITION_INACTIVE;
684 else if (!xstrcasecmp(new_text, "drain"))
685 part_msg->state_up = PARTITION_DRAIN;
686 else
687 goto return_error;
688 type = "availability";
689
690 break;
691 case SORTID_NODE_STATE:
692 type = (char *)new_text;
693 got_edit_signal = xstrdup(new_text);
694 break;
695 case SORTID_FEATURES:
696 type = "Update Features";
697 got_features_edit_signal = xstrdup(new_text);
698 break;
699 case SORTID_QOS_CHAR:
700 type = "QOS Char";
701 part_msg->qos_char = xstrdup(new_text);
702 break;
703 default:
704 type = "unknown";
705 break;
706 }
707
708 if (xstrcmp(type, "unknown"))
709 global_send_update_msg = 1;
710
711 return type;
712
713 return_error:
714 global_edit_error = 1;
715 return type;
716
717 }
718
_admin_edit_combo_box_part(GtkComboBox * combo,update_part_msg_t * part_msg)719 static void _admin_edit_combo_box_part(GtkComboBox *combo,
720 update_part_msg_t *part_msg)
721 {
722 GtkTreeModel *model = NULL;
723 GtkTreeIter iter;
724 int column = 0;
725 char *name = NULL;
726
727 if (!part_msg)
728 return;
729
730 if (!gtk_combo_box_get_active_iter(combo, &iter)) {
731 g_print("nothing selected\n");
732 return;
733 }
734 model = gtk_combo_box_get_model(combo);
735 if (!model) {
736 g_print("nothing selected\n");
737 return;
738 }
739
740 gtk_tree_model_get(model, &iter, 0, &name, -1);
741 gtk_tree_model_get(model, &iter, 1, &column, -1);
742
743 (void) _set_part_msg(part_msg, name, column);
744 if (name)
745 g_free(name);
746 }
747
_admin_focus_out_part(GtkEntry * entry,GdkEventFocus * event,update_part_msg_t * part_msg)748 static gboolean _admin_focus_out_part(GtkEntry *entry,
749 GdkEventFocus *event,
750 update_part_msg_t *part_msg)
751 {
752 if (global_entry_changed) {
753 const char *col_name = NULL;
754 int type = gtk_entry_get_max_length(entry);
755 const char *name = gtk_entry_get_text(entry);
756 type -= DEFAULT_ENTRY_LENGTH;
757 col_name = _set_part_msg(part_msg, name, type);
758 if (global_edit_error) {
759 if (global_edit_error_msg)
760 g_free(global_edit_error_msg);
761 global_edit_error_msg = g_strdup_printf(
762 "Partition %s %s can't be set to %s",
763 part_msg->name,
764 col_name,
765 name);
766 }
767
768 global_entry_changed = 0;
769 }
770 return false;
771 }
772
_admin_full_edit_part(update_part_msg_t * part_msg,GtkTreeModel * model,GtkTreeIter * iter)773 static GtkWidget *_admin_full_edit_part(update_part_msg_t *part_msg,
774 GtkTreeModel *model, GtkTreeIter *iter)
775 {
776 GtkScrolledWindow *window = create_scrolled_window();
777 GtkBin *bin = NULL;
778 GtkViewport *view = NULL;
779 GtkTable *table = NULL;
780 int i = 0, row = 0;
781 display_data_t *display_data = display_data_part;
782
783 gtk_scrolled_window_set_policy(window,
784 GTK_POLICY_NEVER,
785 GTK_POLICY_AUTOMATIC);
786 bin = GTK_BIN(&window->container);
787 view = GTK_VIEWPORT(bin->child);
788 bin = GTK_BIN(&view->bin);
789 table = GTK_TABLE(bin->child);
790 gtk_table_resize(table, SORTID_CNT, 2);
791
792 gtk_table_set_homogeneous(table, false);
793
794 for (i = 0; i < SORTID_CNT; i++) {
795 while (display_data++) {
796 if (display_data->id == -1)
797 break;
798 if (!display_data->name)
799 continue;
800 if (display_data->id != i)
801 continue;
802 display_admin_edit(
803 table, part_msg, &row, model, iter,
804 display_data,
805 G_CALLBACK(_admin_edit_combo_box_part),
806 G_CALLBACK(_admin_focus_out_part),
807 _set_active_combo_part);
808 break;
809 }
810 display_data = display_data_part;
811 }
812 gtk_table_resize(table, row, 2);
813
814 return GTK_WIDGET(window);
815 }
816
_subdivide_part(sview_part_info_t * sview_part_info,GtkTreeModel * model,GtkTreeIter * sub_iter,GtkTreeIter * iter)817 static void _subdivide_part(sview_part_info_t *sview_part_info,
818 GtkTreeModel *model,
819 GtkTreeIter *sub_iter,
820 GtkTreeIter *iter)
821 {
822 GtkTreeIter first_sub_iter;
823 ListIterator itr = NULL;
824 int i = 0, line = 0;
825 sview_part_sub_t *sview_part_sub = NULL;
826 int set = 0;
827
828 memset(&first_sub_iter, 0, sizeof(GtkTreeIter));
829
830 /* make sure all the steps are still here */
831 if (sub_iter) {
832 first_sub_iter = *sub_iter;
833 while (1) {
834 gtk_tree_store_set(GTK_TREE_STORE(model), sub_iter,
835 SORTID_UPDATED, 0, -1);
836 if (!gtk_tree_model_iter_next(model, sub_iter)) {
837 break;
838 }
839 }
840 memcpy(sub_iter, &first_sub_iter, sizeof(GtkTreeIter));
841 set = 1;
842 }
843 itr = list_iterator_create(sview_part_info->sub_list);
844 if ((list_count(sview_part_info->sub_list) == 1) &&
845 (sview_part_sub = list_next(itr))) {
846 gtk_tree_store_set(GTK_TREE_STORE(model), iter,
847 SORTID_ONLY_LINE, 1, -1);
848 _update_part_sub_record(sview_part_sub,
849 GTK_TREE_STORE(model),
850 iter);
851 } else {
852 while ((sview_part_sub = list_next(itr))) {
853 if (!sub_iter) {
854 i = NO_VAL;
855 goto adding;
856 } else {
857 memcpy(sub_iter, &first_sub_iter,
858 sizeof(GtkTreeIter));
859 }
860 line = 0;
861 while (1) {
862 int state;
863 /* Search for the state number and
864 check to see if it is in the
865 list. Here we need to pass an int
866 for system where endian is an
867 issue passing a uint16_t may seg
868 fault. */
869 gtk_tree_model_get(model, sub_iter,
870 SORTID_NODE_STATE_NUM,
871 &state, -1);
872 if ((uint16_t)state
873 == sview_part_sub->node_state) {
874 /* update with new info */
875 _update_part_sub_record(
876 sview_part_sub,
877 GTK_TREE_STORE(model),
878 sub_iter);
879 goto found;
880 }
881
882 line++;
883 if (!gtk_tree_model_iter_next(model,
884 sub_iter)) {
885 break;
886 }
887 }
888 adding:
889 _append_part_sub_record(sview_part_sub,
890 GTK_TREE_STORE(model),
891 iter, line);
892 /* if (i == NO_VAL) */
893 /* line++; */
894 found:
895 ;
896 }
897 }
898 list_iterator_destroy(itr);
899
900 if (set) {
901 sub_iter = &first_sub_iter;
902 /* clear all steps that aren't active */
903 while (1) {
904 gtk_tree_model_get(model, sub_iter,
905 SORTID_UPDATED, &i, -1);
906 if (!i) {
907 if (!gtk_tree_store_remove(
908 GTK_TREE_STORE(model),
909 sub_iter))
910 break;
911 else
912 continue;
913 }
914 if (!gtk_tree_model_iter_next(model, sub_iter)) {
915 break;
916 }
917 }
918 }
919 return;
920 }
921
_layout_part_record(GtkTreeView * treeview,sview_part_info_t * sview_part_info,int update)922 static void _layout_part_record(GtkTreeView *treeview,
923 sview_part_info_t *sview_part_info,
924 int update)
925 {
926 GtkTreeIter iter;
927 char time_buf[20], tmp_buf[20];
928 char tmp_cnt[8];
929 char tmp_cnt1[8];
930 char tmp_cnt2[8];
931 partition_info_t *part_ptr = sview_part_info->part_ptr;
932 sview_part_sub_t *sview_part_sub = NULL;
933 char ind_cnt[1024];
934 const char *job_def_str = NULL, *temp_char = NULL;
935 uint16_t temp_uint16 = 0;
936 int i;
937 int yes_no = -1;
938 uint32_t limit_set = NO_VAL;
939 GtkTreeStore *treestore =
940 GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
941
942 convert_num_unit((float)sview_part_info->sub_part_total.node_alloc_cnt,
943 tmp_cnt, sizeof(tmp_cnt), UNIT_NONE, NO_VAL,
944 working_sview_config.convert_flags);
945 convert_num_unit((float)sview_part_info->sub_part_total.node_idle_cnt,
946 tmp_cnt1, sizeof(tmp_cnt1), UNIT_NONE, NO_VAL,
947 working_sview_config.convert_flags);
948 convert_num_unit((float)sview_part_info->sub_part_total.node_error_cnt,
949 tmp_cnt2, sizeof(tmp_cnt2), UNIT_NONE, NO_VAL,
950 working_sview_config.convert_flags);
951 snprintf(ind_cnt, sizeof(ind_cnt), "%s/%s/%s",
952 tmp_cnt, tmp_cnt1, tmp_cnt2);
953
954 for (i = 0; i < SORTID_CNT; i++) {
955 switch (i) {
956 case SORTID_PART_STATE:
957 switch (part_ptr->state_up) {
958 case PARTITION_UP:
959 temp_char = "up";
960 break;
961 case PARTITION_DOWN:
962 temp_char = "down";
963 break;
964 case PARTITION_INACTIVE:
965 temp_char = "inactive";
966 break;
967 case PARTITION_DRAIN:
968 temp_char = "drain";
969 break;
970 default:
971 temp_char = "unknown";
972 break;
973 }
974 break;
975 case SORTID_ALTERNATE:
976 if (part_ptr->alternate)
977 temp_char = part_ptr->alternate;
978 else
979 temp_char = "";
980 break;
981 case SORTID_CPUS:
982 convert_num_unit((float)part_ptr->total_cpus,
983 tmp_cnt, sizeof(tmp_cnt),
984 UNIT_NONE, NO_VAL,
985 working_sview_config.convert_flags);
986 temp_char = tmp_cnt;
987 break;
988 case SORTID_DEFAULT:
989 if (part_ptr->flags & PART_FLAG_DEFAULT)
990 yes_no = 1;
991 else
992 yes_no = 0;
993 break;
994 case SORTID_FEATURES:
995 if (sview_part_sub)
996 temp_char = sview_part_sub->features;
997 else
998 temp_char = "";
999 break;
1000 case SORTID_GRACE_TIME:
1001 limit_set = part_ptr->grace_time;
1002 break;
1003 case SORTID_ALLOW_ACCOUNTS:
1004 if (part_ptr->allow_accounts)
1005 temp_char = part_ptr->allow_accounts;
1006 else
1007 temp_char = "all";
1008 break;
1009 case SORTID_ALLOW_GROUPS:
1010 if (part_ptr->allow_groups)
1011 temp_char = part_ptr->allow_groups;
1012 else
1013 temp_char = "all";
1014 break;
1015 case SORTID_ALLOW_QOS:
1016 if (part_ptr->allow_qos)
1017 temp_char = part_ptr->allow_qos;
1018 else
1019 temp_char = "all";
1020 break;
1021 case SORTID_CLUSTER_NAME:
1022 if (part_ptr->cluster_name)
1023 temp_char = part_ptr->cluster_name;
1024 break;
1025 case SORTID_DENY_ACCOUNTS:
1026 if (part_ptr->deny_accounts)
1027 temp_char = part_ptr->deny_accounts;
1028 else
1029 temp_char = "none";
1030 break;
1031 case SORTID_DENY_QOS:
1032 if (part_ptr->deny_qos)
1033 temp_char = part_ptr->deny_qos;
1034 else
1035 temp_char = "none";
1036 break;
1037 case SORTID_EXCLUSIVE_USER:
1038 if (part_ptr->flags & PART_FLAG_EXCLUSIVE_USER)
1039 yes_no = 1;
1040 else
1041 yes_no = 0;
1042 break;
1043 case SORTID_HIDDEN:
1044 if (part_ptr->flags & PART_FLAG_HIDDEN)
1045 yes_no = 1;
1046 else
1047 yes_no = 0;
1048 break;
1049 case SORTID_JOB_DEFAULTS:
1050 job_def_str =
1051 job_defaults_str(part_ptr->job_defaults_list);
1052 temp_char = job_def_str;
1053 break;
1054 case SORTID_JOB_SIZE:
1055 _build_min_max_32_string(time_buf, sizeof(time_buf),
1056 part_ptr->min_nodes,
1057 part_ptr->max_nodes, true);
1058 temp_char = time_buf;
1059 break;
1060 case SORTID_MEM:
1061 convert_num_unit((float)sview_part_info->
1062 sub_part_total.mem_total,
1063 tmp_cnt, sizeof(tmp_cnt),
1064 UNIT_MEGA, NO_VAL,
1065 working_sview_config.convert_flags);
1066 temp_char = tmp_cnt;
1067 break;
1068 case SORTID_NODELIST:
1069 temp_char = part_ptr->nodes;
1070 break;
1071 case SORTID_NODES_ALLOWED:
1072 temp_char = part_ptr->allow_alloc_nodes;
1073 break;
1074 case SORTID_NODES:
1075 sprintf(tmp_cnt, "%u", part_ptr->total_nodes);
1076 temp_char = tmp_cnt;
1077 break;
1078 case SORTID_NODES_MAX:
1079 limit_set = part_ptr->max_nodes;
1080 break;
1081 case SORTID_NODES_MIN:
1082 limit_set = part_ptr->min_nodes;
1083 break;
1084 case SORTID_MAX_CPUS_PER_NODE:
1085 limit_set = part_ptr->max_cpus_per_node;
1086 break;
1087 case SORTID_NODE_INX:
1088 break;
1089 case SORTID_ONLY_LINE:
1090 break;
1091 case SORTID_PREEMPT_MODE:
1092 temp_uint16 = part_ptr->preempt_mode;
1093 if (temp_uint16 == NO_VAL16)
1094 temp_uint16 = slurm_get_preempt_mode();
1095 temp_char = preempt_mode_string(temp_uint16);
1096 break;
1097 case SORTID_PRIORITY_JOB_FACTOR:
1098 convert_num_unit((float)part_ptr->priority_job_factor,
1099 time_buf, sizeof(time_buf), UNIT_NONE,
1100 NO_VAL,
1101 working_sview_config.convert_flags);
1102 temp_char = time_buf;
1103 break;
1104 case SORTID_PRIORITY_TIER:
1105 convert_num_unit((float)part_ptr->priority_tier,
1106 time_buf, sizeof(time_buf), UNIT_NONE,
1107 NO_VAL,
1108 working_sview_config.convert_flags);
1109 temp_char = time_buf;
1110 break;
1111 case SORTID_REASON:
1112 sview_part_sub = list_peek(sview_part_info->sub_list);
1113 if (sview_part_sub)
1114 temp_char = sview_part_sub->reason;
1115 else
1116 temp_char = "";
1117 break;
1118 case SORTID_ROOT:
1119 if (part_ptr->flags & PART_FLAG_ROOT_ONLY)
1120 yes_no = 1;
1121 else
1122 yes_no = 0;
1123 break;
1124 case SORTID_OVER_SUBSCRIBE:
1125 if (part_ptr->max_share & SHARED_FORCE) {
1126 snprintf(tmp_buf, sizeof(tmp_buf), "force:%u",
1127 (part_ptr->max_share
1128 & ~(SHARED_FORCE)));
1129 temp_char = tmp_buf;
1130 } else if (part_ptr->max_share == 0)
1131 temp_char = "exclusive";
1132 else if (part_ptr->max_share > 1) {
1133 snprintf(tmp_buf, sizeof(tmp_buf), "yes:%u",
1134 part_ptr->max_share);
1135 temp_char = tmp_buf;
1136 } else
1137 temp_char = "no";
1138 break;
1139 case SORTID_OVER_TIME_LIMIT:
1140 if (part_ptr->over_time_limit == INFINITE16) {
1141 temp_char = "UNLIMITED";
1142 } else if (part_ptr->over_time_limit == NO_VAL16) {
1143 temp_char = "N/A";
1144 } else {
1145 snprintf(tmp_buf, sizeof(tmp_buf), "%u",
1146 part_ptr->over_time_limit);
1147 temp_char = tmp_buf;
1148 }
1149 break;
1150 case SORTID_TMP_DISK:
1151 convert_num_unit(
1152 (float)sview_part_info->sub_part_total.
1153 disk_total,
1154 time_buf, sizeof(time_buf), UNIT_NONE, NO_VAL,
1155 working_sview_config.convert_flags);
1156 temp_char = time_buf;
1157 break;
1158 case SORTID_TIMELIMIT:
1159 limit_set = part_ptr->max_time;
1160 break;
1161 case SORTID_QOS_CHAR:
1162 if (part_ptr->qos_char)
1163 temp_char = part_ptr->qos_char;
1164 else
1165 temp_char = "N/A";
1166 break;
1167 default:
1168 break;
1169 }
1170
1171 if (yes_no != -1) {
1172 if (yes_no)
1173 temp_char = "yes";
1174 else
1175 temp_char = "no";
1176 yes_no = -1;
1177 } else if (limit_set != NO_VAL) {
1178 if (limit_set == INFINITE)
1179 temp_char = "infinite";
1180 else {
1181 convert_num_unit(
1182 (float)limit_set, time_buf,
1183 sizeof(time_buf), UNIT_NONE, NO_VAL,
1184 working_sview_config.convert_flags);
1185 temp_char = time_buf;
1186 }
1187 limit_set = NO_VAL;
1188 }
1189
1190 if (temp_char) {
1191 add_display_treestore_line(
1192 update, treestore, &iter,
1193 find_col_name(display_data_part,
1194 i),
1195 temp_char);
1196 if (i == SORTID_NODES) {
1197 add_display_treestore_line(
1198 update, treestore, &iter,
1199 "Nodes (Allocated/Idle/Other)",
1200 ind_cnt);
1201 }
1202 temp_char = NULL;
1203 }
1204 xfree(job_def_str);
1205 }
1206 }
1207
_update_part_record(sview_part_info_t * sview_part_info,GtkTreeStore * treestore)1208 static void _update_part_record(sview_part_info_t *sview_part_info,
1209 GtkTreeStore *treestore)
1210 {
1211 char tmp_prio_job_factor[40], tmp_prio_tier[40];
1212 char tmp_size[40], tmp_over_subscribe_buf[40], tmp_time[40];
1213 char tmp_max_nodes[40], tmp_min_nodes[40], tmp_grace[40];
1214 char tmp_over_time_limit_buf[40];
1215 char tmp_cpu_cnt[40], tmp_node_cnt[40], tmp_max_cpus_per_node[40];
1216 char *tmp_alt, *tmp_default, *tmp_accounts, *tmp_groups, *tmp_hidden;
1217 char *tmp_deny_accounts, *tmp_qos_char, *tmp_exc_user;
1218 char *tmp_qos, *tmp_deny_qos, *job_def_str = NULL;
1219 char *tmp_root, *tmp_over_subscribe, *tmp_over_time_limit, *tmp_state;
1220 uint16_t tmp_preempt;
1221 partition_info_t *part_ptr = sview_part_info->part_ptr;
1222 GtkTreeIter sub_iter;
1223
1224 if (part_ptr->alternate)
1225 tmp_alt = part_ptr->alternate;
1226 else
1227 tmp_alt = "";
1228
1229 sprintf(tmp_cpu_cnt, "%u", part_ptr->total_cpus);
1230
1231 if (part_ptr->flags & PART_FLAG_DEFAULT)
1232 tmp_default = "yes";
1233 else
1234 tmp_default = "no";
1235
1236 if (part_ptr->allow_accounts)
1237 tmp_accounts = part_ptr->allow_accounts;
1238 else
1239 tmp_accounts = "all";
1240
1241 if (part_ptr->allow_groups)
1242 tmp_groups = part_ptr->allow_groups;
1243 else
1244 tmp_groups = "all";
1245
1246 if (part_ptr->allow_qos)
1247 tmp_qos = part_ptr->allow_qos;
1248 else
1249 tmp_qos = "all";
1250
1251 if (part_ptr->deny_accounts)
1252 tmp_deny_accounts = part_ptr->deny_accounts;
1253 else
1254 tmp_deny_accounts = "none";
1255
1256 if (part_ptr->deny_qos)
1257 tmp_deny_qos = part_ptr->deny_qos;
1258 else
1259 tmp_deny_qos = "none";
1260
1261 if (part_ptr->flags & PART_FLAG_EXCLUSIVE_USER)
1262 tmp_exc_user = "yes";
1263 else
1264 tmp_exc_user = "no";
1265
1266 if (part_ptr->flags & PART_FLAG_HIDDEN)
1267 tmp_hidden = "yes";
1268 else
1269 tmp_hidden = "no";
1270
1271 if (part_ptr->grace_time == NO_VAL)
1272 snprintf(tmp_grace, sizeof(tmp_grace), "none");
1273 else {
1274 secs2time_str(part_ptr->grace_time,
1275 tmp_grace, sizeof(tmp_grace));
1276 }
1277
1278 job_def_str = job_defaults_str(part_ptr->job_defaults_list);
1279
1280 if (part_ptr->max_nodes == INFINITE)
1281 snprintf(tmp_max_nodes, sizeof(tmp_max_nodes), "infinite");
1282 else {
1283 convert_num_unit((float)part_ptr->max_nodes, tmp_max_nodes,
1284 sizeof(tmp_max_nodes), UNIT_NONE, NO_VAL,
1285 working_sview_config.convert_flags);
1286 }
1287
1288 if (part_ptr->min_nodes == INFINITE)
1289 snprintf(tmp_min_nodes, sizeof(tmp_min_nodes), "infinite");
1290 else {
1291 convert_num_unit((float)part_ptr->min_nodes, tmp_min_nodes,
1292 sizeof(tmp_min_nodes), UNIT_NONE, NO_VAL,
1293 working_sview_config.convert_flags);
1294 }
1295
1296 if (part_ptr->max_cpus_per_node == INFINITE) {
1297 sprintf(tmp_max_cpus_per_node, "UNLIMITED");
1298 } else {
1299 sprintf(tmp_max_cpus_per_node, "%u",
1300 part_ptr->max_cpus_per_node);
1301 }
1302
1303 sprintf(tmp_node_cnt, "%u", part_ptr->total_nodes);
1304
1305 if (part_ptr->flags & PART_FLAG_ROOT_ONLY)
1306 tmp_root = "yes";
1307 else
1308 tmp_root = "no";
1309
1310 if (part_ptr->state_up == PARTITION_UP)
1311 tmp_state = "up";
1312 else if (part_ptr->state_up == PARTITION_DOWN)
1313 tmp_state = "down";
1314 else if (part_ptr->state_up == PARTITION_INACTIVE)
1315 tmp_state = "inact";
1316 else if (part_ptr->state_up == PARTITION_DRAIN)
1317 tmp_state = "drain";
1318 else
1319 tmp_state = "unk";
1320
1321 _build_min_max_32_string(tmp_size, sizeof(tmp_size),
1322 part_ptr->min_nodes,
1323 part_ptr->max_nodes, true);
1324
1325 tmp_preempt = part_ptr->preempt_mode;
1326 if (tmp_preempt == NO_VAL16)
1327 tmp_preempt = slurm_get_preempt_mode(); /* use cluster param */
1328
1329 convert_num_unit((float)part_ptr->priority_job_factor,
1330 tmp_prio_job_factor, sizeof(tmp_prio_job_factor),
1331 UNIT_NONE, NO_VAL, working_sview_config.convert_flags);
1332
1333 convert_num_unit((float)part_ptr->priority_tier, tmp_prio_tier,
1334 sizeof(tmp_prio_tier), UNIT_NONE, NO_VAL,
1335 working_sview_config.convert_flags);
1336
1337 if (part_ptr->max_share & SHARED_FORCE) {
1338 snprintf(tmp_over_subscribe_buf, sizeof(tmp_over_subscribe_buf),
1339 "force:%u", (part_ptr->max_share & ~(SHARED_FORCE)));
1340 tmp_over_subscribe = tmp_over_subscribe_buf;
1341 } else if (part_ptr->max_share == 0) {
1342 tmp_over_subscribe = "exclusive";
1343 } else if (part_ptr->max_share > 1) {
1344 snprintf(tmp_over_subscribe_buf,
1345 sizeof(tmp_over_subscribe_buf), "yes:%u",
1346 part_ptr->max_share);
1347 tmp_over_subscribe = tmp_over_subscribe_buf;
1348 } else
1349 tmp_over_subscribe = "no";
1350
1351 if (part_ptr->over_time_limit == INFINITE16) {
1352 tmp_over_time_limit = "UNLIMITED";
1353 } else if (part_ptr->over_time_limit == NO_VAL16) {
1354 tmp_over_time_limit = "N/A";
1355 } else {
1356 snprintf(tmp_over_time_limit_buf,
1357 sizeof(tmp_over_time_limit_buf), "%u",
1358 part_ptr->over_time_limit);
1359 tmp_over_time_limit = tmp_over_time_limit_buf;
1360 }
1361
1362 if (part_ptr->max_time == INFINITE)
1363 snprintf(tmp_time, sizeof(tmp_time), "infinite");
1364 else {
1365 secs2time_str((part_ptr->max_time * 60),
1366 tmp_time, sizeof(tmp_time));
1367 }
1368
1369 if (part_ptr->qos_char)
1370 tmp_qos_char = part_ptr->qos_char;
1371 else
1372 tmp_qos_char = "N/A";
1373
1374 /* Combining these records provides a slight performance improvement
1375 * NOTE: Some of these fields are cleared here and filled in based upon
1376 * the configuration of nodes within this partition. */
1377 gtk_tree_store_set(treestore, &sview_part_info->iter_ptr,
1378 SORTID_ALTERNATE, tmp_alt,
1379 SORTID_CLUSTER_NAME, part_ptr->cluster_name,
1380 SORTID_COLOR,
1381 sview_colors[sview_part_info->color_inx],
1382 SORTID_COLOR_INX, sview_part_info->color_inx,
1383 SORTID_CPUS, tmp_cpu_cnt,
1384 SORTID_DEFAULT, tmp_default,
1385 SORTID_FEATURES, "",
1386 SORTID_FEATURES_ACT, "",
1387 SORTID_GRACE_TIME, tmp_grace,
1388 SORTID_QOS_CHAR, tmp_qos_char,
1389 SORTID_ALLOW_ACCOUNTS, tmp_accounts,
1390 SORTID_ALLOW_GROUPS, tmp_groups,
1391 SORTID_ALLOW_QOS, tmp_qos,
1392 SORTID_DENY_ACCOUNTS, tmp_deny_accounts,
1393 SORTID_DENY_QOS, tmp_deny_qos,
1394 SORTID_EXCLUSIVE_USER, tmp_exc_user,
1395 SORTID_HIDDEN, tmp_hidden,
1396 SORTID_JOB_DEFAULTS, job_def_str,
1397 SORTID_JOB_SIZE, tmp_size,
1398 SORTID_MAX_CPUS_PER_NODE, tmp_max_cpus_per_node,
1399 SORTID_MEM, "",
1400 SORTID_NAME, part_ptr->name,
1401 SORTID_NODE_INX, part_ptr->node_inx,
1402 SORTID_NODE_STATE, "",
1403 SORTID_NODE_STATE_NUM, -1,
1404 SORTID_NODES, tmp_node_cnt,
1405 SORTID_NODES_MAX, tmp_max_nodes,
1406 SORTID_NODES_MIN, tmp_min_nodes,
1407 SORTID_NODELIST, part_ptr->nodes,
1408 SORTID_ONLY_LINE, 0,
1409 SORTID_OVER_SUBSCRIBE, tmp_over_subscribe,
1410 SORTID_OVER_TIME_LIMIT, tmp_over_time_limit,
1411 SORTID_PART_STATE, tmp_state,
1412 SORTID_PREEMPT_MODE,
1413 preempt_mode_string(tmp_preempt),
1414 SORTID_PRIORITY_JOB_FACTOR, tmp_prio_job_factor,
1415 SORTID_PRIORITY_TIER, tmp_prio_tier,
1416 SORTID_REASON, "",
1417 SORTID_ROOT, tmp_root,
1418 SORTID_TIMELIMIT, tmp_time,
1419 SORTID_TMP_DISK, "",
1420 SORTID_UPDATED, 1,
1421 -1);
1422 xfree(job_def_str);
1423
1424 if (gtk_tree_model_iter_children(GTK_TREE_MODEL(treestore),
1425 &sub_iter,
1426 &sview_part_info->iter_ptr))
1427 _subdivide_part(sview_part_info,
1428 GTK_TREE_MODEL(treestore), &sub_iter,
1429 &sview_part_info->iter_ptr);
1430 else
1431 _subdivide_part(sview_part_info,
1432 GTK_TREE_MODEL(treestore), NULL,
1433 &sview_part_info->iter_ptr);
1434
1435 return;
1436 }
1437
_update_part_sub_record(sview_part_sub_t * sview_part_sub,GtkTreeStore * treestore,GtkTreeIter * iter)1438 static void _update_part_sub_record(sview_part_sub_t *sview_part_sub,
1439 GtkTreeStore *treestore, GtkTreeIter *iter)
1440 {
1441 partition_info_t *part_ptr = sview_part_sub->part_ptr;
1442 char *tmp_cpus = NULL, *tmp_nodes = NULL, *tmp_nodelist;
1443 char *tmp_state_lower, *tmp_state_upper;
1444 char tmp_cnt[40], tmp_disk[40], tmp_mem[40];
1445
1446 tmp_state_upper = node_state_string(sview_part_sub->node_state);
1447 tmp_state_lower = str_tolower(tmp_state_upper);
1448
1449 if ((sview_part_sub->node_state & NODE_STATE_BASE)
1450 == NODE_STATE_MIXED) {
1451 if (sview_part_sub->cpu_alloc_cnt) {
1452 convert_num_unit((float)sview_part_sub->cpu_alloc_cnt,
1453 tmp_cnt,
1454 sizeof(tmp_cnt), UNIT_NONE, NO_VAL,
1455 working_sview_config.convert_flags);
1456 xstrfmtcat(tmp_cpus, "Alloc:%s", tmp_cnt);
1457 }
1458 if (sview_part_sub->cpu_idle_cnt) {
1459 convert_num_unit((float)sview_part_sub->cpu_idle_cnt,
1460 tmp_cnt,
1461 sizeof(tmp_cnt), UNIT_NONE, NO_VAL,
1462 working_sview_config.convert_flags);
1463 if (tmp_cpus)
1464 xstrcat(tmp_cpus, " ");
1465 xstrfmtcat(tmp_cpus, "Idle:%s", tmp_cnt);
1466 }
1467 } else {
1468 tmp_cpus = xmalloc(20);
1469 convert_num_unit((float)sview_part_sub->cpu_cnt,
1470 tmp_cpus, 20, UNIT_NONE, NO_VAL,
1471 working_sview_config.convert_flags);
1472 }
1473
1474 if (!tmp_nodes) {
1475 convert_num_unit((float)sview_part_sub->node_cnt, tmp_cnt,
1476 sizeof(tmp_cnt), UNIT_NONE, NO_VAL,
1477 working_sview_config.convert_flags);
1478 tmp_nodes = xstrdup(tmp_cnt);
1479 }
1480
1481 convert_num_unit((float)sview_part_sub->disk_total, tmp_disk,
1482 sizeof(tmp_disk), UNIT_NONE, NO_VAL,
1483 working_sview_config.convert_flags);
1484
1485 convert_num_unit((float)sview_part_sub->mem_total, tmp_mem,
1486 sizeof(tmp_mem), UNIT_MEGA, NO_VAL,
1487 working_sview_config.convert_flags);
1488
1489 tmp_nodelist = hostlist_ranged_string_xmalloc(sview_part_sub->hl);
1490
1491 gtk_tree_store_set(treestore, iter,
1492 SORTID_CPUS, tmp_cpus,
1493 SORTID_FEATURES, sview_part_sub->features,
1494 SORTID_FEATURES_ACT, sview_part_sub->features_act,
1495 SORTID_MEM, tmp_mem,
1496 SORTID_NAME, part_ptr->name,
1497 SORTID_NODE_STATE_NUM, sview_part_sub->node_state,
1498 SORTID_NODELIST, tmp_nodelist,
1499 SORTID_NODES, tmp_nodes,
1500 SORTID_NODE_STATE, tmp_state_lower,
1501 SORTID_REASON, sview_part_sub->reason,
1502 SORTID_TMP_DISK, tmp_disk,
1503 SORTID_UPDATED, 1,
1504 -1);
1505
1506 xfree(tmp_cpus);
1507 xfree(tmp_nodelist);
1508 xfree(tmp_nodes);
1509 xfree(tmp_state_lower);
1510
1511 return;
1512 }
1513
_append_part_record(sview_part_info_t * sview_part_info,GtkTreeStore * treestore)1514 static void _append_part_record(sview_part_info_t *sview_part_info,
1515 GtkTreeStore *treestore)
1516 {
1517 gtk_tree_store_append(treestore, &sview_part_info->iter_ptr, NULL);
1518 gtk_tree_store_set(treestore, &sview_part_info->iter_ptr,
1519 SORTID_POS, sview_part_info->pos, -1);
1520 _update_part_record(sview_part_info, treestore);
1521 }
1522
_append_part_sub_record(sview_part_sub_t * sview_part_sub,GtkTreeStore * treestore,GtkTreeIter * iter,int line)1523 static void _append_part_sub_record(sview_part_sub_t *sview_part_sub,
1524 GtkTreeStore *treestore, GtkTreeIter *iter,
1525 int line)
1526 {
1527 GtkTreeIter sub_iter;
1528
1529 gtk_tree_store_append(treestore, &sub_iter, iter);
1530 gtk_tree_store_set(treestore, &sub_iter, SORTID_POS, line, -1);
1531 _update_part_sub_record(sview_part_sub, treestore, &sub_iter);
1532 }
1533
_update_info_part(List info_list,GtkTreeView * tree_view)1534 static void _update_info_part(List info_list,
1535 GtkTreeView *tree_view)
1536 {
1537 GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
1538 char *name = NULL;
1539 ListIterator itr = NULL;
1540 sview_part_info_t *sview_part_info = NULL;
1541
1542 set_for_update(model, SORTID_UPDATED);
1543
1544 itr = list_iterator_create(info_list);
1545 while ((sview_part_info = list_next(itr))) {
1546 /* This means the tree_store changed (added new column
1547 or something). */
1548 if (last_model != model)
1549 sview_part_info->iter_set = false;
1550
1551 if (sview_part_info->iter_set) {
1552 gtk_tree_model_get(model, &sview_part_info->iter_ptr,
1553 SORTID_NAME, &name, -1);
1554 if (xstrcmp(name, sview_part_info->part_name))
1555 /* Bad pointer */
1556 sview_part_info->iter_set = false;
1557 g_free(name);
1558 }
1559 if (sview_part_info->iter_set)
1560 _update_part_record(sview_part_info,
1561 GTK_TREE_STORE(model));
1562 else {
1563 _append_part_record(sview_part_info,
1564 GTK_TREE_STORE(model));
1565 sview_part_info->iter_set = true;
1566 }
1567 }
1568 list_iterator_destroy(itr);
1569 /* remove all old partitions */
1570 remove_old(model, SORTID_UPDATED);
1571 last_model = model;
1572 return;
1573 }
1574
_part_info_free(sview_part_info_t * sview_part_info)1575 static void _part_info_free(sview_part_info_t *sview_part_info)
1576 {
1577 if (sview_part_info) {
1578 xfree(sview_part_info->cluster_name);
1579 xfree(sview_part_info->part_name);
1580 memset(&sview_part_info->sub_part_total, 0,
1581 sizeof(sview_part_sub_t));
1582 FREE_NULL_LIST(sview_part_info->sub_list);
1583 }
1584 }
1585
_part_info_list_del(void * object)1586 static void _part_info_list_del(void *object)
1587 {
1588 sview_part_info_t *sview_part_info = (sview_part_info_t *)object;
1589
1590 if (sview_part_info) {
1591 _part_info_free(sview_part_info);
1592 xfree(sview_part_info);
1593 }
1594 }
1595
_destroy_part_sub(void * object)1596 static void _destroy_part_sub(void *object)
1597 {
1598 sview_part_sub_t *sview_part_sub = (sview_part_sub_t *)object;
1599
1600 if (sview_part_sub) {
1601 xfree(sview_part_sub->features);
1602 xfree(sview_part_sub->features_act);
1603 xfree(sview_part_sub->reason);
1604 if (sview_part_sub->hl)
1605 hostlist_destroy(sview_part_sub->hl);
1606 FREE_NULL_LIST(sview_part_sub->node_ptr_list);
1607 xfree(sview_part_sub);
1608 }
1609 }
1610
_update_sview_part_sub(sview_part_sub_t * sview_part_sub,node_info_t * node_ptr)1611 static void _update_sview_part_sub(sview_part_sub_t *sview_part_sub,
1612 node_info_t *node_ptr)
1613 {
1614 int idle_cpus = node_ptr->cpus;
1615 uint16_t alloc_cpus = 0;
1616
1617 xassert(sview_part_sub);
1618 xassert(sview_part_sub->node_ptr_list);
1619 xassert(sview_part_sub->hl);
1620
1621 if (sview_part_sub->node_cnt == 0) { /* first node added */
1622 sview_part_sub->node_state = node_ptr->node_state;
1623 sview_part_sub->features = xstrdup(node_ptr->features);
1624 sview_part_sub->features_act = xstrdup(node_ptr->features_act);
1625 sview_part_sub->reason = xstrdup(node_ptr->reason);
1626 } else if (hostlist_find(sview_part_sub->hl, node_ptr->name) != -1) {
1627 /* we already have this node in this record,
1628 * just return, don't duplicate */
1629 g_print("already been here\n");
1630 return;
1631 }
1632
1633 if ((sview_part_sub->node_state & NODE_STATE_BASE)
1634 == NODE_STATE_MIXED) {
1635 slurm_get_select_nodeinfo(node_ptr->select_nodeinfo,
1636 SELECT_NODEDATA_SUBCNT,
1637 NODE_STATE_ALLOCATED,
1638 &alloc_cpus);
1639 idle_cpus -= alloc_cpus;
1640 } else if (sview_part_sub->node_state == NODE_STATE_ALLOCATED) {
1641 alloc_cpus = idle_cpus;
1642 idle_cpus = 0;
1643 }
1644
1645 sview_part_sub->cpu_cnt += alloc_cpus + idle_cpus;
1646 sview_part_sub->cpu_alloc_cnt += alloc_cpus;
1647 sview_part_sub->cpu_idle_cnt += idle_cpus;
1648 sview_part_sub->disk_total += node_ptr->tmp_disk;
1649 sview_part_sub->mem_total += node_ptr->real_memory;
1650 sview_part_sub->node_cnt++;
1651
1652 list_append(sview_part_sub->node_ptr_list, node_ptr);
1653 hostlist_push_host(sview_part_sub->hl, node_ptr->name);
1654 }
1655
1656 /*
1657 * _create_sview_part_sub - create an sview_part_sub record for
1658 * the given partition
1659 * sview_part_sub OUT - ptr to an inited sview_part_sub_t
1660 */
_create_sview_part_sub(partition_info_t * part_ptr,node_info_t * node_ptr)1661 static sview_part_sub_t *_create_sview_part_sub(partition_info_t *part_ptr,
1662 node_info_t *node_ptr)
1663 {
1664 sview_part_sub_t *sview_part_sub_ptr =
1665 xmalloc(sizeof(sview_part_sub_t));
1666
1667 if (!part_ptr) {
1668 g_print("got no part_ptr!\n");
1669 xfree(sview_part_sub_ptr);
1670 return NULL;
1671 }
1672 if (!node_ptr) {
1673 g_print("got no node_ptr!\n");
1674 xfree(sview_part_sub_ptr);
1675 return NULL;
1676 }
1677 sview_part_sub_ptr->part_ptr = part_ptr;
1678 sview_part_sub_ptr->hl = hostlist_create(NULL);
1679 sview_part_sub_ptr->node_ptr_list = list_create(NULL);
1680 _update_sview_part_sub(sview_part_sub_ptr, node_ptr);
1681
1682 return sview_part_sub_ptr;
1683 }
1684
_insert_sview_part_sub(sview_part_info_t * sview_part_info,partition_info_t * part_ptr,node_info_t * node_ptr)1685 static int _insert_sview_part_sub(sview_part_info_t *sview_part_info,
1686 partition_info_t *part_ptr,
1687 node_info_t *node_ptr)
1688 {
1689 sview_part_sub_t *sview_part_sub = NULL;
1690 ListIterator itr = list_iterator_create(sview_part_info->sub_list);
1691
1692 while ((sview_part_sub = list_next(itr))) {
1693 if (sview_part_sub->node_state
1694 == node_ptr->node_state) {
1695 _update_sview_part_sub(sview_part_sub,
1696 node_ptr);
1697 break;
1698 }
1699 }
1700 list_iterator_destroy(itr);
1701
1702 if (!sview_part_sub) {
1703 if ((sview_part_sub = _create_sview_part_sub(
1704 part_ptr, node_ptr)))
1705 list_push(sview_part_info->sub_list,
1706 sview_part_sub);
1707 }
1708 return SLURM_SUCCESS;
1709 }
1710
_sview_part_sort_aval_dec(void * a,void * b)1711 static int _sview_part_sort_aval_dec(void *a, void *b)
1712 {
1713 sview_part_info_t *rec_a = *(sview_part_info_t **)a;
1714 sview_part_info_t *rec_b = *(sview_part_info_t **)b;
1715 int size_a;
1716 int size_b;
1717
1718 size_a = rec_a->part_ptr->total_nodes;
1719 size_b = rec_b->part_ptr->total_nodes;
1720
1721 if (size_a < size_b)
1722 return -1;
1723 else if (size_a > size_b)
1724 return 1;
1725
1726 if (rec_a->part_ptr->nodes && rec_b->part_ptr->nodes) {
1727 size_a = xstrcmp(rec_a->part_ptr->nodes,
1728 rec_b->part_ptr->nodes);
1729 if (size_a < 0)
1730 return -1;
1731 else if (size_a > 0)
1732 return 1;
1733 }
1734 return 0;
1735 }
1736
_sview_sub_part_sort(void * a,void * b)1737 static int _sview_sub_part_sort(void *a, void *b)
1738 {
1739 sview_part_sub_t *rec_a = *(sview_part_sub_t **)a;
1740 sview_part_sub_t *rec_b = *(sview_part_sub_t **)b;
1741 int size_a;
1742 int size_b;
1743
1744 size_a = rec_a->node_state & NODE_STATE_BASE;
1745 size_b = rec_b->node_state & NODE_STATE_BASE;
1746
1747 if (size_a < size_b)
1748 return -1;
1749 else if (size_a > size_b)
1750 return 1;
1751 return 0;
1752 }
1753
_create_part_info_list(partition_info_msg_t * part_info_ptr,node_info_msg_t * node_info_ptr)1754 static List _create_part_info_list(partition_info_msg_t *part_info_ptr,
1755 node_info_msg_t *node_info_ptr)
1756 {
1757 sview_part_info_t *sview_part_info = NULL;
1758 partition_info_t *part_ptr = NULL;
1759 static node_info_msg_t *last_node_info_ptr = NULL;
1760 static partition_info_msg_t *last_part_info_ptr = NULL;
1761 List last_list = NULL;
1762 ListIterator last_list_itr = NULL;
1763 node_info_t *node_ptr = NULL;
1764 static List info_list = NULL;
1765 int i, j2;
1766 sview_part_sub_t *sview_part_sub = NULL;
1767 ListIterator itr;
1768
1769 if (info_list && (node_info_ptr == last_node_info_ptr)
1770 && (part_info_ptr == last_part_info_ptr))
1771 return info_list;
1772
1773 last_node_info_ptr = node_info_ptr;
1774 last_part_info_ptr = part_info_ptr;
1775
1776 if (info_list)
1777 last_list = info_list;
1778
1779 info_list = list_create(_part_info_list_del);
1780
1781 if (last_list)
1782 last_list_itr = list_iterator_create(last_list);
1783 for (i = 0; i < part_info_ptr->record_count; i++) {
1784 int c_offset = 0;
1785 part_ptr = &(part_info_ptr->partition_array[i]);
1786
1787 /* don't include configured excludes */
1788 if (!working_sview_config.show_hidden &&
1789 part_ptr->flags & PART_FLAG_HIDDEN)
1790 continue;
1791
1792 sview_part_info = NULL;
1793
1794 if (last_list_itr) {
1795 while ((sview_part_info =
1796 list_next(last_list_itr))) {
1797 if (sview_part_info->cluster_name &&
1798 xstrcmp(sview_part_info->cluster_name,
1799 part_ptr->cluster_name))
1800 continue;
1801 if (!xstrcmp(sview_part_info->part_name,
1802 part_ptr->name)) {
1803 list_remove(last_list_itr);
1804 _part_info_free(sview_part_info);
1805 break;
1806 }
1807 }
1808 list_iterator_reset(last_list_itr);
1809 }
1810
1811 if (!sview_part_info)
1812 sview_part_info = xmalloc(sizeof(sview_part_info_t));
1813 sview_part_info->part_name = xstrdup(part_ptr->name);
1814 sview_part_info->cluster_name = xstrdup(part_ptr->cluster_name);
1815 sview_part_info->part_ptr = part_ptr;
1816 sview_part_info->sub_list = list_create(_destroy_part_sub);
1817 sview_part_info->pos = i;
1818 list_append(info_list, sview_part_info);
1819 sview_part_info->color_inx = i % sview_colors_cnt;
1820
1821 if (cluster_flags & CLUSTER_FLAG_FED)
1822 c_offset =
1823 get_cluster_node_offset(part_ptr->cluster_name,
1824 node_info_ptr);
1825
1826 j2 = 0;
1827 while (part_ptr->node_inx[j2] >= 0) {
1828 int i2 = 0;
1829 for ((i2 = part_ptr->node_inx[j2]);
1830 (i2 <= part_ptr->node_inx[j2+1]);
1831 i2++) {
1832 node_info_t *node_array;
1833 node_array = node_info_ptr->node_array;
1834 node_ptr = &(node_array[i2 + c_offset]);
1835
1836 _insert_sview_part_sub(sview_part_info,
1837 part_ptr,
1838 node_ptr);
1839 }
1840 j2 += 2;
1841 }
1842 list_sort(sview_part_info->sub_list,
1843 (ListCmpF)_sview_sub_part_sort);
1844
1845 /* Need to do this after the fact so we deal with
1846 complete sub parts.
1847 */
1848
1849 itr = list_iterator_create(sview_part_info->sub_list);
1850 while ((sview_part_sub = list_next(itr))) {
1851 sview_part_info->sub_part_total.node_cnt +=
1852 sview_part_sub->node_cnt;
1853 sview_part_info->sub_part_total.cpu_cnt +=
1854 sview_part_sub->cpu_cnt;
1855
1856 if (((sview_part_sub->node_state
1857 & NODE_STATE_BASE) == NODE_STATE_MIXED) ||
1858 (sview_part_sub->node_state
1859 == NODE_STATE_ALLOCATED))
1860 sview_part_info->sub_part_total.node_alloc_cnt
1861 += sview_part_sub->node_cnt;
1862 else if (sview_part_sub->node_state
1863 != NODE_STATE_IDLE)
1864 sview_part_info->sub_part_total.node_error_cnt
1865 += sview_part_sub->node_cnt;
1866 else
1867 sview_part_info->sub_part_total.node_idle_cnt
1868 += sview_part_sub->node_cnt;
1869
1870 sview_part_info->sub_part_total.cpu_alloc_cnt +=
1871 sview_part_sub->cpu_alloc_cnt;
1872 sview_part_info->sub_part_total.cpu_idle_cnt +=
1873 sview_part_sub->cpu_idle_cnt;
1874 sview_part_info->sub_part_total.disk_total +=
1875 sview_part_sub->disk_total;
1876 sview_part_info->sub_part_total.mem_total +=
1877 sview_part_sub->mem_total;
1878 if (!sview_part_info->sub_part_total.features) {
1879 /* store features and reasons
1880 in the others group */
1881 sview_part_info->sub_part_total.features
1882 = sview_part_sub->features;
1883 sview_part_info->sub_part_total.features_act
1884 = sview_part_sub->features_act;
1885 sview_part_info->sub_part_total.reason
1886 = sview_part_sub->reason;
1887 }
1888 hostlist_sort(sview_part_sub->hl);
1889 }
1890 list_iterator_destroy(itr);
1891 }
1892 list_sort(info_list, (ListCmpF)_sview_part_sort_aval_dec);
1893
1894 if (last_list) {
1895 list_iterator_destroy(last_list_itr);
1896 FREE_NULL_LIST(last_list);
1897 }
1898
1899 return info_list;
1900 }
1901
_display_info_part(List info_list,popup_info_t * popup_win)1902 static void _display_info_part(List info_list, popup_info_t *popup_win)
1903 {
1904 specific_info_t *spec_info = popup_win->spec_info;
1905 char *name = (char *)spec_info->search_info->gchar_data;
1906 char *cluster_name = (char *)spec_info->search_info->cluster_name;
1907 int found = 0;
1908 partition_info_t *part_ptr = NULL;
1909 GtkTreeView *treeview = NULL;
1910 ListIterator itr = NULL;
1911 sview_part_info_t *sview_part_info = NULL;
1912 int update = 0;
1913 int j = 0;
1914
1915 if (!spec_info->search_info->gchar_data) {
1916 //info = xstrdup("No pointer given!");
1917 goto finished;
1918 }
1919
1920 need_refresh:
1921 if (!spec_info->display_widget) {
1922 treeview = create_treeview_2cols_attach_to_table(
1923 popup_win->table);
1924 spec_info->display_widget =
1925 g_object_ref(GTK_WIDGET(treeview));
1926 } else {
1927 treeview = GTK_TREE_VIEW(spec_info->display_widget);
1928 update = 1;
1929 }
1930
1931 itr = list_iterator_create(info_list);
1932 while ((sview_part_info = list_next(itr))) {
1933 part_ptr = sview_part_info->part_ptr;
1934
1935 if (cluster_name &&
1936 xstrcmp(part_ptr->cluster_name, cluster_name))
1937 continue;
1938
1939 if (!xstrcmp(part_ptr->name, name)) {
1940 j = 0;
1941 while (part_ptr->node_inx[j] >= 0) {
1942 change_grid_color(
1943 popup_win->grid_button_list,
1944 part_ptr->node_inx[j],
1945 part_ptr->node_inx[j+1],
1946 sview_part_info->color_inx,
1947 true, 0);
1948 j += 2;
1949 }
1950 _layout_part_record(treeview, sview_part_info, update);
1951 found = 1;
1952 break;
1953 }
1954 }
1955 list_iterator_destroy(itr);
1956 post_setup_popup_grid_list(popup_win);
1957
1958 if (!found) {
1959 if (!popup_win->not_found) {
1960 char *temp = "PARTITION DOESN'T EXSIST\n";
1961 GtkTreeIter iter;
1962 GtkTreeModel *model = NULL;
1963
1964 /* only time this will be run so no update */
1965 model = gtk_tree_view_get_model(treeview);
1966 add_display_treestore_line(0,
1967 GTK_TREE_STORE(model),
1968 &iter,
1969 temp, "");
1970 }
1971 popup_win->not_found = true;
1972 } else {
1973 if (popup_win->not_found) {
1974 popup_win->not_found = false;
1975 gtk_widget_destroy(spec_info->display_widget);
1976
1977 goto need_refresh;
1978 }
1979 }
1980 gtk_widget_show(spec_info->display_widget);
1981
1982 finished:
1983
1984 return;
1985 }
1986
_process_each_partition(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer userdata)1987 static void _process_each_partition(GtkTreeModel *model,
1988 GtkTreePath *path,
1989 GtkTreeIter *iter,
1990 gpointer userdata)
1991 {
1992 char *type = userdata;
1993 if (_DEBUG)
1994 g_print("process_each_partition: global_multi_error = %d\n",
1995 global_multi_error);
1996
1997 if (!global_multi_error) {
1998 admin_part(model, iter, type);
1999 }
2000 }
2001 /*process_each_partition ^^^*/
2002
create_part_entry(update_part_msg_t * part_msg,GtkTreeModel * model,GtkTreeIter * iter)2003 extern GtkWidget *create_part_entry(update_part_msg_t *part_msg,
2004 GtkTreeModel *model, GtkTreeIter *iter)
2005 {
2006 GtkScrolledWindow *window = create_scrolled_window();
2007 GtkBin *bin = NULL;
2008 GtkViewport *view = NULL;
2009 GtkTable *table = NULL;
2010 int i = 0, row = 0;
2011 display_data_t *display_data = create_data_part;
2012
2013 gtk_scrolled_window_set_policy(window,
2014 GTK_POLICY_NEVER,
2015 GTK_POLICY_AUTOMATIC);
2016 bin = GTK_BIN(&window->container);
2017 view = GTK_VIEWPORT(bin->child);
2018 bin = GTK_BIN(&view->bin);
2019 table = GTK_TABLE(bin->child);
2020 gtk_table_resize(table, SORTID_CNT, 2);
2021
2022 gtk_table_set_homogeneous(table, false);
2023
2024 for(i = 0; i < SORTID_CNT; i++) {
2025 while (display_data++) {
2026 if (display_data->id == -1)
2027 break;
2028 if (!display_data->name)
2029 continue;
2030 if (display_data->id != i)
2031 continue;
2032 display_admin_edit(
2033 table, part_msg, &row, model, iter,
2034 display_data,
2035 G_CALLBACK(_admin_edit_combo_box_part),
2036 G_CALLBACK(_admin_focus_out_part),
2037 _set_active_combo_part);
2038 break;
2039 }
2040 display_data = create_data_part;
2041 }
2042 gtk_table_resize(table, row, 2);
2043
2044 return GTK_WIDGET(window);
2045 }
2046
check_part_includes_node(int node_dx)2047 extern bool check_part_includes_node(int node_dx)
2048 {
2049 partition_info_t *part_ptr = NULL;
2050 bool rc = false;
2051 int i;
2052 static partition_info_msg_t *part_info_ptr = NULL;
2053
2054 if (working_sview_config.show_hidden)
2055 return true;
2056
2057 if (!g_part_info_ptr) {
2058 i = get_new_info_part(&part_info_ptr, true);
2059 if (!g_part_info_ptr || (i && (i != SLURM_NO_CHANGE_IN_DATA))) {
2060 if (_DEBUG)
2061 g_print("%s : error %d ", __func__, i);
2062 return false;
2063 }
2064 }
2065
2066 for (i = 0; i < g_part_info_ptr->record_count; i++) {
2067 /* don't include allow group or hidden excludes */
2068 part_ptr = &(g_part_info_ptr->partition_array[i]);
2069 if (part_ptr->flags & PART_FLAG_HIDDEN)
2070 continue;
2071 if (part_ptr->node_inx[0] >= 0) {
2072 if (_DEBUG) {
2073 g_print("node_dx = %d ", node_dx);
2074 g_print("part_node_inx[0] = %d ",
2075 part_ptr->node_inx[0]);
2076 g_print("part_node_inx[1] = %d \n",
2077 part_ptr->node_inx[1]);
2078 }
2079 if (node_dx >= part_ptr->node_inx[0] &&
2080 node_dx <= part_ptr->node_inx[1]) {
2081 rc = true;
2082 if (_DEBUG)
2083 g_print("hit!!\n");
2084 }
2085 }
2086 if (rc)
2087 break;
2088 }
2089 return rc;
2090 }
2091
2092
refresh_part(GtkAction * action,gpointer user_data)2093 extern void refresh_part(GtkAction *action, gpointer user_data)
2094 {
2095 popup_info_t *popup_win = (popup_info_t *)user_data;
2096 xassert(popup_win);
2097 xassert(popup_win->spec_info);
2098 xassert(popup_win->spec_info->title);
2099 popup_win->force_refresh = 1;
2100 specific_info_part(popup_win);
2101 }
2102
2103
get_new_info_part(partition_info_msg_t ** part_ptr,int force)2104 extern int get_new_info_part(partition_info_msg_t **part_ptr, int force)
2105 {
2106 static partition_info_msg_t *new_part_ptr = NULL;
2107 uint16_t show_flags = 0;
2108 int error_code = SLURM_NO_CHANGE_IN_DATA;
2109 time_t now = time(NULL);
2110 static time_t last;
2111 static bool changed = 0;
2112 static uint16_t last_flags = 0;
2113
2114 if (g_part_info_ptr && !force
2115 && ((now - last) < working_sview_config.refresh_delay)) {
2116 if (*part_ptr != g_part_info_ptr)
2117 error_code = SLURM_SUCCESS;
2118 *part_ptr = g_part_info_ptr;
2119 if (changed)
2120 error_code = SLURM_SUCCESS;
2121 goto end_it;
2122 }
2123 last = now;
2124
2125 if (cluster_flags & CLUSTER_FLAG_FED)
2126 show_flags |= SHOW_FEDERATION;
2127 if (working_sview_config.show_hidden)
2128 /*ignore 'AllowGroups, Hidden settings*/
2129 show_flags |= SHOW_ALL;
2130
2131 if (g_part_info_ptr) {
2132 if (show_flags != last_flags)
2133 g_part_info_ptr->last_update = 0;
2134 error_code = slurm_load_partitions(g_part_info_ptr->last_update,
2135 &new_part_ptr, show_flags);
2136 if (error_code == SLURM_SUCCESS) {
2137 slurm_free_partition_info_msg(g_part_info_ptr);
2138 changed = 1;
2139 } else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
2140 error_code = SLURM_NO_CHANGE_IN_DATA;
2141 new_part_ptr = g_part_info_ptr;
2142 changed = 0;
2143 }
2144 } else {
2145 new_part_ptr = NULL;
2146 error_code = slurm_load_partitions((time_t) NULL, &new_part_ptr,
2147 show_flags);
2148 changed = 1;
2149 }
2150
2151 last_flags = show_flags;
2152 g_part_info_ptr = new_part_ptr;
2153
2154 if (g_part_info_ptr && (*part_ptr != g_part_info_ptr))
2155 error_code = SLURM_SUCCESS;
2156
2157 *part_ptr = new_part_ptr;
2158 end_it:
2159
2160 return error_code;
2161 }
2162
_create_model_part2(int type)2163 static GtkListStore *_create_model_part2(int type)
2164 {
2165 GtkListStore *model = NULL;
2166 GtkTreeIter iter;
2167
2168 last_model = NULL; /* Reformat display */
2169 switch (type) {
2170 case SORTID_DEFAULT:
2171 case SORTID_EXCLUSIVE_USER:
2172 case SORTID_HIDDEN:
2173 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2174 gtk_list_store_append(model, &iter);
2175 gtk_list_store_set(model, &iter,
2176 0, "no (default)", 1, SORTID_DEFAULT, -1);
2177 gtk_list_store_append(model, &iter);
2178 gtk_list_store_set(model, &iter,
2179 0, "yes", 1, SORTID_DEFAULT, -1);
2180 break;
2181 case SORTID_ROOT:
2182 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2183 gtk_list_store_append(model, &iter);
2184 gtk_list_store_set(model, &iter,
2185 0, "yes (default)", 1, SORTID_DEFAULT, -1);
2186 gtk_list_store_append(model, &iter);
2187 gtk_list_store_set(model, &iter,
2188 0, "no", 1, SORTID_DEFAULT, -1);
2189 break;
2190 case SORTID_OVER_SUBSCRIBE:
2191 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2192 gtk_list_store_append(model, &iter);
2193 gtk_list_store_set(model, &iter, 0, "no (default)",
2194 1, SORTID_OVER_SUBSCRIBE, -1);
2195 gtk_list_store_append(model, &iter);
2196 gtk_list_store_set(model, &iter, 0, "yes",
2197 1, SORTID_OVER_SUBSCRIBE, -1);
2198 gtk_list_store_append(model, &iter);
2199 gtk_list_store_set(model, &iter, 0, "force",
2200 1, SORTID_OVER_SUBSCRIBE, -1);
2201 gtk_list_store_append(model, &iter);
2202 gtk_list_store_set(model, &iter, 0, "exclusive",
2203 1, SORTID_OVER_SUBSCRIBE, -1);
2204 break;
2205 case SORTID_PART_STATE:
2206 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2207 gtk_list_store_append(model, &iter);
2208 gtk_list_store_set(model, &iter,
2209 0, "up (default)", 1, SORTID_PART_STATE, -1);
2210 gtk_list_store_append(model, &iter);
2211 gtk_list_store_set(model, &iter,
2212 0, "down", 1, SORTID_PART_STATE, -1);
2213 gtk_list_store_append(model, &iter);
2214 gtk_list_store_set(model, &iter,
2215 0, "inactive", 1, SORTID_PART_STATE, -1);
2216 gtk_list_store_append(model, &iter);
2217 gtk_list_store_set(model, &iter,
2218 0, "drain", 1, SORTID_PART_STATE, -1);
2219 break;
2220 case SORTID_PREEMPT_MODE:
2221 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2222 gtk_list_store_append(model, &iter);
2223 gtk_list_store_set(model, &iter, 0,
2224 preempt_mode_string(slurm_get_preempt_mode()),
2225 1, SORTID_PREEMPT_MODE, -1);
2226 gtk_list_store_append(model, &iter);
2227 gtk_list_store_set(model, &iter,
2228 0, "cancel", 1, SORTID_PREEMPT_MODE, -1);
2229 gtk_list_store_append(model, &iter);
2230 gtk_list_store_set(model, &iter,
2231 0, "off", 1, SORTID_PREEMPT_MODE, -1);
2232 gtk_list_store_append(model, &iter);
2233 gtk_list_store_set(model, &iter,
2234 0, "requeue", 1, SORTID_PREEMPT_MODE, -1);
2235 gtk_list_store_append(model, &iter);
2236 gtk_list_store_set(model, &iter,
2237 0, "suspend", 1, SORTID_PREEMPT_MODE, -1);
2238 break;
2239 }
2240
2241 return model;
2242 }
2243
create_model_part(int type)2244 extern GtkListStore *create_model_part(int type)
2245 {
2246 GtkListStore *model = NULL;
2247 GtkTreeIter iter;
2248 char *upper = NULL, *lower = NULL;
2249 int i = 0;
2250
2251 last_model = NULL; /* Reformat display */
2252 switch (type) {
2253 case SORTID_DEFAULT:
2254 case SORTID_EXCLUSIVE_USER:
2255 case SORTID_HIDDEN:
2256 case SORTID_ROOT:
2257 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2258 gtk_list_store_append(model, &iter);
2259 gtk_list_store_set(model, &iter,
2260 0, "yes", 1, type, -1);
2261 gtk_list_store_append(model, &iter);
2262 gtk_list_store_set(model, &iter,
2263 0, "no", 1, type, -1);
2264 break;
2265 case SORTID_PREEMPT_MODE:
2266 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2267 gtk_list_store_append(model, &iter);
2268 gtk_list_store_set(model, &iter,
2269 0, "cancel", 1, SORTID_PREEMPT_MODE, -1);
2270 gtk_list_store_append(model, &iter);
2271 gtk_list_store_set(model, &iter,
2272 0, "off", 1, SORTID_PREEMPT_MODE, -1);
2273 gtk_list_store_append(model, &iter);
2274 gtk_list_store_set(model, &iter,
2275 0, "requeue", 1, SORTID_PREEMPT_MODE, -1);
2276 gtk_list_store_append(model, &iter);
2277 gtk_list_store_set(model, &iter,
2278 0, "suspend", 1, SORTID_PREEMPT_MODE, -1);
2279 break;
2280 case SORTID_GRACE_TIME:
2281 case SORTID_JOB_DEFAULTS:
2282 case SORTID_PRIORITY_JOB_FACTOR:
2283 case SORTID_PRIORITY_TIER:
2284 case SORTID_TIMELIMIT:
2285 case SORTID_NODES_MIN:
2286 case SORTID_NODES_MAX:
2287 case SORTID_MAX_CPUS_PER_NODE:
2288 case SORTID_OVER_TIME_LIMIT:
2289 break;
2290 case SORTID_OVER_SUBSCRIBE:
2291 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2292 gtk_list_store_append(model, &iter);
2293 gtk_list_store_set(model, &iter, 0, "force",
2294 1, SORTID_OVER_SUBSCRIBE, -1);
2295 gtk_list_store_append(model, &iter);
2296 gtk_list_store_set(model, &iter, 0, "no",
2297 1, SORTID_OVER_SUBSCRIBE, -1);
2298 gtk_list_store_append(model, &iter);
2299 gtk_list_store_set(model, &iter, 0, "yes",
2300 1, SORTID_OVER_SUBSCRIBE, -1);
2301 gtk_list_store_append(model, &iter);
2302 gtk_list_store_set(model, &iter, 0, "exclusive",
2303 1, SORTID_OVER_SUBSCRIBE, -1);
2304 break;
2305 case SORTID_ALLOW_ACCOUNTS:
2306 break;
2307 case SORTID_ALLOW_GROUPS:
2308 break;
2309 case SORTID_ALLOW_QOS:
2310 break;
2311 case SORTID_DENY_ACCOUNTS:
2312 break;
2313 case SORTID_DENY_QOS:
2314 break;
2315 case SORTID_NODELIST:
2316 break;
2317 case SORTID_PART_STATE:
2318 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2319 gtk_list_store_append(model, &iter);
2320 gtk_list_store_set(model, &iter,
2321 0, "up", 1, SORTID_PART_STATE, -1);
2322 gtk_list_store_append(model, &iter);
2323 gtk_list_store_set(model, &iter,
2324 0, "down", 1, SORTID_PART_STATE, -1);
2325 gtk_list_store_append(model, &iter);
2326 gtk_list_store_set(model, &iter,
2327 0, "inactive", 1, SORTID_PART_STATE, -1);
2328 gtk_list_store_append(model, &iter);
2329 gtk_list_store_set(model, &iter,
2330 0, "drain", 1, SORTID_PART_STATE, -1);
2331 break;
2332 case SORTID_NODE_STATE:
2333 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
2334 gtk_list_store_append(model, &iter);
2335 gtk_list_store_set(model, &iter,
2336 0, "drain", 1, SORTID_NODE_STATE, -1);
2337 gtk_list_store_append(model, &iter);
2338 gtk_list_store_set(model, &iter,
2339 0, "resume", 1, SORTID_NODE_STATE, -1);
2340 for (i = 0; i < NODE_STATE_END; i++) {
2341 upper = node_state_string(i);
2342 if (!xstrcmp(upper, "UNKNOWN"))
2343 continue;
2344
2345 gtk_list_store_append(model, &iter);
2346 lower = str_tolower(upper);
2347 gtk_list_store_set(model, &iter,
2348 0, lower, 1, SORTID_NODE_STATE, -1);
2349 xfree(lower);
2350 }
2351
2352 break;
2353 }
2354
2355 return model;
2356 }
2357
admin_edit_part(GtkCellRendererText * cell,const char * path_string,const char * new_text,gpointer data)2358 extern void admin_edit_part(GtkCellRendererText *cell,
2359 const char *path_string,
2360 const char *new_text,
2361 gpointer data)
2362 {
2363 GtkTreeStore *treestore = NULL;
2364 GtkTreePath *path = NULL;
2365 GtkTreeIter iter;
2366 update_part_msg_t *part_msg = NULL;
2367
2368 char *temp = NULL;
2369 char *old_text = NULL;
2370 const char *type = NULL;
2371 int column;
2372
2373 if (!new_text || !xstrcmp(new_text, ""))
2374 goto no_input;
2375
2376 if (cluster_flags & CLUSTER_FLAG_FED) {
2377 display_fed_disabled_popup(type);
2378 goto no_input;
2379 }
2380
2381 part_msg = xmalloc(sizeof(update_part_msg_t));
2382
2383 treestore = GTK_TREE_STORE(data);
2384 path = gtk_tree_path_new_from_string(path_string);
2385 gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
2386
2387 column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell), "column"));
2388 if (column != SORTID_NODE_STATE) {
2389 slurm_init_part_desc_msg(part_msg);
2390 gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
2391 SORTID_NAME, &temp,
2392 column, &old_text,
2393 -1);
2394 part_msg->name = xstrdup(temp);
2395 g_free(temp);
2396 }
2397
2398 type = _set_part_msg(part_msg, new_text, column);
2399 if (global_edit_error)
2400 goto print_error;
2401 if (got_edit_signal) {
2402 temp = got_edit_signal;
2403 got_edit_signal = NULL;
2404 admin_part(GTK_TREE_MODEL(treestore), &iter, temp);
2405 xfree(temp);
2406 goto no_input;
2407 }
2408
2409 if (got_features_edit_signal) {
2410 admin_part(GTK_TREE_MODEL(treestore), &iter, (char *)type);
2411 goto no_input;
2412 }
2413
2414 if ((column != SORTID_NODE_STATE) && (column != SORTID_FEATURES)) {
2415 if (old_text && !xstrcmp(old_text, new_text)) {
2416 temp = g_strdup_printf("No change in value.");
2417 } else if (slurm_update_partition(part_msg)
2418 == SLURM_SUCCESS) {
2419 gtk_tree_store_set(treestore, &iter, column,
2420 new_text, -1);
2421 temp = g_strdup_printf("Partition %s %s changed to %s",
2422 part_msg->name,
2423 type,
2424 new_text);
2425 } else {
2426 print_error:
2427 temp = g_strdup_printf("Partition %s %s can't be "
2428 "set to %s",
2429 part_msg->name,
2430 type,
2431 new_text);
2432 }
2433 display_edit_note(temp);
2434 g_free(temp);
2435 }
2436 no_input:
2437 slurm_free_update_part_msg(part_msg);
2438 gtk_tree_path_free(path);
2439 g_free(old_text);
2440 g_mutex_unlock(sview_mutex);
2441 }
2442
get_info_part(GtkTable * table,display_data_t * display_data)2443 extern void get_info_part(GtkTable *table, display_data_t *display_data)
2444 {
2445 int part_error_code = SLURM_SUCCESS;
2446 int node_error_code = SLURM_SUCCESS;
2447 static int view = -1;
2448 static partition_info_msg_t *part_info_ptr = NULL;
2449 static node_info_msg_t *node_info_ptr = NULL;
2450 char error_char[100];
2451 GtkWidget *label = NULL;
2452 GtkTreeView *tree_view = NULL;
2453 static GtkWidget *display_widget = NULL;
2454 List info_list = NULL;
2455 int j, k;
2456 sview_part_info_t *sview_part_info = NULL;
2457 partition_info_t *part_ptr = NULL;
2458 ListIterator itr = NULL;
2459 GtkTreePath *path = NULL;
2460 static bool set_opts = false;
2461
2462 if (!set_opts)
2463 set_page_opts(PART_PAGE, display_data_part,
2464 SORTID_CNT, _initial_page_opts);
2465 set_opts = true;
2466
2467 /* reset */
2468 if (!table && !display_data) {
2469 if (display_widget)
2470 gtk_widget_destroy(display_widget);
2471 display_widget = NULL;
2472 part_info_ptr = NULL;
2473 node_info_ptr = NULL;
2474 goto reset_curs;
2475 }
2476
2477 if (display_data)
2478 local_display_data = display_data;
2479 if (!table) {
2480 display_data_part->set_menu = local_display_data->set_menu;
2481 goto reset_curs;
2482 }
2483 if (display_widget && toggled) {
2484 gtk_widget_destroy(display_widget);
2485 display_widget = NULL;
2486 goto display_it;
2487 }
2488
2489 if ((part_error_code = get_new_info_part(&part_info_ptr, force_refresh))
2490 == SLURM_NO_CHANGE_IN_DATA) {
2491 // just goto the new info node
2492 } else if (part_error_code != SLURM_SUCCESS) {
2493 if (view == ERROR_VIEW)
2494 goto end_it;
2495 if (display_widget)
2496 gtk_widget_destroy(display_widget);
2497 view = ERROR_VIEW;
2498 snprintf(error_char, 100, "slurm_load_partitions: %s",
2499 slurm_strerror(slurm_get_errno()));
2500 label = gtk_label_new(error_char);
2501 display_widget = g_object_ref(GTK_WIDGET(label));
2502 gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
2503 gtk_widget_show(label);
2504 goto end_it;
2505 }
2506
2507 if ((node_error_code = get_new_info_node(&node_info_ptr, force_refresh))
2508 == SLURM_NO_CHANGE_IN_DATA) {
2509 if ((!display_widget || view == ERROR_VIEW)
2510 || (part_error_code != SLURM_NO_CHANGE_IN_DATA))
2511 goto display_it;
2512 } else if (node_error_code != SLURM_SUCCESS) {
2513 if (view == ERROR_VIEW)
2514 goto end_it;
2515 if (display_widget)
2516 gtk_widget_destroy(display_widget);
2517 view = ERROR_VIEW;
2518 snprintf(error_char, 100, "slurm_load_node: %s",
2519 slurm_strerror(slurm_get_errno()));
2520 label = gtk_label_new(error_char);
2521 display_widget = g_object_ref(GTK_WIDGET(label));
2522 gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
2523 gtk_widget_show(label);
2524 goto end_it;
2525 }
2526
2527 display_it:
2528
2529 info_list = _create_part_info_list(part_info_ptr, node_info_ptr);
2530 if (!info_list)
2531 goto reset_curs;
2532
2533 /* set up the grid */
2534 if (display_widget && GTK_IS_TREE_VIEW(display_widget)
2535 && gtk_tree_selection_count_selected_rows(
2536 gtk_tree_view_get_selection(
2537 GTK_TREE_VIEW(display_widget)))) {
2538 GtkTreeViewColumn *focus_column = NULL;
2539 /* highlight the correct nodes from the last selection */
2540 gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget),
2541 &path, &focus_column);
2542 }
2543 if (!path) {
2544 int array_size = node_info_ptr->record_count;
2545 int *color_inx = xmalloc(sizeof(int) * array_size);
2546 bool *color_set_flag = xmalloc(sizeof(bool) * array_size);
2547 itr = list_iterator_create(info_list);
2548 while ((sview_part_info = list_next(itr))) {
2549 part_ptr = sview_part_info->part_ptr;
2550 j = 0;
2551 while (part_ptr->node_inx[j] >= 0) {
2552 for (k = part_ptr->node_inx[j];
2553 k <= part_ptr->node_inx[j+1]; k++) {
2554 color_set_flag[k] = true;
2555 color_inx[k] = sview_part_info->
2556 color_inx;
2557 }
2558 j += 2;
2559 }
2560 }
2561 list_iterator_destroy(itr);
2562 change_grid_color_array(grid_button_list, array_size,
2563 color_inx, color_set_flag, true, 0);
2564 change_grid_color(grid_button_list, -1, -1,
2565 MAKE_WHITE, true, 0);
2566 xfree(color_inx);
2567 xfree(color_set_flag);
2568 } else {
2569 highlight_grid(GTK_TREE_VIEW(display_widget),
2570 SORTID_NODE_INX, SORTID_COLOR_INX,
2571 grid_button_list);
2572 gtk_tree_path_free(path);
2573 }
2574
2575 if (view == ERROR_VIEW && display_widget) {
2576 gtk_widget_destroy(display_widget);
2577 display_widget = NULL;
2578 }
2579 if (!display_widget) {
2580 int def_sort_col = SORTID_NAME;
2581 tree_view = create_treeview(local_display_data,
2582 &grid_button_list);
2583 /*set multiple capability here*/
2584 gtk_tree_selection_set_mode(
2585 gtk_tree_view_get_selection(tree_view),
2586 GTK_SELECTION_MULTIPLE);
2587 display_widget = g_object_ref(GTK_WIDGET(tree_view));
2588 gtk_table_attach_defaults(table,
2589 GTK_WIDGET(tree_view),
2590 0, 1, 0, 1);
2591 /* since this function sets the model of the tree_view
2592 to the treestore we don't really care about
2593 the return value */
2594 if (cluster_flags & CLUSTER_FLAG_FED)
2595 def_sort_col = SORTID_CLUSTER_NAME;
2596 create_treestore(tree_view, display_data_part, SORTID_CNT,
2597 def_sort_col, SORTID_COLOR);
2598 }
2599
2600 view = INFO_VIEW;
2601 _update_info_part(info_list, GTK_TREE_VIEW(display_widget));
2602 end_it:
2603 toggled = false;
2604 force_refresh = false;
2605 reset_curs:
2606 if (main_window && main_window->window)
2607 gdk_window_set_cursor(main_window->window, NULL);
2608 return;
2609 }
2610
specific_info_part(popup_info_t * popup_win)2611 extern void specific_info_part(popup_info_t *popup_win)
2612 {
2613 int part_error_code = SLURM_SUCCESS;
2614 int node_error_code = SLURM_SUCCESS;
2615 static partition_info_msg_t *part_info_ptr = NULL;
2616 static node_info_msg_t *node_info_ptr = NULL;
2617 specific_info_t *spec_info = popup_win->spec_info;
2618 char error_char[100];
2619 GtkWidget *label = NULL;
2620 GtkTreeView *tree_view = NULL;
2621 List info_list = NULL;
2622 List send_info_list = NULL;
2623 int j=0, i=-1;
2624 sview_part_info_t *sview_part_info_ptr = NULL;
2625 partition_info_t *part_ptr = NULL;
2626 ListIterator itr = NULL;
2627 hostset_t hostset = NULL;
2628
2629 if (!spec_info->display_widget)
2630 setup_popup_info(popup_win, display_data_part, SORTID_CNT);
2631
2632 if (spec_info->display_widget && popup_win->toggled) {
2633 gtk_widget_destroy(spec_info->display_widget);
2634 spec_info->display_widget = NULL;
2635 goto display_it;
2636 }
2637
2638 if ((part_error_code = get_new_info_part(&part_info_ptr,
2639 popup_win->force_refresh))
2640 == SLURM_NO_CHANGE_IN_DATA) {
2641
2642 } else if (part_error_code != SLURM_SUCCESS) {
2643 if (spec_info->view == ERROR_VIEW)
2644 goto end_it;
2645 if (spec_info->display_widget) {
2646 gtk_widget_destroy(spec_info->display_widget);
2647 spec_info->display_widget = NULL;
2648 }
2649 spec_info->view = ERROR_VIEW;
2650 snprintf(error_char, 100, "slurm_load_partitions: %s",
2651 slurm_strerror(slurm_get_errno()));
2652 label = gtk_label_new(error_char);
2653 spec_info->display_widget = g_object_ref(GTK_WIDGET(label));
2654 gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1);
2655 gtk_widget_show(label);
2656 goto end_it;
2657 }
2658
2659 if ((node_error_code = get_new_info_node(&node_info_ptr,
2660 popup_win->force_refresh))
2661 == SLURM_NO_CHANGE_IN_DATA) {
2662 if ((!spec_info->display_widget
2663 || spec_info->view == ERROR_VIEW)
2664 || (part_error_code != SLURM_NO_CHANGE_IN_DATA))
2665 goto display_it;
2666 } else if (node_error_code != SLURM_SUCCESS) {
2667 if (spec_info->view == ERROR_VIEW)
2668 goto end_it;
2669 if (spec_info->display_widget)
2670 gtk_widget_destroy(spec_info->display_widget);
2671 spec_info->view = ERROR_VIEW;
2672 snprintf(error_char, 100, "slurm_load_node: %s",
2673 slurm_strerror(slurm_get_errno()));
2674 label = gtk_label_new(error_char);
2675 spec_info->display_widget = g_object_ref(GTK_WIDGET(label));
2676 gtk_table_attach_defaults(popup_win->table, label, 0, 1, 0, 1);
2677 gtk_widget_show(label);
2678 goto end_it;
2679 }
2680
2681 display_it:
2682
2683 info_list = _create_part_info_list(part_info_ptr, node_info_ptr);
2684
2685 if (!info_list)
2686 return;
2687
2688 if (spec_info->view == ERROR_VIEW && spec_info->display_widget) {
2689 gtk_widget_destroy(spec_info->display_widget);
2690 spec_info->display_widget = NULL;
2691 }
2692
2693 if (spec_info->type != INFO_PAGE && !spec_info->display_widget) {
2694 tree_view = create_treeview(local_display_data,
2695 &popup_win->grid_button_list);
2696 /*set multiple capability here*/
2697 gtk_tree_selection_set_mode(
2698 gtk_tree_view_get_selection(tree_view),
2699 GTK_SELECTION_MULTIPLE);
2700
2701 spec_info->display_widget =
2702 g_object_ref(GTK_WIDGET(tree_view));
2703 gtk_table_attach_defaults(popup_win->table,
2704 GTK_WIDGET(tree_view),
2705 0, 1, 0, 1);
2706
2707 /* since this function sets the model of the tree_view
2708 to the treestore we don't really care about
2709 the return value */
2710 create_treestore(tree_view, popup_win->display_data,
2711 SORTID_CNT, SORTID_NAME, SORTID_COLOR);
2712 }
2713
2714 setup_popup_grid_list(popup_win);
2715
2716 spec_info->view = INFO_VIEW;
2717 if (spec_info->type == INFO_PAGE) {
2718 _display_info_part(info_list, popup_win);
2719 goto end_it;
2720 }
2721
2722 /* just linking to another list, don't free the inside, just
2723 the list */
2724 send_info_list = list_create(NULL);
2725
2726 itr = list_iterator_create(info_list);
2727 i = -1;
2728 while ((sview_part_info_ptr = list_next(itr))) {
2729 i++;
2730 part_ptr = sview_part_info_ptr->part_ptr;
2731 switch (spec_info->type) {
2732 case RESV_PAGE:
2733 case NODE_PAGE:
2734 if (!part_ptr->nodes)
2735 continue;
2736
2737 if (!(hostset = hostset_create(
2738 spec_info->search_info->gchar_data)))
2739 continue;
2740 if (!hostset_intersects(hostset, part_ptr->nodes)) {
2741 hostset_destroy(hostset);
2742 continue;
2743 }
2744 hostset_destroy(hostset);
2745 break;
2746 case PART_PAGE:
2747 switch(spec_info->search_info->search_type) {
2748 case SEARCH_PARTITION_NAME:
2749 if (!spec_info->search_info->gchar_data)
2750 continue;
2751
2752 if (xstrcmp(part_ptr->name,
2753 spec_info->search_info->gchar_data))
2754 continue;
2755
2756 if (spec_info->search_info->cluster_name &&
2757 xstrcmp(
2758 part_ptr->cluster_name,
2759 spec_info->search_info->cluster_name))
2760 continue;
2761 break;
2762 case SEARCH_PARTITION_STATE:
2763 if (spec_info->search_info->int_data == NO_VAL)
2764 continue;
2765 if (part_ptr->state_up !=
2766 spec_info->search_info->int_data)
2767 continue;
2768 break;
2769 default:
2770 continue;
2771 break;
2772 }
2773 break;
2774 case JOB_PAGE:
2775 if (!spec_info->search_info->gchar_data)
2776 continue;
2777
2778 if (xstrcmp(part_ptr->name,
2779 spec_info->search_info->gchar_data))
2780 continue;
2781
2782 if (spec_info->search_info->cluster_name &&
2783 xstrcmp(part_ptr->cluster_name,
2784 spec_info->search_info->cluster_name))
2785 continue;
2786 break;
2787 default:
2788 g_print("Unknown type %d\n", spec_info->type);
2789 list_iterator_destroy(itr);
2790 goto end_it;
2791 }
2792 list_push(send_info_list, sview_part_info_ptr);
2793 j=0;
2794 while (part_ptr->node_inx[j] >= 0) {
2795 change_grid_color(
2796 popup_win->grid_button_list,
2797 part_ptr->node_inx[j],
2798 part_ptr->node_inx[j+1],
2799 sview_part_info_ptr->color_inx, true, 0);
2800 j += 2;
2801 }
2802 }
2803 list_iterator_destroy(itr);
2804 post_setup_popup_grid_list(popup_win);
2805
2806 _update_info_part(send_info_list,
2807 GTK_TREE_VIEW(spec_info->display_widget));
2808 FREE_NULL_LIST(send_info_list);
2809 end_it:
2810 popup_win->toggled = 0;
2811 popup_win->force_refresh = 0;
2812
2813 return;
2814 }
2815
set_menus_part(void * arg,void * arg2,GtkTreePath * path,int type)2816 extern void set_menus_part(void *arg, void *arg2, GtkTreePath *path, int type)
2817 {
2818 GtkTreeView *tree_view = (GtkTreeView *)arg;
2819 popup_info_t *popup_win = (popup_info_t *)arg;
2820 GtkMenu *menu = (GtkMenu *)arg2;
2821 List button_list = (List)arg2;
2822
2823 switch(type) {
2824 case TAB_CLICKED:
2825 make_fields_menu(NULL, menu, display_data_part, SORTID_CNT);
2826 break;
2827 case ROW_CLICKED:
2828 make_options_menu(tree_view, path, menu, options_data_part);
2829 break;
2830 case ROW_LEFT_CLICKED:
2831 highlight_grid(tree_view, SORTID_NODE_INX,
2832 SORTID_COLOR_INX, button_list);
2833 break;
2834 case FULL_CLICKED:
2835 {
2836 GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
2837 GtkTreeIter iter;
2838 if (!gtk_tree_model_get_iter(model, &iter, path)) {
2839 g_error("error getting iter from model\n");
2840 break;
2841 }
2842
2843 popup_all_part(model, &iter, INFO_PAGE);
2844
2845 break;
2846 }
2847 case POPUP_CLICKED:
2848 make_fields_menu(popup_win, menu,
2849 popup_win->display_data, SORTID_CNT);
2850 break;
2851 default:
2852 g_error("UNKNOWN type %d given to set_fields\n", type);
2853 }
2854 }
2855
popup_all_part(GtkTreeModel * model,GtkTreeIter * iter,int id)2856 extern void popup_all_part(GtkTreeModel *model, GtkTreeIter *iter, int id)
2857 {
2858 char *name = NULL;
2859 char *cluster_name = NULL;
2860 char *state = NULL;
2861 char title[100] = {0};
2862 int only_line = 0;
2863 ListIterator itr = NULL;
2864 popup_info_t *popup_win = NULL;
2865 GError *error = NULL;
2866 GtkTreeIter par_iter;
2867
2868 gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
2869 gtk_tree_model_get(model, iter, SORTID_CLUSTER_NAME, &cluster_name, -1);
2870
2871 switch(id) {
2872 case JOB_PAGE:
2873 snprintf(title, 100, "Job(s) in partition %s", name);
2874 break;
2875 case RESV_PAGE:
2876 snprintf(title, 100, "Reservation(s) in partition %s", name);
2877 break;
2878 case NODE_PAGE:
2879 gtk_tree_model_get(model, iter, SORTID_ONLY_LINE,
2880 &only_line, -1);
2881 if (!only_line)
2882 gtk_tree_model_get(model, iter,
2883 SORTID_NODE_STATE, &state, -1);
2884 if (!state || !strlen(state))
2885 snprintf(title, 100, "Node(s) in partition %s ",
2886 name);
2887 else
2888 snprintf(title, 100,
2889 "Node(s) in partition %s that are in "
2890 "'%s' state",
2891 name, state);
2892 break;
2893 case SUBMIT_PAGE:
2894 snprintf(title, 100, "Submit job in partition %s", name);
2895 break;
2896 case INFO_PAGE:
2897 snprintf(title, 100, "Full info for partition %s", name);
2898 break;
2899 default:
2900 g_print("part got %d\n", id);
2901 }
2902
2903 if (cluster_name && federation_name &&
2904 (cluster_flags & CLUSTER_FLAG_FED)) {
2905 char *tmp_cname = xstrdup_printf(" (%s:%s)",
2906 federation_name, cluster_name);
2907 strncat(title, tmp_cname, sizeof(title) - strlen(title) - 1);
2908 xfree(tmp_cname);
2909 }
2910
2911 itr = list_iterator_create(popup_list);
2912 while ((popup_win = list_next(itr))) {
2913 if (popup_win->spec_info)
2914 if (!xstrcmp(popup_win->spec_info->title, title)) {
2915 break;
2916 }
2917 }
2918 list_iterator_destroy(itr);
2919
2920 if (!popup_win) {
2921 if (id == INFO_PAGE)
2922 popup_win = create_popup_info(id, PART_PAGE, title);
2923 else
2924 popup_win = create_popup_info(PART_PAGE, id, title);
2925 } else {
2926 g_free(name);
2927 g_free(cluster_name);
2928 g_free(state);
2929 gtk_window_present(GTK_WINDOW(popup_win->popup));
2930 return;
2931 }
2932
2933 /* Pass the model and the structs from the iter so we can always get
2934 the current node_inx.
2935 */
2936 popup_win->model = model;
2937 popup_win->iter = *iter;
2938 popup_win->node_inx_id = SORTID_NODE_INX;
2939
2940 if (cluster_flags & CLUSTER_FLAG_FED) {
2941 popup_win->spec_info->search_info->cluster_name = cluster_name;
2942 cluster_name = NULL;
2943 }
2944 g_free(cluster_name);
2945
2946 switch (id) {
2947 case JOB_PAGE:
2948 case INFO_PAGE:
2949 popup_win->spec_info->search_info->gchar_data = name;
2950 //specific_info_job(popup_win);
2951 break;
2952 case RESV_PAGE:
2953 case NODE_PAGE:
2954 g_free(name);
2955 /* we want to include the parent's nodes here not just
2956 the subset */
2957 if (gtk_tree_model_iter_parent(model, &par_iter, iter))
2958 gtk_tree_model_get(model, &par_iter,
2959 SORTID_NODELIST, &name, -1);
2960 else
2961 gtk_tree_model_get(model, iter,
2962 SORTID_NODELIST, &name, -1);
2963 popup_win->spec_info->search_info->gchar_data = name;
2964 if (state && strlen(state)) {
2965 popup_win->spec_info->search_info->search_type =
2966 SEARCH_NODE_STATE;
2967 gtk_tree_model_get(
2968 model, iter, SORTID_NODE_STATE_NUM,
2969 &popup_win->spec_info->search_info->int_data,
2970 -1);
2971 } else {
2972 popup_win->spec_info->search_info->search_type =
2973 SEARCH_NODE_NAME;
2974 }
2975 g_free(state);
2976
2977 //specific_info_node(popup_win);
2978 break;
2979 case SUBMIT_PAGE:
2980 break;
2981 default:
2982 g_print("part got unknown type %d\n", id);
2983 }
2984 if (!sview_thread_new((gpointer)popup_thr, popup_win, false, &error)) {
2985 g_printerr ("Failed to create part popup thread: %s\n",
2986 error->message);
2987 return;
2988 }
2989 }
2990
select_admin_partitions(GtkTreeModel * model,GtkTreeIter * iter,display_data_t * display_data,GtkTreeView * treeview)2991 extern void select_admin_partitions(GtkTreeModel *model,
2992 GtkTreeIter *iter,
2993 display_data_t *display_data,
2994 GtkTreeView *treeview)
2995 {
2996 select_admin_common(model, iter, display_data, treeview,
2997 SORTID_NODELIST, _process_each_partition);
2998 } /*select_admin_partitions ^^^*/
2999
3000
admin_part(GtkTreeModel * model,GtkTreeIter * iter,char * type)3001 extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
3002 {
3003 char *nodelist = NULL;
3004 char *partid = NULL;
3005 update_part_msg_t *part_msg = NULL;
3006 int edit_type = 0;
3007 int response = 0;
3008 char tmp_char[100];
3009 char *temp = NULL;
3010 GtkWidget *label = NULL;
3011 GtkWidget *entry = NULL;
3012 GtkWidget *popup = NULL;
3013
3014 if (cluster_flags & CLUSTER_FLAG_FED) {
3015 display_fed_disabled_popup(type);
3016 return;
3017 }
3018
3019 popup = gtk_dialog_new_with_buttons(
3020 type,
3021 GTK_WINDOW(main_window),
3022 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
3023 NULL);
3024 gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
3025
3026 gtk_window_set_type_hint(GTK_WINDOW(popup),
3027 GDK_WINDOW_TYPE_HINT_NORMAL);
3028
3029 gtk_tree_model_get(model, iter, SORTID_NAME, &partid, -1);
3030 gtk_tree_model_get(model, iter, SORTID_NODELIST, &nodelist, -1);
3031
3032 part_msg = xmalloc(sizeof(update_part_msg_t));
3033 slurm_init_part_desc_msg(part_msg);
3034 part_msg->name = xstrdup(partid);
3035
3036 if (!xstrcasecmp("Change Partition State", type)) {
3037 GtkCellRenderer *renderer = NULL;
3038 GtkTreeModel *model2 = GTK_TREE_MODEL(
3039 create_model_part(SORTID_PART_STATE));
3040 if (!model2) {
3041 g_print("In change part, no model set up for %d(%s)\n",
3042 SORTID_PART_STATE, partid);
3043 xfree(part_msg);
3044 return;
3045 }
3046 entry = gtk_combo_box_new_with_model(model2);
3047 g_object_unref(model2);
3048
3049 _set_active_combo_part(GTK_COMBO_BOX(entry),
3050 model, iter, SORTID_PART_STATE);
3051
3052 g_signal_connect(entry, "changed",
3053 G_CALLBACK(_admin_edit_combo_box_part),
3054 part_msg);
3055
3056 renderer = gtk_cell_renderer_text_new();
3057 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(entry),
3058 renderer, true);
3059 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(entry),
3060 renderer, "text", 0);
3061
3062 label = gtk_dialog_add_button(GTK_DIALOG(popup),
3063 GTK_STOCK_YES, GTK_RESPONSE_OK);
3064 gtk_window_set_default(GTK_WINDOW(popup), label);
3065 gtk_dialog_add_button(GTK_DIALOG(popup),
3066 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
3067
3068 snprintf(tmp_char, sizeof(tmp_char),
3069 "Which state would you like to set partition '%s' to?",
3070 partid);
3071 label = gtk_label_new(tmp_char);
3072 edit_type = EDIT_PART_STATE;
3073 } else if (!xstrcasecmp("Remove Partition", type)) {
3074 label = gtk_dialog_add_button(GTK_DIALOG(popup),
3075 GTK_STOCK_YES, GTK_RESPONSE_OK);
3076 gtk_window_set_default(GTK_WINDOW(popup), label);
3077 gtk_dialog_add_button(GTK_DIALOG(popup),
3078 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
3079
3080 snprintf(tmp_char, sizeof(tmp_char),
3081 "Are you sure you want to remove partition %s?",
3082 partid);
3083 label = gtk_label_new(tmp_char);
3084 edit_type = EDIT_REMOVE_PART;
3085 } else if (!xstrcasecmp("Edit Partition", type)) {
3086 label = gtk_dialog_add_button(GTK_DIALOG(popup),
3087 GTK_STOCK_OK, GTK_RESPONSE_OK);
3088 gtk_window_set_default(GTK_WINDOW(popup), label);
3089 gtk_dialog_add_button(GTK_DIALOG(popup),
3090 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
3091
3092 gtk_window_set_default_size(GTK_WINDOW(popup), 200, 400);
3093 snprintf(tmp_char, sizeof(tmp_char),
3094 "Editing partition %s think before you type",
3095 partid);
3096 label = gtk_label_new(tmp_char);
3097 edit_type = EDIT_EDIT;
3098 entry = _admin_full_edit_part(part_msg, model, iter);
3099 } else if (!xstrncasecmp("Update", type, 6)) {
3100 char *old_features = NULL;
3101 if (got_features_edit_signal)
3102 old_features = got_features_edit_signal;
3103 else
3104 gtk_tree_model_get(model, iter, SORTID_FEATURES,
3105 &old_features, -1);
3106 update_avail_features_node(GTK_DIALOG(popup),
3107 nodelist, old_features);
3108 if (got_features_edit_signal) {
3109 got_features_edit_signal = NULL;
3110 xfree(old_features);
3111 } else
3112 g_free(old_features);
3113 goto end_it;
3114 } else {
3115 /* something that has to deal with a node state change */
3116 update_state_node(GTK_DIALOG(popup), nodelist, type);
3117 goto end_it;
3118 }
3119
3120 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
3121 label, false, false, 0);
3122 if (entry)
3123 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
3124 entry, true, true, 0);
3125 gtk_widget_show_all(popup);
3126 response = gtk_dialog_run (GTK_DIALOG(popup));
3127
3128 if (response == GTK_RESPONSE_OK) {
3129 int rc;
3130 if (global_edit_error)
3131 temp = global_edit_error_msg;
3132 else if (edit_type == EDIT_REMOVE_PART) {
3133 delete_part_msg_t part_del_msg;
3134 part_del_msg.name = partid;
3135 rc = slurm_delete_partition(&part_del_msg);
3136 if (rc == SLURM_SUCCESS) {
3137 temp = g_strdup_printf(
3138 "Partition %s removed successfully",
3139 partid);
3140 } else {
3141 temp = g_strdup_printf(
3142 "Problem removing partition %s: %s",
3143 partid, slurm_strerror(rc));
3144 global_multi_error = true;
3145 }
3146 } else if (!global_send_update_msg) {
3147 temp = g_strdup_printf("No change detected.");
3148 } else if ((rc = slurm_update_partition(part_msg))
3149 == SLURM_SUCCESS) {
3150 temp = g_strdup_printf(
3151 "Partition %s updated successfully",
3152 partid);
3153 } else {
3154 temp = g_strdup_printf(
3155 "Problem updating partition %s: %s",
3156 partid, slurm_strerror(rc));
3157 global_multi_error = true;
3158 }
3159 display_edit_note(temp);
3160 g_free(temp);
3161 }
3162 end_it:
3163
3164 g_free(partid);
3165 g_free(nodelist);
3166 global_entry_changed = 0;
3167 slurm_free_update_part_msg(part_msg);
3168 gtk_widget_destroy(popup);
3169 if (got_edit_signal) {
3170 type = got_edit_signal;
3171 got_edit_signal = NULL;
3172 admin_part(model, iter, type);
3173 xfree(type);
3174 }
3175 if (got_features_edit_signal) {
3176 type = "Update Features";
3177 admin_part(model, iter, type);
3178 }
3179 return;
3180 }
3181
cluster_change_part(void)3182 extern void cluster_change_part(void)
3183 {
3184 display_data_t *display_data = display_data_part;
3185 while (display_data++) {
3186 if (display_data->id == -1)
3187 break;
3188 if (cluster_flags & CLUSTER_FLAG_FED) {
3189 switch(display_data->id) {
3190 case SORTID_CLUSTER_NAME:
3191 display_data->show = true;
3192 break;
3193 }
3194 } else {
3195 switch (display_data->id) {
3196 case SORTID_CLUSTER_NAME:
3197 display_data->show = false;
3198 break;
3199 }
3200 }
3201 }
3202
3203 get_info_part(NULL, NULL);
3204 }
3205