Esempio n. 1
0
/* callback function invoked from OpenIPMI */
static void	got_discrete_states(ipmi_sensor_t *sensor, int err, ipmi_states_t *states, void *cb_data)
{
	const char		*__function_name = "got_discrete_states";
	char			id_str[2 * IPMI_SENSOR_ID_SZ + 1];

	int			id, i, val, ret, is_state_set;
	ipmi_entity_t		*ent;
	zbx_ipmi_host_t		*h = cb_data;
	zbx_ipmi_sensor_t	*s;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	s = get_ipmi_sensor(h, sensor);

	if (NULL == s)
	{
		THIS_SHOULD_NEVER_HAPPEN;
		h->err = zbx_strdup(h->err, "fatal error");
		h->ret = NOTSUPPORTED;
		goto out;
	}

	if (0 != err)
	{
		h->err = zbx_dsprintf(h->err, "error 0x%x while reading a discrete sensor %s@[%s]:%d", err,
				sensor_id_to_str(id_str, sizeof(id_str), s->id, s->id_type, s->id_sz), h->ip, h->port);
		h->ret = NOTSUPPORTED;
		goto out;
	}

	ent = ipmi_sensor_get_entity(sensor);
	id = ipmi_entity_get_entity_id(ent);

	/* Discrete values are 16-bit. We're storing them into a 64-bit uint. */
#define MAX_DISCRETE_STATES	15

	s->value.discrete = 0;
	for (i = 0; i < MAX_DISCRETE_STATES; i++)
	{
		ret = ipmi_sensor_discrete_event_readable(sensor, i, &val);
		if (0 != ret || 0 == val)
			continue;

		is_state_set = ipmi_is_state_set(states, i);

		zabbix_log(LOG_LEVEL_DEBUG, "State [%s | %s | %s | %s | state %d value is %d]",
				sensor_id_to_str(id_str, sizeof(id_str), s->id, s->id_type, s->id_sz),
				ipmi_get_entity_id_string(id), ipmi_sensor_get_sensor_type_string(sensor),
				ipmi_sensor_get_event_reading_type_string(sensor), i, is_state_set);

		if (0 != is_state_set)
			s->value.discrete |= 1 << i;
	}
#undef MAX_DISCRETE_STATES
out:
	h->done = 1;

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(h->ret));
}
Esempio n. 2
0
int
ipmi_sdr_parse_entity_sensor_name (ipmi_sdr_ctx_t ctx,
				   const void *sdr_record,
				   unsigned int sdr_record_len,
				   uint8_t sensor_number,
				   unsigned int flags,
				   char *buf,
				   unsigned int buflen)
{
  char id_string[IPMI_SDR_MAX_ID_STRING_LENGTH + 1];
  char device_id_string[IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH + 1];
  char entity_name_buf[IPMI_SDR_ENTITY_NAME_BUFLEN + 1];
  char *id_string_ptr = NULL;
  uint8_t entity_id, entity_instance, entity_instance_type;
  const char *entity_id_str;
  uint8_t record_type;
  unsigned int flags_mask = (IPMI_SDR_SENSOR_NAME_FLAGS_IGNORE_SHARED_SENSORS
			     | IPMI_SDR_SENSOR_NAME_FLAGS_ALWAYS_OUTPUT_INSTANCE_NUMBER);

  if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
    {
      ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
      return (-1);
    }

  if (ctx->operation != IPMI_SDR_OPERATION_READ_CACHE)
    {
      SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_CACHE_READ_INITIALIZATION);
      return (-1);
    }

  if (((sdr_record_len && !sdr_record_len)
       || (!sdr_record && sdr_record_len))
      || (flags & ~flags_mask)
      || !buf
      || !buflen)
    {
      SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARAMETERS);
      return (-1);
    }

  memset (buf, '\0', buflen);
  memset (entity_name_buf, '\0', IPMI_SDR_ENTITY_NAME_BUFLEN + 1);

  if (ipmi_sdr_parse_record_id_and_type (ctx,
					 sdr_record,
					 sdr_record_len,
                                         NULL,
                                         &record_type) < 0)
    return (-1);

  if (record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD
      || record_type == IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD
      || record_type == IPMI_SDR_FORMAT_EVENT_ONLY_RECORD)
    {
      memset (id_string, '\0', IPMI_SDR_MAX_ID_STRING_LENGTH + 1);

      if (ipmi_sdr_parse_id_string (ctx,
				    sdr_record,
				    sdr_record_len,
				    id_string,
                                    IPMI_SDR_MAX_ID_STRING_LENGTH) < 0)
	return (-1);

      id_string_ptr = id_string;
    }
  else if (record_type == IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD
           || record_type == IPMI_SDR_FORMAT_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD)
    {
      memset (device_id_string, '\0', IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH + 1);

      if (ipmi_sdr_parse_device_id_string (ctx,
					   sdr_record,
					   sdr_record_len,
                                           device_id_string,
                                           IPMI_SDR_MAX_DEVICE_ID_STRING_LENGTH) < 0)
	return (-1);
      
      id_string_ptr = device_id_string;
    }
  else
    {
      SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
      return (-1);
    }

  if (ipmi_sdr_parse_entity_id_instance_type (ctx,
					      sdr_record,
					      sdr_record_len,
                                              &entity_id,
                                              &entity_instance,
                                              &entity_instance_type) < 0)
    return (-1);

  /* Table 39-1
   *
   * "It is recommended that console software subtract 60h when
   * presenting device-relative Entity Instance values, and present
   * the Entity Instance number along with an ID for the device
   * providing the interface to the entity."
   *
   * achu: For the time being we do not output the device providing
   * the interface, only the right instance number.  Adjust later if
   * necessary.
   */

  if (IPMI_ENTITY_INSTANCE_DEVICE_RELATIVE (entity_instance))
    entity_instance -= IPMI_ENTITY_INSTANCE_DEVICE_RELATIVE_MIN;

  entity_id_str = ipmi_get_entity_id_string (entity_id);

  /* a few special cases, for entity_ids are special, the vendor has
   * specifically stated there is no "entity" associated with this sdr
   * record
   */
  if (entity_id == IPMI_ENTITY_ID_UNSPECIFIED
      || entity_id == IPMI_ENTITY_ID_OTHER
      || entity_id == IPMI_ENTITY_ID_UNKNOWN)
    snprintf (buf,
	      buflen,
	      "%s",
	      id_string_ptr);
  else
    {
      if (ipmi_sdr_stats_compile (ctx) < 0)
	return (-1);

      if (ipmi_sdr_stats_entity_instance_unique (ctx, entity_id) > 1)
        {
          /* special case if sensor sharing is involved */
          if ((record_type == IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD
               || record_type == IPMI_SDR_FORMAT_EVENT_ONLY_RECORD)
              && !(flags & IPMI_SDR_SENSOR_NAME_FLAGS_IGNORE_SHARED_SENSORS))
            {
	      uint8_t share_count;
	      uint8_t entity_instance_sharing;
	      char sensor_name_buf[IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1];

	      if (ipmi_sdr_parse_sensor_record_sharing (ctx,
							sdr_record,
							sdr_record_len,
							&share_count,
							NULL,
							NULL,
							&entity_instance_sharing) < 0)
		return (-1);
      
	      if (share_count > 1
		  && entity_instance_sharing == IPMI_SDR_ENTITY_INSTANCE_INCREMENTS_FOR_EACH_SHARED_RECORD)
		{
		  uint8_t sensor_number_base;
      
		  if (ipmi_sdr_parse_sensor_number (ctx,
						    sdr_record,
						    sdr_record_len,
						    &sensor_number_base) < 0)
		    return (-1);
      
		  /* I guess it's a bug if the sensor number passed in is bad */
		  if (sensor_number >= sensor_number_base)
		    entity_instance += (sensor_number - sensor_number_base);
		  else
		    goto fallthrough;
		}

	      memset (sensor_name_buf, '\0', IPMI_SDR_MAX_SENSOR_NAME_LENGTH + 1);
	      
	      if (_get_shared_sensor_name (ctx,
					   sdr_record,
					   sdr_record_len,
					   sensor_number,
					   id_string_ptr,
					   sensor_name_buf,
					   IPMI_SDR_MAX_SENSOR_NAME_LENGTH) < 0)
		return (-1);

	      snprintf (entity_name_buf,
			IPMI_SDR_ENTITY_NAME_BUFLEN,
			"%s %u",
			entity_id_str,
			entity_instance);

	      /* In odd chance the strings end up identical */
	      if (!strcasecmp (entity_name_buf, sensor_name_buf))
		snprintf (buf,
			  buflen,
			  "%s",
			  sensor_name_buf);
	      else
		snprintf (buf,
			  buflen,
			  "%s %s",
			  entity_name_buf,
			  sensor_name_buf);
	    }
	  else
	    {
	    fallthrough:
	      snprintf (entity_name_buf,
			IPMI_SDR_ENTITY_NAME_BUFLEN,
			"%s %u",
			entity_id_str,
			entity_instance);
	      
	      /* In odd chance the strings end up identical */
	      if (!strcasecmp (entity_name_buf, id_string_ptr))
		snprintf (buf,
			  buflen,
			  "%s",
			  id_string_ptr);
	      else
		snprintf (buf,
			  buflen,
			  "%s %s",
			  entity_name_buf,
			  id_string_ptr);
	    }
	}
      else
	{
	  if (flags & IPMI_SDR_SENSOR_NAME_FLAGS_ALWAYS_OUTPUT_INSTANCE_NUMBER)
	    {
	      snprintf (entity_name_buf,
			IPMI_SDR_ENTITY_NAME_BUFLEN,
			"%s %u",
			entity_id_str,
			entity_instance);
	      
	      /* In odd chance the strings end up identical */
	      if (!strcasecmp (entity_name_buf, id_string_ptr))
		snprintf (buf,
			  buflen,
			  "%s",
			  id_string_ptr);
	      else
		snprintf (buf,
			  buflen,
			  "%s %s",
			  entity_name_buf,
			  id_string_ptr);
	    }
	  else
	    {
	      /* In odd chance the strings end up identical */
	      if (!strcasecmp (entity_id_str, id_string_ptr))
		snprintf (buf,
			  buflen,
			  "%s",
			  id_string_ptr);
	      else
		snprintf (buf,
			  buflen,
			  "%s %s",
			  entity_id_str,
			  id_string_ptr);
	    }
	}
    }

  return (0);
}