PageRenderTime 80ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sview/block_info.c

https://github.com/cfenoy/slurm
C | 1659 lines | 1421 code | 159 blank | 79 comment | 262 complexity | d9f28f99442b58df7e3af85e4d050cbc MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * block_info.c - Functions related to Bluegene block display
  3. * mode of sview.
  4. *****************************************************************************
  5. * Copyright (C) 2004-2007 The Regents of the University of California.
  6. * Copyright (C) 2008 Lawrence Livermore National Security.
  7. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  8. * Written by Danny Auble <da@llnl.gov>
  9. *
  10. * CODE-OCEC-09-009. All rights reserved.
  11. *
  12. * This file is part of SLURM, a resource management program.
  13. * For details, see <http://www.schedmd.com/slurmdocs/>.
  14. * Please also read the included file: DISCLAIMER.
  15. *
  16. * SLURM is free software; you can redistribute it and/or modify it under
  17. * the terms of the GNU General Public License as published by the Free
  18. * Software Foundation; either version 2 of the License, or (at your option)
  19. * any later version.
  20. *
  21. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  22. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  23. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  24. * details.
  25. *
  26. * You should have received a copy of the GNU General Public License along
  27. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  28. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  29. \*****************************************************************************/
  30. #include "src/sview/sview.h"
  31. #include "src/common/node_select.h"
  32. #define _DEBUG 0
  33. typedef struct {
  34. char *bg_block_name;
  35. char *slurm_part_name;
  36. char *mp_str;
  37. uint16_t bg_conn_type[HIGHEST_DIMENSIONS];
  38. uint16_t bg_node_use;
  39. uint16_t state;
  40. int size;
  41. int cnode_cnt;
  42. int cnode_err_cnt;
  43. GtkTreeIter iter_ptr;
  44. bool iter_set;
  45. int *mp_inx; /* list index pairs into node_table for *mp_str:
  46. * start_range_1, end_range_1,
  47. * start_range_2, .., -1 */
  48. int color_inx;
  49. List job_list;
  50. int pos;
  51. bool printed;
  52. char *reason;
  53. bool small_block;
  54. char *imageblrts; /* ImageBlrts for this block */
  55. char *imagelinux; /* ImageLinux for this block */
  56. char *imagemloader; /* imagemloader for this block */
  57. char *imageramdisk; /* ImageRamDisk for this block */
  58. } sview_block_info_t;
  59. enum {
  60. SORTID_POS = POS_LOC,
  61. SORTID_BLOCK,
  62. SORTID_COLOR,
  63. SORTID_COLOR_INX,
  64. SORTID_CONN,
  65. SORTID_JOB,
  66. SORTID_IMAGEBLRTS,
  67. #ifdef HAVE_BGL
  68. SORTID_IMAGELINUX,
  69. SORTID_IMAGEMLOADER,
  70. SORTID_IMAGERAMDISK,
  71. #else
  72. SORTID_IMAGELINUX,
  73. SORTID_IMAGERAMDISK,
  74. SORTID_IMAGEMLOADER,
  75. #endif
  76. SORTID_NODELIST,
  77. SORTID_NODE_CNT,
  78. SORTID_PARTITION,
  79. SORTID_REASON,
  80. SORTID_STATE,
  81. SORTID_UPDATED,
  82. SORTID_USE,
  83. SORTID_NODE_INX,
  84. SORTID_SMALL_BLOCK,
  85. SORTID_USER,
  86. SORTID_CNT
  87. };
  88. /*these are the settings to apply for the user
  89. * on the first startup after a fresh slurm install.*/
  90. static char *_initial_page_opts = "Block_ID,State,JobID,User,Node_Count,"
  91. "Node_Use,MidplaneList,Partition";
  92. static display_data_t display_data_block[] = {
  93. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE, refresh_block,
  94. create_model_block, admin_edit_block},
  95. {G_TYPE_STRING, SORTID_BLOCK, "Block ID",
  96. FALSE, EDIT_NONE, refresh_block,
  97. create_model_block, admin_edit_block},
  98. {G_TYPE_STRING, SORTID_COLOR, NULL, TRUE, EDIT_COLOR,
  99. refresh_block, create_model_block, admin_edit_block},
  100. {G_TYPE_STRING, SORTID_STATE, "State", FALSE, EDIT_MODEL, refresh_block,
  101. create_model_block, admin_edit_block},
  102. {G_TYPE_STRING, SORTID_JOB, "JobID", FALSE, EDIT_NONE, refresh_block,
  103. create_model_block, admin_edit_block},
  104. #ifdef HAVE_BG_L_P
  105. {G_TYPE_STRING, SORTID_USER, "User", FALSE, EDIT_NONE, refresh_block,
  106. create_model_block, admin_edit_block},
  107. #else
  108. {G_TYPE_STRING, SORTID_USER, NULL, FALSE, EDIT_NONE, refresh_block,
  109. create_model_block, admin_edit_block},
  110. #endif
  111. {G_TYPE_STRING, SORTID_NODE_CNT, "Node Count",
  112. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  113. {G_TYPE_STRING, SORTID_CONN, "Connection Type",
  114. FALSE, EDIT_NONE, refresh_block,
  115. create_model_block, admin_edit_block},
  116. {G_TYPE_STRING, SORTID_NODELIST, "MidplaneList", FALSE,
  117. EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  118. {G_TYPE_STRING, SORTID_PARTITION, "Partition",
  119. FALSE, EDIT_NONE, refresh_block,
  120. create_model_block, admin_edit_block},
  121. #ifdef HAVE_BGL
  122. {G_TYPE_STRING, SORTID_USE, "Node Use", FALSE, EDIT_NONE, refresh_block,
  123. create_model_block, admin_edit_block},
  124. {G_TYPE_STRING, SORTID_IMAGEBLRTS, "Image Blrts",
  125. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  126. {G_TYPE_STRING, SORTID_IMAGELINUX, "Image Linux",
  127. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  128. {G_TYPE_STRING, SORTID_IMAGERAMDISK, "Image Ramdisk",
  129. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  130. #elif defined HAVE_BGP
  131. {G_TYPE_STRING, SORTID_USE, NULL, FALSE, EDIT_NONE, refresh_block,
  132. create_model_block, admin_edit_block},
  133. {G_TYPE_STRING, SORTID_IMAGEBLRTS, NULL,
  134. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  135. {G_TYPE_STRING, SORTID_IMAGELINUX, "Image Cnload",
  136. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  137. {G_TYPE_STRING, SORTID_IMAGERAMDISK, "Image Ioload",
  138. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  139. #elif defined HAVE_BGQ
  140. {G_TYPE_STRING, SORTID_USE, NULL, FALSE, EDIT_NONE, refresh_block,
  141. create_model_block, admin_edit_block},
  142. {G_TYPE_STRING, SORTID_IMAGEBLRTS, NULL,
  143. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  144. {G_TYPE_STRING, SORTID_IMAGELINUX, NULL,
  145. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  146. {G_TYPE_STRING, SORTID_IMAGERAMDISK, NULL,
  147. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  148. #endif
  149. {G_TYPE_STRING, SORTID_IMAGEMLOADER, "Image Mloader",
  150. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  151. {G_TYPE_STRING, SORTID_REASON, "Reason",
  152. FALSE, EDIT_NONE, refresh_block, create_model_block, admin_edit_block},
  153. {G_TYPE_POINTER, SORTID_NODE_INX, NULL, FALSE, EDIT_NONE,
  154. refresh_block, create_model_resv, admin_edit_resv},
  155. {G_TYPE_INT, SORTID_COLOR_INX, NULL, FALSE, EDIT_NONE,
  156. refresh_block, create_model_resv, admin_edit_resv},
  157. {G_TYPE_INT, SORTID_SMALL_BLOCK, NULL, FALSE, EDIT_NONE, refresh_block,
  158. create_model_block, admin_edit_block},
  159. {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, EDIT_NONE, refresh_block,
  160. create_model_block, admin_edit_block},
  161. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  162. };
  163. static display_data_t options_data_block[] = {
  164. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE},
  165. {G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, BLOCK_PAGE},
  166. {G_TYPE_STRING, BLOCK_PAGE, "Put block in error state",
  167. TRUE, ADMIN_PAGE},
  168. {G_TYPE_STRING, BLOCK_PAGE, "Put block in free state",
  169. TRUE, ADMIN_PAGE},
  170. {G_TYPE_STRING, BLOCK_PAGE, "Recreate block",
  171. TRUE, ADMIN_PAGE},
  172. {G_TYPE_STRING, BLOCK_PAGE, "Remove block",
  173. TRUE, ADMIN_PAGE},
  174. {G_TYPE_STRING, BLOCK_PAGE, "Resume block",
  175. TRUE, ADMIN_PAGE},
  176. {G_TYPE_STRING, JOB_PAGE, "Jobs", TRUE, BLOCK_PAGE},
  177. {G_TYPE_STRING, PART_PAGE, "Partitions", TRUE, BLOCK_PAGE},
  178. {G_TYPE_STRING, NODE_PAGE, "Midplanes", TRUE, BLOCK_PAGE},
  179. //{G_TYPE_STRING, SUBMIT_PAGE, "Job Submit", FALSE, BLOCK_PAGE},
  180. {G_TYPE_STRING, RESV_PAGE, "Reservations", TRUE, BLOCK_PAGE},
  181. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  182. };
  183. static display_data_t *local_display_data = NULL;
  184. static void _admin_block(GtkTreeModel *model, GtkTreeIter *iter, char *type);
  185. static void _append_block_record(sview_block_info_t *block_ptr,
  186. GtkTreeStore *treestore);
  187. static int _in_slurm_partition(int *part_inx, int *block_inx);
  188. static void _process_each_block(GtkTreeModel *model, GtkTreePath *path,
  189. GtkTreeIter*iter, gpointer userdata);
  190. static char *_set_running_job_str(List job_list, bool compact)
  191. {
  192. int cnt = list_count(job_list);
  193. block_job_info_t *block_job;
  194. if (!cnt) {
  195. return xstrdup("-");
  196. } else if (cnt == 1) {
  197. block_job = list_peek(job_list);
  198. return xstrdup_printf("%u", block_job->job_id);
  199. } else if (compact)
  200. return xstrdup("multiple");
  201. else {
  202. char *tmp_char = NULL;
  203. ListIterator itr = list_iterator_create(job_list);
  204. while ((block_job = list_next(itr))) {
  205. if (tmp_char)
  206. xstrcat(tmp_char, " ");
  207. xstrfmtcat(tmp_char, "%u", block_job->job_id);
  208. }
  209. return tmp_char;
  210. }
  211. return NULL;
  212. }
  213. static void _block_list_del(void *object)
  214. {
  215. sview_block_info_t *block_ptr = (sview_block_info_t *)object;
  216. if (block_ptr) {
  217. xfree(block_ptr->bg_block_name);
  218. xfree(block_ptr->slurm_part_name);
  219. xfree(block_ptr->mp_str);
  220. xfree(block_ptr->reason);
  221. xfree(block_ptr->imageblrts);
  222. xfree(block_ptr->imagelinux);
  223. xfree(block_ptr->imagemloader);
  224. xfree(block_ptr->imageramdisk);
  225. if (block_ptr->job_list) {
  226. list_destroy(block_ptr->job_list);
  227. block_ptr->job_list = NULL;
  228. }
  229. /* don't xfree(block_ptr->mp_inx);
  230. it isn't copied like the chars and is freed in the api
  231. */
  232. xfree(block_ptr);
  233. }
  234. }
  235. static int _in_slurm_partition(int *part_inx, int *mp_inx)
  236. {
  237. int found = 0;
  238. int i=0, j=0;
  239. while (mp_inx[i] >= 0) {
  240. j = 0;
  241. found = 0;
  242. while (part_inx[j] >= 0) {
  243. if ((mp_inx[i] >= part_inx[j])
  244. && mp_inx[i+1] <= part_inx[j+1]) {
  245. found = 1;
  246. break;
  247. }
  248. j += 2;
  249. }
  250. if (!found)
  251. return 0;
  252. i += 2;
  253. }
  254. return 1;
  255. }
  256. static void _layout_block_record(GtkTreeView *treeview,
  257. sview_block_info_t *block_ptr,
  258. int update)
  259. {
  260. char tmp_cnt[18], tmp_cnt2[18];
  261. char *tmp_char = NULL;
  262. GtkTreeIter iter;
  263. GtkTreeStore *treestore =
  264. GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
  265. add_display_treestore_line(update, treestore, &iter,
  266. find_col_name(display_data_block,
  267. SORTID_NODELIST),
  268. block_ptr->mp_str);
  269. tmp_char = conn_type_string_full(block_ptr->bg_conn_type);
  270. add_display_treestore_line(update, treestore, &iter,
  271. find_col_name(display_data_block,
  272. SORTID_CONN),
  273. tmp_char);
  274. xfree(tmp_char);
  275. if (cluster_flags & CLUSTER_FLAG_BGQ) {
  276. add_display_treestore_line(update, treestore, &iter,
  277. find_col_name(display_data_block,
  278. SORTID_IMAGEMLOADER),
  279. block_ptr->imagemloader);
  280. } else if (cluster_flags & CLUSTER_FLAG_BGP) {
  281. add_display_treestore_line(update, treestore, &iter,
  282. find_col_name(display_data_block,
  283. SORTID_IMAGELINUX),
  284. block_ptr->imagelinux);
  285. add_display_treestore_line(update, treestore, &iter,
  286. find_col_name(display_data_block,
  287. SORTID_IMAGERAMDISK),
  288. block_ptr->imageramdisk);
  289. add_display_treestore_line(update, treestore, &iter,
  290. find_col_name(display_data_block,
  291. SORTID_IMAGEMLOADER),
  292. block_ptr->imagemloader);
  293. } else if (cluster_flags & CLUSTER_FLAG_BGL) {
  294. add_display_treestore_line(update, treestore, &iter,
  295. find_col_name(display_data_block,
  296. SORTID_IMAGEBLRTS),
  297. block_ptr->imageblrts);
  298. add_display_treestore_line(update, treestore, &iter,
  299. find_col_name(display_data_block,
  300. SORTID_IMAGELINUX),
  301. block_ptr->imagelinux);
  302. add_display_treestore_line(update, treestore, &iter,
  303. find_col_name(display_data_block,
  304. SORTID_IMAGEMLOADER),
  305. block_ptr->imagemloader);
  306. add_display_treestore_line(update, treestore, &iter,
  307. find_col_name(display_data_block,
  308. SORTID_IMAGERAMDISK),
  309. block_ptr->imageramdisk);
  310. }
  311. tmp_char = _set_running_job_str(block_ptr->job_list, 0);
  312. add_display_treestore_line(update, treestore, &iter,
  313. find_col_name(display_data_block,
  314. SORTID_JOB),
  315. tmp_char);
  316. xfree(tmp_char);
  317. if (cluster_flags & CLUSTER_FLAG_BGL) {
  318. add_display_treestore_line(update, treestore, &iter,
  319. find_col_name(display_data_block,
  320. SORTID_USE),
  321. node_use_string(
  322. block_ptr->bg_node_use));
  323. }
  324. convert_num_unit((float)block_ptr->cnode_cnt, tmp_cnt, sizeof(tmp_cnt),
  325. UNIT_NONE);
  326. if (cluster_flags & CLUSTER_FLAG_BGQ) {
  327. convert_num_unit((float)block_ptr->cnode_err_cnt, tmp_cnt2,
  328. sizeof(tmp_cnt2), UNIT_NONE);
  329. tmp_char = xstrdup_printf("%s/%s", tmp_cnt, tmp_cnt2);
  330. } else
  331. tmp_char = tmp_cnt;
  332. add_display_treestore_line(update, treestore, &iter,
  333. find_col_name(display_data_block,
  334. SORTID_NODE_CNT),
  335. tmp_char);
  336. if (cluster_flags & CLUSTER_FLAG_BGQ)
  337. xfree(tmp_char);
  338. add_display_treestore_line(update, treestore, &iter,
  339. find_col_name(display_data_block,
  340. SORTID_PARTITION),
  341. block_ptr->slurm_part_name);
  342. add_display_treestore_line(update, treestore, &iter,
  343. find_col_name(display_data_block,
  344. SORTID_STATE),
  345. bg_block_state_string(block_ptr->state));
  346. add_display_treestore_line(update, treestore, &iter,
  347. find_col_name(display_data_block,
  348. SORTID_REASON),
  349. block_ptr->reason);
  350. }
  351. static void _update_block_record(sview_block_info_t *block_ptr,
  352. GtkTreeStore *treestore)
  353. {
  354. char cnode_cnt[20], cnode_cnt2[20];
  355. char *tmp_char = NULL, *tmp_char2 = NULL, *tmp_char3 = NULL;
  356. convert_num_unit((float)block_ptr->cnode_cnt, cnode_cnt,
  357. sizeof(cnode_cnt), UNIT_NONE);
  358. if (cluster_flags & CLUSTER_FLAG_BGQ) {
  359. convert_num_unit((float)block_ptr->cnode_err_cnt, cnode_cnt2,
  360. sizeof(cnode_cnt), UNIT_NONE);
  361. tmp_char3 = xstrdup_printf("%s/%s", cnode_cnt, cnode_cnt2);
  362. } else
  363. tmp_char3 = cnode_cnt;
  364. tmp_char = conn_type_string_full(block_ptr->bg_conn_type);
  365. tmp_char2 = _set_running_job_str(block_ptr->job_list, 0);
  366. /* Combining these records provides a slight performance improvement */
  367. gtk_tree_store_set(treestore, &block_ptr->iter_ptr,
  368. SORTID_BLOCK, block_ptr->bg_block_name,
  369. SORTID_COLOR,
  370. sview_colors[block_ptr->color_inx],
  371. SORTID_COLOR_INX, block_ptr->color_inx,
  372. SORTID_CONN, tmp_char,
  373. SORTID_IMAGEMLOADER, block_ptr->imagemloader,
  374. SORTID_JOB, tmp_char2,
  375. SORTID_NODE_INX, block_ptr->mp_inx,
  376. SORTID_NODE_CNT, tmp_char3,
  377. SORTID_NODELIST, block_ptr->mp_str,
  378. SORTID_PARTITION, block_ptr->slurm_part_name,
  379. SORTID_REASON, block_ptr->reason,
  380. SORTID_SMALL_BLOCK, block_ptr->small_block,
  381. SORTID_STATE,
  382. bg_block_state_string(block_ptr->state),
  383. SORTID_UPDATED, 1,
  384. -1);
  385. xfree(tmp_char);
  386. xfree(tmp_char2);
  387. if (cluster_flags & CLUSTER_FLAG_BGQ)
  388. xfree(tmp_char3);
  389. if (cluster_flags & CLUSTER_FLAG_BGP) {
  390. gtk_tree_store_set(treestore, &block_ptr->iter_ptr,
  391. SORTID_IMAGERAMDISK, block_ptr->imageramdisk,
  392. SORTID_IMAGELINUX, block_ptr->imagelinux,
  393. -1);
  394. } else if (cluster_flags & CLUSTER_FLAG_BGL) {
  395. gtk_tree_store_set(treestore, &block_ptr->iter_ptr,
  396. SORTID_IMAGERAMDISK, block_ptr->imageramdisk,
  397. SORTID_IMAGELINUX, block_ptr->imagelinux,
  398. SORTID_IMAGEBLRTS, block_ptr->imageblrts,
  399. SORTID_USE,
  400. node_use_string(block_ptr->bg_node_use),
  401. -1);
  402. }
  403. return;
  404. }
  405. static void _append_block_record(sview_block_info_t *block_ptr,
  406. GtkTreeStore *treestore)
  407. {
  408. gtk_tree_store_append(treestore, &block_ptr->iter_ptr, NULL);
  409. gtk_tree_store_set(treestore, &block_ptr->iter_ptr, SORTID_POS,
  410. block_ptr->pos, -1);
  411. _update_block_record(block_ptr, treestore);
  412. }
  413. static void _update_info_block(List block_list,
  414. GtkTreeView *tree_view)
  415. {
  416. ListIterator itr;
  417. sview_block_info_t *block_ptr = NULL;
  418. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  419. static GtkTreeModel *last_model = NULL;
  420. char *name = NULL;
  421. if (!block_list) {
  422. g_print("No block_list given");
  423. return;
  424. }
  425. set_for_update(model, SORTID_UPDATED);
  426. /* Report the BG Blocks */
  427. itr = list_iterator_create(block_list);
  428. while ((block_ptr = (sview_block_info_t*) list_next(itr))) {
  429. if (block_ptr->cnode_cnt == 0)
  430. block_ptr->cnode_cnt = block_ptr->size;
  431. if (!block_ptr->slurm_part_name)
  432. block_ptr->slurm_part_name = xstrdup("no part");
  433. /* This means the tree_store changed (added new column
  434. or something). */
  435. if (last_model != model)
  436. block_ptr->iter_set = false;
  437. if (block_ptr->iter_set) {
  438. gtk_tree_model_get(model, &block_ptr->iter_ptr,
  439. SORTID_BLOCK, &name, -1);
  440. if (strcmp(name, block_ptr->bg_block_name)) {
  441. /* Bad pointer */
  442. block_ptr->iter_set = false;
  443. }
  444. g_free(name);
  445. }
  446. if (block_ptr->iter_set)
  447. _update_block_record(block_ptr,
  448. GTK_TREE_STORE(model));
  449. else {
  450. GtkTreePath *path = gtk_tree_path_new_first();
  451. /* get the iter, or find out the list is empty
  452. * goto add */
  453. if (gtk_tree_model_get_iter(
  454. model, &block_ptr->iter_ptr, path)) {
  455. do {
  456. /* search for the jobid and
  457. check to see if it is in
  458. the list */
  459. gtk_tree_model_get(
  460. model,
  461. &block_ptr->iter_ptr,
  462. SORTID_BLOCK,
  463. &name, -1);
  464. if (!strcmp(name,
  465. block_ptr->bg_block_name)) {
  466. /* update with new info */
  467. g_free(name);
  468. _update_block_record(
  469. block_ptr,
  470. GTK_TREE_STORE(model));
  471. block_ptr->iter_set = 1;
  472. break;
  473. }
  474. g_free(name);
  475. } while (gtk_tree_model_iter_next(
  476. model,
  477. &block_ptr->iter_ptr));
  478. }
  479. if (!block_ptr->iter_set) {
  480. _append_block_record(block_ptr,
  481. GTK_TREE_STORE(model));
  482. block_ptr->iter_set = true;
  483. }
  484. gtk_tree_path_free(path);
  485. }
  486. }
  487. list_iterator_destroy(itr);
  488. /* remove all old blocks */
  489. remove_old(model, SORTID_UPDATED);
  490. last_model = model;
  491. }
  492. static int _sview_block_sort_aval_dec(sview_block_info_t* rec_a,
  493. sview_block_info_t* rec_b)
  494. {
  495. int size_a = rec_a->cnode_cnt;
  496. int size_b = rec_b->cnode_cnt;
  497. if (list_count(rec_a->job_list) < list_count(rec_b->job_list))
  498. return 1;
  499. else if (list_count(rec_a->job_list) > list_count(rec_b->job_list))
  500. return -1;
  501. if ((rec_a->state == BG_BLOCK_FREE) && (rec_b->state != BG_BLOCK_FREE))
  502. return 1;
  503. else if ((rec_a->state != BG_BLOCK_FREE) &&
  504. (rec_b->state == BG_BLOCK_FREE))
  505. return -1;
  506. if (size_a < size_b)
  507. return -1;
  508. else if (size_a > size_b)
  509. return 1;
  510. if (rec_a->mp_str && rec_b->mp_str) {
  511. size_a = strcmp(rec_a->mp_str, rec_b->mp_str);
  512. if (size_a < 0)
  513. return -1;
  514. else if (size_a > 0)
  515. return 1;
  516. }
  517. return 0;
  518. }
  519. static void _set_block_partition(partition_info_msg_t *part_info_ptr,
  520. sview_block_info_t *block_ptr)
  521. {
  522. int j;
  523. partition_info_t part;
  524. for (j = 0; j < part_info_ptr->record_count; j++) {
  525. part = part_info_ptr->partition_array[j];
  526. if (_in_slurm_partition(part.node_inx,
  527. block_ptr->mp_inx)) {
  528. xfree(block_ptr->slurm_part_name);
  529. block_ptr->slurm_part_name = xstrdup(part.name);
  530. return;
  531. }
  532. }
  533. }
  534. static List _create_block_list(partition_info_msg_t *part_info_ptr,
  535. block_info_msg_t *block_info_ptr)
  536. {
  537. int i;
  538. static List block_list = NULL;
  539. static partition_info_msg_t *last_part_info_ptr = NULL;
  540. static block_info_msg_t *last_block_info_ptr = NULL;
  541. sview_block_info_t *block_ptr = NULL;
  542. char tmp_mp_str[50];
  543. if (block_list && (part_info_ptr == last_part_info_ptr)
  544. && (block_info_ptr == last_block_info_ptr))
  545. return block_list;
  546. last_part_info_ptr = part_info_ptr;
  547. if (block_list) {
  548. /* Only the partition info changed so lets update just
  549. that part.
  550. */
  551. if (block_info_ptr == last_block_info_ptr) {
  552. ListIterator itr = list_iterator_create(block_list);
  553. while ((block_ptr = list_next(itr)))
  554. _set_block_partition(part_info_ptr, block_ptr);
  555. return block_list;
  556. }
  557. list_flush(block_list);
  558. } else
  559. block_list = list_create(_block_list_del);
  560. if (!block_list) {
  561. g_print("malloc error\n");
  562. return NULL;
  563. }
  564. last_block_info_ptr = block_info_ptr;
  565. for (i=0; i<block_info_ptr->record_count; i++) {
  566. /* If we don't have a block name just continue since
  567. ths block hasn't been made in the system yet. */
  568. if (!block_info_ptr->block_array[i].bg_block_id)
  569. continue;
  570. block_ptr = xmalloc(sizeof(sview_block_info_t));
  571. block_ptr->pos = i;
  572. block_ptr->bg_block_name
  573. = xstrdup(block_info_ptr->
  574. block_array[i].bg_block_id);
  575. block_ptr->color_inx =
  576. atoi(block_ptr->bg_block_name+7);
  577. /* on some systems they make there own blocks named
  578. whatever they want, so doing this fixes what could
  579. be a negative number.
  580. */
  581. if (block_ptr->color_inx < 0)
  582. block_ptr->color_inx = i;
  583. block_ptr->color_inx %= sview_colors_cnt;
  584. block_ptr->mp_str
  585. = xstrdup(block_info_ptr->block_array[i].mp_str);
  586. if (block_info_ptr->block_array[i].ionode_str) {
  587. block_ptr->small_block = 1;
  588. snprintf(tmp_mp_str, sizeof(tmp_mp_str),
  589. "%s[%s]",
  590. block_ptr->mp_str,
  591. block_info_ptr->block_array[i].ionode_str);
  592. xfree(block_ptr->mp_str);
  593. block_ptr->mp_str = xstrdup(tmp_mp_str);
  594. }
  595. block_ptr->reason
  596. = xstrdup(block_info_ptr->block_array[i].reason);
  597. if (cluster_flags & CLUSTER_FLAG_BGP) {
  598. block_ptr->imagelinux = xstrdup(
  599. block_info_ptr->block_array[i].linuximage);
  600. block_ptr->imageramdisk = xstrdup(
  601. block_info_ptr->block_array[i].ramdiskimage);
  602. } else if (cluster_flags & CLUSTER_FLAG_BGL) {
  603. block_ptr->imageblrts = xstrdup(
  604. block_info_ptr->block_array[i].blrtsimage);
  605. block_ptr->imagelinux = xstrdup(
  606. block_info_ptr->block_array[i].linuximage);
  607. block_ptr->imageramdisk = xstrdup(
  608. block_info_ptr->block_array[i].ramdiskimage);
  609. }
  610. block_ptr->imagemloader = xstrdup(
  611. block_info_ptr->block_array[i].mloaderimage);
  612. block_ptr->state
  613. = block_info_ptr->block_array[i].state;
  614. memcpy(block_ptr->bg_conn_type,
  615. block_info_ptr->block_array[i].conn_type,
  616. sizeof(block_ptr->bg_conn_type));
  617. if (cluster_flags & CLUSTER_FLAG_BGL)
  618. block_ptr->bg_node_use
  619. = block_info_ptr->block_array[i].node_use;
  620. block_ptr->cnode_cnt
  621. = block_info_ptr->block_array[i].cnode_cnt;
  622. block_ptr->cnode_err_cnt
  623. = block_info_ptr->block_array[i].cnode_err_cnt;
  624. block_ptr->mp_inx
  625. = block_info_ptr->block_array[i].mp_inx;
  626. _set_block_partition(part_info_ptr, block_ptr);
  627. block_ptr->job_list = list_create(slurm_free_block_job_info);
  628. if (block_info_ptr->block_array[i].job_list)
  629. list_transfer(block_ptr->job_list,
  630. block_info_ptr->block_array[i].job_list);
  631. if (block_ptr->bg_conn_type[0] >= SELECT_SMALL)
  632. block_ptr->size = 0;
  633. list_append(block_list, block_ptr);
  634. }
  635. list_sort(block_list,
  636. (ListCmpF)_sview_block_sort_aval_dec);
  637. return block_list;
  638. }
  639. void _display_info_block(List block_list,
  640. popup_info_t *popup_win)
  641. {
  642. specific_info_t *spec_info = popup_win->spec_info;
  643. char *name = (char *)spec_info->search_info->gchar_data;
  644. int j = 0, found = 0;
  645. sview_block_info_t *block_ptr = NULL;
  646. int update = 0;
  647. GtkTreeView *treeview = NULL;
  648. ListIterator itr = NULL;
  649. if (!spec_info->search_info->gchar_data)
  650. goto finished;
  651. need_refresh:
  652. if (!spec_info->display_widget) {
  653. treeview = create_treeview_2cols_attach_to_table(
  654. popup_win->table);
  655. spec_info->display_widget =
  656. gtk_widget_ref(GTK_WIDGET(treeview));
  657. } else {
  658. treeview = GTK_TREE_VIEW(spec_info->display_widget);
  659. update = 1;
  660. }
  661. itr = list_iterator_create(block_list);
  662. while ((block_ptr = (sview_block_info_t*) list_next(itr))) {
  663. if (!strcmp(block_ptr->bg_block_name, name)
  664. || !strcmp(block_ptr->mp_str, name)) {
  665. /* we want to over ride any subgrp in error
  666. state */
  667. enum node_states state = NODE_STATE_UNKNOWN;
  668. if (block_ptr->state & BG_BLOCK_ERROR_FLAG)
  669. state = NODE_STATE_ERROR;
  670. else if (list_count(block_ptr->job_list))
  671. state = NODE_STATE_ALLOCATED;
  672. else
  673. state = NODE_STATE_IDLE;
  674. j = 0;
  675. while (block_ptr->mp_inx[j] >= 0) {
  676. change_grid_color(
  677. popup_win->grid_button_list,
  678. block_ptr->mp_inx[j],
  679. block_ptr->mp_inx[j+1],
  680. block_ptr->color_inx, true,
  681. state);
  682. j += 2;
  683. }
  684. _layout_block_record(treeview, block_ptr, update);
  685. found = 1;
  686. break;
  687. }
  688. }
  689. list_iterator_destroy(itr);
  690. post_setup_popup_grid_list(popup_win);
  691. if (!found) {
  692. if (!popup_win->not_found) {
  693. char *temp = "BLOCK DOESN'T EXSIST\n";
  694. GtkTreeIter iter;
  695. GtkTreeModel *model = NULL;
  696. /* only time this will be run so no update */
  697. model = gtk_tree_view_get_model(treeview);
  698. add_display_treestore_line(0,
  699. GTK_TREE_STORE(model),
  700. &iter,
  701. temp, "");
  702. }
  703. popup_win->not_found = true;
  704. } else {
  705. if (popup_win->not_found) {
  706. popup_win->not_found = false;
  707. gtk_widget_destroy(spec_info->display_widget);
  708. goto need_refresh;
  709. }
  710. }
  711. gtk_widget_show(spec_info->display_widget);
  712. finished:
  713. return;
  714. }
  715. extern void refresh_block(GtkAction *action, gpointer user_data)
  716. {
  717. popup_info_t *popup_win = (popup_info_t *)user_data;
  718. xassert(popup_win);
  719. xassert(popup_win->spec_info);
  720. xassert(popup_win->spec_info->title);
  721. popup_win->force_refresh = 1;
  722. specific_info_block(popup_win);
  723. }
  724. extern int get_new_info_block(block_info_msg_t **block_ptr, int force)
  725. {
  726. int error_code = SLURM_NO_CHANGE_IN_DATA;
  727. block_info_msg_t *new_bg_ptr = NULL;
  728. time_t now = time(NULL);
  729. static time_t last;
  730. static bool changed = 0;
  731. uint16_t show_flags = 0;
  732. if (!(cluster_flags & CLUSTER_FLAG_BG))
  733. return error_code;
  734. if (g_block_info_ptr && !force
  735. && ((now - last) < working_sview_config.refresh_delay)) {
  736. if (*block_ptr != g_block_info_ptr)
  737. error_code = SLURM_SUCCESS;
  738. *block_ptr = g_block_info_ptr;
  739. if (changed)
  740. error_code = SLURM_SUCCESS;
  741. goto end_it;
  742. }
  743. last = now;
  744. if (working_sview_config.show_hidden)
  745. show_flags |= SHOW_ALL;
  746. if (g_block_info_ptr) {
  747. error_code = slurm_load_block_info(
  748. g_block_info_ptr->last_update, &new_bg_ptr, show_flags);
  749. if (error_code == SLURM_SUCCESS) {
  750. slurm_free_block_info_msg(g_block_info_ptr);
  751. changed = 1;
  752. } else if (slurm_get_errno() == SLURM_NO_CHANGE_IN_DATA) {
  753. error_code = SLURM_NO_CHANGE_IN_DATA;
  754. new_bg_ptr = g_block_info_ptr;
  755. changed = 0;
  756. }
  757. } else {
  758. new_bg_ptr = NULL;
  759. error_code = slurm_load_block_info(
  760. (time_t) NULL, &new_bg_ptr, show_flags);
  761. changed = 1;
  762. }
  763. g_block_info_ptr = new_bg_ptr;
  764. if (block_ptr) {
  765. if (g_block_info_ptr && (*block_ptr != g_block_info_ptr))
  766. error_code = SLURM_SUCCESS;
  767. *block_ptr = g_block_info_ptr;
  768. }
  769. end_it:
  770. return error_code;
  771. }
  772. extern int update_state_block(GtkDialog *dialog,
  773. const char *blockid, const char *type)
  774. {
  775. int i = 0;
  776. int rc = SLURM_SUCCESS;
  777. char tmp_char[100];
  778. update_block_msg_t block_msg;
  779. GtkWidget *label = NULL;
  780. int no_dialog = 0;
  781. if (!dialog) {
  782. dialog = GTK_DIALOG(
  783. gtk_dialog_new_with_buttons(
  784. type,
  785. GTK_WINDOW(main_window),
  786. GTK_DIALOG_MODAL
  787. | GTK_DIALOG_DESTROY_WITH_PARENT,
  788. NULL));
  789. no_dialog = 1;
  790. }
  791. slurm_init_update_block_msg(&block_msg);
  792. block_msg.bg_block_id = (char *)blockid;
  793. label = gtk_dialog_add_button(dialog,
  794. GTK_STOCK_YES, GTK_RESPONSE_OK);
  795. gtk_window_set_default(GTK_WINDOW(dialog), label);
  796. gtk_dialog_add_button(dialog,
  797. GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
  798. if (!strcasecmp("Error", type) ||
  799. !strcasecmp("Put block in error state", type)) {
  800. snprintf(tmp_char, sizeof(tmp_char),
  801. "Are you sure you want to put block %s "
  802. "in an error state?",
  803. blockid);
  804. block_msg.state = BG_BLOCK_ERROR_FLAG;
  805. } else if (!strcasecmp("Recreate block", type)) {
  806. snprintf(tmp_char, sizeof(tmp_char),
  807. "Are you sure you want to recreate block %s?",
  808. blockid);
  809. block_msg.state = BG_BLOCK_BOOTING;
  810. } else if (!strcasecmp("Remove block", type)) {
  811. snprintf(tmp_char, sizeof(tmp_char),
  812. "Are you sure you want to remove block %s?",
  813. blockid);
  814. block_msg.state = BG_BLOCK_NAV;
  815. } else if (!strcasecmp("Resume block", type)) {
  816. snprintf(tmp_char, sizeof(tmp_char),
  817. "Are you sure you want to resume block %s?",
  818. blockid);
  819. block_msg.state = BG_BLOCK_TERM;
  820. } else {
  821. snprintf(tmp_char, sizeof(tmp_char),
  822. "Are you sure you want to put block %s "
  823. "in a free state?",
  824. blockid);
  825. block_msg.state = BG_BLOCK_FREE;
  826. }
  827. label = gtk_label_new(tmp_char);
  828. gtk_box_pack_start(GTK_BOX(dialog->vbox), label, FALSE, FALSE, 0);
  829. gtk_widget_show_all(GTK_WIDGET(dialog));
  830. i = gtk_dialog_run(dialog);
  831. if (i == GTK_RESPONSE_OK) {
  832. if (slurm_update_block(&block_msg)
  833. == SLURM_SUCCESS) {
  834. snprintf(tmp_char, sizeof(tmp_char),
  835. "Block %s updated successfully",
  836. blockid);
  837. } else {
  838. snprintf(tmp_char, sizeof(tmp_char),
  839. "Problem updating block %s.",
  840. blockid);
  841. }
  842. display_edit_note(tmp_char);
  843. }
  844. if (no_dialog)
  845. gtk_widget_destroy(GTK_WIDGET(dialog));
  846. return rc;
  847. }
  848. extern GtkListStore *create_model_block(int type)
  849. {
  850. GtkListStore *model = NULL;
  851. GtkTreeIter iter;
  852. switch(type) {
  853. case SORTID_STATE:
  854. model = gtk_list_store_new(2, G_TYPE_STRING,
  855. G_TYPE_INT);
  856. gtk_list_store_append(model, &iter);
  857. gtk_list_store_set(model, &iter,
  858. 0, "Error",
  859. 1, SORTID_STATE,
  860. -1);
  861. gtk_list_store_append(model, &iter);
  862. gtk_list_store_set(model, &iter,
  863. 0, "Free",
  864. 1, SORTID_STATE,
  865. -1);
  866. break;
  867. default:
  868. break;
  869. }
  870. return model;
  871. }
  872. extern void admin_edit_block(GtkCellRendererText *cell,
  873. const char *path_string,
  874. const char *new_text,
  875. gpointer data)
  876. {
  877. GtkTreeStore *treestore = GTK_TREE_STORE(data);
  878. GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
  879. GtkTreeIter iter;
  880. int column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cell),
  881. "column"));
  882. char *blockid = NULL;
  883. char *old_text = NULL;
  884. if (!new_text || !strcmp(new_text, ""))
  885. goto no_input;
  886. gtk_tree_model_get_iter(GTK_TREE_MODEL(treestore), &iter, path);
  887. gtk_tree_model_get(GTK_TREE_MODEL(treestore), &iter,
  888. SORTID_BLOCK, &blockid,
  889. column, &old_text,
  890. -1);
  891. switch(column) {
  892. case SORTID_STATE:
  893. update_state_block(NULL, blockid, new_text);
  894. break;
  895. default:
  896. break;
  897. }
  898. g_free(blockid);
  899. g_free(old_text);
  900. no_input:
  901. gtk_tree_path_free(path);
  902. g_static_mutex_unlock(&sview_mutex);
  903. }
  904. extern void get_info_block(GtkTable *table, display_data_t *display_data)
  905. {
  906. int part_error_code = SLURM_SUCCESS;
  907. int block_error_code = SLURM_SUCCESS;
  908. static int view = -1;
  909. static partition_info_msg_t *part_info_ptr = NULL;
  910. static block_info_msg_t *block_ptr = NULL;
  911. char error_char[100];
  912. GtkWidget *label = NULL;
  913. GtkTreeView *tree_view = NULL;
  914. static GtkWidget *display_widget = NULL;
  915. List block_list = NULL;
  916. int j=0;
  917. ListIterator itr = NULL;
  918. sview_block_info_t *sview_block_info_ptr = NULL;
  919. GtkTreePath *path = NULL;
  920. static bool set_opts = FALSE;
  921. if (!set_opts)
  922. set_page_opts(BLOCK_PAGE, display_data_block,
  923. SORTID_CNT, _initial_page_opts);
  924. set_opts = TRUE;
  925. /* reset */
  926. if (!table && !display_data) {
  927. if (display_widget)
  928. gtk_widget_destroy(display_widget);
  929. display_widget = NULL;
  930. part_info_ptr = NULL;
  931. block_ptr = NULL;
  932. goto reset_curs;
  933. }
  934. if (display_data)
  935. local_display_data = display_data;
  936. if (!table) {
  937. display_data_block->set_menu = local_display_data->set_menu;
  938. goto reset_curs;
  939. }
  940. if (display_widget && toggled) {
  941. gtk_widget_destroy(display_widget);
  942. display_widget = NULL;
  943. goto display_it;
  944. }
  945. if ((part_error_code = get_new_info_part(&part_info_ptr, force_refresh))
  946. == SLURM_NO_CHANGE_IN_DATA) {
  947. } else if (part_error_code != SLURM_SUCCESS) {
  948. if (view == ERROR_VIEW)
  949. goto end_it;
  950. view = ERROR_VIEW;
  951. if (display_widget)
  952. gtk_widget_destroy(display_widget);
  953. sprintf(error_char, "slurm_load_partitions: %s",
  954. slurm_strerror(slurm_get_errno()));
  955. label = gtk_label_new(error_char);
  956. gtk_table_attach_defaults(GTK_TABLE(table),
  957. label,
  958. 0, 1, 0, 1);
  959. gtk_widget_show(label);
  960. display_widget = gtk_widget_ref(label);
  961. goto end_it;
  962. }
  963. if ((block_error_code = get_new_info_block(&block_ptr, force_refresh))
  964. == SLURM_NO_CHANGE_IN_DATA) {
  965. if ((!display_widget || view == ERROR_VIEW)
  966. || (part_error_code != SLURM_NO_CHANGE_IN_DATA)) {
  967. goto display_it;
  968. }
  969. } else if (block_error_code != SLURM_SUCCESS) {
  970. if (view == ERROR_VIEW)
  971. goto end_it;
  972. view = ERROR_VIEW;
  973. if (display_widget)
  974. gtk_widget_destroy(display_widget);
  975. sprintf(error_char, "slurm_load_block: %s",
  976. slurm_strerror(slurm_get_errno()));
  977. label = gtk_label_new(error_char);
  978. gtk_table_attach_defaults(table,
  979. label,
  980. 0, 1, 0, 1);
  981. gtk_widget_show(label);
  982. display_widget = gtk_widget_ref(label);
  983. goto end_it;
  984. }
  985. display_it:
  986. if (!block_ptr) {
  987. view = ERROR_VIEW;
  988. if (display_widget)
  989. gtk_widget_destroy(display_widget);
  990. label = gtk_label_new("No blocks on non-Bluegene systems");
  991. gtk_table_attach_defaults(GTK_TABLE(table),
  992. label,
  993. 0, 1, 0, 1);
  994. gtk_widget_show(label);
  995. display_widget = gtk_widget_ref(label);
  996. goto end_it;
  997. }
  998. if (!part_info_ptr)
  999. goto reset_curs;
  1000. block_list = _create_block_list(part_info_ptr, block_ptr);
  1001. if (!block_list)
  1002. goto reset_curs;
  1003. /* set up the grid */
  1004. if (display_widget && GTK_IS_TREE_VIEW(display_widget)
  1005. && gtk_tree_selection_count_selected_rows(
  1006. gtk_tree_view_get_selection(
  1007. GTK_TREE_VIEW(display_widget)))) {
  1008. GtkTreeViewColumn *focus_column = NULL;
  1009. /* highlight the correct mp_str from the last selection */
  1010. gtk_tree_view_get_cursor(GTK_TREE_VIEW(display_widget),
  1011. &path, &focus_column);
  1012. }
  1013. if (!path) {
  1014. itr = list_iterator_create(block_list);
  1015. while ((sview_block_info_ptr = list_next(itr))) {
  1016. j=0;
  1017. while (sview_block_info_ptr->mp_inx[j] >= 0) {
  1018. change_grid_color(
  1019. grid_button_list,
  1020. sview_block_info_ptr->mp_inx[j],
  1021. sview_block_info_ptr->mp_inx[j+1],
  1022. sview_block_info_ptr->color_inx,
  1023. true, 0);
  1024. j += 2;
  1025. }
  1026. }
  1027. list_iterator_destroy(itr);
  1028. change_grid_color(grid_button_list, -1, -1,
  1029. MAKE_WHITE, true, 0);
  1030. } else
  1031. highlight_grid(GTK_TREE_VIEW(display_widget),
  1032. SORTID_NODE_INX, SORTID_COLOR_INX,
  1033. grid_button_list);
  1034. if (view == ERROR_VIEW && display_widget) {
  1035. gtk_widget_destroy(display_widget);
  1036. display_widget = NULL;
  1037. }
  1038. if (!display_widget) {
  1039. tree_view = create_treeview(local_display_data,
  1040. &grid_button_list);
  1041. gtk_tree_selection_set_mode(
  1042. gtk_tree_view_get_selection(tree_view),
  1043. GTK_SELECTION_MULTIPLE);
  1044. display_widget = gtk_widget_ref(GTK_WIDGET(tree_view));
  1045. gtk_table_attach_defaults(table,
  1046. GTK_WIDGET(tree_view),
  1047. 0, 1, 0, 1);
  1048. /* since this function sets the model of the tree_view
  1049. to the treestore we don't really care about
  1050. the return value */
  1051. create_treestore(tree_view, display_data_block,
  1052. SORTID_CNT, SORTID_NODELIST, SORTID_COLOR);
  1053. }
  1054. view = INFO_VIEW;
  1055. _update_info_block(block_list, GTK_TREE_VIEW(display_widget));
  1056. end_it:
  1057. toggled = FALSE;
  1058. force_refresh = FALSE;
  1059. reset_curs:
  1060. if (main_window && main_window->window)
  1061. gdk_window_set_cursor(main_window->window, NULL);
  1062. return;
  1063. }
  1064. extern void specific_info_block(popup_info_t *popup_win)
  1065. {
  1066. int part_error_code = SLURM_SUCCESS;
  1067. int block_error_code = SLURM_SUCCESS;
  1068. static partition_info_msg_t *part_info_ptr = NULL;
  1069. static block_info_msg_t *block_info_ptr = NULL;
  1070. specific_info_t *spec_info = popup_win->spec_info;
  1071. sview_search_info_t *search_info = spec_info->search_info;
  1072. char error_char[100];
  1073. GtkWidget *label = NULL;
  1074. GtkTreeView *tree_view = NULL;
  1075. List block_list = NULL;
  1076. List send_block_list = NULL;
  1077. sview_block_info_t *block_ptr = NULL;
  1078. int j=0, i=-1;
  1079. hostset_t hostset = NULL;
  1080. ListIterator itr = NULL;
  1081. if (!spec_info->display_widget) {
  1082. setup_popup_info(popup_win, display_data_block, SORTID_CNT);
  1083. }
  1084. if (spec_info->display_widget && popup_win->toggled) {
  1085. gtk_widget_destroy(spec_info->display_widget);
  1086. spec_info->display_widget = NULL;
  1087. goto display_it;
  1088. }
  1089. if ((part_error_code = get_new_info_part(&part_info_ptr,
  1090. popup_win->force_refresh))
  1091. == SLURM_NO_CHANGE_IN_DATA) {
  1092. } else if (part_error_code != SLURM_SUCCESS) {
  1093. if (spec_info->view == ERROR_VIEW)
  1094. goto end_it;
  1095. spec_info->view = ERROR_VIEW;
  1096. if (spec_info->display_widget)
  1097. gtk_widget_destroy(spec_info->display_widget);
  1098. sprintf(error_char, "slurm_load_partitions: %s",
  1099. slurm_strerror(slurm_get_errno()));
  1100. label = gtk_label_new(error_char);
  1101. gtk_table_attach_defaults(popup_win->table,
  1102. label,
  1103. 0, 1, 0, 1);
  1104. gtk_widget_show(label);
  1105. spec_info->display_widget = gtk_widget_ref(label);
  1106. goto end_it;
  1107. }
  1108. if ((block_error_code =
  1109. get_new_info_block(&block_info_ptr, popup_win->force_refresh))
  1110. == SLURM_NO_CHANGE_IN_DATA) {
  1111. if ((!spec_info->display_widget
  1112. || spec_info->view == ERROR_VIEW)
  1113. || (part_error_code != SLURM_NO_CHANGE_IN_DATA)) {
  1114. goto display_it;
  1115. }
  1116. } else if (block_error_code != SLURM_SUCCESS) {
  1117. if (spec_info->view == ERROR_VIEW)
  1118. goto end_it;
  1119. spec_info->view = ERROR_VIEW;
  1120. if (spec_info->display_widget)
  1121. gtk_widget_destroy(spec_info->display_widget);
  1122. sprintf(error_char, "slurm_load_block: %s",
  1123. slurm_strerror(slurm_get_errno()));
  1124. label = gtk_label_new(error_char);
  1125. gtk_table_attach_defaults(popup_win->table,
  1126. label,
  1127. 0, 1, 0, 1);
  1128. gtk_widget_show(label);
  1129. spec_info->display_widget = gtk_widget_ref(label);
  1130. goto end_it;
  1131. }
  1132. display_it:
  1133. block_list = _create_block_list(part_info_ptr, block_info_ptr);
  1134. if (!block_list)
  1135. return;
  1136. if (spec_info->view == ERROR_VIEW && spec_info->display_widget) {
  1137. gtk_widget_destroy(spec_info->display_widget);
  1138. spec_info->display_widget = NULL;
  1139. }
  1140. if (spec_info->type != INFO_PAGE && !spec_info->display_widget) {
  1141. tree_view = create_treeview(local_display_data,
  1142. &popup_win->grid_button_list);
  1143. gtk_tree_selection_set_mode(
  1144. gtk_tree_view_get_selection(tree_view),
  1145. GTK_SELECTION_MULTIPLE);
  1146. spec_info->display_widget =
  1147. gtk_widget_ref(GTK_WIDGET(tree_view));
  1148. gtk_table_attach_defaults(popup_win->table,
  1149. GTK_WIDGET(tree_view),
  1150. 0, 1, 0, 1);
  1151. /* since this function sets the model of the tree_view
  1152. to the treestore we don't really care about
  1153. the return value */
  1154. create_treestore(tree_view, popup_win->display_data,
  1155. SORTID_CNT, SORTID_BLOCK, SORTID_COLOR);
  1156. }
  1157. setup_popup_grid_list(popup_win);
  1158. spec_info->view = INFO_VIEW;
  1159. if (spec_info->type == INFO_PAGE) {
  1160. _display_info_block(block_list, popup_win);
  1161. goto end_it;
  1162. }
  1163. /* just linking to another list, don't free the inside, just
  1164. the list */
  1165. send_block_list = list_create(NULL);
  1166. itr = list_iterator_create(block_list);
  1167. i = -1;
  1168. while ((block_ptr = list_next(itr))) {
  1169. /* we want to over ride any subgrp in error
  1170. state */
  1171. enum node_states state = NODE_STATE_UNKNOWN;
  1172. char *name = NULL;
  1173. i++;
  1174. switch(spec_info->type) {
  1175. case PART_PAGE:
  1176. if (strcmp(block_ptr->slurm_part_name,
  1177. search_info->gchar_data))
  1178. continue;
  1179. break;
  1180. case RESV_PAGE:
  1181. case NODE_PAGE:
  1182. if (!block_ptr->mp_str)
  1183. continue;
  1184. if (!(hostset = hostset_create(
  1185. search_info->gchar_data)))
  1186. continue;
  1187. name = block_ptr->mp_str;
  1188. if (block_ptr->small_block) {
  1189. int j=0;
  1190. /* strip off the ionodes part */
  1191. while (name[j]) {
  1192. if (name[j] == '[') {
  1193. name[j] = '\0';
  1194. break;
  1195. }
  1196. j++;
  1197. }
  1198. }
  1199. if (!hostset_intersects(hostset, name)) {
  1200. hostset_destroy(hostset);
  1201. continue;
  1202. }
  1203. hostset_destroy(hostset);
  1204. break;
  1205. case BLOCK_PAGE:
  1206. switch(search_info->search_type) {
  1207. case SEARCH_BLOCK_NAME:
  1208. if (!search_info->gchar_data)
  1209. continue;
  1210. if (strcmp(block_ptr->bg_block_name,
  1211. search_info->gchar_data))
  1212. continue;
  1213. break;
  1214. case SEARCH_BLOCK_SIZE:
  1215. if (search_info->int_data == NO_VAL)
  1216. continue;
  1217. if (block_ptr->cnode_cnt
  1218. != search_info->int_data)
  1219. continue;
  1220. break;
  1221. case SEARCH_BLOCK_STATE:
  1222. if (search_info->int_data == NO_VAL)
  1223. continue;
  1224. if (block_ptr->state != search_info->int_data)
  1225. continue;
  1226. break;
  1227. default:
  1228. continue;
  1229. break;
  1230. }
  1231. break;
  1232. case JOB_PAGE:
  1233. if (strcmp(block_ptr->bg_block_name,
  1234. search_info->gchar_data))
  1235. continue;
  1236. break;
  1237. default:
  1238. g_print("Unknown type %d\n", spec_info->type);
  1239. continue;
  1240. }
  1241. list_push(send_block_list, block_ptr);
  1242. if (block_ptr->state & BG_BLOCK_ERROR_FLAG)
  1243. state = NODE_STATE_ERROR;
  1244. else if (list_count(block_ptr->job_list))
  1245. state = NODE_STATE_ALLOCATED;
  1246. else
  1247. state = NODE_STATE_IDLE;
  1248. j=0;
  1249. while (block_ptr->mp_inx[j] >= 0) {
  1250. change_grid_color(
  1251. popup_win->grid_button_list,
  1252. block_ptr->mp_inx[j],
  1253. block_ptr->mp_inx[j+1], block_ptr->color_inx,
  1254. true, state);
  1255. j += 2;
  1256. }
  1257. }
  1258. list_iterator_destroy(itr);
  1259. post_setup_popup_grid_list(popup_win);
  1260. _update_info_block(send_block_list,
  1261. GTK_TREE_VIEW(spec_info->display_widget));
  1262. list_destroy(send_block_list);
  1263. end_it:
  1264. popup_win->toggled = 0;
  1265. popup_win->force_refresh = 0;
  1266. return;
  1267. }
  1268. extern void set_menus_block(void *arg, void *arg2, GtkTreePath *path, int type)
  1269. {
  1270. GtkTreeView *tree_view = (GtkTreeView *)arg;
  1271. popup_info_t *popup_win = (popup_info_t *)arg;
  1272. GtkMenu *menu = (GtkMenu *)arg2;
  1273. List button_list = (List)arg2;
  1274. switch(type) {
  1275. case TAB_CLICKED:
  1276. make_fields_menu(NULL, menu, display_data_block, SORTID_CNT);
  1277. break;
  1278. case ROW_CLICKED:
  1279. make_options_menu(tree_view, path, menu, options_data_block);
  1280. break;
  1281. case ROW_LEFT_CLICKED:
  1282. highlight_grid(tree_view, SORTID_NODE_INX,
  1283. SORTID_COLOR_INX, button_list);
  1284. break;
  1285. case FULL_CLICKED:
  1286. {
  1287. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  1288. GtkTreeIter iter;
  1289. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  1290. g_error("error getting iter from model\n");
  1291. break;
  1292. }
  1293. popup_all_block(model, &iter, INFO_PAGE);
  1294. break;
  1295. }
  1296. case POPUP_CLICKED:
  1297. make_fields_menu(popup_win, menu,
  1298. popup_win->display_data, SORTID_CNT);
  1299. break;
  1300. default:
  1301. g_error("UNKNOWN type %d given to set_fields\n", type);
  1302. }
  1303. }
  1304. extern void popup_all_block(GtkTreeModel *model, GtkTreeIter *iter, int id)
  1305. {
  1306. char *name = NULL;
  1307. char title[100];
  1308. ListIterator itr = NULL;
  1309. popup_info_t *popup_win = NULL;
  1310. GError *error = NULL;
  1311. int i=0;
  1312. gtk_tree_model_get(model, iter, SORTID_BLOCK, &name, -1);
  1313. switch(id) {
  1314. case JOB_PAGE:
  1315. snprintf(title, 100, "Jobs(s) in block %s", name);
  1316. break;
  1317. case PART_PAGE:
  1318. snprintf(title, 100, "Partition(s) containing block %s", name);
  1319. break;
  1320. case RESV_PAGE:
  1321. snprintf(title, 100, "Reservations(s) containing block %s",
  1322. name);
  1323. break;
  1324. case NODE_PAGE:
  1325. snprintf(title, 100, "Midplane(s) in block %s", name);
  1326. break;
  1327. case SUBMIT_PAGE:
  1328. snprintf(title, 100, "Submit job on %s", name);
  1329. break;
  1330. case INFO_PAGE:
  1331. snprintf(title, 100, "Full info for block %s", name);
  1332. break;
  1333. default:
  1334. g_print("Block got %d\n", id);
  1335. }
  1336. itr = list_iterator_create(popup_list);
  1337. while ((popup_win = list_next(itr))) {
  1338. if (popup_win->spec_info)
  1339. if (!strcmp(popup_win->spec_info->title, title)) {
  1340. break;
  1341. }
  1342. }
  1343. list_iterator_destroy(itr);
  1344. if (!popup_win) {
  1345. if (id == INFO_PAGE)
  1346. popup_win = create_popup_info(id, BLOCK_PAGE, title);
  1347. else
  1348. popup_win = create_popup_info(BLOCK_PAGE, id, title);
  1349. } else {
  1350. g_free(name);
  1351. gtk_window_present(GTK_WINDOW(popup_win->popup));
  1352. return;
  1353. }
  1354. /* Pass the model and the structs from the iter so we can always get
  1355. the current node_inx.
  1356. */
  1357. popup_win->model = model;
  1358. popup_win->iter = *iter;
  1359. popup_win->node_inx_id = SORTID_NODE_INX;
  1360. switch(id) {
  1361. case JOB_PAGE:
  1362. popup_win->spec_info->search_info->gchar_data = name;
  1363. break;
  1364. case PART_PAGE:
  1365. g_free(name);
  1366. gtk_tree_model_get(model, iter, SORTID_PARTITION, &name, -1);
  1367. popup_win->spec_info->search_info->gchar_data = name;
  1368. break;
  1369. case RESV_PAGE:
  1370. case NODE_PAGE:
  1371. g_free(name);
  1372. gtk_tree_model_get(model, iter, SORTID_NODELIST, &name, -1);
  1373. gtk_tree_model_get(model, iter, SORTID_SMALL_BLOCK, &i, -1);
  1374. if (i) {
  1375. i=0;
  1376. /* strip off the ionodes part */
  1377. while (name[i]) {
  1378. if (name[i] == '[') {
  1379. name[i] = '\0';
  1380. break;
  1381. }
  1382. i++;
  1383. }
  1384. }
  1385. popup_win->spec_info->search_info->gchar_data = name;
  1386. break;
  1387. case INFO_PAGE:
  1388. popup_win->spec_info->search_info->gchar_data = name;
  1389. break;
  1390. default:
  1391. g_print("block got %d\n", id);
  1392. }
  1393. if (!sview_thread_new((gpointer)popup_thr, popup_win, FALSE, &error)) {
  1394. g_printerr ("Failed to create part popup thread: %s\n",
  1395. error->message);
  1396. return;
  1397. }
  1398. }
  1399. static void _process_each_block(GtkTreeModel *model, GtkTreePath *path,
  1400. GtkTreeIter*iter, gpointer userdata)
  1401. {
  1402. char *type = userdata;
  1403. if (_DEBUG)
  1404. g_print("process_each_block: global_multi_error = %d\n",
  1405. global_multi_error);
  1406. if (!global_multi_error) {
  1407. _admin_block(model, iter, type);
  1408. }
  1409. }
  1410. extern void select_admin_block(GtkTreeModel *model, GtkTreeIter *iter,
  1411. display_data_t *display_data,
  1412. GtkTreeView *treeview)
  1413. {
  1414. if (treeview) {
  1415. if (display_data->extra & EXTRA_NODES) {
  1416. select_admin_nodes(model, iter, display_data,
  1417. SORTID_NODELIST, treeview);
  1418. return;
  1419. }
  1420. global_multi_error = FALSE;
  1421. gtk_tree_selection_selected_foreach(
  1422. gtk_tree_view_get_selection(treeview),
  1423. _process_each_block, display_data->name);
  1424. }
  1425. }
  1426. static void _admin_block(GtkTreeModel *model, GtkTreeIter *iter, char *type)
  1427. {
  1428. char *blockid = NULL;
  1429. GtkWidget *popup = gtk_dialog_new_with_buttons(
  1430. type,
  1431. GTK_WINDOW(main_window),
  1432. GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
  1433. NULL);
  1434. gtk_window_set_transient_for(GTK_WINDOW(popup), NULL);
  1435. gtk_tree_model_get(model, iter, SORTID_BLOCK, &blockid, -1);
  1436. update_state_block(GTK_DIALOG(popup), blockid, type);
  1437. g_free(blockid);
  1438. gtk_widget_destroy(popup);
  1439. return;
  1440. }
  1441. extern void cluster_change_block(void)
  1442. {
  1443. display_data_t *display_data = display_data_block;
  1444. while (display_data++) {
  1445. if (display_data->id == -1)
  1446. break;
  1447. if (cluster_flags & CLUSTER_FLAG_BGQ) {
  1448. switch(display_data->id) {
  1449. case SORTID_USE:
  1450. case SORTID_USER:
  1451. case SORTID_IMAGEBLRTS:
  1452. case SORTID_IMAGELINUX:
  1453. case SORTID_IMAGERAMDISK:
  1454. display_data->name = NULL;
  1455. break;
  1456. default:
  1457. break;
  1458. }
  1459. } else if (cluster_flags & CLUSTER_FLAG_BGP) {
  1460. switch(display_data->id) {
  1461. case SORTID_USE:
  1462. case SORTID_IMAGEBLRTS:
  1463. display_data->name = NULL;
  1464. break;
  1465. case SORTID_IMAGELINUX:
  1466. display_data->name = "Image Cnload";
  1467. break;
  1468. case SORTID_IMAGERAMDISK:
  1469. display_data->name = "Image Ioload";
  1470. break;
  1471. case SORTID_USER:
  1472. display_data->name = "User";
  1473. break;
  1474. default:
  1475. break;
  1476. }
  1477. } else if (cluster_flags & CLUSTER_FLAG_BGL) {
  1478. switch(display_data->id) {
  1479. case SORTID_USE:
  1480. display_data->name = "Node Use";
  1481. break;
  1482. case SORTID_IMAGEBLRTS:
  1483. display_data->name = "Image Blrt";
  1484. break;
  1485. case SORTID_IMAGELINUX:
  1486. display_data->name = "Image Linux";
  1487. break;
  1488. case SORTID_IMAGERAMDISK:
  1489. display_data->name = "Image Ramdisk";
  1490. break;
  1491. case SORTID_USER:
  1492. display_data->name = "User";
  1493. break;
  1494. default:
  1495. break;
  1496. }
  1497. }
  1498. }
  1499. get_info_block(NULL, NULL);
  1500. }