2 * rd_stats.c: Read system statistics
3 * (C) 1999-2012 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 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
19 ***************************************************************************
28 #include <sys/types.h>
39 #define _(string) gettext(string)
41 #define _(string) (string)
45 ***************************************************************************
46 * Read CPU statistics and machine uptime.
49 * @st_cpu Structure where stats will be saved.
50 * @nbr Total number of CPU (including cpu "all").
53 * @st_cpu Structure with statistics.
54 * @uptime Machine uptime multiplied by the number of processors.
55 * @uptime0 Machine uptime. Filled only if previously set to zero.
56 ***************************************************************************
58 void read_stat_cpu(struct stats_cpu *st_cpu, int nbr,
59 unsigned long long *uptime, unsigned long long *uptime0)
62 struct stats_cpu *st_cpu_i;
67 if ((fp = fopen(STAT, "r")) == NULL) {
68 fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
72 while (fgets(line, 8192, fp) != NULL) {
74 if (!strncmp(line, "cpu ", 4)) {
77 * All the fields don't necessarily exist,
78 * depending on the kernel version used.
80 memset(st_cpu, 0, STATS_CPU_SIZE);
83 * Read the number of jiffies spent in the different modes
84 * (user, nice, etc.) among all proc. CPU usage is not reduced
85 * to one processor to avoid rounding problems.
87 sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
97 &st_cpu->cpu_guest_nice);
100 * Compute the uptime of the system in jiffies (1/100ths of a second
102 * Machine uptime is multiplied by the number of processors here.
104 * NB: Don't add cpu_guest/cpu_guest_nice because cpu_user/cpu_nice
105 * already include them.
107 *uptime = st_cpu->cpu_user + st_cpu->cpu_nice +
108 st_cpu->cpu_sys + st_cpu->cpu_idle +
109 st_cpu->cpu_iowait + st_cpu->cpu_hardirq +
110 st_cpu->cpu_steal + st_cpu->cpu_softirq;
113 else if (!strncmp(line, "cpu", 3)) {
115 /* All the fields don't necessarily exist */
116 memset(&sc, 0, STATS_CPU_SIZE);
118 * Read the number of jiffies spent in the different modes
119 * (user, nice, etc) for current proc.
120 * This is done only on SMP machines.
122 sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
135 if (proc_nb < (nbr - 1)) {
136 st_cpu_i = st_cpu + proc_nb + 1;
140 * else additional CPUs have been dynamically registered
144 if (!proc_nb && !*uptime0) {
146 * Compute uptime reduced to one proc using proc#0.
147 * Done if /proc/uptime was unavailable.
149 * NB: Don't add cpu_guest/cpu_guest_nice because cpu_user/cpu_nice
150 * already include them.
152 *uptime0 = sc.cpu_user + sc.cpu_nice +
153 sc.cpu_sys + sc.cpu_idle +
154 sc.cpu_iowait + sc.cpu_steal +
155 sc.cpu_hardirq + sc.cpu_softirq;
165 ***************************************************************************
166 * Read processes (tasks) creation and context switches statistics
170 * @st_pcsw Structure where stats will be saved.
173 * @st_pcsw Structure with statistics.
174 ***************************************************************************
176 void read_stat_pcsw(struct stats_pcsw *st_pcsw)
181 if ((fp = fopen(STAT, "r")) == NULL)
184 while (fgets(line, 8192, fp) != NULL) {
186 if (!strncmp(line, "ctxt ", 5)) {
187 /* Read number of context switches */
188 sscanf(line + 5, "%llu", &st_pcsw->context_switch);
191 else if (!strncmp(line, "processes ", 10)) {
192 /* Read number of processes created since system boot */
193 sscanf(line + 10, "%lu", &st_pcsw->processes);
201 ***************************************************************************
202 * Read interrupts statistics from /proc/stat.
205 * @st_irq Structure where stats will be saved.
206 * @nbr Number of interrupts to read, including the total number
210 * @st_irq Structure with statistics.
211 ***************************************************************************
213 void read_stat_irq(struct stats_irq *st_irq, int nbr)
216 struct stats_irq *st_irq_i;
220 if ((fp = fopen(STAT, "r")) == NULL)
223 while (fgets(line, 8192, fp) != NULL) {
225 if (!strncmp(line, "intr ", 5)) {
226 /* Read total number of interrupts received since system boot */
227 sscanf(line + 5, "%llu", &st_irq->irq_nr);
228 pos = strcspn(line + 5, " ") + 5;
230 for (i = 1; i < nbr; i++) {
231 st_irq_i = st_irq + i;
232 sscanf(line + pos, " %llu", &st_irq_i->irq_nr);
233 pos += strcspn(line + pos + 1, " ") + 1;
242 ***************************************************************************
243 * Read queue and load statistics from /proc/loadavg and /proc/stat.
246 * @st_queue Structure where stats will be saved.
249 * @st_queue Structure with statistics.
250 ***************************************************************************
252 void read_loadavg(struct stats_queue *st_queue)
258 if ((fp = fopen(LOADAVG, "r")) == NULL)
261 /* Read load averages and queue length */
262 fscanf(fp, "%d.%d %d.%d %d.%d %ld/%d %*d\n",
263 &load_tmp[0], &st_queue->load_avg_1,
264 &load_tmp[1], &st_queue->load_avg_5,
265 &load_tmp[2], &st_queue->load_avg_15,
266 &st_queue->nr_running,
267 &st_queue->nr_threads);
271 st_queue->load_avg_1 += load_tmp[0] * 100;
272 st_queue->load_avg_5 += load_tmp[1] * 100;
273 st_queue->load_avg_15 += load_tmp[2] * 100;
275 if (st_queue->nr_running) {
276 /* Do not take current process into account */
277 st_queue->nr_running--;
280 /* Read nr of tasks blocked from /proc/stat */
281 if ((fp = fopen(STAT, "r")) == NULL)
284 while (fgets(line, 8192, fp) != NULL) {
286 if (!strncmp(line, "procs_blocked ", 14)) {
287 /* Read number of processes blocked */
288 sscanf(line + 14, "%lu", &st_queue->procs_blocked);
297 ***************************************************************************
298 * Read memory statistics from /proc/meminfo.
301 * @st_memory Structure where stats will be saved.
304 * @st_memory Structure with statistics.
305 ***************************************************************************
307 void read_meminfo(struct stats_memory *st_memory)
312 if ((fp = fopen(MEMINFO, "r")) == NULL)
315 while (fgets(line, 128, fp) != NULL) {
317 if (!strncmp(line, "MemTotal:", 9)) {
318 /* Read the total amount of memory in kB */
319 sscanf(line + 9, "%lu", &st_memory->tlmkb);
321 else if (!strncmp(line, "MemFree:", 8)) {
322 /* Read the amount of free memory in kB */
323 sscanf(line + 8, "%lu", &st_memory->frmkb);
325 else if (!strncmp(line, "Buffers:", 8)) {
326 /* Read the amount of buffered memory in kB */
327 sscanf(line + 8, "%lu", &st_memory->bufkb);
329 else if (!strncmp(line, "Cached:", 7)) {
330 /* Read the amount of cached memory in kB */
331 sscanf(line + 7, "%lu", &st_memory->camkb);
333 else if (!strncmp(line, "SwapCached:", 11)) {
334 /* Read the amount of cached swap in kB */
335 sscanf(line + 11, "%lu", &st_memory->caskb);
337 else if (!strncmp(line, "Active:", 7)) {
338 /* Read the amount of active memory in kB */
339 sscanf(line + 7, "%lu", &st_memory->activekb);
341 else if (!strncmp(line, "Inactive:", 9)) {
342 /* Read the amount of inactive memory in kB */
343 sscanf(line + 9, "%lu", &st_memory->inactkb);
345 else if (!strncmp(line, "SwapTotal:", 10)) {
346 /* Read the total amount of swap memory in kB */
347 sscanf(line + 10, "%lu", &st_memory->tlskb);
349 else if (!strncmp(line, "SwapFree:", 9)) {
350 /* Read the amount of free swap memory in kB */
351 sscanf(line + 9, "%lu", &st_memory->frskb);
353 else if (!strncmp(line, "Committed_AS:", 13)) {
354 /* Read the amount of commited memory in kB */
355 sscanf(line + 13, "%lu", &st_memory->comkb);
363 ***************************************************************************
364 * Read swapping statistics from /proc/vmstat.
367 * @st_swap Structure where stats will be saved.
370 * @st_swap Structure with statistics.
371 ***************************************************************************
373 void read_vmstat_swap(struct stats_swap *st_swap)
378 if ((fp = fopen(VMSTAT, "r")) == NULL)
381 while (fgets(line, 128, fp) != NULL) {
383 if (!strncmp(line, "pswpin ", 7)) {
384 /* Read number of swap pages brought in */
385 sscanf(line + 7, "%lu", &st_swap->pswpin);
387 else if (!strncmp(line, "pswpout ", 8)) {
388 /* Read number of swap pages brought out */
389 sscanf(line + 8, "%lu", &st_swap->pswpout);
397 ***************************************************************************
398 * Read paging statistics from /proc/vmstat.
401 * @st_paging Structure where stats will be saved.
404 * @st_paging Structure with statistics.
405 ***************************************************************************
407 void read_vmstat_paging(struct stats_paging *st_paging)
413 if ((fp = fopen(VMSTAT, "r")) == NULL)
416 st_paging->pgsteal = 0;
417 st_paging->pgscan_kswapd = st_paging->pgscan_direct = 0;
419 while (fgets(line, 128, fp) != NULL) {
421 if (!strncmp(line, "pgpgin ", 7)) {
422 /* Read number of pages the system paged in */
423 sscanf(line + 7, "%lu", &st_paging->pgpgin);
425 else if (!strncmp(line, "pgpgout ", 8)) {
426 /* Read number of pages the system paged out */
427 sscanf(line + 8, "%lu", &st_paging->pgpgout);
429 else if (!strncmp(line, "pgfault ", 8)) {
430 /* Read number of faults (major+minor) made by the system */
431 sscanf(line + 8, "%lu", &st_paging->pgfault);
433 else if (!strncmp(line, "pgmajfault ", 11)) {
434 /* Read number of faults (major only) made by the system */
435 sscanf(line + 11, "%lu", &st_paging->pgmajfault);
437 else if (!strncmp(line, "pgfree ", 7)) {
438 /* Read number of pages freed by the system */
439 sscanf(line + 7, "%lu", &st_paging->pgfree);
441 else if (!strncmp(line, "pgsteal_", 8)) {
442 /* Read number of pages stolen by the system */
443 sscanf(strchr(line, ' '), "%lu", &pgtmp);
444 st_paging->pgsteal += pgtmp;
446 else if (!strncmp(line, "pgscan_kswapd_", 14)) {
447 /* Read number of pages scanned by the kswapd daemon */
448 sscanf(strchr(line, ' '), "%lu", &pgtmp);
449 st_paging->pgscan_kswapd += pgtmp;
451 else if (!strncmp(line, "pgscan_direct_", 14)) {
452 /* Read number of pages scanned directly */
453 sscanf(strchr(line, ' '), "%lu", &pgtmp);
454 st_paging->pgscan_direct += pgtmp;
462 ***************************************************************************
463 * Read I/O and transfer rates statistics from /proc/diskstats.
466 * @st_io Structure where stats will be saved.
469 * @st_io Structure with statistics.
470 ***************************************************************************
472 void read_diskstats_io(struct stats_io *st_io)
476 char dev_name[MAX_NAME_LEN];
477 unsigned int major, minor;
478 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
480 if ((fp = fopen(DISKSTATS, "r")) == NULL)
483 while (fgets(line, 256, fp) != NULL) {
485 if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu",
486 &major, &minor, dev_name,
487 &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) {
489 if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) {
491 * OK: It's a (real) device and not a partition.
492 * Note: Structure should have been initialized first!
494 st_io->dk_drive += rd_ios + wr_ios;
495 st_io->dk_drive_rio += rd_ios;
496 st_io->dk_drive_rblk += rd_sec;
497 st_io->dk_drive_wio += wr_ios;
498 st_io->dk_drive_wblk += wr_sec;
507 ***************************************************************************
508 * Read block devices statistics from /proc/diskstats.
511 * @st_disk Structure where stats will be saved.
512 * @nbr Maximum number of block devices.
513 * @read_part True if disks *and* partitions should be read; False if only
517 * @st_disk Structure with statistics.
518 ***************************************************************************
520 void read_diskstats_disk(struct stats_disk *st_disk, int nbr, int read_part)
524 char dev_name[MAX_NAME_LEN];
526 struct stats_disk *st_disk_i;
527 unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks;
528 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
530 if ((fp = fopen(DISKSTATS, "r")) == NULL)
533 while ((fgets(line, 256, fp) != NULL) && (dsk < nbr)) {
535 if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu"
537 &major, &minor, dev_name,
538 &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks,
539 &tot_ticks, &rq_ticks) == 11) {
541 if (!rd_ios && !wr_ios)
542 /* Unused device: Ignore it */
544 if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) {
545 st_disk_i = st_disk + dsk++;
546 st_disk_i->major = major;
547 st_disk_i->minor = minor;
548 st_disk_i->nr_ios = rd_ios + wr_ios;
549 st_disk_i->rd_sect = rd_sec;
550 st_disk_i->wr_sect = wr_sec;
551 st_disk_i->rd_ticks = rd_ticks;
552 st_disk_i->wr_ticks = wr_ticks;
553 st_disk_i->tot_ticks = tot_ticks;
554 st_disk_i->rq_ticks = rq_ticks;
563 ***************************************************************************
564 * Read serial lines statistics from /proc/tty/driver/serial.
567 * @st_serial Structure where stats will be saved.
568 * @nbr Maximum number of serial lines.
571 * @st_serial Structure with statistics.
572 ***************************************************************************
574 void read_tty_driver_serial(struct stats_serial *st_serial, int nbr)
577 struct stats_serial *st_serial_i;
582 if ((fp = fopen(SERIAL, "r")) == NULL)
585 while ((fgets(line, 256, fp) != NULL) && (sl < nbr)) {
587 if ((p = strstr(line, "tx:")) != NULL) {
588 st_serial_i = st_serial + sl;
589 sscanf(line, "%u", &st_serial_i->line);
591 * A value of 0 means an unused structure.
592 * So increment it to make sure it is not null.
594 (st_serial_i->line)++;
596 * Read the number of chars transmitted and received by
597 * current serial line.
599 sscanf(p + 3, "%u", &st_serial_i->tx);
600 if ((p = strstr(line, "rx:")) != NULL) {
601 sscanf(p + 3, "%u", &st_serial_i->rx);
603 if ((p = strstr(line, "fe:")) != NULL) {
604 sscanf(p + 3, "%u", &st_serial_i->frame);
606 if ((p = strstr(line, "pe:")) != NULL) {
607 sscanf(p + 3, "%u", &st_serial_i->parity);
609 if ((p = strstr(line, "brk:")) != NULL) {
610 sscanf(p + 4, "%u", &st_serial_i->brk);
612 if ((p = strstr(line, "oe:")) != NULL) {
613 sscanf(p + 3, "%u", &st_serial_i->overrun);
624 ***************************************************************************
625 * Read kernel tables statistics from various system files.
628 * @st_ktables Structure where stats will be saved.
631 * @st_ktables Structure with statistics.
632 ***************************************************************************
634 void read_kernel_tables(struct stats_ktables *st_ktables)
639 /* Open /proc/sys/fs/dentry-state file */
640 if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) {
642 &st_ktables->dentry_stat);
646 /* Open /proc/sys/fs/file-nr file */
647 if ((fp = fopen(FFILE_NR, "r")) != NULL) {
649 &st_ktables->file_used, &parm);
652 * The number of used handles is the number of allocated ones
653 * minus the number of free ones.
655 st_ktables->file_used -= parm;
658 /* Open /proc/sys/fs/inode-state file */
659 if ((fp = fopen(FINODE_STATE, "r")) != NULL) {
661 &st_ktables->inode_used, &parm);
664 * The number of inuse inodes is the number of allocated ones
665 * minus the number of free ones.
667 st_ktables->inode_used -= parm;
670 /* Open /proc/sys/kernel/pty/nr file */
671 if ((fp = fopen(PTY_NR, "r")) != NULL) {
673 &st_ktables->pty_nr);
679 ***************************************************************************
680 * Read network interfaces statistics from /proc/net/dev.
683 * @st_net_dev Structure where stats will be saved.
684 * @nbr Maximum number of network interfaces.
687 * @st_net_dev Structure with statistics.
688 ***************************************************************************
690 void read_net_dev(struct stats_net_dev *st_net_dev, int nbr)
693 struct stats_net_dev *st_net_dev_i;
695 char iface[MAX_IFACE_LEN];
699 if ((fp = fopen(NET_DEV, "r")) == NULL)
702 while ((fgets(line, 256, fp) != NULL) && (dev < nbr)) {
704 pos = strcspn(line, ":");
705 if (pos < strlen(line)) {
706 st_net_dev_i = st_net_dev + dev;
707 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
708 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
709 sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */
710 sscanf(line + pos + 1, "%lu %lu %*u %*u %*u %*u %lu %lu %lu %lu "
711 "%*u %*u %*u %*u %*u %lu",
712 &st_net_dev_i->rx_bytes,
713 &st_net_dev_i->rx_packets,
714 &st_net_dev_i->rx_compressed,
715 &st_net_dev_i->multicast,
716 &st_net_dev_i->tx_bytes,
717 &st_net_dev_i->tx_packets,
718 &st_net_dev_i->tx_compressed);
727 ***************************************************************************
728 * Read network interfaces errors statistics from /proc/net/dev.
731 * @st_net_edev Structure where stats will be saved.
732 * @nbr Maximum number of network interfaces.
735 * @st_net_edev Structure with statistics.
736 ***************************************************************************
738 void read_net_edev(struct stats_net_edev *st_net_edev, int nbr)
741 struct stats_net_edev *st_net_edev_i;
742 static char line[256];
743 char iface[MAX_IFACE_LEN];
747 if ((fp = fopen(NET_DEV, "r")) == NULL)
750 while ((fgets(line, 256, fp) != NULL) && (dev < nbr)) {
752 pos = strcspn(line, ":");
753 if (pos < strlen(line)) {
754 st_net_edev_i = st_net_edev + dev;
755 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
756 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
757 sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */
758 sscanf(line + pos + 1, "%*u %*u %lu %lu %lu %lu %*u %*u %*u %*u "
759 "%lu %lu %lu %lu %lu",
760 &st_net_edev_i->rx_errors,
761 &st_net_edev_i->rx_dropped,
762 &st_net_edev_i->rx_fifo_errors,
763 &st_net_edev_i->rx_frame_errors,
764 &st_net_edev_i->tx_errors,
765 &st_net_edev_i->tx_dropped,
766 &st_net_edev_i->tx_fifo_errors,
767 &st_net_edev_i->collisions,
768 &st_net_edev_i->tx_carrier_errors);
777 ***************************************************************************
778 * Read NFS client statistics from /proc/net/rpc/nfs.
781 * @st_net_nfs Structure where stats will be saved.
784 * @st_net_nfs Structure with statistics.
785 ***************************************************************************
787 void read_net_nfs(struct stats_net_nfs *st_net_nfs)
791 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
793 if ((fp = fopen(NET_RPC_NFS, "r")) == NULL)
796 memset(st_net_nfs, 0, STATS_NET_NFS_SIZE);
798 while (fgets(line, 256, fp) != NULL) {
800 if (!strncmp(line, "rpc ", 4)) {
801 sscanf(line + 4, "%u %u",
802 &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans);
804 else if (!strncmp(line, "proc3 ", 6)) {
805 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
806 &getattcnt, &accesscnt, &readcnt, &writecnt);
808 st_net_nfs->nfs_getattcnt += getattcnt;
809 st_net_nfs->nfs_accesscnt += accesscnt;
810 st_net_nfs->nfs_readcnt += readcnt;
811 st_net_nfs->nfs_writecnt += writecnt;
813 else if (!strncmp(line, "proc4 ", 6)) {
814 sscanf(line + 6, "%*u %*u %u %u "
815 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u",
816 &readcnt, &writecnt, &accesscnt, &getattcnt);
818 st_net_nfs->nfs_getattcnt += getattcnt;
819 st_net_nfs->nfs_accesscnt += accesscnt;
820 st_net_nfs->nfs_readcnt += readcnt;
821 st_net_nfs->nfs_writecnt += writecnt;
829 ***************************************************************************
830 * Read NFS server statistics from /proc/net/rpc/nfsd.
833 * @st_net_nfsd Structure where stats will be saved.
836 * @st_net_nfsd Structure with statistics.
837 ***************************************************************************
839 void read_net_nfsd(struct stats_net_nfsd *st_net_nfsd)
843 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
845 if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL)
848 memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE);
850 while (fgets(line, 256, fp) != NULL) {
852 if (!strncmp(line, "rc ", 3)) {
853 sscanf(line + 3, "%u %u",
854 &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses);
856 else if (!strncmp(line, "net ", 4)) {
857 sscanf(line + 4, "%u %u %u",
858 &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt,
859 &st_net_nfsd->nfsd_nettcpcnt);
861 else if (!strncmp(line, "rpc ", 4)) {
862 sscanf(line + 4, "%u %u",
863 &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad);
865 else if (!strncmp(line, "proc3 ", 6)) {
866 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
867 &getattcnt, &accesscnt, &readcnt, &writecnt);
869 st_net_nfsd->nfsd_getattcnt += getattcnt;
870 st_net_nfsd->nfsd_accesscnt += accesscnt;
871 st_net_nfsd->nfsd_readcnt += readcnt;
872 st_net_nfsd->nfsd_writecnt += writecnt;
875 else if (!strncmp(line, "proc4ops ", 9)) {
876 sscanf(line + 9, "%*u %*u %*u %*u %u "
877 "%*u %*u %*u %*u %*u %u "
878 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u "
879 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
880 &accesscnt, &getattcnt, &readcnt, &writecnt);
882 st_net_nfsd->nfsd_getattcnt += getattcnt;
883 st_net_nfsd->nfsd_accesscnt += accesscnt;
884 st_net_nfsd->nfsd_readcnt += readcnt;
885 st_net_nfsd->nfsd_writecnt += writecnt;
893 ***************************************************************************
894 * Read network sockets statistics from /proc/net/sockstat.
897 * @st_net_sock Structure where stats will be saved.
900 * @st_net_sock Structure with statistics.
901 ***************************************************************************
903 void read_net_sock(struct stats_net_sock *st_net_sock)
909 if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL)
912 while (fgets(line, 96, fp) != NULL) {
914 if (!strncmp(line, "sockets:", 8)) {
916 sscanf(line + 14, "%u", &st_net_sock->sock_inuse);
918 else if (!strncmp(line, "TCP:", 4)) {
920 sscanf(line + 11, "%u", &st_net_sock->tcp_inuse);
921 if ((p = strstr(line, "tw")) != NULL) {
922 sscanf(p + 2, "%u", &st_net_sock->tcp_tw);
925 else if (!strncmp(line, "UDP:", 4)) {
927 sscanf(line + 11, "%u", &st_net_sock->udp_inuse);
929 else if (!strncmp(line, "RAW:", 4)) {
931 sscanf(line + 11, "%u", &st_net_sock->raw_inuse);
933 else if (!strncmp(line, "FRAG:", 5)) {
935 sscanf(line + 12, "%u", &st_net_sock->frag_inuse);
943 ***************************************************************************
944 * Read IP network traffic statistics from /proc/net/snmp.
947 * @st_net_ip Structure where stats will be saved.
950 * @st_net_ip Structure with statistics.
951 ***************************************************************************
953 void read_net_ip(struct stats_net_ip *st_net_ip)
959 if ((fp = fopen(NET_SNMP, "r")) == NULL)
962 while (fgets(line, 1024, fp) != NULL) {
964 if (!strncmp(line, "Ip:", 3)) {
966 sscanf(line + 3, "%*u %*u %lu %*u %*u %lu %*u %*u "
967 "%lu %lu %*u %*u %*u %lu %lu %*u %lu %*u %lu",
968 &st_net_ip->InReceives,
969 &st_net_ip->ForwDatagrams,
970 &st_net_ip->InDelivers,
971 &st_net_ip->OutRequests,
972 &st_net_ip->ReasmReqds,
973 &st_net_ip->ReasmOKs,
975 &st_net_ip->FragCreates);
989 ***************************************************************************
990 * Read IP network error statistics from /proc/net/snmp.
993 * @st_net_eip Structure where stats will be saved.
996 * @st_net_eip Structure with statistics.
997 ***************************************************************************
999 void read_net_eip(struct stats_net_eip *st_net_eip)
1005 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1008 while (fgets(line, 1024, fp) != NULL) {
1010 if (!strncmp(line, "Ip:", 3)) {
1012 sscanf(line + 3, "%*u %*u %*u %lu %lu %*u %lu %lu "
1013 "%*u %*u %lu %lu %*u %*u %*u %lu %*u %lu",
1014 &st_net_eip->InHdrErrors,
1015 &st_net_eip->InAddrErrors,
1016 &st_net_eip->InUnknownProtos,
1017 &st_net_eip->InDiscards,
1018 &st_net_eip->OutDiscards,
1019 &st_net_eip->OutNoRoutes,
1020 &st_net_eip->ReasmFails,
1021 &st_net_eip->FragFails);
1035 ***************************************************************************
1036 * Read ICMP network traffic statistics from /proc/net/snmp.
1039 * @st_net_icmp Structure where stats will be saved.
1042 * @st_net_icmp Structure with statistics.
1043 ***************************************************************************
1045 void read_net_icmp(struct stats_net_icmp *st_net_icmp)
1051 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1054 while (fgets(line, 1024, fp) != NULL) {
1056 if (!strncmp(line, "Icmp:", 5)) {
1058 sscanf(line + 5, "%lu %*u %*u %*u %*u %*u %*u "
1059 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1060 "%*u %*u %lu %lu %lu %lu %lu %lu",
1061 &st_net_icmp->InMsgs,
1062 &st_net_icmp->InEchos,
1063 &st_net_icmp->InEchoReps,
1064 &st_net_icmp->InTimestamps,
1065 &st_net_icmp->InTimestampReps,
1066 &st_net_icmp->InAddrMasks,
1067 &st_net_icmp->InAddrMaskReps,
1068 &st_net_icmp->OutMsgs,
1069 &st_net_icmp->OutEchos,
1070 &st_net_icmp->OutEchoReps,
1071 &st_net_icmp->OutTimestamps,
1072 &st_net_icmp->OutTimestampReps,
1073 &st_net_icmp->OutAddrMasks,
1074 &st_net_icmp->OutAddrMaskReps);
1088 ***************************************************************************
1089 * Read ICMP network error statistics from /proc/net/snmp.
1092 * @st_net_eicmp Structure where stats will be saved.
1095 * @st_net_eicmp Structure with statistics.
1096 ***************************************************************************
1098 void read_net_eicmp(struct stats_net_eicmp *st_net_eicmp)
1104 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1107 while (fgets(line, 1024, fp) != NULL) {
1109 if (!strncmp(line, "Icmp:", 5)) {
1111 sscanf(line + 5, "%*u %lu %lu %lu %lu %lu %lu %*u %*u "
1112 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu",
1113 &st_net_eicmp->InErrors,
1114 &st_net_eicmp->InDestUnreachs,
1115 &st_net_eicmp->InTimeExcds,
1116 &st_net_eicmp->InParmProbs,
1117 &st_net_eicmp->InSrcQuenchs,
1118 &st_net_eicmp->InRedirects,
1119 &st_net_eicmp->OutErrors,
1120 &st_net_eicmp->OutDestUnreachs,
1121 &st_net_eicmp->OutTimeExcds,
1122 &st_net_eicmp->OutParmProbs,
1123 &st_net_eicmp->OutSrcQuenchs,
1124 &st_net_eicmp->OutRedirects);
1138 ***************************************************************************
1139 * Read TCP network traffic statistics from /proc/net/snmp.
1142 * @st_net_tcp Structure where stats will be saved.
1145 * @st_net_tcp Structure with statistics.
1146 ***************************************************************************
1148 void read_net_tcp(struct stats_net_tcp *st_net_tcp)
1154 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1157 while (fgets(line, 1024, fp) != NULL) {
1159 if (!strncmp(line, "Tcp:", 4)) {
1161 sscanf(line + 4, "%*u %*u %*u %*d %lu %lu "
1162 "%*u %*u %*u %lu %lu",
1163 &st_net_tcp->ActiveOpens,
1164 &st_net_tcp->PassiveOpens,
1165 &st_net_tcp->InSegs,
1166 &st_net_tcp->OutSegs);
1180 ***************************************************************************
1181 * Read TCP network error statistics from /proc/net/snmp.
1184 * @st_net_etcp Structure where stats will be saved.
1187 * @st_net_etcp Structure with statistics.
1188 ***************************************************************************
1190 void read_net_etcp(struct stats_net_etcp *st_net_etcp)
1196 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1199 while (fgets(line, 1024, fp) != NULL) {
1201 if (!strncmp(line, "Tcp:", 4)) {
1203 sscanf(line + 4, "%*u %*u %*u %*d %*u %*u "
1204 "%lu %lu %*u %*u %*u %lu %lu %lu",
1205 &st_net_etcp->AttemptFails,
1206 &st_net_etcp->EstabResets,
1207 &st_net_etcp->RetransSegs,
1208 &st_net_etcp->InErrs,
1209 &st_net_etcp->OutRsts);
1223 ***************************************************************************
1224 * Read UDP network traffic statistics from /proc/net/snmp.
1227 * @st_net_udp Structure where stats will be saved.
1230 * @st_net_udp Structure with statistics.
1231 ***************************************************************************
1233 void read_net_udp(struct stats_net_udp *st_net_udp)
1239 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1242 while (fgets(line, 1024, fp) != NULL) {
1244 if (!strncmp(line, "Udp:", 4)) {
1246 sscanf(line + 4, "%lu %lu %lu %lu",
1247 &st_net_udp->InDatagrams,
1248 &st_net_udp->NoPorts,
1249 &st_net_udp->InErrors,
1250 &st_net_udp->OutDatagrams);
1264 ***************************************************************************
1265 * Read IPv6 network sockets statistics from /proc/net/sockstat6.
1268 * @st_net_sock6 Structure where stats will be saved.
1271 * @st_net_sock6 Structure with statistics.
1272 ***************************************************************************
1274 void read_net_sock6(struct stats_net_sock6 *st_net_sock6)
1279 if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL)
1282 while (fgets(line, 96, fp) != NULL) {
1284 if (!strncmp(line, "TCP6:", 5)) {
1286 sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse);
1288 else if (!strncmp(line, "UDP6:", 5)) {
1290 sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse);
1292 else if (!strncmp(line, "RAW6:", 5)) {
1293 /* IPv6 RAW sockets */
1294 sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse);
1296 else if (!strncmp(line, "FRAG6:", 6)) {
1297 /* IPv6 FRAGments */
1298 sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse);
1306 ***************************************************************************
1307 * Read IPv6 network traffic statistics from /proc/net/snmp6.
1310 * @st_net_ip6 Structure where stats will be saved.
1313 * @st_net_ip6 Structure with statistics.
1314 ***************************************************************************
1316 void read_net_ip6(struct stats_net_ip6 *st_net_ip6)
1321 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1324 while (fgets(line, 128, fp) != NULL) {
1326 if (!strncmp(line, "Ip6InReceives ", 14)) {
1327 sscanf(line + 14, "%lu", &st_net_ip6->InReceives6);
1329 else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) {
1330 sscanf(line + 20, "%lu", &st_net_ip6->OutForwDatagrams6);
1332 else if (!strncmp(line, "Ip6InDelivers ", 14)) {
1333 sscanf(line + 14, "%lu", &st_net_ip6->InDelivers6);
1335 else if (!strncmp(line, "Ip6OutRequests ", 15)) {
1336 sscanf(line + 15, "%lu", &st_net_ip6->OutRequests6);
1338 else if (!strncmp(line, "Ip6ReasmReqds ", 14)) {
1339 sscanf(line + 14, "%lu", &st_net_ip6->ReasmReqds6);
1341 else if (!strncmp(line, "Ip6ReasmOKs ", 12)) {
1342 sscanf(line + 12, "%lu", &st_net_ip6->ReasmOKs6);
1344 else if (!strncmp(line, "Ip6InMcastPkts ", 15)) {
1345 sscanf(line + 15, "%lu", &st_net_ip6->InMcastPkts6);
1347 else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) {
1348 sscanf(line + 16, "%lu", &st_net_ip6->OutMcastPkts6);
1350 else if (!strncmp(line, "Ip6FragOKs ", 11)) {
1351 sscanf(line + 11, "%lu", &st_net_ip6->FragOKs6);
1353 else if (!strncmp(line, "Ip6FragCreates ", 15)) {
1354 sscanf(line + 15, "%lu", &st_net_ip6->FragCreates6);
1362 ***************************************************************************
1363 * Read IPv6 network error statistics from /proc/net/snmp6.
1366 * @st_net_eip6 Structure where stats will be saved.
1369 * @st_net_eip6 Structure with statistics.
1370 ***************************************************************************
1372 void read_net_eip6(struct stats_net_eip6 *st_net_eip6)
1377 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1380 while (fgets(line, 128, fp) != NULL) {
1382 if (!strncmp(line, "Ip6InHdrErrors ", 15)) {
1383 sscanf(line + 15, "%lu", &st_net_eip6->InHdrErrors6);
1385 else if (!strncmp(line, "Ip6InAddrErrors ", 16)) {
1386 sscanf(line + 16, "%lu", &st_net_eip6->InAddrErrors6);
1388 else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) {
1389 sscanf(line + 19, "%lu", &st_net_eip6->InUnknownProtos6);
1391 else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) {
1392 sscanf(line + 18, "%lu", &st_net_eip6->InTooBigErrors6);
1394 else if (!strncmp(line, "Ip6InDiscards ", 14)) {
1395 sscanf(line + 14, "%lu", &st_net_eip6->InDiscards6);
1397 else if (!strncmp(line, "Ip6OutDiscards ", 15)) {
1398 sscanf(line + 15, "%lu", &st_net_eip6->OutDiscards6);
1400 else if (!strncmp(line, "Ip6InNoRoutes ", 14)) {
1401 sscanf(line + 14, "%lu", &st_net_eip6->InNoRoutes6);
1403 else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) {
1404 sscanf(line + 15, "%lu", &st_net_eip6->OutNoRoutes6);
1406 else if (!strncmp(line, "Ip6ReasmFails ", 14)) {
1407 sscanf(line + 14, "%lu", &st_net_eip6->ReasmFails6);
1409 else if (!strncmp(line, "Ip6FragFails ", 13)) {
1410 sscanf(line + 13, "%lu", &st_net_eip6->FragFails6);
1412 else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) {
1413 sscanf(line + 19, "%lu", &st_net_eip6->InTruncatedPkts6);
1421 ***************************************************************************
1422 * Read ICMPv6 network traffic statistics from /proc/net/snmp6.
1425 * @st_net_icmp6 Structure where stats will be saved.
1428 * @st_net_icmp6 Structure with statistics.
1429 ***************************************************************************
1431 void read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6)
1436 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1439 while (fgets(line, 128, fp) != NULL) {
1441 if (!strncmp(line, "Icmp6InMsgs ", 12)) {
1442 sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6);
1444 else if (!strncmp(line, "Icmp6OutMsgs ", 13)) {
1445 sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6);
1447 else if (!strncmp(line, "Icmp6InEchos ", 13)) {
1448 sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6);
1450 else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) {
1451 sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6);
1453 else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) {
1454 sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6);
1456 else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) {
1457 sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6);
1459 else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) {
1460 sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6);
1462 else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) {
1463 sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6);
1465 else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) {
1466 sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6);
1468 else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) {
1469 sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6);
1471 else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) {
1472 sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6);
1474 else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) {
1475 sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6);
1477 else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) {
1478 sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6);
1480 else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) {
1481 sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6);
1483 else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) {
1484 sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6);
1486 else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) {
1487 sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6);
1489 else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) {
1490 sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6);
1498 ***************************************************************************
1499 * Read ICMPv6 network error statistics from /proc/net/snmp6.
1502 * @st_net_eicmp6 Structure where stats will be saved.
1505 * @st_net_eicmp6 Structure with statistics.
1506 ***************************************************************************
1508 void read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6)
1513 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1516 while (fgets(line, 128, fp) != NULL) {
1518 if (!strncmp(line, "Icmp6InErrors ", 14)) {
1519 sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6);
1521 else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) {
1522 sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6);
1524 else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) {
1525 sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6);
1527 else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) {
1528 sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6);
1530 else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) {
1531 sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6);
1533 else if (!strncmp(line, "Icmp6InParmProblems ", 20)) {
1534 sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6);
1536 else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) {
1537 sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6);
1539 else if (!strncmp(line, "Icmp6InRedirects ", 17)) {
1540 sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6);
1542 else if (!strncmp(line, "Icmp6OutRedirects ", 18)) {
1543 sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6);
1545 else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) {
1546 sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6);
1548 else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) {
1549 sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6);
1557 ***************************************************************************
1558 * Read UDPv6 network traffic statistics from /proc/net/snmp6.
1561 * @st_net_udp6 Structure where stats will be saved.
1564 * @st_net_udp6 Structure with statistics.
1565 ***************************************************************************
1567 void read_net_udp6(struct stats_net_udp6 *st_net_udp6)
1572 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1575 while (fgets(line, 128, fp) != NULL) {
1577 if (!strncmp(line, "Udp6InDatagrams ", 16)) {
1578 sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6);
1580 else if (!strncmp(line, "Udp6OutDatagrams ", 17)) {
1581 sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6);
1583 else if (!strncmp(line, "Udp6NoPorts ", 12)) {
1584 sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6);
1586 else if (!strncmp(line, "Udp6InErrors ", 13)) {
1587 sscanf(line + 13, "%lu", &st_net_udp6->InErrors6);
1595 ***************************************************************************
1596 * Read CPU frequency statistics.
1599 * @st_pwr_cpufreq Structure where stats will be saved.
1600 * @nbr Total number of CPU (including cpu "all").
1603 * @st_pwr_cpufreq Structure with statistics.
1604 ***************************************************************************
1606 void read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, int nbr)
1609 struct stats_pwr_cpufreq *st_pwr_cpufreq_i;
1611 int proc_nb = 0, nr = 0;
1612 unsigned int ifreq, dfreq;
1614 if ((fp = fopen(CPUINFO, "r")) == NULL)
1617 st_pwr_cpufreq->cpufreq = 0;
1619 while (fgets(line, 1024, fp) != NULL) {
1621 if (!strncmp(line, "processor\t", 10)) {
1622 sscanf(strchr(line, ':') + 1, "%d", &proc_nb);
1625 else if (!strncmp(line, "cpu MHz\t", 8)) {
1626 sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq);
1628 if (proc_nb < (nbr - 1)) {
1629 /* Save current CPU frequency */
1630 st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nb + 1;
1631 st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10;
1633 /* Also save it to compute an average CPU frequency */
1634 st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq;
1637 else if (!proc_nb && (nbr == 1)) {
1639 * We are reading freq for "Processor 0" and we have a machine
1640 * with only one processor and not an SMP kernel, with /sys not mounted
1641 * (the nr of proc has been counted using /proc/stat and there was
1642 * only one line with global CPU stats here).
1643 * This is a very specific case, I must admit...
1645 st_pwr_cpufreq->cpufreq = ifreq * 100 + dfreq / 10;
1653 /* Compute average CPU frequency for this machine */
1654 st_pwr_cpufreq->cpufreq /= nr;
1659 ***************************************************************************
1660 * Read hugepages statistics from /proc/meminfo.
1663 * @st_huge Structure where stats will be saved.
1666 * @st_huge Structure with statistics.
1667 ***************************************************************************
1669 void read_meminfo_huge(struct stats_huge *st_huge)
1673 unsigned long szhkb = 0;
1675 if ((fp = fopen(MEMINFO, "r")) == NULL)
1678 while (fgets(line, 128, fp) != NULL) {
1680 if (!strncmp(line, "HugePages_Total:", 16)) {
1681 /* Read the total number of huge pages */
1682 sscanf(line + 16, "%lu", &st_huge->tlhkb);
1684 else if (!strncmp(line, "HugePages_Free:", 15)) {
1685 /* Read the number of free huge pages */
1686 sscanf(line + 15, "%lu", &st_huge->frhkb);
1688 else if (!strncmp(line, "Hugepagesize:", 13)) {
1689 /* Read the default size of a huge page in kB */
1690 sscanf(line + 13, "%lu", &szhkb);
1696 /* We want huge pages stats in kB and not expressed in a number of pages */
1697 st_huge->tlhkb *= szhkb;
1698 st_huge->frhkb *= szhkb;
1702 ***************************************************************************
1703 * Read CPU average frequencies statistics.
1706 * @st_pwr_wghfreq Structure where stats will be saved.
1707 * @cpu_nr CPU number for which time_in_state date will be read.
1708 * @nbr Total number of states (frequencies).
1711 * @st_pwr_wghfreq Structure with statistics.
1712 ***************************************************************************
1714 void read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr)
1717 struct stats_pwr_wghfreq *st_pwr_wghfreq_j;
1718 char filename[MAX_PF_NAME];
1722 unsigned long long time_in_state;
1724 snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s",
1725 SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE);
1726 if ((fp = fopen(filename, "r")) == NULL)
1729 while (fgets(line, 128, fp) != NULL) {
1731 sscanf(line, "%lu %llu", &freq, &time_in_state);
1734 /* Save current frequency and time */
1735 st_pwr_wghfreq_j = st_pwr_wghfreq + j;
1736 st_pwr_wghfreq_j->freq = freq;
1737 st_pwr_wghfreq_j->time_in_state = time_in_state;
1746 ***************************************************************************
1747 * Read current USB device data.
1750 * @st_pwr_usb Structure where stats will be saved.
1751 * @usb_device File name for current USB device.
1754 * @st_pwr_usb Structure with statistics.
1755 ***************************************************************************
1757 void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
1761 char filename[MAX_PF_NAME];
1763 /* Get USB device bus number */
1764 sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
1766 /* Read USB device vendor ID */
1767 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
1768 SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
1769 if ((fp = fopen(filename, "r")) != NULL) {
1771 &st_pwr_usb->vendor_id);
1775 /* Read USB device product ID */
1776 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
1777 SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
1778 if ((fp = fopen(filename, "r")) != NULL) {
1780 &st_pwr_usb->product_id);
1784 /* Read USB device max power consumption */
1785 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
1786 SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
1787 if ((fp = fopen(filename, "r")) != NULL) {
1789 &st_pwr_usb->bmaxpower);
1793 /* Read USB device manufacturer */
1794 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
1795 SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
1796 if ((fp = fopen(filename, "r")) != NULL) {
1797 fgets(st_pwr_usb->manufacturer, MAX_MANUF_LEN - 1, fp);
1799 if ((l = strlen(st_pwr_usb->manufacturer)) > 0) {
1800 /* Remove trailing CR */
1801 st_pwr_usb->manufacturer[l - 1] = '\0';
1805 /* Read USB device product */
1806 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
1807 SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
1808 if ((fp = fopen(filename, "r")) != NULL) {
1809 fgets(st_pwr_usb->product, MAX_PROD_LEN - 1, fp);
1811 if ((l = strlen(st_pwr_usb->product)) > 0) {
1812 /* Remove trailing CR */
1813 st_pwr_usb->product[l - 1] = '\0';
1819 ***************************************************************************
1820 * Read USB devices statistics.
1823 * @st_pwr_usb Structure where stats will be saved.
1824 * @nbr Total number of USB devices.
1827 * @st_pwr_usb Structure with statistics.
1828 ***************************************************************************
1830 void read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, int nbr)
1834 struct stats_pwr_usb *st_pwr_usb_j;
1837 /* Open relevant /sys directory */
1838 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
1841 /* Get current file entry */
1842 while ((drd = readdir(dir)) != NULL) {
1844 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
1846 /* Read current USB device data */
1847 st_pwr_usb_j = st_pwr_usb + j;
1848 read_usb_stats(st_pwr_usb_j, drd->d_name);
1856 /* Close directory */
1861 ***************************************************************************
1862 * Read machine uptime, independently of the number of processors.
1865 * @uptime Uptime value in jiffies.
1866 ***************************************************************************
1868 void read_uptime(unsigned long long *uptime)
1872 unsigned long up_sec, up_cent;
1874 if ((fp = fopen(UPTIME, "r")) == NULL)
1877 if (fgets(line, 128, fp) == NULL) {
1882 sscanf(line, "%lu.%lu", &up_sec, &up_cent);
1883 *uptime = (unsigned long long) up_sec * HZ +
1884 (unsigned long long) up_cent * HZ / 100;
1891 ***************************************************************************
1892 * Count number of interrupts that are in /proc/stat file.
1895 * Number of interrupts, including total number of interrupts.
1896 ***************************************************************************
1898 int get_irq_nr(void)
1905 if ((fp = fopen(STAT, "r")) == NULL)
1908 while (fgets(line, 8192, fp) != NULL) {
1910 if (!strncmp(line, "intr ", 5)) {
1912 while (pos < strlen(line)) {
1914 pos += strcspn(line + pos + 1, " ") + 1;
1925 ***************************************************************************
1926 * Find number of serial lines that support tx/rx accounting
1927 * in /proc/tty/driver/serial file.
1930 * Number of serial lines supporting tx/rx accouting.
1931 ***************************************************************************
1933 int get_serial_nr(void)
1939 if ((fp = fopen(SERIAL, "r")) == NULL)
1940 return 0; /* No SERIAL file */
1942 while (fgets(line, 256, fp) != NULL) {
1944 * tx/rx statistics are always present,
1945 * except when serial line is unknown.
1947 if (strstr(line, "tx:") != NULL) {
1958 ***************************************************************************
1959 * Find number of interfaces (network devices) that are in /proc/net/dev
1963 * Number of network interfaces.
1964 ***************************************************************************
1966 int get_iface_nr(void)
1972 if ((fp = fopen(NET_DEV, "r")) == NULL)
1973 return 0; /* No network device file */
1975 while (fgets(line, 128, fp) != NULL) {
1976 if (strchr(line, ':')) {
1987 ***************************************************************************
1988 * Find number of devices and partitions available in /proc/diskstats.
1991 * @count_part Set to TRUE if devices _and_ partitions are to be
1993 * @only_used_dev When counting devices, set to TRUE if only devices
1994 * with non zero stats must be counted.
1997 * Number of devices (and partitions).
1998 ***************************************************************************
2000 int get_diskstats_dev_nr(int count_part, int only_used_dev)
2004 char dev_name[MAX_NAME_LEN];
2006 unsigned long rd_ios, wr_ios;
2008 if ((fp = fopen(DISKSTATS, "r")) == NULL)
2009 /* File non-existent */
2013 * Counting devices and partitions is simply a matter of counting
2014 * the number of lines...
2016 while (fgets(line, 256, fp) != NULL) {
2018 i = sscanf(line, "%*d %*d %s %lu %*u %*u %*u %lu",
2019 dev_name, &rd_ios, &wr_ios);
2020 if ((i == 2) || !is_device(dev_name, ACCEPT_VIRTUAL_DEVICES))
2021 /* It was a partition and not a device */
2023 if (only_used_dev && !rd_ios && !wr_ios)
2036 ***************************************************************************
2037 * Get number of devices in /proc/diskstats.
2040 * @f Non zero (true) if disks *and* partitions should be counted, and
2041 * zero (false) if only disks must be counted.
2044 * Number of devices.
2045 ***************************************************************************
2047 int get_disk_nr(unsigned int f)
2052 * Partitions are taken into account by sar -d only with
2053 * kernels 2.6.25 and later.
2055 disk_nr = get_diskstats_dev_nr(f, CNT_USED_DEV);
2061 ***************************************************************************
2062 * Count number of processors in /sys.
2065 * Number of processors (online and offline).
2066 * A value of 0 means that /sys was not mounted.
2067 * A value of N (!=0) means N processor(s) (cpu0 .. cpu(N-1)).
2068 ***************************************************************************
2070 int get_sys_cpu_nr(void)
2075 char line[MAX_PF_NAME];
2078 /* Open relevant /sys directory */
2079 if ((dir = opendir(SYSFS_DEVCPU)) == NULL)
2082 /* Get current file entry */
2083 while ((drd = readdir(dir)) != NULL) {
2085 if (!strncmp(drd->d_name, "cpu", 3) && isdigit(drd->d_name[3])) {
2086 snprintf(line, MAX_PF_NAME, "%s/%s", SYSFS_DEVCPU, drd->d_name);
2087 line[MAX_PF_NAME - 1] = '\0';
2088 if (stat(line, &buf) < 0)
2090 if (S_ISDIR(buf.st_mode)) {
2096 /* Close directory */
2103 ***************************************************************************
2104 * Count number of processors in /proc/stat.
2107 * Number of processors. The returned value is greater than or equal to the
2108 * number of online processors.
2109 * A value of 0 means one processor and non SMP kernel.
2110 * A value of N (!=0) means N processor(s) (0 .. N-1) with SMP kernel.
2111 ***************************************************************************
2113 int get_proc_cpu_nr(void)
2117 int num_proc, proc_nr = -1;
2119 if ((fp = fopen(STAT, "r")) == NULL) {
2120 fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
2124 while (fgets(line, 16, fp) != NULL) {
2126 if (strncmp(line, "cpu ", 4) && !strncmp(line, "cpu", 3)) {
2127 sscanf(line + 3, "%d", &num_proc);
2128 if (num_proc > proc_nr) {
2136 return (proc_nr + 1);
2140 ***************************************************************************
2141 * Count the number of processors on the machine.
2142 * Try to use /sys for that, or /proc/stat if /sys doesn't exist.
2145 * @max_nr_cpus Maximum number of proc that sysstat can handle.
2148 * Number of processors.
2149 * 0: one proc and non SMP kernel.
2150 * 1: one proc and SMP kernel (NB: On SMP machines where all the CPUs but
2151 * one have been disabled, we get the total number of proc since we use
2152 * /sys to count them).
2154 ***************************************************************************
2156 int get_cpu_nr(unsigned int max_nr_cpus)
2160 if ((cpu_nr = get_sys_cpu_nr()) == 0) {
2161 /* /sys may be not mounted. Use /proc/stat instead */
2162 cpu_nr = get_proc_cpu_nr();
2165 if (cpu_nr > max_nr_cpus) {
2166 fprintf(stderr, _("Cannot handle so many processors!\n"));
2174 ***************************************************************************
2175 * Find number of interrupts available per processor (use
2176 * /proc/interrupts file or /proc/softirqs).
2179 * @file /proc file to read (interrupts or softirqs).
2180 * @max_nr_irqcpu Maximum number of interrupts per processor that
2182 * @cpu_nr Number of processors.
2185 * Number of interrupts per processor + a pre-allocation constant.
2186 ***************************************************************************
2188 int get_irqcpu_nr(char *file, int max_nr_irqcpu, int cpu_nr)
2192 unsigned int irq = 0;
2195 if ((fp = fopen(file, "r")) == NULL)
2196 return 0; /* No interrupts file */
2198 SREALLOC(line, char, INTERRUPTS_LINE + 11 * cpu_nr);
2200 while ((fgets(line, INTERRUPTS_LINE + 11 * cpu_nr , fp) != NULL) &&
2201 (irq < max_nr_irqcpu)) {
2202 p = strcspn(line, ":");
2203 if ((p > 0) && (p < 16)) {
2218 ***************************************************************************
2219 * Count number of possible frequencies for CPU#0.
2222 * Number of frequencies.
2223 ***************************************************************************
2225 int get_freq_nr(void)
2228 char filename[MAX_PF_NAME];
2232 snprintf(filename, MAX_PF_NAME, "%s/cpu0/%s",
2233 SYSFS_DEVCPU, SYSFS_TIME_IN_STATE);
2234 if ((fp = fopen(filename, "r")) == NULL)
2235 return 0; /* No time_in_state file for CPU#0 */
2237 while (fgets(line, 128, fp) != NULL) {
2247 ***************************************************************************
2248 * Count number of USB devices in /sys/bus/usb/devices.
2251 * Number of USB devices plugged into the system.
2252 * Don't count USB root hubs.
2253 * Return -1 if directory doesn't exist in sysfs.
2254 ***************************************************************************
2256 int get_usb_nr(void)
2262 /* Open relevant /sys directory */
2263 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
2266 /* Get current file entry */
2267 while ((drd = readdir(dir)) != NULL) {
2269 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
2274 /* Close directory */