blob: 13ccade8f8f7d06e0b0cdeba57754632af935afc [file] [log] [blame] [edit]
/*****************************************************************************\
* file_functions.c - functions dealing with files that are generated in the
* accounting system.
*****************************************************************************
* Copyright (C) 2008 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://computing.llnl.gov/linux/slurm/>.
* 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/sacctmgr/sacctmgr.h"
#include "src/common/uid.h"
typedef struct {
slurmdb_admin_level_t admin;
uint16_t classification;
List coord_list; /* char *list */
char *def_acct;
uint32_t def_qos_id;
char *def_wckey;
char *desc;
uint32_t fairshare;
uint64_t grp_cpu_mins;
uint32_t grp_cpus;
uint32_t grp_jobs;
uint32_t grp_nodes;
uint32_t grp_submit_jobs;
uint32_t grp_wall;
uint64_t max_cpu_mins_pj;
uint32_t max_cpus_pj;
uint32_t max_jobs;
uint32_t max_nodes_pj;
uint32_t max_submit_jobs;
uint32_t max_wall_pj;
char *name;
char *org;
char *part;
List qos_list;
List wckey_list;
} sacctmgr_file_opts_t;
typedef enum {
MOD_CLUSTER,
MOD_ACCT,
MOD_USER
} sacctmgr_mod_type_t;
static int _init_sacctmgr_file_opts(sacctmgr_file_opts_t *file_opts)
{
if (!file_opts)
return SLURM_ERROR;
memset(file_opts, 0, sizeof(sacctmgr_file_opts_t));
file_opts->admin = SLURMDB_ADMIN_NOTSET;
file_opts->fairshare = NO_VAL;
file_opts->def_qos_id = NO_VAL;
file_opts->grp_cpu_mins = (uint64_t)NO_VAL;
file_opts->grp_cpus = NO_VAL;
file_opts->grp_jobs = NO_VAL;
file_opts->grp_nodes = NO_VAL;
file_opts->grp_submit_jobs = NO_VAL;
file_opts->grp_wall = NO_VAL;
file_opts->max_cpu_mins_pj = (uint64_t)NO_VAL;
file_opts->max_cpus_pj = NO_VAL;
file_opts->max_jobs = NO_VAL;
file_opts->max_nodes_pj = NO_VAL;
file_opts->max_submit_jobs = NO_VAL;
file_opts->max_wall_pj = NO_VAL;
return SLURM_SUCCESS;
}
static int _strip_continuation(char *buf, int len)
{
char *ptr;
int bs = 0;
for (ptr = buf+len-1; ptr >= buf; ptr--) {
if (*ptr == '\\')
bs++;
else if (isspace(*ptr) && bs == 0)
continue;
else
break;
}
/* Check for an odd number of contiguous backslashes at
the end of the line */
if (bs % 2 == 1) {
ptr = ptr + bs;
*ptr = '\0';
return (ptr - buf);
} else {
return len; /* no continuation */
}
}
/* Strip comments from a line by terminating the string
* where the comment begins.
* Everything after a non-escaped "#" is a comment.
*/
static void _strip_comments(char *line)
{
int i;
int len = strlen(line);
int bs_count = 0;
for (i = 0; i < len; i++) {
/* if # character is preceded by an even number of
* escape characters '\' */
if (line[i] == '#' && (bs_count%2) == 0) {
line[i] = '\0';
break;
} else if (line[i] == '\\') {
bs_count++;
} else {
bs_count = 0;
}
}
}
/*
* Strips any escape characters, "\". If you WANT a back-slash,
* it must be escaped, "\\".
*/
static void _strip_escapes(char *line)
{
int i, j;
int len = strlen(line);
for (i = 0, j = 0; i < len+1; i++, j++) {
if (line[i] == '\\')
i++;
line[j] = line[i];
}
}
/*
* Reads the next line from the "file" into buffer "buf".
*
* Concatonates together lines that are continued on
* the next line by a trailing "\". Strips out comments,
* replaces escaped "\#" with "#", and replaces "\\" with "\".
*/
static int _get_next_line(char *buf, int buf_size, FILE *file)
{
char *ptr = buf;
int leftover = buf_size;
int read_size, new_size;
int lines = 0;
while (fgets(ptr, leftover, file)) {
lines++;
_strip_comments(ptr);
read_size = strlen(ptr);
new_size = _strip_continuation(ptr, read_size);
if (new_size < read_size) {
ptr += new_size;
leftover -= new_size;
} else { /* no continuation */
break;
}
}
/* _strip_cr_nl(buf); */ /* not necessary */
_strip_escapes(buf);
return lines;
}
static void _destroy_sacctmgr_file_opts(void *object)
{
sacctmgr_file_opts_t *file_opts = (sacctmgr_file_opts_t *)object;
if (file_opts) {
if (file_opts->coord_list)
list_destroy(file_opts->coord_list);
xfree(file_opts->def_acct);
xfree(file_opts->def_wckey);
xfree(file_opts->desc);
xfree(file_opts->name);
xfree(file_opts->org);
xfree(file_opts->part);
if (file_opts->qos_list) {
list_destroy(file_opts->qos_list);
file_opts->qos_list = NULL;
}
if (file_opts->wckey_list) {
list_destroy(file_opts->wckey_list);
file_opts->wckey_list = NULL;
}
xfree(file_opts);
}
}
static sacctmgr_file_opts_t *_parse_options(char *options)
{
int start=0, i=0, end=0, mins, quote = 0;
char *sub = NULL;
sacctmgr_file_opts_t *file_opts = xmalloc(sizeof(sacctmgr_file_opts_t));
char *option = NULL;
char quote_c = '\0';
int command_len = 0;
int option2 = 0;
_init_sacctmgr_file_opts(file_opts);
while (options[i]) {
quote = 0;
start=i;
while (options[i] && options[i] != ':' && options[i] != '\n') {
if (options[i] == '"' || options[i] == '\'') {
if (quote) {
if (options[i] == quote_c)
quote = 0;
} else {
quote = 1;
quote_c = options[i];
}
}
i++;
}
if (quote) {
while (options[i] && options[i] != quote_c)
i++;
if (!options[i])
fatal("There is a problem with option "
"%s with quotes.", option);
i++;
}
if (i-start <= 0)
goto next_col;
sub = xstrndup(options+start, i-start);
end = parse_option_end(sub);
command_len = end - 1;
if (sub[end] == '=') {
option2 = (int)sub[end-1];
end++;
}
option = strip_quotes(sub+end, NULL, 1);
if (!end) {
if (file_opts->name) {
exit_code=1;
fprintf(stderr, " Bad format on %s: "
"End your option with "
"an '=' sign\n", sub);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
file_opts->name = xstrdup(option);
} else if (end && !strlen(option)) {
debug("blank field given for %s discarding", sub);
} else if (!strncasecmp (sub, "AdminLevel",
MAX(command_len, 2))) {
file_opts->admin = str_2_slurmdb_admin_level(option);
} else if (!strncasecmp (sub, "Coordinator",
MAX(command_len, 2))) {
if (!file_opts->coord_list)
file_opts->coord_list =
list_create(slurm_destroy_char);
slurm_addto_char_list(file_opts->coord_list, option);
} else if (!strncasecmp (sub, "Classification",
MAX(command_len, 2))) {
file_opts->classification =
str_2_classification(option);
} else if (!strncasecmp (sub, "DefaultAccount",
MAX(command_len, 8))) {
file_opts->def_acct = xstrdup(option);
} else if (!strncasecmp (sub, "DefaultQOS",
MAX(command_len, 8))) {
if (!g_qos_list) {
g_qos_list = acct_storage_g_get_qos(
db_conn, my_uid, NULL);
}
file_opts->def_qos_id = str_2_slurmdb_qos(
g_qos_list, option);
if (file_opts->def_qos_id == NO_VAL) {
fprintf(stderr,
"You gave a bad qos '%s'. "
"Use 'list qos' to get "
"complete list.\n",
option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "DefaultWCKey",
MAX(command_len, 8))) {
file_opts->def_wckey = xstrdup(option);
if (!file_opts->wckey_list)
file_opts->wckey_list =
list_create(slurm_destroy_char);
slurm_addto_char_list(file_opts->wckey_list, option);
} else if (!strncasecmp (sub, "Description",
MAX(command_len, 3))) {
file_opts->desc = xstrdup(option);
} else if (!strncasecmp (sub, "FairShare",
MAX(command_len, 1))
|| !strncasecmp (sub, "Shares",
MAX(command_len, 1))) {
if (get_uint(option, &file_opts->fairshare,
"FairShare") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad FairShare value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpCPUMins",
MAX(command_len, 7))) {
if (get_uint64(option, &file_opts->grp_cpu_mins,
"GrpCPUMins") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad GrpCPUMins value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpCPUs", MAX(command_len, 7))) {
if (get_uint(option, &file_opts->grp_cpus,
"GrpCPUs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad GrpCPUs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpJobs", MAX(command_len, 4))) {
if (get_uint(option, &file_opts->grp_jobs,
"GrpJobs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad GrpJobs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpNodes",
MAX(command_len, 4))) {
if (get_uint(option, &file_opts->grp_nodes,
"GrpNodes") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad GrpNodes value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpSubmitJobs",
MAX(command_len, 4))) {
if (get_uint(option, &file_opts->grp_submit_jobs,
"GrpSubmitJobs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad GrpJobs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "GrpWall", MAX(command_len, 4))) {
mins = time_str2mins(option);
if (mins >= 0) {
file_opts->grp_wall
= (uint32_t) mins;
} else if (strcmp(option, "-1")) {
file_opts->grp_wall = INFINITE;
} else {
exit_code=1;
fprintf(stderr,
" Bad GrpWall time format: %s\n",
option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxCPUMinsPerJob",
MAX(command_len, 7))
|| !strncasecmp (sub, "MaxProcSecPerJob",
MAX(command_len, 4))) {
if (get_uint64(option, &file_opts->max_cpu_mins_pj,
"MaxCPUMins") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad MaxCPUMins value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxCPUsPerJob",
MAX(command_len, 7))) {
if (get_uint(option, &file_opts->max_cpus_pj,
"MaxCPUs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad MaxCPUs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxJobs", MAX(command_len, 4))) {
if (get_uint(option, &file_opts->max_jobs,
"MaxJobs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad MaxJobs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxNodesPerJob",
MAX(command_len, 4))) {
if (get_uint(option, &file_opts->max_nodes_pj,
"MaxNodes") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad MaxNodes value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxSubmitJobs",
MAX(command_len, 4))) {
if (get_uint(option, &file_opts->max_submit_jobs,
"MaxSubmitJobs") != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Bad MaxJobs value: %s\n", option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "MaxWallDurationPerJob",
MAX(command_len, 4))) {
mins = time_str2mins(option);
if (mins >= 0) {
file_opts->max_wall_pj
= (uint32_t) mins;
} else if (strcmp(option, "-1")) {
file_opts->max_wall_pj = INFINITE;
} else {
exit_code=1;
fprintf(stderr,
" Bad MaxWall time format: %s\n",
option);
_destroy_sacctmgr_file_opts(file_opts);
break;
}
} else if (!strncasecmp (sub, "Organization",
MAX(command_len, 1))) {
file_opts->org = xstrdup(option);
} else if (!strncasecmp (sub, "Partition",
MAX(command_len, 1))) {
file_opts->part = xstrdup(option);
} else if (!strncasecmp (sub, "QosLevel", MAX(command_len, 1))
|| !strncasecmp (sub, "Expedite",
MAX(command_len, 1))) {
if (!file_opts->qos_list) {
file_opts->qos_list =
list_create(slurm_destroy_char);
}
if (!g_qos_list) {
g_qos_list = acct_storage_g_get_qos(
db_conn, my_uid, NULL);
}
slurmdb_addto_qos_char_list(file_opts->qos_list,
g_qos_list,
option, option2);
} else if (!strncasecmp (sub, "WCKeys",
MAX(command_len, 2))) {
if (!file_opts->wckey_list)
file_opts->wckey_list =
list_create(slurm_destroy_char);
slurm_addto_char_list(file_opts->wckey_list, option);
} else {
exit_code=1;
fprintf(stderr, " Unknown option: %s\n", sub);
}
xfree(sub);
xfree(option);
next_col:
if (options[i] == ':')
i++;
else
break;
}
xfree(sub);
xfree(option);
if (!file_opts->name) {
exit_code=1;
fprintf(stderr, " No name given\n");
_destroy_sacctmgr_file_opts(file_opts);
file_opts = NULL;
} else if (exit_code) {
_destroy_sacctmgr_file_opts(file_opts);
file_opts = NULL;
}
return file_opts;
}
static int _print_out_assoc(List assoc_list, bool user, bool add)
{
List format_list = NULL;
List print_fields_list = NULL;
ListIterator itr, itr2;
print_field_t *field = NULL;
slurmdb_association_rec_t *assoc = NULL;
int rc = SLURM_SUCCESS;
char *tmp_char = NULL;
if (!assoc_list || !list_count(assoc_list))
return rc;
format_list = list_create(slurm_destroy_char);
if (user)
slurm_addto_char_list(format_list,
"User,Account");
else
slurm_addto_char_list(format_list,
"Account,ParentName");
slurm_addto_char_list(format_list,
"Share,GrpCPUM,GrpCPUs,"
"GrpJ,GrpN,GrpS,GrpW,MaxCPUM,MaxCPUs,"
"MaxJ,MaxS,MaxN,MaxW,QOS,DefaultQOS");
print_fields_list = sacctmgr_process_format_list(format_list);
list_destroy(format_list);
print_fields_header(print_fields_list);
itr = list_iterator_create(assoc_list);
itr2 = list_iterator_create(print_fields_list);
while ((assoc = list_next(itr))) {
while ((field = list_next(itr2))) {
switch(field->type) {
case PRINT_ACCT:
field->print_routine(field,
assoc->acct);
break;
case PRINT_DQOS:
if (!g_qos_list)
g_qos_list = acct_storage_g_get_qos(
db_conn,
my_uid,
NULL);
tmp_char = slurmdb_qos_str(
g_qos_list,
assoc->def_qos_id);
field->print_routine(
field,
tmp_char);
break;
case PRINT_FAIRSHARE:
field->print_routine(field,
assoc->shares_raw);
break;
case PRINT_GRPCM:
field->print_routine(
field,
assoc->grp_cpu_mins);
break;
case PRINT_GRPC:
field->print_routine(field,
assoc->grp_cpus);
break;
case PRINT_GRPJ:
field->print_routine(field,
assoc->grp_jobs);
break;
case PRINT_GRPN:
field->print_routine(field,
assoc->grp_nodes);
break;
case PRINT_GRPS:
field->print_routine(field,
assoc->grp_submit_jobs);
break;
case PRINT_GRPW:
field->print_routine(
field,
assoc->grp_wall);
break;
case PRINT_MAXCM:
field->print_routine(
field,
assoc->max_cpu_mins_pj);
break;
case PRINT_MAXC:
field->print_routine(field,
assoc->max_cpus_pj);
break;
case PRINT_MAXJ:
field->print_routine(field,
assoc->max_jobs);
break;
case PRINT_MAXN:
field->print_routine(field,
assoc->max_nodes_pj);
break;
case PRINT_MAXS:
field->print_routine(field,
assoc->max_submit_jobs);
break;
case PRINT_MAXW:
field->print_routine(
field,
assoc->max_wall_pj);
break;
case PRINT_PNAME:
field->print_routine(field,
assoc->parent_acct);
break;
case PRINT_PART:
field->print_routine(field,
assoc->partition);
break;
case PRINT_QOS:
if (!g_qos_list)
g_qos_list = acct_storage_g_get_qos(
db_conn, my_uid, NULL);
field->print_routine(
field,
g_qos_list,
assoc->qos_list);
break;
case PRINT_USER:
field->print_routine(field,
assoc->user);
break;
default:
field->print_routine(
field, NULL);
break;
}
}
list_iterator_reset(itr2);
printf("\n");
}
list_iterator_destroy(itr);
list_iterator_destroy(itr2);
list_destroy(print_fields_list);
if (add)
rc = acct_storage_g_add_associations(db_conn,
my_uid, assoc_list);
printf("--------------------------------------------------------------\n\n");
return rc;
}
static int _mod_assoc(sacctmgr_file_opts_t *file_opts,
slurmdb_association_rec_t *assoc,
sacctmgr_mod_type_t mod_type,
char *parent)
{
int changed = 0;
slurmdb_association_rec_t mod_assoc;
slurmdb_association_cond_t assoc_cond;
char *type = NULL;
char *name = NULL;
char *my_info = NULL;
switch(mod_type) {
case MOD_CLUSTER:
type = "Cluster";
name = assoc->cluster;
break;
case MOD_ACCT:
type = "Account";
name = assoc->acct;
break;
case MOD_USER:
type = "User";
name = assoc->user;
break;
default:
return 0;
break;
}
slurmdb_init_association_rec(&mod_assoc, 0);
memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
if ((file_opts->fairshare != NO_VAL)
&& (assoc->shares_raw != file_opts->fairshare)) {
mod_assoc.shares_raw = file_opts->fairshare;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed fairshare",
type, name,
assoc->shares_raw,
file_opts->fairshare);
}
if ((file_opts->grp_cpu_mins != NO_VAL)
&& (assoc->grp_cpu_mins != file_opts->grp_cpu_mins)) {
mod_assoc.grp_cpu_mins = file_opts->grp_cpu_mins;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s "
"%8"PRIu64" -> %"PRIu64"\n",
" Changed GrpCPUMins",
type, name,
assoc->grp_cpu_mins,
file_opts->grp_cpu_mins);
}
if ((file_opts->grp_cpus != NO_VAL)
&& (assoc->grp_cpus != file_opts->grp_cpus)) {
mod_assoc.grp_cpus = file_opts->grp_cpus;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed GrpCpus",
type, name,
assoc->grp_cpus,
file_opts->grp_cpus);
}
if ((file_opts->grp_jobs != NO_VAL)
&& (assoc->grp_jobs != file_opts->grp_jobs)) {
mod_assoc.grp_jobs = file_opts->grp_jobs;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed GrpJobs",
type, name,
assoc->grp_jobs,
file_opts->grp_jobs);
}
if ((file_opts->grp_nodes != NO_VAL)
&& (assoc->grp_nodes != file_opts->grp_nodes)) {
mod_assoc.grp_nodes = file_opts->grp_nodes;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed GrpNodes",
type, name,
assoc->grp_nodes,
file_opts->grp_nodes);
}
if ((file_opts->grp_submit_jobs != NO_VAL)
&& (assoc->grp_submit_jobs != file_opts->grp_submit_jobs)) {
mod_assoc.grp_submit_jobs = file_opts->grp_submit_jobs;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed GrpSubmitJobs",
type, name,
assoc->grp_submit_jobs,
file_opts->grp_submit_jobs);
}
if ((file_opts->grp_wall != NO_VAL)
&& (assoc->grp_wall != file_opts->grp_wall)) {
mod_assoc.grp_wall = file_opts->grp_wall;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed GrpWallDuration",
type, name,
assoc->grp_wall,
file_opts->grp_wall);
}
if ((file_opts->max_cpu_mins_pj != (uint64_t)NO_VAL)
&& (assoc->max_cpu_mins_pj != file_opts->max_cpu_mins_pj)) {
mod_assoc.max_cpu_mins_pj =
file_opts->max_cpu_mins_pj;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s "
"%8"PRIu64" -> %"PRIu64"\n",
" Changed MaxCPUMinsPerJob",
type, name,
assoc->max_cpu_mins_pj,
file_opts->max_cpu_mins_pj);
}
if ((file_opts->max_cpus_pj != NO_VAL)
&& (assoc->max_cpus_pj != file_opts->max_cpus_pj)) {
mod_assoc.max_cpus_pj = file_opts->max_cpus_pj;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed MaxCpusPerJob",
type, name,
assoc->max_cpus_pj,
file_opts->max_cpus_pj);
}
if ((file_opts->max_jobs != NO_VAL)
&& (assoc->max_jobs != file_opts->max_jobs)) {
mod_assoc.max_jobs = file_opts->max_jobs;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed MaxJobs",
type, name,
assoc->max_jobs,
file_opts->max_jobs);
}
if ((file_opts->max_nodes_pj != NO_VAL)
&& (assoc->max_nodes_pj != file_opts->max_nodes_pj)) {
mod_assoc.max_nodes_pj = file_opts->max_nodes_pj;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed MaxNodesPerJob",
type, name,
assoc->max_nodes_pj,
file_opts->max_nodes_pj);
}
if ((file_opts->max_submit_jobs != NO_VAL)
&& (assoc->max_submit_jobs != file_opts->max_submit_jobs)) {
mod_assoc.max_submit_jobs = file_opts->max_submit_jobs;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed MaxSubmitJobs",
type, name,
assoc->max_submit_jobs,
file_opts->max_submit_jobs);
}
if ((file_opts->max_wall_pj != NO_VAL)
&& (assoc->max_wall_pj != file_opts->max_wall_pj)) {
mod_assoc.max_wall_pj = file_opts->max_wall_pj;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8d -> %d\n",
" Changed MaxWallDurationPerJob",
type, name,
assoc->max_wall_pj,
file_opts->max_wall_pj);
}
if (assoc->parent_acct && parent
&& strcmp(assoc->parent_acct, parent)) {
mod_assoc.parent_acct = parent;
changed = 1;
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed Parent",
type, name,
assoc->parent_acct,
parent);
}
if (assoc->qos_list && list_count(assoc->qos_list)
&& file_opts->qos_list && list_count(file_opts->qos_list)) {
ListIterator now_qos_itr =
list_iterator_create(assoc->qos_list),
new_qos_itr = list_iterator_create(file_opts->qos_list);
char *now_qos = NULL, *new_qos = NULL;
if (!mod_assoc.qos_list)
mod_assoc.qos_list = list_create(slurm_destroy_char);
while ((new_qos = list_next(new_qos_itr))) {
while ((now_qos = list_next(now_qos_itr))) {
if (!strcmp(new_qos, now_qos))
break;
}
list_iterator_reset(now_qos_itr);
if (!now_qos)
list_append(mod_assoc.qos_list,
xstrdup(new_qos));
}
list_iterator_destroy(new_qos_itr);
list_iterator_destroy(now_qos_itr);
if (mod_assoc.qos_list && list_count(mod_assoc.qos_list))
new_qos = get_qos_complete_str(g_qos_list,
mod_assoc.qos_list);
if (new_qos) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s\n",
" Added QOS",
type, name,
new_qos);
xfree(new_qos);
changed = 1;
} else {
list_destroy(mod_assoc.qos_list);
mod_assoc.qos_list = NULL;
}
} else if (file_opts->qos_list && list_count(file_opts->qos_list)) {
char *new_qos = get_qos_complete_str(g_qos_list,
file_opts->qos_list);
if (new_qos) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s\n",
" Added QOS",
type, name,
new_qos);
xfree(new_qos);
mod_assoc.qos_list = file_opts->qos_list;
file_opts->qos_list = NULL;
changed = 1;
}
}
if (changed) {
List ret_list = NULL;
assoc_cond.cluster_list = list_create(NULL);
list_push(assoc_cond.cluster_list, assoc->cluster);
assoc_cond.acct_list = list_create(NULL);
list_push(assoc_cond.acct_list, assoc->acct);
if (mod_type == MOD_USER) {
assoc_cond.user_list = list_create(NULL);
list_push(assoc_cond.user_list, assoc->user);
if (assoc->partition) {
assoc_cond.partition_list = list_create(NULL);
list_push(assoc_cond.partition_list,
assoc->partition);
}
}
notice_thread_init();
ret_list = acct_storage_g_modify_associations(
db_conn, my_uid,
&assoc_cond,
&mod_assoc);
notice_thread_fini();
if (mod_assoc.qos_list)
list_destroy(mod_assoc.qos_list);
list_destroy(assoc_cond.cluster_list);
list_destroy(assoc_cond.acct_list);
if (assoc_cond.user_list)
list_destroy(assoc_cond.user_list);
if (assoc_cond.partition_list)
list_destroy(assoc_cond.partition_list);
/* if (ret_list && list_count(ret_list)) { */
/* char *object = NULL; */
/* ListIterator itr = list_iterator_create(ret_list); */
/* printf(" Modified account defaults for " */
/* "associations...\n"); */
/* while ((object = list_next(itr))) */
/* printf(" %s\n", object); */
/* list_iterator_destroy(itr); */
/* } */
if (ret_list) {
printf("%s", my_info);
list_destroy(ret_list);
} else
changed = 0;
xfree(my_info);
}
return changed;
}
static int _mod_cluster(sacctmgr_file_opts_t *file_opts,
slurmdb_cluster_rec_t *cluster, char *parent)
{
int changed = 0;
char *my_info = NULL;
slurmdb_cluster_rec_t mod_cluster;
slurmdb_cluster_cond_t cluster_cond;
slurmdb_init_cluster_rec(&mod_cluster, 0);
slurmdb_init_cluster_cond(&cluster_cond, 0);
if (file_opts->classification
&& (file_opts->classification != cluster->classification)) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed Classification", "Cluster",
cluster->name,
get_classification_str(cluster->classification),
get_classification_str(file_opts->classification));
mod_cluster.classification = file_opts->classification;
changed = 1;
}
if (changed) {
List ret_list = NULL;
cluster_cond.cluster_list = list_create(NULL);
list_append(cluster_cond.cluster_list, cluster->name);
notice_thread_init();
ret_list = acct_storage_g_modify_clusters(db_conn, my_uid,
&cluster_cond,
&mod_cluster);
notice_thread_fini();
list_destroy(cluster_cond.cluster_list);
/* if (ret_list && list_count(ret_list)) { */
/* char *object = NULL; */
/* ListIterator itr = list_iterator_create(ret_list); */
/* printf(" Modified account defaults for " */
/* "associations...\n"); */
/* while ((object = list_next(itr))) */
/* printf(" %s\n", object); */
/* list_iterator_destroy(itr); */
/* } */
if (ret_list) {
printf("%s", my_info);
list_destroy(ret_list);
} else
changed = 0;
xfree(my_info);
}
if (!cluster->root_assoc || !cluster->root_assoc->cluster) {
error("Cluster %s doesn't appear to have a root association. "
"Try removing this cluster and then re-run load.",
cluster->name);
exit(1);
}
changed += _mod_assoc(file_opts, cluster->root_assoc,
MOD_CLUSTER, parent);
return changed;
}
static int _mod_acct(sacctmgr_file_opts_t *file_opts,
slurmdb_account_rec_t *acct, char *parent)
{
int changed = 0;
char *desc = NULL, *org = NULL, *my_info = NULL;
slurmdb_account_rec_t mod_acct;
slurmdb_account_cond_t acct_cond;
slurmdb_association_cond_t assoc_cond;
memset(&mod_acct, 0, sizeof(slurmdb_account_rec_t));
memset(&acct_cond, 0, sizeof(slurmdb_account_cond_t));
memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
if (file_opts->desc)
desc = xstrdup(file_opts->desc);
if (desc && strcmp(desc, acct->description)) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed description", "Account",
acct->name,
acct->description,
desc);
mod_acct.description = desc;
changed = 1;
} else
xfree(desc);
if (file_opts->org)
org = xstrdup(file_opts->org);
if (org && strcmp(org, acct->organization)) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed organization", "Account",
acct->name,
acct->organization,
org);
mod_acct.organization = org;
changed = 1;
} else
xfree(org);
if (changed) {
List ret_list = NULL;
assoc_cond.acct_list = list_create(NULL);
list_append(assoc_cond.acct_list, acct->name);
acct_cond.assoc_cond = &assoc_cond;
notice_thread_init();
ret_list = acct_storage_g_modify_accounts(db_conn, my_uid,
&acct_cond,
&mod_acct);
notice_thread_fini();
list_destroy(assoc_cond.acct_list);
/* if (ret_list && list_count(ret_list)) { */
/* char *object = NULL; */
/* ListIterator itr = list_iterator_create(ret_list); */
/* printf(" Modified account defaults for " */
/* "associations...\n"); */
/* while ((object = list_next(itr))) */
/* printf(" %s\n", object); */
/* list_iterator_destroy(itr); */
/* } */
if (ret_list) {
printf("%s", my_info);
list_destroy(ret_list);
} else
changed = 0;
xfree(my_info);
}
xfree(desc);
xfree(org);
return changed;
}
static int _mod_user(sacctmgr_file_opts_t *file_opts,
slurmdb_user_rec_t *user, char *cluster, char *parent)
{
int rc;
int set = 0;
int changed = 0;
char *def_acct = NULL, *def_wckey = NULL, *my_info = NULL;
slurmdb_user_rec_t mod_user;
slurmdb_user_cond_t user_cond;
List ret_list = NULL;
slurmdb_association_cond_t assoc_cond;
if (!user || !user->name) {
fatal(" We need a user name in _mod_user");
}
memset(&mod_user, 0, sizeof(slurmdb_user_rec_t));
memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
assoc_cond.user_list = list_create(NULL);
list_append(assoc_cond.user_list, user->name);
user_cond.assoc_cond = &assoc_cond;
if (file_opts->def_acct)
def_acct = xstrdup(file_opts->def_acct);
if (def_acct &&
(!user->default_acct || strcmp(def_acct, user->default_acct))) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed Default Account", "User",
user->name,
user->default_acct,
def_acct);
mod_user.default_acct = def_acct;
changed = 1;
}
if (file_opts->def_wckey)
def_wckey = xstrdup(file_opts->def_wckey);
if (def_wckey &&
(!user->default_wckey || strcmp(def_wckey, user->default_wckey))) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed Default WCKey", "User",
user->name,
user->default_wckey,
def_wckey);
mod_user.default_wckey = def_wckey;
changed = 1;
}
if (user->admin_level != SLURMDB_ADMIN_NOTSET
&& file_opts->admin != SLURMDB_ADMIN_NOTSET
&& user->admin_level != file_opts->admin) {
xstrfmtcat(my_info,
"%-30.30s for %-7.7s %-10.10s %8s -> %s\n",
" Changed Admin Level", "User",
user->name,
slurmdb_admin_level_str(
user->admin_level),
slurmdb_admin_level_str(
file_opts->admin));
mod_user.admin_level = file_opts->admin;
changed = 1;
}
if (changed) {
notice_thread_init();
ret_list = acct_storage_g_modify_users(
db_conn, my_uid,
&user_cond,
&mod_user);
notice_thread_fini();
/* if (ret_list && list_count(ret_list)) { */
/* char *object = NULL; */
/* ListIterator itr = list_iterator_create(ret_list); */
/* printf(" Modified user defaults for " */
/* "associations...\n"); */
/* while ((object = list_next(itr))) */
/* printf(" %s\n", object); */
/* list_iterator_destroy(itr); */
/* } */
if (ret_list) {
printf("%s", my_info);
list_destroy(ret_list);
set = 1;
}
xfree(my_info);
}
xfree(def_acct);
xfree(def_wckey);
if ((!user->coord_accts || !list_count(user->coord_accts))
&& (file_opts->coord_list
&& list_count(file_opts->coord_list))) {
ListIterator coord_itr = NULL;
char *temp_char = NULL;
slurmdb_coord_rec_t *coord = NULL;
int first = 1;
notice_thread_init();
rc = acct_storage_g_add_coord(db_conn, my_uid,
file_opts->coord_list,
&user_cond);
notice_thread_fini();
user->coord_accts = list_create(slurmdb_destroy_coord_rec);
coord_itr = list_iterator_create(file_opts->coord_list);
printf(" Making User '%s' coordinator for account(s)",
user->name);
while ((temp_char = list_next(coord_itr))) {
coord = xmalloc(sizeof(slurmdb_coord_rec_t));
coord->name = xstrdup(temp_char);
coord->direct = 1;
list_push(user->coord_accts, coord);
if (first) {
printf(" %s", temp_char);
first = 0;
} else
printf(", %s", temp_char);
}
list_iterator_destroy(coord_itr);
printf("\n");
set = 1;
} else if ((user->coord_accts && list_count(user->coord_accts))
&& (file_opts->coord_list
&& list_count(file_opts->coord_list))) {
ListIterator coord_itr = NULL;
ListIterator char_itr = NULL;
char *temp_char = NULL;
slurmdb_coord_rec_t *coord = NULL;
List add_list = list_create(NULL);
coord_itr = list_iterator_create(user->coord_accts);
char_itr = list_iterator_create(file_opts->coord_list);
while ((temp_char = list_next(char_itr))) {
while ((coord = list_next(coord_itr))) {
if (!coord->direct)
continue;
if (!strcmp(coord->name, temp_char)) {
break;
}
}
if (!coord) {
printf(" Making User '%s' coordinator of "
"account '%s'\n",
user->name,
temp_char);
list_append(add_list, temp_char);
}
list_iterator_reset(coord_itr);
}
list_iterator_destroy(char_itr);
list_iterator_destroy(coord_itr);
if (list_count(add_list)) {
notice_thread_init();
rc = acct_storage_g_add_coord(db_conn, my_uid,
add_list,
&user_cond);
notice_thread_fini();
set = 1;
}
list_destroy(add_list);
}
if ((!user->wckey_list || !list_count(user->wckey_list))
&& (file_opts->wckey_list
&& list_count(file_opts->wckey_list))) {
ListIterator wckey_itr = NULL;
char *temp_char = NULL;
slurmdb_wckey_rec_t *wckey = NULL;
int first = 1;
user->wckey_list = list_create(slurmdb_destroy_wckey_rec);
wckey_itr = list_iterator_create(file_opts->wckey_list);
printf(" Adding WCKey(s) ");
while ((temp_char = list_next(wckey_itr))) {
wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
wckey->name = xstrdup(temp_char);
wckey->cluster = xstrdup(cluster);
wckey->user = xstrdup(user->name);
if (!strcmp(wckey->name, user->default_wckey))
wckey->is_def = 1;
list_push(user->wckey_list, wckey);
if (first) {
printf("'%s'", temp_char);
first = 0;
} else
printf(", '%s'", temp_char);
}
list_iterator_destroy(wckey_itr);
printf(" for user '%s'\n", user->name);
set = 1;
notice_thread_init();
rc = acct_storage_g_add_wckeys(db_conn, my_uid,
user->wckey_list);
notice_thread_fini();
} else if ((user->wckey_list && list_count(user->wckey_list))
&& (file_opts->wckey_list
&& list_count(file_opts->wckey_list))) {
ListIterator wckey_itr = NULL;
ListIterator char_itr = NULL;
char *temp_char = NULL;
slurmdb_wckey_rec_t *wckey = NULL;
List add_list = list_create(slurmdb_destroy_wckey_rec);
wckey_itr = list_iterator_create(user->wckey_list);
char_itr = list_iterator_create(file_opts->wckey_list);
while ((temp_char = list_next(char_itr))) {
while ((wckey = list_next(wckey_itr))) {
if (!strcmp(wckey->name, temp_char))
break;
}
if (!wckey) {
printf(" Adding WCKey '%s' to User '%s'\n",
temp_char, user->name);
wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
wckey->name = xstrdup(temp_char);
wckey->cluster = xstrdup(cluster);
wckey->user = xstrdup(user->name);
if (!strcmp(wckey->name, user->default_wckey))
wckey->is_def = 1;
list_append(add_list, wckey);
}
list_iterator_reset(wckey_itr);
}
list_iterator_destroy(char_itr);
list_iterator_destroy(wckey_itr);
if (list_count(add_list)) {
notice_thread_init();
rc = acct_storage_g_add_wckeys(db_conn, my_uid,
add_list);
notice_thread_fini();
set = 1;
}
list_transfer(user->wckey_list, add_list);
list_destroy(add_list);
}
list_destroy(assoc_cond.user_list);
return set;
}
static slurmdb_user_rec_t *_set_user_up(sacctmgr_file_opts_t *file_opts,
char *cluster, char *parent)
{
slurmdb_user_rec_t *user = xmalloc(sizeof(slurmdb_user_rec_t));
user->assoc_list = NULL;
user->name = xstrdup(file_opts->name);
if (file_opts->def_acct)
user->default_acct = xstrdup(file_opts->def_acct);
else
user->default_acct = xstrdup(parent);
if (file_opts->def_wckey)
user->default_wckey = xstrdup(file_opts->def_wckey);
else
user->default_wckey = xstrdup("");
user->admin_level = file_opts->admin;
if (file_opts->coord_list) {
slurmdb_user_cond_t user_cond;
slurmdb_association_cond_t assoc_cond;
ListIterator coord_itr = NULL;
char *temp_char = NULL;
slurmdb_coord_rec_t *coord = NULL;
memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
memset(&assoc_cond, 0, sizeof(slurmdb_association_cond_t));
assoc_cond.user_list = list_create(NULL);
list_append(assoc_cond.user_list, user->name);
user_cond.assoc_cond = &assoc_cond;
notice_thread_init();
acct_storage_g_add_coord(db_conn, my_uid,
file_opts->coord_list,
&user_cond);
notice_thread_fini();
list_destroy(assoc_cond.user_list);
user->coord_accts = list_create(slurmdb_destroy_coord_rec);
coord_itr = list_iterator_create(file_opts->coord_list);
while ((temp_char = list_next(coord_itr))) {
coord = xmalloc(sizeof(slurmdb_coord_rec_t));
coord->name = xstrdup(temp_char);
coord->direct = 1;
list_push(user->coord_accts, coord);
}
list_iterator_destroy(coord_itr);
}
if (file_opts->wckey_list) {
ListIterator wckey_itr = NULL;
char *temp_char = NULL;
slurmdb_wckey_rec_t *wckey = NULL;
user->wckey_list = list_create(slurmdb_destroy_wckey_rec);
wckey_itr = list_iterator_create(file_opts->wckey_list);
while ((temp_char = list_next(wckey_itr))) {
wckey = xmalloc(sizeof(slurmdb_wckey_rec_t));
wckey->name = xstrdup(temp_char);
wckey->user = xstrdup(user->name);
wckey->cluster = xstrdup(cluster);
if (!strcmp(wckey->name, user->default_wckey))
wckey->is_def = 1;
list_push(user->wckey_list, wckey);
}
list_iterator_destroy(wckey_itr);
notice_thread_init();
acct_storage_g_add_wckeys(db_conn, my_uid, user->wckey_list);
notice_thread_fini();
}
return user;
}
static slurmdb_account_rec_t *_set_acct_up(sacctmgr_file_opts_t *file_opts,
char *parent)
{
slurmdb_account_rec_t *acct = xmalloc(sizeof(slurmdb_account_rec_t));
acct->assoc_list = NULL;
acct->name = xstrdup(file_opts->name);
if (file_opts->desc)
acct->description = xstrdup(file_opts->desc);
else
acct->description = xstrdup(file_opts->name);
if (file_opts->org)
acct->organization = xstrdup(file_opts->org);
else if (strcmp(parent, "root"))
acct->organization = xstrdup(parent);
else
acct->organization = xstrdup(file_opts->name);
/* info("adding account %s (%s) (%s)", */
/* acct->name, acct->description, */
/* acct->organization); */
return acct;
}
static slurmdb_association_rec_t *_set_assoc_up(sacctmgr_file_opts_t *file_opts,
sacctmgr_mod_type_t mod_type,
char *cluster, char *parent)
{
slurmdb_association_rec_t *assoc = NULL;
if (!cluster) {
error("No cluster name was given for _set_assoc_up");
return NULL;
}
if (!parent && (mod_type != MOD_CLUSTER)) {
error("No parent was given for _set_assoc_up");
return NULL;
}
assoc = xmalloc(sizeof(slurmdb_association_rec_t));
slurmdb_init_association_rec(assoc, 0);
switch(mod_type) {
case MOD_CLUSTER:
assoc->acct = xstrdup(parent);
assoc->cluster = xstrdup(cluster);
break;
case MOD_ACCT:
assoc->acct = xstrdup(file_opts->name);
assoc->cluster = xstrdup(cluster);
assoc->parent_acct = xstrdup(parent);
break;
case MOD_USER:
assoc->acct = xstrdup(parent);
assoc->cluster = xstrdup(cluster);
assoc->partition = xstrdup(file_opts->part);
assoc->user = xstrdup(file_opts->name);
if (!strcmp(assoc->acct, file_opts->def_acct))
assoc->is_def = 1;
break;
default:
error("Unknown mod type for _set_assoc_up %d", mod_type);
slurmdb_destroy_association_rec(assoc);
assoc = NULL;
break;
}
assoc->shares_raw = file_opts->fairshare;
assoc->def_qos_id = file_opts->def_qos_id;
assoc->grp_cpu_mins = file_opts->grp_cpu_mins;
assoc->grp_cpus = file_opts->grp_cpus;
assoc->grp_jobs = file_opts->grp_jobs;
assoc->grp_nodes = file_opts->grp_nodes;
assoc->grp_submit_jobs = file_opts->grp_submit_jobs;
assoc->grp_wall = file_opts->grp_wall;
assoc->max_cpu_mins_pj = file_opts->max_cpu_mins_pj;
assoc->max_cpus_pj = file_opts->max_cpus_pj;
assoc->max_jobs = file_opts->max_jobs;
assoc->max_nodes_pj = file_opts->max_nodes_pj;
assoc->max_submit_jobs = file_opts->max_submit_jobs;
assoc->max_wall_pj = file_opts->max_wall_pj;
if (file_opts->qos_list && list_count(file_opts->qos_list))
assoc->qos_list = copy_char_list(file_opts->qos_list);
return assoc;
}
static int _print_file_slurmdb_hierarchical_rec_childern(
FILE *fd, List slurmdb_hierarchical_rec_list,
List user_list, List acct_list)
{
ListIterator itr = NULL;
slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
char *line = NULL;
slurmdb_user_rec_t *user_rec = NULL;
slurmdb_account_rec_t *acct_rec = NULL;
itr = list_iterator_create(slurmdb_hierarchical_rec_list);
while ((slurmdb_hierarchical_rec = list_next(itr))) {
if (slurmdb_hierarchical_rec->assoc->user) {
user_rec = sacctmgr_find_user_from_list(
user_list,
slurmdb_hierarchical_rec->assoc->user);
line = xstrdup_printf(
"User - %s",
slurmdb_hierarchical_rec->sort_name);
if (slurmdb_hierarchical_rec->assoc->partition)
xstrfmtcat(line, ":Partition='%s'",
slurmdb_hierarchical_rec->
assoc->partition);
if (user_rec) {
xstrfmtcat(line, ":DefaultAccount='%s'",
user_rec->default_acct);
if (user_rec->default_wckey
&& user_rec->default_wckey[0])
xstrfmtcat(line, ":DefaultWCKey='%s'",
user_rec->default_wckey);
if (user_rec->admin_level > SLURMDB_ADMIN_NONE)
xstrfmtcat(line, ":AdminLevel='%s'",
slurmdb_admin_level_str(
user_rec->
admin_level));
if (user_rec->coord_accts
&& list_count(user_rec->coord_accts)) {
ListIterator itr2 = NULL;
slurmdb_coord_rec_t *coord = NULL;
int first_coord = 1;
list_sort(user_rec->coord_accts,
(ListCmpF)sort_coord_list);
itr2 = list_iterator_create(
user_rec->coord_accts);
while ((coord = list_next(itr2))) {
/* We only care about
* the direct accounts here
*/
if (!coord->direct)
continue;
if (first_coord) {
xstrfmtcat(
line,
":Coordinator"
"='%s",
coord->name);
first_coord = 0;
} else {
xstrfmtcat(line, ",%s",
coord->name);
}
}
if (!first_coord)
xstrcat(line, "'");
list_iterator_destroy(itr2);
}
if (user_rec->wckey_list
&& list_count(user_rec->wckey_list)) {
ListIterator itr2 = NULL;
slurmdb_wckey_rec_t *wckey = NULL;
int first_wckey = 1;
itr2 = list_iterator_create(
user_rec->wckey_list);
while ((wckey = list_next(itr2))) {
/* Avoid sending
non-legitimate wckeys.
*/
if (!wckey->name ||
!wckey->name[0] ||
wckey->name[0] == '*')
continue;
if (first_wckey) {
xstrfmtcat(
line,
":WCKeys='%s",
wckey->name);
first_wckey = 0;
} else {
xstrfmtcat(line, ",%s",
wckey->name);
}
}
if (!first_wckey)
xstrcat(line, "'");
list_iterator_destroy(itr2);
}
}
} else {
acct_rec = sacctmgr_find_account_from_list(
acct_list,
slurmdb_hierarchical_rec->assoc->acct);
line = xstrdup_printf(
"Account - %s",
slurmdb_hierarchical_rec->sort_name);
if (acct_rec) {
xstrfmtcat(line, ":Description='%s'",
acct_rec->description);
xstrfmtcat(line, ":Organization='%s'",
acct_rec->organization);
}
}
print_file_add_limits_to_line(&line,
slurmdb_hierarchical_rec->assoc);
if (fprintf(fd, "%s\n", line) < 0) {
exit_code=1;
fprintf(stderr, " Can't write to file");
xfree(line);
return SLURM_ERROR;
}
info("%s", line);
xfree(line);
}
list_iterator_destroy(itr);
print_file_slurmdb_hierarchical_rec_list(fd,
slurmdb_hierarchical_rec_list,
user_list, acct_list);
return SLURM_SUCCESS;
}
extern int print_file_add_limits_to_line(char **line,
slurmdb_association_rec_t *assoc)
{
if (!assoc)
return SLURM_ERROR;
if (assoc->def_qos_id && (assoc->def_qos_id != NO_VAL)) {
char *tmp_char;
if (!g_qos_list)
g_qos_list = acct_storage_g_get_qos(
db_conn, my_uid, NULL);
if ((tmp_char = slurmdb_qos_str(g_qos_list, assoc->def_qos_id)))
xstrfmtcat(*line, ":DefaultQOS='%s'", tmp_char);
}
if (assoc->shares_raw != INFINITE)
xstrfmtcat(*line, ":Fairshare=%u", assoc->shares_raw);
if (assoc->grp_cpu_mins != (uint64_t)INFINITE)
xstrfmtcat(*line, ":GrpCPUMins=%"PRIu64, assoc->grp_cpu_mins);
if (assoc->grp_cpus != INFINITE)
xstrfmtcat(*line, ":GrpCPUs=%u", assoc->grp_cpus);
if (assoc->grp_jobs != INFINITE)
xstrfmtcat(*line, ":GrpJobs=%u", assoc->grp_jobs);
if (assoc->grp_nodes != INFINITE)
xstrfmtcat(*line, ":GrpNodes=%u", assoc->grp_nodes);
if (assoc->grp_submit_jobs != INFINITE)
xstrfmtcat(*line, ":GrpSubmitJobs=%u", assoc->grp_submit_jobs);
if (assoc->grp_wall != INFINITE)
xstrfmtcat(*line, ":GrpWall=%u", assoc->grp_wall);
if (assoc->max_cpu_mins_pj != (uint64_t)INFINITE)
xstrfmtcat(*line, ":MaxCPUMinsPerJob=%"PRIu64,
assoc->max_cpu_mins_pj);
if (assoc->max_cpus_pj != INFINITE)
xstrfmtcat(*line, ":MaxCPUsPerJob=%u", assoc->max_cpus_pj);
if (assoc->max_jobs != INFINITE)
xstrfmtcat(*line, ":MaxJobs=%u", assoc->max_jobs);
if (assoc->max_nodes_pj != INFINITE)
xstrfmtcat(*line, ":MaxNodesPerJob=%u", assoc->max_nodes_pj);
if (assoc->max_submit_jobs != INFINITE)
xstrfmtcat(*line, ":MaxSubmitJobs=%u", assoc->max_submit_jobs);
if (assoc->max_wall_pj != INFINITE)
xstrfmtcat(*line, ":MaxWallDurationPerJob=%u",
assoc->max_wall_pj);
if (assoc->qos_list && list_count(assoc->qos_list)) {
char *temp_char = NULL;
if (!g_qos_list)
g_qos_list = acct_storage_g_get_qos(
db_conn, my_uid, NULL);
temp_char = get_qos_complete_str(g_qos_list, assoc->qos_list);
xstrfmtcat(*line, ":QOS='%s'", temp_char);
xfree(temp_char);
}
return SLURM_SUCCESS;
}
extern int print_file_slurmdb_hierarchical_rec_list(
FILE *fd,
List slurmdb_hierarchical_rec_list,
List user_list,
List acct_list)
{
ListIterator itr = NULL;
slurmdb_hierarchical_rec_t *slurmdb_hierarchical_rec = NULL;
itr = list_iterator_create(slurmdb_hierarchical_rec_list);
while ((slurmdb_hierarchical_rec = list_next(itr))) {
/* info("got here %d with %d from %s %s", */
/* depth, list_count(slurmdb_hierarchical_rec->childern), */
/* slurmdb_hierarchical_rec->assoc->acct,
slurmdb_hierarchical_rec->assoc->user); */
if (!list_count(slurmdb_hierarchical_rec->childern))
continue;
if (fprintf(fd, "Parent - %s\n",
slurmdb_hierarchical_rec->assoc->acct) < 0) {
error("Can't write to file");
return SLURM_ERROR;
}
info("%s - %s", "Parent",
slurmdb_hierarchical_rec->assoc->acct);
/* info("sending %d from %s", */
/* list_count(slurmdb_hierarchical_rec->childern), */
/* slurmdb_hierarchical_rec->assoc->acct); */
_print_file_slurmdb_hierarchical_rec_childern(
fd, slurmdb_hierarchical_rec->childern,
user_list, acct_list);
}
list_iterator_destroy(itr);
return SLURM_SUCCESS;
}
extern void load_sacctmgr_cfg_file (int argc, char *argv[])
{
DEF_TIMERS;
char line[BUFFER_SIZE];
FILE *fd = NULL;
char *parent = NULL;
char *file_name = NULL;
char *cluster_name = NULL;
char *user_name = NULL;
char object[25];
int start = 0, len = 0, i = 0;
int lc=0, num_lines=0;
int start_clean=0;
int cluster_name_set=0;
int rc = SLURM_SUCCESS;
sacctmgr_file_opts_t *file_opts = NULL;
slurmdb_association_rec_t *assoc = NULL, *assoc2 = NULL;
slurmdb_account_rec_t *acct = NULL, *acct2 = NULL;
slurmdb_cluster_rec_t *cluster = NULL;
slurmdb_user_rec_t *user = NULL, *user2 = NULL;
slurmdb_user_cond_t user_cond;
List curr_assoc_list = NULL;
List curr_acct_list = NULL;
List curr_cluster_list = NULL;
List curr_user_list = NULL;
/* This will be freed in their local counter parts */
List mod_acct_list = NULL;
List acct_list = NULL;
List slurmdb_assoc_list = NULL;
List mod_user_list = NULL;
List user_list = NULL;
List user_assoc_list = NULL;
List mod_assoc_list = NULL;
ListIterator itr;
ListIterator itr2;
List print_fields_list;
List format_list = NULL;
print_field_t *field = NULL;
int set = 0, command_len = 0;
if (readonly_flag) {
exit_code = 1;
fprintf(stderr, "Can't run this command in readonly mode.\n");
return;
}
/* reset the connection to get the most recent stuff */
acct_storage_g_commit(db_conn, 0);
for (i=0; i<argc; i++) {
int option = 0;
int end = parse_option_end(argv[i]);
if (!end)
command_len=strlen(argv[i]);
else {
command_len=end-1;
if (argv[i][end] == '=') {
option = (int)argv[i][end-1];
end++;
}
}
if (!end && !strncasecmp(argv[i], "clean",
MAX(command_len, 3))) {
start_clean = 1;
} else if (!end || !strncasecmp (argv[i], "File",
MAX(command_len, 1))) {
if (file_name) {
exit_code=1;
fprintf(stderr,
" File name already set to %s\n",
file_name);
continue;
}
file_name = xstrdup(argv[i]+end);
} else if (!strncasecmp (argv[i], "Cluster",
MAX(command_len, 3))) {
if (cluster_name) {
exit_code=1;
fprintf(stderr,
" Can only do one cluster at a time. "
"Already doing %s\n", cluster_name);
continue;
}
cluster_name = xstrdup(argv[i]+end);
cluster_name_set = 1;
} else {
exit_code=1;
fprintf(stderr, " Unknown option: %s\n", argv[i]);
}
}
if (!file_name) {
exit_code=1;
xfree(cluster_name);
fprintf(stderr,
" No filename given, specify one with file=''\n");
return;
}
fd = fopen(file_name, "r");
xfree(file_name);
if (fd == NULL) {
exit_code=1;
fprintf(stderr, " Unable to read \"%s\": %m\n", argv[0]);
xfree(cluster_name);
return;
}
curr_acct_list = acct_storage_g_get_accounts(db_conn, my_uid, NULL);
/* These are new info so they need to be freed here */
acct_list = list_create(slurmdb_destroy_account_rec);
slurmdb_assoc_list = list_create(slurmdb_destroy_association_rec);
user_list = list_create(slurmdb_destroy_user_rec);
user_assoc_list = list_create(slurmdb_destroy_association_rec);
mod_acct_list = list_create(slurmdb_destroy_account_rec);
mod_user_list = list_create(slurmdb_destroy_user_rec);
mod_assoc_list = list_create(slurmdb_destroy_association_rec);
format_list = list_create(slurm_destroy_char);
while ((num_lines = _get_next_line(line, BUFFER_SIZE, fd)) > 0) {
lc += num_lines;
/* skip empty lines */
if (line[0] == '\0') {
continue;
}
len = strlen(line);
memset(object, 0, sizeof(object));
/* first find the object */
start=0;
for(i=0; i<len; i++) {
if (line[i] == '-') {
start = i;
if (line[i-1] == ' ')
i--;
if (i<sizeof(object))
strncpy(object, line, i);
break;
}
}
if (!object[0])
continue;
while (line[start] != ' ' && start<len)
start++;
if (start>=len) {
exit_code=1;
fprintf(stderr, " Nothing after object "
"name '%s'. line(%d)\n",
object, lc);
rc = SLURM_ERROR;
break;
}
start++;
if (!strcasecmp("Machine", object)
|| !strcasecmp("Cluster", object)) {
slurmdb_association_cond_t assoc_cond;
if (cluster_name && !cluster_name_set) {
exit_code=1;
fprintf(stderr, " You can only add one cluster "
"at a time.\n");
rc = SLURM_ERROR;
break;
}
file_opts = _parse_options(line+start);
if (!file_opts) {
exit_code=1;
fprintf(stderr,
" error: Problem with line(%d)\n", lc);
rc = SLURM_ERROR;
break;
}
if (!cluster_name_set)
cluster_name = xstrdup(file_opts->name);
/* we have to do this here since this is the
first place we have the cluster_name
*/
memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
user_cond.with_coords = 1;
user_cond.with_assocs = 1;
user_cond.with_wckeys = 1;
memset(&assoc_cond, 0,
sizeof(slurmdb_association_cond_t));
assoc_cond.cluster_list = list_create(NULL);
assoc_cond.with_raw_qos = 1;
assoc_cond.without_parent_limits = 1;
list_append(assoc_cond.cluster_list, cluster_name);
user_cond.assoc_cond = &assoc_cond;
curr_user_list = acct_storage_g_get_users(
db_conn, my_uid, &user_cond);
user_cond.assoc_cond = NULL;
assoc_cond.only_defs = 0;
/* make sure this person running is an admin */
user_name = uid_to_string(my_uid);
if (!(user = sacctmgr_find_user_from_list(
curr_user_list, user_name))) {
exit_code=1;
fprintf(stderr, " Your uid (%u) is not in the "
"accounting system, can't load file.\n",
my_uid);
if (curr_user_list)
list_destroy(curr_user_list);
xfree(user_name);
return;
} else {
if (my_uid != slurm_get_slurm_user_id()
&& my_uid != 0
&& (user->admin_level
< SLURMDB_ADMIN_SUPER_USER)) {
exit_code=1;
fprintf(stderr,
" Your user does not have "
"sufficient "
"privileges to load files.\n");
if (curr_user_list)
list_destroy(curr_user_list);
xfree(user_name);
return;
}
}
xfree(user_name);
if (start_clean) {
slurmdb_cluster_cond_t cluster_cond;
List ret_list = NULL;
if (!commit_check("You requested to flush "
"the cluster before "
"adding it again.\n"
"Are you sure you want "
"to continue?")) {
printf("Aborted\n");
break;
}
slurmdb_init_cluster_cond(&cluster_cond, 0);
cluster_cond.cluster_list = list_create(NULL);
list_append(cluster_cond.cluster_list,
cluster_name);
notice_thread_init();
ret_list = acct_storage_g_remove_clusters(
db_conn, my_uid, &cluster_cond);
notice_thread_fini();
list_destroy(cluster_cond.cluster_list);
if (!ret_list) {
exit_code=1;
fprintf(stderr, " There was a problem "
"removing the cluster.\n");
rc = SLURM_ERROR;
break;
}
/* This needs to be commited or
problems may arise */
acct_storage_g_commit(db_conn, 1);
}
curr_cluster_list = acct_storage_g_get_clusters(
db_conn, my_uid, NULL);
if (cluster_name)
printf("For cluster %s\n", cluster_name);
if (!(cluster = sacctmgr_find_cluster_from_list(
curr_cluster_list, cluster_name))) {
List temp_assoc_list = list_create(NULL);
List cluster_list = list_create(
slurmdb_destroy_cluster_rec);
cluster = xmalloc(
sizeof(slurmdb_cluster_rec_t));
slurmdb_init_cluster_rec(cluster, 0);
list_append(cluster_list, cluster);
cluster->name = xstrdup(cluster_name);
if (file_opts->classification) {
cluster->classification =
file_opts->classification;
printf("Classification: %s\n",
get_classification_str(
cluster->
classification));
}
cluster->root_assoc = _set_assoc_up(
file_opts, MOD_CLUSTER,
cluster_name, "root");
list_append(temp_assoc_list,
cluster->root_assoc);
rc = _print_out_assoc(temp_assoc_list, 0, 0);
list_destroy(temp_assoc_list);
notice_thread_init();
rc = acct_storage_g_add_clusters(
db_conn, my_uid, cluster_list);
notice_thread_fini();
list_destroy(cluster_list);
if (rc != SLURM_SUCCESS) {
exit_code=1;
fprintf(stderr,
" Problem adding cluster: %s\n",
slurm_strerror(rc));
rc = SLURM_ERROR;
_destroy_sacctmgr_file_opts(file_opts);
break;
}
/* This needs to be commited or
problems may arise */
acct_storage_g_commit(db_conn, 1);
set = 1;
} else {
set = _mod_cluster(file_opts,
cluster, parent);
}
_destroy_sacctmgr_file_opts(file_opts);
/* assoc_cond if set up above */
curr_assoc_list = acct_storage_g_get_associations(
db_conn, my_uid, &assoc_cond);
list_destroy(assoc_cond.cluster_list);
if (!curr_assoc_list) {
exit_code=1;
fprintf(stderr, " Problem getting associations "
"for this cluster\n");
rc = SLURM_ERROR;
break;
}
//info("got %d assocs", list_count(curr_assoc_list));
continue;
} else if (!cluster_name) {
exit_code=1;
fprintf(stderr, " You need to specify a cluster name "
"first with 'Cluster - $NAME' in your file\n");
break;
}
if (!strcasecmp("Parent", object)) {
xfree(parent);
i = start;
while (line[i] != '\n' && i<len)
i++;
if (i >= len) {
exit_code=1;
fprintf(stderr, " No parent name "
"given line(%d)\n",
lc);
rc = SLURM_ERROR;
break;
}
parent = xstrndup(line+start, i-start);
//info("got parent %s", parent);
if (!sacctmgr_find_account_base_assoc_from_list(
curr_assoc_list, parent, cluster_name)
&& !sacctmgr_find_account_base_assoc_from_list(
slurmdb_assoc_list, parent, cluster_name)) {
exit_code=1;
fprintf(stderr, " line(%d) You need to add "
"this parent (%s) as a child before "
"you can add childern to it.\n",
lc, parent);
break;
}
continue;
} else if (!parent) {
parent = xstrdup("root");
printf(" No parent given creating off root, "
"If incorrect specify 'Parent - name' "
"before any childern in your file\n");
}
if (!strcasecmp("Project", object)
|| !strcasecmp("Account", object)) {
file_opts = _parse_options(line+start);
if (!file_opts) {
exit_code=1;
fprintf(stderr, " Problem with line(%d)\n", lc);
rc = SLURM_ERROR;
break;
}
//info("got a project %s of %s", file_opts->name, parent);
if (!(acct = sacctmgr_find_account_from_list(
curr_acct_list, file_opts->name))
&& !sacctmgr_find_account_from_list(
acct_list, file_opts->name)) {
acct = _set_acct_up(file_opts, parent);
list_append(acct_list, acct);
/* don't add anything to the
curr_acct_list */
assoc = _set_assoc_up(file_opts, MOD_ACCT,
cluster_name, parent);
list_append(slurmdb_assoc_list, assoc);
/* don't add anything to the
curr_assoc_list */
} else if (!(assoc =
sacctmgr_find_account_base_assoc_from_list(
curr_assoc_list, file_opts->name,
cluster_name)) &&
!sacctmgr_find_account_base_assoc_from_list(
slurmdb_assoc_list, file_opts->name,
cluster_name)) {
acct2 = sacctmgr_find_account_from_list(
mod_acct_list, file_opts->name);
if (!acct2) {
acct2 = xmalloc(
sizeof(slurmdb_account_rec_t));
list_append(mod_acct_list, acct2);
acct2->name = xstrdup(file_opts->name);
if (_mod_acct(file_opts, acct, parent))
set = 1;
} else {
debug2("already modified this account");
}
assoc = _set_assoc_up(file_opts, MOD_ACCT,
cluster_name, parent);
list_append(slurmdb_assoc_list, assoc);
/* don't add anything to the
curr_assoc_list */
} else if (assoc) {
acct2 = sacctmgr_find_account_from_list(
mod_acct_list, file_opts->name);
if (!acct2) {
acct2 = xmalloc(
sizeof(slurmdb_account_rec_t));
list_append(mod_acct_list, acct2);
acct2->name = xstrdup(file_opts->name);
if (_mod_acct(file_opts, acct, parent))
set = 1;
} else {
debug2("already modified this account");
}
assoc2 = sacctmgr_find_association_from_list(
mod_assoc_list,
NULL, file_opts->name,
cluster_name,
NULL);
if (!assoc2) {
assoc2 = xmalloc(
sizeof(slurmdb_association_rec_t));
slurmdb_init_association_rec(assoc2, 0);
list_append(mod_assoc_list, assoc2);
assoc2->cluster = xstrdup(cluster_name);
assoc2->acct = xstrdup(file_opts->name);
assoc2->parent_acct =
xstrdup(assoc->parent_acct);
if (_mod_assoc(file_opts,
assoc, MOD_ACCT, parent))
set = 1;
} else {
debug2("already modified this assoc");
}
}
_destroy_sacctmgr_file_opts(file_opts);
continue;
} else if (!strcasecmp("User", object)) {
file_opts = _parse_options(line+start);
if (!file_opts) {
exit_code=1;
fprintf(stderr, " Problem with line(%d)\n", lc);
rc = SLURM_ERROR;
break;
}
if (!(user = sacctmgr_find_user_from_list(
curr_user_list, file_opts->name))
&& !sacctmgr_find_user_from_list(
user_list, file_opts->name)) {
user = _set_user_up(file_opts, cluster_name,
parent);
list_append(user_list, user);
/* don't add anything to the
curr_user_list */
assoc = _set_assoc_up(file_opts, MOD_USER,
cluster_name, parent);
list_append(user_assoc_list, assoc);
/* don't add anything to the
curr_assoc_list */
} else if (!(assoc =
sacctmgr_find_association_from_list(
curr_assoc_list,
file_opts->name, parent,
cluster_name, file_opts->part))
&& !sacctmgr_find_association_from_list(
user_assoc_list,
file_opts->name, parent,
cluster_name,
file_opts->part)) {
/* This means the user was added
* during this round but this is a new
* association we are adding
*/
if (!user)
goto new_association;
/* This means there could be a change
* on the user.
*/
user2 = sacctmgr_find_user_from_list(
mod_user_list, file_opts->name);
if (!user2) {
user2 = xmalloc(
sizeof(slurmdb_user_rec_t));
list_append(mod_user_list, user2);
user2->name = xstrdup(file_opts->name);
if (_mod_user(file_opts, user,
cluster_name, parent))
set = 1;
} else {
debug2("already modified this user");
}
new_association:
assoc = _set_assoc_up(file_opts, MOD_USER,
cluster_name, parent);
list_append(user_assoc_list, assoc);
/* don't add anything to the
curr_assoc_list */
} else if (assoc) {
user2 = sacctmgr_find_user_from_list(
mod_user_list, file_opts->name);
if (!user2) {
user2 = xmalloc(
sizeof(slurmdb_user_rec_t));
list_append(mod_user_list, user2);
user2->name = xstrdup(file_opts->name);
if (_mod_user(file_opts, user,
cluster_name, parent))
set = 1;
} else {
debug2("already modified this user");
}
assoc2 = sacctmgr_find_association_from_list(
mod_assoc_list,
file_opts->name, parent,
cluster_name,
file_opts->part);
if (!assoc2) {
assoc2 = xmalloc(
sizeof(slurmdb_association_rec_t));
slurmdb_init_association_rec(assoc2, 0);
list_append(mod_assoc_list, assoc2);
assoc2->cluster = xstrdup(cluster_name);
assoc2->acct = xstrdup(parent);
assoc2->user = xstrdup(file_opts->name);
assoc2->partition =
xstrdup(file_opts->part);
if (_mod_assoc(file_opts,
assoc, MOD_USER, parent))
set = 1;
} else {
debug2("already modified this assoc");
}
}
//info("got a user %s", file_opts->name);
_destroy_sacctmgr_file_opts(file_opts);
continue;
} else {
exit_code=1;
fprintf(stderr,
" Misformatted line(%d): %s\n", lc, line);
rc = SLURM_ERROR;
break;
}
}
fclose(fd);
xfree(cluster_name);
xfree(parent);
START_TIMER;
if (rc == SLURM_SUCCESS && list_count(acct_list)) {
printf("Accounts\n");
slurm_addto_char_list(format_list,
"Name,Description,Organization,QOS");
print_fields_list = sacctmgr_process_format_list(format_list);
list_flush(format_list);
print_fields_header(print_fields_list);
itr = list_iterator_create(acct_list);
itr2 = list_iterator_create(print_fields_list);
while ((acct = list_next(itr))) {
while ((field = list_next(itr2))) {
switch(field->type) {
case PRINT_DESC:
field->print_routine(
field, acct->description);
break;
case PRINT_NAME:
field->print_routine(
field, acct->name);
break;
case PRINT_ORG:
field->print_routine(
field, acct->organization);
break;
default:
field->print_routine(
field, NULL);
break;
}
}
list_iterator_reset(itr2);
printf("\n");
}
list_iterator_destroy(itr);
list_iterator_destroy(itr2);
list_destroy(print_fields_list);
rc = acct_storage_g_add_accounts(db_conn, my_uid, acct_list);
printf("-----------------------------"
"----------------------\n\n");
set = 1;
}
if (rc == SLURM_SUCCESS && list_count(slurmdb_assoc_list)) {
printf("Account Associations\n");
rc = _print_out_assoc(slurmdb_assoc_list, 0, 1);
set = 1;
}
if (rc == SLURM_SUCCESS && list_count(user_list)) {
printf("Users\n");
slurm_addto_char_list(format_list,
"Name,DefaultA,DefaultW,QOS,Admin,Coord");
print_fields_list = sacctmgr_process_format_list(format_list);
list_flush(format_list);
print_fields_header(print_fields_list);
itr = list_iterator_create(user_list);
itr2 = list_iterator_create(print_fields_list);
while ((user = list_next(itr))) {
while ((field = list_next(itr2))) {
switch(field->type) {
case PRINT_ADMIN:
field->print_routine(
field,
slurmdb_admin_level_str(
user->admin_level));
break;
case PRINT_COORDS:
field->print_routine(
field,
user->coord_accts);
break;
case PRINT_DACCT:
field->print_routine(
field,
user->default_acct);
break;
case PRINT_DWCKEY:
field->print_routine(
field,
user->default_wckey);
break;
case PRINT_NAME:
field->print_routine(
field, user->name);
break;
case PRINT_WCKEYS:
field->print_routine(
field, user->wckey_list);
break;
default:
field->print_routine(
field, NULL);
break;
}
}
list_iterator_reset(itr2);
printf("\n");
}
list_iterator_destroy(itr);
list_iterator_destroy(itr2);
list_destroy(print_fields_list);
rc = acct_storage_g_add_users(db_conn, my_uid, user_list);
printf("---------------------------"
"------------------------\n\n");
set = 1;
}
if (rc == SLURM_SUCCESS && list_count(user_assoc_list)) {
printf("User Associations\n");
rc = _print_out_assoc(user_assoc_list, 1, 1);
set = 1;
}
END_TIMER2("add cluster");
if (set)
info("Done adding cluster in %s", TIME_STR);
if (rc == SLURM_SUCCESS) {
if (set) {
if (commit_check("Would you like to commit changes?")) {
acct_storage_g_commit(db_conn, 1);
} else {
printf(" Changes Discarded\n");
acct_storage_g_commit(db_conn, 0);
}
} else {
printf(" Nothing new added.\n");
}
} else {
exit_code=1;
fprintf(stderr, " Problem with requests: %s\n",
slurm_strerror(rc));
}
list_destroy(format_list);
list_destroy(mod_acct_list);
list_destroy(acct_list);
list_destroy(slurmdb_assoc_list);
list_destroy(mod_user_list);
list_destroy(user_list);
list_destroy(user_assoc_list);
list_destroy(mod_assoc_list);
if (curr_acct_list)
list_destroy(curr_acct_list);
if (curr_assoc_list)
list_destroy(curr_assoc_list);
if (curr_cluster_list)
list_destroy(curr_cluster_list);
if (curr_user_list)
list_destroy(curr_user_list);
}