tests/*.tmp
tests/sa[012]*
tests/variables
+inisar
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
# 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)
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
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
--- /dev/null
+LC_ALL=C TZ=GMT ./tests/ini/inisar -C -A -f tests/data.tmp > tests/out.data-ini.tmp
--- /dev/null
+diff -u tests/out.data-ini.tmp tests/expected.data-ini
--- /dev/null
+/*
+ * 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
+};
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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");
+ }
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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(×tamp[6]);
+ tse->tm_min = atoi(×tamp[3]);
+ tse->tm_hour = atoi(timestamp);
+
+ if ((tse->tm_sec < 0) || (tse->tm_sec > 59) ||
+ (tse->tm_min < 0) || (tse->tm_min > 59) ||
+ (tse->tm_hour < 0) || (tse->tm_hour > 23))
+ return 1;
+
+ tse->use = TRUE;
+
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Compare two timestamps.
+ *
+ * IN:
+ * @rectime Date and time for current sample.
+ * @tse Timestamp used as reference.
+ *
+ * RETURNS:
+ * A positive value if @rectime is greater than @tse,
+ * a negative one otherwise.
+ ***************************************************************************
+ */
+int datecmp(struct tm *rectime, struct tstamp *tse)
+{
+ if (rectime->tm_hour == tse->tm_hour) {
+ if (rectime->tm_min == tse->tm_min)
+ return (rectime->tm_sec - tse->tm_sec);
+ else
+ return (rectime->tm_min - tse->tm_min);
+ }
+ else
+ return (rectime->tm_hour - tse->tm_hour);
+}
+
+/*
+ ***************************************************************************
+ * Parse a timestamp entered on the command line (hh:mm[:ss]) and decode it.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in the arguments list.
+ * @def_timestamp Default timestamp to use.
+ *
+ * OUT:
+ * @tse Structure containing the decoded timestamp.
+ *
+ * RETURNS:
+ * 0 if the timestamp has been successfully decoded, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_timestamp(char *argv[], int *opt, struct tstamp *tse,
+ const char *def_timestamp)
+{
+ char timestamp[9];
+
+ if (argv[++(*opt)]) {
+ switch (strlen(argv[*opt])) {
+
+ case 5:
+ strncpy(timestamp, argv[(*opt)++], 5);
+ timestamp[5] = '\0';
+ strcat(timestamp, ":00");
+ break;
+
+ case 8:
+ strncpy(timestamp, argv[(*opt)++], 8);
+ break;
+
+ default:
+ strncpy(timestamp, def_timestamp, 8);
+ break;
+ }
+ } else {
+ strncpy(timestamp, def_timestamp, 8);
+ }
+ timestamp[8] = '\0';
+
+ return decode_timestamp(timestamp, tse);
+}
+
+/*
+ ***************************************************************************
+ * Set interval value.
+ *
+ * IN:
+ * @record_hdr_curr Record with current sample statistics.
+ * @record_hdr_prev Record with previous sample statistics.
+ *
+ * OUT:
+ * @itv Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+void get_itv_value(struct record_header *record_hdr_curr,
+ struct record_header *record_hdr_prev,
+ unsigned long long *itv)
+{
+ /* Interval value in jiffies */
+ *itv = get_interval(record_hdr_prev->uptime_cs,
+ record_hdr_curr->uptime_cs);
+}
+
+/*
+ ***************************************************************************
+ * Fill the rectime structure with the file's creation date, based on file's
+ * time data saved in file header.
+ * The resulting timestamp is expressed in the locale of the file creator or
+ * in the user's own locale, depending on whether option -t has been used
+ * or not.
+ *
+ * IN:
+ * @flags Flags for common options and system state.
+ * @file_hdr System activity file standard header.
+ *
+ * OUT:
+ * @rectime Date (and possibly time) from file header. Only the date,
+ * not the time, should be used by the caller.
+ ***************************************************************************
+ */
+void get_file_timestamp_struct(unsigned int flags, struct tm *rectime,
+ struct file_header *file_hdr)
+{
+ struct tm *loc_t;
+
+ if (PRINT_TRUE_TIME(flags)) {
+ /* Get local time. This is just to fill fields with a default value. */
+ get_time(rectime, 0);
+
+ rectime->tm_mday = file_hdr->sa_day;
+ rectime->tm_mon = file_hdr->sa_month;
+ rectime->tm_year = file_hdr->sa_year;
+ /*
+ * Call mktime() to set DST (Daylight Saving Time) flag.
+ * Has anyone a better way to do it?
+ */
+ rectime->tm_hour = rectime->tm_min = rectime->tm_sec = 0;
+ mktime(rectime);
+ }
+ else {
+ if ((loc_t = localtime((const time_t *) &file_hdr->sa_ust_time)) != NULL) {
+ *rectime = *loc_t;
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Print report header.
+ *
+ * IN:
+ * @flags Flags for common options and system state.
+ * @file_hdr System activity file standard header.
+ *
+ * OUT:
+ * @rectime Date and time from file header.
+ ***************************************************************************
+ */
+void print_report_hdr(unsigned int flags, struct tm *rectime,
+ struct file_header *file_hdr)
+{
+
+ /* Get date of file creation */
+ get_file_timestamp_struct(flags, rectime, file_hdr);
+
+ /*
+ * Display the header.
+ * NB: Number of CPU (value in [1, NR_CPUS + 1]).
+ * 1 means that there is only one proc and non SMP kernel.
+ * 2 means one proc and SMP kernel. Etc.
+ */
+ print_gal_header(rectime, file_hdr->sa_sysname, file_hdr->sa_release,
+ file_hdr->sa_nodename, file_hdr->sa_machine,
+ file_hdr->sa_cpu_nr > 1 ? file_hdr->sa_cpu_nr - 1 : 1,
+ PLAIN_OUTPUT);
+}
+
+/*
+ ***************************************************************************
+ * Network interfaces may now be registered (and unregistered) dynamically.
+ * This is what we try to guess here.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @ref Index in array for sample statistics used as reference.
+ * @pos Index on current network interface.
+ *
+ * RETURNS:
+ * Position of current network interface in array of sample statistics used
+ * as reference.
+ * -1 if it is a new interface (it was not present in array of stats used
+ * as reference).
+ * -2 if it is a known interface but which has been unregistered then
+ * registered again on the interval.
+ ***************************************************************************
+ */
+int check_net_dev_reg(struct activity *a, int curr, int ref, int pos)
+{
+ struct stats_net_dev *sndc, *sndp;
+ int j0, j = pos;
+
+ if (!a->nr[ref])
+ /*
+ * No items found in previous iteration:
+ * Current interface is necessarily new.
+ */
+ return -1;
+
+ if (j >= a->nr[ref]) {
+ j = a->nr[ref] - 1;
+ }
+ j0 = j;
+
+ sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + pos * a->msize);
+
+ do {
+ sndp = (struct stats_net_dev *) ((char *) a->buf[ref] + j * a->msize);
+
+ if (!strcmp(sndc->interface, sndp->interface)) {
+ /*
+ * Network interface found.
+ * If a counter has decreased, then we may assume that the
+ * corresponding interface was unregistered, then registered again.
+ */
+ if ((sndc->rx_packets < sndp->rx_packets) ||
+ (sndc->tx_packets < sndp->tx_packets) ||
+ (sndc->rx_bytes < sndp->rx_bytes) ||
+ (sndc->tx_bytes < sndp->tx_bytes) ||
+ (sndc->rx_compressed < sndp->rx_compressed) ||
+ (sndc->tx_compressed < sndp->tx_compressed) ||
+ (sndc->multicast < sndp->multicast)) {
+
+ /*
+ * Special processing for rx_bytes (_packets) and
+ * tx_bytes (_packets) counters: If the number of
+ * bytes (packets) has decreased, whereas the number of
+ * packets (bytes) has increased, then assume that the
+ * relevant counter has met an overflow condition, and that
+ * the interface was not unregistered, which is all the
+ * more plausible that the previous value for the counter
+ * was > ULLONG_MAX/2.
+ * NB: the average value displayed will be wrong in this case...
+ *
+ * If such an overflow is detected, just set the flag. There is no
+ * need to handle this in a special way: the difference is still
+ * properly calculated if the result is of the same type (i.e.
+ * unsigned long) as the two values.
+ */
+ int ovfw = FALSE;
+
+ if ((sndc->rx_bytes < sndp->rx_bytes) &&
+ (sndc->rx_packets > sndp->rx_packets) &&
+ (sndp->rx_bytes > (~0ULL >> 1))) {
+ ovfw = TRUE;
+ }
+ if ((sndc->tx_bytes < sndp->tx_bytes) &&
+ (sndc->tx_packets > sndp->tx_packets) &&
+ (sndp->tx_bytes > (~0ULL >> 1))) {
+ ovfw = TRUE;
+ }
+ if ((sndc->rx_packets < sndp->rx_packets) &&
+ (sndc->rx_bytes > sndp->rx_bytes) &&
+ (sndp->rx_packets > (~0ULL >> 1))) {
+ ovfw = TRUE;
+ }
+ if ((sndc->tx_packets < sndp->tx_packets) &&
+ (sndc->tx_bytes > sndp->tx_bytes) &&
+ (sndp->tx_packets > (~0ULL >> 1))) {
+ ovfw = TRUE;
+ }
+
+ if (!ovfw)
+ /*
+ * OK: Assume here that the device was
+ * actually unregistered.
+ */
+ return -2;
+ }
+ return j;
+ }
+ if (++j >= a->nr[ref]) {
+ j = 0;
+ }
+ }
+ while (j != j0);
+
+ /* This is a newly registered interface */
+ return -1;
+}
+
+/*
+ ***************************************************************************
+ * Network interfaces may now be registered (and unregistered) dynamically.
+ * This is what we try to guess here.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @ref Index in array for sample statistics used as reference.
+ * @pos Index on current network interface.
+ *
+ * RETURNS:
+ * Position of current network interface in array of sample statistics used
+ * as reference.
+ * -1 if it is a newly registered interface.
+ * -2 if it is a known interface but which has been unregistered then
+ * registered again on the interval.
+ ***************************************************************************
+ */
+int check_net_edev_reg(struct activity *a, int curr, int ref, int pos)
+{
+ struct stats_net_edev *snedc, *snedp;
+ int j0, j = pos;
+
+ if (!a->nr[ref])
+ /*
+ * No items found in previous iteration:
+ * Current interface is necessarily new.
+ */
+ return -1;
+
+ if (j >= a->nr[ref]) {
+ j = a->nr[ref] - 1;
+ }
+ j0 = j;
+
+ snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + pos * a->msize);
+
+ do {
+ snedp = (struct stats_net_edev *) ((char *) a->buf[ref] + j * a->msize);
+
+ if (!strcmp(snedc->interface, snedp->interface)) {
+ /*
+ * Network interface found.
+ * If a counter has decreased, then we may assume that the
+ * corresponding interface was unregistered, then registered again.
+ */
+ if ((snedc->tx_errors < snedp->tx_errors) ||
+ (snedc->collisions < snedp->collisions) ||
+ (snedc->rx_dropped < snedp->rx_dropped) ||
+ (snedc->tx_dropped < snedp->tx_dropped) ||
+ (snedc->tx_carrier_errors < snedp->tx_carrier_errors) ||
+ (snedc->rx_frame_errors < snedp->rx_frame_errors) ||
+ (snedc->rx_fifo_errors < snedp->rx_fifo_errors) ||
+ (snedc->tx_fifo_errors < snedp->tx_fifo_errors))
+ /*
+ * OK: assume here that the device was
+ * actually unregistered.
+ */
+ return -2;
+
+ return j;
+ }
+ if (++j >= a->nr[ref]) {
+ j = 0;
+ }
+ }
+ while (j != j0);
+
+ /* This is a newly registered interface */
+ return -1;
+}
+
+/*
+ ***************************************************************************
+ * Disks may be registered dynamically (true in /proc/stat file).
+ * This is what we try to guess here.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @ref Index in array for sample statistics used as reference.
+ * @pos Index on current disk.
+ *
+ * RETURNS:
+ * Position of current disk in array of sample statistics used as reference
+ * -1 if it is a newly registered device.
+ * -2 if it is a known device but which has been unregistered then registered
+ * again on the interval.
+ ***************************************************************************
+ */
+int check_disk_reg(struct activity *a, int curr, int ref, int pos)
+{
+ struct stats_disk *sdc, *sdp;
+ int j0, j = pos;
+
+ if (!a->nr[ref])
+ /*
+ * No items found in previous iteration:
+ * Current interface is necessarily new.
+ */
+ return -1;
+
+ if (j >= a->nr[ref]) {
+ j = a->nr[ref] - 1;
+ }
+ j0 = j;
+
+ sdc = (struct stats_disk *) ((char *) a->buf[curr] + pos * a->msize);
+
+ do {
+ sdp = (struct stats_disk *) ((char *) a->buf[ref] + j * a->msize);
+
+ if ((sdc->major == sdp->major) &&
+ (sdc->minor == sdp->minor)) {
+ /*
+ * Disk found.
+ * If all the counters have decreased then the likelyhood
+ * is that the disk has been unregistered and a new disk inserted.
+ * If only one or two have decreased then the likelyhood
+ * is that the counter has simply wrapped.
+ */
+ if ((sdc->nr_ios < sdp->nr_ios) &&
+ (sdc->rd_sect < sdp->rd_sect) &&
+ (sdc->wr_sect < sdp->wr_sect))
+ /* Same device registered again */
+ return -2;
+
+ return j;
+ }
+ if (++j >= a->nr[ref]) {
+ j = 0;
+ }
+ }
+ while (j != j0);
+
+ /* This is a newly registered device */
+ return -1;
+}
+
+/*
+ ***************************************************************************
+ * Allocate bitmaps for activities that have one.
+ *
+ * IN:
+ * @act Array of activities.
+ ***************************************************************************
+ */
+void allocate_bitmaps(struct activity *act[])
+{
+ int i;
+
+ for (i = 0; i < NR_ACT; i++) {
+ /*
+ * If current activity has a bitmap which has not already
+ * been allocated, then allocate it.
+ * Note that a same bitmap may be used by several activities.
+ */
+ if (act[i]->bitmap && !act[i]->bitmap->b_array) {
+ SREALLOC(act[i]->bitmap->b_array, unsigned char,
+ BITMAP_SIZE(act[i]->bitmap->b_size));
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Free bitmaps for activities that have one.
+ *
+ * IN:
+ * @act Array of activities.
+ ***************************************************************************
+ */
+void free_bitmaps(struct activity *act[])
+{
+ int i;
+
+ for (i = 0; i < NR_ACT; i++) {
+ if (act[i]->bitmap && act[i]->bitmap->b_array) {
+ free(act[i]->bitmap->b_array);
+ /* Set pointer to NULL to prevent it from being freed again */
+ act[i]->bitmap->b_array = NULL;
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Select all activities, even if they have no associated items.
+ *
+ * IN:
+ * @act Array of activities.
+ *
+ * OUT:
+ * @act Array of activities, all of the being selected.
+ ***************************************************************************
+ */
+void select_all_activities(struct activity *act[])
+{
+ int i;
+
+ for (i = 0; i < NR_ACT; i++) {
+ act[i]->options |= AO_SELECTED;
+ }
+}
+
+/*
+ ***************************************************************************
+ * Select CPU activity if no other activities have been explicitly selected.
+ * Also select CPU "all" if no other CPU has been selected.
+ *
+ * IN:
+ * @act Array of activities.
+ *
+ * OUT:
+ * @act Array of activities with CPU activity selected if needed.
+ ***************************************************************************
+ */
+void select_default_activity(struct activity *act[])
+{
+ int p;
+
+ p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND);
+
+ /* Default is CPU activity... */
+ if (!get_activity_nr(act, AO_SELECTED, COUNT_ACTIVITIES)) {
+ /*
+ * Yet A_CPU activity may not be available in file
+ * since the user can choose not to collect it.
+ */
+ act[p]->options |= AO_SELECTED;
+ }
+
+ /*
+ * If no CPU's have been selected then select CPU "all".
+ * cpu_bitmap bitmap may be used by several activities (A_CPU, A_PWR_CPU...)
+ */
+ if (!count_bits(cpu_bitmap.b_array, BITMAP_SIZE(cpu_bitmap.b_size))) {
+ cpu_bitmap.b_array[0] |= 0x01;
+ }
+}
+
+/*
+ ***************************************************************************
+ * Swap bytes for every numerical field in structure. Used to convert from
+ * one endianness type (big-endian or little-endian) to the other.
+ *
+ * IN:
+ * @types_nr Number of fields in structure for each following types:
+ * unsigned long long, unsigned long and int.
+ * @ps Pointer on structure.
+ * @is64bit TRUE if data come from a 64-bit machine.
+ ***************************************************************************
+ */
+void swap_struct(unsigned int types_nr[], void *ps, int is64bit)
+{
+ int i;
+ uint64_t *x;
+ uint32_t *y;
+
+ x = (uint64_t *) ps;
+ /* For each field of type long long (or double) */
+ for (i = 0; i < types_nr[0]; i++) {
+ *x = __builtin_bswap64(*x);
+ x = (uint64_t *) ((char *) x + ULL_ALIGNMENT_WIDTH);
+ }
+
+ y = (uint32_t *) x;
+ /* For each field of type long */
+ for (i = 0; i < types_nr[1]; i++) {
+ if (is64bit) {
+ *x = __builtin_bswap64(*x);
+ x = (uint64_t *) ((char *) x + UL_ALIGNMENT_WIDTH);
+ }
+ else {
+ *y = __builtin_bswap32(*y);
+ y = (uint32_t *) ((char *) y + UL_ALIGNMENT_WIDTH);
+ }
+ }
+
+ if (is64bit) {
+ y = (uint32_t *) x;
+ }
+ /* For each field of type int */
+ for (i = 0; i < types_nr[2]; i++) {
+ *y = __builtin_bswap32(*y);
+ y = (uint32_t *) ((char *) y + U_ALIGNMENT_WIDTH);
+ }
+}
+
+/*
+ ***************************************************************************
+ * Map the fields of a structure containing statistics read from a file to
+ * those of the structure known by current sysstat version.
+ * Each structure (either read from file or from current sysstat version)
+ * are described by 3 values: The number of [unsigned] long long integers,
+ * the number of [unsigned] long integers following in the structure, and
+ * last the number of [unsigned] integers.
+ * We assume that those numbers will *never* decrease with newer sysstat
+ * versions.
+ *
+ * IN:
+ * @gtypes_nr Structure description as expected for current sysstat version.
+ * @ftypes_nr Structure description as read from file.
+ * @ps Pointer on structure containing statistics.
+ * @st_size Size of the structure containing statistics. This is the size
+ * of the structure *read from file* (not the size of the
+ * structure expected by current sysstat version).
+ ***************************************************************************
+ */
+void remap_struct(unsigned int gtypes_nr[], unsigned int ftypes_nr[],
+ void *ps, unsigned int st_size)
+{
+ int d;
+
+ /* Sanity check */
+ if (MAP_SIZE(ftypes_nr) > st_size)
+ return;
+
+ /* Remap [unsigned] long fields */
+ d = gtypes_nr[0] - ftypes_nr[0];
+ if (d) {
+ memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+ ((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+ st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH);
+ if (d > 0) {
+ memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
+ 0, d * ULL_ALIGNMENT_WIDTH);
+ }
+ }
+ /* Remap [unsigned] int fields */
+ d = gtypes_nr[1] - ftypes_nr[1];
+ if (d) {
+ memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + gtypes_nr[1] * UL_ALIGNMENT_WIDTH,
+ ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + ftypes_nr[1] * UL_ALIGNMENT_WIDTH,
+ st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ - ftypes_nr[1] * UL_ALIGNMENT_WIDTH);
+ if (d > 0) {
+ memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + ftypes_nr[1] * UL_ALIGNMENT_WIDTH,
+ 0, d * UL_ALIGNMENT_WIDTH);
+ }
+ }
+ /* Remap possible fields (like strings of chars) following int fields */
+ d = gtypes_nr[2] - ftypes_nr[2];
+ if (d) {
+ memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+ + gtypes_nr[2] * U_ALIGNMENT_WIDTH,
+ ((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+ + ftypes_nr[2] * U_ALIGNMENT_WIDTH,
+ st_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ - ftypes_nr[1] * UL_ALIGNMENT_WIDTH
+ - ftypes_nr[2] * U_ALIGNMENT_WIDTH);
+ if (d > 0) {
+ memset(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH
+ + gtypes_nr[1] * UL_ALIGNMENT_WIDTH
+ + ftypes_nr[2] * U_ALIGNMENT_WIDTH,
+ 0, d * U_ALIGNMENT_WIDTH);
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Read data from a system activity data file.
+ *
+ * IN:
+ * @ifd Input file descriptor.
+ * @buffer Buffer where data are read.
+ * @size Number of bytes to read.
+ * @mode If set to HARD_SIZE, indicate that an EOF should be considered
+ * as an error.
+ *
+ * RETURNS:
+ * 1 if EOF has been reached, 0 otherwise.
+ ***************************************************************************
+ */
+int sa_fread(int ifd, void *buffer, size_t size, int mode)
+{
+ ssize_t n;
+
+ if ((n = read(ifd, buffer, size)) < 0) {
+ fprintf(stderr, _("Error while reading system activity file: %s\n"),
+ strerror(errno));
+ close(ifd);
+ exit(2);
+ }
+
+ if (!n && (mode == SOFT_SIZE))
+ return 1; /* EOF */
+
+ if (n < size) {
+ fprintf(stderr, _("End of system activity file unexpected\n"));
+ close(ifd);
+ exit(2);
+ }
+
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Read the record header of current sample and process it.
+ *
+ * IN:
+ * @ifd Input file descriptor.
+ * @buffer Buffer where data will be read.
+ * @record_hdr Structure where record header will be saved.
+ * @file_hdr file_hdr structure containing data read from file standard
+ * header.
+ * @arch_64 TRUE if file's data come from a 64-bit machine.
+ * @endian_mismatch
+ * TRUE if data read from file don't match current machine's
+ * endianness.
+ *
+ * OUT:
+ * @record_hdr Record header for current sample.
+ *
+ * RETURNS:
+ * 1 if EOF has been reached, 0 otherwise.
+ ***************************************************************************
+ */
+int read_record_hdr(int ifd, void *buffer, struct record_header *record_hdr,
+ struct file_header *file_hdr, int arch_64, int endian_mismatch)
+{
+ if (sa_fread(ifd, buffer, (size_t) file_hdr->rec_size, SOFT_SIZE))
+ /* End of sa data file */
+ return 1;
+
+ /* Remap record header structure to that expected by current version */
+ remap_struct(rec_types_nr, file_hdr->rec_types_nr, buffer, file_hdr->rec_size);
+ memcpy(record_hdr, buffer, RECORD_HEADER_SIZE);
+
+ /* Normalize endianness */
+ if (endian_mismatch) {
+ swap_struct(rec_types_nr, record_hdr, arch_64);
+ }
+
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Move structures data.
+ *
+ * IN:
+ * @act Array of activities.
+ * @id_seq Activity sequence in file.
+ * @record_hdr Current record header.
+ * @dest Index in array where stats have to be copied to.
+ * @src Index in array where stats to copy are.
+ ***************************************************************************
+ */
+void copy_structures(struct activity *act[], unsigned int id_seq[],
+ struct record_header record_hdr[], int dest, int src)
+{
+ int i, p;
+
+ memcpy(&record_hdr[dest], &record_hdr[src], RECORD_HEADER_SIZE);
+
+ for (i = 0; i < NR_ACT; i++) {
+
+ if (!id_seq[i])
+ continue;
+
+ p = get_activity_position(act, id_seq[i], EXIT_IF_NOT_FOUND);
+
+ memcpy(act[p]->buf[dest], act[p]->buf[src],
+ (size_t) act[p]->msize * (size_t) act[p]->nr[src] * (size_t) act[p]->nr2);
+ act[p]->nr[dest] = act[p]->nr[src];
+ }
+}
+
+/*
+ ***************************************************************************
+ * Read an __nr_t value from file.
+ * Such a value can be the new number of CPU saved after a RESTART record,
+ * or the number of structures to read saved before the structures containing
+ * statistics for an activity with a varying number of items in file.
+ *
+ * IN:
+ * @ifd Input file descriptor.
+ * @file Name of file being read.
+ * @file_magic file_magic structure filled with file magic header data.
+ * @endian_mismatch
+ * TRUE if file's data don't match current machine's endianness.
+ * @arch_64 TRUE if file's data come from a 64 bit machine.
+ * @non_zero TRUE if value should not be zero.
+ *
+ * RETURNS:
+ * __nr_t value, as read from file.
+ ***************************************************************************
+ */
+__nr_t read_nr_value(int ifd, char *file, struct file_magic *file_magic,
+ int endian_mismatch, int arch_64, int non_zero)
+{
+ __nr_t value;
+
+ sa_fread(ifd, &value, sizeof(__nr_t), HARD_SIZE);
+
+ /* Normalize endianness for file_activity structures */
+ if (endian_mismatch) {
+ nr_types_nr[2] = 1;
+ swap_struct(nr_types_nr, &value, arch_64);
+ }
+
+ if ((non_zero && !value) || (value < 0)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: Value=%d\n",
+ __FUNCTION__, value);
+#endif
+ /* Value number cannot be zero or negative */
+ handle_invalid_sa_file(ifd, file_magic, file, 0);
+ }
+
+ return value;
+}
+
+/*
+ ***************************************************************************
+ * Read varying part of the statistics from a daily data file.
+ *
+ * IN:
+ * @act Array of activities.
+ * @curr Index in array for current sample statistics.
+ * @ifd Input file descriptor.
+ * @act_nr Number of activities in file.
+ * @file_actlst Activity list in file.
+ * @endian_mismatch
+ * TRUE if file's data don't match current machine's endianness.
+ * @arch_64 TRUE if file's data come from a 64 bit machine.
+ * @dfile Name of system activity data file.
+ * @file_magic file_magic structure containing data read from file magic
+ * header.
+ ***************************************************************************
+ */
+void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr,
+ struct file_activity *file_actlst, int endian_mismatch,
+ int arch_64, char *dfile, struct file_magic *file_magic)
+{
+ int i, j, p;
+ struct file_activity *fal = file_actlst;
+ off_t offset;
+ __nr_t nr_value;
+
+ for (i = 0; i < act_nr; i++, fal++) {
+
+ /* Read __nr_t value preceding statistics structures if it exists */
+ if (fal->has_nr) {
+ nr_value = read_nr_value(ifd, dfile, file_magic,
+ endian_mismatch, arch_64, FALSE);
+ }
+ else {
+ nr_value = fal->nr;
+ }
+
+ if (nr_value > NR_MAX) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: Value=%d Max=%d\n", __FUNCTION__, nr_value, NR_MAX);
+#endif
+ handle_invalid_sa_file(ifd, file_magic, dfile, 0);
+ }
+
+ if (((p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND)) < 0) ||
+ (act[p]->magic != fal->magic)) {
+ /*
+ * Ignore current activity in file, which is unknown to
+ * current sysstat version or has an unknown format.
+ */
+ if (nr_value) {
+ offset = (off_t) fal->size * (off_t) nr_value * (off_t) fal->nr2;
+ if (lseek(ifd, offset, SEEK_CUR) < offset) {
+ close(ifd);
+ perror("lseek");
+ exit(2);
+ }
+ }
+ continue;
+ }
+
+ if (nr_value > act[p]->nr_max) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: %s: Value=%d Max=%d\n",
+ __FUNCTION__, act[p]->name, nr_value, act[p]->nr_max);
+#endif
+ handle_invalid_sa_file(ifd, file_magic, dfile, 0);
+ }
+ act[p]->nr[curr] = nr_value;
+
+ /* Reallocate buffers if needed */
+ if (nr_value > act[p]->nr_allocated) {
+ reallocate_all_buffers(act[p], nr_value);
+ }
+
+ /*
+ * For persistent activities, we must make sure that no statistics
+ * from a previous iteration remain, especially if the number
+ * of structures read is smaller than @nr_ini.
+ */
+ if (HAS_PERSISTENT_VALUES(act[p]->options)) {
+ memset(act[p]->buf[curr], 0,
+ (size_t) act[p]->msize * (size_t) act[p]->nr_ini * (size_t) act[p]->nr2);
+ }
+
+ /* OK, this is a known activity: Read the stats structures */
+ if ((nr_value > 0) &&
+ ((nr_value > 1) || (act[p]->nr2 > 1)) &&
+ (act[p]->msize > act[p]->fsize)) {
+
+ for (j = 0; j < (nr_value * act[p]->nr2); j++) {
+ sa_fread(ifd, (char *) act[p]->buf[curr] + j * act[p]->msize,
+ (size_t) act[p]->fsize, HARD_SIZE);
+ }
+ }
+ else if (nr_value > 0) {
+ /*
+ * Note: If msize was smaller than fsize,
+ * then it has been set to fsize in check_file_actlst().
+ */
+ sa_fread(ifd, act[p]->buf[curr],
+ (size_t) act[p]->fsize * (size_t) nr_value * (size_t) act[p]->nr2, HARD_SIZE);
+ }
+ else {
+ /* nr_value == 0: Nothing to read */
+ continue;
+ }
+
+ /* Normalize endianness for current activity's structures */
+ if (endian_mismatch) {
+ for (j = 0; j < (nr_value * act[p]->nr2); j++) {
+ swap_struct(act[p]->ftypes_nr, (char *) act[p]->buf[curr] + j * act[p]->msize,
+ arch_64);
+ }
+ }
+
+ /* Remap structure's fields to those known by current sysstat version */
+ for (j = 0; j < (nr_value * act[p]->nr2); j++) {
+ remap_struct(act[p]->gtypes_nr, act[p]->ftypes_nr,
+ (char *) act[p]->buf[curr] + j * act[p]->msize, act[p]->fsize);
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Open a sysstat activity data file and read its magic structure.
+ *
+ * IN:
+ * @dfile Name of system activity data file.
+ * @ignore Set to 1 if a true sysstat activity file but with a bad
+ * format should not yield an error message. Useful with
+ * sadf -H and sadf -c.
+ *
+ * OUT:
+ * @fd System activity data file descriptor.
+ * @file_magic file_magic structure containing data read from file magic
+ * header.
+ * @endian_mismatch
+ * TRUE if file's data don't match current machine's endianness.
+ * @do_swap TRUE if endianness should be normalized for sysstat_magic
+ * and format_magic numbers.
+ *
+ * RETURNS:
+ * -1 if data file is a sysstat file with an old format (which we cannot
+ * read), 0 otherwise.
+ ***************************************************************************
+ */
+int sa_open_read_magic(int *fd, char *dfile, struct file_magic *file_magic,
+ int ignore, int *endian_mismatch, int do_swap)
+{
+ int n;
+ unsigned int fm_types_nr[] = {FILE_MAGIC_ULL_NR, FILE_MAGIC_UL_NR, FILE_MAGIC_U_NR};
+
+ /* Open sa data file */
+ if ((*fd = open(dfile, O_RDONLY)) < 0) {
+ int saved_errno = errno;
+
+ fprintf(stderr, _("Cannot open %s: %s\n"), dfile, strerror(errno));
+
+ if ((saved_errno == ENOENT) && default_file_used) {
+ fprintf(stderr, _("Please check if data collecting is enabled\n"));
+ }
+ exit(2);
+ }
+
+ /* Read file magic data */
+ n = read(*fd, file_magic, FILE_MAGIC_SIZE);
+
+ if ((n != FILE_MAGIC_SIZE) ||
+ ((file_magic->sysstat_magic != SYSSTAT_MAGIC) && (file_magic->sysstat_magic != SYSSTAT_MAGIC_SWAPPED)) ||
+ ((file_magic->format_magic != FORMAT_MAGIC) && (file_magic->format_magic != FORMAT_MAGIC_SWAPPED) && !ignore)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: Bytes read=%d sysstat_magic=%x format_magic=%x\n",
+ __FUNCTION__, n, file_magic->sysstat_magic, file_magic->format_magic);
+#endif
+ /* Display error message and exit */
+ handle_invalid_sa_file(*fd, file_magic, dfile, n);
+ }
+
+ *endian_mismatch = (file_magic->sysstat_magic != SYSSTAT_MAGIC);
+ if (*endian_mismatch) {
+ if (do_swap) {
+ /* Swap bytes for file_magic fields */
+ file_magic->sysstat_magic = SYSSTAT_MAGIC;
+ file_magic->format_magic = __builtin_bswap16(file_magic->format_magic);
+ }
+ /*
+ * Start swapping at field "header_size" position.
+ * May not exist for older versions but in this case, it won't be used.
+ */
+ swap_struct(fm_types_nr, &file_magic->header_size, 0);
+ }
+
+ if ((file_magic->sysstat_version > 10) ||
+ ((file_magic->sysstat_version == 10) && (file_magic->sysstat_patchlevel >= 3))) {
+ /* header_size field exists only for sysstat versions 10.3.1 and later */
+ if ((file_magic->header_size <= MIN_FILE_HEADER_SIZE) ||
+ (file_magic->header_size > MAX_FILE_HEADER_SIZE) ||
+ ((file_magic->header_size < FILE_HEADER_SIZE) && !ignore)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: header_size=%u\n",
+ __FUNCTION__, file_magic->header_size);
+#endif
+ /* Display error message and exit */
+ handle_invalid_sa_file(*fd, file_magic, dfile, n);
+ }
+ }
+ if ((file_magic->sysstat_version > 11) ||
+ ((file_magic->sysstat_version == 11) && (file_magic->sysstat_patchlevel >= 7))) {
+ /* hdr_types_nr field exists only for sysstat versions 11.7.1 and later */
+ if (MAP_SIZE(file_magic->hdr_types_nr) > file_magic->header_size) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: map_size=%u header_size=%u\n",
+ __FUNCTION__, MAP_SIZE(file_magic->hdr_types_nr), file_magic->header_size);
+#endif
+ handle_invalid_sa_file(*fd, file_magic, dfile, n);
+ }
+ }
+
+ if ((file_magic->format_magic != FORMAT_MAGIC) &&
+ (file_magic->format_magic != FORMAT_MAGIC_SWAPPED))
+ /*
+ * This is an old (or new) sa datafile format to
+ * be read by sadf (since @ignore was set to TRUE).
+ */
+ return -1;
+
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Open a data file, and perform various checks before reading.
+ * NB: This is called only when reading a datafile (sar and sadf), never
+ * when writing or appending data to a datafile.
+ *
+ * IN:
+ * @dfile Name of system activity data file.
+ * @act Array of activities.
+ * @ignore Set to 1 if a true sysstat activity file but with a bad
+ * format should not yield an error message. Used with
+ * sadf -H (sadf -c doesn't call check_file_actlst() function).
+ *
+ * OUT:
+ * @ifd System activity data file descriptor.
+ * @file_magic file_magic structure containing data read from file magic
+ * header.
+ * @file_hdr file_hdr structure containing data read from file standard
+ * header.
+ * @file_actlst Acvtivity list in file.
+ * @id_seq Activity sequence.
+ * @endian_mismatch
+ * TRUE if file's data don't match current machine's endianness.
+ * @arch_64 TRUE if file's data come from a 64 bit machine.
+ ***************************************************************************
+ */
+void check_file_actlst(int *ifd, char *dfile, struct activity *act[],
+ struct file_magic *file_magic, struct file_header *file_hdr,
+ struct file_activity **file_actlst, unsigned int id_seq[],
+ int ignore, int *endian_mismatch, int *arch_64)
+{
+ int i, j, k, p;
+ struct file_activity *fal;
+ void *buffer = NULL;
+
+ /* Open sa data file and read its magic structure */
+ if (sa_open_read_magic(ifd, dfile, file_magic, ignore, endian_mismatch, TRUE) < 0)
+ /*
+ * Not current sysstat's format.
+ * Return now so that sadf -H can display at least
+ * file's version and magic number.
+ */
+ return;
+
+ /*
+ * We know now that we have a *compatible* sysstat datafile format
+ * (correct FORMAT_MAGIC value), and in this case, we should have
+ * checked header_size value. Anyway, with a corrupted datafile,
+ * this may not be the case. So check again.
+ */
+ if ((file_magic->header_size <= MIN_FILE_HEADER_SIZE) ||
+ (file_magic->header_size > MAX_FILE_HEADER_SIZE)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: header_size=%u\n",
+ __FUNCTION__, file_magic->header_size);
+#endif
+ goto format_error;
+ }
+
+ /* Allocate buffer for file_header structure */
+ SREALLOC(buffer, char, file_magic->header_size);
+
+ /* Read sa data file standard header and allocate activity list */
+ sa_fread(*ifd, buffer, (size_t) file_magic->header_size, HARD_SIZE);
+ /*
+ * Data file header size (file_magic->header_size) may be greater or
+ * smaller than FILE_HEADER_SIZE. Remap the fields of the file header
+ * then copy its contents to the expected structure.
+ */
+ remap_struct(hdr_types_nr, file_magic->hdr_types_nr, buffer, file_magic->header_size);
+ memcpy(file_hdr, buffer, FILE_HEADER_SIZE);
+ free(buffer);
+ buffer = NULL;
+
+ /* Tell that data come from a 64 bit machine */
+ *arch_64 = (file_hdr->sa_sizeof_long == SIZEOF_LONG_64BIT);
+
+ /* Normalize endianness for file_hdr structure */
+ if (*endian_mismatch) {
+ swap_struct(hdr_types_nr, file_hdr, *arch_64);
+ }
+
+ /*
+ * Sanity checks.
+ * NB: Compare against MAX_NR_ACT and not NR_ACT because
+ * we are maybe reading a datafile from a future sysstat version
+ * with more activities than known today.
+ */
+ if ((file_hdr->sa_act_nr > MAX_NR_ACT) ||
+ (file_hdr->act_size > MAX_FILE_ACTIVITY_SIZE) ||
+ (file_hdr->rec_size > MAX_RECORD_HEADER_SIZE) ||
+ (MAP_SIZE(file_hdr->act_types_nr) > file_hdr->act_size) ||
+ (MAP_SIZE(file_hdr->rec_types_nr) > file_hdr->rec_size)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: sa_act_nr=%d act_size=%u rec_size=%u map_size(act)=%u map_size(rec)=%u\n",
+ __FUNCTION__, file_hdr->sa_act_nr, file_hdr->act_size, file_hdr->rec_size,
+ MAP_SIZE(file_hdr->act_types_nr), MAP_SIZE(file_hdr->rec_types_nr));
+#endif
+ /* Maybe a "false positive" sysstat datafile? */
+ goto format_error;
+ }
+
+ SREALLOC(buffer, char, file_hdr->act_size);
+ SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr);
+ fal = *file_actlst;
+
+ /* Read activity list */
+ j = 0;
+ for (i = 0; i < file_hdr->sa_act_nr; i++, fal++) {
+
+ /* Read current file_activity structure from file */
+ sa_fread(*ifd, buffer, (size_t) file_hdr->act_size, HARD_SIZE);
+ /*
+ * Data file_activity size (file_hdr->act_size) may be greater or
+ * smaller than FILE_ACTIVITY_SIZE. Remap the fields of the file's structure
+ * then copy its contents to the expected structure.
+ */
+ remap_struct(act_types_nr, file_hdr->act_types_nr, buffer, file_hdr->act_size);
+ memcpy(fal, buffer, FILE_ACTIVITY_SIZE);
+
+ /* Normalize endianness for file_activity structures */
+ if (*endian_mismatch) {
+ swap_struct(act_types_nr, fal, *arch_64);
+ }
+
+ /*
+ * Every activity, known or unknown, should have
+ * at least one item and sub-item.
+ * Also check that the number of items and sub-items
+ * doesn't exceed a max value. This is necessary
+ * because we will use @nr and @nr2 to
+ * allocate memory to read the file contents. So we
+ * must make sure the file is not corrupted.
+ * NB: Another check will be made below for known
+ * activities which have each a specific max value.
+ */
+ if ((fal->nr < 1) || (fal->nr2 < 1) ||
+ (fal->nr > NR_MAX) || (fal->nr2 > NR2_MAX)) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: id=%d nr=%d nr2=%d\n",
+ __FUNCTION__, fal->id, fal->nr, fal->nr2);
+#endif
+ goto format_error;
+ }
+
+ if ((p = get_activity_position(act, fal->id, RESUME_IF_NOT_FOUND)) < 0)
+ /* Unknown activity */
+ continue;
+
+ if (act[p]->magic != fal->magic) {
+ /* Bad magical number */
+ if (ignore) {
+ /*
+ * This is how sadf -H knows that this
+ * activity has an unknown format.
+ */
+ act[p]->magic = ACTIVITY_MAGIC_UNKNOWN;
+ }
+ else
+ continue;
+ }
+
+ /* Check max value for known activities */
+ if (fal->nr > act[p]->nr_max) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: id=%d nr=%d nr_max=%d\n",
+ __FUNCTION__, fal->id, fal->nr, act[p]->nr_max);
+#endif
+ goto format_error;
+ }
+
+ /*
+ * Number of fields of each type ("long long", or "long"
+ * or "int") composing the structure with statistics may
+ * only increase with new sysstat versions. Here, we may
+ * be reading a file created by current sysstat version,
+ * or by an older or a newer version.
+ */
+ if (!(((fal->types_nr[0] >= act[p]->gtypes_nr[0]) &&
+ (fal->types_nr[1] >= act[p]->gtypes_nr[1]) &&
+ (fal->types_nr[2] >= act[p]->gtypes_nr[2]))
+ ||
+ ((fal->types_nr[0] <= act[p]->gtypes_nr[0]) &&
+ (fal->types_nr[1] <= act[p]->gtypes_nr[1]) &&
+ (fal->types_nr[2] <= act[p]->gtypes_nr[2]))) && !ignore) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: id=%d file=%d,%d,%d activity=%d,%d,%d\n",
+ __FUNCTION__, fal->id, fal->types_nr[0], fal->types_nr[1], fal->types_nr[2],
+ act[p]->gtypes_nr[0], act[p]->gtypes_nr[1], act[p]->gtypes_nr[2]);
+#endif
+ goto format_error;
+ }
+
+ if (MAP_SIZE(fal->types_nr) > fal->size) {
+#ifdef DEBUG
+ fprintf(stderr, "%s: id=%d size=%u map_size=%u\n",
+ __FUNCTION__, fal->id, fal->size, MAP_SIZE(fal->types_nr));
+#endif
+ goto format_error;
+ }
+
+ for (k = 0; k < 3; k++) {
+ act[p]->ftypes_nr[k] = fal->types_nr[k];
+ }
+
+ if (fal->size > act[p]->msize) {
+ act[p]->msize = fal->size;
+ }
+
+ act[p]->nr_ini = fal->nr;
+ act[p]->nr2 = fal->nr2;
+ act[p]->fsize = fal->size;
+ /*
+ * This is a known activity with a known format
+ * (magical number). Only such activities will be displayed.
+ * (Well, this may also be an unknown format if we have entered sadf -H.)
+ */
+ id_seq[j++] = fal->id;
+ }
+
+ while (j < NR_ACT) {
+ id_seq[j++] = 0;
+ }
+
+ free(buffer);
+
+ /* Check that at least one activity selected by the user is available in file */
+ for (i = 0; i < NR_ACT; i++) {
+
+ if (!IS_SELECTED(act[i]->options))
+ continue;
+
+ /* Here is a selected activity: Does it exist in file? */
+ fal = *file_actlst;
+ for (j = 0; j < file_hdr->sa_act_nr; j++, fal++) {
+ if (act[i]->id == fal->id)
+ break;
+ }
+ if (j == file_hdr->sa_act_nr) {
+ /* No: Unselect it */
+ act[i]->options &= ~AO_SELECTED;
+ }
+ }
+
+ /*
+ * None of selected activities exist in file: Abort.
+ * NB: Error is ignored if we only want to display
+ * datafile header (sadf -H).
+ */
+ if (!get_activity_nr(act, AO_SELECTED, COUNT_ACTIVITIES) && !ignore) {
+ fprintf(stderr, _("Requested activities not available in file %s\n"),
+ dfile);
+ close(*ifd);
+ exit(1);
+ }
+
+ return;
+
+format_error:
+ if (buffer) {
+ free(buffer);
+ }
+ handle_invalid_sa_file(*ifd, file_magic, dfile, 0);
+}
+
+/*
+ ***************************************************************************
+ * Parse sar activities options (also used by sadf).
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ * @caller Indicate whether it's sar or sadf that called this function.
+ *
+ * OUT:
+ * @act Array of selected activities.
+ * @flags Common flags and system state.
+ *
+ * RETURNS:
+ * 0 on success.
+ ***************************************************************************
+ */
+int parse_sar_opt(char *argv[], int *opt, struct activity *act[],
+ unsigned int *flags, int caller)
+{
+ int i, p;
+
+ for (i = 1; *(argv[*opt] + i); i++) {
+ /*
+ * Note: argv[*opt] contains something like "-BruW"
+ * *(argv[*opt] + i) will contain 'B', 'r', etc.
+ */
+
+ switch (*(argv[*opt] + i)) {
+
+ case 'A':
+ select_all_activities(act);
+
+ /*
+ * Force '-P ALL -I ALL -r ALL -u ALL -F'.
+ * Setting -F is compulsory because corresponding activity
+ * has AO_MULTIPLE_OUTPUTS flag set.
+ */
+ p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND);
+ act[p]->opt_flags |= AO_F_MEMORY + AO_F_SWAP + AO_F_MEM_ALL;
+
+ p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+ memset(act[p]->bitmap->b_array, ~0,
+ BITMAP_SIZE(act[p]->bitmap->b_size));
+ p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND);
+ memset(act[p]->bitmap->b_array, ~0,
+ BITMAP_SIZE(act[p]->bitmap->b_size));
+ act[p]->opt_flags = AO_F_CPU_ALL;
+
+ p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
+ act[p]->opt_flags = AO_F_FILESYSTEM;
+ break;
+
+ case 'B':
+ SELECT_ACTIVITY(A_PAGE);
+ break;
+
+ case 'b':
+ SELECT_ACTIVITY(A_IO);
+ break;
+
+ case 'C':
+ *flags |= S_F_COMMENT;
+ break;
+
+ case 'd':
+ SELECT_ACTIVITY(A_DISK);
+ break;
+
+ case 'F':
+ p = get_activity_position(act, A_FS, EXIT_IF_NOT_FOUND);
+ act[p]->options |= AO_SELECTED;
+ if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_MOUNT)) {
+ (*opt)++;
+ act[p]->opt_flags |= AO_F_MOUNT;
+ return 0;
+ }
+ else {
+ act[p]->opt_flags |= AO_F_FILESYSTEM;
+ }
+ break;
+
+ case 'H':
+ SELECT_ACTIVITY(A_HUGE);
+ break;
+
+ case 'h':
+ /*
+ * Make output easier to read by a human.
+ * Option -h implies --human and -p (pretty-print).
+ */
+ *flags |= S_F_HUMAN_READ + S_F_UNIT + S_F_DEV_PRETTY;
+ break;
+
+ case 'j':
+ if (!argv[*opt + 1]) {
+ return 1;
+ }
+ (*opt)++;
+ if (strnlen(argv[*opt], MAX_FILE_LEN) >= MAX_FILE_LEN - 1)
+ return 1;
+
+ strncpy(persistent_name_type, argv[*opt], MAX_FILE_LEN - 1);
+ persistent_name_type[MAX_FILE_LEN - 1] = '\0';
+ strtolower(persistent_name_type);
+ if (!get_persistent_type_dir(persistent_name_type)) {
+ fprintf(stderr, _("Invalid type of persistent device name\n"));
+ return 2;
+ }
+ /*
+ * If persistent device name doesn't exist for device, use
+ * its pretty name.
+ */
+ *flags |= S_F_PERSIST_NAME + S_F_DEV_PRETTY;
+ return 0;
+ break;
+
+ case 'p':
+ *flags |= S_F_DEV_PRETTY;
+ break;
+
+ case 'q':
+ SELECT_ACTIVITY(A_QUEUE);
+ break;
+
+ case 'r':
+ p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND);
+ act[p]->options |= AO_SELECTED;
+ act[p]->opt_flags |= AO_F_MEMORY;
+ if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_ALL)) {
+ (*opt)++;
+ act[p]->opt_flags |= AO_F_MEM_ALL;
+ return 0;
+ }
+ break;
+
+ case 'S':
+ p = get_activity_position(act, A_MEMORY, EXIT_IF_NOT_FOUND);
+ act[p]->options |= AO_SELECTED;
+ act[p]->opt_flags |= AO_F_SWAP;
+ break;
+
+ case 't':
+ /*
+ * Check sar option -t here (as it can be combined
+ * with other ones, eg. "sar -rtu ..."
+ * But sadf option -t is checked in sadf.c as it won't
+ * be entered as a sar option after "--".
+ */
+ if (caller != C_SAR) {
+ return 1;
+ }
+ *flags |= S_F_TRUE_TIME;
+ break;
+
+ case 'u':
+ p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND);
+ act[p]->options |= AO_SELECTED;
+ if (!*(argv[*opt] + i + 1) && argv[*opt + 1] && !strcmp(argv[*opt + 1], K_ALL)) {
+ (*opt)++;
+ act[p]->opt_flags = AO_F_CPU_ALL;
+ return 0;
+ }
+ else {
+ act[p]->opt_flags = AO_F_CPU_DEF;
+ }
+ break;
+
+ case 'v':
+ SELECT_ACTIVITY(A_KTABLES);
+ break;
+
+ case 'w':
+ SELECT_ACTIVITY(A_PCSW);
+ break;
+
+ case 'W':
+ SELECT_ACTIVITY(A_SWAP);
+ break;
+
+ case 'y':
+ SELECT_ACTIVITY(A_SERIAL);
+ break;
+
+ case 'z':
+ *flags |= S_F_ZERO_OMIT;
+ break;
+
+ case 'V':
+ print_version();
+ break;
+
+ default:
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Parse sar "-m" option.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ *
+ * OUT:
+ * @act Array of selected activities.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_sar_m_opt(char *argv[], int *opt, struct activity *act[])
+{
+ char *t;
+
+ for (t = strtok(argv[*opt], ","); t; t = strtok(NULL, ",")) {
+ if (!strcmp(t, K_CPU)) {
+ SELECT_ACTIVITY(A_PWR_CPU);
+ }
+ else if (!strcmp(t, K_FAN)) {
+ SELECT_ACTIVITY(A_PWR_FAN);
+ }
+ else if (!strcmp(t, K_IN)) {
+ SELECT_ACTIVITY(A_PWR_IN);
+ }
+ else if (!strcmp(t, K_TEMP)) {
+ SELECT_ACTIVITY(A_PWR_TEMP);
+ }
+ else if (!strcmp(t, K_FREQ)) {
+ SELECT_ACTIVITY(A_PWR_FREQ);
+ }
+ else if (!strcmp(t, K_USB)) {
+ SELECT_ACTIVITY(A_PWR_USB);
+ }
+ else if (!strcmp(t, K_ALL)) {
+ SELECT_ACTIVITY(A_PWR_CPU);
+ SELECT_ACTIVITY(A_PWR_FAN);
+ SELECT_ACTIVITY(A_PWR_IN);
+ SELECT_ACTIVITY(A_PWR_TEMP);
+ SELECT_ACTIVITY(A_PWR_FREQ);
+ SELECT_ACTIVITY(A_PWR_USB);
+ }
+ else
+ return 1;
+ }
+
+ (*opt)++;
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Parse sar "-n" option.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ *
+ * OUT:
+ * @act Array of selected activities.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_sar_n_opt(char *argv[], int *opt, struct activity *act[])
+{
+ char *t;
+
+ for (t = strtok(argv[*opt], ","); t; t = strtok(NULL, ",")) {
+ if (!strcmp(t, K_DEV)) {
+ SELECT_ACTIVITY(A_NET_DEV);
+ }
+ else if (!strcmp(t, K_EDEV)) {
+ SELECT_ACTIVITY(A_NET_EDEV);
+ }
+ else if (!strcmp(t, K_SOCK)) {
+ SELECT_ACTIVITY(A_NET_SOCK);
+ }
+ else if (!strcmp(t, K_NFS)) {
+ SELECT_ACTIVITY(A_NET_NFS);
+ }
+ else if (!strcmp(t, K_NFSD)) {
+ SELECT_ACTIVITY(A_NET_NFSD);
+ }
+ else if (!strcmp(t, K_IP)) {
+ SELECT_ACTIVITY(A_NET_IP);
+ }
+ else if (!strcmp(t, K_EIP)) {
+ SELECT_ACTIVITY(A_NET_EIP);
+ }
+ else if (!strcmp(t, K_ICMP)) {
+ SELECT_ACTIVITY(A_NET_ICMP);
+ }
+ else if (!strcmp(t, K_EICMP)) {
+ SELECT_ACTIVITY(A_NET_EICMP);
+ }
+ else if (!strcmp(t, K_TCP)) {
+ SELECT_ACTIVITY(A_NET_TCP);
+ }
+ else if (!strcmp(t, K_ETCP)) {
+ SELECT_ACTIVITY(A_NET_ETCP);
+ }
+ else if (!strcmp(t, K_UDP)) {
+ SELECT_ACTIVITY(A_NET_UDP);
+ }
+ else if (!strcmp(t, K_SOCK6)) {
+ SELECT_ACTIVITY(A_NET_SOCK6);
+ }
+ else if (!strcmp(t, K_IP6)) {
+ SELECT_ACTIVITY(A_NET_IP6);
+ }
+ else if (!strcmp(t, K_EIP6)) {
+ SELECT_ACTIVITY(A_NET_EIP6);
+ }
+ else if (!strcmp(t, K_ICMP6)) {
+ SELECT_ACTIVITY(A_NET_ICMP6);
+ }
+ else if (!strcmp(t, K_EICMP6)) {
+ SELECT_ACTIVITY(A_NET_EICMP6);
+ }
+ else if (!strcmp(t, K_UDP6)) {
+ SELECT_ACTIVITY(A_NET_UDP6);
+ }
+ else if (!strcmp(t, K_FC)) {
+ SELECT_ACTIVITY(A_NET_FC);
+ }
+ else if (!strcmp(t, K_SOFT)) {
+ SELECT_ACTIVITY(A_NET_SOFT);
+ }
+ else if (!strcmp(t, K_ALL)) {
+ SELECT_ACTIVITY(A_NET_DEV);
+ SELECT_ACTIVITY(A_NET_EDEV);
+ SELECT_ACTIVITY(A_NET_SOCK);
+ SELECT_ACTIVITY(A_NET_NFS);
+ SELECT_ACTIVITY(A_NET_NFSD);
+ SELECT_ACTIVITY(A_NET_IP);
+ SELECT_ACTIVITY(A_NET_EIP);
+ SELECT_ACTIVITY(A_NET_ICMP);
+ SELECT_ACTIVITY(A_NET_EICMP);
+ SELECT_ACTIVITY(A_NET_TCP);
+ SELECT_ACTIVITY(A_NET_ETCP);
+ SELECT_ACTIVITY(A_NET_UDP);
+ SELECT_ACTIVITY(A_NET_SOCK6);
+ SELECT_ACTIVITY(A_NET_IP6);
+ SELECT_ACTIVITY(A_NET_EIP6);
+ SELECT_ACTIVITY(A_NET_ICMP6);
+ SELECT_ACTIVITY(A_NET_EICMP6);
+ SELECT_ACTIVITY(A_NET_UDP6);
+ SELECT_ACTIVITY(A_NET_FC);
+ SELECT_ACTIVITY(A_NET_SOFT);
+ }
+ else
+ return 1;
+ }
+
+ (*opt)++;
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Parse sar "-I" option.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ * @act Array of activities.
+ *
+ * OUT:
+ * @act Array of activities, with interrupts activity selected.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_sar_I_opt(char *argv[], int *opt, struct activity *act[])
+{
+ int p;
+
+ /* Select interrupt activity */
+ p = get_activity_position(act, A_IRQ, EXIT_IF_NOT_FOUND);
+ act[p]->options |= AO_SELECTED;
+
+ if (argv[++(*opt)]) {
+ if (parse_values(argv[*opt], act[p]->bitmap->b_array,
+ act[p]->bitmap->b_size, K_SUM))
+ return 1;
+ (*opt)++;
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ ***************************************************************************
+ * Parse sar and sadf "-P" option.
+ *
+ * IN:
+ * @argv Arguments list.
+ * @opt Index in list of arguments.
+ * @act Array of activities.
+ *
+ * OUT:
+ * @flags Common flags and system state.
+ * @act Array of activities, with CPUs selected.
+ *
+ * RETURNS:
+ * 0 on success, 1 otherwise.
+ ***************************************************************************
+ */
+int parse_sa_P_opt(char *argv[], int *opt, unsigned int *flags, struct activity *act[])
+{
+ int p;
+
+ p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND);
+
+ if (argv[++(*opt)]) {
+ if (parse_values(argv[*opt], act[p]->bitmap->b_array,
+ act[p]->bitmap->b_size, K_LOWERALL))
+ return 1;
+ (*opt)++;
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ ***************************************************************************
+ * Count number of comma-separated values in arguments list. For example,
+ * the number will be 3 for "sar --dev=sda,sdb,sdc -dp 2 5", 1 for
+ * "sar --dev=sda -dp 2 5" and 0 for "sar --dev= -dp 2 5".
+ *
+ * IN:
+ * @arg_v Argument containing the list of coma-separated values.
+ *
+ * RETURNS:
+ * Number of comma-separated values in the list.
+ ***************************************************************************
+ */
+int count_csval_arg(char *arg_v)
+{
+ int nr = 0;
+ char *t;
+
+ if (arg_v[0] == '\0')
+ return 0;
+
+ if (strchr(arg_v, ',')) {
+ for (t = arg_v; t; t = strchr(t + 1, ',')) {
+ nr++;
+ }
+ }
+ if (!nr) {
+ nr = 1;
+ }
+
+ return nr;
+}
+
+/*
+ ***************************************************************************
+ * Look for item in list.
+ *
+ * IN:
+ * @list Pointer on the start of the linked list.
+ * @item_name Item name to look for.
+ *
+ * RETURNS:
+ * 1 if item found in list, 0 otherwise.
+ ***************************************************************************
+ */
+int search_list_item(struct sa_item *list, char *item_name)
+{
+ while (list != NULL) {
+ if (!strcmp(list->item_name, item_name))
+ return 1; /* Item found in list */
+ list = list->next;
+ }
+
+ /* Item not found */
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Add item to the list.
+ *
+ * IN:
+ * @list Address of pointer on the start of the linked list.
+ * @item_name Name of the item.
+ * @max_len Max length of an item.
+ *
+ * RETURNS:
+ * 1 if item has been added to the list (since it was not previously there),
+ * and 0 otherwise (item already in list or item name too long).
+ ***************************************************************************
+ */
+int add_list_item(struct sa_item **list, char *item_name, int max_len)
+{
+ struct sa_item *e;
+ int len;
+
+ if ((len = strnlen(item_name, max_len)) == max_len)
+ /* Item too long */
+ return 0;
+
+ while (*list != NULL) {
+ e = *list;
+ if (!strcmp(e->item_name, item_name))
+ return 0; /* Item found in list */
+ list = &(e->next);
+ }
+
+ /* Item not found: Add it to the list */
+ SREALLOC(*list, struct sa_item, sizeof(struct sa_item));
+ e = *list;
+ if ((e->item_name = (char *) malloc(len + 1)) == NULL) {
+ perror("malloc");
+ exit(4);
+ }
+ strcpy(e->item_name, item_name);
+
+ return 1;
+}
+
+/*
+ ***************************************************************************
+ * Parse devices entered on the command line and save them in activity's
+ * list.
+ *
+ * IN:
+ * @argv Argument with list of devices.
+ * @a Activity for which devices are entered on the command line.
+ * @max_len Max length of a device name.
+ * @opt Index in list of arguments.
+ * @pos Position is string where is located the first device.
+ *
+ * OUT:
+ * @opt Index on next argument.
+ ***************************************************************************
+ */
+void parse_sa_devices(char *argv, struct activity *a, int max_len, int *opt, int pos)
+{
+ char *t;
+
+ for (t = strtok(argv + pos, ","); t; t = strtok(NULL, ",")) {
+ a->item_list_sz += add_list_item(&(a->item_list), t, max_len);
+ }
+ if (a->item_list_sz) {
+ a->options |= AO_LIST_ON_CMDLINE;
+ }
+ (*opt)++;
+}
+
+/*
+ ***************************************************************************
+ * Compute network interface utilization.
+ *
+ * IN:
+ * @st_net_dev Structure with network interface stats.
+ * @rx Number of bytes received per second.
+ * @tx Number of bytes transmitted per second.
+ *
+ * RETURNS:
+ * NIC utilization (0-100%).
+ ***************************************************************************
+ */
+double compute_ifutil(struct stats_net_dev *st_net_dev, double rx, double tx)
+{
+ unsigned long long speed;
+
+ if (st_net_dev->speed) {
+
+ speed = (unsigned long long) st_net_dev->speed * 1000000;
+
+ if (st_net_dev->duplex == C_DUPLEX_FULL) {
+ /* Full duplex */
+ if (rx > tx) {
+ return (rx * 800 / speed);
+ }
+ else {
+ return (tx * 800 / speed);
+ }
+ }
+ else {
+ /* Half duplex */
+ return ((rx + tx) * 800 / speed);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ ***************************************************************************
+ * Read and replace unprintable characters in comment with ".".
+ *
+ * IN:
+ * @ifd Input file descriptor.
+ * @comment Comment.
+ ***************************************************************************
+ */
+void replace_nonprintable_char(int ifd, char *comment)
+{
+ int i;
+
+ /* Read comment */
+ sa_fread(ifd, comment, MAX_COMMENT_LEN, HARD_SIZE);
+ comment[MAX_COMMENT_LEN - 1] = '\0';
+
+ /* Replace non printable chars */
+ for (i = 0; i < strlen(comment); i++) {
+ if (!isprint(comment[i]))
+ comment[i] = '.';
+ }
+}
+
+/*
+ ***************************************************************************
+ * Fill the rectime and loctime structures with current record's date and
+ * time, based on current record's "number of seconds since the epoch" saved
+ * in file.
+ * For loctime (if given): The timestamp is expressed in local time.
+ * For rectime: The timestamp is expressed in UTC, in local time, or in the
+ * time of the file's creator depending on options entered by the user on the
+ * command line.
+ *
+ * IN:
+ * @l_flags Flags indicating the type of time expected by the user.
+ * S_F_LOCAL_TIME means time should be expressed in local time.
+ * S_F_TRUE_TIME means time should be expressed in time of
+ * file's creator.
+ * Default is time expressed in UTC (except for sar, where it
+ * is local time).
+ * @record_hdr Record header containing the number of seconds since the
+ * epoch, and the HH:MM:SS of the file's creator.
+ *
+ * OUT:
+ * @rectime Structure where timestamp for current record has been saved
+ * (in local time or in UTC depending on options used).
+ * @loctime If given, structure where timestamp for current record has
+ * been saved (expressed in local time). This field will be used
+ * for time comparison if options -s and/or -e have been used.
+ *
+ * RETURNS:
+ * 1 if an error was detected, or 0 otherwise.
+ ***************************************************************************
+*/
+int sa_get_record_timestamp_struct(unsigned int l_flags, struct record_header *record_hdr,
+ struct tm *rectime, struct tm *loctime)
+{
+ struct tm *ltm = NULL;
+ int rc = 0;
+
+ /* Fill localtime structure if given */
+ if (loctime) {
+ if ((ltm = localtime((const time_t *) &(record_hdr->ust_time))) != NULL) {
+ *loctime = *ltm;
+ }
+ else {
+ rc = 1;
+ }
+ }
+
+ /* Fill generic rectime structure */
+ if (PRINT_LOCAL_TIME(l_flags) && !ltm) {
+ /* Get local time if not already done */
+ ltm = localtime((const time_t *) &(record_hdr->ust_time));
+ }
+
+ if (!PRINT_LOCAL_TIME(l_flags) && !PRINT_TRUE_TIME(l_flags)) {
+ /*
+ * Get time in UTC
+ * (the user doesn't want local time nor time of file's creator).
+ */
+ ltm = gmtime((const time_t *) &(record_hdr->ust_time));
+ }
+
+ if (ltm) {
+ /* Done even in true time mode so that we have some default values */
+ *rectime = *ltm;
+ }
+ else {
+ rc = 1;
+ }
+
+ if (PRINT_TRUE_TIME(l_flags)) {
+ /* Time of file's creator */
+ rectime->tm_hour = record_hdr->hour;
+ rectime->tm_min = record_hdr->minute;
+ rectime->tm_sec = record_hdr->second;
+ }
+
+ return rc;
+}
+
+/*
+ ***************************************************************************
+ * Set current record's timestamp strings (date and time) using the time
+ * data saved in @rectime structure. The string may be the number of seconds
+ * since the epoch if flag S_F_SEC_EPOCH has been set.
+ *
+ * IN:
+ * @l_flags Flags indicating the type of time expected by the user.
+ * S_F_SEC_EPOCH means the time should be expressed in seconds
+ * since the epoch (01/01/1970).
+ * @record_hdr Record header containing the number of seconds since the
+ * epoch.
+ * @cur_date String where timestamp's date will be saved. May be NULL.
+ * @cur_time String where timestamp's time will be saved.
+ * @len Maximum length of timestamp strings.
+ * @rectime Structure with current timestamp (expressed in local time or
+ * in UTC depending on whether options -T or -t have been used
+ * or not) that should be broken down in date and time strings.
+ *
+ * OUT:
+ * @cur_date Timestamp's date string (if expected).
+ * @cur_time Timestamp's time string. May contain the number of seconds
+ * since the epoch (01-01-1970) if corresponding option has
+ * been used.
+ ***************************************************************************
+*/
+void set_record_timestamp_string(unsigned int l_flags, struct record_header *record_hdr,
+ char *cur_date, char *cur_time, int len, struct tm *rectime)
+{
+ /* Set cur_time date value */
+ if (PRINT_SEC_EPOCH(l_flags) && cur_date) {
+ sprintf(cur_time, "%llu", record_hdr->ust_time);
+ strcpy(cur_date, "");
+ }
+ else {
+ /*
+ * If options -T or -t have been used then cur_time is
+ * expressed in local time. Else it is expressed in UTC.
+ */
+ if (cur_date) {
+ strftime(cur_date, len, "%Y-%m-%d", rectime);
+ }
+ if (USE_PREFD_TIME_OUTPUT(l_flags)) {
+ strftime(cur_time, len, "%X", rectime);
+ }
+ else {
+ strftime(cur_time, len, "%H:%M:%S", rectime);
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Print contents of a special (RESTART or COMMENT) record.
+ * Note: This function is called only when reading a file.
+ *
+ * IN:
+ * @record_hdr Current record header.
+ * @l_flags Flags for common options.
+ * @tm_start Structure filled when option -s has been used.
+ * @tm_end Structure filled when option -e has been used.
+ * @rtype Record type (R_RESTART or R_COMMENT).
+ * @ifd Input file descriptor.
+ * @rectime Structure where timestamp (expressed in local time or in UTC
+ * depending on whether options -T/-t have been used or not) can
+ * be saved for current record.
+ * @loctime Structure where timestamp (expressed in local time) can be
+ * saved for current record. May be NULL.
+ * @file Name of file being read.
+ * @tab Number of tabulations to print.
+ * @file_magic file_magic structure filled with file magic header data.
+ * @file_hdr System activity file standard header.
+ * @act Array of activities.
+ * @ofmt Pointer on report output format structure.
+ * @endian_mismatch
+ * TRUE if file's data don't match current machine's endianness.
+ * @arch_64 TRUE if file's data come from a 64 bit machine.
+ *
+ * OUT:
+ * @rectime Structure where timestamp (expressed in local time or in UTC)
+ * has been saved.
+ * @loctime Structure where timestamp (expressed in local time) has been
+ * saved (if requested).
+ *
+ * RETURNS:
+ * 1 if the record has been successfully displayed, and 0 otherwise.
+ ***************************************************************************
+ */
+int print_special_record(struct record_header *record_hdr, unsigned int l_flags,
+ struct tstamp *tm_start, struct tstamp *tm_end, int rtype, int ifd,
+ struct tm *rectime, struct tm *loctime, char *file, int tab,
+ struct file_magic *file_magic, struct file_header *file_hdr,
+ struct activity *act[], struct report_format *ofmt,
+ int endian_mismatch, int arch_64)
+{
+ char cur_date[TIMESTAMP_LEN], cur_time[TIMESTAMP_LEN];
+ int dp = 1;
+ int p;
+
+ /* Fill timestamp structure (rectime) for current record */
+ if (sa_get_record_timestamp_struct(l_flags, record_hdr, rectime, loctime))
+ return 0;
+
+ /* If loctime is NULL, then use rectime for comparison */
+ if (!loctime) {
+ loctime = rectime;
+ }
+
+ /* The record must be in the interval specified by -s/-e options */
+ if ((tm_start->use && (datecmp(loctime, tm_start) < 0)) ||
+ (tm_end->use && (datecmp(loctime, tm_end) > 0))) {
+ /* Will not display the special record */
+ dp = 0;
+ }
+ else {
+ /* Set date and time strings to be displayed for current record */
+ set_record_timestamp_string(l_flags, record_hdr,
+ cur_date, cur_time, TIMESTAMP_LEN, rectime);
+ }
+
+ if (rtype == R_RESTART) {
+ /* Read new cpu number following RESTART record */
+ file_hdr->sa_cpu_nr = read_nr_value(ifd, file, file_magic,
+ endian_mismatch, arch_64, TRUE);
+
+ /*
+ * We don't know if CPU related activities will be displayed or not.
+ * But if it is the case, @nr_ini will be used in the loop
+ * to process all CPUs. So update their value here and
+ * reallocate buffers if needed.
+ * NB: We may have nr_allocated=0 here if the activity has
+ * not been collected in file (or if it has an unknown format).
+ */
+ for (p = 0; p < NR_ACT; p++) {
+ if (HAS_PERSISTENT_VALUES(act[p]->options)) {
+ act[p]->nr_ini = file_hdr->sa_cpu_nr;
+ if (act[p]->nr_ini > act[p]->nr_allocated) {
+ reallocate_all_buffers(act[p], act[p]->nr_ini);
+ }
+ }
+ }
+
+ if (!dp)
+ return 0;
+
+ if (*ofmt->f_restart) {
+ (*ofmt->f_restart)(&tab, F_MAIN, cur_date, cur_time,
+ !PRINT_LOCAL_TIME(l_flags) &&
+ !PRINT_TRUE_TIME(l_flags), file_hdr);
+ }
+ }
+ else if (rtype == R_COMMENT) {
+ char file_comment[MAX_COMMENT_LEN];
+
+ /* Read and replace non printable chars in comment */
+ replace_nonprintable_char(ifd, file_comment);
+
+ if (!dp || !DISPLAY_COMMENT(l_flags))
+ return 0;
+
+ if (*ofmt->f_comment) {
+ (*ofmt->f_comment)(&tab, F_MAIN, cur_date, cur_time,
+ !PRINT_LOCAL_TIME(l_flags) &&
+ !PRINT_TRUE_TIME(l_flags), file_comment,
+ file_hdr);
+ }
+ }
+
+ return 1;
+}
+
+/*
+ ***************************************************************************
+ * Compute global CPU statistics as the sum of individual CPU ones, and
+ * calculate interval for global CPU.
+ * Also identify offline CPU.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @flags Flags for common options and system state.
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
+ *
+ * OUT:
+ * @a Activity structure with updated statistics (those for global
+ * CPU, and also those for offline CPU).
+ * @offline_cpu_bitmap
+ * CPU bitmap with offline CPU.
+ *
+ * RETURNS:
+ * Interval for global CPU.
+ ***************************************************************************
+ */
+unsigned long long get_global_cpu_statistics(struct activity *a, int prev, int curr,
+ unsigned int flags, unsigned char offline_cpu_bitmap[])
+{
+ int i;
+ unsigned long long tot_jiffies_c, tot_jiffies_p;
+ unsigned long long deltot_jiffies = 0;
+ struct stats_cpu *scc, *scp;
+ struct stats_cpu *scc_all = (struct stats_cpu *) ((char *) a->buf[curr]);
+ struct stats_cpu *scp_all = (struct stats_cpu *) ((char *) a->buf[prev]);
+
+ /*
+ * Initial processing.
+ * Compute CPU "all" as sum of all individual CPU. Done only on SMP machines (a->nr_ini > 1).
+ * For UP machines we keep the values read from global CPU line in /proc/stat.
+ * Also look for offline CPU: They won't be displayed, and some of their values may
+ * have to be modified.
+ */
+ if (a->nr_ini > 1) {
+ memset(scc_all, 0, sizeof(struct stats_cpu));
+ memset(scp_all, 0, sizeof(struct stats_cpu));
+ }
+
+ for (i = 1; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
+
+ /*
+ * The size of a->buf[...] CPU structure may be different from the default
+ * sizeof(struct stats_cpu) value if data have been read from a file!
+ * That's why we don't use a syntax like:
+ * scc = (struct stats_cpu *) a->buf[...] + i;
+ */
+ scc = (struct stats_cpu *) ((char *) a->buf[curr] + i * a->msize);
+ scp = (struct stats_cpu *) ((char *) a->buf[prev] + i * a->msize);
+
+ /*
+ * Compute the total number of jiffies spent by current processor.
+ * NB: Don't add cpu_guest/cpu_guest_nice because cpu_user/cpu_nice
+ * already include them.
+ */
+ tot_jiffies_c = scc->cpu_user + scc->cpu_nice +
+ scc->cpu_sys + scc->cpu_idle +
+ scc->cpu_iowait + scc->cpu_hardirq +
+ scc->cpu_steal + scc->cpu_softirq;
+ tot_jiffies_p = scp->cpu_user + scp->cpu_nice +
+ scp->cpu_sys + scp->cpu_idle +
+ scp->cpu_iowait + scp->cpu_hardirq +
+ scp->cpu_steal + scp->cpu_softirq;
+
+ /*
+ * If the CPU is offline then it is omited from /proc/stat:
+ * All the fields couldn't have been read and the sum of them is zero.
+ */
+ if (tot_jiffies_c == 0) {
+ /*
+ * CPU is currently offline.
+ * Set current struct fields (which have been set to zero)
+ * to values from previous iteration. Hence their values won't
+ * jump from zero when the CPU comes back online.
+ * Note that this workaround no longer fully applies with recent kernels,
+ * as I have noticed that when a CPU comes back online, some fields
+ * restart from their previous value (e.g. user, nice, system)
+ * whereas others restart from zero (idle, iowait)! To deal with this,
+ * the get_per_cpu_interval() function will set these previous values
+ * to zero if necessary.
+ */
+ *scc = *scp;
+
+ /*
+ * Mark CPU as offline to not display it
+ * (and thus it will not be confused with a tickless CPU).
+ */
+ offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07);
+ }
+
+ if ((tot_jiffies_p == 0) && !WANT_SINCE_BOOT(flags)) {
+ /*
+ * CPU has just come back online.
+ * Unfortunately, no reference values are available
+ * from a previous iteration, probably because it was
+ * already offline when the first sample has been taken.
+ * So don't display that CPU to prevent "jump-from-zero"
+ * output syndrome, and don't take it into account for CPU "all".
+ */
+ offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07);
+ continue;
+ }
+
+ /*
+ * Get interval for current CPU and add it to global CPU.
+ * Note: Previous idle and iowait values (saved in scp) may be modified here.
+ */
+ deltot_jiffies += get_per_cpu_interval(scc, scp);
+
+ scc_all->cpu_user += scc->cpu_user;
+ scp_all->cpu_user += scp->cpu_user;
+
+ scc_all->cpu_nice += scc->cpu_nice;
+ scp_all->cpu_nice += scp->cpu_nice;
+
+ scc_all->cpu_sys += scc->cpu_sys;
+ scp_all->cpu_sys += scp->cpu_sys;
+
+ scc_all->cpu_idle += scc->cpu_idle;
+ scp_all->cpu_idle += scp->cpu_idle;
+
+ scc_all->cpu_iowait += scc->cpu_iowait;
+ scp_all->cpu_iowait += scp->cpu_iowait;
+
+ scc_all->cpu_hardirq += scc->cpu_hardirq;
+ scp_all->cpu_hardirq += scp->cpu_hardirq;
+
+ scc_all->cpu_steal += scc->cpu_steal;
+ scp_all->cpu_steal += scp->cpu_steal;
+
+ scc_all->cpu_softirq += scc->cpu_softirq;
+ scp_all->cpu_softirq += scp->cpu_softirq;
+
+ scc_all->cpu_guest += scc->cpu_guest;
+ scp_all->cpu_guest += scp->cpu_guest;
+
+ scc_all->cpu_guest_nice += scc->cpu_guest_nice;
+ scp_all->cpu_guest_nice += scp->cpu_guest_nice;
+ }
+
+ return deltot_jiffies;
+}
+
+/*
+ ***************************************************************************
+ * Compute softnet statistics for CPU "all" as the sum of individual CPU
+ * ones.
+ * Also identify offline CPU.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @flags Flags for common options and system state.
+ * @offline_cpu_bitmap
+ * CPU bitmap for offline CPU.
+ *
+ * OUT:
+ * @a Activity structure with updated statistics (those for global
+ * CPU, and also those for offline CPU).
+ * @offline_cpu_bitmap
+ * CPU bitmap with offline CPU.
+ ***************************************************************************
+ */
+void get_global_soft_statistics(struct activity *a, int prev, int curr,
+ unsigned int flags, unsigned char offline_cpu_bitmap[])
+{
+ int i;
+ struct stats_softnet *ssnc, *ssnp;
+ struct stats_softnet *ssnc_all = (struct stats_softnet *) ((char *) a->buf[curr]);
+ struct stats_softnet *ssnp_all = (struct stats_softnet *) ((char *) a->buf[prev]);
+
+ /*
+ * Init structures that will contain values for CPU "all".
+ * CPU "all" doesn't exist in /proc/net/softnet_stat file, so
+ * we compute its values as the sum of the values of each CPU.
+ */
+ memset(ssnc_all, 0, sizeof(struct stats_softnet));
+ memset(ssnp_all, 0, sizeof(struct stats_softnet));
+
+ for (i = 1; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) {
+
+ /*
+ * The size of a->buf[...] CPU structure may be different from the default
+ * sizeof(struct stats_pwr_cpufreq) value if data have been read from a file!
+ * That's why we don't use a syntax like:
+ * ssnc = (struct stats_softnet *) a->buf[...] + i;
+ */
+ ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize);
+ ssnp = (struct stats_softnet *) ((char *) a->buf[prev] + i * a->msize);
+
+ if (ssnc->processed + ssnc->dropped + ssnc->time_squeeze +
+ ssnc->received_rps + ssnc->flow_limit == 0) {
+ /* Assume current CPU is offline */
+ *ssnc = *ssnp;
+ offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07);
+ }
+
+ if ((ssnp->processed + ssnp->dropped + ssnp->time_squeeze +
+ ssnp->received_rps + ssnp->flow_limit == 0) && !WANT_SINCE_BOOT(flags)) {
+ /* Current CPU back online but no previous sample for it */
+ offline_cpu_bitmap[i >> 3] |= 1 << (i & 0x07);
+ continue;
+ }
+
+ ssnc_all->processed += ssnc->processed;
+ ssnc_all->dropped += ssnc->dropped;
+ ssnc_all->time_squeeze += ssnc->time_squeeze;
+ ssnc_all->received_rps += ssnc->received_rps;
+ ssnc_all->flow_limit += ssnc->flow_limit;
+
+ ssnp_all->processed += ssnp->processed;
+ ssnp_all->dropped += ssnp->dropped;
+ ssnp_all->time_squeeze += ssnp->time_squeeze;
+ ssnp_all->received_rps += ssnp->received_rps;
+ ssnp_all->flow_limit += ssnp->flow_limit;
+ }
+}
+
+/*
+ ***************************************************************************
+ * Get device name (whether pretty-printed, persistent or not).
+ *
+ * IN:
+ * @major Major number of the device.
+ * @minor Minor number of the device.
+ * @flags Flags for common options and system state.
+ *
+ * RETURNS:
+ * The name of the device.
+ ***************************************************************************
+ */
+char *get_sa_devname(unsigned int major, unsigned int minor, unsigned int flags)
+{
+ char *dev_name = NULL, *persist_dev_name = NULL;
+
+ if (DISPLAY_PERSIST_NAME_S(flags)) {
+ persist_dev_name = get_persistent_name_from_pretty(get_devname(major, minor, TRUE));
+ }
+
+ if (persist_dev_name) {
+ dev_name = persist_dev_name;
+ }
+ else {
+ if ((USE_PRETTY_OPTION(flags)) && (major == dm_major)) {
+ dev_name = transform_devmapname(major, minor);
+ }
+
+ if (!dev_name) {
+ dev_name = get_devname(major, minor,
+ USE_PRETTY_OPTION(flags));
+ }
+ }
+
+ return dev_name;
+}
+
+#endif /* SOURCE_SADC undefined */
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
--- /dev/null
+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
--- /dev/null
+12.0.1/
\ No newline at end of file