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; }
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); }
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; }
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; }
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; }
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; }
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; }