/src/sstat/options.c
C | 470 lines | 377 code | 42 blank | 51 comment | 91 complexity | 9fa59b671c2392bdef3130b81d774fb2 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
- /*****************************************************************************\
- * options.c - option functions for sstat
- *
- * $Id: options.c 7541 2006-03-18 01:44:58Z da $
- *****************************************************************************
- * Copyright (C) 2006 The Regents of the University of California.
- * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- * Written by Danny Auble <da@llnl.gov>.
- * CODE-OCEC-09-009. All rights reserved.
- *
- * This file is part of SLURM, a resource management program.
- * For details, see <http://www.schedmd.com/slurmdocs/>.
- * Please also read the included file: DISCLAIMER.
- *
- * SLURM is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * In addition, as a special exception, the copyright holders give permission
- * to link the code of portions of this program with the OpenSSL library under
- * certain conditions as described in each individual source file, and
- * distribute linked combinations including the two. You must obey the GNU
- * General Public License in all respects for all of the code used other than
- * OpenSSL. If you modify file(s) with this exception, you may extend this
- * exception to your version of the file(s), but you are not obligated to do
- * so. If you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files in
- * the program, then also delete it here.
- *
- * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along
- * with SLURM; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- \*****************************************************************************/
- #include "src/common/read_config.h"
- #include "src/common/proc_args.h"
- #include "sstat.h"
- #include <time.h>
- void _help_fields_msg(void);
- void _help_msg(void);
- void _usage(void);
- void _init_params();
- void _help_fields_msg(void)
- {
- int i;
- for (i = 0; fields[i].name; i++) {
- if (i & 3)
- printf(" ");
- else if (i)
- printf("\n");
- printf("%-13s", fields[i].name);
- }
- printf("\n");
- return;
- }
- void _help_msg(void)
- {
- printf("\
- sstat [<OPTION>] -j <job(.stepid)> \n\
- Valid <OPTION> values are: \n\
- -a, --allsteps: \n\
- Print all steps for the given job(s) when no step is \n\
- specified. \n\
- -e, --helpformat: \n\
- Print a list of fields that can be specified with the \n\
- '--format' option \n\
- -h, --help: Print this description of use. \n\
- -i, --pidformat: \n\
- Predefined format to list the pids running for each \n\
- job step. (JobId,Nodes,Pids) \n\
- -j, --jobs: \n\
- Format is <job(.step)>. Stat this job step \n\
- or comma-separated list of job steps. This option is \n\
- required. The step portion will default to lowest step \n\
- running if not specified, unless the --allsteps flag is \n\
- set where not specifying a step will result in all \n\
- running steps to be displayed. A step id of 'batch' \n\
- will display the information about the batch step. \n\
- -n, --noheader: \n\
- No header will be added to the beginning of output. \n\
- The default is to print a header. \n\
- -o, --format: \n\
- Comma separated list of fields. (use \"--helpformat\" \n\
- for a list of available fields). \n\
- -p, --parsable: output will be '|' delimited with a '|' at the end \n\
- -P, --parsable2: output will be '|' delimited without a '|' at the end \n\
- --usage: Display brief usage message. \n\
- -v, --verbose: \n\
- Primarily for debugging purposes, report the state of \n\
- various variables during processing. \n\
- -V, --version: Print version. \n\
- \n");
- return;
- }
- void _usage(void)
- {
- printf("Usage: sstat [options] -j <job(.stepid)>\n"
- "\tUse --help for help\n");
- }
- void _do_help(void)
- {
- switch (params.opt_help) {
- case 1:
- _help_msg();
- break;
- case 2:
- _help_fields_msg();
- break;
- case 3:
- _usage();
- break;
- default:
- fprintf(stderr, "stats bug: params.opt_help=%d\n",
- params.opt_help);
- }
- }
- void _init_params()
- {
- memset(¶ms, 0, sizeof(sstat_parameters_t));
- }
- /* returns number of objects added to list */
- static int _addto_job_list(List job_list, char *names)
- {
- int i=0, start=0;
- char *name = NULL, *dot = NULL;
- slurmdb_selected_step_t *selected_step = NULL;
- slurmdb_selected_step_t *curr_step = NULL;
- ListIterator itr = NULL;
- char quote_c = '\0';
- int quote = 0;
- int count = 0;
- if (!job_list) {
- error("No list was given to fill in");
- return 0;
- }
- itr = list_iterator_create(job_list);
- if (names) {
- if (names[i] == '\"' || names[i] == '\'') {
- quote_c = names[i];
- quote = 1;
- i++;
- }
- start = i;
- while (names[i]) {
- //info("got %d - %d = %d", i, start, i-start);
- if (quote && names[i] == quote_c)
- break;
- else if (names[i] == '\"' || names[i] == '\'')
- names[i] = '`';
- else if (names[i] == ',') {
- if ((i-start) > 0) {
- char *dot = NULL;
- name = xmalloc((i-start+1));
- memcpy(name, names+start, (i-start));
- selected_step = xmalloc(
- sizeof(slurmdb_selected_step_t));
- dot = strstr(name, ".");
- if (dot == NULL) {
- debug2("No jobstep requested");
- selected_step->stepid = NO_VAL;
- } else {
- *dot++ = 0;
- /* can't use NO_VAL
- * since that means all */
- if (!strcmp(dot, "batch"))
- selected_step->stepid =
- INFINITE;
- else
- selected_step->stepid =
- atoi(dot);
- }
- selected_step->jobid = atoi(name);
- xfree(name);
- while ((curr_step = list_next(itr))) {
- if ((curr_step->jobid
- == selected_step->jobid)
- && (curr_step->stepid
- == selected_step->
- stepid))
- break;
- }
- if (!curr_step) {
- list_append(job_list,
- selected_step);
- count++;
- } else
- slurmdb_destroy_selected_step(
- selected_step);
- list_iterator_reset(itr);
- }
- i++;
- start = i;
- }
- i++;
- }
- if ((i-start) > 0) {
- name = xmalloc((i-start)+1);
- memcpy(name, names+start, (i-start));
- selected_step =
- xmalloc(sizeof(slurmdb_selected_step_t));
- dot = strstr(name, ".");
- if (dot == NULL) {
- debug2("No jobstep requested");
- selected_step->stepid = NO_VAL;
- } else {
- *dot++ = 0;
- /* can't use NO_VAL since that means all */
- if (!strcmp(dot, "batch"))
- selected_step->stepid = INFINITE;
- else
- selected_step->stepid = atoi(dot);
- }
- selected_step->jobid = atoi(name);
- xfree(name);
- while ((curr_step = list_next(itr))) {
- if ((curr_step->jobid == selected_step->jobid)
- && (curr_step->stepid
- == selected_step->stepid))
- break;
- }
- if (!curr_step) {
- list_append(job_list, selected_step);
- count++;
- } else
- slurmdb_destroy_selected_step(
- selected_step);
- }
- }
- list_iterator_destroy(itr);
- return count;
- }
- int decode_state_char(char *state)
- {
- if (!strcasecmp(state, "p"))
- return JOB_PENDING; /* we should never see this */
- else if (!strcasecmp(state, "r"))
- return JOB_RUNNING;
- else if (!strcasecmp(state, "su"))
- return JOB_SUSPENDED;
- else if (!strcasecmp(state, "cd"))
- return JOB_COMPLETE;
- else if (!strcasecmp(state, "ca"))
- return JOB_CANCELLED;
- else if (!strcasecmp(state, "f"))
- return JOB_FAILED;
- else if (!strcasecmp(state, "to"))
- return JOB_TIMEOUT;
- else if (!strcasecmp(state, "nf"))
- return JOB_NODE_FAIL;
- else if (!strcasecmp(state, "pr"))
- return JOB_PREEMPTED;
- else
- return -1; // unknown
- }
- void parse_command_line(int argc, char **argv)
- {
- extern int optind;
- int c, i, optionIndex = 0;
- char *end = NULL, *start = NULL;
- slurmdb_selected_step_t *selected_step = NULL;
- ListIterator itr = NULL;
- log_options_t logopt = LOG_OPTS_STDERR_ONLY;
- static struct option long_options[] = {
- {"allsteps", 0, 0, 'a'},
- {"helpformat", 0, 0, 'e'},
- {"help", 0, 0, 'h'},
- {"jobs", 1, 0, 'j'},
- {"noheader", 0, 0, 'n'},
- {"fields", 1, 0, 'o'},
- {"format", 1, 0, 'o'},
- {"pidformat", 0, 0, 'i'},
- {"parsable", 0, 0, 'p'},
- {"parsable2", 0, 0, 'P'},
- {"usage", 0, ¶ms.opt_help, 3},
- {"verbose", 0, 0, 'v'},
- {"version", 0, 0, 'V'},
- {0, 0, 0, 0}};
- log_init(xbasename(argv[0]), logopt, 0, NULL);
- _init_params();
- opterr = 1; /* Let getopt report problems to the user */
- while (1) { /* now cycle through the command line */
- c = getopt_long(argc, argv, "aehij:no:pPvV",
- long_options, &optionIndex);
- if (c == -1)
- break;
- switch (c) {
- case 'a':
- params.opt_all_steps = 1;
- break;
- case 'e':
- params.opt_help = 2;
- break;
- case 'h':
- params.opt_help = 1;
- break;
- case 'i':
- params.pid_format = 1;
- xstrfmtcat(params.opt_field_list, "%s,",
- STAT_FIELDS_PID);
- break;
- case 'j':
- if ((strspn(optarg, "0123456789, ") < strlen(optarg))
- && (strspn(optarg, ".batch0123456789, ")
- < strlen(optarg))) {
- fprintf(stderr, "Invalid jobs list: %s\n",
- optarg);
- exit(1);
- }
- if (!params.opt_job_list)
- params.opt_job_list = list_create(
- slurmdb_destroy_selected_step);
- _addto_job_list(params.opt_job_list, optarg);
- break;
- case 'n':
- print_fields_have_header = 0;
- break;
- case 'o':
- xstrfmtcat(params.opt_field_list, "%s,", optarg);
- break;
- case 'p':
- print_fields_parsable_print =
- PRINT_FIELDS_PARSABLE_ENDING;
- break;
- case 'P':
- print_fields_parsable_print =
- PRINT_FIELDS_PARSABLE_NO_ENDING;
- break;
- case 'v':
- /* Handle -vvv thusly...
- * 0 - report only normal messages and errors
- * 1 - report options selected and major operations
- * 2 - report data anomalies probably not errors
- * 3 - blather on and on
- */
- params.opt_verbose++;
- break;
- case 'V':
- print_slurm_version();
- exit(0);
- break;
- case ':':
- case '?': /* getopt() has explained it */
- exit(1);
- }
- }
- if (params.opt_help) {
- _do_help();
- exit(0);
- }
- if (optind < argc) {
- optarg = argv[optind];
- if ((strspn(optarg, "0123456789, ") < strlen(optarg))
- && (strspn(optarg, ".batch0123456789, ")
- < strlen(optarg))) {
- fprintf(stderr, "Invalid jobs list: %s\n",
- optarg);
- exit(1);
- }
- if (!params.opt_job_list)
- params.opt_job_list = list_create(
- slurmdb_destroy_selected_step);
- _addto_job_list(params.opt_job_list, optarg);
- }
- if (!params.opt_field_list)
- xstrfmtcat(params.opt_field_list, "%s,", STAT_FIELDS);
- if (params.opt_verbose) {
- logopt.stderr_level += params.opt_verbose;
- logopt.prefix_level = 1;
- log_alter(logopt, 0, NULL);
- }
- /* specific jobs requested? */
- if (params.opt_verbose && params.opt_job_list
- && list_count(params.opt_job_list)) {
- debug("Jobs requested:\n");
- itr = list_iterator_create(params.opt_job_list);
- while ((selected_step = list_next(itr))) {
- if (selected_step->stepid != NO_VAL)
- debug("\t: %d.%d\n",
- selected_step->jobid,
- selected_step->stepid);
- else
- debug("\t: %d\n",
- selected_step->jobid);
- }
- list_iterator_destroy(itr);
- }
- start = params.opt_field_list;
- while ((end = strstr(start, ","))) {
- char *tmp_char = NULL;
- int command_len = 0;
- int newlen = 0;
- *end = 0;
- while (isspace(*start))
- start++; /* discard whitespace */
- if (!(int)*start)
- continue;
- if ((tmp_char = strstr(start, "\%"))) {
- newlen = atoi(tmp_char+1);
- tmp_char[0] = '\0';
- }
- command_len = strlen(start);
- for (i = 0; fields[i].name; i++) {
- if (!strncasecmp(fields[i].name, start, command_len))
- goto foundfield;
- }
- error("Invalid field requested: \"%s\"", start);
- exit(1);
- foundfield:
- if (newlen)
- fields[i].len = newlen;
- list_append(print_fields_list, &fields[i]);
- start = end + 1;
- }
- field_count = list_count(print_fields_list);
- if (optind < argc) {
- debug2("Error: Unknown arguments:");
- for (i=optind; i<argc; i++)
- debug2(" %s", argv[i]);
- debug2("\n");
- exit(1);
- }
- return;
- }