| /*****************************************************************************\ |
| * print.c - print functions for sacct |
| ***************************************************************************** |
| * Copyright (C) 2006 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 "sacct.h" |
| #include "src/common/cpu_frequency.h" |
| #include "src/common/parse_time.h" |
| #include "src/common/print_fields.h" |
| #include "src/common/uid.h" |
| #include "slurm/slurm.h" |
| |
| print_field_t *field = NULL; |
| int curr_inx = 1; |
| char outbuf[PATH_MAX]; |
| |
| #define SACCT_TRES_AVE 0x0001 |
| #define SACCT_TRES_OUT 0x0002 |
| #define SACCT_TRES_MIN 0x0004 |
| #define SACCT_TRES_TOT 0x0008 |
| |
| static char *_elapsed_time(uint64_t secs, uint64_t usecs) |
| { |
| uint64_t days, hours, minutes, seconds, subsec = 0; |
| char *str = NULL; |
| |
| if (secs == NO_VAL64) |
| return NULL; |
| |
| if (usecs >= 1E6) { |
| secs += usecs / 1E6; |
| usecs = usecs % (int)1E6; |
| } |
| if (usecs > 0) { |
| /* give me 3 significant digits to tack onto the sec */ |
| subsec = (usecs/1000); |
| } |
| seconds = secs % 60; |
| minutes = (secs / 60) % 60; |
| hours = (secs / 3600) % 24; |
| days = secs / 86400; |
| |
| if (days) |
| str = xstrdup_printf("%"PRIu64"-%2.2"PRIu64":%2.2"PRIu64":%2.2"PRIu64"", |
| days, hours, minutes, seconds); |
| else if (hours) |
| str = xstrdup_printf("%2.2"PRIu64":%2.2"PRIu64":%2.2"PRIu64"", |
| hours, minutes, seconds); |
| else if (subsec) |
| str = xstrdup_printf("%2.2"PRIu64":%2.2"PRIu64".%3.3"PRIu64"", |
| minutes, seconds, subsec); |
| else |
| str = xstrdup_printf("00:%2.2"PRIu64":%2.2"PRIu64"", |
| minutes, seconds); |
| return str; |
| } |
| |
| static char *_find_qos_name_from_list(list_t *qos_list, int qosid) |
| { |
| slurmdb_qos_rec_t *qos; |
| |
| if (!qos_list || qosid == NO_VAL) |
| return NULL; |
| |
| qos = list_find_first(qos_list, slurmdb_find_qos_in_list, &qosid); |
| |
| if (qos) |
| return qos->name; |
| else |
| return "Unknown"; |
| } |
| |
| static void _print_small_double( |
| char *outbuf, int buf_size, double dub, int units) |
| { |
| if (fuzzy_equal(dub, NO_VAL)) |
| return; |
| |
| if (dub > 1) |
| convert_num_unit((double)dub, outbuf, buf_size, units, |
| params.units, params.convert_flags); |
| else if (dub > 0) |
| snprintf(outbuf, buf_size, "%.2fM", dub); |
| else |
| snprintf(outbuf, buf_size, "0"); |
| } |
| |
| static char *_get_tres_node(int type, void *object, int tres_pos, |
| uint16_t flags) |
| { |
| slurmdb_stats_t *stats = NULL; |
| char *tmp_char = NULL; |
| char *nodes = NULL; |
| slurmdb_step_rec_t *step = object; |
| |
| if (type != JOBSTEP) |
| return NULL; |
| |
| stats = &step->stats; |
| nodes = step->nodes; |
| |
| if (!stats) |
| return NULL; |
| |
| if (flags & SACCT_TRES_OUT) |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_out_min_nodeid : |
| stats->tres_usage_out_max_nodeid; |
| else |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_in_min_nodeid : |
| stats->tres_usage_in_max_nodeid; |
| |
| return find_hostname( |
| slurmdb_find_tres_count_in_string(tmp_char, tres_pos), |
| nodes); |
| } |
| |
| static uint32_t _get_tres_task(int type, void *object, int tres_pos, |
| uint16_t flags) |
| { |
| slurmdb_stats_t *stats = NULL; |
| uint32_t tmp_uint32 = NO_VAL; |
| uint64_t tmp_uint64 = NO_VAL64; |
| char *tmp_char = NULL; |
| slurmdb_step_rec_t *step = object; |
| |
| if (type != JOBSTEP) |
| return tmp_uint32; |
| |
| stats = &step->stats; |
| |
| if (!stats) |
| return tmp_uint32; |
| |
| if (flags & SACCT_TRES_OUT) |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_out_min_taskid : |
| stats->tres_usage_out_max_taskid; |
| else |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_in_min_taskid : |
| stats->tres_usage_in_max_taskid; |
| |
| tmp_uint64 = slurmdb_find_tres_count_in_string(tmp_char, tres_pos); |
| |
| if (tmp_uint64 == INFINITE64) |
| tmp_uint64 = NO_VAL64; |
| |
| if (tmp_uint64 != NO_VAL64) |
| tmp_uint32 = tmp_uint64; |
| |
| return tmp_uint32; |
| } |
| |
| static uint64_t _get_tres_cnt(int type, void *object, int tres_pos, |
| uint16_t flags) |
| { |
| slurmdb_stats_t *stats = NULL; |
| uint64_t tmp_uint64 = NO_VAL64; |
| char *tmp_char = NULL; |
| slurmdb_step_rec_t *step = object; |
| |
| if (type != JOBSTEP) |
| return NO_VAL64; |
| |
| stats = &step->stats; |
| |
| if (!stats) |
| return tmp_uint64; |
| |
| if (flags & SACCT_TRES_OUT) { |
| if (flags & SACCT_TRES_AVE) |
| tmp_char = stats->tres_usage_out_ave; |
| else if (flags & SACCT_TRES_TOT) |
| tmp_char = stats->tres_usage_out_tot; |
| else |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_out_min : |
| stats->tres_usage_out_max; |
| } else { |
| if (flags & SACCT_TRES_AVE) |
| tmp_char = stats->tres_usage_in_ave; |
| else if (flags & SACCT_TRES_TOT) |
| tmp_char = stats->tres_usage_in_tot; |
| else |
| tmp_char = (flags & SACCT_TRES_MIN) ? |
| stats->tres_usage_in_min : |
| stats->tres_usage_in_max; |
| } |
| |
| tmp_uint64 = slurmdb_find_tres_count_in_string(tmp_char, tres_pos); |
| |
| if (tmp_uint64 == INFINITE64) |
| tmp_uint64 = NO_VAL64; |
| |
| return tmp_uint64; |
| } |
| |
| static void _print_tres_field(char *tres_in, char *nodes, bool convert, |
| uint32_t tres_flags) |
| { |
| char *temp = NULL; |
| |
| 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(acct_db_conn, &tres_cond); |
| } |
| |
| temp = slurmdb_make_tres_string_from_simple(tres_in, g_tres_list, |
| convert ? |
| params.units : NO_VAL, |
| convert ? |
| params.convert_flags : |
| CONVERT_NUM_UNIT_RAW, |
| tres_flags, |
| nodes); |
| |
| field->print_routine(field, temp, (curr_inx == field_count)); |
| xfree(temp); |
| return; |
| } |
| |
| static void _print_expanded_array_job(slurmdb_job_rec_t *job) |
| { |
| int i_first, i_last; |
| bitstr_t *bitmap; |
| |
| bitmap = bit_alloc(slurm_conf.max_array_sz); |
| (void) bit_unfmt_hexmask(bitmap, job->array_task_str); |
| xfree(job->array_task_str); |
| |
| i_first = bit_ffs(bitmap); |
| if (i_first == -1) |
| i_last = -2; |
| else |
| i_last = bit_fls(bitmap); |
| for (int i = i_first; i <= i_last; i++) { |
| if (!bit_test(bitmap, i)) |
| continue; |
| job->array_task_id = i; |
| print_fields(JOB, job); |
| } |
| FREE_NULL_BITMAP(bitmap); |
| } |
| |
| static void _get_step_jobid_str(char **out, slurmdb_step_rec_t *step) |
| { |
| int written_sz, rem_sz = FORMAT_STRING_SIZE; |
| slurmdb_job_rec_t *job = step->job_ptr; |
| char *id = slurmdb_get_job_id_str(job); |
| |
| *out = xmalloc(rem_sz); |
| written_sz = snprintf(*out, rem_sz, "%s.", id); |
| rem_sz -= written_sz; |
| log_build_step_id_str(&step->step_id, (*out + written_sz), rem_sz, |
| (STEP_ID_FLAG_NO_PREFIX | STEP_ID_FLAG_NO_JOB)); |
| xfree(id); |
| } |
| |
| extern void print_fields(type_t type, void *object) |
| { |
| slurmdb_job_rec_t *job = (slurmdb_job_rec_t *)object; |
| slurmdb_step_rec_t *step = (slurmdb_step_rec_t *)object; |
| jobcomp_job_rec_t *job_comp = (jobcomp_job_rec_t *)object; |
| struct passwd *pw = NULL; |
| int cpu_tres_rec_count = 0; |
| int step_cpu_tres_rec_count = 0; |
| char tmp1[128]; |
| char *nodes = NULL, *tmp_path = NULL; |
| |
| if (!object) { |
| fatal("Job or step record is NULL"); |
| return; |
| } |
| |
| if (params.opt_array && job->array_task_str && (type == JOB)) { |
| _print_expanded_array_job(job); |
| return; |
| } |
| |
| switch (type) { |
| case JOB: |
| if (params.expand_patterns) { |
| if (job->std_in && (*job->std_in != '\0')) { |
| tmp_path = |
| slurmdb_expand_job_stdio_fields( |
| job->std_in, job); |
| xfree(job->std_in); |
| job->std_in = tmp_path; |
| } |
| if (job->std_err && (*job->std_err != '\0')) { |
| tmp_path = |
| slurmdb_expand_job_stdio_fields( |
| job->std_err, job); |
| xfree(job->std_err); |
| job->std_err = tmp_path; |
| } |
| if (job->std_out && (*job->std_out != '\0')) { |
| tmp_path = |
| slurmdb_expand_job_stdio_fields( |
| job->std_out, job); |
| xfree(job->std_out); |
| job->std_out = tmp_path; |
| } |
| } |
| job_comp = NULL; |
| cpu_tres_rec_count = slurmdb_find_tres_count_in_string( |
| job->tres_alloc_str, |
| TRES_CPU); |
| break; |
| case JOBSTEP: |
| job = step->job_ptr; |
| |
| if (params.expand_patterns) { |
| if (step->std_in && (*step->std_in != '\0')) { |
| tmp_path = |
| slurmdb_expand_step_stdio_fields( |
| step->std_in, step); |
| xfree(step->std_in); |
| step->std_in = tmp_path; |
| } |
| if (step->std_err && (*step->std_err != '\0')) { |
| tmp_path = |
| slurmdb_expand_step_stdio_fields( |
| step->std_err, step); |
| xfree(step->std_err); |
| step->std_err = tmp_path; |
| } |
| if (step->std_out && (*step->std_out != '\0')) { |
| tmp_path = |
| slurmdb_expand_step_stdio_fields( |
| step->std_out, step); |
| xfree(step->std_out); |
| step->std_out = tmp_path; |
| } |
| } |
| |
| if ((step_cpu_tres_rec_count = |
| slurmdb_find_tres_count_in_string( |
| step->tres_alloc_str, TRES_CPU)) == INFINITE64) |
| step_cpu_tres_rec_count = |
| slurmdb_find_tres_count_in_string( |
| job->tres_alloc_str, |
| TRES_CPU); |
| |
| job_comp = NULL; |
| break; |
| case JOBCOMP: |
| job = NULL; |
| step = NULL; |
| break; |
| default: |
| break; |
| } |
| |
| if ((uint64_t)cpu_tres_rec_count == INFINITE64) |
| cpu_tres_rec_count = 0; |
| |
| if ((uint64_t)step_cpu_tres_rec_count == INFINITE64) |
| step_cpu_tres_rec_count = 0; |
| |
| curr_inx = 1; |
| list_iterator_reset(print_fields_itr); |
| while ((field = list_next(print_fields_itr))) { |
| char *tmp_char = NULL, *id = NULL; |
| int exit_code, tmp_int = NO_VAL, tmp_int2 = NO_VAL; |
| time_t tmp_time = 0; |
| double tmp_dub = (double)NO_VAL; /* don't use NO_VAL64 |
| unless we can |
| confirm the values |
| coming in are |
| NO_VAL64 */ |
| uint16_t tmp_uint16 = NO_VAL16; |
| uint32_t tmp_uint32 = NO_VAL, tmp2_uint32 = NO_VAL; |
| uint64_t tmp_uint64 = NO_VAL64, tmp2_uint64 = NO_VAL64; |
| |
| memset(&outbuf, 0, sizeof(outbuf)); |
| switch (field->type) { |
| case PRINT_ALLOC_CPUS: |
| switch(type) { |
| case JOB: |
| tmp_int = cpu_tres_rec_count; |
| break; |
| case JOBSTEP: |
| tmp_int = step_cpu_tres_rec_count; |
| break; |
| case JOBCOMP: |
| tmp_int = job_comp->proc_cnt; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_int, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ALLOC_NODES: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->alloc_nodes; |
| tmp_char = job->tres_alloc_str; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->nnodes; |
| tmp_char = step->tres_alloc_str; |
| break; |
| case JOBCOMP: |
| tmp_int = job_comp->node_cnt; |
| break; |
| default: |
| break; |
| } |
| |
| if (!tmp_uint32 && tmp_char) { |
| if ((tmp_uint64 = |
| slurmdb_find_tres_count_in_string( |
| tmp_char, TRES_NODE)) |
| != INFINITE64) |
| tmp_uint32 = tmp_uint64; |
| } |
| convert_num_unit((double)tmp_uint32, outbuf, |
| sizeof(outbuf), UNIT_NONE, NO_VAL, |
| params.convert_flags); |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ACCOUNT: |
| switch(type) { |
| case JOB: |
| tmp_char = job->account; |
| break; |
| case JOBSTEP: |
| tmp_char = step->job_ptr->account; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->account; |
| break; |
| default: |
| tmp_char = "n/a"; |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ACT_CPUFREQ: |
| switch (type) { |
| case JOBSTEP: |
| tmp_dub = step->stats.act_cpufreq; |
| break; |
| default: |
| break; |
| } |
| |
| if (!fuzzy_equal(tmp_dub, NO_VAL)) |
| convert_num_unit2((double)tmp_dub, outbuf, |
| sizeof(outbuf), UNIT_KILO, |
| params.units, 1000, |
| params.convert_flags & |
| (~CONVERT_NUM_UNIT_EXACT)); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ADMIN_COMMENT: |
| switch(type) { |
| case JOB: |
| tmp_char = job->admin_comment; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ASSOCID: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->associd; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->job_ptr->associd; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_AVECPU: |
| tmp_uint64 = _get_tres_cnt( |
| type, object, TRES_CPU, SACCT_TRES_AVE); |
| if (tmp_uint64 != NO_VAL64) { |
| tmp_uint64 /= CPU_TIME_ADJ; |
| tmp_char = _elapsed_time(tmp_uint64, 0); |
| } |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_AVEDISKREAD: |
| tmp_uint64 = _get_tres_cnt( |
| type, object, TRES_FS_DISK, |
| SACCT_TRES_AVE); |
| |
| if (tmp_uint64 != NO_VAL64) |
| tmp_dub = (double)tmp_uint64 / (1 << 20); |
| |
| _print_small_double(outbuf, sizeof(outbuf), |
| tmp_dub, UNIT_MEGA); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_AVEDISKWRITE: |
| tmp_uint64 = _get_tres_cnt( |
| type, object, TRES_FS_DISK, |
| SACCT_TRES_OUT | SACCT_TRES_AVE); |
| |
| if (tmp_uint64 != NO_VAL64) |
| tmp_dub = (double)tmp_uint64 / (1 << 20); |
| |
| _print_small_double(outbuf, sizeof(outbuf), |
| tmp_dub, UNIT_MEGA); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_AVEPAGES: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_PAGES, |
| SACCT_TRES_AVE); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit((double)tmp_uint64, outbuf, |
| sizeof(outbuf), UNIT_NONE, |
| params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_AVERSS: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_MEM, |
| SACCT_TRES_AVE); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit((double)tmp_uint64, outbuf, |
| sizeof(outbuf), UNIT_NONE, |
| params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_AVEVSIZE: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_VMEM, |
| SACCT_TRES_AVE); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit((double)tmp_uint64, outbuf, |
| sizeof(outbuf), UNIT_NONE, |
| params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_BLOCKID: |
| switch(type) { |
| case JOB: |
| tmp_char = job->blockid; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->blockid; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CLUSTER: |
| switch(type) { |
| case JOB: |
| tmp_char = job->cluster; |
| break; |
| case JOBSTEP: |
| tmp_char = step->job_ptr->cluster; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->cluster; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_COMMENT: |
| switch(type) { |
| case JOB: |
| tmp_char = job->derived_es; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CONSTRAINTS: |
| switch(type) { |
| case JOB: |
| tmp_char = job->constraints; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CONTAINER: |
| switch(type) { |
| case JOB: |
| tmp_char = job->container; |
| break; |
| case JOBSTEP: |
| tmp_char = step->container; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CONSUMED_ENERGY: |
| switch (type) { |
| case JOB: |
| if ((tmp_uint64 = |
| slurmdb_find_tres_count_in_string( |
| job->tres_alloc_str, |
| TRES_ENERGY)) |
| == INFINITE64) |
| tmp_uint64 = 0; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->stats.consumed_energy; |
| break; |
| default: |
| break; |
| } |
| |
| if (!fuzzy_equal(tmp_uint64, NO_VAL64)) |
| convert_num_unit2((double)tmp_uint64, outbuf, |
| sizeof(outbuf), UNIT_NONE, |
| params.units, 1000, |
| params.convert_flags & |
| (~CONVERT_NUM_UNIT_EXACT)); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CONSUMED_ENERGY_RAW: |
| switch (type) { |
| case JOB: |
| if ((tmp_uint64 = |
| slurmdb_find_tres_count_in_string( |
| job->tres_alloc_str, |
| TRES_ENERGY)) |
| == INFINITE64) |
| tmp_uint64 = 0; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->stats.consumed_energy; |
| break; |
| default: |
| break; |
| } |
| |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CPU_TIME: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = (uint64_t)job->elapsed |
| * (uint64_t)cpu_tres_rec_count; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = (uint64_t)step->elapsed |
| * (uint64_t)step_cpu_tres_rec_count; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_CPU_TIME_RAW: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = (uint64_t)job->elapsed |
| * (uint64_t)cpu_tres_rec_count; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = (uint64_t)step->elapsed |
| * (uint64_t)step_cpu_tres_rec_count; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_DB_INX: |
| case PRINT_SLUID: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->db_index; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->job_ptr->db_index; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_DERIVED_EC: |
| tmp_int = tmp_int2 = 0; |
| switch (type) { |
| case JOB: |
| if (job->derived_ec == NO_VAL) |
| ; |
| else if (WIFSIGNALED(job->derived_ec)) |
| tmp_int2 = WTERMSIG(job->derived_ec); |
| else if (WIFEXITED(job->derived_ec)) |
| tmp_int = WEXITSTATUS(job->derived_ec); |
| |
| snprintf(outbuf, sizeof(outbuf), "%d:%d", |
| tmp_int, tmp_int2); |
| break; |
| case JOBCOMP: |
| if (job_comp->derived_ec) |
| snprintf(outbuf, sizeof(outbuf), "%s", |
| job_comp->derived_ec); |
| break; |
| default: |
| break; |
| } |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ELAPSED: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->elapsed; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->elapsed; |
| break; |
| case JOBCOMP: |
| tmp_uint64 = job_comp->elapsed_time; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ELAPSED_RAW: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->elapsed; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->elapsed; |
| break; |
| case JOBCOMP: |
| tmp_uint32 = job_comp->elapsed_time; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_ELIGIBLE: |
| switch(type) { |
| case JOB: |
| tmp_time = job->eligible; |
| break; |
| case JOBSTEP: |
| tmp_time = step->start; |
| break; |
| case JOBCOMP: |
| tmp_time = parse_time(job_comp->eligible_time, |
| 1); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_time, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_END: |
| switch(type) { |
| case JOB: |
| tmp_time = job->end; |
| break; |
| case JOBSTEP: |
| tmp_time = step->end; |
| break; |
| case JOBCOMP: |
| tmp_time = parse_time(job_comp->end_time, 1); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_time, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_EXITCODE: |
| exit_code = NO_VAL; |
| switch (type) { |
| case JOB: |
| exit_code = job->exitcode; |
| break; |
| case JOBSTEP: |
| exit_code = step->exitcode; |
| break; |
| case JOBCOMP: |
| if (job_comp->exit_code) |
| snprintf(outbuf, sizeof(outbuf), "%s", |
| job_comp->exit_code); |
| break; |
| default: |
| break; |
| } |
| tmp_int = tmp_int2 = 0; |
| if (exit_code != NO_VAL) { |
| if (WIFSIGNALED(exit_code)) |
| tmp_int2 = WTERMSIG(exit_code); |
| else if (WIFEXITED(exit_code)) |
| tmp_int = WEXITSTATUS(exit_code); |
| snprintf(outbuf, sizeof(outbuf), "%d:%d", |
| tmp_int, tmp_int2); |
| } |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_EXTRA: |
| switch(type) { |
| case JOB: |
| tmp_char = job->extra; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_FAILED_NODE: |
| switch (type) { |
| case JOB: |
| tmp_char = job->failed_node; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_FLAGS: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->flags; |
| break; |
| default: |
| tmp_uint32 = SLURMDB_JOB_FLAG_NONE; |
| break; |
| } |
| if (tmp_uint32 != SLURMDB_JOB_FLAG_NONE) |
| tmp_char = slurmdb_job_flags_str(tmp_uint32); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_GID: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->gid; |
| break; |
| case JOBCOMP: |
| tmp_uint32 = job_comp->gid; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_GROUP: |
| tmp_char = NULL; |
| switch(type) { |
| case JOB: |
| tmp_char = gid_to_string(job->gid); |
| break; |
| case JOBCOMP: |
| tmp_char = gid_to_string(job_comp->gid); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_JOBID: |
| switch (type) { |
| case JOB: |
| if (job) |
| id = slurmdb_get_job_id_str(job); |
| tmp_char = id; |
| id = NULL; |
| break; |
| case JOBSTEP: |
| _get_step_jobid_str(&tmp_char, step); |
| break; |
| case JOBCOMP: |
| tmp_char = xstrdup_printf("%u", |
| job_comp->jobid); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_JOBIDRAW: |
| switch (type) { |
| case JOB: |
| tmp_char = xstrdup_printf("%u", job->jobid); |
| break; |
| case JOBSTEP: |
| tmp_int = FORMAT_STRING_SIZE; |
| tmp_char = xmalloc(tmp_int); |
| tmp_int2 = snprintf(tmp_char, tmp_int, "%u.", |
| step->job_ptr->jobid); |
| tmp_int -= tmp_int2; |
| log_build_step_id_str(&step->step_id, |
| tmp_char + tmp_int2, |
| tmp_int, |
| STEP_ID_FLAG_NO_PREFIX | |
| STEP_ID_FLAG_NO_JOB); |
| break; |
| case JOBCOMP: |
| tmp_char = xstrdup_printf("%u", |
| job_comp->jobid); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_JOBNAME: |
| switch(type) { |
| case JOB: |
| tmp_char = job->jobname; |
| break; |
| case JOBSTEP: |
| tmp_char = step->stepname; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->jobname; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_LAYOUT: |
| { |
| char *name = NULL; |
| |
| switch(type) { |
| case JOBSTEP: |
| name = slurm_step_layout_type_name( |
| step->task_dist); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, name, |
| (curr_inx == field_count)); |
| xfree(name); |
| break; |
| } |
| case PRINT_LICENSES: |
| switch(type) { |
| case JOB: |
| tmp_char = job->licenses; |
| break; |
| case JOBSTEP: |
| break; |
| case JOBCOMP: |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXDISKREAD: |
| tmp_uint64 = _get_tres_cnt( |
| type, object, TRES_FS_DISK, 0); |
| |
| if (tmp_uint64 != NO_VAL64) |
| tmp_dub = (double)tmp_uint64 / (1 << 20); |
| |
| _print_small_double(outbuf, sizeof(outbuf), |
| tmp_dub, UNIT_MEGA); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXDISKREADNODE: |
| tmp_char = _get_tres_node( |
| type, object, TRES_FS_DISK, 0); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MAXDISKREADTASK: |
| tmp_uint32 = _get_tres_task( |
| type, object, TRES_FS_DISK, 0); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXDISKWRITE: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_FS_DISK, |
| SACCT_TRES_OUT); |
| |
| if (tmp_uint64 != NO_VAL64) |
| tmp_dub = (double)tmp_uint64 / (1 << 20); |
| |
| _print_small_double(outbuf, sizeof(outbuf), |
| tmp_dub, UNIT_MEGA); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXDISKWRITENODE: |
| tmp_char = _get_tres_node(type, object, TRES_FS_DISK, |
| SACCT_TRES_OUT); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MAXDISKWRITETASK: |
| tmp_uint32 = _get_tres_task(type, object, TRES_FS_DISK, |
| SACCT_TRES_OUT); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXPAGES: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_PAGES, 0); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit( |
| (double)tmp_uint64, |
| outbuf, sizeof(outbuf), |
| UNIT_NONE, params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXPAGESNODE: |
| tmp_char = _get_tres_node(type, object, TRES_PAGES, 0); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MAXPAGESTASK: |
| tmp_uint32 = _get_tres_task( |
| type, object, TRES_PAGES, 0); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXRSS: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_MEM, 0); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit((double)tmp_uint64, |
| outbuf, sizeof(outbuf), |
| UNIT_NONE, params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXRSSNODE: |
| tmp_char = _get_tres_node(type, object, TRES_MEM, 0); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MAXRSSTASK: |
| tmp_uint32 = _get_tres_task(type, object, TRES_MEM, 0); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MAXVSIZE: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_VMEM, 0); |
| |
| if (tmp_uint64 != NO_VAL64) |
| convert_num_unit((double)tmp_uint64, |
| outbuf, sizeof(outbuf), |
| UNIT_NONE, params.units, |
| params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_TRESUIA: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_in_ave; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUIM: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_max; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUIMN: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_max_nodeid; |
| nodes = step->nodes; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, nodes, 0, 0); |
| break; |
| case PRINT_TRESUIMT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_max_taskid; |
| break; |
| default: |
| break; |
| } |
| _print_tres_field(tmp_char, NULL, 0, 0); |
| break; |
| case PRINT_TRESUIMI: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_min; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUIMIN: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_min_nodeid; |
| nodes = step->nodes; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, nodes, 0, 0); |
| break; |
| case PRINT_TRESUIMIT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_in_min_taskid; |
| break; |
| default: |
| break; |
| } |
| _print_tres_field(tmp_char, NULL, 0, 0); |
| break; |
| case PRINT_TRESUIT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_in_tot; |
| break; |
| default: |
| break; |
| } |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUOA: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_ave; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUOM: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_out_max; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUOMN: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_max_nodeid; |
| nodes = step->nodes; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, nodes, 0, 0); |
| break; |
| case PRINT_TRESUOMT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_max_taskid; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 0, 0); |
| break; |
| case PRINT_TRESUOMI: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = step->stats.tres_usage_out_min; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_TRESUOMIN: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_min_nodeid; |
| nodes = step->nodes; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, nodes, 0, 0); |
| break; |
| case PRINT_TRESUOMIT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_min_taskid; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 0, 0); |
| break; |
| case PRINT_TRESUOT: |
| switch(type) { |
| case JOBSTEP: |
| tmp_char = |
| step->stats.tres_usage_out_tot; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, |
| TRES_STR_FLAG_BYTES); |
| break; |
| case PRINT_MAXVSIZENODE: |
| tmp_char = _get_tres_node(type, object, TRES_VMEM, 0); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MAXVSIZETASK: |
| tmp_uint32 = _get_tres_task(type, object, TRES_VMEM, 0); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MCS_LABEL: |
| switch(type) { |
| case JOB: |
| if (job->mcs_label) |
| tmp_char = job->mcs_label; |
| break; |
| case JOBSTEP: |
| break; |
| case JOBCOMP: |
| break; |
| default: |
| tmp_char = "n/a"; |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_MINCPU: |
| tmp_uint64 = _get_tres_cnt(type, object, TRES_CPU, |
| SACCT_TRES_MIN); |
| |
| if (tmp_uint64 != NO_VAL64) { |
| tmp_uint64 /= CPU_TIME_ADJ; |
| tmp_char = _elapsed_time(tmp_uint64, 0); |
| } |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MINCPUNODE: |
| tmp_char = _get_tres_node(type, object, TRES_CPU, |
| SACCT_TRES_MIN); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_MINCPUTASK: |
| tmp_uint32 = _get_tres_task(type, object, TRES_CPU, |
| SACCT_TRES_MIN); |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_NODELIST: |
| switch(type) { |
| case JOB: |
| tmp_char = job->nodes; |
| break; |
| case JOBSTEP: |
| tmp_char = step->nodes; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->nodelist; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_NNODES: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->alloc_nodes; |
| tmp_char = (job->tres_alloc_str && |
| job->tres_alloc_str[0]) |
| ? job->tres_alloc_str : |
| job->tres_req_str; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->nnodes; |
| tmp_char = step->tres_alloc_str; |
| break; |
| case JOBCOMP: |
| tmp_uint32 = job_comp->node_cnt; |
| break; |
| default: |
| break; |
| } |
| |
| if (!tmp_uint32 && tmp_char) { |
| if ((tmp_uint64 = |
| slurmdb_find_tres_count_in_string( |
| tmp_char, TRES_NODE)) |
| != INFINITE64) |
| tmp_uint32 = tmp_uint64; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_NTASKS: |
| switch(type) { |
| case JOBSTEP: |
| tmp_uint32 = step->ntasks; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_PRIO: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->priority; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_PARTITION: |
| switch(type) { |
| case JOB: |
| tmp_char = job->partition; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->partition; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_QOS: |
| switch(type) { |
| case JOB: |
| tmp_int = job->qosid; |
| if (!g_qos_list) { |
| slurmdb_qos_cond_t qos_cond = { |
| .flags = |
| QOS_COND_FLAG_WITH_DELETED, |
| }; |
| g_qos_list = slurmdb_qos_get( |
| acct_db_conn, &qos_cond); |
| } |
| |
| tmp_char = _find_qos_name_from_list(g_qos_list, |
| tmp_int); |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->qos_name; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_QOSRAW: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->qosid; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_QOSREQ: |
| switch(type) { |
| case JOB: |
| tmp_char = job->qos_req; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REASON: |
| switch(type) { |
| case JOB: |
| tmp_char = (char *) job_state_reason_string( |
| job->state_reason_prev); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_CPUFREQ_MIN: |
| switch (type) { |
| case JOBSTEP: |
| tmp_uint32 = step->req_cpufreq_min; |
| break; |
| default: |
| break; |
| } |
| cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_uint32); |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_CPUFREQ_MAX: |
| switch (type) { |
| case JOBSTEP: |
| tmp_uint32 = step->req_cpufreq_max; |
| break; |
| default: |
| break; |
| } |
| cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_uint32); |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_CPUFREQ_GOV: |
| switch (type) { |
| case JOBSTEP: |
| tmp_uint32 = step->req_cpufreq_gov; |
| break; |
| default: |
| break; |
| } |
| cpu_freq_to_string(outbuf, sizeof(outbuf), tmp_uint32); |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_CPUS: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->req_cpus; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step_cpu_tres_rec_count; |
| break; |
| default: |
| |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_MEM: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = slurmdb_find_tres_count_in_string( |
| job->tres_req_str, TRES_MEM); |
| break; |
| default: |
| break; |
| } |
| |
| if (tmp_uint64 == INFINITE64) |
| tmp_uint64 = 0; |
| |
| if (tmp_uint64 != NO_VAL64) { |
| convert_num_unit((double)tmp_uint64, |
| outbuf, sizeof(outbuf), |
| UNIT_MEGA, params.units, |
| params.convert_flags); |
| } |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_REQ_NODES: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = 0; |
| tmp_char = job->tres_req_str; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->nnodes; |
| tmp_char = step->tres_alloc_str; |
| break; |
| case JOBCOMP: |
| tmp_uint32 = job_comp->node_cnt; |
| break; |
| default: |
| break; |
| } |
| |
| if (!tmp_uint32 && tmp_char) { |
| if ((tmp_uint64 = |
| slurmdb_find_tres_count_in_string( |
| tmp_char, TRES_NODE)) |
| != INFINITE64) |
| tmp_uint32 = tmp_uint64; |
| } |
| convert_num_unit((double)tmp_uint32, outbuf, |
| sizeof(outbuf), UNIT_NONE, |
| params.units, params.convert_flags); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_RESERVATION: |
| switch(type) { |
| case JOB: |
| if (job->resv_name) { |
| tmp_char = job->resv_name; |
| } |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->resv_name; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_RESERVATION_ID: |
| switch(type) { |
| case JOB: |
| if (job->resvid) |
| tmp_uint32 = job->resvid; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_RESERVATION_REQ: |
| switch(type) { |
| case JOB: |
| if (job->resv_req) { |
| tmp_char = job->resv_req; |
| } |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_RESTART_CNT: |
| switch(type) { |
| case JOB: |
| tmp_uint16 = job->restart_cnt; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint16, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_PLANNED: |
| /* |
| * If eligible is 0 or -1, then the job was never |
| * eligible to run, so planned time is 0. |
| * |
| * If the job hasn't started yet and has an end time, |
| * presume the job was cancelled and use end time |
| * instead of start time. |
| */ |
| switch(type) { |
| case JOB: |
| if (!job->eligible || |
| (job->eligible == INFINITE)) |
| tmp_uint64 = 0; |
| else if ((job->start == NO_VAL) && job->end) |
| tmp_uint64 = job->end - job->eligible; |
| else if (job->start) |
| tmp_uint64 = job->start - job->eligible; |
| else |
| tmp_uint64 = time(NULL) - job->eligible; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_PLANNED_CPU: |
| /* |
| * If eligible is 0 or -1, then the job was never |
| * eligible to run, so planned time is 0. |
| */ |
| switch(type) { |
| case JOB: |
| if (!job->eligible || |
| (job->eligible == INFINITE)) { |
| tmp_uint64 = 0; |
| } else if (job->start) { |
| tmp_uint64 = job->start - |
| job->eligible; |
| tmp_uint64 *= job->req_cpus; |
| } else { |
| tmp_uint64 = time(NULL) - |
| job->eligible; |
| tmp_uint64 *= job->req_cpus; |
| } |
| break; |
| default: |
| |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_PLANNED_CPU_RAW: |
| /* |
| * If eligible is 0 or -1, then the job was never |
| * eligible to run, so planned time is 0. |
| */ |
| switch(type) { |
| case JOB: |
| if (!job->eligible || |
| (job->eligible == INFINITE)) |
| tmp_int = 0; |
| else if (job->start) |
| tmp_int = (job->start - job->eligible) |
| * job->req_cpus; |
| else |
| tmp_int = (time(NULL) - job->eligible) |
| * job->req_cpus; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_int, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_SEGMENT_SIZE: |
| switch(type) { |
| case JOB: |
| if (job->segment_size) |
| tmp_uint16 = job->segment_size; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, &tmp_uint16, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_START: |
| switch(type) { |
| case JOB: |
| tmp_time = job->start; |
| break; |
| case JOBSTEP: |
| tmp_time = step->start; |
| break; |
| case JOBCOMP: |
| tmp_time = parse_time(job_comp->start_time, 1); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_time, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_STATE: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->state; |
| tmp2_uint32 = job->requid; |
| break; |
| case JOBSTEP: |
| tmp_uint32 = step->state; |
| tmp2_uint32 = step->requid; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->state; |
| break; |
| default: |
| break; |
| } |
| |
| if (((tmp_uint32 & JOB_STATE_BASE) == JOB_CANCELLED) && |
| (tmp2_uint32 != INFINITE)) |
| snprintf(outbuf, FORMAT_STRING_SIZE, |
| "%s by %u", |
| job_state_string(tmp_uint32), |
| tmp2_uint32); |
| else if (tmp_uint32 != NO_VAL) |
| snprintf(outbuf, FORMAT_STRING_SIZE, |
| "%s", |
| job_state_string(tmp_uint32)); |
| else if (tmp_char) |
| snprintf(outbuf, FORMAT_STRING_SIZE, |
| "%s", |
| tmp_char); |
| |
| field->print_routine(field, |
| outbuf, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_STDERR: |
| switch(type) { |
| case JOB: |
| tmp_char = job->std_err; |
| break; |
| case JOBSTEP: |
| if (step->std_err && |
| (step->std_err[0] != '\0') && |
| (step->std_err[0] != '/')) { |
| snprintf(outbuf, PATH_MAX, "%s/%s", |
| step->cwd, step->std_err); |
| tmp_char = outbuf; |
| } else { |
| tmp_char = step->std_err; |
| } |
| break; |
| case JOBCOMP: |
| default: |
| tmp_char = NULL; |
| break; |
| } |
| field->print_routine(field, tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_STDIN: |
| switch(type) { |
| case JOB: |
| tmp_char = job->std_in; |
| break; |
| case JOBSTEP: |
| if (step->std_in && |
| (step->std_in[0] != '\0') && |
| (step->std_in[0] != '/')) { |
| snprintf(outbuf, PATH_MAX, "%s/%s", |
| step->cwd, step->std_in); |
| tmp_char = outbuf; |
| } else { |
| tmp_char = step->std_in; |
| } |
| break; |
| case JOBCOMP: |
| default: |
| tmp_char = NULL; |
| break; |
| } |
| field->print_routine(field, tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_STDOUT: |
| switch(type) { |
| case JOB: |
| tmp_char = job->std_out; |
| break; |
| case JOBSTEP: |
| if (step->std_out && |
| (step->std_out[0] != '\0') && |
| (step->std_out[0] != '/')) { |
| snprintf(outbuf, PATH_MAX, "%s/%s", |
| step->cwd, step->std_out); |
| tmp_char = outbuf; |
| } else { |
| tmp_char = step->std_out; |
| } |
| break; |
| case JOBCOMP: |
| default: |
| tmp_char = NULL; |
| break; |
| } |
| field->print_routine(field, tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_SUBMIT: |
| switch(type) { |
| case JOB: |
| tmp_time = job->submit; |
| break; |
| case JOBSTEP: |
| tmp_time = step->start; |
| break; |
| case JOBCOMP: |
| tmp_time = parse_time(job_comp->start_time, 1); |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_time, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_SUBMIT_LINE: |
| switch(type) { |
| case JOB: |
| tmp_char = job->submit_line; |
| break; |
| case JOBSTEP: |
| tmp_char = step->submit_line; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_SUSPENDED: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->suspended; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->suspended; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint64, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_SYSTEMCPU: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->sys_cpu_sec; |
| tmp2_uint64 = job->sys_cpu_usec; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->sys_cpu_sec; |
| tmp2_uint64 = step->sys_cpu_usec; |
| break; |
| default: |
| break; |
| } |
| tmp_char = _elapsed_time(tmp_uint64, tmp2_uint64); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_SYSTEM_COMMENT: |
| switch(type) { |
| case JOB: |
| tmp_char = job->system_comment; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_TIMELIMIT: |
| switch (type) { |
| case JOB: |
| if (job->timelimit == INFINITE) |
| tmp_char = "UNLIMITED"; |
| else if (job->timelimit == NO_VAL) |
| tmp_char = "Partition_Limit"; |
| else if (job->timelimit) { |
| mins2time_str(job->timelimit, |
| tmp1, sizeof(tmp1)); |
| tmp_char = tmp1; |
| } |
| break; |
| case JOBSTEP: |
| if (step->timelimit == INFINITE) { |
| /* Leave blank, timelimit was not set */ |
| } else if (step->timelimit == NO_VAL) { |
| tmp_char = "Partition_Limit"; |
| } else if (step->timelimit) { |
| mins2time_str(step->timelimit, tmp1, |
| sizeof(tmp1)); |
| tmp_char = tmp1; |
| } |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->timelimit; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_TIMELIMIT_RAW: |
| switch (type) { |
| case JOB: |
| if (job->timelimit == INFINITE) |
| tmp_char = "UNLIMITED"; |
| else if (job->timelimit == NO_VAL) |
| tmp_char = "Partition_Limit"; |
| else if (job->timelimit) { |
| tmp_int = 1; |
| tmp_char = xstrdup_printf("%u", |
| job->timelimit); |
| } |
| break; |
| case JOBSTEP: |
| if (step->timelimit == INFINITE) { |
| /* Leave blank, timelimit was not set */ |
| } else if (step->timelimit == NO_VAL) { |
| tmp_char = "Partition_Limit"; |
| } else if (step->timelimit) { |
| tmp_int = 1; |
| tmp_char = xstrdup_printf( |
| "%u", step->timelimit); |
| } |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->timelimit; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| if (tmp_int == 1) |
| xfree(tmp_char); |
| break; |
| case PRINT_TOTALCPU: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->tot_cpu_sec; |
| tmp2_uint64 = job->tot_cpu_usec; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->tot_cpu_sec; |
| tmp2_uint64 = step->tot_cpu_usec; |
| break; |
| default: |
| break; |
| } |
| tmp_char = _elapsed_time(tmp_uint64, tmp2_uint64); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_TRESA: |
| switch(type) { |
| case JOB: |
| tmp_char = job->tres_alloc_str; |
| break; |
| case JOBSTEP: |
| tmp_char = step->tres_alloc_str; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, 0); |
| break; |
| case PRINT_TRESR: |
| switch(type) { |
| case JOB: |
| tmp_char = job->tres_req_str; |
| break; |
| default: |
| break; |
| } |
| |
| _print_tres_field(tmp_char, NULL, 1, 0); |
| break; |
| case PRINT_UID: |
| switch(type) { |
| case JOB: |
| if (params.use_local_uid && job->user && |
| (pw = getpwnam(job->user))) |
| tmp_uint32 = pw->pw_uid; |
| else |
| tmp_uint32 = job->uid; |
| break; |
| case JOBCOMP: |
| tmp_uint32 = job_comp->uid; |
| break; |
| default: |
| break; |
| } |
| |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_USER: |
| { |
| char *user = NULL; |
| switch(type) { |
| case JOB: |
| if (job->user) |
| tmp_char = job->user; |
| else { |
| user = uid_to_string(job->uid); |
| tmp_char = user; |
| } |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->uid_name; |
| break; |
| default: |
| break; |
| } |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(user); |
| break; |
| } |
| case PRINT_USERCPU: |
| switch(type) { |
| case JOB: |
| tmp_uint64 = job->user_cpu_sec; |
| tmp2_uint64 = job->user_cpu_usec; |
| break; |
| case JOBSTEP: |
| tmp_uint64 = step->user_cpu_sec; |
| tmp2_uint64 = step->user_cpu_usec; |
| break; |
| default: |
| break; |
| } |
| |
| tmp_char = _elapsed_time(tmp_uint64, tmp2_uint64); |
| |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| xfree(tmp_char); |
| break; |
| case PRINT_WCKEY: |
| switch(type) { |
| case JOB: |
| tmp_char = job->wckey; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->wckey; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_WCKEYID: |
| switch(type) { |
| case JOB: |
| tmp_uint32 = job->wckeyid; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| &tmp_uint32, |
| (curr_inx == field_count)); |
| break; |
| case PRINT_WORK_DIR: |
| switch(type) { |
| case JOB: |
| tmp_char = job->work_dir; |
| break; |
| case JOBCOMP: |
| tmp_char = job_comp->work_dir; |
| break; |
| default: |
| break; |
| } |
| field->print_routine(field, |
| tmp_char, |
| (curr_inx == field_count)); |
| break; |
| default: |
| break; |
| } |
| curr_inx++; |
| } |
| printf("\n"); |
| } |