]> granicus.if.org Git - sysstat/blob - sa_wrap.c
Starting sysstat-12.5.4
[sysstat] / sa_wrap.c
1 /*
2  * sysstat - sa_wrap.c: Functions used in activity.c
3  * (C) 1999-2021 by Sebastien GODARD (sysstat <at> orange.fr)
4  *
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.                                              *
10  *                                                                         *
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 *
14  * for more details.                                                       *
15  *                                                                         *
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  ***************************************************************************
20  */
21
22 #include <dirent.h>
23 #include <string.h>
24
25 #include "sa.h"
26 #include "count.h"
27
28 extern unsigned int flags;
29 extern struct record_header record_hdr;
30
31 /*
32  ***************************************************************************
33  * Reallocate buffer where statistics will be saved. The new size is the
34  * double of the original one.
35  * This is typically called when we find that current buffer is too small
36  * to save all the data.
37  *
38  * IN:
39  * @a   Activity structure.
40  *
41  * RETURNS:
42  * New pointer address on buffer.
43  ***************************************************************************
44  */
45 void *reallocate_buffer(struct activity *a)
46 {
47         SREALLOC(a->_buf0, void,
48                  (size_t) a->msize * (size_t) a->nr_allocated * 2);     /* a->nr2 value is 1 */
49         memset(a->_buf0, 0, (size_t) a->msize * (size_t) a->nr_allocated * 2);
50
51         a->nr_allocated *= 2;   /* NB: nr_allocated > 0 */
52
53         return a->_buf0;
54 }
55
56 /*
57  ***************************************************************************
58  * Read CPU statistics.
59  *
60  * IN:
61  * @a   Activity structure.
62  *
63  * OUT:
64  * @a   Activity structure with statistics.
65  ***************************************************************************
66  */
67 __read_funct_t wrap_read_stat_cpu(struct activity *a)
68 {
69         struct stats_cpu *st_cpu
70                 = (struct stats_cpu *) a->_buf0;
71         __nr_t nr_read = 0;
72
73         /* Read CPU statistics */
74         do {
75                 nr_read = read_stat_cpu(st_cpu, a->nr_allocated);
76
77                 if (nr_read < 0) {
78                         /* Buffer needs to be reallocated */
79                         st_cpu = (struct stats_cpu *) reallocate_buffer(a);
80                 }
81         }
82         while (nr_read < 0);
83
84         a->_nr0 = nr_read;
85
86         return;
87 }
88
89 /*
90  ***************************************************************************
91  * Read process (task) creation and context switch statistics.
92  *
93  * IN:
94  * @a   Activity structure.
95  *
96  * OUT:
97  * @a   Activity structure with statistics.
98  ***************************************************************************
99  */
100 __read_funct_t wrap_read_stat_pcsw(struct activity *a)
101 {
102         struct stats_pcsw *st_pcsw
103                 = (struct stats_pcsw *) a->_buf0;
104
105         /* Read process and context switch stats */
106         read_stat_pcsw(st_pcsw);
107
108         return;
109 }
110
111 /*
112  ***************************************************************************
113  * Read interrupt statistics.
114  *
115  * IN:
116  * @a   Activity structure.
117  *
118  * OUT:
119  * @a   Activity structure with statistics.
120  ***************************************************************************
121  */
122 __read_funct_t wrap_read_stat_irq(struct activity *a)
123 {
124         struct stats_irq *st_irq
125                 = (struct stats_irq *) a->_buf0;
126         __nr_t nr_read;
127
128         /* Read interrupts stats */
129         do {
130                 nr_read = read_stat_irq(st_irq, a->nr_allocated);
131
132                 if (nr_read < 0) {
133                         /* Buffer needs to be reallocated */
134                         st_irq = (struct stats_irq *) reallocate_buffer(a);
135                 }
136         }
137         while (nr_read < 0);
138
139         a->_nr0 = nr_read;
140
141         return;
142 }
143
144 /*
145  ***************************************************************************
146  * Read queue and load statistics.
147  *
148  * IN:
149  * @a   Activity structure.
150  *
151  * OUT:
152  * @a   Activity structure with statistics.
153  ***************************************************************************
154  */
155 __read_funct_t wrap_read_loadavg(struct activity *a)
156 {
157         struct stats_queue *st_queue
158                 = (struct stats_queue *) a->_buf0;
159
160         /* Read queue and load stats */
161         read_loadavg(st_queue);
162
163         return;
164 }
165
166 /*
167  ***************************************************************************
168  * Read memory statistics.
169  *
170  * IN:
171  * @a   Activity structure.
172  *
173  * OUT:
174  * @a   Activity structure with statistics.
175  ***************************************************************************
176  */
177 __read_funct_t wrap_read_meminfo(struct activity *a)
178 {
179         struct stats_memory *st_memory
180                 = (struct stats_memory *) a->_buf0;
181
182         /* Read memory stats */
183         read_meminfo(st_memory);
184
185         return;
186 }
187
188 /*
189  ***************************************************************************
190  * Read swapping statistics.
191  *
192  * IN:
193  * @a   Activity structure.
194  *
195  * OUT:
196  * @a   Activity structure with statistics.
197  ***************************************************************************
198  */
199 __read_funct_t wrap_read_swap(struct activity *a)
200 {
201         struct stats_swap *st_swap
202                 = (struct stats_swap *) a->_buf0;
203
204         /* Read stats from /proc/vmstat */
205         read_vmstat_swap(st_swap);
206
207         return;
208 }
209
210 /*
211  ***************************************************************************
212  * Read paging statistics.
213  *
214  * IN:
215  * @a   Activity structure.
216  *
217  * OUT:
218  * @a   Activity structure with statistics.
219  ***************************************************************************
220  */
221 __read_funct_t wrap_read_paging(struct activity *a)
222 {
223         struct stats_paging *st_paging
224                 = (struct stats_paging *) a->_buf0;
225
226         /* Read stats from /proc/vmstat */
227         read_vmstat_paging(st_paging);
228
229         return;
230 }
231
232 /*
233  ***************************************************************************
234  * Read I/O and transfer rates statistics.
235  *
236  * IN:
237  * @a   Activity structure.
238  *
239  * OUT:
240  * @a   Activity structure with statistics.
241  ***************************************************************************
242  */
243 __read_funct_t wrap_read_io(struct activity *a)
244 {
245         struct stats_io *st_io
246                 = (struct stats_io *) a->_buf0;
247
248         /* Read stats from /proc/diskstats */
249         read_diskstats_io(st_io);
250
251         return;
252 }
253
254 /*
255  ***************************************************************************
256  * Read block devices statistics.
257  *
258  * IN:
259  * @a   Activity structure.
260  *
261  * OUT:
262  * @a   Activity structure with statistics.
263  ***************************************************************************
264  */
265 __read_funct_t wrap_read_disk(struct activity *a)
266 {
267         struct stats_disk *st_disk
268                 = (struct stats_disk *) a->_buf0;
269         __nr_t nr_read = 0;
270
271         /* Read stats from /proc/diskstats */
272         do {
273                 nr_read = read_diskstats_disk(st_disk, a->nr_allocated,
274                                               COLLECT_PARTITIONS(a->opt_flags));
275
276                 if (nr_read < 0) {
277                         /* Buffer needs to be reallocated */
278                         st_disk = (struct stats_disk *) reallocate_buffer(a);
279                 }
280         }
281         while (nr_read < 0);
282
283         a->_nr0 = nr_read;
284
285         return;
286 }
287
288 /*
289  ***************************************************************************
290  * Read serial lines statistics.
291  *
292  * IN:
293  * @a   Activity structure.
294  *
295  * OUT:
296  * @a   Activity structure with statistics.
297  ***************************************************************************
298  */
299 __read_funct_t wrap_read_tty_driver_serial(struct activity *a)
300 {
301         struct stats_serial *st_serial
302                 = (struct stats_serial *) a->_buf0;
303         __nr_t nr_read = 0;
304
305         /* Read serial lines stats */
306         do {
307                 nr_read = read_tty_driver_serial(st_serial, a->nr_allocated);
308
309                 if (nr_read < 0) {
310                         /* Buffer needs to be reallocated */
311                         st_serial = (struct stats_serial *) reallocate_buffer(a);
312                 }
313         }
314         while (nr_read < 0);
315
316         a->_nr0 = nr_read;
317
318         return;
319 }
320
321 /*
322  ***************************************************************************
323  * Read kernel tables statistics.
324  *
325  * IN:
326  * @a   Activity structure.
327  *
328  * OUT:
329  * @a   Activity structure with statistics.
330  ***************************************************************************
331  */
332 __read_funct_t wrap_read_kernel_tables(struct activity *a)
333 {
334         struct stats_ktables *st_ktables
335                 = (struct stats_ktables *) a->_buf0;
336
337         /* Read kernel tables stats */
338         read_kernel_tables(st_ktables);
339
340         return;
341 }
342
343 /*
344  ***************************************************************************
345  * Read network interfaces statistics.
346  *
347  * IN:
348  * @a   Activity structure.
349  *
350  * OUT:
351  * @a   Activity structure with statistics.
352  ***************************************************************************
353  */
354 __read_funct_t wrap_read_net_dev(struct activity *a)
355 {
356         struct stats_net_dev *st_net_dev
357                 = (struct stats_net_dev *) a->_buf0;
358         __nr_t nr_read = 0;
359
360         /* Read network interfaces stats */
361         do {
362                 nr_read = read_net_dev(st_net_dev, a->nr_allocated);
363
364                 if (nr_read < 0) {
365                         /* Buffer needs to be reallocated */
366                         st_net_dev = (struct stats_net_dev *) reallocate_buffer(a);
367                 }
368         }
369         while (nr_read < 0);
370
371         a->_nr0 = nr_read;
372
373         if (!nr_read)
374                 /* No data read. Exit */
375                 return;
376
377         /* Read duplex and speed info for each interface */
378         read_if_info(st_net_dev, nr_read);
379
380         return;
381 }
382
383 /*
384  ***************************************************************************
385  * Read network interfaces errors statistics.
386  *
387  * IN:
388  * @a   Activity structure.
389  *
390  * OUT:
391  * @a   Activity structure with statistics.
392  ***************************************************************************
393  */
394 __read_funct_t wrap_read_net_edev(struct activity *a)
395 {
396         struct stats_net_edev *st_net_edev
397                 = (struct stats_net_edev *) a->_buf0;
398         __nr_t nr_read = 0;
399
400         /* Read network interfaces errors stats */
401         do {
402                 nr_read = read_net_edev(st_net_edev, a->nr_allocated);
403
404                 if (nr_read < 0) {
405                         /* Buffer needs to be reallocated */
406                         st_net_edev = (struct stats_net_edev *) reallocate_buffer(a);
407                 }
408         }
409         while (nr_read < 0);
410
411         a->_nr0 = nr_read;
412
413         return;
414 }
415
416 /*
417  ***************************************************************************
418  * Read NFS client statistics.
419  *
420  * IN:
421  * @a   Activity structure.
422  *
423  * OUT:
424  * @a   Activity structure with statistics.
425  ***************************************************************************
426  */
427 __read_funct_t wrap_read_net_nfs(struct activity *a)
428 {
429         struct stats_net_nfs *st_net_nfs
430                 = (struct stats_net_nfs *) a->_buf0;
431
432         /* Read NFS client stats */
433         read_net_nfs(st_net_nfs);
434
435         return;
436 }
437
438 /*
439  ***************************************************************************
440  * Read NFS server statistics.
441  *
442  * IN:
443  * @a   Activity structure.
444  *
445  * OUT:
446  * @a   Activity structure with statistics.
447  ***************************************************************************
448  */
449 __read_funct_t wrap_read_net_nfsd(struct activity *a)
450 {
451         struct stats_net_nfsd *st_net_nfsd
452                 = (struct stats_net_nfsd *) a->_buf0;
453
454         /* Read NFS server stats */
455         read_net_nfsd(st_net_nfsd);
456
457         return;
458 }
459
460 /*
461  ***************************************************************************
462  * Read network sockets statistics.
463  *
464  * IN:
465  * @a   Activity structure.
466  *
467  * OUT:
468  * @a   Activity structure with statistics.
469  ***************************************************************************
470  */
471 __read_funct_t wrap_read_net_sock(struct activity *a)
472 {
473         struct stats_net_sock *st_net_sock
474                 = (struct stats_net_sock *) a->_buf0;
475
476         /* Read network sockets stats */
477         read_net_sock(st_net_sock);
478
479         return;
480 }
481
482 /*
483  ***************************************************************************
484  * Read IP statistics.
485  *
486  * IN:
487  * @a   Activity structure.
488  *
489  * OUT:
490  * @a   Activity structure with statistics.
491  ***************************************************************************
492  */
493 __read_funct_t wrap_read_net_ip(struct activity *a)
494 {
495         struct stats_net_ip *st_net_ip
496                 = (struct stats_net_ip *) a->_buf0;
497
498         /* Read IP stats */
499         read_net_ip(st_net_ip);
500
501         return;
502 }
503
504 /*
505  ***************************************************************************
506  * Read IP error statistics.
507  *
508  * IN:
509  * @a   Activity structure.
510  *
511  * OUT:
512  * @a   Activity structure with statistics.
513  ***************************************************************************
514  */
515 __read_funct_t wrap_read_net_eip(struct activity *a)
516 {
517         struct stats_net_eip *st_net_eip
518                 = (struct stats_net_eip *) a->_buf0;
519
520         /* Read IP error stats */
521         read_net_eip(st_net_eip);
522
523         return;
524 }
525
526 /*
527  ***************************************************************************
528  * Read ICMP statistics.
529  *
530  * IN:
531  * @a   Activity structure.
532  *
533  * OUT:
534  * @a   Activity structure with statistics.
535  ***************************************************************************
536  */
537 __read_funct_t wrap_read_net_icmp(struct activity *a)
538 {
539         struct stats_net_icmp *st_net_icmp
540                 = (struct stats_net_icmp *) a->_buf0;
541
542         /* Read ICMP stats */
543         read_net_icmp(st_net_icmp);
544
545         return;
546 }
547
548 /*
549  ***************************************************************************
550  * Read ICMP error statistics.
551  *
552  * IN:
553  * @a   Activity structure.
554  *
555  * OUT:
556  * @a   Activity structure with statistics.
557  ***************************************************************************
558  */
559 __read_funct_t wrap_read_net_eicmp(struct activity *a)
560 {
561         struct stats_net_eicmp *st_net_eicmp
562                 = (struct stats_net_eicmp *) a->_buf0;
563
564         /* Read ICMP error stats */
565         read_net_eicmp(st_net_eicmp);
566
567         return;
568 }
569
570 /*
571  ***************************************************************************
572  * Read TCP statistics.
573  *
574  * IN:
575  * @a   Activity structure.
576  *
577  * OUT:
578  * @a   Activity structure with statistics.
579  ***************************************************************************
580  */
581 __read_funct_t wrap_read_net_tcp(struct activity *a)
582 {
583         struct stats_net_tcp *st_net_tcp
584                 = (struct stats_net_tcp *) a->_buf0;
585
586         /* Read TCP stats */
587         read_net_tcp(st_net_tcp);
588
589         return;
590 }
591
592 /*
593  ***************************************************************************
594  * Read TCP error statistics.
595  *
596  * IN:
597  * @a   Activity structure.
598  *
599  * OUT:
600  * @a   Activity structure with statistics.
601  ***************************************************************************
602  */
603 __read_funct_t wrap_read_net_etcp(struct activity *a)
604 {
605         struct stats_net_etcp *st_net_etcp
606                 = (struct stats_net_etcp *) a->_buf0;
607
608         /* Read TCP error stats */
609         read_net_etcp(st_net_etcp);
610
611         return;
612 }
613
614 /*
615  ***************************************************************************
616  * Read UDP statistics.
617  *
618  * IN:
619  * @a   Activity structure.
620  *
621  * OUT:
622  * @a   Activity structure with statistics.
623  ***************************************************************************
624  */
625 __read_funct_t wrap_read_net_udp(struct activity *a)
626 {
627         struct stats_net_udp *st_net_udp
628                 = (struct stats_net_udp *) a->_buf0;
629
630         /* Read UDP stats */
631         read_net_udp(st_net_udp);
632
633         return;
634 }
635
636 /*
637  ***************************************************************************
638  * Read IPv6 network sockets statistics.
639  *
640  * IN:
641  * @a   Activity structure.
642  *
643  * OUT:
644  * @a   Activity structure with statistics.
645  ***************************************************************************
646  */
647 __read_funct_t wrap_read_net_sock6(struct activity *a)
648 {
649         struct stats_net_sock6 *st_net_sock6
650                 = (struct stats_net_sock6 *) a->_buf0;
651
652         /* Read IPv6 network sockets stats */
653         read_net_sock6(st_net_sock6);
654
655         return;
656 }
657
658 /*
659  ***************************************************************************
660  * Read IPv6 statistics.
661  *
662  * IN:
663  * @a   Activity structure.
664  *
665  * OUT:
666  * @a   Activity structure with statistics.
667  ***************************************************************************
668  */
669 __read_funct_t wrap_read_net_ip6(struct activity *a)
670 {
671         struct stats_net_ip6 *st_net_ip6
672                 = (struct stats_net_ip6 *) a->_buf0;
673
674         /* Read IPv6 stats */
675         read_net_ip6(st_net_ip6);
676
677         return;
678 }
679
680 /*
681  ***************************************************************************
682  * Read IPv6 error statistics.
683  *
684  * IN:
685  * @a   Activity structure.
686  *
687  * OUT:
688  * @a   Activity structure with statistics.
689  ***************************************************************************
690  */
691 __read_funct_t wrap_read_net_eip6(struct activity *a)
692 {
693         struct stats_net_eip6 *st_net_eip6
694                 = (struct stats_net_eip6 *) a->_buf0;
695
696         /* Read IPv6 error stats */
697         read_net_eip6(st_net_eip6);
698
699         return;
700 }
701
702 /*
703  ***************************************************************************
704  * Read ICMPv6 statistics.
705  *
706  * IN:
707  * @a   Activity structure.
708  *
709  * OUT:
710  * @a   Activity structure with statistics.
711  ***************************************************************************
712  */
713 __read_funct_t wrap_read_net_icmp6(struct activity *a)
714 {
715         struct stats_net_icmp6 *st_net_icmp6
716                 = (struct stats_net_icmp6 *) a->_buf0;
717
718         /* Read ICMPv6 stats */
719         read_net_icmp6(st_net_icmp6);
720
721         return;
722 }
723
724 /*
725  ***************************************************************************
726  * Read ICMPv6 error statistics.
727  *
728  * IN:
729  * @a   Activity structure.
730  *
731  * OUT:
732  * @a   Activity structure with statistics.
733  ***************************************************************************
734  */
735 __read_funct_t wrap_read_net_eicmp6(struct activity *a)
736 {
737         struct stats_net_eicmp6 *st_net_eicmp6
738                 = (struct stats_net_eicmp6 *) a->_buf0;
739
740         /* Read ICMPv6 error stats */
741         read_net_eicmp6(st_net_eicmp6);
742
743         return;
744 }
745
746 /*
747  ***************************************************************************
748  * Read UDPv6 statistics.
749  *
750  * IN:
751  * @a   Activity structure.
752  *
753  * OUT:
754  * @a   Activity structure with statistics.
755  ***************************************************************************
756  */
757 __read_funct_t wrap_read_net_udp6(struct activity *a)
758 {
759         struct stats_net_udp6 *st_net_udp6
760                 = (struct stats_net_udp6 *) a->_buf0;
761
762         /* Read UDPv6 stats */
763         read_net_udp6(st_net_udp6);
764
765         return;
766 }
767
768 /*
769  ***************************************************************************
770  * Read CPU frequency statistics.
771  *
772  * IN:
773  * @a   Activity structure.
774  *
775  * OUT:
776  * @a   Activity structure with statistics.
777  ***************************************************************************
778  */
779 __read_funct_t wrap_read_cpuinfo(struct activity *a)
780 {
781         struct stats_pwr_cpufreq *st_pwr_cpufreq
782                 = (struct stats_pwr_cpufreq *) a->_buf0;
783         __nr_t nr_read = 0;
784
785         /* Read CPU frequency stats */
786         do {
787                 nr_read = read_cpuinfo(st_pwr_cpufreq, a->nr_allocated);
788
789                 if (nr_read < 0) {
790                         /* Buffer needs to be reallocated */
791                         st_pwr_cpufreq = (struct stats_pwr_cpufreq *) reallocate_buffer(a);
792                 }
793         }
794         while (nr_read < 0);
795
796         a->_nr0 = nr_read;
797
798         return;
799 }
800
801 /*
802  ***************************************************************************
803  * Read fan statistics.
804  *
805  * IN:
806  * @a  Activity structure.
807  *
808  * OUT:
809  * @a  Activity structure with statistics.
810  ***************************************************************************
811  */
812 __read_funct_t wrap_read_fan(struct activity *a)
813 {
814         struct stats_pwr_fan *st_pwr_fan
815                 = (struct stats_pwr_fan *) a->_buf0;
816         __nr_t nr_read = 0;
817
818         /* Read fan stats */
819         do {
820                 nr_read = read_fan(st_pwr_fan, a->nr_allocated);
821
822                 if (nr_read < 0) {
823                         /* Buffer needs to be reallocated */
824                         st_pwr_fan = (struct stats_pwr_fan *) reallocate_buffer(a);
825                 }
826         }
827         while (nr_read < 0);
828
829         a->_nr0 = nr_read;
830
831         return;
832 }
833
834 /*
835  ***************************************************************************
836  * Read temperature statistics.
837  *
838  * IN:
839  * @a  Activity structure.
840  *
841  * OUT:
842  * @a  Activity structure with statistics.
843  ***************************************************************************
844  */
845 __read_funct_t wrap_read_temp(struct activity *a)
846 {
847         struct stats_pwr_temp *st_pwr_temp
848                 = (struct stats_pwr_temp *) a->_buf0;
849         __nr_t nr_read = 0;
850
851         /* Read temperature stats */
852         do {
853                 nr_read = read_temp(st_pwr_temp, a->nr_allocated);
854
855                 if (nr_read < 0) {
856                         /* Buffer needs to be reallocated */
857                         st_pwr_temp = (struct stats_pwr_temp *) reallocate_buffer(a);
858                 }
859         }
860         while (nr_read < 0);
861
862         a->_nr0 = nr_read;
863
864         return;
865 }
866
867 /*
868  ***************************************************************************
869  * Read voltage input statistics.
870  *
871  * IN:
872  * @a  Activity structure.
873  *
874  * OUT:
875  * @a  Activity structure with statistics.
876  ***************************************************************************
877  */
878 __read_funct_t wrap_read_in(struct activity *a)
879 {
880         struct stats_pwr_in *st_pwr_in
881                 = (struct stats_pwr_in *) a->_buf0;
882         __nr_t nr_read = 0;
883
884         /* Read voltage input stats */
885         do {
886                 nr_read = read_in(st_pwr_in, a->nr_allocated);
887
888                 if (nr_read < 0) {
889                         /* Buffer needs to be reallocated */
890                         st_pwr_in = (struct stats_pwr_in *) reallocate_buffer(a);
891                 }
892         }
893         while (nr_read < 0);
894
895         a->_nr0 = nr_read;
896
897         return;
898 }
899
900 /*
901  ***************************************************************************
902  * Read hugepages statistics.
903  *
904  * IN:
905  * @a   Activity structure.
906  *
907  * OUT:
908  * @a   Activity structure with statistics.
909  ***************************************************************************
910  */
911 __read_funct_t wrap_read_meminfo_huge(struct activity *a)
912 {
913         struct stats_huge *st_huge
914                 = (struct stats_huge *) a->_buf0;
915
916         /* Read hugepages stats */
917         read_meminfo_huge(st_huge);
918
919         return;
920 }
921
922 /*
923  ***************************************************************************
924  * Read weighted CPU frequency statistics.
925  *
926  * IN:
927  * @a   Activity structure.
928  *
929  * OUT:
930  * @a   Activity structure with statistics.
931  ***************************************************************************
932  */
933 __read_funct_t wrap_read_cpu_wghfreq(struct activity *a)
934 {
935         struct stats_pwr_wghfreq *st_pwr_wghfreq
936                 = (struct stats_pwr_wghfreq *) a->_buf0;
937         __nr_t  nr_read = 0;
938
939         /* Read weighted CPU frequency statistics */
940         do {
941                 nr_read = read_cpu_wghfreq(st_pwr_wghfreq, a->nr_allocated, a->nr2);
942
943                 if (nr_read < 0) {
944                         /* Buffer needs to be reallocated */
945                         SREALLOC(a->_buf0, void,
946                                  (size_t) a->msize * (size_t) a->nr2 * (size_t) a->nr_allocated * 2);
947                         memset(a->_buf0, 0,
948                                (size_t) a->msize * (size_t) a->nr2 * (size_t) a->nr_allocated * 2);
949
950                         /* NB: nr_allocated > 0 */
951                         a->nr_allocated *= 2;
952                         st_pwr_wghfreq = (struct stats_pwr_wghfreq *) a->_buf0;
953                 }
954         }
955         while(nr_read < 0);
956
957         a->_nr0 = nr_read;
958
959         return;
960 }
961
962 /*
963  ***************************************************************************
964  * Read USB devices statistics.
965  *
966  * IN:
967  * @a  Activity structure.
968  *
969  * OUT:
970  * @a  Activity structure with statistics.
971  ***************************************************************************
972  */
973 __read_funct_t wrap_read_bus_usb_dev(struct activity *a)
974 {
975         struct stats_pwr_usb *st_pwr_usb
976                 = (struct stats_pwr_usb *) a->_buf0;
977         __nr_t nr_read = 0;
978
979         /* Read USB devices stats */
980         do {
981                 nr_read = read_bus_usb_dev(st_pwr_usb, a->nr_allocated);
982
983                 if (nr_read < 0) {
984                         /* Buffer needs to be reallocated */
985                         st_pwr_usb = (struct stats_pwr_usb *) reallocate_buffer(a);
986                 }
987         }
988         while (nr_read < 0);
989
990         a->_nr0 = nr_read;
991
992         return;
993 }
994
995 /*
996  ***************************************************************************
997  * Read filesystem statistics.
998  *
999  * IN:
1000  * @a   Activity structure.
1001  *
1002  * OUT:
1003  * @a   Activity structure with statistics.
1004  ***************************************************************************
1005  */
1006 __read_funct_t wrap_read_filesystem(struct activity *a)
1007 {
1008         struct stats_filesystem *st_filesystem
1009                 = (struct stats_filesystem *) a->_buf0;
1010         __nr_t nr_read = 0;
1011
1012         /* Read filesystems from /etc/mtab */
1013         do {
1014                 nr_read = read_filesystem(st_filesystem, a->nr_allocated);
1015
1016                 if (nr_read < 0) {
1017                         /* Buffer needs to be reallocated */
1018                         st_filesystem = (struct stats_filesystem *) reallocate_buffer(a);
1019                 }
1020         }
1021         while (nr_read < 0);
1022
1023         a->_nr0 = nr_read;
1024
1025         return;
1026 }
1027
1028 /*
1029  ***************************************************************************
1030  * Read Fibre Channel HBA statistics.
1031  *
1032  * IN:
1033  * @a   Activity structure.
1034  *
1035  * OUT:
1036  * @a   Activity structure with statistics.
1037  ***************************************************************************
1038  */
1039 __read_funct_t wrap_read_fchost(struct activity *a)
1040 {
1041         struct stats_fchost *st_fc
1042                 = (struct stats_fchost *) a->_buf0;
1043         __nr_t nr_read = 0;
1044
1045         /* Read FC hosts statistics */
1046         do {
1047                 nr_read = read_fchost(st_fc, a->nr_allocated);
1048
1049                 if (nr_read < 0) {
1050                         /* Buffer needs to be reallocated */
1051                         st_fc = (struct stats_fchost *) reallocate_buffer(a);
1052                 }
1053         }
1054         while (nr_read < 0);
1055
1056         a->_nr0 = nr_read;
1057
1058         return;
1059 }
1060
1061 /*
1062  ***************************************************************************
1063  * Look for online CPU and fill corresponding bitmap.
1064  *
1065  * IN:
1066  * @bitmap_size Size of the CPU bitmap.
1067  *
1068  * OUT:
1069  * @online_cpu_bitmap
1070  *              CPU bitmap which has been filled.
1071  *
1072  * RETURNS:
1073  * Number of CPU for which statistics have to be read.
1074  * 1 means CPU "all", 2 means CPU "all" and CPU 0, etc.
1075  * Or -1 if the buffer was too small and needs to be reallocated.
1076  ***************************************************************************
1077  */
1078 int get_online_cpu_list(unsigned char online_cpu_bitmap[], int bitmap_size)
1079 {
1080         FILE *fp;
1081         char line[8192];
1082         int proc_nr = -2;
1083
1084         if ((fp = fopen(STAT, "r")) == NULL)
1085                 return 0;
1086
1087         while (fgets(line, sizeof(line), fp) != NULL) {
1088
1089                 if (!strncmp(line, "cpu ", 4))
1090                         continue;
1091
1092                 if (!strncmp(line, "cpu", 3)) {
1093                         sscanf(line + 3, "%d", &proc_nr);
1094
1095                         if ((proc_nr + 1 > bitmap_size) || (proc_nr < 0)) {
1096                                 fclose(fp);
1097                                 /* Return -1 or 0 */
1098                                 return ((proc_nr >= 0) * -1);
1099                         }
1100                         online_cpu_bitmap[proc_nr >> 3] |= 1 << (proc_nr & 0x07);
1101                 }
1102         }
1103
1104         fclose(fp);
1105         return proc_nr + 2;
1106 }
1107
1108 /*
1109  ***************************************************************************
1110  * Read softnet statistics.
1111  *
1112  * IN:
1113  * @a   Activity structure.
1114  *
1115  * OUT:
1116  * @a   Activity structure with statistics.
1117  ***************************************************************************
1118  */
1119 __read_funct_t wrap_read_softnet(struct activity *a)
1120 {
1121         struct stats_softnet *st_softnet
1122                 = (struct stats_softnet *) a->_buf0;
1123         __nr_t nr_read = 0;
1124         static unsigned char *online_cpu_bitmap = NULL;
1125         static int bitmap_size = 0;
1126
1127         /* Read softnet stats */
1128         do {
1129                 /* Allocate bitmap for online CPU */
1130                 if (bitmap_size < a->nr_allocated) {
1131                         if ((online_cpu_bitmap = (unsigned char *) realloc(online_cpu_bitmap,
1132                                                                            BITMAP_SIZE(a->nr_allocated))) == NULL) {
1133                                 nr_read = 0;
1134                                 break;
1135                         }
1136                         bitmap_size = a->nr_allocated;
1137                 }
1138                 memset(online_cpu_bitmap, 0, BITMAP_SIZE(a->nr_allocated));
1139
1140                 /* Get online CPU list */
1141                 nr_read = get_online_cpu_list(online_cpu_bitmap, bitmap_size);
1142
1143                 if (nr_read > 0) {
1144                         /* Read /proc/net/softnet stats */
1145                         nr_read *= read_softnet(st_softnet, a->nr_allocated, online_cpu_bitmap);
1146                 }
1147
1148                 if (nr_read < 0) {
1149                         /* Buffer needs to be reallocated */
1150                         st_softnet = (struct stats_softnet *) reallocate_buffer(a);
1151                 }
1152         }
1153         while (nr_read < 0);
1154
1155         a->_nr0 = nr_read;
1156
1157         return;
1158 }
1159
1160 /*
1161  ***************************************************************************
1162  * Read pressure-stall CPU statistics.
1163  *
1164  * IN:
1165  * @a   Activity structure.
1166  *
1167  * OUT:
1168  * @a   Activity structure with statistics.
1169  ***************************************************************************
1170  */
1171 __read_funct_t wrap_read_psicpu(struct activity *a)
1172 {
1173         struct stats_psi_cpu *st_psicpu
1174                 = (struct stats_psi_cpu *) a->_buf0;
1175
1176         /* Read pressure-stall CPU stats */
1177         read_psicpu(st_psicpu);
1178
1179         return;
1180 }
1181
1182 /*
1183  ***************************************************************************
1184  * Read pressure-stall I/O statistics.
1185  *
1186  * IN:
1187  * @a   Activity structure.
1188  *
1189  * OUT:
1190  * @a   Activity structure with statistics.
1191  ***************************************************************************
1192  */
1193 __read_funct_t wrap_read_psiio(struct activity *a)
1194 {
1195         struct stats_psi_io *st_psiio
1196                 = (struct stats_psi_io *) a->_buf0;
1197
1198         /* Read pressure-stall I/O stats */
1199         read_psiio(st_psiio);
1200
1201         return;
1202 }
1203
1204 /*
1205  ***************************************************************************
1206  * Read pressure-stall memory statistics.
1207  *
1208  * IN:
1209  * @a   Activity structure.
1210  *
1211  * OUT:
1212  * @a   Activity structure with statistics.
1213  ***************************************************************************
1214  */
1215 __read_funct_t wrap_read_psimem(struct activity *a)
1216 {
1217         struct stats_psi_mem *st_psimem
1218                 = (struct stats_psi_mem *) a->_buf0;
1219
1220         /* Read pressure-stall memory stats */
1221         read_psimem(st_psimem);
1222
1223         return;
1224 }
1225
1226 /*
1227  ***************************************************************************
1228  * Count number of interrupts that are in /proc/stat file.
1229  * Truncate the number of different individual interrupts to NR_IRQS.
1230  *
1231  * IN:
1232  * @a   Activity structure.
1233  *
1234  * RETURNS:
1235  * Number of interrupts, including total number of interrupts.
1236  * Value in [0, NR_IRQS + 1].
1237  ***************************************************************************
1238  */
1239 __nr_t wrap_get_irq_nr(struct activity *a)
1240 {
1241         __nr_t n;
1242
1243         if ((n = get_irq_nr()) > (a->bitmap->b_size + 1)) {
1244                 n = a->bitmap->b_size + 1;
1245         }
1246
1247         return n;
1248 }
1249
1250 /*
1251  ***************************************************************************
1252  * Find number of serial lines that support tx/rx accounting
1253  * in /proc/tty/driver/serial file.
1254  *
1255  * IN:
1256  * @a   Activity structure.
1257  *
1258  * RETURNS:
1259  * Number of serial lines supporting tx/rx accouting.
1260  * Number cannot exceed MAX_NR_SERIAL_LINES.
1261  ***************************************************************************
1262  */
1263 __nr_t wrap_get_serial_nr(struct activity *a)
1264 {
1265         __nr_t n = 0;
1266
1267         if ((n = get_serial_nr()) > 0) {
1268                 if (n > MAX_NR_SERIAL_LINES)
1269                         return MAX_NR_SERIAL_LINES;
1270                 else
1271                         return n;
1272         }
1273
1274         return 0;
1275 }
1276
1277 /*
1278  ***************************************************************************
1279  * Find number of interfaces (network devices) that are in /proc/net/dev
1280  * file.
1281  *
1282  * IN:
1283  * @a   Activity structure.
1284  *
1285  * RETURNS:
1286  * Number of network interfaces. Number cannot exceed MAX_NR_IFACES.
1287  ***************************************************************************
1288  */
1289 __nr_t wrap_get_iface_nr(struct activity *a)
1290 {
1291         __nr_t n = 0;
1292
1293         if ((n = get_iface_nr()) > 0) {
1294                 if (n > MAX_NR_IFACES)
1295                         return MAX_NR_IFACES;
1296                 else
1297                         return n;
1298         }
1299
1300         return 0;
1301 }
1302
1303 /*
1304  ***************************************************************************
1305  * Compute number of CPU structures to allocate.
1306  *
1307  * IN:
1308  * @a   Activity structure.
1309  *
1310  * RETURNS:
1311  * Number of structures (value in [1, NR_CPUS + 1]).
1312  * 1 means that there is only one proc and non SMP kernel (CPU "all").
1313  * 2 means one proc and SMP kernel (CPU "all" and CPU 0).
1314  * Etc.
1315  ***************************************************************************
1316  */
1317 __nr_t wrap_get_cpu_nr(struct activity *a)
1318 {
1319         return (get_cpu_nr(a->bitmap->b_size, FALSE) + 1);
1320 }
1321
1322 /*
1323  ***************************************************************************
1324  * Get number of devices in /proc/diskstats.
1325  * Always done, since disk stats must be read at least for sar -b
1326  * if not for sar -d.
1327  *
1328  * IN:
1329  * @a   Activity structure.
1330  *
1331  * RETURNS:
1332  * Number of devices. Number cannot exceed MAX_NR_DISKS.
1333  ***************************************************************************
1334  */
1335 __nr_t wrap_get_disk_nr(struct activity *a)
1336 {
1337         __nr_t n = 0;
1338         unsigned int f = COLLECT_PARTITIONS(a->opt_flags);
1339
1340         if ((n = get_disk_nr(f)) > 0) {
1341                 if (n > MAX_NR_DISKS)
1342                         return MAX_NR_DISKS;
1343                 else
1344                         return n;
1345         }
1346
1347         return 0;
1348 }
1349
1350 /*
1351  ***************************************************************************
1352  * Get number of fan sensors.
1353  *
1354  * IN:
1355  * @a  Activity structure.
1356  *
1357  * RETURNS:
1358  * Number of fan sensors. Number cannot exceed MAX_NR_FANS.
1359  ***************************************************************************
1360  */
1361 __nr_t wrap_get_fan_nr(struct activity *a)
1362 {
1363         __nr_t n;
1364
1365         if ((n = get_fan_nr()) > MAX_NR_FANS)
1366                 return MAX_NR_FANS;
1367         else
1368                 return n;
1369 }
1370
1371 /*
1372  ***************************************************************************
1373  * Get number of temp sensors.
1374  *
1375  * IN:
1376  * @a  Activity structure.
1377  *
1378  * RETURNS:
1379  * Number of temp sensors. Number cannot exceed MAX_NR_TEMP_SENSORS.
1380  ***************************************************************************
1381  */
1382 __nr_t wrap_get_temp_nr(struct activity *a)
1383 {
1384         __nr_t n;
1385
1386         if ((n = get_temp_nr()) > MAX_NR_TEMP_SENSORS)
1387                 return MAX_NR_TEMP_SENSORS;
1388         else
1389                 return n;
1390 }
1391
1392 /*
1393  ***************************************************************************
1394  * Get number of voltage input sensors.
1395  *
1396  * IN:
1397  * @a  Activity structure.
1398  *
1399  * RETURNS:
1400  * Number of voltage input sensors. Number cannot exceed MAX_NR_IN_SENSORS.
1401  ***************************************************************************
1402  */
1403 __nr_t wrap_get_in_nr(struct activity *a)
1404 {
1405         __nr_t n;
1406
1407         if ((n = get_in_nr()) > MAX_NR_IN_SENSORS)
1408                 return MAX_NR_IN_SENSORS;
1409         else
1410                 return n;
1411 }
1412
1413 /*
1414  ***************************************************************************
1415  * Count number of possible frequencies for CPU#0.
1416  *
1417  * IN:
1418  * @a   Activity structure.
1419  *
1420  * RETURNS:
1421  * Number of CPU frequencies.
1422  ***************************************************************************
1423  */
1424 __nr_t wrap_get_freq_nr(struct activity *a)
1425 {
1426         __nr_t n = 0;
1427
1428         if ((n = get_freq_nr()) > 0)
1429                 return n;
1430
1431         return 0;
1432 }
1433
1434 /*
1435  ***************************************************************************
1436  * Count number of USB devices plugged into the system.
1437  *
1438  * IN:
1439  * @a   Activity structure.
1440  *
1441  * RETURNS:
1442  * Number of USB devices. Number cannot exceed MAX_NR_USB.
1443  ***************************************************************************
1444  */
1445 __nr_t wrap_get_usb_nr(struct activity *a)
1446 {
1447         __nr_t n = 0;
1448
1449         if ((n = get_usb_nr()) > 0) {
1450                 if (n > MAX_NR_USB)
1451                         return MAX_NR_USB;
1452                 else
1453                         return n;
1454         }
1455
1456         return 0;
1457 }
1458
1459 /*
1460  ***************************************************************************
1461  * Get number of mounted filesystems from /etc/mtab. Don't take into account
1462  * pseudo-filesystems.
1463  *
1464  * IN:
1465  * @a   Activity structure.
1466  *
1467  * RETURNS:
1468  * Number of filesystems. Number cannot exceed MAX_NR_FS.
1469  ***************************************************************************
1470  */
1471 __nr_t wrap_get_filesystem_nr(struct activity *a)
1472 {
1473         __nr_t n = 0;
1474
1475         if ((n = get_filesystem_nr()) > 0) {
1476                 if (n > MAX_NR_FS)
1477                         return MAX_NR_FS;
1478                 else
1479                         return n;
1480         }
1481
1482         return 0;
1483 }
1484
1485 /*
1486  ***************************************************************************
1487  * Get number of FC hosts.
1488  *
1489  * IN:
1490  * @a   Activity structure.
1491  *
1492  * RETURNS:
1493  * Number of FC hosts. Number cannot exceed MAX_NR_FCHOSTS.
1494  ***************************************************************************
1495  */
1496 __nr_t wrap_get_fchost_nr(struct activity *a)
1497 {
1498         __nr_t n = 0;
1499
1500         if ((n = get_fchost_nr()) > 0) {
1501                 if (n > MAX_NR_FCHOSTS)
1502                         return MAX_NR_FCHOSTS;
1503                 else
1504                         return n;
1505         }
1506
1507         return 0;
1508 }
1509
1510 /*
1511  ***************************************************************************
1512  * Check that /proc/pressure directory exists.
1513  *
1514  * IN:
1515  * @a  Activity structure.
1516  *
1517  * RETURNS:
1518  * TRUE if directory exists.
1519  ***************************************************************************
1520  */
1521 __nr_t wrap_detect_psi(struct activity *a)
1522 {
1523         return (check_dir(PRESSURE));
1524 }