]> granicus.if.org Git - sysstat/commitdiff
simtest: Add non regression test for sar forward compatibility
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sat, 17 Aug 2019 08:07:47 +0000 (10:07 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sat, 17 Aug 2019 08:07:47 +0000 (10:07 +0200)
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 <sysstat@users.noreply.github.com>
22 files changed:
.gitignore
Makefile.in
tests/00750 [new file with mode: 0644]
tests/00752 [new file with mode: 0644]
tests/12.0.1/activity.c [new file with mode: 0644]
tests/12.0.1/common.c [new file with mode: 0644]
tests/12.0.1/common.h [new file with mode: 0644]
tests/12.0.1/count.c [new file with mode: 0644]
tests/12.0.1/format.c [new file with mode: 0644]
tests/12.0.1/inisar.c [new file with mode: 0644]
tests/12.0.1/ioconf.c [new file with mode: 0644]
tests/12.0.1/ioconf.h [new file with mode: 0644]
tests/12.0.1/pr_stats.c [new file with mode: 0644]
tests/12.0.1/pr_stats.h [new file with mode: 0644]
tests/12.0.1/rd_sensors.h [new file with mode: 0644]
tests/12.0.1/rd_stats.c [new file with mode: 0644]
tests/12.0.1/rd_stats.h [new file with mode: 0644]
tests/12.0.1/sa.h [new file with mode: 0644]
tests/12.0.1/sa_common.c [new file with mode: 0644]
tests/TLIST
tests/expected.data-ini [new file with mode: 0644]
tests/ini [new symlink]

index 42ed56532da641282ec92815ef088032fa06e148..170e8023581d06d26931bcff6a8aeccd91ff8fae 100644 (file)
@@ -51,3 +51,4 @@ nls/*.gmo
 tests/*.tmp
 tests/sa[012]*
 tests/variables
+inisar
index d0da2a5aca09c6daa1de9691c3d917438171250a..799824a2445c30a10cdc00ef22d354ab50ee835e 100644 (file)
@@ -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 (file)
index 0000000..14c4e03
--- /dev/null
@@ -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 (file)
index 0000000..77fa785
--- /dev/null
@@ -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 (file)
index 0000000..1cc3b22
--- /dev/null
@@ -0,0 +1,1903 @@
+/*
+ * activity.c: Define system activities available for sar/sadc.
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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,
+       /* <network> */
+       &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 */
+       /* </network> */
+       /* <power-management> */
+       &pwr_cpufreq_act,
+       &pwr_fan_act,
+       &pwr_temp_act,
+       &pwr_in_act,
+       &pwr_wghfreq_act,
+       &pwr_usb_act,           /* AO_CLOSE_MARKUP */
+       /* </power-management> */
+       &filesystem_act
+};
diff --git a/tests/12.0.1/common.c b/tests/12.0.1/common.c
new file mode 100644 (file)
index 0000000..d418abf
--- /dev/null
@@ -0,0 +1,1437 @@
+/*
+ * sar, sadc, sadf, mpstat and iostat common routines.
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>    /* For STDOUT_FILENO, among others */
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <libgen.h>
+
+#include "version.h"
+#include "common.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 <at> 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 <ENV_TIME_DEFTM> 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>/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 (file)
index 0000000..050fb6c
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * sysstat: System performance tools for Linux
+ * (C) 1999-2018 by Sebastien Godard (sysstat <at> orange.fr)
+ */
+
+#ifndef _COMMON_H
+#define _COMMON_H
+
+/* Maximum length of sensors device name */
+#define MAX_SENSORS_DEV_LEN    20
+
+#include <time.h>
+#include <sched.h>     /* For __CPU_SETSIZE */
+#include <limits.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_SYSMACROS_H
+/* Needed on some non-glibc environments */
+#include <sys/sysmacros.h>
+#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 (file)
index 0000000..4e008b1
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * count.c: Count items for which statistics will be collected.
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "rd_stats.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 (file)
index 0000000..120ccf5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * format.c: Output format definitions for sadf and sar
+ * (C) 2011-2018 by Sebastien GODARD (sysstat <at> 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 (file)
index 0000000..cc9cacf
--- /dev/null
@@ -0,0 +1,1088 @@
+/*
+ * sar: report system activity
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#include "version.h"
+#include "sa.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 ] [ <interval> [ <count> ] ]\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 { <int_list> | SUM | ALL } ] [ -P { <cpu_list> | ALL } ]\n"
+                         "[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]\n"
+                         "[ --dev=<dev_list> ] [ --fs=<fs_list> ] [ --iface=<iface_list> ]\n"
+                         "[ --dec={ 0 | 1 | 2 } ] [ --help ] [ --human ] [ --sadc ]\n"
+                         "[ -j { ID | LABEL | PATH | UUID | ... } ]\n"
+                         "[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]\n"
+                         "[ -i <interval> ] [ -s [ <hh:mm[:ss]> ] ] [ -e [ <hh:mm[:ss]> ] ]\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 <count> 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 (file)
index 0000000..940b0c5
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * ioconf: ioconf configuration file handling code
+ * Original code (C) 2004 by Red Hat (Charlie Bennett <ccb@redhat.com>)
+ *
+ * Modified and maintained by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "ioconf.h"
+#include "common.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 <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 (file)
index 0000000..15af348
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * ioconf: ioconf configuration file handling code
+ * Original code (C) 2004 by Red Hat (Charlie Bennett <ccb@redhat.com>)
+ *
+ * Modified and maintained by Sebastien GODARD (sysstat <at> 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 (file)
index 0000000..65dc259
--- /dev/null
@@ -0,0 +1,3004 @@
+/*
+ * pr_stats.c: Functions used by sar to display statistics
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "sa.h"
+#include "ioconf.h"
+#include "pr_stats.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 (file)
index 0000000..a56b518
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * pr_stats.h: Include file used to display system statistics
+ * (C) 1999-2018 by Sebastien Godard (sysstat <at> 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 (file)
index 0000000..0539040
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * rd_sensors.h: Include file used to read sensors statistics
+ * (C) 1999-2018 by Sebastien Godard (sysstat <at> 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 (file)
index 0000000..cd6cab5
--- /dev/null
@@ -0,0 +1,2650 @@
+/*
+ * rd_stats.c: Read system statistics
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "rd_stats.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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 (file)
index 0000000..7e2326a
--- /dev/null
@@ -0,0 +1,790 @@
+/*
+ * rd_stats.h: Include file used to read system statistics
+ * (C) 1999-2018 by Sebastien Godard (sysstat <at> orange.fr)
+ */
+
+#ifndef _RD_STATS_H
+#define _RD_STATS_H
+
+/*
+ ***************************************************************************
+ * Miscellaneous constants
+ ***************************************************************************
+ */
+
+/* Get IFNAMSIZ */
+#include <net/if.h>
+#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 (file)
index 0000000..78c9743
--- /dev/null
@@ -0,0 +1,1386 @@
+/*
+ * sar/sadc: Report system activity
+ * (C) 1999-2018 by Sebastien Godard (sysstat <at> orange.fr)
+ */
+
+#ifndef _SA_H
+#define _SA_H
+
+#include <stdio.h>
+
+#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)     | * <count>
+ *     |                             |
+ *     |--                           |
+ *     |(__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 (file)
index 0000000..1b7389d
--- /dev/null
@@ -0,0 +1,3094 @@
+/*
+ * sar and sadf common routines.
+ * (C) 1999-2018 by Sebastien GODARD (sysstat <at> 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>    /* For STDOUT_FILENO, among others */
+#include <dirent.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#include "version.h"
+#include "sa.h"
+#include "ioconf.h"
+
+#ifdef USE_NLS
+#include <locale.h>
+#include <libintl.h>
+#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(&timestamp[6]);
+       tse->tm_min  = atoi(&timestamp[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 */
index 24b8e021e758301a8354cef20d676b17b4932f17..1d02c14378d33caef03ad133763ba9dd1cc6eb6d 100644 (file)
@@ -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 (file)
index 0000000..630fd59
--- /dev/null
@@ -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 (symlink)
index 0000000..40ee7c6
--- /dev/null
+++ b/tests/ini
@@ -0,0 +1 @@
+12.0.1/
\ No newline at end of file