PageRenderTime 48ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/sstat/options.c

https://github.com/cfenoy/slurm
C | 470 lines | 377 code | 42 blank | 51 comment | 91 complexity | 9fa59b671c2392bdef3130b81d774fb2 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. /*****************************************************************************\
  2. * options.c - option functions for sstat
  3. *
  4. * $Id: options.c 7541 2006-03-18 01:44:58Z da $
  5. *****************************************************************************
  6. * Copyright (C) 2006 The Regents of the University of California.
  7. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  8. * Written by Danny Auble <da@llnl.gov>.
  9. * CODE-OCEC-09-009. All rights reserved.
  10. *
  11. * This file is part of SLURM, a resource management program.
  12. * For details, see <http://www.schedmd.com/slurmdocs/>.
  13. * Please also read the included file: DISCLAIMER.
  14. *
  15. * SLURM is free software; you can redistribute it and/or modify it under
  16. * the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. *
  20. * In addition, as a special exception, the copyright holders give permission
  21. * to link the code of portions of this program with the OpenSSL library under
  22. * certain conditions as described in each individual source file, and
  23. * distribute linked combinations including the two. You must obey the GNU
  24. * General Public License in all respects for all of the code used other than
  25. * OpenSSL. If you modify file(s) with this exception, you may extend this
  26. * exception to your version of the file(s), but you are not obligated to do
  27. * so. If you do not wish to do so, delete this exception statement from your
  28. * version. If you delete this exception statement from all source files in
  29. * the program, then also delete it here.
  30. *
  31. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  32. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  33. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  34. * details.
  35. *
  36. * You should have received a copy of the GNU General Public License along
  37. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  38. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  39. \*****************************************************************************/
  40. #include "src/common/read_config.h"
  41. #include "src/common/proc_args.h"
  42. #include "sstat.h"
  43. #include <time.h>
  44. void _help_fields_msg(void);
  45. void _help_msg(void);
  46. void _usage(void);
  47. void _init_params();
  48. void _help_fields_msg(void)
  49. {
  50. int i;
  51. for (i = 0; fields[i].name; i++) {
  52. if (i & 3)
  53. printf(" ");
  54. else if (i)
  55. printf("\n");
  56. printf("%-13s", fields[i].name);
  57. }
  58. printf("\n");
  59. return;
  60. }
  61. void _help_msg(void)
  62. {
  63. printf("\
  64. sstat [<OPTION>] -j <job(.stepid)> \n\
  65. Valid <OPTION> values are: \n\
  66. -a, --allsteps: \n\
  67. Print all steps for the given job(s) when no step is \n\
  68. specified. \n\
  69. -e, --helpformat: \n\
  70. Print a list of fields that can be specified with the \n\
  71. '--format' option \n\
  72. -h, --help: Print this description of use. \n\
  73. -i, --pidformat: \n\
  74. Predefined format to list the pids running for each \n\
  75. job step. (JobId,Nodes,Pids) \n\
  76. -j, --jobs: \n\
  77. Format is <job(.step)>. Stat this job step \n\
  78. or comma-separated list of job steps. This option is \n\
  79. required. The step portion will default to lowest step \n\
  80. running if not specified, unless the --allsteps flag is \n\
  81. set where not specifying a step will result in all \n\
  82. running steps to be displayed. A step id of 'batch' \n\
  83. will display the information about the batch step. \n\
  84. -n, --noheader: \n\
  85. No header will be added to the beginning of output. \n\
  86. The default is to print a header. \n\
  87. -o, --format: \n\
  88. Comma separated list of fields. (use \"--helpformat\" \n\
  89. for a list of available fields). \n\
  90. -p, --parsable: output will be '|' delimited with a '|' at the end \n\
  91. -P, --parsable2: output will be '|' delimited without a '|' at the end \n\
  92. --usage: Display brief usage message. \n\
  93. -v, --verbose: \n\
  94. Primarily for debugging purposes, report the state of \n\
  95. various variables during processing. \n\
  96. -V, --version: Print version. \n\
  97. \n");
  98. return;
  99. }
  100. void _usage(void)
  101. {
  102. printf("Usage: sstat [options] -j <job(.stepid)>\n"
  103. "\tUse --help for help\n");
  104. }
  105. void _do_help(void)
  106. {
  107. switch (params.opt_help) {
  108. case 1:
  109. _help_msg();
  110. break;
  111. case 2:
  112. _help_fields_msg();
  113. break;
  114. case 3:
  115. _usage();
  116. break;
  117. default:
  118. fprintf(stderr, "stats bug: params.opt_help=%d\n",
  119. params.opt_help);
  120. }
  121. }
  122. void _init_params()
  123. {
  124. memset(&params, 0, sizeof(sstat_parameters_t));
  125. }
  126. /* returns number of objects added to list */
  127. static int _addto_job_list(List job_list, char *names)
  128. {
  129. int i=0, start=0;
  130. char *name = NULL, *dot = NULL;
  131. slurmdb_selected_step_t *selected_step = NULL;
  132. slurmdb_selected_step_t *curr_step = NULL;
  133. ListIterator itr = NULL;
  134. char quote_c = '\0';
  135. int quote = 0;
  136. int count = 0;
  137. if (!job_list) {
  138. error("No list was given to fill in");
  139. return 0;
  140. }
  141. itr = list_iterator_create(job_list);
  142. if (names) {
  143. if (names[i] == '\"' || names[i] == '\'') {
  144. quote_c = names[i];
  145. quote = 1;
  146. i++;
  147. }
  148. start = i;
  149. while (names[i]) {
  150. //info("got %d - %d = %d", i, start, i-start);
  151. if (quote && names[i] == quote_c)
  152. break;
  153. else if (names[i] == '\"' || names[i] == '\'')
  154. names[i] = '`';
  155. else if (names[i] == ',') {
  156. if ((i-start) > 0) {
  157. char *dot = NULL;
  158. name = xmalloc((i-start+1));
  159. memcpy(name, names+start, (i-start));
  160. selected_step = xmalloc(
  161. sizeof(slurmdb_selected_step_t));
  162. dot = strstr(name, ".");
  163. if (dot == NULL) {
  164. debug2("No jobstep requested");
  165. selected_step->stepid = NO_VAL;
  166. } else {
  167. *dot++ = 0;
  168. /* can't use NO_VAL
  169. * since that means all */
  170. if (!strcmp(dot, "batch"))
  171. selected_step->stepid =
  172. INFINITE;
  173. else
  174. selected_step->stepid =
  175. atoi(dot);
  176. }
  177. selected_step->jobid = atoi(name);
  178. xfree(name);
  179. while ((curr_step = list_next(itr))) {
  180. if ((curr_step->jobid
  181. == selected_step->jobid)
  182. && (curr_step->stepid
  183. == selected_step->
  184. stepid))
  185. break;
  186. }
  187. if (!curr_step) {
  188. list_append(job_list,
  189. selected_step);
  190. count++;
  191. } else
  192. slurmdb_destroy_selected_step(
  193. selected_step);
  194. list_iterator_reset(itr);
  195. }
  196. i++;
  197. start = i;
  198. }
  199. i++;
  200. }
  201. if ((i-start) > 0) {
  202. name = xmalloc((i-start)+1);
  203. memcpy(name, names+start, (i-start));
  204. selected_step =
  205. xmalloc(sizeof(slurmdb_selected_step_t));
  206. dot = strstr(name, ".");
  207. if (dot == NULL) {
  208. debug2("No jobstep requested");
  209. selected_step->stepid = NO_VAL;
  210. } else {
  211. *dot++ = 0;
  212. /* can't use NO_VAL since that means all */
  213. if (!strcmp(dot, "batch"))
  214. selected_step->stepid = INFINITE;
  215. else
  216. selected_step->stepid = atoi(dot);
  217. }
  218. selected_step->jobid = atoi(name);
  219. xfree(name);
  220. while ((curr_step = list_next(itr))) {
  221. if ((curr_step->jobid == selected_step->jobid)
  222. && (curr_step->stepid
  223. == selected_step->stepid))
  224. break;
  225. }
  226. if (!curr_step) {
  227. list_append(job_list, selected_step);
  228. count++;
  229. } else
  230. slurmdb_destroy_selected_step(
  231. selected_step);
  232. }
  233. }
  234. list_iterator_destroy(itr);
  235. return count;
  236. }
  237. int decode_state_char(char *state)
  238. {
  239. if (!strcasecmp(state, "p"))
  240. return JOB_PENDING; /* we should never see this */
  241. else if (!strcasecmp(state, "r"))
  242. return JOB_RUNNING;
  243. else if (!strcasecmp(state, "su"))
  244. return JOB_SUSPENDED;
  245. else if (!strcasecmp(state, "cd"))
  246. return JOB_COMPLETE;
  247. else if (!strcasecmp(state, "ca"))
  248. return JOB_CANCELLED;
  249. else if (!strcasecmp(state, "f"))
  250. return JOB_FAILED;
  251. else if (!strcasecmp(state, "to"))
  252. return JOB_TIMEOUT;
  253. else if (!strcasecmp(state, "nf"))
  254. return JOB_NODE_FAIL;
  255. else if (!strcasecmp(state, "pr"))
  256. return JOB_PREEMPTED;
  257. else
  258. return -1; // unknown
  259. }
  260. void parse_command_line(int argc, char **argv)
  261. {
  262. extern int optind;
  263. int c, i, optionIndex = 0;
  264. char *end = NULL, *start = NULL;
  265. slurmdb_selected_step_t *selected_step = NULL;
  266. ListIterator itr = NULL;
  267. log_options_t logopt = LOG_OPTS_STDERR_ONLY;
  268. static struct option long_options[] = {
  269. {"allsteps", 0, 0, 'a'},
  270. {"helpformat", 0, 0, 'e'},
  271. {"help", 0, 0, 'h'},
  272. {"jobs", 1, 0, 'j'},
  273. {"noheader", 0, 0, 'n'},
  274. {"fields", 1, 0, 'o'},
  275. {"format", 1, 0, 'o'},
  276. {"pidformat", 0, 0, 'i'},
  277. {"parsable", 0, 0, 'p'},
  278. {"parsable2", 0, 0, 'P'},
  279. {"usage", 0, &params.opt_help, 3},
  280. {"verbose", 0, 0, 'v'},
  281. {"version", 0, 0, 'V'},
  282. {0, 0, 0, 0}};
  283. log_init(xbasename(argv[0]), logopt, 0, NULL);
  284. _init_params();
  285. opterr = 1; /* Let getopt report problems to the user */
  286. while (1) { /* now cycle through the command line */
  287. c = getopt_long(argc, argv, "aehij:no:pPvV",
  288. long_options, &optionIndex);
  289. if (c == -1)
  290. break;
  291. switch (c) {
  292. case 'a':
  293. params.opt_all_steps = 1;
  294. break;
  295. case 'e':
  296. params.opt_help = 2;
  297. break;
  298. case 'h':
  299. params.opt_help = 1;
  300. break;
  301. case 'i':
  302. params.pid_format = 1;
  303. xstrfmtcat(params.opt_field_list, "%s,",
  304. STAT_FIELDS_PID);
  305. break;
  306. case 'j':
  307. if ((strspn(optarg, "0123456789, ") < strlen(optarg))
  308. && (strspn(optarg, ".batch0123456789, ")
  309. < strlen(optarg))) {
  310. fprintf(stderr, "Invalid jobs list: %s\n",
  311. optarg);
  312. exit(1);
  313. }
  314. if (!params.opt_job_list)
  315. params.opt_job_list = list_create(
  316. slurmdb_destroy_selected_step);
  317. _addto_job_list(params.opt_job_list, optarg);
  318. break;
  319. case 'n':
  320. print_fields_have_header = 0;
  321. break;
  322. case 'o':
  323. xstrfmtcat(params.opt_field_list, "%s,", optarg);
  324. break;
  325. case 'p':
  326. print_fields_parsable_print =
  327. PRINT_FIELDS_PARSABLE_ENDING;
  328. break;
  329. case 'P':
  330. print_fields_parsable_print =
  331. PRINT_FIELDS_PARSABLE_NO_ENDING;
  332. break;
  333. case 'v':
  334. /* Handle -vvv thusly...
  335. * 0 - report only normal messages and errors
  336. * 1 - report options selected and major operations
  337. * 2 - report data anomalies probably not errors
  338. * 3 - blather on and on
  339. */
  340. params.opt_verbose++;
  341. break;
  342. case 'V':
  343. print_slurm_version();
  344. exit(0);
  345. break;
  346. case ':':
  347. case '?': /* getopt() has explained it */
  348. exit(1);
  349. }
  350. }
  351. if (params.opt_help) {
  352. _do_help();
  353. exit(0);
  354. }
  355. if (optind < argc) {
  356. optarg = argv[optind];
  357. if ((strspn(optarg, "0123456789, ") < strlen(optarg))
  358. && (strspn(optarg, ".batch0123456789, ")
  359. < strlen(optarg))) {
  360. fprintf(stderr, "Invalid jobs list: %s\n",
  361. optarg);
  362. exit(1);
  363. }
  364. if (!params.opt_job_list)
  365. params.opt_job_list = list_create(
  366. slurmdb_destroy_selected_step);
  367. _addto_job_list(params.opt_job_list, optarg);
  368. }
  369. if (!params.opt_field_list)
  370. xstrfmtcat(params.opt_field_list, "%s,", STAT_FIELDS);
  371. if (params.opt_verbose) {
  372. logopt.stderr_level += params.opt_verbose;
  373. logopt.prefix_level = 1;
  374. log_alter(logopt, 0, NULL);
  375. }
  376. /* specific jobs requested? */
  377. if (params.opt_verbose && params.opt_job_list
  378. && list_count(params.opt_job_list)) {
  379. debug("Jobs requested:\n");
  380. itr = list_iterator_create(params.opt_job_list);
  381. while ((selected_step = list_next(itr))) {
  382. if (selected_step->stepid != NO_VAL)
  383. debug("\t: %d.%d\n",
  384. selected_step->jobid,
  385. selected_step->stepid);
  386. else
  387. debug("\t: %d\n",
  388. selected_step->jobid);
  389. }
  390. list_iterator_destroy(itr);
  391. }
  392. start = params.opt_field_list;
  393. while ((end = strstr(start, ","))) {
  394. char *tmp_char = NULL;
  395. int command_len = 0;
  396. int newlen = 0;
  397. *end = 0;
  398. while (isspace(*start))
  399. start++; /* discard whitespace */
  400. if (!(int)*start)
  401. continue;
  402. if ((tmp_char = strstr(start, "\%"))) {
  403. newlen = atoi(tmp_char+1);
  404. tmp_char[0] = '\0';
  405. }
  406. command_len = strlen(start);
  407. for (i = 0; fields[i].name; i++) {
  408. if (!strncasecmp(fields[i].name, start, command_len))
  409. goto foundfield;
  410. }
  411. error("Invalid field requested: \"%s\"", start);
  412. exit(1);
  413. foundfield:
  414. if (newlen)
  415. fields[i].len = newlen;
  416. list_append(print_fields_list, &fields[i]);
  417. start = end + 1;
  418. }
  419. field_count = list_count(print_fields_list);
  420. if (optind < argc) {
  421. debug2("Error: Unknown arguments:");
  422. for (i=optind; i<argc; i++)
  423. debug2(" %s", argv[i]);
  424. debug2("\n");
  425. exit(1);
  426. }
  427. return;
  428. }