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