Ejemplo n.º 1
0
int get_errorcount(const char *disk, hd_health *hdh) {
  int ret = -1;
  SkDisk *skdisk;

  if (sk_disk_open(disk, &skdisk) < 0) {
    fprintf(stderr, "Failed to open disk %s: %s(%d)\n", disk, strerror(errno), errno);
    return -1;
  }

  if (sk_disk_smart_read_data(skdisk) < 0) {
    fprintf(stderr, "Failed to read SMART data %s: %s(%d)\n", disk, strerror(errno), errno);
    goto done;
  }

  if (sk_disk_smart_parse_attributes(skdisk, (SkSmartAttributeParseCallback) get_errorcount_cb, &hdh->error_count) < 0) {
    fprintf(stderr, "Failed to get attribute: %s(%d)\n", strerror(errno), errno);
    goto done;
  }
  ret = 0;

done:
  sk_disk_free(skdisk);

  return ret;
}
Ejemplo n.º 2
0
AtasmartSensorDriver::AtasmartSensorDriver(string device_path)
: SensorDriver(device_path)
{
	if (sk_disk_open(device_path.c_str(), &disk_) < 0) {
		string msg = std::strerror(errno);
		throw SystemError("sk_disk_open(" + device_path + "): " + msg);
	}
	set_num_temps(1);
}
Ejemplo n.º 3
0
int get_hd_health(const char *disk, hd_health *hdh) {
  int ret = -1;
  SkDisk *skdisk;
  SkBool smart_available = 0;
  uint64_t disk_temp = 0;
  uint64_t disk_ontime = 0;

  if (sk_disk_open(disk, &skdisk) < 0) {
    fprintf(stderr, "Failed to open disk %s: %s(%d)\n", disk, strerror(errno), errno);
    return -1;
  }

  if (sk_disk_smart_is_available(skdisk, &smart_available) < 0) {
    fprintf(stderr, "Failed to query whether SMART is available %s: %s(%d)\n", disk, strerror(errno), errno);
    goto done;
  }
  if (!smart_available) {
    fprintf(stderr, "%s is not support SMART\n", disk);
    goto done;
  }

  if (sk_disk_smart_read_data(skdisk) < 0) {
    fprintf(stderr, "Failed to read SMART data %s: %s(%d)\n", disk, strerror(errno), errno);
    goto done;
  }
  ret = 0;

  if (sk_disk_smart_get_temperature(skdisk, &disk_temp) == 0) {
    uint64_t celsius = (disk_temp - 273150) / 1000;  /* convert milli kelvin to celsius */
    hdh->temperature = celsius;
  }

  if (sk_disk_smart_get_power_on(skdisk, &disk_ontime) == 0) {
    uint64_t onhour = disk_ontime / 1000 / 3600;
    hdh->ontime = onhour;
  }

  sk_disk_check_sleep_mode(skdisk, &hdh->awake);
  sk_disk_smart_status(skdisk, &hdh->status);

  hdh->caution = 0;
  if (sk_disk_smart_parse_attributes(skdisk, (SkSmartAttributeParseCallback) check_caution_cb, &hdh->caution) < 0) {
    fprintf(stderr, "Failed to get attribute: %s(%d)\n", strerror(errno), errno);
    goto done;
  }

done:
  sk_disk_free(skdisk);

  return ret;
}
Ejemplo n.º 4
0
int
main (int argc,
      char *argv[])
{
  int ret;
  const char *device;
  SkDisk *d;
  SkBool smart_is_available;

  d = NULL;
  ret = 1;

  if (argc != 2)
    {
      usage ();
      goto out;
    }

  device = argv[1];

  /* Open disk */
  if (sk_disk_open (device, &d) != 0)
    {
      printf ("Failed to open disk %s: %m\n", device);
      goto out;
    }

  /* Check if smart is available on the disk */
  if (sk_disk_smart_is_available (d, &smart_is_available) != 0)
    {
      printf ("Failed to determine if smart is available for %s: %m\n", device);
      goto out;
    }

  /* main smart data */
  if (sk_disk_smart_read_data (d) != 0)
    {
      printf ("Failed to read smart data for %s: %m\n", device);
      goto out;
    }

  sk_disk_dump(d);

  ret = 0;

 out:

  if (d != NULL)
    sk_disk_free (d);
  return ret;
}
Ejemplo n.º 5
0
int BlockDevice_init(BlockDevice* self, PyObject* args, PyObject* kwds) {
	const char* path = NULL;

	if (!PyArg_ParseTuple(args, "s", &path))
		return -1;

	self->path = strdup(path);

	int r = BlockDevice_get_identity(self);
	if (r) {
		PyErr_Format(PyExc_OSError, "Could not open block device: %s", path);
		return -1;
	}

	r = sk_disk_open(path, &self->disk);
	if (r == 0) {
		if (BlockDevice_smart_is_available(self) == 0) {
			if (BlockDevice_check_sleep_mode(self) == 0) {
				r = sk_disk_smart_read_data(self->disk);
				if (r) {
					PyErr_Format(PyExc_OSError, "Could not open block device %s: %s", path,
						strerror(errno));
					return -1;
				}
			}
		}
	} else {
		PyErr_Format(PyExc_OSError, "Could not open block device %s: %s", path,
			strerror(errno));
		return -1;
	}

	//sk_disk_identify_is_available

	return 0;
}
Ejemplo n.º 6
0
static void
update_sensor_value(IsTemperatureSensor *sensor,
		    IsUdisksPlugin *self)

