1 /*
2  * Copyright (C) 2003-2015 FreeIPMI Core Team
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #if HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #if STDC_HEADERS
26 #include <string.h>
27 #endif /* STDC_HEADERS */
28 #if TIME_WITH_SYS_TIME
29 #include <sys/time.h>
30 #include <time.h>
31 #else /* !TIME_WITH_SYS_TIME */
32 #if HAVE_SYS_TIME_H
33 #include <sys/time.h>
34 #else /* !HAVE_SYS_TIME_H */
35 #include <time.h>
36 #endif /* !HAVE_SYS_TIME_H */
37 #endif /* !TIME_WITH_SYS_TIME */
38 #include <assert.h>
39 
40 #include <freeipmi/freeipmi.h>
41 
42 #include "ipmi-sensors.h"
43 #include "ipmi-sensors-argp.h"
44 #include "ipmi-sensors-simple-output.h"
45 #include "ipmi-sensors-detailed-output.h"
46 #include "ipmi-sensors-oem-intel-node-manager.h"
47 #include "ipmi-sensors-output-common.h"
48 
49 #include "freeipmi-portability.h"
50 #include "pstdout.h"
51 #include "tool-common.h"
52 #include "tool-cmdline-common.h"
53 #include "tool-hostrange-common.h"
54 #include "tool-oem-common.h"
55 #include "tool-sdr-cache-common.h"
56 #include "tool-sensor-common.h"
57 #include "tool-util-common.h"
58 
59 #define IPMI_SENSORS_MESSAGE_LENGTH 1024
60 
61 #define IPMI_SENSORS_TIME_BUFLEN    512
62 
63 static int
_sdr_repository_info(ipmi_sensors_state_data_t * state_data)64 _sdr_repository_info (ipmi_sensors_state_data_t *state_data)
65 {
66   fiid_obj_t obj_cmd_rs = NULL;
67   uint8_t major, minor;
68   uint16_t record_count, free_space;
69   uint64_t val;
70   char timestr[IPMI_SENSORS_TIME_BUFLEN + 1];
71   char *str;
72   int rv = -1;
73   uint8_t allocation_supported = 0;
74 
75   assert (state_data);
76 
77   if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_sdr_repository_info_rs)))
78     {
79       pstdout_fprintf (state_data->pstate,
80                        stderr,
81                        "fiid_obj_create: %s\n",
82                        strerror (errno));
83       goto cleanup;
84     }
85 
86   if (ipmi_cmd_get_sdr_repository_info (state_data->ipmi_ctx, obj_cmd_rs) < 0)
87     {
88       pstdout_fprintf (state_data->pstate,
89                        stderr,
90                        "ipmi_cmd_get_sdr_repository_info: %s\n",
91                        ipmi_ctx_errormsg (state_data->ipmi_ctx));
92       goto cleanup;
93     }
94 
95   if (FIID_OBJ_GET (obj_cmd_rs, "sdr_version_major", &val) < 0)
96     {
97       pstdout_fprintf (state_data->pstate,
98                        stderr,
99                        "fiid_obj_get: 'sdr_version_major': %s\n",
100                        fiid_obj_errormsg (obj_cmd_rs));
101       goto cleanup;
102     }
103   major = val;
104 
105   if (FIID_OBJ_GET (obj_cmd_rs, "sdr_version_minor", &val) < 0)
106     {
107       pstdout_fprintf (state_data->pstate,
108                        stderr,
109                        "fiid_obj_get: 'sdr_version_minor': %s\n",
110                        fiid_obj_errormsg (obj_cmd_rs));
111       goto cleanup;
112     }
113   minor = val;
114 
115   pstdout_printf (state_data->pstate,
116                   "SDR version                                       : %u.%u\n",
117                   major,
118                   minor);
119 
120   if (FIID_OBJ_GET (obj_cmd_rs, "record_count", &val) < 0)
121     {
122       pstdout_fprintf (state_data->pstate,
123                        stderr,
124                        "fiid_obj_get: 'record_count': %s\n",
125                        fiid_obj_errormsg (obj_cmd_rs));
126       goto cleanup;
127     }
128   record_count = val;
129 
130   pstdout_printf (state_data->pstate,
131                   "SDR record count                                  : %u\n",
132                   record_count);
133 
134   if (FIID_OBJ_GET (obj_cmd_rs, "free_space", &val) < 0)
135     {
136       pstdout_fprintf (state_data->pstate,
137                        stderr,
138                        "fiid_obj_get: 'free_space': %s\n",
139                        fiid_obj_errormsg (obj_cmd_rs));
140       goto cleanup;
141     }
142   free_space = val;
143 
144   pstdout_printf (state_data->pstate,
145                   "Free space remaining                              : %u bytes\n",
146                   free_space);
147 
148   if (FIID_OBJ_GET (obj_cmd_rs, "most_recent_addition_timestamp", &val) < 0)
149     {
150       pstdout_fprintf (state_data->pstate,
151                        stderr,
152                        "fiid_obj_get: 'most_recent_addition_timestamp': %s\n",
153                        fiid_obj_errormsg (obj_cmd_rs));
154       goto cleanup;
155     }
156 
157   memset (timestr, '\0', IPMI_SENSORS_TIME_BUFLEN + 1);
158 
159   if (ipmi_timestamp_string ((uint32_t)val,
160                              state_data->prog_data->args->common_args.utc_offset,
161                              get_timestamp_flags (&(state_data->prog_data->args->common_args),
162                                                   IPMI_TIMESTAMP_FLAG_DEFAULT),
163                              "%m/%d/%Y - %H:%M:%S",
164                              timestr,
165                              IPMI_SENSORS_TIME_BUFLEN) < 0)
166     {
167       pstdout_fprintf (state_data->pstate,
168                        stderr,
169                        "ipmi_timestamp_string: %s\n",
170                        strerror (errno));
171       goto cleanup;
172     }
173 
174   pstdout_printf (state_data->pstate,
175                   "Most recent addition timestamp                    : %s\n",
176                   timestr);
177 
178   if (FIID_OBJ_GET (obj_cmd_rs, "most_recent_erase_timestamp", &val) < 0)
179     {
180       pstdout_fprintf (state_data->pstate,
181                        stderr,
182                        "fiid_obj_get: 'most_recent_erase_timestamp': %s\n",
183                        fiid_obj_errormsg (obj_cmd_rs));
184       goto cleanup;
185     }
186 
187   memset (timestr, '\0', IPMI_SENSORS_TIME_BUFLEN + 1);
188 
189   if (ipmi_timestamp_string ((uint32_t)val,
190                              state_data->prog_data->args->common_args.utc_offset,
191                              get_timestamp_flags (&(state_data->prog_data->args->common_args),
192                                                   IPMI_TIMESTAMP_FLAG_DEFAULT),
193                              "%m/%d/%Y - %H:%M:%S",
194                              timestr,
195                              IPMI_SENSORS_TIME_BUFLEN) < 0)
196     {
197       pstdout_fprintf (state_data->pstate,
198                        stderr,
199                        "ipmi_timestamp_string: %s\n",
200                        strerror (errno));
201       goto cleanup;
202     }
203 
204   pstdout_printf (state_data->pstate,
205                   "Most recent erase timestamp                       : %s\n",
206                   timestr);
207 
208   if (FIID_OBJ_GET (obj_cmd_rs, "get_sdr_repository_allocation_info_command_supported", &val) < 0)
209     {
210       pstdout_fprintf (state_data->pstate,
211                        stderr,
212                        "fiid_obj_get: 'get_sdr_repository_allocation_info_command_supported': %s\n",
213                        fiid_obj_errormsg (obj_cmd_rs));
214       goto cleanup;
215     }
216 
217   pstdout_printf (state_data->pstate,
218                   "Get SDR Repository Allocation Information Command : %s\n",
219                   (val ? "supported" : "unsupported"));
220 
221   allocation_supported = val;
222 
223   if (FIID_OBJ_GET (obj_cmd_rs, "reserve_sdr_repository_command_supported", &val) < 0)
224     {
225       pstdout_fprintf (state_data->pstate,
226                        stderr,
227                        "fiid_obj_get: 'reserve_sdr_repository_command_supported': %s\n",
228                        fiid_obj_errormsg (obj_cmd_rs));
229       goto cleanup;
230     }
231 
232   pstdout_printf (state_data->pstate,
233                   "Reserve SDR Repository Command                    : %s\n",
234                   (val ? "supported" : "unsupported"));
235 
236   if (FIID_OBJ_GET (obj_cmd_rs, "partial_add_sdr_command_supported", &val) < 0)
237     {
238       pstdout_fprintf (state_data->pstate,
239                        stderr,
240                        "fiid_obj_get: 'partial_add_sdr_command_supported': %s\n",
241                        fiid_obj_errormsg (obj_cmd_rs));
242       goto cleanup;
243     }
244 
245   pstdout_printf (state_data->pstate,
246                   "Partial Add SDR Command                           : %s\n",
247                   (val ? "supported" : "unsupported"));
248 
249   if (FIID_OBJ_GET (obj_cmd_rs, "delete_sdr_command_supported", &val) < 0)
250     {
251       pstdout_fprintf (state_data->pstate,
252                        stderr,
253                        "fiid_obj_get: 'delete_sdr_command_supported': %s\n",
254                        fiid_obj_errormsg (obj_cmd_rs));
255       goto cleanup;
256     }
257 
258   pstdout_printf (state_data->pstate,
259                   "Delete SDR Command                                : %s\n",
260                   (val ? "supported" : "unsupported"));
261 
262   if (FIID_OBJ_GET (obj_cmd_rs, "modal_non_modal_sdr_repository_update_operation_supported", &val) < 0)
263     {
264       pstdout_fprintf (state_data->pstate,
265                        stderr,
266                        "fiid_obj_get: 'modal_non_modal_sdr_repository_update_operation_supported': %s\n",
267                        fiid_obj_errormsg (obj_cmd_rs));
268       goto cleanup;
269     }
270 
271   switch (val)
272     {
273     case IPMI_SDR_MODAL_NON_MODAL_REPOSITORY_UPDATE_OP_UNSPECIFIED:
274       str = "unspecified";
275       break;
276     case IPMI_SDR_NON_MODAL_REPOSITORY_UPDATE_OP_SUPPORTED:
277       str = "non-Modal supported";
278       break;
279     case IPMI_SDR_MODAL_REPOSITORY_UPDATE_OP_SUPPORTED:
280       str = "modal supported";
281       break;
282     case IPMI_SDR_MODAL_NON_MODAL_REPOSITORY_UPDATE_OP_SUPPORTED:
283       str = "both supported";
284       break;
285     default:
286       str = "unknown";
287     }
288 
289   pstdout_printf (state_data->pstate,
290                   "Modal/non-modal SDR Repository Update operation   : %s\n",
291                   str);
292 
293   if (FIID_OBJ_GET (obj_cmd_rs, "overflow_flag", &val) < 0)
294     {
295       pstdout_fprintf (state_data->pstate,
296                        stderr,
297                        "fiid_obj_get: 'overflow_flag': %s\n",
298                        fiid_obj_errormsg (obj_cmd_rs));
299       goto cleanup;
300     }
301 
302   /* "SDR could not be written due to lack of space in the SDR Repository" */
303   pstdout_printf (state_data->pstate,
304                   "SDR could not be written due to lack of space     : %s\n",
305                   (val ? "Yes" : "No"));
306 
307   if (allocation_supported)
308     {
309       uint16_t number_of_possible_allocation_units;
310       uint16_t allocation_unit_size;
311       uint16_t number_of_free_allocation_units;
312       uint16_t largest_free_block;
313       uint8_t maximum_record_size;
314 
315       fiid_obj_destroy (obj_cmd_rs);
316 
317       if (!(obj_cmd_rs = fiid_obj_create (tmpl_cmd_get_sdr_repository_allocation_info_rs)))
318         {
319           pstdout_fprintf (state_data->pstate,
320                            stderr,
321                            "fiid_obj_create: %s\n",
322                            strerror (errno));
323           goto cleanup;
324         }
325 
326       if (ipmi_cmd_get_sdr_repository_allocation_info (state_data->ipmi_ctx, obj_cmd_rs) < 0)
327         {
328           pstdout_fprintf (state_data->pstate,
329                            stderr,
330                            "ipmi_cmd_get_sdr_repository_allocation_info: %s\n",
331                            ipmi_ctx_errormsg (state_data->ipmi_ctx));
332           goto cleanup;
333         }
334 
335       if (FIID_OBJ_GET (obj_cmd_rs, "number_of_possible_allocation_units", &val) < 0)
336         {
337           pstdout_fprintf (state_data->pstate,
338                            stderr,
339                            "fiid_obj_get: 'number_of_possible_allocation_units': %s\n",
340                            fiid_obj_errormsg (obj_cmd_rs));
341           goto cleanup;
342         }
343       number_of_possible_allocation_units = val;
344 
345       if (FIID_OBJ_GET (obj_cmd_rs, "allocation_unit_size", &val) < 0)
346         {
347           pstdout_fprintf (state_data->pstate,
348                            stderr,
349                            "fiid_obj_get: 'allocation_unit_size': %s\n",
350                            fiid_obj_errormsg (obj_cmd_rs));
351           goto cleanup;
352         }
353       allocation_unit_size = val;
354 
355       if (FIID_OBJ_GET (obj_cmd_rs, "number_of_free_allocation_units", &val) < 0)
356         {
357           pstdout_fprintf (state_data->pstate,
358                            stderr,
359                            "fiid_obj_get: 'number_of_free_allocation_units': %s\n",
360                            fiid_obj_errormsg (obj_cmd_rs));
361           goto cleanup;
362         }
363       number_of_free_allocation_units = val;
364 
365       if (FIID_OBJ_GET (obj_cmd_rs, "largest_free_block", &val) < 0)
366         {
367           pstdout_fprintf (state_data->pstate,
368                            stderr,
369                            "fiid_obj_get: 'largest_free_block': %s\n",
370                            fiid_obj_errormsg (obj_cmd_rs));
371           goto cleanup;
372         }
373       largest_free_block = val;
374 
375       if (FIID_OBJ_GET (obj_cmd_rs, "maximum_record_size", &val) < 0)
376         {
377           pstdout_fprintf (state_data->pstate,
378                            stderr,
379                            "fiid_obj_get: 'maximum_record_size': %s\n",
380                            fiid_obj_errormsg (obj_cmd_rs));
381           goto cleanup;
382         }
383       maximum_record_size = val;
384 
385       if (!number_of_possible_allocation_units)
386         pstdout_printf (state_data->pstate,
387                         "Number of possible allocation units               : unspecified\n");
388       else
389         pstdout_printf (state_data->pstate,
390                         "Number of possible allocation units               : %u\n",
391                         number_of_possible_allocation_units);
392 
393       if (!allocation_unit_size)
394         pstdout_printf (state_data->pstate,
395                         "Allocation unit size                              : unspecified\n");
396       else
397         pstdout_printf (state_data->pstate,
398                         "Allocation unit size                              : %u bytes\n",
399                         allocation_unit_size);
400 
401       pstdout_printf (state_data->pstate,
402                       "Number of free allocation units                   : %u\n",
403                       number_of_free_allocation_units);
404 
405       pstdout_printf (state_data->pstate,
406                       "Largest free block                                : %u allocation units\n",
407                       largest_free_block);
408 
409       pstdout_printf (state_data->pstate,
410                       "Maximum record size                               : %u allocation units\n",
411                       maximum_record_size);
412     }
413 
414   rv = 0;
415  cleanup:
416   fiid_obj_destroy (obj_cmd_rs);
417   return (rv);
418 }
419 
420 static int
_output_setup(ipmi_sensors_state_data_t * state_data)421 _output_setup (ipmi_sensors_state_data_t *state_data)
422 {
423   assert (state_data);
424 
425   if (!state_data->prog_data->args->verbose_count)
426     return (ipmi_sensors_simple_output_setup (state_data));
427 
428   return (0);
429 }
430 
431 static int
_calculate_record_ids(ipmi_sensors_state_data_t * state_data,unsigned int output_record_ids[MAX_SENSOR_RECORD_IDS],unsigned int * output_record_ids_length)432 _calculate_record_ids (ipmi_sensors_state_data_t *state_data,
433                        unsigned int output_record_ids[MAX_SENSOR_RECORD_IDS],
434                        unsigned int *output_record_ids_length)
435 {
436   uint16_t record_count;
437   uint16_t record_id;
438   unsigned int i;
439   unsigned int j;
440 
441   assert (state_data);
442   assert (output_record_ids);
443   assert (output_record_ids_length);
444 
445   memset (output_record_ids, '\0', sizeof (unsigned int) * MAX_SENSOR_RECORD_IDS);
446   (*output_record_ids_length) = 0;
447 
448   if (ipmi_sdr_cache_record_count (state_data->sdr_ctx,
449                                    &record_count) < 0)
450     {
451       pstdout_fprintf (state_data->pstate,
452                        stderr,
453                        "ipmi_sdr_cache_record_count: %s\n",
454                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
455       return (-1);
456     }
457 
458   /*
459    * achu: This code could be done far more concisely, but it got
460    * confusing and hard to understand.  We will divide this up into
461    * simple chunks, if the user specified neither record_ids and
462    * types, record_ids, or types.  record_ids take precedence over
463    * types, and exclude_record_ids takes precedence over
464    * exclude_types.
465    */
466 
467   if (!state_data->prog_data->args->record_ids_length
468       && !state_data->prog_data->args->sensor_types_length)
469     {
470       for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (state_data->sdr_ctx))
471         {
472           if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx,
473                                                  NULL,
474                                                  0,
475                                                  &record_id,
476                                                  NULL) < 0)
477             {
478               pstdout_fprintf (state_data->pstate,
479                                stderr,
480                                "ipmi_sdr_parse_record_id_and_type: %s\n",
481                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
482               return (-1);
483             }
484 
485           if (state_data->prog_data->args->exclude_record_ids_length)
486             {
487               int found_exclude = 0;
488 
489               for (j = 0; j < state_data->prog_data->args->exclude_record_ids_length; j++)
490                 {
491                   if (record_id == state_data->prog_data->args->exclude_record_ids[j])
492                     {
493                       found_exclude++;
494                       break;
495                     }
496                 }
497 
498               if (found_exclude)
499                 continue;
500             }
501 
502           if (state_data->prog_data->args->exclude_sensor_types_length)
503             {
504               int flag;
505 
506               if ((flag = sensor_type_listed_sdr (state_data->pstate,
507                                                   state_data->sdr_ctx,
508                                                   state_data->prog_data->args->exclude_sensor_types,
509                                                   state_data->prog_data->args->exclude_sensor_types_length)) < 0)
510                 return (-1);
511 
512               if (flag)
513                 continue;
514             }
515 
516           output_record_ids[(*output_record_ids_length)] = record_id;
517           (*output_record_ids_length)++;
518 
519           if ((*output_record_ids_length) >= MAX_SENSOR_RECORD_IDS)
520             {
521               pstdout_fprintf (state_data->pstate,
522                                stderr,
523                                "Too many sensors found on system; limit is %u\n",
524                                MAX_SENSOR_RECORD_IDS);
525               return (-1);
526             }
527         }
528     }
529   else if (state_data->prog_data->args->record_ids_length)
530     {
531       for (i = 0; i < state_data->prog_data->args->record_ids_length; i++)
532         {
533           if (state_data->prog_data->args->exclude_record_ids_length)
534             {
535               int found_exclude = 0;
536 
537               for (j = 0; j < state_data->prog_data->args->exclude_record_ids_length; j++)
538                 {
539                   if (state_data->prog_data->args->record_ids[i] == state_data->prog_data->args->exclude_record_ids[j])
540                     {
541                       found_exclude++;
542                       break;
543                     }
544                 }
545 
546               if (found_exclude)
547                 continue;
548             }
549 
550           if (ipmi_sdr_cache_search_record_id (state_data->sdr_ctx, state_data->prog_data->args->record_ids[i]) < 0)
551             {
552               if (ipmi_sdr_ctx_errnum (state_data->sdr_ctx) == IPMI_SDR_ERR_NOT_FOUND)
553                 {
554                   pstdout_printf (state_data->pstate,
555                                   "Sensor Record ID '%d' not found\n",
556                                   state_data->prog_data->args->record_ids[i]);
557                   return (-1);
558                 }
559               else
560                 {
561                   pstdout_fprintf (state_data->pstate,
562                                    stderr,
563                                    "ipmi_sdr_cache_search_record_id: %s\n",
564                                    ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
565                   return (-1);
566                 }
567             }
568 
569           if (state_data->prog_data->args->exclude_sensor_types_length)
570             {
571               int flag;
572 
573               if ((flag = sensor_type_listed_sdr (state_data->pstate,
574                                                   state_data->sdr_ctx,
575                                                   state_data->prog_data->args->exclude_sensor_types,
576                                                   state_data->prog_data->args->exclude_sensor_types_length)) < 0)
577                 return (-1);
578 
579               if (flag)
580                 continue;
581             }
582 
583           output_record_ids[(*output_record_ids_length)] = state_data->prog_data->args->record_ids[i];
584           (*output_record_ids_length)++;
585 
586           if ((*output_record_ids_length) >= MAX_SENSOR_RECORD_IDS)
587             {
588               pstdout_fprintf (state_data->pstate,
589                                stderr,
590                                "Too many sensors specified; limit is %u\n",
591                                MAX_SENSOR_RECORD_IDS);
592               return (-1);
593             }
594         }
595     }
596   else /* state_data->prog_data->args->sensor_types_length */
597     {
598       for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (state_data->sdr_ctx))
599         {
600           int flag;
601 
602           if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx,
603                                                  NULL,
604                                                  0,
605                                                  &record_id,
606                                                  NULL) < 0)
607             {
608               pstdout_fprintf (state_data->pstate,
609                                stderr,
610                                "ipmi_sdr_parse_record_id_and_type: %s\n",
611                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
612               return (-1);
613             }
614 
615           if ((flag = sensor_type_listed_sdr (state_data->pstate,
616                                               state_data->sdr_ctx,
617                                               state_data->prog_data->args->sensor_types,
618                                               state_data->prog_data->args->sensor_types_length)) < 0)
619             return (-1);
620 
621           if (!flag)
622             continue;
623 
624           if (state_data->prog_data->args->exclude_record_ids)
625             {
626               int found_exclude = 0;
627 
628               for (j = 0; j < state_data->prog_data->args->exclude_record_ids_length; j++)
629                 {
630                   if (record_id == state_data->prog_data->args->exclude_record_ids[j])
631                     {
632                       found_exclude++;
633                       break;
634                     }
635                 }
636 
637               if (found_exclude)
638                 continue;
639             }
640 
641           if (state_data->prog_data->args->exclude_sensor_types_length)
642             {
643               if ((flag = sensor_type_listed_sdr (state_data->pstate,
644                                                   state_data->sdr_ctx,
645                                                   state_data->prog_data->args->exclude_sensor_types,
646                                                   state_data->prog_data->args->exclude_sensor_types_length)) < 0)
647                 return (-1);
648 
649               if (flag)
650                 continue;
651             }
652 
653           output_record_ids[(*output_record_ids_length)] = record_id;
654           (*output_record_ids_length)++;
655 
656           if ((*output_record_ids_length) >= MAX_SENSOR_RECORD_IDS)
657             {
658               pstdout_fprintf (state_data->pstate,
659                                stderr,
660                                "Too many sensors found on system; limit is %u\n",
661                                MAX_SENSOR_RECORD_IDS);
662               return (-1);
663             }
664         }
665     }
666 
667   return (0);
668 }
669 
670 /* Return 1 if generated message, 0 if not, -1 on error */
671 static int
_intel_nm_oem_event_message(ipmi_sensors_state_data_t * state_data,uint8_t sensor_reading_raw,char *** event_message_list,unsigned int * event_message_list_len)672 _intel_nm_oem_event_message (ipmi_sensors_state_data_t *state_data,
673                              uint8_t sensor_reading_raw,
674                              char ***event_message_list,
675                              unsigned int *event_message_list_len)
676 {
677   uint8_t sensor_type;
678   uint8_t sensor_number;
679   uint8_t event_reading_type_code;
680   int rv = -1;
681 
682   assert (state_data);
683   assert (event_message_list);
684   assert (event_message_list_len);
685   assert (state_data->prog_data->args->interpret_oem_data);
686   assert (state_data->intel_node_manager.node_manager_data_found);
687 
688   if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
689                                   NULL,
690                                   0,
691                                   &sensor_type) < 0)
692     {
693       pstdout_fprintf (state_data->pstate,
694                        stderr,
695                        "ipmi_sdr_parse_sensor_type: %s\n",
696                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
697       goto cleanup;
698     }
699 
700   if (ipmi_sdr_parse_sensor_number (state_data->sdr_ctx,
701                                     NULL,
702                                     0,
703                                     &sensor_number) < 0)
704     {
705       pstdout_fprintf (state_data->pstate,
706                        stderr,
707                        "ipmi_sdr_parse_sensor_number: %s\n",
708                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
709       goto cleanup;
710     }
711 
712   if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
713                                               NULL,
714                                               0,
715                                               &event_reading_type_code) < 0)
716     {
717       pstdout_fprintf (state_data->pstate,
718                        stderr,
719                        "ipmi_sdr_parse_event_reading_type_code: %s\n",
720                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
721       goto cleanup;
722     }
723 
724   if (event_reading_type_code == IPMI_EVENT_READING_TYPE_CODE_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT
725       && sensor_type == IPMI_SENSOR_TYPE_OEM_INTEL_NODE_MANAGER
726       && state_data->intel_node_manager.nm_operational_capabilities_sensor_number == sensor_number)
727     {
728       uint8_t policy_interface_capability;
729       uint8_t monitoring_capability;
730       uint8_t power_limiting_capability;
731       char policy_interface_capability_str[IPMI_SENSORS_MESSAGE_LENGTH + 1];
732       char monitoring_capability_str[IPMI_SENSORS_MESSAGE_LENGTH + 1];
733       char power_limiting_capability_str[IPMI_SENSORS_MESSAGE_LENGTH + 1];
734       char **tmp_event_message_list = NULL;
735 
736       memset (policy_interface_capability_str, '\0', IPMI_SENSORS_MESSAGE_LENGTH + 1);
737       memset (monitoring_capability_str, '\0', IPMI_SENSORS_MESSAGE_LENGTH + 1);
738       memset (power_limiting_capability_str, '\0', IPMI_SENSORS_MESSAGE_LENGTH + 1);
739 
740       policy_interface_capability = (sensor_reading_raw & IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_POLICY_INTERFACE_CAPABILITY_BITMASK);
741       policy_interface_capability >>= IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_POLICY_INTERFACE_CAPABILITY_SHIFT;
742 
743       monitoring_capability = (sensor_reading_raw & IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_MONITORING_CAPABILITY_BITMASK);
744       monitoring_capability >>= IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_MONITORING_CAPABILITY_SHIFT;
745 
746       power_limiting_capability = (sensor_reading_raw & IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_POWER_LIMITING_CAPABILITY_BITMASK);
747       power_limiting_capability >>= IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_EVENT_DATA1_POWER_LIMITING_CAPABILITY_SHIFT;
748 
749       snprintf (policy_interface_capability_str,
750                 IPMI_SENSORS_MESSAGE_LENGTH,
751                 "Policy Interface Capability %s",
752                 (policy_interface_capability == IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_AVAILABLE) ? "Available" : "Not Available");
753 
754       snprintf (monitoring_capability_str,
755                 IPMI_SENSORS_MESSAGE_LENGTH,
756                 "Monitoring Capability %s",
757                 (monitoring_capability == IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_AVAILABLE) ? "Available" : "Not Available");
758 
759       snprintf (power_limiting_capability_str,
760                 IPMI_SENSORS_MESSAGE_LENGTH,
761                 "Power Limiting Capability %s",
762                 (power_limiting_capability == IPMI_OEM_INTEL_NODE_MANAGER_OPERATIONAL_CAPABILITIES_CHANGE_EVENT_AVAILABLE) ? "Available" : "Not Available");
763 
764       if (!(tmp_event_message_list = (char **) malloc (sizeof (char *) * 4)))
765         {
766           pstdout_perror (state_data->pstate, "malloc");
767           goto cleanup;
768         }
769 
770       if (!(tmp_event_message_list[0] = strdup (policy_interface_capability_str)))
771         {
772           pstdout_perror (state_data->pstate, "strdup");
773           free (tmp_event_message_list);
774           goto cleanup;
775         }
776 
777       if (!(tmp_event_message_list[1] = strdup (monitoring_capability_str)))
778         {
779           pstdout_perror (state_data->pstate, "strdup");
780           free (tmp_event_message_list[0]);
781           free (tmp_event_message_list);
782           goto cleanup;
783         }
784 
785       if (!(tmp_event_message_list[2] = strdup (power_limiting_capability_str)))
786         {
787           pstdout_perror (state_data->pstate, "strdup");
788           free (tmp_event_message_list[1]);
789           free (tmp_event_message_list[0]);
790           free (tmp_event_message_list);
791           goto cleanup;
792         }
793 
794       tmp_event_message_list[3] = NULL;
795 
796       (*event_message_list) = tmp_event_message_list;
797       (*event_message_list_len) = 3;
798 
799       rv = 1;
800     }
801   else
802     rv = 0;
803 
804  cleanup:
805   return (rv);
806 }
807 
808 static int
_get_event_message(ipmi_sensors_state_data_t * state_data,uint16_t sensor_event_bitmask,char *** event_message_list,unsigned int * event_message_list_len)809 _get_event_message (ipmi_sensors_state_data_t *state_data,
810                     uint16_t sensor_event_bitmask,
811                     char ***event_message_list,
812                     unsigned int *event_message_list_len)
813 {
814   uint8_t sensor_type;
815   uint8_t sensor_number;
816   uint8_t event_reading_type_code;
817   uint32_t manufacturer_id = 0;
818   uint16_t product_id = 0;
819   unsigned int flags = IPMI_GET_EVENT_MESSAGES_FLAGS_DEFAULT;
820   int rv = -1;
821 
822   assert (state_data);
823   assert (event_message_list);
824   assert (event_message_list_len);
825 
826   if (ipmi_sdr_parse_sensor_type (state_data->sdr_ctx,
827                                   NULL,
828                                   0,
829                                   &sensor_type) < 0)
830     {
831       pstdout_fprintf (state_data->pstate,
832                        stderr,
833                        "ipmi_sdr_parse_sensor_type: %s\n",
834                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
835       goto cleanup;
836     }
837 
838   if (ipmi_sdr_parse_sensor_number (state_data->sdr_ctx,
839                                     NULL,
840                                     0,
841                                     &sensor_number) < 0)
842     {
843       pstdout_fprintf (state_data->pstate,
844                        stderr,
845                        "ipmi_sdr_parse_sensor_number: %s\n",
846                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
847       goto cleanup;
848     }
849 
850   if (ipmi_sdr_parse_event_reading_type_code (state_data->sdr_ctx,
851                                               NULL,
852                                               0,
853                                               &event_reading_type_code) < 0)
854     {
855       pstdout_fprintf (state_data->pstate,
856                        stderr,
857                        "ipmi_sdr_parse_event_reading_type_code: %s\n",
858                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
859       goto cleanup;
860     }
861 
862   flags |= IPMI_GET_EVENT_MESSAGES_FLAGS_SENSOR_READING;
863 
864   if (!state_data->prog_data->args->verbose_count)
865     flags |= IPMI_GET_EVENT_MESSAGES_FLAGS_SHORT;
866 
867   if (state_data->prog_data->args->interpret_oem_data)
868     {
869       manufacturer_id = state_data->oem_data.manufacturer_id;
870       product_id = state_data->oem_data.product_id;
871       flags |= IPMI_GET_EVENT_MESSAGES_FLAGS_INTERPRET_OEM_DATA;
872     }
873 
874   if (state_data->prog_data->args->ignore_unrecognized_events)
875     flags |= IPMI_GET_EVENT_MESSAGES_FLAGS_IGNORE_UNRECOGNIZED_EVENTS;
876 
877   if (ipmi_get_event_messages (event_reading_type_code,
878                                sensor_type,
879                                sensor_number,
880                                sensor_event_bitmask,
881                                manufacturer_id,
882                                product_id,
883                                event_message_list,
884                                event_message_list_len,
885                                IPMI_SENSORS_NO_EVENT_STRING,
886                                flags) < 0)
887     {
888       pstdout_fprintf (state_data->pstate,
889                        stderr,
890                        "ipmi_get_event_messages: %s\n",
891                        strerror (errno));
892       goto cleanup;
893     }
894 
895   rv = 0;
896  cleanup:
897   return (rv);
898 }
899 
900 static int
_output_sensor(ipmi_sensors_state_data_t * state_data,uint8_t sensor_number_base,uint8_t shared_sensor_number_offset)901 _output_sensor (ipmi_sensors_state_data_t *state_data,
902                 uint8_t sensor_number_base,
903                 uint8_t shared_sensor_number_offset)
904 {
905   uint8_t sdr_record[IPMI_SDR_MAX_RECORD_LENGTH];
906   int sdr_record_len = 0;
907   uint8_t sensor_reading_raw = 0;
908   double *sensor_reading = NULL;
909   uint16_t sensor_event_bitmask = 0;
910   char **event_message_list = NULL;
911   int event_message_output_type = IPMI_SENSORS_EVENT_NORMAL;
912   unsigned int event_message_list_len = 0;
913   int rv = -1;
914 
915   assert (state_data);
916 
917   if ((sdr_record_len = ipmi_sdr_cache_record_read (state_data->sdr_ctx,
918                                                     sdr_record,
919                                                     IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
920     {
921       pstdout_fprintf (state_data->pstate,
922                        stderr,
923                        "ipmi_sdr_cache_record_read: %s\n",
924                        ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
925       goto cleanup;
926     }
927 
928   if (ipmi_sensor_read (state_data->sensor_read_ctx,
929                         sdr_record,
930                         sdr_record_len,
931                         shared_sensor_number_offset,
932                         &sensor_reading_raw,
933                         &sensor_reading,
934                         &sensor_event_bitmask) <= 0)
935     {
936       int errnum = ipmi_sensor_read_ctx_errnum (state_data->sensor_read_ctx);
937 
938       if (errnum == IPMI_SENSOR_READ_ERR_SENSOR_NON_ANALOG
939           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_NON_LINEAR)
940         {
941           if (state_data->prog_data->args->common_args.debug)
942             pstdout_fprintf (state_data->pstate,
943                              stderr,
944                              "Sensor reading cannot be calculated: %s\n",
945                              ipmi_sensor_read_ctx_errormsg (state_data->sensor_read_ctx));
946 
947           goto get_events;
948         }
949 
950       if (errnum == IPMI_SENSOR_READ_ERR_SENSOR_IS_SYSTEM_SOFTWARE
951           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_READING_UNAVAILABLE
952           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_SCANNING_DISABLED
953           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_NON_ANALOG
954           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_NON_LINEAR
955           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_NOT_OWNED_BY_BMC
956           || errnum == IPMI_SENSOR_READ_ERR_SENSOR_CANNOT_BE_BRIDGED)
957         {
958           if (state_data->prog_data->args->common_args.debug)
959             pstdout_fprintf (state_data->pstate,
960                              stderr,
961                              "Sensor reading/event bitmask not available: %s\n",
962                              ipmi_sensor_read_ctx_errormsg (state_data->sensor_read_ctx));
963 
964           if (state_data->prog_data->args->ignore_not_available_sensors)
965             {
966               rv = 0;
967               goto cleanup;
968             }
969 
970           event_message_output_type = IPMI_SENSORS_EVENT_NA;
971 
972           goto output;
973         }
974 
975       if (errnum == IPMI_SENSOR_READ_ERR_SENSOR_READING_CANNOT_BE_OBTAINED
976           || errnum == IPMI_SENSOR_READ_ERR_NODE_BUSY)
977         {
978           if (state_data->prog_data->args->common_args.debug)
979             pstdout_fprintf (state_data->pstate,
980                              stderr,
981                              "Sensor reading/event_bitmask retrieval error: %s\n",
982                              ipmi_sensor_read_ctx_errormsg (state_data->sensor_read_ctx));
983 
984           event_message_output_type = IPMI_SENSORS_EVENT_UNKNOWN;
985 
986           goto output;
987         }
988 
989       if (errnum == IPMI_SENSOR_READ_ERR_INVALID_SDR_RECORD_TYPE)
990         {
991           /* Fall through to output.  detailed-output will output SDR
992            * information if it pleases, simple-output will ignore this
993            * SDR type.
994            */
995 
996           goto output;
997         }
998 
999       pstdout_fprintf (state_data->pstate,
1000                        stderr,
1001                        "ipmi_sensor_read: %s\n",
1002                        ipmi_sensor_read_ctx_errormsg (state_data->sensor_read_ctx));
1003       goto cleanup;
1004     }
1005 
1006  get_events:
1007 
1008   if (!state_data->prog_data->args->output_event_bitmask
1009       || state_data->prog_data->args->legacy_output)
1010     {
1011       int event_msg_generated = 0;
1012 
1013       /* OEM Interpretation
1014        *
1015        * Handle Intel Node Manager special case
1016        */
1017       if (state_data->prog_data->args->interpret_oem_data
1018           && ((state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL
1019                && (state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S5500WB
1020                    || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S2600JF
1021                    || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S2600WP
1022                    || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_QUANTA_QSSC_S4R))
1023               || (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INVENTEC
1024                   && (state_data->oem_data.product_id == IPMI_INVENTEC_PRODUCT_ID_5441
1025                       || state_data->oem_data.product_id == IPMI_INVENTEC_PRODUCT_ID_5442))
1026               || (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_QUANTA
1027                   && state_data->oem_data.product_id == IPMI_QUANTA_PRODUCT_ID_S99Q))
1028           && state_data->intel_node_manager.node_manager_data_found)
1029         {
1030           if ((event_msg_generated = _intel_nm_oem_event_message (state_data,
1031                                                                   sensor_reading_raw,
1032                                                                   &event_message_list,
1033                                                                   &event_message_list_len)) < 0)
1034             goto cleanup;
1035         }
1036 
1037       if (!event_msg_generated)
1038         {
1039           if (_get_event_message (state_data,
1040                                   sensor_event_bitmask,
1041                                   &event_message_list,
1042                                   &event_message_list_len) < 0)
1043             goto cleanup;
1044         }
1045     }
1046 
1047  output:
1048   if (state_data->prog_data->args->verbose_count)
1049     rv = ipmi_sensors_detailed_output (state_data,
1050                                        sensor_number_base + shared_sensor_number_offset,
1051                                        sensor_reading,
1052                                        event_message_output_type,
1053                                        sensor_event_bitmask,
1054                                        event_message_list,
1055                                        event_message_list_len);
1056   else
1057     rv = ipmi_sensors_simple_output (state_data,
1058                                      sensor_number_base + shared_sensor_number_offset,
1059                                      sensor_reading,
1060                                      event_message_output_type,
1061                                      sensor_event_bitmask,
1062                                      event_message_list,
1063                                      event_message_list_len);
1064 
1065  cleanup:
1066   free (sensor_reading);
1067   if (event_message_list)
1068     {
1069       unsigned int j;
1070       for (j = 0; j < event_message_list_len; j++)
1071         free (event_message_list[j]);
1072       free (event_message_list);
1073     }
1074   return (rv);
1075 }
1076 
1077 static int
_display_sensors(ipmi_sensors_state_data_t * state_data)1078 _display_sensors (ipmi_sensors_state_data_t *state_data)
1079 {
1080   struct ipmi_sensors_arguments *args = NULL;
1081   unsigned int output_record_ids[MAX_SENSOR_RECORD_IDS];
1082   unsigned int output_record_ids_length = 0;
1083   unsigned int i;
1084   unsigned int ctx_flags_orig;
1085   int rv = -1;
1086 
1087   assert (state_data);
1088 
1089   args = state_data->prog_data->args;
1090 
1091   if (args->interpret_oem_data)
1092     {
1093       if (ipmi_get_oem_data (state_data->pstate,
1094                              state_data->ipmi_ctx,
1095                              &state_data->oem_data) < 0)
1096         goto cleanup;
1097 
1098       /* OEM Interpretation
1099        *
1100        * Intel Node Manager
1101        *
1102        * For Intel Chips, not just Intel Motherboards.  Confirmed for:
1103        *
1104        * Intel S5500WB/Penguin Computing Relion 700
1105        * Intel S2600JF/Appro 512X
1106        * Intel S2600WP
1107        * Inventec 5441/Dell Xanadu II
1108        * Inventec 5442/Dell Xanadu III
1109        * Quanta S99Q/Dell FS12-TY
1110        * Quanta QSSC-S4R/Appro GB812X-CN (maintains Intel manufacturer ID)
1111        *
1112        * Below confirms the Intel Node Manager exists.  We must do
1113        * this before reading the sensor to determime what type of
1114        * sensor it is via the sensor number.
1115        */
1116       if ((state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INTEL
1117            && (state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S5500WB
1118                || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S2600JF
1119                || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_S2600WP
1120                || state_data->oem_data.product_id == IPMI_INTEL_PRODUCT_ID_QUANTA_QSSC_S4R))
1121           || (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_INVENTEC
1122               && (state_data->oem_data.product_id == IPMI_INVENTEC_PRODUCT_ID_5441
1123                   || state_data->oem_data.product_id == IPMI_INVENTEC_PRODUCT_ID_5442))
1124           || (state_data->oem_data.manufacturer_id == IPMI_IANA_ENTERPRISE_ID_QUANTA
1125               && state_data->oem_data.product_id == IPMI_QUANTA_PRODUCT_ID_S99Q))
1126         {
1127           uint16_t record_count;
1128           int ret;
1129 
1130           if (ipmi_sdr_cache_record_count (state_data->sdr_ctx,
1131                                            &record_count) < 0)
1132             {
1133               pstdout_fprintf (state_data->pstate,
1134                                stderr,
1135                                "ipmi_sdr_cache_record_count: %s\n",
1136                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1137               goto cleanup;
1138             }
1139 
1140           /* achu:
1141            *
1142            * In Intel NM 2.0 specification, sensor numbers are now fixed and you
1143            * don't have to search the SDR for them.  We could check version of
1144            * NM on motherboard to determine if we need to search SDR or not, but
1145            * for time being we'll stick to the search SDR method b/c it will
1146            * always work.
1147            */
1148           for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (state_data->sdr_ctx))
1149             {
1150               if ((ret = ipmi_sdr_oem_parse_intel_node_manager (state_data->sdr_ctx,
1151                                                                 NULL,
1152                                                                 0,
1153                                                                 NULL,
1154                                                                 NULL,
1155                                                                 NULL,
1156                                                                 &state_data->intel_node_manager.nm_health_event_sensor_number,
1157                                                                 &state_data->intel_node_manager.nm_exception_event_sensor_number,
1158                                                                 &state_data->intel_node_manager.nm_operational_capabilities_sensor_number,
1159                                                                 &state_data->intel_node_manager.nm_alert_threshold_exceeded_sensor_number)) < 0)
1160                 {
1161                   pstdout_fprintf (state_data->pstate,
1162                                    stderr,
1163                                    "ipmi_sdr_oem_parse_intel_node_manager: %s\n",
1164                                    ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1165                   goto cleanup;
1166                 }
1167 
1168               if (ret)
1169                 {
1170                   state_data->intel_node_manager.node_manager_data_found = 1;
1171                   break;
1172                 }
1173             }
1174 
1175           if (ipmi_sdr_cache_first (state_data->sdr_ctx) < 0)
1176             {
1177               pstdout_fprintf (state_data->pstate,
1178                                stderr,
1179                                "ipmi_sdr_cache_first: %s\n",
1180                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1181               goto cleanup;
1182             }
1183         }
1184 
1185       if (args->output_sensor_state)
1186         {
1187           if (ipmi_interpret_ctx_set_manufacturer_id (state_data->interpret_ctx,
1188                                                       state_data->oem_data.manufacturer_id) < 0)
1189             {
1190               pstdout_fprintf (state_data->pstate,
1191                                stderr,
1192                                "ipmi_interpret_ctx_set_manufacturer_id: %s\n",
1193                                ipmi_interpret_ctx_errormsg (state_data->interpret_ctx));
1194               goto cleanup;
1195             }
1196 
1197           if (ipmi_interpret_ctx_set_product_id (state_data->interpret_ctx,
1198                                                  state_data->oem_data.product_id) < 0)
1199             {
1200               pstdout_fprintf (state_data->pstate,
1201                                stderr,
1202                                "ipmi_interpret_ctx_set_product_id: %s\n",
1203                                ipmi_interpret_ctx_errormsg (state_data->interpret_ctx));
1204               goto cleanup;
1205             }
1206         }
1207     }
1208 
1209   if (_output_setup (state_data) < 0)
1210     goto cleanup;
1211 
1212   if (_calculate_record_ids (state_data,
1213                              output_record_ids,
1214                              &output_record_ids_length) < 0)
1215     return (-1);
1216 
1217   if (state_data->prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_AUTH_CODE)
1218     {
1219       if (ipmi_ctx_get_flags (state_data->ipmi_ctx, &ctx_flags_orig) < 0)
1220         {
1221           pstdout_fprintf (state_data->pstate,
1222                            stderr,
1223                            "ipmi_ctx_get_flags: %s\n",
1224                            ipmi_ctx_errormsg (state_data->ipmi_ctx));
1225           goto cleanup;
1226         }
1227 
1228       if (ipmi_ctx_set_flags (state_data->ipmi_ctx, ctx_flags_orig | IPMI_FLAGS_IGNORE_AUTHENTICATION_CODE) < 0)
1229         {
1230           pstdout_fprintf (state_data->pstate,
1231                            stderr,
1232                            "ipmi_ctx_set_flags: %s\n",
1233                            ipmi_ctx_errormsg (state_data->ipmi_ctx));
1234           goto cleanup;
1235         }
1236     }
1237 
1238   for (i = 0; i < output_record_ids_length; i++)
1239     {
1240       uint8_t record_type;
1241       uint8_t sensor_number_base = 0;
1242 
1243       if (ipmi_sdr_cache_search_record_id (state_data->sdr_ctx,
1244                                            output_record_ids[i]) < 0)
1245         {
1246           /* at this point shouldn't have record id not found error */
1247           pstdout_fprintf (state_data->pstate,
1248                            stderr,
1249                            "ipmi_sdr_cache_search_record_id: 0x%02X %s\n",
1250                            output_record_ids[i],
1251                            ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1252           goto cleanup;
1253         }
1254 
1255       if (ipmi_sdr_parse_record_id_and_type (state_data->sdr_ctx,
1256                                              NULL,
1257                                              0,
1258                                              NULL,
1259                                              &record_type) < 0)
1260         {
1261           pstdout_fprintf (state_data->pstate,
1262                            stderr,
1263                            "ipmi_sdr_parse_record_id_and_type: %s\n",
1264                            ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1265           goto cleanup;
1266         }
1267 
1268       if (record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD
1269           || record_type == IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD
1270           || record_type == IPMI_SDR_FORMAT_EVENT_ONLY_RECORD)
1271         {
1272           if (ipmi_sdr_parse_sensor_number (state_data->sdr_ctx,
1273                                             NULL,
1274                                             0,
1275                                             &sensor_number_base) < 0)
1276             {
1277               pstdout_fprintf (state_data->pstate,
1278                                stderr,
1279                                "ipmi_sdr_parse_sensor_number: %s\n",
1280                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1281               goto cleanup;
1282             }
1283         }
1284 
1285       if (state_data->prog_data->args->shared_sensors)
1286         {
1287           uint8_t share_count;
1288           int i;
1289 
1290           if (record_type != IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD)
1291             goto fallthrough;
1292 
1293           if (ipmi_sdr_parse_sensor_record_sharing (state_data->sdr_ctx,
1294                                                     NULL,
1295                                                     0,
1296                                                     &share_count,
1297                                                     NULL,
1298                                                     NULL,
1299                                                     NULL) < 0)
1300             {
1301               pstdout_fprintf (state_data->pstate,
1302                                stderr,
1303                                "ipmi_sdr_parse_sensor_record_sharing: %s\n",
1304                                ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
1305               goto cleanup;
1306             }
1307 
1308           if (share_count <= 1)
1309             goto fallthrough;
1310 
1311           /* IPMI spec gives the following example:
1312            *
1313            * "If the starting sensor number was 10, and the share
1314            * count was 3, then sensors 10, 11, and 12 would share
1315            * the record"
1316            */
1317           for (i = 0; i < share_count; i++)
1318             {
1319               if (_output_sensor (state_data,
1320                                   sensor_number_base,
1321                                   i) < 0)
1322                 goto cleanup;
1323             }
1324         }
1325       else
1326         {
1327         fallthrough:
1328           if (_output_sensor (state_data,
1329                               sensor_number_base,
1330                               0) < 0)
1331             goto cleanup;
1332         }
1333     }
1334 
1335   if (state_data->prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_AUTH_CODE)
1336     {
1337       if (ipmi_ctx_set_flags (state_data->ipmi_ctx, ctx_flags_orig) < 0)
1338         {
1339           pstdout_fprintf (state_data->pstate,
1340                            stderr,
1341                            "ipmi_ctx_set_flags: %s\n",
1342                            ipmi_ctx_errormsg (state_data->ipmi_ctx));
1343           goto cleanup;
1344         }
1345     }
1346 
1347   rv = 0;
1348  cleanup:
1349   return (rv);
1350 }
1351 
1352 static int
run_cmd_args(ipmi_sensors_state_data_t * state_data)1353 run_cmd_args (ipmi_sensors_state_data_t *state_data)
1354 {
1355   struct ipmi_sensors_arguments *args;
1356 
1357   assert (state_data);
1358 
1359   args = state_data->prog_data->args;
1360 
1361   assert (!args->common_args.flush_cache);
1362 
1363   if (args->sdr_info)
1364     return (_sdr_repository_info (state_data));
1365 
1366   if (sdr_cache_create_and_load (state_data->sdr_ctx,
1367                                  state_data->pstate,
1368                                  state_data->ipmi_ctx,
1369                                  state_data->hostname,
1370                                  &state_data->prog_data->args->common_args) < 0)
1371     return (-1);
1372 
1373   if (_display_sensors (state_data) < 0)
1374     return (-1);
1375 
1376   return (0);
1377 }
1378 
1379 static int
_ipmi_sensors(pstdout_state_t pstate,const char * hostname,void * arg)1380 _ipmi_sensors (pstdout_state_t pstate,
1381                const char *hostname,
1382                void *arg)
1383 {
1384   ipmi_sensors_state_data_t state_data;
1385   ipmi_sensors_prog_data_t *prog_data;
1386   int exit_code = EXIT_FAILURE;
1387   unsigned int sensor_read_flags = 0;
1388 
1389   assert (pstate);
1390   assert (arg);
1391 
1392   prog_data = (ipmi_sensors_prog_data_t *)arg;
1393 
1394   assert (!prog_data->args->list_sensor_types);
1395 
1396   if (prog_data->args->common_args.flush_cache)
1397     {
1398       if (sdr_cache_flush_cache (pstate,
1399                                  hostname,
1400                                  &prog_data->args->common_args) < 0)
1401         return (EXIT_FAILURE);
1402       return (EXIT_SUCCESS);
1403     }
1404 
1405   memset (&state_data, '\0', sizeof (ipmi_sensors_state_data_t));
1406   state_data.prog_data = prog_data;
1407   state_data.pstate = pstate;
1408   state_data.hostname = (char *)hostname;
1409 
1410   if (!(state_data.ipmi_ctx = ipmi_open (prog_data->progname,
1411                                          hostname,
1412                                          &(prog_data->args->common_args),
1413                                          state_data.pstate,
1414                                          0)))
1415     goto cleanup;
1416 
1417   if (!(state_data.sdr_ctx = ipmi_sdr_ctx_create ()))
1418     {
1419       pstdout_perror (pstate, "ipmi_sdr_ctx_create()");
1420       goto cleanup;
1421     }
1422 
1423   if (!(state_data.sensor_read_ctx = ipmi_sensor_read_ctx_create (state_data.ipmi_ctx)))
1424     {
1425       pstdout_perror (pstate, "ipmi_sensor_read_ctx_create()");
1426       goto cleanup;
1427     }
1428 
1429   if (state_data.prog_data->args->bridge_sensors)
1430     sensor_read_flags |= IPMI_SENSOR_READ_FLAGS_BRIDGE_SENSORS;
1431 
1432   if (state_data.prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_DISCRETE_READING)
1433     sensor_read_flags |= IPMI_SENSOR_READ_FLAGS_DISCRETE_READING;
1434 
1435   if (state_data.prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_IGNORE_SCANNING_DISABLED)
1436     sensor_read_flags |= IPMI_SENSOR_READ_FLAGS_IGNORE_SCANNING_DISABLED;
1437 
1438   if (state_data.prog_data->args->common_args.section_specific_workaround_flags & IPMI_PARSE_SECTION_SPECIFIC_WORKAROUND_FLAGS_ASSUME_BMC_OWNER)
1439     sensor_read_flags |= IPMI_SENSOR_READ_FLAGS_ASSUME_BMC_OWNER;
1440 
1441   if (sensor_read_flags)
1442     {
1443       /* Don't error out, if this fails we can still continue */
1444       if (ipmi_sensor_read_ctx_set_flags (state_data.sensor_read_ctx, sensor_read_flags) < 0)
1445         pstdout_fprintf (pstate,
1446                          stderr,
1447                          "ipmi_sensor_read_ctx_set_flags: %s\n",
1448                          ipmi_sensor_read_ctx_strerror (ipmi_sensor_read_ctx_errnum (state_data.sensor_read_ctx)));
1449     }
1450 
1451   if (prog_data->args->output_sensor_state)
1452     {
1453       if (!(state_data.interpret_ctx = ipmi_interpret_ctx_create ()))
1454         {
1455           pstdout_perror (pstate, "ipmi_interpret_ctx_create()");
1456           goto cleanup;
1457         }
1458 
1459       if (prog_data->args->sensor_state_config_file)
1460         {
1461           if (ipmi_interpret_load_sensor_config (state_data.interpret_ctx,
1462                                                  prog_data->args->sensor_state_config_file) < 0)
1463             {
1464               if (ipmi_interpret_ctx_errnum (state_data.interpret_ctx) == IPMI_INTERPRET_ERR_SENSOR_CONFIG_FILE_DOES_NOT_EXIST)
1465                 pstdout_fprintf (pstate,
1466                                  stderr,
1467                                  "sensor state config file '%s' does not exist\n",
1468                                  prog_data->args->sensor_state_config_file);
1469               else if (ipmi_interpret_ctx_errnum (state_data.interpret_ctx) == IPMI_INTERPRET_ERR_SENSOR_CONFIG_FILE_PARSE)
1470                 pstdout_fprintf (pstate,
1471                                  stderr,
1472                                  "sensor state config file '%s' parse error\n",
1473                                  prog_data->args->sensor_state_config_file);
1474               else
1475                 pstdout_fprintf (pstate,
1476                                  stderr,
1477                                  "ipmi_interpret_load_sensor_config: %s\n",
1478                                  ipmi_interpret_ctx_errormsg (state_data.interpret_ctx));
1479               goto cleanup;
1480             }
1481         }
1482       else
1483         {
1484           if (ipmi_interpret_load_sensor_config (state_data.interpret_ctx, NULL) < 0)
1485             {
1486               if (ipmi_interpret_ctx_errnum (state_data.interpret_ctx) == IPMI_INTERPRET_ERR_SENSOR_CONFIG_FILE_PARSE)
1487                 pstdout_fprintf (pstate,
1488                                  stderr,
1489                                  "sensor state config file parse error\n");
1490               else
1491                 pstdout_fprintf (pstate,
1492                                  stderr,
1493                                  "ipmi_interpret_load_sensor_config: %s\n",
1494                                  ipmi_interpret_ctx_errormsg (state_data.interpret_ctx));
1495               goto cleanup;
1496             }
1497         }
1498 
1499       if (prog_data->args->interpret_oem_data
1500           || prog_data->args->ignore_unrecognized_events)
1501         {
1502           unsigned int flags = 0;
1503 
1504           if (prog_data->args->interpret_oem_data)
1505             flags |= IPMI_INTERPRET_FLAGS_INTERPRET_OEM_DATA;
1506 
1507           if (prog_data->args->ignore_unrecognized_events)
1508             flags |= IPMI_INTERPRET_FLAGS_IGNORE_UNRECOGNIZED_EVENTS;
1509 
1510           if (ipmi_interpret_ctx_set_flags (state_data.interpret_ctx, flags) < 0)
1511             {
1512               pstdout_fprintf (pstate,
1513                                stderr,
1514                                "ipmi_interpret_ctx_set_flags: %s\n",
1515                                ipmi_interpret_ctx_errormsg (state_data.interpret_ctx));
1516               goto cleanup;
1517             }
1518         }
1519     }
1520 
1521   if (run_cmd_args (&state_data) < 0)
1522     goto cleanup;
1523 
1524   exit_code = EXIT_SUCCESS;
1525  cleanup:
1526   ipmi_sdr_ctx_destroy (state_data.sdr_ctx);
1527   ipmi_sensor_read_ctx_destroy (state_data.sensor_read_ctx);
1528   ipmi_interpret_ctx_destroy (state_data.interpret_ctx);
1529   ipmi_ctx_close (state_data.ipmi_ctx);
1530   ipmi_ctx_destroy (state_data.ipmi_ctx);
1531   return (exit_code);
1532 }
1533 
1534 int
main(int argc,char ** argv)1535 main (int argc, char **argv)
1536 {
1537   ipmi_sensors_prog_data_t prog_data;
1538   struct ipmi_sensors_arguments cmd_args;
1539   int hosts_count;
1540   int rv;
1541 
1542   ipmi_disable_coredump ();
1543 
1544   prog_data.progname = argv[0];
1545   ipmi_sensors_argp_parse (argc, argv, &cmd_args);
1546   prog_data.args = &cmd_args;
1547 
1548   /* Special case, just output list, don't do anything else */
1549   if (prog_data.args->list_sensor_types)
1550     {
1551       if (list_sensor_types () < 0)
1552         return (EXIT_FAILURE);
1553 
1554       return (EXIT_SUCCESS);
1555     }
1556 
1557   if ((hosts_count = pstdout_setup (&(prog_data.args->common_args.hostname),
1558                                     &(prog_data.args->common_args))) < 0)
1559     return (EXIT_FAILURE);
1560 
1561   if (!hosts_count)
1562     return (EXIT_SUCCESS);
1563 
1564   /* We don't want caching info to output when are doing ranged output */
1565   if (hosts_count > 1)
1566     prog_data.args->common_args.quiet_cache = 1;
1567 
1568   if ((rv = pstdout_launch (prog_data.args->common_args.hostname,
1569                             _ipmi_sensors,
1570                             &prog_data)) < 0)
1571     {
1572       fprintf (stderr,
1573                "pstdout_launch: %s\n",
1574                pstdout_strerror (pstdout_errnum));
1575       return (EXIT_FAILURE);
1576     }
1577 
1578   return (rv);
1579 }
1580