ipmi_config_err_t
ipmi_config_sensors_seek_to_sdr_record (ipmi_config_state_data_t *state_data,
                                        const char *section_name)
{
  uint16_t record_id;
  char *str = NULL;
  char *ptr;
  char *endptr;
  ipmi_config_err_t rv = IPMI_CONFIG_ERR_FATAL_ERROR;

  assert (state_data);
  assert (section_name);

  if (!(str = strdup (section_name)))
    {
      pstdout_perror (state_data->pstate, "strdup");
      goto cleanup;
    }

  if (!(ptr = strchr (str, '_')))
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "Invalid section_name: %s\n",
                       section_name);
      goto cleanup;
    }

  *ptr = '\0';

  errno = 0;
  record_id = strtoul (str, &endptr,0);
  if (errno
      || endptr[0] != '\0')
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "Invalid section_name: %s\n",
                       section_name);
      goto cleanup;
    }

  if (ipmi_sdr_cache_search_record_id (state_data->sdr_ctx,
                                       record_id) < 0)
    {
      if (state_data->prog_data->args->common_args.debug)
        pstdout_fprintf (state_data->pstate,
                         stderr,
                         "Record_id not found: %u\n",
                         record_id);
      rv = IPMI_CONFIG_ERR_NON_FATAL_ERROR;
      goto cleanup;
    }

  rv = IPMI_CONFIG_ERR_SUCCESS;
 cleanup:
  free (str);
  return (rv);
}
Пример #2
0
static int
_ipmi_oem (pstdout_state_t pstate,
           const char *hostname,
           void *arg)
{
  ipmi_oem_state_data_t state_data;
  ipmi_oem_prog_data_t *prog_data;
  int exit_code = EXIT_FAILURE;

  assert (pstate);
  assert (arg);

  prog_data = (ipmi_oem_prog_data_t *)arg;

  if (prog_data->args->common_args.flush_cache)
    {
      if (sdr_cache_flush_cache (pstate,
                                 hostname,
                                 &prog_data->args->common_args) < 0)
	return (EXIT_FAILURE);
      return (EXIT_SUCCESS);
    }

  memset (&state_data, '\0', sizeof (ipmi_oem_state_data_t));
  state_data.prog_data = prog_data;
  state_data.pstate = pstate;
  state_data.hostname = (char *)hostname;

  /* Special case, we're going to output help info, don't do an IPMI connection */
  if (prog_data->args->oem_command)
    {
      if (!(state_data.ipmi_ctx = ipmi_open (prog_data->progname,
					     hostname,
					     &(prog_data->args->common_args),
					     state_data.pstate)))
	goto cleanup;
    }

  if (!(state_data.sdr_ctx = ipmi_sdr_ctx_create ()))
    {
      pstdout_perror (pstate, "ipmi_sdr_ctx_create()");
      goto cleanup;
    }

  if (run_cmd_args (&state_data) < 0)
    goto cleanup;
  
  exit_code = EXIT_SUCCESS;
 cleanup:
  ipmi_sdr_ctx_destroy (state_data.sdr_ctx);
  ipmi_ctx_close (state_data.ipmi_ctx);
  ipmi_ctx_destroy (state_data.ipmi_ctx);
  return (exit_code);
}
Пример #3
0
int
ipmi_oem_check_response_and_completion_code (ipmi_oem_state_data_t *state_data,
                                             uint8_t *bytes_rs,
                                             unsigned int bytes_rs_len,
                                             unsigned int expected_bytes_rs_len,
                                             uint8_t cmd,
                                             uint8_t netfn)
{
  assert (state_data);
  assert (bytes_rs);

  if (bytes_rs_len < expected_bytes_rs_len)
    {
      if (bytes_rs_len >= 2 && bytes_rs[1] != IPMI_COMP_CODE_COMMAND_SUCCESS)
        goto output_comp_code_error;

      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid response length: %u, expected %u\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       bytes_rs_len,
                       expected_bytes_rs_len);
      return (-1);
    }

 output_comp_code_error:  
  if (bytes_rs[1] != IPMI_COMP_CODE_COMMAND_SUCCESS)
    {
      char errbuf[IPMI_OEM_ERR_BUFLEN];
      
      memset (errbuf, '\0', IPMI_OEM_ERR_BUFLEN);
      if (ipmi_completion_code_strerror_r (cmd, /* cmd */
                                           netfn, /* network function */
                                           bytes_rs[1], /* completion code */
                                           errbuf,
                                           IPMI_OEM_ERR_BUFLEN) < 0)
        {
          pstdout_perror (state_data->pstate, "ipmi_completion_code_strerror_r");
          snprintf (errbuf, IPMI_OEM_ERR_BUFLEN, "completion-code = 0x%X", bytes_rs[1]);
        }
      
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s failed: %s\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       errbuf);
      return (-1);
    }

  return (0);
}
Пример #4
0
int 
ipmi_oem_parse_key_value (ipmi_oem_state_data_t *state_data,
                          unsigned int option_num,
                          char **key,
                          char **value)
{  
  char *tempstr = NULL;
  char *tempptr = NULL;
  char *tempkey = NULL;
  char *tempvalue = NULL;
  int rv = -1;
   
  assert (state_data);
  assert (key);
  assert (value);
   
  if (!(tempstr = strdup (state_data->prog_data->args->oem_options[option_num])))
    {
      pstdout_perror (state_data->pstate, "strdup");
      goto cleanup;
    }
   
  tempptr = strchr (tempstr, '=');
  if (!tempptr)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "%s:%s invalid OEM option argument '%s' : no equal sign\n",
                       state_data->prog_data->args->oem_id,
                       state_data->prog_data->args->oem_command,
                       state_data->prog_data->args->oem_options[option_num]);
      goto cleanup;
    }

  (*tempptr) = '\0'; 
  tempptr++;

  if (!(tempkey = strdup (tempstr)))
    {
      pstdout_perror (state_data->pstate, "strdup");
      goto cleanup;
    }

  if (!(tempvalue = strdup (tempptr)))
    {
      pstdout_perror (state_data->pstate, "strdup");
      goto cleanup; 
    }
  
  (*key) = tempkey;
  (*value) = tempvalue;
  
  rv = 0;
 cleanup:
  free (tempstr);
  if (rv < 0)
    {
      free (tempkey);
      free (tempvalue);
    }
  return (rv);
}
struct config_section *
pef_config_alert_policy_table_section_get (pef_config_state_data_t *state_data, int num)
{
  struct config_section *section = NULL;
  uint8_t lan_channel_number;
  char *strp = NULL;
  config_err_t ret;
  char buf[CONFIG_MAX_SECTION_NAME_LEN];

  if (num <= 0)
    {
      pstdout_fprintf(state_data->pstate,
                      stderr, 
                      "Invalid Num = %d\n",
                      num);
      return NULL;
    }

  snprintf(buf, CONFIG_MAX_SECTION_NAME_LEN, "Alert_Policy_%d", num);

  if (!(section = config_section_create (state_data->pstate, 
                                         buf, 
                                         NULL, 
                                         NULL, 
                                         0,
                                         NULL,
                                         NULL)))
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Policy_Type",
                              "Possible values: Always_Send_To_This_Destination/Proceed_To_Next_Entry/Do_Not_Proceed_Any_More_Entries/Proceed_To_Next_Entry_Different_Channel/Proceed_To_Next_Entry_Different_Destination_Type",
                              0,
                              policy_type_checkout,
                              policy_type_commit,
                              policy_type_validate) < 0) 
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Policy_Enabled",
                              "Possible values: Yes/No",
                              0,
                              policy_enabled_checkout,
                              policy_enabled_commit,
                              config_yes_no_validate) < 0) 
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Policy_Number",
                              "Give a valid number",
                              0,
                              policy_number_checkout,
                              policy_number_commit,
                              config_number_range_four_bits) < 0) 
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Destination_Selector",
                              "Give a valid number",
                              0,
                              destination_selector_checkout,
                              destination_selector_commit,
                              config_number_range_four_bits) < 0) 
    goto cleanup;

  ret = get_lan_channel_number (state_data, &lan_channel_number);
  if (ret == CONFIG_ERR_SUCCESS)
    {
      if (asprintf(&strp, 
                   "Give a valid number (LAN = %u)", 
                   lan_channel_number) < 0)
        {
          if (!strp)
            {
              pstdout_perror(state_data->pstate,
                             "asprintf");
              goto cleanup;
            }
        }
    }
  else
    {
      if (!(strp = strdup("Give a valid number")))
        {
          pstdout_perror(state_data->pstate,
                         "strdup");
          goto cleanup;
        }
    }

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Channel_Number",
                              strp,
                              0,
                              channel_number_checkout,
                              channel_number_commit,
                              config_number_range_four_bits) < 0) 
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Alert_String_Set_Selector",
                              "Give a valid number",
                              0,
                              alert_string_set_selector_checkout,
                              alert_string_set_selector_commit,
                              config_number_range_seven_bits) < 0) 
    goto cleanup;

  if (config_section_add_key (state_data->pstate, 
                              section,
                              "Event_Specific_Alert_String",
                              "Possible values: Yes/No",
                              0,
                              event_specific_alert_string_checkout,
                              event_specific_alert_string_commit,
                              config_yes_no_validate) < 0) 
    goto cleanup;

  if (strp)
    free(strp);
  return section;

 cleanup:
  if (strp)
    free(strp);
  if (section)
    config_section_destroy(state_data->pstate, section);
  return NULL;
}
Пример #6
0
static int
_find_sensor (ipmi_oem_state_data_t *state_data,
              uint8_t sensor_number,
              char *id_string,
              unsigned int id_string_len)
{
  struct ipmi_oem_ibm_find_sensor_sdr_callback sdr_callback_arg;
  struct common_cmd_args common_args;
  ipmi_sdr_ctx_t tmp_sdr_ctx = NULL;
  int rv = -1;

  assert (state_data);
  assert (id_string);
  assert (id_string_len);

  /* Make temporary sdr cache to search for sensor
   *
   * Redo loading of SDR cache since this is being called from a loop
   * using the state_data sdr_ctx.
   */
  if (!(tmp_sdr_ctx = ipmi_sdr_ctx_create ()))
    {
      pstdout_perror (state_data->pstate, "ipmi_sdr_ctx_create()");
      goto cleanup;
    }

  sdr_callback_arg.state_data = state_data;
  sdr_callback_arg.sensor_number = sensor_number;
  sdr_callback_arg.id_string = id_string;
  sdr_callback_arg.id_string_len = id_string_len;
  sdr_callback_arg.found = 0;

  /* Should not cause sdr recreation, since this is the second time we're calling it */
  memcpy (&common_args, &state_data->prog_data->args->common_args, sizeof (struct common_cmd_args));
  common_args.quiet_cache = 1;
  common_args.sdr_cache_recreate = 0;

  if (sdr_cache_create_and_load (tmp_sdr_ctx,
                                 state_data->pstate,
                                 state_data->ipmi_ctx,
                                 state_data->hostname,
				 &common_args) < 0)
    goto cleanup;

  if (ipmi_sdr_cache_iterate (tmp_sdr_ctx,
			      _find_sensor_sdr_callback,
			      &sdr_callback_arg) < 0)
    {
      pstdout_fprintf (state_data->pstate,
		       stderr,
		       "ipmi_sdr_cache_iterate: %s\n",
		       ipmi_sdr_ctx_errormsg (state_data->sdr_ctx));
      goto cleanup;
    }

  if (!sdr_callback_arg.found)
    snprintf (id_string,
              id_string_len,
              "Sensor Number = %02Xh",
              sensor_number);
  rv = 0;
 cleanup:
  ipmi_sdr_ctx_destroy (tmp_sdr_ctx);
  return (rv);
}
Пример #7
0
int
ipmi_oem_fujitsu_get_system_status (ipmi_oem_state_data_t *state_data)
{
  uint8_t bytes_rq[IPMI_OEM_MAX_BYTES];
  uint8_t bytes_rs[IPMI_OEM_MAX_BYTES];
  uint8_t system_status;
  uint8_t signaling;
  uint8_t post_code;
  uint8_t system_power;
  uint8_t sel_entries_available;
  uint8_t watchdog_active;
  uint8_t agent_connected;
  uint8_t post_state;
  uint8_t identify_led;            /* rename from "localize" */
  uint8_t css_led;
  uint8_t global_error_led;
  char *css_led_str = NULL;
  char *global_error_led_str = NULL;
  struct timeval t;
  int rs_len;
  int rv = -1;

  assert (state_data);
  assert (!state_data->prog_data->args->oem_options_count);

  /* Fujitsu OEM
   * 
   * http://manuals.ts.fujitsu.com/file/4390/irmc_s2-en.pdf
   *
   * Request
   *
   * 0x2E - OEM network function
   * 0xF5 - OEM cmd
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x10 - Command Specifier
   * 0x?? - timestamp (LSB first)
   * 0x?? - timestamp
   * 0x?? - timestamp
   * 0x?? - timestamp
   *
   * Response
   *
   * 0xF5 - OEM cmd
   * 0x?? - Completion code
   * 0x?? - Fujitsu IANA (LSB first)
   * 0x?? - Fujitsu IANA
   * 0x?? - Fujitsu IANA
   * 0x?? - System Status
   *      bit 7 - System ON
   *      bit 6 - 
   *      bit 5 - 
   *      bit 4 - SEL entries available
   *      bit 3 - 
   *      bit 2 - Watchdog active
   *      bit 1 - Agent connected
   *      bit 0 - Post State
   * 0x?? - Signaling
   *      bit 7 - Identify LED (sometimes refered as "Localize")
   *      bit 6 - 
   *      bit 5 - 
   *      bit 4 - 
   *      bit 3 - CSS LED (Customer Self Service LED)
   *      bit 2 - CSS LED (Customer Self Service LED)
   *      bit 1 - Global Error LED
   *      bit 0 - Global Error LED
   * 0x?? - Notifications
   *      bit 7 - SEL Modified (New SEL Entry)
   *      bit 6 - SEL Modified (SEL Cleared)
   *      bit 5 - SDR Modified
   *      bit 4 - Nonvolatile IPMI Variable Modified
   *      bit 3 - ConfigSpace Modified
   *      bit 2 - 
   *      bit 1 - 
   *      bit 0 - New Output on LocalView display
   * 0x?? - Last POST Code (Port 80) (HLiebig: renamed from "Post Code" in doc)
   *
   * achu: Docs say "timestamp is only relevant for evaluating the
   * Notifications Byte".  I assume this is because the Notifications
   * timestamp indicates if things have changed in the SEL/SDR.
   */
  
  if (gettimeofday (&t, NULL) < 0)
    {
      pstdout_perror (state_data->pstate, "gettimeofday");
      goto cleanup;
    }

  bytes_rq[0] = IPMI_CMD_OEM_FUJITSU_SYSTEM;
  bytes_rq[1] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x0000FF);
  bytes_rq[2] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0x00FF00) >> 8;
  bytes_rq[3] = (IPMI_IANA_ENTERPRISE_ID_FUJITSU & 0xFF0000) >> 16;
  bytes_rq[4] = IPMI_OEM_FUJITSU_COMMAND_SPECIFIER_GET_SYSTEM_STATUS;
  bytes_rq[5] = (t.tv_sec & 0x000000FF);
  bytes_rq[6] = (t.tv_sec & 0x0000FF00) >> 8;
  bytes_rq[7] = (t.tv_sec & 0x00FF0000) >> 16;
  bytes_rq[8] = (t.tv_sec & 0xFF000000) >> 24;

  if ((rs_len = ipmi_cmd_raw (state_data->ipmi_ctx,
                              0, /* lun */
                              IPMI_NET_FN_OEM_GROUP_RQ, /* network function */
                              bytes_rq, /* data */
                              9, /* num bytes */
                              bytes_rs,
                              IPMI_OEM_MAX_BYTES)) < 0)
    {
      pstdout_fprintf (state_data->pstate,
                       stderr,
                       "ipmi_cmd_raw: %s\n",
                       ipmi_ctx_errormsg (state_data->ipmi_ctx));
      goto cleanup;
    }
  
  if (ipmi_oem_check_response_and_completion_code (state_data,
                                                   bytes_rs,
                                                   rs_len,
                                                   9,
                                                   IPMI_CMD_OEM_FUJITSU_SYSTEM,
                                                   IPMI_NET_FN_OEM_GROUP_RS,
                                                   NULL) < 0)
    goto cleanup;

  /* achu: the "Notifications" are dependent on the timestamp input,
   * we won't bother outputting them
   */
  
  system_status = bytes_rs[5];
  signaling = bytes_rs[6];
  post_code = bytes_rs[8];

  system_power = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SYSTEM_POWER_BITMASK);
  system_power >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SYSTEM_POWER_SHIFT;

  sel_entries_available = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SEL_ENTRIES_AVAILABLE_BITMASK);
  sel_entries_available >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SEL_ENTRIES_AVAILABLE_SHIFT;

  watchdog_active = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_WATCHDOG_ACTIVE_BITMASK);
  watchdog_active >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_WATCHDOG_ACTIVE_SHIFT;

  agent_connected = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_AGENT_CONNECTED_BITMASK);
  agent_connected >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_AGENT_CONNECTED_SHIFT;

  post_state = (system_status & IPMI_OEM_FUJITSU_SYSTEM_STATUS_POST_STATE_BITMASK);
  post_state >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_POST_STATE_SHIFT;

  identify_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_LOCAL_LED_BITMASK);
  identify_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_LOCAL_LED_SHIFT;

  css_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_CSS_LED_BITMASK);
  css_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_CSS_LED_SHIFT;
  
  global_error_led = (signaling & IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_GLOBAL_ERROR_LED_BITMASK);
  global_error_led >>= IPMI_OEM_FUJITSU_SYSTEM_STATUS_SIGNALING_GLOBAL_ERROR_LED_SHIFT;

  pstdout_printf (state_data->pstate,
                  "System Power             : %s\n",
                  system_power ? "On" : "Off");

  pstdout_printf (state_data->pstate,
                  "SEL Entries Available    : %s\n",
                  sel_entries_available ? "Yes" : "No");

  pstdout_printf (state_data->pstate,
                  "Watchdog Active          : %s\n",
                  watchdog_active ? "Yes" : "No");

  pstdout_printf (state_data->pstate,
                  "Agent Connected          : %s\n",
                  agent_connected ? "Yes" : "No");

  /* HLiebig: renamed from "Post State" in doc */
  pstdout_printf (state_data->pstate,
                  "System in POST           : %s\n",
                  post_state ? "Yes" : "No");

  pstdout_printf (state_data->pstate,
                  "Identify LED             : %s\n",
                  identify_led ? "On" : "Off");

  switch (css_led)
    {
    case IPMI_OEM_FUJITSU_CSS_LED_OFF:
      css_led_str = "Off";
      break;
    case IPMI_OEM_FUJITSU_CSS_LED_ON:
      css_led_str = "On";
      break;
    case IPMI_OEM_FUJITSU_CSS_LED_BLINK:
      css_led_str = "Blink";
      break;
    default:
      css_led_str = "Unknown LED State";
    }

  pstdout_printf (state_data->pstate,
                  "CSS LED                  : %s\n",
                  css_led_str);
  
  switch (global_error_led)
    {
    case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_OFF:
      global_error_led_str = "Off";
      break;
    case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_ON:
      global_error_led_str = "On";
      break;
    case IPMI_OEM_FUJITSU_GLOBAL_ERROR_LED_BLINK:
      global_error_led_str = "Blink";
      break;
    default:
      global_error_led_str = "Unknown LED State";
    }

  pstdout_printf (state_data->pstate,
                  "Global Error LED         : %s\n",
                  global_error_led_str);

  /* HLiebig: renamed from "Post Code" in doc */
  pstdout_printf (state_data->pstate,
                  "Last POST Code (Port 80) : %02Xh\n",
                  post_code);

  rv = 0;
 cleanup:
  return (rv);
}
int
ipmi_sensors_get_thresholds (ipmi_sensors_state_data_t *state_data,
                             uint8_t *sdr_record,
                             unsigned int sdr_record_len,
                             double **lower_non_critical_threshold,
                             double **lower_critical_threshold,
                             double **lower_non_recoverable_threshold,
                             double **upper_non_critical_threshold,
                             double **upper_critical_threshold,
                             double **upper_non_recoverable_threshold)
{
  int8_t r_exponent, b_exponent;
  int16_t m, b;
  uint8_t linearization, analog_data_format;
  uint8_t sensor_number;
  fiid_obj_t obj_cmd_rs = NULL;
  double *tmp_lower_non_critical_threshold = NULL;
  double *tmp_lower_critical_threshold = NULL;
  double *tmp_lower_non_recoverable_threshold = NULL;
  double *tmp_upper_non_critical_threshold = NULL;
  double *tmp_upper_critical_threshold = NULL;
  double *tmp_upper_non_recoverable_threshold = NULL;
  double threshold;
  uint8_t threshold_access_support;
  uint64_t val;
  int rv = -1;

  assert(state_data);
  assert(sdr_record);
  assert(sdr_record_len);

  if (lower_non_critical_threshold)
    *lower_non_critical_threshold = NULL;
  if (lower_critical_threshold)
    *lower_critical_threshold = NULL;
  if (lower_non_recoverable_threshold)
    *lower_non_recoverable_threshold = NULL;
  if (upper_non_critical_threshold)
    *upper_non_critical_threshold = NULL;
  if (upper_critical_threshold)
    *upper_critical_threshold = NULL;
  if (upper_non_recoverable_threshold)
    *upper_non_recoverable_threshold = NULL;

  /* achu: first lets check if we have anything to output */
  if (sdr_cache_get_sensor_capabilities (state_data->pstate,
                                         sdr_record,
                                         sdr_record_len,
                                         NULL,
                                         &threshold_access_support,
                                         NULL,
                                         NULL,
                                         NULL) < 0)
    goto cleanup;

  if (threshold_access_support == IPMI_SDR_NO_THRESHOLDS_SUPPORT
      || threshold_access_support == IPMI_SDR_FIXED_UNREADABLE_THRESHOLDS_SUPPORT)
    {
      rv = 0;
      goto cleanup;
    }

  /* achu:
   *
   * I will admit I'm not entirely sure what the best way is
   * to get thresholds.  It seems the information is
   * stored/retrievable in the SDR and through an IPMI command.
   *
   * Since the readable_threshold_mask in the SDR record indicates the
   * mask is for the "Get Sensor Thresholds" command, it suggests the
   * best/right way is to get the values via that command.  Sounds
   * good to me.  Also, I suppose its possible that changes to the
   * thresholds may not be written to the SDR.
   *
   * Also, because the results from the get_sensor_thresholds include
   * readability flags, we can ignore the readability flags in the
   * SDR.
   * 
   */

  if (sdr_cache_get_sensor_number (state_data->pstate,
                                   sdr_record,
                                   sdr_record_len,
                                   &sensor_number) < 0)
    goto cleanup;

  if (sdr_cache_get_sensor_decoding_data(state_data->pstate,
                                         sdr_record,
                                         sdr_record_len,
                                         &r_exponent,
                                         &b_exponent,
                                         &m,
                                         &b,
                                         &linearization,
                                         &analog_data_format) < 0)
    goto cleanup;

  /* if the sensor is not analog, this is most likely a bug in the
   * SDR, since we shouldn't be decoding a non-threshold sensor.
   *
   * Don't return an error.  Allow code to output "NA" or something.
   */
  if (!IPMI_SDR_ANALOG_DATA_FORMAT_VALID(analog_data_format))
    {
      if (state_data->prog_data->args->common.debug)
        pstdout_fprintf(state_data->pstate,
                        stderr,
                        "Attempting to decode non-analog sensor\n");
      rv = 0;
      goto cleanup;
    }

  /* if the sensor is non-linear, I just don't know what to do 
   *
   * Don't return an error.  Allow code to output "NA" or something.
   */
  if (!IPMI_SDR_LINEARIZATION_IS_LINEAR(linearization))
    {
      if (state_data->prog_data->args->common.debug)
        pstdout_fprintf(state_data->pstate,
                        stderr,
                        "Cannot decode non-linear sensor\n");
      rv = 0;
      goto cleanup;
    }
  
  _FIID_OBJ_CREATE(obj_cmd_rs, tmpl_cmd_get_sensor_thresholds_rs);

  if (ipmi_cmd_get_sensor_thresholds (state_data->ipmi_ctx,
                                      sensor_number,
                                      obj_cmd_rs) < 0)
    {
      if (state_data->prog_data->args->common.debug)
        pstdout_fprintf(state_data->pstate,
                        stderr,
                        "ipmi_cmd_get_sensor_thresholds: %s\n",
                        ipmi_ctx_strerror(ipmi_ctx_errnum(state_data->ipmi_ctx)));
      if ((ipmi_ctx_errnum(state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE_REQUEST_DATA_INVALID)
          && (ipmi_check_completion_code(obj_cmd_rs, 
                                         IPMI_COMP_CODE_COMMAND_ILLEGAL_FOR_SENSOR_OR_RECORD_TYPE) == 1
              || ipmi_check_completion_code(obj_cmd_rs,
                                            IPMI_COMP_CODE_REQUEST_SENSOR_DATA_OR_RECORD_NOT_PRESENT) == 1))
        {
          /* The thresholds cannot be gathered for one reason or
           * another, maybe b/c its a OEM sensor or something.  We can
           * return 0 gracefully.
           */
          rv = 0;
          goto cleanup;
        }

      /* 
       * IPMI Workaround (achu)
       *
       * Discovered on HP DL585
       *
       * Seems that the HP machine doesn't support the "Get Sensor
       * Thresholds" command.  When this occurs, we assume the
       * information in the SDR is legit and up to date.  Go get it
       * and fill in the object respectively.
       */
      if ((ipmi_ctx_errnum(state_data->ipmi_ctx) == IPMI_ERR_BAD_COMPLETION_CODE_INVALID_COMMAND)
          && (ipmi_check_completion_code(obj_cmd_rs, IPMI_COMP_CODE_COMMAND_INVALID) == 1))
        {
          if (state_data->prog_data->args->common.debug)
            pstdout_fprintf(state_data->pstate,
                            stderr,
                            "Get Sensor Thresholds failed, using SDR information\n");

          if (_get_sdr_sensor_thresholds (state_data,
                                          sdr_record,
                                          sdr_record_len,
                                          obj_cmd_rs) < 0)
            goto cleanup;

          goto continue_get_sensor_thresholds;
        }

      goto cleanup;
    } 

 continue_get_sensor_thresholds:

  if (lower_non_critical_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.lower_non_critical_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "lower_non_critical_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_lower_non_critical_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_lower_non_critical_threshold = threshold;
        }
    }
  if (lower_critical_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.lower_critical_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "lower_critical_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_lower_critical_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_lower_critical_threshold = threshold;
        }
    }
  if (lower_non_recoverable_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.lower_non_recoverable_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "lower_non_recoverable_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_lower_non_recoverable_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_lower_non_recoverable_threshold = threshold;
        }
    }
  if (upper_non_critical_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.upper_non_critical_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "upper_non_critical_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_upper_non_critical_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_upper_non_critical_threshold = threshold;
        }
    }
  if (upper_critical_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.upper_critical_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "upper_critical_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_upper_critical_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_upper_critical_threshold = threshold;
        }
    }
  if (upper_non_recoverable_threshold)
    {
      _FIID_OBJ_GET (obj_cmd_rs,
                     "readable_thresholds.upper_non_recoverable_threshold",
                     &val);
      if (val)
        {
          _FIID_OBJ_GET(obj_cmd_rs,
                        "upper_non_recoverable_threshold",
                        &val);

          if (ipmi_sensor_decode_value (r_exponent,
                                        b_exponent,
                                        m,
                                        b,
                                        linearization,
                                        analog_data_format,
                                        val,
                                        &threshold) < 0)
            {
              pstdout_fprintf (state_data->pstate,
                               stderr,
                               "ipmi_sensor_decode_value: %s\n",
                               strerror(errno));
              goto cleanup;
            }

          if (!(tmp_upper_non_recoverable_threshold = (double *)malloc(sizeof(double))))
            {
              pstdout_perror(state_data->pstate, "malloc");
              goto cleanup;
            }
          *tmp_upper_non_recoverable_threshold = threshold;
        }
    }

  if (lower_non_critical_threshold)
    *lower_non_critical_threshold = tmp_lower_non_critical_threshold;
  if (lower_critical_threshold)
    *lower_critical_threshold = tmp_lower_critical_threshold;
  if (lower_non_recoverable_threshold)
    *lower_non_recoverable_threshold = tmp_lower_non_recoverable_threshold;
  if (upper_non_critical_threshold)
    *upper_non_critical_threshold = tmp_upper_non_critical_threshold;
  if (upper_critical_threshold)
    *upper_critical_threshold = tmp_upper_critical_threshold;
  if (upper_non_recoverable_threshold)
    *upper_non_recoverable_threshold = tmp_upper_non_recoverable_threshold;

  rv = 0;
 cleanup:
  _FIID_OBJ_DESTROY(obj_cmd_rs);
  if (rv < 0)
    {
      if (tmp_lower_non_critical_threshold)
        free(tmp_lower_non_critical_threshold);
      if (tmp_lower_critical_threshold)
        free(tmp_lower_critical_threshold);
      if (tmp_lower_non_recoverable_threshold)
        free(tmp_lower_non_recoverable_threshold);
      if (tmp_upper_non_critical_threshold)
        free(tmp_upper_non_critical_threshold);
      if (tmp_upper_critical_threshold)
        free(tmp_upper_critical_threshold);
      if (tmp_upper_non_recoverable_threshold)
        free(tmp_upper_non_recoverable_threshold);
    }
  return rv;
}
Пример #9
0
static int
_ipmi_sensors_config (pstdout_state_t pstate,
                      const char *hostname,
                      void *arg)
{
    ipmi_sensors_config_state_data_t state_data;
    ipmi_sensors_config_prog_data_t *prog_data;
    int exit_code = EXIT_FAILURE;
    config_err_t ret = 0;
    int file_opened = 0;
    FILE *fp = NULL;              /* init NULL to remove warnings */

    assert (pstate);
    assert (arg);

    prog_data = (ipmi_sensors_config_prog_data_t *) arg;

    if (prog_data->args->config_args.common_args.flush_cache)
    {
        if (sdr_cache_flush_cache (pstate,
                                   hostname,
                                   &prog_data->args->config_args.common_args) < 0)
            return (EXIT_FAILURE);
        return (EXIT_SUCCESS);
    }

    memset (&state_data, '\0', sizeof (ipmi_sensors_config_state_data_t));
    state_data.prog_data = prog_data;
    state_data.pstate = pstate;

    if (!(state_data.ipmi_ctx = ipmi_open (prog_data->progname,
                                           hostname,
                                           &(prog_data->args->config_args.common_args),
                                           state_data.pstate)))
        goto cleanup;

    if (!(state_data.sdr_ctx = ipmi_sdr_ctx_create ()))
    {
        pstdout_perror (pstate, "ipmi_sdr_ctx_create()");
        goto cleanup;
    }

    if (sdr_cache_create_and_load (state_data.sdr_ctx,
                                   NULL,
                                   state_data.ipmi_ctx,
                                   hostname,
                                   &state_data.prog_data->args->config_args.common_args) < 0)
        goto cleanup;

    if (!(state_data.sections = ipmi_sensors_config_sections_create (&state_data)))
        goto cleanup;

    if (prog_data->args->config_args.action == CONFIG_ACTION_CHECKOUT)
    {
        if (prog_data->args->config_args.filename)
        {
            if (prog_data->hosts_count > 1)
            {
                pstdout_fprintf (pstate,
                                 stderr,
                                 "Cannot output multiple host checkout into a single file\n");
                goto cleanup;
            }

            if (!(fp = fopen (prog_data->args->config_args.filename, "w")))
            {
                pstdout_perror (pstate, "fopen");
                goto cleanup;
            }
            file_opened++;
        }
        else
            fp = stdout;
    }
    else if (prog_data->args->config_args.action == CONFIG_ACTION_COMMIT
             || prog_data->args->config_args.action == CONFIG_ACTION_DIFF)
    {
        if (prog_data->args->config_args.filename
                && strcmp (prog_data->args->config_args.filename, "-"))
        {
            if (!(fp = fopen (prog_data->args->config_args.filename, "r")))
            {
                pstdout_perror (pstate, "fopen");
                goto cleanup;
            }
            file_opened++;
        }
        else
            fp = stdin;
    }

    /* parse if there is an input file or no pairs at all */
    if ((prog_data->args->config_args.action == CONFIG_ACTION_COMMIT
            && prog_data->args->config_args.filename)
            || (prog_data->args->config_args.action == CONFIG_ACTION_COMMIT
                && !prog_data->args->config_args.filename
                && !prog_data->args->config_args.keypairs)
            || (prog_data->args->config_args.action == CONFIG_ACTION_DIFF
                && prog_data->args->config_args.filename)
            || (prog_data->args->config_args.action == CONFIG_ACTION_DIFF
                && !prog_data->args->config_args.filename
                && !prog_data->args->config_args.keypairs))
    {
        if (config_parse (pstate,
                          state_data.sections,
                          &(prog_data->args->config_args),
                          fp) < 0)
        {
            /* errors printed in function call */
            goto cleanup;
        }
    }

    /* note: argp validation catches if user specified keypair and
       filename for a diff
    */
    if ((prog_data->args->config_args.action == CONFIG_ACTION_CHECKOUT
            || prog_data->args->config_args.action == CONFIG_ACTION_COMMIT
            || prog_data->args->config_args.action == CONFIG_ACTION_DIFF)
            && prog_data->args->config_args.keypairs)
    {
        if (config_sections_insert_keyvalues (pstate,
                                              state_data.sections,
                                              prog_data->args->config_args.keypairs) < 0)
        {
            /* errors printed in function call */
            goto cleanup;
        }
    }

    if (prog_data->args->config_args.action == CONFIG_ACTION_COMMIT
            || prog_data->args->config_args.action == CONFIG_ACTION_DIFF)
    {
        int num;

        if ((num = config_sections_validate_keyvalue_inputs (pstate,
                   state_data.sections,
                   &state_data)) < 0)
            goto cleanup;

        /* some errors found */
        if (num)
            goto cleanup;
    }

    if (prog_data->args->config_args.action == CONFIG_ACTION_CHECKOUT
            && prog_data->args->config_args.section_strs)
    {
        struct config_section_str *sstr;

        sstr = prog_data->args->config_args.section_strs;
        while (sstr)
        {
            if (!config_find_section (state_data.sections,
                                      sstr->section_name))
            {
                pstdout_fprintf (pstate,
                                 stderr,
                                 "Unknown section `%s'\n",
                                 sstr->section_name);
                goto cleanup;
            }
            sstr = sstr->next;
        }
    }

    switch (prog_data->args->config_args.action)
    {
    case CONFIG_ACTION_CHECKOUT:
        if (prog_data->args->config_args.section_strs)
        {
            struct config_section_str *sstr;

            /* note: argp validation catches if user specified --section
             * and --keypair, so all_keys_if_none_specified should be '1'.
             */

            sstr = prog_data->args->config_args.section_strs;
            while (sstr)
            {
                struct config_section *s;
                config_err_t this_ret;

                if (!(s = config_find_section (state_data.sections,
                                               sstr->section_name)))
                {
                    pstdout_fprintf (pstate,
                                     stderr,
                                     "## FATAL: Cannot checkout section '%s'\n",
                                     sstr->section_name);
                    continue;
                }

                this_ret = config_checkout_section (pstate,
                                                    s,
                                                    &(prog_data->args->config_args),
                                                    1,
                                                    fp,
                                                    75,
                                                    &state_data);
                if (this_ret != CONFIG_ERR_SUCCESS)
                    ret = this_ret;
                if (ret == CONFIG_ERR_FATAL_ERROR)
                    break;

                sstr = sstr->next;
            }
        }
        else
        {
            int all_keys_if_none_specified = 0;

            if (!prog_data->args->config_args.keypairs)
                all_keys_if_none_specified++;

            ret = config_checkout (pstate,
                                   state_data.sections,
                                   &(prog_data->args->config_args),
                                   all_keys_if_none_specified,
                                   fp,
                                   75,
                                   &state_data);
        }
        break;
    case CONFIG_ACTION_COMMIT:
        ret = config_commit (pstate,
                             state_data.sections,
                             &(prog_data->args->config_args),
                             &state_data);
        break;
    case CONFIG_ACTION_DIFF:
        ret = config_diff (pstate,
                           state_data.sections,
                           &(prog_data->args->config_args),
                           &state_data);
        break;
    case CONFIG_ACTION_LIST_SECTIONS:
        ret = config_output_sections_list (pstate, state_data.sections);
        break;
    }

    if (ret == CONFIG_ERR_FATAL_ERROR)
    {
        exit_code = CONFIG_FATAL_EXIT_VALUE;
        goto cleanup;
    }

    if (ret == CONFIG_ERR_NON_FATAL_ERROR)
    {
        exit_code = CONFIG_NON_FATAL_EXIT_VALUE;
        goto cleanup;
    }

    exit_code = EXIT_SUCCESS;
cleanup:
    ipmi_sdr_ctx_destroy (state_data.sdr_ctx);
    ipmi_ctx_close (state_data.ipmi_ctx);
    ipmi_ctx_destroy (state_data.ipmi_ctx);
    config_sections_destroy (state_data.sections);
    if (file_opened)
        fclose (fp);
    return (exit_code);
}