blob: 1688c2c58ff4643499551cb51de9da0e3a992912 [file] [log] [blame]
/*****************************************************************************\
* common.c - definitions for functions common to all modules in sacctmgr.
*****************************************************************************
* Copyright (C) SchedMD LLC.
* 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://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 "src/sacctmgr/sacctmgr.h"
#include "src/common/macros.h"
#include "src/common/parse_value.h"
#include "src/common/slurmdbd_defs.h"
#include "src/interfaces/auth.h"
#include "src/common/slurm_protocol_defs.h"
#include <unistd.h>
#include <termios.h>
static bool warn_needed = false;
static pthread_mutex_t warn_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t warn_cond = PTHREAD_COND_INITIALIZER;
static pthread_t notice_thread_handler = 0;
static void *_print_lock_warn(void *no_data)
{
struct timespec ts = { 0, 0 };
ts.tv_sec = time(NULL) + 5;
slurm_mutex_lock(&warn_mutex);
if (warn_needed) {
slurm_cond_timedwait(&warn_cond, &warn_mutex, &ts);
if (warn_needed)
printf(" Database is busy or waiting for lock from other user.\n");
warn_needed = false;
}
slurm_mutex_unlock(&warn_mutex);
return NULL;
}
static void _nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
switch(state) {
case 1:
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
break;
default:
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
/*
* IN option - string to parse as /<command>([-+]=<value>)?/
* OUT op_type - Set to the type of operator parsed, '-', '+', or 0.
* OUT command_len - The strlen of <command>
* returns the offset of <value> if it exists, otherwise 0
*/
extern int parse_option_end(char *option, int *op_type, int *command_len)
{
xassert(op_type);
xassert(command_len);
int end = 0;
*op_type = 0;
*command_len = 0;
if (!option)
return 0;
while (option[end] && option[end] != '=')
end++;
*command_len = end; /* before '=' */
if (!option[end]) /* no <value> */
return 0;
if (end) {
char tmp_type = option[end - 1];
if (tmp_type == '+' || tmp_type == '-') {
*op_type = tmp_type;
*command_len = end - 1; /* before "[+-]=" */
}
}
end++; /* past '=' */
return end;
}
extern bool common_verify_option_syntax(char *option, int op_type,
bool allow_op)
{
if (op_type && !allow_op) {
exit_code = 1;
fprintf(stderr, " Invalid operator '%c=' in %s\n", op_type,
option);
return false;
}
return true;
}
/* you need to xfree whatever is sent from here */
extern char *strip_quotes(char *option, int *increased, bool make_lower)
{
int end = 0;
int i=0, start=0;
char *meat = NULL;
char quote_c = '\0';
int quote = 0;
if (!option)
return NULL;
/* first strip off the ("|')'s */
if (option[i] == '\"' || option[i] == '\'') {
quote_c = option[i];
quote = 1;
i++;
}
/* skip beginning spaces */
while (option[i] && isspace(option[i]))
i++;
start = i;
while(option[i]) {
if (quote && option[i] == quote_c) {
end++;
break;
} else if (option[i] == '\"' || option[i] == '\'')
option[i] = '`';
else if (make_lower) {
char lower = tolower(option[i]);
if (lower != option[i])
option[i] = lower;
}
i++;
}
/* trim end spaces */
while ((i - 1) && option[i - 1] && isspace(option[i - 1]))
i--;
end += i;
meat = xmalloc((i-start)+1);
memcpy(meat, option+start, (i-start));
if (increased)
(*increased) += end;
return meat;
}
static print_field_t *_get_print_field(char *object)
{
/* This should be kept in alpha order to avoid picking the
wrong field name.
*/
print_field_t *field = xmalloc(sizeof(print_field_t));
char *tmp_char = NULL;
int command_len, field_len = 0;
if ((tmp_char = strstr(object, "\%"))) {
field_len = atoi(tmp_char+1);
tmp_char[0] = '\0';
}
command_len = strlen(object);
if (!xstrncasecmp("Account", object, MAX(command_len, 3))
|| !xstrncasecmp("Acct", object, MAX(command_len, 4))) {
field->type = PRINT_ACCT;
field->name = xstrdup("Account");
if (tree_display)
field->len = -20;
else
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("ActionRaw", object, MAX(command_len, 7))) {
field->type = PRINT_ACTIONRAW;
field->name = xstrdup("ActionRaw");
field->len = 10;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Action", object, MAX(command_len, 4))) {
field->type = PRINT_ACTION;
field->name = xstrdup("Action");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Actor", object, MAX(command_len, 4))) {
field->type = PRINT_ACTOR;
field->name = xstrdup("Actor");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("AdminLevel", object, MAX(command_len, 2))) {
field->type = PRINT_ADMIN;
field->name = xstrdup("Admin");
field->len = 9;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Allowed", object, MAX(command_len, 2))) {
field->type = PRINT_ALLOWED;
field->name = xstrdup("Allowed");
field->len = 8;
field->print_routine = print_fields_uint32;
} else if (!xstrncasecmp("Associations", object, MAX(command_len, 2))) {
field->type = PRINT_ASSOC_NAME;
field->name = xstrdup("Assocs");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("TRES", object, MAX(command_len, 2))) {
field->type = PRINT_TRES;
field->name = xstrdup("TRES");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Classification", object,
MAX(command_len, 3))) {
field->type = PRINT_CLASS;
field->name = xstrdup("Class");
field->len = 9;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("ClusterNodes", object, MAX(command_len, 8))) {
field->type = PRINT_CLUSTER_NODES;
field->name = xstrdup("Cluster Nodes");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Clusters", object, MAX(command_len, 2))) {
field->type = PRINT_CLUSTER;
field->name = xstrdup("Cluster");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Coordinators", object, MAX(command_len, 3))) {
field->type = PRINT_COORDS;
field->name = xstrdup("Coord Accounts");
field->len = 20;
field->print_routine = sacctmgr_print_coord_list;
} else if (!xstrncasecmp("Comment", object, MAX(command_len, 3))) {
field->type = PRINT_COMMENT;
field->name = xstrdup("Comment");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("ControlHost", object, MAX(command_len, 8))) {
field->type = PRINT_CHOST;
field->name = xstrdup("ControlHost");
field->len = 15;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("ControlPort", object, MAX(command_len, 8))) {
field->type = PRINT_CPORT;
field->name = xstrdup("ControlPort");
field->len = 12;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Count", object, MAX(command_len, 3))) {
field->type = PRINT_COUNT;
field->name = xstrdup("Count");
field->len = 6;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("CountAllowed", object, MAX(command_len, 6))) {
field->type = PRINT_CALLOWED;
field->name = xstrdup("# Allowed");
field->len = 10;
field->print_routine = print_fields_uint32;
} else if (!xstrncasecmp("CountUsed", object, MAX(command_len, 6))) {
field->type = PRINT_CALLOWED;
field->name = xstrdup("# Used");
field->len = 10;
field->print_routine = print_fields_uint32;
} else if (!xstrncasecmp("CPUCount", object,
MAX(command_len, 2))) {
field->type = PRINT_CPUS;
field->name = xstrdup("CPU Cnt");
field->len = 7;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("DefaultAccount", object,
MAX(command_len, 8))) {
field->type = PRINT_DACCT;
field->name = xstrdup("Def Acct");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("DefaultQOS", object, MAX(command_len, 8))) {
field->type = PRINT_DQOS;
field->name = xstrdup("Def QOS");
field->len = 9;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("DefaultWCKey", object, MAX(command_len, 8))) {
field->type = PRINT_DWCKEY;
field->name = xstrdup("Def WCKey");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Description", object, MAX(command_len, 3))) {
field->type = PRINT_DESC;
field->name = xstrdup("Descr");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Duration", object, MAX(command_len, 2))) {
field->type = PRINT_DURATION;
field->name = xstrdup("Duration");
field->len = 13;
field->print_routine = print_fields_time_from_secs;
} else if (!xstrncasecmp("EventRaw", object, MAX(command_len, 6))) {
field->type = PRINT_EVENTRAW;
field->name = xstrdup("EventRaw");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Event", object, MAX(command_len, 2))) {
field->type = PRINT_EVENT;
field->name = xstrdup("Event");
field->len = 7;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Extra", object, MAX(command_len, 2))) {
field->type = PRINT_EXTRA;
field->name = xstrdup("Extra");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Features", object, MAX(command_len, 3))) {
field->type = PRINT_FEATURES;
field->name = xstrdup("Features");
field->len = 20;
field->print_routine = print_fields_char_list;
} else if (!xstrncasecmp("Federation", object, MAX(command_len, 3))) {
field->type = PRINT_FEDERATION;
field->name = xstrdup("Federation");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("FedState", object, MAX(command_len, 4))) {
field->type = PRINT_FEDSTATE;
field->name = xstrdup("FedState");
field->len = 12;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("FedStateRaw", object, MAX(command_len, 9))) {
field->type = PRINT_FEDSTATERAW;
field->name = xstrdup("FedStateRaw");
field->len = 11;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Flags", object, MAX(command_len, 2))) {
field->type = PRINT_FLAGS;
field->name = xstrdup("Flags");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("GraceTime", object, MAX(command_len, 3))) {
field->type = PRINT_GRACE;
field->name = xstrdup("GraceTime");
field->len = 10;
field->print_routine = print_fields_time_from_secs;
} else if (!xstrncasecmp("GrpCPUs", object, MAX(command_len, 6))) {
field->type = PRINT_GRPC;
field->name = xstrdup("GrpCPUs");
field->len = 8;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("GrpCPUMins", object, MAX(command_len, 7))) {
field->type = PRINT_GRPCM;
field->name = xstrdup("GrpCPUMins");
field->len = 11;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("GrpCPURunMins", object, MAX(command_len, 7))) {
field->type = PRINT_GRPCRM;
field->name = xstrdup("GrpCPURunMins");
field->len = 13;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("GrpTRES", object, MAX(command_len, 7))) {
field->type = PRINT_GRPT;
field->name = xstrdup("GrpTRES");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("GrpTRESMins", object, MAX(command_len, 7))) {
field->type = PRINT_GRPTM;
field->name = xstrdup("GrpTRESMins");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("GrpTRESRunMins", object,
MAX(command_len, 7))) {
field->type = PRINT_GRPTRM;
field->name = xstrdup("GrpTRESRunMins");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("GrpJobs", object, MAX(command_len, 4))) {
field->type = PRINT_GRPJ;
field->name = xstrdup("GrpJobs");
field->len = 7;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("GrpJobsAccrue",
object, MAX(command_len, 8))) {
field->type = PRINT_GRPJA;
field->name = xstrdup("GrpJobsAccrue");
field->len = 13;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("GrpMemory", object, MAX(command_len, 4))) {
field->type = PRINT_GRPMEM;
field->name = xstrdup("GrpMem");
field->len = 7;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("GrpNodes", object, MAX(command_len, 4))) {
field->type = PRINT_GRPN;
field->name = xstrdup("GrpNodes");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("GrpSubmitJobs", object, MAX(command_len, 4))) {
field->type = PRINT_GRPS;
field->name = xstrdup("GrpSubmit");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("GrpWall", object, MAX(command_len, 4))) {
field->type = PRINT_GRPW;
field->name = xstrdup("GrpWall");
field->len = 11;
field->print_routine = print_fields_time;
} else if (!xstrncasecmp("ID", object, MAX(command_len, 2))) {
field->type = PRINT_ID;
field->name = xstrdup("ID");
field->len = 6;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Info", object, MAX(command_len, 3))) {
field->type = PRINT_INFO;
field->name = xstrdup("Info");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("InstanceId", object, MAX(command_len, 9))) {
field->type = PRINT_INSTANCE_ID;
field->name = xstrdup("InstanceId");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("InstanceType", object, MAX(command_len, 9))) {
field->type = PRINT_INSTANCE_TYPE;
field->name = xstrdup("InstanceType");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Lineage", object, MAX(command_len, 1))) {
field->type = PRINT_LINEAGE;
field->name = xstrdup("Lineage");
field->len = -20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("servertype", object, MAX(command_len, 10))) {
field->type = PRINT_SERVERTYPE;
field->name = xstrdup("ServerType");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("MaxCPUMinsPerJob", object,
MAX(command_len, 7))) {
field->type = PRINT_MAXCM;
field->name = xstrdup("MaxCPUMins");
field->len = 11;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("MaxCPURunMinsPerUser", object,
MAX(command_len, 7)) ||
!xstrncasecmp("MaxCPURunMinsPU", object,
MAX(command_len, 7))) {
field->type = PRINT_MAXCRM;
field->name = xstrdup("MaxCPURunMinsPU");
field->len = 15;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("MaxCPUsPerJob", object,
MAX(command_len, 7))) {
field->type = PRINT_MAXC;
field->name = xstrdup("MaxCPUs");
field->len = 8;
field->print_routine = print_fields_uint64;
} else if (!xstrncasecmp("MaxCPUsPerUser", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxCPUsPU", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXCU;
field->name = xstrdup("MaxCPUsPU");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxTRES", object,
MAX(command_len, 7)) ||
!xstrncasecmp("MaxTRESPJ", object,
MAX(command_len, 9)) ||
!xstrncasecmp("MaxTRESPerJob", object,
MAX(command_len, 11))) {
field->type = PRINT_MAXT;
field->name = xstrdup("MaxTRES");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESPerNode", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxTRESPN", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXTN;
field->name = xstrdup("MaxTRESPerNode");
field->len = 14;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESMinsPerJob", object,
MAX(command_len, 8)) ||
!xstrncasecmp("MaxTRESMinsPJ", object,
MAX(command_len, 13))) {
field->type = PRINT_MAXTM;
field->name = xstrdup("MaxTRESMins");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESRunMinsPerAccount", object,
MAX(command_len, 18)) ||
!xstrncasecmp("MaxTRESRunMinsPerAcct", object,
MAX(command_len, 18)) ||
!xstrncasecmp("MaxTRESRunMinsPA", object,
MAX(command_len, 15))) {
field->type = PRINT_MAXTRMA;
field->name = xstrdup("MaxTRESRunMinsPA");
field->len = 16;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESRunMinsPerUser", object,
MAX(command_len, 8)) ||
!xstrncasecmp("MaxTRESRunMinsPU", object,
MAX(command_len, 8))) {
field->type = PRINT_MAXTRM;
field->name = xstrdup("MaxTRESRunMinsPU");
field->len = 16;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESPerAccount", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxTRESPerAcct", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxTRESPA", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXTA;
field->name = xstrdup("MaxTRESPA");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxTRESPerUser", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxTRESPU", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXTU;
field->name = xstrdup("MaxTRESPU");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("MaxJobs", object, MAX(command_len, 4))) {
field->type = PRINT_MAXJ;
field->name = xstrdup("MaxJobs");
field->len = 7;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxJobsAccrue",
object, MAX(command_len, 4))) {
field->type = PRINT_MAXJA;
field->name = xstrdup("MaxJobsAccrue");
field->len = 13;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxJobsAccruePerAccount", object,
MAX(command_len, 17)) ||
!xstrncasecmp("MaxJobsAccruePerAcct", object,
MAX(command_len, 17)) ||
!xstrncasecmp("MaxJobsAccruePA", object,
MAX(command_len, 15))) {
field->type = PRINT_MAXJAA;
field->name = xstrdup("MaxJobsAccruePA");
field->len = 15;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxJobsAccruePerUser", object,
MAX(command_len, 17)) ||
!xstrncasecmp("MaxJobsAccruePU", object,
MAX(command_len, 15))) {
field->type = PRINT_MAXJAU;
field->name = xstrdup("MaxJobsAccruePU");
field->len = 15;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxJobsPerAccount", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxJobsPerAcct", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxJobsPA", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXJPA;
field->name = xstrdup("MaxJobsPA");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxJobsPerUser", object,
MAX(command_len, 11)) ||
!xstrncasecmp("MaxJobsPU", object,
MAX(command_len, 9))) {
field->type = PRINT_MAXJ; /* used same as MaxJobs */
field->name = xstrdup("MaxJobsPU");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxNodesPerJob", object,
MAX(command_len, 4))) {
field->type = PRINT_MAXN;
field->name = xstrdup("MaxNodes");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxNodesPerUser", object,
MAX(command_len, 12)) ||
!xstrncasecmp("MaxNodesPU", object,
MAX(command_len, 10))) {
field->type = PRINT_MAXNU;
field->name = xstrdup("MaxNodesPU");
field->len = 10;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MinPrioThreshold", object,
MAX(command_len, 4))) {
field->type = PRINT_MINPT;
field->name = xstrdup("MinPrioThres");
field->len = 12;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxSubmitJobs", object,
MAX(command_len, 4))) {
field->type = PRINT_MAXS;
field->name = xstrdup("MaxSubmit");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxSubmitJobsPerAccount", object,
MAX(command_len, 17)) ||
!xstrncasecmp("MaxSubmitJobsPerAcct", object,
MAX(command_len, 17)) ||
!xstrncasecmp("MaxSubmitJobsPA", object,
MAX(command_len, 15)) ||
!xstrncasecmp("MaxSubmitPA", object,
MAX(command_len, 11))) {
field->type = PRINT_MAXSA;
field->name = xstrdup("MaxSubmitPA");
field->len = 11;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxSubmitJobsPerUser", object,
MAX(command_len, 10)) ||
!xstrncasecmp("MaxSubmitJobsPU", object,
MAX(command_len, 10)) ||
!xstrncasecmp("MaxSubmitPU", object,
MAX(command_len, 6))) {
field->type = PRINT_MAXS; /* used same as MaxSubmitJobs */
field->name = xstrdup("MaxSubmitPU");
field->len = 11;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MaxWallDurationPerJob", object,
MAX(command_len, 4))) {
field->type = PRINT_MAXW;
field->name = xstrdup("MaxWall");
field->len = 11;
field->print_routine = print_fields_time;
} else if (!xstrncasecmp("MinCPUsPerJob", object,
MAX(command_len, 7))) {
field->type = PRINT_MINC;
field->name = xstrdup("MinCPUs");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("MinTRESPerJob", object,
MAX(command_len, 7))) {
field->type = PRINT_MINT;
field->name = xstrdup("MinTRES");
field->len = 13;
field->print_routine = sacctmgr_print_tres;
} else if (!xstrncasecmp("Name", object, MAX(command_len, 2))) {
field->type = PRINT_NAME;
field->name = xstrdup("Name");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("NodeCount", object, MAX(command_len, 5))) {
field->type = PRINT_NODECNT;
field->name = xstrdup("NodeCount");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("NodeInx", object, MAX(command_len, 5))) {
field->type = PRINT_NODEINX;
field->name = xstrdup("NodeInx");
field->len = 9;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("NodeNames", object, MAX(command_len, 5))) {
field->type = PRINT_NODENAME;
field->name = xstrdup("NodeName");
field->len = -15;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Organization", object, MAX(command_len, 1))) {
field->type = PRINT_ORG;
field->name = xstrdup("Org");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("ParentID", object, MAX(command_len, 7))) {
field->type = PRINT_PID;
field->name = xstrdup("ParentID");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("ParentName", object, MAX(command_len, 7))) {
field->type = PRINT_PNAME;
field->name = xstrdup("ParentName");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Partition", object, MAX(command_len, 4))) {
field->type = PRINT_PART;
field->name = xstrdup("Partition");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("PreemptMode", object, MAX(command_len, 8))) {
field->type = PRINT_PREEM;
field->name = xstrdup("PreemptMode");
field->len = 11;
field->print_routine = print_fields_str;
/* Preempt needs to follow PreemptMode */
} else if (!xstrncasecmp("Preempt", object, MAX(command_len, 7))) {
field->type = PRINT_PREE;
field->name = xstrdup("Preempt");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("PreemptExemptTime", object,
MAX(command_len, 8))) {
field->type = PRINT_PRXMPT;
field->name = xstrdup("PreemptExemptTime");
field->len = 19;
field->print_routine = print_fields_time_from_secs;
} else if (!xstrncasecmp("Priority", object, MAX(command_len, 3))) {
field->type = PRINT_PRIO;
field->name = xstrdup("Priority");
field->len = 10;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Problem", object, MAX(command_len, 1))) {
field->type = PRINT_PROBLEM;
field->name = xstrdup("Problem");
field->len = 40;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("QOSLevel", object, MAX(command_len, 3))) {
field->type = PRINT_QOS;
field->name = xstrdup("QOS");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("QOSRAWLevel", object, MAX(command_len, 4))) {
field->type = PRINT_QOS_RAW;
field->name = xstrdup("QOS_RAW");
field->len = 10;
field->print_routine = print_fields_char_list;
} else if (!xstrncasecmp("Reason", object,
MAX(command_len, 1))) {
field->type = PRINT_REASON;
field->name = xstrdup("Reason");
field->len = 30;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("RPC", object, MAX(command_len, 1))) {
field->type = PRINT_RPC_VERSION;
field->name = xstrdup("RPC");
field->len = 5;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("Server", object, MAX(command_len, 3))) {
field->type = PRINT_SERVER;
field->name = xstrdup("Server");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Share", object, MAX(command_len, 1))
|| !xstrncasecmp("FairShare", object, MAX(command_len, 2))) {
field->type = PRINT_FAIRSHARE;
field->name = xstrdup("Share");
field->len = 9;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("StateRaw", object,
MAX(command_len, 6))) {
field->type = PRINT_STATERAW;
field->name = xstrdup("StateRaw");
field->len = 8;
field->print_routine = print_fields_uint;
} else if (!xstrncasecmp("State", object, MAX(command_len, 1))) {
field->type = PRINT_STATE;
field->name = xstrdup("State");
field->len = 6;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("TimeStamp", object, MAX(command_len, 2))) {
field->type = PRINT_TS;
field->name = xstrdup("Time");
field->len = 19;
field->print_routine = print_fields_date;
} else if (!xstrncasecmp("TimeEligible", object, MAX(command_len, 6)) ||
!xstrncasecmp("Eligible", object, MAX(command_len, 2))) {
field->type = PRINT_TIMEELIGIBLE;
field->name = xstrdup("TimeEligible");
field->len = 19;
field->print_routine = print_fields_date;
} else if (!xstrncasecmp("TimeEnd", object, MAX(command_len, 6)) ||
!xstrncasecmp("End", object, MAX(command_len, 2))) {
field->type = PRINT_TIMEEND;
field->name = xstrdup("TimeEnd");
field->len = 19;
field->print_routine = print_fields_date;
} else if (!xstrncasecmp("TimeStart", object, MAX(command_len, 7)) ||
!xstrncasecmp("Start", object, MAX(command_len, 3))) {
field->type = PRINT_TIMESTART;
field->name = xstrdup("TimeStart");
field->len = 19;
field->print_routine = print_fields_date;
} else if (!xstrncasecmp("TimeSubmit", object, MAX(command_len, 6)) ||
!xstrncasecmp("Submit", object, MAX(command_len, 2))) {
field->type = PRINT_TIMESUBMIT;
field->name = xstrdup("TimeSubmit");
field->len = 19;
field->print_routine = print_fields_date;
} else if (!xstrncasecmp("TRES", object,
MAX(command_len, 2))) {
field->type = PRINT_TRES;
field->name = xstrdup("TRES");
field->len = 20;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("Type", object, MAX(command_len, 2))) {
field->type = PRINT_TYPE;
field->name = xstrdup("Type");
field->len = 8;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("UnusedWall", object, MAX(command_len, 2))) {
field->type = PRINT_UNUSED;
field->name = xstrdup("UnusedWall");
field->len = 10;
field->print_routine = print_fields_double;
} else if (!xstrncasecmp("UsageFactor", object, MAX(command_len, 6))) {
field->type = PRINT_UF;
field->name = xstrdup("UsageFactor");
field->len = 11;
field->print_routine = print_fields_double;
} else if (!xstrncasecmp("UsageThreshold", object,
MAX(command_len, 6))) {
field->type = PRINT_UT;
field->name = xstrdup("UsageThres");
field->len = 10;
field->print_routine = print_fields_double;
} else if (!xstrncasecmp("LimitFactor", object, MAX(command_len, 6))) {
field->type = PRINT_LF;
field->name = xstrdup("LimitFactor");
field->len = 11;
field->print_routine = print_fields_double;
} else if (!xstrncasecmp("Allocated", object, MAX(command_len, 7))) {
field->type = PRINT_ALLOCATED;
field->name = xstrdup("Allocated");
field->len = 9;
field->print_routine = print_fields_uint32;
} else if (!xstrncasecmp("LastConsumed", object, MAX(command_len, 8))) {
field->type = PRINT_LAST_CONSUMED;
field->name = xstrdup("LastConsumed");
field->len = 12;
field->print_routine = print_fields_uint32;
} else if (!xstrncasecmp("User", object, MAX(command_len, 1))) {
field->type = PRINT_USER;
field->name = xstrdup("User");
field->len = 10;
field->print_routine = print_fields_str;
} else if (!xstrncasecmp("WCKeys", object, MAX(command_len, 2))) {
field->type = PRINT_WCKEYS;
field->name = xstrdup("WCKeys");
field->len = 20;
field->print_routine = print_fields_char_list;
} else if (!xstrncasecmp("Where", object, MAX(command_len, 2))) {
field->type = PRINT_WHERE;
field->name = xstrdup("Where");
field->len = 20;
field->print_routine = print_fields_str;
} else {
exit_code=1;
fprintf(stderr, "Unknown field '%s'\n", object);
exit(1);
}
if (field_len)
field->len = field_len;
return field;
}
extern void notice_thread_init(void)
{
slurm_mutex_lock(&warn_mutex);
warn_needed = true;
slurm_thread_create(&notice_thread_handler, _print_lock_warn, NULL);
slurm_mutex_unlock(&warn_mutex);
}
extern void notice_thread_fini(void)
{
slurm_mutex_lock(&warn_mutex);
warn_needed = false;
slurm_cond_broadcast(&warn_cond);
slurm_mutex_unlock(&warn_mutex);
if (notice_thread_handler)
slurm_thread_join(notice_thread_handler);
}
extern int commit_check(char *warning)
{
int ans = 0;
int input = 0;
char c = '\0';
int fd = fileno(stdin);
fd_set rfds;
struct timeval tv;
if (!rollback_flag)
return 1;
printf("%s (You have 30 seconds to decide)\n", warning);
_nonblock(1);
while(c != 'Y' && c != 'y'
&& c != 'N' && c != 'n'
&& c != '\n') {
if (c) {
printf("Y or N please\n");
}
printf("(N/y): ");
fflush(stdout);
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Wait up to 30 seconds. */
tv.tv_sec = 30;
tv.tv_usec = 0;
if ((ans = select(fd+1, &rfds, NULL, NULL, &tv)) <= 0)
break;
printf("\n");
if ((input = getchar()) == EOF)
break;
c = (char) input;
}
_nonblock(0);
if (ans == 0)
printf("timeout\n");
else if (c == 'Y' || c == 'y')
return 1;
else if ((ans < 0) || (input < 0))
printf("error: %s\n", strerror(errno));
return 0;
}
extern int sacctmgr_remove_assoc_usage(slurmdb_assoc_cond_t *assoc_cond)
{
list_t *update_list = NULL;
list_t *local_assoc_list = NULL;
list_t *local_cluster_list = NULL;
list_itr_t *itr = NULL;
list_itr_t *itr2 = NULL;
list_itr_t *itr3 = NULL;
char *account = NULL;
char *cluster = NULL;
char *user = NULL;
slurmdb_assoc_rec_t* rec = NULL;
slurmdb_cluster_rec_t* cluster_rec = NULL;
slurmdb_update_object_t* update_obj = NULL;
slurmdb_cluster_cond_t cluster_cond;
int rc = SLURM_SUCCESS;
if (!assoc_cond || !assoc_cond->acct_list ||
!list_count(assoc_cond->acct_list)) {
error("An association name is required to remove usage");
return SLURM_ERROR;
}
if (!assoc_cond->cluster_list)
assoc_cond->cluster_list = list_create(xfree_ptr);
if (!list_count(assoc_cond->cluster_list)) {
printf("No cluster specified, resetting on local cluster %s\n",
slurm_conf.cluster_name);
list_append(assoc_cond->cluster_list,
xstrdup(slurm_conf.cluster_name));
}
if (!commit_check("Would you like to reset usage?")) {
printf(" Changes Discarded\n");
return rc;
}
local_assoc_list = slurmdb_associations_get(db_conn, assoc_cond);
slurmdb_init_cluster_cond(&cluster_cond, 0);
cluster_cond.cluster_list = assoc_cond->cluster_list;
local_cluster_list = slurmdb_clusters_get(db_conn, &cluster_cond);
itr = list_iterator_create(assoc_cond->cluster_list);
itr2 = list_iterator_create(assoc_cond->acct_list);
if (assoc_cond->user_list && list_count(assoc_cond->user_list))
itr3 = list_iterator_create(assoc_cond->user_list);
while((cluster = list_next(itr))) {
cluster_rec = sacctmgr_find_cluster_from_list(
local_cluster_list, cluster);
if (!cluster_rec) {
error("Failed to find cluster %s in database",
cluster);
rc = SLURM_ERROR;
goto end_it;
}
update_list = list_create(slurmdb_destroy_update_object);
update_obj = xmalloc(sizeof(slurmdb_update_object_t));
update_obj->type = SLURMDB_REMOVE_ASSOC_USAGE;
update_obj->objects = list_create(NULL);
if (itr3) {
while ((user = list_next(itr3))) {
while ((account = list_next(itr2))) {
rec = sacctmgr_find_assoc_from_list(
local_assoc_list,
user, account, cluster, "*");
if (!rec) {
error("Failed to find "
"cluster %s "
"account %s user "
"%s association "
"in database",
cluster, account,
user);
rc = SLURM_ERROR;
slurmdb_destroy_update_object(
update_obj);
goto end_it;
}
list_append(update_obj->objects, rec);
}
list_iterator_reset(itr2);
}
list_iterator_reset(itr3);
} else {
while ((account = list_next(itr2))) {
rec = sacctmgr_find_assoc_from_list(
local_assoc_list,
NULL, account, cluster, "*");
if (!rec) {
error("Failed to find cluster %s "
"account %s association in "
"database",
cluster, account);
rc = SLURM_ERROR;
slurmdb_destroy_update_object(
update_obj);
goto end_it;
}
list_append(update_obj->objects, rec);
}
list_iterator_reset(itr2);
}
if (list_count(update_obj->objects)) {
list_append(update_list, update_obj);
rc = slurmdb_send_accounting_update(
update_list, cluster,
cluster_rec->control_host,
cluster_rec->control_port,
cluster_rec->rpc_version);
} else {
slurmdb_destroy_update_object(update_obj);
}
update_obj = NULL;
FREE_NULL_LIST(update_list);
}
end_it:
list_iterator_destroy(itr);
list_iterator_destroy(itr2);
if (itr3)
list_iterator_destroy(itr3);
FREE_NULL_LIST(local_assoc_list);
FREE_NULL_LIST(local_cluster_list);
return rc;
}
extern int sacctmgr_update_qos_usage(slurmdb_qos_cond_t *qos_cond,
long double new_raw_usage)
{
list_t *update_list = NULL;
list_t *cluster_list;
list_t *local_qos_list = NULL;
list_t *local_cluster_list = NULL;
list_itr_t *itr = NULL, *itr2 = NULL;
char *qos_name = NULL, *cluster_name = NULL;
slurmdb_qos_rec_t* rec = NULL;
slurmdb_cluster_rec_t* cluster_rec = NULL;
slurmdb_update_object_t* update_obj = NULL;
slurmdb_cluster_cond_t cluster_cond;
int rc = SLURM_SUCCESS;
cluster_list = qos_cond->description_list;
qos_cond->description_list = NULL;
if (!cluster_list)
cluster_list = list_create(xfree_ptr);
if (!list_count(cluster_list)) {
printf("No cluster specified, resetting on local cluster %s\n",
slurm_conf.cluster_name);
list_append(cluster_list, xstrdup(slurm_conf.cluster_name));
}
if (!commit_check("Would you like to update usage?")) {
printf(" Changes Discarded\n");
return rc;
}
local_qos_list = slurmdb_qos_get(db_conn, qos_cond);
slurmdb_init_cluster_cond(&cluster_cond, 0);
cluster_cond.cluster_list = cluster_list;
local_cluster_list = slurmdb_clusters_get(db_conn, &cluster_cond);
itr = list_iterator_create(cluster_list);
itr2 = list_iterator_create(qos_cond->name_list);
while ((cluster_name = list_next(itr))) {
cluster_rec = sacctmgr_find_cluster_from_list(
local_cluster_list, cluster_name);
if (!cluster_rec) {
error("Failed to find cluster %s in database",
cluster_name);
rc = SLURM_ERROR;
goto end_it;
}
update_list = list_create(slurmdb_destroy_update_object);
update_obj = xmalloc(sizeof(slurmdb_update_object_t));
update_obj->type = SLURMDB_UPDATE_QOS_USAGE;
update_obj->objects = list_create(NULL);
while ((qos_name = list_next(itr2))) {
rec = sacctmgr_find_qos_from_list(
local_qos_list, qos_name);
if (!rec) {
error("Failed to find QOS %s", qos_name);
rc = SLURM_ERROR;
slurmdb_destroy_update_object(update_obj);
goto end_it;
}
if (!rec->usage)
rec->usage = xmalloc(sizeof(*rec->usage));
rec->usage->usage_raw = new_raw_usage;
list_append(update_obj->objects, rec);
}
list_iterator_reset(itr2);
if (list_count(update_obj->objects)) {
list_append(update_list, update_obj);
rc = slurmdb_send_accounting_update(
update_list, cluster_name,
cluster_rec->control_host,
cluster_rec->control_port,
cluster_rec->rpc_version);
} else {
slurmdb_destroy_update_object(update_obj);
}
FREE_NULL_LIST(update_list);
}
end_it:
list_iterator_destroy(itr);
list_iterator_destroy(itr2);
FREE_NULL_LIST(update_list);
FREE_NULL_LIST(local_qos_list);
xfree(cluster_name);
return rc;
}
extern slurmdb_assoc_rec_t *sacctmgr_find_account_base_assoc(
char *account, char *cluster)
{
slurmdb_assoc_rec_t *assoc = NULL;
char *temp = "root";
slurmdb_assoc_cond_t assoc_cond;
list_t *assoc_list = NULL;
if (!cluster)
return NULL;
if (account)
temp = account;
memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
assoc_cond.acct_list = list_create(NULL);
list_append(assoc_cond.cluster_list, temp);
assoc_cond.cluster_list = list_create(NULL);
list_append(assoc_cond.cluster_list, cluster);
assoc_cond.user_list = list_create(NULL);
list_append(assoc_cond.user_list, "");
assoc_list = slurmdb_associations_get(db_conn, &assoc_cond);
FREE_NULL_LIST(assoc_cond.acct_list);
FREE_NULL_LIST(assoc_cond.cluster_list);
FREE_NULL_LIST(assoc_cond.user_list);
if (assoc_list)
assoc = list_pop(assoc_list);
FREE_NULL_LIST(assoc_list);
return assoc;
}
extern slurmdb_assoc_rec_t *sacctmgr_find_root_assoc(char *cluster)
{
return sacctmgr_find_account_base_assoc(NULL, cluster);
}
extern slurmdb_user_rec_t *sacctmgr_find_user(char *name)
{
slurmdb_user_rec_t *user = NULL;
slurmdb_user_cond_t user_cond;
slurmdb_assoc_cond_t assoc_cond;
list_t *user_list = NULL;
if (!name)
return NULL;
memset(&user_cond, 0, sizeof(slurmdb_user_cond_t));
memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
assoc_cond.user_list = list_create(NULL);
list_append(assoc_cond.user_list, name);
user_cond.assoc_cond = &assoc_cond;
user_list = slurmdb_users_get(db_conn, &user_cond);
FREE_NULL_LIST(assoc_cond.user_list);
if (user_list)
user = list_pop(user_list);
FREE_NULL_LIST(user_list);
return user;
}
extern slurmdb_account_rec_t *sacctmgr_find_account(char *name)
{
slurmdb_account_rec_t *account = NULL;
slurmdb_account_cond_t account_cond;
slurmdb_assoc_cond_t assoc_cond;
list_t *account_list = NULL;
if (!name)
return NULL;
memset(&account_cond, 0, sizeof(slurmdb_account_cond_t));
memset(&assoc_cond, 0, sizeof(slurmdb_assoc_cond_t));
assoc_cond.acct_list = list_create(NULL);
list_append(assoc_cond.acct_list, name);
account_cond.assoc_cond = &assoc_cond;
account_list = slurmdb_accounts_get(db_conn, &account_cond);
FREE_NULL_LIST(assoc_cond.acct_list);
if (account_list)
account = list_pop(account_list);
FREE_NULL_LIST(account_list);
return account;
}
extern slurmdb_cluster_rec_t *sacctmgr_find_cluster(char *name)
{
slurmdb_cluster_rec_t *cluster = NULL;
slurmdb_cluster_cond_t cluster_cond;
list_t *cluster_list = NULL;
if (!name)
return NULL;
slurmdb_init_cluster_cond(&cluster_cond, 0);
cluster_cond.cluster_list = list_create(NULL);
list_append(cluster_cond.cluster_list, name);
cluster_list = slurmdb_clusters_get(db_conn, &cluster_cond);
FREE_NULL_LIST(cluster_cond.cluster_list);
if (cluster_list)
cluster = list_pop(cluster_list);
FREE_NULL_LIST(cluster_list);
return cluster;
}
extern slurmdb_assoc_rec_t *sacctmgr_find_assoc_from_list(
list_t *assoc_list, char *user, char *account,
char *cluster, char *partition)
{
list_itr_t *itr = NULL;
slurmdb_assoc_rec_t * assoc = NULL;
if (!assoc_list)
return NULL;
itr = list_iterator_create(assoc_list);
while((assoc = list_next(itr))) {
if (((!user && assoc->user)
|| (user && (!assoc->user
|| xstrcasecmp(user, assoc->user))))
|| (account && (!assoc->acct
|| xstrcasecmp(account, assoc->acct)))
|| ((!cluster && assoc->cluster)
|| (cluster && (!assoc->cluster
|| xstrcasecmp(cluster,
assoc->cluster)))))
continue;
else if (partition) {
if (partition[0] != '*'
&& (!assoc->partition
|| xstrcasecmp(partition, assoc->partition)))
continue;
} else if (assoc->partition)
continue;
break;
}
list_iterator_destroy(itr);
return assoc;
}
extern slurmdb_assoc_rec_t *sacctmgr_find_account_base_assoc_from_list(
list_t *assoc_list, char *account, char *cluster)
{
list_itr_t *itr = NULL;
slurmdb_assoc_rec_t *assoc = NULL;
char *temp = "root";
if (!cluster || !assoc_list)
return NULL;
if (account)
temp = account;
/* info("looking for %s %s in %d", account, cluster, */
/* list_count(assoc_list)); */
itr = list_iterator_create(assoc_list);
while((assoc = list_next(itr))) {
/* info("is it %s %s %s", assoc->user, assoc->acct, assoc->cluster); */
if (assoc->user
|| xstrcasecmp(temp, assoc->acct)
|| xstrcasecmp(cluster, assoc->cluster))
continue;
/* info("found it"); */
break;
}
list_iterator_destroy(itr);
return assoc;
}
extern slurmdb_qos_rec_t *sacctmgr_find_qos_from_list(
list_t *qos_list, char *name)
{
list_itr_t *itr = NULL;
slurmdb_qos_rec_t *qos = NULL;
char *working_name = NULL;
if (!name || !qos_list)
return NULL;
if (name[0] == '+' || name[0] == '-')
working_name = name+1;
else
working_name = name;
itr = list_iterator_create(qos_list);
while((qos = list_next(itr))) {
if (!xstrcasecmp(working_name, qos->name))
break;
}
list_iterator_destroy(itr);
return qos;
}
extern slurmdb_res_rec_t *sacctmgr_find_res_from_list(
list_t *res_list, uint32_t id, char *name, char *server)
{
list_itr_t *itr = NULL;
slurmdb_res_rec_t *res = NULL;
if ((id == NO_VAL) && (!name || !res_list))
return NULL;
itr = list_iterator_create(res_list);
while ((res = list_next(itr))) {
if ((id == res->id)
|| (name && server
&& !xstrcasecmp(server, res->server)
&& !xstrcasecmp(name, res->name)))
break;
}
list_iterator_destroy(itr);
return res;
}
extern slurmdb_user_rec_t *sacctmgr_find_user_from_list(
list_t *user_list, char *name)
{
list_itr_t *itr = NULL;
slurmdb_user_rec_t *user = NULL;
if (!name || !user_list)
return NULL;
itr = list_iterator_create(user_list);
while((user = list_next(itr))) {
if (!xstrcasecmp(name, user->name))
break;
}
list_iterator_destroy(itr);
return user;
}
extern slurmdb_account_rec_t *sacctmgr_find_account_from_list(
list_t *acct_list, char *name)
{
list_itr_t *itr = NULL;
slurmdb_account_rec_t *account = NULL;
if (!name || !acct_list)
return NULL;
itr = list_iterator_create(acct_list);
while((account = list_next(itr))) {
if (!xstrcasecmp(name, account->name))
break;
}
list_iterator_destroy(itr);
return account;
}
extern slurmdb_cluster_rec_t *sacctmgr_find_cluster_from_list(
list_t *cluster_list, char *name)
{
list_itr_t *itr = NULL;
slurmdb_cluster_rec_t *cluster = NULL;
if (!name || !cluster_list)
return NULL;
itr = list_iterator_create(cluster_list);
while((cluster = list_next(itr))) {
if (!xstrcasecmp(name, cluster->name))
break;
}
list_iterator_destroy(itr);
return cluster;
}
extern slurmdb_wckey_rec_t *sacctmgr_find_wckey_from_list(
list_t *wckey_list, char *user, char *name, char *cluster)
{
list_itr_t *itr = NULL;
slurmdb_wckey_rec_t * wckey = NULL;
if (!wckey_list)
return NULL;
itr = list_iterator_create(wckey_list);
while((wckey = list_next(itr))) {
if (((!user && wckey->user)
|| (user && (!wckey->user
|| xstrcasecmp(user, wckey->user))))
|| (name && (!wckey->name
|| xstrcasecmp(name, wckey->name)))
|| ((!cluster && wckey->cluster)
|| (cluster && (!wckey->cluster
|| xstrcasecmp(cluster,
wckey->cluster)))))
continue;
break;
}
list_iterator_destroy(itr);
return wckey;
}
extern int get_uint(char *in_value, uint32_t *out_value, char *type)
{
char *ptr = NULL, *meat = NULL;
long num;
if (!(meat = strip_quotes(in_value, NULL, 1))) {
error("Problem with strip_quotes");
return SLURM_ERROR;
}
num = strtol(meat, &ptr, 10);
if ((num == 0) && ptr && ptr[0]) {
error("Invalid value for %s (%s)", type, meat);
xfree(meat);
return SLURM_ERROR;
}
xfree(meat);
if (num < 0)
*out_value = INFINITE; /* flag to clear */
else
*out_value = (uint32_t) num;
return SLURM_SUCCESS;
}
extern int get_uint16(char *in_value, uint16_t *out_value, char *type)
{
char *ptr = NULL, *meat = NULL;
long num;
if (!(meat = strip_quotes(in_value, NULL, 1))) {
error("Problem with strip_quotes");
return SLURM_ERROR;
}
num = strtol(meat, &ptr, 10);
if ((num == 0) && ptr && ptr[0]) {
error("Invalid value for %s (%s)", type, meat);
xfree(meat);
return SLURM_ERROR;
}
xfree(meat);
if (num < 0)
*out_value = INFINITE16; /* flag to clear */
else
*out_value = (uint16_t) num;
return SLURM_SUCCESS;
}
extern int get_uint64(char *in_value, uint64_t *out_value, char *type)
{
char *ptr = NULL, *meat = NULL;
long long num;
if (!(meat = strip_quotes(in_value, NULL, 1))) {
error("Problem with strip_quotes");
return SLURM_ERROR;
}
num = strtoll(meat, &ptr, 10);
if ((num == 0) && ptr && ptr[0]) {
error("Invalid value for %s (%s)", type, meat);
xfree(meat);
return SLURM_ERROR;
}
xfree(meat);
if (num < 0)
*out_value = INFINITE64; /* flag to clear */
else
*out_value = (uint64_t) num;
return SLURM_SUCCESS;
}
extern int get_double(char *in_value, double *out_value, char *type)
{
char *meat = NULL;
double num;
if (!(meat = strip_quotes(in_value, NULL, 1))) {
error("Problem with strip_quotes");
return SLURM_ERROR;
}
if (s_p_handle_double(&num, type, meat)) {
xfree(meat);
return SLURM_ERROR;
}
xfree(meat);
if (num < 0)
*out_value = (double) INFINITE; /* flag to clear */
else
*out_value = (double) num;
return SLURM_SUCCESS;
}
static int _addto_action_char_list_internal(list_t *char_list, char *name,
void *x)
{
uint32_t id = 0;
char *tmp_name = NULL;
id = str_2_slurmdbd_msg_type(name);
if (id == NO_VAL) {
error("You gave a bad action '%s'.", name);
list_flush(char_list);
return SLURM_ERROR;
}
tmp_name = xstrdup_printf("%u", id);
if (!list_find_first(char_list, slurm_find_char_in_list, tmp_name)) {
list_append(char_list, tmp_name);
return 1;
} else {
xfree(tmp_name);
return 0;
}
}
extern int addto_action_char_list(list_t *char_list, char *names)
{
if (!char_list) {
error("No list was given to fill in");
return 0;
}
return slurm_parse_char_list(char_list, names, NULL,
_addto_action_char_list_internal);
}
extern void sacctmgr_print_coord_list(
print_field_t *field, void *input, int last)
{
int abs_len = abs(field->len);
list_itr_t *itr = NULL;
char *print_this = NULL;
list_t *value = NULL;
slurmdb_coord_rec_t *object = NULL;
if (input)
value = *(list_t **)input;
if (!value || !list_count(value)) {
if (print_fields_parsable_print)
print_this = xstrdup("");
else
print_this = xstrdup(" ");
} else {
list_sort(value, (ListCmpF)sort_coord_list);
itr = list_iterator_create(value);
while((object = list_next(itr))) {
if (print_this)
xstrfmtcat(print_this, ",%s",
object->name);
else
print_this = xstrdup(object->name);
}
list_iterator_destroy(itr);
}
if (print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
&& last)
printf("%s", print_this);
else if (print_fields_parsable_print)
printf("%s|", print_this);
else if (print_this) {
if (strlen(print_this) > abs_len)
print_this[abs_len-1] = '+';
if (field->len == abs_len)
printf("%*.*s ", abs_len, abs_len, print_this);
else
printf("%-*.*s ", abs_len, abs_len, print_this);
}
xfree(print_this);
}
extern void sacctmgr_print_tres(print_field_t *field, void *input, int last)
{
int abs_len = abs(field->len);
char *print_this;
char *value = NULL;
if (input)
value = *(char **) input;
sacctmgr_initialize_g_tres_list();
print_this = slurmdb_make_tres_string_from_simple(
value, g_tres_list, NO_VAL, CONVERT_NUM_UNIT_EXACT, 0, NULL);
if (!print_this)
print_this = xstrdup("");
if (print_fields_parsable_print == PRINT_FIELDS_PARSABLE_NO_ENDING
&& last)
printf("%s", print_this);
else if (print_fields_parsable_print)
printf("%s|", print_this);
else {
if (strlen(print_this) > abs_len)
print_this[abs_len-1] = '+';
if (field->len == abs_len)
printf("%*.*s ", abs_len, abs_len, print_this);
else
printf("%-*.*s ", abs_len, abs_len, print_this);
}
xfree(print_this);
}
extern void sacctmgr_print_assoc_limits(slurmdb_assoc_rec_t *assoc)
{
char *tmp_char;
if (!assoc)
return;
if (assoc->shares_raw == INFINITE)
printf(" Fairshare = NONE\n");
else if (assoc->shares_raw == SLURMDB_FS_USE_PARENT)
printf(" Fairshare = parent\n");
else if (assoc->shares_raw != NO_VAL)
printf(" Fairshare = %u\n", assoc->shares_raw);
if (assoc->grp_jobs == INFINITE)
printf(" GrpJobs = NONE\n");
else if (assoc->grp_jobs != NO_VAL)
printf(" GrpJobs = %u\n", assoc->grp_jobs);
if (assoc->grp_jobs_accrue == INFINITE)
printf(" GrpJobsAccrue = None\n");
else if (assoc->grp_jobs_accrue != NO_VAL)
printf(" GrpJobsAccrue = %u\n",
assoc->grp_jobs_accrue);
if (assoc->grp_submit_jobs == INFINITE)
printf(" GrpSubmitJobs = NONE\n");
else if (assoc->grp_submit_jobs != NO_VAL)
printf(" GrpSubmitJobs = %u\n",
assoc->grp_submit_jobs);
if (assoc->grp_tres) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->grp_tres, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" GrpTRES = %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->grp_tres_mins) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->grp_tres_mins, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);;
printf(" GrpTRESMins = %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->grp_tres_run_mins) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->grp_tres_run_mins, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" GrpTRESRunMins= %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->grp_wall == INFINITE)
printf(" GrpWall = NONE\n");
else if (assoc->grp_wall != NO_VAL) {
char time_buf[32];
mins2time_str((time_t) assoc->grp_wall,
time_buf, sizeof(time_buf));
printf(" GrpWall = %s\n", time_buf);
}
if (assoc->max_jobs == INFINITE)
printf(" MaxJobs = NONE\n");
else if (assoc->max_jobs != NO_VAL)
printf(" MaxJobs = %u\n", assoc->max_jobs);
if (assoc->max_jobs_accrue == INFINITE)
printf(" MaxJobsPrioAcc= NONE\n");
else if (assoc->max_jobs_accrue != NO_VAL)
printf(" MaxJobsPrioAcc= %u\n", assoc->max_jobs_accrue);
if (assoc->max_submit_jobs == INFINITE)
printf(" MaxSubmitJobs = NONE\n");
else if (assoc->max_submit_jobs != NO_VAL)
printf(" MaxSubmitJobs = %u\n",
assoc->max_submit_jobs);
if (assoc->max_tres_pj) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->max_tres_pj, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRES = %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->max_tres_pn) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->max_tres_pn, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESPerNode= %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->max_tres_mins_pj) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->max_tres_mins_pj, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESMins = %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->max_tres_run_mins) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
assoc->max_tres_run_mins, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESRUNMins= %s\n", tmp_char);
xfree(tmp_char);
}
if (assoc->max_wall_pj == INFINITE)
printf(" MaxWall = NONE\n");
else if (assoc->max_wall_pj != NO_VAL) {
char time_buf[32];
mins2time_str((time_t) assoc->max_wall_pj,
time_buf, sizeof(time_buf));
printf(" MaxWall = %s\n", time_buf);
}
if (assoc->min_prio_thresh == INFINITE)
printf(" MinPrioThresh = NONE\n");
else if (assoc->min_prio_thresh != NO_VAL)
printf(" MinPrioThresh = %u\n", assoc->min_prio_thresh);
if (assoc->parent_acct)
printf(" Parent = %s\n", assoc->parent_acct);
if (assoc->priority == INFINITE)
printf(" Priority = NONE\n");
else if (assoc->priority != NO_VAL)
printf(" Priority = %d\n", assoc->priority);
if (assoc->qos_list) {
if (!g_qos_list)
g_qos_list =
slurmdb_qos_get(db_conn, NULL);
char *temp_char = get_qos_complete_str(g_qos_list,
assoc->qos_list);
if (temp_char) {
printf(" QOS = %s\n", temp_char);
xfree(temp_char);
}
}
if (assoc->def_qos_id != NO_VAL) {
if (!g_qos_list)
g_qos_list =
slurmdb_qos_get(db_conn, NULL);
printf(" DefQOS = %s\n",
slurmdb_qos_str(g_qos_list, assoc->def_qos_id));
}
/* This should be last because it might be long */
if (assoc->comment)
printf(" Comment = %s\n", assoc->comment);
}
static int _print_cluster_features(void *object, void *arg)
{
char *feature = (char *)object;
if (feature[0] == '+' || feature[0] == '-')
printf(" Feature %c= %s\n", feature[0], feature + 1);
else
printf(" Feature = %s\n", feature);
return SLURM_SUCCESS;
}
extern void sacctmgr_print_cluster(slurmdb_cluster_rec_t *cluster)
{
if (!cluster)
return;
if (cluster->name)
printf(" Name = %s\n", cluster->name);
if (cluster->classification)
printf(" Classification = %s\n",
get_classification_str(cluster->classification));
if (cluster->fed.feature_list) {
if (!list_count(cluster->fed.feature_list))
printf(" Feature = \n");
else
list_for_each(cluster->fed.feature_list,
_print_cluster_features, NULL);
}
if (cluster->fed.name)
printf(" Federation = %s\n", cluster->fed.name);
if (cluster->fed.state != NO_VAL) {
char *tmp_str = slurmdb_cluster_fed_states_str(
cluster->fed.state);
printf(" FedState = %s\n", tmp_str);
}
}
extern void sacctmgr_print_federation(slurmdb_federation_rec_t *fed)
{
if (!fed)
return;
if (fed->name)
printf(" Name = %s\n", fed->name);
if (fed->flags && (fed->flags != FEDERATION_FLAG_NOTSET)) {
char *mode = NULL;
char *tmp_flags =
slurmdb_federation_flags_str(fed->flags);
if (fed->flags & FEDERATION_FLAG_ADD)
mode = "+";
else if (fed->flags & FEDERATION_FLAG_REMOVE)
mode = "-";
else
mode = " ";
printf(" Flags %s= %s\n", mode, tmp_flags);
xfree(tmp_flags);
}
if (fed->cluster_list) {
list_itr_t *itr = list_iterator_create(fed->cluster_list);
slurmdb_cluster_rec_t *cluster = NULL;
while ((cluster = list_next(itr))) {
char *tmp_name = cluster->name;
if (tmp_name &&
(tmp_name[0] == '+' || tmp_name[0] == '-'))
printf(" Cluster %c= %s\n",
tmp_name[0], tmp_name + 1);
else
printf(" Cluster = %s\n", tmp_name);
}
list_iterator_destroy(itr);
}
}
extern void sacctmgr_print_qos_limits(slurmdb_qos_rec_t *qos)
{
char *tmp_char;
if (!qos)
return;
if (qos->preempt_list && !g_qos_list)
g_qos_list = slurmdb_qos_get(db_conn, NULL);
if (qos->flags && (qos->flags != QOS_FLAG_NOTSET)) {
char *tmp_char = slurmdb_qos_flags_str(qos->flags);
printf(" Flags = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->grace_time == INFINITE)
printf(" GraceTime = NONE\n");
else if (qos->grace_time != NO_VAL)
printf(" GraceTime = %d\n", qos->grace_time);
if (qos->grp_jobs == INFINITE)
printf(" GrpJobs = NONE\n");
else if (qos->grp_jobs != NO_VAL)
printf(" GrpJobs = %u\n", qos->grp_jobs);
if (qos->grp_jobs_accrue == INFINITE)
printf(" GrpJobsAccrue = None\n");
else if (qos->grp_jobs_accrue != NO_VAL)
printf(" GrpJobsAccrue = %u\n",
qos->grp_jobs_accrue);
if (qos->grp_submit_jobs == INFINITE)
printf(" GrpSubmitJobs = NONE\n");
else if (qos->grp_submit_jobs != NO_VAL)
printf(" GrpSubmitJobs = %u\n",
qos->grp_submit_jobs);
if (qos->grp_tres) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->grp_tres, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" GrpTRES = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->grp_tres_mins) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->grp_tres_mins, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" GrpTRESMins = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->grp_tres_run_mins) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->grp_tres_run_mins, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" GrpTRESRunMins = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->grp_wall == INFINITE)
printf(" GrpWall = NONE\n");
else if (qos->grp_wall != NO_VAL) {
char time_buf[32];
mins2time_str((time_t) qos->grp_wall,
time_buf, sizeof(time_buf));
printf(" GrpWall = %s\n", time_buf);
}
if (qos->max_jobs_accrue_pa == INFINITE)
printf(" MaxJobsAccruePerAccount = NONE\n");
else if(qos->max_jobs_accrue_pa != NO_VAL)
printf(" MaxJobsAccruePerAccount = %u\n",
qos->max_jobs_accrue_pa);
if (qos->max_jobs_accrue_pu == INFINITE)
printf(" MaxJobsAccruePerUser = NONE\n");
else if(qos->max_jobs_accrue_pu != NO_VAL)
printf(" MaxJobsAccruePerUser = %u\n",
qos->max_jobs_accrue_pu);
if (qos->max_jobs_pa == INFINITE)
printf(" MaxJobsPerAccount = NONE\n");
else if (qos->max_jobs_pa != NO_VAL)
printf(" MaxJobsPerAccount = %u\n",
qos->max_jobs_pa);
if (qos->max_jobs_pu == INFINITE)
printf(" MaxJobsPerUser = NONE\n");
else if (qos->max_jobs_pu != NO_VAL)
printf(" MaxJobsPerUser = %u\n",
qos->max_jobs_pu);
if (qos->max_submit_jobs_pa == INFINITE)
printf(" MaxSubmitJobsPerAccount = NONE\n");
else if (qos->max_submit_jobs_pa != NO_VAL)
printf(" MaxSubmitJobsPerAccount = %u\n",
qos->max_submit_jobs_pa);
if (qos->max_submit_jobs_pu == INFINITE)
printf(" MaxSubmitJobsPerUser = NONE\n");
else if (qos->max_submit_jobs_pu != NO_VAL)
printf(" MaxSubmitJobsPerUser = %u\n",
qos->max_submit_jobs_pu);
if (qos->max_tres_pa) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_pa, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESPerAccount = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_pj) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_pj, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESPerJob = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_pn) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_pn, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESPerNode = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_pu) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_pu, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESPerUser = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->min_prio_thresh == INFINITE)
printf(" MinPrioThresh = NONE\n");
else if (qos->min_prio_thresh != NO_VAL)
printf(" MinPrioThresh = %u\n",
qos->min_prio_thresh);
if (qos->min_tres_pj) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->min_tres_pj, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MinTRESPerJob = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_mins_pj) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_mins_pj, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESMins = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_run_mins_pa) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_run_mins_pa, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESRUNMinsPerAccount = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_tres_run_mins_pu) {
sacctmgr_initialize_g_tres_list();
tmp_char = slurmdb_make_tres_string_from_simple(
qos->max_tres_run_mins_pu, g_tres_list, NO_VAL,
CONVERT_NUM_UNIT_EXACT, 0, NULL);
printf(" MaxTRESRUNMinsPerUser = %s\n", tmp_char);
xfree(tmp_char);
}
if (qos->max_wall_pj == INFINITE)
printf(" MaxWall = NONE\n");
else if (qos->max_wall_pj != NO_VAL) {
char time_buf[32];
mins2time_str((time_t) qos->max_wall_pj,
time_buf, sizeof(time_buf));
printf(" MaxWall = %s\n", time_buf);
}
if (qos->preempt_list) {
char *temp_char = get_qos_complete_str(g_qos_list,
qos->preempt_list);
if (temp_char) {
printf(" Preempt = %s\n", temp_char);
xfree(temp_char);
}
}
if (qos->preempt_mode && (qos->preempt_mode != NO_VAL16)) {
printf(" PreemptMode = %s\n",
preempt_mode_string(qos->preempt_mode));
}
if (qos->preempt_exempt_time == INFINITE) {
printf(" PreemptExemptTime = NONE\n");
} else if (qos->preempt_exempt_time != NO_VAL) {
char time_buf[32];
secs2time_str((time_t) qos->preempt_exempt_time, time_buf,
sizeof(time_buf));
printf(" PreemptExemptTime = %s\n",
time_buf);
}
if (qos->priority == INFINITE)
printf(" Priority = NONE\n");
else if (qos->priority != NO_VAL)
printf(" Priority = %d\n", qos->priority);
if (qos->usage_factor == INFINITE)
printf(" UsageFactor = NONE\n");
else if(qos->usage_factor != NO_VAL)
printf(" UsageFactor = %.4lf\n", qos->usage_factor);
if (qos->usage_thres == INFINITE)
printf(" UsageThreshold = NONE\n");
else if (qos->usage_thres != NO_VAL)
printf(" UsageThreshold = %.4lf\n", qos->usage_thres);
if (qos->limit_factor == INFINITE)
printf(" LimitFactor = NONE\n");
else if(qos->limit_factor != NO_VAL)
printf(" LimitFactor = %.4lf\n", qos->limit_factor);
}
extern int sort_coord_list(void *a, void *b)
{
slurmdb_coord_rec_t *coord_a = *(slurmdb_coord_rec_t **)a;
slurmdb_coord_rec_t *coord_b = *(slurmdb_coord_rec_t **)b;
int diff;
diff = xstrcmp(coord_a->name, coord_b->name);
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
return 0;
}
extern list_t *sacctmgr_process_format_list(list_t *format_list)
{
list_t *print_fields_list = list_create(destroy_print_field);
list_itr_t *itr = list_iterator_create(format_list);
print_field_t *field = NULL;
char *object = NULL;
while((object = list_next(itr))) {
if (!(field = _get_print_field(object)))
exit(1);
list_append(print_fields_list, field);
}
list_iterator_destroy(itr);
return print_fields_list;
}
extern int sacctmgr_validate_cluster_list(list_t *cluster_list)
{
list_t *temp_list = NULL;
char *cluster = NULL;
int rc = SLURM_SUCCESS;
list_itr_t *itr = NULL, *itr_c = NULL;
xassert(cluster_list);
slurmdb_cluster_cond_t cluster_cond;
slurmdb_init_cluster_cond(&cluster_cond, 0);
cluster_cond.cluster_list = cluster_list;
temp_list = slurmdb_clusters_get(db_conn, &cluster_cond);
itr_c = list_iterator_create(cluster_list);
itr = list_iterator_create(temp_list);
while ((cluster = list_next(itr_c))) {
slurmdb_cluster_rec_t *cluster_rec = NULL;
list_iterator_reset(itr);
while ((cluster_rec = list_next(itr))) {
if (!xstrcasecmp(cluster_rec->name, cluster)) {
if (cluster_rec->flags & CLUSTER_FLAG_EXT) {
fprintf(stderr, " The cluster '%s' is an external cluster. Can't work with it.\n",
cluster);
list_delete_item(itr_c);
}
break;
}
}
if (!cluster_rec) {
exit_code=1;
fprintf(stderr, " This cluster '%s' "
"doesn't exist.\n"
" Contact your admin "
"to add it to accounting.\n",
cluster);
list_delete_item(itr_c);
}
}
list_iterator_destroy(itr);
list_iterator_destroy(itr_c);
FREE_NULL_LIST(temp_list);
if (!list_count(cluster_list))
rc = SLURM_ERROR;
return rc;
}
extern void sacctmgr_initialize_g_tres_list(void)
{
if (!g_tres_list) {
slurmdb_tres_cond_t tres_cond;
memset(&tres_cond, 0, sizeof(slurmdb_tres_cond_t));
tres_cond.with_deleted = 1;
g_tres_list = slurmdb_tres_get(db_conn, &tres_cond);
}
}