[PATCH 3/3] lsirq,irqtop: add support for reading data from given file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is helpful for analyzng data saved from other system.

Signed-off-by: Joe Jin <joe.jin@xxxxxxxxxx>
Cc: Zhenwei Pi <pizhenwei@xxxxxxxxxxxxx>
Cc: Sami Kerola <kerolasa@xxxxxx>
---
 bash-completion/irqtop  |  4 ++++
 bash-completion/lsirq   |  4 ++++
 sys-utils/irq-common.c  | 19 +++++++++----------
 sys-utils/irq-common.h  |  3 ++-
 sys-utils/irqtop.1.adoc |  3 +++
 sys-utils/irqtop.c      | 28 +++++++++++++++++++++++++---
 sys-utils/lsirq.1.adoc  |  3 +++
 sys-utils/lsirq.c       | 28 ++++++++++++++++++++++++----
 8 files changed, 74 insertions(+), 18 deletions(-)

diff --git a/bash-completion/irqtop b/bash-completion/irqtop
index 47b7b0af6..3bea5fc0e 100644
--- a/bash-completion/irqtop
+++ b/bash-completion/irqtop
@@ -15,6 +15,9 @@ _irqtop_module()
 		'-C'|'--cpu-list')
 			return 0
 			;;
+		'-i'|'--input')
+			COMPREPLY=( $(compgen -W "input file" -- $cur) )
+			;;
 		'-t'|'--threshold')
 			return 0
 			;;
@@ -51,6 +54,7 @@ _irqtop_module()
 		--cpu-stat
 		--cpu-list
 		--delay
+		--input
 		--number
 		--sort
 		--output
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.1.adoc b/sys-utils/irqtop.1.adoc
index 75cfe2e41..715008d07 100644
--- a/sys-utils/irqtop.1.adoc
+++ b/sys-utils/irqtop.1.adoc
@@ -37,6 +37,9 @@ Specify cpus in list format to show.
 *-d*, *--delay* _seconds_::
 Update interrupt output every _seconds_ intervals.
 
+*-i*, *--input* _file_::
+Read data from _file_ (Which was created by other tools, e.g. sosreport).
+
 *-n*, *--number* _number_::
 Specifies the maximum _number_ of iterations before quitting.
 
diff --git a/sys-utils/irqtop.c b/sys-utils/irqtop.c
index ba5680671..4cf1dc79a 100644
--- a/sys-utils/irqtop.c
+++ b/sys-utils/irqtop.c
@@ -87,6 +87,8 @@ struct irqtop_ctl {
 	bool	batch;
 	bool	request_exit,
 		softirq;
+
+	char	*input;
 };
 
 #define irqtop_batch_mode(ctl) ((ctl)->batch == true)
@@ -122,8 +124,9 @@ static int update_screen(struct irqtop_ctl *ctl, struct irq_output *out)
 	char timestr[64], *data, *data0, *p;
 
 	/* make irqs table */
-	table = get_scols_table(out, ctl->prev_stat, &stat, ctl->softirq,
-				ctl->threshold, ctl->setsize, ctl->cpuset);
+	table = get_scols_table(ctl->input, out, ctl->prev_stat, &stat,
+				ctl->softirq, ctl->threshold, ctl->setsize,
+				ctl->cpuset);
 	if (!table) {
 		ctl->request_exit = 1;
 		return 1;
@@ -292,6 +295,7 @@ static void __attribute__((__noreturn__)) usage(void)
 	fputs(_(" -c, --cpu-stat <mode> show per-cpu stat (auto, enable, disable)\n"), stdout);
 	fputs(_(" -C, --cpu-list <list> specify cpus in list format\n"), stdout);
 	fputs(_(" -d, --delay <secs>   delay updates\n"), stdout);
+	fputs(_(" -i, --input <file>   read data from file\n"), stdout);
 	fputs(_(" -n, --number <number> the maximum number of iterations\n"), stdout);
 	fputs(_(" -o, --output <list>  define which output columns to use\n"), stdout);
 	fputs(_(" -s, --sort <column>  specify sort column\n"), stdout);
@@ -325,6 +329,7 @@ static void parse_args(	struct irqtop_ctl *ctl,
 		{"cpu-stat", required_argument, NULL, 'c'},
 		{"cpu-list", required_argument, NULL, 'C'},
 		{"delay", required_argument, NULL, 'd'},
+		{"input", required_argument, NULL, 'i'},
 		{"number", required_argument, NULL, 'n'},
 		{"sort", required_argument, NULL, 's'},
 		{"output", required_argument, NULL, 'o'},
@@ -336,7 +341,7 @@ static void parse_args(	struct irqtop_ctl *ctl,
 	};
 	int o;
 
-	while ((o = getopt_long(argc, argv, "bc:C:d:n:o:s:St:hV", longopts, NULL)) != -1) {
+	while ((o = getopt_long(argc, argv, "bc:C:d:i:n:o:s:St:hV", longopts, NULL)) != -1) {
 		switch (o) {
 		case 'b':
 			ctl->batch = true;
@@ -376,6 +381,13 @@ static void parse_args(	struct irqtop_ctl *ctl,
 				ctl->timer.it_value = ctl->timer.it_interval;
 			}
 			break;
+		case 'i':
+			ctl->input = strdup(optarg);
+			if (!ctl->input)
+				err_oom();
+			ctl->number = 1;
+			ctl->batch = true;
+			break;
 		case 'n':
 			ctl->number = str2num_or_err(optarg, 10,
 					_("failed to parse number argument"),
@@ -402,6 +414,15 @@ static void parse_args(	struct irqtop_ctl *ctl,
 		}
 	}
 
+	if (ctl->input == NULL) {
+		if (ctl->softirq == 1)
+			ctl->input = strdup(_PATH_PROC_SOFTIRQS);
+		else
+			ctl->input = strdup(_PATH_PROC_INTERRUPTS);
+		if (!ctl->input)
+			err_oom();
+	}
+
 	/* default */
 	if (!out->ncolumns) {
 		out->columns[out->ncolumns++] = COL_IRQ;
@@ -453,6 +474,7 @@ int main(int argc, char **argv)
 
 	free_irqstat(ctl.prev_stat);
 	free(ctl.hostname);
+	free(ctl.input);
 	cpuset_free(ctl.cpuset);
 
 	if (ctl.batch == false) {
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..45d542919 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 = 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,11 @@ int main(int argc, char **argv)
 		case 'P':
 			out.pairs = 1;
 			break;
+		case 'i':
+			input = strdup(optarg);
+			if (!input)
+				err_oom();
+			break;
 		case 'n':
 			out.no_headings = 1;
 			break;
@@ -157,6 +166,15 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if (input == NULL) {
+		if (softirq == 1)
+			input = strdup(_PATH_PROC_SOFTIRQS);
+		else
+			input = strdup(_PATH_PROC_INTERRUPTS);
+		if (!input)
+			err_oom();
+	}
+
 	/* default */
 	if (!out.ncolumns) {
 		out.columns[out.ncolumns++] = COL_IRQ;
@@ -171,8 +189,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, &out, softirq, threshold, setsize, cpuset) < 0)
 		return EXIT_FAILURE;
 
+	free(input);
+
 	return EXIT_SUCCESS;
 }
-- 
2.43.5





[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux