]> granicus.if.org Git - sysstat/blob - sa_wrap.c
Update non regression tests
[sysstat] / sa_wrap.c
1 /*
2  * sysstat - sa_wrap.c: Functions used in activity.c
3  * (C) 1999-2023 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, a->nr2);
131
132                 if (nr_read < 0) {
133                         /* Buffer needs to be reallocated (for CPU, not interrupts) */
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  * Read batteries statistics.
1064  *
1065  * IN:
1066  * @a   Activity structure.
1067  *
1068  * OUT:
1069  * @a   Activity structure with statistics.
1070  ***************************************************************************
1071  */
1072 __read_funct_t wrap_read_bat(struct activity *a)
1073 {
1074         struct stats_pwr_bat *st_bat
1075         = (struct stats_pwr_bat *) a->_buf0;
1076         __nr_t nr_read = 0;
1077
1078         /* Read batteries statistics */
1079         do {
1080                 nr_read = read_bat(st_bat, a->nr_allocated);
1081
1082                 if (nr_read < 0) {
1083                         /* Buffer needs to be reallocated */
1084                         st_bat = (struct stats_pwr_bat *) reallocate_buffer(a);
1085                 }
1086         }
1087         while (nr_read < 0);
1088
1089         a->_nr0 = nr_read;
1090
1091         return;
1092 }
1093
1094 /*
1095  ***************************************************************************
1096  * Look for online CPU and fill corresponding bitmap.
1097  *
1098  * IN:
1099  * @bitmap_size Size of the CPU bitmap.
1100  *
1101  * OUT:
1102  * @online_cpu_bitmap
1103  *              CPU bitmap which has been filled.
1104  *
1105  * RETURNS:
1106  * Number of CPU for which statistics have to be read.
1107  * 1 means CPU "all", 2 means CPU "all" and CPU 0, etc.
1108  * Or -1 if the buffer was too small and needs to be reallocated.
1109  ***************************************************************************
1110  */
1111 int get_online_cpu_list(unsigned char online_cpu_bitmap[], int bitmap_size)
1112 {
1113         FILE *fp;
1114         char line[8192];
1115         int proc_nr = -2;
1116
1117         if ((fp = fopen(STAT, "r")) == NULL)
1118                 return 0;
1119
1120         while (fgets(line, sizeof(line), fp) != NULL) {
1121
1122                 if (!strncmp(line, "cpu ", 4))
1123                         continue;
1124
1125                 if (!strncmp(line, "cpu", 3)) {
1126                         sscanf(line + 3, "%d", &proc_nr);
1127
1128                         if ((proc_nr + 1 > bitmap_size) || (proc_nr < 0)) {
1129                                 fclose(fp);
1130                                 /* Return -1 or 0 */
1131                                 return ((proc_nr >= 0) * -1);
1132                         }
1133                         online_cpu_bitmap[proc_nr >> 3] |= 1 << (proc_nr & 0x07);
1134                 }
1135         }
1136
1137         fclose(fp);
1138         return proc_nr + 2;
1139 }
1140
1141 /*
1142  ***************************************************************************
1143  * Read softnet statistics.
1144  *
1145  * IN:
1146  * @a   Activity structure.
1147  *
1148  * OUT:
1149  * @a   Activity structure with statistics.
1150  ***************************************************************************
1151  */
1152 __read_funct_t wrap_read_softnet(struct activity *a)
1153 {
1154         struct stats_softnet *st_softnet
1155                 = (struct stats_softnet *) a->_buf0;
1156         __nr_t nr_read = 0;
1157         static unsigned char *online_cpu_bitmap = NULL;
1158         static int bitmap_size = 0;
1159
1160         /* Read softnet stats */
1161         do {
1162                 /* Allocate bitmap for online CPU */
1163                 if (bitmap_size < a->nr_allocated) {
1164                         unsigned char *p = (unsigned char *) realloc(online_cpu_bitmap,
1165                                                                      BITMAP_SIZE(a->nr_allocated));
1166                         if (p == NULL) {
1167                                 nr_read = 0;
1168                                 if (online_cpu_bitmap) {
1169                                         free(online_cpu_bitmap);
1170                                 }
1171                                 break;
1172                         }
1173                         online_cpu_bitmap = p;
1174                         bitmap_size = a->nr_allocated;
1175                 }
1176                 memset(online_cpu_bitmap, 0, BITMAP_SIZE(a->nr_allocated));
1177
1178                 /* Get online CPU list */
1179                 nr_read = get_online_cpu_list(online_cpu_bitmap, bitmap_size);
1180
1181                 if (nr_read > 0) {
1182                         /* Read /proc/net/softnet stats */
1183                         nr_read *= read_softnet(st_softnet, a->nr_allocated, online_cpu_bitmap);
1184                 }
1185
1186                 if (nr_read < 0) {
1187                         /* Buffer needs to be reallocated */
1188                         st_softnet = (struct stats_softnet *) reallocate_buffer(a);
1189                 }
1190         }
1191         while (nr_read < 0);
1192
1193         a->_nr0 = nr_read;
1194
1195         return;
1196 }
1197
1198 /*
1199  ***************************************************************************
1200  * Read pressure-stall CPU statistics.
1201  *
1202  * IN:
1203  * @a   Activity structure.
1204  *
1205  * OUT:
1206  * @a   Activity structure with statistics.
1207  ***************************************************************************
1208  */
1209 __read_funct_t wrap_read_psicpu(struct activity *a)
1210 {
1211         struct stats_psi_cpu *st_psicpu
1212                 = (struct stats_psi_cpu *) a->_buf0;
1213
1214         /* Read pressure-stall CPU stats */
1215         read_psicpu(st_psicpu);
1216
1217         return;
1218 }
1219
1220 /*
1221  ***************************************************************************
1222  * Read pressure-stall I/O statistics.
1223  *
1224  * IN:
1225  * @a   Activity structure.
1226  *
1227  * OUT:
1228  * @a   Activity structure with statistics.
1229  ***************************************************************************
1230  */
1231 __read_funct_t wrap_read_psiio(struct activity *a)
1232 {
1233         struct stats_psi_io *st_psiio
1234                 = (struct stats_psi_io *) a->_buf0;
1235
1236         /* Read pressure-stall I/O stats */
1237         read_psiio(st_psiio);
1238
1239         return;
1240 }
1241
1242 /*
1243  ***************************************************************************
1244  * Read pressure-stall memory statistics.
1245  *
1246  * IN:
1247  * @a   Activity structure.
1248  *
1249  * OUT:
1250  * @a   Activity structure with statistics.
1251  ***************************************************************************
1252  */
1253 __read_funct_t wrap_read_psimem(struct activity *a)
1254 {
1255         struct stats_psi_mem *st_psimem
1256                 = (struct stats_psi_mem *) a->_buf0;
1257
1258         /* Read pressure-stall memory stats */
1259         read_psimem(st_psimem);
1260
1261         return;
1262 }
1263
1264 /*
1265  ***************************************************************************
1266  * Count number of interrupts that are in /proc/interrupts file, including
1267  * total number of interrupts.
1268  * Truncate the number of different individual interrupts to NR_IRQS.
1269  *
1270  * IN:
1271  * @a   Activity structure.
1272  *
1273  * RETURNS:
1274  * Number of interrupts, including total number of interrupts.
1275  * Value in [0, NR_IRQS + 1].
1276  ***************************************************************************
1277  */
1278 __nr_t wrap_get_irq_nr(struct activity *a)
1279 {
1280         __nr_t n;
1281
1282         /*
1283          * Get number of different interrupts.
1284          * Number of CPU (including CPU "all") has already been calculated and saved in a->nr_ini.
1285          */
1286         n = get_irqcpu_nr(INTERRUPTS, a->bitmap->b_size, a->nr_ini - 1);
1287         if (n > 0) {
1288                 n++;    /* Add 1 for total number of interrupts. A value of bitmap->b_size + 1 is OK. */
1289         }
1290
1291         return n;
1292 }
1293
1294 /*
1295  ***************************************************************************
1296  * Find number of serial lines that support tx/rx accounting
1297  * in /proc/tty/driver/serial file.
1298  *
1299  * IN:
1300  * @a   Activity structure.
1301  *
1302  * RETURNS:
1303  * Number of serial lines supporting tx/rx accouting.
1304  * Number cannot exceed MAX_NR_SERIAL_LINES.
1305  ***************************************************************************
1306  */
1307 __nr_t wrap_get_serial_nr(struct activity *a)
1308 {
1309         __nr_t n = 0;
1310
1311         if ((n = get_serial_nr()) > 0) {
1312                 if (n > MAX_NR_SERIAL_LINES)
1313                         return MAX_NR_SERIAL_LINES;
1314                 else
1315                         return n;
1316         }
1317
1318         return 0;
1319 }
1320
1321 /*
1322  ***************************************************************************
1323  * Find number of interfaces (network devices) that are in /proc/net/dev
1324  * file.
1325  *
1326  * IN:
1327  * @a   Activity structure.
1328  *
1329  * RETURNS:
1330  * Number of network interfaces. Number cannot exceed MAX_NR_IFACES.
1331  ***************************************************************************
1332  */
1333 __nr_t wrap_get_iface_nr(struct activity *a)
1334 {
1335         __nr_t n = 0;
1336
1337         if ((n = get_iface_nr()) > 0) {
1338                 if (n > MAX_NR_IFACES)
1339                         return MAX_NR_IFACES;
1340                 else
1341                         return n;
1342         }
1343
1344         return 0;
1345 }
1346
1347 /*
1348  ***************************************************************************
1349  * Compute number of CPU structures to allocate.
1350  *
1351  * IN:
1352  * @a   Activity structure.
1353  *
1354  * RETURNS:
1355  * Number of structures (value in [1, NR_CPUS + 1]).
1356  * 1 means that there is only one proc and non SMP kernel (CPU "all").
1357  * 2 means one proc and SMP kernel (CPU "all" and CPU 0).
1358  * Etc.
1359  ***************************************************************************
1360  */
1361 __nr_t wrap_get_cpu_nr(struct activity *a)
1362 {
1363         return (get_cpu_nr(a->bitmap->b_size, FALSE) + 1);
1364 }
1365
1366 /*
1367  ***************************************************************************
1368  * Get number of devices in /proc/diskstats.
1369  * Always done, since disk stats must be read at least for sar -b
1370  * if not for sar -d.
1371  *
1372  * IN:
1373  * @a   Activity structure.
1374  *
1375  * RETURNS:
1376  * Number of devices. Number cannot exceed MAX_NR_DISKS.
1377  ***************************************************************************
1378  */
1379 __nr_t wrap_get_disk_nr(struct activity *a)
1380 {
1381         __nr_t n = 0;
1382         unsigned int f = COLLECT_PARTITIONS(a->opt_flags);
1383
1384         if ((n = get_disk_nr(f)) > 0) {
1385                 if (n > MAX_NR_DISKS)
1386                         return MAX_NR_DISKS;
1387                 else
1388                         return n;
1389         }
1390
1391         return 0;
1392 }
1393
1394 /*
1395  ***************************************************************************
1396  * Get number of fan sensors.
1397  *
1398  * IN:
1399  * @a  Activity structure.
1400  *
1401  * RETURNS:
1402  * Number of fan sensors. Number cannot exceed MAX_NR_FANS.
1403  ***************************************************************************
1404  */
1405 __nr_t wrap_get_fan_nr(struct activity *a)
1406 {
1407         __nr_t n;
1408
1409         if ((n = get_fan_nr()) > MAX_NR_FANS)
1410                 return MAX_NR_FANS;
1411         else
1412                 return n;
1413 }
1414
1415 /*
1416  ***************************************************************************
1417  * Get number of temp sensors.
1418  *
1419  * IN:
1420  * @a  Activity structure.
1421  *
1422  * RETURNS:
1423  * Number of temp sensors. Number cannot exceed MAX_NR_TEMP_SENSORS.
1424  ***************************************************************************
1425  */
1426 __nr_t wrap_get_temp_nr(struct activity *a)
1427 {
1428         __nr_t n;
1429
1430         if ((n = get_temp_nr()) > MAX_NR_TEMP_SENSORS)
1431                 return MAX_NR_TEMP_SENSORS;
1432         else
1433                 return n;
1434 }
1435
1436 /*
1437  ***************************************************************************
1438  * Get number of voltage input sensors.
1439  *
1440  * IN:
1441  * @a  Activity structure.
1442  *
1443  * RETURNS:
1444  * Number of voltage input sensors. Number cannot exceed MAX_NR_IN_SENSORS.
1445  ***************************************************************************
1446  */
1447 __nr_t wrap_get_in_nr(struct activity *a)
1448 {
1449         __nr_t n;
1450
1451         if ((n = get_in_nr()) > MAX_NR_IN_SENSORS)
1452                 return MAX_NR_IN_SENSORS;
1453         else
1454                 return n;
1455 }
1456
1457 /*
1458  ***************************************************************************
1459  * Count number of possible frequencies for CPU#0.
1460  *
1461  * IN:
1462  * @a   Activity structure.
1463  *
1464  * RETURNS:
1465  * Number of CPU frequencies.
1466  ***************************************************************************
1467  */
1468 __nr_t wrap_get_freq_nr(struct activity *a)
1469 {
1470         __nr_t n = 0;
1471
1472         if ((n = get_freq_nr()) > 0)
1473                 return n;
1474
1475         return 0;
1476 }
1477
1478 /*
1479  ***************************************************************************
1480  * Count number of USB devices plugged into the system.
1481  *
1482  * IN:
1483  * @a   Activity structure.
1484  *
1485  * RETURNS:
1486  * Number of USB devices. Number cannot exceed MAX_NR_USB.
1487  ***************************************************************************
1488  */
1489 __nr_t wrap_get_usb_nr(struct activity *a)
1490 {
1491         __nr_t n = 0;
1492
1493         if ((n = get_usb_nr()) > 0) {
1494                 if (n > MAX_NR_USB)
1495                         return MAX_NR_USB;
1496                 else
1497                         return n;
1498         }
1499
1500         return 0;
1501 }
1502
1503 /*
1504  ***************************************************************************
1505  * Get number of mounted filesystems from /etc/mtab. Don't take into account
1506  * pseudo-filesystems.
1507  *
1508  * IN:
1509  * @a   Activity structure.
1510  *
1511  * RETURNS:
1512  * Number of filesystems. Number cannot exceed MAX_NR_FS.
1513  ***************************************************************************
1514  */
1515 __nr_t wrap_get_filesystem_nr(struct activity *a)
1516 {
1517         __nr_t n = 0;
1518
1519         if ((n = get_filesystem_nr()) > 0) {
1520                 if (n > MAX_NR_FS)
1521                         return MAX_NR_FS;
1522                 else
1523                         return n;
1524         }
1525
1526         return 0;
1527 }
1528
1529 /*
1530  ***************************************************************************
1531  * Get number of FC hosts.
1532  *
1533  * IN:
1534  * @a   Activity structure.
1535  *
1536  * RETURNS:
1537  * Number of FC hosts. Number cannot exceed MAX_NR_FCHOSTS.
1538  ***************************************************************************
1539  */
1540 __nr_t wrap_get_fchost_nr(struct activity *a)
1541 {
1542         __nr_t n = 0;
1543
1544         if ((n = get_fchost_nr()) > 0) {
1545                 if (n > MAX_NR_FCHOSTS)
1546                         return MAX_NR_FCHOSTS;
1547                 else
1548                         return n;
1549         }
1550
1551         return 0;
1552 }
1553
1554 /*
1555  ***************************************************************************
1556  * Check that /proc/pressure directory exists.
1557  *
1558  * IN:
1559  * @a  Activity structure.
1560  *
1561  * RETURNS:
1562  * TRUE if directory exists.
1563  ***************************************************************************
1564  */
1565 __nr_t wrap_detect_psi(struct activity *a)
1566 {
1567         return (check_dir(PRESSURE));
1568 }
1569
1570 /*
1571  * **************************************************************************
1572  * Get number of batteries.
1573  *
1574  * IN:
1575  * @a  Activity structure.
1576  *
1577  * RETURNS:
1578  * Number of batteries installed. Number cannot exceed MAX_NR_BAT.
1579  ***************************************************************************
1580  */
1581 __nr_t wrap_get_bat_nr(struct activity *a)
1582 {
1583         __nr_t n = 0;
1584
1585         if ((n = get_bat_nr()) > 0) {
1586                 if (n > MAX_NR_BATS)
1587                         return MAX_NR_BATS;
1588                 else
1589                         return n;
1590         }
1591
1592         return 0;
1593 }