]> granicus.if.org Git - sysstat/blob - rd_sensors.c
A_IRQ: sadf: Update PCP interface for interrupts statistics
[sysstat] / rd_sensors.c
1 /*
2  * rd_sensors.c: Read sensors statistics
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 <stdio.h>
23 #include <string.h>
24
25 #include "common.h"
26 #include "rd_stats.h"
27 #include "rd_sensors.h"
28
29 #ifdef USE_NLS
30 #include <locale.h>
31 #include <libintl.h>
32 #define _(string) gettext(string)
33 #else
34 #define _(string) (string)
35 #endif
36
37 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
38 #include "sensors/sensors.h"
39 #endif
40
41 /*
42  ***************************************************************************
43  * Read fan statistics.
44  *
45  * IN:
46  * @st_pwr_fan  Structure where stats will be saved.
47  * @nr_alloc    Total number of structures allocated. Value is >= 1.
48  *
49  * OUT:
50  * @st_pwr_fan Structure with statistics.
51  *
52  * RETURNS:
53  * Number of fans read, or -1 if the buffer was too small and needs to be
54  * reallocated.
55  ***************************************************************************
56  */
57 __nr_t read_fan(struct stats_pwr_fan *st_pwr_fan, __nr_t nr_alloc)
58 {
59 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
60         __nr_t fan_read = 0;
61         const sensors_chip_name *chip;
62         const sensors_feature *feature;
63         const sensors_subfeature *sub;
64         struct stats_pwr_fan *st_pwr_fan_i;
65         int chip_nr = 0;
66         int i, j;
67
68         memset(st_pwr_fan, 0, STATS_PWR_FAN_SIZE);
69
70         while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
71                 i = 0;
72                 while ((feature = sensors_get_features(chip, &i))) {
73                         if (feature->type == SENSORS_FEATURE_FAN) {
74                                 j = 0;
75                                 if (fan_read + 1 > nr_alloc)
76                                         return -1;
77                                 st_pwr_fan_i = st_pwr_fan + fan_read++;
78                                 sensors_snprintf_chip_name(st_pwr_fan_i->device, MAX_SENSORS_DEV_LEN, chip);
79
80                                 while ((sub = sensors_get_all_subfeatures(chip, feature, &j))) {
81                                         if ((sub->type == SENSORS_SUBFEATURE_FAN_INPUT) &&
82                                             (sub->flags & SENSORS_MODE_R)) {
83                                                 if (sensors_get_value(chip, sub->number, &st_pwr_fan_i->rpm)) {
84                                                         st_pwr_fan_i->rpm = 0;
85                                                 }
86                                         }
87                                         else if ((sub->type == SENSORS_SUBFEATURE_FAN_MIN)) {
88                                                 if (sensors_get_value(chip, sub->number, &st_pwr_fan_i->rpm_min)) {
89                                                         st_pwr_fan_i->rpm_min = 0;
90                                                 }
91                                         }
92                                 }
93                         }
94                 }
95         }
96
97         return fan_read;
98 #else
99         return 0;
100 #endif /* HAVE_SENSORS */
101 }
102
103 /*
104  ***************************************************************************
105  * Read device temperature statistics.
106  *
107  * IN:
108  * @st_pwr_temp Structure where stats will be saved.
109  * @nr_alloc    Total number of structures allocated. Value is >= 1.
110  *
111  * OUT:
112  * @st_pwr_temp Structure with statistics.
113  *
114  * RETURNS:
115  * Number of devices read, or -1 if the buffer was too small and needs to be
116  * reallocated.
117  ***************************************************************************
118  */
119 __nr_t read_temp(struct stats_pwr_temp *st_pwr_temp, __nr_t nr_alloc)
120 {
121 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
122         __nr_t temp_read = 0;
123         const sensors_chip_name *chip;
124         const sensors_feature *feature;
125         const sensors_subfeature *sub;
126         struct stats_pwr_temp *st_pwr_temp_i;
127         int chip_nr = 0;
128         int i, j;
129
130         memset(st_pwr_temp, 0, STATS_PWR_TEMP_SIZE);
131
132         while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
133                 i = 0;
134                 while ((feature = sensors_get_features(chip, &i))) {
135                         if (feature->type == SENSORS_FEATURE_TEMP) {
136                                 j = 0;
137                                 if (temp_read + 1 > nr_alloc)
138                                         return -1;
139                                 st_pwr_temp_i = st_pwr_temp + temp_read++;
140                                 sensors_snprintf_chip_name(st_pwr_temp_i->device, MAX_SENSORS_DEV_LEN, chip);
141
142                                 while ((sub = sensors_get_all_subfeatures(chip, feature, &j))) {
143                                         if ((sub->type == SENSORS_SUBFEATURE_TEMP_INPUT) &&
144                                                 (sub->flags & SENSORS_MODE_R)) {
145                                                 if (sensors_get_value(chip, sub->number, &st_pwr_temp_i->temp)) {
146                                                         st_pwr_temp_i->temp = 0;
147                                                 }
148                                         }
149                                         else if ((sub->type == SENSORS_SUBFEATURE_TEMP_MIN)) {
150                                                 if (sensors_get_value(chip, sub->number, &st_pwr_temp_i->temp_min)) {
151                                                         st_pwr_temp_i->temp_min = 0;
152                                                 }
153                                         }
154                                         else if ((sub->type == SENSORS_SUBFEATURE_TEMP_MAX)) {
155                                                 if (sensors_get_value(chip, sub->number, &st_pwr_temp_i->temp_max)) {
156                                                         st_pwr_temp_i->temp_max = 0;
157                                                 }
158                                         }
159                                 }
160                         }
161                 }
162         }
163
164         return temp_read;
165 #else
166         return 0;
167 #endif /* HAVE_SENSORS */
168 }
169
170 /*
171  ***************************************************************************
172  * Read voltage inputs statistics.
173  *
174  * IN:
175  * @st_pwr_in   Structure where stats will be saved.
176  * @nr_alloc    Total number of structures allocated. Value is >= 1.
177  *
178  * OUT:
179  * @st_pwr_in   Structure with statistics.
180  *
181  * RETURNS:
182  * Number of devices read, or -1 if the buffer was too small and needs to be
183  * reallocated.
184  ***************************************************************************
185  */
186 __nr_t read_in(struct stats_pwr_in *st_pwr_in, __nr_t nr_alloc)
187 {
188 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
189         __nr_t in_read = 0;
190         const sensors_chip_name *chip;
191         const sensors_feature *feature;
192         const sensors_subfeature *sub;
193         struct stats_pwr_in *st_pwr_in_i;
194         int chip_nr = 0;
195         int i, j;
196
197         memset(st_pwr_in, 0, STATS_PWR_IN_SIZE);
198
199         while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
200                 i = 0;
201                 while ((feature = sensors_get_features(chip, &i))) {
202                         if (feature->type == SENSORS_FEATURE_IN) {
203                                 j = 0;
204                                 if (in_read + 1 > nr_alloc)
205                                         return -1;
206                                 st_pwr_in_i = st_pwr_in + in_read++;
207                                 sensors_snprintf_chip_name(st_pwr_in_i->device, MAX_SENSORS_DEV_LEN, chip);
208
209                                 while ((sub = sensors_get_all_subfeatures(chip, feature, &j))) {
210                                         if ((sub->type == SENSORS_SUBFEATURE_IN_INPUT) &&
211                                                 (sub->flags & SENSORS_MODE_R)) {
212                                                 if (sensors_get_value(chip, sub->number, &st_pwr_in_i->in)) {
213                                                         st_pwr_in_i->in = 0;
214                                                 }
215                                         }
216                                         else if ((sub->type == SENSORS_SUBFEATURE_IN_MIN)) {
217                                                 if (sensors_get_value(chip, sub->number, &st_pwr_in_i->in_min)) {
218                                                         st_pwr_in_i->in_min = 0;
219                                                 }
220                                         }
221                                         else if ((sub->type == SENSORS_SUBFEATURE_IN_MAX)) {
222                                                 if (sensors_get_value(chip, sub->number, &st_pwr_in_i->in_max)) {
223                                                         st_pwr_in_i->in_max = 0;
224                                                 }
225                                         }
226                                 }
227                         }
228                 }
229         }
230
231         return in_read;
232 #else
233         return 0;
234 #endif /* HAVE_SENSORS */
235 }
236
237 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
238 /*
239  ***************************************************************************
240  * Count the number of sensors of given type on the machine.
241  *
242  * IN:
243  * @type        Type of sensors.
244  *
245  * RETURNS:
246  * Number of sensors.
247  ***************************************************************************
248  */
249 __nr_t get_sensors_nr(sensors_feature_type type) {
250         __nr_t count = 0;
251         const sensors_chip_name *chip;
252         const sensors_feature *feature;
253         int chip_nr = 0;
254         int i;
255
256         while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
257                 i = 0;
258                 while ((feature = sensors_get_features(chip, &i))) {
259                         if (feature->type == type) {
260                                 count++;
261                         }
262                 }
263         }
264
265         return count;
266 }
267 #endif /* HAVE_SENSORS */
268
269 /*
270  ***************************************************************************
271  * Count the number of fans on the machine.
272  *
273  * RETURNS:
274  * Number of fans.
275  ***************************************************************************
276  */
277 __nr_t get_fan_nr(void)
278 {
279 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
280         return get_sensors_nr(SENSORS_FEATURE_FAN);
281 #else
282         return 0;
283 #endif /* HAVE_SENSORS */
284 }
285
286 /*
287  ***************************************************************************
288  * Count the number of temperature sensors on the machine.
289  *
290  * RETURNS:
291  * Number of temperature sensors.
292  ***************************************************************************
293  */
294 __nr_t get_temp_nr(void)
295 {
296 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
297         return get_sensors_nr(SENSORS_FEATURE_TEMP);
298 #else
299         return 0;
300 #endif /* HAVE_SENSORS */
301 }
302
303 /*
304  ***************************************************************************
305  * Count the number of voltage inputs on the machine.
306  *
307  * RETURNS:
308  * Number of voltage inputs.
309  ***************************************************************************
310  */
311 __nr_t get_in_nr(void)
312 {
313 #if (defined(HAVE_SENSORS) && !defined(ARCH32)) || (defined(ARCH32) && defined(HAVE_SENSORS32))
314         return get_sensors_nr(SENSORS_FEATURE_IN);
315 #else
316         return 0;
317 #endif /* HAVE_SENSORS */
318 }