PageRenderTime 65ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sview/job_info.c

https://github.com/cfenoy/slurm
C | 4370 lines | 3809 code | 406 blank | 155 comment | 672 complexity | 7c6477fd62adad1796e0a4c59e75ae66 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /*****************************************************************************\
  2. * job_info.c - Functions related to job display mode of sview.
  3. *****************************************************************************
  4. * Copyright (C) 2004-2007 The Regents of the University of California.
  5. * Copyright (C) 2008-2011 Lawrence Livermore National Security.
  6. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  7. * Written by Danny Auble <da@llnl.gov>
  8. *
  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 <fcntl.h>
  30. #include <grp.h>
  31. #include <sys/stat.h>
  32. #include <sys/types.h>
  33. #include "src/common/uid.h"
  34. #include "src/common/node_select.h"
  35. #include "src/sview/sview.h"
  36. #include "src/common/parse_time.h"
  37. #include "src/common/proc_args.h"
  38. #include "src/common/slurm_strcasestr.h"
  39. #define _DEBUG 0
  40. #define MAX_CANCEL_RETRY 10
  41. #define SIZE(a) (sizeof(a)/sizeof(a[0]))
  42. /* We do not read the node table here, but allocated space for up to
  43. * MAX_NODE_SPACE nodes and generate fatal error if we go higher. Increase
  44. * this value if needed */
  45. #ifndef SVIEW_MAX_NODE_SPACE
  46. #define SVIEW_MAX_NODE_SPACE (24 * 1024)
  47. #endif
  48. /* Collection of data for printing reports. Like data is combined here */
  49. typedef struct {
  50. int color_inx;
  51. GtkTreeIter iter_ptr;
  52. bool iter_set;
  53. job_info_t *job_ptr;
  54. int node_cnt;
  55. char *nodes;
  56. int pos;
  57. bool small_block;
  58. List step_list;
  59. } sview_job_info_t;
  60. static List foreach_list = NULL;
  61. static char *stacked_job_list = NULL;
  62. typedef struct {
  63. int job_id;
  64. int state;
  65. int step_id;
  66. } jobs_foreach_t;
  67. typedef struct {
  68. int edit_type;
  69. GtkWidget *entry;
  70. job_desc_msg_t *job_msg;
  71. char *type;
  72. } jobs_foreach_common_t;
  73. enum {
  74. EDIT_SIGNAL = 1,
  75. EDIT_SIGNAL_USER,
  76. EDIT_CANCEL,
  77. EDIT_CANCEL_USER,
  78. EDIT_REQUEUE,
  79. EDIT_SUSPEND,
  80. EDIT_EDIT
  81. };
  82. /* These need to be in alpha order (except POS and CNT) */
  83. enum {
  84. SORTID_POS = POS_LOC,
  85. SORTID_ACCOUNT,
  86. SORTID_ACTION,
  87. SORTID_ALLOC,
  88. SORTID_ALLOC_NODE,
  89. SORTID_ALPS_RESV_ID,
  90. SORTID_BATCH,
  91. SORTID_BATCH_HOST,
  92. SORTID_BLOCK,
  93. SORTID_COLOR,
  94. SORTID_COLOR_INX,
  95. SORTID_COMMAND,
  96. SORTID_COMMENT,
  97. SORTID_CONNECTION,
  98. SORTID_CONTIGUOUS,
  99. /* SORTID_CORES_MAX, */
  100. /* SORTID_CORES_MIN, */
  101. SORTID_CPUS,
  102. SORTID_CPU_MAX,
  103. SORTID_CPU_MIN,
  104. SORTID_CPUS_PER_TASK,
  105. SORTID_DEPENDENCY,
  106. SORTID_DERIVED_EC,
  107. SORTID_EXIT_CODE,
  108. SORTID_FEATURES,
  109. SORTID_GEOMETRY,
  110. SORTID_GRES,
  111. SORTID_GROUP_ID,
  112. SORTID_IMAGE_BLRTS,
  113. #ifdef HAVE_BGL
  114. SORTID_IMAGE_LINUX,
  115. SORTID_IMAGE_MLOADER,
  116. SORTID_IMAGE_RAMDISK,
  117. #else
  118. SORTID_IMAGE_LINUX,
  119. SORTID_IMAGE_RAMDISK,
  120. SORTID_IMAGE_MLOADER,
  121. #endif
  122. SORTID_JOBID,
  123. SORTID_LICENSES,
  124. SORTID_CPU_REQ,
  125. SORTID_MEM_MIN,
  126. SORTID_TMP_DISK,
  127. #ifdef HAVE_BG
  128. SORTID_NODELIST,
  129. SORTID_NODELIST_EXC,
  130. SORTID_NODELIST_REQ,
  131. #endif
  132. SORTID_NAME,
  133. SORTID_NETWORK,
  134. SORTID_NICE,
  135. #ifndef HAVE_BG
  136. SORTID_NODELIST,
  137. SORTID_NODELIST_EXC,
  138. SORTID_NODELIST_REQ,
  139. #endif
  140. SORTID_NODE_INX,
  141. SORTID_NODES,
  142. SORTID_NODES_MAX,
  143. SORTID_NODES_MIN,
  144. /* SORTID_NTASKS_PER_CORE, */
  145. /* SORTID_NTASKS_PER_NODE, */
  146. /* SORTID_NTASKS_PER_SOCKET, */
  147. SORTID_PARTITION,
  148. SORTID_PREEMPT_TIME,
  149. SORTID_PRIORITY,
  150. SORTID_QOS,
  151. SORTID_REASON,
  152. SORTID_REQUEUE,
  153. SORTID_RESV_NAME,
  154. SORTID_RESTARTS,
  155. SORTID_ROTATE,
  156. SORTID_SHARED,
  157. /* SORTID_SOCKETS_MAX, */
  158. /* SORTID_SOCKETS_MIN, */
  159. SORTID_STATE,
  160. SORTID_STATE_NUM,
  161. SORTID_SWITCHES,
  162. SORTID_TASKS,
  163. /* SORTID_THREADS_MAX, */
  164. /* SORTID_THREADS_MIN, */
  165. SORTID_TIME_ELIGIBLE,
  166. SORTID_TIME_END,
  167. SORTID_TIMELIMIT,
  168. SORTID_TIME_RESIZE,
  169. SORTID_TIME_RUNNING,
  170. SORTID_TIME_START,
  171. SORTID_TIME_SUBMIT,
  172. SORTID_TIME_SUSPEND,
  173. SORTID_SMALL_BLOCK,
  174. SORTID_UPDATED,
  175. SORTID_USER_ID,
  176. SORTID_WCKEY,
  177. SORTID_WORKDIR,
  178. SORTID_CNT
  179. };
  180. /* extra field here is for choosing the type of edit you that will
  181. * take place. If you choose EDIT_MODEL (means only display a set of
  182. * known options) create it in function create_model_*.
  183. */
  184. static char *_initial_page_opts = ("JobID,Partition,BG_Block,"
  185. "ALPS_Resv_ID,UserID,Name,"
  186. "State,Time_Running,Node_Count,NodeList");
  187. static display_data_t display_data_job[] = {
  188. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE, refresh_job,
  189. create_model_job, admin_edit_job},
  190. {G_TYPE_INT, SORTID_JOBID, "JobID", FALSE, EDIT_NONE, refresh_job,
  191. create_model_job, admin_edit_job},
  192. {G_TYPE_STRING, SORTID_COLOR, NULL, TRUE, EDIT_COLOR,
  193. refresh_job, create_model_job, admin_edit_job},
  194. {G_TYPE_STRING, SORTID_ACTION, "Action", FALSE,
  195. EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  196. {G_TYPE_INT, SORTID_ALLOC, NULL, FALSE, EDIT_NONE, refresh_job,
  197. create_model_job, admin_edit_job},
  198. {G_TYPE_STRING, SORTID_PARTITION, "Partition", FALSE,
  199. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  200. #ifdef HAVE_BG
  201. {G_TYPE_STRING, SORTID_BLOCK, "BG Block", FALSE, EDIT_NONE, refresh_job,
  202. create_model_job, admin_edit_job},
  203. {G_TYPE_STRING, SORTID_GEOMETRY, "Geometry",
  204. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  205. {G_TYPE_STRING, SORTID_ROTATE, "Rotate",
  206. FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  207. {G_TYPE_STRING, SORTID_CONNECTION, "Connection",
  208. FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  209. #ifdef HAVE_BGL
  210. {G_TYPE_STRING, SORTID_IMAGE_BLRTS, "Image Blrts",
  211. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  212. {G_TYPE_STRING, SORTID_IMAGE_LINUX, "Image Linux",
  213. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  214. {G_TYPE_STRING, SORTID_IMAGE_RAMDISK, "Image Ramdisk",
  215. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  216. #else
  217. {G_TYPE_STRING, SORTID_IMAGE_BLRTS, NULL,
  218. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  219. {G_TYPE_STRING, SORTID_IMAGE_LINUX, "Image Cnload",
  220. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  221. {G_TYPE_STRING, SORTID_IMAGE_RAMDISK, "Image Ioload",
  222. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  223. #endif
  224. {G_TYPE_STRING, SORTID_IMAGE_MLOADER, "Image Mloader",
  225. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  226. #else
  227. {G_TYPE_STRING, SORTID_BLOCK, NULL, TRUE, EDIT_NONE, refresh_job,
  228. create_model_job, admin_edit_job},
  229. {G_TYPE_STRING, SORTID_GEOMETRY, NULL,
  230. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  231. {G_TYPE_STRING, SORTID_ROTATE, NULL,
  232. FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  233. {G_TYPE_STRING, SORTID_CONNECTION, NULL,
  234. FALSE, EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  235. {G_TYPE_STRING, SORTID_IMAGE_BLRTS, NULL,
  236. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  237. {G_TYPE_STRING, SORTID_IMAGE_LINUX, NULL,
  238. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  239. {G_TYPE_STRING, SORTID_IMAGE_RAMDISK, NULL,
  240. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  241. {G_TYPE_STRING, SORTID_IMAGE_MLOADER, NULL,
  242. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  243. #endif
  244. #ifdef HAVE_CRAY
  245. {G_TYPE_STRING, SORTID_ALPS_RESV_ID, "ALPS Resv ID", FALSE, EDIT_NONE,
  246. refresh_job, create_model_job, admin_edit_job},
  247. #else
  248. {G_TYPE_STRING, SORTID_ALPS_RESV_ID, NULL, TRUE, EDIT_NONE,
  249. refresh_job, create_model_job, admin_edit_job},
  250. #endif
  251. {G_TYPE_STRING, SORTID_USER_ID, "UserID", FALSE, EDIT_NONE,
  252. refresh_job, create_model_job, admin_edit_job},
  253. {G_TYPE_STRING, SORTID_GROUP_ID, "GroupID", FALSE, EDIT_NONE,
  254. refresh_job, create_model_job, admin_edit_job},
  255. {G_TYPE_STRING, SORTID_WCKEY, "WCKey", FALSE, EDIT_TEXTBOX, refresh_job,
  256. create_model_job, admin_edit_job},
  257. {G_TYPE_STRING, SORTID_NAME, "Name", FALSE, EDIT_TEXTBOX, refresh_job,
  258. create_model_job, admin_edit_job},
  259. {G_TYPE_STRING, SORTID_STATE, "State", FALSE, EDIT_NONE, refresh_job,
  260. create_model_job, admin_edit_job},
  261. {G_TYPE_INT, SORTID_STATE_NUM, NULL, FALSE, EDIT_NONE, refresh_job,
  262. create_model_job, admin_edit_job},
  263. {G_TYPE_STRING, SORTID_PREEMPT_TIME, "Preempt Time", FALSE,
  264. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  265. {G_TYPE_STRING, SORTID_TIME_RESIZE, "Time Resize", FALSE,
  266. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  267. {G_TYPE_STRING, SORTID_TIME_RUNNING, "Time Running", FALSE,
  268. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  269. {G_TYPE_STRING, SORTID_TIME_SUBMIT, "Time Submit", FALSE,
  270. EDIT_NONE, refresh_job,
  271. create_model_job, admin_edit_job},
  272. {G_TYPE_STRING, SORTID_TIME_ELIGIBLE, "Time Eligible", FALSE,
  273. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  274. {G_TYPE_STRING, SORTID_TIME_START, "Time Start", FALSE,
  275. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  276. {G_TYPE_STRING, SORTID_TIME_END, "Time End", FALSE,
  277. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  278. {G_TYPE_STRING, SORTID_TIME_SUSPEND, "Time Suspended", FALSE,
  279. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  280. {G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", FALSE,
  281. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  282. {G_TYPE_STRING, SORTID_NODES, "Node Count", FALSE, EDIT_TEXTBOX,
  283. refresh_job, create_model_job, admin_edit_job},
  284. {G_TYPE_STRING, SORTID_CPUS, "CPU Count",
  285. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  286. #ifdef HAVE_BG
  287. {G_TYPE_STRING, SORTID_NODELIST, "MidplaneList", FALSE, EDIT_NONE,
  288. refresh_job, create_model_job, admin_edit_job},
  289. {G_TYPE_STRING, SORTID_NODELIST_EXC, "MidplaneList Excluded",
  290. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  291. {G_TYPE_STRING, SORTID_NODELIST_REQ, "MidplaneList Requested",
  292. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  293. #else
  294. {G_TYPE_STRING, SORTID_NODELIST, "NodeList", FALSE,
  295. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  296. {G_TYPE_STRING, SORTID_NODELIST_EXC, "NodeList Excluded",
  297. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  298. {G_TYPE_STRING, SORTID_NODELIST_REQ, "NodeList Requested",
  299. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  300. #endif
  301. {G_TYPE_STRING, SORTID_CONTIGUOUS, "Contiguous", FALSE, EDIT_MODEL,
  302. refresh_job, create_model_job, admin_edit_job},
  303. {G_TYPE_STRING, SORTID_REQUEUE, "Requeue", FALSE, EDIT_MODEL,
  304. refresh_job, create_model_job, admin_edit_job},
  305. {G_TYPE_INT, SORTID_RESTARTS, "Restart Count", FALSE, EDIT_NONE,
  306. refresh_job, create_model_job, admin_edit_job},
  307. /* Priority is a string so we can edit using a text box */
  308. {G_TYPE_STRING, SORTID_PRIORITY, "Priority", FALSE,
  309. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  310. {G_TYPE_STRING, SORTID_DERIVED_EC, "Derived Exit Code", FALSE,
  311. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  312. {G_TYPE_STRING, SORTID_EXIT_CODE, "Exit Code", FALSE,
  313. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  314. {G_TYPE_STRING, SORTID_BATCH, "Batch Flag", FALSE,
  315. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  316. {G_TYPE_STRING, SORTID_BATCH_HOST, "Batch Host", FALSE,
  317. EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  318. {G_TYPE_STRING, SORTID_CPU_MIN, "CPUs Min",
  319. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  320. {G_TYPE_STRING, SORTID_CPU_MAX, "CPUs Max",
  321. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  322. {G_TYPE_STRING, SORTID_TASKS, "Task Count",
  323. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  324. {G_TYPE_STRING, SORTID_SHARED, "Shared", FALSE,
  325. EDIT_MODEL, refresh_job, create_model_job, admin_edit_job},
  326. {G_TYPE_STRING, SORTID_CPUS_PER_TASK, "CPUs per Task",
  327. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  328. {G_TYPE_STRING, SORTID_RESV_NAME, "Reservation Name",
  329. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  330. {G_TYPE_STRING, SORTID_NODES_MIN, "Nodes Min",
  331. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  332. {G_TYPE_STRING, SORTID_NODES_MAX, "Nodes Max",
  333. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  334. {G_TYPE_STRING, SORTID_CPU_REQ, "Min CPUs Per Node",
  335. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  336. {G_TYPE_STRING, SORTID_MEM_MIN, "Min Memory",
  337. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  338. {G_TYPE_STRING, SORTID_TMP_DISK, "Min Tmp Disk Per Node",
  339. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  340. /* Nice is a string so we can edit using a text box */
  341. {G_TYPE_STRING, SORTID_NICE, "Nice", FALSE,
  342. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  343. {G_TYPE_STRING, SORTID_ACCOUNT, "Account", FALSE,
  344. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  345. {G_TYPE_STRING, SORTID_QOS, "QOS", FALSE,
  346. EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  347. {G_TYPE_STRING, SORTID_REASON, "Reason Waiting",
  348. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  349. {G_TYPE_STRING, SORTID_SWITCHES, "Switches",
  350. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  351. {G_TYPE_STRING, SORTID_FEATURES, "Features",
  352. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  353. {G_TYPE_STRING, SORTID_GRES, "Gres",
  354. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  355. {G_TYPE_STRING, SORTID_LICENSES, "Licenses",
  356. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  357. {G_TYPE_STRING, SORTID_DEPENDENCY, "Dependency",
  358. FALSE, EDIT_TEXTBOX, refresh_job, create_model_job, admin_edit_job},
  359. {G_TYPE_STRING, SORTID_ALLOC_NODE, "Alloc Node : Sid",
  360. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  361. #ifdef HAVE_AIX
  362. {G_TYPE_STRING, SORTID_NETWORK, "Network",
  363. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  364. #else
  365. {G_TYPE_STRING, SORTID_NETWORK, NULL,
  366. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  367. #endif
  368. {G_TYPE_STRING, SORTID_COMMAND, "Command",
  369. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  370. {G_TYPE_STRING, SORTID_COMMENT, "Comment",
  371. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  372. {G_TYPE_STRING, SORTID_WORKDIR, "Work Dir",
  373. FALSE, EDIT_NONE, refresh_job, create_model_job, admin_edit_job},
  374. {G_TYPE_INT, SORTID_COLOR_INX, NULL, FALSE, EDIT_NONE,
  375. refresh_job, create_model_job, admin_edit_job},
  376. {G_TYPE_POINTER, SORTID_NODE_INX, NULL, FALSE, EDIT_NONE,
  377. refresh_job, create_model_job, admin_edit_job},
  378. {G_TYPE_INT, SORTID_SMALL_BLOCK, NULL, FALSE, EDIT_NONE, refresh_job,
  379. create_model_job, admin_edit_job},
  380. {G_TYPE_INT, SORTID_UPDATED, NULL, FALSE, EDIT_NONE, refresh_job,
  381. create_model_job, admin_edit_job},
  382. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  383. };
  384. static display_data_t create_data_job[] = {
  385. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE,
  386. refresh_job, create_model_job, admin_edit_job},
  387. {G_TYPE_STRING, SORTID_COMMAND, "Script File", FALSE, EDIT_TEXTBOX,
  388. refresh_job, create_model_job, admin_edit_job},
  389. {G_TYPE_STRING, SORTID_TIMELIMIT, "Time Limit", FALSE, EDIT_TEXTBOX,
  390. refresh_job, create_model_job, admin_edit_job},
  391. {G_TYPE_STRING, SORTID_NODES_MIN, "Nodes Min", FALSE, EDIT_TEXTBOX,
  392. refresh_job, create_model_job, admin_edit_job},
  393. {G_TYPE_STRING, SORTID_TASKS, "Task Count", FALSE, EDIT_TEXTBOX,
  394. refresh_job, create_model_job, admin_edit_job},
  395. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  396. };
  397. static display_data_t options_data_job[] = {
  398. {G_TYPE_INT, SORTID_POS, NULL, FALSE, EDIT_NONE},
  399. {G_TYPE_STRING, INFO_PAGE, "Full Info", TRUE, JOB_PAGE},
  400. {G_TYPE_STRING, JOB_PAGE, "Signal", TRUE, ADMIN_PAGE},
  401. {G_TYPE_STRING, JOB_PAGE, "Requeue", TRUE, ADMIN_PAGE},
  402. {G_TYPE_STRING, JOB_PAGE, "Cancel", TRUE, ADMIN_PAGE},
  403. {G_TYPE_STRING, JOB_PAGE, "Suspend/Resume", TRUE, ADMIN_PAGE},
  404. {G_TYPE_STRING, JOB_PAGE, "Edit Job", TRUE, ADMIN_PAGE},
  405. {G_TYPE_STRING, PART_PAGE, "Partition", TRUE, JOB_PAGE},
  406. #ifdef HAVE_BG
  407. {G_TYPE_STRING, BLOCK_PAGE, "Block", TRUE, JOB_PAGE},
  408. {G_TYPE_STRING, NODE_PAGE, "Midplanes", TRUE, JOB_PAGE},
  409. #else
  410. {G_TYPE_STRING, BLOCK_PAGE, NULL, TRUE, JOB_PAGE},
  411. {G_TYPE_STRING, NODE_PAGE, "Nodes", TRUE, JOB_PAGE},
  412. #endif
  413. {G_TYPE_STRING, RESV_PAGE, "Reservation", TRUE, JOB_PAGE},
  414. {G_TYPE_NONE, -1, NULL, FALSE, EDIT_NONE}
  415. };
  416. struct signv {
  417. char *name;
  418. uint16_t val;
  419. } sig_name_num[ ] = {
  420. { "HUP", SIGHUP },
  421. { "INT", SIGINT },
  422. { "QUIT", SIGQUIT },
  423. { "ABRT", SIGABRT },
  424. { "KILL", SIGKILL },
  425. { "ALRM", SIGALRM },
  426. { "TERM", SIGTERM },
  427. { "USR1", SIGUSR1 },
  428. { "USR2", SIGUSR2 },
  429. { "CONT", SIGCONT },
  430. { "STOP", SIGSTOP },
  431. { "TSTP", SIGTSTP },
  432. { "TTIN", SIGTTIN },
  433. { "TTOU", SIGTTOU },
  434. { "SIGHUP", SIGHUP },
  435. { "SIGINT", SIGINT },
  436. { "SIGQUIT", SIGQUIT },
  437. { "SIGABRT", SIGABRT },
  438. { "SIGKILL", SIGKILL },
  439. { "SIGALRM", SIGALRM },
  440. { "SIGTERM", SIGTERM },
  441. { "SIGUSR1", SIGUSR1 },
  442. { "SIGUSR2", SIGUSR2 },
  443. { "SIGCONT", SIGCONT },
  444. { "SIGSTOP", SIGSTOP },
  445. { "SIGTSTP", SIGTSTP },
  446. { "SIGTTIN", SIGTTIN },
  447. { "SIGTTOU", SIGTTOU }
  448. };
  449. static display_data_t *local_display_data = NULL;
  450. static char *got_edit_signal = NULL;
  451. static void _update_info_step(sview_job_info_t *sview_job_info_ptr,
  452. GtkTreeModel *model,
  453. GtkTreeIter *step_iter,
  454. GtkTreeIter *iter);
  455. static char *_read_file(const char *f_name)
  456. {
  457. int fd, f_size, offset = 0;
  458. ssize_t rd_size;
  459. struct stat f_stat;
  460. char *buf;
  461. fd = open(f_name, 0);
  462. if (fd < 0)
  463. return NULL;
  464. if (fstat(fd, &f_stat)) {
  465. close(fd);
  466. return NULL;
  467. }
  468. f_size = f_stat.st_size;
  469. buf = xmalloc(f_size);
  470. while (offset < f_size) {
  471. rd_size = read(fd, buf+offset, f_size-offset);
  472. if (rd_size < 0) {
  473. if ((errno == EAGAIN) || (errno == EINTR))
  474. continue;
  475. xfree(buf);
  476. break;
  477. }
  478. offset += rd_size;
  479. }
  480. close(fd);
  481. return buf;
  482. }
  483. static void _job_info_list_del(void *object)
  484. {
  485. sview_job_info_t *sview_job_info = (sview_job_info_t *)object;
  486. if (sview_job_info) {
  487. xfree(sview_job_info->nodes);
  488. if (sview_job_info->step_list)
  489. list_destroy(sview_job_info->step_list);
  490. xfree(sview_job_info);
  491. }
  492. }
  493. static void _destroy_jobs_foreach(void *object)
  494. {
  495. jobs_foreach_t *jobs_foreach = (jobs_foreach_t *)object;
  496. xfree(jobs_foreach);
  497. }
  498. /* translate name name to number */
  499. static uint16_t _xlate_signal_name(const char *signal_name)
  500. {
  501. uint16_t sig_num = (uint16_t)NO_VAL;
  502. char *end_ptr, *sig_names = NULL;
  503. int i;
  504. sig_num = (uint16_t) strtol(signal_name, &end_ptr, 10);
  505. if ((*end_ptr == '\0') && (sig_num != 0))
  506. return sig_num;
  507. for (i=0; i<SIZE(sig_name_num); i++) {
  508. if (strcasecmp(sig_name_num[i].name, signal_name) == 0) {
  509. xfree(sig_names);
  510. return sig_name_num[i].val;
  511. }
  512. if (i == 0)
  513. sig_names = xstrdup(sig_name_num[i].name);
  514. else {
  515. xstrcat(sig_names, ",");
  516. xstrcat(sig_names, sig_name_num[i].name);
  517. }
  518. }
  519. xfree(sig_names);
  520. return (uint16_t)NO_VAL;
  521. }
  522. static int _cancel_job_id (uint32_t job_id, uint16_t signal)
  523. {
  524. int error_code = SLURM_SUCCESS, i;
  525. char *temp = NULL;
  526. if (signal == (uint16_t)-1)
  527. signal = SIGKILL;
  528. for (i = 0; i < MAX_CANCEL_RETRY; i++) {
  529. /* NOTE: RPC always sent to slurmctld rather than directly
  530. * to slurmd daemons */
  531. error_code = slurm_kill_job(job_id, signal, false);
  532. if (error_code == 0
  533. || (errno != ESLURM_TRANSITION_STATE_NO_UPDATE
  534. && errno != ESLURM_JOB_PENDING))
  535. break;
  536. temp = g_strdup_printf("Sending signal %u to job %u",
  537. signal, job_id);
  538. display_edit_note(temp);
  539. g_free(temp);
  540. sleep ( 5 + i );
  541. }
  542. if (error_code) {
  543. error_code = slurm_get_errno();
  544. if ((error_code != ESLURM_ALREADY_DONE) &&
  545. (error_code != ESLURM_INVALID_JOB_ID)) {
  546. temp = g_strdup_printf(
  547. "Kill job error on job id %u: %s",
  548. job_id, slurm_strerror(slurm_get_errno()));
  549. display_edit_note(temp);
  550. g_free(temp);
  551. } else {
  552. display_edit_note(slurm_strerror(slurm_get_errno()));
  553. }
  554. }
  555. return error_code;
  556. }
  557. static int _cancel_step_id(uint32_t job_id, uint32_t step_id,
  558. uint16_t signal)
  559. {
  560. int error_code = SLURM_SUCCESS, i;
  561. char *temp = NULL;
  562. if (signal == (uint16_t)-1)
  563. signal = SIGKILL;
  564. for (i = 0; i < MAX_CANCEL_RETRY; i++) {
  565. /* NOTE: RPC always sent to slurmctld rather than directly
  566. * to slurmd daemons */
  567. if (signal == SIGKILL) {
  568. error_code = slurm_terminate_job_step(job_id, step_id);
  569. } else {
  570. error_code = slurm_kill_job_step(job_id, step_id,
  571. signal);
  572. }
  573. if (error_code == 0
  574. || (errno != ESLURM_TRANSITION_STATE_NO_UPDATE
  575. && errno != ESLURM_JOB_PENDING))
  576. break;
  577. temp = g_strdup_printf("Sending signal %u to job step %u.%u",
  578. signal, job_id, step_id);
  579. display_edit_note(temp);
  580. g_free(temp);
  581. sleep ( 5 + i );
  582. }
  583. if (error_code) {
  584. error_code = slurm_get_errno();
  585. if (error_code != ESLURM_ALREADY_DONE) {
  586. temp = g_strdup_printf(
  587. "Kill job error on job step id %u.%u: %s",
  588. job_id, step_id,
  589. slurm_strerror(slurm_get_errno()));
  590. display_edit_note(temp);
  591. g_free(temp);
  592. } else {
  593. display_edit_note(slurm_strerror(slurm_get_errno()));
  594. }
  595. }
  596. return error_code;
  597. }
  598. static void _set_active_combo_job(GtkComboBox *combo,
  599. GtkTreeModel *model, GtkTreeIter *iter,
  600. int type)
  601. {
  602. char *temp_char = NULL;
  603. int action = 0;
  604. if (model)
  605. gtk_tree_model_get(model, iter, type, &temp_char, -1);
  606. if (!temp_char)
  607. goto end_it;
  608. switch(type) {
  609. case SORTID_ACTION:
  610. if (!strcasecmp(temp_char, "None"))
  611. action = 0;
  612. else if (!strcasecmp(temp_char, "Cancel"))
  613. action = 1;
  614. else if (!strcasecmp(temp_char, "Suspend"))
  615. action = 2;
  616. else if (!strcasecmp(temp_char, "Resume"))
  617. action = 3;
  618. else if (!strcasecmp(temp_char, "Checkpoint"))
  619. action = 4;
  620. else if (!strcasecmp(temp_char, "Requeue"))
  621. action = 5;
  622. else
  623. action = 0;
  624. break;
  625. case SORTID_SHARED:
  626. case SORTID_CONTIGUOUS:
  627. case SORTID_REQUEUE:
  628. case SORTID_ROTATE:
  629. if (!strcasecmp(temp_char, "yes"))
  630. action = 0;
  631. else if (!strcasecmp(temp_char, "no"))
  632. action = 1;
  633. else
  634. action = 0;
  635. break;
  636. case SORTID_CONNECTION:
  637. if (!strcasecmp(temp_char, "Torus"))
  638. action = 0;
  639. else if (!strcasecmp(temp_char, "Mesh"))
  640. action = 1;
  641. else if (!strcasecmp(temp_char, "NAV"))
  642. action = 2;
  643. else if (!strcasecmp(temp_char, "HTC_S"))
  644. action = 3;
  645. else if (!strcasecmp(temp_char, "HTC_D"))
  646. action = 4;
  647. else if (!strcasecmp(temp_char, "HTC_V"))
  648. action = 5;
  649. else if (!strcasecmp(temp_char, "HTC_L"))
  650. action = 6;
  651. else
  652. action = 0;
  653. break;
  654. default:
  655. break;
  656. }
  657. g_free(temp_char);
  658. end_it:
  659. gtk_combo_box_set_active(combo, action);
  660. }
  661. /* don't free this char */
  662. static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text,
  663. int column)
  664. {
  665. char *type = "";
  666. int temp_int = 0;
  667. char *p;
  668. uint16_t rotate;
  669. uint16_t conn_type[cluster_dims];
  670. char* token, *delimiter = ",x", *next_ptr;
  671. char *sep_char;
  672. int j;
  673. uint16_t geo[cluster_dims];
  674. char* geometry_tmp = xstrdup(new_text);
  675. char* original_ptr = geometry_tmp;
  676. /* need to clear global_edit_error here (just in case) */
  677. global_edit_error = 0;
  678. if (!job_msg)
  679. return NULL;
  680. switch(column) {
  681. case SORTID_ACTION:
  682. xfree(got_edit_signal);
  683. if (!strcasecmp(new_text, "None"))
  684. got_edit_signal = NULL;
  685. else
  686. got_edit_signal = xstrdup(new_text);
  687. break;
  688. case SORTID_TIMELIMIT:
  689. if (!strcasecmp(new_text, "infinite"))
  690. temp_int = INFINITE;
  691. else
  692. temp_int = time_str2mins((char *)new_text);
  693. type = "timelimit";
  694. if (temp_int <= 0 && temp_int != INFINITE)
  695. goto return_error;
  696. job_msg->time_limit = (uint32_t)temp_int;
  697. break;
  698. case SORTID_PRIORITY:
  699. if (!strcasecmp(new_text, "infinite"))
  700. temp_int = INFINITE;
  701. else
  702. temp_int = strtol(new_text, (char **)NULL, 10);
  703. type = "priority";
  704. if ((temp_int < 0) && (temp_int != INFINITE))
  705. goto return_error;
  706. job_msg->priority = (uint32_t)temp_int;
  707. break;
  708. case SORTID_NICE:
  709. temp_int = strtol(new_text, (char **)NULL, 10);
  710. type = "nice";
  711. if (abs(temp_int) > NICE_OFFSET) {
  712. //error("Invalid nice value, must be between "
  713. // "-%d and %d", NICE_OFFSET, NICE_OFFSET);
  714. goto return_error;
  715. }
  716. job_msg->nice = NICE_OFFSET + temp_int;
  717. break;
  718. case SORTID_CPU_REQ:
  719. temp_int = strtol(new_text, &p, 10);
  720. if (*p == 'k' || *p == 'K')
  721. temp_int *= 1024;
  722. else if (*p == 'm' || *p == 'M')
  723. temp_int *= 1048576;
  724. type = "min cpus per node";
  725. if (temp_int <= 0)
  726. goto return_error;
  727. job_msg->pn_min_cpus = (uint32_t)temp_int;
  728. break;
  729. case SORTID_TASKS:
  730. temp_int = strtol(new_text, (char **)NULL, 10);
  731. type = "requested tasks";
  732. if (temp_int <= 0)
  733. goto return_error;
  734. job_msg->num_tasks = (uint32_t)temp_int;
  735. break;
  736. case SORTID_CPUS_PER_TASK:
  737. temp_int = strtol(new_text, (char **)NULL, 10);
  738. type = "cpus per task";
  739. if (temp_int <= 0)
  740. goto return_error;
  741. job_msg->cpus_per_task = (uint32_t)temp_int;
  742. break;
  743. case SORTID_RESV_NAME:
  744. job_msg->reservation = xstrdup(new_text);
  745. type = "reservation name";
  746. break;
  747. case SORTID_NODES_MIN:
  748. temp_int = strtol(new_text, &p, 10);
  749. if (*p == 'k' || *p == 'K')
  750. temp_int *= 1024;
  751. else if (*p == 'm' || *p == 'M')
  752. temp_int *= 1048576;
  753. type = "min nodes";
  754. if (temp_int <= 0)
  755. goto return_error;
  756. job_msg->min_nodes = (uint32_t)temp_int;
  757. break;
  758. case SORTID_NODES:
  759. temp_int = strtol(new_text, &p, 10);
  760. if (*p == 'k' || *p == 'K')
  761. temp_int *= 1024;
  762. else if (*p == 'm' || *p == 'M')
  763. temp_int *= 1048576;
  764. type = "node count";
  765. if (temp_int <= 0)
  766. goto return_error;
  767. job_msg->min_nodes = job_msg->max_nodes = (uint32_t)temp_int;
  768. break;
  769. case SORTID_NODES_MAX:
  770. temp_int = strtol(new_text, &p, 10);
  771. if (*p == 'k' || *p == 'K')
  772. temp_int *= 1024;
  773. else if (*p == 'm' || *p == 'M')
  774. temp_int *= 1048576;
  775. type = "max nodes";
  776. if (temp_int <= 0)
  777. goto return_error;
  778. if (cluster_flags & CLUSTER_FLAG_BG)
  779. /* this needs to be set up for correct functionality */
  780. if (job_msg->min_nodes == NO_VAL)
  781. job_msg->min_nodes = (uint32_t)temp_int;
  782. job_msg->max_nodes = (uint32_t)temp_int;
  783. break;
  784. case SORTID_MEM_MIN:
  785. temp_int = strtol(new_text, &p, 10);
  786. if (*p == 'g' || *p == 'G')
  787. temp_int *= 1024;
  788. else if (*p == 't' || *p == 'T')
  789. temp_int *= 1048576;
  790. p = slurm_strcasestr((char *)new_text, "cpu");
  791. if (p)
  792. type = "min memory per cpu";
  793. else
  794. type = "min memory per node";
  795. if (temp_int <= 0)
  796. goto return_error;
  797. job_msg->pn_min_memory = (uint32_t)temp_int;
  798. if (p)
  799. job_msg->pn_min_memory |= MEM_PER_CPU;
  800. break;
  801. case SORTID_TMP_DISK:
  802. temp_int = strtol(new_text, &p, 10);
  803. if (*p == 'g' || *p == 'G')
  804. temp_int *= 1024;
  805. else if (*p == 't' || *p == 'T')
  806. temp_int *= 1048576;
  807. type = "min tmp disk per node";
  808. if (temp_int <= 0)
  809. goto return_error;
  810. job_msg->pn_min_tmp_disk = (uint32_t)temp_int;
  811. break;
  812. case SORTID_PARTITION:
  813. job_msg->partition = xstrdup(new_text);
  814. type = "partition";
  815. break;
  816. case SORTID_NAME:
  817. job_msg->name = xstrdup(new_text);
  818. type = "name";
  819. break;
  820. case SORTID_WCKEY:
  821. job_msg->wckey = xstrdup(new_text);
  822. type = "wckey";
  823. break;
  824. case SORTID_SHARED:
  825. if (!strcasecmp(new_text, "yes"))
  826. job_msg->shared = 1;
  827. else
  828. job_msg->shared = 0;
  829. type = "shared";
  830. break;
  831. case SORTID_CONTIGUOUS:
  832. if (!strcasecmp(new_text, "yes"))
  833. job_msg->contiguous = 1;
  834. else
  835. job_msg->contiguous = 0;
  836. type = "contiguous";
  837. break;
  838. case SORTID_REQUEUE:
  839. if (!strcasecmp(new_text, "yes"))
  840. job_msg->requeue = 1;
  841. else
  842. job_msg->requeue = 0;
  843. type = "requeue";
  844. break;
  845. case SORTID_NODELIST_REQ:
  846. job_msg->req_nodes = xstrdup(new_text);
  847. type = "requested nodelist";
  848. break;
  849. case SORTID_NODELIST_EXC:
  850. job_msg->exc_nodes = xstrdup(new_text);
  851. type = "excluded nodelist";
  852. break;
  853. case SORTID_FEATURES:
  854. job_msg->features = xstrdup(new_text);
  855. type = "features";
  856. break;
  857. case SORTID_GRES:
  858. job_msg->gres = xstrdup(new_text);
  859. type = "gres";
  860. break;
  861. case SORTID_LICENSES:
  862. job_msg->licenses = xstrdup(new_text);
  863. type = "licenses";
  864. break;
  865. case SORTID_ACCOUNT:
  866. job_msg->account = xstrdup(new_text);
  867. type = "account";
  868. break;
  869. case SORTID_QOS:
  870. job_msg->qos = xstrdup(new_text);
  871. type = "qos";
  872. break;
  873. case SORTID_COMMAND:
  874. type = "script_file";
  875. xfree(job_msg->script);
  876. job_msg->script = _read_file(new_text);
  877. if (job_msg->script == NULL)
  878. goto return_error;
  879. if (job_msg->argc) {
  880. for (j = 0; j < job_msg->argc; j++)
  881. xfree(job_msg->argv[j]);
  882. }
  883. xfree(job_msg->argv);
  884. xfree(job_msg->name);
  885. job_msg->argc = 1;
  886. job_msg->argv = xmalloc(sizeof(char *) * job_msg->argc);
  887. if (new_text[0] == '/') {
  888. job_msg->argv[0] = xstrdup(new_text);
  889. token = strrchr(new_text, (int) '/');
  890. if (token)
  891. job_msg->name = xstrdup(token + 1);
  892. } else {
  893. job_msg->argv[0] = xmalloc(1024);
  894. if (!getcwd(job_msg->argv[0], 1024))
  895. goto return_error;
  896. xstrcat(job_msg->argv[0], "/");
  897. xstrcat(job_msg->argv[0], new_text);
  898. job_msg->name = xstrdup(new_text);
  899. }
  900. break;
  901. case SORTID_DEPENDENCY:
  902. job_msg->dependency = xstrdup(new_text);
  903. type = "dependency";
  904. break;
  905. case SORTID_GEOMETRY:
  906. type = "geometry";
  907. token = strtok_r(geometry_tmp, delimiter, &next_ptr);
  908. for (j=0; j<cluster_dims; j++)
  909. geo[j] = (uint16_t) NO_VAL;
  910. for (j=0; j<cluster_dims; j++) {
  911. if (!token) {
  912. //error("insufficient dimensions in "
  913. // "Geometry");
  914. goto return_error;
  915. }
  916. geo[j] = (uint16_t) atoi(token);
  917. if (geo[j] <= 0) {
  918. //error("invalid --geometry argument");
  919. goto return_error;
  920. break;
  921. }
  922. geometry_tmp = next_ptr;
  923. token = strtok_r(geometry_tmp, delimiter,
  924. &next_ptr);
  925. }
  926. if (token) {
  927. //error("too many dimensions in Geometry");
  928. goto return_error;
  929. }
  930. if (!job_msg->select_jobinfo)
  931. job_msg->select_jobinfo
  932. = select_g_select_jobinfo_alloc();
  933. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  934. SELECT_JOBDATA_GEOMETRY,
  935. (void *) &geo);
  936. break;
  937. case SORTID_ROTATE:
  938. type = "rotate";
  939. if (!strcasecmp(new_text, "yes")) {
  940. rotate = 1;
  941. } else {
  942. rotate = 0;
  943. }
  944. if (!job_msg->select_jobinfo)
  945. job_msg->select_jobinfo
  946. = select_g_select_jobinfo_alloc();
  947. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  948. SELECT_JOBDATA_ROTATE,
  949. (void *) &rotate);
  950. break;
  951. case SORTID_CONNECTION:
  952. verify_conn_type(new_text, conn_type);
  953. type = "connection";
  954. if (!job_msg->select_jobinfo)
  955. job_msg->select_jobinfo
  956. = select_g_select_jobinfo_alloc();
  957. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  958. SELECT_JOBDATA_CONN_TYPE,
  959. (void *) &conn_type);
  960. break;
  961. case SORTID_IMAGE_BLRTS:
  962. type = "BlrtsImage";
  963. if (!job_msg->select_jobinfo)
  964. job_msg->select_jobinfo
  965. = select_g_select_jobinfo_alloc();
  966. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  967. SELECT_JOBDATA_BLRTS_IMAGE,
  968. (void *) new_text);
  969. break;
  970. case SORTID_IMAGE_LINUX:
  971. if (cluster_flags & CLUSTER_FLAG_BGL)
  972. type = "LinuxImage";
  973. else
  974. type = "CnloadImage";
  975. if (!job_msg->select_jobinfo)
  976. job_msg->select_jobinfo
  977. = select_g_select_jobinfo_alloc();
  978. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  979. SELECT_JOBDATA_LINUX_IMAGE,
  980. (void *) new_text);
  981. break;
  982. case SORTID_IMAGE_MLOADER:
  983. type = "MloaderImage";
  984. if (!job_msg->select_jobinfo)
  985. job_msg->select_jobinfo
  986. = select_g_select_jobinfo_alloc();
  987. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  988. SELECT_JOBDATA_MLOADER_IMAGE,
  989. (void *) new_text);
  990. break;
  991. case SORTID_IMAGE_RAMDISK:
  992. if (cluster_flags & CLUSTER_FLAG_BGL)
  993. type = "RamdiskImage";
  994. else
  995. type = "IoloadImage";
  996. if (!job_msg->select_jobinfo)
  997. job_msg->select_jobinfo
  998. = select_g_select_jobinfo_alloc();
  999. select_g_select_jobinfo_set(job_msg->select_jobinfo,
  1000. SELECT_JOBDATA_RAMDISK_IMAGE,
  1001. (void *) new_text);
  1002. break;
  1003. case SORTID_TIME_ELIGIBLE:
  1004. case SORTID_TIME_START:
  1005. type = "start time";
  1006. job_msg->begin_time = parse_time((char *)new_text, 0);
  1007. if (!job_msg->begin_time)
  1008. goto return_error;
  1009. if (job_msg->begin_time < time(NULL))
  1010. job_msg->begin_time = time(NULL);
  1011. break;
  1012. case SORTID_SWITCHES:
  1013. type = "switches";
  1014. job_msg->req_switch =
  1015. (uint32_t) strtol(new_text, &sep_char, 10);
  1016. if (sep_char && sep_char[0] == '@') {
  1017. job_msg->wait4switch = time_str2mins(sep_char+1) * 60;
  1018. }
  1019. break;
  1020. default:
  1021. type = "unknown";
  1022. break;
  1023. }
  1024. if (strcmp(type, "unknown"))
  1025. global_send_update_msg = 1;
  1026. xfree(original_ptr);
  1027. return type;
  1028. return_error:
  1029. xfree(original_ptr);
  1030. global_edit_error = 1;
  1031. return type;
  1032. }
  1033. static void _admin_edit_combo_box_job(GtkComboBox *combo,
  1034. job_desc_msg_t *job_msg)
  1035. {
  1036. GtkTreeModel *model = NULL;
  1037. GtkTreeIter iter;
  1038. int column = 0;
  1039. char *name = NULL;
  1040. if (!job_msg)
  1041. return;
  1042. if (!gtk_combo_box_get_active_iter(combo, &iter)) {
  1043. g_print("nothing selected\n");
  1044. return;
  1045. }
  1046. model = gtk_combo_box_get_model(combo);
  1047. if (!model) {
  1048. g_print("nothing selected\n");
  1049. return;
  1050. }
  1051. gtk_tree_model_get(model, &iter, 0, &name, -1);
  1052. gtk_tree_model_get(model, &iter, 1, &column, -1);
  1053. _set_job_msg(job_msg, name, column);
  1054. g_free(name);
  1055. }
  1056. static gboolean _admin_focus_out_job(GtkEntry *entry,
  1057. GdkEventFocus *event,
  1058. job_desc_msg_t *job_msg)
  1059. {
  1060. if (global_entry_changed) {
  1061. const char *col_name = NULL;
  1062. int type = gtk_entry_get_max_length(entry);
  1063. const char *name = gtk_entry_get_text(entry);
  1064. type -= DEFAULT_ENTRY_LENGTH;
  1065. col_name = _set_job_msg(job_msg, name, type);
  1066. if (global_edit_error) {
  1067. if (global_edit_error_msg)
  1068. g_free(global_edit_error_msg);
  1069. global_edit_error_msg = g_strdup_printf(
  1070. "Job %d %s can't be set to %s",
  1071. job_msg->job_id,
  1072. col_name,
  1073. name);
  1074. }
  1075. global_entry_changed = 0;
  1076. }
  1077. return false;
  1078. }
  1079. static GtkWidget *_admin_full_edit_job(job_desc_msg_t *job_msg,
  1080. GtkTreeModel *model, GtkTreeIter *iter)
  1081. {
  1082. GtkScrolledWindow *window = create_scrolled_window();
  1083. GtkBin *bin = NULL;
  1084. GtkViewport *view = NULL;
  1085. GtkTable *table = NULL;
  1086. int i = 0, row = 0;
  1087. display_data_t *display_data = display_data_job;
  1088. gtk_scrolled_window_set_policy(window,
  1089. GTK_POLICY_NEVER,
  1090. GTK_POLICY_AUTOMATIC);
  1091. bin = GTK_BIN(&window->container);
  1092. view = GTK_VIEWPORT(bin->child);
  1093. bin = GTK_BIN(&view->bin);
  1094. table = GTK_TABLE(bin->child);
  1095. gtk_table_resize(table, SORTID_CNT, 2);
  1096. gtk_table_set_homogeneous(table, FALSE);
  1097. for(i = 0; i < SORTID_CNT; i++) {
  1098. while (display_data++) {
  1099. if (display_data->id == -1)
  1100. break;
  1101. if (!display_data->name)
  1102. continue;
  1103. if (display_data->id != i)
  1104. continue;
  1105. display_admin_edit(
  1106. table, job_msg, &row, model, iter,
  1107. display_data,
  1108. G_CALLBACK(_admin_edit_combo_box_job),
  1109. G_CALLBACK(_admin_focus_out_job),
  1110. _set_active_combo_job);
  1111. break;
  1112. }
  1113. display_data = display_data_job;
  1114. }
  1115. gtk_table_resize(table, row, 2);
  1116. return GTK_WIDGET(window);
  1117. }
  1118. static int _nodes_in_list(char *node_list)
  1119. {
  1120. hostset_t host_set = hostset_create(node_list);
  1121. int count = hostset_count(host_set);
  1122. hostset_destroy(host_set);
  1123. return count;
  1124. }
  1125. static int _get_node_cnt(job_info_t * job)
  1126. {
  1127. int node_cnt = 0;
  1128. /* For PENDING jobs, return the maximum of the requested nodelist,
  1129. * requested maximum number of nodes, or requested CPUs rounded
  1130. * to nearest node.
  1131. *
  1132. * For COMPLETING jobs, the job->nodes nodelist has already been
  1133. * altered to list only the nodes still in the comp state, and
  1134. * thus we count only those nodes toward the total nodes still
  1135. * allocated to this job.
  1136. */
  1137. if (IS_JOB_PENDING(job)) {
  1138. node_cnt = _nodes_in_list(job->req_nodes);
  1139. node_cnt = MAX(node_cnt, job->num_nodes);
  1140. } else
  1141. node_cnt = _nodes_in_list(job->nodes);
  1142. return node_cnt;
  1143. }
  1144. /* this needs to be freed by xfree() */
  1145. static void _convert_char_to_job_and_step(const char *data,
  1146. int *jobid, int *stepid)
  1147. {
  1148. int i = 0;
  1149. if (!data)
  1150. return;
  1151. *jobid = atoi(data);
  1152. *stepid = NO_VAL;
  1153. while (data[i]) {
  1154. if (data[i] == '.') {
  1155. i++;
  1156. if (data[i])
  1157. *stepid = atoi(&data[i]);
  1158. break;
  1159. }
  1160. i++;
  1161. }
  1162. return;
  1163. }
  1164. static void _layout_job_record(GtkTreeView *treeview,
  1165. sview_job_info_t *sview_job_info_ptr,
  1166. int update)
  1167. {
  1168. char *nodes = NULL, *reason = NULL, *uname = NULL;
  1169. char tmp_char[50];
  1170. char time_buf[32];
  1171. char running_char[50];
  1172. time_t now_time = time(NULL);
  1173. int suspend_secs = 0;
  1174. job_info_t *job_ptr = sview_job_info_ptr->job_ptr;
  1175. struct group *group_info = NULL;
  1176. uint16_t term_sig = 0;
  1177. uint32_t min_mem = 0;
  1178. GtkTreeIter iter;
  1179. GtkTreeStore *treestore =
  1180. GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
  1181. if (!treestore)
  1182. return;
  1183. if (!job_ptr->nodes || !strcasecmp(job_ptr->nodes,"waiting...")) {
  1184. sprintf(running_char,"00:00:00");
  1185. nodes = "waiting...";
  1186. } else {
  1187. if (IS_JOB_SUSPENDED(job_ptr))
  1188. now_time = job_ptr->pre_sus_time;
  1189. else {
  1190. if (!IS_JOB_RUNNING(job_ptr) &&
  1191. (job_ptr->end_time != 0))
  1192. now_time = job_ptr->end_time;
  1193. if (job_ptr->suspend_time) {
  1194. now_time = (time_t)
  1195. (difftime(now_time,
  1196. job_ptr->suspend_time)
  1197. + job_ptr->pre_sus_time);
  1198. } else
  1199. now_time = (time_t)difftime(
  1200. now_time, job_ptr->start_time);
  1201. }
  1202. suspend_secs = (time(NULL) - job_ptr->start_time) - now_time;
  1203. secs2time_str(now_time, running_char, sizeof(running_char));
  1204. nodes = sview_job_info_ptr->nodes;
  1205. }
  1206. add_display_treestore_line(update, treestore, &iter,
  1207. find_col_name(display_data_job,
  1208. SORTID_ACCOUNT),
  1209. job_ptr->account);
  1210. snprintf(tmp_char, sizeof(tmp_char), "%s:%u",
  1211. job_ptr->alloc_node, job_ptr->alloc_sid);
  1212. add_display_treestore_line(update, treestore, &iter,
  1213. find_col_name(display_data_job,
  1214. SORTID_ALLOC_NODE),
  1215. tmp_char);
  1216. if (cluster_flags & CLUSTER_FLAG_CRAYXT)
  1217. add_display_treestore_line(update, treestore, &iter,
  1218. find_col_name(display_data_job,
  1219. SORTID_ALPS_RESV_ID),
  1220. select_g_select_jobinfo_sprint(
  1221. job_ptr->select_jobinfo,
  1222. tmp_char,
  1223. sizeof(tmp_char),
  1224. SELECT_PRINT_DATA));
  1225. if (job_ptr->batch_flag)
  1226. sprintf(tmp_char, "yes");
  1227. else
  1228. sprintf(tmp_char, "no");
  1229. add_display_treestore_line(update, treestore, &iter,
  1230. find_col_name(display_data_job,
  1231. SORTID_BATCH),
  1232. tmp_char);
  1233. add_display_treestore_line(update, treestore, &iter,
  1234. find_col_name(display_data_job,
  1235. SORTID_BATCH_HOST),
  1236. job_ptr->batch_host);
  1237. if (cluster_flags & CLUSTER_FLAG_BG) {
  1238. add_display_treestore_line(update, treestore, &iter,
  1239. find_col_name(display_data_job,
  1240. SORTID_NODELIST),
  1241. nodes);
  1242. add_display_treestore_line(update, treestore, &iter,
  1243. find_col_name(display_data_job,
  1244. SORTID_NODELIST_EXC),
  1245. job_ptr->exc_nodes);
  1246. add_display_treestore_line(update, treestore, &iter,
  1247. find_col_name(display_data_job,
  1248. SORTID_NODELIST_REQ),
  1249. job_ptr->req_nodes);
  1250. add_display_treestore_line(update, treestore, &iter,
  1251. find_col_name(display_data_job,
  1252. SORTID_BLOCK),
  1253. select_g_select_jobinfo_sprint(
  1254. job_ptr->select_jobinfo,
  1255. tmp_char,
  1256. sizeof(tmp_char),
  1257. SELECT_PRINT_BG_ID));
  1258. }
  1259. add_display_treestore_line(update, treestore, &iter,
  1260. find_col_name(display_data_job,
  1261. SORTID_COMMAND),
  1262. job_ptr->command);
  1263. add_display_treestore_line(update, treestore, &iter,
  1264. find_col_name(display_data_job,
  1265. SORTID_COMMENT),
  1266. job_ptr->comment);
  1267. if (cluster_flags & CLUSTER_FLAG_BG)
  1268. add_display_treestore_line(update, treestore, &iter,
  1269. find_col_name(display_data_job,
  1270. SORTID_CONNECTION),
  1271. select_g_select_jobinfo_sprint(
  1272. job_ptr->select_jobinfo,
  1273. tmp_char,
  1274. sizeof(tmp_char),
  1275. SELECT_PRINT_CONNECTION));
  1276. if (job_ptr->contiguous)
  1277. sprintf(tmp_char, "yes");
  1278. else
  1279. sprintf(tmp_char, "no");
  1280. add_display_treestore_line(update, treestore, &iter,
  1281. find_col_name(display_data_job,
  1282. SORTID_CONTIGUOUS),
  1283. tmp_char);
  1284. if (cluster_flags & CLUSTER_FLAG_BG)
  1285. convert_num_unit((float)job_ptr->num_cpus,
  1286. tmp_char, sizeof(tmp_char),
  1287. UNIT_NONE);
  1288. else
  1289. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->num_cpus);
  1290. add_display_treestore_line(update, treestore, &iter,
  1291. find_col_name(display_data_job,
  1292. SORTID_CPUS),
  1293. tmp_char);
  1294. if (cluster_flags & CLUSTER_FLAG_BG)
  1295. convert_num_unit((float)job_ptr->max_cpus,
  1296. tmp_char, sizeof(tmp_char),
  1297. UNIT_NONE);
  1298. else
  1299. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->max_cpus);
  1300. add_display_treestore_line(update, treestore, &iter,
  1301. find_col_name(display_data_job,
  1302. SORTID_CPU_MAX),
  1303. tmp_char);
  1304. if (cluster_flags & CLUSTER_FLAG_BG)
  1305. convert_num_unit((float)job_ptr->num_cpus,
  1306. tmp_char, sizeof(tmp_char),
  1307. UNIT_NONE);
  1308. else
  1309. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->num_cpus);
  1310. add_display_treestore_line(update, treestore, &iter,
  1311. find_col_name(display_data_job,
  1312. SORTID_CPU_MIN),
  1313. tmp_char);
  1314. if (job_ptr->cpus_per_task > 0)
  1315. sprintf(tmp_char, "%u", job_ptr->cpus_per_task);
  1316. else
  1317. sprintf(tmp_char, " ");
  1318. add_display_treestore_line(update, treestore, &iter,
  1319. find_col_name(display_data_job,
  1320. SORTID_CPUS_PER_TASK),
  1321. tmp_char);
  1322. add_display_treestore_line(update, treestore, &iter,
  1323. find_col_name(display_data_job,
  1324. SORTID_DEPENDENCY),
  1325. job_ptr->dependency);
  1326. if (WIFSIGNALED(job_ptr->derived_ec))
  1327. term_sig = WTERMSIG(job_ptr->derived_ec);
  1328. snprintf(tmp_char, sizeof(tmp_char), "%u:%u",
  1329. WEXITSTATUS(job_ptr->derived_ec), term_sig);
  1330. add_display_treestore_line(update, treestore, &iter,
  1331. find_col_name(display_data_job,
  1332. SORTID_DERIVED_EC),
  1333. tmp_char);
  1334. if (WIFSIGNALED(job_ptr->exit_code))
  1335. term_sig = WTERMSIG(job_ptr->exit_code);
  1336. else
  1337. term_sig = 0;
  1338. snprintf(tmp_char, sizeof(tmp_char), "%u:%u",
  1339. WEXITSTATUS(job_ptr->exit_code), term_sig);
  1340. add_display_treestore_line(update, treestore, &iter,
  1341. find_col_name(display_data_job,
  1342. SORTID_EXIT_CODE),
  1343. tmp_char);
  1344. add_display_treestore_line(update, treestore, &iter,
  1345. find_col_name(display_data_job,
  1346. SORTID_FEATURES),
  1347. job_ptr->features);
  1348. add_display_treestore_line(update, treestore, &iter,
  1349. find_col_name(display_data_job,
  1350. SORTID_GRES),
  1351. job_ptr->gres);
  1352. if (cluster_flags & CLUSTER_FLAG_BG)
  1353. add_display_treestore_line(update, treestore, &iter,
  1354. find_col_name(display_data_job,
  1355. SORTID_GEOMETRY),
  1356. select_g_select_jobinfo_sprint(
  1357. job_ptr->select_jobinfo,
  1358. tmp_char,
  1359. sizeof(tmp_char),
  1360. SELECT_PRINT_GEOMETRY));
  1361. group_info = getgrgid((gid_t)job_ptr->group_id);
  1362. if (group_info && group_info->gr_name[0])
  1363. snprintf(tmp_char, sizeof(tmp_char), "%s", group_info->gr_name);
  1364. else
  1365. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->group_id);
  1366. add_display_treestore_line(update, treestore, &iter,
  1367. find_col_name(display_data_job,
  1368. SORTID_GROUP_ID),
  1369. tmp_char);
  1370. if (cluster_flags & CLUSTER_FLAG_BG) {
  1371. if (cluster_flags & CLUSTER_FLAG_BGL)
  1372. add_display_treestore_line(
  1373. update, treestore, &iter,
  1374. find_col_name(display_data_job,
  1375. SORTID_IMAGE_BLRTS),
  1376. select_g_select_jobinfo_sprint(
  1377. job_ptr->select_jobinfo,
  1378. tmp_char,
  1379. sizeof(tmp_char),
  1380. SELECT_PRINT_BLRTS_IMAGE));
  1381. add_display_treestore_line(update, treestore, &iter,
  1382. find_col_name(display_data_job,
  1383. SORTID_IMAGE_LINUX),
  1384. select_g_select_jobinfo_sprint(
  1385. job_ptr->select_jobinfo,
  1386. tmp_char,
  1387. sizeof(tmp_char),
  1388. SELECT_PRINT_LINUX_IMAGE));
  1389. add_display_treestore_line(update, treestore, &iter,
  1390. find_col_name(display_data_job,
  1391. SORTID_IMAGE_MLOADER),
  1392. select_g_select_jobinfo_sprint(
  1393. job_ptr->select_jobinfo,
  1394. tmp_char,
  1395. sizeof(tmp_char),
  1396. SELECT_PRINT_MLOADER_IMAGE));
  1397. add_display_treestore_line(update, treestore, &iter,
  1398. find_col_name(display_data_job,
  1399. SORTID_IMAGE_RAMDISK),
  1400. select_g_select_jobinfo_sprint(
  1401. job_ptr->select_jobinfo,
  1402. tmp_char,
  1403. sizeof(tmp_char),
  1404. SELECT_PRINT_RAMDISK_IMAGE));
  1405. }
  1406. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->job_id);
  1407. add_display_treestore_line(update, treestore, &iter,
  1408. find_col_name(display_data_job,
  1409. SORTID_JOBID),
  1410. tmp_char);
  1411. add_display_treestore_line(update, treestore, &iter,
  1412. find_col_name(display_data_job,
  1413. SORTID_LICENSES),
  1414. job_ptr->licenses);
  1415. convert_num_unit((float)job_ptr->pn_min_cpus,
  1416. tmp_char, sizeof(tmp_char), UNIT_NONE);
  1417. add_display_treestore_line(update, treestore, &iter,
  1418. find_col_name(display_data_job,
  1419. SORTID_CPU_REQ),
  1420. tmp_char);
  1421. min_mem = job_ptr->pn_min_memory;
  1422. if (min_mem & MEM_PER_CPU)
  1423. min_mem &= (~MEM_PER_CPU);
  1424. if (min_mem > 0) {
  1425. int len;
  1426. convert_num_unit((float)min_mem,
  1427. tmp_char, sizeof(tmp_char), UNIT_MEGA);
  1428. len = strlen(tmp_char);
  1429. if (job_ptr->pn_min_memory & MEM_PER_CPU)
  1430. sprintf(tmp_char+len, " Per CPU");
  1431. else
  1432. sprintf(tmp_char+len, " Per Node");
  1433. } else
  1434. sprintf(tmp_char, " ");
  1435. add_display_treestore_line(update, treestore, &iter,
  1436. find_col_name(display_data_job,
  1437. SORTID_MEM_MIN),
  1438. tmp_char);
  1439. if (job_ptr->pn_min_tmp_disk > 0)
  1440. convert_num_unit((float)job_ptr->pn_min_tmp_disk,
  1441. tmp_char, sizeof(tmp_char), UNIT_MEGA);
  1442. else
  1443. sprintf(tmp_char, " ");
  1444. add_display_treestore_line(update, treestore, &iter,
  1445. find_col_name(display_data_job,
  1446. SORTID_TMP_DISK),
  1447. tmp_char);
  1448. add_display_treestore_line(update, treestore, &iter,
  1449. find_col_name(display_data_job,
  1450. SORTID_NAME),
  1451. job_ptr->name);
  1452. if (cluster_flags & CLUSTER_FLAG_AIX)
  1453. add_display_treestore_line(update, treestore, &iter,
  1454. find_col_name(display_data_job,
  1455. SORTID_NETWORK),
  1456. job_ptr->network);
  1457. if (job_ptr->nice > 0)
  1458. sprintf(tmp_char, "%u", job_ptr->nice - NICE_OFFSET);
  1459. else
  1460. sprintf(tmp_char, " ");
  1461. add_display_treestore_line(update, treestore, &iter,
  1462. find_col_name(display_data_job,
  1463. SORTID_NICE),
  1464. tmp_char);
  1465. if (!(cluster_flags & CLUSTER_FLAG_BG)) {
  1466. add_display_treestore_line(update, treestore, &iter,
  1467. find_col_name(display_data_job,
  1468. SORTID_NODELIST),
  1469. nodes);
  1470. add_display_treestore_line(update, treestore, &iter,
  1471. find_col_name(display_data_job,
  1472. SORTID_NODELIST_EXC),
  1473. job_ptr->exc_nodes);
  1474. add_display_treestore_line(update, treestore, &iter,
  1475. find_col_name(display_data_job,
  1476. SORTID_NODELIST_REQ),
  1477. job_ptr->req_nodes);
  1478. }
  1479. if (cluster_flags & CLUSTER_FLAG_BG)
  1480. convert_num_unit((float)sview_job_info_ptr->node_cnt,
  1481. tmp_char, sizeof(tmp_char), UNIT_NONE);
  1482. else
  1483. snprintf(tmp_char, sizeof(tmp_char), "%u",
  1484. sview_job_info_ptr->node_cnt);
  1485. add_display_treestore_line(update, treestore, &iter,
  1486. find_col_name(display_data_job,
  1487. SORTID_NODES),
  1488. tmp_char);
  1489. if (cluster_flags & CLUSTER_FLAG_BG)
  1490. convert_num_unit((float)sview_job_info_ptr->node_cnt,
  1491. tmp_char, sizeof(tmp_char), UNIT_NONE);
  1492. else
  1493. snprintf(tmp_char, sizeof(tmp_char), "%u",
  1494. job_ptr->max_nodes);
  1495. add_display_treestore_line(update, treestore, &iter,
  1496. find_col_name(display_data_job,
  1497. SORTID_NODES_MAX),
  1498. tmp_char);
  1499. if (cluster_flags & CLUSTER_FLAG_BG)
  1500. convert_num_unit((float)sview_job_info_ptr->node_cnt,
  1501. tmp_char, sizeof(tmp_char), UNIT_NONE);
  1502. else
  1503. snprintf(tmp_char, sizeof(tmp_char), "%u",
  1504. job_ptr->num_nodes);
  1505. add_display_treestore_line(update, treestore, &iter,
  1506. find_col_name(display_data_job,
  1507. SORTID_NODES_MIN),
  1508. tmp_char);
  1509. add_display_treestore_line(update, treestore, &iter,
  1510. find_col_name(display_data_job,
  1511. SORTID_PARTITION),
  1512. job_ptr->partition);
  1513. sprintf(tmp_char, "%u", job_ptr->priority);
  1514. add_display_treestore_line(update, treestore, &iter,
  1515. find_col_name(display_data_job,
  1516. SORTID_PRIORITY),
  1517. tmp_char);
  1518. add_display_treestore_line(update, treestore, &iter,
  1519. find_col_name(display_data_job,
  1520. SORTID_QOS),
  1521. job_ptr->qos);
  1522. if (job_ptr->state_desc)
  1523. reason = job_ptr->state_desc;
  1524. else
  1525. reason = job_reason_string(job_ptr->state_reason);
  1526. add_display_treestore_line(update, treestore, &iter,
  1527. find_col_name(display_data_job,
  1528. SORTID_REASON), reason);
  1529. if (job_ptr->requeue)
  1530. sprintf(tmp_char, "yes");
  1531. else
  1532. sprintf(tmp_char, "no");
  1533. add_display_treestore_line(update, treestore, &iter,
  1534. find_col_name(display_data_job,
  1535. SORTID_REQUEUE),
  1536. tmp_char);
  1537. add_display_treestore_line(update, treestore, &iter,
  1538. find_col_name(display_data_job,
  1539. SORTID_RESV_NAME),
  1540. job_ptr->resv_name);
  1541. snprintf(tmp_char, sizeof(tmp_char), "%u", job_ptr->restart_cnt);
  1542. add_display_treestore_line(update, treestore, &iter,
  1543. find_col_name(display_data_job,
  1544. SORTID_RESTARTS),
  1545. tmp_char);
  1546. if (cluster_flags & CLUSTER_FLAG_BG)
  1547. add_display_treestore_line(update, treestore, &iter,
  1548. find_col_name(display_data_job,
  1549. SORTID_ROTATE),
  1550. select_g_select_jobinfo_sprint(
  1551. job_ptr->select_jobinfo,
  1552. tmp_char,
  1553. sizeof(tmp_char),

Large files files are truncated, but you can click here to view the full file