{
	IsUdisksPluginPrivate *priv;
	gchar *device, *path;
	GDBusProxy *proxy;
	GVariant *var;
	GError *error = NULL;
	SkDisk *sk_disk;
	const gchar *blob;
	gsize len;
	guint64 temperature;
	gdouble value;

	priv = self->priv;

	device = g_path_get_basename(is_sensor_get_path(IS_SENSOR(sensor)));
	path = g_strdup_printf("%s/devices/%s", UDISKS_OBJECT_PATH, device);
	proxy = g_dbus_proxy_new_sync(priv->connection,
				      G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
				      NULL,
				      UDISKS_BUS_NAME,
				      path,
				      UDISKS_DEVICE_INTERFACE_NAME,
				      NULL, &error);
	g_free(path);
	g_free(device);

	if (!proxy) {
		g_prefix_error(&error,
			       _("Error reading new SMART data for sensor %s"),
			       is_sensor_get_path(IS_SENSOR(sensor)));
		is_sensor_emit_error(IS_SENSOR(sensor), error);
		g_error_free(error);
		goto out;
	}

	/* update smart data */
	var = g_variant_new_strv(NULL, 0);
	var = g_dbus_proxy_call_sync(proxy, "DriveAtaSmartRefreshData",
				     g_variant_new_tuple(&var,
							 1),
				     G_DBUS_CALL_FLAGS_NONE,
				     -1, NULL, &error);
	if (!var) {
		g_prefix_error(&error,
			       _("Error refreshing SMART data for sensor %s"),
			       is_sensor_get_path(IS_SENSOR(sensor)));
		is_sensor_emit_error(IS_SENSOR(sensor), error);
		g_error_free(error);
		g_object_unref(proxy);
		goto out;
	}
	g_variant_unref(var);

	var = g_dbus_proxy_get_cached_property(proxy,
					       "DriveAtaSmartBlob");
	if (!var) {
		is_debug("udisks", "unable to get atasmartblob for sensor %s",
			is_sensor_get_path(IS_SENSOR(sensor)));
		g_object_unref(proxy);
		goto out;
	}
	g_object_unref(proxy);

	/* can't unref var until done with blob */
	blob = g_variant_get_fixed_array(var, &len, sizeof(gchar));
	if (!blob) {
		/* this can occur if udisks doesn't update immediately,
		 * ignore */
		g_variant_unref(var);
		goto out;
	}
	sk_disk_open(NULL, &sk_disk);
	sk_disk_set_blob(sk_disk, blob, len);
	if (sk_disk_smart_get_temperature(sk_disk, &temperature) < 0)
	{
		is_debug("udisks", "Error getting temperature from AtaSmartBlob for sensor %s",
			is_sensor_get_path(IS_SENSOR(sensor)));
		sk_disk_free(sk_disk);
		g_variant_unref(var);
		/* TODO: emit error */
		goto out;
	}

	sk_disk_free(sk_disk);
	g_variant_unref(var);

	/* Temperature is in mK, so convert it to K first */
	temperature /= 1000;
	value = (gdouble)temperature - 273.15;
	is_temperature_sensor_set_celsius_value(sensor, value);

out:
	return;
}
Ejemplo n.º 7
0
static void smart_handle_disk (const char *dev)
{
  SkDisk *d = NULL;
  SkBool awake = FALSE;
  SkBool available = FALSE;
  const char *shortname;
  const SkSmartParsedData *spd;
  uint64_t poweron, powercycles, badsectors, temperature;

  shortname = strrchr(dev, '/');
  if (!shortname) return;
  shortname++;
  if (ignorelist_match (ignorelist, shortname) != 0) {
    INFO ("smart plugin: ignoring %s.", dev);
    return;
  }

  INFO ("smart plugin: checking SMART status of %s.",
         dev);

  if (sk_disk_open (dev, &d) < 0)
  {
    ERROR ("smart plugin: unable to open %s.", dev);
    return;
  }
  if (sk_disk_identify_is_available (d, &available) < 0 || !available)
  {
    INFO ("smart plugin: disk %s cannot be identified.", dev);
    /* goto end;*/
  }
  if (sk_disk_smart_is_available (d, &available) < 0 || !available)
  {
    INFO ("smart plugin: disk %s has no SMART support.", dev);
    goto end;
  }
  if (sk_disk_check_sleep_mode (d, &awake) < 0 || !awake)
  {
    INFO ("smart plugin: disk %s is sleeping.", dev);
    goto end;
  }
  if (sk_disk_smart_read_data (d) < 0)
  {
    ERROR ("smart plugin: unable to get SMART data for disk %s.", dev);
    goto end;
  }
  if (sk_disk_smart_parse (d, &spd) < 0)
  {
    ERROR ("smart plugin: unable to parse SMART data for disk %s.", dev);
    goto end;
  }

  /* Get some specific values */
  if (sk_disk_smart_get_power_on (d, &poweron) < 0)
  {
    WARNING ("smart plugin: unable to get milliseconds since power on for %s.",
             dev);
  }
  else
    smart_submit (shortname, "smart_poweron", "", poweron / 1000.);

  if (sk_disk_smart_get_power_cycle (d, &powercycles) < 0)
  {
    WARNING ("smart plugin: unable to get number of power cycles for %s.",
             dev);
  }
  else
    smart_submit (shortname, "smart_powercycles", "", powercycles);

  if (sk_disk_smart_get_bad (d, &badsectors) < 0)
  {
    WARNING ("smart plugin: unable to get number of bad sectors for %s.",
             dev);
  }
  else
    smart_submit (shortname, "smart_badsectors", "", badsectors);

  if (sk_disk_smart_get_temperature (d, &temperature) < 0)
  {
    WARNING ("smart plugin: unable to get temperature for %s.",
             dev);
  }
  else
    smart_submit (shortname, "smart_temperature", "", temperature / 1000. - 273.15);

  /* Grab all attributes */
  if (sk_disk_smart_parse_attributes(d, smart_handle_disk_attribute,
                                     (char *)shortname) < 0)
  {
    ERROR ("smart plugin: unable to handle SMART attributes for %s.",
           dev);
  }

end:
  sk_disk_free(d);
}
static gdouble udisks_plugin_get_sensor_value(const gchar *path,
					      const gchar *id,
					      SensorType type,
					      GError **error) {
	GValue smart_blob_val = { 0, };
	GArray *smart_blob;
	gdouble temperature;
	guint64 temperature_placer;
	DBusGProxy *sensor_proxy;
	guint count;
	DevInfo *info;
	SkDisk *sk_disk;

	info = (DevInfo *)g_hash_table_lookup(devices, path);
	if (info == NULL)
	{
		g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, 0,
			    "Error finding disk with path %s", path);
		return 0.0;
	}

	/* If the device has changed, we find the new temperature and return
	 * it
	 */
	if (info->changed)
	{
		GValue smart_time = { 0, };
		sensor_proxy = dbus_g_proxy_new_for_name(connection,
							 UDISKS_BUS_NAME,
							 path,
							 UDISKS_PROPERTIES_INTERFACE);
		if (!dbus_g_proxy_call(sensor_proxy, "Get", error,
				       G_TYPE_STRING, UDISKS_BUS_NAME,
				       G_TYPE_STRING, "DriveAtaSmartTimeCollected", G_TYPE_INVALID,
				       G_TYPE_VALUE, &smart_time,
				       G_TYPE_INVALID) ||
		    !g_value_get_uint64(&smart_time))
		{
			g_debug("Smart data has not been collected yet... returning 0.0 temp for now to avoid waking drive up unnecessarily");
			g_object_unref(sensor_proxy);
			return 0.0;
		}

		if (dbus_g_proxy_call(sensor_proxy, "Get", error,
				      G_TYPE_STRING, UDISKS_BUS_NAME,
				      G_TYPE_STRING, "DriveAtaSmartBlob", G_TYPE_INVALID,
				      G_TYPE_VALUE, &smart_blob_val,
				      G_TYPE_INVALID))
		{
			smart_blob = g_value_get_boxed(&smart_blob_val);

			sk_disk_open(NULL, &sk_disk);
			sk_disk_set_blob (sk_disk, smart_blob->data, smart_blob->len);
			/* Note: A gdouble cannot be passed in through a cast as it is likely that the
			 * temperature is placed in it purely through memory functions, hence a guint64
			 * is passed and the number is then placed in a gdouble manually 
			 */
			sk_disk_smart_get_temperature (sk_disk, &temperature_placer);
			temperature = temperature_placer;

			/* Temperature is in mK, so convert it to K first */
			temperature /= 1000;
			info->temp = temperature - 273.15;
			info->changed = FALSE;

			g_free (sk_disk);
			g_array_free(smart_blob, TRUE);
		}
		g_object_unref(sensor_proxy);
	}
	return info->temp;
}