blob: 152fca7fd9fe7c3aae182753ddaa5ecf583f05f7 [file] [log] [blame]
/*****************************************************************************\
* print.c - sprio print job functions
*****************************************************************************
* Copyright (C) SchedMD LLC.
* Copyright (C) 2009 Lawrence Livermore National Security.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Don Lipari <lipari1@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 <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include "src/common/list.h"
#include "src/common/macros.h"
#include "src/slurmctld/slurmctld.h"
#include "src/common/uid.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"
#include "src/sprio/print.h"
#include "src/sprio/sprio.h"
static int _print_str(char *str, int width, bool right, bool cut_output);
/*****************************************************************************
* Global Print Functions
*****************************************************************************/
int print_jobs_array(list_t *jobs, list_t *format)
{
if (!params.no_header)
print_job_from_format(NULL, format);
if (params.weights) {
print_job_from_format((priority_factors_object_t *) -1, format);
return SLURM_SUCCESS;
}
/* Print the jobs of interest */
if (jobs) {
sort_job_list(jobs);
list_for_each (jobs, (ListForF) print_job_from_format,
(void *) format);
}
return SLURM_SUCCESS;
}
double get_priority_from_factors(priority_factors_object_t *prio_factors_obj)
{
int i = 0;
priority_factors_t *prio_factors;
double priority;
if (prio_factors_obj->direct_prio > 0)
return prio_factors_obj->direct_prio;
prio_factors = prio_factors_obj->prio_factors;
xassert(prio_factors);
priority = prio_factors->priority_age +
prio_factors->priority_assoc +
prio_factors->priority_fs +
prio_factors->priority_js +
prio_factors->priority_part +
prio_factors->priority_qos +
(double)((int64_t)prio_factors->priority_site - NICE_OFFSET) -
(double)((int64_t)prio_factors->nice - NICE_OFFSET);
for (i = 0; i < prio_factors->tres_cnt; i++) {
if (!prio_factors->priority_tres[i])
continue;
priority += prio_factors->priority_tres[i];
}
/* Priority 0 is reserved for held jobs */
if (priority < 1)
priority = 1;
return priority;
}
static int _print_str(char *str, int width, bool right, bool cut_output)
{
char format[64];
int printed = 0;
if (right == true && width != 0)
snprintf(format, 64, "%%%ds", width);
else if (width != 0)
snprintf(format, 64, "%%.%ds", width);
else {
format[0] = '%';
format[1] = 's';
format[2] = '\0';
}
if ((width == 0) || (cut_output == false)) {
if ((printed = printf(format, str)) < 0)
return printed;
} else {
char temp[width + 1];
snprintf(temp, width + 1, format, str);
if ((printed = printf("%s",temp)) < 0)
return printed;
}
while (printed++ < width)
printf(" ");
return printed;
}
static int _print_int(double number, int width, bool right, bool cut_output)
{
char buf[32];
snprintf(buf, 32, "%.0f", number);
return _print_str(buf, width, right, cut_output);
}
static int _print_norm(double number, int width, bool right, bool cut_output)
{
char buf[32];
snprintf(buf, 32, "%.7lf", number);
return _print_str(buf, width, right, cut_output);
}
/*****************************************************************************
* Job Print Functions
*****************************************************************************/
int print_job_from_format(priority_factors_object_t * job, list_t *list)
{
list_itr_t *i = list_iterator_create(list);
job_format_t *current;
while ((current = list_next(i))) {
if (current->
function(job, current->width, current->right_justify,
current->suffix)
!= SLURM_SUCCESS)
return SLURM_ERROR;
}
list_iterator_destroy(i);
printf("\n");
return SLURM_SUCCESS;
}
int job_format_add_function(list_t *list, int width, bool right, char *suffix,
int (*function) (priority_factors_object_t *,
int, bool, char*))
{
job_format_t *tmp = (job_format_t *) xmalloc(sizeof(job_format_t));
tmp->function = function;
tmp->width = width;
tmp->right_justify = right;
tmp->suffix = suffix;
list_append(list, tmp);
return SLURM_SUCCESS;
}
int _print_account(priority_factors_object_t *job, int width, bool right,
char *suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("ACCOUNT", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else
_print_str(job->account, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_job_id(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("JOBID", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("Weights", width, right, true);
else {
char id[FORMAT_STRING_SIZE];
snprintf(id, FORMAT_STRING_SIZE, "%u", job->job_id);
_print_str(id, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_prefix(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_age_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("AGE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_age, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
priority_factors_t *prio_factors = job->prio_factors;
if (weight_age)
num = prio_factors->priority_age / weight_age;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_age_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("AGE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_age, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int(job->prio_factors->priority_age, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_assoc_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("ASSOC", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_assoc, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
if (weight_assoc)
num = job->prio_factors->priority_assoc / weight_assoc;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_assoc_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("ASSOC", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_assoc, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int(job->prio_factors->priority_assoc,
width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_cluster_name(priority_factors_object_t *job, int width,
bool right, char *suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("CLUSTER", width, right, true);
else
_print_str(job->cluster_name, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_fs_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("FAIRSHARE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_fs, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
if (weight_fs)
num = job->prio_factors->priority_fs / weight_fs;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_fs_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("FAIRSHARE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_fs, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int(job->prio_factors->priority_fs, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
char temp[FORMAT_STRING_SIZE];
if (job == NULL) /* Print the Header instead */
_print_str("PRIORITY", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else if (job->direct_prio > 0) {
sprintf(temp, "%16.14f", job->direct_prio);
_print_str(temp, width, right, true);
} else {
double priority = get_priority_from_factors(job);
double prio = priority / (double) ((uint32_t) 0xffffffff);
sprintf(temp, "%16.14f", prio);
_print_str(temp, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
char temp[FORMAT_STRING_SIZE];
if (job == NULL) /* Print the Header instead */
_print_str("PRIORITY", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else {
sprintf(temp, "%lld", (long long)get_priority_from_factors(job));
_print_str(temp, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_js_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("JOBSIZE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_js, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
if (weight_js)
num = job->prio_factors->priority_js / weight_js;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_js_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("JOBSIZE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_js, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
_print_int(job->prio_factors->priority_js, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_part_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("PARTITION", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_part, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
if (weight_part)
num = job->prio_factors->priority_part / weight_part;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_part_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("PARTITION", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_part, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int(job->prio_factors->priority_part,
width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_partition(priority_factors_object_t *job, int width, bool right,
char *suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("PARTITION", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else
_print_str(job->partition, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_qos_name(priority_factors_object_t *job, int width, bool right,
char *suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("QOSNAME", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else
_print_str(job->qos, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_qos_priority_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("QOS", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_qos, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else {
double num = 0;
if (weight_qos)
num = job->prio_factors->priority_qos / weight_qos;
_print_norm(num, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_qos_priority_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("QOS", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(weight_qos, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int(job->prio_factors->priority_qos, width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_site_priority(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("SITE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_int(1, width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int((int64_t)job->prio_factors->priority_site -
NICE_OFFSET, width,
right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_nice(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("NICE", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else if (job->direct_prio > 0)
_print_int(0, width, right, true);
else
_print_int((int64_t)job->prio_factors->nice - NICE_OFFSET,
width, right, true);
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_job_user_name(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) /* Print the Header instead */
_print_str("USER", width, right, true);
else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else {
char *uname = uid_to_string_cached((uid_t) job->user_id);
_print_str(uname, width, right, true);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_tres_normalized(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) { /* Print the Header instead */
_print_str("TRES", width, right, true);
} else if (job == (priority_factors_object_t *) -1)
_print_str("", width, right, true);
else if (job->direct_prio > 0)
_print_str("", width, right, true);
else {
priority_factors_t *prio_factors = job->prio_factors;
char *values = xstrdup("");
int i = 0;
for (i = 0; i < prio_factors->tres_cnt; i++) {
if (!prio_factors->priority_tres[i])
continue;
if (values[0])
xstrcat(values, ",");
xstrfmtcat(values, "%s=%.2f",
prio_factors->tres_names[i],
prio_factors->priority_tres[i] /
prio_factors->tres_weights[i]);
}
_print_str(values, width, right, true);
xfree(values);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}
int _print_tres_weighted(priority_factors_object_t * job, int width,
bool right, char* suffix)
{
if (job == NULL) { /* Print the Header instead */
_print_str("TRES", width, right, true);
} else if (job == (priority_factors_object_t *) -1)
_print_str(weight_tres, width, right, true);
else if (job->direct_prio > 0)
_print_str("", width, right, true);
else {
priority_factors_t *prio_factors = job->prio_factors;
char *values = xstrdup("");
int i = 0;
for (i = 0; i < prio_factors->tres_cnt; i++) {
if (!prio_factors->priority_tres[i])
continue;
if (values[0])
xstrcat(values, ",");
xstrfmtcat(values, "%s=%.0f",
prio_factors->tres_names[i],
prio_factors->priority_tres[i]);
}
_print_str(values, width, right, true);
xfree(values);
}
if (suffix)
printf("%s", suffix);
return SLURM_SUCCESS;
}