From 4a1eeff0bc597efa4982f7faafcda597b38fbac4 Mon Sep 17 00:00:00 2001 From: Joe Jin Date: Fri, 28 Feb 2025 08:13:34 -0800 Subject: [PATCH] lsirq: add support for reading data from given file This is helpful for analyzng data saved from other system. Signed-off-by: Joe Jin Cc: Zhenwei Pi Cc: Sami Kerola Cc: Karel Zak --- bash-completion/lsirq | 4 ++++ sys-utils/irq-common.c | 19 +++++++++---------- sys-utils/irq-common.h | 3 ++- sys-utils/irqtop.c | 12 ++++++++++-- sys-utils/lsirq.1.adoc | 3 +++ sys-utils/lsirq.c | 24 ++++++++++++++++++++---- 6 files changed, 48 insertions(+), 17 deletions(-) diff --git a/bash-completion/lsirq b/bash-completion/lsirq index 4c3c9f04f..b913eecd0 100644 --- a/bash-completion/lsirq +++ b/bash-completion/lsirq @@ -5,6 +5,9 @@ _lsirq_module() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" case $prev in + '-i'|'--input') + COMPREPLY=( $(compgen -W "input file" -- $cur) ) + ;; '-o'|'--output') local prefix realcur OUTPUT realcur="${cur##*,}" @@ -35,6 +38,7 @@ _lsirq_module() OPTS=" --json --pairs --noheadings + --input --output --softirq --sort diff --git a/sys-utils/irq-common.c b/sys-utils/irq-common.c index f069d8a63..560dd4b82 100644 --- a/sys-utils/irq-common.c +++ b/sys-utils/irq-common.c @@ -233,7 +233,8 @@ static bool cpu_in_list(int cpu, size_t setsize, cpu_set_t *cpuset) /* * irqinfo - parse the system's interrupts */ -static struct irq_stat *get_irqinfo(int softirq, size_t setsize, cpu_set_t *cpuset) +static struct irq_stat *get_irqinfo(const char *input_file, int softirq, + size_t setsize, cpu_set_t *cpuset) { FILE *irqfile; char *line = NULL, *tmp; @@ -247,18 +248,15 @@ static struct irq_stat *get_irqinfo(int softirq, size_t setsize, cpu_set_t *cpus stat->irq_info = xmalloc(sizeof(*stat->irq_info) * IRQ_INFO_LEN); stat->nr_irq_info = IRQ_INFO_LEN; - if (softirq) - irqfile = fopen(_PATH_PROC_SOFTIRQS, "r"); - else - irqfile = fopen(_PATH_PROC_INTERRUPTS, "r"); + irqfile = fopen(input_file, "r"); if (!irqfile) { - warn(_("cannot open %s"), _PATH_PROC_INTERRUPTS); + warn(_("cannot open %s"), input_file); goto free_stat; } /* read header firstly */ if (getline(&line, &len, irqfile) < 0) { - warn(_("cannot read %s"), _PATH_PROC_INTERRUPTS); + warn(_("cannot read %s"), input_file); goto close_file; } @@ -270,7 +268,7 @@ static struct irq_stat *get_irqinfo(int softirq, size_t setsize, cpu_set_t *cpus stat->cpus = xcalloc(stat->nr_active_cpu, sizeof(struct irq_cpu)); - /* parse each line of _PATH_PROC_INTERRUPTS */ + /* parse each line of input file */ while (getline(&line, &len, irqfile) >= 0) { unsigned long count; size_t index; @@ -527,7 +525,8 @@ struct libscols_table *get_scols_cpus_table(struct irq_output *out, return NULL; } -struct libscols_table *get_scols_table(struct irq_output *out, +struct libscols_table *get_scols_table(const char *input_file, + struct irq_output *out, struct irq_stat *prev, struct irq_stat **xstat, int softirq, @@ -542,7 +541,7 @@ struct libscols_table *get_scols_table(struct irq_output *out, size_t i; /* the stats */ - stat = get_irqinfo(softirq, setsize, cpuset); + stat = get_irqinfo(input_file, softirq, setsize, cpuset); if (!stat) return NULL; diff --git a/sys-utils/irq-common.h b/sys-utils/irq-common.h index 02b72d752..b9cf72d2a 100644 --- a/sys-utils/irq-common.h +++ b/sys-utils/irq-common.h @@ -73,7 +73,8 @@ void irq_print_columns(FILE *f, int nodelta); void set_sort_func_by_name(struct irq_output *out, const char *name); void set_sort_func_by_key(struct irq_output *out, const char c); -struct libscols_table *get_scols_table(struct irq_output *out, +struct libscols_table *get_scols_table(const char *input_file, + struct irq_output *out, struct irq_stat *prev, struct irq_stat **xstat, int softirq, diff --git a/sys-utils/irqtop.c b/sys-utils/irqtop.c index 48b65201f..6d001cb10 100644 --- a/sys-utils/irqtop.c +++ b/sys-utils/irqtop.c @@ -130,10 +130,18 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out) struct irq_stat *stat; time_t now = time(NULL); char timestr[64], *data, *data0, *p; + char *input_file; /* make irqs table */ - table = get_scols_table(out, ctl->prev_stat, &stat, ctl->softirq, - ctl->threshold, ctl->setsize, ctl->cpuset); + if (ctl->softirq) + input_file = xstrdup(_PATH_PROC_SOFTIRQS); + else + input_file = xstrdup(_PATH_PROC_INTERRUPTS); + + table = get_scols_table(input_file, out, ctl->prev_stat, &stat, + ctl->softirq, ctl->threshold, ctl->setsize, + ctl->cpuset); + free(input_file); if (!table) { ctl->request_exit = 1; return 1; diff --git a/sys-utils/lsirq.1.adoc b/sys-utils/lsirq.1.adoc index 02aea16b3..dd265710c 100644 --- a/sys-utils/lsirq.1.adoc +++ b/sys-utils/lsirq.1.adoc @@ -25,6 +25,9 @@ The default output is subject to change. So whenever possible, you should avoid *-n*, *--noheadings*:: Don't print headings. +*-i*, *--input* _file_:: +Read data from _file_ (Which was created by other tools, e.g. sosreport). + *-o*, *--output* _list_:: Specify which output columns to print. Use *--help* to get a list of all supported columns. The default list of columns may be extended if list is specified in the format _+list_. diff --git a/sys-utils/lsirq.c b/sys-utils/lsirq.c index e31addaf5..fa2dcaaf3 100644 --- a/sys-utils/lsirq.c +++ b/sys-utils/lsirq.c @@ -29,16 +29,17 @@ #include "optutils.h" #include "strutils.h" #include "xalloc.h" +#include "pathnames.h" #include "irq-common.h" -static int print_irq_data(struct irq_output *out, +static int print_irq_data(const char *input_file, struct irq_output *out, int softirq, unsigned long threshold, size_t setsize, cpu_set_t *cpuset) { struct libscols_table *table; - table = get_scols_table(out, NULL, NULL, softirq, threshold, setsize, cpuset); + table = get_scols_table(input_file, out, NULL, NULL, softirq, threshold, setsize, cpuset); if (!table) return -1; @@ -58,6 +59,7 @@ static void __attribute__((__noreturn__)) usage(void) fputs(USAGE_OPTIONS, stdout); fputs(_(" -J, --json use JSON output format\n"), stdout); fputs(_(" -P, --pairs use key=\"value\" output format\n"), stdout); + fputs(_(" -i, --input read data from input file\n"), stdout); fputs(_(" -n, --noheadings don't print headings\n"), stdout); fputs(_(" -o, --output define which output columns to use\n"), stdout); fputs(_(" -s, --sort specify sort column\n"), stdout); @@ -82,6 +84,7 @@ int main(int argc, char **argv) static const struct option longopts[] = { {"sort", required_argument, NULL, 's'}, {"noheadings", no_argument, NULL, 'n'}, + {"input", required_argument, NULL, 'i'}, {"output", required_argument, NULL, 'o'}, {"threshold", required_argument, NULL, 't'}, {"cpu-list", required_argument, NULL, 'C'}, @@ -103,10 +106,11 @@ int main(int argc, char **argv) cpu_set_t *cpuset = NULL; size_t setsize = 0; int softirq = 0; + char *input_file = NULL; setlocale(LC_ALL, ""); - while ((c = getopt_long(argc, argv, "no:s:t:C:ShJPV", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "i:no:s:t:C:ShJPV", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); switch (c) { @@ -116,6 +120,9 @@ int main(int argc, char **argv) case 'P': out.pairs = 1; break; + case 'i': + input_file = xstrdup(optarg); + break; case 'n': out.no_headings = 1; break; @@ -157,6 +164,13 @@ int main(int argc, char **argv) } } + if (input_file == NULL) { + if (softirq == 1) + input_file = xstrdup(_PATH_PROC_SOFTIRQS); + else + input_file = xstrdup(_PATH_PROC_INTERRUPTS); + } + /* default */ if (!out.ncolumns) { out.columns[out.ncolumns++] = COL_IRQ; @@ -171,8 +185,10 @@ int main(int argc, char **argv) irq_column_name_to_id) < 0) exit(EXIT_FAILURE); - if (print_irq_data(&out, softirq, threshold, setsize, cpuset) < 0) + if (print_irq_data(input_file, &out, softirq, threshold, setsize, cpuset) < 0) return EXIT_FAILURE; + free(input_file); + return EXIT_SUCCESS; } -- 2.47.2