2 * rd_stats.c: Read system statistics
3 * (C) 1999-2017 by Sebastien GODARD (sysstat <at> orange.fr)
5 ***************************************************************************
6 * This program is free software; you can redistribute it and/or modify it *
7 * under the terms of the GNU General Public License as published by the *
8 * Free Software Foundation; either version 2 of the License, or (at your *
9 * option) any later version. *
11 * This program is distributed in the hope that it will be useful, but *
12 * WITHOUT ANY WARRANTY; without the implied warranty of MERCHANTABILITY *
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
16 * You should have received a copy of the GNU General Public License along *
17 * with this program; if not, write to the Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA *
19 ***************************************************************************
28 #include <sys/types.h>
30 #include <sys/statvfs.h>
40 #define _(string) gettext(string)
42 #define _(string) (string)
46 ***************************************************************************
47 * Read CPU statistics.
48 * Remember that this function is used by several sysstat commands!
51 * @st_cpu Buffer where structures containing stats will be saved.
52 * @nr_alloc Total number of structures allocated. Value is >= 1.
55 * @st_cpu Buffer with statistics.
58 * Highest CPU number(*) for which statistics have been read.
59 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
60 * Or -1 if the buffer was too small and needs to be reallocated.
62 * (*)This doesn't account for all processors in the machine in the case
63 * where some CPU are offline and located at the end of the list.
64 ***************************************************************************
66 __nr_t read_stat_cpu(struct stats_cpu *st_cpu, __nr_t nr_alloc)
69 struct stats_cpu *st_cpu_i;
75 if ((fp = fopen(STAT, "r")) == NULL) {
76 fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
80 while (fgets(line, sizeof(line), fp) != NULL) {
82 if (!strncmp(line, "cpu ", 4)) {
85 * All the fields don't necessarily exist,
86 * depending on the kernel version used.
88 memset(st_cpu, 0, STATS_CPU_SIZE);
91 * Read the number of jiffies spent in the different modes
92 * (user, nice, etc.) among all proc. CPU usage is not reduced
93 * to one processor to avoid rounding problems.
95 sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
101 &st_cpu->cpu_hardirq,
102 &st_cpu->cpu_softirq,
105 &st_cpu->cpu_guest_nice);
112 /* We just want to read stats for CPU "all" */
116 else if (!strncmp(line, "cpu", 3)) {
117 /* All the fields don't necessarily exist */
118 memset(&sc, 0, STATS_CPU_SIZE);
120 * Read the number of jiffies spent in the different modes
121 * (user, nice, etc) for current proc.
122 * This is done only on SMP machines.
124 sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
137 if (proc_nr + 2 > nr_alloc) {
142 st_cpu_i = st_cpu + proc_nr + 1;
145 if (proc_nr + 2 > cpu_read) {
146 cpu_read = proc_nr + 2;
156 ***************************************************************************
157 * Read interrupts statistics from /proc/stat.
158 * Remember that this function is used by several sysstat commands!
161 * @st_irq Structure where stats will be saved.
162 * @nr_alloc Number of structures allocated. Value is >= 1.
165 * @st_irq Structure with statistics.
168 * Number of interrupts read, or -1 if the buffer was too small and
169 * needs to be reallocated.
170 ***************************************************************************
172 __nr_t read_stat_irq(struct stats_irq *st_irq, __nr_t nr_alloc)
175 struct stats_irq *st_irq_i;
178 unsigned long long irq_nr;
181 if ((fp = fopen(STAT, "r")) == NULL)
184 while (fgets(line, sizeof(line), fp) != NULL) {
186 if (!strncmp(line, "intr ", 5)) {
187 /* Read total number of interrupts received since system boot */
188 sscanf(line + 5, "%llu", &st_irq->irq_nr);
189 pos = strcspn(line + 5, " ") + 5;
193 /* We just want to read the total number of interrupts */
197 i = sscanf(line + pos, " %llu", &irq_nr);
201 if (irq_read + 1 > nr_alloc) {
205 st_irq_i = st_irq + irq_read++;
206 st_irq_i->irq_nr = irq_nr;
208 i = strcspn(line + pos + 1, " ");
211 while ((i > 0) && (pos < sizeof(line)));
215 for (i = 1; i < nbr; i++) {
216 st_irq_i = st_irq + i;
217 sscanf(line + pos, " %llu", &st_irq_i->irq_nr);
218 pos += strcspn(line + pos + 1, " ") + 1;
229 ***************************************************************************
230 * Read memory statistics from /proc/meminfo.
233 * @st_memory Structure where stats will be saved.
236 * @st_memory Structure with statistics.
239 * 1 on success, 0 otherwise.
240 ***************************************************************************
242 __nr_t read_meminfo(struct stats_memory *st_memory)
247 if ((fp = fopen(MEMINFO, "r")) == NULL)
250 while (fgets(line, sizeof(line), fp) != NULL) {
252 if (!strncmp(line, "MemTotal:", 9)) {
253 /* Read the total amount of memory in kB */
254 sscanf(line + 9, "%lu", &st_memory->tlmkb);
256 else if (!strncmp(line, "MemFree:", 8)) {
257 /* Read the amount of free memory in kB */
258 sscanf(line + 8, "%lu", &st_memory->frmkb);
260 else if (!strncmp(line, "MemAvailable:", 13)) {
261 /* Read the amount of available memory in kB */
262 sscanf(line + 13, "%lu", &st_memory->availablekb);
264 else if (!strncmp(line, "Buffers:", 8)) {
265 /* Read the amount of buffered memory in kB */
266 sscanf(line + 8, "%lu", &st_memory->bufkb);
268 else if (!strncmp(line, "Cached:", 7)) {
269 /* Read the amount of cached memory in kB */
270 sscanf(line + 7, "%lu", &st_memory->camkb);
272 else if (!strncmp(line, "SwapCached:", 11)) {
273 /* Read the amount of cached swap in kB */
274 sscanf(line + 11, "%lu", &st_memory->caskb);
276 else if (!strncmp(line, "Active:", 7)) {
277 /* Read the amount of active memory in kB */
278 sscanf(line + 7, "%lu", &st_memory->activekb);
280 else if (!strncmp(line, "Inactive:", 9)) {
281 /* Read the amount of inactive memory in kB */
282 sscanf(line + 9, "%lu", &st_memory->inactkb);
284 else if (!strncmp(line, "SwapTotal:", 10)) {
285 /* Read the total amount of swap memory in kB */
286 sscanf(line + 10, "%lu", &st_memory->tlskb);
288 else if (!strncmp(line, "SwapFree:", 9)) {
289 /* Read the amount of free swap memory in kB */
290 sscanf(line + 9, "%lu", &st_memory->frskb);
292 else if (!strncmp(line, "Dirty:", 6)) {
293 /* Read the amount of dirty memory in kB */
294 sscanf(line + 6, "%lu", &st_memory->dirtykb);
296 else if (!strncmp(line, "Committed_AS:", 13)) {
297 /* Read the amount of commited memory in kB */
298 sscanf(line + 13, "%lu", &st_memory->comkb);
300 else if (!strncmp(line, "AnonPages:", 10)) {
301 /* Read the amount of pages mapped into userspace page tables in kB */
302 sscanf(line + 10, "%lu", &st_memory->anonpgkb);
304 else if (!strncmp(line, "Slab:", 5)) {
305 /* Read the amount of in-kernel data structures cache in kB */
306 sscanf(line + 5, "%lu", &st_memory->slabkb);
308 else if (!strncmp(line, "KernelStack:", 12)) {
309 /* Read the kernel stack utilization in kB */
310 sscanf(line + 12, "%lu", &st_memory->kstackkb);
312 else if (!strncmp(line, "PageTables:", 11)) {
313 /* Read the amount of memory dedicated to the lowest level of page tables in kB */
314 sscanf(line + 11, "%lu", &st_memory->pgtblkb);
316 else if (!strncmp(line, "VmallocUsed:", 12)) {
317 /* Read the amount of vmalloc area which is used in kB */
318 sscanf(line + 12, "%lu", &st_memory->vmusedkb);
327 ***************************************************************************
328 * Read machine uptime, independently of the number of processors.
331 * @uptime Uptime value in hundredths of a second.
332 ***************************************************************************
334 void read_uptime(unsigned long long *uptime)
338 unsigned long up_sec, up_cent;
341 if ((fp = fopen(UPTIME, "r")) == NULL) {
344 else if (fgets(line, sizeof(line), fp) == NULL) {
347 else if (sscanf(line, "%lu.%lu", &up_sec, &up_cent) == 2) {
348 *uptime = (unsigned long long) up_sec * 100 +
349 (unsigned long long) up_cent;
359 fprintf(stderr, _("Cannot read %s\n"), UPTIME);
365 /*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
368 ***************************************************************************
369 * Replace octal codes in string with their corresponding characters.
372 * @str String to parse.
375 * @str String with octal codes replaced with characters.
376 ***************************************************************************
378 void oct2chr(char *str)
385 while (i < len - 3) {
386 if ((str[i] == '\\') &&
387 (str[i + 1] >= '0') && (str[i + 1] <= '3') &&
388 (str[i + 2] >= '0') && (str[i + 2] <= '7') &&
389 (str[i + 3] >= '0') && (str[i + 3] <= '7')) {
390 /* Octal code found */
391 str[i] = (str[i + 1] - 48) * 64 +
392 (str[i + 2] - 48) * 8 +
394 for (j = i + 4; j <= len; j++) {
404 ***************************************************************************
405 * Read processes (tasks) creation and context switches statistics
409 * @st_pcsw Structure where stats will be saved.
412 * @st_pcsw Structure with statistics.
415 * 1 on success, 0 otherwise.
416 ***************************************************************************
418 __nr_t read_stat_pcsw(struct stats_pcsw *st_pcsw)
423 if ((fp = fopen(STAT, "r")) == NULL)
426 while (fgets(line, sizeof(line), fp) != NULL) {
428 if (!strncmp(line, "ctxt ", 5)) {
429 /* Read number of context switches */
430 sscanf(line + 5, "%llu", &st_pcsw->context_switch);
433 else if (!strncmp(line, "processes ", 10)) {
434 /* Read number of processes created since system boot */
435 sscanf(line + 10, "%lu", &st_pcsw->processes);
444 ***************************************************************************
445 * Read queue and load statistics from /proc/loadavg and /proc/stat.
448 * @st_queue Structure where stats will be saved.
451 * @st_queue Structure with statistics.
454 * 1 on success, 0 otherwise.
455 ***************************************************************************
457 __nr_t read_loadavg(struct stats_queue *st_queue)
464 if ((fp = fopen(LOADAVG, "r")) == NULL)
467 /* Read load averages and queue length */
468 rc = fscanf(fp, "%d.%u %d.%u %d.%u %lu/%u %*d\n",
469 &load_tmp[0], &st_queue->load_avg_1,
470 &load_tmp[1], &st_queue->load_avg_5,
471 &load_tmp[2], &st_queue->load_avg_15,
472 &st_queue->nr_running,
473 &st_queue->nr_threads);
480 st_queue->load_avg_1 += load_tmp[0] * 100;
481 st_queue->load_avg_5 += load_tmp[1] * 100;
482 st_queue->load_avg_15 += load_tmp[2] * 100;
484 if (st_queue->nr_running) {
485 /* Do not take current process into account */
486 st_queue->nr_running--;
489 /* Read nr of tasks blocked from /proc/stat */
490 if ((fp = fopen(STAT, "r")) == NULL)
493 while (fgets(line, sizeof(line), fp) != NULL) {
495 if (!strncmp(line, "procs_blocked ", 14)) {
496 /* Read number of processes blocked */
497 sscanf(line + 14, "%lu", &st_queue->procs_blocked);
507 ***************************************************************************
508 * Read swapping statistics from /proc/vmstat.
511 * @st_swap Structure where stats will be saved.
514 * @st_swap Structure with statistics.
517 * 1 on success, 0 otherwise.
518 ***************************************************************************
520 __nr_t read_vmstat_swap(struct stats_swap *st_swap)
525 if ((fp = fopen(VMSTAT, "r")) == NULL)
528 while (fgets(line, sizeof(line), fp) != NULL) {
530 if (!strncmp(line, "pswpin ", 7)) {
531 /* Read number of swap pages brought in */
532 sscanf(line + 7, "%lu", &st_swap->pswpin);
534 else if (!strncmp(line, "pswpout ", 8)) {
535 /* Read number of swap pages brought out */
536 sscanf(line + 8, "%lu", &st_swap->pswpout);
545 ***************************************************************************
546 * Read paging statistics from /proc/vmstat.
549 * @st_paging Structure where stats will be saved.
552 * @st_paging Structure with statistics.
555 * 1 on success, 0 otherwise.
556 ***************************************************************************
558 __nr_t read_vmstat_paging(struct stats_paging *st_paging)
564 if ((fp = fopen(VMSTAT, "r")) == NULL)
567 st_paging->pgsteal = 0;
568 st_paging->pgscan_kswapd = st_paging->pgscan_direct = 0;
570 while (fgets(line, sizeof(line), fp) != NULL) {
572 if (!strncmp(line, "pgpgin ", 7)) {
573 /* Read number of pages the system paged in */
574 sscanf(line + 7, "%lu", &st_paging->pgpgin);
576 else if (!strncmp(line, "pgpgout ", 8)) {
577 /* Read number of pages the system paged out */
578 sscanf(line + 8, "%lu", &st_paging->pgpgout);
580 else if (!strncmp(line, "pgfault ", 8)) {
581 /* Read number of faults (major+minor) made by the system */
582 sscanf(line + 8, "%lu", &st_paging->pgfault);
584 else if (!strncmp(line, "pgmajfault ", 11)) {
585 /* Read number of faults (major only) made by the system */
586 sscanf(line + 11, "%lu", &st_paging->pgmajfault);
588 else if (!strncmp(line, "pgfree ", 7)) {
589 /* Read number of pages freed by the system */
590 sscanf(line + 7, "%lu", &st_paging->pgfree);
592 else if (!strncmp(line, "pgsteal_", 8)) {
593 /* Read number of pages stolen by the system */
594 sscanf(strchr(line, ' '), "%lu", &pgtmp);
595 st_paging->pgsteal += pgtmp;
597 else if (!strncmp(line, "pgscan_kswapd", 13)) {
598 /* Read number of pages scanned by the kswapd daemon */
599 sscanf(strchr(line, ' '), "%lu", &pgtmp);
600 st_paging->pgscan_kswapd += pgtmp;
602 else if (!strncmp(line, "pgscan_direct", 13)) {
603 /* Read number of pages scanned directly */
604 sscanf(strchr(line, ' '), "%lu", &pgtmp);
605 st_paging->pgscan_direct += pgtmp;
614 ***************************************************************************
615 * Read I/O and transfer rates statistics from /proc/diskstats.
618 * @st_io Structure where stats will be saved.
621 * @st_io Structure with statistics.
624 * 1 on success, 0 otherwise.
625 ***************************************************************************
627 __nr_t read_diskstats_io(struct stats_io *st_io)
631 char dev_name[MAX_NAME_LEN];
632 unsigned int major, minor;
633 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
635 if ((fp = fopen(DISKSTATS, "r")) == NULL)
638 while (fgets(line, sizeof(line), fp) != NULL) {
640 if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu",
641 &major, &minor, dev_name,
642 &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) {
644 if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) {
646 * OK: It's a (real) device and not a partition.
647 * Note: Structure should have been initialized first!
649 st_io->dk_drive += (unsigned long long) rd_ios + (unsigned long long) wr_ios;
650 st_io->dk_drive_rio += rd_ios;
651 st_io->dk_drive_rblk += rd_sec;
652 st_io->dk_drive_wio += wr_ios;
653 st_io->dk_drive_wblk += wr_sec;
663 ***************************************************************************
664 * Read block devices statistics from /proc/diskstats.
667 * @st_disk Structure where stats will be saved.
668 * @nr_alloc Total number of structures allocated. Value is >= 1.
669 * @read_part True if disks *and* partitions should be read; False if only
673 * @st_disk Structure with statistics.
676 * Number of block devices read, or -1 if the buffer was too small and
677 * needs to be reallocated.
678 ***************************************************************************
680 __nr_t read_diskstats_disk(struct stats_disk *st_disk, __nr_t nr_alloc,
685 char dev_name[MAX_NAME_LEN];
686 struct stats_disk *st_disk_i;
687 unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks;
688 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
691 if ((fp = fopen(DISKSTATS, "r")) == NULL)
694 while (fgets(line, sizeof(line), fp) != NULL) {
696 if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu"
698 &major, &minor, dev_name,
699 &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks,
700 &tot_ticks, &rq_ticks) == 11) {
702 if (!rd_ios && !wr_ios)
703 /* Unused device: Ignore it */
705 if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) {
707 if (dsk_read + 1 > nr_alloc) {
712 st_disk_i = st_disk + dsk_read++;
713 st_disk_i->major = major;
714 st_disk_i->minor = minor;
715 st_disk_i->nr_ios = (unsigned long long) rd_ios + (unsigned long long) wr_ios;
716 st_disk_i->rd_sect = rd_sec;
717 st_disk_i->wr_sect = wr_sec;
718 st_disk_i->rd_ticks = rd_ticks;
719 st_disk_i->wr_ticks = wr_ticks;
720 st_disk_i->tot_ticks = tot_ticks;
721 st_disk_i->rq_ticks = rq_ticks;
731 ***************************************************************************
732 * Read serial lines statistics from /proc/tty/driver/serial.
735 * @st_serial Structure where stats will be saved.
736 * @nr_alloc Total number of structures allocated. Value is >= 1.
739 * @st_serial Structure with statistics.
742 * Number of serial lines read, or -1 if the buffer was too small and
743 * needs to be reallocated.
744 ***************************************************************************
746 __nr_t read_tty_driver_serial(struct stats_serial *st_serial, __nr_t nr_alloc)
749 struct stats_serial *st_serial_i;
754 if ((fp = fopen(SERIAL, "r")) == NULL)
757 while (fgets(line, sizeof(line), fp) != NULL ) {
759 if ((p = strstr(line, "tx:")) != NULL) {
761 if (sl_read + 1 > nr_alloc) {
766 st_serial_i = st_serial + sl_read++;
767 /* Read serial line number */
768 sscanf(line, "%u", &st_serial_i->line);
770 * A value of 0 means an unused structure.
771 * So increment the value we have just read
772 * to make sure it is not zero.
774 (st_serial_i->line)++;
776 * Read the number of chars transmitted and received by
777 * current serial line.
779 sscanf(p + 3, "%u", &st_serial_i->tx);
780 if ((p = strstr(line, "rx:")) != NULL) {
781 sscanf(p + 3, "%u", &st_serial_i->rx);
783 if ((p = strstr(line, "fe:")) != NULL) {
784 sscanf(p + 3, "%u", &st_serial_i->frame);
786 if ((p = strstr(line, "pe:")) != NULL) {
787 sscanf(p + 3, "%u", &st_serial_i->parity);
789 if ((p = strstr(line, "brk:")) != NULL) {
790 sscanf(p + 4, "%u", &st_serial_i->brk);
792 if ((p = strstr(line, "oe:")) != NULL) {
793 sscanf(p + 3, "%u", &st_serial_i->overrun);
803 ***************************************************************************
804 * Read kernel tables statistics from various system files.
807 * @st_ktables Structure where stats will be saved.
810 * @st_ktables Structure with statistics.
813 * 1 (always success).
814 ***************************************************************************
816 __nr_t read_kernel_tables(struct stats_ktables *st_ktables)
822 /* Open /proc/sys/fs/dentry-state file */
823 if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) {
824 rc = fscanf(fp, "%*d %u",
825 &st_ktables->dentry_stat);
828 st_ktables->dentry_stat = 0;
832 /* Open /proc/sys/fs/file-nr file */
833 if ((fp = fopen(FFILE_NR, "r")) != NULL) {
834 rc = fscanf(fp, "%u %u",
835 &st_ktables->file_used, &parm);
838 * The number of used handles is the number of allocated ones
839 * minus the number of free ones.
842 st_ktables->file_used -= parm;
845 st_ktables->file_used = 0;
849 /* Open /proc/sys/fs/inode-state file */
850 if ((fp = fopen(FINODE_STATE, "r")) != NULL) {
851 rc = fscanf(fp, "%u %u",
852 &st_ktables->inode_used, &parm);
855 * The number of inuse inodes is the number of allocated ones
856 * minus the number of free ones.
859 st_ktables->inode_used -= parm;
862 st_ktables->inode_used = 0;
866 /* Open /proc/sys/kernel/pty/nr file */
867 if ((fp = fopen(PTY_NR, "r")) != NULL) {
868 rc = fscanf(fp, "%u",
869 &st_ktables->pty_nr);
872 st_ktables->pty_nr = 0;
880 ***************************************************************************
881 * Read network interfaces statistics from /proc/net/dev.
884 * @st_net_dev Structure where stats will be saved.
885 * @nr_alloc Total number of structures allocated. Value is >= 1.
888 * @st_net_dev Structure with statistics.
891 * Number of interfaces read, or -1 if the buffer was too small and
892 * needs to be reallocated.
893 ***************************************************************************
895 __nr_t read_net_dev(struct stats_net_dev *st_net_dev, __nr_t nr_alloc)
898 struct stats_net_dev *st_net_dev_i;
900 char iface[MAX_IFACE_LEN];
904 if ((fp = fopen(NET_DEV, "r")) == NULL)
907 while (fgets(line, sizeof(line), fp) != NULL) {
909 pos = strcspn(line, ":");
910 if (pos < strlen(line)) {
912 if (dev_read + 1 > nr_alloc) {
917 st_net_dev_i = st_net_dev + dev_read++;
918 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
919 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
920 sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */
921 sscanf(line + pos + 1, "%llu %llu %*u %*u %*u %*u %llu %llu %llu %llu "
922 "%*u %*u %*u %*u %*u %llu",
923 &st_net_dev_i->rx_bytes,
924 &st_net_dev_i->rx_packets,
925 &st_net_dev_i->rx_compressed,
926 &st_net_dev_i->multicast,
927 &st_net_dev_i->tx_bytes,
928 &st_net_dev_i->tx_packets,
929 &st_net_dev_i->tx_compressed);
938 ***************************************************************************
939 * Read duplex and speed data for network interface cards.
942 * @st_net_dev Structure where stats will be saved.
943 * @nbr Number of network interfaces to read.
946 * @st_net_dev Structure with statistics.
947 ***************************************************************************
949 void read_if_info(struct stats_net_dev *st_net_dev, int nbr)
952 struct stats_net_dev *st_net_dev_i;
953 char filename[128], duplex[32];
956 for (dev = 0; dev < nbr; dev++) {
958 st_net_dev_i = st_net_dev + dev;
960 /* Read speed info */
961 sprintf(filename, IF_DUPLEX, st_net_dev_i->interface);
963 if ((fp = fopen(filename, "r")) == NULL)
964 /* Cannot read NIC duplex */
967 n = fscanf(fp, "%31s", duplex);
972 /* Cannot read NIC duplex */
975 if (!strcmp(duplex, K_DUPLEX_FULL)) {
976 st_net_dev_i->duplex = C_DUPLEX_FULL;
978 else if (!strcmp(duplex, K_DUPLEX_HALF)) {
979 st_net_dev_i->duplex = C_DUPLEX_HALF;
984 /* Read speed info */
985 sprintf(filename, IF_SPEED, st_net_dev_i->interface);
987 if ((fp = fopen(filename, "r")) == NULL)
988 /* Cannot read NIC speed */
991 n = fscanf(fp, "%u", &st_net_dev_i->speed);
996 st_net_dev_i->speed = 0;
1003 ***************************************************************************
1004 * Read network interfaces errors statistics from /proc/net/dev.
1007 * @st_net_edev Structure where stats will be saved.
1008 * @nr_alloc Total number of structures allocated. Value is >= 1.
1011 * @st_net_edev Structure with statistics.
1014 * Number of interfaces read, or -1 if the buffer was too small and
1015 * needs to be reallocated.
1016 ***************************************************************************
1018 __nr_t read_net_edev(struct stats_net_edev *st_net_edev, __nr_t nr_alloc)
1021 struct stats_net_edev *st_net_edev_i;
1022 static char line[256];
1023 char iface[MAX_IFACE_LEN];
1024 __nr_t dev_read = 0;
1027 if ((fp = fopen(NET_DEV, "r")) == NULL)
1030 while (fgets(line, sizeof(line), fp) != NULL) {
1032 pos = strcspn(line, ":");
1033 if (pos < strlen(line)) {
1035 if (dev_read + 1 > nr_alloc) {
1040 st_net_edev_i = st_net_edev + dev_read++;
1041 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1042 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1043 sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */
1044 sscanf(line + pos + 1, "%*u %*u %llu %llu %llu %llu %*u %*u %*u %*u "
1045 "%llu %llu %llu %llu %llu",
1046 &st_net_edev_i->rx_errors,
1047 &st_net_edev_i->rx_dropped,
1048 &st_net_edev_i->rx_fifo_errors,
1049 &st_net_edev_i->rx_frame_errors,
1050 &st_net_edev_i->tx_errors,
1051 &st_net_edev_i->tx_dropped,
1052 &st_net_edev_i->tx_fifo_errors,
1053 &st_net_edev_i->collisions,
1054 &st_net_edev_i->tx_carrier_errors);
1063 ***************************************************************************
1064 * Read NFS client statistics from /proc/net/rpc/nfs.
1067 * @st_net_nfs Structure where stats will be saved.
1070 * @st_net_nfs Structure with statistics.
1073 * 1 on success, 0 otherwise.
1074 ***************************************************************************
1076 __nr_t read_net_nfs(struct stats_net_nfs *st_net_nfs)
1080 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1082 if ((fp = fopen(NET_RPC_NFS, "r")) == NULL)
1085 memset(st_net_nfs, 0, STATS_NET_NFS_SIZE);
1087 while (fgets(line, sizeof(line), fp) != NULL) {
1089 if (!strncmp(line, "rpc ", 4)) {
1090 sscanf(line + 4, "%u %u",
1091 &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans);
1093 else if (!strncmp(line, "proc3 ", 6)) {
1094 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1095 &getattcnt, &accesscnt, &readcnt, &writecnt);
1097 st_net_nfs->nfs_getattcnt += getattcnt;
1098 st_net_nfs->nfs_accesscnt += accesscnt;
1099 st_net_nfs->nfs_readcnt += readcnt;
1100 st_net_nfs->nfs_writecnt += writecnt;
1102 else if (!strncmp(line, "proc4 ", 6)) {
1103 sscanf(line + 6, "%*u %*u %u %u "
1104 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u",
1105 &readcnt, &writecnt, &accesscnt, &getattcnt);
1107 st_net_nfs->nfs_getattcnt += getattcnt;
1108 st_net_nfs->nfs_accesscnt += accesscnt;
1109 st_net_nfs->nfs_readcnt += readcnt;
1110 st_net_nfs->nfs_writecnt += writecnt;
1119 ***************************************************************************
1120 * Read NFS server statistics from /proc/net/rpc/nfsd.
1123 * @st_net_nfsd Structure where stats will be saved.
1126 * @st_net_nfsd Structure with statistics.
1129 * 1 on success, 0 otherwise.
1130 ***************************************************************************
1132 __nr_t read_net_nfsd(struct stats_net_nfsd *st_net_nfsd)
1136 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1138 if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL)
1141 memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE);
1143 while (fgets(line, sizeof(line), fp) != NULL) {
1145 if (!strncmp(line, "rc ", 3)) {
1146 sscanf(line + 3, "%u %u",
1147 &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses);
1149 else if (!strncmp(line, "net ", 4)) {
1150 sscanf(line + 4, "%u %u %u",
1151 &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt,
1152 &st_net_nfsd->nfsd_nettcpcnt);
1154 else if (!strncmp(line, "rpc ", 4)) {
1155 sscanf(line + 4, "%u %u",
1156 &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad);
1158 else if (!strncmp(line, "proc3 ", 6)) {
1159 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1160 &getattcnt, &accesscnt, &readcnt, &writecnt);
1162 st_net_nfsd->nfsd_getattcnt += getattcnt;
1163 st_net_nfsd->nfsd_accesscnt += accesscnt;
1164 st_net_nfsd->nfsd_readcnt += readcnt;
1165 st_net_nfsd->nfsd_writecnt += writecnt;
1168 else if (!strncmp(line, "proc4ops ", 9)) {
1169 sscanf(line + 9, "%*u %*u %*u %*u %u "
1170 "%*u %*u %*u %*u %*u %u "
1171 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u "
1172 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
1173 &accesscnt, &getattcnt, &readcnt, &writecnt);
1175 st_net_nfsd->nfsd_getattcnt += getattcnt;
1176 st_net_nfsd->nfsd_accesscnt += accesscnt;
1177 st_net_nfsd->nfsd_readcnt += readcnt;
1178 st_net_nfsd->nfsd_writecnt += writecnt;
1187 ***************************************************************************
1188 * Read network sockets statistics from /proc/net/sockstat.
1191 * @st_net_sock Structure where stats will be saved.
1194 * @st_net_sock Structure with statistics.
1197 * 1 on success, 0 otherwise.
1198 ***************************************************************************
1200 __nr_t read_net_sock(struct stats_net_sock *st_net_sock)
1206 if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL)
1209 while (fgets(line, sizeof(line), fp) != NULL) {
1211 if (!strncmp(line, "sockets:", 8)) {
1213 sscanf(line + 14, "%u", &st_net_sock->sock_inuse);
1215 else if (!strncmp(line, "TCP:", 4)) {
1217 sscanf(line + 11, "%u", &st_net_sock->tcp_inuse);
1218 if ((p = strstr(line, "tw")) != NULL) {
1219 sscanf(p + 2, "%u", &st_net_sock->tcp_tw);
1222 else if (!strncmp(line, "UDP:", 4)) {
1224 sscanf(line + 11, "%u", &st_net_sock->udp_inuse);
1226 else if (!strncmp(line, "RAW:", 4)) {
1228 sscanf(line + 11, "%u", &st_net_sock->raw_inuse);
1230 else if (!strncmp(line, "FRAG:", 5)) {
1232 sscanf(line + 12, "%u", &st_net_sock->frag_inuse);
1241 ***************************************************************************
1242 * Read IP network traffic statistics from /proc/net/snmp.
1245 * @st_net_ip Structure where stats will be saved.
1248 * @st_net_ip Structure with statistics.
1251 * 1 on success, 0 otherwise.
1252 ***************************************************************************
1254 __nr_t read_net_ip(struct stats_net_ip *st_net_ip)
1260 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1263 while (fgets(line, sizeof(line), fp) != NULL) {
1265 if (!strncmp(line, "Ip:", 3)) {
1267 sscanf(line + 3, "%*u %*u %llu %*u %*u %llu %*u %*u "
1268 "%llu %llu %*u %*u %*u %llu %llu %*u %llu %*u %llu",
1269 &st_net_ip->InReceives,
1270 &st_net_ip->ForwDatagrams,
1271 &st_net_ip->InDelivers,
1272 &st_net_ip->OutRequests,
1273 &st_net_ip->ReasmReqds,
1274 &st_net_ip->ReasmOKs,
1275 &st_net_ip->FragOKs,
1276 &st_net_ip->FragCreates);
1291 ***************************************************************************
1292 * Read IP network errors statistics from /proc/net/snmp.
1295 * @st_net_eip Structure where stats will be saved.
1298 * @st_net_eip Structure with statistics.
1301 * 1 on success, 0 otherwise.
1302 ***************************************************************************
1304 __nr_t read_net_eip(struct stats_net_eip *st_net_eip)
1310 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1313 while (fgets(line, sizeof(line), fp) != NULL) {
1315 if (!strncmp(line, "Ip:", 3)) {
1317 sscanf(line + 3, "%*u %*u %*u %llu %llu %*u %llu %llu "
1318 "%*u %*u %llu %llu %*u %*u %*u %llu %*u %llu",
1319 &st_net_eip->InHdrErrors,
1320 &st_net_eip->InAddrErrors,
1321 &st_net_eip->InUnknownProtos,
1322 &st_net_eip->InDiscards,
1323 &st_net_eip->OutDiscards,
1324 &st_net_eip->OutNoRoutes,
1325 &st_net_eip->ReasmFails,
1326 &st_net_eip->FragFails);
1341 ***************************************************************************
1342 * Read ICMP network traffic statistics from /proc/net/snmp.
1345 * @st_net_icmp Structure where stats will be saved.
1348 * @st_net_icmp Structure with statistics.
1351 * 1 on success, 0 otherwise.
1352 ***************************************************************************
1354 __nr_t read_net_icmp(struct stats_net_icmp *st_net_icmp)
1358 static char format[256] = "";
1361 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1364 while (fgets(line, sizeof(line), fp) != NULL) {
1366 if (!strncmp(line, "Icmp:", 5)) {
1368 sscanf(line + 5, format,
1369 &st_net_icmp->InMsgs,
1370 &st_net_icmp->InEchos,
1371 &st_net_icmp->InEchoReps,
1372 &st_net_icmp->InTimestamps,
1373 &st_net_icmp->InTimestampReps,
1374 &st_net_icmp->InAddrMasks,
1375 &st_net_icmp->InAddrMaskReps,
1376 &st_net_icmp->OutMsgs,
1377 &st_net_icmp->OutEchos,
1378 &st_net_icmp->OutEchoReps,
1379 &st_net_icmp->OutTimestamps,
1380 &st_net_icmp->OutTimestampReps,
1381 &st_net_icmp->OutAddrMasks,
1382 &st_net_icmp->OutAddrMaskReps);
1387 if (!strlen(format)) {
1388 if (strstr(line, "InCsumErrors")) {
1390 * New format: InCsumErrors field exists at position #3.
1391 * Capture: 1,9,10,11,12,13,14,15,22,23,24,25,26,27.
1393 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u %*u "
1394 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1395 "%*u %*u %lu %lu %lu %lu %lu %lu");
1399 * Old format: InCsumErrors field doesn't exist.
1400 * Capture: 1,8,9,10,11,12,13,14,21,22,23,24,25,26.
1402 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u "
1403 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1404 "%*u %*u %lu %lu %lu %lu %lu %lu");
1417 ***************************************************************************
1418 * Read ICMP network errors statistics from /proc/net/snmp.
1421 * @st_net_eicmp Structure where stats will be saved.
1424 * @st_net_eicmp Structure with statistics.
1427 * 1 on success, 0 otherwise.
1428 ***************************************************************************
1430 __nr_t read_net_eicmp(struct stats_net_eicmp *st_net_eicmp)
1436 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1439 while (fgets(line, sizeof(line), fp) != NULL) {
1441 if (!strncmp(line, "Icmp:", 5)) {
1443 sscanf(line + 5, "%*u %lu %lu %lu %lu %lu %lu %*u %*u "
1444 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu",
1445 &st_net_eicmp->InErrors,
1446 &st_net_eicmp->InDestUnreachs,
1447 &st_net_eicmp->InTimeExcds,
1448 &st_net_eicmp->InParmProbs,
1449 &st_net_eicmp->InSrcQuenchs,
1450 &st_net_eicmp->InRedirects,
1451 &st_net_eicmp->OutErrors,
1452 &st_net_eicmp->OutDestUnreachs,
1453 &st_net_eicmp->OutTimeExcds,
1454 &st_net_eicmp->OutParmProbs,
1455 &st_net_eicmp->OutSrcQuenchs,
1456 &st_net_eicmp->OutRedirects);
1471 ***************************************************************************
1472 * Read TCP network traffic statistics from /proc/net/snmp.
1475 * @st_net_tcp Structure where stats will be saved.
1478 * @st_net_tcp Structure with statistics.
1481 * 1 on success, 0 otherwise.
1482 ***************************************************************************
1484 __nr_t read_net_tcp(struct stats_net_tcp *st_net_tcp)
1490 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1493 while (fgets(line, sizeof(line), fp) != NULL) {
1495 if (!strncmp(line, "Tcp:", 4)) {
1497 sscanf(line + 4, "%*u %*u %*u %*d %lu %lu "
1498 "%*u %*u %*u %lu %lu",
1499 &st_net_tcp->ActiveOpens,
1500 &st_net_tcp->PassiveOpens,
1501 &st_net_tcp->InSegs,
1502 &st_net_tcp->OutSegs);
1517 ***************************************************************************
1518 * Read TCP network errors statistics from /proc/net/snmp.
1521 * @st_net_etcp Structure where stats will be saved.
1524 * @st_net_etcp Structure with statistics.
1527 * 1 on success, 0 otherwise.
1528 ***************************************************************************
1530 __nr_t read_net_etcp(struct stats_net_etcp *st_net_etcp)
1536 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1539 while (fgets(line, sizeof(line), fp) != NULL) {
1541 if (!strncmp(line, "Tcp:", 4)) {
1543 sscanf(line + 4, "%*u %*u %*u %*d %*u %*u "
1544 "%lu %lu %*u %*u %*u %lu %lu %lu",
1545 &st_net_etcp->AttemptFails,
1546 &st_net_etcp->EstabResets,
1547 &st_net_etcp->RetransSegs,
1548 &st_net_etcp->InErrs,
1549 &st_net_etcp->OutRsts);
1564 ***************************************************************************
1565 * Read UDP network traffic statistics from /proc/net/snmp.
1568 * @st_net_udp Structure where stats will be saved.
1571 * @st_net_udp Structure with statistics.
1574 * 1 on success, 0 otherwise.
1575 ***************************************************************************
1577 __nr_t read_net_udp(struct stats_net_udp *st_net_udp)
1583 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1586 while (fgets(line, sizeof(line), fp) != NULL) {
1588 if (!strncmp(line, "Udp:", 4)) {
1590 sscanf(line + 4, "%lu %lu %lu %lu",
1591 &st_net_udp->InDatagrams,
1592 &st_net_udp->NoPorts,
1593 &st_net_udp->InErrors,
1594 &st_net_udp->OutDatagrams);
1609 ***************************************************************************
1610 * Read IPv6 network sockets statistics from /proc/net/sockstat6.
1613 * @st_net_sock6 Structure where stats will be saved.
1616 * @st_net_sock6 Structure with statistics.
1619 * 1 on success, 0 otherwise.
1620 ***************************************************************************
1622 __nr_t read_net_sock6(struct stats_net_sock6 *st_net_sock6)
1627 if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL)
1630 while (fgets(line, sizeof(line), fp) != NULL) {
1632 if (!strncmp(line, "TCP6:", 5)) {
1634 sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse);
1636 else if (!strncmp(line, "UDP6:", 5)) {
1638 sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse);
1640 else if (!strncmp(line, "RAW6:", 5)) {
1641 /* IPv6 RAW sockets */
1642 sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse);
1644 else if (!strncmp(line, "FRAG6:", 6)) {
1645 /* IPv6 FRAGments */
1646 sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse);
1655 ***************************************************************************
1656 * Read IPv6 network traffic statistics from /proc/net/snmp6.
1659 * @st_net_ip6 Structure where stats will be saved.
1662 * @st_net_ip6 Structure with statistics.
1665 * 1 on success, 0 otherwise.
1666 ***************************************************************************
1668 __nr_t read_net_ip6(struct stats_net_ip6 *st_net_ip6)
1673 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1676 while (fgets(line, sizeof(line), fp) != NULL) {
1678 if (!strncmp(line, "Ip6InReceives ", 14)) {
1679 sscanf(line + 14, "%llu", &st_net_ip6->InReceives6);
1681 else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) {
1682 sscanf(line + 20, "%llu", &st_net_ip6->OutForwDatagrams6);
1684 else if (!strncmp(line, "Ip6InDelivers ", 14)) {
1685 sscanf(line + 14, "%llu", &st_net_ip6->InDelivers6);
1687 else if (!strncmp(line, "Ip6OutRequests ", 15)) {
1688 sscanf(line + 15, "%llu", &st_net_ip6->OutRequests6);
1690 else if (!strncmp(line, "Ip6ReasmReqds ", 14)) {
1691 sscanf(line + 14, "%llu", &st_net_ip6->ReasmReqds6);
1693 else if (!strncmp(line, "Ip6ReasmOKs ", 12)) {
1694 sscanf(line + 12, "%llu", &st_net_ip6->ReasmOKs6);
1696 else if (!strncmp(line, "Ip6InMcastPkts ", 15)) {
1697 sscanf(line + 15, "%llu", &st_net_ip6->InMcastPkts6);
1699 else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) {
1700 sscanf(line + 16, "%llu", &st_net_ip6->OutMcastPkts6);
1702 else if (!strncmp(line, "Ip6FragOKs ", 11)) {
1703 sscanf(line + 11, "%llu", &st_net_ip6->FragOKs6);
1705 else if (!strncmp(line, "Ip6FragCreates ", 15)) {
1706 sscanf(line + 15, "%llu", &st_net_ip6->FragCreates6);
1715 ***************************************************************************
1716 * Read IPv6 network errors statistics from /proc/net/snmp6.
1719 * @st_net_eip6 Structure where stats will be saved.
1722 * @st_net_eip6 Structure with statistics.
1725 * 1 on success, 0 otherwise.
1726 ***************************************************************************
1728 __nr_t read_net_eip6(struct stats_net_eip6 *st_net_eip6)
1733 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1736 while (fgets(line, sizeof(line), fp) != NULL) {
1738 if (!strncmp(line, "Ip6InHdrErrors ", 15)) {
1739 sscanf(line + 15, "%llu", &st_net_eip6->InHdrErrors6);
1741 else if (!strncmp(line, "Ip6InAddrErrors ", 16)) {
1742 sscanf(line + 16, "%llu", &st_net_eip6->InAddrErrors6);
1744 else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) {
1745 sscanf(line + 19, "%llu", &st_net_eip6->InUnknownProtos6);
1747 else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) {
1748 sscanf(line + 18, "%llu", &st_net_eip6->InTooBigErrors6);
1750 else if (!strncmp(line, "Ip6InDiscards ", 14)) {
1751 sscanf(line + 14, "%llu", &st_net_eip6->InDiscards6);
1753 else if (!strncmp(line, "Ip6OutDiscards ", 15)) {
1754 sscanf(line + 15, "%llu", &st_net_eip6->OutDiscards6);
1756 else if (!strncmp(line, "Ip6InNoRoutes ", 14)) {
1757 sscanf(line + 14, "%llu", &st_net_eip6->InNoRoutes6);
1759 else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) {
1760 sscanf(line + 15, "%llu", &st_net_eip6->OutNoRoutes6);
1762 else if (!strncmp(line, "Ip6ReasmFails ", 14)) {
1763 sscanf(line + 14, "%llu", &st_net_eip6->ReasmFails6);
1765 else if (!strncmp(line, "Ip6FragFails ", 13)) {
1766 sscanf(line + 13, "%llu", &st_net_eip6->FragFails6);
1768 else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) {
1769 sscanf(line + 19, "%llu", &st_net_eip6->InTruncatedPkts6);
1778 ***************************************************************************
1779 * Read ICMPv6 network traffic statistics from /proc/net/snmp6.
1782 * @st_net_icmp6 Structure where stats will be saved.
1785 * @st_net_icmp6 Structure with statistics.
1788 * 1 on success, 0 otherwise.
1789 ***************************************************************************
1791 __nr_t read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6)
1796 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1799 while (fgets(line, sizeof(line), fp) != NULL) {
1801 if (!strncmp(line, "Icmp6InMsgs ", 12)) {
1802 sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6);
1804 else if (!strncmp(line, "Icmp6OutMsgs ", 13)) {
1805 sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6);
1807 else if (!strncmp(line, "Icmp6InEchos ", 13)) {
1808 sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6);
1810 else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) {
1811 sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6);
1813 else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) {
1814 sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6);
1816 else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) {
1817 sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6);
1819 else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) {
1820 sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6);
1822 else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) {
1823 sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6);
1825 else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) {
1826 sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6);
1828 else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) {
1829 sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6);
1831 else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) {
1832 sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6);
1834 else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) {
1835 sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6);
1837 else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) {
1838 sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6);
1840 else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) {
1841 sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6);
1843 else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) {
1844 sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6);
1846 else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) {
1847 sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6);
1849 else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) {
1850 sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6);
1859 ***************************************************************************
1860 * Read ICMPv6 network errors statistics from /proc/net/snmp6.
1863 * @st_net_eicmp6 Structure where stats will be saved.
1866 * @st_net_eicmp6 Structure with statistics.
1869 * 1 on success, 0 otherwise.
1870 ***************************************************************************
1872 __nr_t read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6)
1877 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1880 while (fgets(line, sizeof(line), fp) != NULL) {
1882 if (!strncmp(line, "Icmp6InErrors ", 14)) {
1883 sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6);
1885 else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) {
1886 sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6);
1888 else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) {
1889 sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6);
1891 else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) {
1892 sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6);
1894 else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) {
1895 sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6);
1897 else if (!strncmp(line, "Icmp6InParmProblems ", 20)) {
1898 sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6);
1900 else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) {
1901 sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6);
1903 else if (!strncmp(line, "Icmp6InRedirects ", 17)) {
1904 sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6);
1906 else if (!strncmp(line, "Icmp6OutRedirects ", 18)) {
1907 sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6);
1909 else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) {
1910 sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6);
1912 else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) {
1913 sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6);
1922 ***************************************************************************
1923 * Read UDPv6 network traffic statistics from /proc/net/snmp6.
1926 * @st_net_udp6 Structure where stats will be saved.
1929 * @st_net_udp6 Structure with statistics.
1932 * 1 on success, 0 otherwise.
1933 ***************************************************************************
1935 __nr_t read_net_udp6(struct stats_net_udp6 *st_net_udp6)
1940 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1943 while (fgets(line, sizeof(line), fp) != NULL) {
1945 if (!strncmp(line, "Udp6InDatagrams ", 16)) {
1946 sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6);
1948 else if (!strncmp(line, "Udp6OutDatagrams ", 17)) {
1949 sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6);
1951 else if (!strncmp(line, "Udp6NoPorts ", 12)) {
1952 sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6);
1954 else if (!strncmp(line, "Udp6InErrors ", 13)) {
1955 sscanf(line + 13, "%lu", &st_net_udp6->InErrors6);
1964 ***************************************************************************
1965 * Read CPU frequency statistics.
1968 * @st_pwr_cpufreq Structure where stats will be saved.
1969 * @nr_alloc Total number of structures allocated. Value is >= 1.
1972 * @st_pwr_cpufreq Structure with statistics.
1975 * Highest CPU number for which statistics have been read.
1976 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
1977 * Or -1 if the buffer was too small and needs to be reallocated.
1978 ***************************************************************************
1980 __nr_t read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, __nr_t nr_alloc)
1983 struct stats_pwr_cpufreq *st_pwr_cpufreq_i;
1986 __nr_t cpu_read = 1; /* For CPU "all" */
1987 unsigned int proc_nr = 0, ifreq, dfreq;
1989 if ((fp = fopen(CPUINFO, "r")) == NULL)
1992 st_pwr_cpufreq->cpufreq = 0;
1994 while (fgets(line, sizeof(line), fp) != NULL) {
1996 if (!strncmp(line, "processor\t", 10)) {
1997 sscanf(strchr(line, ':') + 1, "%u", &proc_nr);
1999 if (proc_nr + 2 > nr_alloc) {
2005 /* Entry in /proc/cpuinfo is different between Intel and Power architectures */
2006 else if (!strncmp(line, "cpu MHz\t", 8) ||
2007 !strncmp(line, "clock\t", 6)) {
2008 sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq);
2010 /* Save current CPU frequency */
2011 st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nr + 1;
2012 st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10;
2014 /* Also save it to compute an average CPU frequency */
2015 st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq;
2018 if (proc_nr + 2 > cpu_read) {
2019 cpu_read = proc_nr + 2;
2027 /* Compute average CPU frequency for this machine */
2028 st_pwr_cpufreq->cpufreq /= nr;
2034 ***************************************************************************
2035 * Read hugepages statistics from /proc/meminfo.
2038 * @st_huge Structure where stats will be saved.
2041 * @st_huge Structure with statistics.
2044 * 1 on success, 0 otherwise.
2045 ***************************************************************************
2047 __nr_t read_meminfo_huge(struct stats_huge *st_huge)
2051 unsigned long szhkb = 0;
2053 if ((fp = fopen(MEMINFO, "r")) == NULL)
2056 while (fgets(line, sizeof(line), fp) != NULL) {
2058 if (!strncmp(line, "HugePages_Total:", 16)) {
2059 /* Read the total number of huge pages */
2060 sscanf(line + 16, "%lu", &st_huge->tlhkb);
2062 else if (!strncmp(line, "HugePages_Free:", 15)) {
2063 /* Read the number of free huge pages */
2064 sscanf(line + 15, "%lu", &st_huge->frhkb);
2066 else if (!strncmp(line, "Hugepagesize:", 13)) {
2067 /* Read the default size of a huge page in kB */
2068 sscanf(line + 13, "%lu", &szhkb);
2074 /* We want huge pages stats in kB and not expressed in a number of pages */
2075 st_huge->tlhkb *= szhkb;
2076 st_huge->frhkb *= szhkb;
2081 ***************************************************************************
2082 * Read CPU average frequencies statistics.
2085 * @st_pwr_wghfreq Structure where stats will be saved.
2086 * @cpu_nr CPU number for which time_in_state date will be read.
2087 * @nbr Total number of states (frequencies).
2090 * @st_pwr_wghfreq Structure with statistics.
2093 * 1 on success, 0 otherwise.
2094 ***************************************************************************
2096 int read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr)
2099 struct stats_pwr_wghfreq *st_pwr_wghfreq_j;
2100 char filename[MAX_PF_NAME];
2104 unsigned long long time_in_state;
2106 snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s",
2107 SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE);
2108 if ((fp = fopen(filename, "r")) == NULL)
2111 while (fgets(line, sizeof(line), fp) != NULL) {
2113 sscanf(line, "%lu %llu", &freq, &time_in_state);
2116 /* Save current frequency and time */
2117 st_pwr_wghfreq_j = st_pwr_wghfreq + j;
2118 st_pwr_wghfreq_j->freq = freq;
2119 st_pwr_wghfreq_j->time_in_state = time_in_state;
2129 ***************************************************************************
2130 * Read weighted CPU frequency statistics.
2133 * @st_pwr_wghfreq Structure where stats will be saved.
2134 * @nr_alloc Total number of structures allocated. Value is >= 0.
2135 * @nr2 Number of sub-items allocated per structure.
2138 * @st_pwr_wghfreq Structure with statistics.
2141 * Number of CPU for which statistics have been read.
2142 * 1 means CPU "all", 2 means CPU "all" and 0, etc.
2143 * Or -1 if the buffer was to small and needs to be reallocated.
2144 ***************************************************************************
2146 __nr_t read_cpu_wghfreq(struct stats_pwr_wghfreq *st_pwr_wghfreq, __nr_t nr_alloc,
2149 __nr_t cpu_read = 0;
2151 struct stats_pwr_wghfreq *st_pwr_wghfreq_i, *st_pwr_wghfreq_j, *st_pwr_wghfreq_all_j;
2154 if (cpu_read + 2 > nr_alloc)
2157 /* Read current CPU time-in-state data */
2158 st_pwr_wghfreq_i = st_pwr_wghfreq + (cpu_read + 1) * nr2;
2159 if (!read_time_in_state(st_pwr_wghfreq_i, cpu_read, nr2))
2162 /* Also save data for CPU 'all' */
2163 for (j = 0; j < nr2; j++) {
2164 st_pwr_wghfreq_j = st_pwr_wghfreq_i + j; /* CPU #cpu, state #j */
2165 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2167 /* Assume that possible frequencies are the same for all CPUs */
2168 st_pwr_wghfreq_all_j->freq = st_pwr_wghfreq_j->freq;
2170 st_pwr_wghfreq_all_j->time_in_state += st_pwr_wghfreq_j->time_in_state;
2177 for (j = 0; j < nr2; j++) {
2178 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2179 st_pwr_wghfreq_all_j->time_in_state /= cpu_read;
2182 return cpu_read + 1; /* For CPU "all" */
2189 ***************************************************************************
2190 * Read current USB device data.
2193 * @st_pwr_usb Structure where stats will be saved.
2194 * @usb_device File name for current USB device.
2197 * @st_pwr_usb Structure with statistics.
2198 ***************************************************************************
2200 void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
2205 char filename[MAX_PF_NAME];
2207 /* Get USB device bus number */
2208 sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
2210 /* Read USB device vendor ID */
2211 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2212 SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
2213 if ((fp = fopen(filename, "r")) != NULL) {
2214 rc = fscanf(fp, "%x",
2215 &st_pwr_usb->vendor_id);
2218 st_pwr_usb->vendor_id = 0;
2222 /* Read USB device product ID */
2223 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2224 SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
2225 if ((fp = fopen(filename, "r")) != NULL) {
2226 rc = fscanf(fp, "%x",
2227 &st_pwr_usb->product_id);
2230 st_pwr_usb->product_id = 0;
2234 /* Read USB device max power consumption */
2235 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2236 SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
2237 if ((fp = fopen(filename, "r")) != NULL) {
2238 rc = fscanf(fp, "%u",
2239 &st_pwr_usb->bmaxpower);
2242 st_pwr_usb->bmaxpower = 0;
2246 /* Read USB device manufacturer */
2247 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2248 SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
2249 if ((fp = fopen(filename, "r")) != NULL) {
2250 rs = fgets(st_pwr_usb->manufacturer,
2251 MAX_MANUF_LEN - 1, fp);
2254 (l = strlen(st_pwr_usb->manufacturer)) > 0) {
2255 /* Remove trailing CR */
2256 st_pwr_usb->manufacturer[l - 1] = '\0';
2260 /* Read USB device product */
2261 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2262 SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
2263 if ((fp = fopen(filename, "r")) != NULL) {
2264 rs = fgets(st_pwr_usb->product,
2265 MAX_PROD_LEN - 1, fp);
2268 (l = strlen(st_pwr_usb->product)) > 0) {
2269 /* Remove trailing CR */
2270 st_pwr_usb->product[l - 1] = '\0';
2276 ***************************************************************************
2277 * Read USB devices statistics.
2280 * @st_pwr_usb Structure where stats will be saved.
2281 * @nr_alloc Total number of structures allocated. Value is >= 0.
2284 * @st_pwr_usb Structure with statistics.
2287 * Number of USB devices read, or -1 if the buffer was too small and
2288 * needs to be reallocated.
2289 ***************************************************************************
2291 __nr_t read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, __nr_t nr_alloc)
2295 struct stats_pwr_usb *st_pwr_usb_i;
2296 __nr_t usb_read = 0;
2298 /* Open relevant /sys directory */
2299 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
2302 /* Get current file entry */
2303 while ((drd = readdir(dir)) != NULL) {
2305 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
2307 if (usb_read + 1 > nr_alloc) {
2312 /* Read current USB device data */
2313 st_pwr_usb_i = st_pwr_usb + usb_read++;
2314 read_usb_stats(st_pwr_usb_i, drd->d_name);
2318 /* Close directory */
2324 ***************************************************************************
2325 * Read filesystems statistics.
2328 * @st_filesystem Structure where stats will be saved.
2329 * @nr_alloc Total number of structures allocated. Value is >= 0.
2332 * @st_filesystem Structure with statistics.
2335 * Number of filesystems read, or -1 if the buffer was too small and
2336 * needs to be reallocated.
2337 ***************************************************************************
2339 __nr_t read_filesystem(struct stats_filesystem *st_filesystem, __nr_t nr_alloc)
2342 char line[512], fs_name[128], mountp[256];
2343 int skip = 0, skip_next = 0;
2346 struct stats_filesystem *st_filesystem_i;
2349 if ((fp = fopen(MTAB, "r")) == NULL)
2352 while (fgets(line, sizeof(line), fp) != NULL) {
2354 * Ignore line if the preceding line did not contain '\n'.
2355 * (Some very long lines may be found for instance when
2356 * overlay2 filesystem with docker is used).
2359 skip_next = (strchr(line, '\n') == NULL);
2363 if (line[0] == '/') {
2364 /* Find field separator position */
2365 pos = strchr(line, ' ');
2369 /* Read current filesystem name */
2370 sscanf(line, "%127s", fs_name);
2372 * And now read the corresponding mount point.
2373 * Read fs name and mount point in two distinct operations.
2374 * Indeed, if fs name length is greater than 127 chars,
2375 * previous scanf() will read only the first 127 chars, and
2376 * mount point name will be read using the remaining chars
2377 * from the fs name. This will result in a bogus name
2378 * and following statvfs() function will always fail.
2380 sscanf(pos + 1, "%255s", mountp);
2382 /* Replace octal codes */
2386 * It's important to have read the whole mount point name
2387 * for statvfs() to work properly (see above).
2389 if ((statvfs(mountp, &buf) < 0) || (!buf.f_blocks))
2392 if (fs_read + 1 > nr_alloc) {
2397 st_filesystem_i = st_filesystem + fs_read++;
2398 st_filesystem_i->f_blocks = (unsigned long long) buf.f_blocks * (unsigned long long) buf.f_frsize;
2399 st_filesystem_i->f_bfree = (unsigned long long) buf.f_bfree * (unsigned long long) buf.f_frsize;
2400 st_filesystem_i->f_bavail = (unsigned long long) buf.f_bavail * (unsigned long long) buf.f_frsize;
2401 st_filesystem_i->f_files = (unsigned long long) buf.f_files;
2402 st_filesystem_i->f_ffree = (unsigned long long) buf.f_ffree;
2403 strncpy(st_filesystem_i->fs_name, fs_name, MAX_FS_LEN);
2404 st_filesystem_i->fs_name[MAX_FS_LEN - 1] = '\0';
2405 strncpy(st_filesystem_i->mountp, mountp, MAX_FS_LEN);
2406 st_filesystem_i->mountp[MAX_FS_LEN - 1] = '\0';
2415 ***************************************************************************
2416 * Read Fibre Channel HBA statistics.
2419 * @st_fc Structure where stats will be saved.
2420 * @nr_alloc Total number of structures allocated. Value is >= 0.
2423 * @st_fc Structure with statistics.
2426 * Number of FC hosts read, or -1 if the buffer was too small and needs to
2428 ***************************************************************************
2430 __nr_t read_fchost(struct stats_fchost *st_fc, __nr_t nr_alloc)
2435 struct stats_fchost *st_fc_i;
2436 __nr_t fch_read = 0;
2437 char fcstat_filename[MAX_PF_NAME];
2439 unsigned long rx_frames, tx_frames, rx_words, tx_words;
2441 /* Each host, if present, will have its own hostX entry within SYSFS_FCHOST */
2442 if ((dir = opendir(SYSFS_FCHOST)) == NULL)
2443 return 0; /* No FC hosts */
2446 * Read each of the counters via sysfs, where they are
2447 * returned as hex values (e.g. 0x72400).
2449 while ((drd = readdir(dir)) != NULL) {
2450 rx_frames = tx_frames = rx_words = tx_words = 0;
2452 if (!strncmp(drd->d_name, "host", 4)) {
2454 if (fch_read + 1 > nr_alloc) {
2459 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_FRAMES,
2460 SYSFS_FCHOST, drd->d_name);
2461 if ((fp = fopen(fcstat_filename, "r"))) {
2462 if (fgets(line, sizeof(line), fp)) {
2463 sscanf(line, "%lx", &rx_frames);
2468 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_FRAMES,
2469 SYSFS_FCHOST, drd->d_name);
2470 if ((fp = fopen(fcstat_filename, "r"))) {
2471 if (fgets(line, sizeof(line), fp)) {
2472 sscanf(line, "%lx", &tx_frames);
2477 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_WORDS,
2478 SYSFS_FCHOST, drd->d_name);
2479 if ((fp = fopen(fcstat_filename, "r"))) {
2480 if (fgets(line, sizeof(line), fp)) {
2481 sscanf(line, "%lx", &rx_words);
2486 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_WORDS,
2487 SYSFS_FCHOST, drd->d_name);
2488 if ((fp = fopen(fcstat_filename, "r"))) {
2489 if (fgets(line, sizeof(line), fp)) {
2490 sscanf(line, "%lx", &tx_words);
2495 st_fc_i = st_fc + fch_read++;
2496 st_fc_i->f_rxframes = rx_frames;
2497 st_fc_i->f_txframes = tx_frames;
2498 st_fc_i->f_rxwords = rx_words;
2499 st_fc_i->f_txwords = tx_words;
2500 strncpy(st_fc_i->fchost_name, drd->d_name, MAX_FCH_LEN);
2501 st_fc_i->fchost_name[MAX_FCH_LEN - 1] = '\0';
2510 ***************************************************************************
2511 * Read softnet statistics.
2514 * @st_softnet Structure where stats will be saved.
2515 * @nr_alloc Total number of structures allocated. Value is >= 0.
2518 * @st_softnet Structure with statistics.
2521 * Number of CPU for which statistics have been read.
2522 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
2523 * Or -1 if the buffer was too small and needs to be reallocated.
2524 ***************************************************************************
2526 __nr_t read_softnet(struct stats_softnet *st_softnet, __nr_t nr_alloc)
2529 struct stats_softnet *st_softnet_i;
2531 __nr_t cpu_read = 1; /* For CPU "all" */
2533 /* Open /proc/net/softnet_stat file */
2534 if ((fp = fopen(NET_SOFTNET, "r")) == NULL)
2538 * Init a structure that will contain the values for CPU "all".
2539 * CPU "all" doesn't exist in /proc/net/softnet_stat file, so
2540 * we compute its values as the sum of the values of each CPU.
2542 memset(st_softnet, 0, sizeof(struct stats_softnet));
2544 while (fgets(line, sizeof(line), fp) != NULL) {
2546 if (cpu_read + 1 > nr_alloc) {
2551 st_softnet_i = st_softnet + cpu_read++;
2552 sscanf(line, "%x %x %x %*x %*x %*x %*x %*x %*x %x %x",
2553 &st_softnet_i->processed,
2554 &st_softnet_i->dropped,
2555 &st_softnet_i->time_squeeze,
2556 &st_softnet_i->received_rps,
2557 &st_softnet_i->flow_limit);
2559 st_softnet->processed += st_softnet_i->processed;
2560 st_softnet->dropped += st_softnet_i->dropped;
2561 st_softnet->time_squeeze += st_softnet_i->time_squeeze;
2562 st_softnet->received_rps += st_softnet_i->received_rps;
2563 st_softnet->flow_limit += st_softnet_i->flow_limit;
2570 /*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
2571 #endif /* SOURCE_SADC */