]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsirq: add support for reading data from given file
authorJoe Jin <joe.jin@oracle.com>
Fri, 28 Feb 2025 16:13:34 +0000 (08:13 -0800)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Mar 2025 08:26:20 +0000 (09:26 +0100)
This is helpful for analyzng data saved from other system.

Signed-off-by: Joe Jin <joe.jin@oracle.com>
Cc: Zhenwei Pi <pizhenwei@bytedance.com>
Cc: Sami Kerola <kerolasa@iki.fi>
Cc: Karel Zak <kzak@redhat.com>
bash-completion/lsirq
sys-utils/irq-common.c
sys-utils/irq-common.h
sys-utils/irqtop.c
sys-utils/lsirq.1.adoc
sys-utils/lsirq.c

index 4c3c9f04fa2bbb2fd51f828533d5133f15f7727d..b913eecd0b89869eb5614837ba55b3c09e9d4c77 100644 (file)
@@ -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
index f069d8a631ffe9add8435df847525148803f5fb1..560dd4b82715f3e6f32a0929e7a0a64b1c543609 100644 (file)
@@ -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;
 
index 02b72d75230a289f6af64e88d7a3770955e749de..b9cf72d2a3c78a78e7db883068802957b16b79d9 100644 (file)
@@ -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,
index 48b65201fba7a0395bbd2c6cc1a78073e9ba5f9e..6d001cb10afab9f6c7198faf22adb03989f3a3b8 100644 (file)
@@ -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;
index 02aea16b31fcc9368fe65cf9929b840235fdfa9a..dd265710cc68f2881c91f448dc154101a012fd50 100644 (file)
@@ -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_.
 
index e31addaf595ec57e43a085555638be66719cf368..fa2dcaaf30f78ecc7aaf5a93afc9ec245f119f3b 100644 (file)
 #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 <list>  define which output columns to use\n"), stdout);
        fputs(_(" -s, --sort <column>  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;
 }