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)
373 = ((double) (sdc->nr_ios - sdp->nr_ios)) * 100 / itv;
375 xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
376 xds->svctm = tput ? xds->util / tput : 0.0;
378 * Kernel gives ticks already in milliseconds for all platforms
379 * => no need for further scaling.
381 xds->await = (sdc->nr_ios - sdp->nr_ios) ?
382 ((sdc->rd_ticks - sdp->rd_ticks) + (sdc->wr_ticks - sdp->wr_ticks)) /
383 ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
384 xds->arqsz = (sdc->nr_ios - sdp->nr_ios) ?
385 ((sdc->rd_sect - sdp->rd_sect) + (sdc->wr_sect - sdp->wr_sect)) /
386 ((double) (sdc->nr_ios - sdp->nr_ios)) : 0.0;
390 ***************************************************************************
391 * Since ticks may vary slightly from CPU to CPU, we'll want
392 * to recalculate itv based on this CPU's tick count, rather
393 * than that reported by the "cpu" line. Otherwise we
394 * occasionally end up with slightly skewed figures, with
395 * the skew being greater as the time interval grows shorter.
398 * @scc Current sample statistics for current CPU.
399 * @scp Previous sample statistics for current CPU.
402 * Interval of time based on current CPU, expressed in jiffies.
403 ***************************************************************************
405 unsigned long long get_per_cpu_interval(struct stats_cpu *scc,
406 struct stats_cpu *scp)
408 unsigned long long ishift = 0LL;
410 if ((scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest)) {
412 * Sometimes the nr of jiffies spent in guest mode given by the guest
413 * counter in /proc/stat is slightly higher than that included in
414 * the user counter. Update the interval value accordingly.
416 ishift += (scp->cpu_user - scp->cpu_guest) -
417 (scc->cpu_user - scc->cpu_guest);
419 if ((scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice)) {
421 * Idem for nr of jiffies spent in guest_nice mode.
423 ishift += (scp->cpu_nice - scp->cpu_guest_nice) -
424 (scc->cpu_nice - scc->cpu_guest_nice);
428 * Workaround for CPU coming back online: With recent kernels
429 * some fields (user, nice, system) restart from their previous value,
430 * whereas others (idle, iowait) restart from zero.
431 * For the latter we need to set their previous value to zero to
432 * avoid getting an interval value < 0.
433 * (I don't know how the other fields like hardirq, steal... behave).
434 * Don't assume the CPU has come back from offline state if previous
435 * value was greater than ULLONG_MAX - 0x7ffff (the counter probably
438 if ((scc->cpu_idle < scp->cpu_idle) && (scp->cpu_idle < (ULLONG_MAX - 0x7ffff))) {
441 if ((scc->cpu_iowait < scp->cpu_iowait) && (scp->cpu_iowait < (ULLONG_MAX - 0x7ffff))) {
446 * Don't take cpu_guest and cpu_guest_nice into account
447 * because cpu_user and cpu_nice already include them.
449 return ((scc->cpu_user + scc->cpu_nice +
450 scc->cpu_sys + scc->cpu_iowait +
451 scc->cpu_idle + scc->cpu_steal +
452 scc->cpu_hardirq + scc->cpu_softirq) -
453 (scp->cpu_user + scp->cpu_nice +
454 scp->cpu_sys + scp->cpu_iowait +
455 scp->cpu_idle + scp->cpu_steal +
456 scp->cpu_hardirq + scp->cpu_softirq) +
461 /*---------------- BEGIN: FUNCTIONS USED BY SADC ONLY ---------------------*/
464 ***************************************************************************
465 * Replace octal codes in string with their corresponding characters.
468 * @str String to parse.
471 * @str String with octal codes replaced with characters.
472 ***************************************************************************
474 void oct2chr(char *str)
481 while (i < len - 3) {
482 if ((str[i] == '\\') &&
483 (str[i + 1] >= '0') && (str[i + 1] <= '3') &&
484 (str[i + 2] >= '0') && (str[i + 2] <= '7') &&
485 (str[i + 3] >= '0') && (str[i + 3] <= '7')) {
486 /* Octal code found */
487 str[i] = (str[i + 1] - 48) * 64 +
488 (str[i + 2] - 48) * 8 +
490 for (j = i + 4; j <= len; j++) {
500 ***************************************************************************
501 * Read processes (tasks) creation and context switches statistics
505 * @st_pcsw Structure where stats will be saved.
508 * @st_pcsw Structure with statistics.
511 * 1 on success, 0 otherwise.
512 ***************************************************************************
514 __nr_t read_stat_pcsw(struct stats_pcsw *st_pcsw)
519 if ((fp = fopen(STAT, "r")) == NULL)
522 while (fgets(line, sizeof(line), fp) != NULL) {
524 if (!strncmp(line, "ctxt ", 5)) {
525 /* Read number of context switches */
526 sscanf(line + 5, "%llu", &st_pcsw->context_switch);
529 else if (!strncmp(line, "processes ", 10)) {
530 /* Read number of processes created since system boot */
531 sscanf(line + 10, "%lu", &st_pcsw->processes);
540 ***************************************************************************
541 * Read queue and load statistics from /proc/loadavg and /proc/stat.
544 * @st_queue Structure where stats will be saved.
547 * @st_queue Structure with statistics.
550 * 1 on success, 0 otherwise.
551 ***************************************************************************
553 __nr_t read_loadavg(struct stats_queue *st_queue)
557 unsigned int load_tmp[3];
560 if ((fp = fopen(LOADAVG, "r")) == NULL)
563 /* Read load averages and queue length */
564 rc = fscanf(fp, "%u.%u %u.%u %u.%u %llu/%llu %*d\n",
565 &load_tmp[0], &st_queue->load_avg_1,
566 &load_tmp[1], &st_queue->load_avg_5,
567 &load_tmp[2], &st_queue->load_avg_15,
568 &st_queue->nr_running,
569 &st_queue->nr_threads);
576 st_queue->load_avg_1 += load_tmp[0] * 100;
577 st_queue->load_avg_5 += load_tmp[1] * 100;
578 st_queue->load_avg_15 += load_tmp[2] * 100;
580 if (st_queue->nr_running) {
581 /* Do not take current process into account */
582 st_queue->nr_running--;
585 /* Read nr of tasks blocked from /proc/stat */
586 if ((fp = fopen(STAT, "r")) == NULL)
589 while (fgets(line, sizeof(line), fp) != NULL) {
591 if (!strncmp(line, "procs_blocked ", 14)) {
592 /* Read number of processes blocked */
593 sscanf(line + 14, "%llu", &st_queue->procs_blocked);
603 ***************************************************************************
604 * Read swapping statistics from /proc/vmstat.
607 * @st_swap Structure where stats will be saved.
610 * @st_swap Structure with statistics.
613 * 1 on success, 0 otherwise.
614 ***************************************************************************
616 __nr_t read_vmstat_swap(struct stats_swap *st_swap)
621 if ((fp = fopen(VMSTAT, "r")) == NULL)
624 while (fgets(line, sizeof(line), fp) != NULL) {
626 if (!strncmp(line, "pswpin ", 7)) {
627 /* Read number of swap pages brought in */
628 sscanf(line + 7, "%lu", &st_swap->pswpin);
630 else if (!strncmp(line, "pswpout ", 8)) {
631 /* Read number of swap pages brought out */
632 sscanf(line + 8, "%lu", &st_swap->pswpout);
641 ***************************************************************************
642 * Read paging statistics from /proc/vmstat.
645 * @st_paging Structure where stats will be saved.
648 * @st_paging Structure with statistics.
651 * 1 on success, 0 otherwise.
652 ***************************************************************************
654 __nr_t read_vmstat_paging(struct stats_paging *st_paging)
660 if ((fp = fopen(VMSTAT, "r")) == NULL)
663 st_paging->pgsteal = 0;
664 st_paging->pgscan_kswapd = st_paging->pgscan_direct = 0;
666 while (fgets(line, sizeof(line), fp) != NULL) {
668 if (!strncmp(line, "pgpgin ", 7)) {
669 /* Read number of pages the system paged in */
670 sscanf(line + 7, "%lu", &st_paging->pgpgin);
672 else if (!strncmp(line, "pgpgout ", 8)) {
673 /* Read number of pages the system paged out */
674 sscanf(line + 8, "%lu", &st_paging->pgpgout);
676 else if (!strncmp(line, "pgfault ", 8)) {
677 /* Read number of faults (major+minor) made by the system */
678 sscanf(line + 8, "%lu", &st_paging->pgfault);
680 else if (!strncmp(line, "pgmajfault ", 11)) {
681 /* Read number of faults (major only) made by the system */
682 sscanf(line + 11, "%lu", &st_paging->pgmajfault);
684 else if (!strncmp(line, "pgfree ", 7)) {
685 /* Read number of pages freed by the system */
686 sscanf(line + 7, "%lu", &st_paging->pgfree);
688 else if (!strncmp(line, "pgsteal_", 8)) {
689 /* Read number of pages stolen by the system */
690 sscanf(strchr(line, ' '), "%lu", &pgtmp);
691 st_paging->pgsteal += pgtmp;
693 else if (!strncmp(line, "pgscan_kswapd", 13)) {
694 /* Read number of pages scanned by the kswapd daemon */
695 sscanf(strchr(line, ' '), "%lu", &pgtmp);
696 st_paging->pgscan_kswapd += pgtmp;
698 else if (!strncmp(line, "pgscan_direct", 13)) {
699 /* Read number of pages scanned directly */
700 sscanf(strchr(line, ' '), "%lu", &pgtmp);
701 st_paging->pgscan_direct += pgtmp;
710 ***************************************************************************
711 * Read I/O and transfer rates statistics from /proc/diskstats.
714 * @st_io Structure where stats will be saved.
717 * @st_io Structure with statistics.
720 * 1 on success, 0 otherwise.
721 ***************************************************************************
723 __nr_t read_diskstats_io(struct stats_io *st_io)
727 char dev_name[MAX_NAME_LEN];
728 unsigned int major, minor;
729 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
731 if ((fp = fopen(DISKSTATS, "r")) == NULL)
734 while (fgets(line, sizeof(line), fp) != NULL) {
736 if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu",
737 &major, &minor, dev_name,
738 &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) {
740 if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) {
742 * OK: It's a (real) device and not a partition.
743 * Note: Structure should have been initialized first!
745 st_io->dk_drive += (unsigned long long) rd_ios + (unsigned long long) wr_ios;
746 st_io->dk_drive_rio += rd_ios;
747 st_io->dk_drive_rblk += rd_sec;
748 st_io->dk_drive_wio += wr_ios;
749 st_io->dk_drive_wblk += wr_sec;
759 ***************************************************************************
760 * Read block devices statistics from /proc/diskstats.
763 * @st_disk Structure where stats will be saved.
764 * @nr_alloc Total number of structures allocated. Value is >= 1.
765 * @read_part True if disks *and* partitions should be read; False if only
769 * @st_disk Structure with statistics.
772 * Number of block devices read, or -1 if the buffer was too small and
773 * needs to be reallocated.
774 ***************************************************************************
776 __nr_t read_diskstats_disk(struct stats_disk *st_disk, __nr_t nr_alloc,
781 char dev_name[MAX_NAME_LEN];
782 struct stats_disk *st_disk_i;
783 unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks;
784 unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
787 if ((fp = fopen(DISKSTATS, "r")) == NULL)
790 while (fgets(line, sizeof(line), fp) != NULL) {
792 if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu"
794 &major, &minor, dev_name,
795 &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks,
796 &tot_ticks, &rq_ticks) == 11) {
798 if (!rd_ios && !wr_ios)
799 /* Unused device: Ignore it */
801 if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) {
803 if (dsk_read + 1 > nr_alloc) {
808 st_disk_i = st_disk + dsk_read++;
809 st_disk_i->major = major;
810 st_disk_i->minor = minor;
811 st_disk_i->nr_ios = (unsigned long long) rd_ios + (unsigned long long) wr_ios;
812 st_disk_i->rd_sect = rd_sec;
813 st_disk_i->wr_sect = wr_sec;
814 st_disk_i->rd_ticks = rd_ticks;
815 st_disk_i->wr_ticks = wr_ticks;
816 st_disk_i->tot_ticks = tot_ticks;
817 st_disk_i->rq_ticks = rq_ticks;
827 ***************************************************************************
828 * Read serial lines statistics from /proc/tty/driver/serial.
831 * @st_serial Structure where stats will be saved.
832 * @nr_alloc Total number of structures allocated. Value is >= 1.
835 * @st_serial Structure with statistics.
838 * Number of serial lines read, or -1 if the buffer was too small and
839 * needs to be reallocated.
840 ***************************************************************************
842 __nr_t read_tty_driver_serial(struct stats_serial *st_serial, __nr_t nr_alloc)
845 struct stats_serial *st_serial_i;
850 if ((fp = fopen(SERIAL, "r")) == NULL)
853 while (fgets(line, sizeof(line), fp) != NULL ) {
855 if ((p = strstr(line, "tx:")) != NULL) {
857 if (sl_read + 1 > nr_alloc) {
862 st_serial_i = st_serial + sl_read++;
863 /* Read serial line number */
864 sscanf(line, "%u", &st_serial_i->line);
866 * Read the number of chars transmitted and received by
867 * current serial line.
869 sscanf(p + 3, "%u", &st_serial_i->tx);
870 if ((p = strstr(line, "rx:")) != NULL) {
871 sscanf(p + 3, "%u", &st_serial_i->rx);
873 if ((p = strstr(line, "fe:")) != NULL) {
874 sscanf(p + 3, "%u", &st_serial_i->frame);
876 if ((p = strstr(line, "pe:")) != NULL) {
877 sscanf(p + 3, "%u", &st_serial_i->parity);
879 if ((p = strstr(line, "brk:")) != NULL) {
880 sscanf(p + 4, "%u", &st_serial_i->brk);
882 if ((p = strstr(line, "oe:")) != NULL) {
883 sscanf(p + 3, "%u", &st_serial_i->overrun);
893 ***************************************************************************
894 * Read kernel tables statistics from various system files.
897 * @st_ktables Structure where stats will be saved.
900 * @st_ktables Structure with statistics.
903 * 1 (always success).
904 ***************************************************************************
906 __nr_t read_kernel_tables(struct stats_ktables *st_ktables)
909 unsigned long long parm;
912 /* Open /proc/sys/fs/dentry-state file */
913 if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) {
914 rc = fscanf(fp, "%*d %llu",
915 &st_ktables->dentry_stat);
918 st_ktables->dentry_stat = 0;
922 /* Open /proc/sys/fs/file-nr file */
923 if ((fp = fopen(FFILE_NR, "r")) != NULL) {
924 rc = fscanf(fp, "%llu %llu",
925 &st_ktables->file_used, &parm);
928 * The number of used handles is the number of allocated ones
929 * minus the number of free ones.
932 st_ktables->file_used -= parm;
935 st_ktables->file_used = 0;
939 /* Open /proc/sys/fs/inode-state file */
940 if ((fp = fopen(FINODE_STATE, "r")) != NULL) {
941 rc = fscanf(fp, "%llu %llu",
942 &st_ktables->inode_used, &parm);
945 * The number of inuse inodes is the number of allocated ones
946 * minus the number of free ones.
949 st_ktables->inode_used -= parm;
952 st_ktables->inode_used = 0;
956 /* Open /proc/sys/kernel/pty/nr file */
957 if ((fp = fopen(PTY_NR, "r")) != NULL) {
958 rc = fscanf(fp, "%llu",
959 &st_ktables->pty_nr);
962 st_ktables->pty_nr = 0;
970 ***************************************************************************
971 * Read network interfaces statistics from /proc/net/dev.
974 * @st_net_dev Structure where stats will be saved.
975 * @nr_alloc Total number of structures allocated. Value is >= 1.
978 * @st_net_dev Structure with statistics.
981 * Number of interfaces read, or -1 if the buffer was too small and
982 * needs to be reallocated.
983 ***************************************************************************
985 __nr_t read_net_dev(struct stats_net_dev *st_net_dev, __nr_t nr_alloc)
988 struct stats_net_dev *st_net_dev_i;
990 char iface[MAX_IFACE_LEN];
994 if ((fp = fopen(NET_DEV, "r")) == NULL)
997 while (fgets(line, sizeof(line), fp) != NULL) {
999 pos = strcspn(line, ":");
1000 if (pos < strlen(line)) {
1002 if (dev_read + 1 > nr_alloc) {
1007 st_net_dev_i = st_net_dev + dev_read++;
1008 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1009 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1010 sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */
1011 sscanf(line + pos + 1, "%llu %llu %*u %*u %*u %*u %llu %llu %llu %llu "
1012 "%*u %*u %*u %*u %*u %llu",
1013 &st_net_dev_i->rx_bytes,
1014 &st_net_dev_i->rx_packets,
1015 &st_net_dev_i->rx_compressed,
1016 &st_net_dev_i->multicast,
1017 &st_net_dev_i->tx_bytes,
1018 &st_net_dev_i->tx_packets,
1019 &st_net_dev_i->tx_compressed);
1028 ***************************************************************************
1029 * Read duplex and speed data for network interface cards.
1032 * @st_net_dev Structure where stats will be saved.
1033 * @nbr Number of network interfaces to read.
1036 * @st_net_dev Structure with statistics.
1037 ***************************************************************************
1039 void read_if_info(struct stats_net_dev *st_net_dev, int nbr)
1042 struct stats_net_dev *st_net_dev_i;
1043 char filename[128], duplex[32];
1046 for (dev = 0; dev < nbr; dev++) {
1048 st_net_dev_i = st_net_dev + dev;
1050 /* Read speed info */
1051 sprintf(filename, IF_DUPLEX, st_net_dev_i->interface);
1053 if ((fp = fopen(filename, "r")) == NULL)
1054 /* Cannot read NIC duplex */
1057 n = fscanf(fp, "%31s", duplex);
1062 /* Cannot read NIC duplex */
1065 if (!strcmp(duplex, K_DUPLEX_FULL)) {
1066 st_net_dev_i->duplex = C_DUPLEX_FULL;
1068 else if (!strcmp(duplex, K_DUPLEX_HALF)) {
1069 st_net_dev_i->duplex = C_DUPLEX_HALF;
1074 /* Read speed info */
1075 sprintf(filename, IF_SPEED, st_net_dev_i->interface);
1077 if ((fp = fopen(filename, "r")) == NULL)
1078 /* Cannot read NIC speed */
1081 n = fscanf(fp, "%u", &st_net_dev_i->speed);
1086 st_net_dev_i->speed = 0;
1093 ***************************************************************************
1094 * Read network interfaces errors statistics from /proc/net/dev.
1097 * @st_net_edev Structure where stats will be saved.
1098 * @nr_alloc Total number of structures allocated. Value is >= 1.
1101 * @st_net_edev Structure with statistics.
1104 * Number of interfaces read, or -1 if the buffer was too small and
1105 * needs to be reallocated.
1106 ***************************************************************************
1108 __nr_t read_net_edev(struct stats_net_edev *st_net_edev, __nr_t nr_alloc)
1111 struct stats_net_edev *st_net_edev_i;
1112 static char line[256];
1113 char iface[MAX_IFACE_LEN];
1114 __nr_t dev_read = 0;
1117 if ((fp = fopen(NET_DEV, "r")) == NULL)
1120 while (fgets(line, sizeof(line), fp) != NULL) {
1122 pos = strcspn(line, ":");
1123 if (pos < strlen(line)) {
1125 if (dev_read + 1 > nr_alloc) {
1130 st_net_edev_i = st_net_edev + dev_read++;
1131 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1132 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1133 sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */
1134 sscanf(line + pos + 1, "%*u %*u %llu %llu %llu %llu %*u %*u %*u %*u "
1135 "%llu %llu %llu %llu %llu",
1136 &st_net_edev_i->rx_errors,
1137 &st_net_edev_i->rx_dropped,
1138 &st_net_edev_i->rx_fifo_errors,
1139 &st_net_edev_i->rx_frame_errors,
1140 &st_net_edev_i->tx_errors,
1141 &st_net_edev_i->tx_dropped,
1142 &st_net_edev_i->tx_fifo_errors,
1143 &st_net_edev_i->collisions,
1144 &st_net_edev_i->tx_carrier_errors);
1153 ***************************************************************************
1154 * Read NFS client statistics from /proc/net/rpc/nfs.
1157 * @st_net_nfs Structure where stats will be saved.
1160 * @st_net_nfs Structure with statistics.
1163 * 1 on success, 0 otherwise.
1164 ***************************************************************************
1166 __nr_t read_net_nfs(struct stats_net_nfs *st_net_nfs)
1170 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1172 if ((fp = fopen(NET_RPC_NFS, "r")) == NULL)
1175 memset(st_net_nfs, 0, STATS_NET_NFS_SIZE);
1177 while (fgets(line, sizeof(line), fp) != NULL) {
1179 if (!strncmp(line, "rpc ", 4)) {
1180 sscanf(line + 4, "%u %u",
1181 &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans);
1183 else if (!strncmp(line, "proc3 ", 6)) {
1184 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1185 &getattcnt, &accesscnt, &readcnt, &writecnt);
1187 st_net_nfs->nfs_getattcnt += getattcnt;
1188 st_net_nfs->nfs_accesscnt += accesscnt;
1189 st_net_nfs->nfs_readcnt += readcnt;
1190 st_net_nfs->nfs_writecnt += writecnt;
1192 else if (!strncmp(line, "proc4 ", 6)) {
1193 sscanf(line + 6, "%*u %*u %u %u "
1194 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u",
1195 &readcnt, &writecnt, &accesscnt, &getattcnt);
1197 st_net_nfs->nfs_getattcnt += getattcnt;
1198 st_net_nfs->nfs_accesscnt += accesscnt;
1199 st_net_nfs->nfs_readcnt += readcnt;
1200 st_net_nfs->nfs_writecnt += writecnt;
1209 ***************************************************************************
1210 * Read NFS server statistics from /proc/net/rpc/nfsd.
1213 * @st_net_nfsd Structure where stats will be saved.
1216 * @st_net_nfsd Structure with statistics.
1219 * 1 on success, 0 otherwise.
1220 ***************************************************************************
1222 __nr_t read_net_nfsd(struct stats_net_nfsd *st_net_nfsd)
1226 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1228 if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL)
1231 memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE);
1233 while (fgets(line, sizeof(line), fp) != NULL) {
1235 if (!strncmp(line, "rc ", 3)) {
1236 sscanf(line + 3, "%u %u",
1237 &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses);
1239 else if (!strncmp(line, "net ", 4)) {
1240 sscanf(line + 4, "%u %u %u",
1241 &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt,
1242 &st_net_nfsd->nfsd_nettcpcnt);
1244 else if (!strncmp(line, "rpc ", 4)) {
1245 sscanf(line + 4, "%u %u",
1246 &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad);
1248 else if (!strncmp(line, "proc3 ", 6)) {
1249 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1250 &getattcnt, &accesscnt, &readcnt, &writecnt);
1252 st_net_nfsd->nfsd_getattcnt += getattcnt;
1253 st_net_nfsd->nfsd_accesscnt += accesscnt;
1254 st_net_nfsd->nfsd_readcnt += readcnt;
1255 st_net_nfsd->nfsd_writecnt += writecnt;
1258 else if (!strncmp(line, "proc4ops ", 9)) {
1259 sscanf(line + 9, "%*u %*u %*u %*u %u "
1260 "%*u %*u %*u %*u %*u %u "
1261 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u "
1262 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
1263 &accesscnt, &getattcnt, &readcnt, &writecnt);
1265 st_net_nfsd->nfsd_getattcnt += getattcnt;
1266 st_net_nfsd->nfsd_accesscnt += accesscnt;
1267 st_net_nfsd->nfsd_readcnt += readcnt;
1268 st_net_nfsd->nfsd_writecnt += writecnt;
1277 ***************************************************************************
1278 * Read network sockets statistics from /proc/net/sockstat.
1281 * @st_net_sock Structure where stats will be saved.
1284 * @st_net_sock Structure with statistics.
1287 * 1 on success, 0 otherwise.
1288 ***************************************************************************
1290 __nr_t read_net_sock(struct stats_net_sock *st_net_sock)
1296 if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL)
1299 while (fgets(line, sizeof(line), fp) != NULL) {
1301 if (!strncmp(line, "sockets:", 8)) {
1303 sscanf(line + 14, "%u", &st_net_sock->sock_inuse);
1305 else if (!strncmp(line, "TCP:", 4)) {
1307 sscanf(line + 11, "%u", &st_net_sock->tcp_inuse);
1308 if ((p = strstr(line, "tw")) != NULL) {
1309 sscanf(p + 2, "%u", &st_net_sock->tcp_tw);
1312 else if (!strncmp(line, "UDP:", 4)) {
1314 sscanf(line + 11, "%u", &st_net_sock->udp_inuse);
1316 else if (!strncmp(line, "RAW:", 4)) {
1318 sscanf(line + 11, "%u", &st_net_sock->raw_inuse);
1320 else if (!strncmp(line, "FRAG:", 5)) {
1322 sscanf(line + 12, "%u", &st_net_sock->frag_inuse);
1331 ***************************************************************************
1332 * Read IP network traffic statistics from /proc/net/snmp.
1335 * @st_net_ip Structure where stats will be saved.
1338 * @st_net_ip Structure with statistics.
1341 * 1 on success, 0 otherwise.
1342 ***************************************************************************
1344 __nr_t read_net_ip(struct stats_net_ip *st_net_ip)
1350 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1353 while (fgets(line, sizeof(line), fp) != NULL) {
1355 if (!strncmp(line, "Ip:", 3)) {
1357 sscanf(line + 3, "%*u %*u %llu %*u %*u %llu %*u %*u "
1358 "%llu %llu %*u %*u %*u %llu %llu %*u %llu %*u %llu",
1359 &st_net_ip->InReceives,
1360 &st_net_ip->ForwDatagrams,
1361 &st_net_ip->InDelivers,
1362 &st_net_ip->OutRequests,
1363 &st_net_ip->ReasmReqds,
1364 &st_net_ip->ReasmOKs,
1365 &st_net_ip->FragOKs,
1366 &st_net_ip->FragCreates);
1381 ***************************************************************************
1382 * Read IP network errors statistics from /proc/net/snmp.
1385 * @st_net_eip Structure where stats will be saved.
1388 * @st_net_eip Structure with statistics.
1391 * 1 on success, 0 otherwise.
1392 ***************************************************************************
1394 __nr_t read_net_eip(struct stats_net_eip *st_net_eip)
1400 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1403 while (fgets(line, sizeof(line), fp) != NULL) {
1405 if (!strncmp(line, "Ip:", 3)) {
1407 sscanf(line + 3, "%*u %*u %*u %llu %llu %*u %llu %llu "
1408 "%*u %*u %llu %llu %*u %*u %*u %llu %*u %llu",
1409 &st_net_eip->InHdrErrors,
1410 &st_net_eip->InAddrErrors,
1411 &st_net_eip->InUnknownProtos,
1412 &st_net_eip->InDiscards,
1413 &st_net_eip->OutDiscards,
1414 &st_net_eip->OutNoRoutes,
1415 &st_net_eip->ReasmFails,
1416 &st_net_eip->FragFails);
1431 ***************************************************************************
1432 * Read ICMP network traffic statistics from /proc/net/snmp.
1435 * @st_net_icmp Structure where stats will be saved.
1438 * @st_net_icmp Structure with statistics.
1441 * 1 on success, 0 otherwise.
1442 ***************************************************************************
1444 __nr_t read_net_icmp(struct stats_net_icmp *st_net_icmp)
1448 static char format[256] = "";
1451 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1454 while (fgets(line, sizeof(line), fp) != NULL) {
1456 if (!strncmp(line, "Icmp:", 5)) {
1458 sscanf(line + 5, format,
1459 &st_net_icmp->InMsgs,
1460 &st_net_icmp->InEchos,
1461 &st_net_icmp->InEchoReps,
1462 &st_net_icmp->InTimestamps,
1463 &st_net_icmp->InTimestampReps,
1464 &st_net_icmp->InAddrMasks,
1465 &st_net_icmp->InAddrMaskReps,
1466 &st_net_icmp->OutMsgs,
1467 &st_net_icmp->OutEchos,
1468 &st_net_icmp->OutEchoReps,
1469 &st_net_icmp->OutTimestamps,
1470 &st_net_icmp->OutTimestampReps,
1471 &st_net_icmp->OutAddrMasks,
1472 &st_net_icmp->OutAddrMaskReps);
1477 if (!strlen(format)) {
1478 if (strstr(line, "InCsumErrors")) {
1480 * New format: InCsumErrors field exists at position #3.
1481 * Capture: 1,9,10,11,12,13,14,15,22,23,24,25,26,27.
1483 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u %*u "
1484 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1485 "%*u %*u %lu %lu %lu %lu %lu %lu");
1489 * Old format: InCsumErrors field doesn't exist.
1490 * Capture: 1,8,9,10,11,12,13,14,21,22,23,24,25,26.
1492 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u "
1493 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1494 "%*u %*u %lu %lu %lu %lu %lu %lu");
1507 ***************************************************************************
1508 * Read ICMP network errors statistics from /proc/net/snmp.
1511 * @st_net_eicmp Structure where stats will be saved.
1514 * @st_net_eicmp Structure with statistics.
1517 * 1 on success, 0 otherwise.
1518 ***************************************************************************
1520 __nr_t read_net_eicmp(struct stats_net_eicmp *st_net_eicmp)
1526 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1529 while (fgets(line, sizeof(line), fp) != NULL) {
1531 if (!strncmp(line, "Icmp:", 5)) {
1533 sscanf(line + 5, "%*u %lu %lu %lu %lu %lu %lu %*u %*u "
1534 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu",
1535 &st_net_eicmp->InErrors,
1536 &st_net_eicmp->InDestUnreachs,
1537 &st_net_eicmp->InTimeExcds,
1538 &st_net_eicmp->InParmProbs,
1539 &st_net_eicmp->InSrcQuenchs,
1540 &st_net_eicmp->InRedirects,
1541 &st_net_eicmp->OutErrors,
1542 &st_net_eicmp->OutDestUnreachs,
1543 &st_net_eicmp->OutTimeExcds,
1544 &st_net_eicmp->OutParmProbs,
1545 &st_net_eicmp->OutSrcQuenchs,
1546 &st_net_eicmp->OutRedirects);
1561 ***************************************************************************
1562 * Read TCP network traffic statistics from /proc/net/snmp.
1565 * @st_net_tcp Structure where stats will be saved.
1568 * @st_net_tcp Structure with statistics.
1571 * 1 on success, 0 otherwise.
1572 ***************************************************************************
1574 __nr_t read_net_tcp(struct stats_net_tcp *st_net_tcp)
1580 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1583 while (fgets(line, sizeof(line), fp) != NULL) {
1585 if (!strncmp(line, "Tcp:", 4)) {
1587 sscanf(line + 4, "%*u %*u %*u %*d %lu %lu "
1588 "%*u %*u %*u %lu %lu",
1589 &st_net_tcp->ActiveOpens,
1590 &st_net_tcp->PassiveOpens,
1591 &st_net_tcp->InSegs,
1592 &st_net_tcp->OutSegs);
1607 ***************************************************************************
1608 * Read TCP network errors statistics from /proc/net/snmp.
1611 * @st_net_etcp Structure where stats will be saved.
1614 * @st_net_etcp Structure with statistics.
1617 * 1 on success, 0 otherwise.
1618 ***************************************************************************
1620 __nr_t read_net_etcp(struct stats_net_etcp *st_net_etcp)
1626 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1629 while (fgets(line, sizeof(line), fp) != NULL) {
1631 if (!strncmp(line, "Tcp:", 4)) {
1633 sscanf(line + 4, "%*u %*u %*u %*d %*u %*u "
1634 "%lu %lu %*u %*u %*u %lu %lu %lu",
1635 &st_net_etcp->AttemptFails,
1636 &st_net_etcp->EstabResets,
1637 &st_net_etcp->RetransSegs,
1638 &st_net_etcp->InErrs,
1639 &st_net_etcp->OutRsts);
1654 ***************************************************************************
1655 * Read UDP network traffic statistics from /proc/net/snmp.
1658 * @st_net_udp Structure where stats will be saved.
1661 * @st_net_udp Structure with statistics.
1664 * 1 on success, 0 otherwise.
1665 ***************************************************************************
1667 __nr_t read_net_udp(struct stats_net_udp *st_net_udp)
1673 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1676 while (fgets(line, sizeof(line), fp) != NULL) {
1678 if (!strncmp(line, "Udp:", 4)) {
1680 sscanf(line + 4, "%lu %lu %lu %lu",
1681 &st_net_udp->InDatagrams,
1682 &st_net_udp->NoPorts,
1683 &st_net_udp->InErrors,
1684 &st_net_udp->OutDatagrams);
1699 ***************************************************************************
1700 * Read IPv6 network sockets statistics from /proc/net/sockstat6.
1703 * @st_net_sock6 Structure where stats will be saved.
1706 * @st_net_sock6 Structure with statistics.
1709 * 1 on success, 0 otherwise.
1710 ***************************************************************************
1712 __nr_t read_net_sock6(struct stats_net_sock6 *st_net_sock6)
1717 if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL)
1720 while (fgets(line, sizeof(line), fp) != NULL) {
1722 if (!strncmp(line, "TCP6:", 5)) {
1724 sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse);
1726 else if (!strncmp(line, "UDP6:", 5)) {
1728 sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse);
1730 else if (!strncmp(line, "RAW6:", 5)) {
1731 /* IPv6 RAW sockets */
1732 sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse);
1734 else if (!strncmp(line, "FRAG6:", 6)) {
1735 /* IPv6 FRAGments */
1736 sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse);
1745 ***************************************************************************
1746 * Read IPv6 network traffic statistics from /proc/net/snmp6.
1749 * @st_net_ip6 Structure where stats will be saved.
1752 * @st_net_ip6 Structure with statistics.
1755 * 1 on success, 0 otherwise.
1756 ***************************************************************************
1758 __nr_t read_net_ip6(struct stats_net_ip6 *st_net_ip6)
1763 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1766 while (fgets(line, sizeof(line), fp) != NULL) {
1768 if (!strncmp(line, "Ip6InReceives ", 14)) {
1769 sscanf(line + 14, "%llu", &st_net_ip6->InReceives6);
1771 else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) {
1772 sscanf(line + 20, "%llu", &st_net_ip6->OutForwDatagrams6);
1774 else if (!strncmp(line, "Ip6InDelivers ", 14)) {
1775 sscanf(line + 14, "%llu", &st_net_ip6->InDelivers6);
1777 else if (!strncmp(line, "Ip6OutRequests ", 15)) {
1778 sscanf(line + 15, "%llu", &st_net_ip6->OutRequests6);
1780 else if (!strncmp(line, "Ip6ReasmReqds ", 14)) {
1781 sscanf(line + 14, "%llu", &st_net_ip6->ReasmReqds6);
1783 else if (!strncmp(line, "Ip6ReasmOKs ", 12)) {
1784 sscanf(line + 12, "%llu", &st_net_ip6->ReasmOKs6);
1786 else if (!strncmp(line, "Ip6InMcastPkts ", 15)) {
1787 sscanf(line + 15, "%llu", &st_net_ip6->InMcastPkts6);
1789 else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) {
1790 sscanf(line + 16, "%llu", &st_net_ip6->OutMcastPkts6);
1792 else if (!strncmp(line, "Ip6FragOKs ", 11)) {
1793 sscanf(line + 11, "%llu", &st_net_ip6->FragOKs6);
1795 else if (!strncmp(line, "Ip6FragCreates ", 15)) {
1796 sscanf(line + 15, "%llu", &st_net_ip6->FragCreates6);
1805 ***************************************************************************
1806 * Read IPv6 network errors statistics from /proc/net/snmp6.
1809 * @st_net_eip6 Structure where stats will be saved.
1812 * @st_net_eip6 Structure with statistics.
1815 * 1 on success, 0 otherwise.
1816 ***************************************************************************
1818 __nr_t read_net_eip6(struct stats_net_eip6 *st_net_eip6)
1823 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1826 while (fgets(line, sizeof(line), fp) != NULL) {
1828 if (!strncmp(line, "Ip6InHdrErrors ", 15)) {
1829 sscanf(line + 15, "%llu", &st_net_eip6->InHdrErrors6);
1831 else if (!strncmp(line, "Ip6InAddrErrors ", 16)) {
1832 sscanf(line + 16, "%llu", &st_net_eip6->InAddrErrors6);
1834 else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) {
1835 sscanf(line + 19, "%llu", &st_net_eip6->InUnknownProtos6);
1837 else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) {
1838 sscanf(line + 18, "%llu", &st_net_eip6->InTooBigErrors6);
1840 else if (!strncmp(line, "Ip6InDiscards ", 14)) {
1841 sscanf(line + 14, "%llu", &st_net_eip6->InDiscards6);
1843 else if (!strncmp(line, "Ip6OutDiscards ", 15)) {
1844 sscanf(line + 15, "%llu", &st_net_eip6->OutDiscards6);
1846 else if (!strncmp(line, "Ip6InNoRoutes ", 14)) {
1847 sscanf(line + 14, "%llu", &st_net_eip6->InNoRoutes6);
1849 else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) {
1850 sscanf(line + 15, "%llu", &st_net_eip6->OutNoRoutes6);
1852 else if (!strncmp(line, "Ip6ReasmFails ", 14)) {
1853 sscanf(line + 14, "%llu", &st_net_eip6->ReasmFails6);
1855 else if (!strncmp(line, "Ip6FragFails ", 13)) {
1856 sscanf(line + 13, "%llu", &st_net_eip6->FragFails6);
1858 else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) {
1859 sscanf(line + 19, "%llu", &st_net_eip6->InTruncatedPkts6);
1868 ***************************************************************************
1869 * Read ICMPv6 network traffic statistics from /proc/net/snmp6.
1872 * @st_net_icmp6 Structure where stats will be saved.
1875 * @st_net_icmp6 Structure with statistics.
1878 * 1 on success, 0 otherwise.
1879 ***************************************************************************
1881 __nr_t read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6)
1886 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1889 while (fgets(line, sizeof(line), fp) != NULL) {
1891 if (!strncmp(line, "Icmp6InMsgs ", 12)) {
1892 sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6);
1894 else if (!strncmp(line, "Icmp6OutMsgs ", 13)) {
1895 sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6);
1897 else if (!strncmp(line, "Icmp6InEchos ", 13)) {
1898 sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6);
1900 else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) {
1901 sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6);
1903 else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) {
1904 sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6);
1906 else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) {
1907 sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6);
1909 else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) {
1910 sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6);
1912 else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) {
1913 sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6);
1915 else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) {
1916 sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6);
1918 else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) {
1919 sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6);
1921 else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) {
1922 sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6);
1924 else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) {
1925 sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6);
1927 else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) {
1928 sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6);
1930 else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) {
1931 sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6);
1933 else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) {
1934 sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6);
1936 else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) {
1937 sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6);
1939 else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) {
1940 sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6);
1949 ***************************************************************************
1950 * Read ICMPv6 network errors statistics from /proc/net/snmp6.
1953 * @st_net_eicmp6 Structure where stats will be saved.
1956 * @st_net_eicmp6 Structure with statistics.
1959 * 1 on success, 0 otherwise.
1960 ***************************************************************************
1962 __nr_t read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6)
1967 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1970 while (fgets(line, sizeof(line), fp) != NULL) {
1972 if (!strncmp(line, "Icmp6InErrors ", 14)) {
1973 sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6);
1975 else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) {
1976 sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6);
1978 else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) {
1979 sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6);
1981 else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) {
1982 sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6);
1984 else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) {
1985 sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6);
1987 else if (!strncmp(line, "Icmp6InParmProblems ", 20)) {
1988 sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6);
1990 else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) {
1991 sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6);
1993 else if (!strncmp(line, "Icmp6InRedirects ", 17)) {
1994 sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6);
1996 else if (!strncmp(line, "Icmp6OutRedirects ", 18)) {
1997 sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6);
1999 else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) {
2000 sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6);
2002 else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) {
2003 sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6);
2012 ***************************************************************************
2013 * Read UDPv6 network traffic statistics from /proc/net/snmp6.
2016 * @st_net_udp6 Structure where stats will be saved.
2019 * @st_net_udp6 Structure with statistics.
2022 * 1 on success, 0 otherwise.
2023 ***************************************************************************
2025 __nr_t read_net_udp6(struct stats_net_udp6 *st_net_udp6)
2030 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
2033 while (fgets(line, sizeof(line), fp) != NULL) {
2035 if (!strncmp(line, "Udp6InDatagrams ", 16)) {
2036 sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6);
2038 else if (!strncmp(line, "Udp6OutDatagrams ", 17)) {
2039 sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6);
2041 else if (!strncmp(line, "Udp6NoPorts ", 12)) {
2042 sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6);
2044 else if (!strncmp(line, "Udp6InErrors ", 13)) {
2045 sscanf(line + 13, "%lu", &st_net_udp6->InErrors6);
2054 ***************************************************************************
2055 * Read CPU frequency statistics.
2058 * @st_pwr_cpufreq Structure where stats will be saved.
2059 * @nr_alloc Total number of structures allocated. Value is >= 1.
2062 * @st_pwr_cpufreq Structure with statistics.
2065 * Highest CPU number for which statistics have been read.
2066 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
2067 * Or -1 if the buffer was too small and needs to be reallocated.
2068 ***************************************************************************
2070 __nr_t read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, __nr_t nr_alloc)
2073 struct stats_pwr_cpufreq *st_pwr_cpufreq_i;
2076 __nr_t cpu_read = 1; /* For CPU "all" */
2077 unsigned int proc_nr = 0, ifreq, dfreq;
2079 if ((fp = fopen(CPUINFO, "r")) == NULL)
2082 st_pwr_cpufreq->cpufreq = 0;
2084 while (fgets(line, sizeof(line), fp) != NULL) {
2086 if (!strncmp(line, "processor\t", 10)) {
2087 sscanf(strchr(line, ':') + 1, "%u", &proc_nr);
2089 if (proc_nr + 2 > nr_alloc) {
2095 /* Entry in /proc/cpuinfo is different between Intel and Power architectures */
2096 else if (!strncmp(line, "cpu MHz\t", 8) ||
2097 !strncmp(line, "clock\t", 6)) {
2098 sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq);
2100 /* Save current CPU frequency */
2101 st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nr + 1;
2102 st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10;
2104 /* Also save it to compute an average CPU frequency */
2105 st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq;
2108 if (proc_nr + 2 > cpu_read) {
2109 cpu_read = proc_nr + 2;
2117 /* Compute average CPU frequency for this machine */
2118 st_pwr_cpufreq->cpufreq /= nr;
2124 ***************************************************************************
2125 * Read hugepages statistics from /proc/meminfo.
2128 * @st_huge Structure where stats will be saved.
2131 * @st_huge Structure with statistics.
2134 * 1 on success, 0 otherwise.
2135 ***************************************************************************
2137 __nr_t read_meminfo_huge(struct stats_huge *st_huge)
2141 unsigned long szhkb = 0;
2143 if ((fp = fopen(MEMINFO, "r")) == NULL)
2146 while (fgets(line, sizeof(line), fp) != NULL) {
2148 if (!strncmp(line, "HugePages_Total:", 16)) {
2149 /* Read the total number of huge pages */
2150 sscanf(line + 16, "%llu", &st_huge->tlhkb);
2152 else if (!strncmp(line, "HugePages_Free:", 15)) {
2153 /* Read the number of free huge pages */
2154 sscanf(line + 15, "%llu", &st_huge->frhkb);
2156 else if (!strncmp(line, "Hugepagesize:", 13)) {
2157 /* Read the default size of a huge page in kB */
2158 sscanf(line + 13, "%lu", &szhkb);
2164 /* We want huge pages stats in kB and not expressed in a number of pages */
2165 st_huge->tlhkb *= szhkb;
2166 st_huge->frhkb *= szhkb;
2171 ***************************************************************************
2172 * Read CPU average frequencies statistics.
2175 * @st_pwr_wghfreq Structure where stats will be saved.
2176 * @cpu_nr CPU number for which time_in_state date will be read.
2177 * @nbr Total number of states (frequencies).
2180 * @st_pwr_wghfreq Structure with statistics.
2183 * 1 on success, 0 otherwise.
2184 ***************************************************************************
2186 int read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr)
2189 struct stats_pwr_wghfreq *st_pwr_wghfreq_j;
2190 char filename[MAX_PF_NAME];
2194 unsigned long long time_in_state;
2196 snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s",
2197 SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE);
2198 if ((fp = fopen(filename, "r")) == NULL)
2201 while (fgets(line, sizeof(line), fp) != NULL) {
2203 sscanf(line, "%lu %llu", &freq, &time_in_state);
2206 /* Save current frequency and time */
2207 st_pwr_wghfreq_j = st_pwr_wghfreq + j;
2208 st_pwr_wghfreq_j->freq = freq;
2209 st_pwr_wghfreq_j->time_in_state = time_in_state;
2219 ***************************************************************************
2220 * Read weighted CPU frequency statistics.
2223 * @st_pwr_wghfreq Structure where stats will be saved.
2224 * @nr_alloc Total number of structures allocated. Value is >= 0.
2225 * @nr2 Number of sub-items allocated per structure.
2228 * @st_pwr_wghfreq Structure with statistics.
2231 * Number of CPU for which statistics have been read.
2232 * 1 means CPU "all", 2 means CPU "all" and 0, etc.
2233 * Or -1 if the buffer was to small and needs to be reallocated.
2234 ***************************************************************************
2236 __nr_t read_cpu_wghfreq(struct stats_pwr_wghfreq *st_pwr_wghfreq, __nr_t nr_alloc,
2239 __nr_t cpu_read = 0;
2241 struct stats_pwr_wghfreq *st_pwr_wghfreq_i, *st_pwr_wghfreq_j, *st_pwr_wghfreq_all_j;
2244 if (cpu_read + 2 > nr_alloc)
2247 /* Read current CPU time-in-state data */
2248 st_pwr_wghfreq_i = st_pwr_wghfreq + (cpu_read + 1) * nr2;
2249 if (!read_time_in_state(st_pwr_wghfreq_i, cpu_read, nr2))
2252 /* Also save data for CPU 'all' */
2253 for (j = 0; j < nr2; j++) {
2254 st_pwr_wghfreq_j = st_pwr_wghfreq_i + j; /* CPU #cpu, state #j */
2255 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2257 /* Assume that possible frequencies are the same for all CPUs */
2258 st_pwr_wghfreq_all_j->freq = st_pwr_wghfreq_j->freq;
2260 st_pwr_wghfreq_all_j->time_in_state += st_pwr_wghfreq_j->time_in_state;
2267 for (j = 0; j < nr2; j++) {
2268 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2269 st_pwr_wghfreq_all_j->time_in_state /= cpu_read;
2272 return cpu_read + 1; /* For CPU "all" */
2279 ***************************************************************************
2280 * Read current USB device data.
2283 * @st_pwr_usb Structure where stats will be saved.
2284 * @usb_device File name for current USB device.
2287 * @st_pwr_usb Structure with statistics.
2288 ***************************************************************************
2290 void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
2295 char filename[MAX_PF_NAME];
2297 /* Get USB device bus number */
2298 sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
2300 /* Read USB device vendor ID */
2301 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2302 SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
2303 if ((fp = fopen(filename, "r")) != NULL) {
2304 rc = fscanf(fp, "%x",
2305 &st_pwr_usb->vendor_id);
2308 st_pwr_usb->vendor_id = 0;
2312 /* Read USB device product ID */
2313 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2314 SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
2315 if ((fp = fopen(filename, "r")) != NULL) {
2316 rc = fscanf(fp, "%x",
2317 &st_pwr_usb->product_id);
2320 st_pwr_usb->product_id = 0;
2324 /* Read USB device max power consumption */
2325 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2326 SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
2327 if ((fp = fopen(filename, "r")) != NULL) {
2328 rc = fscanf(fp, "%u",
2329 &st_pwr_usb->bmaxpower);
2332 st_pwr_usb->bmaxpower = 0;
2336 /* Read USB device manufacturer */
2337 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2338 SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
2339 if ((fp = fopen(filename, "r")) != NULL) {
2340 rs = fgets(st_pwr_usb->manufacturer,
2341 MAX_MANUF_LEN - 1, fp);
2344 (l = strlen(st_pwr_usb->manufacturer)) > 0) {
2345 /* Remove trailing CR */
2346 st_pwr_usb->manufacturer[l - 1] = '\0';
2350 /* Read USB device product */
2351 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2352 SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
2353 if ((fp = fopen(filename, "r")) != NULL) {
2354 rs = fgets(st_pwr_usb->product,
2355 MAX_PROD_LEN - 1, fp);
2358 (l = strlen(st_pwr_usb->product)) > 0) {
2359 /* Remove trailing CR */
2360 st_pwr_usb->product[l - 1] = '\0';
2366 ***************************************************************************
2367 * Read USB devices statistics.
2370 * @st_pwr_usb Structure where stats will be saved.
2371 * @nr_alloc Total number of structures allocated. Value is >= 0.
2374 * @st_pwr_usb Structure with statistics.
2377 * Number of USB devices read, or -1 if the buffer was too small and
2378 * needs to be reallocated.
2379 ***************************************************************************
2381 __nr_t read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, __nr_t nr_alloc)
2385 struct stats_pwr_usb *st_pwr_usb_i;
2386 __nr_t usb_read = 0;
2388 /* Open relevant /sys directory */
2389 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
2392 /* Get current file entry */
2393 while ((drd = readdir(dir)) != NULL) {
2395 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
2397 if (usb_read + 1 > nr_alloc) {
2402 /* Read current USB device data */
2403 st_pwr_usb_i = st_pwr_usb + usb_read++;
2404 read_usb_stats(st_pwr_usb_i, drd->d_name);
2408 /* Close directory */
2414 ***************************************************************************
2415 * Read filesystems statistics.
2418 * @st_filesystem Structure where stats will be saved.
2419 * @nr_alloc Total number of structures allocated. Value is >= 0.
2422 * @st_filesystem Structure with statistics.
2425 * Number of filesystems read, or -1 if the buffer was too small and
2426 * needs to be reallocated.
2427 ***************************************************************************
2429 __nr_t read_filesystem(struct stats_filesystem *st_filesystem, __nr_t nr_alloc)
2432 char line[512], fs_name[128], mountp[256];
2433 int skip = 0, skip_next = 0;
2436 struct stats_filesystem *st_filesystem_i;
2439 if ((fp = fopen(MTAB, "r")) == NULL)
2442 while (fgets(line, sizeof(line), fp) != NULL) {
2444 * Ignore line if the preceding line did not contain '\n'.
2445 * (Some very long lines may be found for instance when
2446 * overlay2 filesystem with docker is used).
2449 skip_next = (strchr(line, '\n') == NULL);
2453 if (line[0] == '/') {
2454 /* Find field separator position */
2455 pos = strchr(line, ' ');
2459 /* Read current filesystem name */
2460 sscanf(line, "%127s", fs_name);
2462 * And now read the corresponding mount point.
2463 * Read fs name and mount point in two distinct operations.
2464 * Indeed, if fs name length is greater than 127 chars,
2465 * previous scanf() will read only the first 127 chars, and
2466 * mount point name will be read using the remaining chars
2467 * from the fs name. This will result in a bogus name
2468 * and following statvfs() function will always fail.
2470 sscanf(pos + 1, "%255s", mountp);
2472 /* Replace octal codes */
2476 * It's important to have read the whole mount point name
2477 * for statvfs() to work properly (see above).
2479 if ((statvfs(mountp, &buf) < 0) || (!buf.f_blocks))
2482 if (fs_read + 1 > nr_alloc) {
2487 st_filesystem_i = st_filesystem + fs_read++;
2488 st_filesystem_i->f_blocks = (unsigned long long) buf.f_blocks * (unsigned long long) buf.f_frsize;
2489 st_filesystem_i->f_bfree = (unsigned long long) buf.f_bfree * (unsigned long long) buf.f_frsize;
2490 st_filesystem_i->f_bavail = (unsigned long long) buf.f_bavail * (unsigned long long) buf.f_frsize;
2491 st_filesystem_i->f_files = (unsigned long long) buf.f_files;
2492 st_filesystem_i->f_ffree = (unsigned long long) buf.f_ffree;
2493 strncpy(st_filesystem_i->fs_name, fs_name, MAX_FS_LEN);
2494 st_filesystem_i->fs_name[MAX_FS_LEN - 1] = '\0';
2495 strncpy(st_filesystem_i->mountp, mountp, MAX_FS_LEN);
2496 st_filesystem_i->mountp[MAX_FS_LEN - 1] = '\0';
2505 ***************************************************************************
2506 * Read Fibre Channel HBA statistics.
2509 * @st_fc Structure where stats will be saved.
2510 * @nr_alloc Total number of structures allocated. Value is >= 0.
2513 * @st_fc Structure with statistics.
2516 * Number of FC hosts read, or -1 if the buffer was too small and needs to
2518 ***************************************************************************
2520 __nr_t read_fchost(struct stats_fchost *st_fc, __nr_t nr_alloc)
2525 struct stats_fchost *st_fc_i;
2526 __nr_t fch_read = 0;
2527 char fcstat_filename[MAX_PF_NAME];
2529 unsigned long rx_frames, tx_frames, rx_words, tx_words;
2531 /* Each host, if present, will have its own hostX entry within SYSFS_FCHOST */
2532 if ((dir = opendir(SYSFS_FCHOST)) == NULL)
2533 return 0; /* No FC hosts */
2536 * Read each of the counters via sysfs, where they are
2537 * returned as hex values (e.g. 0x72400).
2539 while ((drd = readdir(dir)) != NULL) {
2540 rx_frames = tx_frames = rx_words = tx_words = 0;
2542 if (!strncmp(drd->d_name, "host", 4)) {
2544 if (fch_read + 1 > nr_alloc) {
2549 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_FRAMES,
2550 SYSFS_FCHOST, drd->d_name);
2551 if ((fp = fopen(fcstat_filename, "r"))) {
2552 if (fgets(line, sizeof(line), fp)) {
2553 sscanf(line, "%lx", &rx_frames);
2558 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_FRAMES,
2559 SYSFS_FCHOST, drd->d_name);
2560 if ((fp = fopen(fcstat_filename, "r"))) {
2561 if (fgets(line, sizeof(line), fp)) {
2562 sscanf(line, "%lx", &tx_frames);
2567 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_WORDS,
2568 SYSFS_FCHOST, drd->d_name);
2569 if ((fp = fopen(fcstat_filename, "r"))) {
2570 if (fgets(line, sizeof(line), fp)) {
2571 sscanf(line, "%lx", &rx_words);
2576 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_WORDS,
2577 SYSFS_FCHOST, drd->d_name);
2578 if ((fp = fopen(fcstat_filename, "r"))) {
2579 if (fgets(line, sizeof(line), fp)) {
2580 sscanf(line, "%lx", &tx_words);
2585 st_fc_i = st_fc + fch_read++;
2586 st_fc_i->f_rxframes = rx_frames;
2587 st_fc_i->f_txframes = tx_frames;
2588 st_fc_i->f_rxwords = rx_words;
2589 st_fc_i->f_txwords = tx_words;
2590 strncpy(st_fc_i->fchost_name, drd->d_name, MAX_FCH_LEN);
2591 st_fc_i->fchost_name[MAX_FCH_LEN - 1] = '\0';
2600 ***************************************************************************
2601 * Read softnet statistics.
2604 * @st_softnet Structure where stats will be saved.
2605 * @nr_alloc Total number of structures allocated. Value is >= 0.
2606 * @online_cpu_bitmap
2607 * Bitmap listing online CPU.
2610 * @st_softnet Structure with statistics.
2613 * 1 if stats have been sucessfully read, or 0 otherwise.
2614 ***************************************************************************
2616 int read_softnet(struct stats_softnet *st_softnet, __nr_t nr_alloc,
2617 unsigned char online_cpu_bitmap[])
2620 struct stats_softnet *st_softnet_i;
2624 /* Open /proc/net/softnet_stat file */
2625 if ((fp = fopen(NET_SOFTNET, "r")) == NULL)
2628 for (cpu = 1; cpu < nr_alloc; cpu++) {
2629 if (!(online_cpu_bitmap[(cpu - 1) >> 3] & (1 << ((cpu - 1) & 0x07))))
2630 /* CPU is offline */
2633 if (fgets(line, sizeof(line), fp) == NULL)
2636 st_softnet_i = st_softnet + cpu;
2637 sscanf(line, "%x %x %x %*x %*x %*x %*x %*x %*x %x %x",
2638 &st_softnet_i->processed,
2639 &st_softnet_i->dropped,
2640 &st_softnet_i->time_squeeze,
2641 &st_softnet_i->received_rps,
2642 &st_softnet_i->flow_limit);
2649 /*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
2650 #endif /* SOURCE_SADC */