blob: 940d886cf1ed46d27fe41091a3e0718dcae9db74 [file] [log] [blame]
/*****************************************************************************\
* sacctmgr.c - administration tool for slurm's accounting.
* provides interface to read, write, update, and configure
* accounting.
*****************************************************************************
* Copyright (C) 2008-2009 Lawrence Livermore National Security.
* Copyright (C) 2002-2007 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 <https://slurm.schedmd.com/>.
* 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 "config.h"
#include "src/sacctmgr/sacctmgr.h"
#include "src/common/data.h"
#include "src/common/ref.h"
#include "src/common/xsignal.h"
#include "src/common/proc_args.h"
#include "src/common/strlcpy.h"
#include "src/interfaces/data_parser.h"
#include "src/interfaces/serializer.h"
#define OPT_LONG_AUTOCOMP 0x100
#define OPT_LONG_JSON 0x101
#define OPT_LONG_YAML 0x102
char *command_name;
int exit_code; /* sacctmgr's exit code, =1 on any error at any time */
int exit_flag; /* program to terminate if =1 */
int one_liner; /* one record per line if =1 */
int quiet_flag; /* quiet=1, verbose=-1, normal=0 */
int readonly_flag; /* make it so you can only run list commands */
int verbosity; /* count of -v options */
int rollback_flag; /* immediate execute=1, else = 0 */
int with_assoc_flag = 0;
void *db_conn = NULL;
uint32_t my_uid = 0;
char *my_user_name = NULL;
list_t *g_qos_list = NULL;
list_t *g_res_list = NULL;
list_t *g_tres_list = NULL;
const char *mime_type = NULL; /* mimetype if we are using data_parser */
const char *data_parser = NULL; /* data_parser args */
/* by default, normalize all usernames to lower case */
bool user_case_norm = true;
bool tree_display = 0;
bool have_db_conn = false;
static void _add_it(int argc, char **argv);
static void _archive_it(int argc, char **argv);
static void _clear_it(int argc, char **argv);
static void _show_it(int argc, char **argv);
static void _modify_it(int argc, char **argv);
static void _delete_it(int argc, char **argv);
static int _get_command(int *argc, char **argv);
static int _ping(int argc, char **argv);
static void _print_version(void);
static int _process_command(int argc, char **argv);
static void _usage(void);
decl_static_data(usage_txt);
int main(int argc, char **argv)
{
int error_code = SLURM_SUCCESS, opt_char;
log_options_t opts = LOG_OPTS_STDERR_ONLY ;
int local_exit_code = 0;
int option_index;
uint16_t persist_conn_flags = 0;
static struct option long_options[] = {
{"autocomplete", required_argument, 0, OPT_LONG_AUTOCOMP},
{"help", 0, 0, 'h'},
{"usage", 0, 0, 'h'},
{"immediate",0, 0, 'i'},
{"noheader",0, 0, 'n'},
{"oneliner", 0, 0, 'o'},
{"parsable", 0, 0, 'p'},
{"parsable2", 0, 0, 'P'},
{"quiet", 0, 0, 'Q'},
{"readonly", 0, 0, 'r'},
{"associations", 0, 0, 's'},
{"verbose", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{"json", optional_argument, 0, OPT_LONG_JSON},
{"yaml", optional_argument, 0, OPT_LONG_YAML},
{NULL, 0, 0, 0}
};
command_name = argv[0];
rollback_flag = 1;
exit_code = 0;
exit_flag = 0;
quiet_flag = 0;
readonly_flag = 0;
verbosity = 0;
slurm_init(NULL);
log_init("sacctmgr", opts, SYSLOG_FACILITY_DAEMON, NULL);
while((opt_char = getopt_long(argc, argv, "hionpPQrsvV",
long_options, &option_index)) != -1) {
switch (opt_char) {
case (int)'?':
fprintf(stderr, "Try \"sacctmgr --help\" "
"for more information\n");
exit(1);
break;
case (int)'h':
_usage ();
exit(exit_code);
break;
case (int)'i':
rollback_flag = 0;
break;
case (int)'o':
one_liner = 1;
break;
case (int)'n':
print_fields_have_header = 0;
break;
case (int)'p':
print_fields_parsable_print =
PRINT_FIELDS_PARSABLE_ENDING;
break;
case (int)'P':
print_fields_parsable_print =
PRINT_FIELDS_PARSABLE_NO_ENDING;
break;
case (int)'Q':
quiet_flag = 1;
break;
case (int)'r':
readonly_flag = 1;
break;
case (int)'s':
with_assoc_flag = 1;
break;
case (int)'v':
quiet_flag = -1;
verbosity++;
break;
case (int)'V':
_print_version();
exit(exit_code);
break;
case OPT_LONG_AUTOCOMP:
suggest_completion(long_options, optarg);
exit(0);
break;
case OPT_LONG_JSON :
mime_type = MIME_TYPE_JSON;
data_parser = optarg;
serializer_required(MIME_TYPE_JSON);
break;
case OPT_LONG_YAML :
mime_type = MIME_TYPE_YAML;
data_parser = optarg;
serializer_required(MIME_TYPE_YAML);
break;
default:
exit_code = 1;
fprintf(stderr, "getopt error, returned %c\n",
opt_char);
exit(exit_code);
}
}
if (verbosity) {
opts.stderr_level += verbosity;
opts.prefix_level = 1;
log_alter(opts, 0, NULL);
}
/* Check to see if we are running a supported accounting plugin */
if (!slurm_with_slurmdbd()) {
fprintf(stderr,
"You are not running a supported accounting_storage plugin\n"
"Only 'accounting_storage/slurmdbd' is supported.\n");
exit(1);
}
errno = 0;
db_conn = slurmdb_connection_get(&persist_conn_flags);
if (!errno)
have_db_conn = true;
my_uid = getuid();
my_user_name = uid_to_string_cached(my_uid);
if (persist_conn_flags & PERSIST_FLAG_P_USER_CASE)
user_case_norm = false;
/* We are only running a single command and exiting */
if (optind < argc) {
error_code = _process_command(argc - optind, argv + optind);
} else if ((argc == 2) && (optind == argc) && mime_type &&
!xstrcmp(data_parser, "list")) {
/*
* We are only listing the available data parser plugins.
* Calling DATA_DUMP_CLI_SINGLE() with a dummy type to get to
* "list".
* TODO: After Bug 18109 is fixed, replace this logic:
*/
DATA_DUMP_CLI_SINGLE(OPENAPI_PING_ARRAY_RESP, NULL, argc, argv,
NULL, mime_type, data_parser, exit_code);
} else {
/* We are running interactively multiple commands */
int input_field_count = 0;
char **input_fields = xcalloc(MAX_INPUT_FIELDS, sizeof(char *));
while (error_code == SLURM_SUCCESS) {
error_code = _get_command(
&input_field_count, input_fields);
if (error_code || exit_flag)
break;
error_code = _process_command(
input_field_count, input_fields);
/* This is here so if someone made a mistake we allow
* them to fix it and let the process happen since there
* are checks for global exit_code we need to reset it.
*/
if (exit_code) {
local_exit_code = exit_code;
exit_code = 0;
}
if (exit_flag)
break;
}
xfree(input_fields);
}
/* readline library writes \n when echoes the input string, it does
* not when it sees the EOF, so in that case we have to print it to
* align the terminal prompt.
*/
if (exit_flag == 2)
putchar('\n');
if (local_exit_code)
exit_code = local_exit_code;
slurmdb_connection_close(&db_conn);
#ifdef MEMORY_LEAK_DEBUG
log_fini();
slurm_fini();
uid_cache_clear();
FREE_NULL_LIST(g_qos_list);
FREE_NULL_LIST(g_res_list);
FREE_NULL_LIST(g_tres_list);
#endif
exit(exit_code);
}
#if !HAVE_READLINE
/*
* Alternative to readline if readline is not available
*/
static char *_getline(const char *prompt)
{
char buf[4096];
char *line;
int len;
printf("%s", prompt);
/* Set "line" here to avoid a warning, discard later */
line = fgets(buf, 4096, stdin);
if (line == NULL)
return NULL;
len = strlen(buf);
if ((len == 0) || (len >= 4096))
return NULL;
if (buf[len-1] == '\n')
buf[len-1] = '\0';
else
len++;
line = malloc(len);
if (!line)
return NULL;
strlcpy(line, buf, len);
return line;
}
#endif
/*
* _get_command - get a command from the user
* OUT argc - location to store count of arguments
* OUT argv - location to store the argument list
*/
static int _get_command (int *argc, char **argv)
{
char *in_line;
static char *last_in_line = NULL;
int i, in_line_size;
static int last_in_line_size = 0;
*argc = 0;
#if HAVE_READLINE
in_line = readline ("sacctmgr: ");
#else
in_line = _getline("sacctmgr: ");
#endif
if (in_line == NULL) {
exit_flag = 2;
return 0;
} else if (xstrncmp (in_line, "#", 1) == 0) {
free (in_line);
return 0;
} else if (xstrcmp (in_line, "!!") == 0) {
free (in_line);
in_line = last_in_line;
in_line_size = last_in_line_size;
} else {
if (last_in_line)
free (last_in_line);
last_in_line = in_line;
last_in_line_size = in_line_size = strlen (in_line);
}
#if HAVE_READLINE
add_history(in_line);
#endif
/* break in_line into tokens */
for (i = 0; i < in_line_size; i++) {
bool double_quote = false, single_quote = false;
if (in_line[i] == '\0')
break;
if (isspace ((int) in_line[i]))
continue;
if (((*argc) + 1) > MAX_INPUT_FIELDS) { /* bogus input line */
exit_code = 1;
fprintf (stderr,
"%s: can not process over %d words\n",
command_name, MAX_INPUT_FIELDS-1);
return E2BIG;
}
argv[(*argc)++] = &in_line[i];
for (i++; i < in_line_size; i++) {
if (in_line[i] == '\042') {
double_quote = !double_quote;
continue;
}
if (in_line[i] == '\047') {
single_quote = !single_quote;
continue;
}
if (in_line[i] == '\0')
break;
if (double_quote || single_quote)
continue;
if (isspace ((int) in_line[i])) {
in_line[i] = '\0';
break;
}
}
}
return 0;
}
static void _set_ping_exit_code(slurmdbd_ping_t *ping)
{
static bool slurmdbd_up = false;
if (ping->pinged) {
exit_code = SLURM_SUCCESS;
slurmdbd_up = true;
} else if (!slurmdbd_up) {
/* don't overwrite exit code if another slurmdbd is up */
exit_code = 1;
}
}
static void _print_db_ping(slurmdbd_ping_t *ping)
{
char *state;
char *mode;
if (ping->pinged)
state = "UP";
else
state = "DOWN";
if (ping->offset == 0)
mode = "primary";
else
mode = "backup";
printf("slurmdbd(%s) at %s is %s\n", mode, ping->hostname, state);
}
static int _ping(int argc, char **argv)
{
int rc = SLURM_SUCCESS;
slurmdbd_ping_t *pings = NULL;
if (!(pings = slurmdb_ping_all())) {
error("Failed to perform slurmdbd pings");
return SLURM_ERROR;
}
if (mime_type) {
DATA_DUMP_CLI_SINGLE(OPENAPI_SLURMDBD_PING_RESP, pings, argc,
argv, db_conn, mime_type, data_parser, rc);
} else {
for (int i = 0; pings[i].hostname; i++) {
_print_db_ping(&pings[i]);
_set_ping_exit_code(&pings[i]);
}
}
xfree(pings);
return rc;
}
static void _print_version(void)
{
print_slurm_version();
if (quiet_flag == -1) {
long version = slurm_api_version();
printf("slurm_api_version: %ld, %ld.%ld.%ld\n", version,
SLURM_VERSION_MAJOR(version),
SLURM_VERSION_MINOR(version),
SLURM_VERSION_MICRO(version));
}
}
/*
* _process_command - process the user's command
* IN argc - count of arguments
* IN argv - the arguments
* RET 0 or errno (only for errors fatal to sacctmgr)
*/
static int _process_command (int argc, char **argv)
{
int command_len = 0, rc;
if (argc < 1) {
exit_code = 1;
if (quiet_flag == -1)
fprintf(stderr, "no input");
return 0;
}
command_len = strlen(argv[0]);
if (xstrncasecmp (argv[0], "associations",
MAX(command_len, 3)) == 0) {
with_assoc_flag = 1;
} else if (xstrncasecmp(argv[0], "dump", MAX(command_len, 3)) == 0) {
sacctmgr_dump_cluster((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "help", MAX(command_len, 2)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for keyword:%s\n",
argv[0]);
}
_usage ();
} else if (xstrncasecmp(argv[0], "load", MAX(command_len, 2)) == 0) {
load_sacctmgr_cfg_file((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "oneliner",
MAX(command_len, 1)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for keyword:%s\n",
argv[0]);
}
one_liner = 1;
} else if (xstrncasecmp(argv[0], "quiet", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr, "too many arguments for keyword:%s\n",
argv[0]);
}
quiet_flag = 1;
} else if ((xstrncasecmp(argv[0], "exit", MAX(command_len, 4)) == 0) ||
(xstrncasecmp(argv[0], "\\q", MAX(command_len, 2)) == 0) ||
(xstrncasecmp(argv[0], "quit", MAX(command_len, 4)) == 0)) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for keyword:%s\n",
argv[0]);
}
exit_flag = 1;
} else if ((xstrncasecmp(argv[0], "add", MAX(command_len, 3)) == 0) ||
(xstrncasecmp(argv[0], "create",
MAX(command_len, 3)) == 0)) {
_add_it((argc - 1), &argv[1]);
} else if ((xstrncasecmp(argv[0], "archive",
MAX(command_len, 3)) == 0)) {
_archive_it((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "clear", MAX(command_len, 3)) == 0) {
_clear_it((argc - 1), &argv[1]);
} else if ((xstrncasecmp(argv[0], "show", MAX(command_len, 3)) == 0) ||
(xstrncasecmp(argv[0], "list", MAX(command_len, 3)) == 0)) {
_show_it((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "modify", MAX(command_len, 1))
|| !xstrncasecmp(argv[0], "update", MAX(command_len, 1))) {
_modify_it((argc - 1), &argv[1]);
} else if ((xstrncasecmp(argv[0], "delete",
MAX(command_len, 3)) == 0) ||
(xstrncasecmp(argv[0], "remove",
MAX(command_len, 3)) == 0)) {
_delete_it((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "verbose", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
quiet_flag = -1;
} else if (xstrncasecmp(argv[0], "ping", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf(stderr, "too many arguments for %s keyword\n",
argv[0]);
}
if (_ping(argc, argv))
fprintf(stderr, "unable to run ping\n");
} else if (xstrncasecmp(argv[0], "readonly",
MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
readonly_flag = 1;
} else if (xstrncasecmp(argv[0], "reconfigure",
MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
slurmdb_reconfig(db_conn);
} else if (xstrncasecmp(argv[0], "rollup", MAX(command_len, 2)) == 0) {
time_t my_start = 0;
time_t my_end = 0;
uint16_t archive_data = 0;
if (argc > 4) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
if (argc > 1)
my_start = parse_time(argv[1], 1);
if (argc > 2)
my_end = parse_time(argv[2], 1);
if (argc > 3)
archive_data = atoi(argv[3]);
if (slurmdb_usage_roll(db_conn, my_start, my_end, archive_data,
NULL) == SLURM_SUCCESS) {
if (commit_check("Would you like to commit rollup?")) {
exit_code =
slurmdb_connection_commit(db_conn, 1);
if (exit_code != SLURM_SUCCESS)
fprintf(stderr, " Error committing changes: %s\n",
slurm_strerror(exit_code));
} else {
printf(" Rollup Discarded\n");
exit_code =
slurmdb_connection_commit(db_conn, 0);
if (exit_code != SLURM_SUCCESS)
fprintf(stderr, " Error rolling back changes: %s\n",
slurm_strerror(exit_code));
}
}
} else if (xstrncasecmp(argv[0], "shutdown", MAX(command_len, 4)) ==
0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
rc = slurmdb_shutdown(db_conn);
if (rc != SLURM_SUCCESS) {
fprintf(stderr, " Problem shutting down server: %s\n",
slurm_strerror(rc));
exit_code = 1;
}
} else if (xstrncasecmp(argv[0], "version", MAX(command_len, 4)) == 0) {
if (argc > 1) {
exit_code = 1;
fprintf (stderr,
"too many arguments for %s keyword\n",
argv[0]);
}
_print_version();
} else {
exit_code = 1;
fprintf (stderr, "invalid keyword: %s\n", argv[0]);
}
return 0;
}
/*
* _add_it - add the entity per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _add_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!have_db_conn) {
exit_code = 1;
return;
}
if (readonly_flag) {
exit_code = 1;
fprintf(stderr, "Can't run this command in readonly mode.\n");
return;
}
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
/* reset the connection to get the most recent stuff */
slurmdb_connection_commit(db_conn, 0);
/* First identify the entity to add */
if (!xstrncasecmp(argv[0], "Account", MAX(command_len, 1))
|| !xstrncasecmp(argv[0], "Acct", MAX(command_len, 4))) {
error_code = sacctmgr_add_account((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Cluster", MAX(command_len, 2))) {
error_code = sacctmgr_add_cluster((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Coordinator", MAX(command_len, 2))) {
error_code = sacctmgr_add_coord((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Federation", MAX(command_len, 1))) {
error_code = sacctmgr_add_federation((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "QOS", MAX(command_len, 1))) {
error_code = sacctmgr_add_qos((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Resource", MAX(command_len, 1))) {
error_code = sacctmgr_add_res((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "User", MAX(command_len, 1))) {
error_code = sacctmgr_add_user((argc - 1), &argv[1]);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in add command\n");
fprintf(stderr, "Input line must include ");
fprintf(stderr, "\"Account\", \"Cluster\", \"Coordinator\", ");
fprintf(stderr, "\"Federation\", \"QOS\", \"Resource\", ");
fprintf(stderr, "or \"User\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
/*
* _archive_it - archive the entity per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _archive_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!have_db_conn) {
exit_code = 1;
return;
}
if (readonly_flag) {
exit_code = 1;
fprintf(stderr, "Can't run this command in readonly mode.\n");
return;
}
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
/* reset the connection to get the most recent stuff */
slurmdb_connection_commit(db_conn, 0);
/* First identify the entity to add */
if (xstrncasecmp(argv[0], "dump", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_archive_dump((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "load", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_archive_load((argc - 1), &argv[1]);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in archive command\n");
fprintf(stderr, "Input line must include, ");
fprintf(stderr, "\"Dump\", or \"load\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
/*
* _clear_it - Clear the slurm configuration per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _clear_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!have_db_conn) {
exit_code = 1;
return;
}
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
/* First identify the entity to list */
if (!xstrncasecmp(argv[0], "Stats", MAX(command_len, 1))) {
error_code = slurmdb_clear_stats(db_conn);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in list command\n");
fprintf(stderr, "Input line must include ");
fprintf(stderr, "\"Stats\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
/*
* _show_it - list the slurm configuration per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
* undocumented association options wopi and wopl
* without parent info and without parent limits
*/
static void _show_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
if (!have_db_conn &&
xstrncasecmp(argv[0], "Configuration",
MAX(command_len, 2))) {
exit_code = 1;
return;
}
/* reset the connection to get the most recent stuff */
slurmdb_connection_commit(db_conn, 0);
/* First identify the entity to list */
if (xstrncasecmp(argv[0], "Accounts", MAX(command_len, 2)) == 0
|| !xstrncasecmp(argv[0], "Acct", MAX(command_len, 4))) {
error_code = sacctmgr_list_account((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Associations",
MAX(command_len, 2)) == 0) {
error_code = sacctmgr_list_assoc((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Clusters",
MAX(command_len, 2)) == 0) {
error_code = sacctmgr_list_cluster((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Configuration",
MAX(command_len, 2)) == 0) {
error_code = sacctmgr_list_config();
} else if (xstrncasecmp(argv[0], "Events",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_event((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Federation",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_federation((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Instances",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_instance((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Problems",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_problem((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "RunawayJobs", MAX(command_len, 2)) ||
!xstrncasecmp(argv[0], "OrphanJobs", MAX(command_len, 1)) ||
!xstrncasecmp(argv[0], "LostJobs", MAX(command_len, 1))) {
error_code = sacctmgr_list_runaway_jobs((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "QOS", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_qos((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Resource", MAX(command_len, 4))) {
error_code = sacctmgr_list_res((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Reservations", MAX(command_len, 4))||
!xstrncasecmp(argv[0], "Resv", MAX(command_len, 4))) {
error_code = sacctmgr_list_reservation((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Stats", MAX(command_len, 1))) {
error_code = sacctmgr_list_stats((argc - 1), &argv[1]);
} else if (!xstrncasecmp(argv[0], "Transactions", MAX(command_len, 1))
|| !xstrncasecmp(argv[0], "Txn", MAX(command_len, 1))) {
error_code = sacctmgr_list_txn((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Users", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_user((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "WCKeys", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_list_wckey((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "tres", MAX(command_len, 2)) == 0) {
error_code = sacctmgr_list_tres(argc - 1, &argv[1]);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in list command\n");
fprintf(stderr, "Input line must include ");
fprintf(stderr, "\"Account\", \"Association\", "
"\"Cluster\", \"Configuration\",\n\"Event\", "
"\"Federation\", \"Problem\", \"QOS\", \"Resource\", "
"\"Reservation\",\n\"RunAwayJobs\", \"Stats\", "
"\"Transaction\", \"TRES\", \"User\", or \"WCKey\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
/*
* _modify_it - modify the slurm configuration per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _modify_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!have_db_conn) {
exit_code = 1;
return;
}
if (readonly_flag) {
exit_code = 1;
fprintf(stderr, "Can't run this command in readonly mode.\n");
return;
}
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
/* reset the connection to get the most recent stuff */
slurmdb_connection_commit(db_conn, 0);
/* First identify the entity to modify */
if (xstrncasecmp(argv[0], "Accounts", MAX(command_len, 1)) == 0
|| !xstrncasecmp(argv[0], "Acct", MAX(command_len, 4))) {
error_code = sacctmgr_modify_account((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Clusters",
MAX(command_len, 5)) == 0) {
error_code = sacctmgr_modify_cluster((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Federation",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_modify_federation((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Job", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_modify_job((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "QOSs", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_modify_qos((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Resource", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_modify_res((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Users", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_modify_user((argc - 1), &argv[1]);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in modify command\n");
fprintf(stderr, "Input line must include ");
fprintf(stderr, "\"Account\", \"Cluster\", \"Federation\", "
"\"Job\", \"QOS\", \"Resource\" or \"User\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
/*
* _delete_it - delete the slurm configuration per the supplied arguments
* IN argc - count of arguments
* IN argv - list of arguments
*/
static void _delete_it(int argc, char **argv)
{
int error_code = SLURM_SUCCESS;
int command_len = 0;
if (!have_db_conn) {
exit_code = 1;
return;
}
if (readonly_flag) {
exit_code = 1;
fprintf(stderr, "Can't run this command in readonly mode.\n");
return;
}
if (!argv[0])
goto helpme;
command_len = strlen(argv[0]);
/* reset the connection to get the most recent stuff */
slurmdb_connection_commit(db_conn, 0);
/* First identify the entity to delete */
if (xstrncasecmp(argv[0], "Accounts", MAX(command_len, 1)) == 0
|| !xstrncasecmp(argv[0], "Acct", MAX(command_len, 4))) {
error_code = sacctmgr_delete_account((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Clusters",
MAX(command_len, 2)) == 0) {
error_code = sacctmgr_delete_cluster((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Coordinators",
MAX(command_len, 2)) == 0) {
error_code = sacctmgr_delete_coord((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Federations",
MAX(command_len, 1)) == 0) {
error_code = sacctmgr_delete_federation((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "QOS", MAX(command_len, 2)) == 0) {
error_code = sacctmgr_delete_qos((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Resource", MAX(command_len, 1)) == 0){
error_code = sacctmgr_delete_res((argc - 1), &argv[1]);
} else if (xstrncasecmp(argv[0], "Users", MAX(command_len, 1)) == 0) {
error_code = sacctmgr_delete_user((argc - 1), &argv[1]);
} else {
helpme:
exit_code = 1;
fprintf(stderr, "No valid entity in delete command\n");
fprintf(stderr, "Input line must include ");
fprintf(stderr, "\"Account\", \"Cluster\", \"Coordinator\", ");
fprintf(stderr, "\"Federation\", \"QOS\", \"Resource\", or ");
fprintf(stderr, "\"User\"\n");
}
if (error_code != SLURM_SUCCESS) {
exit_code = 1;
}
}
static void _usage(void)
{
char *txt;
static_ref_to_cstring(txt, usage_txt);
printf("%s\n", txt);
xfree(txt);
}