2 * rd_stats.c: Read system statistics
3 * (C) 1999-2019 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, dc_ios;
726 unsigned long rd_sec, wr_sec, dc_sec;
728 if ((fp = fopen(DISKSTATS, "r")) == NULL)
731 while (fgets(line, sizeof(line), fp) != NULL) {
733 /* Discard I/O stats may be not available */
742 &major, &minor, dev_name,
745 &dc_ios, &dc_sec) >= 7) {
747 if (is_device(dev_name, IGNORE_VIRTUAL_DEVICES)) {
749 * OK: It's a (real) device and not a partition.
750 * Note: Structure should have been initialized first!
752 st_io->dk_drive += (unsigned long long) rd_ios +
753 (unsigned long long) wr_ios +
754 (unsigned long long) dc_ios;
755 st_io->dk_drive_rio += rd_ios;
756 st_io->dk_drive_rblk += rd_sec;
757 st_io->dk_drive_wio += wr_ios;
758 st_io->dk_drive_wblk += wr_sec;
759 st_io->dk_drive_dio += dc_ios;
760 st_io->dk_drive_dblk += dc_sec;
770 ***************************************************************************
771 * Read block devices statistics from /proc/diskstats.
774 * @st_disk Structure where stats will be saved.
775 * @nr_alloc Total number of structures allocated. Value is >= 1.
776 * @read_part True if disks *and* partitions should be read; False if only
780 * @st_disk Structure with statistics.
783 * Number of block devices read, or -1 if the buffer was too small and
784 * needs to be reallocated.
785 ***************************************************************************
787 __nr_t read_diskstats_disk(struct stats_disk *st_disk, __nr_t nr_alloc,
792 char dev_name[MAX_NAME_LEN];
793 struct stats_disk *st_disk_i;
794 unsigned int major, minor, rd_ticks, wr_ticks, dc_ticks, tot_ticks, rq_ticks;
795 unsigned long rd_ios, wr_ios, dc_ios, rd_sec, wr_sec, dc_sec;
798 if ((fp = fopen(DISKSTATS, "r")) == NULL)
801 while (fgets(line, sizeof(line), fp) != NULL) {
803 /* Discard I/O stats may be not available */
804 dc_ios = dc_sec = dc_ticks = 0;
812 &major, &minor, dev_name,
813 &rd_ios, &rd_sec, &rd_ticks,
814 &wr_ios, &wr_sec, &wr_ticks,
815 &tot_ticks, &rq_ticks,
816 &dc_ios, &dc_sec, &dc_ticks) >= 11) {
818 if (!rd_ios && !wr_ios && !dc_ios)
819 /* Unused device: Ignore it */
821 if (read_part || is_device(dev_name, ACCEPT_VIRTUAL_DEVICES)) {
823 if (dsk_read + 1 > nr_alloc) {
828 st_disk_i = st_disk + dsk_read++;
829 st_disk_i->major = major;
830 st_disk_i->minor = minor;
831 st_disk_i->nr_ios = (unsigned long long) rd_ios +
832 (unsigned long long) wr_ios +
833 (unsigned long long) dc_ios;
834 st_disk_i->rd_sect = rd_sec;
835 st_disk_i->wr_sect = wr_sec;
836 st_disk_i->dc_sect = dc_sec;
837 st_disk_i->rd_ticks = rd_ticks;
838 st_disk_i->wr_ticks = wr_ticks;
839 st_disk_i->dc_ticks = dc_ticks;
840 st_disk_i->tot_ticks = tot_ticks;
841 st_disk_i->rq_ticks = rq_ticks;
851 ***************************************************************************
852 * Read serial lines statistics from /proc/tty/driver/serial.
855 * @st_serial Structure where stats will be saved.
856 * @nr_alloc Total number of structures allocated. Value is >= 1.
859 * @st_serial Structure with statistics.
862 * Number of serial lines read, or -1 if the buffer was too small and
863 * needs to be reallocated.
864 ***************************************************************************
866 __nr_t read_tty_driver_serial(struct stats_serial *st_serial, __nr_t nr_alloc)
869 struct stats_serial *st_serial_i;
874 if ((fp = fopen(SERIAL, "r")) == NULL)
877 while (fgets(line, sizeof(line), fp) != NULL ) {
879 if ((p = strstr(line, "tx:")) != NULL) {
881 if (sl_read + 1 > nr_alloc) {
886 st_serial_i = st_serial + sl_read++;
887 /* Read serial line number */
888 sscanf(line, "%u", &st_serial_i->line);
890 * Read the number of chars transmitted and received by
891 * current serial line.
893 sscanf(p + 3, "%u", &st_serial_i->tx);
894 if ((p = strstr(line, "rx:")) != NULL) {
895 sscanf(p + 3, "%u", &st_serial_i->rx);
897 if ((p = strstr(line, "fe:")) != NULL) {
898 sscanf(p + 3, "%u", &st_serial_i->frame);
900 if ((p = strstr(line, "pe:")) != NULL) {
901 sscanf(p + 3, "%u", &st_serial_i->parity);
903 if ((p = strstr(line, "brk:")) != NULL) {
904 sscanf(p + 4, "%u", &st_serial_i->brk);
906 if ((p = strstr(line, "oe:")) != NULL) {
907 sscanf(p + 3, "%u", &st_serial_i->overrun);
917 ***************************************************************************
918 * Read kernel tables statistics from various system files.
921 * @st_ktables Structure where stats will be saved.
924 * @st_ktables Structure with statistics.
927 * 1 (always success).
928 ***************************************************************************
930 __nr_t read_kernel_tables(struct stats_ktables *st_ktables)
933 unsigned long long parm;
936 /* Open /proc/sys/fs/dentry-state file */
937 if ((fp = fopen(FDENTRY_STATE, "r")) != NULL) {
938 rc = fscanf(fp, "%*d %llu",
939 &st_ktables->dentry_stat);
942 st_ktables->dentry_stat = 0;
946 /* Open /proc/sys/fs/file-nr file */
947 if ((fp = fopen(FFILE_NR, "r")) != NULL) {
948 rc = fscanf(fp, "%llu %llu",
949 &st_ktables->file_used, &parm);
952 * The number of used handles is the number of allocated ones
953 * minus the number of free ones.
956 st_ktables->file_used -= parm;
959 st_ktables->file_used = 0;
963 /* Open /proc/sys/fs/inode-state file */
964 if ((fp = fopen(FINODE_STATE, "r")) != NULL) {
965 rc = fscanf(fp, "%llu %llu",
966 &st_ktables->inode_used, &parm);
969 * The number of inuse inodes is the number of allocated ones
970 * minus the number of free ones.
973 st_ktables->inode_used -= parm;
976 st_ktables->inode_used = 0;
980 /* Open /proc/sys/kernel/pty/nr file */
981 if ((fp = fopen(PTY_NR, "r")) != NULL) {
982 rc = fscanf(fp, "%llu",
983 &st_ktables->pty_nr);
986 st_ktables->pty_nr = 0;
994 ***************************************************************************
995 * Read network interfaces statistics from /proc/net/dev.
998 * @st_net_dev Structure where stats will be saved.
999 * @nr_alloc Total number of structures allocated. Value is >= 1.
1002 * @st_net_dev Structure with statistics.
1005 * Number of interfaces read, or -1 if the buffer was too small and
1006 * needs to be reallocated.
1007 ***************************************************************************
1009 __nr_t read_net_dev(struct stats_net_dev *st_net_dev, __nr_t nr_alloc)
1012 struct stats_net_dev *st_net_dev_i;
1014 char iface[MAX_IFACE_LEN];
1015 __nr_t dev_read = 0;
1018 if ((fp = fopen(NET_DEV, "r")) == NULL)
1021 while (fgets(line, sizeof(line), fp) != NULL) {
1023 pos = strcspn(line, ":");
1024 if (pos < strlen(line)) {
1026 if (dev_read + 1 > nr_alloc) {
1031 st_net_dev_i = st_net_dev + dev_read++;
1032 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1033 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1034 sscanf(iface, "%s", st_net_dev_i->interface); /* Skip heading spaces */
1035 sscanf(line + pos + 1, "%llu %llu %*u %*u %*u %*u %llu %llu %llu %llu "
1036 "%*u %*u %*u %*u %*u %llu",
1037 &st_net_dev_i->rx_bytes,
1038 &st_net_dev_i->rx_packets,
1039 &st_net_dev_i->rx_compressed,
1040 &st_net_dev_i->multicast,
1041 &st_net_dev_i->tx_bytes,
1042 &st_net_dev_i->tx_packets,
1043 &st_net_dev_i->tx_compressed);
1052 ***************************************************************************
1053 * Read duplex and speed data for network interface cards.
1056 * @st_net_dev Structure where stats will be saved.
1057 * @nbr Number of network interfaces to read.
1060 * @st_net_dev Structure with statistics.
1061 ***************************************************************************
1063 void read_if_info(struct stats_net_dev *st_net_dev, int nbr)
1066 struct stats_net_dev *st_net_dev_i;
1067 char filename[128], duplex[32];
1070 for (dev = 0; dev < nbr; dev++) {
1072 st_net_dev_i = st_net_dev + dev;
1074 /* Read speed info */
1075 sprintf(filename, IF_DUPLEX, st_net_dev_i->interface);
1077 if ((fp = fopen(filename, "r")) == NULL)
1078 /* Cannot read NIC duplex */
1081 n = fscanf(fp, "%31s", duplex);
1086 /* Cannot read NIC duplex */
1089 if (!strcmp(duplex, K_DUPLEX_FULL)) {
1090 st_net_dev_i->duplex = C_DUPLEX_FULL;
1092 else if (!strcmp(duplex, K_DUPLEX_HALF)) {
1093 st_net_dev_i->duplex = C_DUPLEX_HALF;
1098 /* Read speed info */
1099 sprintf(filename, IF_SPEED, st_net_dev_i->interface);
1101 if ((fp = fopen(filename, "r")) == NULL)
1102 /* Cannot read NIC speed */
1105 n = fscanf(fp, "%u", &st_net_dev_i->speed);
1110 st_net_dev_i->speed = 0;
1117 ***************************************************************************
1118 * Read network interfaces errors statistics from /proc/net/dev.
1121 * @st_net_edev Structure where stats will be saved.
1122 * @nr_alloc Total number of structures allocated. Value is >= 1.
1125 * @st_net_edev Structure with statistics.
1128 * Number of interfaces read, or -1 if the buffer was too small and
1129 * needs to be reallocated.
1130 ***************************************************************************
1132 __nr_t read_net_edev(struct stats_net_edev *st_net_edev, __nr_t nr_alloc)
1135 struct stats_net_edev *st_net_edev_i;
1136 static char line[256];
1137 char iface[MAX_IFACE_LEN];
1138 __nr_t dev_read = 0;
1141 if ((fp = fopen(NET_DEV, "r")) == NULL)
1144 while (fgets(line, sizeof(line), fp) != NULL) {
1146 pos = strcspn(line, ":");
1147 if (pos < strlen(line)) {
1149 if (dev_read + 1 > nr_alloc) {
1154 st_net_edev_i = st_net_edev + dev_read++;
1155 strncpy(iface, line, MINIMUM(pos, MAX_IFACE_LEN - 1));
1156 iface[MINIMUM(pos, MAX_IFACE_LEN - 1)] = '\0';
1157 sscanf(iface, "%s", st_net_edev_i->interface); /* Skip heading spaces */
1158 sscanf(line + pos + 1, "%*u %*u %llu %llu %llu %llu %*u %*u %*u %*u "
1159 "%llu %llu %llu %llu %llu",
1160 &st_net_edev_i->rx_errors,
1161 &st_net_edev_i->rx_dropped,
1162 &st_net_edev_i->rx_fifo_errors,
1163 &st_net_edev_i->rx_frame_errors,
1164 &st_net_edev_i->tx_errors,
1165 &st_net_edev_i->tx_dropped,
1166 &st_net_edev_i->tx_fifo_errors,
1167 &st_net_edev_i->collisions,
1168 &st_net_edev_i->tx_carrier_errors);
1177 ***************************************************************************
1178 * Read NFS client statistics from /proc/net/rpc/nfs.
1181 * @st_net_nfs Structure where stats will be saved.
1184 * @st_net_nfs Structure with statistics.
1187 * 1 on success, 0 otherwise.
1188 ***************************************************************************
1190 __nr_t read_net_nfs(struct stats_net_nfs *st_net_nfs)
1194 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1196 if ((fp = fopen(NET_RPC_NFS, "r")) == NULL)
1199 memset(st_net_nfs, 0, STATS_NET_NFS_SIZE);
1201 while (fgets(line, sizeof(line), fp) != NULL) {
1203 if (!strncmp(line, "rpc ", 4)) {
1204 sscanf(line + 4, "%u %u",
1205 &st_net_nfs->nfs_rpccnt, &st_net_nfs->nfs_rpcretrans);
1207 else if (!strncmp(line, "proc3 ", 6)) {
1208 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1209 &getattcnt, &accesscnt, &readcnt, &writecnt);
1211 st_net_nfs->nfs_getattcnt += getattcnt;
1212 st_net_nfs->nfs_accesscnt += accesscnt;
1213 st_net_nfs->nfs_readcnt += readcnt;
1214 st_net_nfs->nfs_writecnt += writecnt;
1216 else if (!strncmp(line, "proc4 ", 6)) {
1217 sscanf(line + 6, "%*u %*u %u %u "
1218 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u %u",
1219 &readcnt, &writecnt, &accesscnt, &getattcnt);
1221 st_net_nfs->nfs_getattcnt += getattcnt;
1222 st_net_nfs->nfs_accesscnt += accesscnt;
1223 st_net_nfs->nfs_readcnt += readcnt;
1224 st_net_nfs->nfs_writecnt += writecnt;
1233 ***************************************************************************
1234 * Read NFS server statistics from /proc/net/rpc/nfsd.
1237 * @st_net_nfsd Structure where stats will be saved.
1240 * @st_net_nfsd Structure with statistics.
1243 * 1 on success, 0 otherwise.
1244 ***************************************************************************
1246 __nr_t read_net_nfsd(struct stats_net_nfsd *st_net_nfsd)
1250 unsigned int getattcnt = 0, accesscnt = 0, readcnt = 0, writecnt = 0;
1252 if ((fp = fopen(NET_RPC_NFSD, "r")) == NULL)
1255 memset(st_net_nfsd, 0, STATS_NET_NFSD_SIZE);
1257 while (fgets(line, sizeof(line), fp) != NULL) {
1259 if (!strncmp(line, "rc ", 3)) {
1260 sscanf(line + 3, "%u %u",
1261 &st_net_nfsd->nfsd_rchits, &st_net_nfsd->nfsd_rcmisses);
1263 else if (!strncmp(line, "net ", 4)) {
1264 sscanf(line + 4, "%u %u %u",
1265 &st_net_nfsd->nfsd_netcnt, &st_net_nfsd->nfsd_netudpcnt,
1266 &st_net_nfsd->nfsd_nettcpcnt);
1268 else if (!strncmp(line, "rpc ", 4)) {
1269 sscanf(line + 4, "%u %u",
1270 &st_net_nfsd->nfsd_rpccnt, &st_net_nfsd->nfsd_rpcbad);
1272 else if (!strncmp(line, "proc3 ", 6)) {
1273 sscanf(line + 6, "%*u %*u %u %*u %*u %u %*u %u %u",
1274 &getattcnt, &accesscnt, &readcnt, &writecnt);
1276 st_net_nfsd->nfsd_getattcnt += getattcnt;
1277 st_net_nfsd->nfsd_accesscnt += accesscnt;
1278 st_net_nfsd->nfsd_readcnt += readcnt;
1279 st_net_nfsd->nfsd_writecnt += writecnt;
1282 else if (!strncmp(line, "proc4ops ", 9)) {
1283 sscanf(line + 9, "%*u %*u %*u %*u %u "
1284 "%*u %*u %*u %*u %*u %u "
1285 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u "
1286 "%*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u",
1287 &accesscnt, &getattcnt, &readcnt, &writecnt);
1289 st_net_nfsd->nfsd_getattcnt += getattcnt;
1290 st_net_nfsd->nfsd_accesscnt += accesscnt;
1291 st_net_nfsd->nfsd_readcnt += readcnt;
1292 st_net_nfsd->nfsd_writecnt += writecnt;
1301 ***************************************************************************
1302 * Read network sockets statistics from /proc/net/sockstat.
1305 * @st_net_sock Structure where stats will be saved.
1308 * @st_net_sock Structure with statistics.
1311 * 1 on success, 0 otherwise.
1312 ***************************************************************************
1314 __nr_t read_net_sock(struct stats_net_sock *st_net_sock)
1320 if ((fp = fopen(NET_SOCKSTAT, "r")) == NULL)
1323 while (fgets(line, sizeof(line), fp) != NULL) {
1325 if (!strncmp(line, "sockets:", 8)) {
1327 sscanf(line + 14, "%u", &st_net_sock->sock_inuse);
1329 else if (!strncmp(line, "TCP:", 4)) {
1331 sscanf(line + 11, "%u", &st_net_sock->tcp_inuse);
1332 if ((p = strstr(line, "tw")) != NULL) {
1333 sscanf(p + 2, "%u", &st_net_sock->tcp_tw);
1336 else if (!strncmp(line, "UDP:", 4)) {
1338 sscanf(line + 11, "%u", &st_net_sock->udp_inuse);
1340 else if (!strncmp(line, "RAW:", 4)) {
1342 sscanf(line + 11, "%u", &st_net_sock->raw_inuse);
1344 else if (!strncmp(line, "FRAG:", 5)) {
1346 sscanf(line + 12, "%u", &st_net_sock->frag_inuse);
1355 ***************************************************************************
1356 * Read IP network traffic statistics from /proc/net/snmp.
1359 * @st_net_ip Structure where stats will be saved.
1362 * @st_net_ip Structure with statistics.
1365 * 1 on success, 0 otherwise.
1366 ***************************************************************************
1368 __nr_t read_net_ip(struct stats_net_ip *st_net_ip)
1374 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1377 while (fgets(line, sizeof(line), fp) != NULL) {
1379 if (!strncmp(line, "Ip:", 3)) {
1381 sscanf(line + 3, "%*u %*u %llu %*u %*u %llu %*u %*u "
1382 "%llu %llu %*u %*u %*u %llu %llu %*u %llu %*u %llu",
1383 &st_net_ip->InReceives,
1384 &st_net_ip->ForwDatagrams,
1385 &st_net_ip->InDelivers,
1386 &st_net_ip->OutRequests,
1387 &st_net_ip->ReasmReqds,
1388 &st_net_ip->ReasmOKs,
1389 &st_net_ip->FragOKs,
1390 &st_net_ip->FragCreates);
1405 ***************************************************************************
1406 * Read IP network errors statistics from /proc/net/snmp.
1409 * @st_net_eip Structure where stats will be saved.
1412 * @st_net_eip Structure with statistics.
1415 * 1 on success, 0 otherwise.
1416 ***************************************************************************
1418 __nr_t read_net_eip(struct stats_net_eip *st_net_eip)
1424 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1427 while (fgets(line, sizeof(line), fp) != NULL) {
1429 if (!strncmp(line, "Ip:", 3)) {
1431 sscanf(line + 3, "%*u %*u %*u %llu %llu %*u %llu %llu "
1432 "%*u %*u %llu %llu %*u %*u %*u %llu %*u %llu",
1433 &st_net_eip->InHdrErrors,
1434 &st_net_eip->InAddrErrors,
1435 &st_net_eip->InUnknownProtos,
1436 &st_net_eip->InDiscards,
1437 &st_net_eip->OutDiscards,
1438 &st_net_eip->OutNoRoutes,
1439 &st_net_eip->ReasmFails,
1440 &st_net_eip->FragFails);
1455 ***************************************************************************
1456 * Read ICMP network traffic statistics from /proc/net/snmp.
1459 * @st_net_icmp Structure where stats will be saved.
1462 * @st_net_icmp Structure with statistics.
1465 * 1 on success, 0 otherwise.
1466 ***************************************************************************
1468 __nr_t read_net_icmp(struct stats_net_icmp *st_net_icmp)
1472 static char format[256] = "";
1475 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1478 while (fgets(line, sizeof(line), fp) != NULL) {
1480 if (!strncmp(line, "Icmp:", 5)) {
1482 sscanf(line + 5, format,
1483 &st_net_icmp->InMsgs,
1484 &st_net_icmp->InEchos,
1485 &st_net_icmp->InEchoReps,
1486 &st_net_icmp->InTimestamps,
1487 &st_net_icmp->InTimestampReps,
1488 &st_net_icmp->InAddrMasks,
1489 &st_net_icmp->InAddrMaskReps,
1490 &st_net_icmp->OutMsgs,
1491 &st_net_icmp->OutEchos,
1492 &st_net_icmp->OutEchoReps,
1493 &st_net_icmp->OutTimestamps,
1494 &st_net_icmp->OutTimestampReps,
1495 &st_net_icmp->OutAddrMasks,
1496 &st_net_icmp->OutAddrMaskReps);
1501 if (!strlen(format)) {
1502 if (strstr(line, "InCsumErrors")) {
1504 * New format: InCsumErrors field exists at position #3.
1505 * Capture: 1,9,10,11,12,13,14,15,22,23,24,25,26,27.
1507 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u %*u "
1508 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1509 "%*u %*u %lu %lu %lu %lu %lu %lu");
1513 * Old format: InCsumErrors field doesn't exist.
1514 * Capture: 1,8,9,10,11,12,13,14,21,22,23,24,25,26.
1516 strcpy(format, "%lu %*u %*u %*u %*u %*u %*u "
1517 "%lu %lu %lu %lu %lu %lu %lu %*u %*u %*u %*u "
1518 "%*u %*u %lu %lu %lu %lu %lu %lu");
1531 ***************************************************************************
1532 * Read ICMP network errors statistics from /proc/net/snmp.
1535 * @st_net_eicmp Structure where stats will be saved.
1538 * @st_net_eicmp Structure with statistics.
1541 * 1 on success, 0 otherwise.
1542 ***************************************************************************
1544 __nr_t read_net_eicmp(struct stats_net_eicmp *st_net_eicmp)
1548 static char format[256] = "";
1551 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1554 while (fgets(line, sizeof(line), fp) != NULL) {
1556 if (!strncmp(line, "Icmp:", 5)) {
1558 sscanf(line + 5, format,
1559 &st_net_eicmp->InErrors,
1560 &st_net_eicmp->InDestUnreachs,
1561 &st_net_eicmp->InTimeExcds,
1562 &st_net_eicmp->InParmProbs,
1563 &st_net_eicmp->InSrcQuenchs,
1564 &st_net_eicmp->InRedirects,
1565 &st_net_eicmp->OutErrors,
1566 &st_net_eicmp->OutDestUnreachs,
1567 &st_net_eicmp->OutTimeExcds,
1568 &st_net_eicmp->OutParmProbs,
1569 &st_net_eicmp->OutSrcQuenchs,
1570 &st_net_eicmp->OutRedirects);
1575 if (!strlen(format)) {
1576 if (strstr(line, "InCsumErrors")) {
1578 * New format: InCsumErrors field exists at position #3.
1579 * Capture: 2,4,5,6,7,8,16,17,18,19,20,21
1581 strcpy(format, "%*u %lu %*u %lu %lu %lu %lu %lu %*u %*u "
1582 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu");
1586 * Old format: InCsumErrors field doesn't exist.
1587 * Capture: 2,3,4,5,6,7,15,16,17,18,19,20
1589 strcpy(format, "%*u %lu %lu %lu %lu %lu %lu %*u %*u "
1590 "%*u %*u %*u %*u %*u %lu %lu %lu %lu %lu %lu");
1604 ***************************************************************************
1605 * Read TCP network traffic statistics from /proc/net/snmp.
1608 * @st_net_tcp Structure where stats will be saved.
1611 * @st_net_tcp Structure with statistics.
1614 * 1 on success, 0 otherwise.
1615 ***************************************************************************
1617 __nr_t read_net_tcp(struct stats_net_tcp *st_net_tcp)
1623 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1626 while (fgets(line, sizeof(line), fp) != NULL) {
1628 if (!strncmp(line, "Tcp:", 4)) {
1630 sscanf(line + 4, "%*u %*u %*u %*d %lu %lu "
1631 "%*u %*u %*u %lu %lu",
1632 &st_net_tcp->ActiveOpens,
1633 &st_net_tcp->PassiveOpens,
1634 &st_net_tcp->InSegs,
1635 &st_net_tcp->OutSegs);
1650 ***************************************************************************
1651 * Read TCP network errors statistics from /proc/net/snmp.
1654 * @st_net_etcp Structure where stats will be saved.
1657 * @st_net_etcp Structure with statistics.
1660 * 1 on success, 0 otherwise.
1661 ***************************************************************************
1663 __nr_t read_net_etcp(struct stats_net_etcp *st_net_etcp)
1669 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1672 while (fgets(line, sizeof(line), fp) != NULL) {
1674 if (!strncmp(line, "Tcp:", 4)) {
1676 sscanf(line + 4, "%*u %*u %*u %*d %*u %*u "
1677 "%lu %lu %*u %*u %*u %lu %lu %lu",
1678 &st_net_etcp->AttemptFails,
1679 &st_net_etcp->EstabResets,
1680 &st_net_etcp->RetransSegs,
1681 &st_net_etcp->InErrs,
1682 &st_net_etcp->OutRsts);
1697 ***************************************************************************
1698 * Read UDP network traffic statistics from /proc/net/snmp.
1701 * @st_net_udp Structure where stats will be saved.
1704 * @st_net_udp Structure with statistics.
1707 * 1 on success, 0 otherwise.
1708 ***************************************************************************
1710 __nr_t read_net_udp(struct stats_net_udp *st_net_udp)
1716 if ((fp = fopen(NET_SNMP, "r")) == NULL)
1719 while (fgets(line, sizeof(line), fp) != NULL) {
1721 if (!strncmp(line, "Udp:", 4)) {
1723 sscanf(line + 4, "%lu %lu %lu %lu",
1724 &st_net_udp->InDatagrams,
1725 &st_net_udp->NoPorts,
1726 &st_net_udp->InErrors,
1727 &st_net_udp->OutDatagrams);
1742 ***************************************************************************
1743 * Read IPv6 network sockets statistics from /proc/net/sockstat6.
1746 * @st_net_sock6 Structure where stats will be saved.
1749 * @st_net_sock6 Structure with statistics.
1752 * 1 on success, 0 otherwise.
1753 ***************************************************************************
1755 __nr_t read_net_sock6(struct stats_net_sock6 *st_net_sock6)
1760 if ((fp = fopen(NET_SOCKSTAT6, "r")) == NULL)
1763 while (fgets(line, sizeof(line), fp) != NULL) {
1765 if (!strncmp(line, "TCP6:", 5)) {
1767 sscanf(line + 12, "%u", &st_net_sock6->tcp6_inuse);
1769 else if (!strncmp(line, "UDP6:", 5)) {
1771 sscanf(line + 12, "%u", &st_net_sock6->udp6_inuse);
1773 else if (!strncmp(line, "RAW6:", 5)) {
1774 /* IPv6 RAW sockets */
1775 sscanf(line + 12, "%u", &st_net_sock6->raw6_inuse);
1777 else if (!strncmp(line, "FRAG6:", 6)) {
1778 /* IPv6 FRAGments */
1779 sscanf(line + 13, "%u", &st_net_sock6->frag6_inuse);
1788 ***************************************************************************
1789 * Read IPv6 network traffic statistics from /proc/net/snmp6.
1792 * @st_net_ip6 Structure where stats will be saved.
1795 * @st_net_ip6 Structure with statistics.
1798 * 1 on success, 0 otherwise.
1799 ***************************************************************************
1801 __nr_t read_net_ip6(struct stats_net_ip6 *st_net_ip6)
1806 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1809 while (fgets(line, sizeof(line), fp) != NULL) {
1811 if (!strncmp(line, "Ip6InReceives ", 14)) {
1812 sscanf(line + 14, "%llu", &st_net_ip6->InReceives6);
1814 else if (!strncmp(line, "Ip6OutForwDatagrams ", 20)) {
1815 sscanf(line + 20, "%llu", &st_net_ip6->OutForwDatagrams6);
1817 else if (!strncmp(line, "Ip6InDelivers ", 14)) {
1818 sscanf(line + 14, "%llu", &st_net_ip6->InDelivers6);
1820 else if (!strncmp(line, "Ip6OutRequests ", 15)) {
1821 sscanf(line + 15, "%llu", &st_net_ip6->OutRequests6);
1823 else if (!strncmp(line, "Ip6ReasmReqds ", 14)) {
1824 sscanf(line + 14, "%llu", &st_net_ip6->ReasmReqds6);
1826 else if (!strncmp(line, "Ip6ReasmOKs ", 12)) {
1827 sscanf(line + 12, "%llu", &st_net_ip6->ReasmOKs6);
1829 else if (!strncmp(line, "Ip6InMcastPkts ", 15)) {
1830 sscanf(line + 15, "%llu", &st_net_ip6->InMcastPkts6);
1832 else if (!strncmp(line, "Ip6OutMcastPkts ", 16)) {
1833 sscanf(line + 16, "%llu", &st_net_ip6->OutMcastPkts6);
1835 else if (!strncmp(line, "Ip6FragOKs ", 11)) {
1836 sscanf(line + 11, "%llu", &st_net_ip6->FragOKs6);
1838 else if (!strncmp(line, "Ip6FragCreates ", 15)) {
1839 sscanf(line + 15, "%llu", &st_net_ip6->FragCreates6);
1848 ***************************************************************************
1849 * Read IPv6 network errors statistics from /proc/net/snmp6.
1852 * @st_net_eip6 Structure where stats will be saved.
1855 * @st_net_eip6 Structure with statistics.
1858 * 1 on success, 0 otherwise.
1859 ***************************************************************************
1861 __nr_t read_net_eip6(struct stats_net_eip6 *st_net_eip6)
1866 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1869 while (fgets(line, sizeof(line), fp) != NULL) {
1871 if (!strncmp(line, "Ip6InHdrErrors ", 15)) {
1872 sscanf(line + 15, "%llu", &st_net_eip6->InHdrErrors6);
1874 else if (!strncmp(line, "Ip6InAddrErrors ", 16)) {
1875 sscanf(line + 16, "%llu", &st_net_eip6->InAddrErrors6);
1877 else if (!strncmp(line, "Ip6InUnknownProtos ", 19)) {
1878 sscanf(line + 19, "%llu", &st_net_eip6->InUnknownProtos6);
1880 else if (!strncmp(line, "Ip6InTooBigErrors ", 18)) {
1881 sscanf(line + 18, "%llu", &st_net_eip6->InTooBigErrors6);
1883 else if (!strncmp(line, "Ip6InDiscards ", 14)) {
1884 sscanf(line + 14, "%llu", &st_net_eip6->InDiscards6);
1886 else if (!strncmp(line, "Ip6OutDiscards ", 15)) {
1887 sscanf(line + 15, "%llu", &st_net_eip6->OutDiscards6);
1889 else if (!strncmp(line, "Ip6InNoRoutes ", 14)) {
1890 sscanf(line + 14, "%llu", &st_net_eip6->InNoRoutes6);
1892 else if (!strncmp(line, "Ip6OutNoRoutes ", 15)) {
1893 sscanf(line + 15, "%llu", &st_net_eip6->OutNoRoutes6);
1895 else if (!strncmp(line, "Ip6ReasmFails ", 14)) {
1896 sscanf(line + 14, "%llu", &st_net_eip6->ReasmFails6);
1898 else if (!strncmp(line, "Ip6FragFails ", 13)) {
1899 sscanf(line + 13, "%llu", &st_net_eip6->FragFails6);
1901 else if (!strncmp(line, "Ip6InTruncatedPkts ", 19)) {
1902 sscanf(line + 19, "%llu", &st_net_eip6->InTruncatedPkts6);
1911 ***************************************************************************
1912 * Read ICMPv6 network traffic statistics from /proc/net/snmp6.
1915 * @st_net_icmp6 Structure where stats will be saved.
1918 * @st_net_icmp6 Structure with statistics.
1921 * 1 on success, 0 otherwise.
1922 ***************************************************************************
1924 __nr_t read_net_icmp6(struct stats_net_icmp6 *st_net_icmp6)
1929 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
1932 while (fgets(line, sizeof(line), fp) != NULL) {
1934 if (!strncmp(line, "Icmp6InMsgs ", 12)) {
1935 sscanf(line + 12, "%lu", &st_net_icmp6->InMsgs6);
1937 else if (!strncmp(line, "Icmp6OutMsgs ", 13)) {
1938 sscanf(line + 13, "%lu", &st_net_icmp6->OutMsgs6);
1940 else if (!strncmp(line, "Icmp6InEchos ", 13)) {
1941 sscanf(line + 13, "%lu", &st_net_icmp6->InEchos6);
1943 else if (!strncmp(line, "Icmp6InEchoReplies ", 19)) {
1944 sscanf(line + 19, "%lu", &st_net_icmp6->InEchoReplies6);
1946 else if (!strncmp(line, "Icmp6OutEchoReplies ", 20)) {
1947 sscanf(line + 20, "%lu", &st_net_icmp6->OutEchoReplies6);
1949 else if (!strncmp(line, "Icmp6InGroupMembQueries ", 24)) {
1950 sscanf(line + 24, "%lu", &st_net_icmp6->InGroupMembQueries6);
1952 else if (!strncmp(line, "Icmp6InGroupMembResponses ", 26)) {
1953 sscanf(line + 26, "%lu", &st_net_icmp6->InGroupMembResponses6);
1955 else if (!strncmp(line, "Icmp6OutGroupMembResponses ", 27)) {
1956 sscanf(line + 27, "%lu", &st_net_icmp6->OutGroupMembResponses6);
1958 else if (!strncmp(line, "Icmp6InGroupMembReductions ", 27)) {
1959 sscanf(line + 27, "%lu", &st_net_icmp6->InGroupMembReductions6);
1961 else if (!strncmp(line, "Icmp6OutGroupMembReductions ", 28)) {
1962 sscanf(line + 28, "%lu", &st_net_icmp6->OutGroupMembReductions6);
1964 else if (!strncmp(line, "Icmp6InRouterSolicits ", 22)) {
1965 sscanf(line + 22, "%lu", &st_net_icmp6->InRouterSolicits6);
1967 else if (!strncmp(line, "Icmp6OutRouterSolicits ", 23)) {
1968 sscanf(line + 23, "%lu", &st_net_icmp6->OutRouterSolicits6);
1970 else if (!strncmp(line, "Icmp6InRouterAdvertisements ", 28)) {
1971 sscanf(line + 28, "%lu", &st_net_icmp6->InRouterAdvertisements6);
1973 else if (!strncmp(line, "Icmp6InNeighborSolicits ", 24)) {
1974 sscanf(line + 24, "%lu", &st_net_icmp6->InNeighborSolicits6);
1976 else if (!strncmp(line, "Icmp6OutNeighborSolicits ", 25)) {
1977 sscanf(line + 25, "%lu", &st_net_icmp6->OutNeighborSolicits6);
1979 else if (!strncmp(line, "Icmp6InNeighborAdvertisements ", 30)) {
1980 sscanf(line + 30, "%lu", &st_net_icmp6->InNeighborAdvertisements6);
1982 else if (!strncmp(line, "Icmp6OutNeighborAdvertisements ", 31)) {
1983 sscanf(line + 31, "%lu", &st_net_icmp6->OutNeighborAdvertisements6);
1992 ***************************************************************************
1993 * Read ICMPv6 network errors statistics from /proc/net/snmp6.
1996 * @st_net_eicmp6 Structure where stats will be saved.
1999 * @st_net_eicmp6 Structure with statistics.
2002 * 1 on success, 0 otherwise.
2003 ***************************************************************************
2005 __nr_t read_net_eicmp6(struct stats_net_eicmp6 *st_net_eicmp6)
2010 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
2013 while (fgets(line, sizeof(line), fp) != NULL) {
2015 if (!strncmp(line, "Icmp6InErrors ", 14)) {
2016 sscanf(line + 14, "%lu", &st_net_eicmp6->InErrors6);
2018 else if (!strncmp(line, "Icmp6InDestUnreachs ", 20)) {
2019 sscanf(line + 20, "%lu", &st_net_eicmp6->InDestUnreachs6);
2021 else if (!strncmp(line, "Icmp6OutDestUnreachs ", 21)) {
2022 sscanf(line + 21, "%lu", &st_net_eicmp6->OutDestUnreachs6);
2024 else if (!strncmp(line, "Icmp6InTimeExcds ", 17)) {
2025 sscanf(line + 17, "%lu", &st_net_eicmp6->InTimeExcds6);
2027 else if (!strncmp(line, "Icmp6OutTimeExcds ", 18)) {
2028 sscanf(line + 18, "%lu", &st_net_eicmp6->OutTimeExcds6);
2030 else if (!strncmp(line, "Icmp6InParmProblems ", 20)) {
2031 sscanf(line + 20, "%lu", &st_net_eicmp6->InParmProblems6);
2033 else if (!strncmp(line, "Icmp6OutParmProblems ", 21)) {
2034 sscanf(line + 21, "%lu", &st_net_eicmp6->OutParmProblems6);
2036 else if (!strncmp(line, "Icmp6InRedirects ", 17)) {
2037 sscanf(line + 17, "%lu", &st_net_eicmp6->InRedirects6);
2039 else if (!strncmp(line, "Icmp6OutRedirects ", 18)) {
2040 sscanf(line + 18, "%lu", &st_net_eicmp6->OutRedirects6);
2042 else if (!strncmp(line, "Icmp6InPktTooBigs ", 18)) {
2043 sscanf(line + 18, "%lu", &st_net_eicmp6->InPktTooBigs6);
2045 else if (!strncmp(line, "Icmp6OutPktTooBigs ", 19)) {
2046 sscanf(line + 19, "%lu", &st_net_eicmp6->OutPktTooBigs6);
2055 ***************************************************************************
2056 * Read UDPv6 network traffic statistics from /proc/net/snmp6.
2059 * @st_net_udp6 Structure where stats will be saved.
2062 * @st_net_udp6 Structure with statistics.
2065 * 1 on success, 0 otherwise.
2066 ***************************************************************************
2068 __nr_t read_net_udp6(struct stats_net_udp6 *st_net_udp6)
2073 if ((fp = fopen(NET_SNMP6, "r")) == NULL)
2076 while (fgets(line, sizeof(line), fp) != NULL) {
2078 if (!strncmp(line, "Udp6InDatagrams ", 16)) {
2079 sscanf(line + 16, "%lu", &st_net_udp6->InDatagrams6);
2081 else if (!strncmp(line, "Udp6OutDatagrams ", 17)) {
2082 sscanf(line + 17, "%lu", &st_net_udp6->OutDatagrams6);
2084 else if (!strncmp(line, "Udp6NoPorts ", 12)) {
2085 sscanf(line + 12, "%lu", &st_net_udp6->NoPorts6);
2087 else if (!strncmp(line, "Udp6InErrors ", 13)) {
2088 sscanf(line + 13, "%lu", &st_net_udp6->InErrors6);
2097 ***************************************************************************
2098 * Read CPU frequency statistics.
2101 * @st_pwr_cpufreq Structure where stats will be saved.
2102 * @nr_alloc Total number of structures allocated. Value is >= 1.
2105 * @st_pwr_cpufreq Structure with statistics.
2108 * Highest CPU number for which statistics have been read.
2109 * 1 means CPU "all", 2 means CPU 0, 3 means CPU 1, etc.
2110 * Or -1 if the buffer was too small and needs to be reallocated.
2111 ***************************************************************************
2113 __nr_t read_cpuinfo(struct stats_pwr_cpufreq *st_pwr_cpufreq, __nr_t nr_alloc)
2116 struct stats_pwr_cpufreq *st_pwr_cpufreq_i;
2119 __nr_t cpu_read = 1; /* For CPU "all" */
2120 unsigned int proc_nr = 0, ifreq, dfreq;
2122 if ((fp = fopen(CPUINFO, "r")) == NULL)
2125 st_pwr_cpufreq->cpufreq = 0;
2127 while (fgets(line, sizeof(line), fp) != NULL) {
2129 if (!strncmp(line, "processor\t", 10)) {
2130 sscanf(strchr(line, ':') + 1, "%u", &proc_nr);
2132 if (proc_nr + 2 > nr_alloc) {
2138 /* Entry in /proc/cpuinfo is different between Intel and Power architectures */
2139 else if (!strncmp(line, "cpu MHz\t", 8) ||
2140 !strncmp(line, "clock\t", 6)) {
2141 sscanf(strchr(line, ':') + 1, "%u.%u", &ifreq, &dfreq);
2143 /* Save current CPU frequency */
2144 st_pwr_cpufreq_i = st_pwr_cpufreq + proc_nr + 1;
2145 st_pwr_cpufreq_i->cpufreq = ifreq * 100 + dfreq / 10;
2147 /* Also save it to compute an average CPU frequency */
2148 st_pwr_cpufreq->cpufreq += st_pwr_cpufreq_i->cpufreq;
2151 if (proc_nr + 2 > cpu_read) {
2152 cpu_read = proc_nr + 2;
2160 /* Compute average CPU frequency for this machine */
2161 st_pwr_cpufreq->cpufreq /= nr;
2167 ***************************************************************************
2168 * Read hugepages statistics from /proc/meminfo.
2171 * @st_huge Structure where stats will be saved.
2174 * @st_huge Structure with statistics.
2177 * 1 on success, 0 otherwise.
2178 ***************************************************************************
2180 __nr_t read_meminfo_huge(struct stats_huge *st_huge)
2184 unsigned long szhkb = 0;
2186 if ((fp = fopen(MEMINFO, "r")) == NULL)
2189 while (fgets(line, sizeof(line), fp) != NULL) {
2191 if (!strncmp(line, "HugePages_Total:", 16)) {
2192 /* Read the total number of huge pages */
2193 sscanf(line + 16, "%llu", &st_huge->tlhkb);
2195 else if (!strncmp(line, "HugePages_Free:", 15)) {
2196 /* Read the number of free huge pages */
2197 sscanf(line + 15, "%llu", &st_huge->frhkb);
2199 else if (!strncmp(line, "HugePages_Rsvd:", 15)) {
2200 /* Read the number of reserved huge pages */
2201 sscanf(line + 15, "%llu", &st_huge->rsvdhkb);
2203 else if (!strncmp(line, "HugePages_Surp:", 15)) {
2204 /* Read the number of surplus huge pages */
2205 sscanf(line + 15, "%llu", &st_huge->surphkb);
2207 else if (!strncmp(line, "Hugepagesize:", 13)) {
2208 /* Read the default size of a huge page in kB */
2209 sscanf(line + 13, "%lu", &szhkb);
2215 /* We want huge pages stats in kB and not expressed in a number of pages */
2216 st_huge->tlhkb *= szhkb;
2217 st_huge->frhkb *= szhkb;
2218 st_huge->rsvdhkb *= szhkb;
2219 st_huge->surphkb *= szhkb;
2225 ***************************************************************************
2226 * Read CPU average frequencies statistics.
2229 * @st_pwr_wghfreq Structure where stats will be saved.
2230 * @cpu_nr CPU number for which time_in_state date will be read.
2231 * @nbr Total number of states (frequencies).
2234 * @st_pwr_wghfreq Structure with statistics.
2237 * 1 on success, 0 otherwise.
2238 ***************************************************************************
2240 int read_time_in_state(struct stats_pwr_wghfreq *st_pwr_wghfreq, int cpu_nr, int nbr)
2243 struct stats_pwr_wghfreq *st_pwr_wghfreq_j;
2244 char filename[MAX_PF_NAME];
2248 unsigned long long time_in_state;
2250 snprintf(filename, MAX_PF_NAME, "%s/cpu%d/%s",
2251 SYSFS_DEVCPU, cpu_nr, SYSFS_TIME_IN_STATE);
2252 if ((fp = fopen(filename, "r")) == NULL)
2255 while (fgets(line, sizeof(line), fp) != NULL) {
2257 sscanf(line, "%lu %llu", &freq, &time_in_state);
2260 /* Save current frequency and time */
2261 st_pwr_wghfreq_j = st_pwr_wghfreq + j;
2262 st_pwr_wghfreq_j->freq = freq;
2263 st_pwr_wghfreq_j->time_in_state = time_in_state;
2273 ***************************************************************************
2274 * Read weighted CPU frequency statistics.
2277 * @st_pwr_wghfreq Structure where stats will be saved.
2278 * @nr_alloc Total number of structures allocated. Value is >= 0.
2279 * @nr2 Number of sub-items allocated per structure.
2282 * @st_pwr_wghfreq Structure with statistics.
2285 * Number of CPU for which statistics have been read.
2286 * 1 means CPU "all", 2 means CPU "all" and 0, etc.
2287 * Or -1 if the buffer was to small and needs to be reallocated.
2288 ***************************************************************************
2290 __nr_t read_cpu_wghfreq(struct stats_pwr_wghfreq *st_pwr_wghfreq, __nr_t nr_alloc,
2293 __nr_t cpu_read = 0;
2295 struct stats_pwr_wghfreq *st_pwr_wghfreq_i, *st_pwr_wghfreq_j, *st_pwr_wghfreq_all_j;
2298 if (cpu_read + 2 > nr_alloc)
2301 /* Read current CPU time-in-state data */
2302 st_pwr_wghfreq_i = st_pwr_wghfreq + (cpu_read + 1) * nr2;
2303 if (!read_time_in_state(st_pwr_wghfreq_i, cpu_read, nr2))
2306 /* Also save data for CPU 'all' */
2307 for (j = 0; j < nr2; j++) {
2308 st_pwr_wghfreq_j = st_pwr_wghfreq_i + j; /* CPU #cpu, state #j */
2309 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2311 /* Assume that possible frequencies are the same for all CPUs */
2312 st_pwr_wghfreq_all_j->freq = st_pwr_wghfreq_j->freq;
2314 st_pwr_wghfreq_all_j->time_in_state += st_pwr_wghfreq_j->time_in_state;
2321 for (j = 0; j < nr2; j++) {
2322 st_pwr_wghfreq_all_j = st_pwr_wghfreq + j; /* CPU #all, state #j */
2323 st_pwr_wghfreq_all_j->time_in_state /= cpu_read;
2326 return cpu_read + 1; /* For CPU "all" */
2333 ***************************************************************************
2334 * Read current USB device data.
2337 * @st_pwr_usb Structure where stats will be saved.
2338 * @usb_device File name for current USB device.
2341 * @st_pwr_usb Structure with statistics.
2342 ***************************************************************************
2344 void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
2349 char filename[MAX_PF_NAME];
2351 /* Get USB device bus number */
2352 sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
2354 /* Read USB device vendor ID */
2355 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2356 SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
2357 if ((fp = fopen(filename, "r")) != NULL) {
2358 rc = fscanf(fp, "%x",
2359 &st_pwr_usb->vendor_id);
2362 st_pwr_usb->vendor_id = 0;
2366 /* Read USB device product ID */
2367 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2368 SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
2369 if ((fp = fopen(filename, "r")) != NULL) {
2370 rc = fscanf(fp, "%x",
2371 &st_pwr_usb->product_id);
2374 st_pwr_usb->product_id = 0;
2378 /* Read USB device max power consumption */
2379 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2380 SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
2381 if ((fp = fopen(filename, "r")) != NULL) {
2382 rc = fscanf(fp, "%u",
2383 &st_pwr_usb->bmaxpower);
2386 st_pwr_usb->bmaxpower = 0;
2390 /* Read USB device manufacturer */
2391 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2392 SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
2393 if ((fp = fopen(filename, "r")) != NULL) {
2394 rs = fgets(st_pwr_usb->manufacturer,
2395 MAX_MANUF_LEN - 1, fp);
2398 (l = strlen(st_pwr_usb->manufacturer)) > 0) {
2399 /* Remove trailing CR */
2400 st_pwr_usb->manufacturer[l - 1] = '\0';
2404 /* Read USB device product */
2405 snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
2406 SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
2407 if ((fp = fopen(filename, "r")) != NULL) {
2408 rs = fgets(st_pwr_usb->product,
2409 MAX_PROD_LEN - 1, fp);
2412 (l = strlen(st_pwr_usb->product)) > 0) {
2413 /* Remove trailing CR */
2414 st_pwr_usb->product[l - 1] = '\0';
2420 ***************************************************************************
2421 * Read USB devices statistics.
2424 * @st_pwr_usb Structure where stats will be saved.
2425 * @nr_alloc Total number of structures allocated. Value is >= 0.
2428 * @st_pwr_usb Structure with statistics.
2431 * Number of USB devices read, or -1 if the buffer was too small and
2432 * needs to be reallocated.
2433 ***************************************************************************
2435 __nr_t read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, __nr_t nr_alloc)
2439 struct stats_pwr_usb *st_pwr_usb_i;
2440 __nr_t usb_read = 0;
2442 /* Open relevant /sys directory */
2443 if ((dir = opendir(SYSFS_USBDEV)) == NULL)
2446 /* Get current file entry */
2447 while ((drd = readdir(dir)) != NULL) {
2449 if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
2451 if (usb_read + 1 > nr_alloc) {
2456 /* Read current USB device data */
2457 st_pwr_usb_i = st_pwr_usb + usb_read++;
2458 read_usb_stats(st_pwr_usb_i, drd->d_name);
2462 /* Close directory */
2468 ***************************************************************************
2469 * Read filesystems statistics.
2472 * @st_filesystem Structure where stats will be saved.
2473 * @nr_alloc Total number of structures allocated. Value is >= 0.
2476 * @st_filesystem Structure with statistics.
2479 * Number of filesystems read, or -1 if the buffer was too small and
2480 * needs to be reallocated.
2481 ***************************************************************************
2483 __nr_t read_filesystem(struct stats_filesystem *st_filesystem, __nr_t nr_alloc)
2486 char line[512], fs_name[MAX_FS_LEN], mountp[256], type[128];
2487 int skip = 0, skip_next = 0;
2488 char *pos = 0, *pos2 = 0;
2490 struct stats_filesystem *st_filesystem_i;
2493 if ((fp = fopen(MTAB, "r")) == NULL)
2496 while (fgets(line, sizeof(line), fp) != NULL) {
2498 * Ignore line if the preceding line did not contain '\n'.
2499 * (Some very long lines may be found for instance when
2500 * overlay2 filesystem with docker is used).
2503 skip_next = (strchr(line, '\n') == NULL);
2507 if (line[0] == '/') {
2508 /* Find field separator position */
2509 pos = strchr(line, ' ');
2514 * Find second field separator position,
2515 * read filesystem type,
2516 * if filesystem type is autofs, skip it
2518 pos2 = strchr(pos + 1, ' ');
2522 sscanf(pos2 + 1, "%127s", type);
2523 if(strcmp(type, "autofs") == 0)
2526 /* Read current filesystem name */
2527 sscanf(line, "%127s", fs_name);
2529 * And now read the corresponding mount point.
2530 * Read fs name and mount point in two distinct operations.
2531 * Indeed, if fs name length is greater than 127 chars,
2532 * previous scanf() will read only the first 127 chars, and
2533 * mount point name will be read using the remaining chars
2534 * from the fs name. This will result in a bogus name
2535 * and following statvfs() function will always fail.
2537 sscanf(pos + 1, "%255s", mountp);
2539 /* Replace octal codes */
2543 * It's important to have read the whole mount point name
2544 * for statvfs() to work properly (see above).
2546 if ((__statvfs(mountp, &buf) < 0) || (!buf.f_blocks))
2549 if (fs_read + 1 > nr_alloc) {
2554 st_filesystem_i = st_filesystem + fs_read++;
2555 st_filesystem_i->f_blocks = (unsigned long long) buf.f_blocks * (unsigned long long) buf.f_frsize;
2556 st_filesystem_i->f_bfree = (unsigned long long) buf.f_bfree * (unsigned long long) buf.f_frsize;
2557 st_filesystem_i->f_bavail = (unsigned long long) buf.f_bavail * (unsigned long long) buf.f_frsize;
2558 st_filesystem_i->f_files = (unsigned long long) buf.f_files;
2559 st_filesystem_i->f_ffree = (unsigned long long) buf.f_ffree;
2560 strncpy(st_filesystem_i->fs_name, fs_name, MAX_FS_LEN);
2561 st_filesystem_i->fs_name[MAX_FS_LEN - 1] = '\0';
2562 strncpy(st_filesystem_i->mountp, mountp, MAX_FS_LEN);
2563 st_filesystem_i->mountp[MAX_FS_LEN - 1] = '\0';
2572 ***************************************************************************
2573 * Read Fibre Channel HBA statistics.
2576 * @st_fc Structure where stats will be saved.
2577 * @nr_alloc Total number of structures allocated. Value is >= 0.
2580 * @st_fc Structure with statistics.
2583 * Number of FC hosts read, or -1 if the buffer was too small and needs to
2585 ***************************************************************************
2587 __nr_t read_fchost(struct stats_fchost *st_fc, __nr_t nr_alloc)
2592 struct stats_fchost *st_fc_i;
2593 __nr_t fch_read = 0;
2594 char fcstat_filename[MAX_PF_NAME];
2596 unsigned long rx_frames, tx_frames, rx_words, tx_words;
2598 /* Each host, if present, will have its own hostX entry within SYSFS_FCHOST */
2599 if ((dir = opendir(SYSFS_FCHOST)) == NULL)
2600 return 0; /* No FC hosts */
2603 * Read each of the counters via sysfs, where they are
2604 * returned as hex values (e.g. 0x72400).
2606 while ((drd = readdir(dir)) != NULL) {
2607 rx_frames = tx_frames = rx_words = tx_words = 0;
2609 if (!strncmp(drd->d_name, "host", 4)) {
2611 if (fch_read + 1 > nr_alloc) {
2616 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_FRAMES,
2617 SYSFS_FCHOST, drd->d_name);
2618 if ((fp = fopen(fcstat_filename, "r"))) {
2619 if (fgets(line, sizeof(line), fp)) {
2620 sscanf(line, "%lx", &rx_frames);
2625 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_FRAMES,
2626 SYSFS_FCHOST, drd->d_name);
2627 if ((fp = fopen(fcstat_filename, "r"))) {
2628 if (fgets(line, sizeof(line), fp)) {
2629 sscanf(line, "%lx", &tx_frames);
2634 snprintf(fcstat_filename, MAX_PF_NAME, FC_RX_WORDS,
2635 SYSFS_FCHOST, drd->d_name);
2636 if ((fp = fopen(fcstat_filename, "r"))) {
2637 if (fgets(line, sizeof(line), fp)) {
2638 sscanf(line, "%lx", &rx_words);
2643 snprintf(fcstat_filename, MAX_PF_NAME, FC_TX_WORDS,
2644 SYSFS_FCHOST, drd->d_name);
2645 if ((fp = fopen(fcstat_filename, "r"))) {
2646 if (fgets(line, sizeof(line), fp)) {
2647 sscanf(line, "%lx", &tx_words);
2652 st_fc_i = st_fc + fch_read++;
2653 st_fc_i->f_rxframes = rx_frames;
2654 st_fc_i->f_txframes = tx_frames;
2655 st_fc_i->f_rxwords = rx_words;
2656 st_fc_i->f_txwords = tx_words;
2657 memcpy(st_fc_i->fchost_name, drd->d_name, MAX_FCH_LEN);
2658 st_fc_i->fchost_name[MAX_FCH_LEN - 1] = '\0';
2667 ***************************************************************************
2668 * Read softnet statistics.
2671 * @st_softnet Structure where stats will be saved.
2672 * @nr_alloc Total number of structures allocated. Value is >= 0.
2673 * @online_cpu_bitmap
2674 * Bitmap listing online CPU.
2677 * @st_softnet Structure with statistics.
2680 * 1 if stats have been sucessfully read, or 0 otherwise.
2681 ***************************************************************************
2683 int read_softnet(struct stats_softnet *st_softnet, __nr_t nr_alloc,
2684 unsigned char online_cpu_bitmap[])
2687 struct stats_softnet *st_softnet_i;
2691 /* Open /proc/net/softnet_stat file */
2692 if ((fp = fopen(NET_SOFTNET, "r")) == NULL)
2695 for (cpu = 1; cpu < nr_alloc; cpu++) {
2696 if (!(online_cpu_bitmap[(cpu - 1) >> 3] & (1 << ((cpu - 1) & 0x07))))
2697 /* CPU is offline */
2700 if (fgets(line, sizeof(line), fp) == NULL)
2703 st_softnet_i = st_softnet + cpu;
2704 sscanf(line, "%x %x %x %*x %*x %*x %*x %*x %*x %x %x",
2705 &st_softnet_i->processed,
2706 &st_softnet_i->dropped,
2707 &st_softnet_i->time_squeeze,
2708 &st_softnet_i->received_rps,
2709 &st_softnet_i->flow_limit);
2716 /*------------------ END: FUNCTIONS USED BY SADC ONLY ---------------------*/
2717 #endif /* SOURCE_SADC */