2 * rd_stats.c: Read system statistics
3 * (C) 1999-2018 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>
39 #define _(string) gettext(string)
41 #define _(string) (string)
45 ***************************************************************************
46 * Read CPU statistics.
47 * Remember that this function is used by several sysstat commands!
50 * @st_cpu Buffer where structures containing stats will be saved.
51 * @nr_alloc Total number of structures allocated. Value is >= 1.
54 * @st_cpu Buffer with statistics.
57 * Highest CPU number(*) for which statistics have been read.
58 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
59 * Or -1 if the buffer was too small and needs to be reallocated.
61 * (*)This doesn't account for all processors in the machine in the case
62 * where some CPU are offline and located at the end of the list.
63 ***************************************************************************
65 __nr_t read_stat_cpu(struct stats_cpu *st_cpu, __nr_t nr_alloc)
68 struct stats_cpu *st_cpu_i;
74 if ((fp = fopen(STAT, "r")) == NULL) {
75 fprintf(stderr, _("Cannot open %s: %s\n"), STAT, strerror(errno));
79 while (fgets(line, sizeof(line), fp) != NULL) {
81 if (!strncmp(line, "cpu ", 4)) {
84 * All the fields don't necessarily exist,
85 * depending on the kernel version used.
87 memset(st_cpu, 0, STATS_CPU_SIZE);
90 * Read the number of jiffies spent in the different modes
91 * (user, nice, etc.) among all proc. CPU usage is not reduced
92 * to one processor to avoid rounding problems.
94 sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
100 &st_cpu->cpu_hardirq,
101 &st_cpu->cpu_softirq,
104 &st_cpu->cpu_guest_nice);
111 /* We just want to read stats for CPU "all" */
115 else if (!strncmp(line, "cpu", 3)) {
116 /* All the fields don't necessarily exist */
117 memset(&sc, 0, STATS_CPU_SIZE);
119 * Read the number of jiffies spent in the different modes
120 * (user, nice, etc) for current proc.
121 * This is done only on SMP machines.
123 sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
136 if (proc_nr + 2 > nr_alloc) {
141 st_cpu_i = st_cpu + proc_nr + 1;
144 if (proc_nr + 2 > cpu_read) {
145 cpu_read = proc_nr + 2;
155 ***************************************************************************
156 * Read interrupts statistics from /proc/stat.
157 * Remember that this function is used by several sysstat commands!
160 * @st_irq Structure where stats will be saved.
161 * @nr_alloc Number of structures allocated. Value is >= 1.
164 * @st_irq Structure with statistics.
167 * Number of interrupts read, or -1 if the buffer was too small and
168 * needs to be reallocated.
169 ***************************************************************************
171 __nr_t read_stat_irq(struct stats_irq *st_irq, __nr_t nr_alloc)
174 struct stats_irq *st_irq_i;
177 unsigned long long irq_nr;
180 if ((fp = fopen(STAT, "r")) == NULL)
183 while (fgets(line, sizeof(line), fp) != NULL) {
185 if (!strncmp(line, "intr ", 5)) {
186 /* Read total number of interrupts received since system boot */
187 sscanf(line + 5, "%llu", &st_irq->irq_nr);
188 pos = strcspn(line + 5, " ") + 5;
192 /* We just want to read the total number of interrupts */
196 i = sscanf(line + pos, " %llu", &irq_nr);
200 if (irq_read + 1 > nr_alloc) {
204 st_irq_i = st_irq + irq_read++;
205 st_irq_i->irq_nr = irq_nr;
207 i = strcspn(line + pos + 1, " ");
210 while ((i > 0) && (pos < (sizeof(line) - 1)));
221 ***************************************************************************
222 * Read memory statistics from /proc/meminfo.
225 * @st_memory Structure where stats will be saved.
228 * @st_memory Structure with statistics.
231 * 1 on success, 0 otherwise.
232 ***************************************************************************
234 __nr_t read_meminfo(struct stats_memory *st_memory)
239 if ((fp = fopen(MEMINFO, "r")) == NULL)
242 while (fgets(line, sizeof(line), fp) != NULL) {
244 if (!strncmp(line, "MemTotal:", 9)) {
245 /* Read the total amount of memory in kB */
246 sscanf(line + 9, "%llu", &st_memory->tlmkb);
248 else if (!strncmp(line, "MemFree:", 8)) {
249 /* Read the amount of free memory in kB */
250 sscanf(line + 8, "%llu", &st_memory->frmkb);
252 else if (!strncmp(line, "MemAvailable:", 13)) {
253 /* Read the amount of available memory in kB */
254 sscanf(line + 13, "%llu", &st_memory->availablekb);
256 else if (!strncmp(line, "Buffers:", 8)) {
257 /* Read the amount of buffered memory in kB */
258 sscanf(line + 8, "%llu", &st_memory->bufkb);
260 else if (!strncmp(line, "Cached:", 7)) {
261 /* Read the amount of cached memory in kB */
262 sscanf(line + 7, "%llu", &st_memory->camkb);
264 else if (!strncmp(line, "SwapCached:", 11)) {
265 /* Read the amount of cached swap in kB */
266 sscanf(line + 11, "%llu", &st_memory->caskb);
268 else if (!strncmp(line, "Active:", 7)) {
269 /* Read the amount of active memory in kB */
270 sscanf(line + 7, "%llu", &st_memory->activekb);
272 else if (!strncmp(line, "Inactive:", 9)) {
273 /* Read the amount of inactive memory in kB */
274 sscanf(line + 9, "%llu", &st_memory->inactkb);
276 else if (!strncmp(line, "SwapTotal:", 10)) {
277 /* Read the total amount of swap memory in kB */
278 sscanf(line + 10, "%llu", &st_memory->tlskb);
280 else if (!strncmp(line, "SwapFree:", 9)) {
281 /* Read the amount of free swap memory in kB */
282 sscanf(line + 9, "%llu", &st_memory->frskb);
284 else if (!strncmp(line, "Dirty:", 6)) {
285 /* Read the amount of dirty memory in kB */
286 sscanf(line + 6, "%llu", &st_memory->dirtykb);
288 else if (!strncmp(line, "Committed_AS:", 13)) {
289 /* Read the amount of commited memory in kB */
290 sscanf(line + 13, "%llu", &st_memory->comkb);
292 else if (!strncmp(line, "AnonPages:", 10)) {
293 /* Read the amount of pages mapped into userspace page tables in kB */
294 sscanf(line + 10, "%llu", &st_memory->anonpgkb);
296 else if (!strncmp(line, "Slab:", 5)) {
297 /* Read the amount of in-kernel data structures cache in kB */
298 sscanf(line + 5, "%llu", &st_memory->slabkb);
300 else if (!strncmp(line, "KernelStack:", 12)) {
301 /* Read the kernel stack utilization in kB */
302 sscanf(line + 12, "%llu", &st_memory->kstackkb);
304 else if (!strncmp(line, "PageTables:", 11)) {
305 /* Read the amount of memory dedicated to the lowest level of page tables in kB */
306 sscanf(line + 11, "%llu", &st_memory->pgtblkb);
308 else if (!strncmp(line, "VmallocUsed:", 12)) {
309 /* Read the amount of vmalloc area which is used in kB */
310 sscanf(line + 12, "%llu", &st_memory->vmusedkb);
319 ***************************************************************************
320 * Read machine uptime, independently of the number of processors.
323 * @uptime Uptime value in hundredths of a second.
324 ***************************************************************************
326 void read_uptime(unsigned long long *uptime)
330 unsigned long up_sec, up_cent;
333 if ((fp = fopen(UPTIME, "r")) == NULL) {
336 else if (fgets(line, sizeof(line), fp) == NULL) {
339 else if (sscanf(line, "%lu.%lu", &up_sec, &up_cent) == 2) {
340 *uptime = (unsigned long long) up_sec * 100 +
341 (unsigned long long) up_cent;
351 fprintf(stderr, _("Cannot read %s\n"), UPTIME);
357 ***************************************************************************
358 * Compute "extended" device statistics (service time, etc.).
361 * @sdc Structure with current device statistics.
362 * @sdp Structure with previous device statistics.
363 * @itv Interval of time in 1/100th of a second.
366 * @xds Structure with extended statistics.
367 ***************************************************************************
369 void compute_ext_disk_stats(struct stats_disk *sdc, struct stats_disk *sdp,
370 unsigned long long itv, struct ext_disk_stats *xds)
372 xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
374 * Kernel gives ticks already in milliseconds for all platforms
375 * => no need for further scaling.
377 xds->await = (sdc->nr_ios - sdp->nr_ios) ?
378 ((sdc->rd_ticks - sdp->rd_ticks) + (sdc->wr_ticks - sdp->wr_ticks) + (sdc->dc_ticks - sdp->dc_ticks)) /
379 ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
380 xds->arqsz = (sdc->nr_ios - sdp->nr_ios) ?
381 ((sdc->rd_sect - sdp->rd_sect) + (sdc->wr_sect - sdp->wr_sect) + (sdc->dc_sect - sdp->dc_sect)) /
382 ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
386 ***************************************************************************
387 * Since ticks may vary slightly from CPU to CPU, we'll want
388 * to recalculate itv based on this CPU's tick count, rather
389 * than that reported by the "cpu" line. Otherwise we
390 * occasionally end up with slightly skewed figures, with
391 * the skew being greater as the time interval grows shorter.
394 * @scc Current sample statistics for current CPU.
395 * @scp Previous sample statistics for current CPU.
398 * Interval of time based on current CPU, expressed in jiffies.
399 ***************************************************************************
401 unsigned long long get_per_cpu_interval(struct stats_cpu *scc,
402 struct stats_cpu *scp)
404 unsigned long long ishift = 0LL;
406 if ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest)) {
408 * Sometimes the nr of jiffies spent in guest mode given by the guest
409 * counter in /proc/stat is slightly higher than that included in
410 * the user counter. Update the interval value accordingly.
412 ishift += (scp->cpu_user - scp->cpu_guest) -
413 (scc->cpu_user - scc->cpu_guest);
415 if ((scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice)) {
417 * Idem for nr of jiffies spent in guest_nice mode.
419 ishift += (scp->cpu_nice - scp->cpu_guest_nice) -
420 (scc->cpu_nice - scc->cpu_guest_nice);
424 * Workaround for CPU coming back online: With recent kernels
425 * some fields (user, nice, system) restart from their previous value,
426 * whereas others (idle, iowait) restart from zero.
427 * For the latter we need to set their previous value to zero to
428 * avoid getting an interval value < 0.
429 * (I don't know how the other fields like hardirq, steal... behave).
430 * Don't assume the CPU has come back from offline state if previous
431 * value was greater than ULLONG_MAX - 0x7ffff (the counter probably
434 if ((scc->cpu_idle < scp->cpu_idle) && (scp->cpu_idle < (ULLONG_MAX - 0x7ffff))) {
437 if ((scc->cpu_iowait < scp->cpu_iowait) && (scp->cpu_iowait < (ULLONG_MAX - 0x7ffff))) {
442 * Don't take cpu_guest and cpu_guest_nice into account
443 * because cpu_user and cpu_nice already include them.
445 return ((scc->cpu_user + scc->cpu_nice +
446 scc->cpu_sys + scc->cpu_iowait +
447 scc->cpu_idle + scc->cpu_steal +
448 scc->cpu_hardirq + scc->cpu_softirq) -
449 (scp->cpu_user + scp->cpu_nice +
450 scp->cpu_sys + scp->cpu_iowait +
451 scp->cpu_idle + scp->cpu_steal +
452 scp->cpu_hardirq + scp->cpu_softirq) +
457 /*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
460 ***************************************************************************
461 * Replace octal codes in string with their corresponding characters.
464 * @str String to parse.
467 * @str String with octal codes replaced with characters.
468 ***************************************************************************
470 void oct2chr(char *str)
477 while (i < len - 3) {
478 if ((str[i] == '\\') &&
479 (str[i + 1] >= '0') && (str[i + 1] <= '3') &&
480 (str[i + 2] >= '0') && (str[i + 2] <= '7') &&
481 (str[i + 3] >= '0') && (str[i + 3] <= '7')) {
482 /* Octal code found */
483 str[i] = (str[i + 1] - 48) * 64 +
484 (str[i + 2] - 48) * 8 +
486 for (j = i + 4; j <= len; j++) {
496 ***************************************************************************
497 * Read processes (tasks) creation and context switches statistics
501 * @st_pcsw Structure where stats will be saved.
504 * @st_pcsw Structure with statistics.
507 * 1 on success, 0 otherwise.
508 ***************************************************************************
510 __nr_t read_stat_pcsw(struct stats_pcsw *st_pcsw)
515 if ((fp = fopen(STAT, "r")) == NULL)
518 while (fgets(line, sizeof(line), fp) != NULL) {
520 if (!strncmp(line, "ctxt ", 5)) {
521 /* Read number of context switches */
522 sscanf(line + 5, "%llu", &st_pcsw->context_switch);
525 else if (!strncmp(line, "processes ", 10)) {
526 /* Read number of processes created since system boot */
527 sscanf(line + 10, "%lu", &st_pcsw->processes);
536 ***************************************************************************
537 * Read queue and load statistics from /proc/loadavg and /proc/stat.
540 * @st_queue Structure where stats will be saved.
543 * @st_queue Structure with statistics.
546 * 1 on success, 0 otherwise.
547 ***************************************************************************
549 __nr_t read_loadavg(struct stats_queue *st_queue)
553 unsigned int load_tmp[3];
556 if ((fp = fopen(LOADAVG, "r")) == NULL)
559 /* Read load averages and queue length */
560 rc = fscanf(fp, "%u.%u %u.%u %u.%u %llu/%llu %*d\n",
561 &load_tmp[0], &st_queue->load_avg_1,
562 &load_tmp[1], &st_queue->load_avg_5,
563 &load_tmp[2], &st_queue->load_avg_15,
564 &st_queue->nr_running,
565 &st_queue->nr_threads);
572 st_queue->load_avg_1 += load_tmp[0] * 100;
573 st_queue->load_avg_5 += load_tmp[1] * 100;
574 st_queue->load_avg_15 += load_tmp[2] * 100;
576 if (st_queue->nr_running) {
577 /* Do not take current process into account */
578 st_queue->nr_running--;
581 /* Read nr of tasks blocked from /proc/stat */
582 if ((fp = fopen(STAT, "r")) == NULL)
585 while (fgets(line, sizeof(line), fp) != NULL) {
587 if (!strncmp(line, "procs_blocked ", 14)) {
588 /* Read number of processes blocked */
589 sscanf(line + 14, "%llu", &st_queue->procs_blocked);
599 ***************************************************************************
600 * Read swapping statistics from /proc/vmstat.
603 * @st_swap Structure where stats will be saved.
606 * @st_swap Structure with statistics.
609 * 1 on success, 0 otherwise.
610 ***************************************************************************
612 __nr_t read_vmstat_swap(struct stats_swap *st_swap)
617 if ((fp = fopen(VMSTAT, "r")) == NULL)
620 while (fgets(line, sizeof(line), fp) != NULL) {
622 if (!strncmp(line, "pswpin ", 7)) {
623 /* Read number of swap pages brought in */
624 sscanf(line + 7, "%lu", &st_swap->pswpin);
626 else if (!strncmp(line, "pswpout ", 8)) {
627 /* Read number of swap pages brought out */
628 sscanf(line + 8, "%lu", &st_swap->pswpout);
637 ***************************************************************************
638 * Read paging statistics from /proc/vmstat.
641 * @st_paging Structure where stats will be saved.
644 * @st_paging Structure with statistics.
647 * 1 on success, 0 otherwise.
648 ***************************************************************************
650 __nr_t read_vmstat_paging(struct stats_paging *st_paging)
656 if ((fp = fopen(VMSTAT, "r")) == NULL)
659 st_paging->pgsteal = 0;
660 st_paging->pgscan_kswapd = st_paging->pgscan_direct = 0;
662 while (fgets(line, sizeof(line), fp) != NULL) {
664 if (!strncmp(line, "pgpgin ", 7)) {
665 /* Read number of pages the system paged in */
666 sscanf(line + 7, "%lu", &st_paging->pgpgin);
668 else if (!strncmp(line, "pgpgout ", 8)) {
669 /* Read number of pages the system paged out */
670 sscanf(line + 8, "%lu", &st_paging->pgpgout);
672 else if (!strncmp(line, "pgfault ", 8)) {
673 /* Read number of faults (major+minor) made by the system */
674 sscanf(line + 8, "%lu", &st_paging->pgfault);
676 else if (!strncmp(line, "pgmajfault ", 11)) {
677 /* Read number of faults (major only) made by the system */
678 sscanf(line + 11, "%lu", &st_paging->pgmajfault);
680 else if (!strncmp(line, "pgfree ", 7)) {
681 /* Read number of pages freed by the system */
682 sscanf(line + 7, "%lu", &st_paging->pgfree);
684 else if (!strncmp(line, "pgsteal_", 8)) {
685 /* Read number of pages stolen by the system */
686 sscanf(strchr(line, ' '), "%lu", &pgtmp);
687 st_paging->pgsteal += pgtmp;
689 else if (!strncmp(line, "pgscan_kswapd", 13)) {
690 /* Read number of pages scanned by the kswapd daemon */
691 sscanf(strchr(line, ' '), "%lu", &pgtmp);
692 st_paging->pgscan_kswapd += pgtmp;
694 else if (!strncmp(line, "pgscan_direct", 13)) {
695 /* Read number of pages scanned directly */
696 sscanf(strchr(line, ' '), "%lu", &pgtmp);
697 st_paging->pgscan_direct += pgtmp;
706 ***************************************************************************
707 * Read I/O and transfer rates statistics from /proc/diskstats.
710 * @st_io Structure where stats will be saved.
713 * @st_io Structure with statistics.
716 * 1 on success, 0 otherwise.
717 ***************************************************************************
719 __nr_t read_diskstats_io(struct stats_io *st_io)
723 char dev_name[MAX_NAME_LEN];
724 unsigned int major, minor;
725 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
727 if ((fp = fopen(DISKSTATS, "r")) == NULL)
730 while (fgets(line, sizeof(line), fp) != NULL) {
732 if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu",
733 &major, &minor, dev_name,
734 &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) {
736 if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) {
738 * OK: It's a (real) device and not a partition.
739 * Note: Structure should have been initialized first!
741 st_io->dk_drive += (unsigned long long) rd_ios + (unsigned long long) wr_ios;
742 st_io->dk_drive_rio += rd_ios;
743 st_io->dk_drive_rblk += rd_sec;
744 st_io->dk_drive_wio += wr_ios;
745 st_io->dk_drive_wblk += wr_sec;
755 ***************************************************************************
756 * Read block devices statistics from /proc/diskstats.
759 * @st_disk Structure where stats will be saved.
760 * @nr_alloc Total number of structures allocated. Value is >= 1.
761 * @read_part True if disks *and* partitions should be read; False if only
765 * @st_disk Structure with statistics.
768 * Number of block devices read, or -1 if the buffer was too small and
769 * needs to be reallocated.
770 ***************************************************************************
772 __nr_t read_diskstats_disk(struct stats_disk *st_disk, __nr_t nr_alloc,
777 char dev_name[MAX_NAME_LEN];
778 struct stats_disk *st_disk_i;
779 unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks;
780 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
783 if ((fp = fopen(DISKSTATS, "r")) == NULL)
786 while (fgets(line, sizeof(line), fp) != NULL) {
788 if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu"
790 &major, &minor, dev_name,
791 &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks,
792 &tot_ticks, &rq_ticks) == 11) {
794 if (!rd_ios && !wr_ios)
795 /* Unused device: Ignore it */
797 if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) {
799 if (dsk_read + 1 > nr_alloc) {
804 st_disk_i = st_disk + dsk_read++;
805 st_disk_i->major = major;
806 st_disk_i->minor = minor;
807 st_disk_i->nr_ios = (unsigned long long) rd_ios + (unsigned long long) wr_ios;
808 st_disk_i->rd_sect = rd_sec;
809 st_disk_i->wr_sect = wr_sec;
810 st_disk_i->rd_ticks = rd_ticks;
811 st_disk_i->wr_ticks = wr_ticks;
812 st_disk_i->tot_ticks = tot_ticks;
813 st_disk_i->rq_ticks = rq_ticks;
823 ***************************************************************************
824 * Read serial lines statistics from /proc/tty/driver/serial.
827 * @st_serial Structure where stats will be saved.
828 * @nr_alloc Total number of structures allocated. Value is >= 1.
831 * @st_serial Structure with statistics.
834 * Number of serial lines read, or -1 if the buffer was too small and
835 * needs to be reallocated.
836 ***************************************************************************
838 __nr_t read_tty_driver_serial(struct stats_serial *st_serial, __nr_t nr_alloc)
841 struct stats_serial *st_serial_i;
846 if ((fp = fopen(SERIAL, "r")) == NULL)
849 while (fgets(line, sizeof(line), fp) != NULL ) {
851 if ((p = strstr(line, "tx:")) != NULL) {
853 if (sl_read + 1 > nr_alloc) {
858 st_serial_i = st_serial + sl_read++;
859 /* Read serial line number */
860 sscanf(line, "%u", &st_serial_i->line);
862 * Read the number of chars transmitted and received by
863 * current serial line.
865 sscanf(p + 3, "%u", &st_serial_i->tx);
866 if ((p = strstr(line, "rx:")) != NULL) {
867 sscanf(p + 3, "%u", &st_serial_i->rx);
869 if ((p = strstr(line, "fe:")) != NULL) {
870 sscanf(p + 3, "%u", &st_serial_i->frame);
872 if ((p = strstr(line, "pe:")) != NULL) {
873 sscanf(p + 3, "%u", &st_serial_i->parity);
875 if ((p = strstr(line, "brk:")) != NULL) {
876 sscanf(p + 4, "%u", &st_serial_i->brk);
878 if ((p = strstr(line, "oe:")) != NULL) {
879 sscanf(p + 3, "%u", &st_serial_i->overrun);
889 ***************************************************************************
890 * Read kernel tables statistics from various system files.
893 * @st_ktables Structure where stats will be saved.
896 * @st_ktables Structure with statistics.
899 * 1 (always success).
900 ***************************************************************************
902 __nr_t read_kernel_tables(struct stats_ktables *st_ktables)
905 unsigned long long parm;
908 /* Open /proc/sys/fs/dentry-state file */
909 if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) {
910 rc = fscanf(fp, "%*d %llu",
911 &st_ktables->dentry_stat);
914 st_ktables->dentry_stat = 0;
918 /* Open /proc/sys/fs/file-nr file */
919 if ((fp = fopen(FFILE_NR, "r")) != NULL) {
920 rc = fscanf(fp, "%llu %llu",
921 &st_ktables->file_used, &parm);
924 * The number of used handles is the number of allocated ones
925 * minus the number of free ones.
928 st_ktables->file_used -= parm;
931 st_ktables->file_used = 0;
935 /* Open /proc/sys/fs/inode-state file */
936 if ((fp = fopen(FINODE_STATE, "r")) != NULL) {
937 rc = fscanf(fp, "%llu %llu",
938 &st_ktables->inode_used, &parm);
941 * The number of inuse inodes is the number of allocated ones
942 * minus the number of free ones.
945 st_ktables->inode_used -= parm;
948 st_ktables->inode_used = 0;
952 /* Open /proc/sys/kernel/pty/nr file */
953 if ((fp = fopen(PTY_NR, "r")) != NULL) {
954 rc = fscanf(fp, "%llu",
955 &st_ktables->pty_nr);
958 st_ktables->pty_nr = 0;
966 ***************************************************************************
967 * Read network interfaces statistics from /proc/net/dev.
970 * @st_net_dev Structure where stats will be saved.
971 * @nr_alloc Total number of structures allocated. Value is >= 1.
974 * @st_net_dev Structure with statistics.
977 * Number of interfaces read, or -1 if the buffer was too small and
978 * needs to be reallocated.
979 ***************************************************************************
981 __nr_t read_net_dev(struct stats_net_dev *st_net_dev, __nr_t nr_alloc)
984 struct stats_net_dev *st_net_dev_i;
986 char iface[MAX_IFACE_LEN];
990 if ((fp = fopen(NET_DEV, "r")) == NULL)
993 while (fgets(line, sizeof(line), fp) != NULL) {
995 pos = strcspn(line, ":");
996 if (pos < strlen(line)) {
998 if (dev_read + 1 > nr_alloc) {
1003 st_net_dev_i = st_net_dev + dev_read++;
1004 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1005 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1006 sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */
1007 sscanf(line + pos + 1, "%llu %llu %*u %*u %*u %*u %llu %llu %llu %llu "
1008 "%*u %*u %*u %*u %*u %llu",
1009 &st_net_dev_i->rx_bytes,
1010 &st_net_dev_i->rx_packets,
1011 &st_net_dev_i->rx_compressed,
1012 &st_net_dev_i->multicast,
1013 &st_net_dev_i->tx_bytes,
1014 &st_net_dev_i->tx_packets,
1015 &st_net_dev_i->tx_compressed);
1024 ***************************************************************************
1025 * Read duplex and speed data for network interface cards.
1028 * @st_net_dev Structure where stats will be saved.
1029 * @nbr Number of network interfaces to read.
1032 * @st_net_dev Structure with statistics.
1033 ***************************************************************************
1035 void read_if_info(struct stats_net_dev *st_net_dev, int nbr)
1038 struct stats_net_dev *st_net_dev_i;
1039 char filename[128], duplex[32];
1042 for (dev = 0; dev < nbr; dev++) {
1044 st_net_dev_i = st_net_dev + dev;
1046 /* Read speed info */
1047 sprintf(filename, IF_DUPLEX, st_net_dev_i->interface);
1049 if ((fp = fopen(filename, "r")) == NULL)
1050 /* Cannot read NIC duplex */
1053 n = fscanf(fp, "%31s", duplex);
1058 /* Cannot read NIC duplex */
1061 if (!strcmp(duplex, K_DUPLEX_FULL)) {
1062 st_net_dev_i->duplex = C_DUPLEX_FULL;
1064 else if (!strcmp(duplex, K_DUPLEX_HALF)) {
1065 st_net_dev_i->duplex = C_DUPLEX_HALF;
1070 /* Read speed info */
1071 sprintf(filename, IF_SPEED, st_net_dev_i->interface);
1073 if ((fp = fopen(filename, "r")) == NULL)
1074 /* Cannot read NIC speed */
1077 n = fscanf(fp, "%u", &st_net_dev_i->speed);
1082 st_net_dev_i->speed = 0;
1089 ***************************************************************************
1090 * Read network interfaces errors statistics from /proc/net/dev.
1093 * @st_net_edev Structure where stats will be saved.
1094 * @nr_alloc Total number of structures allocated. Value is >= 1.
1097 * @st_net_edev Structure with statistics.
1100 * Number of interfaces read, or -1 if the buffer was too small and
1101 * needs to be reallocated.
1102 ***************************************************************************
1104 __nr_t read_net_edev(struct stats_net_edev *st_net_edev, __nr_t nr_alloc)
1107 struct stats_net_edev *st_net_edev_i;
1108 static char line[256];
1109 char iface[MAX_IFACE_LEN];
1110 __nr_t dev_read = 0;
1113 if ((fp = fopen(NET_DEV, "r")) == NULL)
1116 while (fgets(line, sizeof(line), fp) != NULL) {
1118 pos = strcspn(line, ":");
1119 if (pos < strlen(line)) {
1121 if (dev_read + 1 > nr_alloc) {
1126 st_net_edev_i = st_net_edev + dev_read++;
1127 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1128 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1129 sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */
1130 sscanf(line + pos + 1, "%*u %*u %llu %llu %llu %llu %*u %*u %*u %*u "
1131 "%llu %llu %llu %llu %llu",
1132 &st_net_edev_i->rx_errors,
1133 &st_net_edev_i->rx_dropped,
1134 &st_net_edev_i->rx_fifo_errors,
1135 &st_net_edev_i->rx_frame_errors,
1136 &st_net_edev_i->tx_errors,
1137 &st_net_edev_i->tx_dropped,
1138 &st_net_edev_i->tx_fifo_errors,
1139 &st_net_edev_i->collisions,
1140 &st_net_edev_i->tx_carrier_errors);
1149 ***************************************************************************
1150 * Read NFS client statistics from /proc/net/rpc/nfs.
1153 * @st_net_nfs Structure where stats will be saved.
1156 * @st_net_nfs Structure with statistics.
1159 * 1 on success, 0 otherwise.
1160 ***************************************************************************
1162 __nr_t read_net_nfs(struct stats_net_nfs *st_net_nfs)
1166 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1168 if ((fp = fopen(NET_RPC_NFS, "r")) == NULL)
1171 memset(st_net_nfs, 0, STATS_NET_NFS_SIZE);
1173 while (fgets(line, sizeof(line), fp) != NULL) {
1175 if (!strncmp(line, "rpc ", 4)) {
1176 sscanf(line + 4, "%u %u",
1177 &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans);
1179 else if (!strncmp(line, "proc3 ", 6)) {
1180 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1181 &getattcnt, &accesscnt, &readcnt, &writecnt);
1183 st_net_nfs->nfs_getattcnt += getattcnt;
1184 st_net_nfs->nfs_accesscnt += accesscnt;
1185 st_net_nfs->nfs_readcnt += readcnt;
1186 st_net_nfs->nfs_writecnt += writecnt;
1188 else if (!strncmp(line, "proc4 ", 6)) {
1189 sscanf(line + 6, "%*u %*u %u %u "
1190 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u",
1191 &readcnt, &writecnt, &accesscnt, &getattcnt);
1193 st_net_nfs->nfs_getattcnt += getattcnt;
1194 st_net_nfs->nfs_accesscnt += accesscnt;
1195 st_net_nfs->nfs_readcnt += readcnt;
1196 st_net_nfs->nfs_writecnt += writecnt;
1205 ***************************************************************************
1206 * Read NFS server statistics from /proc/net/rpc/nfsd.
1209 * @st_net_nfsd Structure where stats will be saved.
1212 * @st_net_nfsd Structure with statistics.
1215 * 1 on success, 0 otherwise.
1216 ***************************************************************************
1218 __nr_t read_net_nfsd(struct stats_net_nfsd *st_net_nfsd)
1222 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1224 if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL)
1227 memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE);
1229 while (fgets(line, sizeof(line), fp) != NULL) {
1231 if (!strncmp(line, "rc ", 3)) {
1232 sscanf(line + 3, "%u %u",
1233 &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses);
1235 else if (!strncmp(line, "net ", 4)) {
1236 sscanf(line + 4, "%u %u %u",
1237 &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt,
1238 &st_net_nfsd->nfsd_nettcpcnt);
1240 else if (!strncmp(line, "rpc ", 4)) {
1241 sscanf(line + 4, "%u %u",
1242 &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad);
1244 else if (!strncmp(line, "proc3 ", 6)) {
1245 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1246 &getattcnt, &accesscnt, &readcnt, &writecnt);
1248 st_net_nfsd->nfsd_getattcnt += getattcnt;
1249 st_net_nfsd->nfsd_accesscnt += accesscnt;
1250 st_net_nfsd->nfsd_readcnt += readcnt;
1251 st_net_nfsd->nfsd_writecnt += writecnt;
1254 else if (!strncmp(line, "proc4ops ", 9)) {
1255 sscanf(line + 9, "%*u %*u %*u %*u %u "
1256 "%*u %*u %*u %*u %*u %u "
1257 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u "
1258 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
1259 &accesscnt, &getattcnt, &readcnt, &writecnt);
1261 st_net_nfsd->nfsd_getattcnt += getattcnt;
1262 st_net_nfsd->nfsd_accesscnt += accesscnt;
1263 st_net_nfsd->nfsd_readcnt += readcnt;
1264 st_net_nfsd->nfsd_writecnt += writecnt;
1273 ***************************************************************************
1274 * Read network sockets statistics from /proc/net/sockstat.
1277 * @st_net_sock Structure where stats will be saved.
1280 * @st_net_sock Structure with statistics.
1283 * 1 on success, 0 otherwise.
1284 ***************************************************************************
1286 __nr_t read_net_sock(struct stats_net_sock *st_net_sock)
1292 if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL)
1295 while (fgets(line, sizeof(line), fp) != NULL) {
1297 if (!strncmp(line, "sockets:", 8)) {
1299 sscanf(line + 14, "%u", &st_net_sock->sock_inuse);
1301 else if (!strncmp(line, "TCP:", 4)) {
1303 sscanf(line + 11, "%u", &st_net_sock->tcp_inuse);
1304 if ((p = strstr(line, "tw")) != NULL) {
1305 sscanf(p + 2, "%u", &st_net_sock->tcp_tw);
1308 else if (!strncmp(line, "UDP:", 4)) {
1310 sscanf(line + 11, "%u", &st_net_sock->udp_inuse);
1312 else if (!strncmp(line, "RAW:", 4)) {
1314 sscanf(line + 11, "%u", &st_net_sock->raw_inuse);
1316 else if (!strncmp(line, "FRAG:", 5)) {
1318 sscanf(line + 12, "%u", &st_net_sock->frag_inuse);
1327 ***************************************************************************
1328 * Read IP network traffic statistics from /proc/net/snmp.
1331 * @st_net_ip Structure where stats will be saved.
1334 * @st_net_ip Structure with statistics.
1337 * 1 on success, 0 otherwise.
1338 ***************************************************************************
1340 __nr_t read_net_ip(struct stats_net_ip *st_net_ip)
1346 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1349 while (fgets(line, sizeof(line), fp) != NULL) {
1351 if (!strncmp(line, "Ip:", 3)) {
1353 sscanf(line + 3, "%*u %*u %llu %*u %*u %llu %*u %*u "
1354 "%llu %llu %*u %*u %*u %llu %llu %*u %llu %*u %llu",
1355 &st_net_ip->InReceives,
1356 &st_net_ip->ForwDatagrams,
1357 &st_net_ip->InDelivers,
1358 &st_net_ip->OutRequests,
1359 &st_net_ip->ReasmReqds,
1360 &st_net_ip->ReasmOKs,
1361 &st_net_ip->FragOKs,
1362 &st_net_ip->FragCreates);
1377 ***************************************************************************
1378 * Read IP network errors statistics from /proc/net/snmp.
1381 * @st_net_eip Structure where stats will be saved.
1384 * @st_net_eip Structure with statistics.
1387 * 1 on success, 0 otherwise.
1388 ***************************************************************************
1390 __nr_t read_net_eip(struct stats_net_eip *st_net_eip)
1396 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1399 while (fgets(line, sizeof(line), fp) != NULL) {
1401 if (!strncmp(line, "Ip:", 3)) {
1403 sscanf(line + 3, "%*u %*u %*u %llu %llu %*u %llu %llu "
1404 "%*u %*u %llu %llu %*u %*u %*u %llu %*u %llu",
1405 &st_net_eip->InHdrErrors,
1406 &st_net_eip->InAddrErrors,
1407 &st_net_eip->InUnknownProtos,
1408 &st_net_eip->InDiscards,
1409 &st_net_eip->OutDiscards,
1410 &st_net_eip->OutNoRoutes,
1411 &st_net_eip->ReasmFails,
1412 &st_net_eip->FragFails);
1427 ***************************************************************************
1428 * Read ICMP network traffic statistics from /proc/net/snmp.
1431 * @st_net_icmp Structure where stats will be saved.
1434 * @st_net_icmp Structure with statistics.
1437 * 1 on success, 0 otherwise.
1438 ***************************************************************************
1440 __nr_t read_net_icmp(struct stats_net_icmp *st_net_icmp)
1444 static char format[256] = "";
1447 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1450 while (fgets(line, sizeof(line), fp) != NULL) {
1452 if (!strncmp(line, "Icmp:", 5)) {
1454 sscanf(line + 5, format,
1455 &st_net_icmp->InMsgs,
1456 &st_net_icmp->InEchos,
1457 &st_net_icmp->InEchoReps,
1458 &st_net_icmp->InTimestamps,
1459 &st_net_icmp->InTimestampReps,
1460 &st_net_icmp->InAddrMasks,
1461 &st_net_icmp->InAddrMaskReps,
1462 &st_net_icmp->OutMsgs,
1463 &st_net_icmp->OutEchos,
1464 &st_net_icmp->OutEchoReps,
1465 &st_net_icmp->OutTimestamps,
1466 &st_net_icmp->OutTimestampReps,
1467 &st_net_icmp->OutAddrMasks,
1468 &st_net_icmp->OutAddrMaskReps);
1473 if (!strlen(format)) {
1474 if (strstr(line, "InCsumErrors")) {
1476 * New format: InCsumErrors field exists at position #3.
1477 * Capture: 1,9,10,11,12,13,14,15,22,23,24,25,26,27.
1479 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u %*u "
1480 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1481 "%*u %*u %lu %lu %lu %lu %lu %lu");
1485 * Old format: InCsumErrors field doesn't exist.
1486 * Capture: 1,8,9,10,11,12,13,14,21,22,23,24,25,26.
1488 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u "
1489 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1490 "%*u %*u %lu %lu %lu %lu %lu %lu");
1503 ***************************************************************************
1504 * Read ICMP network errors statistics from /proc/net/snmp.
1507 * @st_net_eicmp Structure where stats will be saved.
1510 * @st_net_eicmp Structure with statistics.
1513 * 1 on success, 0 otherwise.
1514 ***************************************************************************
1516 __nr_t read_net_eicmp(struct stats_net_eicmp *st_net_eicmp)
1522 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1525 while (fgets(line, sizeof(line), fp) != NULL) {
1527 if (!strncmp(line, "Icmp:", 5)) {
1529 sscanf(line + 5, "%*u %lu %lu %lu %lu %lu %lu %*u %*u "
1530 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu",
1531 &st_net_eicmp->InErrors,
1532 &st_net_eicmp->InDestUnreachs,
1533 &st_net_eicmp->InTimeExcds,
1534 &st_net_eicmp->InParmProbs,
1535 &st_net_eicmp->InSrcQuenchs,
1536 &st_net_eicmp->InRedirects,
1537 &st_net_eicmp->OutErrors,
1538 &st_net_eicmp->OutDestUnreachs,
1539 &st_net_eicmp->OutTimeExcds,
1540 &st_net_eicmp->OutParmProbs,
1541 &st_net_eicmp->OutSrcQuenchs,
1542 &st_net_eicmp->OutRedirects);
1557 ***************************************************************************
1558 * Read TCP network traffic statistics from /proc/net/snmp.
1561 * @st_net_tcp Structure where stats will be saved.
1564 * @st_net_tcp Structure with statistics.
1567 * 1 on success, 0 otherwise.
1568 ***************************************************************************
1570 __nr_t read_net_tcp(struct stats_net_tcp *st_net_tcp)
1576 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1579 while (fgets(line, sizeof(line), fp) != NULL) {
1581 if (!strncmp(line, "Tcp:", 4)) {
1583 sscanf(line + 4, "%*u %*u %*u %*d %lu %lu "
1584 "%*u %*u %*u %lu %lu",
1585 &st_net_tcp->ActiveOpens,
1586 &st_net_tcp->PassiveOpens,
1587 &st_net_tcp->InSegs,
1588 &st_net_tcp->OutSegs);
1603 ***************************************************************************
1604 * Read TCP network errors statistics from /proc/net/snmp.
1607 * @st_net_etcp Structure where stats will be saved.
1610 * @st_net_etcp Structure with statistics.
1613 * 1 on success, 0 otherwise.
1614 ***************************************************************************
1616 __nr_t read_net_etcp(struct stats_net_etcp *st_net_etcp)
1622 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1625 while (fgets(line, sizeof(line), fp) != NULL) {
1627 if (!strncmp(line, "Tcp:", 4)) {
1629 sscanf(line + 4, "%*u %*u %*u %*d %*u %*u "
1630 "%lu %lu %*u %*u %*u %lu %lu %lu",
1631 &st_net_etcp->AttemptFails,
1632 &st_net_etcp->EstabResets,
1633 &st_net_etcp->RetransSegs,
1634 &st_net_etcp->InErrs,
1635 &st_net_etcp->OutRsts);
1650 ***************************************************************************
1651 * Read UDP network traffic statistics from /proc/net/snmp.
1654 * @st_net_udp Structure where stats will be saved.
1657 * @st_net_udp Structure with statistics.
1660 * 1 on success, 0 otherwise.
1661 ***************************************************************************
1663 __nr_t read_net_udp(struct stats_net_udp *st_net_udp)
1669 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1672 while (fgets(line, sizeof(line), fp) != NULL) {
1674 if (!strncmp(line, "Udp:", 4)) {
1676 sscanf(line + 4, "%lu %lu %lu %lu",
1677 &st_net_udp->InDatagrams,
1678 &st_net_udp->NoPorts,
1679 &st_net_udp->InErrors,
1680 &st_net_udp->OutDatagrams);
1695 ***************************************************************************
1696 * Read IPv6 network sockets statistics from /proc/net/sockstat6.
1699 * @st_net_sock6 Structure where stats will be saved.
1702 * @st_net_sock6 Structure with statistics.
1705 * 1 on success, 0 otherwise.
1706 ***************************************************************************
1708 __nr_t read_net_sock6(struct stats_net_sock6 *st_net_sock6)
1713 if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL)
1716 while (fgets(line, sizeof(line), fp) != NULL) {
1718 if (!strncmp(line, "TCP6:", 5)) {
1720 sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse);
1722 else if (!strncmp(line, "UDP6:", 5)) {
1724 sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse);
1726 else if (!strncmp(line, "RAW6:", 5)) {
1727 /* IPv6 RAW sockets */
1728 sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse);
1730 else if (!strncmp(line, "FRAG6:", 6)) {
1731 /* IPv6 FRAGments */
1732 sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse);
1741 ***************************************************************************
1742 * Read IPv6 network traffic statistics from /proc/net/snmp6.
1745 * @st_net_ip6 Structure where stats will be saved.
1748 * @st_net_ip6 Structure with statistics.
1751 * 1 on success, 0 otherwise.
1752 ***************************************************************************
1754 __nr_t read_net_ip6(struct stats_net_ip6 *st_net_ip6)
1759 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1762 while (fgets(line, sizeof(line), fp) != NULL) {
1764 if (!strncmp(line, "Ip6InReceives ", 14)) {
1765 sscanf(line + 14, "%llu", &st_net_ip6->InReceives6);
1767 else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) {
1768 sscanf(line + 20, "%llu", &st_net_ip6->OutForwDatagrams6);
1770 else if (!strncmp(line, "Ip6InDelivers ", 14)) {
1771 sscanf(line + 14, "%llu", &st_net_ip6->InDelivers6);
1773 else if (!strncmp(line, "Ip6OutRequests ", 15)) {
1774 sscanf(line + 15, "%llu", &st_net_ip6->OutRequests6);
1776 else if (!strncmp(line, "Ip6ReasmReqds ", 14)) {
1777 sscanf(line + 14, "%llu", &st_net_ip6->ReasmReqds6);
1779 else if (!strncmp(line, "Ip6ReasmOKs ", 12)) {
1780 sscanf(line + 12, "%llu", &st_net_ip6->ReasmOKs6);
1782 else if (!strncmp(line, "Ip6InMcastPkts ", 15)) {
1783 sscanf(line + 15, "%llu", &st_net_ip6->InMcastPkts6);
1785 else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) {
1786 sscanf(line + 16, "%llu", &st_net_ip6->OutMcastPkts6);
1788 else if (!strncmp(line, "Ip6FragOKs ", 11)) {
1789 sscanf(line + 11, "%llu", &st_net_ip6->FragOKs6);
1791 else if (!strncmp(line, "Ip6FragCreates ", 15)) {
1792 sscanf(line + 15, "%llu", &st_net_ip6->FragCreates6);
1801 ***************************************************************************
1802 * Read IPv6 network errors statistics from /proc/net/snmp6.
1805 * @st_net_eip6 Structure where stats will be saved.
1808 * @st_net_eip6 Structure with statistics.
1811 * 1 on success, 0 otherwise.
1812 ***************************************************************************
1814 __nr_t read_net_eip6(struct stats_net_eip6 *st_net_eip6)
1819 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1822 while (fgets(line, sizeof(line), fp) != NULL) {
1824 if (!strncmp(line, "Ip6InHdrErrors ", 15)) {
1825 sscanf(line + 15, "%llu", &st_net_eip6->InHdrErrors6);
1827 else if (!strncmp(line, "Ip6InAddrErrors ", 16)) {
1828 sscanf(line + 16, "%llu", &st_net_eip6->InAddrErrors6);
1830 else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) {
1831 sscanf(line + 19, "%llu", &st_net_eip6->InUnknownProtos6);
1833 else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) {
1834 sscanf(line + 18, "%llu", &st_net_eip6->InTooBigErrors6);
1836 else if (!strncmp(line, "Ip6InDiscards ", 14)) {
1837 sscanf(line + 14, "%llu", &st_net_eip6->InDiscards6);
1839 else if (!strncmp(line, "Ip6OutDiscards ", 15)) {
1840 sscanf(line + 15, "%llu", &st_net_eip6->OutDiscards6);
1842 else if (!strncmp(line, "Ip6InNoRoutes ", 14)) {
1843 sscanf(line + 14, "%llu", &st_net_eip6->InNoRoutes6);
1845 else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) {
1846 sscanf(line + 15, "%llu", &st_net_eip6->OutNoRoutes6);
1848 else if (!strncmp(line, "Ip6ReasmFails ", 14)) {
1849 sscanf(line + 14, "%llu", &st_net_eip6->ReasmFails6);
1851 else if (!strncmp(line, "Ip6FragFails ", 13)) {
1852 sscanf(line + 13, "%llu", &st_net_eip6->FragFails6);
1854 else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) {
1855 sscanf(line + 19, "%llu", &st_net_eip6->InTruncatedPkts6);
1864 ***************************************************************************
1865 * Read ICMPv6 network traffic statistics from /proc/net/snmp6.
1868 * @st_net_icmp6 Structure where stats will be saved.
1871 * @st_net_icmp6 Structure with statistics.
1874 * 1 on success, 0 otherwise.
1875 ***************************************************************************
1877 __nr_t read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6)
1882 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1885 while (fgets(line, sizeof(line), fp) != NULL) {
1887 if (!strncmp(line, "Icmp6InMsgs ", 12)) {
1888 sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6);
1890 else if (!strncmp(line, "Icmp6OutMsgs ", 13)) {
1891 sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6);
1893 else if (!strncmp(line, "Icmp6InEchos ", 13)) {
1894 sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6);
1896 else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) {
1897 sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6);
1899 else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) {
1900 sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6);
1902 else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) {
1903 sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6);
1905 else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) {
1906 sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6);
1908 else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) {
1909 sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6);
1911 else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) {
1912 sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6);
1914 else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) {
1915 sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6);
1917 else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) {
1918 sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6);
1920 else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) {
1921 sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6);
1923 else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) {
1924 sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6);
1926 else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) {
1927 sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6);
1929 else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) {
1930 sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6);
1932 else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) {
1933 sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6);
1935 else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) {
1936 sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6);
1945 ***************************************************************************
1946 * Read ICMPv6 network errors statistics from /proc/net/snmp6.
1949 * @st_net_eicmp6 Structure where stats will be saved.
1952 * @st_net_eicmp6 Structure with statistics.
1955 * 1 on success, 0 otherwise.
1956 ***************************************************************************
1958 __nr_t read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6)
1963 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1966 while (fgets(line, sizeof(line), fp) != NULL) {
1968 if (!strncmp(line, "Icmp6InErrors ", 14)) {
1969 sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6);
1971 else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) {
1972 sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6);
1974 else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) {
1975 sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6);
1977 else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) {
1978 sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6);
1980 else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) {
1981 sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6);
1983 else if (!strncmp(line, "Icmp6InParmProblems ", 20)) {
1984 sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6);
1986 else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) {
1987 sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6);
1989 else if (!strncmp(line, "Icmp6InRedirects ", 17)) {
1990 sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6);
1992 else if (!strncmp(line, "Icmp6OutRedirects ", 18)) {
1993 sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6);
1995 else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) {
1996 sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6);
1998 else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) {
1999 sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6);
2008 ***************************************************************************
2009 * Read UDPv6 network traffic statistics from /proc/net/snmp6.
2012 * @st_net_udp6 Structure where stats will be saved.
2015 * @st_net_udp6 Structure with statistics.
2018 * 1 on success, 0 otherwise.
2019 ***************************************************************************
2021 __nr_t read_net_udp6(struct stats_net_udp6 *st_net_udp6)
2026 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
2029 while (fgets(line, sizeof(line), fp) != NULL) {
2031 if (!strncmp(line, "Udp6InDatagrams ", 16)) {
2032 sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6);
2034 else if (!strncmp(line, "Udp6OutDatagrams ", 17)) {
2035 sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6);
2037 else if (!strncmp(line, "Udp6NoPorts ", 12)) {
2038 sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6);
2040 else if (!strncmp(line, "Udp6InErrors ", 13)) {
2041 sscanf(line + 13, "%lu", &st_net_udp6->InErrors6);
2050 ***************************************************************************
2051 * Read CPU frequency statistics.
2054 * @st_pwr_cpufreq Structure where stats will be saved.
2055 * @nr_alloc Total number of structures allocated. Value is >= 1.
2058 * @st_pwr_cpufreq Structure with statistics.
2061 * Highest CPU number for which statistics have been read.
2062 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
2063 * Or -1 if the buffer was too small and needs to be reallocated.
2064 ***************************************************************************
2066 __nr_t read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, __nr_t nr_alloc)
2069 struct stats_pwr_cpufreq *st_pwr_cpufreq_i;
2072 __nr_t cpu_read = 1; /* For CPU "all" */
2073 unsigned int proc_nr = 0, ifreq, dfreq;
2075 if ((fp = fopen(CPUINFO, "r")) == NULL)
2078 st_pwr_cpufreq->cpufreq = 0;
2080 while (fgets(line, sizeof(line), fp) != NULL) {
2082 if (!strncmp(line, "processor\t", 10)) {
2083 sscanf(strchr(line, ':') + 1, "%u", &proc_nr);
2085 if (proc_nr + 2 > nr_alloc) {
2091 /* Entry in /proc/cpuinfo is different between Intel and Power architectures */
2092 else if (!strncmp(line, "cpu MHz\t", 8) ||
2093 !strncmp(line, "clock\t", 6)) {
2094 sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq);
2096 /* Save current CPU frequency */
2097 st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nr + 1;
2098 st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10;
2100 /* Also save it to compute an average CPU frequency */
2101 st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq;
2104 if (proc_nr + 2 > cpu_read) {
2105 cpu_read = proc_nr + 2;
2113 /* Compute average CPU frequency for this machine */
2114 st_pwr_cpufreq->cpufreq /= nr;
2120 ***************************************************************************
2121 * Read hugepages statistics from /proc/meminfo.
2124 * @st_huge Structure where stats will be saved.
2127 * @st_huge Structure with statistics.
2130 * 1 on success, 0 otherwise.
2131 ***************************************************************************
2133 __nr_t read_meminfo_huge(struct stats_huge *st_huge)
2137 unsigned long szhkb = 0;
2139 if ((fp = fopen(MEMINFO, "r")) == NULL)
2142 while (fgets(line, sizeof(line), fp) != NULL) {
2144 if (!strncmp(line, "HugePages_Total:", 16)) {
2145 /* Read the total number of huge pages */
2146 sscanf(line + 16, "%llu", &st_huge->tlhkb);
2148 else if (!strncmp(line, "HugePages_Free:", 15)) {
2149 /* Read the number of free huge pages */
2150 sscanf(line + 15, "%llu", &st_huge->frhkb);
2152 else if (!strncmp(line, "HugePages_Rsvd:", 15)) {
2153 /* Read the number of reserved huge pages */
2154 sscanf(line + 15, "%llu", &st_huge->rsvdhkb);
2156 else if (!strncmp(line, "HugePages_Surp:", 15)) {
2157 /* Read the number of surplus huge pages */
2158 sscanf(line + 15, "%llu", &st_huge->surphkb);
2160 else if (!strncmp(line, "Hugepagesize:", 13)) {
2161 /* Read the default size of a huge page in kB */
2162 sscanf(line + 13, "%lu", &szhkb);
2168 /* We want huge pages stats in kB and not expressed in a number of pages */
2169 st_huge->tlhkb *= szhkb;
2170 st_huge->frhkb *= szhkb;
2171 st_huge->rsvdhkb *= szhkb;
2172 st_huge->surphkb *= szhkb;
2178 ***************************************************************************
2179 * Read CPU average frequencies statistics.
2182 * @st_pwr_wghfreq Structure where stats will be saved.
2183 * @cpu_nr CPU number for which time_in_state date will be read.
2184 * @nbr Total number of states (frequencies).
2187 * @st_pwr_wghfreq Structure with statistics.
2190 * 1 on success, 0 otherwise.
2191 ***************************************************************************
2193 int read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr)
2196 struct stats_pwr_wghfreq *st_pwr_wghfreq_j;
2197 char filename[MAX_PF_NAME];
2201 unsigned long long time_in_state;
2203 snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s",
2204 SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE);
2205 if ((fp = fopen(filename, "r")) == NULL)
2208 while (fgets(line, sizeof(line), fp) != NULL) {
2210 sscanf(line, "%lu %llu", &freq, &time_in_state);
2213 /* Save current frequency and time */
2214 st_pwr_wghfreq_j = st_pwr_wghfreq + j;
2215 st_pwr_wghfreq_j->freq = freq;
2216 st_pwr_wghfreq_j->time_in_state = time_in_state;
2226 ***************************************************************************
2227 * Read weighted CPU frequency statistics.
2230 * @st_pwr_wghfreq Structure where stats will be saved.
2231 * @nr_alloc Total number of structures allocated. Value is >= 0.
2232 * @nr2 Number of sub-items allocated per structure.
2235 * @st_pwr_wghfreq Structure with statistics.
2238 * Number of CPU for which statistics have been read.
2239 * 1 means CPU "all", 2 means CPU "all" and 0, etc.
2240 * Or -1 if the buffer was to small and needs to be reallocated.
2241 ***************************************************************************
2243 __nr_t read_cpu_wghfreq(struct stats_pwr_wghfreq *st_pwr_wghfreq, __nr_t nr_alloc,
2246 __nr_t cpu_read = 0;
2248 struct stats_pwr_wghfreq *st_pwr_wghfreq_i, *st_pwr_wghfreq_j, *st_pwr_wghfreq_all_j;
2251 if (cpu_read + 2 > nr_alloc)
2254 /* Read current CPU time-in-state data */
2255 st_pwr_wghfreq_i = st_pwr_wghfreq + (cpu_read + 1) * nr2;
2256 if (!read_time_in_state(st_pwr_wghfreq_i, cpu_read, nr2))
2259 /* Also save data for CPU 'all' */
2260 for (j = 0; j < nr2; j++) {
2261 st_pwr_wghfreq_j = st_pwr_wghfreq_i + j; /* CPU #cpu, state #j */
2262 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2264 /* Assume that possible frequencies are the same for all CPUs */
2265 st_pwr_wghfreq_all_j->freq = st_pwr_wghfreq_j->freq;
2267 st_pwr_wghfreq_all_j->time_in_state += st_pwr_wghfreq_j->time_in_state;
2274 for (j = 0; j < nr2; j++) {
2275 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2276 st_pwr_wghfreq_all_j->time_in_state /= cpu_read;
2279 return cpu_read + 1; /* For CPU "all" */
2286 ***************************************************************************
2287 * Read current USB device data.
2290 * @st_pwr_usb Structure where stats will be saved.
2291 * @usb_device File name for current USB device.
2294 * @st_pwr_usb Structure with statistics.
2295 ***************************************************************************
2297 void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
2302 char filename[MAX_PF_NAME];
2304 /* Get USB device bus number */
2305 sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
2307 /* Read USB device vendor ID */
2308 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2309 SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
2310 if ((fp = fopen(filename, "r")) != NULL) {
2311 rc = fscanf(fp, "%x",
2312 &st_pwr_usb->vendor_id);
2315 st_pwr_usb->vendor_id = 0;
2319 /* Read USB device product ID */
2320 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2321 SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
2322 if ((fp = fopen(filename, "r")) != NULL) {
2323 rc = fscanf(fp, "%x",
2324 &st_pwr_usb->product_id);
2327 st_pwr_usb->product_id = 0;
2331 /* Read USB device max power consumption */
2332 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2333 SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
2334 if ((fp = fopen(filename, "r")) != NULL) {
2335 rc = fscanf(fp, "%u",
2336 &st_pwr_usb->bmaxpower);
2339 st_pwr_usb->bmaxpower = 0;
2343 /* Read USB device manufacturer */
2344 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2345 SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
2346 if ((fp = fopen(filename, "r")) != NULL) {
2347 rs = fgets(st_pwr_usb->manufacturer,
2348 MAX_MANUF_LEN - 1, fp);
2351 (l = strlen(st_pwr_usb->manufacturer)) > 0) {
2352 /* Remove trailing CR */
2353 st_pwr_usb->manufacturer[l - 1] = '\0';
2357 /* Read USB device product */
2358 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2359 SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
2360 if ((fp = fopen(filename, "r")) != NULL) {
2361 rs = fgets(st_pwr_usb->product,
2362 MAX_PROD_LEN - 1, fp);
2365 (l = strlen(st_pwr_usb->product)) > 0) {
2366 /* Remove trailing CR */
2367 st_pwr_usb->product[l - 1] = '\0';
2373 ***************************************************************************
2374 * Read USB devices statistics.
2377 * @st_pwr_usb Structure where stats will be saved.
2378 * @nr_alloc Total number of structures allocated. Value is >= 0.
2381 * @st_pwr_usb Structure with statistics.
2384 * Number of USB devices read, or -1 if the buffer was too small and
2385 * needs to be reallocated.
2386 ***************************************************************************
2388 __nr_t read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, __nr_t nr_alloc)
2392 struct stats_pwr_usb *st_pwr_usb_i;
2393 __nr_t usb_read = 0;
2395 /* Open relevant /sys directory */
2396 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
2399 /* Get current file entry */
2400 while ((drd = readdir(dir)) != NULL) {
2402 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
2404 if (usb_read + 1 > nr_alloc) {
2409 /* Read current USB device data */
2410 st_pwr_usb_i = st_pwr_usb + usb_read++;
2411 read_usb_stats(st_pwr_usb_i, drd->d_name);
2415 /* Close directory */
2421 ***************************************************************************
2422 * Read filesystems statistics.
2425 * @st_filesystem Structure where stats will be saved.
2426 * @nr_alloc Total number of structures allocated. Value is >= 0.
2429 * @st_filesystem Structure with statistics.
2432 * Number of filesystems read, or -1 if the buffer was too small and
2433 * needs to be reallocated.
2434 ***************************************************************************
2436 __nr_t read_filesystem(struct stats_filesystem *st_filesystem, __nr_t nr_alloc)
2439 char line[512], fs_name[128], mountp[256];
2440 int skip = 0, skip_next = 0;
2443 struct stats_filesystem *st_filesystem_i;
2446 if ((fp = fopen(MTAB, "r")) == NULL)
2449 while (fgets(line, sizeof(line), fp) != NULL) {
2451 * Ignore line if the preceding line did not contain '\n'.
2452 * (Some very long lines may be found for instance when
2453 * overlay2 filesystem with docker is used).
2456 skip_next = (strchr(line, '\n') == NULL);
2460 if (line[0] == '/') {
2461 /* Find field separator position */
2462 pos = strchr(line, ' ');
2466 /* Read current filesystem name */
2467 sscanf(line, "%127s", fs_name);
2469 * And now read the corresponding mount point.
2470 * Read fs name and mount point in two distinct operations.
2471 * Indeed, if fs name length is greater than 127 chars,
2472 * previous scanf() will read only the first 127 chars, and
2473 * mount point name will be read using the remaining chars
2474 * from the fs name. This will result in a bogus name
2475 * and following statvfs() function will always fail.
2477 sscanf(pos + 1, "%255s", mountp);
2479 /* Replace octal codes */
2483 * It's important to have read the whole mount point name
2484 * for statvfs() to work properly (see above).
2486 if ((statvfs(mountp, &buf) < 0) || (!buf.f_blocks))
2489 if (fs_read + 1 > nr_alloc) {
2494 st_filesystem_i = st_filesystem + fs_read++;
2495 st_filesystem_i->f_blocks = (unsigned long long) buf.f_blocks * (unsigned long long) buf.f_frsize;
2496 st_filesystem_i->f_bfree = (unsigned long long) buf.f_bfree * (unsigned long long) buf.f_frsize;
2497 st_filesystem_i->f_bavail = (unsigned long long) buf.f_bavail * (unsigned long long) buf.f_frsize;
2498 st_filesystem_i->f_files = (unsigned long long) buf.f_files;
2499 st_filesystem_i->f_ffree = (unsigned long long) buf.f_ffree;
2500 strncpy(st_filesystem_i->fs_name, fs_name, MAX_FS_LEN);
2501 st_filesystem_i->fs_name[MAX_FS_LEN - 1] = '\0';
2502 strncpy(st_filesystem_i->mountp, mountp, MAX_FS_LEN);
2503 st_filesystem_i->mountp[MAX_FS_LEN - 1] = '\0';
2512 ***************************************************************************
2513 * Read Fibre Channel HBA statistics.
2516 * @st_fc Structure where stats will be saved.
2517 * @nr_alloc Total number of structures allocated. Value is >= 0.
2520 * @st_fc Structure with statistics.
2523 * Number of FC hosts read, or -1 if the buffer was too small and needs to
2525 ***************************************************************************
2527 __nr_t read_fchost(struct stats_fchost *st_fc, __nr_t nr_alloc)
2532 struct stats_fchost *st_fc_i;
2533 __nr_t fch_read = 0;
2534 char fcstat_filename[MAX_PF_NAME];
2536 unsigned long rx_frames, tx_frames, rx_words, tx_words;
2538 /* Each host, if present, will have its own hostX entry within SYSFS_FCHOST */
2539 if ((dir = opendir(SYSFS_FCHOST)) == NULL)
2540 return 0; /* No FC hosts */
2543 * Read each of the counters via sysfs, where they are
2544 * returned as hex values (e.g. 0x72400).
2546 while ((drd = readdir(dir)) != NULL) {
2547 rx_frames = tx_frames = rx_words = tx_words = 0;
2549 if (!strncmp(drd->d_name, "host", 4)) {
2551 if (fch_read + 1 > nr_alloc) {
2556 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_FRAMES,
2557 SYSFS_FCHOST, drd->d_name);
2558 if ((fp = fopen(fcstat_filename, "r"))) {
2559 if (fgets(line, sizeof(line), fp)) {
2560 sscanf(line, "%lx", &rx_frames);
2565 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_FRAMES,
2566 SYSFS_FCHOST, drd->d_name);
2567 if ((fp = fopen(fcstat_filename, "r"))) {
2568 if (fgets(line, sizeof(line), fp)) {
2569 sscanf(line, "%lx", &tx_frames);
2574 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_WORDS,
2575 SYSFS_FCHOST, drd->d_name);
2576 if ((fp = fopen(fcstat_filename, "r"))) {
2577 if (fgets(line, sizeof(line), fp)) {
2578 sscanf(line, "%lx", &rx_words);
2583 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_WORDS,
2584 SYSFS_FCHOST, drd->d_name);
2585 if ((fp = fopen(fcstat_filename, "r"))) {
2586 if (fgets(line, sizeof(line), fp)) {
2587 sscanf(line, "%lx", &tx_words);
2592 st_fc_i = st_fc + fch_read++;
2593 st_fc_i->f_rxframes = rx_frames;
2594 st_fc_i->f_txframes = tx_frames;
2595 st_fc_i->f_rxwords = rx_words;
2596 st_fc_i->f_txwords = tx_words;
2597 memcpy(st_fc_i->fchost_name, drd->d_name, MAX_FCH_LEN);
2598 st_fc_i->fchost_name[MAX_FCH_LEN - 1] = '\0';
2607 ***************************************************************************
2608 * Read softnet statistics.
2611 * @st_softnet Structure where stats will be saved.
2612 * @nr_alloc Total number of structures allocated. Value is >= 0.
2613 * @online_cpu_bitmap
2614 * Bitmap listing online CPU.
2617 * @st_softnet Structure with statistics.
2620 * 1 if stats have been sucessfully read, or 0 otherwise.
2621 ***************************************************************************
2623 int read_softnet(struct stats_softnet *st_softnet, __nr_t nr_alloc,
2624 unsigned char online_cpu_bitmap[])
2627 struct stats_softnet *st_softnet_i;
2631 /* Open /proc/net/softnet_stat file */
2632 if ((fp = fopen(NET_SOFTNET, "r")) == NULL)
2635 for (cpu = 1; cpu < nr_alloc; cpu++) {
2636 if (!(online_cpu_bitmap[(cpu - 1) >> 3] & (1 << ((cpu - 1) & 0x07))))
2637 /* CPU is offline */
2640 if (fgets(line, sizeof(line), fp) == NULL)
2643 st_softnet_i = st_softnet + cpu;
2644 sscanf(line, "%x %x %x %*x %*x %*x %*x %*x %*x %x %x",
2645 &st_softnet_i->processed,
2646 &st_softnet_i->dropped,
2647 &st_softnet_i->time_squeeze,
2648 &st_softnet_i->received_rps,
2649 &st_softnet_i->flow_limit);
2656 /*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
2657 #endif /* SOURCE_SADC */