From: Joe Jin <joe.jin@oracle.com>
To: Karel Zak <kzak@redhat.com>, Zhenwei Pi <pizhenwei@bytedance.com>,
Sami Kerola <kerolasa@iki.fi>
Cc: util-linux@vger.kernel.org, Joe Jin <joe.jin@oracle.com>
Subject: [PATCH V2 4/4] lsirq: add support for reading data from given file
Date: Fri, 28 Feb 2025 08:13:34 -0800 [thread overview]
Message-ID: <20250228161334.82987-5-joe.jin@oracle.com> (raw)
In-Reply-To: <20250228161334.82987-1-joe.jin@oracle.com>
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 | 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 <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;
}
--
2.43.5
next prev parent reply other threads:[~2025-02-28 16:14 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-28 16:13 [PATCH V2 0/4] irqtop,lsirq: Miscellaneous enhancements Joe Jin
2025-02-28 16:13 ` [PATCH V2 1/4] irqtop: add batch mode support Joe Jin
2025-02-28 16:13 ` [PATCH V2 2/4] irqtop: add max iteration support Joe Jin
2025-03-03 9:39 ` zhenwei pi
2025-03-04 1:39 ` Joe Jin
2025-03-04 3:49 ` zhenwei pi
2025-02-28 16:13 ` [PATCH V2 3/4] irqtop: support json output format Joe Jin
2025-02-28 16:13 ` Joe Jin [this message]
2025-03-03 10:16 ` [PATCH V2 0/4] irqtop,lsirq: Miscellaneous enhancements Karel Zak
2025-03-04 1:38 ` Joe Jin
2025-03-04 3:50 ` zhenwei pi
2025-03-04 10:58 ` Karel Zak
2025-03-05 2:23 ` Joe Jin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250228161334.82987-5-joe.jin@oracle.com \
--to=joe.jin@oracle.com \
--cc=kerolasa@iki.fi \
--cc=kzak@redhat.com \
--cc=pizhenwei@bytedance.com \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox