PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sview/front_end_info.c

https://github.com/cfenoy/slurm
C | 1090 lines | 915 code | 115 blank | 60 comment | 145 complexity | 10dbdef5b8e9599d4f078f2e73fbc6b7 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * front_end_info.c - Functions related to front end node display
  3. * mode of sview.
  4. *****************************************************************************
  5. * Copyright (C) 2004-2007 The Regents of the University of California.
  6. * Copyright (C) 2008-2011 Lawrence Livermore National Security.
  7. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  8. * Written by Morris Jette <jette@llnl.gov>
  9. * CODE-OCEC-09-009. All rights reserved.
  10. *
  11. * This file is part of SLURM, a resource management program.
  12. * For details, see <http://www.schedmd.com/slurmdocs/>.
  13. * Please also read the included file: DISCLAIMER.
  14. *
  15. * SLURM is free software; you can redistribute it and/or modify it under
  16. * the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. *
  20. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  21. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  22. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  23. * details.
  24. *
  25. * You should have received a copy of the GNU General Public License along
  26. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  27. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  28. \*****************************************************************************/
  29. #include "src/common/uid.h"
  30. #include "src/sview/sview.h"
  31. #include "src/common/parse_time.h"
  32. #define _DEBUG 0
  33. /* Collection of data for printing reports. Like data is combined here */
  34. typedef struct {
  35. int color_inx;
  36. front_end_info_t *front_end_ptr;
  37. char *boot_time;
  38. int node_inx[3];
  39. char *reason;
  40. char *slurmd_start_time;
  41. char *state;
  42. } sview_front_end_info_t;
  43. typedef struct {
  44. char *node_list;
  45. } front_end_user_data_t;
  46. enum {
  47. EDIT_REMOVE = 1,
  48. EDIT_EDIT
  49. };
  50. /* These need to be in alpha order (except POS and CNT) */
  51. enum {
  52. SORTID_POS = POS_LOC,
  53. SORTID_BOOT_TIME,
  54. SORTID_COLOR,
  55. SORTID_COLOR_INX,
  56. SORTID_NAME,
  57. SORTID_NODE_INX,
  58. SORTID_REASON,
  59. SORTID_SLURMD_START_TIME,
  60. SORTID_STATE,
  61. SORTID_CNT
  62. };
  63. /* extra field here is for choosing the type of edit you that will
  64. * take place. If you choose EDIT_MODEL (means only display a set of
  65. * known options) create it in function create_model_*.
  66. */
  67. /*these are the settings to apply for the user
  68. * on the first startup after a fresh slurm install.
  69. * s/b a const probably*/
  70. static char *_initial_page_opts = "Name,State";
  71. static display_data_t display_data_front_end[] = {
  72. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE,
  73. refresh_front_end, create_model_front_end, admin_edit_front_end},
  74. {G_TYPE_STRING, SORTID_NAME, "Name", FALSE, EDIT_NONE,
  75. refresh_front_end, create_model_front_end, admin_edit_front_end},
  76. {G_TYPE_STRING, SORTID_COLOR, NULL, TRUE, EDIT_COLOR,
  77. refresh_front_end, create_model_front_end, admin_edit_front_end},
  78. {G_TYPE_STRING, SORTID_STATE, "State", FALSE, EDIT_MODEL,
  79. refresh_front_end, create_model_front_end, admin_edit_front_end},
  80. {G_TYPE_STRING, SORTID_BOOT_TIME, "BootTime", FALSE, EDIT_NONE,
  81. refresh_front_end, create_model_front_end, admin_edit_front_end},
  82. {G_TYPE_STRING, SORTID_SLURMD_START_TIME, "SlurmdStartTime",
  83. FALSE, EDIT_NONE,
  84. refresh_front_end, create_model_front_end, admin_edit_front_end},
  85. {G_TYPE_STRING, SORTID_REASON, "Reason", FALSE, EDIT_NONE,
  86. refresh_front_end, create_model_front_end, admin_edit_front_end},
  87. {G_TYPE_INT, SORTID_COLOR_INX, NULL, FALSE, EDIT_NONE,
  88. refresh_front_end, create_model_front_end, admin_edit_front_end},
  89. {G_TYPE_POINTER, SORTID_NODE_INX, NULL, FALSE, EDIT_NONE,
  90. refresh_front_end, create_model_front_end, admin_edit_front_end},
  91. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  92. };
  93. static display_data_t options_data_front_end[] = {
  94. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE},
  95. {G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, FRONT_END_PAGE},
  96. {G_TYPE_STRING, FRONT_END_PAGE, "Drain Front End Node", TRUE,
  97. ADMIN_PAGE},
  98. {G_TYPE_STRING, FRONT_END_PAGE, "Resume Front End Node", TRUE,
  99. ADMIN_PAGE},
  100. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  101. };
  102. static display_data_t *local_display_data = NULL;
  103. static char *got_edit_signal = NULL;
  104. static void _admin_front_end(GtkTreeModel *model, GtkTreeIter *iter, char *type,
  105. char *node_list);
  106. static void _process_each_front_end(GtkTreeModel *model, GtkTreePath *path,
  107. GtkTreeIter*iter, gpointer userdata);
  108. static void _front_end_info_list_del(void *object)
  109. {
  110. sview_front_end_info_t *sview_front_end_info;
  111. sview_front_end_info = (sview_front_end_info_t *)object;
  112. if (sview_front_end_info) {
  113. xfree(sview_front_end_info->boot_time);
  114. xfree(sview_front_end_info->reason);
  115. xfree(sview_front_end_info->slurmd_start_time);
  116. xfree(sview_front_end_info->state);
  117. xfree(sview_front_end_info);
  118. }
  119. }
  120. static void _layout_front_end_record(GtkTreeView *treeview,
  121. sview_front_end_info_t *
  122. sview_front_end_info,
  123. int update)
  124. {
  125. GtkTreeIter iter;
  126. front_end_info_t *front_end_ptr =
  127. sview_front_end_info->front_end_ptr;
  128. GtkTreeStore *treestore =
  129. GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
  130. if (!treestore)
  131. return;
  132. add_display_treestore_line(update, treestore, &iter,
  133. find_col_name(display_data_front_end,
  134. SORTID_NAME),
  135. front_end_ptr->name);
  136. add_display_treestore_line(update, treestore, &iter,
  137. find_col_name(display_data_front_end,
  138. SORTID_STATE),
  139. sview_front_end_info->state);
  140. add_display_treestore_line(update, treestore, &iter,
  141. find_col_name(display_data_front_end,
  142. SORTID_BOOT_TIME),
  143. sview_front_end_info->boot_time);
  144. add_display_treestore_line(update, treestore, &iter,
  145. find_col_name(display_data_front_end,
  146. SORTID_SLURMD_START_TIME),
  147. sview_front_end_info->slurmd_start_time);
  148. add_display_treestore_line(update, treestore, &iter,
  149. find_col_name(display_data_front_end,
  150. SORTID_REASON),
  151. sview_front_end_info->reason);
  152. }
  153. static void _update_front_end_record(
  154. sview_front_end_info_t *sview_front_end_info_ptr,
  155. GtkTreeStore *treestore,
  156. GtkTreeIter *iter)
  157. {
  158. front_end_info_t *front_end_ptr;
  159. front_end_ptr = sview_front_end_info_ptr->front_end_ptr;
  160. /* Combining these records provides a slight performance improvement */
  161. gtk_tree_store_set(treestore, iter,
  162. SORTID_BOOT_TIME,
  163. sview_front_end_info_ptr->boot_time,
  164. SORTID_COLOR, sview_colors[
  165. sview_front_end_info_ptr->color_inx],
  166. SORTID_COLOR_INX,
  167. sview_front_end_info_ptr->color_inx,
  168. SORTID_NODE_INX,
  169. sview_front_end_info_ptr->node_inx,
  170. SORTID_NAME, front_end_ptr->name,
  171. SORTID_REASON, sview_front_end_info_ptr->reason,
  172. SORTID_SLURMD_START_TIME,
  173. sview_front_end_info_ptr->slurmd_start_time,
  174. SORTID_STATE, sview_front_end_info_ptr->state,
  175. -1);
  176. return;
  177. }
  178. static void _append_front_end_record(
  179. sview_front_end_info_t *sview_front_end_info_ptr,
  180. GtkTreeStore *treestore, GtkTreeIter *iter,
  181. int line)
  182. {
  183. gtk_tree_store_append(treestore, iter, NULL);
  184. gtk_tree_store_set(treestore, iter, SORTID_POS, line, -1);
  185. _update_front_end_record(sview_front_end_info_ptr, treestore, iter);
  186. }
  187. static void _update_info_front_end(List info_list, GtkTreeView *tree_view)
  188. {
  189. GtkTreePath *path = gtk_tree_path_new_first();
  190. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  191. GtkTreeIter iter;
  192. front_end_info_t *front_end_ptr = NULL;
  193. int line = 0;
  194. char *host = NULL, *front_end_name = NULL;
  195. ListIterator itr = NULL;
  196. sview_front_end_info_t *sview_front_end_info = NULL;
  197. /* get the iter, or find out the list is empty goto add */
  198. if (gtk_tree_model_get_iter(model, &iter, path)) {
  199. /* make sure all the reserves are still here */
  200. while (1) {
  201. if (!gtk_tree_model_iter_next(model, &iter)) {
  202. break;
  203. }
  204. }
  205. }
  206. itr = list_iterator_create(info_list);
  207. while ((sview_front_end_info = list_next(itr))) {
  208. front_end_ptr = sview_front_end_info->front_end_ptr;
  209. /* get the iter, or find out the list is empty goto add */
  210. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  211. goto adding;
  212. }
  213. line = 0;
  214. while (1) {
  215. /* search for the jobid and check to see if
  216. it is in the list */
  217. gtk_tree_model_get(model, &iter, SORTID_NAME,
  218. &front_end_name, -1);
  219. if (!strcmp(front_end_name, front_end_ptr->name)) {
  220. /* update with new info */
  221. g_free(front_end_name);
  222. _update_front_end_record(sview_front_end_info,
  223. GTK_TREE_STORE(model),
  224. &iter);
  225. goto found;
  226. }
  227. g_free(front_end_name);
  228. line++;
  229. if (!gtk_tree_model_iter_next(model, &iter)) {
  230. break;
  231. }
  232. }
  233. adding:
  234. _append_front_end_record(sview_front_end_info,
  235. GTK_TREE_STORE(model),
  236. &iter, line);
  237. found:
  238. ;
  239. }
  240. list_iterator_destroy(itr);
  241. if (host)
  242. free(host);
  243. gtk_tree_path_free(path);
  244. return;
  245. }
  246. static List _create_front_end_info_list(
  247. front_end_info_msg_t *front_end_info_ptr, int changed)
  248. {
  249. char *upper = NULL;
  250. char user[32], time_str[32];
  251. static List info_list = NULL;
  252. int i = 0;
  253. sview_front_end_info_t *sview_front_end_info_ptr = NULL;
  254. front_end_info_t *front_end_ptr = NULL;
  255. if (!changed && info_list)
  256. goto update_color;
  257. if (info_list)
  258. list_flush(info_list);
  259. else
  260. info_list = list_create(_front_end_info_list_del);
  261. if (!info_list) {
  262. g_print("malloc error\n");
  263. return NULL;
  264. }
  265. for (i = 0; i < front_end_info_ptr->record_count; i++) {
  266. front_end_ptr = &(front_end_info_ptr->front_end_array[i]);
  267. sview_front_end_info_ptr =
  268. xmalloc(sizeof(sview_front_end_info_t));
  269. sview_front_end_info_ptr->front_end_ptr = front_end_ptr;
  270. sview_front_end_info_ptr->color_inx = i % sview_colors_cnt;
  271. if (g_node_info_ptr) {
  272. sview_front_end_info_ptr->node_inx[0] = 0;
  273. sview_front_end_info_ptr->node_inx[1] =
  274. g_node_info_ptr->record_count - 1;
  275. sview_front_end_info_ptr->node_inx[2] = -1;
  276. } else
  277. sview_front_end_info_ptr->node_inx[0] = -1;
  278. if (front_end_ptr->boot_time) {
  279. slurm_make_time_str(&front_end_ptr->boot_time,
  280. time_str, sizeof(time_str));
  281. sview_front_end_info_ptr->boot_time =
  282. xstrdup(time_str);
  283. }
  284. if (front_end_ptr->slurmd_start_time) {
  285. slurm_make_time_str(&front_end_ptr->slurmd_start_time,
  286. time_str, sizeof(time_str));
  287. sview_front_end_info_ptr->slurmd_start_time =
  288. xstrdup(time_str);
  289. }
  290. upper = node_state_string(front_end_ptr->node_state);
  291. sview_front_end_info_ptr->state = str_tolower(upper);
  292. if (front_end_ptr->reason && front_end_ptr->reason_time &&
  293. (front_end_ptr->reason_uid != NO_VAL)) {
  294. struct passwd *pw = NULL;
  295. if ((pw=getpwuid(front_end_ptr->reason_uid)))
  296. snprintf(user, sizeof(user), "%s", pw->pw_name);
  297. else
  298. snprintf(user, sizeof(user), "Unk(%u)",
  299. front_end_ptr->reason_uid);
  300. slurm_make_time_str(&front_end_ptr->reason_time,
  301. time_str, sizeof(time_str));
  302. sview_front_end_info_ptr->reason =
  303. xstrdup_printf("%s [%s@%s]",
  304. front_end_ptr->reason, user,
  305. time_str);
  306. } else {
  307. sview_front_end_info_ptr->reason =
  308. xstrdup(front_end_ptr->reason);
  309. }
  310. list_append(info_list, sview_front_end_info_ptr);
  311. }
  312. update_color:
  313. return info_list;
  314. }
  315. static void _display_info_front_end(List info_list, popup_info_t *popup_win)
  316. {
  317. specific_info_t *spec_info = popup_win->spec_info;
  318. char *name = (char *)spec_info->search_info->gchar_data;
  319. int found = 0, j;
  320. front_end_info_t *front_end_ptr = NULL;
  321. GtkTreeView *treeview = NULL;
  322. ListIterator itr = NULL;
  323. sview_front_end_info_t *sview_fe_info = NULL;
  324. int update = 0;
  325. if (!spec_info->search_info->gchar_data) {
  326. //info = xstrdup("No pointer given!");
  327. goto finished;
  328. }
  329. need_refresh:
  330. if (!spec_info->display_widget) {
  331. treeview = create_treeview_2cols_attach_to_table(
  332. popup_win->table);
  333. spec_info->display_widget =
  334. gtk_widget_ref(GTK_WIDGET(treeview));
  335. } else {
  336. treeview = GTK_TREE_VIEW(spec_info->display_widget);
  337. update = 1;
  338. }
  339. itr = list_iterator_create(info_list);
  340. while ((sview_fe_info = (sview_front_end_info_t*) list_next(itr))) {
  341. front_end_ptr = sview_fe_info->front_end_ptr;
  342. if (strcmp(front_end_ptr->name, name) == 0) {
  343. j = 0;
  344. while (sview_fe_info->node_inx[j] >= 0) {
  345. change_grid_color(popup_win->grid_button_list,
  346. sview_fe_info->node_inx[j],
  347. sview_fe_info->node_inx[j+1],
  348. sview_fe_info->color_inx,
  349. true, 0);
  350. j += 2;
  351. }
  352. _layout_front_end_record(treeview, sview_fe_info,
  353. update);
  354. found = 1;
  355. break;
  356. }
  357. }
  358. list_iterator_destroy(itr);
  359. post_setup_popup_grid_list(popup_win);
  360. if (!found) {
  361. if (!popup_win->not_found) {
  362. char *temp = "FRONT END DOESN'T EXSIST\n";
  363. GtkTreeIter iter;
  364. GtkTreeModel *model = NULL;
  365. /* only time this will be run so no update */
  366. model = gtk_tree_view_get_model(treeview);
  367. add_display_treestore_line(0,
  368. GTK_TREE_STORE(model),
  369. &iter,
  370. temp, "");
  371. }
  372. popup_win->not_found = true;
  373. } else {
  374. if (popup_win->not_found) {
  375. popup_win->not_found = false;
  376. gtk_widget_destroy(spec_info->display_widget);
  377. goto need_refresh;
  378. }
  379. }
  380. gtk_widget_show(spec_info->display_widget);
  381. finished:
  382. return;
  383. }
  384. extern void refresh_front_end(GtkAction *action, gpointer user_data)
  385. {
  386. popup_info_t *popup_win = (popup_info_t *)user_data;
  387. xassert(popup_win);
  388. xassert(popup_win->spec_info);
  389. xassert(popup_win->spec_info->title);
  390. popup_win->force_refresh = 1;
  391. specific_info_front_end(popup_win);
  392. }
  393. extern int get_new_info_front_end(front_end_info_msg_t **info_ptr, int force)
  394. {
  395. static front_end_info_msg_t *new_front_end_ptr = NULL;
  396. int error_code = SLURM_NO_CHANGE_IN_DATA;
  397. time_t now = time(NULL);
  398. static time_t last;
  399. static bool changed = 0;
  400. if (g_front_end_info_ptr && !force &&
  401. ((now - last) < working_sview_config.refresh_delay)) {
  402. if (*info_ptr != g_front_end_info_ptr)
  403. error_code = SLURM_SUCCESS;
  404. *info_ptr = g_front_end_info_ptr;
  405. if (changed)
  406. error_code = SLURM_SUCCESS;
  407. goto end_it;
  408. }
  409. last = now;
  410. if (g_front_end_info_ptr) {
  411. error_code = slurm_load_front_end(
  412. g_front_end_info_ptr->last_update, &new_front_end_ptr);
  413. if (error_code == SLURM_SUCCESS) {
  414. slurm_free_front_end_info_msg(g_front_end_info_ptr);
  415. changed = 1;
  416. } else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
  417. error_code = SLURM_NO_CHANGE_IN_DATA;
  418. new_front_end_ptr = g_front_end_info_ptr;
  419. changed = 0;
  420. }
  421. } else {
  422. new_front_end_ptr = NULL;
  423. error_code = slurm_load_front_end((time_t) NULL,
  424. &new_front_end_ptr);
  425. changed = 1;
  426. }
  427. g_front_end_info_ptr = new_front_end_ptr;
  428. if (g_front_end_info_ptr && (*info_ptr != g_front_end_info_ptr))
  429. error_code = SLURM_SUCCESS;
  430. *info_ptr = g_front_end_info_ptr;
  431. end_it:
  432. return error_code;
  433. }
  434. extern GtkListStore *create_model_front_end(int type)
  435. {
  436. GtkListStore *model = NULL;
  437. GtkTreeIter iter;
  438. int i = 0;
  439. switch(type) {
  440. case SORTID_STATE:
  441. model = gtk_list_store_new(2, G_TYPE_STRING,
  442. G_TYPE_INT);
  443. gtk_list_store_append(model, &iter);
  444. gtk_list_store_set(model, &iter,
  445. 0, "Drain",
  446. 1, i,
  447. -1);
  448. gtk_list_store_append(model, &iter);
  449. gtk_list_store_set(model, &iter,
  450. 0, "Resume",
  451. 1, i,
  452. -1);
  453. break;
  454. }
  455. return model;
  456. }
  457. extern void admin_edit_front_end(GtkCellRendererText *cell,
  458. const char *path_string,
  459. const char *new_text, gpointer data)
  460. {
  461. GtkTreeStore *treestore = GTK_TREE_STORE(data);
  462. GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
  463. GtkTreeIter iter;
  464. char *node_list = NULL;
  465. int column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell),
  466. "column"));
  467. if (!new_text || !strcmp(new_text, ""))
  468. goto no_input;
  469. gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
  470. switch(column) {
  471. case SORTID_STATE:
  472. gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
  473. SORTID_NAME,
  474. &node_list, -1);
  475. _admin_front_end(GTK_TREE_MODEL(treestore), &iter,
  476. (char *)new_text, node_list);
  477. g_free(node_list);
  478. default:
  479. break;
  480. }
  481. no_input:
  482. gtk_tree_path_free(path);
  483. g_static_mutex_unlock(&sview_mutex);
  484. }
  485. extern void get_info_front_end(GtkTable *table, display_data_t *display_data)
  486. {
  487. int error_code = SLURM_SUCCESS;
  488. List info_list = NULL;
  489. static int view = -1;
  490. static front_end_info_msg_t *front_end_info_ptr = NULL;
  491. char error_char[100];
  492. GtkWidget *label = NULL;
  493. GtkTreeView *tree_view = NULL;
  494. static GtkWidget *display_widget = NULL;
  495. int changed = 1, j;
  496. ListIterator itr = NULL;
  497. GtkTreePath *path = NULL;
  498. static bool set_opts = FALSE;
  499. if (!set_opts)
  500. set_page_opts(FRONT_END_PAGE, display_data_front_end,
  501. SORTID_CNT, _initial_page_opts);
  502. set_opts = TRUE;
  503. /* reset */
  504. if (!table && !display_data) {
  505. if (display_widget)
  506. gtk_widget_destroy(display_widget);
  507. display_widget = NULL;
  508. front_end_info_ptr = NULL;
  509. goto reset_curs;
  510. }
  511. if (display_data)
  512. local_display_data = display_data;
  513. if (!table) {
  514. display_data_front_end->set_menu = local_display_data->set_menu;
  515. goto reset_curs;
  516. }
  517. if (display_widget && toggled) {
  518. gtk_widget_destroy(display_widget);
  519. display_widget = NULL;
  520. goto display_it;
  521. }
  522. error_code = get_new_info_front_end(&front_end_info_ptr, force_refresh);
  523. if (error_code == SLURM_NO_CHANGE_IN_DATA) {
  524. changed = 0;
  525. } else if (error_code != SLURM_SUCCESS) {
  526. if (view == ERROR_VIEW)
  527. goto end_it;
  528. if (display_widget)
  529. gtk_widget_destroy(display_widget);
  530. view = ERROR_VIEW;
  531. sprintf(error_char, "slurm_load_front_end: %s",
  532. slurm_strerror(slurm_get_errno()));
  533. label = gtk_label_new(error_char);
  534. gtk_table_attach_defaults(table, label, 0, 1, 0, 1);
  535. gtk_widget_show(label);
  536. display_widget = gtk_widget_ref(GTK_WIDGET(label));
  537. goto end_it;
  538. }
  539. display_it:
  540. info_list = _create_front_end_info_list(front_end_info_ptr, changed);
  541. if (!info_list)
  542. goto reset_curs;
  543. /* set up the grid */
  544. if (display_widget && GTK_IS_TREE_VIEW(display_widget) &&
  545. gtk_tree_selection_count_selected_rows(
  546. gtk_tree_view_get_selection(
  547. GTK_TREE_VIEW(display_widget)))) {
  548. GtkTreeViewColumn *focus_column = NULL;
  549. /* highlight the correct nodes from the last selection */
  550. gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget),
  551. &path, &focus_column);
  552. }
  553. if (!path) {
  554. sview_front_end_info_t *fe_ptr;
  555. itr = list_iterator_create(info_list);
  556. while ((fe_ptr = list_next(itr))) {
  557. j = 0;
  558. while (fe_ptr->node_inx[j] >= 0) {
  559. change_grid_color(grid_button_list,
  560. fe_ptr->node_inx[j],
  561. fe_ptr->node_inx[j+1],
  562. fe_ptr->color_inx,
  563. true, 0);
  564. j += 2;
  565. }
  566. }
  567. list_iterator_destroy(itr);
  568. change_grid_color(grid_button_list, -1, -1,
  569. MAKE_WHITE, true, 0);
  570. } else {
  571. highlight_grid(GTK_TREE_VIEW(display_widget),
  572. SORTID_NODE_INX, SORTID_COLOR_INX,
  573. grid_button_list);
  574. }
  575. if (view == ERROR_VIEW && display_widget) {
  576. gtk_widget_destroy(display_widget);
  577. display_widget = NULL;
  578. }
  579. if (!display_widget) {
  580. tree_view = create_treeview(local_display_data,
  581. &grid_button_list);
  582. gtk_tree_selection_set_mode(
  583. gtk_tree_view_get_selection(tree_view),
  584. GTK_SELECTION_MULTIPLE);
  585. display_widget = gtk_widget_ref(GTK_WIDGET(tree_view));
  586. gtk_table_attach_defaults(table,
  587. GTK_WIDGET(tree_view),
  588. 0, 1, 0, 1);
  589. /* since this function sets the model of the tree_view
  590. to the treestore we don't really care about
  591. the return value */
  592. create_treestore(tree_view, display_data_front_end,
  593. SORTID_CNT, SORTID_NAME, SORTID_COLOR);
  594. }
  595. view = INFO_VIEW;
  596. _update_info_front_end(info_list, GTK_TREE_VIEW(display_widget));
  597. end_it:
  598. toggled = FALSE;
  599. force_refresh = FALSE;
  600. reset_curs:
  601. if (main_window && main_window->window)
  602. gdk_window_set_cursor(main_window->window, NULL);
  603. return;
  604. }
  605. extern void specific_info_front_end(popup_info_t *popup_win)
  606. {
  607. int resv_error_code = SLURM_SUCCESS;
  608. static front_end_info_msg_t *front_end_info_ptr = NULL;
  609. static front_end_info_t *front_end_ptr = NULL;
  610. specific_info_t *spec_info = popup_win->spec_info;
  611. sview_search_info_t *search_info = spec_info->search_info;
  612. char error_char[100];
  613. GtkWidget *label = NULL;
  614. GtkTreeView *tree_view = NULL;
  615. List resv_list = NULL;
  616. List send_resv_list = NULL;
  617. int changed = 1;
  618. sview_front_end_info_t *sview_front_end_info_ptr = NULL;
  619. int i = -1;
  620. ListIterator itr = NULL;
  621. if (!spec_info->display_widget) {
  622. setup_popup_info(popup_win, display_data_front_end, SORTID_CNT);
  623. }
  624. if (spec_info->display_widget && popup_win->toggled) {
  625. gtk_widget_destroy(spec_info->display_widget);
  626. spec_info->display_widget = NULL;
  627. goto display_it;
  628. }
  629. resv_error_code = get_new_info_front_end(&front_end_info_ptr,
  630. popup_win->force_refresh);
  631. if (resv_error_code == SLURM_NO_CHANGE_IN_DATA) {
  632. if (!spec_info->display_widget || spec_info->view == ERROR_VIEW)
  633. goto display_it;
  634. changed = 0;
  635. } else if (resv_error_code != SLURM_SUCCESS) {
  636. if (spec_info->view == ERROR_VIEW)
  637. goto end_it;
  638. spec_info->view = ERROR_VIEW;
  639. if (spec_info->display_widget)
  640. gtk_widget_destroy(spec_info->display_widget);
  641. sprintf(error_char, "get_new_info_front_end: %s",
  642. slurm_strerror(slurm_get_errno()));
  643. label = gtk_label_new(error_char);
  644. gtk_table_attach_defaults(popup_win->table,
  645. label,
  646. 0, 1, 0, 1);
  647. gtk_widget_show(label);
  648. spec_info->display_widget = gtk_widget_ref(label);
  649. goto end_it;
  650. }
  651. display_it:
  652. resv_list = _create_front_end_info_list(front_end_info_ptr, changed);
  653. if (!resv_list)
  654. return;
  655. if (spec_info->view == ERROR_VIEW && spec_info->display_widget) {
  656. gtk_widget_destroy(spec_info->display_widget);
  657. spec_info->display_widget = NULL;
  658. }
  659. if (spec_info->type != INFO_PAGE && !spec_info->display_widget) {
  660. tree_view = create_treeview(local_display_data,
  661. &popup_win->grid_button_list);
  662. gtk_tree_selection_set_mode(
  663. gtk_tree_view_get_selection(tree_view),
  664. GTK_SELECTION_MULTIPLE);
  665. spec_info->display_widget =
  666. gtk_widget_ref(GTK_WIDGET(tree_view));
  667. gtk_table_attach_defaults(popup_win->table,
  668. GTK_WIDGET(tree_view),
  669. 0, 1, 0, 1);
  670. /* since this function sets the model of the tree_view
  671. to the treestore we don't really care about
  672. the return value */
  673. create_treestore(tree_view, popup_win->display_data,
  674. SORTID_CNT, SORTID_NAME, SORTID_COLOR);
  675. }
  676. setup_popup_grid_list(popup_win);
  677. spec_info->view = INFO_VIEW;
  678. if (spec_info->type == INFO_PAGE) {
  679. _display_info_front_end(resv_list, popup_win);
  680. goto end_it;
  681. }
  682. /* just linking to another list, don't free the inside, just
  683. the list */
  684. send_resv_list = list_create(NULL);
  685. itr = list_iterator_create(resv_list);
  686. i = -1;
  687. while ((sview_front_end_info_ptr = list_next(itr))) {
  688. i++;
  689. front_end_ptr = sview_front_end_info_ptr->front_end_ptr;
  690. switch (spec_info->type) {
  691. case PART_PAGE:
  692. case BLOCK_PAGE:
  693. case NODE_PAGE:
  694. break;
  695. case JOB_PAGE:
  696. if (strcmp(front_end_ptr->name,
  697. search_info->gchar_data))
  698. continue;
  699. break;
  700. case RESV_PAGE:
  701. switch (search_info->search_type) {
  702. case SEARCH_RESERVATION_NAME:
  703. if (!search_info->gchar_data)
  704. continue;
  705. if (strcmp(front_end_ptr->name,
  706. search_info->gchar_data))
  707. continue;
  708. break;
  709. default:
  710. continue;
  711. }
  712. break;
  713. default:
  714. g_print("Unknown type %d\n", spec_info->type);
  715. continue;
  716. }
  717. list_push(send_resv_list, sview_front_end_info_ptr);
  718. }
  719. list_iterator_destroy(itr);
  720. post_setup_popup_grid_list(popup_win);
  721. _update_info_front_end(send_resv_list,
  722. GTK_TREE_VIEW(spec_info->display_widget));
  723. list_destroy(send_resv_list);
  724. end_it:
  725. popup_win->toggled = 0;
  726. popup_win->force_refresh = 0;
  727. return;
  728. }
  729. extern void set_menus_front_end(void *arg, void *arg2, GtkTreePath *path,
  730. int type)
  731. {
  732. GtkTreeView *tree_view = (GtkTreeView *)arg;
  733. popup_info_t *popup_win = (popup_info_t *)arg;
  734. GtkMenu *menu = (GtkMenu *)arg2;
  735. List button_list = (List)arg2;
  736. switch (type) {
  737. case TAB_CLICKED:
  738. make_fields_menu(NULL, menu, display_data_front_end,
  739. SORTID_CNT);
  740. break;
  741. case ROW_CLICKED:
  742. make_options_menu(tree_view, path, menu,
  743. options_data_front_end);
  744. break;
  745. case ROW_LEFT_CLICKED:
  746. highlight_grid(tree_view, SORTID_NODE_INX,
  747. SORTID_COLOR_INX, button_list);
  748. break;
  749. case FULL_CLICKED:
  750. {
  751. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  752. GtkTreeIter iter;
  753. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  754. g_error("error getting iter from model\n");
  755. break;
  756. }
  757. popup_all_front_end(model, &iter, INFO_PAGE);
  758. break;
  759. }
  760. case POPUP_CLICKED:
  761. make_fields_menu(popup_win, menu,
  762. popup_win->display_data, SORTID_CNT);
  763. break;
  764. default:
  765. g_error("UNKNOWN type %d given to set_fields\n", type);
  766. }
  767. }
  768. extern void popup_all_front_end(GtkTreeModel *model, GtkTreeIter *iter, int id)
  769. {
  770. char *name = NULL;
  771. char title[100];
  772. ListIterator itr = NULL;
  773. popup_info_t *popup_win = NULL;
  774. GError *error = NULL;
  775. gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
  776. switch (id) {
  777. case INFO_PAGE:
  778. snprintf(title, 100, "Full info for front end node %s", name);
  779. break;
  780. default:
  781. g_print("front end got %d\n", id);
  782. }
  783. itr = list_iterator_create(popup_list);
  784. while ((popup_win = list_next(itr))) {
  785. if (popup_win->spec_info)
  786. if (!strcmp(popup_win->spec_info->title, title)) {
  787. break;
  788. }
  789. }
  790. list_iterator_destroy(itr);
  791. if (!popup_win) {
  792. if (id == INFO_PAGE)
  793. popup_win = create_popup_info(id, FRONT_END_PAGE,
  794. title);
  795. else {
  796. popup_win = create_popup_info(FRONT_END_PAGE, id,
  797. title);
  798. }
  799. } else {
  800. g_free(name);
  801. gtk_window_present(GTK_WINDOW(popup_win->popup));
  802. return;
  803. }
  804. /* Pass the model and the structs from the iter so we can always get
  805. * the current node_inx.
  806. */
  807. popup_win->model = model;
  808. popup_win->iter = *iter;
  809. popup_win->node_inx_id = SORTID_NODE_INX;
  810. switch (id) {
  811. case INFO_PAGE:
  812. popup_win->spec_info->search_info->gchar_data = name;
  813. break;
  814. default:
  815. g_print("resv got unknown type %d\n", id);
  816. }
  817. if (!sview_thread_new((gpointer)popup_thr, popup_win, FALSE, &error)) {
  818. g_printerr ("Failed to create resv popup thread: %s\n",
  819. error->message);
  820. return;
  821. }
  822. }
  823. static void _process_each_front_end(GtkTreeModel *model, GtkTreePath *path,
  824. GtkTreeIter*iter, gpointer user_data)
  825. {
  826. char *name = NULL;
  827. front_end_user_data_t *fe_data = user_data;
  828. gtk_tree_model_get(model, iter, SORTID_NAME, &name, -1);
  829. if (fe_data->node_list)
  830. xstrfmtcat(fe_data->node_list, ",%s", name);
  831. else
  832. fe_data->node_list = xstrdup(name);
  833. g_free(name);
  834. }
  835. extern void select_admin_front_end(GtkTreeModel *model, GtkTreeIter *iter,
  836. display_data_t *display_data,
  837. GtkTreeView *treeview)
  838. {
  839. if (treeview) {
  840. char *node_list;
  841. hostlist_t hl = NULL;
  842. front_end_user_data_t user_data;
  843. memset(&user_data, 0, sizeof(front_end_user_data_t));
  844. gtk_tree_selection_selected_foreach(
  845. gtk_tree_view_get_selection(treeview),
  846. _process_each_front_end, &user_data);
  847. hl = hostlist_create(user_data.node_list);
  848. hostlist_uniq(hl);
  849. hostlist_sort(hl);
  850. xfree(user_data.node_list);
  851. node_list = hostlist_ranged_string_xmalloc(hl);
  852. hostlist_destroy(hl);
  853. _admin_front_end(model, iter, display_data->name, node_list);
  854. xfree(node_list);
  855. }
  856. }
  857. static void _admin_front_end(GtkTreeModel *model, GtkTreeIter *iter, char *type,
  858. char *node_list)
  859. {
  860. uint16_t state = (uint16_t) NO_VAL;
  861. update_front_end_msg_t front_end_update_msg;
  862. char *new_type = NULL, *reason = NULL;
  863. char tmp_char[100];
  864. char *lower;
  865. int rc;
  866. GtkWidget *label = NULL;
  867. GtkWidget *entry = NULL;
  868. GtkWidget *popup = gtk_dialog_new_with_buttons(
  869. type,
  870. GTK_WINDOW(main_window),
  871. GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
  872. NULL);
  873. gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
  874. label = gtk_dialog_add_button(GTK_DIALOG(popup),
  875. GTK_STOCK_YES, GTK_RESPONSE_OK);
  876. gtk_window_set_default(GTK_WINDOW(popup), label);
  877. gtk_dialog_add_button(GTK_DIALOG(popup),
  878. GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
  879. if (!strncasecmp("Drain", type, 5)) {
  880. new_type = "DRAIN";
  881. reason = "\n\nPlease enter reason.";
  882. state = NODE_STATE_DRAIN;
  883. entry = create_entry();
  884. } else if (!strncasecmp("Resume", type, 6)) {
  885. new_type = "RESUME";
  886. reason = "";
  887. state = NODE_RESUME;
  888. }
  889. snprintf(tmp_char, sizeof(tmp_char),
  890. "Are you sure you want to set state of front end node %s "
  891. "to %s?%s", node_list, new_type, reason);
  892. label = gtk_label_new(tmp_char);
  893. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
  894. label, FALSE, FALSE, 0);
  895. if (entry)
  896. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup)->vbox),
  897. entry, TRUE, TRUE, 0);
  898. gtk_widget_show_all(popup);
  899. rc = gtk_dialog_run (GTK_DIALOG(popup));
  900. slurm_init_update_front_end_msg(&front_end_update_msg);
  901. if (rc == GTK_RESPONSE_OK) {
  902. front_end_update_msg.name = node_list;
  903. front_end_update_msg.node_state = state;
  904. if (entry) {
  905. front_end_update_msg.reason = xstrdup(
  906. gtk_entry_get_text(GTK_ENTRY(entry)));
  907. if (!front_end_update_msg.reason ||
  908. !strlen(front_end_update_msg.reason)) {
  909. lower = g_strdup_printf(
  910. "You need a reason to do that.");
  911. display_edit_note(lower);
  912. g_free(lower);
  913. goto end_it;
  914. }
  915. rc = uid_from_string(getlogin(),
  916. &front_end_update_msg.reason_uid);
  917. if (rc < 0)
  918. front_end_update_msg.reason_uid = getuid();
  919. }
  920. rc = slurm_update_front_end(&front_end_update_msg);
  921. if (rc == SLURM_SUCCESS) {
  922. lower = g_strdup_printf(
  923. "Nodes %s updated successfully.",
  924. node_list);
  925. display_edit_note(lower);
  926. g_free(lower);
  927. } else {
  928. lower = g_strdup_printf(
  929. "Problem updating nodes %s: %s",
  930. node_list, slurm_strerror(rc));
  931. display_edit_note(lower);
  932. g_free(lower);
  933. }
  934. }
  935. end_it:
  936. global_entry_changed = 0;
  937. xfree(front_end_update_msg.reason);
  938. gtk_widget_destroy(popup);
  939. if (got_edit_signal) {
  940. type = got_edit_signal;
  941. got_edit_signal = NULL;
  942. _admin_front_end(model, iter, type, node_list);
  943. xfree(type);
  944. }
  945. return;
  946. }
  947. extern void cluster_change_front_end(void)
  948. {
  949. display_data_t *display_data = display_data_front_end;
  950. display_data = options_data_front_end;
  951. while (display_data++) {
  952. if (display_data->id == -1)
  953. break;
  954. if (cluster_flags & CLUSTER_FLAG_BG) {
  955. switch (display_data->id) {
  956. case BLOCK_PAGE:
  957. display_data->name = "Blocks";
  958. break;
  959. case NODE_PAGE:
  960. display_data->name = "Midplanes";
  961. break;
  962. }
  963. } else {
  964. switch (display_data->id) {
  965. case BLOCK_PAGE:
  966. display_data->name = NULL;
  967. break;
  968. case NODE_PAGE:
  969. display_data->name = "Nodes";
  970. break;
  971. }
  972. }
  973. }
  974. get_info_front_end(NULL, NULL);
  975. }