From 91a59a187c384ecdacea212cc492ffa18fb66b3f Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sat, 17 Aug 2019 10:07:47 +0200 Subject: [PATCH] simtest: Add non regression test for sar forward compatibility This test makes sure that an old sar version (here, 12.0.1) can still read a binary data file created by latest up-to-date sar version. Signed-off-by: Sebastien GODARD --- .gitignore | 1 + Makefile.in | 34 +- tests/00750 | 1 + tests/00752 | 1 + tests/12.0.1/activity.c | 1903 +++++++++++++++++ tests/12.0.1/common.c | 1437 +++++++++++++ tests/12.0.1/common.h | 298 +++ tests/12.0.1/count.c | 266 +++ tests/12.0.1/format.c | 48 + tests/12.0.1/inisar.c | 1088 ++++++++++ tests/12.0.1/ioconf.c | 533 +++++ tests/12.0.1/ioconf.h | 92 + tests/12.0.1/pr_stats.c | 3004 ++++++++++++++++++++++++++ tests/12.0.1/pr_stats.h | 124 ++ tests/12.0.1/rd_sensors.h | 85 + tests/12.0.1/rd_stats.c | 2650 +++++++++++++++++++++++ tests/12.0.1/rd_stats.h | 790 +++++++ tests/12.0.1/sa.h | 1386 ++++++++++++ tests/12.0.1/sa_common.c | 3094 +++++++++++++++++++++++++++ tests/TLIST | 6 + tests/expected.data-ini | 4192 +++++++++++++++++++++++++++++++++++++ tests/ini | 1 + 22 files changed, 21032 insertions(+), 2 deletions(-) create mode 100644 tests/00750 create mode 100644 tests/00752 create mode 100644 tests/12.0.1/activity.c create mode 100644 tests/12.0.1/common.c create mode 100644 tests/12.0.1/common.h create mode 100644 tests/12.0.1/count.c create mode 100644 tests/12.0.1/format.c create mode 100644 tests/12.0.1/inisar.c create mode 100644 tests/12.0.1/ioconf.c create mode 100644 tests/12.0.1/ioconf.h create mode 100644 tests/12.0.1/pr_stats.c create mode 100644 tests/12.0.1/pr_stats.h create mode 100644 tests/12.0.1/rd_sensors.h create mode 100644 tests/12.0.1/rd_stats.c create mode 100644 tests/12.0.1/rd_stats.h create mode 100644 tests/12.0.1/sa.h create mode 100644 tests/12.0.1/sa_common.c create mode 100644 tests/expected.data-ini create mode 120000 tests/ini diff --git a/.gitignore b/.gitignore index 42ed565..170e802 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ nls/*.gmo tests/*.tmp tests/sa[012]* tests/variables +inisar diff --git a/Makefile.in b/Makefile.in index d0da2a5..799824a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -299,6 +299,32 @@ cifsiostat.o: cifsiostat.c cifsiostat.h count.h rd_stats.h version.h common.h cifsiostat: cifsiostat.o librdstats_light.a libsyscom.a +tests/ini/sa_common.o: tests/ini/sa_common.c tests/ini/version.h tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/ioconf.h tests/ini/sysconfig.h + +tests/ini/act_sar.o: tests/ini/activity.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/pr_stats.h + $(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $< + +tests/ini/rd_stats_light.o: tests/ini/rd_stats.c tests/ini/common.h tests/ini/rd_stats.h tests/ini/ioconf.h tests/ini/sysconfig.h + $(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $< + +tests/ini/count_light.o: tests/ini/count.c tests/ini/common.h tests/ini/rd_stats.h + $(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $< + +tests/ini/libsyscom.a: tests/ini/common.o tests/ini/ioconf.o + $(AR) rvs $@ $? + +tests/ini/format_sar.o: tests/ini/format.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h + $(CC) -o $@ -c $(CFLAGS) -DSOURCE_SAR $(DFLAGS) $< + +tests/ini/pr_stats.o: tests/ini/pr_stats.c tests/ini/sa.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h tests/ini/ioconf.h tests/ini/sysconfig.h tests/ini/pr_stats.h + +tests/ini/librdstats_light.a: tests/ini/rd_stats_light.o tests/ini/count_light.o + $(AR) rvs $@ $? + +tests/ini/inisar.o: tests/ini/inisar.c tests/ini/sa.h tests/ini/version.h tests/ini/common.h tests/ini/rd_stats.h tests/ini/rd_sensors.h + +tests/ini/inisar: tests/ini/inisar.o tests/ini/act_sar.o tests/ini/format_sar.o tests/ini/sa_common.o tests/ini/pr_stats.o tests/ini/librdstats_light.a tests/ini/libsyscom.a + ifdef REQUIRE_NLS locales: $(NLSGMO) else @@ -310,7 +336,7 @@ nls/sysstat.pot: $(wildcard *.c) # Phony targets .PHONY: clean distclean install install_base install_all uninstall \ - uninstall_base uninstall_all dist bdist xdist gitdist squeeze test simtest + uninstall_base uninstall_all dist bdist xdist gitdist squeeze simtest install_man: man/sadc.8 man/sar.1 man/sadf.1 man/sa1.8 man/sa2.8 man/sysstat.5 ifeq ($(INSTALL_DOC),y) @@ -599,11 +625,13 @@ TESTDIR="tests" TESTRUN="/bin/sh" TESTLIST:=$(shell ls $(TESTDIR) | egrep '^[0-9]+$$' | sort -n) +testcomp: tests/ini/inisar + unit: @echo $(X) 2>&1 @cat $(TESTDIR)/$(X) | $(TESTRUN) -simtest: all +simtest: all testcomp @$(foreach x, $(TESTLIST), $(MAKE) X=$x unit || exit;) rm -f tests/root ln -s root1 tests/root @@ -614,6 +642,8 @@ clean: rm -f tests/sa[012]* rm -f tests/root ln -s root1 tests/root + rm -f tests/ini/inisar + rm -f tests/ini/*.o tests/ini/*.a tests/ini/core find nls -name "*.gmo" -exec rm -f {} \; almost-distclean: clean nls/sysstat.pot diff --git a/tests/00750 b/tests/00750 new file mode 100644 index 0000000..14c4e03 --- /dev/null +++ b/tests/00750 @@ -0,0 +1 @@ +LC_ALL=C TZ=GMT ./tests/ini/inisar -C -A -f tests/data.tmp > tests/out.data-ini.tmp diff --git a/tests/00752 b/tests/00752 new file mode 100644 index 0000000..77fa785 --- /dev/null +++ b/tests/00752 @@ -0,0 +1 @@ +diff -u tests/out.data-ini.tmp tests/expected.data-ini diff --git a/tests/12.0.1/activity.c b/tests/12.0.1/activity.c new file mode 100644 index 0000000..1cc3b22 --- /dev/null +++ b/tests/12.0.1/activity.c @@ -0,0 +1,1903 @@ +/* + * activity.c: Define system activities available for sar/sadc. + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include "sa.h" + +#ifdef SOURCE_SAR +#include "pr_stats.h" +#endif + +#ifdef SOURCE_SADF +#include "rndr_stats.h" +#include "xml_stats.h" +#include "json_stats.h" +#include "svg_stats.h" +#include "raw_stats.h" +#endif + +/* + *************************************************************************** + * Definitions of system activities. + * See sa.h file for activity structure definition. + * Activity structure doesn't matter for daily data files. + *************************************************************************** + */ + +/* + * Bitmaps needed by activities. + * Remember to allocate them before use! + */ + +/* CPU bitmap */ +struct act_bitmap cpu_bitmap = { + .b_array = NULL, + .b_size = NR_CPUS +}; + +/* Interrupts bitmap */ +struct act_bitmap irq_bitmap = { + .b_array = NULL, + .b_size = NR_IRQS +}; + + +/* + * CPU statistics. + * This is the only activity which *must* be collected by sadc + * so that uptime can be filled. + */ +struct activity cpu_act = { + .id = A_CPU, + .options = AO_COLLECTED + AO_COUNTED + AO_PERSISTENT + + AO_MULTIPLE_OUTPUTS + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = 0, /* wrap_get_cpu_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_stat_cpu, +#endif +#ifdef SOURCE_SAR + .f_print = print_cpu_stats, + .f_print_avg = print_cpu_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "CPU;%user;%nice;%system;%iowait;%steal;%idle|" + "CPU;%usr;%nice;%sys;%iowait;%steal;%irq;%soft;%guest;%gnice;%idle", +#endif + .gtypes_nr = {STATS_CPU_ULL, STATS_CPU_UL, STATS_CPU_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_cpu_stats, + .f_xml_print = xml_print_cpu_stats, + .f_json_print = json_print_cpu_stats, + .f_svg_print = svg_print_cpu_stats, + .f_raw_print = raw_print_cpu_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "CPU utilization", +#endif + .name = "A_CPU", + .item_list_sz = 0, + .g_nr = 1, + .nr_ini = -1, + .nr2 = 1, + .nr_max = NR_CPUS + 1, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_CPU_SIZE, + .msize = STATS_CPU_SIZE, + .opt_flags = AO_F_CPU_DEF, + .buf = {NULL, NULL, NULL}, + .bitmap = &cpu_bitmap +}; + +/* Process (task) creation and context switch activity */ +struct activity pcsw_act = { + .id = A_PCSW, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_stat_pcsw, +#endif +#ifdef SOURCE_SAR + .f_print = print_pcsw_stats, + .f_print_avg = print_pcsw_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "proc/s;cswch/s", +#endif + .gtypes_nr = {STATS_PCSW_ULL, STATS_PCSW_UL, STATS_PCSW_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pcsw_stats, + .f_xml_print = xml_print_pcsw_stats, + .f_json_print = json_print_pcsw_stats, + .f_svg_print = svg_print_pcsw_stats, + .f_raw_print = raw_print_pcsw_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Task creation and switching activity", +#endif + .name = "A_PCSW", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_PCSW_SIZE, + .msize = STATS_PCSW_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Interrupts statistics */ +struct activity irq_act = { + .id = A_IRQ, + .options = AO_COUNTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_INT, +#ifdef SOURCE_SADC + .f_count_index = 1, /* wrap_get_irq_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_stat_irq, +#endif +#ifdef SOURCE_SAR + .f_print = print_irq_stats, + .f_print_avg = print_irq_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "INTR;intr/s", +#endif + .gtypes_nr = {STATS_IRQ_ULL, STATS_IRQ_UL, STATS_IRQ_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_irq_stats, + .f_xml_print = xml_print_irq_stats, + .f_json_print = json_print_irq_stats, + .f_svg_print = NULL, + .f_raw_print = raw_print_irq_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Interrupts statistics", +#endif + .name = "A_IRQ", + .item_list_sz = 0, + .g_nr = 0, + .nr_ini = -1, + .nr2 = 1, + .nr_max = NR_IRQS + 1, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_IRQ_SIZE, + .msize = STATS_IRQ_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = &irq_bitmap +}; + +/* Swapping activity */ +struct activity swap_act = { + .id = A_SWAP, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_swap, +#endif +#ifdef SOURCE_SAR + .f_print = print_swap_stats, + .f_print_avg = print_swap_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "pswpin/s;pswpout/s", +#endif + .gtypes_nr = {STATS_SWAP_ULL, STATS_SWAP_UL, STATS_SWAP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_swap_stats, + .f_xml_print = xml_print_swap_stats, + .f_json_print = json_print_swap_stats, + .f_svg_print = svg_print_swap_stats, + .f_raw_print = raw_print_swap_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Swap activity", +#endif + .name = "A_SWAP", + .item_list_sz = 0, + .g_nr = 1, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_SWAP_SIZE, + .msize = STATS_SWAP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Paging activity */ +struct activity paging_act = { + .id = A_PAGE, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_paging, +#endif +#ifdef SOURCE_SAR + .f_print = print_paging_stats, + .f_print_avg = print_paging_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "pgpgin/s;pgpgout/s;fault/s;majflt/s;" + "pgfree/s;pgscank/s;pgscand/s;pgsteal/s;%vmeff", +#endif + .gtypes_nr = {STATS_PAGING_ULL, STATS_PAGING_UL, STATS_PAGING_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_paging_stats, + .f_xml_print = xml_print_paging_stats, + .f_json_print = json_print_paging_stats, + .f_svg_print = svg_print_paging_stats, + .f_raw_print = raw_print_paging_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Paging activity", +#endif + .name = "A_PAGE", + .item_list_sz = 0, + .g_nr = 3, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_PAGING_SIZE, + .msize = STATS_PAGING_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* I/O and transfer rate activity */ +struct activity io_act = { + .id = A_IO, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_io, +#endif +#ifdef SOURCE_SAR + .f_print = print_io_stats, + .f_print_avg = print_io_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "tps;rtps;wtps;bread/s;bwrtn/s", +#endif + .gtypes_nr = {STATS_IO_ULL, STATS_IO_UL, STATS_IO_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_io_stats, + .f_xml_print = xml_print_io_stats, + .f_json_print = json_print_io_stats, + .f_svg_print = svg_print_io_stats, + .f_raw_print = raw_print_io_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "I/O and transfer rate statistics", +#endif + .name = "A_IO", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_IO_SIZE, + .msize = STATS_IO_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Memory and swap space utilization activity */ +struct activity memory_act = { + .id = A_MEMORY, + .options = AO_COLLECTED + AO_MULTIPLE_OUTPUTS, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_meminfo, +#endif +#ifdef SOURCE_SAR + .f_print = print_memory_stats, + .f_print_avg = print_avg_memory_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "kbmemfree;kbavail;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact;kbdirty&kbanonpg;kbslab;kbkstack;kbpgtbl;kbvmused|" + "kbswpfree;kbswpused;%swpused;kbswpcad;%swpcad", +#endif + .gtypes_nr = {STATS_MEMORY_ULL, STATS_MEMORY_UL, STATS_MEMORY_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_memory_stats, + .f_xml_print = xml_print_memory_stats, + .f_json_print = json_print_memory_stats, + .f_svg_print = svg_print_memory_stats, + .f_raw_print = raw_print_memory_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Memory and/or swap utilization", +#endif + .name = "A_MEMORY", + .item_list_sz = 0, + .g_nr = 9, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_MEMORY_SIZE, + .msize = STATS_MEMORY_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Kernel tables activity */ +struct activity ktables_act = { + .id = A_KTABLES, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_kernel_tables, +#endif +#ifdef SOURCE_SAR + .f_print = print_ktables_stats, + .f_print_avg = print_avg_ktables_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "dentunusd;file-nr;inode-nr;pty-nr", +#endif + .gtypes_nr = {STATS_KTABLES_ULL, STATS_KTABLES_UL, STATS_KTABLES_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_ktables_stats, + .f_xml_print = xml_print_ktables_stats, + .f_json_print = json_print_ktables_stats, + .f_svg_print = svg_print_ktables_stats, + .f_raw_print = raw_print_ktables_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Kernel tables statistics", +#endif + .name = "A_KTABLES", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_KTABLES_SIZE, + .msize = STATS_KTABLES_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Queue and load activity */ +struct activity queue_act = { + .id = A_QUEUE, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_loadavg, +#endif +#ifdef SOURCE_SAR + .f_print = print_queue_stats, + .f_print_avg = print_avg_queue_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "runq-sz;plist-sz;ldavg-1;ldavg-5;ldavg-15;blocked", +#endif + .gtypes_nr = {STATS_QUEUE_ULL, STATS_QUEUE_UL, STATS_QUEUE_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_queue_stats, + .f_xml_print = xml_print_queue_stats, + .f_json_print = json_print_queue_stats, + .f_svg_print = svg_print_queue_stats, + .f_raw_print = raw_print_queue_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Queue length and load average statistics", +#endif + .name = "A_QUEUE", + .item_list_sz = 0, + .g_nr = 3, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_QUEUE_SIZE, + .msize = STATS_QUEUE_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Serial lines activity */ +struct activity serial_act = { + .id = A_SERIAL, + .options = AO_COLLECTED + AO_COUNTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = 2, /* wrap_get_serial_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_tty_driver_serial, +#endif +#ifdef SOURCE_SAR + .f_print = print_serial_stats, + .f_print_avg = print_serial_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "TTY;rcvin/s;txmtin/s;framerr/s;prtyerr/s;brk/s;ovrun/s", +#endif + .gtypes_nr = {STATS_SERIAL_ULL, STATS_SERIAL_UL, STATS_SERIAL_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_serial_stats, + .f_xml_print = xml_print_serial_stats, + .f_json_print = json_print_serial_stats, + .f_svg_print = NULL, + .f_raw_print = raw_print_serial_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "TTY devices statistics", +#endif + .name = "A_SERIAL", + .item_list_sz = 0, + .g_nr = 0, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_SERIAL_LINES, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_SERIAL_SIZE, + .msize = STATS_SERIAL_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Block devices activity */ +struct activity disk_act = { + .id = A_DISK, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_DISK, +#ifdef SOURCE_SADC + .f_count_index = 3, /* wrap_get_disk_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_disk, +#endif +#ifdef SOURCE_SAR + .f_print = print_disk_stats, + .f_print_avg = print_disk_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "DEV;tps;rkB/s;wkB/s;areq-sz;aqu-sz;await;svctm;%util", +#endif + .gtypes_nr = {STATS_DISK_ULL, STATS_DISK_UL, STATS_DISK_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_disk_stats, + .f_xml_print = xml_print_disk_stats, + .f_json_print = json_print_disk_stats, + .f_svg_print = svg_print_disk_stats, + .f_raw_print = raw_print_disk_stats, + .f_count_new = count_new_disk, + .item_list = NULL, + .desc = "Block devices statistics", +#endif + .name = "A_DISK", + .item_list_sz = 0, + .g_nr = 5, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_DISKS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_DISK_SIZE, + .msize = STATS_DISK_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Network interfaces activity */ +struct activity net_dev_act = { + .id = A_NET_DEV, + .options = AO_COLLECTED + AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE + 3, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = 4, /* wrap_get_iface_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_net_dev, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_dev_stats, + .f_print_avg = print_net_dev_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "IFACE;rxpck/s;txpck/s;rxkB/s;txkB/s;rxcmp/s;txcmp/s;rxmcst/s;%ifutil", +#endif + .gtypes_nr = {STATS_NET_DEV_ULL, STATS_NET_DEV_UL, STATS_NET_DEV_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_dev_stats, + .f_xml_print = xml_print_net_dev_stats, + .f_json_print = json_print_net_dev_stats, + .f_svg_print = svg_print_net_dev_stats, + .f_raw_print = raw_print_net_dev_stats, + .f_count_new = count_new_net_dev, + .item_list = NULL, + .desc = "Network interfaces statistics", +#endif + .name = "A_NET_DEV", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_IFACES, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_NET_DEV_SIZE, + .msize = STATS_NET_DEV_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Network interfaces (errors) activity */ +struct activity net_edev_act = { + .id = A_NET_EDEV, + .options = AO_COLLECTED + AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = 4, /* wrap_get_iface_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_net_edev, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_edev_stats, + .f_print_avg = print_net_edev_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "IFACE;rxerr/s;txerr/s;coll/s;rxdrop/s;txdrop/s;" + "txcarr/s;rxfram/s;rxfifo/s;txfifo/s", +#endif + .gtypes_nr = {STATS_NET_EDEV_ULL, STATS_NET_EDEV_UL, STATS_NET_EDEV_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_edev_stats, + .f_xml_print = xml_print_net_edev_stats, + .f_json_print = json_print_net_edev_stats, + .f_svg_print = svg_print_net_edev_stats, + .f_raw_print = raw_print_net_edev_stats, + .f_count_new = count_new_net_edev, + .item_list = NULL, + .desc = "Network interfaces errors statistics", +#endif + .name = "A_NET_EDEV", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_IFACES, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_NET_EDEV_SIZE, + .msize = STATS_NET_EDEV_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* NFS client activity */ +struct activity net_nfs_act = { + .id = A_NET_NFS, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_nfs, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_nfs_stats, + .f_print_avg = print_net_nfs_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "call/s;retrans/s;read/s;write/s;access/s;getatt/s", +#endif + .gtypes_nr = {STATS_NET_NFS_ULL, STATS_NET_NFS_UL, STATS_NET_NFS_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_nfs_stats, + .f_xml_print = xml_print_net_nfs_stats, + .f_json_print = json_print_net_nfs_stats, + .f_svg_print = svg_print_net_nfs_stats, + .f_raw_print = raw_print_net_nfs_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "NFS client statistics", +#endif + .name = "A_NET_NFS", + .item_list_sz = 0, + .g_nr = 3, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_NFS_SIZE, + .msize = STATS_NET_NFS_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* NFS server activity */ +struct activity net_nfsd_act = { + .id = A_NET_NFSD, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_nfsd, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_nfsd_stats, + .f_print_avg = print_net_nfsd_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "scall/s;badcall/s;packet/s;udp/s;tcp/s;hit/s;miss/s;" + "sread/s;swrite/s;saccess/s;sgetatt/s", +#endif + .gtypes_nr = {STATS_NET_NFSD_ULL, STATS_NET_NFSD_UL, STATS_NET_NFSD_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_nfsd_stats, + .f_xml_print = xml_print_net_nfsd_stats, + .f_json_print = json_print_net_nfsd_stats, + .f_svg_print = svg_print_net_nfsd_stats, + .f_raw_print = raw_print_net_nfsd_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "NFS server statistics", +#endif + .name = "A_NET_NFSD", + .item_list_sz = 0, + .g_nr = 5, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_NFSD_SIZE, + .msize = STATS_NET_NFSD_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Network sockets activity */ +struct activity net_sock_act = { + .id = A_NET_SOCK, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_sock, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_sock_stats, + .f_print_avg = print_avg_net_sock_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "totsck;tcpsck;udpsck;rawsck;ip-frag;tcp-tw", +#endif + .gtypes_nr = {STATS_NET_SOCK_ULL, STATS_NET_SOCK_UL, STATS_NET_SOCK_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_sock_stats, + .f_xml_print = xml_print_net_sock_stats, + .f_json_print = json_print_net_sock_stats, + .f_svg_print = svg_print_net_sock_stats, + .f_raw_print = raw_print_net_sock_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv4 sockets statistics", +#endif + .name = "A_NET_SOCK", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_SOCK_SIZE, + .msize = STATS_NET_SOCK_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* IP network traffic activity */ +struct activity net_ip_act = { + .id = A_NET_IP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_ip, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_ip_stats, + .f_print_avg = print_net_ip_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "irec/s;fwddgm/s;idel/s;orq/s;asmrq/s;asmok/s;fragok/s;fragcrt/s", +#endif + .gtypes_nr = {STATS_NET_IP_ULL, STATS_NET_IP_UL, STATS_NET_IP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_ip_stats, + .f_xml_print = xml_print_net_ip_stats, + .f_json_print = json_print_net_ip_stats, + .f_svg_print = svg_print_net_ip_stats, + .f_raw_print = raw_print_net_ip_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv4 traffic statistics", +#endif + .name = "A_NET_IP", + .item_list_sz = 0, + .g_nr = 3, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_IP_SIZE, + .msize = STATS_NET_IP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* IP network traffic (errors) activity */ +struct activity net_eip_act = { + .id = A_NET_EIP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_eip, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_eip_stats, + .f_print_avg = print_net_eip_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "ihdrerr/s;iadrerr/s;iukwnpr/s;idisc/s;odisc/s;onort/s;asmf/s;fragf/s", +#endif + .gtypes_nr = {STATS_NET_EIP_ULL, STATS_NET_EIP_UL, STATS_NET_EIP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_eip_stats, + .f_xml_print = xml_print_net_eip_stats, + .f_json_print = json_print_net_eip_stats, + .f_svg_print = svg_print_net_eip_stats, + .f_raw_print = raw_print_net_eip_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv4 traffic errors statistics", +#endif + .name = "A_NET_EIP", + .item_list_sz = 0, + .g_nr = 3, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_EIP_SIZE, + .msize = STATS_NET_EIP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* ICMP network traffic activity */ +struct activity net_icmp_act = { + .id = A_NET_ICMP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_icmp, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_icmp_stats, + .f_print_avg = print_net_icmp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "imsg/s;omsg/s;iech/s;iechr/s;oech/s;oechr/s;itm/s;itmr/s;otm/s;" + "otmr/s;iadrmk/s;iadrmkr/s;oadrmk/s;oadrmkr/s", +#endif + .gtypes_nr = {STATS_NET_ICMP_ULL, STATS_NET_ICMP_UL, STATS_NET_ICMP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_icmp_stats, + .f_xml_print = xml_print_net_icmp_stats, + .f_json_print = json_print_net_icmp_stats, + .f_svg_print = svg_print_net_icmp_stats, + .f_raw_print = raw_print_net_icmp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "ICMPv4 traffic statistics", +#endif + .name = "A_NET_ICMP", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_ICMP_SIZE, + .msize = STATS_NET_ICMP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* ICMP network traffic (errors) activity */ +struct activity net_eicmp_act = { + .id = A_NET_EICMP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_eicmp, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_eicmp_stats, + .f_print_avg = print_net_eicmp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "ierr/s;oerr/s;idstunr/s;odstunr/s;itmex/s;otmex/s;" + "iparmpb/s;oparmpb/s;isrcq/s;osrcq/s;iredir/s;oredir/s", +#endif + .gtypes_nr = {STATS_NET_EICMP_ULL, STATS_NET_EICMP_UL, STATS_NET_EICMP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_eicmp_stats, + .f_xml_print = xml_print_net_eicmp_stats, + .f_json_print = json_print_net_eicmp_stats, + .f_svg_print = svg_print_net_eicmp_stats, + .f_raw_print = raw_print_net_eicmp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "ICMPv4 traffic errors statistics", +#endif + .name = "A_NET_EICMP", + .item_list_sz = 0, + .g_nr = 6, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_EICMP_SIZE, + .msize = STATS_NET_EICMP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* TCP network traffic activity */ +struct activity net_tcp_act = { + .id = A_NET_TCP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_tcp, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_tcp_stats, + .f_print_avg = print_net_tcp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "active/s;passive/s;iseg/s;oseg/s", +#endif + .gtypes_nr = {STATS_NET_TCP_ULL, STATS_NET_TCP_UL, STATS_NET_TCP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_tcp_stats, + .f_xml_print = xml_print_net_tcp_stats, + .f_json_print = json_print_net_tcp_stats, + .f_svg_print = svg_print_net_tcp_stats, + .f_raw_print = raw_print_net_tcp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "TCPv4 traffic statistics", +#endif + .name = "A_NET_TCP", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_TCP_SIZE, + .msize = STATS_NET_TCP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* TCP network traffic (errors) activity */ +struct activity net_etcp_act = { + .id = A_NET_ETCP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_etcp, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_etcp_stats, + .f_print_avg = print_net_etcp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "atmptf/s;estres/s;retrans/s;isegerr/s;orsts/s", +#endif + .gtypes_nr = {STATS_NET_ETCP_ULL, STATS_NET_ETCP_UL, STATS_NET_ETCP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_etcp_stats, + .f_xml_print = xml_print_net_etcp_stats, + .f_json_print = json_print_net_etcp_stats, + .f_svg_print = svg_print_net_etcp_stats, + .f_raw_print = raw_print_net_etcp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "TCPv4 traffic errors statistics", +#endif + .name = "A_NET_ETCP", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_ETCP_SIZE, + .msize = STATS_NET_ETCP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* UDP network traffic activity */ +struct activity net_udp_act = { + .id = A_NET_UDP, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_SNMP, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_udp, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_udp_stats, + .f_print_avg = print_net_udp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "idgm/s;odgm/s;noport/s;idgmerr/s", +#endif + .gtypes_nr = {STATS_NET_UDP_ULL, STATS_NET_UDP_UL, STATS_NET_UDP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_udp_stats, + .f_xml_print = xml_print_net_udp_stats, + .f_json_print = json_print_net_udp_stats, + .f_svg_print = svg_print_net_udp_stats, + .f_raw_print = raw_print_net_udp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "UDPv4 traffic statistics", +#endif + .name = "A_NET_UDP", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_UDP_SIZE, + .msize = STATS_NET_UDP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* IPv6 sockets activity */ +struct activity net_sock6_act = { + .id = A_NET_SOCK6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_sock6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_sock6_stats, + .f_print_avg = print_avg_net_sock6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "tcp6sck;udp6sck;raw6sck;ip6-frag", +#endif + .gtypes_nr = {STATS_NET_SOCK6_ULL, STATS_NET_SOCK6_UL, STATS_NET_SOCK6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_sock6_stats, + .f_xml_print = xml_print_net_sock6_stats, + .f_json_print = json_print_net_sock6_stats, + .f_svg_print = svg_print_net_sock6_stats, + .f_raw_print = raw_print_net_sock6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv6 sockets statistics", +#endif + .name = "A_NET_SOCK6", + .item_list_sz = 0, + .g_nr = 1, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_SOCK6_SIZE, + .msize = STATS_NET_SOCK6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* IPv6 network traffic activity */ +struct activity net_ip6_act = { + .id = A_NET_IP6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_ip6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_ip6_stats, + .f_print_avg = print_net_ip6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "irec6/s;fwddgm6/s;idel6/s;orq6/s;asmrq6/s;asmok6/s;" + "imcpck6/s;omcpck6/s;fragok6/s;fragcr6/s", +#endif + .gtypes_nr = {STATS_NET_IP6_ULL, STATS_NET_IP6_UL, STATS_NET_IP6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_ip6_stats, + .f_xml_print = xml_print_net_ip6_stats, + .f_json_print = json_print_net_ip6_stats, + .f_svg_print = svg_print_net_ip6_stats, + .f_raw_print = raw_print_net_ip6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv6 traffic statistics", +#endif + .name = "A_NET_IP6", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_IP6_SIZE, + .msize = STATS_NET_IP6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* IPv6 network traffic (errors) activity */ +struct activity net_eip6_act = { + .id = A_NET_EIP6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE + 2, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_eip6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_eip6_stats, + .f_print_avg = print_net_eip6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "ihdrer6/s;iadrer6/s;iukwnp6/s;i2big6/s;idisc6/s;odisc6/s;" + "inort6/s;onort6/s;asmf6/s;fragf6/s;itrpck6/s", +#endif + .gtypes_nr = {STATS_NET_EIP6_ULL, STATS_NET_EIP6_UL, STATS_NET_EIP6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_eip6_stats, + .f_xml_print = xml_print_net_eip6_stats, + .f_json_print = json_print_net_eip6_stats, + .f_svg_print = svg_print_net_eip6_stats, + .f_raw_print = raw_print_net_eip6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "IPv6 traffic errors statistics", +#endif + .name = "A_NET_EIP6", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_EIP6_SIZE, + .msize = STATS_NET_EIP6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* ICMPv6 network traffic activity */ +struct activity net_icmp6_act = { + .id = A_NET_ICMP6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_icmp6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_icmp6_stats, + .f_print_avg = print_net_icmp6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "imsg6/s;omsg6/s;iech6/s;iechr6/s;oechr6/s;igmbq6/s;igmbr6/s;ogmbr6/s;" + "igmbrd6/s;ogmbrd6/s;irtsol6/s;ortsol6/s;irtad6/s;inbsol6/s;onbsol6/s;" + "inbad6/s;onbad6/s", +#endif + .gtypes_nr = {STATS_NET_ICMP6_ULL, STATS_NET_ICMP6_UL, STATS_NET_ICMP6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_icmp6_stats, + .f_xml_print = xml_print_net_icmp6_stats, + .f_json_print = json_print_net_icmp6_stats, + .f_svg_print = svg_print_net_icmp6_stats, + .f_raw_print = raw_print_net_icmp6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "ICMPv6 traffic statistics", +#endif + .name = "A_NET_ICMP6", + .item_list_sz = 0, + .g_nr = 5, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_ICMP6_SIZE, + .msize = STATS_NET_ICMP6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* ICMPv6 network traffic (errors) activity */ +struct activity net_eicmp6_act = { + .id = A_NET_EICMP6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_eicmp6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_eicmp6_stats, + .f_print_avg = print_net_eicmp6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "ierr6/s;idtunr6/s;odtunr6/s;itmex6/s;otmex6/s;" + "iprmpb6/s;oprmpb6/s;iredir6/s;oredir6/s;ipck2b6/s;opck2b6/s", +#endif + .gtypes_nr = {STATS_NET_EICMP6_ULL, STATS_NET_EICMP6_UL, STATS_NET_EICMP6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_eicmp6_stats, + .f_xml_print = xml_print_net_eicmp6_stats, + .f_json_print = json_print_net_eicmp6_stats, + .f_svg_print = svg_print_net_eicmp6_stats, + .f_raw_print = raw_print_net_eicmp6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "ICMPv6 traffic errors statistics", +#endif + .name = "A_NET_EICMP6", + .item_list_sz = 0, + .g_nr = 6, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_EICMP6_SIZE, + .msize = STATS_NET_EICMP6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* UDPv6 network traffic activity */ +struct activity net_udp6_act = { + .id = A_NET_UDP6, + .options = AO_NULL, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_IPV6, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_net_udp6, +#endif +#ifdef SOURCE_SAR + .f_print = print_net_udp6_stats, + .f_print_avg = print_net_udp6_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "idgm6/s;odgm6/s;noport6/s;idgmer6/s", +#endif + .gtypes_nr = {STATS_NET_UDP6_ULL, STATS_NET_UDP6_UL, STATS_NET_UDP6_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_net_udp6_stats, + .f_xml_print = xml_print_net_udp6_stats, + .f_json_print = json_print_net_udp6_stats, + .f_svg_print = svg_print_net_udp6_stats, + .f_raw_print = raw_print_net_udp6_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "UDPv6 traffic statistics", +#endif + .name = "A_NET_UDP6", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_NET_UDP6_SIZE, + .msize = STATS_NET_UDP6_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* CPU frequency */ +struct activity pwr_cpufreq_act = { + .id = A_PWR_CPU, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 0, /* wrap_get_cpu_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_cpuinfo, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_cpufreq_stats, + .f_print_avg = print_avg_pwr_cpufreq_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "CPU;MHz", +#endif + .gtypes_nr = {STATS_PWR_CPUFREQ_ULL, STATS_PWR_CPUFREQ_UL, STATS_PWR_CPUFREQ_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_cpufreq_stats, + .f_xml_print = xml_print_pwr_cpufreq_stats, + .f_json_print = json_print_pwr_cpufreq_stats, + .f_svg_print = svg_print_pwr_cpufreq_stats, + .f_raw_print = raw_print_pwr_cpufreq_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "CPU clock frequency", +#endif + .name = "A_PWR_CPU", + .item_list_sz = 0, + .g_nr = 1, + .nr_ini = -1, + .nr2 = 1, + .nr_max = NR_CPUS + 1, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_CPUFREQ_SIZE, + .msize = STATS_PWR_CPUFREQ_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = &cpu_bitmap +}; + +/* Fan */ +struct activity pwr_fan_act = { + .id = A_PWR_FAN, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 5, /* wrap_get_fan_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_fan, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_fan_stats, + .f_print_avg = print_avg_pwr_fan_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "FAN;DEVICE;rpm;drpm", +#endif + .gtypes_nr = {STATS_PWR_FAN_ULL, STATS_PWR_FAN_UL, STATS_PWR_FAN_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_fan_stats, + .f_xml_print = xml_print_pwr_fan_stats, + .f_json_print = json_print_pwr_fan_stats, + .f_svg_print = svg_print_pwr_fan_stats, + .f_raw_print = raw_print_pwr_fan_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Fans speed", +#endif + .name = "A_PWR_FAN", + .item_list_sz = 0, + .g_nr = 1, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_FANS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_FAN_SIZE, + .msize = STATS_PWR_FAN_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Temperature */ +struct activity pwr_temp_act = { + .id = A_PWR_TEMP, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 6, /* wrap_get_temp_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_temp, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_temp_stats, + .f_print_avg = print_avg_pwr_temp_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "TEMP;DEVICE;degC;%temp", +#endif + .gtypes_nr = {STATS_PWR_TEMP_ULL, STATS_PWR_TEMP_UL, STATS_PWR_TEMP_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_temp_stats, + .f_xml_print = xml_print_pwr_temp_stats, + .f_json_print = json_print_pwr_temp_stats, + .f_svg_print = svg_print_pwr_temp_stats, + .f_raw_print = raw_print_pwr_temp_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Devices temperature", +#endif + .name = "A_PWR_TEMP", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_TEMP_SENSORS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_TEMP_SIZE, + .msize = STATS_PWR_TEMP_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Voltage inputs */ +struct activity pwr_in_act = { + .id = A_PWR_IN, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 7, /* wrap_get_in_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_in, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_in_stats, + .f_print_avg = print_avg_pwr_in_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "IN;DEVICE;inV;%in", +#endif + .gtypes_nr = {STATS_PWR_IN_ULL, STATS_PWR_IN_UL, STATS_PWR_IN_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_in_stats, + .f_xml_print = xml_print_pwr_in_stats, + .f_json_print = json_print_pwr_in_stats, + .f_svg_print = svg_print_pwr_in_stats, + .f_raw_print = raw_print_pwr_in_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Voltage inputs statistics", +#endif + .name = "A_PWR_IN", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_IN_SENSORS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_IN_SIZE, + .msize = STATS_PWR_IN_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Hugepages activity */ +struct activity huge_act = { + .id = A_HUGE, + .options = AO_COLLECTED, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = -1, + .f_count2 = NULL, + .f_read = wrap_read_meminfo_huge, +#endif +#ifdef SOURCE_SAR + .f_print = print_huge_stats, + .f_print_avg = print_avg_huge_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "kbhugfree;kbhugused;%hugused", +#endif + .gtypes_nr = {STATS_HUGE_ULL, STATS_HUGE_UL, STATS_HUGE_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_huge_stats, + .f_xml_print = xml_print_huge_stats, + .f_json_print = json_print_huge_stats, + .f_svg_print = svg_print_huge_stats, + .f_raw_print = raw_print_huge_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Huge pages utilization", +#endif + .name = "A_HUGE", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = 1, + .nr2 = 1, + .nr_max = 1, + .nr = {1, 1, 1}, + .nr_allocated = 0, + .fsize = STATS_HUGE_SIZE, + .msize = STATS_HUGE_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* CPU weighted frequency */ +struct activity pwr_wghfreq_act = { + .id = A_PWR_FREQ, + .options = AO_COUNTED + AO_MATRIX, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 0, /* wrap_get_cpu_nr() */ + .f_count2 = wrap_get_freq_nr, + .f_read = wrap_read_cpu_wghfreq, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_wghfreq_stats, + .f_print_avg = print_pwr_wghfreq_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "CPU;wghMHz", +#endif + .gtypes_nr = {STATS_PWR_WGHFREQ_ULL, STATS_PWR_WGHFREQ_UL, STATS_PWR_WGHFREQ_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_wghfreq_stats, + .f_xml_print = xml_print_pwr_wghfreq_stats, + .f_json_print = json_print_pwr_wghfreq_stats, + .f_svg_print = NULL, + .f_raw_print = raw_print_pwr_wghfreq_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "CPU weighted frequency", +#endif + .name = "A_PWR_FREQ", + .item_list_sz = 0, + .g_nr = 0, + .nr_ini = -1, + .nr2 = -1, + .nr_max = NR_CPUS + 1, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_WGHFREQ_SIZE, + .msize = STATS_PWR_WGHFREQ_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = &cpu_bitmap +}; + +/* USB devices plugged into the system */ +struct activity pwr_usb_act = { + .id = A_PWR_USB, + .options = AO_COUNTED + AO_CLOSE_MARKUP, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_POWER, +#ifdef SOURCE_SADC + .f_count_index = 8, /* wrap_get_usb_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_bus_usb_dev, +#endif +#ifdef SOURCE_SAR + .f_print = print_pwr_usb_stats, + .f_print_avg = print_avg_pwr_usb_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "manufact;product;BUS;idvendor;idprod;maxpower", +#endif + .gtypes_nr = {STATS_PWR_USB_ULL, STATS_PWR_USB_UL, STATS_PWR_USB_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_pwr_usb_stats, + .f_xml_print = xml_print_pwr_usb_stats, + .f_json_print = json_print_pwr_usb_stats, + .f_svg_print = NULL, + .f_raw_print = raw_print_pwr_usb_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "USB devices", +#endif + .name = "A_PWR_USB", + .item_list_sz = 0, + .g_nr = 0, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_USB, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_PWR_USB_SIZE, + .msize = STATS_PWR_USB_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Filesystem usage activity */ +struct activity filesystem_act = { + .id = A_FS, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM + AO_MULTIPLE_OUTPUTS, + .magic = ACTIVITY_MAGIC_BASE + 1, + .group = G_XDISK, +#ifdef SOURCE_SADC + .f_count_index = 9, /* wrap_get_filesystem_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_filesystem, +#endif +#ifdef SOURCE_SAR + .f_print = print_filesystem_stats, + .f_print_avg = print_avg_filesystem_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "FILESYSTEM;MBfsfree;MBfsused;%fsused;%ufsused;Ifree;Iused;%Iused|" + "MOUNTPOINT;MBfsfree;MBfsused;%fsused;%ufsused;Ifree;Iused;%Iused", +#endif + .gtypes_nr = {STATS_FILESYSTEM_ULL, STATS_FILESYSTEM_UL, STATS_FILESYSTEM_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_filesystem_stats, + .f_xml_print = xml_print_filesystem_stats, + .f_json_print = json_print_filesystem_stats, + .f_svg_print = svg_print_filesystem_stats, + .f_raw_print = raw_print_filesystem_stats, + .f_count_new = count_new_filesystem, + .item_list = NULL, + .desc = "Filesystems statistics", +#endif + .name = "A_FS", + .item_list_sz = 0, + .g_nr = 4, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_FS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_FILESYSTEM_SIZE, + .msize = STATS_FILESYSTEM_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Fibre Channel HBA usage activity */ +struct activity fchost_act = { + .id = A_NET_FC, + .options = AO_COUNTED + AO_GRAPH_PER_ITEM, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DISK, +#ifdef SOURCE_SADC + .f_count_index = 10, /* wrap_get_fchost_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_fchost, +#endif +#ifdef SOURCE_SAR + .f_print = print_fchost_stats, + .f_print_avg = print_fchost_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "FCHOST;fch_rxf/s;fch_txf/s;fch_rxw/s;fch_txw/s", +#endif + .gtypes_nr = {STATS_FCHOST_ULL, STATS_FCHOST_UL, STATS_FCHOST_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_fchost_stats, + .f_xml_print = xml_print_fchost_stats, + .f_json_print = json_print_fchost_stats, + .f_svg_print = svg_print_fchost_stats, + .f_raw_print = raw_print_fchost_stats, + .f_count_new = count_new_fchost, + .item_list = NULL, + .desc = "Fibre Channel HBA statistics", +#endif + .name = "A_NET_FC", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = -1, + .nr2 = 1, + .nr_max = MAX_NR_FCHOSTS, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_FCHOST_SIZE, + .msize = STATS_FCHOST_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = NULL +}; + +/* Softnet activity */ +struct activity softnet_act = { + .id = A_NET_SOFT, + .options = AO_COLLECTED + AO_COUNTED + AO_CLOSE_MARKUP + + AO_GRAPH_PER_ITEM + AO_PERSISTENT, + .magic = ACTIVITY_MAGIC_BASE, + .group = G_DEFAULT, +#ifdef SOURCE_SADC + .f_count_index = 0, /* wrap_get_cpu_nr() */ + .f_count2 = NULL, + .f_read = wrap_read_softnet, +#endif +#ifdef SOURCE_SAR + .f_print = print_softnet_stats, + .f_print_avg = print_softnet_stats, +#endif +#if defined(SOURCE_SAR) || defined(SOURCE_SADF) + .hdr_line = "CPU;total/s;dropd/s;squeezd/s;rx_rps/s;flw_lim/s", +#endif + .gtypes_nr = {STATS_SOFTNET_ULL, STATS_SOFTNET_UL, STATS_SOFTNET_U}, + .ftypes_nr = {0, 0, 0}, +#ifdef SOURCE_SADF + .f_render = render_softnet_stats, + .f_xml_print = xml_print_softnet_stats, + .f_json_print = json_print_softnet_stats, + .f_svg_print = svg_print_softnet_stats, + .f_raw_print = raw_print_softnet_stats, + .f_count_new = NULL, + .item_list = NULL, + .desc = "Software-based network processing statistics", +#endif + .name = "A_NET_SOFT", + .item_list_sz = 0, + .g_nr = 2, + .nr_ini = -1, + .nr2 = 1, + .nr_max = NR_CPUS + 1, + .nr = {-1, -1, -1}, + .nr_allocated = 0, + .fsize = STATS_SOFTNET_SIZE, + .msize = STATS_SOFTNET_SIZE, + .opt_flags = 0, + .buf = {NULL, NULL, NULL}, + .bitmap = &cpu_bitmap +}; + +#ifdef SOURCE_SADC +/* + * Array of functions used to count number of items. + */ +__nr_t (*f_count[NR_F_COUNT]) (struct activity *) = { + wrap_get_cpu_nr, + wrap_get_irq_nr, + wrap_get_serial_nr, + wrap_get_disk_nr, + wrap_get_iface_nr, + wrap_get_fan_nr, + wrap_get_temp_nr, + wrap_get_in_nr, + wrap_get_usb_nr, + wrap_get_filesystem_nr, + wrap_get_fchost_nr +}; +#endif + +/* + * Array of activities. + * (Order of activities doesn't matter for daily data files). + */ +struct activity *act[NR_ACT] = { + &cpu_act, + &pcsw_act, + &irq_act, + &swap_act, + &paging_act, + &io_act, + &memory_act, + &huge_act, + &ktables_act, + &queue_act, + &serial_act, + &disk_act, + /* */ + &net_dev_act, + &net_edev_act, + &net_nfs_act, + &net_nfsd_act, + &net_sock_act, + &net_ip_act, + &net_eip_act, + &net_icmp_act, + &net_eicmp_act, + &net_tcp_act, + &net_etcp_act, + &net_udp_act, + &net_sock6_act, + &net_ip6_act, + &net_eip6_act, + &net_icmp6_act, + &net_eicmp6_act, + &net_udp6_act, + &fchost_act, + &softnet_act, /* AO_CLOSE_MARKUP */ + /* */ + /* */ + &pwr_cpufreq_act, + &pwr_fan_act, + &pwr_temp_act, + &pwr_in_act, + &pwr_wghfreq_act, + &pwr_usb_act, /* AO_CLOSE_MARKUP */ + /* */ + &filesystem_act +}; diff --git a/tests/12.0.1/common.c b/tests/12.0.1/common.c new file mode 100644 index 0000000..d418abf --- /dev/null +++ b/tests/12.0.1/common.c @@ -0,0 +1,1437 @@ +/* + * sar, sadc, sadf, mpstat and iostat common routines. + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* For STDOUT_FILENO, among others */ +#include +#include +#include +#include +#include + +#include "version.h" +#include "common.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +/* Number of decimal places */ +extern int dplaces_nr; + +/* Units (sectors, Bytes, kilobytes, etc.) */ +char units[] = {'s', 'B', 'k', 'M', 'G', 'T', 'P', '?'}; + +/* Number of ticks per second */ +unsigned long hz; +/* Number of bit shifts to convert pages to kB */ +unsigned int kb_shift; + +/* Colors strings */ +char sc_percent_high[MAX_SGR_LEN] = C_BOLD_RED; +char sc_percent_low[MAX_SGR_LEN] = C_BOLD_MAGENTA; +char sc_zero_int_stat[MAX_SGR_LEN] = C_LIGHT_BLUE; +char sc_int_stat[MAX_SGR_LEN] = C_BOLD_BLUE; +char sc_item_name[MAX_SGR_LEN] = C_LIGHT_GREEN; +char sc_sa_restart[MAX_SGR_LEN] = C_LIGHT_RED; +char sc_sa_comment[MAX_SGR_LEN] = C_LIGHT_YELLOW; +char sc_normal[MAX_SGR_LEN] = C_NORMAL; + +/* Type of persistent device names used in sar and iostat */ +char persistent_name_type[MAX_FILE_LEN]; + +/* + *************************************************************************** + * Print sysstat version number and exit. + *************************************************************************** + */ +void print_version(void) +{ + printf(_("sysstat version %s\n"), VERSION); + printf("(C) Sebastien Godard (sysstat orange.fr)\n"); + exit(0); +} + +/* + *************************************************************************** + * Get local date and time. + * + * IN: + * @d_off Day offset (number of days to go back in the past). + * + * OUT: + * @rectime Current local date and time. + * + * RETURNS: + * Value of time in seconds since the Epoch. + *************************************************************************** + */ +time_t get_localtime(struct tm *rectime, int d_off) +{ + time_t timer; + struct tm *ltm; + + time(&timer); + timer -= SEC_PER_DAY * d_off; + ltm = localtime(&timer); + + if (ltm) { + *rectime = *ltm; + } + return timer; +} + +/* + *************************************************************************** + * Get date and time expressed in UTC. + * + * IN: + * @d_off Day offset (number of days to go back in the past). + * + * OUT: + * @rectime Current date and time expressed in UTC. + * + * RETURNS: + * Value of time in seconds since the Epoch. + *************************************************************************** + */ +time_t get_gmtime(struct tm *rectime, int d_off) +{ + time_t timer; + struct tm *ltm; + + time(&timer); + timer -= SEC_PER_DAY * d_off; + ltm = gmtime(&timer); + + if (ltm) { + *rectime = *ltm; + } + return timer; +} + +/* + *************************************************************************** + * Get date and time and take into account variable. + * + * IN: + * @d_off Day offset (number of days to go back in the past). + * + * OUT: + * @rectime Current date and time. + * + * RETURNS: + * Value of time in seconds since the Epoch. + *************************************************************************** + */ +time_t get_time(struct tm *rectime, int d_off) +{ + static int utc = 0; + char *e; + + if (!utc) { + /* Read environment variable value once */ + if ((e = getenv(ENV_TIME_DEFTM)) != NULL) { + utc = !strcmp(e, K_UTC); + } + utc++; + } + + if (utc == 2) + return get_gmtime(rectime, d_off); + else + return get_localtime(rectime, d_off); +} + +#ifdef USE_NLS +/* + *************************************************************************** + * Init National Language Support. + *************************************************************************** + */ +void init_nls(void) +{ + setlocale(LC_MESSAGES, ""); + setlocale(LC_CTYPE, ""); + setlocale(LC_TIME, ""); + setlocale(LC_NUMERIC, ""); + + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); +} +#endif + +/* + *************************************************************************** + * Test whether given name is a device or a partition, using sysfs. + * This is more straightforward that using ioc_iswhole() function from + * ioconf.c which should be used only with kernels that don't have sysfs. + * + * IN: + * @name Device or partition name. + * @allow_virtual TRUE if virtual devices are also accepted. + * The device is assumed to be virtual if no + * /sys/block//device link exists. + * + * RETURNS: + * TRUE if @name is not a partition. + *************************************************************************** + */ +int is_device(char *name, int allow_virtual) +{ + char syspath[PATH_MAX]; + char *slash; + + /* Some devices may have a slash in their name (eg. cciss/c0d0...) */ + while ((slash = strchr(name, '/'))) { + *slash = '!'; + } + snprintf(syspath, sizeof(syspath), "%s/%s%s", SYSFS_BLOCK, name, + allow_virtual ? "" : "/device"); + + return !(access(syspath, F_OK)); +} + +/* + *************************************************************************** + * Get page shift in kB. + *************************************************************************** + */ +void get_kb_shift(void) +{ + int shift = 0; + long size; + + /* One can also use getpagesize() to get the size of a page */ + if ((size = sysconf(_SC_PAGESIZE)) == -1) { + perror("sysconf"); + } + + size >>= 10; /* Assume that a page has a minimum size of 1 kB */ + + while (size > 1) { + shift++; + size >>= 1; + } + + kb_shift = (unsigned int) shift; +} + +/* + *************************************************************************** + * Get number of clock ticks per second. + *************************************************************************** + */ +void get_HZ(void) +{ + long ticks; + + if ((ticks = sysconf(_SC_CLK_TCK)) == -1) { + perror("sysconf"); + } + + hz = (unsigned long) ticks; +} + +/* + *************************************************************************** + * Unhandled situation: Panic and exit. Should never happen. + * + * IN: + * @function Function name where situation occured. + * @error_code Error code. + *************************************************************************** + */ +void sysstat_panic(const char *function, int error_code) +{ + fprintf(stderr, "sysstat: %s[%d]: Internal error...\n", + function, error_code); + exit(1); +} + +#ifndef SOURCE_SADC +/* + *************************************************************************** + * Count number of comma-separated values in arguments list. For example, + * the number will be 3 for the list "foobar -p 1 -p 2,3,4 2 5". + * + * IN: + * @arg_c Number of arguments in the list. + * @arg_v Arguments list. + * + * RETURNS: + * Number of comma-separated values in the list. + *************************************************************************** + */ +int count_csvalues(int arg_c, char **arg_v) +{ + int opt = 1; + int nr = 0; + char *t; + + while (opt < arg_c) { + if (strchr(arg_v[opt], ',')) { + for (t = arg_v[opt]; t; t = strchr(t + 1, ',')) { + nr++; + } + } + opt++; + } + + return nr; +} + +/* + *************************************************************************** + * Look for partitions of a given block device in /sys filesystem. + * + * IN: + * @dev_name Name of the block device. + * + * RETURNS: + * Number of partitions for the given block device. + *************************************************************************** + */ +int get_dev_part_nr(char *dev_name) +{ + DIR *dir; + struct dirent *drd; + char dfile[MAX_PF_NAME], line[MAX_PF_NAME]; + int part = 0, err; + + snprintf(dfile, MAX_PF_NAME, "%s/%s", SYSFS_BLOCK, dev_name); + dfile[MAX_PF_NAME - 1] = '\0'; + + /* Open current device directory in /sys/block */ + if ((dir = opendir(dfile)) == NULL) + return 0; + + /* Get current file entry */ + while ((drd = readdir(dir)) != NULL) { + if (!strcmp(drd->d_name, ".") || !strcmp(drd->d_name, "..")) + continue; + err = snprintf(line, MAX_PF_NAME, "%s/%s/%s", dfile, drd->d_name, S_STAT); + if ((err < 0) || (err >= MAX_PF_NAME)) + continue; + + /* Try to guess if current entry is a directory containing a stat file */ + if (!access(line, R_OK)) { + /* Yep... */ + part++; + } + } + + /* Close directory */ + closedir(dir); + + return part; +} + +/* + *************************************************************************** + * Look for block devices present in /sys/ filesystem: + * Check first that sysfs is mounted (done by trying to open /sys/block + * directory), then find number of devices registered. + * + * IN: + * @display_partitions Set to TRUE if partitions must also be counted. + * + * RETURNS: + * Total number of block devices (and partitions if @display_partitions was + * set). + *************************************************************************** + */ +int get_sysfs_dev_nr(int display_partitions) +{ + DIR *dir; + struct dirent *drd; + char line[MAX_PF_NAME]; + int dev = 0; + + /* Open /sys/block directory */ + if ((dir = opendir(SYSFS_BLOCK)) == NULL) + /* sysfs not mounted, or perhaps this is an old kernel */ + return 0; + + /* Get current file entry in /sys/block directory */ + while ((drd = readdir(dir)) != NULL) { + if (!strcmp(drd->d_name, ".") || !strcmp(drd->d_name, "..")) + continue; + snprintf(line, MAX_PF_NAME, "%s/%s/%s", SYSFS_BLOCK, drd->d_name, S_STAT); + line[MAX_PF_NAME - 1] = '\0'; + + /* Try to guess if current entry is a directory containing a stat file */ + if (!access(line, R_OK)) { + /* Yep... */ + dev++; + + if (display_partitions) { + /* We also want the number of partitions for this device */ + dev += get_dev_part_nr(drd->d_name); + } + } + } + + /* Close /sys/block directory */ + closedir(dir); + + return dev; +} + +/* + *************************************************************************** + * Read /proc/devices file and get device-mapper major number. + * If device-mapper entry is not found in file, assume it's not active. + * + * RETURNS: + * Device-mapper major number. + *************************************************************************** + */ +unsigned int get_devmap_major(void) +{ + FILE *fp; + char line[128]; + /* + * Linux uses 12 bits for the major number, + * so this shouldn't match any real device. + */ + unsigned int dm_major = ~0U; + + if ((fp = fopen(DEVICES, "r")) == NULL) + return dm_major; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (strstr(line, "device-mapper")) { + /* Read device-mapper major number */ + sscanf(line, "%u", &dm_major); + } + } + + fclose(fp); + + return dm_major; +} + +/* + *************************************************************************** + * Returns whether S_TIME_FORMAT is set to ISO. + * + * RETURNS: + * TRUE if S_TIME_FORMAT is set to ISO, or FALSE otherwise. + *************************************************************************** + */ +int is_iso_time_fmt(void) +{ + static int is_iso = -1; + char *e; + + if (is_iso < 0) { + is_iso = (((e = getenv(ENV_TIME_FMT)) != NULL) && !strcmp(e, K_ISO)); + } + return is_iso; +} + +/* + *************************************************************************** + * Print tabulations + * + * IN: + * @nr_tab Number of tabs to print. + *************************************************************************** + */ +void prtab(int nr_tab) +{ + int i; + + for (i = 0; i < nr_tab; i++) { + printf("\t"); + } +} + +/* + *************************************************************************** + * printf() function modified for XML-like output. Don't print a CR at the + * end of the line. + * + * IN: + * @nr_tab Number of tabs to print. + * @fmtf printf() format. + *************************************************************************** + */ +void xprintf0(int nr_tab, const char *fmtf, ...) +{ + static char buf[1024]; + va_list args; + + va_start(args, fmtf); + vsnprintf(buf, sizeof(buf), fmtf, args); + va_end(args); + + prtab(nr_tab); + printf("%s", buf); +} + +/* + *************************************************************************** + * printf() function modified for XML-like output. Print a CR at the end of + * the line. + * + * IN: + * @nr_tab Number of tabs to print. + * @fmtf printf() format. + *************************************************************************** + */ +void xprintf(int nr_tab, const char *fmtf, ...) +{ + static char buf[1024]; + va_list args; + + va_start(args, fmtf); + vsnprintf(buf, sizeof(buf), fmtf, args); + va_end(args); + + prtab(nr_tab); + printf("%s\n", buf); +} + +/* + *************************************************************************** + * Get report date as a string of characters. + * + * IN: + * @rectime Date to display (don't use time fields). + * @cur_date String where date will be saved. + * @sz Max size of cur_date string. + * + * OUT: + * @cur_date Date (string format). + * + * RETURNS: + * TRUE if S_TIME_FORMAT is set to ISO, or FALSE otherwise. + *************************************************************************** + */ +int set_report_date(struct tm *rectime, char cur_date[], int sz) +{ + if (rectime == NULL) { + strncpy(cur_date, "?/?/?", sz); + cur_date[sz - 1] = '\0'; + } + else if (is_iso_time_fmt()) { + strftime(cur_date, sz, "%Y-%m-%d", rectime); + return 1; + } + else { + strftime(cur_date, sz, "%x", rectime); + } + + return 0; +} + +/* + *************************************************************************** + * Print banner. + * + * IN: + * @rectime Date to display (don't use time fields). + * @sysname System name to display. + * @release System release number to display. + * @nodename Hostname to display. + * @machine Machine architecture to display. + * @cpu_nr Number of CPU. + * @format Set to FALSE for (default) plain output, and to TRUE for + * JSON format output. + * + * RETURNS: + * TRUE if S_TIME_FORMAT is set to ISO, or FALSE otherwise. + *************************************************************************** + */ +int print_gal_header(struct tm *rectime, char *sysname, char *release, + char *nodename, char *machine, int cpu_nr, int format) +{ + char cur_date[TIMESTAMP_LEN]; + int rc = 0; + + rc = set_report_date(rectime, cur_date, sizeof(cur_date)); + + if (format == PLAIN_OUTPUT) { + /* Plain output */ + printf("%s %s (%s) \t%s \t_%s_\t(%d CPU)\n", sysname, release, nodename, + cur_date, machine, cpu_nr); + } + else { + /* JSON output */ + xprintf(0, "{\"sysstat\": {"); + xprintf(1, "\"hosts\": ["); + xprintf(2, "{"); + xprintf(3, "\"nodename\": \"%s\",", nodename); + xprintf(3, "\"sysname\": \"%s\",", sysname); + xprintf(3, "\"release\": \"%s\",", release); + xprintf(3, "\"machine\": \"%s\",", machine); + xprintf(3, "\"number-of-cpus\": %d,", cpu_nr); + xprintf(3, "\"date\": \"%s\",", cur_date); + xprintf(3, "\"statistics\": ["); + } + + return rc; +} + +/* + *************************************************************************** + * Get number of rows for current window. + * + * RETURNS: + * Number of rows. + *************************************************************************** + */ +int get_win_height(void) +{ + struct winsize win; + /* + * This default value will be used whenever STDOUT + * is redirected to a pipe or a file + */ + int rows = 3600 * 24; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1) { + if (win.ws_row > 2) { + rows = win.ws_row - 2; + } + } + return rows; +} + +/* + *************************************************************************** + * Canonicalize and remove /dev from path name. + * + * IN: + * @name Device name (may begin with "/dev/" or can be a symlink). + * + * RETURNS: + * Device basename. + *************************************************************************** + */ +char *device_name(char *name) +{ + static char out[MAX_FILE_LEN]; + char *resolved_name; + int i = 0; + + /* realpath() creates new string, so we need to free it later */ + resolved_name = realpath(name, NULL); + + /* If path doesn't exist, just return input */ + if (!resolved_name) { + return name; + } + + if (!strncmp(resolved_name, "/dev/", 5)) { + i = 5; + } + strncpy(out, resolved_name + i, MAX_FILE_LEN); + out[MAX_FILE_LEN - 1] = '\0'; + + free(resolved_name); + + return out; +} + +/* + *************************************************************************** + * Workaround for CPU counters read from /proc/stat: Dyn-tick kernels + * have a race issue that can make those counters go backward. + *************************************************************************** + */ +double ll_sp_value(unsigned long long value1, unsigned long long value2, + unsigned long long itv) +{ + if (value2 < value1) + return (double) 0; + else + return SP_VALUE(value1, value2, itv); +} + +/* + *************************************************************************** + * Compute time interval. + * + * IN: + * @prev_uptime Previous uptime value (in jiffies or 1/100th of a second). + * @curr_uptime Current uptime value (in jiffies or 1/100th of a second). + * + * RETURNS: + * Interval of time in jiffies or 1/100th of a second. + *************************************************************************** + */ +unsigned long long get_interval(unsigned long long prev_uptime, + unsigned long long curr_uptime) +{ + unsigned long long itv; + + /* prev_time=0 when displaying stats since system startup */ + itv = curr_uptime - prev_uptime; + + if (!itv) { /* Paranoia checking */ + itv = 1; + } + + return itv; +} + +/* + *************************************************************************** + * Count number of bits set in an array. + * + * IN: + * @ptr Pointer to array. + * @size Size of array in bytes. + * + * RETURNS: + * Number of bits set in the array. + *************************************************************************** +*/ +int count_bits(void *ptr, int size) +{ + int nr = 0, i, k; + char *p; + + p = ptr; + for (i = 0; i < size; i++, p++) { + k = 0x80; + while (k) { + if (*p & k) + nr++; + k >>= 1; + } + } + + return nr; +} + +/* + *************************************************************************** + * Convert in-place input string to lowercase. + * + * IN: + * @str String to be converted. + * + * OUT: + * @str String in lowercase. + * + * RETURNS: + * String in lowercase. + *************************************************************************** +*/ +char *strtolower(char *str) +{ + char *cp = str; + + while (*cp) { + *cp = tolower(*cp); + cp++; + } + + return(str); +} + +/* + *************************************************************************** + * Get persistent type name directory from type. + * + * IN: + * @type Persistent type name (UUID, LABEL, etc.) + * + * RETURNS: + * Path to the persistent type name directory, or NULL if access is denied. + *************************************************************************** +*/ +char *get_persistent_type_dir(char *type) +{ + static char dir[32]; + + snprintf(dir, 32, "%s-%s", DEV_DISK_BY, type); + + if (access(dir, R_OK)) { + return (NULL); + } + + return (dir); +} + +/* + *************************************************************************** + * Get persistent name absolute path. + * + * IN: + * @name Persistent name. + * + * RETURNS: + * Path to the persistent name, or NULL if file doesn't exist. + *************************************************************************** +*/ +char *get_persistent_name_path(char *name) +{ + static char path[PATH_MAX]; + + snprintf(path, PATH_MAX, "%s/%s", + get_persistent_type_dir(persistent_name_type), name); + + if (access(path, F_OK)) { + return (NULL); + } + + return (path); +} + +/* + *************************************************************************** + * Get files from persistent type name directory. + * + * RETURNS: + * List of files in the persistent type name directory in alphabetical order. + *************************************************************************** +*/ +char **get_persistent_names(void) +{ + int n, i, k = 0; + char *dir; + char **files = NULL; + struct dirent **namelist; + + /* Get directory name for selected persistent type */ + dir = get_persistent_type_dir(persistent_name_type); + if (!dir) + return (NULL); + + n = scandir(dir, &namelist, NULL, alphasort); + if (n < 0) + return (NULL); + + /* If directory is empty, it contains 2 entries: "." and ".." */ + if (n <= 2) + /* Free list and return NULL */ + goto free_list; + + /* Ignore the "." and "..", but keep place for one last NULL. */ + files = (char **) calloc(n - 1, sizeof(char *)); + if (!files) + goto free_list; + + /* + * i is for traversing namelist, k is for files. + * i != k because we are ignoring "." and ".." entries. + */ + for (i = 0; i < n; i++) { + /* Ignore "." and "..". */ + if (!strcmp(".", namelist[i]->d_name) || + !strcmp("..", namelist[i]->d_name)) + continue; + + files[k] = (char *) calloc(strlen(namelist[i]->d_name) + 1, sizeof(char)); + if (!files[k]) + continue; + + strcpy(files[k++], namelist[i]->d_name); + } + files[k] = NULL; + +free_list: + + for (i = 0; i < n; i++) { + free(namelist[i]); + } + free(namelist); + + return (files); +} + +/* + *************************************************************************** + * Get persistent name from pretty name. + * + * IN: + * @pretty Pretty name (e.g. sda, sda1, ..). + * + * RETURNS: + * Persistent name. + *************************************************************************** +*/ +char *get_persistent_name_from_pretty(char *pretty) +{ + int i = -1; + ssize_t r; + char *link, *name; + char **persist_names; + char target[PATH_MAX]; + static char persist_name[FILENAME_MAX]; + + persist_name[0] = '\0'; + + /* Get list of files from persistent type name directory */ + persist_names = get_persistent_names(); + if (!persist_names) + return (NULL); + + while (persist_names[++i]) { + /* Get absolute path for current persistent name */ + link = get_persistent_name_path(persist_names[i]); + if (!link) + continue; + + /* Persistent name is usually a symlink: Read it... */ + r = readlink(link, target, PATH_MAX); + if ((r <= 0) || (r >= PATH_MAX)) + continue; + + target[r] = '\0'; + + /* ... and get device pretty name it points at */ + name = basename(target); + if (!name || (name[0] == '\0')) + continue; + + if (!strncmp(name, pretty, FILENAME_MAX)) { + /* We have found pretty name for current persistent one */ + strncpy(persist_name, persist_names[i], FILENAME_MAX); + persist_name[FILENAME_MAX - 1] = '\0'; + break; + } + } + + i = -1; + while (persist_names[++i]) { + free (persist_names[i]); + } + free (persist_names); + + if (strlen(persist_name) <= 0) + return (NULL); + + return persist_name; +} + +/* + *************************************************************************** + * Get pretty name (sda, sda1...) from persistent name. + * + * IN: + * @persistent Persistent name. + * + * RETURNS: + * Pretty name. + *************************************************************************** +*/ +char *get_pretty_name_from_persistent(char *persistent) +{ + ssize_t r; + char *link, *pretty, target[PATH_MAX]; + + /* Get absolute path for persistent name */ + link = get_persistent_name_path(persistent); + if (!link) + return (NULL); + + /* Persistent name is usually a symlink: Read it... */ + r = readlink(link, target, PATH_MAX); + if ((r <= 0) || (r >= PATH_MAX)) + return (NULL); + + target[r] = '\0'; + + /* ... and get device pretty name it points at */ + pretty = basename(target); + if (!pretty || (pretty[0] == '\0')) + return (NULL); + + return pretty; +} + +/* + *************************************************************************** + * Init color strings. + *************************************************************************** + */ +void init_colors(void) +{ + char *e, *p; + int len; + + /* Read S_COLORS environment variable */ + if (((e = getenv(ENV_COLORS)) == NULL) || + !strcmp(e, C_NEVER) || + (strcmp(e, C_ALWAYS) && !isatty(STDOUT_FILENO))) { + /* + * Environment variable not set, or set to "never", + * or set to "auto" and stdout is not a terminal: + * Unset color strings. + */ + strcpy(sc_percent_high, ""); + strcpy(sc_percent_low, ""); + strcpy(sc_zero_int_stat, ""); + strcpy(sc_int_stat, ""); + strcpy(sc_item_name, ""); + strcpy(sc_sa_comment, ""); + strcpy(sc_sa_restart, ""); + strcpy(sc_normal, ""); + + return; + } + + /* Read S_COLORS_SGR environment variable */ + if ((e = getenv(ENV_COLORS_SGR)) == NULL) + /* Environment variable not set */ + return; + + for (p = strtok(e, ":"); p; p =strtok(NULL, ":")) { + + len = strlen(p); + if ((len > 7) || (len < 3) || (*(p + 1) != '=') || + (strspn(p + 2, ";0123456789") != (len - 2))) + /* Ignore malformed codes */ + continue; + + switch (*p) { + case 'H': + snprintf(sc_percent_high, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'M': + snprintf(sc_percent_low, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'Z': + snprintf(sc_zero_int_stat, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'N': + snprintf(sc_int_stat, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'I': + snprintf(sc_item_name, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'C': + snprintf(sc_sa_comment, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + case 'R': + snprintf(sc_sa_restart, MAX_SGR_LEN, "\e[%sm", p + 2); + break; + } + } +} + +/* + *************************************************************************** + * Print a value in human readable format. Such a value is a decimal number + * followed by a unit (B, k, M, etc.) + * + * IN: + * @unit Default value unit. + * @dval Value to print. + * @wi Output width. + *************************************************************************** +*/ +void cprintf_unit(int unit, int wi, double dval) +{ + if (wi < 4) { + /* E.g. 1.3M */ + wi = 4; + } + if (!unit) { + /* Value is a number of sectors. Convert it to kB */ + dval /= 2; + unit = 2; + } + while (dval >= 1024) { + dval /= 1024; + unit++; + } + printf(" %*.*f", wi - 1, dplaces_nr ? 1 : 0, dval); + printf("%s", sc_normal); + + /* Display unit */ + if (unit >= NR_UNITS) { + unit = NR_UNITS - 1; + } + printf("%c", units[unit]); +} + +/* + *************************************************************************** + * Print 64 bit unsigned values using colors, possibly followed by a unit. + * + * IN: + * @unit Default values unit. -1 if no unit should be displayed. + * @num Number of values to print. + * @wi Output width. + *************************************************************************** +*/ +void cprintf_u64(int unit, int num, int wi, ...) +{ + int i; + uint64_t val; + va_list args; + + va_start(args, wi); + + for (i = 0; i < num; i++) { + val = va_arg(args, unsigned long long); + if (!val) { + printf("%s", sc_zero_int_stat); + } + else { + printf("%s", sc_int_stat); + } + if (unit < 0) { + printf(" %*"PRIu64, wi, val); + printf("%s", sc_normal); + } + else { + cprintf_unit(unit, wi, (double) val); + } + } + + va_end(args); +} + +/* + *************************************************************************** + * Print hex values using colors. + * + * IN: + * @num Number of values to print. + * @wi Output width. + *************************************************************************** +*/ +void cprintf_x(int num, int wi, ...) +{ + int i; + unsigned int val; + va_list args; + + va_start(args, wi); + + for (i = 0; i < num; i++) { + val = va_arg(args, unsigned int); + printf("%s", sc_int_stat); + printf(" %*x", wi, val); + printf("%s", sc_normal); + } + + va_end(args); +} + +/* + *************************************************************************** + * Print "double" statistics values using colors, possibly followed by a + * unit. + * + * IN: + * @unit Default values unit. -1 if no unit should be displayed. + * @num Number of values to print. + * @wi Output width. + * @wd Number of decimal places. + *************************************************************************** +*/ +void cprintf_f(int unit, int num, int wi, int wd, ...) +{ + int i; + double val, lim = 0.005;; + va_list args; + + /* + * If there are decimal places then get the value + * entered on the command line (if existing). + */ + if ((wd > 0) && (dplaces_nr >= 0)) { + wd = dplaces_nr; + } + + /* Update limit value according to number of decimal places */ + if (wd == 1) { + lim = 0.05; + } + + va_start(args, wd); + + for (i = 0; i < num; i++) { + val = va_arg(args, double); + if (((wd > 0) && (val < lim) && (val > (lim * -1))) || + ((wd == 0) && (val <= 0.5) && (val >= -0.5))) { /* "Round half to even" law */ + printf("%s", sc_zero_int_stat); + } + else { + printf("%s", sc_int_stat); + } + + if (unit < 0) { + printf(" %*.*f", wi, wd, val); + printf("%s", sc_normal); + } + else { + cprintf_unit(unit, wi, val); + } + } + + va_end(args); +} + +/* + *************************************************************************** + * Print "percent" statistics values using colors. + * + * IN: + * @human Set to > 0 if a percent sign (%) shall be displayed after + * the value. + * @num Number of values to print. + * @wi Output width. + * @wd Number of decimal places. + *************************************************************************** +*/ +void cprintf_pc(int human, int num, int wi, int wd, ...) +{ + int i; + double val, lim = 0.005; + va_list args; + + /* + * If there are decimal places then get the value + * entered on the command line (if existing). + */ + if ((wd > 0) && (dplaces_nr >= 0)) { + wd = dplaces_nr; + } + + /* + * If a percent sign is to be displayed, then there will be + * zero (or one) decimal place. + */ + if (human > 0) { + if (wi < 4) { + /* E.g., 100% */ + wi = 4; + } + /* Keep one place for the percent sign */ + wi -= 1; + if (wd > 1) { + wd -= 1; + } + } + + /* Update limit value according to number of decimal places */ + if (wd == 1) { + lim = 0.05; + } + + va_start(args, wd); + + for (i = 0; i < num; i++) { + val = va_arg(args, double); + if (val >= PERCENT_LIMIT_HIGH) { + printf("%s", sc_percent_high); + } + else if (val >= PERCENT_LIMIT_LOW) { + printf("%s", sc_percent_low); + } + else if (((wd > 0) && (val < lim)) || + ((wd == 0) && (val <= 0.5))) { /* "Round half to even" law */ + printf("%s", sc_zero_int_stat); + } + else { + printf("%s", sc_int_stat); + } + printf(" %*.*f", wi, wd, val); + printf("%s", sc_normal); + if (human > 0) printf("%%"); + } + + va_end(args); +} + +/* + *************************************************************************** + * Print item name using selected color. + * Only one name can be displayed. Name can be an integer or a string. + * + * IN: + * @type 0 if name is an int, 1 if name is a string + * @format Output format. + * @item_string Item name (given as a string of characters). + * @item_int Item name (given as an integer value). + *************************************************************************** +*/ +void cprintf_in(int type, char *format, char *item_string, int item_int) +{ + printf("%s", sc_item_name); + if (type) { + printf(format, item_string); + } + else { + printf(format, item_int); + } + printf("%s", sc_normal); +} + +/* + *************************************************************************** + * Print a string using selected color. + * + * IN: + * @type Type of string to display. + * @format Output format. + * @string String to display. + *************************************************************************** +*/ +void cprintf_s(int type, char *format, char *string) +{ + if (type == IS_STR) { + printf("%s", sc_int_stat); + } + else if (type == IS_ZERO) { + printf("%s", sc_zero_int_stat); + } + else if (type == IS_RESTART) { + printf("%s", sc_sa_restart); + } + else { + /* IS_COMMENT */ + printf("%s", sc_sa_comment); + } + printf(format, string); + printf("%s", sc_normal); +} + +/* + *************************************************************************** + * Parse a string containing a numerical value (e.g. CPU or IRQ number). + * The string should contain only one value, not a range of values. + * + * IN: + * @s String to parse. + * @max_val Upper limit that value should not reach. + * + * OUT: + * @val Value, or -1 if the string @s was empty. + * + * RETURNS: + * 0 if the value has been properly read, 1 otherwise. + *************************************************************************** + */ +int parse_valstr(char *s, int max_val, int *val) +{ + if (!strlen(s)) { + *val = -1; + return 0; + } + if (strspn(s, DIGITS) != strlen(s)) + return 1; + + *val = atoi(s); + if ((*val < 0) || (*val >= max_val)) + return 1; + + return 0; +} + +/* + *************************************************************************** + * Parse string containing a set of coma-separated values or ranges of + * values (e.g. "0,2-5,10-"). The ALL keyword is allowed and indicate that + * all possible values are selected. + * + * IN: + * @strargv Current argument in list to parse. + * @bitmap Bitmap whose contents will indicate which values have been + * selected. + * @max_val Upper limit that value should not reach. + * @__K_VALUE0 Keyword corresponding to the first bit in bitmap (e.g "all", + * "SUM"...) + * + * OUT: + * @bitmap Bitmap updated with selected values. + * + * RETURNS: + * 0 on success, 1 otherwise. + *************************************************************************** + */ +int parse_values(char *strargv, unsigned char bitmap[], int max_val, const char *__K_VALUE0) +{ + int i, val_low, val; + char *t, *s, *valstr, range[16]; + + if (!strcmp(strargv, K_ALL)) { + /* Set bit for every possible values (CPU, IRQ, etc.) */ + memset(bitmap, ~0, BITMAP_SIZE(max_val)); + return 0; + } + + for (t = strtok(strargv, ","); t; t = strtok(NULL, ",")) { + if (!strcmp(t, __K_VALUE0)) { + /* + * Set bit 0 in bitmap. This may correspond + * to CPU "all" or IRQ "SUM" for example. + */ + bitmap[0] |= 1; + } + else { + /* Parse value or range of values */ + strncpy(range, t, 16); + range[15] = '\0'; + valstr = t; + if ((s = index(range, '-')) != NULL) { + /* Possible range of values */ + *s = '\0'; + if (parse_valstr(range, max_val, &val_low) || (val_low < 0)) + return 1; + valstr = s + 1; + } + if (parse_valstr(valstr, max_val, &val)) + return 1; + if (s && val < 0) { + /* Range of values with no upper limit (e.g. "3-") */ + val = max_val - 1; + } + if ((!s && (val < 0)) || (s && (val < val_low))) + /* + * Individual value: string cannot be empty. + * Range of values: n-m: m can be empty (e.g. "3-") but + * cannot be lower than n. + */ + return 1; + if (!s) { + val_low = val; + } + for (i = val_low; i <= val; i++) { + bitmap[(i + 1) >> 3] |= 1 << ((i + 1) & 0x07); + } + } + } + + return 0; +} +#endif /* SOURCE_SADC undefined */ diff --git a/tests/12.0.1/common.h b/tests/12.0.1/common.h new file mode 100644 index 0000000..050fb6c --- /dev/null +++ b/tests/12.0.1/common.h @@ -0,0 +1,298 @@ +/* + * sysstat: System performance tools for Linux + * (C) 1999-2018 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _COMMON_H +#define _COMMON_H + +/* Maximum length of sensors device name */ +#define MAX_SENSORS_DEV_LEN 20 + +#include +#include /* For __CPU_SETSIZE */ +#include +#include + +#ifdef HAVE_SYS_SYSMACROS_H +/* Needed on some non-glibc environments */ +#include +#endif + +/* + *************************************************************************** + * Various keywords and constants + *************************************************************************** + */ + +#define FALSE 0 +#define TRUE 1 + +#define PLAIN_OUTPUT 0 + +#define DISP_HDR 1 + +/* Index in units array (see common.c) */ +#define NO_UNIT -1 +#define UNIT_SECTOR 0 +#define UNIT_BYTE 1 +#define UNIT_KILOBYTE 2 + +#define NR_UNITS 8 + +/* Timestamp buffer length */ +#define TIMESTAMP_LEN 64 + +/* Number of seconds per day */ +#define SEC_PER_DAY 3600 * 24 + +/* Maximum number of CPUs */ +#if defined(__CPU_SETSIZE) && __CPU_SETSIZE > 8192 +#define NR_CPUS __CPU_SETSIZE +#else +#define NR_CPUS 8192 +#endif + +/* Maximum number of interrupts */ +#define NR_IRQS 4096 + +/* Size of /proc/interrupts line, CPU data excluded */ +#define INTERRUPTS_LINE 128 + +/* Keywords */ +#define K_ISO "ISO" +#define K_ALL "ALL" +#define K_LOWERALL "all" +#define K_UTC "UTC" +#define K_JSON "JSON" + +/* Files */ +#define STAT "/proc/stat" +#define UPTIME "/proc/uptime" +#define DISKSTATS "/proc/diskstats" +#define INTERRUPTS "/proc/interrupts" +#define MEMINFO "/proc/meminfo" +#define SYSFS_BLOCK "/sys/block" +#define SYSFS_DEV_BLOCK "/sys/dev/block" +#define SYSFS_DEVCPU "/sys/devices/system/cpu" +#define SYSFS_TIME_IN_STATE "cpufreq/stats/time_in_state" +#define S_STAT "stat" +#define DEVMAP_DIR "/dev/mapper" +#define DEVICES "/proc/devices" +#define SYSFS_USBDEV "/sys/bus/usb/devices" +#define DEV_DISK_BY "/dev/disk/by" +#define SYSFS_IDVENDOR "idVendor" +#define SYSFS_IDPRODUCT "idProduct" +#define SYSFS_BMAXPOWER "bMaxPower" +#define SYSFS_MANUFACTURER "manufacturer" +#define SYSFS_PRODUCT "product" +#define SYSFS_FCHOST "/sys/class/fc_host" + +#define MAX_FILE_LEN 512 +#define MAX_PF_NAME 1024 +#define MAX_NAME_LEN 128 + +#define IGNORE_VIRTUAL_DEVICES FALSE +#define ACCEPT_VIRTUAL_DEVICES TRUE + +/* Environment variables */ +#define ENV_TIME_FMT "S_TIME_FORMAT" +#define ENV_TIME_DEFTM "S_TIME_DEF_TIME" +#define ENV_COLORS "S_COLORS" +#define ENV_COLORS_SGR "S_COLORS_SGR" + +#define C_NEVER "never" +#define C_ALWAYS "always" + +#define DIGITS "0123456789" + +/* + *************************************************************************** + * Macro functions definitions. + *************************************************************************** + */ + +/* + * Macro used to define activity bitmap size. + * All those bitmaps have an additional bit used for global activity + * (eg. CPU "all" or total number of interrupts). That's why we do "(m) + 1". + */ +#define BITMAP_SIZE(m) ((((m) + 1) >> 3) + 1) + +/* Allocate and init structure */ +#define SREALLOC(S, TYPE, SIZE) do { \ + TYPE *_p_ = S; \ + if ((SIZE) != 0) { \ + if ((S = (TYPE *) realloc(S, (SIZE))) == NULL) { \ + perror("realloc"); \ + exit(4); \ + } \ + /* If the ptr was null, then it's a malloc() */ \ + if (!_p_) { \ + memset(S, 0, (SIZE)); \ + } \ + } \ + if (!S) { \ + /* Should never happen */ \ + fprintf(stderr, "srealloc\n"); \ + exit(4); \ + } \ + } while (0) + +/* + * Macros used to display statistics values. + * + */ +/* With S_VALUE macro, the interval of time (@p) is given in 1/100th of a second */ +#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * 100) +/* Define SP_VALUE() to normalize to % */ +#define SP_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * 100) + +/* + * Under very special circumstances, STDOUT may become unavailable. + * This is what we try to guess here. + */ +#define TEST_STDOUT(_fd_) do { \ + if (write(_fd_, "", 0) == -1) { \ + perror("stdout"); \ + exit(6); \ + } \ + } while (0) + +#define MINIMUM(a,b) ((a) < (b) ? (a) : (b)) + +#define PANIC(m) sysstat_panic(__FUNCTION__, m) + +/* Number of ticks per second */ +#define HZ hz +extern unsigned long hz; + +/* Number of bit shifts to convert pages to kB */ +extern unsigned int kb_shift; + +/* + * kB <-> number of pages. + * Page size depends on machine architecture (4 kB, 8 kB, 16 kB, 64 kB...) + */ +#define KB_TO_PG(k) ((k) >> kb_shift) +#define PG_TO_KB(k) ((k) << kb_shift) + +/* Type of persistent device names used in sar and iostat */ +extern char persistent_name_type[MAX_FILE_LEN]; + +/* + *************************************************************************** + * Colors definitions + *************************************************************************** + */ + +#define C_LIGHT_RED "\e[31;22m" +#define C_BOLD_RED "\e[31;1m" +#define C_LIGHT_GREEN "\e[32;22m" +#define C_LIGHT_YELLOW "\e[33;22m" +#define C_BOLD_MAGENTA "\e[35;1m" +#define C_BOLD_BLUE "\e[34;1m" +#define C_LIGHT_BLUE "\e[34;22m" +#define C_NORMAL "\e[0m" + +#define PERCENT_LIMIT_HIGH 75.0 +#define PERCENT_LIMIT_LOW 50.0 + +#define MAX_SGR_LEN 16 + +#define IS_INT 0 +#define IS_STR 1 +#define IS_RESTART 2 +#define IS_COMMENT 3 +#define IS_ZERO 4 + +/* + *************************************************************************** + * Structures definitions + *************************************************************************** + */ + +/* Structure used for extended disk statistics */ +struct ext_disk_stats { + double util; + double await; + double svctm; + double arqsz; +}; + +/* + *************************************************************************** + * Functions prototypes + *************************************************************************** + */ +void print_version + (void); +void get_HZ + (void); +void get_kb_shift + (void); +time_t get_localtime + (struct tm *, int); +time_t get_time + (struct tm *, int); +void init_nls + (void); +int is_device + (char *, int); +void sysstat_panic + (const char *, int); + +#ifndef SOURCE_SADC +int count_bits + (void *, int); +int count_csvalues + (int, char **); +void cprintf_f + (int, int, int, int, ...); +void cprintf_in + (int, char *, char *, int); +void cprintf_pc + (int, int, int, int, ...); +void cprintf_s + (int, char *, char *); +void cprintf_u64 + (int, int, int, ...); +void cprintf_x + (int, int, ...); +char *device_name + (char *); +unsigned int get_devmap_major + (void); +unsigned long long get_interval + (unsigned long long, unsigned long long); +char *get_persistent_name_from_pretty + (char *); +char *get_persistent_type_dir + (char *); +char *get_pretty_name_from_persistent + (char *); +int get_sysfs_dev_nr + (int); +int get_win_height + (void); +void init_colors + (void); +double ll_sp_value + (unsigned long long, unsigned long long, unsigned long long); +int is_iso_time_fmt + (void); +int parse_values + (char *, unsigned char[], int, const char *); +int print_gal_header + (struct tm *, char *, char *, char *, char *, int, int); +int set_report_date + (struct tm *, char[], int); +char *strtolower + (char *); +void xprintf + (int, const char *, ...); +void xprintf0 + (int, const char *, ...); + +#endif /* SOURCE_SADC undefined */ +#endif /* _COMMON_H */ diff --git a/tests/12.0.1/count.c b/tests/12.0.1/count.c new file mode 100644 index 0000000..4e008b1 --- /dev/null +++ b/tests/12.0.1/count.c @@ -0,0 +1,266 @@ +/* + * count.c: Count items for which statistics will be collected. + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "rd_stats.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + + +/* + *************************************************************************** + * Count number of processors in /sys. + * + * IN: + * @highest If set to TRUE, then look for the highest processor number. + * This is used when eg. the machine has 4 CPU numbered 0, 1, 4 + * and 5. In this case, this procedure will return 6. + * + * RETURNS: + * Number of processors (online and offline). + * A value of 0 means that /sys was not mounted. + * A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)). + *************************************************************************** + */ +int get_sys_cpu_nr(int highest) +{ + DIR *dir; + struct dirent *drd; + struct stat buf; + char line[MAX_PF_NAME]; + int num_proc, proc_nr = -1; + + /* Open relevant /sys directory */ + if ((dir = opendir(SYSFS_DEVCPU)) == NULL) + return 0; + + /* Get current file entry */ + while ((drd = readdir(dir)) != NULL) { + + if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) { + snprintf(line, MAX_PF_NAME, "%s/%s", SYSFS_DEVCPU, drd->d_name); + line[MAX_PF_NAME - 1] = '\0'; + if (stat(line, &buf) < 0) + continue; + if (S_ISDIR(buf.st_mode)) { + if (highest) { + sscanf(drd->d_name + 3, "%d", &num_proc); + if (num_proc > proc_nr) { + proc_nr = num_proc; + } + } + else { + proc_nr++; + } + } + } + } + + /* Close directory */ + closedir(dir); + + return (proc_nr + 1); +} + +/* + *************************************************************************** + * Count number of processors in /proc/stat. + * + * RETURNS: + * Number of processors. The returned value is greater than or equal to the + * number of online processors. + * A value of 0 means one processor and non SMP kernel. + * A value of N (!=0) means N processor(s) (0 .. N-1) with SMP kernel. + *************************************************************************** + */ +int get_proc_cpu_nr(void) +{ + FILE *fp; + char line[16]; + int num_proc, proc_nr = -1; + + if ((fp = fopen(STAT, "r")) == NULL) { + fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno)); + exit(1); + } + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (strncmp(line, "cpu ", 4) && !strncmp(line, "cpu", 3)) { + sscanf(line + 3, "%d", &num_proc); + if (num_proc > proc_nr) { + proc_nr = num_proc; + } + } + } + + fclose(fp); + + proc_nr++; + return proc_nr; +} + +/* + *************************************************************************** + * Count the number of processors on the machine, or look for the + * highest processor number. + * Try to use /sys for that, or /proc/stat if /sys doesn't exist. + * + * IN: + * @max_nr_cpus Maximum number of proc that sysstat can handle. + * @highest If set to TRUE, then look for the highest processor number. + * This is used when eg. the machine has 4 CPU numbered 0, 1, 4 + * and 5. In this case, this procedure will return 6. + * + * RETURNS: + * Number of processors. + * 0: one proc and non SMP kernel. + * 1: one proc and SMP kernel (NB: On SMP machines where all the CPUs but + * one have been disabled, we get the total number of proc since we use + * /sys to count them). + * 2: two proc... + *************************************************************************** + */ +__nr_t get_cpu_nr(unsigned int max_nr_cpus, int highest) +{ + __nr_t cpu_nr; + + if ((cpu_nr = get_sys_cpu_nr(highest)) == 0) { + /* /sys may be not mounted. Use /proc/stat instead */ + cpu_nr = get_proc_cpu_nr(); + } + + if (cpu_nr > max_nr_cpus) { + fprintf(stderr, _("Cannot handle so many processors!\n")); + exit(1); + } + + return cpu_nr; +} + +/* + *************************************************************************** + * Find number of interrupts available per processor (use + * /proc/interrupts file or /proc/softirqs). + * + * IN: + * @file /proc file to read (interrupts or softirqs). + * @max_nr_irqcpu Maximum number of interrupts per processor that + * sadc can handle. + * @cpu_nr Number of processors. + * + * RETURNS: + * Number of interrupts per processor. + *************************************************************************** + */ +__nr_t get_irqcpu_nr(char *file, int max_nr_irqcpu, int cpu_nr) +{ + FILE *fp; + char *line = NULL; + __nr_t irq = 0; + int p; + + if ((fp = fopen(file, "r")) == NULL) + return 0; /* No interrupts file */ + + SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr); + + while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr , fp) != NULL) && + (irq < max_nr_irqcpu)) { + p = strcspn(line, ":"); + if ((p > 0) && (p < 16)) { + irq++; + } + } + + fclose(fp); + + free(line); + + return irq; +} + +/* + *************************************************************************** + * Find number of devices and partitions available in /proc/diskstats. + * + * IN: + * @count_part Set to TRUE if devices _and_ partitions are to be + * counted. + * @only_used_dev When counting devices, set to TRUE if only devices + * with non zero stats must be counted. + * + * RETURNS: + * Number of devices (and partitions). + *************************************************************************** + */ +__nr_t get_diskstats_dev_nr(int count_part, int only_used_dev) +{ + FILE *fp; + char line[256]; + char dev_name[MAX_NAME_LEN]; + __nr_t dev = 0; + int i; + unsigned long rd_ios, wr_ios; + + if ((fp = fopen(DISKSTATS, "r")) == NULL) + /* File non-existent */ + return 0; + + /* + * Counting devices and partitions is simply a matter of counting + * the number of lines... + */ + while (fgets(line, sizeof(line), fp) != NULL) { + if (!count_part) { + i = sscanf(line, "%*d %*d %s %lu %*u %*u %*u %lu", + dev_name, &rd_ios, &wr_ios); + if ((i == 2) || !is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) + /* It was a partition and not a device */ + continue; + if (only_used_dev && !rd_ios && !wr_ios) + /* Unused device */ + continue; + } + dev++; + } + + fclose(fp); + + return dev; +} diff --git a/tests/12.0.1/format.c b/tests/12.0.1/format.c new file mode 100644 index 0000000..120ccf5 --- /dev/null +++ b/tests/12.0.1/format.c @@ -0,0 +1,48 @@ +/* + * format.c: Output format definitions for sadf and sar + * (C) 2011-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#ifdef SOURCE_SAR +#include "sa.h" +#endif + +/* + *************************************************************************** + * Definitions of output formats. + * See sadf.h file for format structure definition. + *************************************************************************** + */ + +#ifdef SOURCE_SAR +/* + * Special output format for sar. + * Used only for functions to display special + * (RESTART and COMMENT) records. + */ +struct report_format sar_fmt = { + .id = 0, + .options = 0, + .f_header = NULL, + .f_statistics = NULL, + .f_timestamp = NULL, + .f_restart = print_sar_restart, + .f_comment = print_sar_comment +}; +#endif diff --git a/tests/12.0.1/inisar.c b/tests/12.0.1/inisar.c new file mode 100644 index 0000000..cc9cacf --- /dev/null +++ b/tests/12.0.1/inisar.c @@ -0,0 +1,1088 @@ +/* + * sar: report system activity + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "version.h" +#include "sa.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +#ifdef USE_SCCSID +#define SCCSID "@(#)sysstat-" VERSION ": " __FILE__ " compiled " __DATE__ " " __TIME__ +char *sccsid(void) { return (SCCSID); } +#endif + +/* Interval and count parameters */ +long interval = -1, count = 0; + +/* TRUE if a header line must be printed */ +int dis = TRUE; +/* TRUE if data read from file don't match current machine's endianness */ +int endian_mismatch = FALSE; +/* TRUE if file's data come from a 64 bit machine */ +int arch_64 = FALSE; +/* Number of decimal places */ +int dplaces_nr = -1; + +unsigned int flags = 0; +unsigned int dm_major; /* Device-mapper major number */ + +char timestamp[2][TIMESTAMP_LEN]; +extern unsigned int rec_types_nr[]; + +unsigned long avg_count = 0; + +/* File header */ +struct file_header file_hdr; + +/* Current record header */ +struct record_header record_hdr[3]; + +/* + * Activity sequence. + * This array must always be entirely filled (even with trailing zeros). + */ +unsigned int id_seq[NR_ACT]; + +struct tm rectime; + +/* Contain the date specified by -s and -e options */ +struct tstamp tm_start, tm_end; + +char *args[MAX_ARGV_NR]; + +extern struct activity *act[]; +extern struct report_format sar_fmt; + +struct sigaction int_act; +int sigint_caught = 0; + +/* + *************************************************************************** + * Print usage title message. + * + * IN: + * @progname Name of sysstat command + *************************************************************************** + */ +void print_usage_title(FILE *fp, char *progname) +{ + fprintf(fp, _("Usage: %s [ options ] [ [ ] ]\n"), + progname); +} + +/* + *************************************************************************** + * Print usage and exit. + * + * IN: + * @progname Name of sysstat command + *************************************************************************** + */ +void usage(char *progname) +{ + print_usage_title(stderr, progname); + fprintf(stderr, _("Options are:\n" + "[ -A ] [ -B ] [ -b ] [ -C ] [ -D ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ]\n" + "[ -p ] [ -q ] [ -r [ ALL ] ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ]\n" + "[ -v ] [ -W ] [ -w ] [ -y ] [ -z ]\n" + "[ -I { | SUM | ALL } ] [ -P { | ALL } ]\n" + "[ -m { [,...] | ALL } ] [ -n { [,...] | ALL } ]\n" + "[ --dev= ] [ --fs= ] [ --iface= ]\n" + "[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --sadc ]\n" + "[ -j { ID | LABEL | PATH | UUID | ... } ]\n" + "[ -f [ ] | -o [ ] | -[0-9]+ ]\n" + "[ -i ] [ -s [ ] ] [ -e [ ] ]\n")); + exit(1); +} + +/* + *************************************************************************** + * SIGINT signal handler. + * + * IN: + * @sig Signal number. + *************************************************************************** + */ +void int_handler(int sig) +{ + sigint_caught = 1; + printf("\n"); /* Skip "^C" displayed on screen */ + +} + +/* + *************************************************************************** + * Init some structures. + *************************************************************************** + */ +void init_structures(void) +{ + int i; + + for (i = 0; i < 3; i++) + memset(&record_hdr[i], 0, RECORD_HEADER_SIZE); +} + +/* + *************************************************************************** + * Display an error message. + * + * IN: + * @error_code Code of error message to display. + *************************************************************************** + */ +void print_read_error(int error_code) +{ + switch (error_code) { + + case END_OF_DATA_UNEXPECTED: + /* Happens when the data collector doesn't send enough data */ + fprintf(stderr, _("End of data collecting unexpected\n")); + break; + + default: + /* Strange data sent by sadc...! */ + fprintf(stderr, _("Inconsistent input data\n")); + break; + } + exit(3); +} + +/* + *************************************************************************** + * Check that every selected activity actually belongs to the sequence list. + * If not, then the activity should be unselected since it will not be sent + * by sadc. An activity can be not sent if its number of items is zero. + * + * IN: + * @act_nr Size of sequence list. + *************************************************************************** + */ +void reverse_check_act(unsigned int act_nr) +{ + int i, j; + + for (i = 0; i < NR_ACT; i++) { + + if (IS_SELECTED(act[i]->options)) { + + for (j = 0; j < act_nr; j++) { + if (id_seq[j] == act[i]->id) + break; + } + if (j == act_nr) + act[i]->options &= ~AO_SELECTED; + } + } +} + +/* + *************************************************************************** + * Determine if a stat header line has to be displayed. + * + * RETURNS: + * TRUE if a header line has to be displayed. + *************************************************************************** +*/ +int check_line_hdr(void) +{ + int i, rc = FALSE; + + /* Get number of options entered on the command line */ + if (get_activity_nr(act, AO_SELECTED, COUNT_OUTPUTS) > 1) + return TRUE; + + for (i = 0; i < NR_ACT; i++) { + if (IS_SELECTED(act[i]->options)) { + /* Special processing for activities using a bitmap */ + if (act[i]->bitmap) { + if (count_bits(act[i]->bitmap->b_array, + BITMAP_SIZE(act[i]->bitmap->b_size)) > 1) { + rc = TRUE; + } + } + else if (act[i]->nr_ini > 1) { + rc = TRUE; + } + /* Stop now since we have only one selected activity */ + break; + } + } + + return rc; +} + +/* + *************************************************************************** + * Print statistics average. + * + * IN: + * @curr Index in array for current sample statistics. + * @read_from_file Set to TRUE if stats are read from a system activity + * data file. + * @act_id Activity that can be displayed, or ~0 for all. + * Remember that when reading stats from a file, only + * one activity can be displayed at a time. + *************************************************************************** + */ +void write_stats_avg(int curr, int read_from_file, unsigned int act_id) +{ + int i; + unsigned long long itv; + + /* Interval value in 1/100th of a second */ + itv = get_interval(record_hdr[2].uptime_cs, record_hdr[curr].uptime_cs); + + strncpy(timestamp[curr], _("Average:"), TIMESTAMP_LEN); + timestamp[curr][TIMESTAMP_LEN - 1] = '\0'; + memcpy(timestamp[!curr], timestamp[curr], TIMESTAMP_LEN); + + /* Test stdout */ + TEST_STDOUT(STDOUT_FILENO); + + for (i = 0; i < NR_ACT; i++) { + + if ((act_id != ALL_ACTIVITIES) && (act[i]->id != act_id)) + continue; + + if (IS_SELECTED(act[i]->options) && (act[i]->nr[curr] > 0)) { + /* Display current average activity statistics */ + (*act[i]->f_print_avg)(act[i], 2, curr, itv); + } + } + + if (read_from_file) { + /* + * Reset number of lines printed only if we read stats + * from a system activity file. + */ + avg_count = 0; + } +} + +/* + *************************************************************************** + * Print system statistics. + * This is called when we read stats either from a file or from sadc. + * + * IN: + * @curr Index in array for current sample statistics. + * @read_from_file Set to TRUE if stats are read from a system activity + * data file. + * @use_tm_start Set to TRUE if option -s has been used. + * @use_tm_end Set to TRUE if option -e has been used. + * @reset Set to TRUE if last_uptime variable should be + * reinitialized (used in next_slice() function). + * @act_id Activity that can be displayed or ~0 for all. + * Remember that when reading stats from a file, only + * one activity can be displayed at a time. + * @reset_cd TRUE if static cross_day variable should be reset + * (see below). + * + * OUT: + * @cnt Number of remaining lines to display. + * + * RETURNS: + * 1 if stats have been successfully displayed, and 0 otherwise. + *************************************************************************** + */ +int write_stats(int curr, int read_from_file, long *cnt, int use_tm_start, + int use_tm_end, int reset, unsigned int act_id, int reset_cd) +{ + int i; + unsigned long long itv; + static int cross_day = 0; + + if (reset_cd) { + /* + * cross_day is a static variable that is set to 1 when the first + * record of stats from a new day is read from a unique data file + * (in the case where the file contains data from two consecutive + * days). When set to 1, every following records timestamp will + * have its hour value increased by 24. + * Yet when a new activity (being read from the file) is going to + * be displayed, we start reading the file from the beginning + * again, and so cross_day should be reset in this case. + */ + cross_day = 0; + } + + /* Check time (1) */ + if (read_from_file) { + if (!next_slice(record_hdr[2].uptime_cs, record_hdr[curr].uptime_cs, + reset, interval)) + /* Not close enough to desired interval */ + return 0; + } + + if (!is_iso_time_fmt()) + flags |= S_F_PREFD_TIME_OUTPUT; + + /* Get then set previous timestamp */ + if (sa_get_record_timestamp_struct(flags + S_F_LOCAL_TIME, &record_hdr[!curr], + &rectime, NULL)) + return 0; + set_record_timestamp_string(flags, &record_hdr[!curr], + NULL, timestamp[!curr], TIMESTAMP_LEN, &rectime); + + /* Get then set current timestamp */ + if (sa_get_record_timestamp_struct(flags + S_F_LOCAL_TIME, &record_hdr[curr], + &rectime, NULL)) + return 0; + set_record_timestamp_string(flags, &record_hdr[curr], + NULL, timestamp[curr], TIMESTAMP_LEN, &rectime); + + /* Check if we are beginning a new day */ + if (use_tm_start && record_hdr[!curr].ust_time && + (record_hdr[curr].ust_time > record_hdr[!curr].ust_time) && + (record_hdr[curr].hour < record_hdr[!curr].hour)) { + cross_day = 1; + } + + if (cross_day) { + /* + * This is necessary if we want to properly handle something like: + * sar -s time_start -e time_end with + * time_start(day D) > time_end(day D+1) + */ + rectime.tm_hour += 24; + } + + /* Check time (2) */ + if (use_tm_start && (datecmp(&rectime, &tm_start) < 0)) + /* it's too soon... */ + return 0; + + /* Get interval value in 1/100th of a second */ + get_itv_value(&record_hdr[curr], &record_hdr[!curr], &itv); + + /* Check time (3) */ + if (use_tm_end && (datecmp(&rectime, &tm_end) > 0)) { + /* It's too late... */ + *cnt = 0; + return 0; + } + + avg_count++; + + /* Test stdout */ + TEST_STDOUT(STDOUT_FILENO); + + for (i = 0; i < NR_ACT; i++) { + + if ((act_id != ALL_ACTIVITIES) && (act[i]->id != act_id)) + continue; + + if (IS_SELECTED(act[i]->options) && (act[i]->nr[curr] > 0)) { + /* Display current activity statistics */ + (*act[i]->f_print)(act[i], !curr, curr, itv); + } + } + + return 1; +} + +/* + *************************************************************************** + * Display stats since system startup. + * + * IN: + * @curr Index in array for current sample statistics. + *************************************************************************** + */ +void write_stats_startup(int curr) +{ + int i; + + /* Set to 0 previous structures corresponding to boot time */ + memset(&record_hdr[!curr], 0, RECORD_HEADER_SIZE); + record_hdr[!curr].record_type = R_STATS; + record_hdr[!curr].hour = record_hdr[curr].hour; + record_hdr[!curr].minute = record_hdr[curr].minute; + record_hdr[!curr].second = record_hdr[curr].second; + record_hdr[!curr].ust_time = record_hdr[curr].ust_time; + + for (i = 0; i < NR_ACT; i++) { + if (IS_SELECTED(act[i]->options) && (act[i]->nr[curr] > 0)) { + /* + * Using nr[curr] and not nr[!curr] below because we initialize + * reference structures for each structure that has been + * currently read in memory. + * No problem with buffers allocation since they all have the + * same size. + */ + memset(act[i]->buf[!curr], 0, + (size_t) act[i]->msize * (size_t) act[i]->nr[curr] * (size_t) act[i]->nr2); + } + } + + flags |= S_F_SINCE_BOOT; + dis = TRUE; + + write_stats(curr, USE_SADC, &count, NO_TM_START, NO_TM_END, NO_RESET, + ALL_ACTIVITIES, TRUE); + + exit(0); +} + +/* + *************************************************************************** + * Display a restart message (contents of a R_RESTART record). + * + * IN: + * @tab Number of tabulations (unused here). + * @action Action expected from current function (unused here). + * @cur_date Date string of current restart message (unused here). + * @cur_time Time string of current restart message. + * @utc True if @cur_time is expressed in UTC (unused here). + * @file_hdr System activity file standard header (unused here). + *************************************************************************** + */ +__printf_funct_t print_sar_restart(int *tab, int action, char *cur_date, char *cur_time, + int utc, struct file_header *file_hdr) +{ + char restart[64]; + + printf("\n%-11s", cur_time); + sprintf(restart, " LINUX RESTART\t(%d CPU)\n", + file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1); + cprintf_s(IS_RESTART, "%s", restart); + +} + +/* + *************************************************************************** + * Display a comment (contents of R_COMMENT record). + * + * IN: + * @tab Number of tabulations (unused here). + * @action Action expected from current function (unused here). + * @cur_date Date string of current comment (unused here). + * @cur_time Time string of current comment. + * @utc True if @cur_time is expressed in UTC (unused here). + * @comment Comment to display. + * @file_hdr System activity file standard header (unused here). + *************************************************************************** + */ +__print_funct_t print_sar_comment(int *tab, int action, char *cur_date, char *cur_time, int utc, + char *comment, struct file_header *file_hdr) +{ + printf("%-11s", cur_time); + cprintf_s(IS_COMMENT, " COM %s\n", comment); +} + +/* + *************************************************************************** + * Read stats for current activity from file and display them. + * + * IN: + * @ifd Input file descriptor. + * @fpos Position in file where reading must start. + * @curr Index in array for current sample statistics. + * @rows Number of rows of screen. + * @act_id Activity to display. + * @file_actlst List of activities in file. + * @file Name of file being read. + * @file_magic file_magic structure filled with file magic header data. + * @rec_hdr_tmp Temporary buffer where current record header will be saved. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @arch_64 TRUE if file's data come from a 64 bit machine. + * + * OUT: + * @curr Index in array for next sample statistics. + * @cnt Number of remaining lines of stats to write. + * @eosaf Set to TRUE if EOF (end of file) has been reached. + * @reset Set to TRUE if last_uptime variable should be reinitialized + * (used in next_slice() function). + *************************************************************************** + */ +void handle_curr_act_stats(int ifd, off_t fpos, int *curr, long *cnt, int *eosaf, + int rows, unsigned int act_id, int *reset, + struct file_activity *file_actlst, char *file, + struct file_magic *file_magic, void *rec_hdr_tmp, + int endian_mismatch, int arch_64) +{ + int p, reset_cd; + unsigned long lines = 0; + unsigned char rtype; + int davg = 0, next, inc = 0; + + if (lseek(ifd, fpos, SEEK_SET) < fpos) { + perror("lseek"); + exit(2); + } + + /* + * Restore the first stats collected. + * Used to compute the rate displayed on the first line. + */ + copy_structures(act, id_seq, record_hdr, !*curr, 2); + + *cnt = count; + + /* Assess number of lines printed when a bitmap is used */ + p = get_activity_position(act, act_id, EXIT_IF_NOT_FOUND); + if (act[p]->bitmap) { + inc = count_bits(act[p]->bitmap->b_array, + BITMAP_SIZE(act[p]->bitmap->b_size)); + } + reset_cd = 1; + + do { + /* + * Display lines of stats. + * Start with reading current sample's record header. + */ + *eosaf = read_record_hdr(ifd, rec_hdr_tmp, &record_hdr[*curr], + &file_hdr, arch_64, endian_mismatch); + rtype = record_hdr[*curr].record_type; + + if (!*eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { + /* Read the extra fields since it's not a special record */ + read_file_stat_bunch(act, *curr, ifd, file_hdr.sa_act_nr, file_actlst, + endian_mismatch, arch_64, file, file_magic); + } + + if ((lines >= rows) || !lines) { + lines = 0; + dis = 1; + } + else + dis = 0; + + if (!*eosaf && (rtype != R_RESTART)) { + + if (rtype == R_COMMENT) { + /* Display comment */ + next = print_special_record(&record_hdr[*curr], flags + S_F_LOCAL_TIME, + &tm_start, &tm_end, R_COMMENT, ifd, + &rectime, NULL, file, 0, + file_magic, &file_hdr, act, &sar_fmt, + endian_mismatch, arch_64); + if (next) { + /* A line of comment was actually displayed */ + lines++; + } + continue; + } + + /* next is set to 1 when we were close enough to desired interval */ + next = write_stats(*curr, USE_SA_FILE, cnt, tm_start.use, tm_end.use, + *reset, act_id, reset_cd); + reset_cd = 0; + if (next && (*cnt > 0)) { + (*cnt)--; + } + + if (next) { + davg++; + *curr ^= 1; + + if (inc) { + lines += inc; + } + else { + lines += act[p]->nr[*curr]; + } + } + *reset = FALSE; + } + } + while (*cnt && !*eosaf && (rtype != R_RESTART)); + + if (davg) { + write_stats_avg(!*curr, USE_SA_FILE, act_id); + } + + *reset = TRUE; +} + +/* + *************************************************************************** + * Read statistics from a system activity data file. + * + * IN: + * @from_file Input file name. + *************************************************************************** + */ +void read_stats_from_file(char from_file[]) +{ + struct file_magic file_magic; + struct file_activity *file_actlst = NULL; + char rec_hdr_tmp[MAX_RECORD_HEADER_SIZE]; + int curr = 1, i, p; + int ifd, rtype; + int rows, eosaf = TRUE, reset = FALSE; + long cnt = 1; + off_t fpos; + + /* Get window size */ + rows = get_win_height(); + + /* Read file headers and activity list */ + check_file_actlst(&ifd, from_file, act, &file_magic, &file_hdr, + &file_actlst, id_seq, FALSE, &endian_mismatch, &arch_64); + + /* Perform required allocations */ + allocate_structures(act); + + /* Print report header */ + print_report_hdr(flags, &rectime, &file_hdr); + + /* Read system statistics from file */ + do { + /* + * If this record is a special (RESTART or COMMENT) one, print it and + * (try to) get another one. + */ + do { + if (read_record_hdr(ifd, rec_hdr_tmp, &record_hdr[0], &file_hdr, + arch_64, endian_mismatch)) { + /* End of sa data file */ + return; + } + + rtype = record_hdr[0].record_type; + if ((rtype == R_RESTART) || (rtype == R_COMMENT)) { + print_special_record(&record_hdr[0], flags + S_F_LOCAL_TIME, + &tm_start, &tm_end, rtype, ifd, + &rectime, NULL, from_file, 0, &file_magic, + &file_hdr, act, &sar_fmt, endian_mismatch, arch_64); + } + else { + /* + * OK: Previous record was not a special one. + * So read now the extra fields. + */ + read_file_stat_bunch(act, 0, ifd, file_hdr.sa_act_nr, + file_actlst, endian_mismatch, arch_64, + from_file, &file_magic); + if (sa_get_record_timestamp_struct(flags + S_F_LOCAL_TIME, + &record_hdr[0], + &rectime, NULL)) + /* + * An error was detected. + * The timestamp hasn't been updated. + */ + continue; + } + } + while ((rtype == R_RESTART) || (rtype == R_COMMENT) || + (tm_start.use && (datecmp(&rectime, &tm_start) < 0)) || + (tm_end.use && (datecmp(&rectime, &tm_end) >=0))); + + /* Save the first stats collected. Will be used to compute the average */ + copy_structures(act, id_seq, record_hdr, 2, 0); + + reset = TRUE; /* Set flag to reset last_uptime variable */ + + /* Save current file position */ + if ((fpos = lseek(ifd, 0, SEEK_CUR)) < 0) { + perror("lseek"); + exit(2); + } + + /* + * Read and write stats located between two possible Linux restarts. + * Activities that should be displayed are saved in id_seq[] array. + * Since we are reading from a file, we print all the stats for an + * activity before displaying the next activity. + * id_seq[] has been created in check_file_actlst(), retaining only + * activities known by current sysstat version. + */ + for (i = 0; i < NR_ACT; i++) { + + if (!id_seq[i]) + continue; + + p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND); + if (!IS_SELECTED(act[p]->options)) + continue; + + if (!HAS_MULTIPLE_OUTPUTS(act[p]->options)) { + handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, rows, + act[p]->id, &reset, file_actlst, + from_file, &file_magic, rec_hdr_tmp, + endian_mismatch, arch_64); + } + else { + unsigned int optf, msk; + + optf = act[p]->opt_flags; + + for (msk = 1; msk < 0x100; msk <<= 1) { + if ((act[p]->opt_flags & 0xff) & msk) { + act[p]->opt_flags &= (0xffffff00 + msk); + + handle_curr_act_stats(ifd, fpos, &curr, &cnt, &eosaf, + rows, act[p]->id, &reset, file_actlst, + from_file, &file_magic, rec_hdr_tmp, + endian_mismatch, arch_64); + act[p]->opt_flags = optf; + } + } + } + } + + if (!cnt) { + /* Go to next Linux restart, if possible */ + do { + /* Read next record header */ + eosaf = read_record_hdr(ifd, rec_hdr_tmp, &record_hdr[curr], + &file_hdr, arch_64, endian_mismatch); + rtype = record_hdr[curr].record_type; + + if (!eosaf && (rtype != R_RESTART) && (rtype != R_COMMENT)) { + read_file_stat_bunch(act, curr, ifd, file_hdr.sa_act_nr, + file_actlst, endian_mismatch, arch_64, + from_file, &file_magic); + } + else if (!eosaf && (rtype == R_COMMENT)) { + /* This was a COMMENT record: print it */ + print_special_record(&record_hdr[curr], flags + S_F_LOCAL_TIME, + &tm_start, &tm_end, R_COMMENT, ifd, + &rectime, NULL, from_file, 0, + &file_magic, &file_hdr, act, &sar_fmt, + endian_mismatch, arch_64); + } + } + while (!eosaf && (rtype != R_RESTART)); + } + + /* The last record we read was a RESTART one: Print it */ + if (!eosaf && (record_hdr[curr].record_type == R_RESTART)) { + print_special_record(&record_hdr[curr], flags + S_F_LOCAL_TIME, + &tm_start, &tm_end, R_RESTART, ifd, + &rectime, NULL, from_file, 0, + &file_magic, &file_hdr, act, &sar_fmt, + endian_mismatch, arch_64); + } + } + while (!eosaf); + + close(ifd); + + free(file_actlst); +} + +/* + *************************************************************************** + * Main entry to the sar program. + *************************************************************************** + */ +int main(int argc, char **argv) +{ + int rc, opt = 1, p, q; + int day_offset = 0; + char from_file[MAX_FILE_LEN], to_file[MAX_FILE_LEN]; + + /* Compute page shift in kB */ + get_kb_shift(); + + from_file[0] = to_file[0] = '\0'; + +#ifdef USE_NLS + /* Init National Language Support */ + init_nls(); +#endif + + /* Init color strings */ + init_colors(); + + tm_start.use = tm_end.use = FALSE; + + /* Allocate and init activity bitmaps */ + allocate_bitmaps(act); + + init_structures(); + + /* Process options */ + while (opt < argc) { + + if (!strncmp(argv[opt], "--dev=", 6)) { + /* Parse devices entered on the command line */ + p = get_activity_position(act, A_DISK, EXIT_IF_NOT_FOUND); + parse_sa_devices(argv[opt], act[p], MAX_DEV_LEN, &opt, 6); + } + + else if (!strncmp(argv[opt], "--fs=", 5)) { + /* Parse devices entered on the command line */ + p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND); + parse_sa_devices(argv[opt], act[p], MAX_FS_LEN, &opt, 5); + } + + else if (!strncmp(argv[opt], "--iface=", 8)) { + /* Parse devices entered on the command line */ + p = get_activity_position(act, A_NET_DEV, EXIT_IF_NOT_FOUND); + parse_sa_devices(argv[opt], act[p], MAX_IFACE_LEN, &opt, 8); + q = get_activity_position(act, A_NET_EDEV, EXIT_IF_NOT_FOUND); + act[q]->item_list = act[p]->item_list; + act[q]->item_list_sz = act[p]->item_list_sz; + act[q]->options |= AO_LIST_ON_CMDLINE; + } + + else if (!strcmp(argv[opt], "--human")) { + /* Display sizes in a human readable format */ + flags |= S_F_UNIT; + opt++; + } + + else if (!strncmp(argv[opt], "--dec=", 6) && (strlen(argv[opt]) == 7)) { + /* Get number of decimal places */ + dplaces_nr = atoi(argv[opt] + 6); + if ((dplaces_nr < 0) || (dplaces_nr > 2)) { + usage(argv[0]); + } + opt++; + } + + else if (!strcmp(argv[opt], "-I")) { + /* Parse -I option */ + if (parse_sar_I_opt(argv, &opt, act)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-D")) { + /* Option to tell sar to write to saYYYYMMDD data files */ + flags |= S_F_SA_YYYYMMDD; + opt++; + } + + else if (!strcmp(argv[opt], "-P")) { + /* Parse -P option */ + if (parse_sa_P_opt(argv, &opt, &flags, act)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-o")) { + if (to_file[0]) { + /* Output file already specified */ + usage(argv[0]); + } + /* Save stats to a file */ + if ((argv[++opt]) && strncmp(argv[opt], "-", 1) && + (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) { + strncpy(to_file, argv[opt++], MAX_FILE_LEN); + to_file[MAX_FILE_LEN - 1] = '\0'; + } + else { + strcpy(to_file, "-"); + } + } + + else if (!strcmp(argv[opt], "-f")) { + if (from_file[0] || day_offset) { + /* Input file already specified */ + usage(argv[0]); + } + /* Read stats from a file */ + if ((argv[++opt]) && strncmp(argv[opt], "-", 1) && + (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) { + strncpy(from_file, argv[opt++], MAX_FILE_LEN); + from_file[MAX_FILE_LEN - 1] = '\0'; + /* Check if this is an alternate directory for sa files */ + check_alt_sa_dir(from_file, day_offset, -1); + } + else { + set_default_file(from_file, day_offset, -1); + } + } + + else if (!strcmp(argv[opt], "-s")) { + /* Get time start */ + if (parse_timestamp(argv, &opt, &tm_start, DEF_TMSTART)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-e")) { + /* Get time end */ + if (parse_timestamp(argv, &opt, &tm_end, DEF_TMEND)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-i")) { + if (!argv[++opt] || (strspn(argv[opt], DIGITS) != strlen(argv[opt]))) { + usage(argv[0]); + } + interval = atol(argv[opt++]); + if (interval < 1) { + usage(argv[0]); + } + flags |= S_F_INTERVAL_SET; + } + + else if (!strcmp(argv[opt], "-m")) { + if (!argv[++opt]) { + usage(argv[0]); + } + /* Parse option -m */ + if (parse_sar_m_opt(argv, &opt, act)) { + usage(argv[0]); + } + } + + else if (!strcmp(argv[opt], "-n")) { + if (!argv[++opt]) { + usage(argv[0]); + } + /* Parse option -n */ + if (parse_sar_n_opt(argv, &opt, act)) { + usage(argv[0]); + } + } + + else if ((strlen(argv[opt]) > 1) && + (strlen(argv[opt]) < 4) && + !strncmp(argv[opt], "-", 1) && + (strspn(argv[opt] + 1, DIGITS) == (strlen(argv[opt]) - 1))) { + if (from_file[0] || day_offset) { + /* Input file already specified */ + usage(argv[0]); + } + day_offset = atoi(argv[opt++] + 1); + } + + else if (!strncmp(argv[opt], "-", 1)) { + /* Other options not previously tested */ + if ((rc = parse_sar_opt(argv, &opt, act, &flags, C_SAR)) != 0) { + if (rc == 1) { + usage(argv[0]); + } + exit(1); + } + opt++; + } + + else if (interval < 0) { + /* Get interval */ + if (strspn(argv[opt], DIGITS) != strlen(argv[opt])) { + usage(argv[0]); + } + interval = atol(argv[opt++]); + if (interval < 0) { + usage(argv[0]); + } + } + + else { + /* Get count value */ + if ((strspn(argv[opt], DIGITS) != strlen(argv[opt])) || + !interval) { + usage(argv[0]); + } + if (count) { + /* Count parameter already set */ + usage(argv[0]); + } + count = atol(argv[opt++]); + if (count < 1) { + usage(argv[0]); + } + } + } + + /* 'sar' is equivalent to 'sar -f' */ + if ((argc == 1) || + ((interval < 0) && !from_file[0] && !to_file[0])) { + set_default_file(from_file, day_offset, -1); + } + + if (tm_start.use && tm_end.use && (tm_end.tm_hour < tm_start.tm_hour)) { + tm_end.tm_hour += 24; + } + + /* + * Check option dependencies. + */ + /* You read from a file OR you write to it... */ + if (from_file[0] && to_file[0]) { + fprintf(stderr, _("-f and -o options are mutually exclusive\n")); + exit(1); + } + /* Use time start or option -i only when reading stats from a file */ + if ((tm_start.use || INTERVAL_SET(flags)) && !from_file[0]) { + fprintf(stderr, + _("Not reading from a system activity file (use -f option)\n")); + exit(1); + } + /* Don't print stats since boot time if -o or -f options are used */ + if (!interval && (from_file[0] || to_file[0])) { + usage(argv[0]); + } + + /* Cannot enter a day shift with -o option */ + if (to_file[0] && day_offset) { + usage(argv[0]); + } + + if (USE_PRETTY_OPTION(flags)) { + dm_major = get_devmap_major(); + } + + if (!count) { + /* + * count parameter not set: Display all the contents of the file + * or generate a report continuously. + */ + count = -1; + } + + /* Default is CPU activity... */ + select_default_activity(act); + + /* Reading stats from file: */ + if (from_file[0]) { + if (interval < 0) { + interval = 1; + } + + /* Read stats from file */ + read_stats_from_file(from_file); + + /* Free stuctures and activity bitmaps */ + free_bitmaps(act); + free_structures(act); + + return 0; + } + + return 0; +} diff --git a/tests/12.0.1/ioconf.c b/tests/12.0.1/ioconf.c new file mode 100644 index 0000000..940b0c5 --- /dev/null +++ b/tests/12.0.1/ioconf.c @@ -0,0 +1,533 @@ +/* + * ioconf: ioconf configuration file handling code + * Original code (C) 2004 by Red Hat (Charlie Bennett ) + * + * Modified and maintained by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include + +#include "ioconf.h" +#include "common.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +static unsigned int ioc_parsed = 0; +static struct ioc_entry *ioconf[MAX_BLKDEV + 1]; +static unsigned int ioc_refnr[MAX_BLKDEV + 1]; + +/* + *************************************************************************** + * Free ioc_entry structures + *************************************************************************** + */ +static void ioc_free(void) +{ + unsigned int i; + struct ioc_entry **p; + + /* Take out all of the references first */ + for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) { + if ((*p == NULL) || ((*p)->live)) + continue; + + if ((*p)->desc != (*p)->blkp->desc) { + /* Not a shared description */ + free((*p)->desc); + } + free(*p); + *p = NULL; + } + + /* Now the live ones */ + for (i = 0, p = ioconf; i < MAX_BLKDEV; ++i, ++p) { + if (*p == NULL) + continue; + free((*p)->blkp); + free(*p); + *p = NULL; + } +} + +/* + *************************************************************************** + * ioc_conv - Turn a number into a string in radix using symbol + * set (and ordering) syms. Use nozero to generate strings + * in which the number system uses a single sym for the + * radix value (not 2, like decimal) and adds a column only + * at radix+1. If decimal were like this: + * + * (no zero) 1 2 3 4 5 6 7 8 9 0 11 12 13 14 15 16 17 18 19 10 ... + *************************************************************************** + */ +static char *ioc_conv(int radix, int nozero, const char *syms, + unsigned int val) +{ + static char out[17]; + char *p; + int j; + + *(p = out + 16) = '\0'; + + val += nozero; + + if (val == 0) { + if (!nozero) { + *--p = '0'; + } + return (p); /* Empty string if nozero radix gets val == 0 */ + } + + while (val > 0) { + *--p = syms[j = val % radix]; + val /= radix; + if (nozero && (j == 0)) { + /* Comp for 10 in nozero bases */ + --val; + } + } + return (p); +} + +char *ioc_ito10(unsigned int n) +{ + return (ioc_conv(10, 0, "0123456789", n)); +} + +char *ioc_ito26(unsigned int n) +{ + return (ioc_conv(26, 1, "zabcdefghijklmnopqrstuvwxy", n)); +} + +/* + *************************************************************************** + * ioc_init() - internalize the ioconf file + * + * given: void + * does: parses IOCONF into ioconf, an array of ioc_entry * + * Only entries having lines in IOCONF will have valid pointers + * return: 1 on success + * 0 on failure + *************************************************************************** + */ +int ioc_init(void) +{ + FILE *fp; + unsigned int i, major, indirect, count = 0; + char buf[IOC_LINESIZ]; + char cfmt[IOC_FMTLEN]; + char dfmt[IOC_FMTLEN]; + char pfmt[IOC_FMTLEN]; + char desc[IOC_DESCLEN]; + struct ioc_entry *iocp = NULL; + struct blk_config *blkp = NULL; + char ioconf_name[64]; + + if ((fp = fopen(IOCONF, "r")) == NULL) { + if ((fp = fopen(LOCAL_IOCONF, "r")) == NULL) + return 0; + strncpy(ioconf_name, LOCAL_IOCONF, 64); + } + else { + strncpy(ioconf_name, IOCONF, 64); + } + ioconf_name[63] = '\0'; + + /* Init ioc_refnr array */ + memset(ioc_refnr, 0, sizeof(ioc_refnr)); + + while (fgets(buf, IOC_LINESIZ - 1, fp)) { + + if ((*buf == '#') || (*buf == '\n')) + continue; + + /* + * Preallocate some (probably) needed data structures + */ + IOC_ALLOC(blkp, struct blk_config, BLK_CONFIG_SIZE); + IOC_ALLOC(iocp, struct ioc_entry, IOC_ENTRY_SIZE); + memset(blkp, 0, BLK_CONFIG_SIZE); + memset(iocp, 0, IOC_ENTRY_SIZE); + + i = sscanf(buf, "%u:%u:%u:%s", + &major, &indirect, &iocp->ctrlno, desc); + + if (i != 4) { + i = sscanf(buf, "%u:%u:%u", + &major, &indirect, &iocp->ctrlno); + } + + if ((i == 3) || (i == 4)) { + /* indirect record */ + if (indirect == 0) { + /* conventional usage for unsupported device */ + continue; + } + if (indirect > MAX_BLKDEV) { + fprintf(stderr, "%s: Indirect major #%u out of range\n", + ioconf_name, indirect); + continue; + } + if (major > MAX_BLKDEV) { + fprintf(stderr, "%s: Major #%u out of range\n", + ioconf_name, major); + continue; + } + if (ioconf[indirect] == NULL) { + fprintf(stderr, + "%s: Indirect record '%u:%u:%u:...'" + " references not yet seen major %u\n", + ioconf_name, major, indirect, iocp->ctrlno, major); + continue; + } + /* + * Cool. Point this device at its referent. + * Skip last: (last field my be empty...) + * if it was empty and : was in the sscanf spec + * we'd only see 3 fields... + */ + if (i == 3) { + /* reference the mothership */ + iocp->desc = ioconf[indirect]->blkp->desc; + } + else { + IOC_ALLOC(iocp->desc, char, IOC_DESCLEN); + memcpy(iocp->desc, desc, IOC_DESCLEN); + } + ioc_refnr[indirect]++; + ioconf[major] = iocp; + iocp->basemajor = indirect; + iocp->blkp = ioconf[indirect]->blkp; + iocp->live = 0; + iocp = NULL; + continue; + /* all done with indirect record */ + } + + /* maybe it's a full record? */ + + i = sscanf(buf, "%u:%[^:]:%[^:]:%u:%[^:]:%u:%[^:]:%u:%s", + &major, blkp->name, + cfmt, &iocp->ctrlno, + dfmt, &blkp->dcount, + pfmt, &blkp->pcount, + desc); + + if (i != 9) { + fprintf(stderr, "%s: Malformed %u field record: %s\n", + ioconf_name, i, buf); + continue; + } + + /* this is a full-fledged direct record */ + + if ((major == 0) || (major >= MAX_BLKDEV)) { + fprintf(stderr, "%s: major #%u out of range\n", + __FUNCTION__, major); + continue; + } + + /* is this an exception record? */ + if (*cfmt == 'x') { + struct blk_config *xblkp; + + /* + * device has an aliased minor + * for now we only support one exception per major + * (catering to initrd: (1,250)) + */ + if (ioconf[major] == NULL) { + fprintf(stderr, "%s: type 'x' record for" + " major #%u must follow the base record - ignored\n", + ioconf_name, major); + continue; + } + xblkp = ioconf[major]->blkp; + + if (xblkp->ext) { + /* + * Enforce one minor exception per major policy + * note: this applies to each major number and + * all of it's indirect (short form) majors + */ + fprintf(stderr, "%s: duplicate 'x' record for" + " major #%u - ignored\ninput line: %s\n", + ioconf_name, major, buf); + continue; + } + /* + * Decorate the base major struct with the + * exception info + */ + xblkp->ext_minor = iocp->ctrlno; + strncpy(xblkp->ext_name, blkp->name, IOC_NAMELEN); + xblkp->ext_name[IOC_NAMELEN - 1] = '\0'; + xblkp->ext = 1; + continue; + } + + /* + * Preformat the sprintf format strings for generating + * c-d-p info in ioc_name() + */ + + /* basename of device + provided string + controller # */ + if (*cfmt == '*') { + strncpy(blkp->cfmt, blkp->name, sizeof(blkp->cfmt) - 1); + blkp->cfmt[sizeof(blkp->cfmt) - 1] = '\0'; + } + else { + sprintf(blkp->cfmt, "%s%s%%d", blkp->name, cfmt); + ++(blkp->ctrl_explicit); + } + + /* Disk */ + *blkp->dfmt = '\0'; + switch (*dfmt) { + case 'a': + blkp->cconv = ioc_ito26; + strcpy(blkp->dfmt, "%s"); + break; + + case '%': + strncpy(blkp->dfmt, dfmt + 1, IOC_FMTLEN - 1); + /* fallthrough to next case */ + case 'd': + blkp->cconv = ioc_ito10; + strcat(blkp->dfmt, "%s"); + break; + } + + /* Partition */ + sprintf(blkp->pfmt, "%s%%d", (*pfmt == '*') ? "" : pfmt); + + /* + * We're good to go. + * Stuff the ioc_entry and ref it. + */ + iocp->live = 1; + iocp->blkp = blkp; + iocp->desc = NULL; + iocp->basemajor = major; + ioconf[major] = iocp; + memcpy(blkp->desc, desc, IOC_DESCLEN); + blkp = NULL; iocp = NULL; + ++count; + } + fclose(fp); + + /* + * These will become leaks if we ever 'continue' + * after IOC_ALLOC( blkp->desc ... ). + * Right now, we don't. + */ + free(blkp); + free(iocp); + + /* Indicate that ioconf file has been parsed */ + ioc_parsed = 1; + + return (count); + +free_and_return: + /* Free pointers and return */ + fclose(fp); + if (blkp) { + free(blkp); + } + if (iocp) { + free(iocp); + } + + return 0; +} + +/* + *************************************************************************** + * ioc_name() - Generate a name from a maj,min pair + * + * IN: + * @major Device major number. + * @minor Device minor number. + * + * RETURNS: + * Returns NULL if major or minor are out of range + * otherwise returns a pointer to a static string containing + * the generated name. + *************************************************************************** + */ + +char *ioc_name(unsigned int major, unsigned int minor) +{ + static char name[IOC_DEVLEN]; + struct ioc_entry *p; + int base, offset; + + if ((major > MAX_BLKDEV) || (minor > IOC_MAXMINOR)) { + return (NULL); + } + + if (!ioc_parsed && !ioc_init()) + return (NULL); + + p = ioconf[major]; + + /* Invalid major or minor numbers? */ + if ((p == NULL) || ((minor & 0xff) >= (p->blkp->dcount * p->blkp->pcount))) { + /* + * That minor test is only there for IDE-style devices + * that have no minors over 128. + */ + strcpy(name, K_NODEV); + return (name); + } + + /* Is this an extension record? */ + if (p->blkp->ext && (p->blkp->ext_minor == minor)) { + strncpy(name, p->blkp->ext_name, IOC_DEVLEN); + name[IOC_DEVLEN - 1] = '\0'; + return (name); + } + + /* OK. we're doing an actual device name... */ + + /* + * Assemble base + optional controller info + * this is of course too clever by half + * the parser has already cooked cfmt, dfmt to make this easy + * (we parse once but may generate lots of names) + */ + base = p->ctrlno * p->blkp->dcount; + if (minor >= 256) { + base += p->blkp->dcount * (ioc_refnr[p->basemajor] + 1) * (minor >> 8); + } + + offset = (minor & 0xff) / p->blkp->pcount; + if (!p->blkp->ctrl_explicit) { + offset += base; + } + + /* + * These sprintfs can't be coalesced because the first might + * ignore its first arg + */ + sprintf(name, p->blkp->cfmt, p->ctrlno); + sprintf(name + strlen(name), p->blkp->dfmt, p->blkp->cconv(offset)); + + if (!IS_WHOLE(major, minor)) { + /* + * Tack on partition info, format string cooked (curried?) by + * the parser + */ + sprintf(name + strlen(name), p->blkp->pfmt, minor % p->blkp->pcount); + } + return (name); +} + +/* + *************************************************************************** + * Check whether a device is a whole disk device or not. + * + * IN: + * @major Device major number. + * @minor Device minor number. + * + * RETURNS: + * Predicate: Returns 1 if dev (major,minor) is a whole disk device. + * Returns 0 otherwise. + *************************************************************************** + */ +int ioc_iswhole(unsigned int major, unsigned int minor) +{ + if (!ioc_parsed && !ioc_init()) + return 0; + + if (major > MAX_BLKDEV) + return 0; + + if (ioconf[major] == NULL) + /* Device not registered */ + return 0; + + return (IS_WHOLE(major, minor)); +} + +/* + *************************************************************************** + * Transform device mapper name: Get the user assigned name of the logical + * device instead of the internal device mapper numbering. + * + * IN: + * @major Device major number. + * @minor Device minor number. + * + * RETURNS: + * Assigned name of the logical device. + *************************************************************************** + */ +char *transform_devmapname(unsigned int major, unsigned int minor) +{ + DIR *dm_dir; + struct dirent *dp; + char filen[MAX_FILE_LEN]; + char *dm_name = NULL; + static char name[MAX_NAME_LEN]; + struct stat aux; + unsigned int dm_major, dm_minor; + + if ((dm_dir = opendir(DEVMAP_DIR)) == NULL) { + fprintf(stderr, _("Cannot open %s: %s\n"), DEVMAP_DIR, strerror(errno)); + exit(4); + } + + while ((dp = readdir(dm_dir)) != NULL) { + /* For each file in DEVMAP_DIR */ + + snprintf(filen, MAX_FILE_LEN, "%s/%s", DEVMAP_DIR, dp->d_name); + filen[MAX_FILE_LEN - 1] = '\0'; + + if (stat(filen, &aux) == 0) { + /* Get its minor and major numbers */ + + dm_major = major(aux.st_rdev); + dm_minor = minor(aux.st_rdev); + + if ((dm_minor == minor) && (dm_major == major)) { + strncpy(name, dp->d_name, MAX_NAME_LEN); + name[MAX_NAME_LEN - 1] = '\0'; + dm_name = name; + break; + } + } + } + closedir(dm_dir); + + return dm_name; +} diff --git a/tests/12.0.1/ioconf.h b/tests/12.0.1/ioconf.h new file mode 100644 index 0000000..15af348 --- /dev/null +++ b/tests/12.0.1/ioconf.h @@ -0,0 +1,92 @@ +/* + * ioconf: ioconf configuration file handling code + * Original code (C) 2004 by Red Hat (Charlie Bennett ) + * + * Modified and maintained by Sebastien GODARD (sysstat orange.fr) + */ + +#ifndef _IOCONF_H +#define _IOCONF_H + +#include "sysconfig.h" + +#define IOC_NAMELEN 32 +#define IOC_DESCLEN 64 +#define IOC_DEVLEN 48 +#define IOC_LINESIZ 256 +#define IOC_FMTLEN 16 +#define IOC_XFMTLEN (IOC_FMTLEN + IOC_NAMELEN + 3) + +#ifndef MINORBITS +#define MINORBITS 20 +#endif +#define IOC_MAXMINOR ((1U << MINORBITS) - 1) +#ifndef MAX_BLKDEV +/* #define MAX_BLKDEV ((1U << (32 - MINORBITS)) - 1) */ +/* Use a lower value since this value is used to allocate arrays statically in ioconf.c */ +#define MAX_BLKDEV 511 +#endif + +#define K_NODEV "nodev" + +#define IS_WHOLE(maj,min) ((min % ioconf[maj]->blkp->pcount) == 0) + +/* + * When is C going to get templates? + */ +#define IOC_ALLOC(P,TYPE,SIZE) \ + do { \ + if (P == NULL) { \ + P = (TYPE *) malloc(SIZE); \ + if (P == NULL) { \ + perror("malloc"); \ + ioc_free(); \ + goto free_and_return; \ + } \ + } \ + } \ + while (0) +/* That dummy while allows ';' on the line that invokes the macro... */ + + +struct blk_config { + char name[IOC_NAMELEN]; /* device basename */ + char cfmt[IOC_XFMTLEN]; /* controller format string */ + char dfmt[IOC_FMTLEN]; /* disk format string */ + char pfmt[IOC_FMTLEN + 2]; /* partition format string */ + /* ctrlno is in the ioc_entry */ + unsigned int ctrl_explicit; /* use "cN" in name */ + unsigned int dcount; /* number of devices handled by this major */ + unsigned int pcount; /* partitions per device */ + char desc[IOC_DESCLEN]; + /* disk info unit # conversion function */ + char *(*cconv)(unsigned int); + + /* extension properties (all this for initrd?) */ + char ext_name[IOC_NAMELEN]; + unsigned int ext; /* flag - this is an extension record */ + unsigned int ext_minor; /* which minor does this apply to */ +}; + +#define BLK_CONFIG_SIZE (sizeof(struct blk_config)) + + +struct ioc_entry { + int live; /* is this a Direct entry? */ + unsigned int ctrlno; /* controller number */ + unsigned int basemajor; /* Major number of the template */ + char *desc; /* (dynamic) per-controller description */ + struct blk_config *blkp; /* the real info, may be a shared ref */ +}; + +#define IOC_ENTRY_SIZE (sizeof(struct ioc_entry)) + + +int ioc_iswhole + (unsigned int, unsigned int); +char *ioc_name + (unsigned int, unsigned int); +char *transform_devmapname + (unsigned int, unsigned int); + +#endif diff --git a/tests/12.0.1/pr_stats.c b/tests/12.0.1/pr_stats.c new file mode 100644 index 0000000..65dc259 --- /dev/null +++ b/tests/12.0.1/pr_stats.c @@ -0,0 +1,3004 @@ +/* + * pr_stats.c: Functions used by sar to display statistics + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include + +#include "sa.h" +#include "ioconf.h" +#include "pr_stats.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +extern unsigned int flags; +extern int dis; +extern char timestamp[][TIMESTAMP_LEN]; +extern unsigned long avg_count; + +/* + *************************************************************************** + * Display current activity header line. + * + * IN: + * @timestamp Timestamp for previous stat sample. + * @a Activity structure. + * @pos Index in @.hdr_line string, 0 being the first one (header + * are delimited by the '|' character). + * @iwidth First column width (generally this is the item name). A + * negative value means that the corresponding field shall be + * displayed at the end of the line, with no indication of width. + * @vwidth Column width for stats values. + *************************************************************************** + */ +void print_hdr_line(char *timestamp, struct activity *a, int pos, int iwidth, int vwidth) +{ + char hline[HEADER_LINE_LEN] = ""; + char *hl, *tk, *it = NULL; + int i = -1, j; + int p = pos; + + strncpy(hline, a->hdr_line, HEADER_LINE_LEN - 1); + hline[HEADER_LINE_LEN - 1] = '\0'; + for (hl = strtok(hline, "|"); hl && (pos > 0); hl = strtok(NULL, "|"), pos--); + if (!hl) + /* Bad @pos arg given to function */ + return; + + printf("\n%-11s", timestamp); + + if (strchr(hl, '&')) { + j = strcspn(hl, "&"); + if ((a->opt_flags & 0xff00) & (1 << (8 + p))) { + /* Display whole header line */ + *(hl + j) = ';'; + } + else { + /* Display only the first part of the header line */ + *(hl + j) = '\0'; + } + } + /* Display each field */ + for (tk = strtok(hl, ";"); tk; tk = strtok(NULL, ";"), i--) { + if (iwidth > 0) { + printf(" %*s", iwidth, tk); + iwidth = 0; + continue; + } + if ((iwidth < 0) && (iwidth == i)) { + it = tk; + iwidth = 0; + } + else { + printf(" %*s", vwidth, tk); + } + } + if (it) { + printf(" %s", it); + } + printf("\n"); +} + +/* + *************************************************************************** + * Display CPU statistics. + * NB: The stats are only calculated over the part of the time interval when + * the CPU was online. As a consequence, the sum (%user + %nice + ... + %idle) + * will always be 100% on the time interval even if the CPU has been offline + * most of the time. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second (independent of the + * number of processors). Unused here. + *************************************************************************** + */ +__print_funct_t print_cpu_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i; + unsigned long long deltot_jiffies = 1; + struct stats_cpu *scc, *scp; + unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0}; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST + DISPLAY_CPU_ALL(a->opt_flags), 7, 9); + } + + /* + * @nr[curr] cannot normally be greater than @nr_ini + * (since @nr_ini counts up all CPU, even those offline). + * If this happens, it may be because the machine has been + * restarted with more CPU and no LINUX_RESTART has been + * inserted in file. + * No problem here with @nr_allocated. Having been able to + * read @nr[curr] structures shows that buffers are large enough. + */ + if (a->nr[curr] > a->nr_ini) { + a->nr_ini = a->nr[curr]; + } + + /* + * Compute CPU "all" as sum of all individual CPU (on SMP machines) + * and look for offline CPU. + */ + if (a->nr_ini > 1) { + deltot_jiffies = get_global_cpu_statistics(a, prev, curr, + flags, offline_cpu_bitmap); + } + + /* + * Now display CPU statistics (including CPU "all"), + * except for offline CPU or CPU that the user doesn't want to see. + */ + for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { + + /* + * Should current CPU (including CPU "all") be displayed? + * Note: @nr[curr] is in [1, NR_CPUS + 1]. + * Bitmap size is provided for (NR_CPUS + 1) CPUs. + * Anyway, NR_CPUS may vary between the version of sysstat + * used by sadc to create a file, and the version of sysstat + * used by sar to read it... + */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) || + offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07))) + /* Don't display CPU */ + continue; + + scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize); + scp = (struct stats_cpu *) ((char *) a->buf[prev] + i * a->msize); + + printf("%-11s", timestamp[curr]); + + if (i == 0) { + /* This is CPU "all" */ + cprintf_in(IS_STR, " %s", " all", 0); + + if (a->nr_ini == 1) { + /* + * This is a UP machine. In this case + * interval has still not been calculated. + */ + deltot_jiffies = get_per_cpu_interval(scc, scp); + } + if (!deltot_jiffies) { + /* CPU "all" cannot be tickless */ + deltot_jiffies = 1; + } + } + else { + cprintf_in(IS_INT, " %7d", "", i - 1); + + /* Recalculate interval for current proc */ + deltot_jiffies = get_per_cpu_interval(scc, scp); + + if (!deltot_jiffies) { + /* + * If the CPU is tickless then there is no change in CPU values + * but the sum of values is not zero. + * %user, %nice, %system, %iowait, %steal, ..., %idle + */ + cprintf_pc(DISPLAY_UNIT(flags), 5, 9, 2, + 0.0, 0.0, 0.0, 0.0, 0.0); + + if (DISPLAY_CPU_DEF(a->opt_flags)) { + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, 100.0); + printf("\n"); + } + /* + * Four additional fields to display: + * %irq, %soft, %guest, %gnice. + */ + else if (DISPLAY_CPU_ALL(a->opt_flags)) { + cprintf_pc(DISPLAY_UNIT(flags), 4, 9, 2, + 0.0, 0.0, 0.0, 100.0); + printf("\n"); + } + continue; + } + } + + if (DISPLAY_CPU_DEF(a->opt_flags)) { + cprintf_pc(DISPLAY_UNIT(flags), 6, 9, 2, + ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies), + ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies), + ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq, + scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq, + deltot_jiffies), + ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies), + ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies), + scc->cpu_idle < scp->cpu_idle ? + 0.0 : + ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies)); + printf("\n"); + } + else if (DISPLAY_CPU_ALL(a->opt_flags)) { + cprintf_pc(DISPLAY_UNIT(flags), 10, 9, 2, + (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ? + 0.0 : + ll_sp_value(scp->cpu_user - scp->cpu_guest, + scc->cpu_user - scc->cpu_guest, deltot_jiffies), + (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ? + 0.0 : + ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice, + scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies), + ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies), + ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies), + ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies), + ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies), + ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies), + ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies), + ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies), + scc->cpu_idle < scp->cpu_idle ? + 0.0 : + ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies)); + printf("\n"); + } + } +} + +/* + *************************************************************************** + * Display tasks creation and context switches statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pcsw_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_pcsw + *spc = (struct stats_pcsw *) a->buf[curr], + *spp = (struct stats_pcsw *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 2, 9, 2, + S_VALUE(spp->processes, spc->processes, itv), + S_VALUE(spp->context_switch, spc->context_switch, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display interrupts statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_irq_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i; + struct stats_irq *sic, *sip; + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) { + + /* + * If @nr[curr] > @nr[prev] then we consider that previous + * interrupt value was 0. + */ + sic = (struct stats_irq *) ((char *) a->buf[curr] + i * a->msize); + sip = (struct stats_irq *) ((char *) a->buf[prev] + i * a->msize); + + /* + * Note: @nr[curr] gives the number of interrupts read (1 .. NR_IRQS + 1). + * Bitmap size is provided for (NR_IRQS + 1) interrupts. + * Anyway, NR_IRQS may vary between the version of sysstat + * used by sadc to create a file, and the version of sysstat + * used by sar to read it... + */ + + /* Should current interrupt (including int "sum") be displayed? */ + if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) { + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sip, sic, STATS_IRQ_SIZE)) + continue; + + /* Yes: Display it */ + printf("%-11s", timestamp[curr]); + if (!i) { + /* This is interrupt "sum" */ + cprintf_in(IS_STR, " %s", " sum", 0); + } + else { + cprintf_in(IS_INT, " %9d", "", i -1); + } + + cprintf_f(NO_UNIT, 1, 9, 2, S_VALUE(sip->irq_nr, sic->irq_nr, itv)); + printf("\n"); + } + } +} + +/* + *************************************************************************** + * Display swapping statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_swap_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_swap + *ssc = (struct stats_swap *) a->buf[curr], + *ssp = (struct stats_swap *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 2, 9, 2, + S_VALUE(ssp->pswpin, ssc->pswpin, itv), + S_VALUE(ssp->pswpout, ssc->pswpout, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display paging statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_paging_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_paging + *spc = (struct stats_paging *) a->buf[curr], + *spp = (struct stats_paging *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 8, 9, 2, + S_VALUE(spp->pgpgin, spc->pgpgin, itv), + S_VALUE(spp->pgpgout, spc->pgpgout, itv), + S_VALUE(spp->pgfault, spc->pgfault, itv), + S_VALUE(spp->pgmajfault, spc->pgmajfault, itv), + S_VALUE(spp->pgfree, spc->pgfree, itv), + S_VALUE(spp->pgscan_kswapd, spc->pgscan_kswapd, itv), + S_VALUE(spp->pgscan_direct, spc->pgscan_direct, itv), + S_VALUE(spp->pgsteal, spc->pgsteal, itv)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (spc->pgscan_kswapd + spc->pgscan_direct - + spp->pgscan_kswapd - spp->pgscan_direct) ? + SP_VALUE(spp->pgsteal, spc->pgsteal, + spc->pgscan_kswapd + spc->pgscan_direct - + spp->pgscan_kswapd - spp->pgscan_direct) + : 0.0); + printf("\n"); +} + +/* + *************************************************************************** + * Display I/O and transfer rate statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_io_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_io + *sic = (struct stats_io *) a->buf[curr], + *sip = (struct stats_io *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + /* + * If we get negative values, this is probably because + * one or more devices/filesystems have been unmounted. + * We display 0.0 in this case though we should rather tell + * the user that the value cannot be calculated here. + */ + cprintf_f(NO_UNIT, 5, 9, 2, + sic->dk_drive < sip->dk_drive ? 0.0 : + S_VALUE(sip->dk_drive, sic->dk_drive, itv), + sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 : + S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv), + sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 : + S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv), + sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 : + S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv), + sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 : + S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display memory and swap statistics. This function is used to + * display instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_memory_stats(struct activity *a, int prev, int curr, int dispavg) +{ + struct stats_memory + *smc = (struct stats_memory *) a->buf[curr]; + static unsigned long long + avg_frmkb = 0, + avg_bufkb = 0, + avg_camkb = 0, + avg_comkb = 0, + avg_activekb = 0, + avg_inactkb = 0, + avg_dirtykb = 0, + avg_anonpgkb = 0, + avg_slabkb = 0, + avg_kstackkb = 0, + avg_pgtblkb = 0, + avg_vmusedkb = 0, + avg_availablekb = 0; + static unsigned long long + avg_frskb = 0, + avg_tlskb = 0, + avg_caskb = 0; + int unit = NO_UNIT; + unsigned long long nousedmem; + + if (DISPLAY_UNIT(flags)) { + /* Default values unit is kB */ + unit = UNIT_KILOBYTE; + } + + if (DISPLAY_MEMORY(a->opt_flags)) { + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb; + if (nousedmem > smc->tlmkb) { + nousedmem = smc->tlmkb; + } + printf("%-11s", timestamp[curr]); + cprintf_u64(unit, 3, 9, + (unsigned long long) smc->frmkb, + (unsigned long long) smc->availablekb, + (unsigned long long) (smc->tlmkb - nousedmem)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + smc->tlmkb ? + SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) + : 0.0); + cprintf_u64(unit, 3, 9, + (unsigned long long) smc->bufkb, + (unsigned long long) smc->camkb, + (unsigned long long) smc->comkb); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (smc->tlmkb + smc->tlskb) ? + SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) + : 0.0); + cprintf_u64(unit, 3, 9, + (unsigned long long) smc->activekb, + (unsigned long long) smc->inactkb, + (unsigned long long) smc->dirtykb); + + if (DISPLAY_MEM_ALL(a->opt_flags)) { + /* Display extended memory statistics */ + cprintf_u64(unit, 5, 9, + (unsigned long long) smc->anonpgkb, + (unsigned long long) smc->slabkb, + (unsigned long long) smc->kstackkb, + (unsigned long long) smc->pgtblkb, + (unsigned long long) smc->vmusedkb); + } + + printf("\n"); + + /* + * Will be used to compute the average. + * We assume that the total amount of memory installed can not vary + * during the interval given on the command line. + */ + avg_frmkb += smc->frmkb; + avg_bufkb += smc->bufkb; + avg_camkb += smc->camkb; + avg_comkb += smc->comkb; + avg_activekb += smc->activekb; + avg_inactkb += smc->inactkb; + avg_dirtykb += smc->dirtykb; + avg_anonpgkb += smc->anonpgkb; + avg_slabkb += smc->slabkb; + avg_kstackkb += smc->kstackkb; + avg_pgtblkb += smc->pgtblkb; + avg_vmusedkb += smc->vmusedkb; + avg_availablekb += smc->availablekb; + } + else { + /* Display average values */ + nousedmem = avg_frmkb + avg_bufkb + avg_camkb + avg_slabkb; + printf("%-11s", timestamp[curr]); + cprintf_f(unit, 3, 9, 0, + (double) avg_frmkb / avg_count, + (double) avg_availablekb / avg_count, + (double) smc->tlmkb - ((double) nousedmem / avg_count)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + smc->tlmkb ? + SP_VALUE((double) (nousedmem / avg_count), smc->tlmkb, smc->tlmkb) + : 0.0); + cprintf_f(unit, 3, 9, 0, + (double) avg_bufkb / avg_count, + (double) avg_camkb / avg_count, + (double) avg_comkb / avg_count); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (smc->tlmkb + smc->tlskb) ? + SP_VALUE(0.0, (double) (avg_comkb / avg_count), smc->tlmkb + smc->tlskb) + : 0.0); + cprintf_f(unit, 3, 9, 0, + (double) avg_activekb / avg_count, + (double) avg_inactkb / avg_count, + (double) avg_dirtykb / avg_count); + + if (DISPLAY_MEM_ALL(a->opt_flags)) { + cprintf_f(unit, 5, 9, 0, + (double) avg_anonpgkb / avg_count, + (double) avg_slabkb / avg_count, + (double) avg_kstackkb / avg_count, + (double) avg_pgtblkb / avg_count, + (double) avg_vmusedkb / avg_count); + } + + printf("\n"); + + /* Reset average counters */ + avg_frmkb = avg_bufkb = avg_camkb = avg_comkb = 0; + avg_activekb = avg_inactkb = avg_dirtykb = 0; + avg_anonpgkb = avg_slabkb = avg_kstackkb = 0; + avg_pgtblkb = avg_vmusedkb = avg_availablekb = 0; + } + } + + if (DISPLAY_SWAP(a->opt_flags)) { + if (dis) { + print_hdr_line(timestamp[!curr], a, SECOND, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(unit, 2, 9, + (unsigned long long) smc->frskb, + (unsigned long long) (smc->tlskb - smc->frskb)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + smc->tlskb ? + SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb) + : 0.0); + cprintf_u64(unit, 1, 9, + (unsigned long long) smc->caskb); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (smc->tlskb - smc->frskb) ? + SP_VALUE(0, smc->caskb, smc->tlskb - smc->frskb) + : 0.0); + + printf("\n"); + + /* + * Will be used to compute the average. + * We assume that the total amount of swap space may vary. + */ + avg_frskb += smc->frskb; + avg_tlskb += smc->tlskb; + avg_caskb += smc->caskb; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(unit, 2, 9, 0, + (double) avg_frskb / avg_count, + ((double) avg_tlskb / avg_count) - + ((double) avg_frskb / avg_count)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + avg_tlskb ? + SP_VALUE((double) avg_frskb / avg_count, + (double) avg_tlskb / avg_count, + (double) avg_tlskb / avg_count) + : 0.0); + cprintf_f(unit, 1, 9, 0, + (double) avg_caskb / avg_count); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (avg_tlskb != avg_frskb) ? + SP_VALUE(0.0, (double) avg_caskb / avg_count, + ((double) avg_tlskb / avg_count) - + ((double) avg_frskb / avg_count)) + : 0.0); + printf("\n"); + + /* Reset average counters */ + avg_frskb = avg_tlskb = avg_caskb = 0; + } + } +} + +/* + *************************************************************************** + * Display memory and swap statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_memory_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_memory_stats(a, prev, curr, FALSE); +} + +/* + *************************************************************************** + * Display average memory statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_memory_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_memory_stats(a, prev, curr, TRUE); +} + +/* + *************************************************************************** + * Display kernel tables statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg True if displaying average statistics. + *************************************************************************** + */ +void stub_print_ktables_stats(struct activity *a, int curr, int dispavg) +{ + struct stats_ktables + *skc = (struct stats_ktables *) a->buf[curr]; + static unsigned long long + avg_dentry_stat = 0, + avg_file_used = 0, + avg_inode_used = 0, + avg_pty_nr = 0; + + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(NO_UNIT, 4, 9, + (unsigned long long) skc->dentry_stat, + (unsigned long long) skc->file_used, + (unsigned long long) skc->inode_used, + (unsigned long long) skc->pty_nr); + printf("\n"); + + /* + * Will be used to compute the average. + * Note: Overflow unlikely to happen but not impossible... + */ + avg_dentry_stat += skc->dentry_stat; + avg_file_used += skc->file_used; + avg_inode_used += skc->inode_used; + avg_pty_nr += skc->pty_nr; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 0, + (double) avg_dentry_stat / avg_count, + (double) avg_file_used / avg_count, + (double) avg_inode_used / avg_count, + (double) avg_pty_nr / avg_count); + printf("\n"); + + /* Reset average counters */ + avg_dentry_stat = avg_file_used = avg_inode_used = avg_pty_nr = 0; + } +} + +/* + *************************************************************************** + * Display kernel tables statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_ktables_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_ktables_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average kernel tables statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_ktables_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_ktables_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display queue and load statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_queue_stats(struct activity *a, int curr, int dispavg) +{ + struct stats_queue + *sqc = (struct stats_queue *) a->buf[curr]; + static unsigned long long + avg_nr_running = 0, + avg_nr_threads = 0, + avg_load_avg_1 = 0, + avg_load_avg_5 = 0, + avg_load_avg_15 = 0, + avg_procs_blocked = 0; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(NO_UNIT, 2, 9, + (unsigned long long) sqc->nr_running, + (unsigned long long) sqc->nr_threads); + cprintf_f(NO_UNIT, 3, 9, 2, + (double) sqc->load_avg_1 / 100, + (double) sqc->load_avg_5 / 100, + (double) sqc->load_avg_15 / 100); + cprintf_u64(NO_UNIT, 1, 9, + (unsigned long long) sqc->procs_blocked); + printf("\n"); + + /* Will be used to compute the average */ + avg_nr_running += sqc->nr_running; + avg_nr_threads += sqc->nr_threads; + avg_load_avg_1 += sqc->load_avg_1; + avg_load_avg_5 += sqc->load_avg_5; + avg_load_avg_15 += sqc->load_avg_15; + avg_procs_blocked += sqc->procs_blocked; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 2, 9, 0, + (double) avg_nr_running / avg_count, + (double) avg_nr_threads / avg_count); + cprintf_f(NO_UNIT, 3, 9, 2, + (double) avg_load_avg_1 / (avg_count * 100), + (double) avg_load_avg_5 / (avg_count * 100), + (double) avg_load_avg_15 / (avg_count * 100)); + cprintf_f(NO_UNIT, 1, 9, 0, + (double) avg_procs_blocked / avg_count); + printf("\n"); + + /* Reset average counters */ + avg_nr_running = avg_nr_threads = 0; + avg_load_avg_1 = avg_load_avg_5 = avg_load_avg_15 = 0; + avg_procs_blocked = 0; + } +} + +/* + *************************************************************************** + * Display queue and load statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_queue_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_queue_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average queue and load statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_queue_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_queue_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display serial lines statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_serial_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, j, j0, found; + struct stats_serial *ssc, *ssp; + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + ssc = (struct stats_serial *) ((char *) a->buf[curr] + i * a->msize); + + if (WANT_SINCE_BOOT(flags)) { + /* + * We want to display statistics since boot time. + * Take the first structure from buf[prev]: This is a + * structure that only contains 0 (it has been set to 0 + * when it has been allocated), and which exists since + * there is the same number of allocated structures for + * buf[prev] and bur[curr] (even if nothing has been read). + */ + ssp = (struct stats_serial *) ((char *) a->buf[prev]); + found = TRUE; + } + else { + found = FALSE; + + if (a->nr[prev] > 0) { + /* Look for corresponding serial line in previous iteration */ + j = i; + + if (j >= a->nr[prev]) { + j = a->nr[prev] - 1; + } + + j0 = j; + + do { + ssp = (struct stats_serial *) ((char *) a->buf[prev] + j * a->msize); + if (ssc->line == ssp->line) { + found = TRUE; + break; + } + if (++j >= a->nr[prev]) { + j = 0; + } + } + while (j != j0); + } + } + + if (!found) + continue; + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssp, ssc, STATS_SERIAL_SIZE)) + continue; + + printf("%-11s", timestamp[curr]); + cprintf_in(IS_INT, " %3d", "", ssc->line); + + cprintf_f(NO_UNIT, 6, 9, 2, + S_VALUE(ssp->rx, ssc->rx, itv), + S_VALUE(ssp->tx, ssc->tx, itv), + S_VALUE(ssp->frame, ssc->frame, itv), + S_VALUE(ssp->parity, ssc->parity, itv), + S_VALUE(ssp->brk, ssc->brk, itv), + S_VALUE(ssp->overrun, ssc->overrun, itv)); + printf("\n"); + } +} + +/* + *************************************************************************** + * Display disks statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_disk_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, j; + struct stats_disk *sdc, *sdp, sdpzero; + struct ext_disk_stats xds; + char *dev_name; + int unit = NO_UNIT; + + memset(&sdpzero, 0, STATS_DISK_SIZE); + + if (DISPLAY_UNIT(flags)) { + /* Default values unit is kB */ + unit = UNIT_KILOBYTE; + } + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize); + + if (!WANT_SINCE_BOOT(flags)) { + j = check_disk_reg(a, curr, prev, i); + } + else { + j = -1; + } + if (j < 0) { + /* + * This is a newly registered device or we want stats since boot time. + * Previous stats are zero. + */ + sdp = &sdpzero; + } + else { + sdp = (struct stats_disk *) ((char *) a->buf[prev] + j * a->msize); + } + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sdp, sdc, STATS_DISK_SIZE)) + continue; + + /* Get device name */ + dev_name = get_sa_devname(sdc->major, sdc->minor, flags); + + if (a->item_list != NULL) { + /* A list of devices has been entered on the command line */ + if (!search_list_item(a->item_list, dev_name)) + /* Device not found */ + continue; + } + + /* Compute service time, etc. */ + compute_ext_disk_stats(sdc, sdp, itv, &xds); + + printf("%-11s", timestamp[curr]); + + if (!DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %9s", dev_name, 0); + } + cprintf_f(NO_UNIT, 1, 9, 2, + S_VALUE(sdp->nr_ios, sdc->nr_ios, itv)); + cprintf_f(unit, 2, 9, 2, + S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2, + S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2); + /* See iostat for explanations */ + cprintf_f(unit, 1, 9, 2, + xds.arqsz / 2); + cprintf_f(NO_UNIT, 3, 9, 2, + S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0, + xds.await, + xds.svctm); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + xds.util / 10.0); + if (DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %s", dev_name, 0); + } + printf("\n"); + } +} + +/* + *************************************************************************** + * Display network interfaces statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_dev_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, j; + struct stats_net_dev *sndc, *sndp, sndzero; + double rxkb, txkb, ifutil; + int unit = NO_UNIT; + + memset(&sndzero, 0, STATS_NET_DEV_SIZE); + + if (DISPLAY_UNIT(flags)) { + /* Default values unit is bytes */ + unit = UNIT_BYTE; + } + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize); + + if (a->item_list != NULL) { + /* A list of devices has been entered on the command line */ + if (!search_list_item(a->item_list, sndc->interface)) + /* Device not found */ + continue; + } + + if (!WANT_SINCE_BOOT(flags)) { + j = check_net_dev_reg(a, curr, prev, i); + } + else { + j = -1; + } + if (j < 0) { + /* + * This is a newly registered interface or we want stats since boot time. + * Previous stats are zero. + */ + sndp = &sndzero; + } + else { + sndp = (struct stats_net_dev *) ((char *) a->buf[prev] + j * a->msize); + } + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(sndp, sndc, STATS_NET_DEV_SIZE2CMP)) + continue; + + printf("%-11s", timestamp[curr]); + + if (!DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %9s", sndc->interface, 0); + } + rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv); + txkb = S_VALUE(sndp->tx_bytes, sndc->tx_bytes, itv); + + cprintf_f(NO_UNIT, 2, 9, 2, + S_VALUE(sndp->rx_packets, sndc->rx_packets, itv), + S_VALUE(sndp->tx_packets, sndc->tx_packets, itv)); + cprintf_f(unit, 2, 9, 2, + unit < 0 ? rxkb / 1024 : rxkb, + unit < 0 ? txkb / 1024 : txkb); + cprintf_f(NO_UNIT, 3, 9, 2, + S_VALUE(sndp->rx_compressed, sndc->rx_compressed, itv), + S_VALUE(sndp->tx_compressed, sndc->tx_compressed, itv), + S_VALUE(sndp->multicast, sndc->multicast, itv)); + ifutil = compute_ifutil(sndc, rxkb, txkb); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, ifutil); + if (DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %s", sndc->interface, 0); + } + printf("\n"); + } +} + +/* + *************************************************************************** + * Display network interface errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_edev_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, j; + struct stats_net_edev *snedc, *snedp, snedzero; + + memset(&snedzero, 0, STATS_NET_EDEV_SIZE); + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, DISPLAY_HUMAN_READ(flags) ? -1 : 0, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize); + + if (a->item_list != NULL) { + /* A list of devices has been entered on the command line */ + if (!search_list_item(a->item_list, snedc->interface)) + /* Device not found */ + continue; + } + + if (!WANT_SINCE_BOOT(flags)) { + j = check_net_edev_reg(a, curr, prev, i); + } + else { + j = -1; + } + if (j < 0) { + /* + * This is a newly registered interface or we want stats since boot time. + * Previous stats are zero. + */ + snedp = &snedzero; + } + else { + snedp = (struct stats_net_edev *) ((char *) a->buf[prev] + j * a->msize); + } + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(snedp, snedc, STATS_NET_EDEV_SIZE2CMP)) + continue; + + printf("%-11s", timestamp[curr]); + + if (!DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %9s", snedc->interface, 0); + } + cprintf_f(NO_UNIT, 9, 9, 2, + S_VALUE(snedp->rx_errors, snedc->rx_errors, itv), + S_VALUE(snedp->tx_errors, snedc->tx_errors, itv), + S_VALUE(snedp->collisions, snedc->collisions, itv), + S_VALUE(snedp->rx_dropped, snedc->rx_dropped, itv), + S_VALUE(snedp->tx_dropped, snedc->tx_dropped, itv), + S_VALUE(snedp->tx_carrier_errors, snedc->tx_carrier_errors, itv), + S_VALUE(snedp->rx_frame_errors, snedc->rx_frame_errors, itv), + S_VALUE(snedp->rx_fifo_errors, snedc->rx_fifo_errors, itv), + S_VALUE(snedp->tx_fifo_errors, snedc->tx_fifo_errors, itv)); + if (DISPLAY_HUMAN_READ(flags)) { + cprintf_in(IS_STR, " %s", snedc->interface, 0); + } + printf("\n"); + } +} + +/* + *************************************************************************** + * Display NFS client statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_nfs_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_nfs + *snnc = (struct stats_net_nfs *) a->buf[curr], + *snnp = (struct stats_net_nfs *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 6, 9, 2, + S_VALUE(snnp->nfs_rpccnt, snnc->nfs_rpccnt, itv), + S_VALUE(snnp->nfs_rpcretrans, snnc->nfs_rpcretrans, itv), + S_VALUE(snnp->nfs_readcnt, snnc->nfs_readcnt, itv), + S_VALUE(snnp->nfs_writecnt, snnc->nfs_writecnt, itv), + S_VALUE(snnp->nfs_accesscnt, snnc->nfs_accesscnt, itv), + S_VALUE(snnp->nfs_getattcnt, snnc->nfs_getattcnt, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display NFS server statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_nfsd_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_nfsd + *snndc = (struct stats_net_nfsd *) a->buf[curr], + *snndp = (struct stats_net_nfsd *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 11, 9, 2, + S_VALUE(snndp->nfsd_rpccnt, snndc->nfsd_rpccnt, itv), + S_VALUE(snndp->nfsd_rpcbad, snndc->nfsd_rpcbad, itv), + S_VALUE(snndp->nfsd_netcnt, snndc->nfsd_netcnt, itv), + S_VALUE(snndp->nfsd_netudpcnt, snndc->nfsd_netudpcnt, itv), + S_VALUE(snndp->nfsd_nettcpcnt, snndc->nfsd_nettcpcnt, itv), + S_VALUE(snndp->nfsd_rchits, snndc->nfsd_rchits, itv), + S_VALUE(snndp->nfsd_rcmisses, snndc->nfsd_rcmisses, itv), + S_VALUE(snndp->nfsd_readcnt, snndc->nfsd_readcnt, itv), + S_VALUE(snndp->nfsd_writecnt, snndc->nfsd_writecnt, itv), + S_VALUE(snndp->nfsd_accesscnt, snndc->nfsd_accesscnt, itv), + S_VALUE(snndp->nfsd_getattcnt, snndc->nfsd_getattcnt, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display network sockets statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_net_sock_stats(struct activity *a, int curr, int dispavg) +{ + struct stats_net_sock + *snsc = (struct stats_net_sock *) a->buf[curr]; + static unsigned long long + avg_sock_inuse = 0, + avg_tcp_inuse = 0, + avg_udp_inuse = 0, + avg_raw_inuse = 0, + avg_frag_inuse = 0, + avg_tcp_tw = 0; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(NO_UNIT, 6, 9, + (unsigned long long) snsc->sock_inuse, + (unsigned long long) snsc->tcp_inuse, + (unsigned long long) snsc->udp_inuse, + (unsigned long long) snsc->raw_inuse, + (unsigned long long) snsc->frag_inuse, + (unsigned long long) snsc->tcp_tw); + printf("\n"); + + /* Will be used to compute the average */ + avg_sock_inuse += snsc->sock_inuse; + avg_tcp_inuse += snsc->tcp_inuse; + avg_udp_inuse += snsc->udp_inuse; + avg_raw_inuse += snsc->raw_inuse; + avg_frag_inuse += snsc->frag_inuse; + avg_tcp_tw += snsc->tcp_tw; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 6, 9, 0, + (double) avg_sock_inuse / avg_count, + (double) avg_tcp_inuse / avg_count, + (double) avg_udp_inuse / avg_count, + (double) avg_raw_inuse / avg_count, + (double) avg_frag_inuse / avg_count, + (double) avg_tcp_tw / avg_count); + printf("\n"); + + /* Reset average counters */ + avg_sock_inuse = avg_tcp_inuse = avg_udp_inuse = 0; + avg_raw_inuse = avg_frag_inuse = avg_tcp_tw = 0; + } +} + +/* + *************************************************************************** + * Display network sockets statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_sock_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_net_sock_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average network sockets statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_net_sock_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_net_sock_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display IP network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_ip_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_ip + *snic = (struct stats_net_ip *) a->buf[curr], + *snip = (struct stats_net_ip *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 8, 9, 2, + S_VALUE(snip->InReceives, snic->InReceives, itv), + S_VALUE(snip->ForwDatagrams, snic->ForwDatagrams, itv), + S_VALUE(snip->InDelivers, snic->InDelivers, itv), + S_VALUE(snip->OutRequests, snic->OutRequests, itv), + S_VALUE(snip->ReasmReqds, snic->ReasmReqds, itv), + S_VALUE(snip->ReasmOKs, snic->ReasmOKs, itv), + S_VALUE(snip->FragOKs, snic->FragOKs, itv), + S_VALUE(snip->FragCreates, snic->FragCreates, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display IP network errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_eip_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_eip + *sneic = (struct stats_net_eip *) a->buf[curr], + *sneip = (struct stats_net_eip *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 8, 9, 2, + S_VALUE(sneip->InHdrErrors, sneic->InHdrErrors, itv), + S_VALUE(sneip->InAddrErrors, sneic->InAddrErrors, itv), + S_VALUE(sneip->InUnknownProtos, sneic->InUnknownProtos, itv), + S_VALUE(sneip->InDiscards, sneic->InDiscards, itv), + S_VALUE(sneip->OutDiscards, sneic->OutDiscards, itv), + S_VALUE(sneip->OutNoRoutes, sneic->OutNoRoutes, itv), + S_VALUE(sneip->ReasmFails, sneic->ReasmFails, itv), + S_VALUE(sneip->FragFails, sneic->FragFails, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display ICMP network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_icmp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_icmp + *snic = (struct stats_net_icmp *) a->buf[curr], + *snip = (struct stats_net_icmp *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 14, 9, 2, + S_VALUE(snip->InMsgs, snic->InMsgs, itv), + S_VALUE(snip->OutMsgs, snic->OutMsgs, itv), + S_VALUE(snip->InEchos, snic->InEchos, itv), + S_VALUE(snip->InEchoReps, snic->InEchoReps, itv), + S_VALUE(snip->OutEchos, snic->OutEchos, itv), + S_VALUE(snip->OutEchoReps, snic->OutEchoReps, itv), + S_VALUE(snip->InTimestamps, snic->InTimestamps, itv), + S_VALUE(snip->InTimestampReps, snic->InTimestampReps, itv), + S_VALUE(snip->OutTimestamps, snic->OutTimestamps, itv), + S_VALUE(snip->OutTimestampReps, snic->OutTimestampReps, itv), + S_VALUE(snip->InAddrMasks, snic->InAddrMasks, itv), + S_VALUE(snip->InAddrMaskReps, snic->InAddrMaskReps, itv), + S_VALUE(snip->OutAddrMasks, snic->OutAddrMasks, itv), + S_VALUE(snip->OutAddrMaskReps, snic->OutAddrMaskReps, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display ICMP network errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_eicmp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_eicmp + *sneic = (struct stats_net_eicmp *) a->buf[curr], + *sneip = (struct stats_net_eicmp *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 12, 9, 2, + S_VALUE(sneip->InErrors, sneic->InErrors, itv), + S_VALUE(sneip->OutErrors, sneic->OutErrors, itv), + S_VALUE(sneip->InDestUnreachs, sneic->InDestUnreachs, itv), + S_VALUE(sneip->OutDestUnreachs, sneic->OutDestUnreachs, itv), + S_VALUE(sneip->InTimeExcds, sneic->InTimeExcds, itv), + S_VALUE(sneip->OutTimeExcds, sneic->OutTimeExcds, itv), + S_VALUE(sneip->InParmProbs, sneic->InParmProbs, itv), + S_VALUE(sneip->OutParmProbs, sneic->OutParmProbs, itv), + S_VALUE(sneip->InSrcQuenchs, sneic->InSrcQuenchs, itv), + S_VALUE(sneip->OutSrcQuenchs, sneic->OutSrcQuenchs, itv), + S_VALUE(sneip->InRedirects, sneic->InRedirects, itv), + S_VALUE(sneip->OutRedirects, sneic->OutRedirects, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display TCP network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_tcp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_tcp + *sntc = (struct stats_net_tcp *) a->buf[curr], + *sntp = (struct stats_net_tcp *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 2, + S_VALUE(sntp->ActiveOpens, sntc->ActiveOpens, itv), + S_VALUE(sntp->PassiveOpens, sntc->PassiveOpens, itv), + S_VALUE(sntp->InSegs, sntc->InSegs, itv), + S_VALUE(sntp->OutSegs, sntc->OutSegs, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display TCP network errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_etcp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_etcp + *snetc = (struct stats_net_etcp *) a->buf[curr], + *snetp = (struct stats_net_etcp *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 5, 9, 2, + S_VALUE(snetp->AttemptFails, snetc->AttemptFails, itv), + S_VALUE(snetp->EstabResets, snetc->EstabResets, itv), + S_VALUE(snetp->RetransSegs, snetc->RetransSegs, itv), + S_VALUE(snetp->InErrs, snetc->InErrs, itv), + S_VALUE(snetp->OutRsts, snetc->OutRsts, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display UDP network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_udp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_udp + *snuc = (struct stats_net_udp *) a->buf[curr], + *snup = (struct stats_net_udp *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 2, + S_VALUE(snup->InDatagrams, snuc->InDatagrams, itv), + S_VALUE(snup->OutDatagrams, snuc->OutDatagrams, itv), + S_VALUE(snup->NoPorts, snuc->NoPorts, itv), + S_VALUE(snup->InErrors, snuc->InErrors, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display IPv6 sockets statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_net_sock6_stats(struct activity *a, int curr, int dispavg) +{ + struct stats_net_sock6 + *snsc = (struct stats_net_sock6 *) a->buf[curr]; + static unsigned long long + avg_tcp6_inuse = 0, + avg_udp6_inuse = 0, + avg_raw6_inuse = 0, + avg_frag6_inuse = 0; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(NO_UNIT, 4, 9, + (unsigned long long) snsc->tcp6_inuse, + (unsigned long long) snsc->udp6_inuse, + (unsigned long long) snsc->raw6_inuse, + (unsigned long long) snsc->frag6_inuse); + printf("\n"); + + /* Will be used to compute the average */ + avg_tcp6_inuse += snsc->tcp6_inuse; + avg_udp6_inuse += snsc->udp6_inuse; + avg_raw6_inuse += snsc->raw6_inuse; + avg_frag6_inuse += snsc->frag6_inuse; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 0, + (double) avg_tcp6_inuse / avg_count, + (double) avg_udp6_inuse / avg_count, + (double) avg_raw6_inuse / avg_count, + (double) avg_frag6_inuse / avg_count); + printf("\n"); + + /* Reset average counters */ + avg_tcp6_inuse = avg_udp6_inuse = avg_raw6_inuse = avg_frag6_inuse = 0; + } +} + +/* + *************************************************************************** + * Display IPv6 sockets statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_sock6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_net_sock6_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average IPv6 sockets statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_net_sock6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_net_sock6_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display IPv6 network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_ip6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_ip6 + *snic = (struct stats_net_ip6 *) a->buf[curr], + *snip = (struct stats_net_ip6 *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 10, 9, 2, + S_VALUE(snip->InReceives6, snic->InReceives6, itv), + S_VALUE(snip->OutForwDatagrams6, snic->OutForwDatagrams6, itv), + S_VALUE(snip->InDelivers6, snic->InDelivers6, itv), + S_VALUE(snip->OutRequests6, snic->OutRequests6, itv), + S_VALUE(snip->ReasmReqds6, snic->ReasmReqds6, itv), + S_VALUE(snip->ReasmOKs6, snic->ReasmOKs6, itv), + S_VALUE(snip->InMcastPkts6, snic->InMcastPkts6, itv), + S_VALUE(snip->OutMcastPkts6, snic->OutMcastPkts6, itv), + S_VALUE(snip->FragOKs6, snic->FragOKs6, itv), + S_VALUE(snip->FragCreates6, snic->FragCreates6, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display IPv6 network errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_eip6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_eip6 + *sneic = (struct stats_net_eip6 *) a->buf[curr], + *sneip = (struct stats_net_eip6 *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 11, 9, 2, + S_VALUE(sneip->InHdrErrors6, sneic->InHdrErrors6, itv), + S_VALUE(sneip->InAddrErrors6, sneic->InAddrErrors6, itv), + S_VALUE(sneip->InUnknownProtos6, sneic->InUnknownProtos6, itv), + S_VALUE(sneip->InTooBigErrors6, sneic->InTooBigErrors6, itv), + S_VALUE(sneip->InDiscards6, sneic->InDiscards6, itv), + S_VALUE(sneip->OutDiscards6, sneic->OutDiscards6, itv), + S_VALUE(sneip->InNoRoutes6, sneic->InNoRoutes6, itv), + S_VALUE(sneip->OutNoRoutes6, sneic->OutNoRoutes6, itv), + S_VALUE(sneip->ReasmFails6, sneic->ReasmFails6, itv), + S_VALUE(sneip->FragFails6, sneic->FragFails6, itv), + S_VALUE(sneip->InTruncatedPkts6, sneic->InTruncatedPkts6, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display ICMPv6 network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_icmp6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_icmp6 + *snic = (struct stats_net_icmp6 *) a->buf[curr], + *snip = (struct stats_net_icmp6 *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 17, 9, 2, + S_VALUE(snip->InMsgs6, snic->InMsgs6, itv), + S_VALUE(snip->OutMsgs6, snic->OutMsgs6, itv), + S_VALUE(snip->InEchos6, snic->InEchos6, itv), + S_VALUE(snip->InEchoReplies6, snic->InEchoReplies6, itv), + S_VALUE(snip->OutEchoReplies6, snic->OutEchoReplies6, itv), + S_VALUE(snip->InGroupMembQueries6, snic->InGroupMembQueries6, itv), + S_VALUE(snip->InGroupMembResponses6, snic->InGroupMembResponses6, itv), + S_VALUE(snip->OutGroupMembResponses6, snic->OutGroupMembResponses6, itv), + S_VALUE(snip->InGroupMembReductions6, snic->InGroupMembReductions6, itv), + S_VALUE(snip->OutGroupMembReductions6, snic->OutGroupMembReductions6, itv), + S_VALUE(snip->InRouterSolicits6, snic->InRouterSolicits6, itv), + S_VALUE(snip->OutRouterSolicits6, snic->OutRouterSolicits6, itv), + S_VALUE(snip->InRouterAdvertisements6, snic->InRouterAdvertisements6, itv), + S_VALUE(snip->InNeighborSolicits6, snic->InNeighborSolicits6, itv), + S_VALUE(snip->OutNeighborSolicits6, snic->OutNeighborSolicits6, itv), + S_VALUE(snip->InNeighborAdvertisements6, snic->InNeighborAdvertisements6, itv), + S_VALUE(snip->OutNeighborAdvertisements6, snic->OutNeighborAdvertisements6, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display ICMPv6 network errors statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_eicmp6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_eicmp6 + *sneic = (struct stats_net_eicmp6 *) a->buf[curr], + *sneip = (struct stats_net_eicmp6 *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 11, 9, 2, + S_VALUE(sneip->InErrors6, sneic->InErrors6, itv), + S_VALUE(sneip->InDestUnreachs6, sneic->InDestUnreachs6, itv), + S_VALUE(sneip->OutDestUnreachs6, sneic->OutDestUnreachs6, itv), + S_VALUE(sneip->InTimeExcds6, sneic->InTimeExcds6, itv), + S_VALUE(sneip->OutTimeExcds6, sneic->OutTimeExcds6, itv), + S_VALUE(sneip->InParmProblems6, sneic->InParmProblems6, itv), + S_VALUE(sneip->OutParmProblems6, sneic->OutParmProblems6, itv), + S_VALUE(sneip->InRedirects6, sneic->InRedirects6, itv), + S_VALUE(sneip->OutRedirects6, sneic->OutRedirects6, itv), + S_VALUE(sneip->InPktTooBigs6, sneic->InPktTooBigs6, itv), + S_VALUE(sneip->OutPktTooBigs6, sneic->OutPktTooBigs6, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display UDPv6 network traffic statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_net_udp6_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + struct stats_net_udp6 + *snuc = (struct stats_net_udp6 *) a->buf[curr], + *snup = (struct stats_net_udp6 *) a->buf[prev]; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 2, + S_VALUE(snup->InDatagrams6, snuc->InDatagrams6, itv), + S_VALUE(snup->OutDatagrams6, snuc->OutDatagrams6, itv), + S_VALUE(snup->NoPorts6, snuc->NoPorts6, itv), + S_VALUE(snup->InErrors6, snuc->InErrors6, itv)); + printf("\n"); +} + +/* + *************************************************************************** + * Display CPU frequency statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg True if displaying average statistics. + *************************************************************************** + */ +void stub_print_pwr_cpufreq_stats(struct activity *a, int curr, int dispavg) +{ + int i; + struct stats_pwr_cpufreq *spc; + static __nr_t nr_alloc = 0; + static unsigned long long + *avg_cpufreq = NULL; + + if (!avg_cpufreq || (a->nr[curr] > nr_alloc)) { + /* Allocate array of CPU frequency */ + SREALLOC(avg_cpufreq, unsigned long long, sizeof(unsigned long long) * a->nr[curr]); + if (a->nr[curr] > nr_alloc) { + /* Init additional space allocated */ + memset(avg_cpufreq + nr_alloc, 0, + sizeof(unsigned long long) * (a->nr[curr] - nr_alloc)); + } + nr_alloc = a->nr[curr]; + } + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 7, 9); + } + + for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) { + + /* + * The size of a->buf[...] CPU structure may be different from the default + * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file! + * That's why we don't use a syntax like: + * spc = (struct stats_pwr_cpufreq *) a->buf[...] + i; + */ + spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize); + + if (!spc->cpufreq) + /* This CPU is offline: Don't display it */ + continue; + + /* + * Note: @nr[curr] is in [1, NR_CPUS + 1]. + * Bitmap size is provided for (NR_CPUS + 1) CPUs. + * Anyway, NR_CPUS may vary between the version of sysstat + * used by sadc to create a file, and the version of sysstat + * used by sar to read it... + */ + + /* Should current CPU (including CPU "all") be displayed? */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07)))) + /* No */ + continue; + + printf("%-11s", timestamp[curr]); + + if (!i) { + /* This is CPU "all" */ + cprintf_in(IS_STR, "%s", " all", 0); + } + else { + cprintf_in(IS_INT, " %3d", "", i - 1); + } + + if (!dispavg) { + /* Display instantaneous values */ + cprintf_f(NO_UNIT, 1, 9, 2, + ((double) spc->cpufreq) / 100); + printf("\n"); + /* + * Will be used to compute the average. + * Note: Overflow unlikely to happen but not impossible... + */ + avg_cpufreq[i] += spc->cpufreq; + } + else { + /* Display average values */ + cprintf_f(NO_UNIT, 1, 9, 2, + (double) avg_cpufreq[i] / (100 * avg_count)); + printf("\n"); + } + } + + if (dispavg && avg_cpufreq) { + /* Array of CPU frequency no longer needed: Free it! */ + free(avg_cpufreq); + avg_cpufreq = NULL; + nr_alloc = 0; + } +} + +/* + *************************************************************************** + * Display CPU frequency statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pwr_cpufreq_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_cpufreq_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average CPU frequency statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_pwr_cpufreq_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_cpufreq_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display fan statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg True if displaying average statistics. + *************************************************************************** + */ +void stub_print_pwr_fan_stats(struct activity *a, int curr, int dispavg) +{ + int i; + struct stats_pwr_fan *spc; + static __nr_t nr_alloc = 0; + static double *avg_fan = NULL; + static double *avg_fan_min = NULL; + + /* Allocate arrays of fan RPMs */ + if (!avg_fan || (a->nr[curr] > nr_alloc)) { + SREALLOC(avg_fan, double, sizeof(double) * a->nr[curr]); + SREALLOC(avg_fan_min, double, sizeof(double) * a->nr[curr]); + + if (a->nr[curr] > nr_alloc) { + /* Init additional space allocated */ + memset(avg_fan + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + memset(avg_fan_min + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + } + nr_alloc = a->nr[curr]; + } + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, -2, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize); + + printf("%-11s", timestamp[curr]); + cprintf_in(IS_INT, " %5d", "", i + 1); + + if (dispavg) { + /* Display average values */ + cprintf_f(NO_UNIT, 2, 9, 2, + (double) avg_fan[i] / avg_count, + (double) (avg_fan[i] - avg_fan_min[i]) / avg_count); + } + else { + /* Display instantaneous values */ + cprintf_f(NO_UNIT, 2, 9, 2, + spc->rpm, + spc->rpm - spc->rpm_min); + avg_fan[i] += spc->rpm; + avg_fan_min[i] += spc->rpm_min; + } + + cprintf_in(IS_STR, " %s\n", spc->device, 0); + } + + if (dispavg && avg_fan) { + free(avg_fan); + free(avg_fan_min); + avg_fan = NULL; + avg_fan_min = NULL; + nr_alloc = 0; + } +} + +/* + *************************************************************************** + * Display fan statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pwr_fan_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_fan_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average fan statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_pwr_fan_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_fan_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display device temperature statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg True if displaying average statistics. + *************************************************************************** + */ +void stub_print_pwr_temp_stats(struct activity *a, int curr, int dispavg) +{ + int i; + struct stats_pwr_temp *spc; + static __nr_t nr_alloc = 0; + static double *avg_temp = NULL; + static double *avg_temp_min = NULL, *avg_temp_max = NULL; + + /* Allocate arrays of temperatures */ + if (!avg_temp || (a->nr[curr] > nr_alloc)) { + SREALLOC(avg_temp, double, sizeof(double) * a->nr[curr]); + SREALLOC(avg_temp_min, double, sizeof(double) * a->nr[curr]); + SREALLOC(avg_temp_max, double, sizeof(double) * a->nr[curr]); + + if (a->nr[curr] > nr_alloc) { + /* Init additional space allocated */ + memset(avg_temp + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + memset(avg_temp_min + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + memset(avg_temp_max + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + } + nr_alloc = a->nr[curr]; + } + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, -2, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize); + + printf("%-11s", timestamp[curr]); + cprintf_in(IS_INT, " %5d", "", i + 1); + + if (dispavg) { + /* Display average values */ + cprintf_f(NO_UNIT, 1, 9, 2, (double) avg_temp[i] / avg_count); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (avg_temp_max[i] - avg_temp_min[i]) ? + ((double) (avg_temp[i] / avg_count) - avg_temp_min[i]) / (avg_temp_max[i] - avg_temp_min[i]) * 100 + : 0.0); + } + else { + /* Display instantaneous values */ + cprintf_f(NO_UNIT, 1, 9, 2, spc->temp); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (spc->temp_max - spc->temp_min) ? + (spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 + : 0.0); + avg_temp[i] += spc->temp; + /* Assume that min and max temperatures cannot vary */ + avg_temp_min[i] = spc->temp_min; + avg_temp_max[i] = spc->temp_max; + } + + cprintf_in(IS_STR, " %s\n", spc->device, 0); + } + + if (dispavg && avg_temp) { + free(avg_temp); + free(avg_temp_min); + free(avg_temp_max); + avg_temp = NULL; + avg_temp_min = NULL; + avg_temp_max = NULL; + nr_alloc = 0; + } +} + +/* + *************************************************************************** + * Display temperature statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pwr_temp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_temp_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average temperature statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_pwr_temp_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_temp_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display voltage inputs statistics. This function is used to display + * instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg True if displaying average statistics. + *************************************************************************** + */ +void stub_print_pwr_in_stats(struct activity *a, int curr, int dispavg) +{ + int i; + struct stats_pwr_in *spc; + static __nr_t nr_alloc = 0; + static double *avg_in = NULL; + static double *avg_in_min = NULL, *avg_in_max = NULL; + + /* Allocate arrays of voltage inputs */ + if (!avg_in || (a->nr[curr] > nr_alloc)) { + SREALLOC(avg_in, double, sizeof(double) * a->nr[curr]); + SREALLOC(avg_in_min, double, sizeof(double) * a->nr[curr]); + SREALLOC(avg_in_max, double, sizeof(double) * a->nr[curr]); + + if (a->nr[curr] > nr_alloc) { + /* Init additional space allocated */ + memset(avg_in + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + memset(avg_in_min + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + memset(avg_in_max + nr_alloc, 0, + sizeof(double) * (a->nr[curr] - nr_alloc)); + } + nr_alloc = a->nr[curr]; + } + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, -2, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize); + + printf("%-11s", timestamp[curr]); + cprintf_in(IS_INT, " %5d", "", i); + + if (dispavg) { + /* Display average values */ + cprintf_f(NO_UNIT, 1, 9, 2, (double) avg_in[i] / avg_count); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (avg_in_max[i] - avg_in_min[i]) ? + ((double) (avg_in[i] / avg_count) - avg_in_min[i]) / (avg_in_max[i] - avg_in_min[i]) * 100 + : 0.0); + } + else { + /* Display instantaneous values */ + cprintf_f(NO_UNIT, 1, 9, 2, spc->in); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + (spc->in_max - spc->in_min) ? + (spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 + : 0.0); + avg_in[i] += spc->in; + /* Assume that min and max voltage inputs cannot vary */ + avg_in_min[i] = spc->in_min; + avg_in_max[i] = spc->in_max; + } + + cprintf_in(IS_STR, " %s\n", spc->device, 0); + } + + if (dispavg && avg_in) { + free(avg_in); + free(avg_in_min); + free(avg_in_max); + avg_in = NULL; + avg_in_min = NULL; + avg_in_max = NULL; + nr_alloc = 0; + } +} + +/* + *************************************************************************** + * Display voltage inputs statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pwr_in_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_in_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average voltage inputs statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_pwr_in_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_in_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display huge pages statistics. This function is used to + * display instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_huge_stats(struct activity *a, int curr, int dispavg) +{ + struct stats_huge + *smc = (struct stats_huge *) a->buf[curr]; + static unsigned long long + avg_frhkb = 0, + avg_tlhkb = 0; + int unit = NO_UNIT; + + if (DISPLAY_UNIT(flags)) { + /* Default values unit is kB */ + unit = UNIT_KILOBYTE; + } + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 0, 9); + } + + if (!dispavg) { + /* Display instantaneous values */ + printf("%-11s", timestamp[curr]); + cprintf_u64(unit, 2, 9, + (unsigned long long) smc->frhkb, + (unsigned long long) (smc->tlhkb - smc->frhkb)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + smc->tlhkb ? + SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) : 0.0); + printf("\n"); + + /* Will be used to compute the average */ + avg_frhkb += smc->frhkb; + avg_tlhkb += smc->tlhkb; + } + else { + /* Display average values */ + printf("%-11s", timestamp[curr]); + cprintf_f(unit, 2, 9, 0, + (double) avg_frhkb / avg_count, + ((double) avg_tlhkb / avg_count) - + ((double) avg_frhkb / avg_count)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + avg_tlhkb ? + SP_VALUE((double) avg_frhkb / avg_count, + (double) avg_tlhkb / avg_count, + (double) avg_tlhkb / avg_count) : 0.0); + printf("\n"); + + /* Reset average counters */ + avg_frhkb = avg_tlhkb = 0; + } +} + +/* + *************************************************************************** + * Display huge pages statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_huge_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_huge_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display huge pages statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_huge_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_huge_stats(a, curr, TRUE); +} + +/* + *************************************************************************** + * Display CPU weighted frequency statistics. This function is used to + * display instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +void print_pwr_wghfreq_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, k; + struct stats_pwr_wghfreq *spc, *spp, *spc_k, *spp_k; + unsigned long long tis, tisfreq; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, 7, 9); + } + + for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) { + + /* + * The size of a->buf[...] CPU structure may be different from the default + * sizeof(struct stats_pwr_wghfreq) value if data have been read from a file! + * That's why we don't use a syntax like: + * spc = (struct stats_pwr_wghfreq *) a->buf[...] + i; + */ + spc = (struct stats_pwr_wghfreq *) ((char *) a->buf[curr] + i * a->msize * a->nr2); + spp = (struct stats_pwr_wghfreq *) ((char *) a->buf[prev] + i * a->msize * a->nr2); + + /* + * Note: a->nr is in [1, NR_CPUS + 1]. + * Bitmap size is provided for (NR_CPUS + 1) CPUs. + * Anyway, NR_CPUS may vary between the version of sysstat + * used by sadc to create a file, and the version of sysstat + * used by sar to read it... + */ + + /* Should current CPU (including CPU "all") be displayed? */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07)))) + /* No */ + continue; + + /* Yes: Display it */ + printf("%-11s", timestamp[curr]); + + if (!i) { + /* This is CPU "all" */ + cprintf_in(IS_STR, "%s", " all", 0); + } + else { + cprintf_in(IS_INT, " %3d", "", i - 1); + } + + tisfreq = 0; + tis = 0; + + for (k = 0; k < a->nr2; k++) { + + spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * a->msize); + if (!spc_k->freq) + break; + spp_k = (struct stats_pwr_wghfreq *) ((char *) spp + k * a->msize); + + tisfreq += (spc_k->freq / 1000) * + (spc_k->time_in_state - spp_k->time_in_state); + tis += (spc_k->time_in_state - spp_k->time_in_state); + } + + /* Display weighted frequency for current CPU */ + cprintf_f(NO_UNIT, 1, 9, 2, + tis ? ((double) tisfreq) / tis : 0.0); + printf("\n"); + } +} + +/* + *************************************************************************** + * Display USB devices statistics. This function is used to + * display instantaneous and summary statistics. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +void stub_print_pwr_usb_stats(struct activity *a, int curr, int dispavg) +{ + int i, j; + char fmt[16]; + struct stats_pwr_usb *suc, *sum; + + if (dis) { + printf("\n%-11s BUS idvendor idprod maxpower", + (dispavg ? _("Summary:") : timestamp[!curr])); + printf(" %-*s product\n", MAX_MANUF_LEN - 1, "manufact"); + } + + for (i = 0; i < a->nr[curr]; i++) { + suc = (struct stats_pwr_usb *) ((char *) a->buf[curr] + i * a->msize); + + printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr])); + cprintf_in(IS_INT, " %6d", "", suc->bus_nr); + cprintf_x(2, 9, + suc->vendor_id, + suc->product_id); + cprintf_u64(NO_UNIT, 1, 9, + /* bMaxPower is expressed in 2 mA units */ + (unsigned long long) (suc->bmaxpower << 1)); + + snprintf(fmt, 16, " %%-%ds", MAX_MANUF_LEN - 1); + cprintf_s(IS_STR, fmt, suc->manufacturer); + cprintf_s(IS_STR, " %s\n", suc->product); + + if (!dispavg) { + /* Save current USB device in summary list */ + for (j = 0; j < a->nr_allocated; j++) { + sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize); + + if ((sum->bus_nr == suc->bus_nr) && + (sum->vendor_id == suc->vendor_id) && + (sum->product_id == suc->product_id)) + /* USB device found in summary list */ + break; + if (!sum->bus_nr) { + /* + * Current slot is free: + * Save USB device in summary list. + */ + *sum = *suc; + a->nr[2] = j + 1; + break; + } + } + if (j == a->nr_allocated) { + /* + * No free slot has been found for current device. + * So enlarge buffers then save device in list. + */ + reallocate_all_buffers(a, j); + sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize); + *sum = *suc; + a->nr[2] = j + 1; + } + } + } +} + +/* + *************************************************************************** + * Display USB devices statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_pwr_usb_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_usb_stats(a, curr, FALSE); +} + +/* + *************************************************************************** + * Display average USB devices statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_pwr_usb_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_pwr_usb_stats(a, 2, TRUE); +} + +/* + *************************************************************************** + * Display filesystems statistics. This function is used to + * display instantaneous and average statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @dispavg TRUE if displaying average statistics. + *************************************************************************** + */ +__print_funct_t stub_print_filesystem_stats(struct activity *a, int prev, int curr, int dispavg) +{ + int i, j, j0, found; + struct stats_filesystem *sfc, *sfp, *sfm; + int unit = NO_UNIT; + + if (DISPLAY_UNIT(flags)) { + /* Default values unit is B */ + unit = UNIT_BYTE; + } + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line((dispavg ? _("Summary:") : timestamp[!curr]), + a, FIRST + DISPLAY_MOUNT(a->opt_flags), -1, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize); + + if (a->item_list != NULL) { + /* A list of devices has been entered on the command line */ + if (!search_list_item(a->item_list, + DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name)) + /* Device not found */ + continue; + } + + found = FALSE; + if (DISPLAY_ZERO_OMIT(flags) && !dispavg) { + + if (a->nr[prev] > 0) { + /* Look for corresponding fs in previous iteration */ + j = i; + + if (j >= a->nr[prev]) { + j = a->nr[prev] - 1; + } + + j0 = j; + + do { + sfp = (struct stats_filesystem *) ((char *) a->buf[prev] + j * a->msize); + if (!strcmp(sfp->fs_name, sfc->fs_name)) { + found = TRUE; + break; + } + if (++j >= a->nr[prev]) { + j = 0; + } + } + while (j != j0); + } + } + + if (!DISPLAY_ZERO_OMIT(flags) || dispavg || WANT_SINCE_BOOT(flags) || !found || + (found && memcmp(sfp, sfc, STATS_FILESYSTEM_SIZE2CMP))) { + + printf("%-11s", (dispavg ? _("Summary:") : timestamp[curr])); + cprintf_f(unit, 2, 9, 0, + unit < 0 ? (double) sfc->f_bfree / 1024 / 1024 : (double) sfc->f_bfree, + unit < 0 ? (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024 : + (double) (sfc->f_blocks - sfc->f_bfree)); + cprintf_pc(DISPLAY_UNIT(flags), 2, 9, 2, + /* f_blocks is not zero. But test it anyway ;-) */ + sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks) + : 0.0, + sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks) + : 0.0); + cprintf_u64(NO_UNIT, 2, 9, + (unsigned long long) sfc->f_ffree, + (unsigned long long) (sfc->f_files - sfc->f_ffree)); + cprintf_pc(DISPLAY_UNIT(flags), 1, 9, 2, + sfc->f_files ? SP_VALUE(sfc->f_ffree, sfc->f_files, sfc->f_files) + : 0.0); + cprintf_in(IS_STR, " %s\n", + DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name, 0); + } + + if (!dispavg) { + /* Save current filesystem in summary list */ + for (j = 0; j < a->nr_allocated; j++) { + sfm = (struct stats_filesystem *) ((char *) a->buf[2] + j * a->msize); + + if (!strcmp(sfm->fs_name, sfc->fs_name) || + !sfm->f_blocks) { + /* + * Filesystem found in list (then save again its stats) + * or free slot (end of list). + */ + *sfm = *sfc; + if (j >= a->nr[2]) { + a->nr[2] = j + 1; + } + break; + } + } + if (j == a->nr_allocated) { + /* + * No free slot has been found for current filesystem. + * So enlarge buffers then save filesystem in list. + */ + reallocate_all_buffers(a, j); + sfm = (struct stats_filesystem *) ((char *) a->buf[2] + j * a->msize); + *sfm = *sfc; + a->nr[2] = j + 1; + } + } + } +} + +/* + *************************************************************************** + * Display filesystems statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_filesystem_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_filesystem_stats(a, prev, curr, FALSE); +} + +/* + *************************************************************************** + * Display average filesystems statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_filesystem_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_filesystem_stats(a, prev, 2, TRUE); +} + +/* + *************************************************************************** + * Display Fibre Channel HBA statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_fchost_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i, j, j0, found; + struct stats_fchost *sfcc, *sfcp; + + if (dis) { + print_hdr_line(timestamp[!curr], a, FIRST, -1, 9); + } + + for (i = 0; i < a->nr[curr]; i++) { + sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize); + + if (WANT_SINCE_BOOT(flags)) { + sfcp = (struct stats_fchost *) ((char *) a->buf[prev]); + found = TRUE; + } + else { + found = FALSE; + + if (a->nr[prev] > 0) { + /* Look for corresponding structure in previous iteration */ + j = i; + + if (j >= a->nr[prev]) { + j = a->nr[prev] - 1; + } + + j0 = j; + + do { + sfcp = (struct stats_fchost *) ((char *) a->buf[prev] + j * a->msize); + if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) { + found = TRUE; + break; + } + + if (++j >= a->nr[prev]) { + j = 0; + } + } + while (j != j0); + } + } + + if (!found) + continue; + + printf("%-11s", timestamp[curr]); + cprintf_f(NO_UNIT, 4, 9, 2, + S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv), + S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv), + S_VALUE(sfcp->f_rxwords, sfcc->f_rxwords, itv), + S_VALUE(sfcp->f_txwords, sfcc->f_txwords, itv)); + cprintf_in(IS_STR, " %s\n", sfcc->fchost_name, 0); + } +} + +/* + *************************************************************************** + * Display softnet statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_softnet_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + int i; + struct stats_softnet + *ssnc = (struct stats_softnet *) a->buf[curr], + *ssnp = (struct stats_softnet *) a->buf[prev]; + unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0}; + + if (dis || DISPLAY_ZERO_OMIT(flags)) { + print_hdr_line(timestamp[!curr], a, FIRST, 7, 9); + } + + /* + * @nr[curr] cannot normally be greater than @nr_ini + * (since @nr_ini counts up all CPU, even those offline). + * If this happens, it may be because the machine has been + * restarted with more CPU and no LINUX_RESTART has been + * inserted in file. + */ + if (a->nr[curr] > a->nr_ini) { + a->nr_ini = a->nr[curr]; + } + + /* Compute statistics for CPU "all" */ + get_global_soft_statistics(a, prev, curr, flags, offline_cpu_bitmap); + + for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { + + /* + * Should current CPU (including CPU "all") be displayed? + * Note: a->nr is in [1, NR_CPUS + 1]. + * Bitmap size is provided for (NR_CPUS + 1) CPUs. + * Anyway, NR_CPUS may vary between the version of sysstat + * used by sadc to create a file, and the version of sysstat + * used by sar to read it... + */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) || + offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07))) + /* No */ + continue; + /* + * The size of a->buf[...] CPU structure may be different from the default + * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file! + * That's why we don't use a syntax like: + * ssnc = (struct stats_softnet *) a->buf[...] + i; + */ + ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize); + ssnp = (struct stats_softnet *) ((char *) a->buf[prev] + i * a->msize); + + if (DISPLAY_ZERO_OMIT(flags) && !memcmp(ssnp, ssnc, STATS_SOFTNET_SIZE)) + continue; + + printf("%-11s", timestamp[curr]); + + if (!i) { + /* This is CPU "all" */ + cprintf_in(IS_STR, " %s", " all", 0); + } + else { + cprintf_in(IS_INT, " %7d", "", i - 1); + } + + cprintf_f(NO_UNIT, 5, 9, 2, + S_VALUE(ssnp->processed, ssnc->processed, itv), + S_VALUE(ssnp->dropped, ssnc->dropped, itv), + S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv), + S_VALUE(ssnp->received_rps, ssnc->received_rps, itv), + S_VALUE(ssnp->flow_limit, ssnc->flow_limit, itv)); + printf("\n"); + } +} diff --git a/tests/12.0.1/pr_stats.h b/tests/12.0.1/pr_stats.h new file mode 100644 index 0000000..a56b518 --- /dev/null +++ b/tests/12.0.1/pr_stats.h @@ -0,0 +1,124 @@ +/* + * pr_stats.h: Include file used to display system statistics + * (C) 1999-2018 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _PR_STATS_H +#define _PR_STATS_H + +#include "common.h" + + +/* + *************************************************************************** + * Prototypes for functions used to display system statistics + *************************************************************************** + */ + +/* Functions used to display instantaneous statistics */ +__print_funct_t print_cpu_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pcsw_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_irq_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_swap_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_paging_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_io_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_memory_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_ktables_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_queue_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_serial_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_disk_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_dev_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_edev_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_nfs_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_nfsd_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_sock_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_ip_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_eip_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_icmp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_eicmp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_tcp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_etcp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_udp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_sock6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_ip6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_eip6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_icmp6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_eicmp6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_net_udp6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_cpufreq_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_fan_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_temp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_in_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_huge_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_wghfreq_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_pwr_usb_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_filesystem_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_fchost_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_softnet_stats + (struct activity *, int, int, unsigned long long); + +/* Functions used to display average statistics */ +__print_funct_t print_avg_memory_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_ktables_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_queue_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_net_sock_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_net_sock6_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_pwr_cpufreq_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_pwr_fan_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_pwr_temp_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_pwr_in_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_huge_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_pwr_usb_stats + (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_filesystem_stats + (struct activity *, int, int, unsigned long long); + +#endif /* _PR_STATS_H */ diff --git a/tests/12.0.1/rd_sensors.h b/tests/12.0.1/rd_sensors.h new file mode 100644 index 0000000..0539040 --- /dev/null +++ b/tests/12.0.1/rd_sensors.h @@ -0,0 +1,85 @@ +/* + * rd_sensors.h: Include file used to read sensors statistics + * (C) 1999-2018 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _RD_SENSORS_H +#define _RD_SENSORS_H + +/* + *************************************************************************** + * Definitions of structures for sensors statistics + *************************************************************************** + */ + +/* + * Structure for fan statistics. + */ +struct stats_pwr_fan { + double rpm __attribute__ ((aligned (8))); + double rpm_min __attribute__ ((aligned (8))); + char device[MAX_SENSORS_DEV_LEN] __attribute__ ((aligned (8))); +}; + +#define STATS_PWR_FAN_SIZE (sizeof(struct stats_pwr_fan)) +#define STATS_PWR_FAN_ULL 2 +#define STATS_PWR_FAN_UL 0 +#define STATS_PWR_FAN_U 0 + +/* + * Structure for device temperature statistics. + */ +struct stats_pwr_temp { + double temp __attribute__ ((aligned (8))); + double temp_min __attribute__ ((aligned (8))); + double temp_max __attribute__ ((aligned (8))); + char device[MAX_SENSORS_DEV_LEN] __attribute__ ((aligned (8))); +}; + +#define STATS_PWR_TEMP_SIZE (sizeof(struct stats_pwr_temp)) +#define STATS_PWR_TEMP_ULL 3 +#define STATS_PWR_TEMP_UL 0 +#define STATS_PWR_TEMP_U 0 + +/* + * Structure for voltage inputs statistics. + */ +struct stats_pwr_in { + double in __attribute__ ((aligned (8))); + double in_min __attribute__ ((aligned (8))); + double in_max __attribute__ ((aligned (8))); + char device[MAX_SENSORS_DEV_LEN] __attribute__ ((aligned (8))); +}; + +#define STATS_PWR_IN_SIZE (sizeof(struct stats_pwr_in)) +#define STATS_PWR_IN_ULL 3 +#define STATS_PWR_IN_UL 0 +#define STATS_PWR_IN_U 0 + +/* + *************************************************************************** + * Prototypes for functions used to read sensors statistics + *************************************************************************** + */ + +__nr_t read_fan + (struct stats_pwr_fan *, __nr_t); +__nr_t read_temp + (struct stats_pwr_temp *, __nr_t); +__nr_t read_in + (struct stats_pwr_in *, __nr_t); + +/* + *************************************************************************** + * Prototypes for functions used to count number of items + *************************************************************************** + */ + +__nr_t get_fan_nr + (void); +__nr_t get_temp_nr + (void); +__nr_t get_in_nr + (void); + +#endif /* _RD_SENSORS_H */ diff --git a/tests/12.0.1/rd_stats.c b/tests/12.0.1/rd_stats.c new file mode 100644 index 0000000..cd6cab5 --- /dev/null +++ b/tests/12.0.1/rd_stats.c @@ -0,0 +1,2650 @@ +/* + * rd_stats.c: Read system statistics + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "rd_stats.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +/* + *************************************************************************** + * Read CPU statistics. + * Remember that this function is used by several sysstat commands! + * + * IN: + * @st_cpu Buffer where structures containing stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * + * OUT: + * @st_cpu Buffer with statistics. + * + * RETURNS: + * Highest CPU number(*) for which statistics have been read. + * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc. + * Or -1 if the buffer was too small and needs to be reallocated. + * + * (*)This doesn't account for all processors in the machine in the case + * where some CPU are offline and located at the end of the list. + *************************************************************************** + */ +__nr_t read_stat_cpu(struct stats_cpu *st_cpu, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_cpu *st_cpu_i; + struct stats_cpu sc; + char line[8192]; + int proc_nr; + __nr_t cpu_read = 0; + + if ((fp = fopen(STAT, "r")) == NULL) { + fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno)); + exit(2); + } + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "cpu ", 4)) { + + /* + * All the fields don't necessarily exist, + * depending on the kernel version used. + */ + memset(st_cpu, 0, STATS_CPU_SIZE); + + /* + * Read the number of jiffies spent in the different modes + * (user, nice, etc.) among all proc. CPU usage is not reduced + * to one processor to avoid rounding problems. + */ + sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", + &st_cpu->cpu_user, + &st_cpu->cpu_nice, + &st_cpu->cpu_sys, + &st_cpu->cpu_idle, + &st_cpu->cpu_iowait, + &st_cpu->cpu_hardirq, + &st_cpu->cpu_softirq, + &st_cpu->cpu_steal, + &st_cpu->cpu_guest, + &st_cpu->cpu_guest_nice); + + if (!cpu_read) { + cpu_read = 1; + } + + if (nr_alloc == 1) + /* We just want to read stats for CPU "all" */ + break; + } + + else if (!strncmp(line, "cpu", 3)) { + /* All the fields don't necessarily exist */ + memset(&sc, 0, STATS_CPU_SIZE); + /* + * Read the number of jiffies spent in the different modes + * (user, nice, etc) for current proc. + * This is done only on SMP machines. + */ + sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", + &proc_nr, + &sc.cpu_user, + &sc.cpu_nice, + &sc.cpu_sys, + &sc.cpu_idle, + &sc.cpu_iowait, + &sc.cpu_hardirq, + &sc.cpu_softirq, + &sc.cpu_steal, + &sc.cpu_guest, + &sc.cpu_guest_nice); + + if (proc_nr + 2 > nr_alloc) { + cpu_read = -1; + break; + } + + st_cpu_i = st_cpu + proc_nr + 1; + *st_cpu_i = sc; + + if (proc_nr + 2 > cpu_read) { + cpu_read = proc_nr + 2; + } + } + } + + fclose(fp); + return cpu_read; +} + +/* + *************************************************************************** + * Read interrupts statistics from /proc/stat. + * Remember that this function is used by several sysstat commands! + * + * IN: + * @st_irq Structure where stats will be saved. + * @nr_alloc Number of structures allocated. Value is >= 1. + * + * OUT: + * @st_irq Structure with statistics. + * + * RETURNS: + * Number of interrupts read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_stat_irq(struct stats_irq *st_irq, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_irq *st_irq_i; + char line[8192]; + int i, pos; + unsigned long long irq_nr; + __nr_t irq_read = 0; + + if ((fp = fopen(STAT, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "intr ", 5)) { + /* Read total number of interrupts received since system boot */ + sscanf(line + 5, "%llu", &st_irq->irq_nr); + pos = strcspn(line + 5, " ") + 5; + + irq_read++; + if (nr_alloc == 1) + /* We just want to read the total number of interrupts */ + break; + + do { + i = sscanf(line + pos, " %llu", &irq_nr); + if (i < 1) + break; + + if (irq_read + 1 > nr_alloc) { + irq_read = -1; + break; + } + st_irq_i = st_irq + irq_read++; + st_irq_i->irq_nr = irq_nr; + + i = strcspn(line + pos + 1, " "); + pos += i + 1; + } + while ((i > 0) && (pos < (sizeof(line) - 1))); + + break; + } + } + + fclose(fp); + return irq_read; +} + +/* + *************************************************************************** + * Read memory statistics from /proc/meminfo. + * + * IN: + * @st_memory Structure where stats will be saved. + * + * OUT: + * @st_memory Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_meminfo(struct stats_memory *st_memory) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(MEMINFO, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "MemTotal:", 9)) { + /* Read the total amount of memory in kB */ + sscanf(line + 9, "%llu", &st_memory->tlmkb); + } + else if (!strncmp(line, "MemFree:", 8)) { + /* Read the amount of free memory in kB */ + sscanf(line + 8, "%llu", &st_memory->frmkb); + } + else if (!strncmp(line, "MemAvailable:", 13)) { + /* Read the amount of available memory in kB */ + sscanf(line + 13, "%llu", &st_memory->availablekb); + } + else if (!strncmp(line, "Buffers:", 8)) { + /* Read the amount of buffered memory in kB */ + sscanf(line + 8, "%llu", &st_memory->bufkb); + } + else if (!strncmp(line, "Cached:", 7)) { + /* Read the amount of cached memory in kB */ + sscanf(line + 7, "%llu", &st_memory->camkb); + } + else if (!strncmp(line, "SwapCached:", 11)) { + /* Read the amount of cached swap in kB */ + sscanf(line + 11, "%llu", &st_memory->caskb); + } + else if (!strncmp(line, "Active:", 7)) { + /* Read the amount of active memory in kB */ + sscanf(line + 7, "%llu", &st_memory->activekb); + } + else if (!strncmp(line, "Inactive:", 9)) { + /* Read the amount of inactive memory in kB */ + sscanf(line + 9, "%llu", &st_memory->inactkb); + } + else if (!strncmp(line, "SwapTotal:", 10)) { + /* Read the total amount of swap memory in kB */ + sscanf(line + 10, "%llu", &st_memory->tlskb); + } + else if (!strncmp(line, "SwapFree:", 9)) { + /* Read the amount of free swap memory in kB */ + sscanf(line + 9, "%llu", &st_memory->frskb); + } + else if (!strncmp(line, "Dirty:", 6)) { + /* Read the amount of dirty memory in kB */ + sscanf(line + 6, "%llu", &st_memory->dirtykb); + } + else if (!strncmp(line, "Committed_AS:", 13)) { + /* Read the amount of commited memory in kB */ + sscanf(line + 13, "%llu", &st_memory->comkb); + } + else if (!strncmp(line, "AnonPages:", 10)) { + /* Read the amount of pages mapped into userspace page tables in kB */ + sscanf(line + 10, "%llu", &st_memory->anonpgkb); + } + else if (!strncmp(line, "Slab:", 5)) { + /* Read the amount of in-kernel data structures cache in kB */ + sscanf(line + 5, "%llu", &st_memory->slabkb); + } + else if (!strncmp(line, "KernelStack:", 12)) { + /* Read the kernel stack utilization in kB */ + sscanf(line + 12, "%llu", &st_memory->kstackkb); + } + else if (!strncmp(line, "PageTables:", 11)) { + /* Read the amount of memory dedicated to the lowest level of page tables in kB */ + sscanf(line + 11, "%llu", &st_memory->pgtblkb); + } + else if (!strncmp(line, "VmallocUsed:", 12)) { + /* Read the amount of vmalloc area which is used in kB */ + sscanf(line + 12, "%llu", &st_memory->vmusedkb); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read machine uptime, independently of the number of processors. + * + * OUT: + * @uptime Uptime value in hundredths of a second. + *************************************************************************** + */ +void read_uptime(unsigned long long *uptime) +{ + FILE *fp = NULL; + char line[128]; + unsigned long up_sec, up_cent; + int err = FALSE; + + if ((fp = fopen(UPTIME, "r")) == NULL) { + err = TRUE; + } + else if (fgets(line, sizeof(line), fp) == NULL) { + err = TRUE; + } + else if (sscanf(line, "%lu.%lu", &up_sec, &up_cent) == 2) { + *uptime = (unsigned long long) up_sec * 100 + + (unsigned long long) up_cent; + } + else { + err = TRUE; + } + + if (fp != NULL) { + fclose(fp); + } + if (err) { + fprintf(stderr, _("Cannot read %s\n"), UPTIME); + exit(2); + } +} + +/* + *************************************************************************** + * Compute "extended" device statistics (service time, etc.). + * + * IN: + * @sdc Structure with current device statistics. + * @sdp Structure with previous device statistics. + * @itv Interval of time in 1/100th of a second. + * + * OUT: + * @xds Structure with extended statistics. + *************************************************************************** +*/ +void compute_ext_disk_stats(struct stats_disk *sdc, struct stats_disk *sdp, + unsigned long long itv, struct ext_disk_stats *xds) +{ + double tput + = ((double) (sdc->nr_ios - sdp->nr_ios)) * 100 / itv; + + xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv); + xds->svctm = tput ? xds->util / tput : 0.0; + /* + * Kernel gives ticks already in milliseconds for all platforms + * => no need for further scaling. + */ + xds->await = (sdc->nr_ios - sdp->nr_ios) ? + ((sdc->rd_ticks - sdp->rd_ticks) + (sdc->wr_ticks - sdp->wr_ticks)) / + ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0; + xds->arqsz = (sdc->nr_ios - sdp->nr_ios) ? + ((sdc->rd_sect - sdp->rd_sect) + (sdc->wr_sect - sdp->wr_sect)) / + ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0; +} + +/* + *************************************************************************** + * Since ticks may vary slightly from CPU to CPU, we'll want + * to recalculate itv based on this CPU's tick count, rather + * than that reported by the "cpu" line. Otherwise we + * occasionally end up with slightly skewed figures, with + * the skew being greater as the time interval grows shorter. + * + * IN: + * @scc Current sample statistics for current CPU. + * @scp Previous sample statistics for current CPU. + * + * RETURNS: + * Interval of time based on current CPU, expressed in jiffies. + *************************************************************************** + */ +unsigned long long get_per_cpu_interval(struct stats_cpu *scc, + struct stats_cpu *scp) +{ + unsigned long long ishift = 0LL; + + if ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest)) { + /* + * Sometimes the nr of jiffies spent in guest mode given by the guest + * counter in /proc/stat is slightly higher than that included in + * the user counter. Update the interval value accordingly. + */ + ishift += (scp->cpu_user - scp->cpu_guest) - + (scc->cpu_user - scc->cpu_guest); + } + if ((scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice)) { + /* + * Idem for nr of jiffies spent in guest_nice mode. + */ + ishift += (scp->cpu_nice - scp->cpu_guest_nice) - + (scc->cpu_nice - scc->cpu_guest_nice); + } + + /* + * Workaround for CPU coming back online: With recent kernels + * some fields (user, nice, system) restart from their previous value, + * whereas others (idle, iowait) restart from zero. + * For the latter we need to set their previous value to zero to + * avoid getting an interval value < 0. + * (I don't know how the other fields like hardirq, steal... behave). + * Don't assume the CPU has come back from offline state if previous + * value was greater than ULLONG_MAX - 0x7ffff (the counter probably + * overflew). + */ + if ((scc->cpu_idle < scp->cpu_idle) && (scp->cpu_idle < (ULLONG_MAX - 0x7ffff))) { + scp->cpu_idle = 0; + } + if ((scc->cpu_iowait < scp->cpu_iowait) && (scp->cpu_iowait < (ULLONG_MAX - 0x7ffff))) { + scp->cpu_iowait = 0; + } + + /* + * Don't take cpu_guest and cpu_guest_nice into account + * because cpu_user and cpu_nice already include them. + */ + return ((scc->cpu_user + scc->cpu_nice + + scc->cpu_sys + scc->cpu_iowait + + scc->cpu_idle + scc->cpu_steal + + scc->cpu_hardirq + scc->cpu_softirq) - + (scp->cpu_user + scp->cpu_nice + + scp->cpu_sys + scp->cpu_iowait + + scp->cpu_idle + scp->cpu_steal + + scp->cpu_hardirq + scp->cpu_softirq) + + ishift); +} + +#ifdef SOURCE_SADC +/*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/ + +/* + *************************************************************************** + * Replace octal codes in string with their corresponding characters. + * + * IN: + * @str String to parse. + * + * OUT: + * @str String with octal codes replaced with characters. + *************************************************************************** + */ +void oct2chr(char *str) +{ + int i = 0; + int j, len; + + len = strlen(str); + + while (i < len - 3) { + if ((str[i] == '\\') && + (str[i + 1] >= '0') && (str[i + 1] <= '3') && + (str[i + 2] >= '0') && (str[i + 2] <= '7') && + (str[i + 3] >= '0') && (str[i + 3] <= '7')) { + /* Octal code found */ + str[i] = (str[i + 1] - 48) * 64 + + (str[i + 2] - 48) * 8 + + (str[i + 3] - 48); + for (j = i + 4; j <= len; j++) { + str[j - 3] = str[j]; + } + len -= 3; + } + i++; + } +} + +/* + *************************************************************************** + * Read processes (tasks) creation and context switches statistics + * from /proc/stat. + * + * IN: + * @st_pcsw Structure where stats will be saved. + * + * OUT: + * @st_pcsw Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_stat_pcsw(struct stats_pcsw *st_pcsw) +{ + FILE *fp; + char line[8192]; + + if ((fp = fopen(STAT, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "ctxt ", 5)) { + /* Read number of context switches */ + sscanf(line + 5, "%llu", &st_pcsw->context_switch); + } + + else if (!strncmp(line, "processes ", 10)) { + /* Read number of processes created since system boot */ + sscanf(line + 10, "%lu", &st_pcsw->processes); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read queue and load statistics from /proc/loadavg and /proc/stat. + * + * IN: + * @st_queue Structure where stats will be saved. + * + * OUT: + * @st_queue Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_loadavg(struct stats_queue *st_queue) +{ + FILE *fp; + char line[8192]; + unsigned int load_tmp[3]; + int rc; + + if ((fp = fopen(LOADAVG, "r")) == NULL) + return 0; + + /* Read load averages and queue length */ + rc = fscanf(fp, "%u.%u %u.%u %u.%u %llu/%llu %*d\n", + &load_tmp[0], &st_queue->load_avg_1, + &load_tmp[1], &st_queue->load_avg_5, + &load_tmp[2], &st_queue->load_avg_15, + &st_queue->nr_running, + &st_queue->nr_threads); + + fclose(fp); + + if (rc < 8) + return 0; + + st_queue->load_avg_1 += load_tmp[0] * 100; + st_queue->load_avg_5 += load_tmp[1] * 100; + st_queue->load_avg_15 += load_tmp[2] * 100; + + if (st_queue->nr_running) { + /* Do not take current process into account */ + st_queue->nr_running--; + } + + /* Read nr of tasks blocked from /proc/stat */ + if ((fp = fopen(STAT, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "procs_blocked ", 14)) { + /* Read number of processes blocked */ + sscanf(line + 14, "%llu", &st_queue->procs_blocked); + break; + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read swapping statistics from /proc/vmstat. + * + * IN: + * @st_swap Structure where stats will be saved. + * + * OUT: + * @st_swap Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_vmstat_swap(struct stats_swap *st_swap) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(VMSTAT, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "pswpin ", 7)) { + /* Read number of swap pages brought in */ + sscanf(line + 7, "%lu", &st_swap->pswpin); + } + else if (!strncmp(line, "pswpout ", 8)) { + /* Read number of swap pages brought out */ + sscanf(line + 8, "%lu", &st_swap->pswpout); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read paging statistics from /proc/vmstat. + * + * IN: + * @st_paging Structure where stats will be saved. + * + * OUT: + * @st_paging Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_vmstat_paging(struct stats_paging *st_paging) +{ + FILE *fp; + char line[128]; + unsigned long pgtmp; + + if ((fp = fopen(VMSTAT, "r")) == NULL) + return 0; + + st_paging->pgsteal = 0; + st_paging->pgscan_kswapd = st_paging->pgscan_direct = 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "pgpgin ", 7)) { + /* Read number of pages the system paged in */ + sscanf(line + 7, "%lu", &st_paging->pgpgin); + } + else if (!strncmp(line, "pgpgout ", 8)) { + /* Read number of pages the system paged out */ + sscanf(line + 8, "%lu", &st_paging->pgpgout); + } + else if (!strncmp(line, "pgfault ", 8)) { + /* Read number of faults (major+minor) made by the system */ + sscanf(line + 8, "%lu", &st_paging->pgfault); + } + else if (!strncmp(line, "pgmajfault ", 11)) { + /* Read number of faults (major only) made by the system */ + sscanf(line + 11, "%lu", &st_paging->pgmajfault); + } + else if (!strncmp(line, "pgfree ", 7)) { + /* Read number of pages freed by the system */ + sscanf(line + 7, "%lu", &st_paging->pgfree); + } + else if (!strncmp(line, "pgsteal_", 8)) { + /* Read number of pages stolen by the system */ + sscanf(strchr(line, ' '), "%lu", &pgtmp); + st_paging->pgsteal += pgtmp; + } + else if (!strncmp(line, "pgscan_kswapd", 13)) { + /* Read number of pages scanned by the kswapd daemon */ + sscanf(strchr(line, ' '), "%lu", &pgtmp); + st_paging->pgscan_kswapd += pgtmp; + } + else if (!strncmp(line, "pgscan_direct", 13)) { + /* Read number of pages scanned directly */ + sscanf(strchr(line, ' '), "%lu", &pgtmp); + st_paging->pgscan_direct += pgtmp; + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read I/O and transfer rates statistics from /proc/diskstats. + * + * IN: + * @st_io Structure where stats will be saved. + * + * OUT: + * @st_io Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_diskstats_io(struct stats_io *st_io) +{ + FILE *fp; + char line[1024]; + char dev_name[MAX_NAME_LEN]; + unsigned int major, minor; + unsigned long rd_ios, wr_ios, rd_sec, wr_sec; + + if ((fp = fopen(DISKSTATS, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu", + &major, &minor, dev_name, + &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) { + + if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) { + /* + * OK: It's a (real) device and not a partition. + * Note: Structure should have been initialized first! + */ + st_io->dk_drive += (unsigned long long) rd_ios + (unsigned long long) wr_ios; + st_io->dk_drive_rio += rd_ios; + st_io->dk_drive_rblk += rd_sec; + st_io->dk_drive_wio += wr_ios; + st_io->dk_drive_wblk += wr_sec; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read block devices statistics from /proc/diskstats. + * + * IN: + * @st_disk Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * @read_part True if disks *and* partitions should be read; False if only + * disks are read. + * + * OUT: + * @st_disk Structure with statistics. + * + * RETURNS: + * Number of block devices read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_diskstats_disk(struct stats_disk *st_disk, __nr_t nr_alloc, + int read_part) +{ + FILE *fp; + char line[1024]; + char dev_name[MAX_NAME_LEN]; + struct stats_disk *st_disk_i; + unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks; + unsigned long rd_ios, wr_ios, rd_sec, wr_sec; + __nr_t dsk_read = 0; + + if ((fp = fopen(DISKSTATS, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu" + " %u %*u %u %u", + &major, &minor, dev_name, + &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks, + &tot_ticks, &rq_ticks) == 11) { + + if (!rd_ios && !wr_ios) + /* Unused device: Ignore it */ + continue; + if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) { + + if (dsk_read + 1 > nr_alloc) { + dsk_read = -1; + break; + } + + st_disk_i = st_disk + dsk_read++; + st_disk_i->major = major; + st_disk_i->minor = minor; + st_disk_i->nr_ios = (unsigned long long) rd_ios + (unsigned long long) wr_ios; + st_disk_i->rd_sect = rd_sec; + st_disk_i->wr_sect = wr_sec; + st_disk_i->rd_ticks = rd_ticks; + st_disk_i->wr_ticks = wr_ticks; + st_disk_i->tot_ticks = tot_ticks; + st_disk_i->rq_ticks = rq_ticks; + } + } + } + + fclose(fp); + return dsk_read; +} + +/* + *************************************************************************** + * Read serial lines statistics from /proc/tty/driver/serial. + * + * IN: + * @st_serial Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * + * OUT: + * @st_serial Structure with statistics. + * + * RETURNS: + * Number of serial lines read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_tty_driver_serial(struct stats_serial *st_serial, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_serial *st_serial_i; + char line[256]; + char *p; + __nr_t sl_read = 0; + + if ((fp = fopen(SERIAL, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL ) { + + if ((p = strstr(line, "tx:")) != NULL) { + + if (sl_read + 1 > nr_alloc) { + sl_read = -1; + break; + } + + st_serial_i = st_serial + sl_read++; + /* Read serial line number */ + sscanf(line, "%u", &st_serial_i->line); + /* + * Read the number of chars transmitted and received by + * current serial line. + */ + sscanf(p + 3, "%u", &st_serial_i->tx); + if ((p = strstr(line, "rx:")) != NULL) { + sscanf(p + 3, "%u", &st_serial_i->rx); + } + if ((p = strstr(line, "fe:")) != NULL) { + sscanf(p + 3, "%u", &st_serial_i->frame); + } + if ((p = strstr(line, "pe:")) != NULL) { + sscanf(p + 3, "%u", &st_serial_i->parity); + } + if ((p = strstr(line, "brk:")) != NULL) { + sscanf(p + 4, "%u", &st_serial_i->brk); + } + if ((p = strstr(line, "oe:")) != NULL) { + sscanf(p + 3, "%u", &st_serial_i->overrun); + } + } + } + + fclose(fp); + return sl_read; +} + +/* + *************************************************************************** + * Read kernel tables statistics from various system files. + * + * IN: + * @st_ktables Structure where stats will be saved. + * + * OUT: + * @st_ktables Structure with statistics. + * + * RETURNS: + * 1 (always success). + *************************************************************************** + */ +__nr_t read_kernel_tables(struct stats_ktables *st_ktables) +{ + FILE *fp; + unsigned long long parm; + int rc = 0; + + /* Open /proc/sys/fs/dentry-state file */ + if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) { + rc = fscanf(fp, "%*d %llu", + &st_ktables->dentry_stat); + fclose(fp); + if (rc == 0) { + st_ktables->dentry_stat = 0; + } + } + + /* Open /proc/sys/fs/file-nr file */ + if ((fp = fopen(FFILE_NR, "r")) != NULL) { + rc = fscanf(fp, "%llu %llu", + &st_ktables->file_used, &parm); + fclose(fp); + /* + * The number of used handles is the number of allocated ones + * minus the number of free ones. + */ + if (rc == 2) { + st_ktables->file_used -= parm; + } + else { + st_ktables->file_used = 0; + } + } + + /* Open /proc/sys/fs/inode-state file */ + if ((fp = fopen(FINODE_STATE, "r")) != NULL) { + rc = fscanf(fp, "%llu %llu", + &st_ktables->inode_used, &parm); + fclose(fp); + /* + * The number of inuse inodes is the number of allocated ones + * minus the number of free ones. + */ + if (rc == 2) { + st_ktables->inode_used -= parm; + } + else { + st_ktables->inode_used = 0; + } + } + + /* Open /proc/sys/kernel/pty/nr file */ + if ((fp = fopen(PTY_NR, "r")) != NULL) { + rc = fscanf(fp, "%llu", + &st_ktables->pty_nr); + fclose(fp); + if (rc == 0) { + st_ktables->pty_nr = 0; + } + } + + return 1; +} + +/* + *************************************************************************** + * Read network interfaces statistics from /proc/net/dev. + * + * IN: + * @st_net_dev Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * + * OUT: + * @st_net_dev Structure with statistics. + * + * RETURNS: + * Number of interfaces read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_net_dev(struct stats_net_dev *st_net_dev, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_net_dev *st_net_dev_i; + char line[256]; + char iface[MAX_IFACE_LEN]; + __nr_t dev_read = 0; + int pos; + + if ((fp = fopen(NET_DEV, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + pos = strcspn(line, ":"); + if (pos < strlen(line)) { + + if (dev_read + 1 > nr_alloc) { + dev_read = -1; + break; + } + + st_net_dev_i = st_net_dev + dev_read++; + strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1)); + iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0'; + sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */ + sscanf(line + pos + 1, "%llu %llu %*u %*u %*u %*u %llu %llu %llu %llu " + "%*u %*u %*u %*u %*u %llu", + &st_net_dev_i->rx_bytes, + &st_net_dev_i->rx_packets, + &st_net_dev_i->rx_compressed, + &st_net_dev_i->multicast, + &st_net_dev_i->tx_bytes, + &st_net_dev_i->tx_packets, + &st_net_dev_i->tx_compressed); + } + } + + fclose(fp); + return dev_read; +} + +/* + *************************************************************************** + * Read duplex and speed data for network interface cards. + * + * IN: + * @st_net_dev Structure where stats will be saved. + * @nbr Number of network interfaces to read. + * + * OUT: + * @st_net_dev Structure with statistics. + *************************************************************************** + */ +void read_if_info(struct stats_net_dev *st_net_dev, int nbr) +{ + FILE *fp; + struct stats_net_dev *st_net_dev_i; + char filename[128], duplex[32]; + int dev, n; + + for (dev = 0; dev < nbr; dev++) { + + st_net_dev_i = st_net_dev + dev; + + /* Read speed info */ + sprintf(filename, IF_DUPLEX, st_net_dev_i->interface); + + if ((fp = fopen(filename, "r")) == NULL) + /* Cannot read NIC duplex */ + continue; + + n = fscanf(fp, "%31s", duplex); + + fclose(fp); + + if (n != 1) + /* Cannot read NIC duplex */ + continue; + + if (!strcmp(duplex, K_DUPLEX_FULL)) { + st_net_dev_i->duplex = C_DUPLEX_FULL; + } + else if (!strcmp(duplex, K_DUPLEX_HALF)) { + st_net_dev_i->duplex = C_DUPLEX_HALF; + } + else + continue; + + /* Read speed info */ + sprintf(filename, IF_SPEED, st_net_dev_i->interface); + + if ((fp = fopen(filename, "r")) == NULL) + /* Cannot read NIC speed */ + continue; + + n = fscanf(fp, "%u", &st_net_dev_i->speed); + + fclose(fp); + + if (n != 1) { + st_net_dev_i->speed = 0; + } + } +} + + +/* + *************************************************************************** + * Read network interfaces errors statistics from /proc/net/dev. + * + * IN: + * @st_net_edev Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * + * OUT: + * @st_net_edev Structure with statistics. + * + * RETURNS: + * Number of interfaces read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_net_edev(struct stats_net_edev *st_net_edev, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_net_edev *st_net_edev_i; + static char line[256]; + char iface[MAX_IFACE_LEN]; + __nr_t dev_read = 0; + int pos; + + if ((fp = fopen(NET_DEV, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + pos = strcspn(line, ":"); + if (pos < strlen(line)) { + + if (dev_read + 1 > nr_alloc) { + dev_read = -1; + break; + } + + st_net_edev_i = st_net_edev + dev_read++; + strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1)); + iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0'; + sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */ + sscanf(line + pos + 1, "%*u %*u %llu %llu %llu %llu %*u %*u %*u %*u " + "%llu %llu %llu %llu %llu", + &st_net_edev_i->rx_errors, + &st_net_edev_i->rx_dropped, + &st_net_edev_i->rx_fifo_errors, + &st_net_edev_i->rx_frame_errors, + &st_net_edev_i->tx_errors, + &st_net_edev_i->tx_dropped, + &st_net_edev_i->tx_fifo_errors, + &st_net_edev_i->collisions, + &st_net_edev_i->tx_carrier_errors); + } + } + + fclose(fp); + return dev_read; +} + +/* + *************************************************************************** + * Read NFS client statistics from /proc/net/rpc/nfs. + * + * IN: + * @st_net_nfs Structure where stats will be saved. + * + * OUT: + * @st_net_nfs Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_nfs(struct stats_net_nfs *st_net_nfs) +{ + FILE *fp; + char line[256]; + unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0; + + if ((fp = fopen(NET_RPC_NFS, "r")) == NULL) + return 0; + + memset(st_net_nfs, 0, STATS_NET_NFS_SIZE); + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "rpc ", 4)) { + sscanf(line + 4, "%u %u", + &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans); + } + else if (!strncmp(line, "proc3 ", 6)) { + sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u", + &getattcnt, &accesscnt, &readcnt, &writecnt); + + st_net_nfs->nfs_getattcnt += getattcnt; + st_net_nfs->nfs_accesscnt += accesscnt; + st_net_nfs->nfs_readcnt += readcnt; + st_net_nfs->nfs_writecnt += writecnt; + } + else if (!strncmp(line, "proc4 ", 6)) { + sscanf(line + 6, "%*u %*u %u %u " + "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u", + &readcnt, &writecnt, &accesscnt, &getattcnt); + + st_net_nfs->nfs_getattcnt += getattcnt; + st_net_nfs->nfs_accesscnt += accesscnt; + st_net_nfs->nfs_readcnt += readcnt; + st_net_nfs->nfs_writecnt += writecnt; + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read NFS server statistics from /proc/net/rpc/nfsd. + * + * IN: + * @st_net_nfsd Structure where stats will be saved. + * + * OUT: + * @st_net_nfsd Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_nfsd(struct stats_net_nfsd *st_net_nfsd) +{ + FILE *fp; + char line[256]; + unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0; + + if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL) + return 0; + + memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE); + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "rc ", 3)) { + sscanf(line + 3, "%u %u", + &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses); + } + else if (!strncmp(line, "net ", 4)) { + sscanf(line + 4, "%u %u %u", + &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt, + &st_net_nfsd->nfsd_nettcpcnt); + } + else if (!strncmp(line, "rpc ", 4)) { + sscanf(line + 4, "%u %u", + &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad); + } + else if (!strncmp(line, "proc3 ", 6)) { + sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u", + &getattcnt, &accesscnt, &readcnt, &writecnt); + + st_net_nfsd->nfsd_getattcnt += getattcnt; + st_net_nfsd->nfsd_accesscnt += accesscnt; + st_net_nfsd->nfsd_readcnt += readcnt; + st_net_nfsd->nfsd_writecnt += writecnt; + + } + else if (!strncmp(line, "proc4ops ", 9)) { + sscanf(line + 9, "%*u %*u %*u %*u %u " + "%*u %*u %*u %*u %*u %u " + "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u " + "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u", + &accesscnt, &getattcnt, &readcnt, &writecnt); + + st_net_nfsd->nfsd_getattcnt += getattcnt; + st_net_nfsd->nfsd_accesscnt += accesscnt; + st_net_nfsd->nfsd_readcnt += readcnt; + st_net_nfsd->nfsd_writecnt += writecnt; + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read network sockets statistics from /proc/net/sockstat. + * + * IN: + * @st_net_sock Structure where stats will be saved. + * + * OUT: + * @st_net_sock Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_sock(struct stats_net_sock *st_net_sock) +{ + FILE *fp; + char line[96]; + char *p; + + if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "sockets:", 8)) { + /* Sockets */ + sscanf(line + 14, "%u", &st_net_sock->sock_inuse); + } + else if (!strncmp(line, "TCP:", 4)) { + /* TCP sockets */ + sscanf(line + 11, "%u", &st_net_sock->tcp_inuse); + if ((p = strstr(line, "tw")) != NULL) { + sscanf(p + 2, "%u", &st_net_sock->tcp_tw); + } + } + else if (!strncmp(line, "UDP:", 4)) { + /* UDP sockets */ + sscanf(line + 11, "%u", &st_net_sock->udp_inuse); + } + else if (!strncmp(line, "RAW:", 4)) { + /* RAW sockets */ + sscanf(line + 11, "%u", &st_net_sock->raw_inuse); + } + else if (!strncmp(line, "FRAG:", 5)) { + /* FRAGments */ + sscanf(line + 12, "%u", &st_net_sock->frag_inuse); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read IP network traffic statistics from /proc/net/snmp. + * + * IN: + * @st_net_ip Structure where stats will be saved. + * + * OUT: + * @st_net_ip Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_ip(struct stats_net_ip *st_net_ip) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Ip:", 3)) { + if (sw) { + sscanf(line + 3, "%*u %*u %llu %*u %*u %llu %*u %*u " + "%llu %llu %*u %*u %*u %llu %llu %*u %llu %*u %llu", + &st_net_ip->InReceives, + &st_net_ip->ForwDatagrams, + &st_net_ip->InDelivers, + &st_net_ip->OutRequests, + &st_net_ip->ReasmReqds, + &st_net_ip->ReasmOKs, + &st_net_ip->FragOKs, + &st_net_ip->FragCreates); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read IP network errors statistics from /proc/net/snmp. + * + * IN: + * @st_net_eip Structure where stats will be saved. + * + * OUT: + * @st_net_eip Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_eip(struct stats_net_eip *st_net_eip) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Ip:", 3)) { + if (sw) { + sscanf(line + 3, "%*u %*u %*u %llu %llu %*u %llu %llu " + "%*u %*u %llu %llu %*u %*u %*u %llu %*u %llu", + &st_net_eip->InHdrErrors, + &st_net_eip->InAddrErrors, + &st_net_eip->InUnknownProtos, + &st_net_eip->InDiscards, + &st_net_eip->OutDiscards, + &st_net_eip->OutNoRoutes, + &st_net_eip->ReasmFails, + &st_net_eip->FragFails); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read ICMP network traffic statistics from /proc/net/snmp. + * + * IN: + * @st_net_icmp Structure where stats will be saved. + * + * OUT: + * @st_net_icmp Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_icmp(struct stats_net_icmp *st_net_icmp) +{ + FILE *fp; + char line[1024]; + static char format[256] = ""; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Icmp:", 5)) { + if (sw) { + sscanf(line + 5, format, + &st_net_icmp->InMsgs, + &st_net_icmp->InEchos, + &st_net_icmp->InEchoReps, + &st_net_icmp->InTimestamps, + &st_net_icmp->InTimestampReps, + &st_net_icmp->InAddrMasks, + &st_net_icmp->InAddrMaskReps, + &st_net_icmp->OutMsgs, + &st_net_icmp->OutEchos, + &st_net_icmp->OutEchoReps, + &st_net_icmp->OutTimestamps, + &st_net_icmp->OutTimestampReps, + &st_net_icmp->OutAddrMasks, + &st_net_icmp->OutAddrMaskReps); + + break; + } + else { + if (!strlen(format)) { + if (strstr(line, "InCsumErrors")) { + /* + * New format: InCsumErrors field exists at position #3. + * Capture: 1,9,10,11,12,13,14,15,22,23,24,25,26,27. + */ + strcpy(format, "%lu %*u %*u %*u %*u %*u %*u %*u " + "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u " + "%*u %*u %lu %lu %lu %lu %lu %lu"); + } + else { + /* + * Old format: InCsumErrors field doesn't exist. + * Capture: 1,8,9,10,11,12,13,14,21,22,23,24,25,26. + */ + strcpy(format, "%lu %*u %*u %*u %*u %*u %*u " + "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u " + "%*u %*u %lu %lu %lu %lu %lu %lu"); + } + } + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read ICMP network errors statistics from /proc/net/snmp. + * + * IN: + * @st_net_eicmp Structure where stats will be saved. + * + * OUT: + * @st_net_eicmp Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_eicmp(struct stats_net_eicmp *st_net_eicmp) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Icmp:", 5)) { + if (sw) { + sscanf(line + 5, "%*u %lu %lu %lu %lu %lu %lu %*u %*u " + "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu", + &st_net_eicmp->InErrors, + &st_net_eicmp->InDestUnreachs, + &st_net_eicmp->InTimeExcds, + &st_net_eicmp->InParmProbs, + &st_net_eicmp->InSrcQuenchs, + &st_net_eicmp->InRedirects, + &st_net_eicmp->OutErrors, + &st_net_eicmp->OutDestUnreachs, + &st_net_eicmp->OutTimeExcds, + &st_net_eicmp->OutParmProbs, + &st_net_eicmp->OutSrcQuenchs, + &st_net_eicmp->OutRedirects); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read TCP network traffic statistics from /proc/net/snmp. + * + * IN: + * @st_net_tcp Structure where stats will be saved. + * + * OUT: + * @st_net_tcp Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_tcp(struct stats_net_tcp *st_net_tcp) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Tcp:", 4)) { + if (sw) { + sscanf(line + 4, "%*u %*u %*u %*d %lu %lu " + "%*u %*u %*u %lu %lu", + &st_net_tcp->ActiveOpens, + &st_net_tcp->PassiveOpens, + &st_net_tcp->InSegs, + &st_net_tcp->OutSegs); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read TCP network errors statistics from /proc/net/snmp. + * + * IN: + * @st_net_etcp Structure where stats will be saved. + * + * OUT: + * @st_net_etcp Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_etcp(struct stats_net_etcp *st_net_etcp) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Tcp:", 4)) { + if (sw) { + sscanf(line + 4, "%*u %*u %*u %*d %*u %*u " + "%lu %lu %*u %*u %*u %lu %lu %lu", + &st_net_etcp->AttemptFails, + &st_net_etcp->EstabResets, + &st_net_etcp->RetransSegs, + &st_net_etcp->InErrs, + &st_net_etcp->OutRsts); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read UDP network traffic statistics from /proc/net/snmp. + * + * IN: + * @st_net_udp Structure where stats will be saved. + * + * OUT: + * @st_net_udp Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_udp(struct stats_net_udp *st_net_udp) +{ + FILE *fp; + char line[1024]; + int sw = FALSE; + + if ((fp = fopen(NET_SNMP, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Udp:", 4)) { + if (sw) { + sscanf(line + 4, "%lu %lu %lu %lu", + &st_net_udp->InDatagrams, + &st_net_udp->NoPorts, + &st_net_udp->InErrors, + &st_net_udp->OutDatagrams); + + break; + } + else { + sw = TRUE; + } + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read IPv6 network sockets statistics from /proc/net/sockstat6. + * + * IN: + * @st_net_sock6 Structure where stats will be saved. + * + * OUT: + * @st_net_sock6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_sock6(struct stats_net_sock6 *st_net_sock6) +{ + FILE *fp; + char line[96]; + + if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "TCP6:", 5)) { + /* TCPv6 sockets */ + sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse); + } + else if (!strncmp(line, "UDP6:", 5)) { + /* UDPv6 sockets */ + sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse); + } + else if (!strncmp(line, "RAW6:", 5)) { + /* IPv6 RAW sockets */ + sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse); + } + else if (!strncmp(line, "FRAG6:", 6)) { + /* IPv6 FRAGments */ + sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read IPv6 network traffic statistics from /proc/net/snmp6. + * + * IN: + * @st_net_ip6 Structure where stats will be saved. + * + * OUT: + * @st_net_ip6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_ip6(struct stats_net_ip6 *st_net_ip6) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(NET_SNMP6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Ip6InReceives ", 14)) { + sscanf(line + 14, "%llu", &st_net_ip6->InReceives6); + } + else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) { + sscanf(line + 20, "%llu", &st_net_ip6->OutForwDatagrams6); + } + else if (!strncmp(line, "Ip6InDelivers ", 14)) { + sscanf(line + 14, "%llu", &st_net_ip6->InDelivers6); + } + else if (!strncmp(line, "Ip6OutRequests ", 15)) { + sscanf(line + 15, "%llu", &st_net_ip6->OutRequests6); + } + else if (!strncmp(line, "Ip6ReasmReqds ", 14)) { + sscanf(line + 14, "%llu", &st_net_ip6->ReasmReqds6); + } + else if (!strncmp(line, "Ip6ReasmOKs ", 12)) { + sscanf(line + 12, "%llu", &st_net_ip6->ReasmOKs6); + } + else if (!strncmp(line, "Ip6InMcastPkts ", 15)) { + sscanf(line + 15, "%llu", &st_net_ip6->InMcastPkts6); + } + else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) { + sscanf(line + 16, "%llu", &st_net_ip6->OutMcastPkts6); + } + else if (!strncmp(line, "Ip6FragOKs ", 11)) { + sscanf(line + 11, "%llu", &st_net_ip6->FragOKs6); + } + else if (!strncmp(line, "Ip6FragCreates ", 15)) { + sscanf(line + 15, "%llu", &st_net_ip6->FragCreates6); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read IPv6 network errors statistics from /proc/net/snmp6. + * + * IN: + * @st_net_eip6 Structure where stats will be saved. + * + * OUT: + * @st_net_eip6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_eip6(struct stats_net_eip6 *st_net_eip6) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(NET_SNMP6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Ip6InHdrErrors ", 15)) { + sscanf(line + 15, "%llu", &st_net_eip6->InHdrErrors6); + } + else if (!strncmp(line, "Ip6InAddrErrors ", 16)) { + sscanf(line + 16, "%llu", &st_net_eip6->InAddrErrors6); + } + else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) { + sscanf(line + 19, "%llu", &st_net_eip6->InUnknownProtos6); + } + else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) { + sscanf(line + 18, "%llu", &st_net_eip6->InTooBigErrors6); + } + else if (!strncmp(line, "Ip6InDiscards ", 14)) { + sscanf(line + 14, "%llu", &st_net_eip6->InDiscards6); + } + else if (!strncmp(line, "Ip6OutDiscards ", 15)) { + sscanf(line + 15, "%llu", &st_net_eip6->OutDiscards6); + } + else if (!strncmp(line, "Ip6InNoRoutes ", 14)) { + sscanf(line + 14, "%llu", &st_net_eip6->InNoRoutes6); + } + else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) { + sscanf(line + 15, "%llu", &st_net_eip6->OutNoRoutes6); + } + else if (!strncmp(line, "Ip6ReasmFails ", 14)) { + sscanf(line + 14, "%llu", &st_net_eip6->ReasmFails6); + } + else if (!strncmp(line, "Ip6FragFails ", 13)) { + sscanf(line + 13, "%llu", &st_net_eip6->FragFails6); + } + else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) { + sscanf(line + 19, "%llu", &st_net_eip6->InTruncatedPkts6); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read ICMPv6 network traffic statistics from /proc/net/snmp6. + * + * IN: + * @st_net_icmp6 Structure where stats will be saved. + * + * OUT: + * @st_net_icmp6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(NET_SNMP6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Icmp6InMsgs ", 12)) { + sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6); + } + else if (!strncmp(line, "Icmp6OutMsgs ", 13)) { + sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6); + } + else if (!strncmp(line, "Icmp6InEchos ", 13)) { + sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6); + } + else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) { + sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6); + } + else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) { + sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6); + } + else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) { + sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6); + } + else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) { + sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6); + } + else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) { + sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6); + } + else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) { + sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6); + } + else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) { + sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6); + } + else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) { + sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6); + } + else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) { + sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6); + } + else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) { + sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6); + } + else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) { + sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6); + } + else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) { + sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6); + } + else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) { + sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6); + } + else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) { + sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read ICMPv6 network errors statistics from /proc/net/snmp6. + * + * IN: + * @st_net_eicmp6 Structure where stats will be saved. + * + * OUT: + * @st_net_eicmp6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(NET_SNMP6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Icmp6InErrors ", 14)) { + sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6); + } + else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) { + sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6); + } + else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) { + sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6); + } + else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) { + sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6); + } + else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) { + sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6); + } + else if (!strncmp(line, "Icmp6InParmProblems ", 20)) { + sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6); + } + else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) { + sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6); + } + else if (!strncmp(line, "Icmp6InRedirects ", 17)) { + sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6); + } + else if (!strncmp(line, "Icmp6OutRedirects ", 18)) { + sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6); + } + else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) { + sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6); + } + else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) { + sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read UDPv6 network traffic statistics from /proc/net/snmp6. + * + * IN: + * @st_net_udp6 Structure where stats will be saved. + * + * OUT: + * @st_net_udp6 Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_net_udp6(struct stats_net_udp6 *st_net_udp6) +{ + FILE *fp; + char line[128]; + + if ((fp = fopen(NET_SNMP6, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "Udp6InDatagrams ", 16)) { + sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6); + } + else if (!strncmp(line, "Udp6OutDatagrams ", 17)) { + sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6); + } + else if (!strncmp(line, "Udp6NoPorts ", 12)) { + sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6); + } + else if (!strncmp(line, "Udp6InErrors ", 13)) { + sscanf(line + 13, "%lu", &st_net_udp6->InErrors6); + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read CPU frequency statistics. + * + * IN: + * @st_pwr_cpufreq Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 1. + * + * OUT: + * @st_pwr_cpufreq Structure with statistics. + * + * RETURNS: + * Highest CPU number for which statistics have been read. + * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc. + * Or -1 if the buffer was too small and needs to be reallocated. + *************************************************************************** + */ +__nr_t read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, __nr_t nr_alloc) +{ + FILE *fp; + struct stats_pwr_cpufreq *st_pwr_cpufreq_i; + char line[1024]; + int nr = 0; + __nr_t cpu_read = 1; /* For CPU "all" */ + unsigned int proc_nr = 0, ifreq, dfreq; + + if ((fp = fopen(CPUINFO, "r")) == NULL) + return 0; + + st_pwr_cpufreq->cpufreq = 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "processor\t", 10)) { + sscanf(strchr(line, ':') + 1, "%u", &proc_nr); + + if (proc_nr + 2 > nr_alloc) { + cpu_read = -1; + break; + } + } + + /* Entry in /proc/cpuinfo is different between Intel and Power architectures */ + else if (!strncmp(line, "cpu MHz\t", 8) || + !strncmp(line, "clock\t", 6)) { + sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq); + + /* Save current CPU frequency */ + st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nr + 1; + st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10; + + /* Also save it to compute an average CPU frequency */ + st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq; + nr++; + + if (proc_nr + 2 > cpu_read) { + cpu_read = proc_nr + 2; + } + } + } + + fclose(fp); + + if (nr) { + /* Compute average CPU frequency for this machine */ + st_pwr_cpufreq->cpufreq /= nr; + } + return cpu_read; +} + +/* + *************************************************************************** + * Read hugepages statistics from /proc/meminfo. + * + * IN: + * @st_huge Structure where stats will be saved. + * + * OUT: + * @st_huge Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +__nr_t read_meminfo_huge(struct stats_huge *st_huge) +{ + FILE *fp; + char line[128]; + unsigned long szhkb = 0; + + if ((fp = fopen(MEMINFO, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + if (!strncmp(line, "HugePages_Total:", 16)) { + /* Read the total number of huge pages */ + sscanf(line + 16, "%llu", &st_huge->tlhkb); + } + else if (!strncmp(line, "HugePages_Free:", 15)) { + /* Read the number of free huge pages */ + sscanf(line + 15, "%llu", &st_huge->frhkb); + } + else if (!strncmp(line, "Hugepagesize:", 13)) { + /* Read the default size of a huge page in kB */ + sscanf(line + 13, "%lu", &szhkb); + } + } + + fclose(fp); + + /* We want huge pages stats in kB and not expressed in a number of pages */ + st_huge->tlhkb *= szhkb; + st_huge->frhkb *= szhkb; + return 1; +} + +/* + *************************************************************************** + * Read CPU average frequencies statistics. + * + * IN: + * @st_pwr_wghfreq Structure where stats will be saved. + * @cpu_nr CPU number for which time_in_state date will be read. + * @nbr Total number of states (frequencies). + * + * OUT: + * @st_pwr_wghfreq Structure with statistics. + * + * RETURNS: + * 1 on success, 0 otherwise. + *************************************************************************** + */ +int read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr) +{ + FILE *fp; + struct stats_pwr_wghfreq *st_pwr_wghfreq_j; + char filename[MAX_PF_NAME]; + char line[128]; + int j = 0; + unsigned long freq; + unsigned long long time_in_state; + + snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s", + SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE); + if ((fp = fopen(filename, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + + sscanf(line, "%lu %llu", &freq, &time_in_state); + + if (j < nbr) { + /* Save current frequency and time */ + st_pwr_wghfreq_j = st_pwr_wghfreq + j; + st_pwr_wghfreq_j->freq = freq; + st_pwr_wghfreq_j->time_in_state = time_in_state; + j++; + } + } + + fclose(fp); + return 1; +} + +/* + *************************************************************************** + * Read weighted CPU frequency statistics. + * + * IN: + * @st_pwr_wghfreq Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 0. + * @nr2 Number of sub-items allocated per structure. + * + * OUT: + * @st_pwr_wghfreq Structure with statistics. + * + * RETURNS: + * Number of CPU for which statistics have been read. + * 1 means CPU "all", 2 means CPU "all" and 0, etc. + * Or -1 if the buffer was to small and needs to be reallocated. + *************************************************************************** + */ +__nr_t read_cpu_wghfreq(struct stats_pwr_wghfreq *st_pwr_wghfreq, __nr_t nr_alloc, + __nr_t nr2) +{ + __nr_t cpu_read = 0; + int j; + struct stats_pwr_wghfreq *st_pwr_wghfreq_i, *st_pwr_wghfreq_j, *st_pwr_wghfreq_all_j; + + do { + if (cpu_read + 2 > nr_alloc) + return -1; + + /* Read current CPU time-in-state data */ + st_pwr_wghfreq_i = st_pwr_wghfreq + (cpu_read + 1) * nr2; + if (!read_time_in_state(st_pwr_wghfreq_i, cpu_read, nr2)) + break; + + /* Also save data for CPU 'all' */ + for (j = 0; j < nr2; j++) { + st_pwr_wghfreq_j = st_pwr_wghfreq_i + j; /* CPU #cpu, state #j */ + st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */ + if (!cpu_read) { + /* Assume that possible frequencies are the same for all CPUs */ + st_pwr_wghfreq_all_j->freq = st_pwr_wghfreq_j->freq; + } + st_pwr_wghfreq_all_j->time_in_state += st_pwr_wghfreq_j->time_in_state; + } + cpu_read++; + } + while (1); + + if (cpu_read > 0) { + for (j = 0; j < nr2; j++) { + st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */ + st_pwr_wghfreq_all_j->time_in_state /= cpu_read; + } + + return cpu_read + 1; /* For CPU "all" */ + } + + return 0; +} + +/* + *************************************************************************** + * Read current USB device data. + * + * IN: + * @st_pwr_usb Structure where stats will be saved. + * @usb_device File name for current USB device. + * + * OUT: + * @st_pwr_usb Structure with statistics. + *************************************************************************** + */ +void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device) +{ + int l, rc; + FILE *fp; + char * rs; + char filename[MAX_PF_NAME]; + + /* Get USB device bus number */ + sscanf(usb_device, "%u", &st_pwr_usb->bus_nr); + + /* Read USB device vendor ID */ + snprintf(filename, MAX_PF_NAME, "%s/%s/%s", + SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR); + if ((fp = fopen(filename, "r")) != NULL) { + rc = fscanf(fp, "%x", + &st_pwr_usb->vendor_id); + fclose(fp); + if (rc == 0) { + st_pwr_usb->vendor_id = 0; + } + } + + /* Read USB device product ID */ + snprintf(filename, MAX_PF_NAME, "%s/%s/%s", + SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT); + if ((fp = fopen(filename, "r")) != NULL) { + rc = fscanf(fp, "%x", + &st_pwr_usb->product_id); + fclose(fp); + if (rc == 0) { + st_pwr_usb->product_id = 0; + } + } + + /* Read USB device max power consumption */ + snprintf(filename, MAX_PF_NAME, "%s/%s/%s", + SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER); + if ((fp = fopen(filename, "r")) != NULL) { + rc = fscanf(fp, "%u", + &st_pwr_usb->bmaxpower); + fclose(fp); + if (rc == 0) { + st_pwr_usb->bmaxpower = 0; + } + } + + /* Read USB device manufacturer */ + snprintf(filename, MAX_PF_NAME, "%s/%s/%s", + SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER); + if ((fp = fopen(filename, "r")) != NULL) { + rs = fgets(st_pwr_usb->manufacturer, + MAX_MANUF_LEN - 1, fp); + fclose(fp); + if ((rs != NULL) && + (l = strlen(st_pwr_usb->manufacturer)) > 0) { + /* Remove trailing CR */ + st_pwr_usb->manufacturer[l - 1] = '\0'; + } + } + + /* Read USB device product */ + snprintf(filename, MAX_PF_NAME, "%s/%s/%s", + SYSFS_USBDEV, usb_device, SYSFS_PRODUCT); + if ((fp = fopen(filename, "r")) != NULL) { + rs = fgets(st_pwr_usb->product, + MAX_PROD_LEN - 1, fp); + fclose(fp); + if ((rs != NULL) && + (l = strlen(st_pwr_usb->product)) > 0) { + /* Remove trailing CR */ + st_pwr_usb->product[l - 1] = '\0'; + } + } +} + +/* + *************************************************************************** + * Read USB devices statistics. + * + * IN: + * @st_pwr_usb Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 0. + * + * OUT: + * @st_pwr_usb Structure with statistics. + * + * RETURNS: + * Number of USB devices read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, __nr_t nr_alloc) +{ + DIR *dir; + struct dirent *drd; + struct stats_pwr_usb *st_pwr_usb_i; + __nr_t usb_read = 0; + + /* Open relevant /sys directory */ + if ((dir = opendir(SYSFS_USBDEV)) == NULL) + return 0; + + /* Get current file entry */ + while ((drd = readdir(dir)) != NULL) { + + if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) { + + if (usb_read + 1 > nr_alloc) { + usb_read = -1; + break; + } + + /* Read current USB device data */ + st_pwr_usb_i = st_pwr_usb + usb_read++; + read_usb_stats(st_pwr_usb_i, drd->d_name); + } + } + + /* Close directory */ + closedir(dir); + return usb_read; +} + +/* + *************************************************************************** + * Read filesystems statistics. + * + * IN: + * @st_filesystem Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 0. + * + * OUT: + * @st_filesystem Structure with statistics. + * + * RETURNS: + * Number of filesystems read, or -1 if the buffer was too small and + * needs to be reallocated. + *************************************************************************** + */ +__nr_t read_filesystem(struct stats_filesystem *st_filesystem, __nr_t nr_alloc) +{ + FILE *fp; + char line[512], fs_name[128], mountp[256]; + int skip = 0, skip_next = 0; + char *pos = 0; + __nr_t fs_read = 0; + struct stats_filesystem *st_filesystem_i; + struct statvfs buf; + + if ((fp = fopen(MTAB, "r")) == NULL) + return 0; + + while (fgets(line, sizeof(line), fp) != NULL) { + /* + * Ignore line if the preceding line did not contain '\n'. + * (Some very long lines may be found for instance when + * overlay2 filesystem with docker is used). + */ + skip = skip_next; + skip_next = (strchr(line, '\n') == NULL); + if (skip) + continue; + + if (line[0] == '/') { + /* Find field separator position */ + pos = strchr(line, ' '); + if (pos == NULL) + continue; + + /* Read current filesystem name */ + sscanf(line, "%127s", fs_name); + /* + * And now read the corresponding mount point. + * Read fs name and mount point in two distinct operations. + * Indeed, if fs name length is greater than 127 chars, + * previous scanf() will read only the first 127 chars, and + * mount point name will be read using the remaining chars + * from the fs name. This will result in a bogus name + * and following statvfs() function will always fail. + */ + sscanf(pos + 1, "%255s", mountp); + + /* Replace octal codes */ + oct2chr(mountp); + + /* + * It's important to have read the whole mount point name + * for statvfs() to work properly (see above). + */ + if ((statvfs(mountp, &buf) < 0) || (!buf.f_blocks)) + continue; + + if (fs_read + 1 > nr_alloc) { + fs_read = -1; + break; + } + + st_filesystem_i = st_filesystem + fs_read++; + st_filesystem_i->f_blocks = (unsigned long long) buf.f_blocks * (unsigned long long) buf.f_frsize; + st_filesystem_i->f_bfree = (unsigned long long) buf.f_bfree * (unsigned long long) buf.f_frsize; + st_filesystem_i->f_bavail = (unsigned long long) buf.f_bavail * (unsigned long long) buf.f_frsize; + st_filesystem_i->f_files = (unsigned long long) buf.f_files; + st_filesystem_i->f_ffree = (unsigned long long) buf.f_ffree; + strncpy(st_filesystem_i->fs_name, fs_name, MAX_FS_LEN); + st_filesystem_i->fs_name[MAX_FS_LEN - 1] = '\0'; + strncpy(st_filesystem_i->mountp, mountp, MAX_FS_LEN); + st_filesystem_i->mountp[MAX_FS_LEN - 1] = '\0'; + } + } + + fclose(fp); + return fs_read; +} + +/* + *************************************************************************** + * Read Fibre Channel HBA statistics. + * + * IN: + * @st_fc Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 0. + * + * OUT: + * @st_fc Structure with statistics. + * + * RETURNS: + * Number of FC hosts read, or -1 if the buffer was too small and needs to + * be reallocated. + *************************************************************************** + */ +__nr_t read_fchost(struct stats_fchost *st_fc, __nr_t nr_alloc) +{ + DIR *dir; + FILE *fp; + struct dirent *drd; + struct stats_fchost *st_fc_i; + __nr_t fch_read = 0; + char fcstat_filename[MAX_PF_NAME]; + char line[256]; + unsigned long rx_frames, tx_frames, rx_words, tx_words; + + /* Each host, if present, will have its own hostX entry within SYSFS_FCHOST */ + if ((dir = opendir(SYSFS_FCHOST)) == NULL) + return 0; /* No FC hosts */ + + /* + * Read each of the counters via sysfs, where they are + * returned as hex values (e.g. 0x72400). + */ + while ((drd = readdir(dir)) != NULL) { + rx_frames = tx_frames = rx_words = tx_words = 0; + + if (!strncmp(drd->d_name, "host", 4)) { + + if (fch_read + 1 > nr_alloc) { + fch_read = -1; + break; + } + + snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_FRAMES, + SYSFS_FCHOST, drd->d_name); + if ((fp = fopen(fcstat_filename, "r"))) { + if (fgets(line, sizeof(line), fp)) { + sscanf(line, "%lx", &rx_frames); + } + fclose(fp); + } + + snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_FRAMES, + SYSFS_FCHOST, drd->d_name); + if ((fp = fopen(fcstat_filename, "r"))) { + if (fgets(line, sizeof(line), fp)) { + sscanf(line, "%lx", &tx_frames); + } + fclose(fp); + } + + snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_WORDS, + SYSFS_FCHOST, drd->d_name); + if ((fp = fopen(fcstat_filename, "r"))) { + if (fgets(line, sizeof(line), fp)) { + sscanf(line, "%lx", &rx_words); + } + fclose(fp); + } + + snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_WORDS, + SYSFS_FCHOST, drd->d_name); + if ((fp = fopen(fcstat_filename, "r"))) { + if (fgets(line, sizeof(line), fp)) { + sscanf(line, "%lx", &tx_words); + } + fclose(fp); + } + + st_fc_i = st_fc + fch_read++; + st_fc_i->f_rxframes = rx_frames; + st_fc_i->f_txframes = tx_frames; + st_fc_i->f_rxwords = rx_words; + st_fc_i->f_txwords = tx_words; + strncpy(st_fc_i->fchost_name, drd->d_name, MAX_FCH_LEN); + st_fc_i->fchost_name[MAX_FCH_LEN - 1] = '\0'; + } + } + + closedir(dir); + return fch_read; +} + +/* + *************************************************************************** + * Read softnet statistics. + * + * IN: + * @st_softnet Structure where stats will be saved. + * @nr_alloc Total number of structures allocated. Value is >= 0. + * @online_cpu_bitmap + * Bitmap listing online CPU. + * + * OUT: + * @st_softnet Structure with statistics. + * + * RETURNS: + * 1 if stats have been sucessfully read, or 0 otherwise. + *************************************************************************** + */ +int read_softnet(struct stats_softnet *st_softnet, __nr_t nr_alloc, + unsigned char online_cpu_bitmap[]) +{ + FILE *fp; + struct stats_softnet *st_softnet_i; + char line[1024]; + int cpu; + + /* Open /proc/net/softnet_stat file */ + if ((fp = fopen(NET_SOFTNET, "r")) == NULL) + return 0; + + for (cpu = 1; cpu < nr_alloc; cpu++) { + if (!(online_cpu_bitmap[(cpu - 1) >> 3] & (1 << ((cpu - 1) & 0x07)))) + /* CPU is offline */ + continue; + + if (fgets(line, sizeof(line), fp) == NULL) + break; + + st_softnet_i = st_softnet + cpu; + sscanf(line, "%x %x %x %*x %*x %*x %*x %*x %*x %x %x", + &st_softnet_i->processed, + &st_softnet_i->dropped, + &st_softnet_i->time_squeeze, + &st_softnet_i->received_rps, + &st_softnet_i->flow_limit); + } + + fclose(fp); + return 1; +} + +/*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/ +#endif /* SOURCE_SADC */ diff --git a/tests/12.0.1/rd_stats.h b/tests/12.0.1/rd_stats.h new file mode 100644 index 0000000..7e2326a --- /dev/null +++ b/tests/12.0.1/rd_stats.h @@ -0,0 +1,790 @@ +/* + * rd_stats.h: Include file used to read system statistics + * (C) 1999-2018 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _RD_STATS_H +#define _RD_STATS_H + +/* + *************************************************************************** + * Miscellaneous constants + *************************************************************************** + */ + +/* Get IFNAMSIZ */ +#include +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +/* Maximum length of block device name */ +#define MAX_DEV_LEN 128 +/* Maximum length of network interface name */ +#define MAX_IFACE_LEN IFNAMSIZ +/* Maximum length of USB manufacturer string */ +#define MAX_MANUF_LEN 24 +/* Maximum length of USB product string */ +#define MAX_PROD_LEN 48 +/* Maximum length of filesystem name */ +#define MAX_FS_LEN 128 +/* Maximum length of FC host name */ +#define MAX_FCH_LEN 16 + +#define CNT_PART 1 +#define CNT_ALL_DEV 0 +#define CNT_USED_DEV 1 + +#define K_DUPLEX_HALF "half" +#define K_DUPLEX_FULL "full" + +#define C_DUPLEX_HALF 1 +#define C_DUPLEX_FULL 2 + +/* Type for all functions counting items. Value can be negative (-1) */ +#define __nr_t int + +/* + *************************************************************************** + * System files containing statistics + *************************************************************************** + */ + +/* Files */ +#define PROC "/proc" +#define SERIAL "/proc/tty/driver/serial" +#define FDENTRY_STATE "/proc/sys/fs/dentry-state" +#define FFILE_NR "/proc/sys/fs/file-nr" +#define FINODE_STATE "/proc/sys/fs/inode-state" +#define PTY_NR "/proc/sys/kernel/pty/nr" +#define NET_DEV "/proc/net/dev" +#define NET_SOCKSTAT "/proc/net/sockstat" +#define NET_SOCKSTAT6 "/proc/net/sockstat6" +#define NET_RPC_NFS "/proc/net/rpc/nfs" +#define NET_RPC_NFSD "/proc/net/rpc/nfsd" +#define NET_SOFTNET "/proc/net/softnet_stat" +#define LOADAVG "/proc/loadavg" +#define VMSTAT "/proc/vmstat" +#define NET_SNMP "/proc/net/snmp" +#define NET_SNMP6 "/proc/net/snmp6" +#define CPUINFO "/proc/cpuinfo" +#define MTAB "/etc/mtab" +#define IF_DUPLEX "/sys/class/net/%s/duplex" +#define IF_SPEED "/sys/class/net/%s/speed" +#define FC_RX_FRAMES "%s/%s/statistics/rx_frames" +#define FC_TX_FRAMES "%s/%s/statistics/tx_frames" +#define FC_RX_WORDS "%s/%s/statistics/rx_words" +#define FC_TX_WORDS "%s/%s/statistics/tx_words" + +/* + *************************************************************************** + * Definitions of structures for system statistics. + * WARNING: Fields order matters for SVG graphs! + *************************************************************************** + */ + +#define SIZEOF_LONG_64BIT 8 +#define ULL_ALIGNMENT_WIDTH 8 +#define UL_ALIGNMENT_WIDTH SIZEOF_LONG_64BIT +#define U_ALIGNMENT_WIDTH 4 + +#define MAP_SIZE(m) ((m[0] * ULL_ALIGNMENT_WIDTH) + \ + (m[1] * UL_ALIGNMENT_WIDTH) + \ + (m[2] * U_ALIGNMENT_WIDTH)) + +/* + * Structure for CPU statistics. + * In activity buffer: First structure is for global CPU utilisation ("all"). + * Following structures are for each individual CPU (0, 1, etc.) + */ +struct stats_cpu { + unsigned long long cpu_user; + unsigned long long cpu_nice; + unsigned long long cpu_sys; + unsigned long long cpu_idle; + unsigned long long cpu_iowait; + unsigned long long cpu_steal; + unsigned long long cpu_hardirq; + unsigned long long cpu_softirq; + unsigned long long cpu_guest; + unsigned long long cpu_guest_nice; +}; + +#define STATS_CPU_SIZE (sizeof(struct stats_cpu)) +#define STATS_CPU_ULL 10 +#define STATS_CPU_UL 0 +#define STATS_CPU_U 0 + +/* + * Structure for task creation and context switch statistics. + * The attribute (aligned(16)) is necessary so that sizeof(structure) has + * the same value on 32 and 64-bit architectures. + */ +struct stats_pcsw { + unsigned long long context_switch; + unsigned long processes __attribute__ ((aligned (8))); +}; + +#define STATS_PCSW_SIZE (sizeof(struct stats_pcsw)) +#define STATS_PCSW_ULL 1 +#define STATS_PCSW_UL 1 +#define STATS_PCSW_U 0 + +/* + * Structure for interrupts statistics. + * In activity buffer: First structure is for total number of interrupts ("SUM"). + * Following structures are for each individual interrupt (0, 1, etc.) + */ +struct stats_irq { + unsigned long long irq_nr; +}; + +#define STATS_IRQ_SIZE (sizeof(struct stats_irq)) +#define STATS_IRQ_ULL 1 +#define STATS_IRQ_UL 0 +#define STATS_IRQ_U 0 + +/* Structure for swapping statistics */ +struct stats_swap { + unsigned long pswpin __attribute__ ((aligned (8))); + unsigned long pswpout __attribute__ ((aligned (8))); +}; + +#define STATS_SWAP_SIZE (sizeof(struct stats_swap)) +#define STATS_SWAP_ULL 0 +#define STATS_SWAP_UL 2 +#define STATS_SWAP_U 0 + +/* Structure for paging statistics */ +struct stats_paging { + unsigned long pgpgin __attribute__ ((aligned (8))); + unsigned long pgpgout __attribute__ ((aligned (8))); + unsigned long pgfault __attribute__ ((aligned (8))); + unsigned long pgmajfault __attribute__ ((aligned (8))); + unsigned long pgfree __attribute__ ((aligned (8))); + unsigned long pgscan_kswapd __attribute__ ((aligned (8))); + unsigned long pgscan_direct __attribute__ ((aligned (8))); + unsigned long pgsteal __attribute__ ((aligned (8))); +}; + +#define STATS_PAGING_SIZE (sizeof(struct stats_paging)) +#define STATS_PAGING_ULL 0 +#define STATS_PAGING_UL 8 +#define STATS_PAGING_U 0 + +/* Structure for I/O and transfer rate statistics */ +struct stats_io { + unsigned long long dk_drive; + unsigned long long dk_drive_rio; + unsigned long long dk_drive_wio; + unsigned long long dk_drive_rblk; + unsigned long long dk_drive_wblk; +}; + +#define STATS_IO_SIZE (sizeof(struct stats_io)) +#define STATS_IO_ULL 5 +#define STATS_IO_UL 0 +#define STATS_IO_U 0 + +/* Structure for memory and swap space utilization statistics */ +struct stats_memory { + unsigned long long frmkb; + unsigned long long bufkb; + unsigned long long camkb; + unsigned long long tlmkb; + unsigned long long frskb; + unsigned long long tlskb; + unsigned long long caskb; + unsigned long long comkb; + unsigned long long activekb; + unsigned long long inactkb; + unsigned long long dirtykb; + unsigned long long anonpgkb; + unsigned long long slabkb; + unsigned long long kstackkb; + unsigned long long pgtblkb; + unsigned long long vmusedkb; + unsigned long long availablekb; +}; + +#define STATS_MEMORY_SIZE (sizeof(struct stats_memory)) +#define STATS_MEMORY_ULL 17 +#define STATS_MEMORY_UL 0 +#define STATS_MEMORY_U 0 + +/* Structure for kernel tables statistics */ +struct stats_ktables { + unsigned long long file_used; + unsigned long long inode_used; + unsigned long long dentry_stat; + unsigned long long pty_nr; +}; + +#define STATS_KTABLES_SIZE (sizeof(struct stats_ktables)) +#define STATS_KTABLES_ULL 4 +#define STATS_KTABLES_UL 0 +#define STATS_KTABLES_U 0 + +/* Structure for queue and load statistics */ +struct stats_queue { + unsigned long long nr_running; + unsigned long long procs_blocked; + unsigned long long nr_threads; + unsigned int load_avg_1; + unsigned int load_avg_5; + unsigned int load_avg_15; +}; + +#define STATS_QUEUE_SIZE (sizeof(struct stats_queue)) +#define STATS_QUEUE_ULL 3 +#define STATS_QUEUE_UL 0 +#define STATS_QUEUE_U 3 + +/* Structure for serial statistics */ +struct stats_serial { + unsigned int rx; + unsigned int tx; + unsigned int frame; + unsigned int parity; + unsigned int brk; + unsigned int overrun; + unsigned int line; +}; + +#define STATS_SERIAL_SIZE (sizeof(struct stats_serial)) +#define STATS_SERIAL_ULL 0 +#define STATS_SERIAL_UL 0 +#define STATS_SERIAL_U 7 + +/* Structure for block devices statistics */ +struct stats_disk { + unsigned long long nr_ios; + unsigned long rd_sect __attribute__ ((aligned (8))); + unsigned long wr_sect __attribute__ ((aligned (8))); + unsigned int rd_ticks __attribute__ ((aligned (8))); + unsigned int wr_ticks; + unsigned int tot_ticks; + unsigned int rq_ticks; + unsigned int major; + unsigned int minor; +}; + +#define STATS_DISK_SIZE (sizeof(struct stats_disk)) +#define STATS_DISK_ULL 1 +#define STATS_DISK_UL 2 +#define STATS_DISK_U 6 + +/* Structure for network interfaces statistics */ +struct stats_net_dev { + unsigned long long rx_packets; + unsigned long long tx_packets; + unsigned long long rx_bytes; + unsigned long long tx_bytes; + unsigned long long rx_compressed; + unsigned long long tx_compressed; + unsigned long long multicast; + unsigned int speed; + char interface[MAX_IFACE_LEN]; + char duplex; +}; + +#define STATS_NET_DEV_SIZE (sizeof(struct stats_net_dev)) +#define STATS_NET_DEV_SIZE2CMP (STATS_NET_DEV_SIZE - MAX_IFACE_LEN - 1) +#define STATS_NET_DEV_ULL 7 +#define STATS_NET_DEV_UL 0 +#define STATS_NET_DEV_U 1 + +/* Structure for network interface errors statistics */ +struct stats_net_edev { + unsigned long long collisions; + unsigned long long rx_errors; + unsigned long long tx_errors; + unsigned long long rx_dropped; + unsigned long long tx_dropped; + unsigned long long rx_fifo_errors; + unsigned long long tx_fifo_errors; + unsigned long long rx_frame_errors; + unsigned long long tx_carrier_errors; + char interface[MAX_IFACE_LEN]; +}; + +#define STATS_NET_EDEV_SIZE (sizeof(struct stats_net_edev)) +#define STATS_NET_EDEV_SIZE2CMP (STATS_NET_EDEV_SIZE - MAX_IFACE_LEN) +#define STATS_NET_EDEV_ULL 9 +#define STATS_NET_EDEV_UL 0 +#define STATS_NET_EDEV_U 0 + +/* Structure for NFS client statistics */ +struct stats_net_nfs { + unsigned int nfs_rpccnt; + unsigned int nfs_rpcretrans; + unsigned int nfs_readcnt; + unsigned int nfs_writecnt; + unsigned int nfs_accesscnt; + unsigned int nfs_getattcnt; +}; + +#define STATS_NET_NFS_SIZE (sizeof(struct stats_net_nfs)) +#define STATS_NET_NFS_ULL 0 +#define STATS_NET_NFS_UL 0 +#define STATS_NET_NFS_U 6 + +/* Structure for NFS server statistics */ +struct stats_net_nfsd { + unsigned int nfsd_rpccnt; + unsigned int nfsd_rpcbad; + unsigned int nfsd_netcnt; + unsigned int nfsd_netudpcnt; + unsigned int nfsd_nettcpcnt; + unsigned int nfsd_rchits; + unsigned int nfsd_rcmisses; + unsigned int nfsd_readcnt; + unsigned int nfsd_writecnt; + unsigned int nfsd_accesscnt; + unsigned int nfsd_getattcnt; +}; + +#define STATS_NET_NFSD_SIZE (sizeof(struct stats_net_nfsd)) +#define STATS_NET_NFSD_ULL 0 +#define STATS_NET_NFSD_UL 0 +#define STATS_NET_NFSD_U 11 + +/* Structure for IPv4 sockets statistics */ +struct stats_net_sock { + unsigned int sock_inuse; + unsigned int tcp_inuse; + unsigned int tcp_tw; + unsigned int udp_inuse; + unsigned int raw_inuse; + unsigned int frag_inuse; +}; + +#define STATS_NET_SOCK_SIZE (sizeof(struct stats_net_sock)) +#define STATS_NET_SOCK_ULL 0 +#define STATS_NET_SOCK_UL 0 +#define STATS_NET_SOCK_U 6 + +/* Structure for IP statistics */ +struct stats_net_ip { + unsigned long long InReceives; + unsigned long long ForwDatagrams; + unsigned long long InDelivers; + unsigned long long OutRequests; + unsigned long long ReasmReqds; + unsigned long long ReasmOKs; + unsigned long long FragOKs; + unsigned long long FragCreates; +}; + +#define STATS_NET_IP_SIZE (sizeof(struct stats_net_ip)) +#define STATS_NET_IP_ULL 8 +#define STATS_NET_IP_UL 0 +#define STATS_NET_IP_U 0 + +/* Structure for IP errors statistics */ +struct stats_net_eip { + unsigned long long InHdrErrors; + unsigned long long InAddrErrors; + unsigned long long InUnknownProtos; + unsigned long long InDiscards; + unsigned long long OutDiscards; + unsigned long long OutNoRoutes; + unsigned long long ReasmFails; + unsigned long long FragFails; +}; + +#define STATS_NET_EIP_SIZE (sizeof(struct stats_net_eip)) +#define STATS_NET_EIP_ULL 8 +#define STATS_NET_EIP_UL 0 +#define STATS_NET_EIP_U 0 + +/* Structure for ICMP statistics */ +struct stats_net_icmp { + unsigned long InMsgs __attribute__ ((aligned (8))); + unsigned long OutMsgs __attribute__ ((aligned (8))); + unsigned long InEchos __attribute__ ((aligned (8))); + unsigned long InEchoReps __attribute__ ((aligned (8))); + unsigned long OutEchos __attribute__ ((aligned (8))); + unsigned long OutEchoReps __attribute__ ((aligned (8))); + unsigned long InTimestamps __attribute__ ((aligned (8))); + unsigned long InTimestampReps __attribute__ ((aligned (8))); + unsigned long OutTimestamps __attribute__ ((aligned (8))); + unsigned long OutTimestampReps __attribute__ ((aligned (8))); + unsigned long InAddrMasks __attribute__ ((aligned (8))); + unsigned long InAddrMaskReps __attribute__ ((aligned (8))); + unsigned long OutAddrMasks __attribute__ ((aligned (8))); + unsigned long OutAddrMaskReps __attribute__ ((aligned (8))); +}; + +#define STATS_NET_ICMP_SIZE (sizeof(struct stats_net_icmp)) +#define STATS_NET_ICMP_ULL 0 +#define STATS_NET_ICMP_UL 14 +#define STATS_NET_ICMP_U 0 + +/* Structure for ICMP error message statistics */ +struct stats_net_eicmp { + unsigned long InErrors __attribute__ ((aligned (8))); + unsigned long OutErrors __attribute__ ((aligned (8))); + unsigned long InDestUnreachs __attribute__ ((aligned (8))); + unsigned long OutDestUnreachs __attribute__ ((aligned (8))); + unsigned long InTimeExcds __attribute__ ((aligned (8))); + unsigned long OutTimeExcds __attribute__ ((aligned (8))); + unsigned long InParmProbs __attribute__ ((aligned (8))); + unsigned long OutParmProbs __attribute__ ((aligned (8))); + unsigned long InSrcQuenchs __attribute__ ((aligned (8))); + unsigned long OutSrcQuenchs __attribute__ ((aligned (8))); + unsigned long InRedirects __attribute__ ((aligned (8))); + unsigned long OutRedirects __attribute__ ((aligned (8))); +}; + +#define STATS_NET_EICMP_SIZE (sizeof(struct stats_net_eicmp)) +#define STATS_NET_EICMP_ULL 0 +#define STATS_NET_EICMP_UL 12 +#define STATS_NET_EICMP_U 0 + +/* Structure for TCP statistics */ +struct stats_net_tcp { + unsigned long ActiveOpens __attribute__ ((aligned (8))); + unsigned long PassiveOpens __attribute__ ((aligned (8))); + unsigned long InSegs __attribute__ ((aligned (8))); + unsigned long OutSegs __attribute__ ((aligned (8))); +}; + +#define STATS_NET_TCP_SIZE (sizeof(struct stats_net_tcp)) +#define STATS_NET_TCP_ULL 0 +#define STATS_NET_TCP_UL 4 +#define STATS_NET_TCP_U 0 + +/* Structure for TCP errors statistics */ +struct stats_net_etcp { + unsigned long AttemptFails __attribute__ ((aligned (8))); + unsigned long EstabResets __attribute__ ((aligned (8))); + unsigned long RetransSegs __attribute__ ((aligned (8))); + unsigned long InErrs __attribute__ ((aligned (8))); + unsigned long OutRsts __attribute__ ((aligned (8))); +}; + +#define STATS_NET_ETCP_SIZE (sizeof(struct stats_net_etcp)) +#define STATS_NET_ETCP_ULL 0 +#define STATS_NET_ETCP_UL 5 +#define STATS_NET_ETCP_U 0 + +/* Structure for UDP statistics */ +struct stats_net_udp { + unsigned long InDatagrams __attribute__ ((aligned (8))); + unsigned long OutDatagrams __attribute__ ((aligned (8))); + unsigned long NoPorts __attribute__ ((aligned (8))); + unsigned long InErrors __attribute__ ((aligned (8))); +}; + +#define STATS_NET_UDP_SIZE (sizeof(struct stats_net_udp)) +#define STATS_NET_UDP_ULL 0 +#define STATS_NET_UDP_UL 4 +#define STATS_NET_UDP_U 0 + +/* Structure for IPv6 sockets statistics */ +struct stats_net_sock6 { + unsigned int tcp6_inuse; + unsigned int udp6_inuse; + unsigned int raw6_inuse; + unsigned int frag6_inuse; +}; + +#define STATS_NET_SOCK6_SIZE (sizeof(struct stats_net_sock6)) +#define STATS_NET_SOCK6_ULL 0 +#define STATS_NET_SOCK6_UL 0 +#define STATS_NET_SOCK6_U 4 + +/* Structure for IPv6 statistics */ +struct stats_net_ip6 { + unsigned long long InReceives6; + unsigned long long OutForwDatagrams6; + unsigned long long InDelivers6; + unsigned long long OutRequests6; + unsigned long long ReasmReqds6; + unsigned long long ReasmOKs6; + unsigned long long InMcastPkts6; + unsigned long long OutMcastPkts6; + unsigned long long FragOKs6; + unsigned long long FragCreates6; +}; + +#define STATS_NET_IP6_SIZE (sizeof(struct stats_net_ip6)) +#define STATS_NET_IP6_ULL 10 +#define STATS_NET_IP6_UL 0 +#define STATS_NET_IP6_U 0 + +/* Structure for IPv6 errors statistics */ +struct stats_net_eip6 { + unsigned long long InHdrErrors6; + unsigned long long InAddrErrors6; + unsigned long long InUnknownProtos6; + unsigned long long InTooBigErrors6; + unsigned long long InDiscards6; + unsigned long long OutDiscards6; + unsigned long long InNoRoutes6; + unsigned long long OutNoRoutes6; + unsigned long long ReasmFails6; + unsigned long long FragFails6; + unsigned long long InTruncatedPkts6; +}; + +#define STATS_NET_EIP6_SIZE (sizeof(struct stats_net_eip6)) +#define STATS_NET_EIP6_ULL 11 +#define STATS_NET_EIP6_UL 0 +#define STATS_NET_EIP6_U 0 + +/* Structure for ICMPv6 statistics */ +struct stats_net_icmp6 { + unsigned long InMsgs6 __attribute__ ((aligned (8))); + unsigned long OutMsgs6 __attribute__ ((aligned (8))); + unsigned long InEchos6 __attribute__ ((aligned (8))); + unsigned long InEchoReplies6 __attribute__ ((aligned (8))); + unsigned long OutEchoReplies6 __attribute__ ((aligned (8))); + unsigned long InGroupMembQueries6 __attribute__ ((aligned (8))); + unsigned long InGroupMembResponses6 __attribute__ ((aligned (8))); + unsigned long OutGroupMembResponses6 __attribute__ ((aligned (8))); + unsigned long InGroupMembReductions6 __attribute__ ((aligned (8))); + unsigned long OutGroupMembReductions6 __attribute__ ((aligned (8))); + unsigned long InRouterSolicits6 __attribute__ ((aligned (8))); + unsigned long OutRouterSolicits6 __attribute__ ((aligned (8))); + unsigned long InRouterAdvertisements6 __attribute__ ((aligned (8))); + unsigned long InNeighborSolicits6 __attribute__ ((aligned (8))); + unsigned long OutNeighborSolicits6 __attribute__ ((aligned (8))); + unsigned long InNeighborAdvertisements6 __attribute__ ((aligned (8))); + unsigned long OutNeighborAdvertisements6 __attribute__ ((aligned (8))); +}; + +#define STATS_NET_ICMP6_SIZE (sizeof(struct stats_net_icmp6)) +#define STATS_NET_ICMP6_ULL 0 +#define STATS_NET_ICMP6_UL 17 +#define STATS_NET_ICMP6_U 0 + +/* Structure for ICMPv6 error message statistics */ +struct stats_net_eicmp6 { + unsigned long InErrors6 __attribute__ ((aligned (8))); + unsigned long InDestUnreachs6 __attribute__ ((aligned (8))); + unsigned long OutDestUnreachs6 __attribute__ ((aligned (8))); + unsigned long InTimeExcds6 __attribute__ ((aligned (8))); + unsigned long OutTimeExcds6 __attribute__ ((aligned (8))); + unsigned long InParmProblems6 __attribute__ ((aligned (8))); + unsigned long OutParmProblems6 __attribute__ ((aligned (8))); + unsigned long InRedirects6 __attribute__ ((aligned (8))); + unsigned long OutRedirects6 __attribute__ ((aligned (8))); + unsigned long InPktTooBigs6 __attribute__ ((aligned (8))); + unsigned long OutPktTooBigs6 __attribute__ ((aligned (8))); +}; + +#define STATS_NET_EICMP6_SIZE (sizeof(struct stats_net_eicmp6)) +#define STATS_NET_EICMP6_ULL 0 +#define STATS_NET_EICMP6_UL 11 +#define STATS_NET_EICMP6_U 0 + +/* Structure for UDPv6 statistics */ +struct stats_net_udp6 { + unsigned long InDatagrams6 __attribute__ ((aligned (8))); + unsigned long OutDatagrams6 __attribute__ ((aligned (8))); + unsigned long NoPorts6 __attribute__ ((aligned (8))); + unsigned long InErrors6 __attribute__ ((aligned (8))); +}; + +#define STATS_NET_UDP6_SIZE (sizeof(struct stats_net_udp6)) +#define STATS_NET_UDP6_ULL 0 +#define STATS_NET_UDP6_UL 4 +#define STATS_NET_UDP6_U 0 + +/* + * Structure for CPU frequency statistics. + * In activity buffer: First structure is for global CPU utilisation ("all"). + * Following structures are for each individual CPU (0, 1, etc.) + */ +struct stats_pwr_cpufreq { + unsigned long cpufreq __attribute__ ((aligned (8))); +}; + +#define STATS_PWR_CPUFREQ_SIZE (sizeof(struct stats_pwr_cpufreq)) +#define STATS_PWR_CPUFREQ_ULL 0 +#define STATS_PWR_CPUFREQ_UL 1 +#define STATS_PWR_CPUFREQ_U 0 + +/* Structure for hugepages statistics */ +struct stats_huge { + unsigned long long frhkb; + unsigned long long tlhkb; +}; + +#define STATS_HUGE_SIZE (sizeof(struct stats_huge)) +#define STATS_HUGE_ULL 2 +#define STATS_HUGE_UL 0 +#define STATS_HUGE_U 0 + +/* + * Structure for weighted CPU frequency statistics. + * In activity buffer: First structure is for global CPU utilisation ("all"). + * Following structures are for each individual CPU (0, 1, etc.) + */ +struct stats_pwr_wghfreq { + unsigned long long time_in_state; + unsigned long freq __attribute__ ((aligned (8))); +}; + +#define STATS_PWR_WGHFREQ_SIZE (sizeof(struct stats_pwr_wghfreq)) +#define STATS_PWR_WGHFREQ_ULL 1 +#define STATS_PWR_WGHFREQ_UL 1 +#define STATS_PWR_WGHFREQ_U 0 + +/* + * Structure for USB devices plugged into the system. + */ +struct stats_pwr_usb { + unsigned int bus_nr; + unsigned int vendor_id; + unsigned int product_id; + unsigned int bmaxpower; + char manufacturer[MAX_MANUF_LEN]; + char product[MAX_PROD_LEN]; +}; + +#define STATS_PWR_USB_SIZE (sizeof(struct stats_pwr_usb)) +#define STATS_PWR_USB_ULL 0 +#define STATS_PWR_USB_UL 0 +#define STATS_PWR_USB_U 4 + +/* Structure for filesystems statistics */ +struct stats_filesystem { + unsigned long long f_blocks; + unsigned long long f_bfree; + unsigned long long f_bavail; + unsigned long long f_files; + unsigned long long f_ffree; + char fs_name[MAX_FS_LEN]; + char mountp[MAX_FS_LEN]; +}; + +#define STATS_FILESYSTEM_SIZE (sizeof(struct stats_filesystem)) +#define STATS_FILESYSTEM_SIZE2CMP (STATS_FILESYSTEM_SIZE - 2 * MAX_FS_LEN) +#define STATS_FILESYSTEM_ULL 5 +#define STATS_FILESYSTEM_UL 0 +#define STATS_FILESYSTEM_U 0 + +/* Structure for Fibre Channel HBA statistics */ +struct stats_fchost { + unsigned long f_rxframes __attribute__ ((aligned (8))); + unsigned long f_txframes __attribute__ ((aligned (8))); + unsigned long f_rxwords __attribute__ ((aligned (8))); + unsigned long f_txwords __attribute__ ((aligned (8))); + char fchost_name[MAX_FCH_LEN] __attribute__ ((aligned (8))); +}; + +#define STATS_FCHOST_SIZE (sizeof(struct stats_fchost)) +#define STATS_FCHOST_ULL 0 +#define STATS_FCHOST_UL 4 +#define STATS_FCHOST_U 0 + +/* Structure for softnet statistics */ +struct stats_softnet { + unsigned int processed; + unsigned int dropped; + unsigned int time_squeeze; + unsigned int received_rps; + unsigned int flow_limit; +}; + +#define STATS_SOFTNET_SIZE (sizeof(struct stats_softnet)) +#define STATS_SOFTNET_ULL 0 +#define STATS_SOFTNET_UL 0 +#define STATS_SOFTNET_U 5 + +/* + *************************************************************************** + * Prototypes for functions used to read system statistics + *************************************************************************** + */ + +void compute_ext_disk_stats + (struct stats_disk *, struct stats_disk *, unsigned long long, + struct ext_disk_stats *); +unsigned long long get_per_cpu_interval + (struct stats_cpu *, struct stats_cpu *); +__nr_t read_stat_cpu + (struct stats_cpu *, __nr_t); +__nr_t read_stat_irq + (struct stats_irq *, __nr_t); +__nr_t read_meminfo + (struct stats_memory *); +void read_uptime + (unsigned long long *); +#ifdef SOURCE_SADC +void oct2chr + (char *); +__nr_t read_stat_pcsw + (struct stats_pcsw *); +__nr_t read_loadavg + (struct stats_queue *); +__nr_t read_vmstat_swap + (struct stats_swap *); +__nr_t read_vmstat_paging + (struct stats_paging *); +__nr_t read_diskstats_io + (struct stats_io *); +__nr_t read_diskstats_disk + (struct stats_disk *, __nr_t, int); +__nr_t read_tty_driver_serial + (struct stats_serial *, __nr_t); +__nr_t read_kernel_tables + (struct stats_ktables *); +__nr_t read_net_dev + (struct stats_net_dev *, __nr_t); +void read_if_info + (struct stats_net_dev *, int); +__nr_t read_net_edev + (struct stats_net_edev *, __nr_t); +__nr_t read_net_nfs + (struct stats_net_nfs *); +__nr_t read_net_nfsd + (struct stats_net_nfsd *); +__nr_t read_net_sock + (struct stats_net_sock *); +__nr_t read_net_ip + (struct stats_net_ip *); +__nr_t read_net_eip + (struct stats_net_eip *); +__nr_t read_net_icmp + (struct stats_net_icmp *); +__nr_t read_net_eicmp + (struct stats_net_eicmp *); +__nr_t read_net_tcp + (struct stats_net_tcp *); +__nr_t read_net_etcp + (struct stats_net_etcp *); +__nr_t read_net_udp + (struct stats_net_udp *); +__nr_t read_net_sock6 + (struct stats_net_sock6 *); +__nr_t read_net_ip6 + (struct stats_net_ip6 *); +__nr_t read_net_eip6 + (struct stats_net_eip6 *); +__nr_t read_net_icmp6 + (struct stats_net_icmp6 *); +__nr_t read_net_eicmp6 + (struct stats_net_eicmp6 *); +__nr_t read_net_udp6 + (struct stats_net_udp6 *); +__nr_t read_cpuinfo + (struct stats_pwr_cpufreq *, __nr_t); +__nr_t read_meminfo_huge + (struct stats_huge *); +__nr_t read_cpu_wghfreq + (struct stats_pwr_wghfreq *, __nr_t, __nr_t); +__nr_t read_bus_usb_dev + (struct stats_pwr_usb *, __nr_t); +__nr_t read_filesystem + (struct stats_filesystem *, __nr_t); +__nr_t read_fchost + (struct stats_fchost *, __nr_t); +int read_softnet + (struct stats_softnet *, __nr_t, unsigned char []); +#endif /* SOURCE_SADC */ + +#endif /* _RD_STATS_H */ diff --git a/tests/12.0.1/sa.h b/tests/12.0.1/sa.h new file mode 100644 index 0000000..78c9743 --- /dev/null +++ b/tests/12.0.1/sa.h @@ -0,0 +1,1386 @@ +/* + * sar/sadc: Report system activity + * (C) 1999-2018 by Sebastien Godard (sysstat orange.fr) + */ + +#ifndef _SA_H +#define _SA_H + +#include + +#include "common.h" +#include "rd_stats.h" +#include "rd_sensors.h" + +/* + *************************************************************************** + * Activity identification values. + *************************************************************************** + */ + +/* Number of activities */ +#define NR_ACT 39 +/* The value below is used for sanity check */ +#define MAX_NR_ACT 256 + +/* Number of functions used to count items */ +#define NR_F_COUNT 11 + +/* Activities */ +#define A_CPU 1 +#define A_PCSW 2 +#define A_IRQ 3 +#define A_SWAP 4 +#define A_PAGE 5 +#define A_IO 6 +#define A_MEMORY 7 +#define A_KTABLES 8 +#define A_QUEUE 9 +#define A_SERIAL 10 +#define A_DISK 11 +#define A_NET_DEV 12 +#define A_NET_EDEV 13 +#define A_NET_NFS 14 +#define A_NET_NFSD 15 +#define A_NET_SOCK 16 +#define A_NET_IP 17 +#define A_NET_EIP 18 +#define A_NET_ICMP 19 +#define A_NET_EICMP 20 +#define A_NET_TCP 21 +#define A_NET_ETCP 22 +#define A_NET_UDP 23 +#define A_NET_SOCK6 24 +#define A_NET_IP6 25 +#define A_NET_EIP6 26 +#define A_NET_ICMP6 27 +#define A_NET_EICMP6 28 +#define A_NET_UDP6 29 +#define A_PWR_CPU 30 +#define A_PWR_FAN 31 +#define A_PWR_TEMP 32 +#define A_PWR_IN 33 +#define A_HUGE 34 +#define A_PWR_FREQ 35 +#define A_PWR_USB 36 +#define A_FS 37 +#define A_NET_FC 38 +#define A_NET_SOFT 39 + + +/* Macro used to flag an activity that should be collected */ +#define COLLECT_ACTIVITY(m) act[get_activity_position(act, m, EXIT_IF_NOT_FOUND)]->options |= AO_COLLECTED + +/* Macro used to flag an activity that should be selected */ +#define SELECT_ACTIVITY(m) act[get_activity_position(act, m, EXIT_IF_NOT_FOUND)]->options |= AO_SELECTED + + +/* + *************************************************************************** + * Flags. + *************************************************************************** + */ + +#define S_F_SINCE_BOOT 0x00000001 +#define S_F_SA_ROTAT 0x00000002 +#define S_F_DEV_PRETTY 0x00000004 +#define S_F_FORCE_FILE 0x00000008 +#define S_F_INTERVAL_SET 0x00000010 +#define S_F_TRUE_TIME 0x00000020 +#define S_F_LOCK_FILE 0x00000040 +#define S_F_SEC_EPOCH 0x00000080 +#define S_F_HDR_ONLY 0x00000100 +#define S_F_FILE_LOCKED 0x00000200 +#define S_F_SA_YYYYMMDD 0x00000400 +#define S_F_HORIZONTALLY 0x00000800 +#define S_F_COMMENT 0x00001000 +#define S_F_PERSIST_NAME 0x00002000 +#define S_F_LOCAL_TIME 0x00004000 +#define S_F_PREFD_TIME_OUTPUT 0x00008000 +#define S_F_SVG_SKIP 0x00010000 +/* Same value as S_F_SVG_SKIP above. Used for a different output format */ +#define S_F_RAW_DEBUG_MODE 0x00010000 +#define S_F_SVG_AUTOSCALE 0x00020000 +#define S_F_SVG_ONE_DAY 0x00040000 +#define S_F_SVG_SHOW_IDLE 0x00080000 +#define S_F_UNIT 0x00100000 +#define S_F_SVG_HEIGHT 0x00200000 +#define S_F_SVG_PACKED 0x00400000 +#define S_F_SVG_SHOW_INFO 0x00800000 +#define S_F_HUMAN_READ 0x01000000 +#define S_F_ZERO_OMIT 0x02000000 +#define S_F_SVG_SHOW_TOC 0x04000000 + +#define WANT_SINCE_BOOT(m) (((m) & S_F_SINCE_BOOT) == S_F_SINCE_BOOT) +#define WANT_SA_ROTAT(m) (((m) & S_F_SA_ROTAT) == S_F_SA_ROTAT) +#define USE_PRETTY_OPTION(m) (((m) & S_F_DEV_PRETTY) == S_F_DEV_PRETTY) +#define FORCE_FILE(m) (((m) & S_F_FORCE_FILE) == S_F_FORCE_FILE) +#define INTERVAL_SET(m) (((m) & S_F_INTERVAL_SET) == S_F_INTERVAL_SET) +#define PRINT_TRUE_TIME(m) (((m) & S_F_TRUE_TIME) == S_F_TRUE_TIME) +#define LOCK_FILE(m) (((m) & S_F_LOCK_FILE) == S_F_LOCK_FILE) +#define PRINT_SEC_EPOCH(m) (((m) & S_F_SEC_EPOCH) == S_F_SEC_EPOCH) +#define DISPLAY_HDR_ONLY(m) (((m) & S_F_HDR_ONLY) == S_F_HDR_ONLY) +#define FILE_LOCKED(m) (((m) & S_F_FILE_LOCKED) == S_F_FILE_LOCKED) +#define USE_SA_YYYYMMDD(m) (((m) & S_F_SA_YYYYMMDD) == S_F_SA_YYYYMMDD) +#define DISPLAY_HORIZONTALLY(m) (((m) & S_F_HORIZONTALLY) == S_F_HORIZONTALLY) +#define DISPLAY_COMMENT(m) (((m) & S_F_COMMENT) == S_F_COMMENT) +#define DISPLAY_PERSIST_NAME_S(m) (((m) & S_F_PERSIST_NAME) == S_F_PERSIST_NAME) +#define PRINT_LOCAL_TIME(m) (((m) & S_F_LOCAL_TIME) == S_F_LOCAL_TIME) +#define USE_PREFD_TIME_OUTPUT(m) (((m) & S_F_PREFD_TIME_OUTPUT) == S_F_PREFD_TIME_OUTPUT) +#define SKIP_EMPTY_VIEWS(m) (((m) & S_F_SVG_SKIP) == S_F_SVG_SKIP) +#define DISPLAY_ZERO_OMIT(m) (((m) & S_F_ZERO_OMIT) == S_F_ZERO_OMIT) +#define DISPLAY_DEBUG_MODE(m) (((m) & S_F_RAW_DEBUG_MODE) == S_F_RAW_DEBUG_MODE) +#define AUTOSCALE_ON(m) (((m) & S_F_SVG_AUTOSCALE) == S_F_SVG_AUTOSCALE) +#define DISPLAY_ONE_DAY(m) (((m) & S_F_SVG_ONE_DAY) == S_F_SVG_ONE_DAY) +#define DISPLAY_IDLE(m) (((m) & S_F_SVG_SHOW_IDLE) == S_F_SVG_SHOW_IDLE) +#define DISPLAY_INFO(m) (((m) & S_F_SVG_SHOW_INFO) == S_F_SVG_SHOW_INFO) +#define DISPLAY_UNIT(m) (((m) & S_F_UNIT) == S_F_UNIT) +#define SET_CANVAS_HEIGHT(m) (((m) & S_F_SVG_HEIGHT) == S_F_SVG_HEIGHT) +#define PACK_VIEWS(m) (((m) & S_F_SVG_PACKED) == S_F_SVG_PACKED) +#define DISPLAY_HUMAN_READ(m) (((m) & S_F_HUMAN_READ) == S_F_HUMAN_READ) +#define DISPLAY_TOC(m) (((m) & S_F_SVG_SHOW_TOC) == S_F_SVG_SHOW_TOC) + +#define AO_F_NULL 0x00000000 + +/* Output flags for options -r / -S */ +#define AO_F_MEMORY 0x00000001 +#define AO_F_SWAP 0x00000002 +/* AO_F_MEM_ALL: See opt_flags in struct activity below */ +#define AO_F_MEM_ALL (AO_F_MEMORY << 8) + +#define DISPLAY_MEMORY(m) (((m) & AO_F_MEMORY) == AO_F_MEMORY) +#define DISPLAY_SWAP(m) (((m) & AO_F_SWAP) == AO_F_SWAP) +#define DISPLAY_MEM_ALL(m) (((m) & AO_F_MEM_ALL) == AO_F_MEM_ALL) + +/* Output flags for option -u [ ALL ] */ +#define AO_F_CPU_DEF 0x00000001 +#define AO_F_CPU_ALL 0x00000002 + +#define DISPLAY_CPU_DEF(m) (((m) & AO_F_CPU_DEF) == AO_F_CPU_DEF) +#define DISPLAY_CPU_ALL(m) (((m) & AO_F_CPU_ALL) == AO_F_CPU_ALL) + +/* Output flags for option -d */ +#define AO_F_DISK_PART 0x00000001 + +#define COLLECT_PARTITIONS(m) (((m) & AO_F_DISK_PART) == AO_F_DISK_PART) + +/* Output flags for option -F */ +#define AO_F_FILESYSTEM 0x00000001 +#define AO_F_MOUNT 0x00000002 + +#define DISPLAY_MOUNT(m) (((m) & AO_F_MOUNT) == AO_F_MOUNT) + +/* + *************************************************************************** + * Various keywords and constants. + *************************************************************************** + */ + +/* Keywords */ +#define K_A_NULL "A_NULL" +#define K_XALL "XALL" +#define K_SUM "SUM" +#define K_DEV "DEV" +#define K_EDEV "EDEV" +#define K_NFS "NFS" +#define K_NFSD "NFSD" +#define K_SOCK "SOCK" +#define K_IP "IP" +#define K_EIP "EIP" +#define K_ICMP "ICMP" +#define K_EICMP "EICMP" +#define K_TCP "TCP" +#define K_ETCP "ETCP" +#define K_UDP "UDP" +#define K_SOCK6 "SOCK6" +#define K_IP6 "IP6" +#define K_EIP6 "EIP6" +#define K_ICMP6 "ICMP6" +#define K_EICMP6 "EICMP6" +#define K_UDP6 "UDP6" +#define K_CPU "CPU" +#define K_FAN "FAN" +#define K_TEMP "TEMP" +#define K_IN "IN" +#define K_FREQ "FREQ" +#define K_MOUNT "MOUNT" +#define K_FC "FC" +#define K_SOFT "SOFT" + +#define K_INT "INT" +#define K_DISK "DISK" +#define K_XDISK "XDISK" +#define K_SNMP "SNMP" +#define K_IPV6 "IPV6" +#define K_POWER "POWER" +#define K_USB "USB" + +#define K_SKIP_EMPTY "skipempty" +#define K_AUTOSCALE "autoscale" +#define K_ONEDAY "oneday" +#define K_SHOWIDLE "showidle" +#define K_SHOWINFO "showinfo" +#define K_DEBUG "debug" +#define K_HEIGHT "height=" +#define K_PACKED "packed" +#define K_SHOWTOC "showtoc" + +/* Groups of activities */ +#define G_DEFAULT 0x00 +#define G_INT 0x01 +#define G_DISK 0x02 +#define G_SNMP 0x04 +#define G_IPV6 0x08 +#define G_POWER 0x10 +#define G_XDISK 0x20 + +/* sadc program */ +#define SADC "sadc" + +/* Time must have the format HH:MM:SS with HH in 24-hour format */ +#define DEF_TMSTART "08:00:00" +#define DEF_TMEND "18:00:00" + +#define UTSNAME_LEN 65 +#define HEADER_LINE_LEN 512 + +/* + * Define upper limit for various items. + * Made necessary because we have to check the number of + * items for each activity when we read a (possibly tainted) + * sa data file. + */ +#define MAX_NR_SERIAL_LINES 65536 +#define MAX_NR_DISKS (65536 * 4096) +#define MAX_NR_IFACES 65536 +#define MAX_NR_FANS 4096 +#define MAX_NR_TEMP_SENSORS 4096 +#define MAX_NR_IN_SENSORS 4096 +#define MAX_NR_USB 65536 +#define MAX_NR_FS (65536 * 4096) +#define MAX_NR_FCHOSTS 65536 + +/* NR_MAX is the upper limit used for unknown activities */ +#define NR_MAX (65536 * 4096) +#define NR2_MAX 1024 + +/* Maximum number of args that can be passed to sadc */ +#define MAX_ARGV_NR 32 + +/* Miscellaneous constants */ +#define USE_SADC 0 +#define USE_SA_FILE 1 +#define NO_TM_START 0 +#define NO_TM_END 0 +#define NO_RESET 0 +#define NON_FATAL 0 +#define FATAL 1 +#define C_SAR 0 +#define C_SADF 1 +#define ALL_ACTIVITIES ~0U +#define EXIT_IF_NOT_FOUND 1 +#define RESUME_IF_NOT_FOUND 0 + +#define SOFT_SIZE 0 +#define HARD_SIZE 1 + +#define FIRST 0 +#define SECOND 1 + +#define END_OF_DATA_UNEXPECTED 1 +#define INCONSISTENT_INPUT_DATA 2 + +#define CLOSE_XML_MARKUP 0 +#define OPEN_XML_MARKUP 1 + +#define CLOSE_JSON_MARKUP 0 +#define OPEN_JSON_MARKUP 1 + +#define COUNT_ACTIVITIES 0 +#define COUNT_OUTPUTS 1 + +/* Type for all functions reading statistics */ +#define __read_funct_t void +/* Type for all functions displaying statistics */ +#define __print_funct_t void + +/* Structure for SVG specific parameters */ +struct svg_parm { + unsigned long long dt; /* Interval of time for current sample */ + unsigned long long ust_time_ref; /* X axis start time in seconds since the epoch */ + unsigned long long ust_time_end; /* X axis end time in seconds since the epoch */ + unsigned long long ust_time_first; /* Time (in seconds since the epoch) for first sample */ + int graph_no; /* Total number of views already displayed */ + int restart; /* TRUE if we have just met a RESTART record */ + int nr_act_dispd; /* Number of activities that will be displayed */ + struct file_header *file_hdr; /* Pointer on file header structure */ +}; + +/* Structure used when displaying SVG header */ +struct svg_hdr_parm { + int graph_nr; /* Number of rows of views to display or canvas height entered on the command line */ + int views_per_row; /* Maximum number of views on a single row */ + int nr_act_dispd; /* Number of activities that will be displayed */ +}; + +/* + *************************************************************************** + * System activity data files + * + * The rule is: "strict writing, read any", meaning that sar/sadc can + * only append data to a datafile whose format is strictly the same as that + * of current version (checking FORMAT_MAGIC is not enough), but sar/sadf + * can read data from different versions, providing that FORMAT_MAGIC value + * has not changed (note that we are talking here of data read from a file, + * not data that sar reads from sadc, in which case the "strict" rule applies). + * + * Format of system activity data files: + * __ + * | + * | file_magic structure + * | + * |-- + * | + * | file_header structure + * | + * |-- --| + * | | + * | file_activity structure | * sa_act_nr + * | | + * |-- --| + * | | + * | record_header structure | + * | | + * |-- | + * |(__nr_t) | + * |-- | + * | | + * | Statistics structure(s) | * + * | | + * |-- | + * |(__nr_t) | + * |-- | + * | | + * | Statistics structure(s)... | + * | | + * |-- --| + * + * Note: For activities with varying number of items, a __nr_t value, giving + * the number of items, arrives before the statistics structures so that + * we know how many of them have to be read. + * NB: This value exists for all the activities even if they share the same + * count function (e.g. A_NET_DEV and A_NET_EDEV). Indeed, statistics are not + * read atomically and the number of items (e.g. network interfaces) may have + * varied in between. + * + * If the record header's type is R_COMMENT then we find only a comment + * following the record_header structure. + * If the record_header's type is R_RESTART then we find only the number of CPU + * (of type __nr_t) of the machine following the record_header structure. + *************************************************************************** + */ + +/* + * Sysstat magic number. Should never be modified. + * Indicate that the file was created by sysstat. + */ +#define SYSSTAT_MAGIC 0xd596 +#define SYSSTAT_MAGIC_SWAPPED (((SYSSTAT_MAGIC << 8) | (SYSSTAT_MAGIC >> 8)) & 0xffff) + +/* + * Datafile format magic number. + * Modified to indicate that the format of the file is + * no longer compatible with that of previous sysstat versions. + */ +#define FORMAT_MAGIC 0x2175 +#define FORMAT_MAGIC_SWAPPED (((FORMAT_MAGIC << 8) | (FORMAT_MAGIC >> 8)) & 0xffff) + +/* Previous datafile format magic numbers used by older sysstat versions */ +#define FORMAT_MAGIC_2171 0x2171 +#define FORMAT_MAGIC_2171_SWAPPED (((FORMAT_MAGIC_2171 << 8) | (FORMAT_MAGIC_2171 >> 8)) & 0xffff) +#define FORMAT_MAGIC_2173 0x2173 +#define FORMAT_MAGIC_2173_SWAPPED (((FORMAT_MAGIC_2173 << 8) | (FORMAT_MAGIC_2173 >> 8)) & 0xffff) + +/* Padding in file_magic structure. See below. */ +#define FILE_MAGIC_PADDING 48 + +/* Structure for file magic header data */ +struct file_magic { + /* + * This field identifies the file as a file created by sysstat. + */ + unsigned short sysstat_magic; + /* + * The value of this field varies whenever datafile format changes. + */ + unsigned short format_magic; + /* + * Sysstat version used to create the file. + */ + unsigned char sysstat_version; + unsigned char sysstat_patchlevel; + unsigned char sysstat_sublevel; + unsigned char sysstat_extraversion; +#define FILE_MAGIC_ULL_NR 0 /* Nr of unsigned long long below */ +#define FILE_MAGIC_UL_NR 0 /* Nr of unsigned long below */ +#define FILE_MAGIC_U_NR 5 /* Nr of [unsigned] int below */ + /* + * Size of file's header (size of file_header structure used by file). + */ + unsigned int header_size; + /* + * Set to non zero if data file has been converted with "sadf -c" from + * an old format (version x.y.z) to a newest format (version X.Y.Z). + * In this case, the value is: Y*256 + Z + 1. + * The FORMAT_MAGIC value of the file can be used to determine X. + */ + unsigned int upgraded; + /* + * Description of the file_header structure + * (nr of "long long", nr of "long" and nr of "int"). + */ + unsigned int hdr_types_nr[3]; + /* + * Padding. Reserved for future use while avoiding a format change. + * sysstat always reads a number of bytes which is that expected for + * current sysstat version (FILE_MAGIC_SIZE). We cannot guess if we + * are going to read a file from current, an older or a newer version. + */ + unsigned char pad[FILE_MAGIC_PADDING]; +}; + +#define FILE_MAGIC_SIZE (sizeof(struct file_magic)) + +/* Header structure for system activity data file */ +struct file_header { + /* + * Timestamp in seconds since the epoch. + */ + unsigned long long sa_ust_time; + /* + * Number of jiffies per second. + */ + unsigned long sa_hz __attribute__ ((aligned (8))); + /* + * Number of [online or offline] CPU (1 .. CPU_NR + 1) + * when the datafile has been created. + * When reading a datafile, this value is updated (in memory) + * whenever a RESTART record is found. + * When writing or appending data to a file, this field is updated + * neither in file nor in memory. + */ + unsigned int sa_cpu_nr __attribute__ ((aligned (8))); + /* + * Number of activities saved in file. + */ + unsigned int sa_act_nr; + /* + * Current year. + */ + int sa_year; + /* + * Description of the file_activity and record_header structures + * (nr of "long long", nr of "long" and nr of "int"). + */ + unsigned int act_types_nr[3]; + unsigned int rec_types_nr[3]; + /* + * Size of file_activity and record_header structures used by file. + */ + unsigned int act_size; + unsigned int rec_size; + /* + * Current day and month. + * No need to save DST (Daylight Saving Time) flag, since it is not taken + * into account by the strftime() function used to print the timestamp. + */ + unsigned char sa_day; + unsigned char sa_month; + /* + * Size of a long integer. Useful to know the architecture on which + * the datafile was created. + */ + char sa_sizeof_long; + /* + * Operating system name. + */ + char sa_sysname[UTSNAME_LEN]; + /* + * Machine hostname. + */ + char sa_nodename[UTSNAME_LEN]; + /* + * Operating system release number. + */ + char sa_release[UTSNAME_LEN]; + /* + * Machine architecture. + */ + char sa_machine[UTSNAME_LEN]; +}; + +#define FILE_HEADER_SIZE (sizeof(struct file_header)) +#define FILE_HEADER_ULL_NR 1 /* Nr of unsigned long long in file_header structure */ +#define FILE_HEADER_UL_NR 1 /* Nr of unsigned long in file_header structure */ +#define FILE_HEADER_U_NR 11 /* Nr of [unsigned] int in file_header structure */ +/* The values below are used for sanity check */ +#define MIN_FILE_HEADER_SIZE 0 +#define MAX_FILE_HEADER_SIZE 8192 + + +/* + * Base magical number for activities. + */ +#define ACTIVITY_MAGIC_BASE 0x8a +/* + * Magical value used for activities with + * unknown format (used for sadf -H only). + */ +#define ACTIVITY_MAGIC_UNKNOWN 0x89 + +/* List of activities saved in file */ +struct file_activity { + /* + * Identification value of activity. + */ + unsigned int id; + /* + * Activity magical number. + */ + unsigned int magic; + /* + * Number of items for this activity + * when the data file has been created. + */ + __nr_t nr; + /* + * Number of sub-items for this activity. + */ + __nr_t nr2; + /* + * Set to TRUE if statistics are preceded by + * a value giving the number of structures to read. + */ + int has_nr; + /* + * Size of an item structure. + */ + int size; + /* + * Description of the structure containing statistics for the + * given activity (nr of "long long", nr of "long" and nr of "int"). + */ + unsigned int types_nr[3]; +}; + +#define FILE_ACTIVITY_SIZE (sizeof(struct file_activity)) +#define MAX_FILE_ACTIVITY_SIZE 1024 /* Used for sanity check */ +#define FILE_ACTIVITY_ULL_NR 0 /* Nr of unsigned long long in file_activity structure */ +#define FILE_ACTIVITY_UL_NR 0 /* Nr of unsigned long in file_activity structure */ +#define FILE_ACTIVITY_U_NR 9 /* Nr of [unsigned] int in file_activity structure */ + + +/* Record type */ +/* + * R_STATS means that this is a record of statistics. + */ +#define R_STATS 1 +/* + * R_RESTART means that this is a special record containing + * a LINUX RESTART message. + */ +#define R_RESTART 2 +/* + * R_LAST_STATS warns sar that this is the last record to be written + * to file before a file rotation, and that the next data to come will + * be a header file. + * Such a record is tagged R_STATS anyway before being written to file. + */ +#define R_LAST_STATS 3 +/* + * R_COMMENT means that this is a special record containing + * a comment. + */ +#define R_COMMENT 4 + +/* Maximum length of a comment */ +#define MAX_COMMENT_LEN 64 + +/* Header structure for every record */ +struct record_header { + /* + * Machine uptime in 1/100th of a second. + */ + unsigned long long uptime_cs; + /* + * Timestamp (number of seconds since the epoch). + */ + unsigned long long ust_time; + /* + * Record type: R_STATS, R_RESTART,... + */ + unsigned char record_type; + /* + * Timestamp: Hour (0-23), minute (0-59) and second (0-59). + * Used to determine TRUE time (immutable, non locale dependent time). + */ + unsigned char hour; + unsigned char minute; + unsigned char second; +}; + +#define RECORD_HEADER_SIZE (sizeof(struct record_header)) +#define MAX_RECORD_HEADER_SIZE 512 /* Used for sanity check */ +#define RECORD_HEADER_ULL_NR 2 /* Nr of unsigned long long in record_header structure */ +#define RECORD_HEADER_UL_NR 0 /* Nr of unsigned long in record_header structure */ +#define RECORD_HEADER_U_NR 0 /* Nr of unsigned int in record_header structure */ + + +/* + *************************************************************************** + * Generic description of an activity. + *************************************************************************** + */ + +/* Activity options */ +#define AO_NULL 0x00 +/* + * Indicate that corresponding activity should be collected by sadc. + */ +#define AO_COLLECTED 0x01 +/* + * Indicate that corresponding activity should be displayed by sar. + */ +#define AO_SELECTED 0x02 +/* + * Indicate that corresponding activity has items that need to be counted. + * This means that its @f_count_index values is >= 0. + * (We use AO_COUNTED instead of @f_count_index because @f_count_index + * is available (initialized) only for sadc). + */ +#define AO_COUNTED 0x04 +/* + * Indicate that activity's metrics have persistent values when devices + * are registered again (this means that when the device is registered again, + * the metrics pick the values they had when they had been unregistered). + * Exclusively used for CPU related statistics at the present time. + */ +#define AO_PERSISTENT 0x08 +/* + * This flag should be set for every activity closing a markup used + * by several activities. Used by sadf f_xml_print() functions to + * display XML output. + */ +#define AO_CLOSE_MARKUP 0x10 +/* + * Indicate that corresponding activity has multiple different + * output formats. This is the case for example for memory activity + * with options -r and -R. + * PS: Such an activity should appear in the list of activities that + * sar -A is supposed to display. + */ +#define AO_MULTIPLE_OUTPUTS 0x20 +/* + * Indicate that one (SVG) graph will be displayed for each + * distinct item for this activity (sadf -g). + */ +#define AO_GRAPH_PER_ITEM 0x40 +/* + * Indicate that this activity may have sub-items. + */ +#define AO_MATRIX 0x80 +/* + * Indicate that a list of devices has been entered on the command + * line for this activity (see options --dev=, --iface=, ...) + */ +#define AO_LIST_ON_CMDLINE 0x100 + +#define IS_COLLECTED(m) (((m) & AO_COLLECTED) == AO_COLLECTED) +#define IS_SELECTED(m) (((m) & AO_SELECTED) == AO_SELECTED) +#define HAS_COUNT_FUNCTION(m) (((m) & AO_COUNTED) == AO_COUNTED) +#define HAS_PERSISTENT_VALUES(m) (((m) & AO_PERSISTENT) == AO_PERSISTENT) +#define CLOSE_MARKUP(m) (((m) & AO_CLOSE_MARKUP) == AO_CLOSE_MARKUP) +#define HAS_MULTIPLE_OUTPUTS(m) (((m) & AO_MULTIPLE_OUTPUTS) == AO_MULTIPLE_OUTPUTS) +#define ONE_GRAPH_PER_ITEM(m) (((m) & AO_GRAPH_PER_ITEM) == AO_GRAPH_PER_ITEM) +#define IS_MATRIX(m) (((m) & AO_MATRIX) == AO_MATRIX) +#define HAS_LIST_ON_CMDLINE(m) (((m) & AO_LIST_ON_CMDLINE) == AO_LIST_ON_CMDLINE) + +#define _buf0 buf[0] +#define _nr0 nr[0] + +/* Structure used to define a bitmap needed by an activity */ +struct act_bitmap { + /* + * Bitmap for activities that need one. Remember to allocate it + * before use! + */ + unsigned char *b_array; + /* + * Size of the bitmap in bits. In fact, bitmap is sized to b_size + 1 + * to take into account CPU "all" + */ + int b_size; +}; + +/* + * Structure used to define an activity. + * Note: This structure can be modified without changing the format of data files. + */ +struct activity { + /* + * This variable contains the identification value (A_...) for this activity. + */ + unsigned int id; + /* + * Activity options (AO_...) + */ + unsigned int options; + /* + * Activity magical number. This number changes when activity format in file + * is no longer compatible with the format of that same activity from + * previous versions. + */ + unsigned int magic; + /* + * An activity belongs to a group (and only one). + * Groups are those selected with option -S of sadc. + */ + unsigned int group; + /* + * Index in f_count[] array to determine function used to count + * the number of items (serial lines, network interfaces, etc.) -> @nr + * Such a function should _always_ return a value greater than + * or equal to 0. + * + * A value of -1 indicates that the number of items + * is a constant (and @nr is set to this value). + * + * These functions are called even if corresponding activities have not + * been selected, to make sure that all items have been calculated + * (including #CPU, etc.) + */ + int f_count_index; + /* + * The f_count2() function is used to count the number of + * sub-items -> @nr2 + * Such a function should _always_ return a value greater than + * or equal to 0. + * + * A NULL value for this function pointer indicates that the number of items + * is a constant (and @nr2 is set to this value). + */ + __nr_t (*f_count2) (struct activity *); + /* + * This function reads the relevant file and fill the buffer + * with statistics corresponding to given activity. + */ + __read_funct_t (*f_read) (struct activity *); + /* + * This function displays activity statistics onto the screen. + */ + __print_funct_t (*f_print) (struct activity *, int, int, unsigned long long); + /* + * This function displays average activity statistics onto the screen. + */ + __print_funct_t (*f_print_avg) (struct activity *, int, int, unsigned long long); + /* + * This function is used by sadf to display activity in a format that can + * easily be ingested by a relational database, or a format that can be + * handled by pattern processing commands like "awk". + */ + __print_funct_t (*f_render) (struct activity *, int, char *, int, unsigned long long); + /* + * This function is used by sadf to display activity statistics in XML. + */ + __print_funct_t (*f_xml_print) (struct activity *, int, int, unsigned long long); + /* + * This function is used by sadf to display activity statistics in JSON. + */ + __print_funct_t (*f_json_print) (struct activity *, int, int, unsigned long long); + /* + * This function is used by sadf to display activity statistics in SVG. + */ + __print_funct_t (*f_svg_print) (struct activity *, int, int, struct svg_parm *, + unsigned long long, struct record_header *); + /* + * This function is used by sadf to display activity statistics in raw format. + */ + __print_funct_t (*f_raw_print) (struct activity *, char *, int); + /* + * This function is used by sadf to count the number of new items in current + * sample and add them to the linked list @item_list. + */ + __nr_t (*f_count_new) (struct activity *, int); + /* + * Linked list containing item names. This is either all the different items + * found in a file for activities that have a @f_count_function() (used by sadf), + * or a list entered on the command line (used by sadf and sar). + */ + struct sa_item *item_list; + /* + * Number of different items found in file (calculated by sadf). + * This is also the number of items in @item_list if this list exists. + */ + __nr_t item_list_sz; + /* + * Header string displayed by sadf -d. + * Header lines for each output (for activities with multiple outputs) are + * separated with a '|' character. + * For a given output, the first field corresponding to extended statistics + * (eg. -r ALL) begins with a '&' character. + */ + char *hdr_line; + /* + * Description of activity. + */ + char *desc; + /* + * Name of activity. + */ + char *name; + /* + * Description of the corresponding structure containing statistics (as defined + * in rd_stats.h or rd_sensors.h). Such a structure has 0+ fields of type + * "long long", followed by 0+ fields of type "long", followed by 0+ fields of + * type "int", followed by 0+ other fields (e.g. of type char). The array below + * gives the number of "long long" fields composing the structure, then the number + * of "long" fields, then the number of "int" fields. + */ + unsigned int gtypes_nr[3]; + /* + * This array has the same meaning as @gtypes_nr[] above, but the values are those + * read from current data file. They may be different from those of @gtypes_nr[] + * because we can read data from a different sysstat version (older or newer). + */ + unsigned int ftypes_nr[3]; + /* + * Number of SVG graphs for this activity. The total number of graphs for + * the activity can be greater though if flag AO_GRAPH_PER_ITEM is set, in + * which case the total number will be @g_nr * @nr. + */ + int g_nr; + /* + * Number of items on the system, as counted when the system is initialized. + * A negative value (-1) is the default value and indicates that this number + * has still not been calculated by the f_count() function. + * A value of 0 means that this number has been calculated, but no items have + * been found. + * A positive value (>0) has either been calculated or is a constant. + */ + __nr_t nr_ini; + /* + * Number of sub-items on the system. + * @nr2 is in fact the second dimension of a matrix of items, the first + * one being @nr. @nr is the number of lines, and @nr2 the number of columns. + * A negative value (-1) is the default value and indicates that this number + * has still not been calculated by the f_count2() function. + * A value of 0 means that this number has been calculated, but no sub-items have + * been found. + * A positive value (>0) has either been calculated or is a constant. + * Rules: + * 1) IF @nr2 = 0 THEN @nr = 0 + * Note: If @nr = 0, then @nr2 is undetermined (may be -1, 0 or >0). + * 2) IF @nr > 0 THEN @nr2 > 0. + * Note: If @nr2 > 0 then @nr is undetermined (may be -1, 0 or >0). + * 3) IF @nr <= 0 THEN @nr2 = -1 (this is the default value for @nr2, + * meaning that it has not been calculated). + */ + __nr_t nr2; + /* + * Maximum number of elements that sar can handle for this item. + * NB: The maximum number of elements that sar can handle for sub-items + * is NR2_MAX. + */ + __nr_t nr_max; + /* + * Number of items, as read and saved in corresponding buffer (@buf: See below). + * The value may be zero for a particular sample if no items have been found. + */ + __nr_t nr[3]; + /* + * Number of structures allocated in @buf[*]. This number should be greater + * than or equal to @nr[*]. + */ + __nr_t nr_allocated; + /* + * Size of an item. + * This is the size of the corresponding structure, as read from or written + * to a file, or read from or written by the data collector. + */ + int fsize; + /* + * Size of an item. + * This is the size of the corresponding structure as mapped into memory. + * @msize can be different from @fsize when data are read from or written to + * a data file from a different sysstat version. + */ + int msize; + /* + * Optional flags for activity. This is eg. used when AO_MULTIPLE_OUTPUTS + * option is set. + * 0x0001 - 0x0080 : Multiple outputs (eg. AO_F_MEMORY, AO_F_SWAP...) + * 0x0100 - 0x8000 : If bit set then display complete header (hdr_line) for + * corresponding output + * 0x010000+ : Optional flags + */ + unsigned int opt_flags; + /* + * Buffers that will contain the statistics read. Its size is @nr * @nr2 * @size each. + * [0]: used by sadc. + * [0] and [1]: current/previous statistics values (used by sar). + * [2]: Used by sar to save first collected stats (used later to + * compute average). + */ + void *buf[3]; + /* + * Bitmap for activities that need one. Such a bitmap is needed by activity + * if @bitmap is not NULL. + */ + struct act_bitmap *bitmap; +}; + + +/* + *************************************************************************** + * Generic description of an output format for sadf (and sar). + *************************************************************************** + */ + +/* Type for all functions used by sadf to display stats in various formats */ +#define __printf_funct_t void +#define __tm_funct_t char * + +/* + * Structure used to define a report. + * A XML-like report has the following format: + * __ + * | + * | Header block + * | __ + * | | + * | | Statistics block + * | | __ + * | | | + * | | | Timestamp block + * | | | __ + * | | | | + * | | | | Activity #1 + * | | | |__ + * | | | | + * | | | | ... + * | | | |__ + * | | | | + * | | | | Activity #n + * | | | |__ + * | | |__ + * | |__ + * | | + * | | Restart messages block + * | |__ + * | | + * | | Comments block + * | |__ + * |__ + */ +struct report_format { + /* + * This variable contains the identification value (F_...) for this report format. + */ + unsigned int id; + /* + * Format options (FO_...). + */ + unsigned int options; + /* + * This function displays the report header + * (data displayed once at the beginning of the report). + */ + __printf_funct_t (*f_header) (void *, int, char *, struct file_magic *, struct file_header *, + struct activity * [], unsigned int [], struct file_activity *); + /* + * This function defines the statistics part of the report. + * Used only with textual (XML-like) reports. + */ + __printf_funct_t (*f_statistics) (int *, int); + /* + * This function defines the timestamp part of the report. + * Used only with textual (XML-like) reports. + */ + __tm_funct_t (*f_timestamp) (void *, int, char *, char *, unsigned long long, + struct file_header *, unsigned int); + /* + * This function displays the restart messages. + */ + __printf_funct_t (*f_restart) (int *, int, char *, char *, int, struct file_header *); + /* + * This function displays the comments. + */ + __printf_funct_t (*f_comment) (int *, int, char *, char *, int, char *, struct file_header *); +}; + +/* Possible actions for functions used to display reports */ +#define F_BEGIN 0x01 +#define F_MAIN 0x02 +#define F_END 0x04 + +/* + *************************************************************************** + * SVG output definitions + *************************************************************************** + */ + +/* + * ^ + * 1 | General header + * v + * ^ + * 9 | One line from table of contents (if any) + * v + * ^ ^ ^ + * | | 4 | Graph title + * | | v + * | | ^ | Caption + * | 3 | | | + * | | | G |Y + * 2 | | 5 | r | + * | | | a |A + * | | | d |x + * | | | . |i + * | | | |s X Axis + * | | v |------------------------------- + * | | Grad. + * | v <---><------------------------------> + * | 6 8 + * | Gap + * v<---------------------------------------------------------------> Gap + * 7 + * <---------------------------------------------------------------------> + * 8 + */ + +/* #8 */ +#define SVG_G_XSIZE 720 +/* #6 */ +#define SVG_M_XSIZE 70 +/* #7 */ +#define SVG_V_XSIZE 1050 +/* #8 */ +#define SVG_T_XSIZE 1060 + +/* #5 */ +#define SVG_G_YSIZE 200 +/* #1 */ +#define SVG_H_YSIZE 60 +/* #4 */ +#define SVG_M_YSIZE 50 +/* #2 */ +#define SVG_T_YSIZE 310 +/* #3 */ +#define SVG_V_YSIZE 300 +/* #9 */ +#define SVG_C_YSIZE 20 + +/* Grid: Nr of horizontal lines */ +#define SVG_H_GRIDNR 3 +/* Grid: Nr of vertical lines */ +#define SVG_V_GRIDNR 10 + +/* Block size used to allocate arrays for graphs data */ +#define CHUNKSIZE 4096 + +/* Maximum number of views on a single row */ +#define MAX_VIEWS_ON_A_ROW 6 + +#define SVG_LINE_GRAPH 1 +#define SVG_BAR_GRAPH 2 + +/* Maximum number of horizontal lines for the background grid */ +#define MAX_HLINES_NR 10 + +#define MAYBE 0x80 + +/* + *************************************************************************** + * Macro functions definitions. + * + * Note: Using 'do ... while' makes the macros safer to use + * (remember that macro use is followed by a semicolon). + *************************************************************************** + */ + +/* Close file descriptors */ +#define CLOSE_ALL(_fd_) do { \ + close(_fd_[0]); \ + close(_fd_[1]); \ + } while (0) + +#define CLOSE(_fd_) if (_fd_ >= 0) \ + close(_fd_) + + +/* + *************************************************************************** + * Various structure definitions. + *************************************************************************** + */ + +/* Structure for timestamps */ +struct tstamp { + int tm_sec; + int tm_min; + int tm_hour; + int use; +}; + +/* Structure for items in list */ +struct sa_item { + char *item_name; + struct sa_item *next; +}; + + +/* + *************************************************************************** + * Functions prototypes. + *************************************************************************** + */ + +/* + * Prototypes used to count new items + */ +__nr_t count_new_net_dev + (struct activity *, int); +__nr_t count_new_net_edev + (struct activity *, int); +__nr_t count_new_filesystem + (struct activity *, int); +__nr_t count_new_fchost + (struct activity *, int); +__nr_t count_new_disk + (struct activity *, int); + +/* Functions used to count number of items */ +__nr_t wrap_get_cpu_nr + (struct activity *); +__nr_t wrap_get_irq_nr + (struct activity *); +__nr_t wrap_get_serial_nr + (struct activity *); +__nr_t wrap_get_disk_nr + (struct activity *); +__nr_t wrap_get_iface_nr + (struct activity *); +__nr_t wrap_get_fan_nr + (struct activity *); +__nr_t wrap_get_temp_nr + (struct activity *); +__nr_t wrap_get_in_nr + (struct activity *); +__nr_t wrap_get_freq_nr + (struct activity *); +__nr_t wrap_get_usb_nr + (struct activity *); +__nr_t wrap_get_filesystem_nr + (struct activity *); +__nr_t wrap_get_fchost_nr + (struct activity *); + +/* Functions used to read activities statistics */ +__read_funct_t wrap_read_stat_cpu + (struct activity *); +__read_funct_t wrap_read_stat_pcsw + (struct activity *); +__read_funct_t wrap_read_stat_irq + (struct activity *); +__read_funct_t wrap_read_swap + (struct activity *); +__read_funct_t wrap_read_paging + (struct activity *); +__read_funct_t wrap_read_io + (struct activity *); +__read_funct_t wrap_read_meminfo + (struct activity *); +__read_funct_t wrap_read_kernel_tables + (struct activity *); +__read_funct_t wrap_read_loadavg + (struct activity *); +__read_funct_t wrap_read_tty_driver_serial + (struct activity *); +__read_funct_t wrap_read_disk + (struct activity *); +__read_funct_t wrap_read_net_dev + (struct activity *); +__read_funct_t wrap_read_net_edev + (struct activity *); +__read_funct_t wrap_read_net_nfs + (struct activity *); +__read_funct_t wrap_read_net_nfsd + (struct activity *); +__read_funct_t wrap_read_net_sock + (struct activity *); +__read_funct_t wrap_read_net_ip + (struct activity *); +__read_funct_t wrap_read_net_eip + (struct activity *); +__read_funct_t wrap_read_net_icmp + (struct activity *); +__read_funct_t wrap_read_net_eicmp + (struct activity *); +__read_funct_t wrap_read_net_tcp + (struct activity *); +__read_funct_t wrap_read_net_etcp + (struct activity *); +__read_funct_t wrap_read_net_udp + (struct activity *); +__read_funct_t wrap_read_net_sock6 + (struct activity *); +__read_funct_t wrap_read_net_ip6 + (struct activity *); +__read_funct_t wrap_read_net_eip6 + (struct activity *); +__read_funct_t wrap_read_net_icmp6 + (struct activity *); +__read_funct_t wrap_read_net_eicmp6 + (struct activity *); +__read_funct_t wrap_read_net_udp6 + (struct activity *); +__read_funct_t wrap_read_cpuinfo + (struct activity *); +__read_funct_t wrap_read_fan + (struct activity *); +__read_funct_t wrap_read_temp + (struct activity *); +__read_funct_t wrap_read_in + (struct activity *); +__read_funct_t wrap_read_meminfo_huge + (struct activity *); +__read_funct_t wrap_read_cpu_wghfreq + (struct activity *); +__read_funct_t wrap_read_bus_usb_dev + (struct activity *); +__read_funct_t wrap_read_filesystem + (struct activity *); +__read_funct_t wrap_read_fchost + (struct activity *); +__read_funct_t wrap_read_softnet + (struct activity *); + +/* Other functions */ +int check_alt_sa_dir + (char *, int, int); +void enum_version_nr + (struct file_magic *); +int get_activity_nr + (struct activity * [], unsigned int, int); +int get_activity_position + (struct activity * [], unsigned int, int); +void handle_invalid_sa_file + (int, struct file_magic *, char *, int); +void print_collect_error + (void); +int set_default_file + (char *, int, int); +int write_all + (int, const void *, int); + +#ifndef SOURCE_SADC +int add_list_item + (struct sa_item **, char *, int); +void allocate_bitmaps + (struct activity * []); +void allocate_structures + (struct activity * []); +int check_disk_reg + (struct activity *, int, int, int); +void check_file_actlst + (int *, char *, struct activity * [], struct file_magic *, struct file_header *, + struct file_activity **, unsigned int [], int, int *, int *); +int check_net_dev_reg + (struct activity *, int, int, int); +int check_net_edev_reg + (struct activity *, int, int, int); +double compute_ifutil + (struct stats_net_dev *, double, double); +void copy_structures + (struct activity * [], unsigned int [], struct record_header [], int, int); +int datecmp + (struct tm *, struct tstamp *); +void display_sa_file_version + (FILE *, struct file_magic *); +void free_bitmaps + (struct activity * []); +void free_structures + (struct activity * []); +char *get_devname + (unsigned int, unsigned int, int); +char *get_sa_devname + (unsigned int, unsigned int, unsigned int); +void get_file_timestamp_struct + (unsigned int, struct tm *, struct file_header *); +unsigned long long get_global_cpu_statistics + (struct activity *, int, int, unsigned int, unsigned char []); +void get_global_soft_statistics + (struct activity *, int, int, unsigned int, unsigned char []); +void get_itv_value + (struct record_header *, struct record_header *, unsigned long long *); +int next_slice + (unsigned long long, unsigned long long, int, long); +void parse_sa_devices + (char *, struct activity *, int, int *, int); +int parse_sar_opt + (char * [], int *, struct activity * [], unsigned int *, int); +int parse_sar_I_opt + (char * [], int *, struct activity * []); +int parse_sa_P_opt + (char * [], int *, unsigned int *, struct activity * []); +int parse_sar_m_opt + (char * [], int *, struct activity * []); +int parse_sar_n_opt + (char * [], int *, struct activity * []); +int parse_timestamp + (char * [], int *, struct tstamp *, const char *); +void print_report_hdr + (unsigned int, struct tm *, struct file_header *); +void print_sar_comment + (int *, int, char *, char *, int, char *, struct file_header *); +__printf_funct_t print_sar_restart + (int *, int, char *, char *, int, struct file_header *); +int print_special_record + (struct record_header *, unsigned int, struct tstamp *, struct tstamp *, + int, int, struct tm *, struct tm *, char *, int, struct file_magic *, + struct file_header *, struct activity * [], struct report_format *, int, int); +void read_file_stat_bunch + (struct activity * [], int, int, int, struct file_activity *, int, int, + char *, struct file_magic *); +__nr_t read_nr_value + (int, char *, struct file_magic *, int, int, int); +int read_record_hdr + (int, void *, struct record_header *, struct file_header *, int, int); +void reallocate_all_buffers + (struct activity *, __nr_t); +void remap_struct + (unsigned int [], unsigned int [], void *, unsigned int); +void replace_nonprintable_char + (int, char *); +int sa_fread + (int, void *, size_t, int); +int sa_get_record_timestamp_struct + (unsigned int, struct record_header *, struct tm *, struct tm *); +int sa_open_read_magic + (int *, char *, struct file_magic *, int, int *, int); +int search_list_item + (struct sa_item *, char *); +void select_all_activities + (struct activity * []); +void select_default_activity + (struct activity * []); +void set_bitmap + (unsigned char [], unsigned char, unsigned int); +void set_hdr_rectime + (unsigned int, struct tm *, struct file_header *); +void set_record_timestamp_string + (unsigned int, struct record_header *, char *, char *, int, struct tm *); +void swap_struct + (unsigned int [], void *, int); +#endif /* SOURCE_SADC undefined */ +#endif /* _SA_H */ diff --git a/tests/12.0.1/sa_common.c b/tests/12.0.1/sa_common.c new file mode 100644 index 0000000..1b7389d --- /dev/null +++ b/tests/12.0.1/sa_common.c @@ -0,0 +1,3094 @@ +/* + * sar and sadf common routines. + * (C) 1999-2018 by Sebastien GODARD (sysstat orange.fr) + * + *************************************************************************** + * This program 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. * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without 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 this program; if not, write to the Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA * + *************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include /* For STDOUT_FILENO, among others */ +#include +#include +#include +#include +#include +#include + +#include "version.h" +#include "sa.h" +#include "ioconf.h" + +#ifdef USE_NLS +#include +#include +#define _(string) gettext(string) +#else +#define _(string) (string) +#endif + +int default_file_used = FALSE; +extern struct act_bitmap cpu_bitmap; +extern unsigned int dm_major; + +unsigned int hdr_types_nr[] = {FILE_HEADER_ULL_NR, FILE_HEADER_UL_NR, FILE_HEADER_U_NR}; +unsigned int act_types_nr[] = {FILE_ACTIVITY_ULL_NR, FILE_ACTIVITY_UL_NR, FILE_ACTIVITY_U_NR}; +unsigned int rec_types_nr[] = {RECORD_HEADER_ULL_NR, RECORD_HEADER_UL_NR, RECORD_HEADER_U_NR}; +unsigned int nr_types_nr[] = {0, 0, 1}; + +/* + *************************************************************************** + * Look for activity in array. + * + * IN: + * @act Array of activities. + * @act_flag Activity flag to look for. + * @stop TRUE if sysstat should exit when activity is not found. + * + * RETURNS: + * Position of activity in array, or -1 if not found (this may happen when + * reading data from a system activity file created by another version of + * sysstat). + *************************************************************************** + */ +int get_activity_position(struct activity *act[], unsigned int act_flag, int stop) +{ + int i; + + for (i = 0; i < NR_ACT; i++) { + if (act[i]->id == act_flag) + return i; + } + + if (stop) { + PANIC((int) act_flag); + } + + return -1; +} + +/* + *************************************************************************** + * Count number of activities with given option. + * + * IN: + * @act Array of activities. + * @option Option that activities should have to be counted + * (eg. AO_COLLECTED...) + * @count_outputs TRUE if each output should be counted for activities with + * multiple outputs. + * + * RETURNS: + * Number of selected activities + *************************************************************************** + */ +int get_activity_nr(struct activity *act[], unsigned int option, int count_outputs) +{ + int i, n = 0; + unsigned int msk; + + for (i = 0; i < NR_ACT; i++) { + if ((act[i]->options & option) == option) { + + if (HAS_MULTIPLE_OUTPUTS(act[i]->options) && count_outputs) { + for (msk = 1; msk < 0x100; msk <<= 1) { + if ((act[i]->opt_flags & 0xff) & msk) { + n++; + } + } + } + else { + n++; + } + } + } + + return n; +} + +/* + *************************************************************************** + * Look for the most recent of saDD and saYYYYMMDD to decide which one to + * use. If neither exists then use saDD by default. + * + * IN: + * @sa_dir Directory where standard daily data files are saved. + * @rectime Structure containing the current date. + * + * OUT: + * @sa_name 0 to use saDD data files, + * 1 to use saYYYYMMDD data files. + *************************************************************************** + */ +void guess_sa_name(char *sa_dir, struct tm *rectime, int *sa_name) +{ + char filename[MAX_FILE_LEN]; + struct stat sb; + time_t sa_mtime; + + /* Use saDD by default */ + *sa_name = 0; + + /* Look for saYYYYMMDD */ + snprintf(filename, MAX_FILE_LEN, + "%s/sa%04d%02d%02d", sa_dir, + rectime->tm_year + 1900, + rectime->tm_mon + 1, + rectime->tm_mday); + filename[MAX_FILE_LEN - 1] = '\0'; + + if (stat(filename, &sb) < 0) + /* Cannot find or access saYYYYMMDD, so use saDD */ + return; + sa_mtime = sb.st_mtime; + + /* Look for saDD */ + snprintf(filename, MAX_FILE_LEN, + "%s/sa%02d", sa_dir, + rectime->tm_mday); + filename[MAX_FILE_LEN - 1] = '\0'; + + if (stat(filename, &sb) < 0) { + /* Cannot find or access saDD, so use saYYYYMMDD */ + *sa_name = 1; + return; + } + + if (sa_mtime > sb.st_mtime) { + /* saYYYYMMDD is more recent than saDD, so use it */ + *sa_name = 1; + } +} + +/* + *************************************************************************** + * Set current daily data file name. + * + * IN: + * @datafile If not an empty string then this is the alternate directory + * location where daily data files will be saved. + * @d_off Day offset (number of days to go back in the past). + * @sa_name 0 for saDD data files, + * 1 for saYYYYMMDD data files, + * -1 if unknown. In this case, will look for the most recent + * of saDD and saYYYYMMDD and use it. + * + * OUT: + * @datafile Name of daily data file. + * + * RETURNS: + * 1 if an output error has been encountered or if datafile name has been + * truncated, or 0 otherwise. + *************************************************************************** + */ +int set_default_file(char *datafile, int d_off, int sa_name) +{ + char sa_dir[MAX_FILE_LEN]; + struct tm rectime = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL}; + int err = 0; + + /* Set directory where daily data files will be saved */ + if (datafile[0]) { + strncpy(sa_dir, datafile, MAX_FILE_LEN); + } + else { + strncpy(sa_dir, SA_DIR, MAX_FILE_LEN); + } + sa_dir[MAX_FILE_LEN - 1] = '\0'; + + get_time(&rectime, d_off); + if (sa_name < 0) { + /* + * Look for the most recent of saDD and saYYYYMMDD + * and use it. If neither exists then use saDD. + * sa_name is set accordingly. + */ + guess_sa_name(sa_dir, &rectime, &sa_name); + } + if (sa_name) { + /* Using saYYYYMMDD data files */ + err = snprintf(datafile, MAX_FILE_LEN, + "%s/sa%04d%02d%02d", sa_dir, + rectime.tm_year + 1900, + rectime.tm_mon + 1, + rectime.tm_mday); + } + else { + /* Using saDD data files */ + err = snprintf(datafile, MAX_FILE_LEN, + "%s/sa%02d", sa_dir, + rectime.tm_mday); + } + datafile[MAX_FILE_LEN - 1] = '\0'; + default_file_used = TRUE; + + return ((err < 0) || (err >= MAX_FILE_LEN)); +} + +/* + *************************************************************************** + * Check data file type. If it is a directory then this is the alternate + * location where daily data files will be saved. + * + * IN: + * @datafile Name of the daily data file. May be a directory. + * @d_off Day offset (number of days to go back in the past). + * @sa_name 0 for saDD data files, + * 1 for saYYYYMMDD data files, + * -1 if unknown. In this case, will look for the most recent + * of saDD and saYYYYMMDD and use it. + * + * + * OUT: + * @datafile Name of the daily data file. This is now a plain file, not + * a directory. + * + * RETURNS: + * 1 if @datafile was a directory, and 0 otherwise. + *************************************************************************** + */ +int check_alt_sa_dir(char *datafile, int d_off, int sa_name) +{ + struct stat sb; + + if (stat(datafile, &sb) == 0) { + if (S_ISDIR(sb.st_mode)) { + /* + * This is a directory: So append + * the default file name to it. + */ + set_default_file(datafile, d_off, sa_name); + return 1; + } + } + + return 0; +} + +/* + *************************************************************************** + * Display sysstat version used to create system activity data file. + * + * IN: + * @st Output stream (stderr or stdout). + * @file_magic File magic header. + *************************************************************************** + */ +void display_sa_file_version(FILE *st, struct file_magic *file_magic) +{ + fprintf(st, _("File created by sar/sadc from sysstat version %d.%d.%d"), + file_magic->sysstat_version, + file_magic->sysstat_patchlevel, + file_magic->sysstat_sublevel); + + if (file_magic->sysstat_extraversion) { + fprintf(st, ".%d", file_magic->sysstat_extraversion); + } + fprintf(st, "\n"); +} + +/* + *************************************************************************** + * An invalid system activity file has been opened for reading. + * If this file was created by an old version of sysstat, tell it to the + * user... + * + * IN: + * @fd Descriptor of the file that has been opened. + * @file_magic file_magic structure filled with file magic header data. + * May contain invalid data. + * @file Name of the file being read. + * @n Number of bytes read while reading file magic header. + * This function may also be called after failing to read file + * standard header, or if CPU activity has not been found in + * file. In this case, n is set to 0. + *************************************************************************** + */ +void handle_invalid_sa_file(int fd, struct file_magic *file_magic, char *file, + int n) +{ + fprintf(stderr, _("Invalid system activity file: %s\n"), file); + + if (n == FILE_MAGIC_SIZE) { + if ((file_magic->sysstat_magic == SYSSTAT_MAGIC) || (file_magic->sysstat_magic == SYSSTAT_MAGIC_SWAPPED)) { + /* This is a sysstat file, but this file has an old format */ + display_sa_file_version(stderr, file_magic); + + fprintf(stderr, + _("Current sysstat version cannot read the format of this file (%#x)\n"), + file_magic->sysstat_magic == SYSSTAT_MAGIC ? + file_magic->format_magic : __builtin_bswap16(file_magic->format_magic)); + } + } + + close (fd); + exit(3); +} + +/* + *************************************************************************** + * Display an error message then exit. + *************************************************************************** + */ +void print_collect_error(void) +{ + fprintf(stderr, _("Requested activities not available\n")); + exit(1); +} + +/* + *************************************************************************** + * Fill system activity file magic header. + * + * IN: + * @file_magic System activity file magic header. + *************************************************************************** + */ +void enum_version_nr(struct file_magic *fm) +{ + char *v; + char version[16]; + + fm->sysstat_extraversion = 0; + + strcpy(version, VERSION); + + /* Get version number */ + if ((v = strtok(version, ".")) == NULL) + return; + fm->sysstat_version = atoi(v) & 0xff; + + /* Get patchlevel number */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_patchlevel = atoi(v) & 0xff; + + /* Get sublevel number */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_sublevel = atoi(v) & 0xff; + + /* Get extraversion number. Don't necessarily exist */ + if ((v = strtok(NULL, ".")) == NULL) + return; + fm->sysstat_extraversion = atoi(v) & 0xff; +} + +#ifndef SOURCE_SADC +/* + *************************************************************************** + * Allocate structures. + * + * IN: + * @act Array of activities. + *************************************************************************** + */ +void allocate_structures(struct activity *act[]) +{ + int i, j; + + for (i = 0; i < NR_ACT; i++) { + if (act[i]->nr_ini > 0) { + for (j = 0; j < 3; j++) { + SREALLOC(act[i]->buf[j], void, + (size_t) act[i]->msize * (size_t) act[i]->nr_ini * (size_t) act[i]->nr2); + } + act[i]->nr_allocated = act[i]->nr_ini; + } + } +} + +/* + *************************************************************************** + * Free structures. + * + * IN: + * @act Array of activities. + *************************************************************************** + */ +void free_structures(struct activity *act[]) +{ + int i, j; + + for (i = 0; i < NR_ACT; i++) { + if (act[i]->nr_allocated > 0) { + for (j = 0; j < 3; j++) { + if (act[i]->buf[j]) { + free(act[i]->buf[j]); + act[i]->buf[j] = NULL; + } + } + act[i]->nr_allocated = 0; + } + } +} + +/* + *************************************************************************** + * Reallocate all the buffers for a given activity. + * + * IN: + * @a Activity whose buffers need to be reallocated. + * @nr_min Minimum number of items that the new buffers should be able + * to receive. + *************************************************************************** + */ +void reallocate_all_buffers(struct activity *a, __nr_t nr_min) +{ + int j; + size_t nr_realloc; + + if (nr_min <= 0) { + nr_min = 1; + } + if (!a->nr_allocated) { + nr_realloc = nr_min; + } + else { + nr_realloc = a->nr_allocated; + do { + nr_realloc = nr_realloc * 2; + } + while (nr_realloc < nr_min); + } + + for (j = 0; j < 3; j++) { + SREALLOC(a->buf[j], void, + (size_t) a->msize * nr_realloc * (size_t) a->nr2); + /* Init additional space which has been allocated */ + if (a->nr_allocated) { + memset(a->buf[j] + a->msize * a->nr_allocated * a->nr2, 0, + (size_t) a->msize * (size_t) (nr_realloc - a->nr_allocated) * (size_t) a->nr2); + } + } + + a->nr_allocated = nr_realloc; +} + +/* + *************************************************************************** + * Try to get device real name from sysfs tree. + * + * IN: + * @major Major number of the device. + * @minor Minor number of the device. + * + * RETURNS: + * The name of the device, which may be the real name (as it appears in /dev) + * or NULL. + *************************************************************************** + */ +char *get_devname_from_sysfs(unsigned int major, unsigned int minor) +{ + static char link[32], target[PATH_MAX]; + char *devname; + ssize_t r; + + snprintf(link, 32, "%s/%u:%u", SYSFS_DEV_BLOCK, major, minor); + + /* Get full path to device knowing its major and minor numbers */ + r = readlink(link, target, PATH_MAX); + if (r <= 0 || r >= PATH_MAX) { + return (NULL); + } + + target[r] = '\0'; + + /* Get device name */ + devname = basename(target); + if (!devname || strnlen(devname, FILENAME_MAX) == 0) { + return (NULL); + } + + return (devname); +} + +/* + *************************************************************************** + * Get device real name if possible. + * Warning: This routine may return a bad name on 2.4 kernels where + * disk activities are read from /proc/stat. + * + * IN: + * @major Major number of the device. + * @minor Minor number of the device. + * @pretty TRUE if the real name of the device (as it appears in /dev) + * should be returned. + * + * RETURNS: + * The name of the device, which may be the real name (as it appears in /dev) + * or a string with the following format devM-n. + *************************************************************************** + */ +char *get_devname(unsigned int major, unsigned int minor, int pretty) +{ + static char buf[32]; + char *name; + + snprintf(buf, 32, "dev%u-%u", major, minor); + + if (!pretty) + return (buf); + + name = get_devname_from_sysfs(major, minor); + if (name != NULL) + return (name); + + name = ioc_name(major, minor); + if ((name != NULL) && strcmp(name, K_NODEV)) + return (name); + + return (buf); +} + +/* + *************************************************************************** + * Check if we are close enough to desired interval. + * + * IN: + * @uptime_ref Uptime used as reference. This is the system uptime for the + * first sample statistics, or the first system uptime after a + * LINUX RESTART (in 1/100th of a second). + * @uptime Current system uptime (in 1/100th of a second). + * @reset TRUE if @last_uptime should be reset with @uptime_ref. + * @interval Interval of time. + * + * RETURNS: + * 1 if we are actually close enough to desired interval, 0 otherwise. + *************************************************************************** +*/ +int next_slice(unsigned long long uptime_ref, unsigned long long uptime, + int reset, long interval) +{ + unsigned long file_interval, entry; + static unsigned long long last_uptime = 0; + int min, max, pt1, pt2; + double f; + + /* uptime is expressed in 1/100th of a second */ + if (!last_uptime || reset) { + last_uptime = uptime_ref; + } + + /* Interval cannot be greater than 0xffffffff here */ + f = ((double) ((uptime - last_uptime) & 0xffffffff)) / 100; + file_interval = (unsigned long) f; + if ((f * 10) - (file_interval * 10) >= 5) { + file_interval++; /* Rounding to correct value */ + } + + last_uptime = uptime; + + /* + * A few notes about the "algorithm" used here to display selected entries + * from the system activity file (option -f with -i flag): + * Let 'Iu' be the interval value given by the user on the command line, + * 'If' the interval between current and previous line in the system + * activity file, + * and 'En' the nth entry (identified by its time stamp) of the file. + * We choose In = [ En - If/2, En + If/2 [ if If is even, + * or In = [ En - If/2, En + If/2 ] if not. + * En will be displayed if + * (Pn * Iu) or (P'n * Iu) belongs to In + * with Pn = En / Iu and P'n = En / Iu + 1 + */ + f = ((double) ((uptime - uptime_ref) & 0xffffffff)) / 100; + entry = (unsigned long) f; + if ((f * 10) - (entry * 10) >= 5) { + entry++; + } + + min = entry - (file_interval / 2); + max = entry + (file_interval / 2) + (file_interval & 0x1); + pt1 = (entry / interval) * interval; + pt2 = ((entry / interval) + 1) * interval; + + return (((pt1 >= min) && (pt1 < max)) || ((pt2 >= min) && (pt2 < max))); +} + +/* + *************************************************************************** + * Use time stamp to fill tstamp structure. + * + * IN: + * @timestamp Timestamp to decode (format: HH:MM:SS). + * + * OUT: + * @tse Structure containing the decoded timestamp. + * + * RETURNS: + * 0 if the timestamp has been successfully decoded, 1 otherwise. + *************************************************************************** + */ +int decode_timestamp(char timestamp[], struct tstamp *tse) +{ + timestamp[2] = timestamp[5] = '\0'; + tse->tm_sec = atoi(×tamp[6]); + tse->tm_min = atoi(×tamp[3]); + tse->tm_hour = atoi(timestamp); + + if ((tse->tm_sec < 0) || (tse->tm_sec > 59) || + (tse->tm_min < 0) || (tse->tm_min > 59) || + (tse->tm_hour < 0) || (tse->tm_hour > 23)) + return 1; + + tse->use = TRUE; + + return 0; +} + +/* + *************************************************************************** + * Compare two timestamps. + * + * IN: + * @rectime Date and time for current sample. + * @tse Timestamp used as reference. + * + * RETURNS: + * A positive value if @rectime is greater than @tse, + * a negative one otherwise. + *************************************************************************** + */ +int datecmp(struct tm *rectime, struct tstamp *tse) +{ + if (rectime->tm_hour == tse->tm_hour) { + if (rectime->tm_min == tse->tm_min) + return (rectime->tm_sec - tse->tm_sec); + else + return (rectime->tm_min - tse->tm_min); + } + else + return (rectime->tm_hour - tse->tm_hour); +} + +/* + *************************************************************************** + * Parse a timestamp entered on the command line (hh:mm[:ss]) and decode it. + * + * IN: + * @argv Arguments list. + * @opt Index in the arguments list. + * @def_timestamp Default timestamp to use. + * + * OUT: + * @tse Structure containing the decoded timestamp. + * + * RETURNS: + * 0 if the timestamp has been successfully decoded, 1 otherwise. + *************************************************************************** + */ +int parse_timestamp(char *argv[], int *opt, struct tstamp *tse, + const char *def_timestamp) +{ + char timestamp[9]; + + if (argv[++(*opt)]) { + switch (strlen(argv[*opt])) { + + case 5: + strncpy(timestamp, argv[(*opt)++], 5); + timestamp[5] = '\0'; + strcat(timestamp, ":00"); + break; + + case 8: + strncpy(timestamp, argv[(*opt)++], 8); + break; + + default: + strncpy(timestamp, def_timestamp, 8); + break; + } + } else { + strncpy(timestamp, def_timestamp, 8); + } + timestamp[8] = '\0'; + + return decode_timestamp(timestamp, tse); +} + +/* + *************************************************************************** + * Set interval value. + * + * IN: + * @record_hdr_curr Record with current sample statistics. + * @record_hdr_prev Record with previous sample statistics. + * + * OUT: + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +void get_itv_value(struct record_header *record_hdr_curr, + struct record_header *record_hdr_prev, + unsigned long long *itv) +{ + /* Interval value in jiffies */ + *itv = get_interval(record_hdr_prev->uptime_cs, + record_hdr_curr->uptime_cs); +} + +/* + *************************************************************************** + * Fill the rectime structure with the file's creation date, based on file's + * time data saved in file header. + * The resulting timestamp is expressed in the locale of the file creator or + * in the user's own locale, depending on whether option -t has been used + * or not. + * + * IN: + * @flags Flags for common options and system state. + * @file_hdr System activity file standard header. + * + * OUT: + * @rectime Date (and possibly time) from file header. Only the date, + * not the time, should be used by the caller. + *************************************************************************** + */ +void get_file_timestamp_struct(unsigned int flags, struct tm *rectime, + struct file_header *file_hdr) +{ + struct tm *loc_t; + + if (PRINT_TRUE_TIME(flags)) { + /* Get local time. This is just to fill fields with a default value. */ + get_time(rectime, 0); + + rectime->tm_mday = file_hdr->sa_day; + rectime->tm_mon = file_hdr->sa_month; + rectime->tm_year = file_hdr->sa_year; + /* + * Call mktime() to set DST (Daylight Saving Time) flag. + * Has anyone a better way to do it? + */ + rectime->tm_hour = rectime->tm_min = rectime->tm_sec = 0; + mktime(rectime); + } + else { + if ((loc_t = localtime((const time_t *) &file_hdr->sa_ust_time)) != NULL) { + *rectime = *loc_t; + } + } +} + +/* + *************************************************************************** + * Print report header. + * + * IN: + * @flags Flags for common options and system state. + * @file_hdr System activity file standard header. + * + * OUT: + * @rectime Date and time from file header. + *************************************************************************** + */ +void print_report_hdr(unsigned int flags, struct tm *rectime, + struct file_header *file_hdr) +{ + + /* Get date of file creation */ + get_file_timestamp_struct(flags, rectime, file_hdr); + + /* + * Display the header. + * NB: Number of CPU (value in [1, NR_CPUS + 1]). + * 1 means that there is only one proc and non SMP kernel. + * 2 means one proc and SMP kernel. Etc. + */ + print_gal_header(rectime, file_hdr->sa_sysname, file_hdr->sa_release, + file_hdr->sa_nodename, file_hdr->sa_machine, + file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1, + PLAIN_OUTPUT); +} + +/* + *************************************************************************** + * Network interfaces may now be registered (and unregistered) dynamically. + * This is what we try to guess here. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @ref Index in array for sample statistics used as reference. + * @pos Index on current network interface. + * + * RETURNS: + * Position of current network interface in array of sample statistics used + * as reference. + * -1 if it is a new interface (it was not present in array of stats used + * as reference). + * -2 if it is a known interface but which has been unregistered then + * registered again on the interval. + *************************************************************************** + */ +int check_net_dev_reg(struct activity *a, int curr, int ref, int pos) +{ + struct stats_net_dev *sndc, *sndp; + int j0, j = pos; + + if (!a->nr[ref]) + /* + * No items found in previous iteration: + * Current interface is necessarily new. + */ + return -1; + + if (j >= a->nr[ref]) { + j = a->nr[ref] - 1; + } + j0 = j; + + sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + pos * a->msize); + + do { + sndp = (struct stats_net_dev *) ((char *) a->buf[ref] + j * a->msize); + + if (!strcmp(sndc->interface, sndp->interface)) { + /* + * Network interface found. + * If a counter has decreased, then we may assume that the + * corresponding interface was unregistered, then registered again. + */ + if ((sndc->rx_packets < sndp->rx_packets) || + (sndc->tx_packets < sndp->tx_packets) || + (sndc->rx_bytes < sndp->rx_bytes) || + (sndc->tx_bytes < sndp->tx_bytes) || + (sndc->rx_compressed < sndp->rx_compressed) || + (sndc->tx_compressed < sndp->tx_compressed) || + (sndc->multicast < sndp->multicast)) { + + /* + * Special processing for rx_bytes (_packets) and + * tx_bytes (_packets) counters: If the number of + * bytes (packets) has decreased, whereas the number of + * packets (bytes) has increased, then assume that the + * relevant counter has met an overflow condition, and that + * the interface was not unregistered, which is all the + * more plausible that the previous value for the counter + * was > ULLONG_MAX/2. + * NB: the average value displayed will be wrong in this case... + * + * If such an overflow is detected, just set the flag. There is no + * need to handle this in a special way: the difference is still + * properly calculated if the result is of the same type (i.e. + * unsigned long) as the two values. + */ + int ovfw = FALSE; + + if ((sndc->rx_bytes < sndp->rx_bytes) && + (sndc->rx_packets > sndp->rx_packets) && + (sndp->rx_bytes > (~0ULL >> 1))) { + ovfw = TRUE; + } + if ((sndc->tx_bytes < sndp->tx_bytes) && + (sndc->tx_packets > sndp->tx_packets) && + (sndp->tx_bytes > (~0ULL >> 1))) { + ovfw = TRUE; + } + if ((sndc->rx_packets < sndp->rx_packets) && + (sndc->rx_bytes > sndp->rx_bytes) && + (sndp->rx_packets > (~0ULL >> 1))) { + ovfw = TRUE; + } + if ((sndc->tx_packets < sndp->tx_packets) && + (sndc->tx_bytes > sndp->tx_bytes) && + (sndp->tx_packets > (~0ULL >> 1))) { + ovfw = TRUE; + } + + if (!ovfw) + /* + * OK: Assume here that the device was + * actually unregistered. + */ + return -2; + } + return j; + } + if (++j >= a->nr[ref]) { + j = 0; + } + } + while (j != j0); + + /* This is a newly registered interface */ + return -1; +} + +/* + *************************************************************************** + * Network interfaces may now be registered (and unregistered) dynamically. + * This is what we try to guess here. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @ref Index in array for sample statistics used as reference. + * @pos Index on current network interface. + * + * RETURNS: + * Position of current network interface in array of sample statistics used + * as reference. + * -1 if it is a newly registered interface. + * -2 if it is a known interface but which has been unregistered then + * registered again on the interval. + *************************************************************************** + */ +int check_net_edev_reg(struct activity *a, int curr, int ref, int pos) +{ + struct stats_net_edev *snedc, *snedp; + int j0, j = pos; + + if (!a->nr[ref]) + /* + * No items found in previous iteration: + * Current interface is necessarily new. + */ + return -1; + + if (j >= a->nr[ref]) { + j = a->nr[ref] - 1; + } + j0 = j; + + snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + pos * a->msize); + + do { + snedp = (struct stats_net_edev *) ((char *) a->buf[ref] + j * a->msize); + + if (!strcmp(snedc->interface, snedp->interface)) { + /* + * Network interface found. + * If a counter has decreased, then we may assume that the + * corresponding interface was unregistered, then registered again. + */ + if ((snedc->tx_errors < snedp->tx_errors) || + (snedc->collisions < snedp->collisions) || + (snedc->rx_dropped < snedp->rx_dropped) || + (snedc->tx_dropped < snedp->tx_dropped) || + (snedc->tx_carrier_errors < snedp->tx_carrier_errors) || + (snedc->rx_frame_errors < snedp->rx_frame_errors) || + (snedc->rx_fifo_errors < snedp->rx_fifo_errors) || + (snedc->tx_fifo_errors < snedp->tx_fifo_errors)) + /* + * OK: assume here that the device was + * actually unregistered. + */ + return -2; + + return j; + } + if (++j >= a->nr[ref]) { + j = 0; + } + } + while (j != j0); + + /* This is a newly registered interface */ + return -1; +} + +/* + *************************************************************************** + * Disks may be registered dynamically (true in /proc/stat file). + * This is what we try to guess here. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @ref Index in array for sample statistics used as reference. + * @pos Index on current disk. + * + * RETURNS: + * Position of current disk in array of sample statistics used as reference + * -1 if it is a newly registered device. + * -2 if it is a known device but which has been unregistered then registered + * again on the interval. + *************************************************************************** + */ +int check_disk_reg(struct activity *a, int curr, int ref, int pos) +{ + struct stats_disk *sdc, *sdp; + int j0, j = pos; + + if (!a->nr[ref]) + /* + * No items found in previous iteration: + * Current interface is necessarily new. + */ + return -1; + + if (j >= a->nr[ref]) { + j = a->nr[ref] - 1; + } + j0 = j; + + sdc = (struct stats_disk *) ((char *) a->buf[curr] + pos * a->msize); + + do { + sdp = (struct stats_disk *) ((char *) a->buf[ref] + j * a->msize); + + if ((sdc->major == sdp->major) && + (sdc->minor == sdp->minor)) { + /* + * Disk found. + * If all the counters have decreased then the likelyhood + * is that the disk has been unregistered and a new disk inserted. + * If only one or two have decreased then the likelyhood + * is that the counter has simply wrapped. + */ + if ((sdc->nr_ios < sdp->nr_ios) && + (sdc->rd_sect < sdp->rd_sect) && + (sdc->wr_sect < sdp->wr_sect)) + /* Same device registered again */ + return -2; + + return j; + } + if (++j >= a->nr[ref]) { + j = 0; + } + } + while (j != j0); + + /* This is a newly registered device */ + return -1; +} + +/* + *************************************************************************** + * Allocate bitmaps for activities that have one. + * + * IN: + * @act Array of activities. + *************************************************************************** + */ +void allocate_bitmaps(struct activity *act[]) +{ + int i; + + for (i = 0; i < NR_ACT; i++) { + /* + * If current activity has a bitmap which has not already + * been allocated, then allocate it. + * Note that a same bitmap may be used by several activities. + */ + if (act[i]->bitmap && !act[i]->bitmap->b_array) { + SREALLOC(act[i]->bitmap->b_array, unsigned char, + BITMAP_SIZE(act[i]->bitmap->b_size)); + } + } +} + +/* + *************************************************************************** + * Free bitmaps for activities that have one. + * + * IN: + * @act Array of activities. + *************************************************************************** + */ +void free_bitmaps(struct activity *act[]) +{ + int i; + + for (i = 0; i < NR_ACT; i++) { + if (act[i]->bitmap && act[i]->bitmap->b_array) { + free(act[i]->bitmap->b_array); + /* Set pointer to NULL to prevent it from being freed again */ + act[i]->bitmap->b_array = NULL; + } + } +} + +/* + *************************************************************************** + * Select all activities, even if they have no associated items. + * + * IN: + * @act Array of activities. + * + * OUT: + * @act Array of activities, all of the being selected. + *************************************************************************** + */ +void select_all_activities(struct activity *act[]) +{ + int i; + + for (i = 0; i < NR_ACT; i++) { + act[i]->options |= AO_SELECTED; + } +} + +/* + *************************************************************************** + * Select CPU activity if no other activities have been explicitly selected. + * Also select CPU "all" if no other CPU has been selected. + * + * IN: + * @act Array of activities. + * + * OUT: + * @act Array of activities with CPU activity selected if needed. + *************************************************************************** + */ +void select_default_activity(struct activity *act[]) +{ + int p; + + p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND); + + /* Default is CPU activity... */ + if (!get_activity_nr(act, AO_SELECTED, COUNT_ACTIVITIES)) { + /* + * Yet A_CPU activity may not be available in file + * since the user can choose not to collect it. + */ + act[p]->options |= AO_SELECTED; + } + + /* + * If no CPU's have been selected then select CPU "all". + * cpu_bitmap bitmap may be used by several activities (A_CPU, A_PWR_CPU...) + */ + if (!count_bits(cpu_bitmap.b_array, BITMAP_SIZE(cpu_bitmap.b_size))) { + cpu_bitmap.b_array[0] |= 0x01; + } +} + +/* + *************************************************************************** + * Swap bytes for every numerical field in structure. Used to convert from + * one endianness type (big-endian or little-endian) to the other. + * + * IN: + * @types_nr Number of fields in structure for each following types: + * unsigned long long, unsigned long and int. + * @ps Pointer on structure. + * @is64bit TRUE if data come from a 64-bit machine. + *************************************************************************** + */ +void swap_struct(unsigned int types_nr[], void *ps, int is64bit) +{ + int i; + uint64_t *x; + uint32_t *y; + + x = (uint64_t *) ps; + /* For each field of type long long (or double) */ + for (i = 0; i < types_nr[0]; i++) { + *x = __builtin_bswap64(*x); + x = (uint64_t *) ((char *) x + ULL_ALIGNMENT_WIDTH); + } + + y = (uint32_t *) x; + /* For each field of type long */ + for (i = 0; i < types_nr[1]; i++) { + if (is64bit) { + *x = __builtin_bswap64(*x); + x = (uint64_t *) ((char *) x + UL_ALIGNMENT_WIDTH); + } + else { + *y = __builtin_bswap32(*y); + y = (uint32_t *) ((char *) y + UL_ALIGNMENT_WIDTH); + } + } + + if (is64bit) { + y = (uint32_t *) x; + } + /* For each field of type int */ + for (i = 0; i < types_nr[2]; i++) { + *y = __builtin_bswap32(*y); + y = (uint32_t *) ((char *) y + U_ALIGNMENT_WIDTH); + } +} + +/* + *************************************************************************** + * Map the fields of a structure containing statistics read from a file to + * those of the structure known by current sysstat version. + * Each structure (either read from file or from current sysstat version) + * are described by 3 values: The number of [unsigned] long long integers, + * the number of [unsigned] long integers following in the structure, and + * last the number of [unsigned] integers. + * We assume that those numbers will *never* decrease with newer sysstat + * versions. + * + * IN: + * @gtypes_nr Structure description as expected for current sysstat version. + * @ftypes_nr Structure description as read from file. + * @ps Pointer on structure containing statistics. + * @st_size Size of the structure containing statistics. This is the size + * of the structure *read from file* (not the size of the + * structure expected by current sysstat version). + *************************************************************************** + */ +void remap_struct(unsigned int gtypes_nr[], unsigned int ftypes_nr[], + void *ps, unsigned int st_size) +{ + int d; + + /* Sanity check */ + if (MAP_SIZE(ftypes_nr) > st_size) + return; + + /* Remap [unsigned] long fields */ + d = gtypes_nr[0] - ftypes_nr[0]; + if (d) { + memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH, + ((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH, + st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH); + if (d > 0) { + memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH, + 0, d * ULL_ALIGNMENT_WIDTH); + } + } + /* Remap [unsigned] int fields */ + d = gtypes_nr[1] - ftypes_nr[1]; + if (d) { + memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + gtypes_nr[1] * UL_ALIGNMENT_WIDTH, + ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + ftypes_nr[1] * UL_ALIGNMENT_WIDTH, + st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH + - ftypes_nr[1] * UL_ALIGNMENT_WIDTH); + if (d > 0) { + memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + ftypes_nr[1] * UL_ALIGNMENT_WIDTH, + 0, d * UL_ALIGNMENT_WIDTH); + } + } + /* Remap possible fields (like strings of chars) following int fields */ + d = gtypes_nr[2] - ftypes_nr[2]; + if (d) { + memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + gtypes_nr[1] * UL_ALIGNMENT_WIDTH + + gtypes_nr[2] * U_ALIGNMENT_WIDTH, + ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + gtypes_nr[1] * UL_ALIGNMENT_WIDTH + + ftypes_nr[2] * U_ALIGNMENT_WIDTH, + st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH + - ftypes_nr[1] * UL_ALIGNMENT_WIDTH + - ftypes_nr[2] * U_ALIGNMENT_WIDTH); + if (d > 0) { + memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + + gtypes_nr[1] * UL_ALIGNMENT_WIDTH + + ftypes_nr[2] * U_ALIGNMENT_WIDTH, + 0, d * U_ALIGNMENT_WIDTH); + } + } +} + +/* + *************************************************************************** + * Read data from a system activity data file. + * + * IN: + * @ifd Input file descriptor. + * @buffer Buffer where data are read. + * @size Number of bytes to read. + * @mode If set to HARD_SIZE, indicate that an EOF should be considered + * as an error. + * + * RETURNS: + * 1 if EOF has been reached, 0 otherwise. + *************************************************************************** + */ +int sa_fread(int ifd, void *buffer, size_t size, int mode) +{ + ssize_t n; + + if ((n = read(ifd, buffer, size)) < 0) { + fprintf(stderr, _("Error while reading system activity file: %s\n"), + strerror(errno)); + close(ifd); + exit(2); + } + + if (!n && (mode == SOFT_SIZE)) + return 1; /* EOF */ + + if (n < size) { + fprintf(stderr, _("End of system activity file unexpected\n")); + close(ifd); + exit(2); + } + + return 0; +} + +/* + *************************************************************************** + * Read the record header of current sample and process it. + * + * IN: + * @ifd Input file descriptor. + * @buffer Buffer where data will be read. + * @record_hdr Structure where record header will be saved. + * @file_hdr file_hdr structure containing data read from file standard + * header. + * @arch_64 TRUE if file's data come from a 64-bit machine. + * @endian_mismatch + * TRUE if data read from file don't match current machine's + * endianness. + * + * OUT: + * @record_hdr Record header for current sample. + * + * RETURNS: + * 1 if EOF has been reached, 0 otherwise. + *************************************************************************** + */ +int read_record_hdr(int ifd, void *buffer, struct record_header *record_hdr, + struct file_header *file_hdr, int arch_64, int endian_mismatch) +{ + if (sa_fread(ifd, buffer, (size_t) file_hdr->rec_size, SOFT_SIZE)) + /* End of sa data file */ + return 1; + + /* Remap record header structure to that expected by current version */ + remap_struct(rec_types_nr, file_hdr->rec_types_nr, buffer, file_hdr->rec_size); + memcpy(record_hdr, buffer, RECORD_HEADER_SIZE); + + /* Normalize endianness */ + if (endian_mismatch) { + swap_struct(rec_types_nr, record_hdr, arch_64); + } + + return 0; +} + +/* + *************************************************************************** + * Move structures data. + * + * IN: + * @act Array of activities. + * @id_seq Activity sequence in file. + * @record_hdr Current record header. + * @dest Index in array where stats have to be copied to. + * @src Index in array where stats to copy are. + *************************************************************************** + */ +void copy_structures(struct activity *act[], unsigned int id_seq[], + struct record_header record_hdr[], int dest, int src) +{ + int i, p; + + memcpy(&record_hdr[dest], &record_hdr[src], RECORD_HEADER_SIZE); + + for (i = 0; i < NR_ACT; i++) { + + if (!id_seq[i]) + continue; + + p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND); + + memcpy(act[p]->buf[dest], act[p]->buf[src], + (size_t) act[p]->msize * (size_t) act[p]->nr[src] * (size_t) act[p]->nr2); + act[p]->nr[dest] = act[p]->nr[src]; + } +} + +/* + *************************************************************************** + * Read an __nr_t value from file. + * Such a value can be the new number of CPU saved after a RESTART record, + * or the number of structures to read saved before the structures containing + * statistics for an activity with a varying number of items in file. + * + * IN: + * @ifd Input file descriptor. + * @file Name of file being read. + * @file_magic file_magic structure filled with file magic header data. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @arch_64 TRUE if file's data come from a 64 bit machine. + * @non_zero TRUE if value should not be zero. + * + * RETURNS: + * __nr_t value, as read from file. + *************************************************************************** + */ +__nr_t read_nr_value(int ifd, char *file, struct file_magic *file_magic, + int endian_mismatch, int arch_64, int non_zero) +{ + __nr_t value; + + sa_fread(ifd, &value, sizeof(__nr_t), HARD_SIZE); + + /* Normalize endianness for file_activity structures */ + if (endian_mismatch) { + nr_types_nr[2] = 1; + swap_struct(nr_types_nr, &value, arch_64); + } + + if ((non_zero && !value) || (value < 0)) { +#ifdef DEBUG + fprintf(stderr, "%s: Value=%d\n", + __FUNCTION__, value); +#endif + /* Value number cannot be zero or negative */ + handle_invalid_sa_file(ifd, file_magic, file, 0); + } + + return value; +} + +/* + *************************************************************************** + * Read varying part of the statistics from a daily data file. + * + * IN: + * @act Array of activities. + * @curr Index in array for current sample statistics. + * @ifd Input file descriptor. + * @act_nr Number of activities in file. + * @file_actlst Activity list in file. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @arch_64 TRUE if file's data come from a 64 bit machine. + * @dfile Name of system activity data file. + * @file_magic file_magic structure containing data read from file magic + * header. + *************************************************************************** + */ +void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr, + struct file_activity *file_actlst, int endian_mismatch, + int arch_64, char *dfile, struct file_magic *file_magic) +{ + int i, j, p; + struct file_activity *fal = file_actlst; + off_t offset; + __nr_t nr_value; + + for (i = 0; i < act_nr; i++, fal++) { + + /* Read __nr_t value preceding statistics structures if it exists */ + if (fal->has_nr) { + nr_value = read_nr_value(ifd, dfile, file_magic, + endian_mismatch, arch_64, FALSE); + } + else { + nr_value = fal->nr; + } + + if (nr_value > NR_MAX) { +#ifdef DEBUG + fprintf(stderr, "%s: Value=%d Max=%d\n", __FUNCTION__, nr_value, NR_MAX); +#endif + handle_invalid_sa_file(ifd, file_magic, dfile, 0); + } + + if (((p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND)) < 0) || + (act[p]->magic != fal->magic)) { + /* + * Ignore current activity in file, which is unknown to + * current sysstat version or has an unknown format. + */ + if (nr_value) { + offset = (off_t) fal->size * (off_t) nr_value * (off_t) fal->nr2; + if (lseek(ifd, offset, SEEK_CUR) < offset) { + close(ifd); + perror("lseek"); + exit(2); + } + } + continue; + } + + if (nr_value > act[p]->nr_max) { +#ifdef DEBUG + fprintf(stderr, "%s: %s: Value=%d Max=%d\n", + __FUNCTION__, act[p]->name, nr_value, act[p]->nr_max); +#endif + handle_invalid_sa_file(ifd, file_magic, dfile, 0); + } + act[p]->nr[curr] = nr_value; + + /* Reallocate buffers if needed */ + if (nr_value > act[p]->nr_allocated) { + reallocate_all_buffers(act[p], nr_value); + } + + /* + * For persistent activities, we must make sure that no statistics + * from a previous iteration remain, especially if the number + * of structures read is smaller than @nr_ini. + */ + if (HAS_PERSISTENT_VALUES(act[p]->options)) { + memset(act[p]->buf[curr], 0, + (size_t) act[p]->msize * (size_t) act[p]->nr_ini * (size_t) act[p]->nr2); + } + + /* OK, this is a known activity: Read the stats structures */ + if ((nr_value > 0) && + ((nr_value > 1) || (act[p]->nr2 > 1)) && + (act[p]->msize > act[p]->fsize)) { + + for (j = 0; j < (nr_value * act[p]->nr2); j++) { + sa_fread(ifd, (char *) act[p]->buf[curr] + j * act[p]->msize, + (size_t) act[p]->fsize, HARD_SIZE); + } + } + else if (nr_value > 0) { + /* + * Note: If msize was smaller than fsize, + * then it has been set to fsize in check_file_actlst(). + */ + sa_fread(ifd, act[p]->buf[curr], + (size_t) act[p]->fsize * (size_t) nr_value * (size_t) act[p]->nr2, HARD_SIZE); + } + else { + /* nr_value == 0: Nothing to read */ + continue; + } + + /* Normalize endianness for current activity's structures */ + if (endian_mismatch) { + for (j = 0; j < (nr_value * act[p]->nr2); j++) { + swap_struct(act[p]->ftypes_nr, (char *) act[p]->buf[curr] + j * act[p]->msize, + arch_64); + } + } + + /* Remap structure's fields to those known by current sysstat version */ + for (j = 0; j < (nr_value * act[p]->nr2); j++) { + remap_struct(act[p]->gtypes_nr, act[p]->ftypes_nr, + (char *) act[p]->buf[curr] + j * act[p]->msize, act[p]->fsize); + } + } +} + +/* + *************************************************************************** + * Open a sysstat activity data file and read its magic structure. + * + * IN: + * @dfile Name of system activity data file. + * @ignore Set to 1 if a true sysstat activity file but with a bad + * format should not yield an error message. Useful with + * sadf -H and sadf -c. + * + * OUT: + * @fd System activity data file descriptor. + * @file_magic file_magic structure containing data read from file magic + * header. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @do_swap TRUE if endianness should be normalized for sysstat_magic + * and format_magic numbers. + * + * RETURNS: + * -1 if data file is a sysstat file with an old format (which we cannot + * read), 0 otherwise. + *************************************************************************** + */ +int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic, + int ignore, int *endian_mismatch, int do_swap) +{ + int n; + unsigned int fm_types_nr[] = {FILE_MAGIC_ULL_NR, FILE_MAGIC_UL_NR, FILE_MAGIC_U_NR}; + + /* Open sa data file */ + if ((*fd = open(dfile, O_RDONLY)) < 0) { + int saved_errno = errno; + + fprintf(stderr, _("Cannot open %s: %s\n"), dfile, strerror(errno)); + + if ((saved_errno == ENOENT) && default_file_used) { + fprintf(stderr, _("Please check if data collecting is enabled\n")); + } + exit(2); + } + + /* Read file magic data */ + n = read(*fd, file_magic, FILE_MAGIC_SIZE); + + if ((n != FILE_MAGIC_SIZE) || + ((file_magic->sysstat_magic != SYSSTAT_MAGIC) && (file_magic->sysstat_magic != SYSSTAT_MAGIC_SWAPPED)) || + ((file_magic->format_magic != FORMAT_MAGIC) && (file_magic->format_magic != FORMAT_MAGIC_SWAPPED) && !ignore)) { +#ifdef DEBUG + fprintf(stderr, "%s: Bytes read=%d sysstat_magic=%x format_magic=%x\n", + __FUNCTION__, n, file_magic->sysstat_magic, file_magic->format_magic); +#endif + /* Display error message and exit */ + handle_invalid_sa_file(*fd, file_magic, dfile, n); + } + + *endian_mismatch = (file_magic->sysstat_magic != SYSSTAT_MAGIC); + if (*endian_mismatch) { + if (do_swap) { + /* Swap bytes for file_magic fields */ + file_magic->sysstat_magic = SYSSTAT_MAGIC; + file_magic->format_magic = __builtin_bswap16(file_magic->format_magic); + } + /* + * Start swapping at field "header_size" position. + * May not exist for older versions but in this case, it won't be used. + */ + swap_struct(fm_types_nr, &file_magic->header_size, 0); + } + + if ((file_magic->sysstat_version > 10) || + ((file_magic->sysstat_version == 10) && (file_magic->sysstat_patchlevel >= 3))) { + /* header_size field exists only for sysstat versions 10.3.1 and later */ + if ((file_magic->header_size <= MIN_FILE_HEADER_SIZE) || + (file_magic->header_size > MAX_FILE_HEADER_SIZE) || + ((file_magic->header_size < FILE_HEADER_SIZE) && !ignore)) { +#ifdef DEBUG + fprintf(stderr, "%s: header_size=%u\n", + __FUNCTION__, file_magic->header_size); +#endif + /* Display error message and exit */ + handle_invalid_sa_file(*fd, file_magic, dfile, n); + } + } + if ((file_magic->sysstat_version > 11) || + ((file_magic->sysstat_version == 11) && (file_magic->sysstat_patchlevel >= 7))) { + /* hdr_types_nr field exists only for sysstat versions 11.7.1 and later */ + if (MAP_SIZE(file_magic->hdr_types_nr) > file_magic->header_size) { +#ifdef DEBUG + fprintf(stderr, "%s: map_size=%u header_size=%u\n", + __FUNCTION__, MAP_SIZE(file_magic->hdr_types_nr), file_magic->header_size); +#endif + handle_invalid_sa_file(*fd, file_magic, dfile, n); + } + } + + if ((file_magic->format_magic != FORMAT_MAGIC) && + (file_magic->format_magic != FORMAT_MAGIC_SWAPPED)) + /* + * This is an old (or new) sa datafile format to + * be read by sadf (since @ignore was set to TRUE). + */ + return -1; + + return 0; +} + +/* + *************************************************************************** + * Open a data file, and perform various checks before reading. + * NB: This is called only when reading a datafile (sar and sadf), never + * when writing or appending data to a datafile. + * + * IN: + * @dfile Name of system activity data file. + * @act Array of activities. + * @ignore Set to 1 if a true sysstat activity file but with a bad + * format should not yield an error message. Used with + * sadf -H (sadf -c doesn't call check_file_actlst() function). + * + * OUT: + * @ifd System activity data file descriptor. + * @file_magic file_magic structure containing data read from file magic + * header. + * @file_hdr file_hdr structure containing data read from file standard + * header. + * @file_actlst Acvtivity list in file. + * @id_seq Activity sequence. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @arch_64 TRUE if file's data come from a 64 bit machine. + *************************************************************************** + */ +void check_file_actlst(int *ifd, char *dfile, struct activity *act[], + struct file_magic *file_magic, struct file_header *file_hdr, + struct file_activity **file_actlst, unsigned int id_seq[], + int ignore, int *endian_mismatch, int *arch_64) +{ + int i, j, k, p; + struct file_activity *fal; + void *buffer = NULL; + + /* Open sa data file and read its magic structure */ + if (sa_open_read_magic(ifd, dfile, file_magic, ignore, endian_mismatch, TRUE) < 0) + /* + * Not current sysstat's format. + * Return now so that sadf -H can display at least + * file's version and magic number. + */ + return; + + /* + * We know now that we have a *compatible* sysstat datafile format + * (correct FORMAT_MAGIC value), and in this case, we should have + * checked header_size value. Anyway, with a corrupted datafile, + * this may not be the case. So check again. + */ + if ((file_magic->header_size <= MIN_FILE_HEADER_SIZE) || + (file_magic->header_size > MAX_FILE_HEADER_SIZE)) { +#ifdef DEBUG + fprintf(stderr, "%s: header_size=%u\n", + __FUNCTION__, file_magic->header_size); +#endif + goto format_error; + } + + /* Allocate buffer for file_header structure */ + SREALLOC(buffer, char, file_magic->header_size); + + /* Read sa data file standard header and allocate activity list */ + sa_fread(*ifd, buffer, (size_t) file_magic->header_size, HARD_SIZE); + /* + * Data file header size (file_magic->header_size) may be greater or + * smaller than FILE_HEADER_SIZE. Remap the fields of the file header + * then copy its contents to the expected structure. + */ + remap_struct(hdr_types_nr, file_magic->hdr_types_nr, buffer, file_magic->header_size); + memcpy(file_hdr, buffer, FILE_HEADER_SIZE); + free(buffer); + buffer = NULL; + + /* Tell that data come from a 64 bit machine */ + *arch_64 = (file_hdr->sa_sizeof_long == SIZEOF_LONG_64BIT); + + /* Normalize endianness for file_hdr structure */ + if (*endian_mismatch) { + swap_struct(hdr_types_nr, file_hdr, *arch_64); + } + + /* + * Sanity checks. + * NB: Compare against MAX_NR_ACT and not NR_ACT because + * we are maybe reading a datafile from a future sysstat version + * with more activities than known today. + */ + if ((file_hdr->sa_act_nr > MAX_NR_ACT) || + (file_hdr->act_size > MAX_FILE_ACTIVITY_SIZE) || + (file_hdr->rec_size > MAX_RECORD_HEADER_SIZE) || + (MAP_SIZE(file_hdr->act_types_nr) > file_hdr->act_size) || + (MAP_SIZE(file_hdr->rec_types_nr) > file_hdr->rec_size)) { +#ifdef DEBUG + fprintf(stderr, "%s: sa_act_nr=%d act_size=%u rec_size=%u map_size(act)=%u map_size(rec)=%u\n", + __FUNCTION__, file_hdr->sa_act_nr, file_hdr->act_size, file_hdr->rec_size, + MAP_SIZE(file_hdr->act_types_nr), MAP_SIZE(file_hdr->rec_types_nr)); +#endif + /* Maybe a "false positive" sysstat datafile? */ + goto format_error; + } + + SREALLOC(buffer, char, file_hdr->act_size); + SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr); + fal = *file_actlst; + + /* Read activity list */ + j = 0; + for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) { + + /* Read current file_activity structure from file */ + sa_fread(*ifd, buffer, (size_t) file_hdr->act_size, HARD_SIZE); + /* + * Data file_activity size (file_hdr->act_size) may be greater or + * smaller than FILE_ACTIVITY_SIZE. Remap the fields of the file's structure + * then copy its contents to the expected structure. + */ + remap_struct(act_types_nr, file_hdr->act_types_nr, buffer, file_hdr->act_size); + memcpy(fal, buffer, FILE_ACTIVITY_SIZE); + + /* Normalize endianness for file_activity structures */ + if (*endian_mismatch) { + swap_struct(act_types_nr, fal, *arch_64); + } + + /* + * Every activity, known or unknown, should have + * at least one item and sub-item. + * Also check that the number of items and sub-items + * doesn't exceed a max value. This is necessary + * because we will use @nr and @nr2 to + * allocate memory to read the file contents. So we + * must make sure the file is not corrupted. + * NB: Another check will be made below for known + * activities which have each a specific max value. + */ + if ((fal->nr < 1) || (fal->nr2 < 1) || + (fal->nr > NR_MAX) || (fal->nr2 > NR2_MAX)) { +#ifdef DEBUG + fprintf(stderr, "%s: id=%d nr=%d nr2=%d\n", + __FUNCTION__, fal->id, fal->nr, fal->nr2); +#endif + goto format_error; + } + + if ((p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND)) < 0) + /* Unknown activity */ + continue; + + if (act[p]->magic != fal->magic) { + /* Bad magical number */ + if (ignore) { + /* + * This is how sadf -H knows that this + * activity has an unknown format. + */ + act[p]->magic = ACTIVITY_MAGIC_UNKNOWN; + } + else + continue; + } + + /* Check max value for known activities */ + if (fal->nr > act[p]->nr_max) { +#ifdef DEBUG + fprintf(stderr, "%s: id=%d nr=%d nr_max=%d\n", + __FUNCTION__, fal->id, fal->nr, act[p]->nr_max); +#endif + goto format_error; + } + + /* + * Number of fields of each type ("long long", or "long" + * or "int") composing the structure with statistics may + * only increase with new sysstat versions. Here, we may + * be reading a file created by current sysstat version, + * or by an older or a newer version. + */ + if (!(((fal->types_nr[0] >= act[p]->gtypes_nr[0]) && + (fal->types_nr[1] >= act[p]->gtypes_nr[1]) && + (fal->types_nr[2] >= act[p]->gtypes_nr[2])) + || + ((fal->types_nr[0] <= act[p]->gtypes_nr[0]) && + (fal->types_nr[1] <= act[p]->gtypes_nr[1]) && + (fal->types_nr[2] <= act[p]->gtypes_nr[2]))) && !ignore) { +#ifdef DEBUG + fprintf(stderr, "%s: id=%d file=%d,%d,%d activity=%d,%d,%d\n", + __FUNCTION__, fal->id, fal->types_nr[0], fal->types_nr[1], fal->types_nr[2], + act[p]->gtypes_nr[0], act[p]->gtypes_nr[1], act[p]->gtypes_nr[2]); +#endif + goto format_error; + } + + if (MAP_SIZE(fal->types_nr) > fal->size) { +#ifdef DEBUG + fprintf(stderr, "%s: id=%d size=%u map_size=%u\n", + __FUNCTION__, fal->id, fal->size, MAP_SIZE(fal->types_nr)); +#endif + goto format_error; + } + + for (k = 0; k < 3; k++) { + act[p]->ftypes_nr[k] = fal->types_nr[k]; + } + + if (fal->size > act[p]->msize) { + act[p]->msize = fal->size; + } + + act[p]->nr_ini = fal->nr; + act[p]->nr2 = fal->nr2; + act[p]->fsize = fal->size; + /* + * This is a known activity with a known format + * (magical number). Only such activities will be displayed. + * (Well, this may also be an unknown format if we have entered sadf -H.) + */ + id_seq[j++] = fal->id; + } + + while (j < NR_ACT) { + id_seq[j++] = 0; + } + + free(buffer); + + /* Check that at least one activity selected by the user is available in file */ + for (i = 0; i < NR_ACT; i++) { + + if (!IS_SELECTED(act[i]->options)) + continue; + + /* Here is a selected activity: Does it exist in file? */ + fal = *file_actlst; + for (j = 0; j < file_hdr->sa_act_nr; j++, fal++) { + if (act[i]->id == fal->id) + break; + } + if (j == file_hdr->sa_act_nr) { + /* No: Unselect it */ + act[i]->options &= ~AO_SELECTED; + } + } + + /* + * None of selected activities exist in file: Abort. + * NB: Error is ignored if we only want to display + * datafile header (sadf -H). + */ + if (!get_activity_nr(act, AO_SELECTED, COUNT_ACTIVITIES) && !ignore) { + fprintf(stderr, _("Requested activities not available in file %s\n"), + dfile); + close(*ifd); + exit(1); + } + + return; + +format_error: + if (buffer) { + free(buffer); + } + handle_invalid_sa_file(*ifd, file_magic, dfile, 0); +} + +/* + *************************************************************************** + * Parse sar activities options (also used by sadf). + * + * IN: + * @argv Arguments list. + * @opt Index in list of arguments. + * @caller Indicate whether it's sar or sadf that called this function. + * + * OUT: + * @act Array of selected activities. + * @flags Common flags and system state. + * + * RETURNS: + * 0 on success. + *************************************************************************** + */ +int parse_sar_opt(char *argv[], int *opt, struct activity *act[], + unsigned int *flags, int caller) +{ + int i, p; + + for (i = 1; *(argv[*opt] + i); i++) { + /* + * Note: argv[*opt] contains something like "-BruW" + * *(argv[*opt] + i) will contain 'B', 'r', etc. + */ + + switch (*(argv[*opt] + i)) { + + case 'A': + select_all_activities(act); + + /* + * Force '-P ALL -I ALL -r ALL -u ALL -F'. + * Setting -F is compulsory because corresponding activity + * has AO_MULTIPLE_OUTPUTS flag set. + */ + p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND); + act[p]->opt_flags |= AO_F_MEMORY + AO_F_SWAP + AO_F_MEM_ALL; + + p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND); + memset(act[p]->bitmap->b_array, ~0, + BITMAP_SIZE(act[p]->bitmap->b_size)); + p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND); + memset(act[p]->bitmap->b_array, ~0, + BITMAP_SIZE(act[p]->bitmap->b_size)); + act[p]->opt_flags = AO_F_CPU_ALL; + + p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND); + act[p]->opt_flags = AO_F_FILESYSTEM; + break; + + case 'B': + SELECT_ACTIVITY(A_PAGE); + break; + + case 'b': + SELECT_ACTIVITY(A_IO); + break; + + case 'C': + *flags |= S_F_COMMENT; + break; + + case 'd': + SELECT_ACTIVITY(A_DISK); + break; + + case 'F': + p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND); + act[p]->options |= AO_SELECTED; + if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_MOUNT)) { + (*opt)++; + act[p]->opt_flags |= AO_F_MOUNT; + return 0; + } + else { + act[p]->opt_flags |= AO_F_FILESYSTEM; + } + break; + + case 'H': + SELECT_ACTIVITY(A_HUGE); + break; + + case 'h': + /* + * Make output easier to read by a human. + * Option -h implies --human and -p (pretty-print). + */ + *flags |= S_F_HUMAN_READ + S_F_UNIT + S_F_DEV_PRETTY; + break; + + case 'j': + if (!argv[*opt + 1]) { + return 1; + } + (*opt)++; + if (strnlen(argv[*opt], MAX_FILE_LEN) >= MAX_FILE_LEN - 1) + return 1; + + strncpy(persistent_name_type, argv[*opt], MAX_FILE_LEN - 1); + persistent_name_type[MAX_FILE_LEN - 1] = '\0'; + strtolower(persistent_name_type); + if (!get_persistent_type_dir(persistent_name_type)) { + fprintf(stderr, _("Invalid type of persistent device name\n")); + return 2; + } + /* + * If persistent device name doesn't exist for device, use + * its pretty name. + */ + *flags |= S_F_PERSIST_NAME + S_F_DEV_PRETTY; + return 0; + break; + + case 'p': + *flags |= S_F_DEV_PRETTY; + break; + + case 'q': + SELECT_ACTIVITY(A_QUEUE); + break; + + case 'r': + p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND); + act[p]->options |= AO_SELECTED; + act[p]->opt_flags |= AO_F_MEMORY; + if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_ALL)) { + (*opt)++; + act[p]->opt_flags |= AO_F_MEM_ALL; + return 0; + } + break; + + case 'S': + p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND); + act[p]->options |= AO_SELECTED; + act[p]->opt_flags |= AO_F_SWAP; + break; + + case 't': + /* + * Check sar option -t here (as it can be combined + * with other ones, eg. "sar -rtu ..." + * But sadf option -t is checked in sadf.c as it won't + * be entered as a sar option after "--". + */ + if (caller != C_SAR) { + return 1; + } + *flags |= S_F_TRUE_TIME; + break; + + case 'u': + p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND); + act[p]->options |= AO_SELECTED; + if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_ALL)) { + (*opt)++; + act[p]->opt_flags = AO_F_CPU_ALL; + return 0; + } + else { + act[p]->opt_flags = AO_F_CPU_DEF; + } + break; + + case 'v': + SELECT_ACTIVITY(A_KTABLES); + break; + + case 'w': + SELECT_ACTIVITY(A_PCSW); + break; + + case 'W': + SELECT_ACTIVITY(A_SWAP); + break; + + case 'y': + SELECT_ACTIVITY(A_SERIAL); + break; + + case 'z': + *flags |= S_F_ZERO_OMIT; + break; + + case 'V': + print_version(); + break; + + default: + return 1; + } + } + return 0; +} + +/* + *************************************************************************** + * Parse sar "-m" option. + * + * IN: + * @argv Arguments list. + * @opt Index in list of arguments. + * + * OUT: + * @act Array of selected activities. + * + * RETURNS: + * 0 on success, 1 otherwise. + *************************************************************************** + */ +int parse_sar_m_opt(char *argv[], int *opt, struct activity *act[]) +{ + char *t; + + for (t = strtok(argv[*opt], ","); t; t = strtok(NULL, ",")) { + if (!strcmp(t, K_CPU)) { + SELECT_ACTIVITY(A_PWR_CPU); + } + else if (!strcmp(t, K_FAN)) { + SELECT_ACTIVITY(A_PWR_FAN); + } + else if (!strcmp(t, K_IN)) { + SELECT_ACTIVITY(A_PWR_IN); + } + else if (!strcmp(t, K_TEMP)) { + SELECT_ACTIVITY(A_PWR_TEMP); + } + else if (!strcmp(t, K_FREQ)) { + SELECT_ACTIVITY(A_PWR_FREQ); + } + else if (!strcmp(t, K_USB)) { + SELECT_ACTIVITY(A_PWR_USB); + } + else if (!strcmp(t, K_ALL)) { + SELECT_ACTIVITY(A_PWR_CPU); + SELECT_ACTIVITY(A_PWR_FAN); + SELECT_ACTIVITY(A_PWR_IN); + SELECT_ACTIVITY(A_PWR_TEMP); + SELECT_ACTIVITY(A_PWR_FREQ); + SELECT_ACTIVITY(A_PWR_USB); + } + else + return 1; + } + + (*opt)++; + return 0; +} + +/* + *************************************************************************** + * Parse sar "-n" option. + * + * IN: + * @argv Arguments list. + * @opt Index in list of arguments. + * + * OUT: + * @act Array of selected activities. + * + * RETURNS: + * 0 on success, 1 otherwise. + *************************************************************************** + */ +int parse_sar_n_opt(char *argv[], int *opt, struct activity *act[]) +{ + char *t; + + for (t = strtok(argv[*opt], ","); t; t = strtok(NULL, ",")) { + if (!strcmp(t, K_DEV)) { + SELECT_ACTIVITY(A_NET_DEV); + } + else if (!strcmp(t, K_EDEV)) { + SELECT_ACTIVITY(A_NET_EDEV); + } + else if (!strcmp(t, K_SOCK)) { + SELECT_ACTIVITY(A_NET_SOCK); + } + else if (!strcmp(t, K_NFS)) { + SELECT_ACTIVITY(A_NET_NFS); + } + else if (!strcmp(t, K_NFSD)) { + SELECT_ACTIVITY(A_NET_NFSD); + } + else if (!strcmp(t, K_IP)) { + SELECT_ACTIVITY(A_NET_IP); + } + else if (!strcmp(t, K_EIP)) { + SELECT_ACTIVITY(A_NET_EIP); + } + else if (!strcmp(t, K_ICMP)) { + SELECT_ACTIVITY(A_NET_ICMP); + } + else if (!strcmp(t, K_EICMP)) { + SELECT_ACTIVITY(A_NET_EICMP); + } + else if (!strcmp(t, K_TCP)) { + SELECT_ACTIVITY(A_NET_TCP); + } + else if (!strcmp(t, K_ETCP)) { + SELECT_ACTIVITY(A_NET_ETCP); + } + else if (!strcmp(t, K_UDP)) { + SELECT_ACTIVITY(A_NET_UDP); + } + else if (!strcmp(t, K_SOCK6)) { + SELECT_ACTIVITY(A_NET_SOCK6); + } + else if (!strcmp(t, K_IP6)) { + SELECT_ACTIVITY(A_NET_IP6); + } + else if (!strcmp(t, K_EIP6)) { + SELECT_ACTIVITY(A_NET_EIP6); + } + else if (!strcmp(t, K_ICMP6)) { + SELECT_ACTIVITY(A_NET_ICMP6); + } + else if (!strcmp(t, K_EICMP6)) { + SELECT_ACTIVITY(A_NET_EICMP6); + } + else if (!strcmp(t, K_UDP6)) { + SELECT_ACTIVITY(A_NET_UDP6); + } + else if (!strcmp(t, K_FC)) { + SELECT_ACTIVITY(A_NET_FC); + } + else if (!strcmp(t, K_SOFT)) { + SELECT_ACTIVITY(A_NET_SOFT); + } + else if (!strcmp(t, K_ALL)) { + SELECT_ACTIVITY(A_NET_DEV); + SELECT_ACTIVITY(A_NET_EDEV); + SELECT_ACTIVITY(A_NET_SOCK); + SELECT_ACTIVITY(A_NET_NFS); + SELECT_ACTIVITY(A_NET_NFSD); + SELECT_ACTIVITY(A_NET_IP); + SELECT_ACTIVITY(A_NET_EIP); + SELECT_ACTIVITY(A_NET_ICMP); + SELECT_ACTIVITY(A_NET_EICMP); + SELECT_ACTIVITY(A_NET_TCP); + SELECT_ACTIVITY(A_NET_ETCP); + SELECT_ACTIVITY(A_NET_UDP); + SELECT_ACTIVITY(A_NET_SOCK6); + SELECT_ACTIVITY(A_NET_IP6); + SELECT_ACTIVITY(A_NET_EIP6); + SELECT_ACTIVITY(A_NET_ICMP6); + SELECT_ACTIVITY(A_NET_EICMP6); + SELECT_ACTIVITY(A_NET_UDP6); + SELECT_ACTIVITY(A_NET_FC); + SELECT_ACTIVITY(A_NET_SOFT); + } + else + return 1; + } + + (*opt)++; + return 0; +} + +/* + *************************************************************************** + * Parse sar "-I" option. + * + * IN: + * @argv Arguments list. + * @opt Index in list of arguments. + * @act Array of activities. + * + * OUT: + * @act Array of activities, with interrupts activity selected. + * + * RETURNS: + * 0 on success, 1 otherwise. + *************************************************************************** + */ +int parse_sar_I_opt(char *argv[], int *opt, struct activity *act[]) +{ + int p; + + /* Select interrupt activity */ + p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND); + act[p]->options |= AO_SELECTED; + + if (argv[++(*opt)]) { + if (parse_values(argv[*opt], act[p]->bitmap->b_array, + act[p]->bitmap->b_size, K_SUM)) + return 1; + (*opt)++; + return 0; + } + + return 1; +} + +/* + *************************************************************************** + * Parse sar and sadf "-P" option. + * + * IN: + * @argv Arguments list. + * @opt Index in list of arguments. + * @act Array of activities. + * + * OUT: + * @flags Common flags and system state. + * @act Array of activities, with CPUs selected. + * + * RETURNS: + * 0 on success, 1 otherwise. + *************************************************************************** + */ +int parse_sa_P_opt(char *argv[], int *opt, unsigned int *flags, struct activity *act[]) +{ + int p; + + p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND); + + if (argv[++(*opt)]) { + if (parse_values(argv[*opt], act[p]->bitmap->b_array, + act[p]->bitmap->b_size, K_LOWERALL)) + return 1; + (*opt)++; + return 0; + } + + return 1; +} + +/* + *************************************************************************** + * Count number of comma-separated values in arguments list. For example, + * the number will be 3 for "sar --dev=sda,sdb,sdc -dp 2 5", 1 for + * "sar --dev=sda -dp 2 5" and 0 for "sar --dev= -dp 2 5". + * + * IN: + * @arg_v Argument containing the list of coma-separated values. + * + * RETURNS: + * Number of comma-separated values in the list. + *************************************************************************** + */ +int count_csval_arg(char *arg_v) +{ + int nr = 0; + char *t; + + if (arg_v[0] == '\0') + return 0; + + if (strchr(arg_v, ',')) { + for (t = arg_v; t; t = strchr(t + 1, ',')) { + nr++; + } + } + if (!nr) { + nr = 1; + } + + return nr; +} + +/* + *************************************************************************** + * Look for item in list. + * + * IN: + * @list Pointer on the start of the linked list. + * @item_name Item name to look for. + * + * RETURNS: + * 1 if item found in list, 0 otherwise. + *************************************************************************** + */ +int search_list_item(struct sa_item *list, char *item_name) +{ + while (list != NULL) { + if (!strcmp(list->item_name, item_name)) + return 1; /* Item found in list */ + list = list->next; + } + + /* Item not found */ + return 0; +} + +/* + *************************************************************************** + * Add item to the list. + * + * IN: + * @list Address of pointer on the start of the linked list. + * @item_name Name of the item. + * @max_len Max length of an item. + * + * RETURNS: + * 1 if item has been added to the list (since it was not previously there), + * and 0 otherwise (item already in list or item name too long). + *************************************************************************** + */ +int add_list_item(struct sa_item **list, char *item_name, int max_len) +{ + struct sa_item *e; + int len; + + if ((len = strnlen(item_name, max_len)) == max_len) + /* Item too long */ + return 0; + + while (*list != NULL) { + e = *list; + if (!strcmp(e->item_name, item_name)) + return 0; /* Item found in list */ + list = &(e->next); + } + + /* Item not found: Add it to the list */ + SREALLOC(*list, struct sa_item, sizeof(struct sa_item)); + e = *list; + if ((e->item_name = (char *) malloc(len + 1)) == NULL) { + perror("malloc"); + exit(4); + } + strcpy(e->item_name, item_name); + + return 1; +} + +/* + *************************************************************************** + * Parse devices entered on the command line and save them in activity's + * list. + * + * IN: + * @argv Argument with list of devices. + * @a Activity for which devices are entered on the command line. + * @max_len Max length of a device name. + * @opt Index in list of arguments. + * @pos Position is string where is located the first device. + * + * OUT: + * @opt Index on next argument. + *************************************************************************** + */ +void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos) +{ + char *t; + + for (t = strtok(argv + pos, ","); t; t = strtok(NULL, ",")) { + a->item_list_sz += add_list_item(&(a->item_list), t, max_len); + } + if (a->item_list_sz) { + a->options |= AO_LIST_ON_CMDLINE; + } + (*opt)++; +} + +/* + *************************************************************************** + * Compute network interface utilization. + * + * IN: + * @st_net_dev Structure with network interface stats. + * @rx Number of bytes received per second. + * @tx Number of bytes transmitted per second. + * + * RETURNS: + * NIC utilization (0-100%). + *************************************************************************** + */ +double compute_ifutil(struct stats_net_dev *st_net_dev, double rx, double tx) +{ + unsigned long long speed; + + if (st_net_dev->speed) { + + speed = (unsigned long long) st_net_dev->speed * 1000000; + + if (st_net_dev->duplex == C_DUPLEX_FULL) { + /* Full duplex */ + if (rx > tx) { + return (rx * 800 / speed); + } + else { + return (tx * 800 / speed); + } + } + else { + /* Half duplex */ + return ((rx + tx) * 800 / speed); + } + } + + return 0; +} + +/* + *************************************************************************** + * Read and replace unprintable characters in comment with ".". + * + * IN: + * @ifd Input file descriptor. + * @comment Comment. + *************************************************************************** + */ +void replace_nonprintable_char(int ifd, char *comment) +{ + int i; + + /* Read comment */ + sa_fread(ifd, comment, MAX_COMMENT_LEN, HARD_SIZE); + comment[MAX_COMMENT_LEN - 1] = '\0'; + + /* Replace non printable chars */ + for (i = 0; i < strlen(comment); i++) { + if (!isprint(comment[i])) + comment[i] = '.'; + } +} + +/* + *************************************************************************** + * Fill the rectime and loctime structures with current record's date and + * time, based on current record's "number of seconds since the epoch" saved + * in file. + * For loctime (if given): The timestamp is expressed in local time. + * For rectime: The timestamp is expressed in UTC, in local time, or in the + * time of the file's creator depending on options entered by the user on the + * command line. + * + * IN: + * @l_flags Flags indicating the type of time expected by the user. + * S_F_LOCAL_TIME means time should be expressed in local time. + * S_F_TRUE_TIME means time should be expressed in time of + * file's creator. + * Default is time expressed in UTC (except for sar, where it + * is local time). + * @record_hdr Record header containing the number of seconds since the + * epoch, and the HH:MM:SS of the file's creator. + * + * OUT: + * @rectime Structure where timestamp for current record has been saved + * (in local time or in UTC depending on options used). + * @loctime If given, structure where timestamp for current record has + * been saved (expressed in local time). This field will be used + * for time comparison if options -s and/or -e have been used. + * + * RETURNS: + * 1 if an error was detected, or 0 otherwise. + *************************************************************************** +*/ +int sa_get_record_timestamp_struct(unsigned int l_flags, struct record_header *record_hdr, + struct tm *rectime, struct tm *loctime) +{ + struct tm *ltm = NULL; + int rc = 0; + + /* Fill localtime structure if given */ + if (loctime) { + if ((ltm = localtime((const time_t *) &(record_hdr->ust_time))) != NULL) { + *loctime = *ltm; + } + else { + rc = 1; + } + } + + /* Fill generic rectime structure */ + if (PRINT_LOCAL_TIME(l_flags) && !ltm) { + /* Get local time if not already done */ + ltm = localtime((const time_t *) &(record_hdr->ust_time)); + } + + if (!PRINT_LOCAL_TIME(l_flags) && !PRINT_TRUE_TIME(l_flags)) { + /* + * Get time in UTC + * (the user doesn't want local time nor time of file's creator). + */ + ltm = gmtime((const time_t *) &(record_hdr->ust_time)); + } + + if (ltm) { + /* Done even in true time mode so that we have some default values */ + *rectime = *ltm; + } + else { + rc = 1; + } + + if (PRINT_TRUE_TIME(l_flags)) { + /* Time of file's creator */ + rectime->tm_hour = record_hdr->hour; + rectime->tm_min = record_hdr->minute; + rectime->tm_sec = record_hdr->second; + } + + return rc; +} + +/* + *************************************************************************** + * Set current record's timestamp strings (date and time) using the time + * data saved in @rectime structure. The string may be the number of seconds + * since the epoch if flag S_F_SEC_EPOCH has been set. + * + * IN: + * @l_flags Flags indicating the type of time expected by the user. + * S_F_SEC_EPOCH means the time should be expressed in seconds + * since the epoch (01/01/1970). + * @record_hdr Record header containing the number of seconds since the + * epoch. + * @cur_date String where timestamp's date will be saved. May be NULL. + * @cur_time String where timestamp's time will be saved. + * @len Maximum length of timestamp strings. + * @rectime Structure with current timestamp (expressed in local time or + * in UTC depending on whether options -T or -t have been used + * or not) that should be broken down in date and time strings. + * + * OUT: + * @cur_date Timestamp's date string (if expected). + * @cur_time Timestamp's time string. May contain the number of seconds + * since the epoch (01-01-1970) if corresponding option has + * been used. + *************************************************************************** +*/ +void set_record_timestamp_string(unsigned int l_flags, struct record_header *record_hdr, + char *cur_date, char *cur_time, int len, struct tm *rectime) +{ + /* Set cur_time date value */ + if (PRINT_SEC_EPOCH(l_flags) && cur_date) { + sprintf(cur_time, "%llu", record_hdr->ust_time); + strcpy(cur_date, ""); + } + else { + /* + * If options -T or -t have been used then cur_time is + * expressed in local time. Else it is expressed in UTC. + */ + if (cur_date) { + strftime(cur_date, len, "%Y-%m-%d", rectime); + } + if (USE_PREFD_TIME_OUTPUT(l_flags)) { + strftime(cur_time, len, "%X", rectime); + } + else { + strftime(cur_time, len, "%H:%M:%S", rectime); + } + } +} + +/* + *************************************************************************** + * Print contents of a special (RESTART or COMMENT) record. + * Note: This function is called only when reading a file. + * + * IN: + * @record_hdr Current record header. + * @l_flags Flags for common options. + * @tm_start Structure filled when option -s has been used. + * @tm_end Structure filled when option -e has been used. + * @rtype Record type (R_RESTART or R_COMMENT). + * @ifd Input file descriptor. + * @rectime Structure where timestamp (expressed in local time or in UTC + * depending on whether options -T/-t have been used or not) can + * be saved for current record. + * @loctime Structure where timestamp (expressed in local time) can be + * saved for current record. May be NULL. + * @file Name of file being read. + * @tab Number of tabulations to print. + * @file_magic file_magic structure filled with file magic header data. + * @file_hdr System activity file standard header. + * @act Array of activities. + * @ofmt Pointer on report output format structure. + * @endian_mismatch + * TRUE if file's data don't match current machine's endianness. + * @arch_64 TRUE if file's data come from a 64 bit machine. + * + * OUT: + * @rectime Structure where timestamp (expressed in local time or in UTC) + * has been saved. + * @loctime Structure where timestamp (expressed in local time) has been + * saved (if requested). + * + * RETURNS: + * 1 if the record has been successfully displayed, and 0 otherwise. + *************************************************************************** + */ +int print_special_record(struct record_header *record_hdr, unsigned int l_flags, + struct tstamp *tm_start, struct tstamp *tm_end, int rtype, int ifd, + struct tm *rectime, struct tm *loctime, char *file, int tab, + struct file_magic *file_magic, struct file_header *file_hdr, + struct activity *act[], struct report_format *ofmt, + int endian_mismatch, int arch_64) +{ + char cur_date[TIMESTAMP_LEN], cur_time[TIMESTAMP_LEN]; + int dp = 1; + int p; + + /* Fill timestamp structure (rectime) for current record */ + if (sa_get_record_timestamp_struct(l_flags, record_hdr, rectime, loctime)) + return 0; + + /* If loctime is NULL, then use rectime for comparison */ + if (!loctime) { + loctime = rectime; + } + + /* The record must be in the interval specified by -s/-e options */ + if ((tm_start->use && (datecmp(loctime, tm_start) < 0)) || + (tm_end->use && (datecmp(loctime, tm_end) > 0))) { + /* Will not display the special record */ + dp = 0; + } + else { + /* Set date and time strings to be displayed for current record */ + set_record_timestamp_string(l_flags, record_hdr, + cur_date, cur_time, TIMESTAMP_LEN, rectime); + } + + if (rtype == R_RESTART) { + /* Read new cpu number following RESTART record */ + file_hdr->sa_cpu_nr = read_nr_value(ifd, file, file_magic, + endian_mismatch, arch_64, TRUE); + + /* + * We don't know if CPU related activities will be displayed or not. + * But if it is the case, @nr_ini will be used in the loop + * to process all CPUs. So update their value here and + * reallocate buffers if needed. + * NB: We may have nr_allocated=0 here if the activity has + * not been collected in file (or if it has an unknown format). + */ + for (p = 0; p < NR_ACT; p++) { + if (HAS_PERSISTENT_VALUES(act[p]->options)) { + act[p]->nr_ini = file_hdr->sa_cpu_nr; + if (act[p]->nr_ini > act[p]->nr_allocated) { + reallocate_all_buffers(act[p], act[p]->nr_ini); + } + } + } + + if (!dp) + return 0; + + if (*ofmt->f_restart) { + (*ofmt->f_restart)(&tab, F_MAIN, cur_date, cur_time, + !PRINT_LOCAL_TIME(l_flags) && + !PRINT_TRUE_TIME(l_flags), file_hdr); + } + } + else if (rtype == R_COMMENT) { + char file_comment[MAX_COMMENT_LEN]; + + /* Read and replace non printable chars in comment */ + replace_nonprintable_char(ifd, file_comment); + + if (!dp || !DISPLAY_COMMENT(l_flags)) + return 0; + + if (*ofmt->f_comment) { + (*ofmt->f_comment)(&tab, F_MAIN, cur_date, cur_time, + !PRINT_LOCAL_TIME(l_flags) && + !PRINT_TRUE_TIME(l_flags), file_comment, + file_hdr); + } + } + + return 1; +} + +/* + *************************************************************************** + * Compute global CPU statistics as the sum of individual CPU ones, and + * calculate interval for global CPU. + * Also identify offline CPU. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @flags Flags for common options and system state. + * @offline_cpu_bitmap + * CPU bitmap for offline CPU. + * + * OUT: + * @a Activity structure with updated statistics (those for global + * CPU, and also those for offline CPU). + * @offline_cpu_bitmap + * CPU bitmap with offline CPU. + * + * RETURNS: + * Interval for global CPU. + *************************************************************************** + */ +unsigned long long get_global_cpu_statistics(struct activity *a, int prev, int curr, + unsigned int flags, unsigned char offline_cpu_bitmap[]) +{ + int i; + unsigned long long tot_jiffies_c, tot_jiffies_p; + unsigned long long deltot_jiffies = 0; + struct stats_cpu *scc, *scp; + struct stats_cpu *scc_all = (struct stats_cpu *) ((char *) a->buf[curr]); + struct stats_cpu *scp_all = (struct stats_cpu *) ((char *) a->buf[prev]); + + /* + * Initial processing. + * Compute CPU "all" as sum of all individual CPU. Done only on SMP machines (a->nr_ini > 1). + * For UP machines we keep the values read from global CPU line in /proc/stat. + * Also look for offline CPU: They won't be displayed, and some of their values may + * have to be modified. + */ + if (a->nr_ini > 1) { + memset(scc_all, 0, sizeof(struct stats_cpu)); + memset(scp_all, 0, sizeof(struct stats_cpu)); + } + + for (i = 1; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { + + /* + * The size of a->buf[...] CPU structure may be different from the default + * sizeof(struct stats_cpu) value if data have been read from a file! + * That's why we don't use a syntax like: + * scc = (struct stats_cpu *) a->buf[...] + i; + */ + scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize); + scp = (struct stats_cpu *) ((char *) a->buf[prev] + i * a->msize); + + /* + * Compute the total number of jiffies spent by current processor. + * NB: Don't add cpu_guest/cpu_guest_nice because cpu_user/cpu_nice + * already include them. + */ + tot_jiffies_c = scc->cpu_user + scc->cpu_nice + + scc->cpu_sys + scc->cpu_idle + + scc->cpu_iowait + scc->cpu_hardirq + + scc->cpu_steal + scc->cpu_softirq; + tot_jiffies_p = scp->cpu_user + scp->cpu_nice + + scp->cpu_sys + scp->cpu_idle + + scp->cpu_iowait + scp->cpu_hardirq + + scp->cpu_steal + scp->cpu_softirq; + + /* + * If the CPU is offline then it is omited from /proc/stat: + * All the fields couldn't have been read and the sum of them is zero. + */ + if (tot_jiffies_c == 0) { + /* + * CPU is currently offline. + * Set current struct fields (which have been set to zero) + * to values from previous iteration. Hence their values won't + * jump from zero when the CPU comes back online. + * Note that this workaround no longer fully applies with recent kernels, + * as I have noticed that when a CPU comes back online, some fields + * restart from their previous value (e.g. user, nice, system) + * whereas others restart from zero (idle, iowait)! To deal with this, + * the get_per_cpu_interval() function will set these previous values + * to zero if necessary. + */ + *scc = *scp; + + /* + * Mark CPU as offline to not display it + * (and thus it will not be confused with a tickless CPU). + */ + offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07); + } + + if ((tot_jiffies_p == 0) && !WANT_SINCE_BOOT(flags)) { + /* + * CPU has just come back online. + * Unfortunately, no reference values are available + * from a previous iteration, probably because it was + * already offline when the first sample has been taken. + * So don't display that CPU to prevent "jump-from-zero" + * output syndrome, and don't take it into account for CPU "all". + */ + offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07); + continue; + } + + /* + * Get interval for current CPU and add it to global CPU. + * Note: Previous idle and iowait values (saved in scp) may be modified here. + */ + deltot_jiffies += get_per_cpu_interval(scc, scp); + + scc_all->cpu_user += scc->cpu_user; + scp_all->cpu_user += scp->cpu_user; + + scc_all->cpu_nice += scc->cpu_nice; + scp_all->cpu_nice += scp->cpu_nice; + + scc_all->cpu_sys += scc->cpu_sys; + scp_all->cpu_sys += scp->cpu_sys; + + scc_all->cpu_idle += scc->cpu_idle; + scp_all->cpu_idle += scp->cpu_idle; + + scc_all->cpu_iowait += scc->cpu_iowait; + scp_all->cpu_iowait += scp->cpu_iowait; + + scc_all->cpu_hardirq += scc->cpu_hardirq; + scp_all->cpu_hardirq += scp->cpu_hardirq; + + scc_all->cpu_steal += scc->cpu_steal; + scp_all->cpu_steal += scp->cpu_steal; + + scc_all->cpu_softirq += scc->cpu_softirq; + scp_all->cpu_softirq += scp->cpu_softirq; + + scc_all->cpu_guest += scc->cpu_guest; + scp_all->cpu_guest += scp->cpu_guest; + + scc_all->cpu_guest_nice += scc->cpu_guest_nice; + scp_all->cpu_guest_nice += scp->cpu_guest_nice; + } + + return deltot_jiffies; +} + +/* + *************************************************************************** + * Compute softnet statistics for CPU "all" as the sum of individual CPU + * ones. + * Also identify offline CPU. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @flags Flags for common options and system state. + * @offline_cpu_bitmap + * CPU bitmap for offline CPU. + * + * OUT: + * @a Activity structure with updated statistics (those for global + * CPU, and also those for offline CPU). + * @offline_cpu_bitmap + * CPU bitmap with offline CPU. + *************************************************************************** + */ +void get_global_soft_statistics(struct activity *a, int prev, int curr, + unsigned int flags, unsigned char offline_cpu_bitmap[]) +{ + int i; + struct stats_softnet *ssnc, *ssnp; + struct stats_softnet *ssnc_all = (struct stats_softnet *) ((char *) a->buf[curr]); + struct stats_softnet *ssnp_all = (struct stats_softnet *) ((char *) a->buf[prev]); + + /* + * Init structures that will contain values for CPU "all". + * CPU "all" doesn't exist in /proc/net/softnet_stat file, so + * we compute its values as the sum of the values of each CPU. + */ + memset(ssnc_all, 0, sizeof(struct stats_softnet)); + memset(ssnp_all, 0, sizeof(struct stats_softnet)); + + for (i = 1; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { + + /* + * The size of a->buf[...] CPU structure may be different from the default + * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file! + * That's why we don't use a syntax like: + * ssnc = (struct stats_softnet *) a->buf[...] + i; + */ + ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize); + ssnp = (struct stats_softnet *) ((char *) a->buf[prev] + i * a->msize); + + if (ssnc->processed + ssnc->dropped + ssnc->time_squeeze + + ssnc->received_rps + ssnc->flow_limit == 0) { + /* Assume current CPU is offline */ + *ssnc = *ssnp; + offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07); + } + + if ((ssnp->processed + ssnp->dropped + ssnp->time_squeeze + + ssnp->received_rps + ssnp->flow_limit == 0) && !WANT_SINCE_BOOT(flags)) { + /* Current CPU back online but no previous sample for it */ + offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07); + continue; + } + + ssnc_all->processed += ssnc->processed; + ssnc_all->dropped += ssnc->dropped; + ssnc_all->time_squeeze += ssnc->time_squeeze; + ssnc_all->received_rps += ssnc->received_rps; + ssnc_all->flow_limit += ssnc->flow_limit; + + ssnp_all->processed += ssnp->processed; + ssnp_all->dropped += ssnp->dropped; + ssnp_all->time_squeeze += ssnp->time_squeeze; + ssnp_all->received_rps += ssnp->received_rps; + ssnp_all->flow_limit += ssnp->flow_limit; + } +} + +/* + *************************************************************************** + * Get device name (whether pretty-printed, persistent or not). + * + * IN: + * @major Major number of the device. + * @minor Minor number of the device. + * @flags Flags for common options and system state. + * + * RETURNS: + * The name of the device. + *************************************************************************** + */ +char *get_sa_devname(unsigned int major, unsigned int minor, unsigned int flags) +{ + char *dev_name = NULL, *persist_dev_name = NULL; + + if (DISPLAY_PERSIST_NAME_S(flags)) { + persist_dev_name = get_persistent_name_from_pretty(get_devname(major, minor, TRUE)); + } + + if (persist_dev_name) { + dev_name = persist_dev_name; + } + else { + if ((USE_PRETTY_OPTION(flags)) && (major == dm_major)) { + dev_name = transform_devmapname(major, minor); + } + + if (!dev_name) { + dev_name = get_devname(major, minor, + USE_PRETTY_OPTION(flags)); + } + } + + return dev_name; +} + +#endif /* SOURCE_SADC undefined */ diff --git a/tests/TLIST b/tests/TLIST index 24b8e02..1d02c14 100644 --- a/tests/TLIST +++ b/tests/TLIST @@ -94,6 +94,12 @@ NOTES: 00700 LC_ALL=C TZ=GMT ./sar -C -A -f tests/data-ppc-11.7.2 > tests/out.data-ppc-11.7.2.tmp 00702 diff -u tests/out.data-ppc-11.7.2.tmp tests/expected.data-ppc-11.7.2 +===== Reading data.tmp using an old sysstat version +00750 LC_ALL=C TZ=GMT ./tests/ini/inisar -C -A -f tests/data.tmp > tests/out.data-ini.tmp +00752 diff -u tests/out.data-ini.tmp tests/expected.data-ini + [There may be some small differences in ext disks stats between initial and current version + outputs, because initial version doesn't take into account discard fields] + ===== Testing sar's options 00800 LC_ALL=C TZ=GMT ./sar --iface=lo,enp6s0,eth0 -n DEV,EDEV -f tests/data.tmp > tests/out.sar-iface.tmp 00802 diff -u tests/out.sar-iface.tmp tests/expected.sar-iface diff --git a/tests/expected.data-ini b/tests/expected.data-ini new file mode 100644 index 0000000..630fd59 --- /dev/null +++ b/tests/expected.data-ini @@ -0,0 +1,4192 @@ +Linux 1.2.3-TEST (SYSSTAT.TEST) 04/18/19 _x86_64_ (8 CPU) + +13:20:09 CPU %usr %nice %sys %iowait %steal %irq %soft %guest %gnice %idle +13:20:19 all 2.15 12.50 1.84 0.12 0.00 0.34 0.19 0.00 0.00 82.88 +13:20:19 0 2.71 0.03 2.16 0.00 0.00 0.32 0.64 0.00 0.00 94.14 +13:20:19 1 2.85 0.00 4.28 0.00 0.00 0.68 0.19 0.00 0.00 91.99 +13:20:19 2 2.25 0.03 1.51 0.68 0.00 0.23 0.13 0.00 0.00 95.18 +13:20:19 3 0.00 99.55 0.06 0.00 0.00 0.32 0.06 0.00 0.00 0.00 +13:20:19 4 2.41 0.00 1.61 0.03 0.00 0.26 0.19 0.00 0.00 95.50 +13:20:19 5 1.65 0.00 2.33 0.00 0.00 0.36 0.10 0.00 0.00 95.57 +13:20:19 6 2.41 0.00 2.03 0.16 0.00 0.48 0.10 0.00 0.00 94.82 +13:20:19 7 2.89 0.00 0.74 0.06 0.00 0.06 0.06 0.00 0.00 96.18 +13:20:29 all 2.28 0.00 1.55 0.50 0.00 0.19 0.19 0.00 0.00 95.29 +13:20:29 0 1.25 0.00 1.51 0.35 0.00 0.19 0.58 0.00 0.00 96.12 +13:20:29 1 2.15 0.00 0.96 0.77 0.00 0.10 0.16 0.00 0.00 95.87 +13:20:29 2 3.27 0.00 1.73 0.77 0.00 0.22 0.10 0.00 0.00 93.90 +13:20:29 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +13:20:29 4 3.44 0.00 2.16 0.84 0.00 0.32 0.16 0.00 0.00 93.08 +13:20:29 5 2.76 0.00 2.08 0.16 0.00 0.19 0.10 0.00 0.00 94.71 +13:20:29 7 0.83 0.00 0.83 0.10 0.00 0.10 0.06 0.00 0.00 98.08 +13:20:39 all 2.66 23.20 1.74 0.16 0.00 0.33 0.20 0.00 0.00 71.71 +13:20:39 0 2.19 52.01 1.46 0.00 0.00 0.36 0.39 0.00 0.00 43.59 +13:20:39 1 3.45 0.00 2.33 0.55 0.00 0.34 0.39 0.00 0.00 92.94 +13:20:39 2 0.68 16.81 1.77 0.39 0.00 0.34 0.08 0.00 0.00 79.93 +13:20:39 3 2.33 44.73 1.03 0.01 0.00 0.29 0.16 0.00 0.00 51.44 +13:20:39 4 3.11 31.18 2.27 0.00 0.00 0.50 0.18 0.00 0.00 62.76 +13:20:39 5 3.92 0.00 2.56 0.03 0.00 0.37 0.10 0.00 0.00 93.02 +13:20:39 7 3.23 0.00 1.35 0.26 0.00 0.13 0.13 0.00 0.00 94.90 +13:20:49 all 6.53 9.63 3.44 0.54 0.00 0.60 0.38 0.00 0.00 78.89 +13:20:49 0 2.69 47.44 1.26 0.18 0.00 0.36 0.85 0.00 0.00 47.22 +13:20:49 1 9.25 0.00 4.06 0.18 0.00 0.59 0.95 0.00 0.00 84.97 +13:20:49 2 9.90 0.04 3.78 0.90 0.00 0.49 0.49 0.00 0.00 84.39 +13:20:49 3 31.64 0.00 18.43 4.30 0.00 2.46 1.23 0.00 0.00 41.94 +13:20:49 4 4.54 52.40 1.80 0.00 0.00 0.49 0.27 0.00 0.00 40.50 +13:20:49 5 7.62 0.00 4.01 0.14 0.00 0.50 0.23 0.00 0.00 87.51 +13:20:49 6 4.13 0.01 2.72 0.63 0.00 0.59 0.13 0.00 0.00 91.79 +13:20:49 7 7.81 0.00 4.38 0.32 0.00 0.63 0.23 0.00 0.00 86.63 +Average: all 3.51 13.20 2.22 0.31 0.00 0.38 0.25 0.00 0.00 80.13 +Average: 0 2.17 24.86 1.61 0.12 0.00 0.31 0.59 0.00 0.00 70.34 +Average: 1 4.02 0.00 2.78 0.40 0.00 0.41 0.38 0.00 0.00 92.01 +Average: 2 3.40 5.26 2.06 0.65 0.00 0.31 0.17 0.00 0.00 88.14 +Average: 3 5.15 86.99 2.71 0.39 0.00 0.64 0.29 0.00 0.00 3.82 +Average: 4 3.28 19.24 1.99 0.22 0.00 0.39 0.20 0.00 0.00 74.69 +Average: 5 3.72 0.00 2.64 0.07 0.00 0.34 0.12 0.00 0.00 93.10 +Average: 6 3.69 0.01 2.54 0.51 0.00 0.56 0.12 0.00 0.00 92.56 +Average: 7 3.36 0.00 1.61 0.18 0.00 0.20 0.11 0.00 0.00 94.54 + +13:20:09 proc/s cswch/s +13:20:19 3.56 68409.30 +13:20:29 4.83 46287.74 +13:20:39 3.66 64945.01 +13:20:49 5.27 108286.78 +Average: 4.23 68964.08 + +13:20:09 INTR intr/s +13:20:19 sum 35525.06 +13:20:19 0 0.00 +13:20:19 1 0.00 +13:20:19 2 0.00 +13:20:19 3 0.00 +13:20:19 4 0.00 +13:20:19 5 0.00 +13:20:19 6 0.00 +13:20:19 7 0.00 +13:20:19 8 0.00 +13:20:19 9 0.00 +13:20:19 10 0.00 +13:20:19 11 0.00 +13:20:19 12 0.00 +13:20:19 13 0.00 +13:20:19 14 0.00 +13:20:19 15 0.00 +13:20:19 16 0.00 +13:20:19 17 0.00 +13:20:19 18 0.00 +13:20:19 19 25.92 +13:20:19 20 0.00 +13:20:19 21 0.00 +13:20:19 22 0.00 +13:20:19 23 35.03 +13:20:19 24 10.39 +13:20:19 25 0.00 +13:20:19 26 0.00 +13:20:19 27 0.00 +13:20:19 28 0.00 +13:20:19 29 0.00 +13:20:19 30 0.00 +13:20:19 31 0.00 +13:20:19 32 0.00 +13:20:19 33 15.11 +13:20:19 34 149.98 +13:20:19 35 0.00 +13:20:19 36 0.00 +13:20:19 37 0.00 +13:20:19 38 0.00 +13:20:19 39 0.00 +13:20:19 40 0.00 +13:20:19 41 0.00 +13:20:19 42 0.00 +13:20:19 43 0.00 +13:20:19 44 0.00 +13:20:19 45 0.00 +13:20:19 46 0.00 +13:20:19 47 0.00 +13:20:19 48 0.00 +13:20:19 49 0.00 +13:20:19 50 0.00 +13:20:19 51 0.00 +13:20:19 52 0.00 +13:20:19 53 0.00 +13:20:19 54 0.00 +13:20:19 55 0.00 +13:20:19 56 0.00 +13:20:19 57 0.00 +13:20:19 58 0.00 +13:20:19 59 0.00 +13:20:19 60 0.00 +13:20:19 61 0.00 +13:20:19 62 0.00 +13:20:19 63 0.00 +13:20:19 64 0.00 +13:20:19 65 0.00 +13:20:19 66 0.00 +13:20:19 67 0.00 +13:20:19 68 0.00 +13:20:19 69 0.00 +13:20:19 70 0.00 +13:20:19 71 0.00 +13:20:19 72 0.00 +13:20:19 73 0.00 +13:20:19 74 0.00 +13:20:19 75 0.00 +13:20:19 76 0.00 +13:20:19 77 0.00 +13:20:19 78 0.00 +13:20:19 79 0.00 +13:20:19 80 0.00 +13:20:19 81 0.00 +13:20:19 82 0.00 +13:20:19 83 0.00 +13:20:19 84 0.00 +13:20:19 85 0.00 +13:20:19 86 0.00 +13:20:19 87 0.00 +13:20:19 88 0.00 +13:20:19 89 0.00 +13:20:19 90 0.00 +13:20:19 91 0.00 +13:20:19 92 0.00 +13:20:19 93 0.00 +13:20:19 94 0.00 +13:20:19 95 0.00 +13:20:19 96 0.00 +13:20:19 97 0.00 +13:20:19 98 0.00 +13:20:19 99 0.00 +13:20:19 100 0.00 +13:20:19 101 0.00 +13:20:19 102 0.00 +13:20:19 103 0.00 +13:20:19 104 0.00 +13:20:19 105 0.00 +13:20:19 106 0.00 +13:20:19 107 0.00 +13:20:19 108 0.00 +13:20:19 109 0.00 +13:20:19 110 0.00 +13:20:19 111 0.00 +13:20:19 112 0.00 +13:20:19 113 0.00 +13:20:19 114 0.00 +13:20:19 115 0.00 +13:20:19 116 0.00 +13:20:19 117 0.00 +13:20:19 118 0.00 +13:20:19 119 0.00 +13:20:19 120 0.00 +13:20:19 121 0.00 +13:20:19 122 0.00 +13:20:19 123 0.00 +13:20:19 124 0.00 +13:20:19 125 0.00 +13:20:19 126 0.00 +13:20:19 127 0.00 +13:20:19 128 0.00 +13:20:19 129 0.00 +13:20:19 130 0.00 +13:20:19 131 0.00 +13:20:19 132 0.00 +13:20:19 133 0.00 +13:20:19 134 0.00 +13:20:19 135 0.00 +13:20:19 136 0.00 +13:20:19 137 0.00 +13:20:19 138 0.00 +13:20:19 139 0.00 +13:20:19 140 0.00 +13:20:19 141 0.00 +13:20:19 142 0.00 +13:20:19 143 0.00 +13:20:19 144 0.00 +13:20:19 145 0.00 +13:20:19 146 0.00 +13:20:19 147 0.00 +13:20:19 148 0.00 +13:20:19 149 0.00 +13:20:19 150 0.00 +13:20:19 151 0.00 +13:20:19 152 0.00 +13:20:19 153 0.00 +13:20:19 154 0.00 +13:20:19 155 0.00 +13:20:19 156 0.00 +13:20:19 157 0.00 +13:20:19 158 0.00 +13:20:19 159 0.00 +13:20:19 160 0.00 +13:20:19 161 0.00 +13:20:19 162 0.00 +13:20:19 163 0.00 +13:20:19 164 0.00 +13:20:19 165 0.00 +13:20:19 166 0.00 +13:20:19 167 0.00 +13:20:19 168 0.00 +13:20:19 169 0.00 +13:20:19 170 0.00 +13:20:19 171 0.00 +13:20:19 172 0.00 +13:20:19 173 0.00 +13:20:19 174 0.00 +13:20:19 175 0.00 +13:20:19 176 0.00 +13:20:19 177 0.00 +13:20:19 178 0.00 +13:20:19 179 0.00 +13:20:19 180 0.00 +13:20:19 181 0.00 +13:20:19 182 0.00 +13:20:19 183 0.00 +13:20:19 184 0.00 +13:20:19 185 0.00 +13:20:19 186 0.00 +13:20:19 187 0.00 +13:20:19 188 0.00 +13:20:19 189 0.00 +13:20:19 190 0.00 +13:20:19 191 0.00 +13:20:19 192 0.00 +13:20:19 193 0.00 +13:20:19 194 0.00 +13:20:19 195 0.00 +13:20:19 196 0.00 +13:20:19 197 0.00 +13:20:19 198 0.00 +13:20:19 199 0.00 +13:20:19 200 0.00 +13:20:19 201 0.00 +13:20:19 202 0.00 +13:20:19 203 0.00 +13:20:19 204 0.00 +13:20:19 205 0.00 +13:20:19 206 0.00 +13:20:19 207 0.00 +13:20:19 208 0.00 +13:20:19 209 0.00 +13:20:19 210 0.00 +13:20:19 211 0.00 +13:20:19 212 0.00 +13:20:19 213 0.00 +13:20:19 214 0.00 +13:20:19 215 0.00 +13:20:19 216 0.00 +13:20:19 217 0.00 +13:20:19 218 0.00 +13:20:19 219 0.00 +13:20:19 220 0.00 +13:20:19 221 0.00 +13:20:19 222 0.00 +13:20:19 223 0.00 +13:20:19 224 0.00 +13:20:19 225 0.00 +13:20:19 226 0.00 +13:20:19 227 0.00 +13:20:19 228 0.00 +13:20:19 229 0.00 +13:20:19 230 0.00 +13:20:19 231 0.00 +13:20:19 232 0.00 +13:20:19 233 0.00 +13:20:19 234 0.00 +13:20:19 235 0.00 +13:20:19 236 0.00 +13:20:19 237 0.00 +13:20:19 238 0.00 +13:20:19 239 0.00 +13:20:19 240 0.00 +13:20:19 241 0.00 +13:20:19 242 0.00 +13:20:19 243 0.00 +13:20:19 244 0.00 +13:20:19 245 0.00 +13:20:19 246 0.00 +13:20:19 247 0.00 +13:20:19 248 0.00 +13:20:19 249 0.00 +13:20:19 250 0.00 +13:20:19 251 0.00 +13:20:19 252 0.00 +13:20:19 253 0.00 +13:20:19 254 0.00 +13:20:19 255 0.00 +13:20:19 256 0.00 +13:20:19 257 0.00 +13:20:19 258 0.00 +13:20:19 259 0.00 +13:20:19 260 0.00 +13:20:19 261 0.00 +13:20:19 262 0.00 +13:20:19 263 0.00 +13:20:19 264 0.00 +13:20:19 265 0.00 +13:20:19 266 0.00 +13:20:19 267 0.00 +13:20:19 268 0.00 +13:20:19 269 0.00 +13:20:19 270 0.00 +13:20:19 271 0.00 +13:20:19 272 0.00 +13:20:19 273 0.00 +13:20:19 274 0.00 +13:20:19 275 0.00 +13:20:19 276 0.00 +13:20:19 277 0.00 +13:20:19 278 0.00 +13:20:19 279 0.00 +13:20:19 280 0.00 +13:20:19 281 0.00 +13:20:19 282 0.00 +13:20:19 283 0.00 +13:20:19 284 0.00 +13:20:19 285 0.00 +13:20:19 286 0.00 +13:20:19 287 0.00 +13:20:19 288 0.00 +13:20:19 289 0.00 +13:20:19 290 0.00 +13:20:19 291 0.00 +13:20:19 292 0.00 +13:20:19 293 0.00 +13:20:19 294 0.00 +13:20:19 295 0.00 +13:20:19 296 0.00 +13:20:19 297 0.00 +13:20:19 298 0.00 +13:20:19 299 0.00 +13:20:19 300 0.00 +13:20:19 301 0.00 +13:20:19 302 0.00 +13:20:19 303 0.00 +13:20:19 304 0.00 +13:20:19 305 0.00 +13:20:19 306 0.00 +13:20:19 307 0.00 +13:20:19 308 0.00 +13:20:19 309 0.00 +13:20:19 310 0.00 +13:20:19 311 0.00 +13:20:19 312 0.00 +13:20:19 313 0.00 +13:20:19 314 0.00 +13:20:19 315 0.00 +13:20:19 316 0.00 +13:20:19 317 0.00 +13:20:19 318 0.00 +13:20:19 319 0.00 +13:20:19 320 0.00 +13:20:19 321 0.00 +13:20:19 322 0.00 +13:20:19 323 0.00 +13:20:19 324 0.00 +13:20:19 325 0.00 +13:20:19 326 0.00 +13:20:19 327 0.00 +13:20:19 328 0.00 +13:20:19 329 0.00 +13:20:19 330 0.00 +13:20:19 331 0.00 +13:20:19 332 0.00 +13:20:19 333 0.00 +13:20:19 334 0.00 +13:20:19 335 0.00 +13:20:19 336 0.00 +13:20:19 337 0.00 +13:20:19 338 0.00 +13:20:19 339 0.00 +13:20:19 340 0.00 +13:20:19 341 0.00 +13:20:19 342 0.00 +13:20:19 343 0.00 +13:20:19 344 0.00 +13:20:19 345 0.00 +13:20:19 346 0.00 +13:20:19 347 0.00 +13:20:19 348 0.00 +13:20:19 349 0.00 +13:20:19 350 0.00 +13:20:19 351 0.00 +13:20:19 352 0.00 +13:20:19 353 0.00 +13:20:19 354 0.00 +13:20:19 355 0.00 +13:20:19 356 0.00 +13:20:19 357 0.00 +13:20:19 358 0.00 +13:20:19 359 0.00 +13:20:19 360 0.00 +13:20:19 361 0.00 +13:20:19 362 0.00 +13:20:19 363 0.00 +13:20:19 364 0.00 +13:20:19 365 0.00 +13:20:19 366 0.00 +13:20:19 367 0.00 +13:20:19 368 0.00 +13:20:19 369 0.00 +13:20:19 370 0.00 +13:20:19 371 0.00 +13:20:19 372 0.00 +13:20:19 373 0.00 +13:20:19 374 0.00 +13:20:19 375 0.00 +13:20:19 376 0.00 +13:20:19 377 0.00 +13:20:19 378 0.00 +13:20:19 379 0.00 +13:20:19 380 0.00 +13:20:19 381 0.00 +13:20:19 382 0.00 +13:20:19 383 0.00 +13:20:19 384 0.00 +13:20:19 385 0.00 +13:20:19 386 0.00 +13:20:19 387 0.00 +13:20:19 388 0.00 +13:20:19 389 0.00 +13:20:19 390 0.00 +13:20:19 391 0.00 +13:20:19 392 0.00 +13:20:19 393 0.00 +13:20:19 394 0.00 +13:20:19 395 0.00 +13:20:19 396 0.00 +13:20:19 397 0.00 +13:20:19 398 0.00 +13:20:19 399 0.00 +13:20:19 400 0.00 +13:20:19 401 0.00 +13:20:19 402 0.00 +13:20:19 403 0.00 +13:20:19 404 0.00 +13:20:19 405 0.00 +13:20:19 406 0.00 +13:20:19 407 0.00 +13:20:19 408 0.00 +13:20:19 409 0.00 +13:20:19 410 0.00 +13:20:19 411 0.00 +13:20:19 412 0.00 +13:20:19 413 0.00 +13:20:19 414 0.00 +13:20:19 415 0.00 +13:20:19 416 0.00 +13:20:19 417 0.00 +13:20:19 418 0.00 +13:20:19 419 0.00 +13:20:19 420 0.00 +13:20:19 421 0.00 +13:20:19 422 0.00 +13:20:19 423 0.00 +13:20:19 424 0.00 +13:20:19 425 0.00 +13:20:19 426 0.00 +13:20:19 427 0.00 +13:20:19 428 0.00 +13:20:19 429 0.00 +13:20:19 430 0.00 +13:20:19 431 0.00 +13:20:19 432 0.00 +13:20:19 433 0.00 +13:20:19 434 0.00 +13:20:19 435 0.00 +13:20:19 436 0.00 +13:20:19 437 0.00 +13:20:19 438 0.00 +13:20:19 439 0.00 +13:20:19 440 0.00 +13:20:19 441 0.00 +13:20:19 442 0.00 +13:20:19 443 0.00 +13:20:19 444 0.00 +13:20:19 445 0.00 +13:20:19 446 0.00 +13:20:19 447 0.00 +13:20:19 448 0.00 +13:20:19 449 0.00 +13:20:19 450 0.00 +13:20:19 451 0.00 +13:20:19 452 0.00 +13:20:19 453 0.00 +13:20:19 454 0.00 +13:20:19 455 0.00 +13:20:19 456 0.00 +13:20:19 457 0.00 +13:20:19 458 0.00 +13:20:19 459 0.00 +13:20:19 460 0.00 +13:20:19 461 0.00 +13:20:19 462 0.00 +13:20:19 463 0.00 +13:20:19 464 0.00 +13:20:19 465 0.00 +13:20:19 466 0.00 +13:20:19 467 0.00 +13:20:19 468 0.00 +13:20:19 469 0.00 +13:20:19 470 0.00 +13:20:19 471 0.00 +13:20:19 472 0.00 +13:20:19 473 0.00 +13:20:19 474 0.00 +13:20:19 475 0.00 +13:20:19 476 0.00 +13:20:19 477 0.00 +13:20:19 478 0.00 +13:20:19 479 0.00 +13:20:19 480 0.00 +13:20:19 481 0.00 +13:20:19 482 0.00 +13:20:19 483 0.00 +13:20:19 484 0.00 +13:20:19 485 0.00 +13:20:19 486 0.00 +13:20:19 487 0.00 +13:20:29 sum 24402.62 +13:20:29 0 0.00 +13:20:29 1 0.00 +13:20:29 2 0.00 +13:20:29 3 0.00 +13:20:29 4 0.00 +13:20:29 5 0.00 +13:20:29 6 0.00 +13:20:29 7 0.00 +13:20:29 8 0.00 +13:20:29 9 0.00 +13:20:29 10 0.00 +13:20:29 11 0.00 +13:20:29 12 0.00 +13:20:29 13 0.00 +13:20:29 14 0.00 +13:20:29 15 0.00 +13:20:29 16 0.00 +13:20:29 17 0.00 +13:20:29 18 0.00 +13:20:29 19 23.34 +13:20:29 20 0.00 +13:20:29 21 0.00 +13:20:29 22 0.00 +13:20:29 23 23.88 +13:20:29 24 12.93 +13:20:29 25 0.00 +13:20:29 26 0.00 +13:20:29 27 0.00 +13:20:29 28 0.00 +13:20:29 29 0.00 +13:20:29 30 0.00 +13:20:29 31 0.00 +13:20:29 32 0.00 +13:20:29 33 10.21 +13:20:29 34 137.10 +13:20:29 35 0.00 +13:20:29 36 0.00 +13:20:29 37 0.00 +13:20:29 38 0.00 +13:20:29 39 0.00 +13:20:29 40 0.00 +13:20:29 41 0.00 +13:20:29 42 0.00 +13:20:29 43 0.00 +13:20:29 44 0.00 +13:20:29 45 0.00 +13:20:29 46 0.00 +13:20:29 47 0.00 +13:20:29 48 0.00 +13:20:29 49 0.00 +13:20:29 50 0.00 +13:20:29 51 0.00 +13:20:29 52 0.00 +13:20:29 53 0.00 +13:20:29 54 0.00 +13:20:29 55 0.00 +13:20:29 56 0.00 +13:20:29 57 0.00 +13:20:29 58 0.00 +13:20:29 59 0.00 +13:20:29 60 0.00 +13:20:29 61 0.00 +13:20:29 62 0.00 +13:20:29 63 0.00 +13:20:29 64 0.00 +13:20:29 65 0.00 +13:20:29 66 0.00 +13:20:29 67 0.00 +13:20:29 68 0.00 +13:20:29 69 0.00 +13:20:29 70 0.00 +13:20:29 71 0.00 +13:20:29 72 0.00 +13:20:29 73 0.00 +13:20:29 74 0.00 +13:20:29 75 0.00 +13:20:29 76 0.00 +13:20:29 77 0.00 +13:20:29 78 0.00 +13:20:29 79 0.00 +13:20:29 80 0.00 +13:20:29 81 0.00 +13:20:29 82 0.00 +13:20:29 83 0.00 +13:20:29 84 0.00 +13:20:29 85 0.00 +13:20:29 86 0.00 +13:20:29 87 0.00 +13:20:29 88 0.00 +13:20:29 89 0.00 +13:20:29 90 0.00 +13:20:29 91 0.00 +13:20:29 92 0.00 +13:20:29 93 0.00 +13:20:29 94 0.00 +13:20:29 95 0.00 +13:20:29 96 0.00 +13:20:29 97 0.00 +13:20:29 98 0.00 +13:20:29 99 0.00 +13:20:29 100 0.00 +13:20:29 101 0.00 +13:20:29 102 0.00 +13:20:29 103 0.00 +13:20:29 104 0.00 +13:20:29 105 0.00 +13:20:29 106 0.00 +13:20:29 107 0.00 +13:20:29 108 0.00 +13:20:29 109 0.00 +13:20:29 110 0.00 +13:20:29 111 0.00 +13:20:29 112 0.00 +13:20:29 113 0.00 +13:20:29 114 0.00 +13:20:29 115 0.00 +13:20:29 116 0.00 +13:20:29 117 0.00 +13:20:29 118 0.00 +13:20:29 119 0.00 +13:20:29 120 0.00 +13:20:29 121 0.00 +13:20:29 122 0.00 +13:20:29 123 0.00 +13:20:29 124 0.00 +13:20:29 125 0.00 +13:20:29 126 0.00 +13:20:29 127 0.00 +13:20:29 128 0.00 +13:20:29 129 0.00 +13:20:29 130 0.00 +13:20:29 131 0.00 +13:20:29 132 0.00 +13:20:29 133 0.00 +13:20:29 134 0.00 +13:20:29 135 0.00 +13:20:29 136 0.00 +13:20:29 137 0.00 +13:20:29 138 0.00 +13:20:29 139 0.00 +13:20:29 140 0.00 +13:20:29 141 0.00 +13:20:29 142 0.00 +13:20:29 143 0.00 +13:20:29 144 0.00 +13:20:29 145 0.00 +13:20:29 146 0.00 +13:20:29 147 0.00 +13:20:29 148 0.00 +13:20:29 149 0.00 +13:20:29 150 0.00 +13:20:29 151 0.00 +13:20:29 152 0.00 +13:20:29 153 0.00 +13:20:29 154 0.00 +13:20:29 155 0.00 +13:20:29 156 0.00 +13:20:29 157 0.00 +13:20:29 158 0.00 +13:20:29 159 0.00 +13:20:29 160 0.00 +13:20:29 161 0.00 +13:20:29 162 0.00 +13:20:29 163 0.00 +13:20:29 164 0.00 +13:20:29 165 0.00 +13:20:29 166 0.00 +13:20:29 167 0.00 +13:20:29 168 0.00 +13:20:29 169 0.00 +13:20:29 170 0.00 +13:20:29 171 0.00 +13:20:29 172 0.00 +13:20:29 173 0.00 +13:20:29 174 0.00 +13:20:29 175 0.00 +13:20:29 176 0.00 +13:20:29 177 0.00 +13:20:29 178 0.00 +13:20:29 179 0.00 +13:20:29 180 0.00 +13:20:29 181 0.00 +13:20:29 182 0.00 +13:20:29 183 0.00 +13:20:29 184 0.00 +13:20:29 185 0.00 +13:20:29 186 0.00 +13:20:29 187 0.00 +13:20:29 188 0.00 +13:20:29 189 0.00 +13:20:29 190 0.00 +13:20:29 191 0.00 +13:20:29 192 0.00 +13:20:29 193 0.00 +13:20:29 194 0.00 +13:20:29 195 0.00 +13:20:29 196 0.00 +13:20:29 197 0.00 +13:20:29 198 0.00 +13:20:29 199 0.00 +13:20:29 200 0.00 +13:20:29 201 0.00 +13:20:29 202 0.00 +13:20:29 203 0.00 +13:20:29 204 0.00 +13:20:29 205 0.00 +13:20:29 206 0.00 +13:20:29 207 0.00 +13:20:29 208 0.00 +13:20:29 209 0.00 +13:20:29 210 0.00 +13:20:29 211 0.00 +13:20:29 212 0.00 +13:20:29 213 0.00 +13:20:29 214 0.00 +13:20:29 215 0.00 +13:20:29 216 0.00 +13:20:29 217 0.00 +13:20:29 218 0.00 +13:20:29 219 0.00 +13:20:29 220 0.00 +13:20:29 221 0.00 +13:20:29 222 0.00 +13:20:29 223 0.00 +13:20:29 224 0.00 +13:20:29 225 0.00 +13:20:29 226 0.00 +13:20:29 227 0.00 +13:20:29 228 0.00 +13:20:29 229 0.00 +13:20:29 230 0.00 +13:20:29 231 0.00 +13:20:29 232 0.00 +13:20:29 233 0.00 +13:20:29 234 0.00 +13:20:29 235 0.00 +13:20:29 236 0.00 +13:20:29 237 0.00 +13:20:29 238 0.00 +13:20:29 239 0.00 +13:20:29 240 0.00 +13:20:29 241 0.00 +13:20:29 242 0.00 +13:20:29 243 0.00 +13:20:29 244 0.00 +13:20:29 245 0.00 +13:20:29 246 0.00 +13:20:29 247 0.00 +13:20:29 248 0.00 +13:20:29 249 0.00 +13:20:29 250 0.00 +13:20:29 251 0.00 +13:20:29 252 0.00 +13:20:29 253 0.00 +13:20:29 254 0.00 +13:20:29 255 0.00 +13:20:29 256 0.00 +13:20:29 257 0.00 +13:20:29 258 0.00 +13:20:29 259 0.00 +13:20:29 260 0.00 +13:20:29 261 0.00 +13:20:29 262 0.00 +13:20:29 263 0.00 +13:20:29 264 0.00 +13:20:29 265 0.00 +13:20:29 266 0.00 +13:20:29 267 0.00 +13:20:29 268 0.00 +13:20:29 269 0.00 +13:20:29 270 0.00 +13:20:29 271 0.00 +13:20:29 272 0.00 +13:20:29 273 0.00 +13:20:29 274 0.00 +13:20:29 275 0.00 +13:20:29 276 0.00 +13:20:29 277 0.00 +13:20:29 278 0.00 +13:20:29 279 0.00 +13:20:29 280 0.00 +13:20:29 281 0.00 +13:20:29 282 0.00 +13:20:29 283 0.00 +13:20:29 284 0.00 +13:20:29 285 0.00 +13:20:29 286 0.00 +13:20:29 287 0.00 +13:20:29 288 0.00 +13:20:29 289 0.00 +13:20:29 290 0.00 +13:20:29 291 0.00 +13:20:29 292 0.00 +13:20:29 293 0.00 +13:20:29 294 0.00 +13:20:29 295 0.00 +13:20:29 296 0.00 +13:20:29 297 0.00 +13:20:29 298 0.00 +13:20:29 299 0.00 +13:20:29 300 0.00 +13:20:29 301 0.00 +13:20:29 302 0.00 +13:20:29 303 0.00 +13:20:29 304 0.00 +13:20:29 305 0.00 +13:20:29 306 0.00 +13:20:29 307 0.00 +13:20:29 308 0.00 +13:20:29 309 0.00 +13:20:29 310 0.00 +13:20:29 311 0.00 +13:20:29 312 0.00 +13:20:29 313 0.00 +13:20:29 314 0.00 +13:20:29 315 0.00 +13:20:29 316 0.00 +13:20:29 317 0.00 +13:20:29 318 0.00 +13:20:29 319 0.00 +13:20:29 320 0.00 +13:20:29 321 0.00 +13:20:29 322 0.00 +13:20:29 323 0.00 +13:20:29 324 0.00 +13:20:29 325 0.00 +13:20:29 326 0.00 +13:20:29 327 0.00 +13:20:29 328 0.00 +13:20:29 329 0.00 +13:20:29 330 0.00 +13:20:29 331 0.00 +13:20:29 332 0.00 +13:20:29 333 0.00 +13:20:29 334 0.00 +13:20:29 335 0.00 +13:20:29 336 0.00 +13:20:29 337 0.00 +13:20:29 338 0.00 +13:20:29 339 0.00 +13:20:29 340 0.00 +13:20:29 341 0.00 +13:20:29 342 0.00 +13:20:29 343 0.00 +13:20:29 344 0.00 +13:20:29 345 0.00 +13:20:29 346 0.00 +13:20:29 347 0.00 +13:20:29 348 0.00 +13:20:29 349 0.00 +13:20:29 350 0.00 +13:20:29 351 0.00 +13:20:29 352 0.00 +13:20:29 353 0.00 +13:20:29 354 0.00 +13:20:29 355 0.00 +13:20:29 356 0.00 +13:20:29 357 0.00 +13:20:29 358 0.00 +13:20:29 359 0.00 +13:20:29 360 0.00 +13:20:29 361 0.00 +13:20:29 362 0.00 +13:20:29 363 0.00 +13:20:29 364 0.00 +13:20:29 365 0.00 +13:20:29 366 0.00 +13:20:29 367 0.00 +13:20:29 368 0.00 +13:20:29 369 0.00 +13:20:29 370 0.00 +13:20:29 371 0.00 +13:20:29 372 0.00 +13:20:29 373 0.00 +13:20:29 374 0.00 +13:20:29 375 0.00 +13:20:29 376 0.00 +13:20:29 377 0.00 +13:20:29 378 0.00 +13:20:29 379 0.00 +13:20:29 380 0.00 +13:20:29 381 0.00 +13:20:29 382 0.00 +13:20:29 383 0.00 +13:20:29 384 0.00 +13:20:29 385 0.00 +13:20:29 386 0.00 +13:20:29 387 0.00 +13:20:29 388 0.00 +13:20:29 389 0.00 +13:20:29 390 0.00 +13:20:29 391 0.00 +13:20:29 392 0.00 +13:20:29 393 0.00 +13:20:29 394 0.00 +13:20:29 395 0.00 +13:20:29 396 0.00 +13:20:29 397 0.00 +13:20:29 398 0.00 +13:20:29 399 0.00 +13:20:29 400 0.00 +13:20:29 401 0.00 +13:20:29 402 0.00 +13:20:29 403 0.00 +13:20:29 404 0.00 +13:20:29 405 0.00 +13:20:29 406 0.00 +13:20:29 407 0.00 +13:20:29 408 0.00 +13:20:29 409 0.00 +13:20:29 410 0.00 +13:20:29 411 0.00 +13:20:29 412 0.00 +13:20:29 413 0.00 +13:20:29 414 0.00 +13:20:29 415 0.00 +13:20:29 416 0.00 +13:20:29 417 0.00 +13:20:29 418 0.00 +13:20:29 419 0.00 +13:20:29 420 0.00 +13:20:29 421 0.00 +13:20:29 422 0.00 +13:20:29 423 0.00 +13:20:29 424 0.00 +13:20:29 425 0.00 +13:20:29 426 0.00 +13:20:29 427 0.00 +13:20:29 428 0.00 +13:20:29 429 0.00 +13:20:29 430 0.00 +13:20:29 431 0.00 +13:20:29 432 0.00 +13:20:29 433 0.00 +13:20:29 434 0.00 +13:20:29 435 0.00 +13:20:29 436 0.00 +13:20:29 437 0.00 +13:20:29 438 0.00 +13:20:29 439 0.00 +13:20:29 440 0.00 +13:20:29 441 0.00 +13:20:29 442 0.00 +13:20:29 443 0.00 +13:20:29 444 0.00 +13:20:29 445 0.00 +13:20:29 446 0.00 +13:20:29 447 0.00 +13:20:29 448 0.00 +13:20:29 449 0.00 +13:20:29 450 0.00 +13:20:29 451 0.00 +13:20:29 452 0.00 +13:20:29 453 0.00 +13:20:29 454 0.00 +13:20:29 455 0.00 +13:20:29 456 0.00 +13:20:29 457 0.00 +13:20:29 458 0.00 +13:20:29 459 0.00 +13:20:29 460 0.00 +13:20:29 461 0.00 +13:20:29 462 0.00 +13:20:29 463 0.00 +13:20:29 464 0.00 +13:20:29 465 0.00 +13:20:29 466 0.00 +13:20:29 467 0.00 +13:20:29 468 0.00 +13:20:29 469 0.00 +13:20:29 470 0.00 +13:20:29 471 0.00 +13:20:29 472 0.00 +13:20:29 473 0.00 +13:20:29 474 0.00 +13:20:29 475 0.00 +13:20:29 476 0.00 +13:20:29 477 0.00 +13:20:29 478 0.00 +13:20:29 479 0.00 +13:20:29 480 0.00 +13:20:29 481 0.00 +13:20:29 482 0.00 +13:20:29 483 0.00 +13:20:29 484 0.00 +13:20:29 485 0.00 +13:20:29 486 0.00 +13:20:29 487 0.00 +13:20:39 sum 33602.60 +13:20:39 0 0.00 +13:20:39 1 0.00 +13:20:39 2 0.00 +13:20:39 3 0.00 +13:20:39 4 0.00 +13:20:39 5 0.00 +13:20:39 6 0.00 +13:20:39 7 0.00 +13:20:39 8 0.00 +13:20:39 9 0.00 +13:20:39 10 0.00 +13:20:39 11 0.00 +13:20:39 12 0.00 +13:20:39 13 0.00 +13:20:39 14 0.00 +13:20:39 15 0.00 +13:20:39 16 0.00 +13:20:39 17 0.00 +13:20:39 18 0.00 +13:20:39 19 22.73 +13:20:39 20 0.00 +13:20:39 21 0.00 +13:20:39 22 0.00 +13:20:39 23 31.12 +13:20:39 24 8.78 +13:20:39 25 0.00 +13:20:39 26 0.00 +13:20:39 27 0.00 +13:20:39 28 0.00 +13:20:39 29 0.00 +13:20:39 30 0.00 +13:20:39 31 0.00 +13:20:39 32 0.00 +13:20:39 33 61.71 +13:20:39 34 152.88 +13:20:39 35 0.00 +13:20:39 36 0.00 +13:20:39 37 0.00 +13:20:39 38 0.00 +13:20:39 39 0.00 +13:20:39 40 0.00 +13:20:39 41 0.00 +13:20:39 42 0.00 +13:20:39 43 0.00 +13:20:39 44 0.00 +13:20:39 45 0.00 +13:20:39 46 0.00 +13:20:39 47 0.00 +13:20:39 48 0.00 +13:20:39 49 0.00 +13:20:39 50 0.00 +13:20:39 51 0.00 +13:20:39 52 0.00 +13:20:39 53 0.00 +13:20:39 54 0.00 +13:20:39 55 0.00 +13:20:39 56 0.00 +13:20:39 57 0.00 +13:20:39 58 0.00 +13:20:39 59 0.00 +13:20:39 60 0.00 +13:20:39 61 0.00 +13:20:39 62 0.00 +13:20:39 63 0.00 +13:20:39 64 0.00 +13:20:39 65 0.00 +13:20:39 66 0.00 +13:20:39 67 0.00 +13:20:39 68 0.00 +13:20:39 69 0.00 +13:20:39 70 0.00 +13:20:39 71 0.00 +13:20:39 72 0.00 +13:20:39 73 0.00 +13:20:39 74 0.00 +13:20:39 75 0.00 +13:20:39 76 0.00 +13:20:39 77 0.00 +13:20:39 78 0.00 +13:20:39 79 0.00 +13:20:39 80 0.00 +13:20:39 81 0.00 +13:20:39 82 0.00 +13:20:39 83 0.00 +13:20:39 84 0.00 +13:20:39 85 0.00 +13:20:39 86 0.00 +13:20:39 87 0.00 +13:20:39 88 0.00 +13:20:39 89 0.00 +13:20:39 90 0.00 +13:20:39 91 0.00 +13:20:39 92 0.00 +13:20:39 93 0.00 +13:20:39 94 0.00 +13:20:39 95 0.00 +13:20:39 96 0.00 +13:20:39 97 0.00 +13:20:39 98 0.00 +13:20:39 99 0.00 +13:20:39 100 0.00 +13:20:39 101 0.00 +13:20:39 102 0.00 +13:20:39 103 0.00 +13:20:39 104 0.00 +13:20:39 105 0.00 +13:20:39 106 0.00 +13:20:39 107 0.00 +13:20:39 108 0.00 +13:20:39 109 0.00 +13:20:39 110 0.00 +13:20:39 111 0.00 +13:20:39 112 0.00 +13:20:39 113 0.00 +13:20:39 114 0.00 +13:20:39 115 0.00 +13:20:39 116 0.00 +13:20:39 117 0.00 +13:20:39 118 0.00 +13:20:39 119 0.00 +13:20:39 120 0.00 +13:20:39 121 0.00 +13:20:39 122 0.00 +13:20:39 123 0.00 +13:20:39 124 0.00 +13:20:39 125 0.00 +13:20:39 126 0.00 +13:20:39 127 0.00 +13:20:39 128 0.00 +13:20:39 129 0.00 +13:20:39 130 0.00 +13:20:39 131 0.00 +13:20:39 132 0.00 +13:20:39 133 0.00 +13:20:39 134 0.00 +13:20:39 135 0.00 +13:20:39 136 0.00 +13:20:39 137 0.00 +13:20:39 138 0.00 +13:20:39 139 0.00 +13:20:39 140 0.00 +13:20:39 141 0.00 +13:20:39 142 0.00 +13:20:39 143 0.00 +13:20:39 144 0.00 +13:20:39 145 0.00 +13:20:39 146 0.00 +13:20:39 147 0.00 +13:20:39 148 0.00 +13:20:39 149 0.00 +13:20:39 150 0.00 +13:20:39 151 0.00 +13:20:39 152 0.00 +13:20:39 153 0.00 +13:20:39 154 0.00 +13:20:39 155 0.00 +13:20:39 156 0.00 +13:20:39 157 0.00 +13:20:39 158 0.00 +13:20:39 159 0.00 +13:20:39 160 0.00 +13:20:39 161 0.00 +13:20:39 162 0.00 +13:20:39 163 0.00 +13:20:39 164 0.00 +13:20:39 165 0.00 +13:20:39 166 0.00 +13:20:39 167 0.00 +13:20:39 168 0.00 +13:20:39 169 0.00 +13:20:39 170 0.00 +13:20:39 171 0.00 +13:20:39 172 0.00 +13:20:39 173 0.00 +13:20:39 174 0.00 +13:20:39 175 0.00 +13:20:39 176 0.00 +13:20:39 177 0.00 +13:20:39 178 0.00 +13:20:39 179 0.00 +13:20:39 180 0.00 +13:20:39 181 0.00 +13:20:39 182 0.00 +13:20:39 183 0.00 +13:20:39 184 0.00 +13:20:39 185 0.00 +13:20:39 186 0.00 +13:20:39 187 0.00 +13:20:39 188 0.00 +13:20:39 189 0.00 +13:20:39 190 0.00 +13:20:39 191 0.00 +13:20:39 192 0.00 +13:20:39 193 0.00 +13:20:39 194 0.00 +13:20:39 195 0.00 +13:20:39 196 0.00 +13:20:39 197 0.00 +13:20:39 198 0.00 +13:20:39 199 0.00 +13:20:39 200 0.00 +13:20:39 201 0.00 +13:20:39 202 0.00 +13:20:39 203 0.00 +13:20:39 204 0.00 +13:20:39 205 0.00 +13:20:39 206 0.00 +13:20:39 207 0.00 +13:20:39 208 0.00 +13:20:39 209 0.00 +13:20:39 210 0.00 +13:20:39 211 0.00 +13:20:39 212 0.00 +13:20:39 213 0.00 +13:20:39 214 0.00 +13:20:39 215 0.00 +13:20:39 216 0.00 +13:20:39 217 0.00 +13:20:39 218 0.00 +13:20:39 219 0.00 +13:20:39 220 0.00 +13:20:39 221 0.00 +13:20:39 222 0.00 +13:20:39 223 0.00 +13:20:39 224 0.00 +13:20:39 225 0.00 +13:20:39 226 0.00 +13:20:39 227 0.00 +13:20:39 228 0.00 +13:20:39 229 0.00 +13:20:39 230 0.00 +13:20:39 231 0.00 +13:20:39 232 0.00 +13:20:39 233 0.00 +13:20:39 234 0.00 +13:20:39 235 0.00 +13:20:39 236 0.00 +13:20:39 237 0.00 +13:20:39 238 0.00 +13:20:39 239 0.00 +13:20:39 240 0.00 +13:20:39 241 0.00 +13:20:39 242 0.00 +13:20:39 243 0.00 +13:20:39 244 0.00 +13:20:39 245 0.00 +13:20:39 246 0.00 +13:20:39 247 0.00 +13:20:39 248 0.00 +13:20:39 249 0.00 +13:20:39 250 0.00 +13:20:39 251 0.00 +13:20:39 252 0.00 +13:20:39 253 0.00 +13:20:39 254 0.00 +13:20:39 255 0.00 +13:20:39 256 0.00 +13:20:39 257 0.00 +13:20:39 258 0.00 +13:20:39 259 0.00 +13:20:39 260 0.00 +13:20:39 261 0.00 +13:20:39 262 0.00 +13:20:39 263 0.00 +13:20:39 264 0.00 +13:20:39 265 0.00 +13:20:39 266 0.00 +13:20:39 267 0.00 +13:20:39 268 0.00 +13:20:39 269 0.00 +13:20:39 270 0.00 +13:20:39 271 0.00 +13:20:39 272 0.00 +13:20:39 273 0.00 +13:20:39 274 0.00 +13:20:39 275 0.00 +13:20:39 276 0.00 +13:20:39 277 0.00 +13:20:39 278 0.00 +13:20:39 279 0.00 +13:20:39 280 0.00 +13:20:39 281 0.00 +13:20:39 282 0.00 +13:20:39 283 0.00 +13:20:39 284 0.00 +13:20:39 285 0.00 +13:20:39 286 0.00 +13:20:39 287 0.00 +13:20:39 288 0.00 +13:20:39 289 0.00 +13:20:39 290 0.00 +13:20:39 291 0.00 +13:20:39 292 0.00 +13:20:39 293 0.00 +13:20:39 294 0.00 +13:20:39 295 0.00 +13:20:39 296 0.00 +13:20:39 297 0.00 +13:20:39 298 0.00 +13:20:39 299 0.00 +13:20:39 300 0.00 +13:20:39 301 0.00 +13:20:39 302 0.00 +13:20:39 303 0.00 +13:20:39 304 0.00 +13:20:39 305 0.00 +13:20:39 306 0.00 +13:20:39 307 0.00 +13:20:39 308 0.00 +13:20:39 309 0.00 +13:20:39 310 0.00 +13:20:39 311 0.00 +13:20:39 312 0.00 +13:20:39 313 0.00 +13:20:39 314 0.00 +13:20:39 315 0.00 +13:20:39 316 0.00 +13:20:39 317 0.00 +13:20:39 318 0.00 +13:20:39 319 0.00 +13:20:39 320 0.00 +13:20:39 321 0.00 +13:20:39 322 0.00 +13:20:39 323 0.00 +13:20:39 324 0.00 +13:20:39 325 0.00 +13:20:39 326 0.00 +13:20:39 327 0.00 +13:20:39 328 0.00 +13:20:39 329 0.00 +13:20:39 330 0.00 +13:20:39 331 0.00 +13:20:39 332 0.00 +13:20:39 333 0.00 +13:20:39 334 0.00 +13:20:39 335 0.00 +13:20:39 336 0.00 +13:20:39 337 0.00 +13:20:39 338 0.00 +13:20:39 339 0.00 +13:20:39 340 0.00 +13:20:39 341 0.00 +13:20:39 342 0.00 +13:20:39 343 0.00 +13:20:39 344 0.00 +13:20:39 345 0.00 +13:20:39 346 0.00 +13:20:39 347 0.00 +13:20:39 348 0.00 +13:20:39 349 0.00 +13:20:39 350 0.00 +13:20:39 351 0.00 +13:20:39 352 0.00 +13:20:39 353 0.00 +13:20:39 354 0.00 +13:20:39 355 0.00 +13:20:39 356 0.00 +13:20:39 357 0.00 +13:20:39 358 0.00 +13:20:39 359 0.00 +13:20:39 360 0.00 +13:20:39 361 0.00 +13:20:39 362 0.00 +13:20:39 363 0.00 +13:20:39 364 0.00 +13:20:39 365 0.00 +13:20:39 366 0.00 +13:20:39 367 0.00 +13:20:39 368 0.00 +13:20:39 369 0.00 +13:20:39 370 0.00 +13:20:39 371 0.00 +13:20:39 372 0.00 +13:20:39 373 0.00 +13:20:39 374 0.00 +13:20:39 375 0.00 +13:20:39 376 0.00 +13:20:39 377 0.00 +13:20:39 378 0.00 +13:20:39 379 0.00 +13:20:39 380 0.00 +13:20:39 381 0.00 +13:20:39 382 0.00 +13:20:39 383 0.00 +13:20:39 384 0.00 +13:20:39 385 0.00 +13:20:39 386 0.00 +13:20:39 387 0.00 +13:20:39 388 0.00 +13:20:39 389 0.00 +13:20:39 390 0.00 +13:20:39 391 0.00 +13:20:39 392 0.00 +13:20:39 393 0.00 +13:20:39 394 0.00 +13:20:39 395 0.00 +13:20:39 396 0.00 +13:20:39 397 0.00 +13:20:39 398 0.00 +13:20:39 399 0.00 +13:20:39 400 0.00 +13:20:39 401 0.00 +13:20:39 402 0.00 +13:20:39 403 0.00 +13:20:39 404 0.00 +13:20:39 405 0.00 +13:20:39 406 0.00 +13:20:39 407 0.00 +13:20:39 408 0.00 +13:20:39 409 0.00 +13:20:39 410 0.00 +13:20:39 411 0.00 +13:20:39 412 0.00 +13:20:39 413 0.00 +13:20:39 414 0.00 +13:20:39 415 0.00 +13:20:39 416 0.00 +13:20:39 417 0.00 +13:20:39 418 0.00 +13:20:39 419 0.00 +13:20:39 420 0.00 +13:20:39 421 0.00 +13:20:39 422 0.00 +13:20:39 423 0.00 +13:20:39 424 0.00 +13:20:39 425 0.00 +13:20:39 426 0.00 +13:20:39 427 0.00 +13:20:39 428 0.00 +13:20:39 429 0.00 +13:20:39 430 0.00 +13:20:39 431 0.00 +13:20:39 432 0.00 +13:20:39 433 0.00 +13:20:39 434 0.00 +13:20:39 435 0.00 +13:20:39 436 0.00 +13:20:39 437 0.00 +13:20:39 438 0.00 +13:20:39 439 0.00 +13:20:39 440 0.00 +13:20:39 441 0.00 +13:20:39 442 0.00 +13:20:39 443 0.00 +13:20:39 444 0.00 +13:20:39 445 0.00 +13:20:39 446 0.00 +13:20:39 447 0.00 +13:20:39 448 0.00 +13:20:39 449 0.00 +13:20:39 450 0.00 +13:20:39 451 0.00 +13:20:39 452 0.00 +13:20:39 453 0.00 +13:20:39 454 0.00 +13:20:39 455 0.00 +13:20:39 456 0.00 +13:20:39 457 0.00 +13:20:39 458 0.00 +13:20:39 459 0.00 +13:20:39 460 0.00 +13:20:39 461 0.00 +13:20:39 462 0.00 +13:20:39 463 0.00 +13:20:39 464 0.00 +13:20:39 465 0.00 +13:20:39 466 0.00 +13:20:39 467 0.00 +13:20:39 468 0.00 +13:20:39 469 0.00 +13:20:39 470 0.00 +13:20:39 471 0.00 +13:20:39 472 0.00 +13:20:39 473 0.00 +13:20:39 474 0.00 +13:20:39 475 0.00 +13:20:39 476 0.00 +13:20:39 477 0.00 +13:20:39 478 0.00 +13:20:39 479 0.00 +13:20:39 480 0.00 +13:20:39 481 0.00 +13:20:39 482 0.00 +13:20:39 483 0.00 +13:20:39 484 0.00 +13:20:39 485 0.00 +13:20:39 486 0.00 +13:20:39 487 0.00 +13:20:49 sum 56126.26 +13:20:49 0 0.00 +13:20:49 1 0.00 +13:20:49 2 0.00 +13:20:49 3 0.00 +13:20:49 4 0.00 +13:20:49 5 0.00 +13:20:49 6 0.00 +13:20:49 7 0.00 +13:20:49 8 0.00 +13:20:49 9 0.00 +13:20:49 10 0.00 +13:20:49 11 0.00 +13:20:49 12 0.00 +13:20:49 13 0.00 +13:20:49 14 0.00 +13:20:49 15 0.00 +13:20:49 16 0.00 +13:20:49 17 0.00 +13:20:49 18 0.00 +13:20:49 19 26.75 +13:20:49 20 0.00 +13:20:49 21 0.00 +13:20:49 22 0.00 +13:20:49 23 17.55 +13:20:49 24 15.14 +13:20:49 25 0.00 +13:20:49 26 0.00 +13:20:49 27 0.00 +13:20:49 28 0.00 +13:20:49 29 0.00 +13:20:49 30 0.00 +13:20:49 31 0.00 +13:20:49 32 0.00 +13:20:49 33 22.20 +13:20:49 34 195.13 +13:20:49 35 0.00 +13:20:49 36 0.00 +13:20:49 37 0.00 +13:20:49 38 0.00 +13:20:49 39 0.00 +13:20:49 40 0.00 +13:20:49 41 0.00 +13:20:49 42 0.00 +13:20:49 43 0.00 +13:20:49 44 0.00 +13:20:49 45 0.00 +13:20:49 46 0.00 +13:20:49 47 0.00 +13:20:49 48 0.00 +13:20:49 49 0.00 +13:20:49 50 0.00 +13:20:49 51 0.00 +13:20:49 52 0.00 +13:20:49 53 0.00 +13:20:49 54 0.00 +13:20:49 55 0.00 +13:20:49 56 0.00 +13:20:49 57 0.00 +13:20:49 58 0.00 +13:20:49 59 0.00 +13:20:49 60 0.00 +13:20:49 61 0.00 +13:20:49 62 0.00 +13:20:49 63 0.00 +13:20:49 64 0.00 +13:20:49 65 0.00 +13:20:49 66 0.00 +13:20:49 67 0.00 +13:20:49 68 0.00 +13:20:49 69 0.00 +13:20:49 70 0.00 +13:20:49 71 0.00 +13:20:49 72 0.00 +13:20:49 73 0.00 +13:20:49 74 0.00 +13:20:49 75 0.00 +13:20:49 76 0.00 +13:20:49 77 0.00 +13:20:49 78 0.00 +13:20:49 79 0.00 +13:20:49 80 0.00 +13:20:49 81 0.00 +13:20:49 82 0.00 +13:20:49 83 0.00 +13:20:49 84 0.00 +13:20:49 85 0.00 +13:20:49 86 0.00 +13:20:49 87 0.00 +13:20:49 88 0.00 +13:20:49 89 0.00 +13:20:49 90 0.00 +13:20:49 91 0.00 +13:20:49 92 0.00 +13:20:49 93 0.00 +13:20:49 94 0.00 +13:20:49 95 0.00 +13:20:49 96 0.00 +13:20:49 97 0.00 +13:20:49 98 0.00 +13:20:49 99 0.00 +13:20:49 100 0.00 +13:20:49 101 0.00 +13:20:49 102 0.00 +13:20:49 103 0.00 +13:20:49 104 0.00 +13:20:49 105 0.00 +13:20:49 106 0.00 +13:20:49 107 0.00 +13:20:49 108 0.00 +13:20:49 109 0.00 +13:20:49 110 0.00 +13:20:49 111 0.00 +13:20:49 112 0.00 +13:20:49 113 0.00 +13:20:49 114 0.00 +13:20:49 115 0.00 +13:20:49 116 0.00 +13:20:49 117 0.00 +13:20:49 118 0.00 +13:20:49 119 0.00 +13:20:49 120 0.00 +13:20:49 121 0.00 +13:20:49 122 0.00 +13:20:49 123 0.00 +13:20:49 124 0.00 +13:20:49 125 0.00 +13:20:49 126 0.00 +13:20:49 127 0.00 +13:20:49 128 0.00 +13:20:49 129 0.00 +13:20:49 130 0.00 +13:20:49 131 0.00 +13:20:49 132 0.00 +13:20:49 133 0.00 +13:20:49 134 0.00 +13:20:49 135 0.00 +13:20:49 136 0.00 +13:20:49 137 0.00 +13:20:49 138 0.00 +13:20:49 139 0.00 +13:20:49 140 0.00 +13:20:49 141 0.00 +13:20:49 142 0.00 +13:20:49 143 0.00 +13:20:49 144 0.00 +13:20:49 145 0.00 +13:20:49 146 0.00 +13:20:49 147 0.00 +13:20:49 148 0.00 +13:20:49 149 0.00 +13:20:49 150 0.00 +13:20:49 151 0.00 +13:20:49 152 0.00 +13:20:49 153 0.00 +13:20:49 154 0.00 +13:20:49 155 0.00 +13:20:49 156 0.00 +13:20:49 157 0.00 +13:20:49 158 0.00 +13:20:49 159 0.00 +13:20:49 160 0.00 +13:20:49 161 0.00 +13:20:49 162 0.00 +13:20:49 163 0.00 +13:20:49 164 0.00 +13:20:49 165 0.00 +13:20:49 166 0.00 +13:20:49 167 0.00 +13:20:49 168 0.00 +13:20:49 169 0.00 +13:20:49 170 0.00 +13:20:49 171 0.00 +13:20:49 172 0.00 +13:20:49 173 0.00 +13:20:49 174 0.00 +13:20:49 175 0.00 +13:20:49 176 0.00 +13:20:49 177 0.00 +13:20:49 178 0.00 +13:20:49 179 0.00 +13:20:49 180 0.00 +13:20:49 181 0.00 +13:20:49 182 0.00 +13:20:49 183 0.00 +13:20:49 184 0.00 +13:20:49 185 0.00 +13:20:49 186 0.00 +13:20:49 187 0.00 +13:20:49 188 0.00 +13:20:49 189 0.00 +13:20:49 190 0.00 +13:20:49 191 0.00 +13:20:49 192 0.00 +13:20:49 193 0.00 +13:20:49 194 0.00 +13:20:49 195 0.00 +13:20:49 196 0.00 +13:20:49 197 0.00 +13:20:49 198 0.00 +13:20:49 199 0.00 +13:20:49 200 0.00 +13:20:49 201 0.00 +13:20:49 202 0.00 +13:20:49 203 0.00 +13:20:49 204 0.00 +13:20:49 205 0.00 +13:20:49 206 0.00 +13:20:49 207 0.00 +13:20:49 208 0.00 +13:20:49 209 0.00 +13:20:49 210 0.00 +13:20:49 211 0.00 +13:20:49 212 0.00 +13:20:49 213 0.00 +13:20:49 214 0.00 +13:20:49 215 0.00 +13:20:49 216 0.00 +13:20:49 217 0.00 +13:20:49 218 0.00 +13:20:49 219 0.00 +13:20:49 220 0.00 +13:20:49 221 0.00 +13:20:49 222 0.00 +13:20:49 223 0.00 +13:20:49 224 0.00 +13:20:49 225 0.00 +13:20:49 226 0.00 +13:20:49 227 0.00 +13:20:49 228 0.00 +13:20:49 229 0.00 +13:20:49 230 0.00 +13:20:49 231 0.00 +13:20:49 232 0.00 +13:20:49 233 0.00 +13:20:49 234 0.00 +13:20:49 235 0.00 +13:20:49 236 0.00 +13:20:49 237 0.00 +13:20:49 238 0.00 +13:20:49 239 0.00 +13:20:49 240 0.00 +13:20:49 241 0.00 +13:20:49 242 0.00 +13:20:49 243 0.00 +13:20:49 244 0.00 +13:20:49 245 0.00 +13:20:49 246 0.00 +13:20:49 247 0.00 +13:20:49 248 0.00 +13:20:49 249 0.00 +13:20:49 250 0.00 +13:20:49 251 0.00 +13:20:49 252 0.00 +13:20:49 253 0.00 +13:20:49 254 0.00 +13:20:49 255 0.00 +13:20:49 256 0.00 +13:20:49 257 0.00 +13:20:49 258 0.00 +13:20:49 259 0.00 +13:20:49 260 0.00 +13:20:49 261 0.00 +13:20:49 262 0.00 +13:20:49 263 0.00 +13:20:49 264 0.00 +13:20:49 265 0.00 +13:20:49 266 0.00 +13:20:49 267 0.00 +13:20:49 268 0.00 +13:20:49 269 0.00 +13:20:49 270 0.00 +13:20:49 271 0.00 +13:20:49 272 0.00 +13:20:49 273 0.00 +13:20:49 274 0.00 +13:20:49 275 0.00 +13:20:49 276 0.00 +13:20:49 277 0.00 +13:20:49 278 0.00 +13:20:49 279 0.00 +13:20:49 280 0.00 +13:20:49 281 0.00 +13:20:49 282 0.00 +13:20:49 283 0.00 +13:20:49 284 0.00 +13:20:49 285 0.00 +13:20:49 286 0.00 +13:20:49 287 0.00 +13:20:49 288 0.00 +13:20:49 289 0.00 +13:20:49 290 0.00 +13:20:49 291 0.00 +13:20:49 292 0.00 +13:20:49 293 0.00 +13:20:49 294 0.00 +13:20:49 295 0.00 +13:20:49 296 0.00 +13:20:49 297 0.00 +13:20:49 298 0.00 +13:20:49 299 0.00 +13:20:49 300 0.00 +13:20:49 301 0.00 +13:20:49 302 0.00 +13:20:49 303 0.00 +13:20:49 304 0.00 +13:20:49 305 0.00 +13:20:49 306 0.00 +13:20:49 307 0.00 +13:20:49 308 0.00 +13:20:49 309 0.00 +13:20:49 310 0.00 +13:20:49 311 0.00 +13:20:49 312 0.00 +13:20:49 313 0.00 +13:20:49 314 0.00 +13:20:49 315 0.00 +13:20:49 316 0.00 +13:20:49 317 0.00 +13:20:49 318 0.00 +13:20:49 319 0.00 +13:20:49 320 0.00 +13:20:49 321 0.00 +13:20:49 322 0.00 +13:20:49 323 0.00 +13:20:49 324 0.00 +13:20:49 325 0.00 +13:20:49 326 0.00 +13:20:49 327 0.00 +13:20:49 328 0.00 +13:20:49 329 0.00 +13:20:49 330 0.00 +13:20:49 331 0.00 +13:20:49 332 0.00 +13:20:49 333 0.00 +13:20:49 334 0.00 +13:20:49 335 0.00 +13:20:49 336 0.00 +13:20:49 337 0.00 +13:20:49 338 0.00 +13:20:49 339 0.00 +13:20:49 340 0.00 +13:20:49 341 0.00 +13:20:49 342 0.00 +13:20:49 343 0.00 +13:20:49 344 0.00 +13:20:49 345 0.00 +13:20:49 346 0.00 +13:20:49 347 0.00 +13:20:49 348 0.00 +13:20:49 349 0.00 +13:20:49 350 0.00 +13:20:49 351 0.00 +13:20:49 352 0.00 +13:20:49 353 0.00 +13:20:49 354 0.00 +13:20:49 355 0.00 +13:20:49 356 0.00 +13:20:49 357 0.00 +13:20:49 358 0.00 +13:20:49 359 0.00 +13:20:49 360 0.00 +13:20:49 361 0.00 +13:20:49 362 0.00 +13:20:49 363 0.00 +13:20:49 364 0.00 +13:20:49 365 0.00 +13:20:49 366 0.00 +13:20:49 367 0.00 +13:20:49 368 0.00 +13:20:49 369 0.00 +13:20:49 370 0.00 +13:20:49 371 0.00 +13:20:49 372 0.00 +13:20:49 373 0.00 +13:20:49 374 0.00 +13:20:49 375 0.00 +13:20:49 376 0.00 +13:20:49 377 0.00 +13:20:49 378 0.00 +13:20:49 379 0.00 +13:20:49 380 0.00 +13:20:49 381 0.00 +13:20:49 382 0.00 +13:20:49 383 0.00 +13:20:49 384 0.00 +13:20:49 385 0.00 +13:20:49 386 0.00 +13:20:49 387 0.00 +13:20:49 388 0.00 +13:20:49 389 0.00 +13:20:49 390 0.00 +13:20:49 391 0.00 +13:20:49 392 0.00 +13:20:49 393 0.00 +13:20:49 394 0.00 +13:20:49 395 0.00 +13:20:49 396 0.00 +13:20:49 397 0.00 +13:20:49 398 0.00 +13:20:49 399 0.00 +13:20:49 400 0.00 +13:20:49 401 0.00 +13:20:49 402 0.00 +13:20:49 403 0.00 +13:20:49 404 0.00 +13:20:49 405 0.00 +13:20:49 406 0.00 +13:20:49 407 0.00 +13:20:49 408 0.00 +13:20:49 409 0.00 +13:20:49 410 0.00 +13:20:49 411 0.00 +13:20:49 412 0.00 +13:20:49 413 0.00 +13:20:49 414 0.00 +13:20:49 415 0.00 +13:20:49 416 0.00 +13:20:49 417 0.00 +13:20:49 418 0.00 +13:20:49 419 0.00 +13:20:49 420 0.00 +13:20:49 421 0.00 +13:20:49 422 0.00 +13:20:49 423 0.00 +13:20:49 424 0.00 +13:20:49 425 0.00 +13:20:49 426 0.00 +13:20:49 427 0.00 +13:20:49 428 0.00 +13:20:49 429 0.00 +13:20:49 430 0.00 +13:20:49 431 0.00 +13:20:49 432 0.00 +13:20:49 433 0.00 +13:20:49 434 0.00 +13:20:49 435 0.00 +13:20:49 436 0.00 +13:20:49 437 0.00 +13:20:49 438 0.00 +13:20:49 439 0.00 +13:20:49 440 0.00 +13:20:49 441 0.00 +13:20:49 442 0.00 +13:20:49 443 0.00 +13:20:49 444 0.00 +13:20:49 445 0.00 +13:20:49 446 0.00 +13:20:49 447 0.00 +13:20:49 448 0.00 +13:20:49 449 0.00 +13:20:49 450 0.00 +13:20:49 451 0.00 +13:20:49 452 0.00 +13:20:49 453 0.00 +13:20:49 454 0.00 +13:20:49 455 0.00 +13:20:49 456 0.00 +13:20:49 457 0.00 +13:20:49 458 0.00 +13:20:49 459 0.00 +13:20:49 460 0.00 +13:20:49 461 0.00 +13:20:49 462 0.00 +13:20:49 463 0.00 +13:20:49 464 0.00 +13:20:49 465 0.00 +13:20:49 466 0.00 +13:20:49 467 0.00 +13:20:49 468 0.00 +13:20:49 469 0.00 +13:20:49 470 0.00 +13:20:49 471 0.00 +13:20:49 472 0.00 +13:20:49 473 0.00 +13:20:49 474 0.00 +13:20:49 475 0.00 +13:20:49 476 0.00 +13:20:49 477 0.00 +13:20:49 478 0.00 +13:20:49 479 0.00 +13:20:49 480 0.00 +13:20:49 481 0.00 +13:20:49 482 0.00 +13:20:49 483 0.00 +13:20:49 484 0.00 +13:20:49 485 0.00 +13:20:49 486 0.00 +13:20:49 487 0.00 +Average: sum 35847.70 +Average: 0 0.00 +Average: 1 0.00 +Average: 2 0.00 +Average: 3 0.00 +Average: 4 0.00 +Average: 5 0.00 +Average: 6 0.00 +Average: 7 0.00 +Average: 8 0.00 +Average: 9 0.00 +Average: 10 0.00 +Average: 11 0.00 +Average: 12 0.00 +Average: 13 0.00 +Average: 14 0.00 +Average: 15 0.00 +Average: 16 0.00 +Average: 17 0.00 +Average: 18 0.00 +Average: 19 24.42 +Average: 20 0.00 +Average: 21 0.00 +Average: 22 0.00 +Average: 23 27.81 +Average: 24 11.39 +Average: 25 0.00 +Average: 26 0.00 +Average: 27 0.00 +Average: 28 0.00 +Average: 29 0.00 +Average: 30 0.00 +Average: 31 0.00 +Average: 32 0.00 +Average: 33 29.71 +Average: 34 155.82 +Average: 35 0.00 +Average: 36 0.00 +Average: 37 0.00 +Average: 38 0.00 +Average: 39 0.00 +Average: 40 0.00 +Average: 41 0.00 +Average: 42 0.00 +Average: 43 0.00 +Average: 44 0.00 +Average: 45 0.00 +Average: 46 0.00 +Average: 47 0.00 +Average: 48 0.00 +Average: 49 0.00 +Average: 50 0.00 +Average: 51 0.00 +Average: 52 0.00 +Average: 53 0.00 +Average: 54 0.00 +Average: 55 0.00 +Average: 56 0.00 +Average: 57 0.00 +Average: 58 0.00 +Average: 59 0.00 +Average: 60 0.00 +Average: 61 0.00 +Average: 62 0.00 +Average: 63 0.00 +Average: 64 0.00 +Average: 65 0.00 +Average: 66 0.00 +Average: 67 0.00 +Average: 68 0.00 +Average: 69 0.00 +Average: 70 0.00 +Average: 71 0.00 +Average: 72 0.00 +Average: 73 0.00 +Average: 74 0.00 +Average: 75 0.00 +Average: 76 0.00 +Average: 77 0.00 +Average: 78 0.00 +Average: 79 0.00 +Average: 80 0.00 +Average: 81 0.00 +Average: 82 0.00 +Average: 83 0.00 +Average: 84 0.00 +Average: 85 0.00 +Average: 86 0.00 +Average: 87 0.00 +Average: 88 0.00 +Average: 89 0.00 +Average: 90 0.00 +Average: 91 0.00 +Average: 92 0.00 +Average: 93 0.00 +Average: 94 0.00 +Average: 95 0.00 +Average: 96 0.00 +Average: 97 0.00 +Average: 98 0.00 +Average: 99 0.00 +Average: 100 0.00 +Average: 101 0.00 +Average: 102 0.00 +Average: 103 0.00 +Average: 104 0.00 +Average: 105 0.00 +Average: 106 0.00 +Average: 107 0.00 +Average: 108 0.00 +Average: 109 0.00 +Average: 110 0.00 +Average: 111 0.00 +Average: 112 0.00 +Average: 113 0.00 +Average: 114 0.00 +Average: 115 0.00 +Average: 116 0.00 +Average: 117 0.00 +Average: 118 0.00 +Average: 119 0.00 +Average: 120 0.00 +Average: 121 0.00 +Average: 122 0.00 +Average: 123 0.00 +Average: 124 0.00 +Average: 125 0.00 +Average: 126 0.00 +Average: 127 0.00 +Average: 128 0.00 +Average: 129 0.00 +Average: 130 0.00 +Average: 131 0.00 +Average: 132 0.00 +Average: 133 0.00 +Average: 134 0.00 +Average: 135 0.00 +Average: 136 0.00 +Average: 137 0.00 +Average: 138 0.00 +Average: 139 0.00 +Average: 140 0.00 +Average: 141 0.00 +Average: 142 0.00 +Average: 143 0.00 +Average: 144 0.00 +Average: 145 0.00 +Average: 146 0.00 +Average: 147 0.00 +Average: 148 0.00 +Average: 149 0.00 +Average: 150 0.00 +Average: 151 0.00 +Average: 152 0.00 +Average: 153 0.00 +Average: 154 0.00 +Average: 155 0.00 +Average: 156 0.00 +Average: 157 0.00 +Average: 158 0.00 +Average: 159 0.00 +Average: 160 0.00 +Average: 161 0.00 +Average: 162 0.00 +Average: 163 0.00 +Average: 164 0.00 +Average: 165 0.00 +Average: 166 0.00 +Average: 167 0.00 +Average: 168 0.00 +Average: 169 0.00 +Average: 170 0.00 +Average: 171 0.00 +Average: 172 0.00 +Average: 173 0.00 +Average: 174 0.00 +Average: 175 0.00 +Average: 176 0.00 +Average: 177 0.00 +Average: 178 0.00 +Average: 179 0.00 +Average: 180 0.00 +Average: 181 0.00 +Average: 182 0.00 +Average: 183 0.00 +Average: 184 0.00 +Average: 185 0.00 +Average: 186 0.00 +Average: 187 0.00 +Average: 188 0.00 +Average: 189 0.00 +Average: 190 0.00 +Average: 191 0.00 +Average: 192 0.00 +Average: 193 0.00 +Average: 194 0.00 +Average: 195 0.00 +Average: 196 0.00 +Average: 197 0.00 +Average: 198 0.00 +Average: 199 0.00 +Average: 200 0.00 +Average: 201 0.00 +Average: 202 0.00 +Average: 203 0.00 +Average: 204 0.00 +Average: 205 0.00 +Average: 206 0.00 +Average: 207 0.00 +Average: 208 0.00 +Average: 209 0.00 +Average: 210 0.00 +Average: 211 0.00 +Average: 212 0.00 +Average: 213 0.00 +Average: 214 0.00 +Average: 215 0.00 +Average: 216 0.00 +Average: 217 0.00 +Average: 218 0.00 +Average: 219 0.00 +Average: 220 0.00 +Average: 221 0.00 +Average: 222 0.00 +Average: 223 0.00 +Average: 224 0.00 +Average: 225 0.00 +Average: 226 0.00 +Average: 227 0.00 +Average: 228 0.00 +Average: 229 0.00 +Average: 230 0.00 +Average: 231 0.00 +Average: 232 0.00 +Average: 233 0.00 +Average: 234 0.00 +Average: 235 0.00 +Average: 236 0.00 +Average: 237 0.00 +Average: 238 0.00 +Average: 239 0.00 +Average: 240 0.00 +Average: 241 0.00 +Average: 242 0.00 +Average: 243 0.00 +Average: 244 0.00 +Average: 245 0.00 +Average: 246 0.00 +Average: 247 0.00 +Average: 248 0.00 +Average: 249 0.00 +Average: 250 0.00 +Average: 251 0.00 +Average: 252 0.00 +Average: 253 0.00 +Average: 254 0.00 +Average: 255 0.00 +Average: 256 0.00 +Average: 257 0.00 +Average: 258 0.00 +Average: 259 0.00 +Average: 260 0.00 +Average: 261 0.00 +Average: 262 0.00 +Average: 263 0.00 +Average: 264 0.00 +Average: 265 0.00 +Average: 266 0.00 +Average: 267 0.00 +Average: 268 0.00 +Average: 269 0.00 +Average: 270 0.00 +Average: 271 0.00 +Average: 272 0.00 +Average: 273 0.00 +Average: 274 0.00 +Average: 275 0.00 +Average: 276 0.00 +Average: 277 0.00 +Average: 278 0.00 +Average: 279 0.00 +Average: 280 0.00 +Average: 281 0.00 +Average: 282 0.00 +Average: 283 0.00 +Average: 284 0.00 +Average: 285 0.00 +Average: 286 0.00 +Average: 287 0.00 +Average: 288 0.00 +Average: 289 0.00 +Average: 290 0.00 +Average: 291 0.00 +Average: 292 0.00 +Average: 293 0.00 +Average: 294 0.00 +Average: 295 0.00 +Average: 296 0.00 +Average: 297 0.00 +Average: 298 0.00 +Average: 299 0.00 +Average: 300 0.00 +Average: 301 0.00 +Average: 302 0.00 +Average: 303 0.00 +Average: 304 0.00 +Average: 305 0.00 +Average: 306 0.00 +Average: 307 0.00 +Average: 308 0.00 +Average: 309 0.00 +Average: 310 0.00 +Average: 311 0.00 +Average: 312 0.00 +Average: 313 0.00 +Average: 314 0.00 +Average: 315 0.00 +Average: 316 0.00 +Average: 317 0.00 +Average: 318 0.00 +Average: 319 0.00 +Average: 320 0.00 +Average: 321 0.00 +Average: 322 0.00 +Average: 323 0.00 +Average: 324 0.00 +Average: 325 0.00 +Average: 326 0.00 +Average: 327 0.00 +Average: 328 0.00 +Average: 329 0.00 +Average: 330 0.00 +Average: 331 0.00 +Average: 332 0.00 +Average: 333 0.00 +Average: 334 0.00 +Average: 335 0.00 +Average: 336 0.00 +Average: 337 0.00 +Average: 338 0.00 +Average: 339 0.00 +Average: 340 0.00 +Average: 341 0.00 +Average: 342 0.00 +Average: 343 0.00 +Average: 344 0.00 +Average: 345 0.00 +Average: 346 0.00 +Average: 347 0.00 +Average: 348 0.00 +Average: 349 0.00 +Average: 350 0.00 +Average: 351 0.00 +Average: 352 0.00 +Average: 353 0.00 +Average: 354 0.00 +Average: 355 0.00 +Average: 356 0.00 +Average: 357 0.00 +Average: 358 0.00 +Average: 359 0.00 +Average: 360 0.00 +Average: 361 0.00 +Average: 362 0.00 +Average: 363 0.00 +Average: 364 0.00 +Average: 365 0.00 +Average: 366 0.00 +Average: 367 0.00 +Average: 368 0.00 +Average: 369 0.00 +Average: 370 0.00 +Average: 371 0.00 +Average: 372 0.00 +Average: 373 0.00 +Average: 374 0.00 +Average: 375 0.00 +Average: 376 0.00 +Average: 377 0.00 +Average: 378 0.00 +Average: 379 0.00 +Average: 380 0.00 +Average: 381 0.00 +Average: 382 0.00 +Average: 383 0.00 +Average: 384 0.00 +Average: 385 0.00 +Average: 386 0.00 +Average: 387 0.00 +Average: 388 0.00 +Average: 389 0.00 +Average: 390 0.00 +Average: 391 0.00 +Average: 392 0.00 +Average: 393 0.00 +Average: 394 0.00 +Average: 395 0.00 +Average: 396 0.00 +Average: 397 0.00 +Average: 398 0.00 +Average: 399 0.00 +Average: 400 0.00 +Average: 401 0.00 +Average: 402 0.00 +Average: 403 0.00 +Average: 404 0.00 +Average: 405 0.00 +Average: 406 0.00 +Average: 407 0.00 +Average: 408 0.00 +Average: 409 0.00 +Average: 410 0.00 +Average: 411 0.00 +Average: 412 0.00 +Average: 413 0.00 +Average: 414 0.00 +Average: 415 0.00 +Average: 416 0.00 +Average: 417 0.00 +Average: 418 0.00 +Average: 419 0.00 +Average: 420 0.00 +Average: 421 0.00 +Average: 422 0.00 +Average: 423 0.00 +Average: 424 0.00 +Average: 425 0.00 +Average: 426 0.00 +Average: 427 0.00 +Average: 428 0.00 +Average: 429 0.00 +Average: 430 0.00 +Average: 431 0.00 +Average: 432 0.00 +Average: 433 0.00 +Average: 434 0.00 +Average: 435 0.00 +Average: 436 0.00 +Average: 437 0.00 +Average: 438 0.00 +Average: 439 0.00 +Average: 440 0.00 +Average: 441 0.00 +Average: 442 0.00 +Average: 443 0.00 +Average: 444 0.00 +Average: 445 0.00 +Average: 446 0.00 +Average: 447 0.00 +Average: 448 0.00 +Average: 449 0.00 +Average: 450 0.00 +Average: 451 0.00 +Average: 452 0.00 +Average: 453 0.00 +Average: 454 0.00 +Average: 455 0.00 +Average: 456 0.00 +Average: 457 0.00 +Average: 458 0.00 +Average: 459 0.00 +Average: 460 0.00 +Average: 461 0.00 +Average: 462 0.00 +Average: 463 0.00 +Average: 464 0.00 +Average: 465 0.00 +Average: 466 0.00 +Average: 467 0.00 +Average: 468 0.00 +Average: 469 0.00 +Average: 470 0.00 +Average: 471 0.00 +Average: 472 0.00 +Average: 473 0.00 +Average: 474 0.00 +Average: 475 0.00 +Average: 476 0.00 +Average: 477 0.00 +Average: 478 0.00 +Average: 479 0.00 +Average: 480 0.00 +Average: 481 0.00 +Average: 482 0.00 +Average: 483 0.00 +Average: 484 0.00 +Average: 485 0.00 +Average: 486 0.00 +Average: 487 0.00 + +13:20:09 pswpin/s pswpout/s +13:20:19 0.00 0.00 +13:20:29 0.00 0.00 +13:20:39 0.00 0.00 +13:20:49 0.00 0.00 +Average: 0.00 0.00 + +13:20:09 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 tps rtps wtps bread/s bwrtn/s +13:20:19 0.00 0.00 0.00 0.00 0.00 +13:20:29 5.44 2.24 3.20 0.00 3.20 +13:20:39 0.00 0.91 0.00 299.22 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 + +13:20:09 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty kbanonpg kbslab kbkstack kbpgtbl kbvmused +13:20:19 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 +13:20:29 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 +13:20:39 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 +13:20:49 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 +Average: 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 + +13:20:09 kbswpfree kbswpused %swpused kbswpcad %swpcad +13:20:19 16777212 0 0.00 0 0.00 +13:20:29 16777212 0 0.00 0 0.00 +13:20:39 16777212 0 0.00 0 0.00 +13:20:49 16777212 0 0.00 0 0.00 +Average: 16777212 0 0.00 0 0.00 + +13:20:09 kbhugfree kbhugused %hugused +13:20:19 0 0 0.00 +13:20:29 0 0 0.00 +13:20:39 0 0 0.00 +13:20:49 0 0 0.00 +Average: 0 0 0.00 + +13:20:09 dentunusd file-nr inode-nr pty-nr +13:20:19 156063 16704 157735 4 +13:20:29 156063 16704 157735 4 +13:20:39 156063 16704 157735 4 +13:20:49 156063 16704 157735 4 +Average: 156063 16704 157735 4 + +13:20:09 runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 blocked +13:20:19 3 956 3.16 3.24 3.43 0 +13:20:29 3 956 3.16 3.24 3.43 0 +13:20:39 3 956 3.16 3.24 3.43 0 +13:20:49 3 956 3.16 3.24 3.43 0 +Average: 3 956 3.16 3.24 3.43 0 + +13:20:09 TTY rcvin/s txmtin/s framerr/s prtyerr/s brk/s ovrun/s +13:20:19 0 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 1 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 1 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 1 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 1 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 1 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util +13:20:19 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 dev8-16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-0 6.40 1.60 1.60 0.50 0.00 1.00 0.50 0.32 +13:20:29 dev8-1 6.40 1.60 1.60 0.50 0.00 1.00 0.50 0.32 +13:20:29 dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 dev8-16 590484765483660416.00 295242382741830208.00 0.00 0.50 137482.95 0.00 0.00 13748294.72 +13:20:39 dev8-0 1604.70 41499.97 10663.48 32.51 18.56 12.00 0.53 85.36 +13:20:39 dev8-1 1.32 54.75 0.00 41.33 0.08 60.92 0.80 0.11 +13:20:39 dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 dev8-80 1.22 54.34 0.00 44.51 0.08 62.51 0.70 0.09 +13:20:39 dev8-96 2.91 114.91 0.31 39.61 0.07 24.75 0.65 0.19 +13:20:49 dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-80 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 dev8-96 0.94 22.33 0.22 24.05 0.04 6.19 0.95 0.09 +Average: dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-10 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-11 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-80 0.38 16.97 0.00 44.51 0.02 62.51 0.70 0.03 +Average: dev8-96 1.08 39.94 0.14 37.15 0.03 21.82 0.70 0.08 + +13:20:09 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +13:20:19 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 enp6s0 53.55 17.45 64.37 3.38 0.00 0.00 9.25 0.05 +13:20:29 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 enp6s1 1.90 1.17 0.23 0.21 0.00 0.00 2.31 0.00 +13:20:39 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 wlp5s1 0.39 0.13 0.03 0.01 0.00 0.00 0.00 0.00 +13:20:49 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 enp6s0 7397.68 2412.77 8891.46 466.82 0.00 0.00 116.21 7.28 +13:20:49 enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 wlp5s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s1 0.59 0.36 0.07 0.06 0.00 0.00 0.72 0.00 +Average: virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s1 0.12 0.04 0.01 0.00 0.00 0.00 0.00 0.00 + +13:20:09 IFACE rxerr/s txerr/s coll/s rxdrop/s txdrop/s txcarr/s rxfram/s rxfifo/s txfifo/s +13:20:19 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:19 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 wlp5s1 0.00 0.00 0.26 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 wlp5s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s1 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 call/s retrans/s read/s write/s access/s getatt/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 scall/s badcall/s packet/s udp/s tcp/s hit/s miss/s sread/s swrite/s saccess/s sgetatt/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 totsck tcpsck udpsck rawsck ip-frag tcp-tw +13:20:19 1316 10 6 0 0 1 +13:20:29 1316 10 6 0 0 1 +13:20:39 1316 10 6 0 0 1 +13:20:49 1316 10 6 0 0 1 +Average: 1316 10 6 0 0 1 + +13:20:09 irec/s fwddgm/s idel/s orq/s asmrq/s asmok/s fragok/s fragcrt/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 ihdrerr/s iadrerr/s iukwnpr/s idisc/s odisc/s onort/s asmf/s fragf/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 imsg/s omsg/s iech/s iechr/s oech/s oechr/s itm/s itmr/s otm/s otmr/s iadrmk/s iadrmkr/s oadrmk/s oadrmkr/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 ierr/s oerr/s idstunr/s odstunr/s itmex/s otmex/s iparmpb/s oparmpb/s isrcq/s osrcq/s iredir/s oredir/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 active/s passive/s iseg/s oseg/s +13:20:19 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:20:09 atmptf/s estres/s retrans/s isegerr/s orsts/s +13:20:19 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 + +13:20:09 idgm/s odgm/s noport/s idgmerr/s +13:20:19 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:20:09 tcp6sck udp6sck raw6sck ip6-frag +13:20:19 3 3 1 0 +13:20:29 3 3 1 0 +13:20:39 3 3 1 0 +13:20:49 3 3 1 0 +Average: 3 3 1 0 + +13:20:09 irec6/s fwddgm6/s idel6/s orq6/s asmrq6/s asmok6/s imcpck6/s omcpck6/s fragok6/s fragcr6/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 ihdrer6/s iadrer6/s iukwnp6/s i2big6/s idisc6/s odisc6/s inort6/s onort6/s asmf6/s fragf6/s itrpck6/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 imsg6/s omsg6/s iech6/s iechr6/s oechr6/s igmbq6/s igmbr6/s ogmbr6/s igmbrd6/s ogmbrd6/s irtsol6/s ortsol6/s irtad6/s inbsol6/s onbsol6/s inbad6/s onbad6/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 ierr6/s idtunr6/s odtunr6/s itmex6/s otmex6/s iprmpb6/s oprmpb6/s iredir6/s oredir6/s ipck2b6/s opck2b6/s +13:20:19 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:20:09 idgm6/s odgm6/s noport6/s idgmer6/s +13:20:19 0.00 0.00 0.00 0.00 +13:20:29 0.00 0.00 0.00 0.00 +13:20:39 0.00 0.00 0.00 0.00 +13:20:49 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:20:09 fch_rxf/s fch_txf/s fch_rxw/s fch_txw/s FCHOST +13:20:19 0.00 0.00 0.00 0.00 host0 +13:20:29 0.00 0.00 0.00 0.00 host0 +13:20:39 0.00 0.00 0.00 0.00 host0 +13:20:49 0.00 0.00 0.00 0.00 host0 +13:20:49 0.00 0.00 0.00 0.00 host1 +Average: 0.00 0.00 0.00 0.00 host0 + +13:20:09 CPU total/s dropd/s squeezd/s rx_rps/s flw_lim/s +13:20:19 all 0.00 0.00 0.00 0.00 0.00 +13:20:19 0 0.00 0.00 0.00 0.00 0.00 +13:20:19 1 0.00 0.00 0.00 0.00 0.00 +13:20:19 2 0.00 0.00 0.00 0.00 0.00 +13:20:19 3 0.00 0.00 0.00 0.00 0.00 +13:20:19 4 0.00 0.00 0.00 0.00 0.00 +13:20:19 5 0.00 0.00 0.00 0.00 0.00 +13:20:19 6 0.00 0.00 0.00 0.00 0.00 +13:20:19 7 0.00 0.00 0.00 0.00 0.00 +13:20:29 all 0.00 0.00 0.00 0.00 0.00 +13:20:29 0 0.00 0.00 0.00 0.00 0.00 +13:20:29 1 0.00 0.00 0.00 0.00 0.00 +13:20:29 2 0.00 0.00 0.00 0.00 0.00 +13:20:29 3 0.00 0.00 0.00 0.00 0.00 +13:20:29 4 0.00 0.00 0.00 0.00 0.00 +13:20:29 5 0.00 0.00 0.00 0.00 0.00 +13:20:29 7 0.00 0.00 0.00 0.00 0.00 +13:20:39 all 0.00 0.00 0.00 0.00 0.00 +13:20:39 0 0.00 0.00 0.00 0.00 0.00 +13:20:39 1 0.00 0.00 0.00 0.00 0.00 +13:20:39 2 0.00 0.00 0.00 0.00 0.00 +13:20:39 3 0.00 0.00 0.00 0.00 0.00 +13:20:39 4 0.00 0.00 0.00 0.00 0.00 +13:20:39 5 0.00 0.00 0.00 0.00 0.00 +13:20:39 7 0.00 0.00 0.00 0.00 0.00 +13:20:49 all 0.00 0.00 0.00 0.00 0.00 +13:20:49 0 0.00 0.00 0.00 0.00 0.00 +13:20:49 1 0.00 0.00 0.00 0.00 0.00 +13:20:49 2 0.00 0.00 0.00 0.00 0.00 +13:20:49 3 0.00 0.00 0.00 0.00 0.00 +13:20:49 4 0.00 0.00 0.00 0.00 0.00 +13:20:49 5 0.00 0.00 0.00 0.00 0.00 +13:20:49 6 0.00 0.00 0.00 0.00 0.00 +13:20:49 7 0.00 0.00 0.00 0.00 0.00 +Average: all 0.00 0.00 0.00 0.00 0.00 +Average: 0 0.00 0.00 0.00 0.00 0.00 +Average: 1 0.00 0.00 0.00 0.00 0.00 +Average: 2 0.00 0.00 0.00 0.00 0.00 +Average: 3 0.00 0.00 0.00 0.00 0.00 +Average: 4 0.00 0.00 0.00 0.00 0.00 +Average: 5 0.00 0.00 0.00 0.00 0.00 +Average: 6 0.00 0.00 0.00 0.00 0.00 +Average: 7 0.00 0.00 0.00 0.00 0.00 + +13:20:09 CPU MHz +13:20:19 all 3522.54 +13:20:19 0 3566.48 +13:20:19 1 3566.39 +13:20:19 2 3492.11 +13:20:19 3 3566.22 +13:20:19 4 3505.84 +13:20:19 5 3493.55 +13:20:19 6 3492.22 +13:20:19 7 3497.56 +13:20:29 all 3522.54 +13:20:29 0 3566.48 +13:20:29 1 3566.39 +13:20:29 2 3492.11 +13:20:29 3 3566.22 +13:20:29 4 3505.84 +13:20:29 5 3493.55 +13:20:29 6 3492.22 +13:20:29 7 3497.56 +13:20:39 all 3522.54 +13:20:39 0 3566.48 +13:20:39 1 3566.39 +13:20:39 2 3492.11 +13:20:39 3 3566.22 +13:20:39 4 3505.84 +13:20:39 5 3493.55 +13:20:39 6 3492.22 +13:20:39 7 3497.56 +13:20:49 all 3522.54 +13:20:49 0 3566.48 +13:20:49 1 3566.39 +13:20:49 2 3492.11 +13:20:49 3 3566.22 +13:20:49 4 3505.84 +13:20:49 5 3493.55 +13:20:49 6 3492.22 +13:20:49 7 3497.56 +Average: all 3522.54 +Average: 0 3566.48 +Average: 1 3566.39 +Average: 2 3492.11 +Average: 3 3566.22 +Average: 4 3505.84 +Average: 5 3493.55 +Average: 6 3492.22 +Average: 7 3497.56 + +13:20:09 MBfsfree MBfsused %fsused %ufsused Ifree Iused %Iused FILESYSTEM +13:20:19 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda9 +13:20:19 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda7 +13:20:19 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda12 +13:20:19 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda6 +13:20:29 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda9 +13:20:29 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda7 +13:20:29 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda12 +13:20:29 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda6 +13:20:29 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sdf +13:20:29 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sdg +13:20:39 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda9 +13:20:39 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda7 +13:20:39 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda12 +13:20:39 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda6 +13:20:39 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sdf +13:20:39 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sdg +13:20:49 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda9 +13:20:49 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda7 +13:20:49 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda12 +13:20:49 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda6 +Summary: 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda9 +Summary: 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda7 +Summary: 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda12 +Summary: 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda6 +Summary: 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sdf +Summary: 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sdg + +13:37:29 LINUX RESTART (8 CPU) +13:39:09 COM Testing sysstat! + +13:54:09 LINUX RESTART (10 CPU) + +13:54:15 CPU %usr %nice %sys %iowait %steal %irq %soft %guest %gnice %idle +13:54:35 all 2.47 17.21 2.21 0.77 0.00 0.96 0.22 0.00 0.00 76.16 +13:54:35 0 2.71 0.03 2.16 0.00 0.00 0.32 0.64 0.00 0.00 94.14 +13:54:35 1 2.85 0.00 4.28 0.00 0.00 0.68 0.19 0.00 0.00 91.99 +13:54:35 2 2.25 0.03 1.51 0.68 0.00 0.23 0.13 0.00 0.00 95.18 +13:54:35 3 0.00 99.55 0.06 0.00 0.00 0.32 0.06 0.00 0.00 0.00 +13:54:35 4 2.41 0.00 1.61 0.03 0.00 0.26 0.19 0.00 0.00 95.50 +13:54:35 5 1.65 0.00 2.33 0.00 0.00 0.36 0.10 0.00 0.00 95.57 +13:54:35 6 2.41 0.00 2.03 0.16 0.00 0.48 0.10 0.00 0.00 94.82 +13:54:35 7 2.89 0.00 0.74 0.06 0.00 0.06 0.06 0.00 0.00 96.18 +13:54:35 8 4.15 41.49 4.15 4.15 0.00 4.15 0.41 0.00 0.00 41.49 +13:54:35 9 4.15 41.49 4.15 4.15 0.00 4.15 0.41 0.00 0.00 41.49 +Average: all 2.47 17.21 2.21 0.77 0.00 0.96 0.22 0.00 0.00 76.16 +Average: 0 2.71 0.03 2.16 0.00 0.00 0.32 0.64 0.00 0.00 94.14 +Average: 1 2.85 0.00 4.28 0.00 0.00 0.68 0.19 0.00 0.00 91.99 +Average: 2 2.25 0.03 1.51 0.68 0.00 0.23 0.13 0.00 0.00 95.18 +Average: 3 0.00 99.55 0.06 0.00 0.00 0.32 0.06 0.00 0.00 0.00 +Average: 4 2.41 0.00 1.61 0.03 0.00 0.26 0.19 0.00 0.00 95.50 +Average: 5 1.65 0.00 2.33 0.00 0.00 0.36 0.10 0.00 0.00 95.57 +Average: 6 2.41 0.00 2.03 0.16 0.00 0.48 0.10 0.00 0.00 94.82 +Average: 7 2.89 0.00 0.74 0.06 0.00 0.06 0.06 0.00 0.00 96.18 +Average: 8 4.15 41.49 4.15 4.15 0.00 4.15 0.41 0.00 0.00 41.49 +Average: 9 4.15 41.49 4.15 4.15 0.00 4.15 0.41 0.00 0.00 41.49 + +13:54:15 proc/s cswch/s +13:54:35 3.56 68409.30 +Average: 3.56 68409.30 + +13:54:15 INTR intr/s +13:54:35 sum 35525.06 +13:54:35 0 0.00 +13:54:35 1 0.00 +13:54:35 2 0.00 +13:54:35 3 0.00 +13:54:35 4 0.00 +13:54:35 5 0.00 +13:54:35 6 0.00 +13:54:35 7 0.00 +13:54:35 8 0.00 +13:54:35 9 0.00 +13:54:35 10 0.00 +13:54:35 11 0.00 +13:54:35 12 0.00 +13:54:35 13 0.00 +13:54:35 14 0.00 +13:54:35 15 0.00 +13:54:35 16 0.00 +13:54:35 17 0.00 +13:54:35 18 0.00 +13:54:35 19 25.92 +13:54:35 20 0.00 +13:54:35 21 0.00 +13:54:35 22 0.00 +13:54:35 23 35.03 +13:54:35 24 10.39 +13:54:35 25 0.00 +13:54:35 26 0.00 +13:54:35 27 0.00 +13:54:35 28 0.00 +13:54:35 29 0.00 +13:54:35 30 0.00 +13:54:35 31 0.00 +13:54:35 32 0.00 +13:54:35 33 15.11 +13:54:35 34 149.98 +13:54:35 35 0.00 +13:54:35 36 0.00 +13:54:35 37 0.00 +13:54:35 38 0.00 +13:54:35 39 0.00 +13:54:35 40 0.00 +13:54:35 41 0.00 +13:54:35 42 0.00 +13:54:35 43 0.00 +13:54:35 44 0.00 +13:54:35 45 0.00 +13:54:35 46 0.00 +13:54:35 47 0.00 +13:54:35 48 0.00 +13:54:35 49 0.00 +13:54:35 50 0.00 +13:54:35 51 0.00 +13:54:35 52 0.00 +13:54:35 53 0.00 +13:54:35 54 0.00 +13:54:35 55 0.00 +13:54:35 56 0.00 +13:54:35 57 0.00 +13:54:35 58 0.00 +13:54:35 59 0.00 +13:54:35 60 0.00 +13:54:35 61 0.00 +13:54:35 62 0.00 +13:54:35 63 0.00 +13:54:35 64 0.00 +13:54:35 65 0.00 +13:54:35 66 0.00 +13:54:35 67 0.00 +13:54:35 68 0.00 +13:54:35 69 0.00 +13:54:35 70 0.00 +13:54:35 71 0.00 +13:54:35 72 0.00 +13:54:35 73 0.00 +13:54:35 74 0.00 +13:54:35 75 0.00 +13:54:35 76 0.00 +13:54:35 77 0.00 +13:54:35 78 0.00 +13:54:35 79 0.00 +13:54:35 80 0.00 +13:54:35 81 0.00 +13:54:35 82 0.00 +13:54:35 83 0.00 +13:54:35 84 0.00 +13:54:35 85 0.00 +13:54:35 86 0.00 +13:54:35 87 0.00 +13:54:35 88 0.00 +13:54:35 89 0.00 +13:54:35 90 0.00 +13:54:35 91 0.00 +13:54:35 92 0.00 +13:54:35 93 0.00 +13:54:35 94 0.00 +13:54:35 95 0.00 +13:54:35 96 0.00 +13:54:35 97 0.00 +13:54:35 98 0.00 +13:54:35 99 0.00 +13:54:35 100 0.00 +13:54:35 101 0.00 +13:54:35 102 0.00 +13:54:35 103 0.00 +13:54:35 104 0.00 +13:54:35 105 0.00 +13:54:35 106 0.00 +13:54:35 107 0.00 +13:54:35 108 0.00 +13:54:35 109 0.00 +13:54:35 110 0.00 +13:54:35 111 0.00 +13:54:35 112 0.00 +13:54:35 113 0.00 +13:54:35 114 0.00 +13:54:35 115 0.00 +13:54:35 116 0.00 +13:54:35 117 0.00 +13:54:35 118 0.00 +13:54:35 119 0.00 +13:54:35 120 0.00 +13:54:35 121 0.00 +13:54:35 122 0.00 +13:54:35 123 0.00 +13:54:35 124 0.00 +13:54:35 125 0.00 +13:54:35 126 0.00 +13:54:35 127 0.00 +13:54:35 128 0.00 +13:54:35 129 0.00 +13:54:35 130 0.00 +13:54:35 131 0.00 +13:54:35 132 0.00 +13:54:35 133 0.00 +13:54:35 134 0.00 +13:54:35 135 0.00 +13:54:35 136 0.00 +13:54:35 137 0.00 +13:54:35 138 0.00 +13:54:35 139 0.00 +13:54:35 140 0.00 +13:54:35 141 0.00 +13:54:35 142 0.00 +13:54:35 143 0.00 +13:54:35 144 0.00 +13:54:35 145 0.00 +13:54:35 146 0.00 +13:54:35 147 0.00 +13:54:35 148 0.00 +13:54:35 149 0.00 +13:54:35 150 0.00 +13:54:35 151 0.00 +13:54:35 152 0.00 +13:54:35 153 0.00 +13:54:35 154 0.00 +13:54:35 155 0.00 +13:54:35 156 0.00 +13:54:35 157 0.00 +13:54:35 158 0.00 +13:54:35 159 0.00 +13:54:35 160 0.00 +13:54:35 161 0.00 +13:54:35 162 0.00 +13:54:35 163 0.00 +13:54:35 164 0.00 +13:54:35 165 0.00 +13:54:35 166 0.00 +13:54:35 167 0.00 +13:54:35 168 0.00 +13:54:35 169 0.00 +13:54:35 170 0.00 +13:54:35 171 0.00 +13:54:35 172 0.00 +13:54:35 173 0.00 +13:54:35 174 0.00 +13:54:35 175 0.00 +13:54:35 176 0.00 +13:54:35 177 0.00 +13:54:35 178 0.00 +13:54:35 179 0.00 +13:54:35 180 0.00 +13:54:35 181 0.00 +13:54:35 182 0.00 +13:54:35 183 0.00 +13:54:35 184 0.00 +13:54:35 185 0.00 +13:54:35 186 0.00 +13:54:35 187 0.00 +13:54:35 188 0.00 +13:54:35 189 0.00 +13:54:35 190 0.00 +13:54:35 191 0.00 +13:54:35 192 0.00 +13:54:35 193 0.00 +13:54:35 194 0.00 +13:54:35 195 0.00 +13:54:35 196 0.00 +13:54:35 197 0.00 +13:54:35 198 0.00 +13:54:35 199 0.00 +13:54:35 200 0.00 +13:54:35 201 0.00 +13:54:35 202 0.00 +13:54:35 203 0.00 +13:54:35 204 0.00 +13:54:35 205 0.00 +13:54:35 206 0.00 +13:54:35 207 0.00 +13:54:35 208 0.00 +13:54:35 209 0.00 +13:54:35 210 0.00 +13:54:35 211 0.00 +13:54:35 212 0.00 +13:54:35 213 0.00 +13:54:35 214 0.00 +13:54:35 215 0.00 +13:54:35 216 0.00 +13:54:35 217 0.00 +13:54:35 218 0.00 +13:54:35 219 0.00 +13:54:35 220 0.00 +13:54:35 221 0.00 +13:54:35 222 0.00 +13:54:35 223 0.00 +13:54:35 224 0.00 +13:54:35 225 0.00 +13:54:35 226 0.00 +13:54:35 227 0.00 +13:54:35 228 0.00 +13:54:35 229 0.00 +13:54:35 230 0.00 +13:54:35 231 0.00 +13:54:35 232 0.00 +13:54:35 233 0.00 +13:54:35 234 0.00 +13:54:35 235 0.00 +13:54:35 236 0.00 +13:54:35 237 0.00 +13:54:35 238 0.00 +13:54:35 239 0.00 +13:54:35 240 0.00 +13:54:35 241 0.00 +13:54:35 242 0.00 +13:54:35 243 0.00 +13:54:35 244 0.00 +13:54:35 245 0.00 +13:54:35 246 0.00 +13:54:35 247 0.00 +13:54:35 248 0.00 +13:54:35 249 0.00 +13:54:35 250 0.00 +13:54:35 251 0.00 +13:54:35 252 0.00 +13:54:35 253 0.00 +13:54:35 254 0.00 +13:54:35 255 0.00 +13:54:35 256 0.00 +13:54:35 257 0.00 +13:54:35 258 0.00 +13:54:35 259 0.00 +13:54:35 260 0.00 +13:54:35 261 0.00 +13:54:35 262 0.00 +13:54:35 263 0.00 +13:54:35 264 0.00 +13:54:35 265 0.00 +13:54:35 266 0.00 +13:54:35 267 0.00 +13:54:35 268 0.00 +13:54:35 269 0.00 +13:54:35 270 0.00 +13:54:35 271 0.00 +13:54:35 272 0.00 +13:54:35 273 0.00 +13:54:35 274 0.00 +13:54:35 275 0.00 +13:54:35 276 0.00 +13:54:35 277 0.00 +13:54:35 278 0.00 +13:54:35 279 0.00 +13:54:35 280 0.00 +13:54:35 281 0.00 +13:54:35 282 0.00 +13:54:35 283 0.00 +13:54:35 284 0.00 +13:54:35 285 0.00 +13:54:35 286 0.00 +13:54:35 287 0.00 +13:54:35 288 0.00 +13:54:35 289 0.00 +13:54:35 290 0.00 +13:54:35 291 0.00 +13:54:35 292 0.00 +13:54:35 293 0.00 +13:54:35 294 0.00 +13:54:35 295 0.00 +13:54:35 296 0.00 +13:54:35 297 0.00 +13:54:35 298 0.00 +13:54:35 299 0.00 +13:54:35 300 0.00 +13:54:35 301 0.00 +13:54:35 302 0.00 +13:54:35 303 0.00 +13:54:35 304 0.00 +13:54:35 305 0.00 +13:54:35 306 0.00 +13:54:35 307 0.00 +13:54:35 308 0.00 +13:54:35 309 0.00 +13:54:35 310 0.00 +13:54:35 311 0.00 +13:54:35 312 0.00 +13:54:35 313 0.00 +13:54:35 314 0.00 +13:54:35 315 0.00 +13:54:35 316 0.00 +13:54:35 317 0.00 +13:54:35 318 0.00 +13:54:35 319 0.00 +13:54:35 320 0.00 +13:54:35 321 0.00 +13:54:35 322 0.00 +13:54:35 323 0.00 +13:54:35 324 0.00 +13:54:35 325 0.00 +13:54:35 326 0.00 +13:54:35 327 0.00 +13:54:35 328 0.00 +13:54:35 329 0.00 +13:54:35 330 0.00 +13:54:35 331 0.00 +13:54:35 332 0.00 +13:54:35 333 0.00 +13:54:35 334 0.00 +13:54:35 335 0.00 +13:54:35 336 0.00 +13:54:35 337 0.00 +13:54:35 338 0.00 +13:54:35 339 0.00 +13:54:35 340 0.00 +13:54:35 341 0.00 +13:54:35 342 0.00 +13:54:35 343 0.00 +13:54:35 344 0.00 +13:54:35 345 0.00 +13:54:35 346 0.00 +13:54:35 347 0.00 +13:54:35 348 0.00 +13:54:35 349 0.00 +13:54:35 350 0.00 +13:54:35 351 0.00 +13:54:35 352 0.00 +13:54:35 353 0.00 +13:54:35 354 0.00 +13:54:35 355 0.00 +13:54:35 356 0.00 +13:54:35 357 0.00 +13:54:35 358 0.00 +13:54:35 359 0.00 +13:54:35 360 0.00 +13:54:35 361 0.00 +13:54:35 362 0.00 +13:54:35 363 0.00 +13:54:35 364 0.00 +13:54:35 365 0.00 +13:54:35 366 0.00 +13:54:35 367 0.00 +13:54:35 368 0.00 +13:54:35 369 0.00 +13:54:35 370 0.00 +13:54:35 371 0.00 +13:54:35 372 0.00 +13:54:35 373 0.00 +13:54:35 374 0.00 +13:54:35 375 0.00 +13:54:35 376 0.00 +13:54:35 377 0.00 +13:54:35 378 0.00 +13:54:35 379 0.00 +13:54:35 380 0.00 +13:54:35 381 0.00 +13:54:35 382 0.00 +13:54:35 383 0.00 +13:54:35 384 0.00 +13:54:35 385 0.00 +13:54:35 386 0.00 +13:54:35 387 0.00 +13:54:35 388 0.00 +13:54:35 389 0.00 +13:54:35 390 0.00 +13:54:35 391 0.00 +13:54:35 392 0.00 +13:54:35 393 0.00 +13:54:35 394 0.00 +13:54:35 395 0.00 +13:54:35 396 0.00 +13:54:35 397 0.00 +13:54:35 398 0.00 +13:54:35 399 0.00 +13:54:35 400 0.00 +13:54:35 401 0.00 +13:54:35 402 0.00 +13:54:35 403 0.00 +13:54:35 404 0.00 +13:54:35 405 0.00 +13:54:35 406 0.00 +13:54:35 407 0.00 +13:54:35 408 0.00 +13:54:35 409 0.00 +13:54:35 410 0.00 +13:54:35 411 0.00 +13:54:35 412 0.00 +13:54:35 413 0.00 +13:54:35 414 0.00 +13:54:35 415 0.00 +13:54:35 416 0.00 +13:54:35 417 0.00 +13:54:35 418 0.00 +13:54:35 419 0.00 +13:54:35 420 0.00 +13:54:35 421 0.00 +13:54:35 422 0.00 +13:54:35 423 0.00 +13:54:35 424 0.00 +13:54:35 425 0.00 +13:54:35 426 0.00 +13:54:35 427 0.00 +13:54:35 428 0.00 +13:54:35 429 0.00 +13:54:35 430 0.00 +13:54:35 431 0.00 +13:54:35 432 0.00 +13:54:35 433 0.00 +13:54:35 434 0.00 +13:54:35 435 0.00 +13:54:35 436 0.00 +13:54:35 437 0.00 +13:54:35 438 0.00 +13:54:35 439 0.00 +13:54:35 440 0.00 +13:54:35 441 0.00 +13:54:35 442 0.00 +13:54:35 443 0.00 +13:54:35 444 0.00 +13:54:35 445 0.00 +13:54:35 446 0.00 +13:54:35 447 0.00 +13:54:35 448 0.00 +13:54:35 449 0.00 +13:54:35 450 0.00 +13:54:35 451 0.00 +13:54:35 452 0.00 +13:54:35 453 0.00 +13:54:35 454 0.00 +13:54:35 455 0.00 +13:54:35 456 0.00 +13:54:35 457 0.00 +13:54:35 458 0.00 +13:54:35 459 0.00 +13:54:35 460 0.00 +13:54:35 461 0.00 +13:54:35 462 0.00 +13:54:35 463 0.00 +13:54:35 464 0.00 +13:54:35 465 0.00 +13:54:35 466 0.00 +13:54:35 467 0.00 +13:54:35 468 0.00 +13:54:35 469 0.00 +13:54:35 470 0.00 +13:54:35 471 0.00 +13:54:35 472 0.00 +13:54:35 473 0.00 +13:54:35 474 0.00 +13:54:35 475 0.00 +13:54:35 476 0.00 +13:54:35 477 0.00 +13:54:35 478 0.00 +13:54:35 479 0.00 +13:54:35 480 0.00 +13:54:35 481 0.00 +13:54:35 482 0.00 +13:54:35 483 0.00 +13:54:35 484 0.00 +13:54:35 485 0.00 +13:54:35 486 0.00 +13:54:35 487 0.00 +Average: sum 35525.06 +Average: 0 0.00 +Average: 1 0.00 +Average: 2 0.00 +Average: 3 0.00 +Average: 4 0.00 +Average: 5 0.00 +Average: 6 0.00 +Average: 7 0.00 +Average: 8 0.00 +Average: 9 0.00 +Average: 10 0.00 +Average: 11 0.00 +Average: 12 0.00 +Average: 13 0.00 +Average: 14 0.00 +Average: 15 0.00 +Average: 16 0.00 +Average: 17 0.00 +Average: 18 0.00 +Average: 19 25.92 +Average: 20 0.00 +Average: 21 0.00 +Average: 22 0.00 +Average: 23 35.03 +Average: 24 10.39 +Average: 25 0.00 +Average: 26 0.00 +Average: 27 0.00 +Average: 28 0.00 +Average: 29 0.00 +Average: 30 0.00 +Average: 31 0.00 +Average: 32 0.00 +Average: 33 15.11 +Average: 34 149.98 +Average: 35 0.00 +Average: 36 0.00 +Average: 37 0.00 +Average: 38 0.00 +Average: 39 0.00 +Average: 40 0.00 +Average: 41 0.00 +Average: 42 0.00 +Average: 43 0.00 +Average: 44 0.00 +Average: 45 0.00 +Average: 46 0.00 +Average: 47 0.00 +Average: 48 0.00 +Average: 49 0.00 +Average: 50 0.00 +Average: 51 0.00 +Average: 52 0.00 +Average: 53 0.00 +Average: 54 0.00 +Average: 55 0.00 +Average: 56 0.00 +Average: 57 0.00 +Average: 58 0.00 +Average: 59 0.00 +Average: 60 0.00 +Average: 61 0.00 +Average: 62 0.00 +Average: 63 0.00 +Average: 64 0.00 +Average: 65 0.00 +Average: 66 0.00 +Average: 67 0.00 +Average: 68 0.00 +Average: 69 0.00 +Average: 70 0.00 +Average: 71 0.00 +Average: 72 0.00 +Average: 73 0.00 +Average: 74 0.00 +Average: 75 0.00 +Average: 76 0.00 +Average: 77 0.00 +Average: 78 0.00 +Average: 79 0.00 +Average: 80 0.00 +Average: 81 0.00 +Average: 82 0.00 +Average: 83 0.00 +Average: 84 0.00 +Average: 85 0.00 +Average: 86 0.00 +Average: 87 0.00 +Average: 88 0.00 +Average: 89 0.00 +Average: 90 0.00 +Average: 91 0.00 +Average: 92 0.00 +Average: 93 0.00 +Average: 94 0.00 +Average: 95 0.00 +Average: 96 0.00 +Average: 97 0.00 +Average: 98 0.00 +Average: 99 0.00 +Average: 100 0.00 +Average: 101 0.00 +Average: 102 0.00 +Average: 103 0.00 +Average: 104 0.00 +Average: 105 0.00 +Average: 106 0.00 +Average: 107 0.00 +Average: 108 0.00 +Average: 109 0.00 +Average: 110 0.00 +Average: 111 0.00 +Average: 112 0.00 +Average: 113 0.00 +Average: 114 0.00 +Average: 115 0.00 +Average: 116 0.00 +Average: 117 0.00 +Average: 118 0.00 +Average: 119 0.00 +Average: 120 0.00 +Average: 121 0.00 +Average: 122 0.00 +Average: 123 0.00 +Average: 124 0.00 +Average: 125 0.00 +Average: 126 0.00 +Average: 127 0.00 +Average: 128 0.00 +Average: 129 0.00 +Average: 130 0.00 +Average: 131 0.00 +Average: 132 0.00 +Average: 133 0.00 +Average: 134 0.00 +Average: 135 0.00 +Average: 136 0.00 +Average: 137 0.00 +Average: 138 0.00 +Average: 139 0.00 +Average: 140 0.00 +Average: 141 0.00 +Average: 142 0.00 +Average: 143 0.00 +Average: 144 0.00 +Average: 145 0.00 +Average: 146 0.00 +Average: 147 0.00 +Average: 148 0.00 +Average: 149 0.00 +Average: 150 0.00 +Average: 151 0.00 +Average: 152 0.00 +Average: 153 0.00 +Average: 154 0.00 +Average: 155 0.00 +Average: 156 0.00 +Average: 157 0.00 +Average: 158 0.00 +Average: 159 0.00 +Average: 160 0.00 +Average: 161 0.00 +Average: 162 0.00 +Average: 163 0.00 +Average: 164 0.00 +Average: 165 0.00 +Average: 166 0.00 +Average: 167 0.00 +Average: 168 0.00 +Average: 169 0.00 +Average: 170 0.00 +Average: 171 0.00 +Average: 172 0.00 +Average: 173 0.00 +Average: 174 0.00 +Average: 175 0.00 +Average: 176 0.00 +Average: 177 0.00 +Average: 178 0.00 +Average: 179 0.00 +Average: 180 0.00 +Average: 181 0.00 +Average: 182 0.00 +Average: 183 0.00 +Average: 184 0.00 +Average: 185 0.00 +Average: 186 0.00 +Average: 187 0.00 +Average: 188 0.00 +Average: 189 0.00 +Average: 190 0.00 +Average: 191 0.00 +Average: 192 0.00 +Average: 193 0.00 +Average: 194 0.00 +Average: 195 0.00 +Average: 196 0.00 +Average: 197 0.00 +Average: 198 0.00 +Average: 199 0.00 +Average: 200 0.00 +Average: 201 0.00 +Average: 202 0.00 +Average: 203 0.00 +Average: 204 0.00 +Average: 205 0.00 +Average: 206 0.00 +Average: 207 0.00 +Average: 208 0.00 +Average: 209 0.00 +Average: 210 0.00 +Average: 211 0.00 +Average: 212 0.00 +Average: 213 0.00 +Average: 214 0.00 +Average: 215 0.00 +Average: 216 0.00 +Average: 217 0.00 +Average: 218 0.00 +Average: 219 0.00 +Average: 220 0.00 +Average: 221 0.00 +Average: 222 0.00 +Average: 223 0.00 +Average: 224 0.00 +Average: 225 0.00 +Average: 226 0.00 +Average: 227 0.00 +Average: 228 0.00 +Average: 229 0.00 +Average: 230 0.00 +Average: 231 0.00 +Average: 232 0.00 +Average: 233 0.00 +Average: 234 0.00 +Average: 235 0.00 +Average: 236 0.00 +Average: 237 0.00 +Average: 238 0.00 +Average: 239 0.00 +Average: 240 0.00 +Average: 241 0.00 +Average: 242 0.00 +Average: 243 0.00 +Average: 244 0.00 +Average: 245 0.00 +Average: 246 0.00 +Average: 247 0.00 +Average: 248 0.00 +Average: 249 0.00 +Average: 250 0.00 +Average: 251 0.00 +Average: 252 0.00 +Average: 253 0.00 +Average: 254 0.00 +Average: 255 0.00 +Average: 256 0.00 +Average: 257 0.00 +Average: 258 0.00 +Average: 259 0.00 +Average: 260 0.00 +Average: 261 0.00 +Average: 262 0.00 +Average: 263 0.00 +Average: 264 0.00 +Average: 265 0.00 +Average: 266 0.00 +Average: 267 0.00 +Average: 268 0.00 +Average: 269 0.00 +Average: 270 0.00 +Average: 271 0.00 +Average: 272 0.00 +Average: 273 0.00 +Average: 274 0.00 +Average: 275 0.00 +Average: 276 0.00 +Average: 277 0.00 +Average: 278 0.00 +Average: 279 0.00 +Average: 280 0.00 +Average: 281 0.00 +Average: 282 0.00 +Average: 283 0.00 +Average: 284 0.00 +Average: 285 0.00 +Average: 286 0.00 +Average: 287 0.00 +Average: 288 0.00 +Average: 289 0.00 +Average: 290 0.00 +Average: 291 0.00 +Average: 292 0.00 +Average: 293 0.00 +Average: 294 0.00 +Average: 295 0.00 +Average: 296 0.00 +Average: 297 0.00 +Average: 298 0.00 +Average: 299 0.00 +Average: 300 0.00 +Average: 301 0.00 +Average: 302 0.00 +Average: 303 0.00 +Average: 304 0.00 +Average: 305 0.00 +Average: 306 0.00 +Average: 307 0.00 +Average: 308 0.00 +Average: 309 0.00 +Average: 310 0.00 +Average: 311 0.00 +Average: 312 0.00 +Average: 313 0.00 +Average: 314 0.00 +Average: 315 0.00 +Average: 316 0.00 +Average: 317 0.00 +Average: 318 0.00 +Average: 319 0.00 +Average: 320 0.00 +Average: 321 0.00 +Average: 322 0.00 +Average: 323 0.00 +Average: 324 0.00 +Average: 325 0.00 +Average: 326 0.00 +Average: 327 0.00 +Average: 328 0.00 +Average: 329 0.00 +Average: 330 0.00 +Average: 331 0.00 +Average: 332 0.00 +Average: 333 0.00 +Average: 334 0.00 +Average: 335 0.00 +Average: 336 0.00 +Average: 337 0.00 +Average: 338 0.00 +Average: 339 0.00 +Average: 340 0.00 +Average: 341 0.00 +Average: 342 0.00 +Average: 343 0.00 +Average: 344 0.00 +Average: 345 0.00 +Average: 346 0.00 +Average: 347 0.00 +Average: 348 0.00 +Average: 349 0.00 +Average: 350 0.00 +Average: 351 0.00 +Average: 352 0.00 +Average: 353 0.00 +Average: 354 0.00 +Average: 355 0.00 +Average: 356 0.00 +Average: 357 0.00 +Average: 358 0.00 +Average: 359 0.00 +Average: 360 0.00 +Average: 361 0.00 +Average: 362 0.00 +Average: 363 0.00 +Average: 364 0.00 +Average: 365 0.00 +Average: 366 0.00 +Average: 367 0.00 +Average: 368 0.00 +Average: 369 0.00 +Average: 370 0.00 +Average: 371 0.00 +Average: 372 0.00 +Average: 373 0.00 +Average: 374 0.00 +Average: 375 0.00 +Average: 376 0.00 +Average: 377 0.00 +Average: 378 0.00 +Average: 379 0.00 +Average: 380 0.00 +Average: 381 0.00 +Average: 382 0.00 +Average: 383 0.00 +Average: 384 0.00 +Average: 385 0.00 +Average: 386 0.00 +Average: 387 0.00 +Average: 388 0.00 +Average: 389 0.00 +Average: 390 0.00 +Average: 391 0.00 +Average: 392 0.00 +Average: 393 0.00 +Average: 394 0.00 +Average: 395 0.00 +Average: 396 0.00 +Average: 397 0.00 +Average: 398 0.00 +Average: 399 0.00 +Average: 400 0.00 +Average: 401 0.00 +Average: 402 0.00 +Average: 403 0.00 +Average: 404 0.00 +Average: 405 0.00 +Average: 406 0.00 +Average: 407 0.00 +Average: 408 0.00 +Average: 409 0.00 +Average: 410 0.00 +Average: 411 0.00 +Average: 412 0.00 +Average: 413 0.00 +Average: 414 0.00 +Average: 415 0.00 +Average: 416 0.00 +Average: 417 0.00 +Average: 418 0.00 +Average: 419 0.00 +Average: 420 0.00 +Average: 421 0.00 +Average: 422 0.00 +Average: 423 0.00 +Average: 424 0.00 +Average: 425 0.00 +Average: 426 0.00 +Average: 427 0.00 +Average: 428 0.00 +Average: 429 0.00 +Average: 430 0.00 +Average: 431 0.00 +Average: 432 0.00 +Average: 433 0.00 +Average: 434 0.00 +Average: 435 0.00 +Average: 436 0.00 +Average: 437 0.00 +Average: 438 0.00 +Average: 439 0.00 +Average: 440 0.00 +Average: 441 0.00 +Average: 442 0.00 +Average: 443 0.00 +Average: 444 0.00 +Average: 445 0.00 +Average: 446 0.00 +Average: 447 0.00 +Average: 448 0.00 +Average: 449 0.00 +Average: 450 0.00 +Average: 451 0.00 +Average: 452 0.00 +Average: 453 0.00 +Average: 454 0.00 +Average: 455 0.00 +Average: 456 0.00 +Average: 457 0.00 +Average: 458 0.00 +Average: 459 0.00 +Average: 460 0.00 +Average: 461 0.00 +Average: 462 0.00 +Average: 463 0.00 +Average: 464 0.00 +Average: 465 0.00 +Average: 466 0.00 +Average: 467 0.00 +Average: 468 0.00 +Average: 469 0.00 +Average: 470 0.00 +Average: 471 0.00 +Average: 472 0.00 +Average: 473 0.00 +Average: 474 0.00 +Average: 475 0.00 +Average: 476 0.00 +Average: 477 0.00 +Average: 478 0.00 +Average: 479 0.00 +Average: 480 0.00 +Average: 481 0.00 +Average: 482 0.00 +Average: 483 0.00 +Average: 484 0.00 +Average: 485 0.00 +Average: 486 0.00 +Average: 487 0.00 + +13:54:15 pswpin/s pswpout/s +13:54:35 0.00 0.00 +Average: 0.00 0.00 + +13:54:15 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 tps rtps wtps bread/s bwrtn/s +13:54:35 32404.56 320.82 32082.13 0.00 0.00 +Average: 32404.56 320.82 32082.13 0.00 0.00 + +13:54:15 kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty kbanonpg kbslab kbkstack kbpgtbl kbvmused +13:54:35 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 +Average: 1437740 4389516 3179712 39.04 260172 2821596 12097852 48.54 4042384 1772396 396 2733164 445740 15328 73760 0 + +13:54:15 kbswpfree kbswpused %swpused kbswpcad %swpcad +13:54:35 16777212 0 0.00 0 0.00 +Average: 16777212 0 0.00 0 0.00 + +13:54:15 kbhugfree kbhugused %hugused +13:54:35 0 0 0.00 +Average: 0 0 0.00 + +13:54:15 dentunusd file-nr inode-nr pty-nr +13:54:35 156063 16704 157735 4 +Average: 156063 16704 157735 4 + +13:54:15 runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 blocked +13:54:35 3 956 3.16 3.24 3.43 0 +Average: 3 956 3.16 3.24 3.43 0 + +13:54:15 TTY rcvin/s txmtin/s framerr/s prtyerr/s brk/s ovrun/s +13:54:35 0 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 1 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 1 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util +13:54:35 dev8-0 1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-1 1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev104-0 32402.95 0.00 0.00 0.00 0.00 0.10 0.00 0.00 +13:54:35 dev104-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 dev104-2 32402.95 0.00 0.00 0.00 0.00 0.10 0.00 0.00 +Average: dev8-0 1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-1 1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev8-9 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev104-0 32402.95 0.00 0.00 0.00 0.00 0.10 0.00 0.00 +Average: dev104-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: dev104-2 32402.95 0.00 0.00 0.00 0.00 0.10 0.00 0.00 + +13:54:15 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil +13:54:35 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 enp6s1 51.33 16.04 64.23 25.16 0.00 0.00 89.89 0.00 +13:54:35 enp6s2 232.08 16.75 185.16 3.10 0.00 0.00 89.89 0.00 +13:54:35 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 wlp5s1 186.59 186.91 0.86 25.95 0.00 0.00 0.00 0.00 +13:54:35 wlp5s2 186.59 186.91 0.52 25.95 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s1 51.33 16.04 64.23 25.16 0.00 0.00 89.89 0.00 +Average: enp6s2 232.08 16.75 185.16 3.10 0.00 0.00 89.89 0.00 +Average: virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s1 186.59 186.91 0.86 25.95 0.00 0.00 0.00 0.00 +Average: wlp5s2 186.59 186.91 0.52 25.95 0.00 0.00 0.00 0.00 + +13:54:15 IFACE rxerr/s txerr/s coll/s rxdrop/s txdrop/s txcarr/s rxfram/s rxfifo/s txfifo/s +13:54:35 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 enp6s2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 wlp5s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +13:54:35 wlp5s2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: enp6s2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: wlp5s2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 call/s retrans/s read/s write/s access/s getatt/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 scall/s badcall/s packet/s udp/s tcp/s hit/s miss/s sread/s swrite/s saccess/s sgetatt/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 totsck tcpsck udpsck rawsck ip-frag tcp-tw +13:54:35 1316 10 6 0 0 1 +Average: 1316 10 6 0 0 1 + +13:54:15 irec/s fwddgm/s idel/s orq/s asmrq/s asmok/s fragok/s fragcrt/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 ihdrerr/s iadrerr/s iukwnpr/s idisc/s odisc/s onort/s asmf/s fragf/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 imsg/s omsg/s iech/s iechr/s oech/s oechr/s itm/s itmr/s otm/s otmr/s iadrmk/s iadrmkr/s oadrmk/s oadrmkr/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 ierr/s oerr/s idstunr/s odstunr/s itmex/s otmex/s iparmpb/s oparmpb/s isrcq/s osrcq/s iredir/s oredir/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 active/s passive/s iseg/s oseg/s +13:54:35 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:54:15 atmptf/s estres/s retrans/s isegerr/s orsts/s +13:54:35 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 + +13:54:15 idgm/s odgm/s noport/s idgmerr/s +13:54:35 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:54:15 tcp6sck udp6sck raw6sck ip6-frag +13:54:35 3 3 1 0 +Average: 3 3 1 0 + +13:54:15 irec6/s fwddgm6/s idel6/s orq6/s asmrq6/s asmok6/s imcpck6/s omcpck6/s fragok6/s fragcr6/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 ihdrer6/s iadrer6/s iukwnp6/s i2big6/s idisc6/s odisc6/s inort6/s onort6/s asmf6/s fragf6/s itrpck6/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 imsg6/s omsg6/s iech6/s iechr6/s oechr6/s igmbq6/s igmbr6/s ogmbr6/s igmbrd6/s ogmbrd6/s irtsol6/s ortsol6/s irtad6/s inbsol6/s onbsol6/s inbad6/s onbad6/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 ierr6/s idtunr6/s odtunr6/s itmex6/s otmex6/s iprmpb6/s oprmpb6/s iredir6/s oredir6/s ipck2b6/s opck2b6/s +13:54:35 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 + +13:54:15 idgm6/s odgm6/s noport6/s idgmer6/s +13:54:35 0.00 0.00 0.00 0.00 +Average: 0.00 0.00 0.00 0.00 + +13:54:15 fch_rxf/s fch_txf/s fch_rxw/s fch_txw/s FCHOST +13:54:35 0.00 0.00 0.00 0.00 host0 +Average: 0.00 0.00 0.00 0.00 host0 + +13:54:15 CPU total/s dropd/s squeezd/s rx_rps/s flw_lim/s +13:54:35 all 0.00 0.00 0.00 0.00 0.00 +13:54:35 0 0.00 0.00 0.00 0.00 0.00 +13:54:35 1 0.00 0.00 0.00 0.00 0.00 +13:54:35 2 0.00 0.00 0.00 0.00 0.00 +13:54:35 3 0.00 0.00 0.00 0.00 0.00 +13:54:35 4 0.00 0.00 0.00 0.00 0.00 +13:54:35 5 0.00 0.00 0.00 0.00 0.00 +13:54:35 6 0.00 0.00 0.00 0.00 0.00 +13:54:35 7 0.00 0.00 0.00 0.00 0.00 +13:54:35 8 0.00 0.00 0.00 0.00 0.00 +13:54:35 9 0.00 0.00 0.00 0.00 0.00 +Average: all 0.00 0.00 0.00 0.00 0.00 +Average: 0 0.00 0.00 0.00 0.00 0.00 +Average: 1 0.00 0.00 0.00 0.00 0.00 +Average: 2 0.00 0.00 0.00 0.00 0.00 +Average: 3 0.00 0.00 0.00 0.00 0.00 +Average: 4 0.00 0.00 0.00 0.00 0.00 +Average: 5 0.00 0.00 0.00 0.00 0.00 +Average: 6 0.00 0.00 0.00 0.00 0.00 +Average: 7 0.00 0.00 0.00 0.00 0.00 +Average: 8 0.00 0.00 0.00 0.00 0.00 +Average: 9 0.00 0.00 0.00 0.00 0.00 + +13:54:15 CPU MHz +13:54:35 all 3517.54 +13:54:35 0 3566.48 +13:54:35 1 3566.39 +13:54:35 2 3492.11 +13:54:35 3 3566.22 +13:54:35 4 3505.84 +13:54:35 5 3493.55 +13:54:35 6 3492.22 +13:54:35 7 3497.56 +13:54:35 8 3497.56 +13:54:35 9 3497.56 +Average: all 3517.54 +Average: 0 3566.48 +Average: 1 3566.39 +Average: 2 3492.11 +Average: 3 3566.22 +Average: 4 3505.84 +Average: 5 3493.55 +Average: 6 3492.22 +Average: 7 3497.56 +Average: 8 3497.56 +Average: 9 3497.56 + +13:54:15 MBfsfree MBfsused %fsused %ufsused Ifree Iused %Iused FILESYSTEM +13:54:35 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda9 +13:54:35 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda7 +13:54:35 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda12 +13:54:35 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda6 +Summary: 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda9 +Summary: 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda7 +Summary: 85582 7774 8.33 13.45 6008414 102818 1.68 /dev/sda12 +Summary: 279700 15464 5.24 10.33 19201593 455 0.00 /dev/sda6 diff --git a/tests/ini b/tests/ini new file mode 120000 index 0000000..40ee7c6 --- /dev/null +++ b/tests/ini @@ -0,0 +1 @@ +12.0.1/ \ No newline at end of file -- 2.40.0