| /*****************************************************************************\ |
| * 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; |
| } |