blob: f6c659ddec42ac75a957d02726fd0d2be4aa7b3a [file] [log] [blame]
/*****************************************************************************\
* as_mysql_qos.c - functions dealing with qos.
*****************************************************************************
* Copyright (C) 2004-2007 The Regents of the University of California.
* Copyright (C) 2008-2010 Lawrence Livermore National Security.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
*
* 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 "as_mysql_qos.h"
static char *mqos_req_inx[] = {
"id",
"name",
"preempt",
"grp_tres_mins",
"grp_tres_run_mins",
"grp_tres",
"max_tres_mins_pj",
"max_tres_run_mins_pa",
"max_tres_run_mins_pu",
"max_tres_pa",
"max_tres_pj",
"max_tres_pn",
"max_tres_pu",
"min_tres_pj",
};
enum {
MQOS_ID,
MQOS_NAME,
MQOS_PREEMPT,
MQOS_GTM,
MQOS_GTRM,
MQOS_GT,
MQOS_MTMPJ,
MQOS_MTRMA,
MQOS_MTRM,
MQOS_MTPA,
MQOS_MTPJ,
MQOS_MTPN,
MQOS_MTPU,
MQOS_MITPJ,
MQOS_COUNT
};
static int _preemption_loop(mysql_conn_t *mysql_conn, int begin_qosid,
bitstr_t *preempt_bitstr)
{
slurmdb_qos_rec_t qos_rec;
int rc = 0, i = 0;
xassert(preempt_bitstr);
if (bit_test(preempt_bitstr, begin_qosid)) {
error("QOS ID %d has an internal loop", begin_qosid);
return 1;
}
/* check in the preempt list for all qos's preempted */
for (i = 0; i < bit_size(preempt_bitstr); i++) {
if (!bit_test(preempt_bitstr, i))
continue;
memset(&qos_rec, 0, sizeof(qos_rec));
qos_rec.id = i;
if (assoc_mgr_fill_in_qos(mysql_conn, &qos_rec,
ACCOUNTING_ENFORCE_QOS, NULL, 0) !=
SLURM_SUCCESS) {
error("QOS ID %d not found", i);
rc = 1;
break;
}
/*
* check if the begin_qosid is preempted by this qos
* if so we have a loop
*/
if (qos_rec.preempt_bitstr
&& (bit_test(qos_rec.preempt_bitstr, begin_qosid) ||
bit_test(qos_rec.preempt_bitstr, i))) {
error("QOS ID %d has a loop at QOS %s",
begin_qosid, qos_rec.name);
rc = 1;
break;
} else if (qos_rec.preempt_bitstr) {
/*
* check this qos' preempt list and make sure
* no loops exist there either
*/
if ((rc = _preemption_loop(mysql_conn, begin_qosid,
qos_rec.preempt_bitstr)))
break;
}
}
return rc;
}
static int _setup_qos_cond_limits(slurmdb_qos_cond_t *qos_cond, char **extra)
{
int set = 0;
list_itr_t *itr = NULL;
char *object = NULL;
xassert(extra);
xassert(*extra);
if (!qos_cond)
return 0;
/*
* Don't handle with_deleted here, we don't want to delete or modify
* deleted things
*/
/* if (qos_cond->with_deleted) */
/* xstrcat(extra, "where (deleted=0 || deleted=1)"); */
/* else */
/* xstrcat(extra, "where deleted=0"); */
if (qos_cond->description_list &&
list_count(qos_cond->description_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(qos_cond->description_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "description='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
}
if (qos_cond->id_list &&
list_count(qos_cond->id_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(qos_cond->id_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "id='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
}
if (qos_cond->name_list &&
list_count(qos_cond->name_list)) {
set = 0;
xstrcat(*extra, " && (");
itr = list_iterator_create(qos_cond->name_list);
while ((object = list_next(itr))) {
if (set)
xstrcat(*extra, " || ");
xstrfmtcat(*extra, "name='%s'", object);
set = 1;
}
list_iterator_destroy(itr);
xstrcat(*extra, ")");
}
if ((qos_cond->preempt_mode != NO_VAL16) && qos_cond->preempt_mode) {
set = 1;
xstrfmtcat(*extra, " && (preempt_mode&%d",
qos_cond->preempt_mode);
if (qos_cond->preempt_mode & PREEMPT_MODE_COND_OFF)
xstrcat(*extra, " || preempt_mode=0");
xstrcat(*extra, ")");
}
return set;
}
static int _setup_qos_limits(slurmdb_qos_rec_t *qos,
char **cols, char **vals,
char **extra, char **added_preempt,
bool for_add)
{
uint32_t tres_str_flags = TRES_STR_FLAG_REMOVE |
TRES_STR_FLAG_SORT_ID | TRES_STR_FLAG_SIMPLE |
TRES_STR_FLAG_NO_NULL;
if (!qos)
return SLURM_ERROR;
if (for_add) {
/* If we are adding we should make sure we don't get
old reside sitting around from a former life.
*/
if (!qos->description)
qos->description = xstrdup("");
if (qos->flags & (QOS_FLAG_NOTSET | QOS_FLAG_REMOVE))
qos->flags = 0;
if (qos->grace_time == NO_VAL)
qos->grace_time = 0;
if (qos->grp_jobs == NO_VAL)
qos->grp_jobs = INFINITE;
if (qos->grp_jobs_accrue == NO_VAL)
qos->grp_jobs_accrue = INFINITE;
if (qos->grp_submit_jobs == NO_VAL)
qos->grp_submit_jobs = INFINITE;
if (qos->grp_wall == NO_VAL)
qos->grp_wall = INFINITE;
if (qos->max_jobs_pa == NO_VAL)
qos->max_jobs_pa = INFINITE;
if (qos->max_jobs_pu == NO_VAL)
qos->max_jobs_pu = INFINITE;
if (qos->max_jobs_accrue_pa == NO_VAL)
qos->max_jobs_accrue_pa = INFINITE;
if (qos->max_jobs_accrue_pu == NO_VAL)
qos->max_jobs_accrue_pu = INFINITE;
if (qos->min_prio_thresh == NO_VAL)
qos->min_prio_thresh = INFINITE;
if (qos->max_submit_jobs_pa == NO_VAL)
qos->max_submit_jobs_pa = INFINITE;
if (qos->max_submit_jobs_pu == NO_VAL)
qos->max_submit_jobs_pu = INFINITE;
if (qos->max_wall_pj == NO_VAL)
qos->max_wall_pj = INFINITE;
if (qos->preempt_exempt_time == NO_VAL)
qos->preempt_exempt_time = INFINITE;
if (qos->preempt_mode == NO_VAL16)
qos->preempt_mode = 0;
if (qos->priority == NO_VAL)
qos->priority = 0;
if (fuzzy_equal(qos->usage_factor, NO_VAL))
qos->usage_factor = 1;
if (fuzzy_equal(qos->usage_thres, NO_VAL))
qos->usage_thres = (double)INFINITE;
if (fuzzy_equal(qos->limit_factor, NO_VAL))
qos->limit_factor = INFINITE;
}
if (qos->description) {
xstrcat(*cols, ", description");
xstrfmtcat(*vals, ", '%s'", qos->description);
xstrfmtcat(*extra, ", description='%s'",
qos->description);
}
if (!(qos->flags & QOS_FLAG_NOTSET)) {
if (qos->flags & QOS_FLAG_REMOVE) {
if (qos->flags)
xstrfmtcat(*extra, ", flags=(flags & ~%u)",
qos->flags & ~QOS_FLAG_REMOVE);
} else {
/* If we are only removing there is no reason
to set up the cols and vals. */
if (qos->flags & QOS_FLAG_ADD) {
if (qos->flags) {
xstrfmtcat(*extra,
", flags=(flags | %u)",
qos->flags & ~QOS_FLAG_ADD);
}
} else
xstrfmtcat(*extra, ", flags=%u", qos->flags);
xstrcat(*cols, ", flags");
xstrfmtcat(*vals, ", '%u'", qos->flags & ~QOS_FLAG_ADD);
}
}
if (qos->grace_time == INFINITE) {
xstrcat(*cols, ", grace_time");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", grace_time=NULL");
} else if ((qos->grace_time != NO_VAL) &&
((int32_t)qos->grace_time >= 0)) {
xstrcat(*cols, ", grace_time");
xstrfmtcat(*vals, ", %u", qos->grace_time);
xstrfmtcat(*extra, ", grace_time=%u", qos->grace_time);
}
if (qos->grp_jobs == INFINITE) {
xstrcat(*cols, ", grp_jobs");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", grp_jobs=NULL");
} else if ((qos->grp_jobs != NO_VAL)
&& ((int32_t)qos->grp_jobs >= 0)) {
xstrcat(*cols, ", grp_jobs");
xstrfmtcat(*vals, ", %u", qos->grp_jobs);
xstrfmtcat(*extra, ", grp_jobs=%u", qos->grp_jobs);
}
if (qos->grp_jobs_accrue == INFINITE) {
xstrcat(*cols, ", grp_jobs_accrue");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", grp_jobs_accrue=NULL");
} else if ((qos->grp_jobs_accrue != NO_VAL)
&& ((int32_t)qos->grp_jobs_accrue >= 0)) {
xstrcat(*cols, ", grp_jobs_accrue");
xstrfmtcat(*vals, ", %u", qos->grp_jobs_accrue);
xstrfmtcat(*extra, ", grp_jobs_accrue=%u",
qos->grp_jobs_accrue);
}
if (qos->grp_submit_jobs == INFINITE) {
xstrcat(*cols, ", grp_submit_jobs");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", grp_submit_jobs=NULL");
} else if ((qos->grp_submit_jobs != NO_VAL)
&& ((int32_t)qos->grp_submit_jobs >= 0)) {
xstrcat(*cols, ", grp_submit_jobs");
xstrfmtcat(*vals, ", %u", qos->grp_submit_jobs);
xstrfmtcat(*extra, ", grp_submit_jobs=%u",
qos->grp_submit_jobs);
}
if (qos->grp_wall == INFINITE) {
xstrcat(*cols, ", grp_wall");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", grp_wall=NULL");
} else if ((qos->grp_wall != NO_VAL)
&& ((int32_t)qos->grp_wall >= 0)) {
xstrcat(*cols, ", grp_wall");
xstrfmtcat(*vals, ", %u", qos->grp_wall);
xstrfmtcat(*extra, ", grp_wall=%u", qos->grp_wall);
}
if (qos->max_jobs_pa == INFINITE) {
xstrcat(*cols, ", max_jobs_pa");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_jobs_pa=NULL");
} else if ((qos->max_jobs_pa != NO_VAL)
&& ((int32_t)qos->max_jobs_pa >= 0)) {
xstrcat(*cols, ", max_jobs_pa");
xstrfmtcat(*vals, ", %u", qos->max_jobs_pa);
xstrfmtcat(*extra, ", max_jobs_pa=%u", qos->max_jobs_pa);
}
if (qos->max_jobs_pu == INFINITE) {
xstrcat(*cols, ", max_jobs_per_user");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_jobs_per_user=NULL");
} else if ((qos->max_jobs_pu != NO_VAL)
&& ((int32_t)qos->max_jobs_pu >= 0)) {
xstrcat(*cols, ", max_jobs_per_user");
xstrfmtcat(*vals, ", %u", qos->max_jobs_pu);
xstrfmtcat(*extra, ", max_jobs_per_user=%u", qos->max_jobs_pu);
}
if (qos->max_jobs_accrue_pa == INFINITE) {
xstrcat(*cols, ", max_jobs_accrue_pa");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_jobs_accrue_pa=NULL");
} else if ((qos->max_jobs_accrue_pa != NO_VAL)
&& ((int32_t)qos->max_jobs_accrue_pa >= 0)) {
xstrcat(*cols, ", max_jobs_accrue_pa");
xstrfmtcat(*vals, ", %u", qos->max_jobs_accrue_pa);
xstrfmtcat(*extra, ", max_jobs_accrue_pa=%u",
qos->max_jobs_accrue_pa);
}
if (qos->max_jobs_accrue_pu == INFINITE) {
xstrcat(*cols, ", max_jobs_accrue_pu");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_jobs_accrue_pu=NULL");
} else if ((qos->max_jobs_accrue_pu != NO_VAL)
&& ((int32_t)qos->max_jobs_accrue_pu >= 0)) {
xstrcat(*cols, ", max_jobs_accrue_pu");
xstrfmtcat(*vals, ", %u", qos->max_jobs_accrue_pu);
xstrfmtcat(*extra, ", max_jobs_accrue_pu=%u",
qos->max_jobs_accrue_pu);
}
if (qos->min_prio_thresh == INFINITE) {
xstrcat(*cols, ", min_prio_thresh");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", min_prio_thresh=NULL");
} else if ((qos->min_prio_thresh != NO_VAL)
&& ((int32_t)qos->min_prio_thresh >= 0)) {
xstrcat(*cols, ", min_prio_thresh");
xstrfmtcat(*vals, ", %u", qos->min_prio_thresh);
xstrfmtcat(*extra, ", min_prio_thresh=%u",
qos->min_prio_thresh);
}
if (qos->max_submit_jobs_pa == INFINITE) {
xstrcat(*cols, ", max_submit_jobs_pa");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_submit_jobs_pa=NULL");
} else if ((qos->max_submit_jobs_pa != NO_VAL)
&& ((int32_t)qos->max_submit_jobs_pa >= 0)) {
xstrcat(*cols, ", max_submit_jobs_pa");
xstrfmtcat(*vals, ", %u", qos->max_submit_jobs_pa);
xstrfmtcat(*extra, ", max_submit_jobs_pa=%u",
qos->max_submit_jobs_pa);
}
if (qos->max_submit_jobs_pu == INFINITE) {
xstrcat(*cols, ", max_submit_jobs_per_user");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_submit_jobs_per_user=NULL");
} else if ((qos->max_submit_jobs_pu != NO_VAL)
&& ((int32_t)qos->max_submit_jobs_pu >= 0)) {
xstrcat(*cols, ", max_submit_jobs_per_user");
xstrfmtcat(*vals, ", %u", qos->max_submit_jobs_pu);
xstrfmtcat(*extra, ", max_submit_jobs_per_user=%u",
qos->max_submit_jobs_pu);
}
if ((qos->max_wall_pj != NO_VAL)
&& ((int32_t)qos->max_wall_pj >= 0)) {
xstrcat(*cols, ", max_wall_duration_per_job");
xstrfmtcat(*vals, ", %u", qos->max_wall_pj);
xstrfmtcat(*extra, ", max_wall_duration_per_job=%u",
qos->max_wall_pj);
} else if (qos->max_wall_pj == INFINITE) {
xstrcat(*cols, ", max_wall_duration_per_job");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", max_wall_duration_per_job=NULL");
}
if (qos->preempt_list && list_count(qos->preempt_list)) {
char *preempt_val = NULL;
char *tmp_char = NULL, *last_preempt = NULL;
bool adding_straight = 0;
list_itr_t *preempt_itr =
list_iterator_create(qos->preempt_list);
xstrcat(*cols, ", preempt");
while ((tmp_char = list_next(preempt_itr))) {
if (tmp_char[0] == '-') {
preempt_val = xstrdup_printf(
"replace(%s, ',%s,', ',')",
last_preempt ? last_preempt : "preempt",
tmp_char+1);
xfree(last_preempt);
last_preempt = preempt_val;
preempt_val = NULL;
} else if (tmp_char[0] == '+') {
preempt_val = xstrdup_printf(
"replace(concat(replace(%s, "
"',%s,', ''), ',%s,'), ',,', ',')",
last_preempt ? last_preempt : "preempt",
tmp_char+1, tmp_char+1);
if (added_preempt)
xstrfmtcat(*added_preempt, ",%s",
tmp_char+1);
xfree(last_preempt);
last_preempt = preempt_val;
preempt_val = NULL;
} else if (tmp_char[0]) {
xstrfmtcat(preempt_val, ",%s", tmp_char);
if (added_preempt)
xstrfmtcat(*added_preempt, ",%s",
tmp_char);
adding_straight = 1;
} else
xstrcat(preempt_val, "");
}
list_iterator_destroy(preempt_itr);
if (last_preempt) {
preempt_val = last_preempt;
last_preempt = NULL;
}
if (adding_straight) {
xstrfmtcat(*vals, ", \'%s,\'", preempt_val);
xstrfmtcat(*extra, ", preempt=\'%s,\'", preempt_val);
} else if (preempt_val && preempt_val[0]) {
xstrfmtcat(*vals, ", %s", preempt_val);
xstrfmtcat(*extra, ", preempt=if(%s=',', '', %s)",
preempt_val, preempt_val);
} else {
xstrcat(*vals, ", ''");
xstrcat(*extra, ", preempt=''");
}
xfree(preempt_val);
}
if (qos->preempt_exempt_time == INFINITE) {
xstrcat(*cols, ", preempt_exempt_time");
xstrfmtcat(*vals, ", NULL");
xstrfmtcat(*extra, ", preempt_exempt_time=NULL");
} else if (qos->preempt_exempt_time != NO_VAL) {
xstrcat(*cols, ", preempt_exempt_time");
xstrfmtcat(*vals, ", %u", qos->preempt_exempt_time);
xstrfmtcat(*extra, ", preempt_exempt_time=%u",
qos->preempt_exempt_time);
}
if (qos->preempt_mode != NO_VAL16) {
xstrcat(*cols, ", preempt_mode");
xstrfmtcat(*vals, ", %u", qos->preempt_mode);
xstrfmtcat(*extra, ", preempt_mode=%u", qos->preempt_mode);
}
if (qos->priority == INFINITE) {
xstrcat(*cols, ", priority");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", priority=NULL");
} else if ((qos->priority != NO_VAL)
&& ((int32_t)qos->priority >= 0)) {
xstrcat(*cols, ", priority");
xstrfmtcat(*vals, ", %u", qos->priority);
xstrfmtcat(*extra, ", priority=%u", qos->priority);
}
if (fuzzy_equal(qos->usage_factor, INFINITE)) {
xstrcat(*cols, ", usage_factor");
xstrcat(*vals, ", 1");
xstrcat(*extra, ", usage_factor=1");
} else if (!fuzzy_equal(qos->usage_factor, NO_VAL)
&& (qos->usage_factor >= 0)) {
xstrcat(*cols, ", usage_factor");
xstrfmtcat(*vals, ", %f", qos->usage_factor);
xstrfmtcat(*extra, ", usage_factor=%f", qos->usage_factor);
}
if (fuzzy_equal(qos->usage_thres, INFINITE)) {
xstrcat(*cols, ", usage_thres");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", usage_thres=NULL");
} else if (!fuzzy_equal(qos->usage_thres, NO_VAL)
&& (qos->usage_thres >= 0)) {
xstrcat(*cols, ", usage_thres");
xstrfmtcat(*vals, ", %f", qos->usage_thres);
xstrfmtcat(*extra, ", usage_thres=%f", qos->usage_thres);
}
if (fuzzy_equal(qos->limit_factor, INFINITE)) {
xstrcat(*cols, ", limit_factor");
xstrcat(*vals, ", NULL");
xstrcat(*extra, ", limit_factor=NULL");
} else if (!fuzzy_equal(qos->limit_factor, NO_VAL)
&& (qos->limit_factor > 0)) {
xstrcat(*cols, ", limit_factor");
xstrfmtcat(*vals, ", %f", qos->limit_factor);
xstrfmtcat(*extra, ", limit_factor=%f", qos->limit_factor);
}
/* When modifying anything below this comment it happens in
* the actual function since we have to wait until we hear
* about the original first.
* What we do to make it known something needs to be changed
* is we cat "" onto extra which will inform the caller
* something needs changing.
*/
if (qos->grp_tres) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", grp_tres");
slurmdb_combine_tres_strings(
&qos->grp_tres, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->grp_tres);
xstrfmtcat(*extra, ", grp_tres='%s'", qos->grp_tres);
}
if (qos->grp_tres_mins) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", grp_tres_mins");
slurmdb_combine_tres_strings(
&qos->grp_tres_mins, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->grp_tres_mins);
xstrfmtcat(*extra, ", grp_tres_mins='%s'",
qos->grp_tres_mins);
}
if (qos->grp_tres_run_mins) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", grp_tres_run_mins");
slurmdb_combine_tres_strings(
&qos->grp_tres_run_mins, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->grp_tres_run_mins);
xstrfmtcat(*extra, ", grp_tres_run_mins='%s'",
qos->grp_tres_run_mins);
}
if (qos->max_tres_pa) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_pa");
slurmdb_combine_tres_strings(
&qos->max_tres_pa, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_pa);
xstrfmtcat(*extra, ", max_tres_pa='%s'", qos->max_tres_pa);
}
if (qos->max_tres_pj) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_pj");
slurmdb_combine_tres_strings(
&qos->max_tres_pj, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_pj);
xstrfmtcat(*extra, ", max_tres_pj='%s'", qos->max_tres_pj);
}
if (qos->max_tres_pn) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_pn");
slurmdb_combine_tres_strings(
&qos->max_tres_pn, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_pn);
xstrfmtcat(*extra, ", max_tres_pn='%s'", qos->max_tres_pn);
}
if (qos->max_tres_pu) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_pu");
slurmdb_combine_tres_strings(
&qos->max_tres_pu, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_pu);
xstrfmtcat(*extra, ", max_tres_pu='%s'", qos->max_tres_pu);
}
if (qos->max_tres_mins_pj) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_mins_pj");
slurmdb_combine_tres_strings(
&qos->max_tres_mins_pj, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_mins_pj);
xstrfmtcat(*extra, ", max_tres_mins_pj='%s'",
qos->max_tres_mins_pj);
}
if (qos->max_tres_run_mins_pa) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_run_mins_pa");
slurmdb_combine_tres_strings(
&qos->max_tres_run_mins_pa, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_run_mins_pa);
xstrfmtcat(*extra, ", max_tres_run_mins_pa='%s'",
qos->max_tres_run_mins_pa);
}
if (qos->max_tres_run_mins_pu) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", max_tres_run_mins_pu");
slurmdb_combine_tres_strings(
&qos->max_tres_run_mins_pu, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->max_tres_run_mins_pu);
xstrfmtcat(*extra, ", max_tres_run_mins_pu='%s'",
qos->max_tres_run_mins_pu);
}
if (qos->min_tres_pj) {
if (!for_add) {
xstrcat(*extra, "");
goto end_modify;
}
xstrcat(*cols, ", min_tres_pj");
slurmdb_combine_tres_strings(
&qos->min_tres_pj, NULL, tres_str_flags);
xstrfmtcat(*vals, ", '%s'", qos->min_tres_pj);
xstrfmtcat(*extra, ", min_tres_pj='%s'", qos->min_tres_pj);
}
end_modify:
return SLURM_SUCCESS;
}
extern int as_mysql_add_qos(mysql_conn_t *mysql_conn, uint32_t uid,
list_t *qos_list)
{
list_itr_t *itr = NULL;
int rc = SLURM_SUCCESS;
slurmdb_qos_rec_t *object = NULL;
char *cols = NULL, *extra = NULL, *vals = NULL, *query = NULL,
*tmp_extra = NULL;
time_t now = time(NULL);
char *user_name = NULL;
int affect_rows = 0;
int added = 0;
char *added_preempt = NULL;
uint32_t qos_cnt;
assoc_mgr_lock_t locks = {
.qos = READ_LOCK,
};
if (check_connection(mysql_conn) != SLURM_SUCCESS)
return ESLURM_DB_CONNECTION;
if (!is_user_min_admin_level(mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER))
return ESLURM_ACCESS_DENIED;
if (!qos_list || !list_count(qos_list)) {
error("%s: Trying to add empty qos list", __func__);
return ESLURM_EMPTY_LIST;
}
assoc_mgr_lock(&locks);
qos_cnt = g_qos_count;
assoc_mgr_unlock(&locks);
user_name = uid_to_string((uid_t) uid);
itr = list_iterator_create(qos_list);
while ((object = list_next(itr))) {
if (!object->name || !object->name[0]) {
error("We need a qos name to add.");
rc = SLURM_ERROR;
continue;
}
xstrcat(cols, "creation_time, mod_time, name");
xstrfmtcat(vals, "%ld, %ld, '%s'",
now, now, object->name);
xstrfmtcat(extra, ", mod_time=%ld", now);
_setup_qos_limits(object, &cols, &vals,
&extra, &added_preempt, 1);
if (added_preempt) {
object->preempt_bitstr = bit_alloc(qos_cnt);
bit_unfmt(object->preempt_bitstr, added_preempt+1);
xfree(added_preempt);
}
xstrfmtcat(query,
"insert into %s (%s) values (%s) "
"on duplicate key update deleted=0, "
"id=LAST_INSERT_ID(id)%s;",
qos_table, cols, vals, extra);
DB_DEBUG(DB_QOS, mysql_conn->conn, "query\n%s", query);
object->id = (uint32_t)mysql_db_insert_ret_id(
mysql_conn, query);
xfree(query);
if (!object->id) {
error("Couldn't add qos %s", object->name);
added=0;
xfree(cols);
xfree(extra);
xfree(vals);
break;
}
affect_rows = last_affected_rows(mysql_conn);
if (!affect_rows) {
debug2("nothing changed %d", affect_rows);
xfree(cols);
xfree(extra);
xfree(vals);
continue;
}
/* we always have a ', ' as the first 2 chars */
tmp_extra = slurm_add_slash_to_quotes(extra+2);
xstrfmtcat(query,
"insert into %s "
"(timestamp, action, name, actor, info) "
"values (%ld, %u, '%s', '%s', '%s');",
txn_table,
now, DBD_ADD_QOS, object->name, user_name,
tmp_extra);
xfree(tmp_extra);
xfree(cols);
xfree(extra);
xfree(vals);
debug4("query\n%s",query);
rc = mysql_db_query(mysql_conn, query);
xfree(query);
if (rc != SLURM_SUCCESS) {
error("Couldn't add txn");
} else {
if (addto_update_list(mysql_conn->update_list,
SLURMDB_ADD_QOS,
object) == SLURM_SUCCESS)
list_remove(itr);
added++;
}
}
list_iterator_destroy(itr);
xfree(user_name);
if (!added) {
reset_mysql_conn(mysql_conn);
}
return rc;
}
extern list_t *as_mysql_modify_qos(mysql_conn_t *mysql_conn, uint32_t uid,
slurmdb_qos_cond_t *qos_cond,
slurmdb_qos_rec_t *qos)
{
list_t *ret_list = NULL;
int rc = SLURM_SUCCESS;
char *object = NULL;
char *vals = NULL, *extra = NULL, *query = NULL, *name_char = NULL;
time_t now = time(NULL);
char *user_name = NULL;
int i;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
char *tmp_char1=NULL, *tmp_char2=NULL;
bitstr_t *preempt_bitstr = NULL;
char *added_preempt = NULL;
uint32_t qos_cnt;
assoc_mgr_lock_t locks = {
.qos = READ_LOCK,
};
if (!qos_cond || !qos) {
error("we need something to change");
return NULL;
}
if (check_connection(mysql_conn) != SLURM_SUCCESS)
return NULL;
if (!is_user_min_admin_level(mysql_conn, uid,
SLURMDB_ADMIN_SUPER_USER)) {
errno = ESLURM_ACCESS_DENIED;
return NULL;
}
xstrcat(extra, "where deleted=0");
_setup_qos_cond_limits(qos_cond, &extra);
_setup_qos_limits(qos, &tmp_char1, &tmp_char2,
&vals, &added_preempt, 0);
assoc_mgr_lock(&locks);
qos_cnt = g_qos_count;
assoc_mgr_unlock(&locks);
if (added_preempt) {
preempt_bitstr = bit_alloc(qos_cnt);
bit_unfmt(preempt_bitstr, added_preempt+1);
xfree(added_preempt);
}
xfree(tmp_char1);
xfree(tmp_char2);
if (!extra || !vals) {
errno = SLURM_NO_CHANGE_IN_DATA;
FREE_NULL_BITMAP(preempt_bitstr);
error("Nothing to change");
return NULL;
}
object = xstrdup(mqos_req_inx[0]);
for (i = 1; i < MQOS_COUNT; i++)
xstrfmtcat(object, ", %s", mqos_req_inx[i]);
query = xstrdup_printf("select %s from %s %s;",
object, qos_table, extra);
xfree(extra);
xfree(object);
if (!(result = mysql_db_query_ret(mysql_conn, query, 0))) {
xfree(query);
FREE_NULL_BITMAP(preempt_bitstr);
return NULL;
}
rc = 0;
ret_list = list_create(xfree_ptr);
while ((row = mysql_fetch_row(result))) {
slurmdb_qos_rec_t *qos_rec = NULL;
uint32_t id = slurm_atoul(row[MQOS_ID]);
if (preempt_bitstr) {
if (_preemption_loop(mysql_conn, id, preempt_bitstr))
break;
}
object = xstrdup(row[MQOS_NAME]);
list_append(ret_list, object);
if (!rc) {
xstrfmtcat(name_char, "(name='%s'", object);
rc = 1;
} else {
xstrfmtcat(name_char, " || name='%s'", object);
}
qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t));
qos_rec->name = xstrdup(object);
qos_rec->id = id;
qos_rec->flags = qos->flags;
qos_rec->grace_time = qos->grace_time;
mod_tres_str(&qos_rec->grp_tres,
qos->grp_tres, row[MQOS_GT],
NULL, "grp_tres", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->grp_tres_mins,
qos->grp_tres_mins, row[MQOS_GTM],
NULL, "grp_tres_mins", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->grp_tres_run_mins,
qos->grp_tres_run_mins, row[MQOS_GTRM],
NULL, "grp_tres_run_mins", &vals,
qos_rec->id, 0);
qos_rec->grp_jobs = qos->grp_jobs;
qos_rec->grp_jobs_accrue = qos->grp_jobs_accrue;
qos_rec->grp_submit_jobs = qos->grp_submit_jobs;
qos_rec->grp_wall = qos->grp_wall;
mod_tres_str(&qos_rec->max_tres_pa,
qos->max_tres_pa, row[MQOS_MTPA],
NULL, "max_tres_pa", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_pj,
qos->max_tres_pj, row[MQOS_MTPJ],
NULL, "max_tres_pj", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_pn,
qos->max_tres_pn, row[MQOS_MTPN],
NULL, "max_tres_pn", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_pu,
qos->max_tres_pu, row[MQOS_MTPU],
NULL, "max_tres_pu", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_mins_pj,
qos->max_tres_mins_pj, row[MQOS_MTMPJ],
NULL, "max_tres_mins_pj", &vals, qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_run_mins_pa,
qos->max_tres_run_mins_pa, row[MQOS_MTRMA],
NULL, "max_tres_run_mins_pa", &vals,
qos_rec->id, 0);
mod_tres_str(&qos_rec->max_tres_run_mins_pu,
qos->max_tres_run_mins_pu, row[MQOS_MTRM],
NULL, "max_tres_run_mins_pu", &vals,
qos_rec->id, 0);
qos_rec->max_jobs_pa = qos->max_jobs_pa;
qos_rec->max_jobs_pu = qos->max_jobs_pu;
qos_rec->max_jobs_accrue_pa = qos->max_jobs_accrue_pa;
qos_rec->max_jobs_accrue_pu = qos->max_jobs_accrue_pu;
qos_rec->min_prio_thresh = qos->min_prio_thresh;
qos_rec->max_submit_jobs_pa = qos->max_submit_jobs_pa;
qos_rec->max_submit_jobs_pu = qos->max_submit_jobs_pu;
qos_rec->max_wall_pj = qos->max_wall_pj;
mod_tres_str(&qos_rec->min_tres_pj,
qos->min_tres_pj, row[MQOS_MITPJ],
NULL, "min_tres_pj", &vals, qos_rec->id, 0);
qos_rec->preempt_mode = qos->preempt_mode;
qos_rec->priority = qos->priority;
if (qos->preempt_list) {
list_itr_t *new_preempt_itr =
list_iterator_create(qos->preempt_list);
char *new_preempt = NULL;
bool cleared = 0;
qos_rec->preempt_bitstr = bit_alloc(qos_cnt);
if (row[MQOS_PREEMPT] && row[MQOS_PREEMPT][0])
bit_unfmt(qos_rec->preempt_bitstr,
row[MQOS_PREEMPT]+1);
while ((new_preempt = list_next(new_preempt_itr))) {
if (new_preempt[0] == '-') {
bit_clear(qos_rec->preempt_bitstr,
atol(new_preempt+1));
} else if (new_preempt[0] == '+') {
bit_set(qos_rec->preempt_bitstr,
atol(new_preempt+1));
} else if (new_preempt[0] == '\0') {
bit_clear_all(qos_rec->preempt_bitstr);
} else {
if (!cleared) {
cleared = 1;
bit_clear_all(
qos_rec->preempt_bitstr);
}
bit_set(qos_rec->preempt_bitstr,
atol(new_preempt));
}
}
list_iterator_destroy(new_preempt_itr);
}
qos_rec->preempt_exempt_time = qos->preempt_exempt_time;
qos_rec->usage_factor = qos->usage_factor;
qos_rec->usage_thres = qos->usage_thres;
qos_rec->limit_factor = qos->limit_factor;
if (addto_update_list(mysql_conn->update_list,
SLURMDB_MODIFY_QOS, qos_rec)
!= SLURM_SUCCESS)
slurmdb_destroy_qos_rec(qos_rec);
}
mysql_free_result(result);
FREE_NULL_BITMAP(preempt_bitstr);
if (row) {
xfree(vals);
xfree(name_char);
xfree(query);
FREE_NULL_LIST(ret_list);
ret_list = NULL;
errno = ESLURM_QOS_PREEMPTION_LOOP;
return ret_list;
}
if (!list_count(ret_list)) {
errno = SLURM_NO_CHANGE_IN_DATA;
DB_DEBUG(DB_QOS, mysql_conn->conn,
"didn't affect anything\n%s", query);
xfree(vals);
xfree(query);
return ret_list;
}
xfree(query);
xstrcat(name_char, ")");
user_name = uid_to_string((uid_t) uid);
rc = modify_common(mysql_conn, DBD_MODIFY_QOS, now,
user_name, qos_table, name_char, vals, NULL);
xfree(user_name);
xfree(name_char);
xfree(vals);
if (rc == SLURM_ERROR) {
error("Couldn't modify qos");
FREE_NULL_LIST(ret_list);
ret_list = NULL;
}
return ret_list;
}
extern list_t *as_mysql_remove_qos(mysql_conn_t *mysql_conn, uint32_t uid,
slurmdb_qos_cond_t *qos_cond)
{
list_itr_t *itr = NULL;
list_t *ret_list = NULL;
int rc = SLURM_SUCCESS;
char *object = NULL;
char *extra = NULL, *query = NULL,
*name_char = NULL, *assoc_char = NULL;
char *removed_ids = NULL, *rmid_pos = NULL;
time_t now = time(NULL);
MYSQL_RES *result = NULL;
MYSQL_ROW row;
list_t *cluster_list_tmp = NULL;
remove_common_args_t args = {
.jobs_running = false,
.mysql_conn = mysql_conn,
.now = now,
.table = qos_table,
.type = DBD_REMOVE_QOS,
};
if (!qos_cond) {
error("we need something to change");
return NULL;
}
if (check_connection(mysql_conn) != SLURM_SUCCESS)
return NULL;
if (!is_user_min_admin_level(
mysql_conn, uid, SLURMDB_ADMIN_SUPER_USER)) {
errno = ESLURM_ACCESS_DENIED;
return NULL;
}
xstrcat(extra, "where deleted=0");
_setup_qos_cond_limits(qos_cond, &extra);
if (!extra) {
error("Nothing to remove");
return NULL;
}
query = xstrdup_printf("select id, name from %s %s;", qos_table, extra);
xfree(extra);
if (!(result = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
return NULL;
}
name_char = NULL;
ret_list = list_create(xfree_ptr);
while ((row = mysql_fetch_row(result))) {
slurmdb_qos_rec_t *qos_rec = NULL;
list_append(ret_list, xstrdup(row[1]));
if (!name_char)
xstrfmtcat(name_char, "id='%s'", row[0]);
else
xstrfmtcat(name_char, " || id='%s'", row[0]);
if (!assoc_char)
xstrfmtcat(assoc_char, "id_qos='%s'", row[0]);
else
xstrfmtcat(assoc_char, " || id_qos='%s'", row[0]);
xstrfmtcat(extra,
", qos=replace(qos, ',%s,', if(qos=',%s,', '', ','))"
", delta_qos=replace(delta_qos, ',+%s,', if(delta_qos=',+%s,', '', ','))"
", delta_qos=replace(delta_qos, ',-%s,', if(delta_qos=',-%s,', '', ','))",
row[0], row[0], row[0], row[0], row[0], row[0]);
/* Track removed QOS ids for removal from preempt lists */
if (!removed_ids) {
xstrfmtcatat(removed_ids, &rmid_pos,
"update %s set preempt=regexp_replace("
"preempt, '",
qos_table);
}
xstrfmtcatat(removed_ids, &rmid_pos, ",%s\\\\b|", row[0]);
qos_rec = xmalloc(sizeof(slurmdb_qos_rec_t));
/* we only need id when removing no real need to init */
qos_rec->id = slurm_atoul(row[0]);
if (addto_update_list(mysql_conn->update_list,
SLURMDB_REMOVE_QOS, qos_rec)
!= SLURM_SUCCESS)
slurmdb_destroy_qos_rec(qos_rec);
}
mysql_free_result(result);
if (!list_count(ret_list)) {
errno = SLURM_NO_CHANGE_IN_DATA;
DB_DEBUG(DB_QOS, mysql_conn->conn,
"didn't affect anything\n%s", query);
xfree(query);
return ret_list;
}
xfree(query);
if (removed_ids) {
/* write over trailing | from removed_ids */
xassert(rmid_pos);
rmid_pos--;
xstrcatat(removed_ids, &rmid_pos, "', '');");
DB_DEBUG(DB_QOS, mysql_conn->conn, "query\n%s", removed_ids);
rc = mysql_db_query(mysql_conn, removed_ids);
xfree(removed_ids);
if (rc != SLURM_SUCCESS)
goto end_it;
}
args.user_name = uid_to_string((uid_t) uid);
slurm_rwlock_rdlock(&as_mysql_cluster_list_lock);
cluster_list_tmp = list_shallow_copy(as_mysql_cluster_list);
if (list_count(cluster_list_tmp)) {
itr = list_iterator_create(cluster_list_tmp);
while ((object = list_next(itr))) {
/*
* remove this qos from all the associations
* that have it
*/
query = xstrdup_printf("update \"%s_%s\" set mod_time=%ld %s where deleted=0;",
object, assoc_table,
now, extra);
DB_DEBUG(DB_QOS, mysql_conn->conn, "query\n%s", query);
rc = mysql_db_query(mysql_conn, query);
xfree(query);
if (rc != SLURM_SUCCESS) {
reset_mysql_conn(mysql_conn);
break;
}
}
list_iterator_destroy(itr);
}
args.assoc_char = assoc_char;
args.name_char = name_char;
args.ret_list = ret_list;
args.use_cluster_list = cluster_list_tmp;
rc = remove_common(&args);
FREE_NULL_LIST(cluster_list_tmp);
slurm_rwlock_unlock(&as_mysql_cluster_list_lock);
end_it:
xfree(extra);
xfree(assoc_char);
xfree(name_char);
xfree(args.user_name);
if (rc != SLURM_SUCCESS) {
FREE_NULL_LIST(ret_list);
return NULL;
}
if (args.jobs_running)
errno = ESLURM_JOBS_RUNNING_ON_ASSOC;
else
errno = SLURM_SUCCESS;
return ret_list;
}
extern list_t *as_mysql_get_qos(mysql_conn_t *mysql_conn, uid_t uid,
slurmdb_qos_cond_t *qos_cond)
{
char *query = NULL;
char *extra = NULL;
char *tmp = NULL;
list_t *qos_list = NULL;
int i=0;
MYSQL_RES *result = NULL;
MYSQL_ROW row;
uint32_t qos_cnt;
assoc_mgr_lock_t locks = {
.qos = READ_LOCK,
};
/* if this changes you will need to edit the corresponding enum */
char *qos_req_inx[] = {
"name",
"deleted",
"description",
"id",
"flags",
"grace_time",
"grp_tres_mins",
"grp_tres_run_mins",
"grp_tres",
"grp_jobs",
"grp_jobs_accrue",
"grp_submit_jobs",
"grp_wall",
"max_tres_mins_pj",
"max_tres_run_mins_pa",
"max_tres_run_mins_pu",
"max_tres_pa",
"max_tres_pj",
"max_tres_pn",
"max_tres_pu",
"max_jobs_pa",
"max_jobs_per_user",
"max_jobs_accrue_pa",
"max_jobs_accrue_pu",
"min_prio_thresh",
"max_submit_jobs_pa",
"max_submit_jobs_per_user",
"max_wall_duration_per_job",
"substr(preempt, 1, length(preempt) - 1)",
"preempt_mode",
"preempt_exempt_time",
"priority",
"usage_factor",
"usage_thres",
"min_tres_pj",
"limit_factor",
};
enum {
QOS_REQ_NAME,
QOS_REQ_DELETED,
QOS_REQ_DESC,
QOS_REQ_ID,
QOS_REQ_FLAGS,
QOS_REQ_GRACE,
QOS_REQ_GTM,
QOS_REQ_GTRM,
QOS_REQ_GT,
QOS_REQ_GJ,
QOS_REQ_GJA,
QOS_REQ_GSJ,
QOS_REQ_GW,
QOS_REQ_MTMPJ,
QOS_REQ_MTRMA,
QOS_REQ_MTRM,
QOS_REQ_MTPA,
QOS_REQ_MTPJ,
QOS_REQ_MTPN,
QOS_REQ_MTPU,
QOS_REQ_MJPA,
QOS_REQ_MJPU,
QOS_REQ_MJAPA,
QOS_REQ_MJAPU,
QOS_REQ_MPT,
QOS_REQ_MSJPA,
QOS_REQ_MSJPU,
QOS_REQ_MWPJ,
QOS_REQ_PREE,
QOS_REQ_PREEM,
QOS_REQ_PREXMPT,
QOS_REQ_PRIO,
QOS_REQ_UF,
QOS_REQ_UT,
QOS_REQ_MITPJ,
QOS_REQ_LF,
QOS_REQ_COUNT
};
if (check_connection(mysql_conn) != SLURM_SUCCESS)
return NULL;
if (!qos_cond) {
xstrcat(extra, "where deleted=0");
goto empty;
}
if (qos_cond->flags & QOS_COND_FLAG_WITH_DELETED)
xstrcat(extra, "where (deleted=0 || deleted=1)");
else
xstrcat(extra, "where deleted=0");
_setup_qos_cond_limits(qos_cond, &extra);
empty:
xfree(tmp);
xstrfmtcat(tmp, "%s", qos_req_inx[i]);
for(i=1; i<QOS_REQ_COUNT; i++) {
xstrfmtcat(tmp, ", %s", qos_req_inx[i]);
}
query = xstrdup_printf("select %s from %s %s", tmp, qos_table, extra);
xfree(tmp);
xfree(extra);
DB_DEBUG(DB_QOS, mysql_conn->conn, "query\n%s", query);
if (!(result = mysql_db_query_ret(
mysql_conn, query, 0))) {
xfree(query);
return NULL;
}
xfree(query);
qos_list = list_create(slurmdb_destroy_qos_rec);
assoc_mgr_lock(&locks);
qos_cnt = g_qos_count;
assoc_mgr_unlock(&locks);
while ((row = mysql_fetch_row(result))) {
slurmdb_qos_rec_t *qos = xmalloc(sizeof(slurmdb_qos_rec_t));
list_append(qos_list, qos);
if (row[QOS_REQ_DESC] && row[QOS_REQ_DESC][0])
qos->description = xstrdup(row[QOS_REQ_DESC]);
qos->id = slurm_atoul(row[QOS_REQ_ID]);
qos->flags = slurm_atoul(row[QOS_REQ_FLAGS]);
if (row[QOS_REQ_DELETED] && (row[QOS_REQ_DELETED][0] == '1'))
qos->flags |= QOS_FLAG_DELETED;
if (row[QOS_REQ_NAME] && row[QOS_REQ_NAME][0])
qos->name = xstrdup(row[QOS_REQ_NAME]);
if (row[QOS_REQ_GRACE])
qos->grace_time = slurm_atoul(row[QOS_REQ_GRACE]);
if (row[QOS_REQ_GT][0])
qos->grp_tres = xstrdup(row[QOS_REQ_GT]);
if (row[QOS_REQ_GTM][0])
qos->grp_tres_mins = xstrdup(row[QOS_REQ_GTM]);
if (row[QOS_REQ_GTRM][0])
qos->grp_tres_run_mins = xstrdup(row[QOS_REQ_GTRM]);
if (row[QOS_REQ_GJ])
qos->grp_jobs = slurm_atoul(row[QOS_REQ_GJ]);
else
qos->grp_jobs = INFINITE;
if (row[QOS_REQ_GJA])
qos->grp_jobs_accrue = slurm_atoul(row[QOS_REQ_GJA]);
else
qos->grp_jobs_accrue = INFINITE;
if (row[QOS_REQ_GSJ])
qos->grp_submit_jobs = slurm_atoul(row[QOS_REQ_GSJ]);
else
qos->grp_submit_jobs = INFINITE;
if (row[QOS_REQ_GW])
qos->grp_wall = slurm_atoul(row[QOS_REQ_GW]);
else
qos->grp_wall = INFINITE;
if (row[QOS_REQ_MJPA])
qos->max_jobs_pa = slurm_atoul(row[QOS_REQ_MJPA]);
else
qos->max_jobs_pa = INFINITE;
if (row[QOS_REQ_MJPU])
qos->max_jobs_pu = slurm_atoul(row[QOS_REQ_MJPU]);
else
qos->max_jobs_pu = INFINITE;
if (row[QOS_REQ_MJAPA])
qos->max_jobs_accrue_pa =
slurm_atoul(row[QOS_REQ_MJAPA]);
else
qos->max_jobs_accrue_pa = INFINITE;
if (row[QOS_REQ_MJAPU])
qos->max_jobs_accrue_pu =
slurm_atoul(row[QOS_REQ_MJAPU]);
else
qos->max_jobs_accrue_pu = INFINITE;
if (row[QOS_REQ_MPT])
qos->min_prio_thresh = slurm_atoul(row[QOS_REQ_MPT]);
else
qos->min_prio_thresh = INFINITE;
if (row[QOS_REQ_MSJPA])
qos->max_submit_jobs_pa =
slurm_atoul(row[QOS_REQ_MSJPA]);
else
qos->max_submit_jobs_pa = INFINITE;
if (row[QOS_REQ_MSJPU])
qos->max_submit_jobs_pu =
slurm_atoul(row[QOS_REQ_MSJPU]);
else
qos->max_submit_jobs_pu = INFINITE;
if (row[QOS_REQ_MTPA][0])
qos->max_tres_pa = xstrdup(row[QOS_REQ_MTPA]);
if (row[QOS_REQ_MTPJ][0])
qos->max_tres_pj = xstrdup(row[QOS_REQ_MTPJ]);
if (row[QOS_REQ_MTPN][0])
qos->max_tres_pn = xstrdup(row[QOS_REQ_MTPN]);
if (row[QOS_REQ_MTPU][0])
qos->max_tres_pu = xstrdup(row[QOS_REQ_MTPU]);
if (row[QOS_REQ_MTMPJ][0])
qos->max_tres_mins_pj = xstrdup(row[QOS_REQ_MTMPJ]);
if (row[QOS_REQ_MTRMA][0])
qos->max_tres_run_mins_pa = xstrdup(row[QOS_REQ_MTRMA]);
if (row[QOS_REQ_MTRM][0])
qos->max_tres_run_mins_pu = xstrdup(row[QOS_REQ_MTRM]);
if (row[QOS_REQ_MWPJ])
qos->max_wall_pj = slurm_atoul(row[QOS_REQ_MWPJ]);
else
qos->max_wall_pj = INFINITE;
if (row[QOS_REQ_PREE] && row[QOS_REQ_PREE][0]) {
if (!qos->preempt_bitstr)
qos->preempt_bitstr = bit_alloc(qos_cnt);
bit_unfmt(qos->preempt_bitstr, row[QOS_REQ_PREE]+1);
}
if (row[QOS_REQ_PREEM])
qos->preempt_mode = slurm_atoul(row[QOS_REQ_PREEM]);
if (row[QOS_REQ_PREXMPT])
qos->preempt_exempt_time =
slurm_atoul(row[QOS_REQ_PREXMPT]);
else
qos->preempt_exempt_time = INFINITE;
if (row[QOS_REQ_PRIO])
qos->priority = slurm_atoul(row[QOS_REQ_PRIO]);
if (row[QOS_REQ_UF])
qos->usage_factor = atof(row[QOS_REQ_UF]);
if (row[QOS_REQ_UT])
qos->usage_thres = atof(row[QOS_REQ_UT]);
else
qos->usage_thres = (double)INFINITE;
if (row[QOS_REQ_MITPJ][0])
qos->min_tres_pj = xstrdup(row[QOS_REQ_MITPJ]);
if (row[QOS_REQ_LF])
qos->limit_factor = atof(row[QOS_REQ_LF]);
else
qos->limit_factor = (double)INFINITE;
}
mysql_free_result(result);
return qos_list;
}