changequote([,])dnl
fi
-have_zlib="false"
-AC_CHECK_LIB([z], [compress2], [have_zlib="true"])
-if test x$have_zlib != "xtrue"; then
- AC_MSG_ERROR([zlib is needed])
-fi
-ZLIB_CFLAGS=
-ZLIB_LIBS="-lz"
-AC_SUBST(ZLIB_CFLAGS)
-AC_SUBST(ZLIB_LIBS)
-
have_sgutils="false"
AC_CHECK_LIB([sgutils2], [sg_ll_inquiry], have_sgutils="true")
if test x$have_sgutils != "xtrue"; then
AC_SUBST(SGUTILS_LIBS)
-PKG_CHECK_MODULES(SQLITE3, [sqlite3])
-AC_SUBST(SQLITE3_CFLAGS)
-AC_SUBST(SQLITE3_LIBS)
-
PKG_CHECK_MODULES(GUDEV, [gudev-1.0 >= 001])
AC_SUBST(GUDEV_CFLAGS)
AC_SUBST(GUDEV_LIBS)
<!-- ************************************************************ -->
- <method name="DriveAtaSmartGetHistoricalData">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg name="since" direction="in" type="t">
- <doc:doc><doc:summary>
- Don't fetch data collected earlier than this point
- in time (seconds since the Epoch Jan 1, 1970 0:00 UTC).
- </doc:summary></doc:doc>
- </arg>
- <arg name="until" direction="in" type="t">
- <doc:doc><doc:summary>
- Don't fetch data collected later than this point in
- time (seconds since the Epoch Jan 1, 1970 0:00 UTC). If 0 is
- passed the current time will be used.
- </doc:summary></doc:doc>
- </arg>
- <arg name="spacing" direction="in" type="t">
- <doc:doc><doc:summary>
- The minimum spacing (in seconds) between two data points or 0
- to get all data points between @since and @until.
- </doc:summary></doc:doc>
- </arg>
- <arg name="data" direction="out" type="a(tbbbbdta(usubbybybybbbutay))">
- <doc:doc><doc:summary>
- An array of historical data sorted by collection date. Each element contains
- the following members (TODO).
- </doc:summary></doc:doc>
- </arg>
- <doc:doc>
- <doc:description>
- <doc:para>
- Retrieves historical ATA SMART data from the drive in the
- given time interval. Note that this is data collected and
- stored by the host as ATA SMART capable devices cannot
- store or return historical data by themselves.
- </doc:para>
- </doc:description>
- <doc:permission>
- The caller will need one of the following PolicyKit authorizations:
- <doc:list>
- <doc:item>
- <doc:term>org.freedesktop.devicekit.disks.drive-ata-smart-retrieve-historical-data</doc:term>
- <doc:definition>To retrieve historical ATA SMART data</doc:definition>
- </doc:item>
- </doc:list>
- </doc:permission>
- <doc:errors>
- <doc:error name="&ERROR_NOT_AUTHORIZED;">if the caller lacks the appropriate PolicyKit authorization</doc:error>
- <doc:error name="&ERROR_FAILED;">if the operation failed</doc:error>
- <doc:error name="&ERROR_CANCELLED;">if the job was cancelled</doc:error>
- </doc:errors>
- </doc:doc>
- </method>
-
- <!-- ************************************************************ -->
-
<method name="DriveAtaSmartInitiateSelftest">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<property name="drive-ata-smart-is-available" type="b" access="read">
<doc:doc><doc:description><doc:para>
- TRUE only if drive is capable of reporting
- <doc:ulink url="http://en.wikipedia.org/wiki/S.M.A.R.T">ATA SMART</doc:ulink>
- data.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-is-failing" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Set to TRUE if ATA SMART indicates that the disk is failing, TRUE otherwise.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero and the property
- <doc:ref type="property" to="Device:drive-ata-smart-status-valid">drive-ata-smart-status-valid</doc:ref>
- is TRUE.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-is-failing-valid" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Set to TRUE only if the property
- <doc:ref type="property" to="Device:drive-ata-smart-status">drive-ata-smart-status</doc:ref>
- is valid.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-has-bad-sectors" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Set to TRUE if ATA SMART indicates that one or more sectors are bad, TRUE otherwise.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-has-bad-attributes" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Set to TRUE if ATA SMART indicates that one or more attributes are exceeding their threshold, TRUE otherwise.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-temperature-kelvin" type="d" access="read">
- <doc:doc><doc:description><doc:para>
- Temperature of the drive in kelvin or 0 if unknown.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-power-on-seconds" type="t" access="read">
- <doc:doc><doc:description><doc:para>
- Seconds the drive has been powered on or 0 if unknown.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
+ TRUE if the disk is capable of reporting SMART data, FALSE otherwise.
</doc:para></doc:description></doc:doc>
</property>
<property name="drive-ata-smart-time-collected" type="t" access="read">
<doc:doc><doc:description><doc:para>
The point in time (seconds since the Epoch Jan 1, 1970
- 0:00 UTC) when ATA SMART data was collected. If data
- was never collected, this property will assume the value
- 0. This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-is-available">drive-ata-smart-is-available</doc:ref>
- is TRUE.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-offline-data-collection-status" type="u" access="read">
- <doc:doc><doc:description><doc:para>
- Offline data collection status (TODO: specify values).
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-offline-data-collection-seconds" type="u" access="read">
- <doc:doc><doc:description><doc:para>
- Number of seconds needed to perform offline data collection status.
+ 0:00 UTC) when ATA SMART data was collected.
This property is only valid if
<doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
is greater than zero.
</doc:para></doc:description></doc:doc>
</property>
- <property name="drive-ata-smart-self-test-execution-status" type="u" access="read">
+ <property name="drive-ata-smart-status" type="s" access="read">
<doc:doc><doc:description><doc:para>
- Current status of self test (TODO: specify values).
+ The overall assessment for the disk. Is one of the following strings
+ <quote>GOOD</quote>,
+ <quote>BAD_ATTRIBUTES_IN_THE_PAST</quote> (At least one pre-fail attribute is exceeded its threshold in the past),
+ <quote>BAD_SECTOR</quote> (At least one bad sector),
+ <quote>BAD_ATTRIBUTE_NOW</quote> (At least one pre-fail attribute is exceeding its threshold now),
+ <quote>BAD_SECTOR_MANY</quote> (Many bad sectors)),
+ <quote>BAD_STATUS</quote> (Smart Self Assessment negative)
+ or empty if some error occured trying to determine the result.
This property is only valid if
<doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
is greater than zero.
</doc:para></doc:description></doc:doc>
</property>
- <property name="drive-ata-smart-self-test-execution-percent-remaining" type="u" access="read">
+ <property name="drive-ata-smart-blob" type="ay" access="read">
<doc:doc><doc:description><doc:para>
- The progress of an ongoing self test or 0 if no self test is in progress.
+ A blob containing the ATA SMART data. This blob can be used with libatasmart to get
+ more information.
This property is only valid if
<doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
is greater than zero.
</doc:para></doc:description></doc:doc>
</property>
- <property name="drive-ata-smart-short-and-extended-self-test-available" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Whether the short and extended self-tests are available.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-conveyance-self-test-available" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Whether the conveyance self-test is available.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-start-self-test-available" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Whether the start self-test is available.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-abort-self-test-available" type="b" access="read">
- <doc:doc><doc:description><doc:para>
- Whether the abort self-test is available.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
-
- <property name="drive-ata-smart-short-self-test-polling-minutes" type="u" access="read">
- <doc:doc><doc:description><doc:para>
- Recommended polling time in minutes for short self-test.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-extended-self-test-polling-minutes" type="u" access="read">
- <doc:doc><doc:description><doc:para>
- Recommended polling time in minutes for extended self-test.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-conveyance-self-test-polling-minutes" type="u" access="read">
- <doc:doc><doc:description><doc:para>
- Recommended polling time in minutes for conveyance self-test.
- This property is only valid if
- <doc:ref type="property" to="Device:drive-ata-smart-time-collected">drive-ata-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
- <property name="drive-ata-smart-attributes" type="a(usubbybybybbbutay)" access="read">
- <doc:doc><doc:description><doc:para>
- An array of ATA SMART attributes. Each element contains the following members (TODO).
- This property is only valid if
- <doc:ref type="property" to="Device:drive-smart-time-collected">drive-smart-time-collected</doc:ref>
- is greater than zero.
- </doc:para></doc:description></doc:doc>
- </property>
<!-- **************************************************************************************************** -->
devkit-disks-mount.h devkit-disks-mount.c \
devkit-disks-mount-monitor.h devkit-disks-mount-monitor.c \
devkit-disks-inhibitor.h devkit-disks-inhibitor.c \
- devkit-disks-ata-smart-db.h devkit-disks-ata-smart-db.c \
devkit-disks-poller.h devkit-disks-poller.c \
main.c \
$(BUILT_SOURCES)
$(NULL)
devkit_disks_daemon_CFLAGS = \
- $(ZLIB_CFLAGS) \
- $(SQLITE3_CFLAGS) \
$(LIBATASMART_CFLAGS) \
$(NULL)
$(DBUS_GLIB_LIBS) \
$(POLKIT_GOBJECT_1_LIBS) \
$(GUDEV_LIBS) \
- $(ZLIB_LIBS) \
- $(SQLITE3_LIBS) \
$(LIBATASMART_LIBS) \
$(NULL)
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib/gi18n-lib.h>
-#include <glib-object.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <sqlite3.h>
-#include <zlib.h>
-
-#include "devkit-disks-daemon.h"
-#include "devkit-disks-device.h"
-#include "devkit-disks-device-private.h"
-#include "devkit-disks-ata-smart-db.h"
-
-struct DevkitDisksAtaSmartDbPrivate
-{
- sqlite3 *db;
-};
-
-G_DEFINE_TYPE (DevkitDisksAtaSmartDb, devkit_disks_ata_smart_db, G_TYPE_OBJECT)
-
-#define DEVKIT_DISKS_ATA_SMART_DB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVKIT_DISKS_TYPE_DEVICE, DevkitDisksDevicePrivate))
-
-
-static void
-devkit_disks_ata_smart_db_finalize (GObject *object)
-{
- DevkitDisksAtaSmartDb *db = DEVKIT_DISKS_ATA_SMART_DB (object);
-
- if (db->priv->db != NULL)
- sqlite3_close (db->priv->db);
-
- if (G_OBJECT_CLASS (devkit_disks_ata_smart_db_parent_class)->finalize != NULL)
- G_OBJECT_CLASS (devkit_disks_ata_smart_db_parent_class)->finalize (object);
-}
-
-static void
-devkit_disks_ata_smart_db_class_init (DevkitDisksAtaSmartDbClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
-
- g_type_class_add_private (klass, sizeof (DevkitDisksAtaSmartDbPrivate));
-
- object_class->finalize = devkit_disks_ata_smart_db_finalize;
-}
-
-static void
-devkit_disks_ata_smart_db_init (DevkitDisksAtaSmartDb *db)
-{
- gint ret;
- gchar *err_msg;
-
- db->priv = G_TYPE_INSTANCE_GET_PRIVATE (db, DEVKIT_DISKS_TYPE_ATA_SMART_DB, DevkitDisksAtaSmartDbPrivate);
-
- ret = sqlite3_open_v2 (PACKAGE_LOCALSTATE_DIR "/lib/DeviceKit-disks/ata-smart-db.sqlite3",
- &db->priv->db,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
- NULL);
- if (ret != SQLITE_OK) {
- g_debug ("error opening sqlite3 database at "
- PACKAGE_LOCALSTATE_DIR "/lib/DeviceKit-disks/ata-smart-db.sqlite3"
- ": %s", sqlite3_errmsg (db->priv->db));
- sqlite3_close (db->priv->db);
- g_object_unref (db);
- goto out;
- }
-
- /* create tables */
- ret = sqlite3_exec (db->priv->db,
- "CREATE TABLE AtaSmartEntry ("
- " disk_id TEXT, "
- " time_collected INTEGER, "
- " is_failing INTEGER,"
- " is_failing_valid INTEGER,"
- " has_bad_sectors INTEGER,"
- " has_bad_attributes INTEGER,"
- " temperature_kelvin REAL,"
- " power_on_secs INTEGER,"
- " compressed_data BLOB "
- ");",
- NULL,
- NULL,
- &err_msg);
- if (ret != SQLITE_OK) {
- g_debug ("SQL error creating tables: %s", err_msg);
- sqlite3_free (err_msg);
- }
-
- out:
- ;
-}
-
-DevkitDisksAtaSmartDb *
-devkit_disks_ata_smart_db_new (void)
-{
- return DEVKIT_DISKS_ATA_SMART_DB (g_object_new (DEVKIT_DISKS_TYPE_ATA_SMART_DB, NULL));
-}
-
-static gchar *
-get_disk_id (DevkitDisksDevice *device)
-{
- gchar *s;
- gchar *result;
-
- result = NULL;
-
- if (device->priv->drive_vendor == NULL || strlen (device->priv->drive_vendor) == 0)
- goto out;
- if (device->priv->drive_model == NULL || strlen (device->priv->drive_model) == 0)
- goto out;
- if (device->priv->drive_revision == NULL || strlen (device->priv->drive_revision) == 0)
- goto out;
- if (device->priv->drive_serial == NULL || strlen (device->priv->drive_serial) == 0)
- goto out;
-
- s = g_strdup_printf ("%s_%s_%s_%s",
- device->priv->drive_vendor,
- device->priv->drive_model,
- device->priv->drive_revision,
- device->priv->drive_serial);
- result = g_uri_escape_string (s, NULL, FALSE);
- g_free (s);
-
-out:
- return result;
-}
-
-void
-devkit_disks_ata_smart_db_add_entry (DevkitDisksAtaSmartDb *db,
- DevkitDisksDevice *device,
- time_t time_collected,
- gboolean is_failing,
- gboolean is_failing_valid,
- gboolean has_bad_sectors,
- gboolean has_bad_attributes,
- gdouble temperature_kelvin,
- guint64 power_on_seconds,
- const void *blob,
- gsize blob_size)
-{
- gint ret;
- char *s;
- gchar *disk_id;
- sqlite3_stmt *stmt;
- guchar *compressed_blob;
- uLongf compressed_blob_size;
-
- s = NULL;
- stmt = NULL;
- disk_id = NULL;
- compressed_blob = NULL;
-
- if (db->priv->db == NULL) {
- g_warning ("No database");
- goto out;
- }
-
- disk_id = get_disk_id (device);
- if (disk_id == NULL) {
- g_warning ("Error getting stable ID for device");
- goto out;
- }
-
- /* compress the data */
- compressed_blob = g_new0 (guchar, blob_size * 2 + 32);
- compressed_blob_size = blob_size * 2 + 32;
- ret = compress2 (compressed_blob, &compressed_blob_size,
- blob, blob_size,
- 1);
- if (ret != Z_OK) {
- g_warning ("Error compressing blob (size=%d): %d", (gint) blob_size, ret);
- goto out;
- }
-
- //g_debug ("Compressed %ld bytes into %ld bytes", blob_size, compressed_blob_size);
-
- /* insert it into the database */
- s = sqlite3_mprintf ("INSERT INTO AtaSmartEntry "
- "(disk_id, "
- "time_collected, "
- "is_failing, "
- "is_failing_valid, "
- "has_bad_sectors, "
- "has_bad_attributes, "
- "temperature_kelvin, "
- "power_on_secs, "
- "compressed_data) "
- "VALUES ('%q', "
- "%" G_GUINT64_FORMAT ", "
- "%d, "
- "%d, "
- "%d, "
- "%d, "
- "%g, "
- "%" G_GUINT64_FORMAT ", "
- "?)",
- disk_id,
- (guint64) time_collected,
- is_failing,
- is_failing_valid,
- has_bad_sectors,
- has_bad_attributes,
- temperature_kelvin,
- power_on_seconds);
- ret = sqlite3_prepare_v2 (db->priv->db,
- s,
- -1,
- &stmt,
- NULL);
- if (ret != SQLITE_OK) {
- g_warning ("SQL error preparing statement: %d", ret);
- goto out;
- }
- ret = sqlite3_bind_blob (stmt,
- 1,
- compressed_blob,
- compressed_blob_size,
- SQLITE_STATIC);
- if (ret != SQLITE_OK) {
- g_warning ("SQL error binding BLOB: %d", ret);
- goto out;
- }
- ret = sqlite3_step (stmt);
- if (ret != SQLITE_DONE) {
- g_warning ("SQL error executing statement: %d", ret);
- goto out;
- }
-
- out:
- g_free (compressed_blob);
- g_free (disk_id);
- if (s != NULL)
- sqlite3_free (s);
- if (stmt != NULL)
- sqlite3_finalize (stmt);
-}
-
-void
-devkit_disks_ata_smart_db_delete_entries (DevkitDisksAtaSmartDb *db,
- time_t cut_off_point)
-{
- char *s;
- gint ret;
- sqlite3_stmt *stmt;
-
- s = NULL;
- stmt = NULL;
-
- s = sqlite3_mprintf ("DELETE FROM AtaSmartEntry WHERE time_collected < %"G_GUINT64_FORMAT ";",
- (guint64) cut_off_point);
- ret = sqlite3_prepare_v2 (db->priv->db,
- s,
- -1,
- &stmt,
- NULL);
- if (ret != SQLITE_OK) {
- g_warning ("SQL error preparing statement: %d", ret);
- goto out;
- }
- ret = sqlite3_step (stmt);
- if (ret != SQLITE_DONE) {
- g_warning ("SQL error executing statement: %d", ret);
- goto out;
- }
-
- out:
- if (s != NULL)
- sqlite3_free (s);
- if (stmt != NULL)
- sqlite3_finalize (stmt);
-}
-
-gboolean
-devkit_disks_ata_smart_db_get_entries (DevkitDisksAtaSmartDb *db,
- DevkitDisksDevice *device,
- time_t since,
- time_t until,
- guint64 spacing,
- DevkitDisksAtaSmartDbGetEntriesFunc callback,
- gpointer user_data)
-{
- gboolean ret;
- char *s;
- sqlite3_stmt *stmt;
- gchar *disk_id;
- guint64 last_time_collected;
-
- ret = FALSE;
- stmt = NULL;
-
- if (db->priv->db == NULL) {
- g_warning ("No database");
- goto out;
- }
-
- disk_id = get_disk_id (device);
- if (disk_id == NULL) {
- g_warning ("Error getting stable ID for device");
- goto out;
- }
-
- s = sqlite3_mprintf ("SELECT"
- " AtaSmartEntry.time_collected,"
- " AtaSmartEntry.compressed_data, "
- " AtaSmartEntry.is_failing, "
- " AtaSmartEntry.is_failing_valid, "
- " AtaSmartEntry.has_bad_sectors, "
- " AtaSmartEntry.has_bad_attributes, "
- " AtaSmartEntry.temperature_kelvin, "
- " AtaSmartEntry.power_on_secs "
- "FROM AtaSmartEntry "
- "WHERE"
- " AtaSmartEntry.disk_id='%q' AND"
- " AtaSmartEntry.time_collected >= %" G_GUINT64_FORMAT " AND"
- " AtaSmartEntry.time_collected <= %" G_GUINT64_FORMAT " "
- "ORDER BY AtaSmartEntry.time_collected;",
- disk_id,
- since,
- until);
- ret = sqlite3_prepare_v2 (db->priv->db,
- s,
- -1,
- &stmt,
- NULL);
- if (ret != SQLITE_OK) {
- g_warning ("SQL error preparing statement: %d", ret);
- goto out;
- }
-
- last_time_collected = 0;
- do {
- guint64 time_collected;
- const void *compressed_blob;
- gsize compressed_blob_size;
- static guchar blob[2048]; /* assume 2k is enough */
- uLongf blob_size;
- gint rc;
- gboolean is_failing;
- gboolean is_failing_valid;
- gboolean has_bad_sectors;
- gboolean has_bad_attributes;
- gdouble temperature_kelvin;
- guint64 power_on_seconds;
-
- ret = sqlite3_step (stmt);
-
- if (ret == SQLITE_DONE)
- break;
-
- if (ret != SQLITE_ROW) {
- g_warning ("SQL error stepping: %d", ret);
- goto out;
- }
-
- time_collected = sqlite3_column_int64 (stmt, 0);
-
- if (time_collected < (guint64) since)
- continue;
- if (time_collected > (guint64) until)
- continue;
- if (time_collected - last_time_collected < spacing)
- continue;
-
- last_time_collected = time_collected;
-
-
- compressed_blob = sqlite3_column_blob (stmt, 1);
- compressed_blob_size = sqlite3_column_bytes (stmt, 1);
-
- is_failing = sqlite3_column_int (stmt, 2);
- is_failing_valid = sqlite3_column_int (stmt, 3);
- has_bad_sectors = sqlite3_column_int (stmt, 4);
- has_bad_attributes = sqlite3_column_int (stmt, 5);
- temperature_kelvin = sqlite3_column_double (stmt, 6);
- power_on_seconds = sqlite3_column_int64 (stmt, 7);
-
- blob_size = sizeof blob;
- rc = uncompress (blob, &blob_size, compressed_blob, compressed_blob_size);
- if (rc != Z_OK) {
- g_warning ("Decompression of compressed blob of size %d from time %" G_GUINT64_FORMAT
- " for device %s FAILED with return code %d. Ignoring.",
- (gint) compressed_blob_size,
- time_collected,
- device->priv->device_file,
- rc);
- continue;
- }
-
- //g_debug ("haz row %ld %ld %ld", time_collected, compressed_blob_size, blob_size);
-
- callback (time_collected,
- is_failing,
- is_failing_valid,
- has_bad_sectors,
- has_bad_attributes,
- temperature_kelvin,
- power_on_seconds,
- blob,
- blob_size,
- user_data);
-
- } while (ret != SQLITE_DONE);
-
-
- out:
- g_free (disk_id);
- if (s != NULL)
- sqlite3_free (s);
- if (stmt != NULL)
- sqlite3_finalize (stmt);
- return ret;
-}
-
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifndef __DEVKIT_DISKS_ATA_SMART_DB_H__
-#define __DEVKIT_DISKS_ATA_SMART_DB_H__
-
-#include "devkit-disks-types.h"
-
-G_BEGIN_DECLS
-
-#define DEVKIT_DISKS_TYPE_ATA_SMART_DB (devkit_disks_ata_smart_db_get_type ())
-#define DEVKIT_DISKS_ATA_SMART_DB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVKIT_DISKS_TYPE_ATA_SMART_DB, DevkitDisksAtaSmartDb))
-#define DEVKIT_DISKS_ATA_SMART_DB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), DEVKIT_DISKS_TYPE_ATA_SMART_DB, DevkitDisksAtaSmartDbClass))
-#define DEVKIT_DISKS_IS_ATA_SMART_DB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVKIT_DISKS_TYPE_ATA_SMART_DB))
-#define DEVKIT_DISKS_IS_ATA_SMART_DB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVKIT_DISKS_TYPE_ATA_SMART_DB))
-#define DEVKIT_DISKS_ATA_SMART_DB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVKIT_DISKS_TYPE_ATA_SMART_DB, DevkitDisksAtaSmartDbClass))
-
-typedef struct DevkitDisksAtaSmartDbClass DevkitDisksAtaSmartDbClass;
-typedef struct DevkitDisksAtaSmartDbPrivate DevkitDisksAtaSmartDbPrivate;
-
-struct DevkitDisksAtaSmartDb
-{
- GObject parent;
- DevkitDisksAtaSmartDbPrivate *priv;
-};
-
-struct DevkitDisksAtaSmartDbClass
-{
- GObjectClass parent_class;
-};
-
-typedef gboolean (*DevkitDisksAtaSmartDbGetEntriesFunc) (time_t time_collected,
- gboolean is_failing,
- gboolean is_failing_valid,
- gboolean has_bad_sectors,
- gboolean has_bad_attributes,
- gdouble temperature_kelvin,
- guint64 power_on_seconds,
- const void *blob,
- gsize blob_size,
- gpointer user_data);
-
-GType devkit_disks_ata_smart_db_get_type (void) G_GNUC_CONST;
-DevkitDisksAtaSmartDb *devkit_disks_ata_smart_db_new (void);
-void devkit_disks_ata_smart_db_add_entry (DevkitDisksAtaSmartDb *db,
- DevkitDisksDevice *device,
- time_t time_collected,
- gboolean is_failing,
- gboolean is_failing_valid,
- gboolean has_bad_sectors,
- gboolean has_bad_attributes,
- gdouble temperature_kelvin,
- guint64 power_on_seconds,
- const void *blob,
- gsize blob_size);
-void devkit_disks_ata_smart_db_delete_entries (DevkitDisksAtaSmartDb *db,
- time_t cut_off_point);
-gboolean devkit_disks_ata_smart_db_get_entries (DevkitDisksAtaSmartDb *db,
- DevkitDisksDevice *device,
- time_t since,
- time_t until,
- guint64 spacing,
- DevkitDisksAtaSmartDbGetEntriesFunc callback,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* __DEVKIT_DISKS_ATA_SMART_DB_H__ */
/* clean up old ATA SMART entries every 24 hours (and on startup) */
#define ATA_SMART_CLEANUP_INTERVAL_SECONDS (24*60*60)
-/* delete entries older than five days */
-#define ATA_SMART_KEEP_ENTRIES_SECONDS (5*24*60*60)
-
/* ---------------------------------------------------------------------------------------------------- */
#include <stdlib.h>
#include "devkit-disks-mount-monitor.h"
#include "devkit-disks-poller.h"
#include "devkit-disks-inhibitor.h"
-#include "devkit-disks-ata-smart-db.h"
#include "devkit-disks-daemon-glue.h"
#include "devkit-disks-marshal.h"
DevkitDisksMountMonitor *mount_monitor;
- DevkitDisksAtaSmartDb *ata_smart_db;
-
guint ata_smart_refresh_timer_id;
guint ata_smart_cleanup_timer_id;
static const int num_known_file_systems = sizeof (known_file_systems) / sizeof (DevkitDisksFilesystem);
-DevkitDisksAtaSmartDb *
-devkit_disks_daemon_local_get_ata_smart_db (DevkitDisksDaemon *daemon)
-{
- return daemon->priv->ata_smart_db;
-}
-
const DevkitDisksFilesystem *
devkit_disks_daemon_local_get_fs_details (DevkitDisksDaemon *daemon,
const gchar *filesystem_id)
g_object_unref (daemon->priv->mount_monitor);
}
- if (daemon->priv->ata_smart_db != NULL) {
- g_object_unref (daemon->priv->ata_smart_db);
- }
-
if (daemon->priv->gudev_client != NULL) {
g_object_unref (daemon->priv->gudev_client);
}
}
static gboolean
-cleanup_ata_smart_data (DevkitDisksDaemon *daemon)
-{
- time_t now;
- time_t cut_off_point;
-
- now = time (NULL);
- cut_off_point = now - ATA_SMART_KEEP_ENTRIES_SECONDS;
-
- g_print ("**** Deleting all ATA SMART data older than %d seconds\n", ATA_SMART_KEEP_ENTRIES_SECONDS);
-
- devkit_disks_ata_smart_db_delete_entries (daemon->priv->ata_smart_db,
- cut_off_point);
-
- /* cleanup in another N seconds */
- daemon->priv->ata_smart_cleanup_timer_id = g_timeout_add_seconds (ATA_SMART_CLEANUP_INTERVAL_SECONDS,
- (GSourceFunc) cleanup_ata_smart_data,
- daemon);
-
- return FALSE;
-}
-
-static gboolean
refresh_ata_smart_data (DevkitDisksDaemon *daemon)
{
DevkitDisksDevice *device;
g_signal_connect (daemon->priv->mount_monitor, "mount-added", (GCallback) mount_added, daemon);
g_signal_connect (daemon->priv->mount_monitor, "mount-removed", (GCallback) mount_removed, daemon);
- daemon->priv->ata_smart_db = devkit_disks_ata_smart_db_new ();
-
return TRUE;
error:
return FALSE;
devkit_disks_mount_file_clean_stale (l);
g_list_free (l);
- /* clean up old ATA SMART data from the database */
- cleanup_ata_smart_data (daemon);
-
/* set up timer for refreshing ATA SMART data - we don't want to refresh immediately because
* when adding a device we also do this...
*/
DevkitDisksDevice *devkit_disks_daemon_local_find_by_dev (DevkitDisksDaemon *daemon,
dev_t dev);
-DevkitDisksAtaSmartDb *devkit_disks_daemon_local_get_ata_smart_db (DevkitDisksDaemon *daemon);
-
-
typedef void (*DevkitDisksCheckAuthCallback) (DevkitDisksDaemon *daemon,
DevkitDisksDevice *device,
DBusGMethodInvocation *context,
}
void
-devkit_disks_device_set_drive_ata_smart_is_failing (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_is_failing != value))
- {
- device->priv->drive_ata_smart_is_failing = value;
- emit_changed (device, "drive_ata_smart_is_failing");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_is_failing_valid (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_is_failing_valid != value))
- {
- device->priv->drive_ata_smart_is_failing_valid = value;
- emit_changed (device, "drive_ata_smart_is_failing_valid");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_has_bad_sectors (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_has_bad_sectors != value))
- {
- device->priv->drive_ata_smart_has_bad_sectors = value;
- emit_changed (device, "drive_ata_smart_has_bad_sectors");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_has_bad_attributes (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_has_bad_attributes != value))
- {
- device->priv->drive_ata_smart_has_bad_attributes = value;
- emit_changed (device, "drive_ata_smart_has_bad_attributes");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_temperature_kelvin (DevkitDisksDevice *device, gdouble value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_temperature_kelvin != value))
- {
- device->priv->drive_ata_smart_temperature_kelvin = value;
- emit_changed (device, "drive_ata_smart_temperature_kelvin");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_power_on_seconds (DevkitDisksDevice *device, guint64 value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_power_on_seconds != value))
- {
- device->priv->drive_ata_smart_power_on_seconds = value;
- emit_changed (device, "drive_ata_smart_power_on_seconds");
- }
-}
-
-void
devkit_disks_device_set_drive_ata_smart_time_collected (DevkitDisksDevice *device, guint64 value)
{
if (G_UNLIKELY (device->priv->drive_ata_smart_time_collected != value))
}
void
-devkit_disks_device_set_drive_ata_smart_offline_data_collection_status (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_offline_data_collection_status != value))
- {
- device->priv->drive_ata_smart_offline_data_collection_status = value;
- emit_changed (device, "drive_ata_smart_offline_data_collection_status");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_offline_data_collection_seconds (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_offline_data_collection_seconds != value))
- {
- device->priv->drive_ata_smart_offline_data_collection_seconds = value;
- emit_changed (device, "drive_ata_smart_offline_data_collection_seconds");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_self_test_execution_status (DevkitDisksDevice *device, guint value)
+devkit_disks_device_set_drive_ata_smart_status (DevkitDisksDevice *device, SkSmartOverall value)
{
- if (G_UNLIKELY (device->priv->drive_ata_smart_self_test_execution_status != value))
+ if (G_UNLIKELY (device->priv->drive_ata_smart_status != value))
{
- device->priv->drive_ata_smart_self_test_execution_status = value;
- emit_changed (device, "drive_ata_smart_self_test_execution_status");
+ device->priv->drive_ata_smart_status = value;
+ emit_changed (device, "drive_ata_smart_status");
}
}
void
-devkit_disks_device_set_drive_ata_smart_self_test_execution_percent_remaining (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_self_test_execution_percent_remaining != value))
- {
- device->priv->drive_ata_smart_self_test_execution_percent_remaining = value;
- emit_changed (device, "drive_ata_smart_self_test_execution_percent_remaining");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_short_and_extended_self_test_available (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_short_and_extended_self_test_available != value))
- {
- device->priv->drive_ata_smart_short_and_extended_self_test_available = value;
- emit_changed (device, "drive_ata_smart_short_and_extended_self_test_available");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_conveyance_self_test_available (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_conveyance_self_test_available != value))
- {
- device->priv->drive_ata_smart_conveyance_self_test_available = value;
- emit_changed (device, "drive_ata_smart_conveyance_self_test_available");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_start_self_test_available (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_start_self_test_available != value))
- {
- device->priv->drive_ata_smart_start_self_test_available = value;
- emit_changed (device, "drive_ata_smart_start_self_test_available");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_abort_self_test_available (DevkitDisksDevice *device, gboolean value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_abort_self_test_available != value))
- {
- device->priv->drive_ata_smart_abort_self_test_available = value;
- emit_changed (device, "drive_ata_smart_abort_self_test_available");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_short_self_test_polling_minutes (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_short_self_test_polling_minutes != value))
- {
- device->priv->drive_ata_smart_short_self_test_polling_minutes = value;
- emit_changed (device, "drive_ata_smart_short_self_test_polling_minutes");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_extended_self_test_polling_minutes (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_extended_self_test_polling_minutes != value))
- {
- device->priv->drive_ata_smart_extended_self_test_polling_minutes = value;
- emit_changed (device, "drive_ata_smart_extended_self_test_polling_minutes");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_conveyance_self_test_polling_minutes (DevkitDisksDevice *device, guint value)
-{
- if (G_UNLIKELY (device->priv->drive_ata_smart_conveyance_self_test_polling_minutes != value))
- {
- device->priv->drive_ata_smart_conveyance_self_test_polling_minutes = value;
- emit_changed (device, "drive_ata_smart_conveyance_self_test_polling_minutes");
- }
-}
-
-void
-devkit_disks_device_set_drive_ata_smart_attributes_steal (DevkitDisksDevice *device, GPtrArray *attributes)
+devkit_disks_device_set_drive_ata_smart_blob_steal (DevkitDisksDevice *device, gchar *blob, gsize blob_size)
{
/* TODO: compare? Not really needed, this happens very rarely */
- g_ptr_array_foreach (device->priv->drive_ata_smart_attributes, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (device->priv->drive_ata_smart_attributes, TRUE);
-
- device->priv->drive_ata_smart_attributes = attributes;
+ g_free (device->priv->drive_ata_smart_blob);
+ device->priv->drive_ata_smart_blob = blob;
+ device->priv->drive_ata_smart_blob_size = blob_size;
- emit_changed (device, "drive_ata_smart_attributes");
+ emit_changed (device, "drive_ata_smart_blob");
}
#include <dbus/dbus-glib.h>
#include <gudev/gudev.h>
+#include <atasmart.h>
#include "devkit-disks-types.h"
struct Job;
typedef struct Job Job;
-#define ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
- G_TYPE_UINT, \
- G_TYPE_STRING, \
- G_TYPE_UINT, \
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
- G_TYPE_UINT, G_TYPE_UINT64, \
- dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), \
- G_TYPE_INVALID))
-
-#define ATA_SMART_HISTORICAL_SMART_DATA_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
- G_TYPE_UINT64, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_DOUBLE, \
- G_TYPE_UINT64, \
- dbus_g_type_get_collection ("GPtrArray", ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE), \
- G_TYPE_INVALID))
-
#define LSOF_DATA_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
G_TYPE_UINT, \
G_TYPE_UINT, \
guint64 linux_md_sync_speed;
gboolean drive_ata_smart_is_available;
- gboolean drive_ata_smart_is_failing;
- gboolean drive_ata_smart_is_failing_valid;
- gboolean drive_ata_smart_has_bad_sectors;
- gboolean drive_ata_smart_has_bad_attributes;
- gdouble drive_ata_smart_temperature_kelvin;
- guint64 drive_ata_smart_power_on_seconds;
guint64 drive_ata_smart_time_collected;
- guint drive_ata_smart_offline_data_collection_status;
- guint drive_ata_smart_offline_data_collection_seconds;
- guint drive_ata_smart_self_test_execution_status;
- guint drive_ata_smart_self_test_execution_percent_remaining;
- gboolean drive_ata_smart_short_and_extended_self_test_available;
- gboolean drive_ata_smart_conveyance_self_test_available;
- gboolean drive_ata_smart_start_self_test_available;
- gboolean drive_ata_smart_abort_self_test_available;
- guint drive_ata_smart_short_self_test_polling_minutes;
- guint drive_ata_smart_extended_self_test_polling_minutes;
- guint drive_ata_smart_conveyance_self_test_polling_minutes;
- GPtrArray *drive_ata_smart_attributes;
+ SkSmartOverall drive_ata_smart_status;
+ void *drive_ata_smart_blob;
+ gsize drive_ata_smart_blob_size;
/* the following properties are not (yet) exported */
char *dm_name;
void devkit_disks_device_set_holders_objpath (DevkitDisksDevice *device, GStrv value);
void devkit_disks_device_set_drive_ata_smart_is_available (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_is_failing (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_is_failing_valid (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_has_bad_sectors (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_has_bad_attributes (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_temperature_kelvin (DevkitDisksDevice *device, gdouble value);
-void devkit_disks_device_set_drive_ata_smart_power_on_seconds (DevkitDisksDevice *device, guint64 value);
void devkit_disks_device_set_drive_ata_smart_time_collected (DevkitDisksDevice *device, guint64 value);
-void devkit_disks_device_set_drive_ata_smart_offline_data_collection_status (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_offline_data_collection_seconds (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_self_test_execution_status (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_self_test_execution_percent_remaining (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_short_and_extended_self_test_available (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_conveyance_self_test_available (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_start_self_test_available (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_abort_self_test_available (DevkitDisksDevice *device, gboolean value);
-void devkit_disks_device_set_drive_ata_smart_short_self_test_polling_minutes (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_extended_self_test_polling_minutes (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_conveyance_self_test_polling_minutes (DevkitDisksDevice *device, guint value);
-void devkit_disks_device_set_drive_ata_smart_attributes_steal (DevkitDisksDevice *device, GPtrArray *attributes);
+void devkit_disks_device_set_drive_ata_smart_status (DevkitDisksDevice *device, SkSmartOverall value);
+void devkit_disks_device_set_drive_ata_smart_blob_steal (DevkitDisksDevice *device, gchar *blob, gsize blob_size);
G_END_DECLS
#include "devkit-disks-mount-file.h"
#include "devkit-disks-inhibitor.h"
#include "devkit-disks-poller.h"
-#include "devkit-disks-ata-smart-db.h"
/*--------------------------------------------------------------------------------------------------------------*/
#include "devkit-disks-device-glue.h"
PROP_OPTICAL_DISC_NUM_SESSIONS,
PROP_DRIVE_ATA_SMART_IS_AVAILABLE,
- PROP_DRIVE_ATA_SMART_IS_FAILING,
- PROP_DRIVE_ATA_SMART_IS_FAILING_VALID,
- PROP_DRIVE_ATA_SMART_HAS_BAD_SECTORS,
- PROP_DRIVE_ATA_SMART_HAS_BAD_ATTRIBUTES,
- PROP_DRIVE_ATA_SMART_TEMPERATURE_KELVIN,
- PROP_DRIVE_ATA_SMART_POWER_ON_SECONDS,
PROP_DRIVE_ATA_SMART_TIME_COLLECTED,
- PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_STATUS,
- PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_SECONDS,
- PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_STATUS,
- PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_PERCENT_REMAINING,
- PROP_DRIVE_ATA_SMART_SHORT_AND_EXTENDED_SELF_TEST_AVAILABLE,
- PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_AVAILABLE,
- PROP_DRIVE_ATA_SMART_START_SELF_TEST_AVAILABLE,
- PROP_DRIVE_ATA_SMART_ABORT_SELF_TEST_AVAILABLE,
- PROP_DRIVE_ATA_SMART_SHORT_SELF_TEST_POLLING_MINUTES,
- PROP_DRIVE_ATA_SMART_EXTENDED_SELF_TEST_POLLING_MINUTES,
- PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_POLLING_MINUTES,
- PROP_DRIVE_ATA_SMART_ATTRIBUTES,
+ PROP_DRIVE_ATA_SMART_STATUS,
+ PROP_DRIVE_ATA_SMART_BLOB,
PROP_LINUX_MD_COMPONENT_LEVEL,
PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES,
case PROP_DRIVE_ATA_SMART_IS_AVAILABLE:
g_value_set_boolean (value, device->priv->drive_ata_smart_is_available);
break;
- case PROP_DRIVE_ATA_SMART_IS_FAILING:
- g_value_set_boolean (value, device->priv->drive_ata_smart_is_failing);
- break;
- case PROP_DRIVE_ATA_SMART_IS_FAILING_VALID:
- g_value_set_boolean (value, device->priv->drive_ata_smart_is_failing_valid);
- break;
- case PROP_DRIVE_ATA_SMART_HAS_BAD_SECTORS:
- g_value_set_boolean (value, device->priv->drive_ata_smart_has_bad_sectors);
- break;
- case PROP_DRIVE_ATA_SMART_HAS_BAD_ATTRIBUTES:
- g_value_set_boolean (value, device->priv->drive_ata_smart_has_bad_attributes);
- break;
- case PROP_DRIVE_ATA_SMART_TEMPERATURE_KELVIN:
- g_value_set_double (value, device->priv->drive_ata_smart_temperature_kelvin);
- break;
- case PROP_DRIVE_ATA_SMART_POWER_ON_SECONDS:
- g_value_set_uint64 (value, device->priv->drive_ata_smart_power_on_seconds);
- break;
case PROP_DRIVE_ATA_SMART_TIME_COLLECTED:
g_value_set_uint64 (value, device->priv->drive_ata_smart_time_collected);
break;
- case PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_STATUS:
- g_value_set_uint (value, device->priv->drive_ata_smart_offline_data_collection_status);
- break;
- case PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_SECONDS:
- g_value_set_uint (value, device->priv->drive_ata_smart_offline_data_collection_seconds);
- break;
- case PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_STATUS:
- g_value_set_uint (value, device->priv->drive_ata_smart_self_test_execution_status);
- break;
- case PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_PERCENT_REMAINING:
- g_value_set_uint (value, device->priv->drive_ata_smart_self_test_execution_percent_remaining);
- break;
- case PROP_DRIVE_ATA_SMART_SHORT_AND_EXTENDED_SELF_TEST_AVAILABLE:
- g_value_set_boolean (value, device->priv->drive_ata_smart_short_and_extended_self_test_available);
- break;
- case PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_AVAILABLE:
- g_value_set_boolean (value, device->priv->drive_ata_smart_conveyance_self_test_available);
- break;
- case PROP_DRIVE_ATA_SMART_START_SELF_TEST_AVAILABLE:
- g_value_set_boolean (value, device->priv->drive_ata_smart_start_self_test_available);
- break;
- case PROP_DRIVE_ATA_SMART_ABORT_SELF_TEST_AVAILABLE:
- g_value_set_boolean (value, device->priv->drive_ata_smart_abort_self_test_available);
- break;
- case PROP_DRIVE_ATA_SMART_SHORT_SELF_TEST_POLLING_MINUTES:
- g_value_set_uint (value, device->priv->drive_ata_smart_short_self_test_polling_minutes);
- break;
- case PROP_DRIVE_ATA_SMART_EXTENDED_SELF_TEST_POLLING_MINUTES:
- g_value_set_uint (value, device->priv->drive_ata_smart_extended_self_test_polling_minutes);
- break;
- case PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_POLLING_MINUTES:
- g_value_set_uint (value, device->priv->drive_ata_smart_conveyance_self_test_polling_minutes);
+ case PROP_DRIVE_ATA_SMART_STATUS:
+ {
+ const gchar *status;
+ if (device->priv->drive_ata_smart_status == (SkSmartOverall) -1)
+ status = "";
+ else
+ status = sk_smart_overall_to_string (device->priv->drive_ata_smart_status);
+ g_value_set_string (value, status);
+ }
break;
- case PROP_DRIVE_ATA_SMART_ATTRIBUTES:
- g_value_set_boxed (value, device->priv->drive_ata_smart_attributes);
+ case PROP_DRIVE_ATA_SMART_BLOB:
+ {
+ GArray *a;
+ a = g_array_new (FALSE, FALSE, 1);
+ if (device->priv->drive_ata_smart_blob != NULL) {
+ g_array_append_vals (a,
+ device->priv->drive_ata_smart_blob,
+ device->priv->drive_ata_smart_blob_size);
+ }
+ g_value_set_boxed (value, a);
+ g_array_unref (a);
+ }
break;
case PROP_LINUX_MD_COMPONENT_LEVEL:
g_param_spec_boolean ("drive-ata-smart-is-available", NULL, NULL, FALSE, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
- PROP_DRIVE_ATA_SMART_IS_FAILING,
- g_param_spec_boolean ("drive-ata-smart-is-failing", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_IS_FAILING_VALID,
- g_param_spec_boolean ("drive-ata-smart-is-failing-valid", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_HAS_BAD_SECTORS,
- g_param_spec_boolean ("drive-ata-smart-has-bad-sectors", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_HAS_BAD_ATTRIBUTES,
- g_param_spec_boolean ("drive-ata-smart-has-bad-attributes", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_TEMPERATURE_KELVIN,
- g_param_spec_double ("drive-ata-smart-temperature-kelvin", NULL, NULL, 0, G_MAXDOUBLE, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_POWER_ON_SECONDS,
- g_param_spec_uint64 ("drive-ata-smart-power-on-seconds", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
PROP_DRIVE_ATA_SMART_TIME_COLLECTED,
g_param_spec_uint64 ("drive-ata-smart-time-collected", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
- PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_STATUS,
- g_param_spec_uint ("drive-ata-smart-offline-data-collection-status", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_OFFLINE_DATA_COLLECTION_SECONDS,
- g_param_spec_uint ("drive-ata-smart-offline-data-collection-seconds", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_STATUS,
- g_param_spec_uint ("drive-ata-smart-self-test-execution-status", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_SELF_TEST_EXECUTION_PERCENT_REMAINING,
- g_param_spec_uint ("drive-ata-smart-self-test-execution-percent-remaining", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_SHORT_AND_EXTENDED_SELF_TEST_AVAILABLE,
- g_param_spec_boolean ("drive-ata-smart-short-and-extended-self-test-available", NULL, NULL, FALSE, G_PARAM_READABLE));
+ PROP_DRIVE_ATA_SMART_STATUS,
+ g_param_spec_string ("drive-ata-smart-status", NULL, NULL, NULL, G_PARAM_READABLE));
g_object_class_install_property (
object_class,
- PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_AVAILABLE,
- g_param_spec_boolean ("drive-ata-smart-conveyance-self-test-available", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_START_SELF_TEST_AVAILABLE,
- g_param_spec_boolean ("drive-ata-smart-start-self-test-available", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_ABORT_SELF_TEST_AVAILABLE,
- g_param_spec_boolean ("drive-ata-smart-abort-self-test-available", NULL, NULL, FALSE, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_SHORT_SELF_TEST_POLLING_MINUTES,
- g_param_spec_uint ("drive-ata-smart-short-self-test-polling-minutes", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_EXTENDED_SELF_TEST_POLLING_MINUTES,
- g_param_spec_uint ("drive-ata-smart-extended-self-test-polling-minutes", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_CONVEYANCE_SELF_TEST_POLLING_MINUTES,
- g_param_spec_uint ("drive-ata-smart-conveyance-self-test-polling-minutes", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE));
- g_object_class_install_property (
- object_class,
- PROP_DRIVE_ATA_SMART_ATTRIBUTES,
- g_param_spec_boxed ("drive-ata-smart-attributes", NULL, NULL,
- dbus_g_type_get_collection ("GPtrArray", ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE),
+ PROP_DRIVE_ATA_SMART_BLOB,
+ g_param_spec_boxed ("drive-ata-smart-blob", NULL, NULL,
+ dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR),
G_PARAM_READABLE));
device->priv->slaves_objpath = g_ptr_array_new ();
device->priv->holders_objpath = g_ptr_array_new ();
- device->priv->drive_ata_smart_attributes = g_ptr_array_new ();
+ device->priv->drive_ata_smart_status = -1;
}
static void
g_free (device->priv->native_path);
- g_ptr_array_foreach (device->priv->drive_ata_smart_attributes, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (device->priv->drive_ata_smart_attributes, TRUE);
-
for (l = device->priv->polling_inhibitors; l != NULL; l = l->next) {
DevkitDisksInhibitor *inhibitor = DEVKIT_DISKS_INHIBITOR (l->data);
g_signal_handlers_disconnect_by_func (inhibitor, polling_inhibitor_disconnected_cb, device);
g_ptr_array_foreach (device->priv->linux_md_slaves, (GFunc) g_free, NULL);
g_ptr_array_free (device->priv->linux_md_slaves, TRUE);
+ g_free (device->priv->drive_ata_smart_blob);
+
g_free (device->priv->dm_name);
g_ptr_array_foreach (device->priv->slaves_objpath, (GFunc) g_free, NULL);
g_ptr_array_free (device->priv->slaves_objpath, TRUE);
/*--------------------------------------------------------------------------------------------------------------*/
-typedef struct {
- gboolean simulation;
-} DriveRefreshAtaSmartDataData;
-
-static DriveRefreshAtaSmartDataData *
-drive_ata_smart_refresh_data_data_new (gboolean simulation)
-{
- DriveRefreshAtaSmartDataData *data;
- data = g_new0 (DriveRefreshAtaSmartDataData, 1);
- data->simulation = simulation;
- return data;
-}
-
-static void
-drive_ata_smart_refresh_data_unref (DriveRefreshAtaSmartDataData *data)
-{
- g_free (data);
-}
-
-typedef struct
-{
- GPtrArray *attributes;
- gboolean has_bad_attributes;
-
-} AtaSmartCollectAttrsData;
-
-static void
-ata_smart_collect_attrs (SkDisk *d, const SkSmartAttributeParsedData *a, void *user_data)
-{
- AtaSmartCollectAttrsData *data = user_data;
- GValue elem = {0};
- GArray *raw_data;
-
- raw_data = g_array_new (FALSE, TRUE, sizeof (guchar));
- g_array_append_val (raw_data, a->raw[0]);
- g_array_append_val (raw_data, a->raw[1]);
- g_array_append_val (raw_data, a->raw[2]);
- g_array_append_val (raw_data, a->raw[3]);
- g_array_append_val (raw_data, a->raw[4]);
- g_array_append_val (raw_data, a->raw[5]);
-
- g_value_init (&elem, ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE);
- g_value_take_boxed (&elem, dbus_g_type_specialized_construct (ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE));
- dbus_g_type_struct_set (&elem,
- 0, a->id,
- 1, a->name,
- 2, a->flags,
- 3, a->online,
- 4, a->prefailure,
- 5, a->current_value,
- 6, a->current_value_valid,
- 7, a->worst_value,
- 8, a->worst_value_valid,
- 9, a->threshold,
- 10, a->threshold_valid,
- 11, a->good_now,
- 12, a->good_now_valid,
- 13, a->pretty_unit,
- 14, a->pretty_value,
- 15, raw_data,
- G_MAXUINT);
-
- if (!a->good_now && a->good_now_valid && a->prefailure)
- data->has_bad_attributes = TRUE;
-
- g_ptr_array_add (data->attributes, g_value_get_boxed (&elem));
-
- g_array_free (raw_data, TRUE);
-}
-
/* may be called with context==NULL */
static void
drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
const char *stdout,
gpointer user_data)
{
- DriveRefreshAtaSmartDataData *data = user_data;
gint rc;
- SkBool good;
- uint64_t num_bad_sectors;
- uint64_t temperature_mkelvin;
- uint64_t power_on_mseconds;
- const SkSmartParsedData *asd;
SkDisk *d;
- guchar *blob;
+ gchar *blob;
gsize blob_size;
time_t time_collected;
- gboolean is_failing;
- gboolean is_failing_valid;
- AtaSmartCollectAttrsData collect_attrs_data;
- DevkitDisksAtaSmartDb *db;
+ SkSmartOverall overall;
d = NULL;
blob = NULL;
goto out;
}
- blob = g_base64_decode (stdout, &blob_size);
+ blob = (gchar *) g_base64_decode (stdout, &blob_size);
if (sk_disk_open (NULL, &d) != 0) {
if (context != NULL) {
goto out;
}
- if (sk_disk_smart_status (d, &good) != 0) {
- is_failing = FALSE;
- is_failing_valid = FALSE;
- } else {
- is_failing = !good;
- is_failing_valid = TRUE;
- }
- devkit_disks_device_set_drive_ata_smart_is_failing (device, is_failing);
- devkit_disks_device_set_drive_ata_smart_is_failing_valid (device, is_failing_valid);
-
- if (sk_disk_smart_get_bad (d, &num_bad_sectors) != 0) {
- num_bad_sectors = 0;
- }
- devkit_disks_device_set_drive_ata_smart_has_bad_sectors (device, (num_bad_sectors > 0));
-
time_collected = time (NULL);
devkit_disks_device_set_drive_ata_smart_time_collected (device, time_collected);
- if (sk_disk_smart_get_temperature (d, &temperature_mkelvin) != 0) {
- temperature_mkelvin = 0;
- }
- devkit_disks_device_set_drive_ata_smart_temperature_kelvin (device, temperature_mkelvin / 1000.0);
-
- if (sk_disk_smart_get_power_on (d, &power_on_mseconds) != 0) {
- power_on_mseconds = 0;
- }
- devkit_disks_device_set_drive_ata_smart_power_on_seconds (device, power_on_mseconds / 1000);
-
- if (sk_disk_smart_parse (d, &asd) != 0) {
- devkit_disks_device_set_drive_ata_smart_offline_data_collection_status (device, 0);
- devkit_disks_device_set_drive_ata_smart_offline_data_collection_seconds (device, 0);
- devkit_disks_device_set_drive_ata_smart_self_test_execution_status (device, 0);
- devkit_disks_device_set_drive_ata_smart_self_test_execution_percent_remaining (device, 0);
- devkit_disks_device_set_drive_ata_smart_short_and_extended_self_test_available (device, FALSE);
- devkit_disks_device_set_drive_ata_smart_conveyance_self_test_available (device, FALSE);
- devkit_disks_device_set_drive_ata_smart_start_self_test_available (device, FALSE);
- devkit_disks_device_set_drive_ata_smart_abort_self_test_available (device, FALSE);
- devkit_disks_device_set_drive_ata_smart_short_self_test_polling_minutes (device, 0);
- devkit_disks_device_set_drive_ata_smart_extended_self_test_polling_minutes (device, 0);
- devkit_disks_device_set_drive_ata_smart_conveyance_self_test_polling_minutes (device, 0);
- } else {
- devkit_disks_device_set_drive_ata_smart_offline_data_collection_status
- (device, asd->offline_data_collection_status);
- devkit_disks_device_set_drive_ata_smart_offline_data_collection_seconds
- (device, asd->total_offline_data_collection_seconds);
- devkit_disks_device_set_drive_ata_smart_self_test_execution_status
- (device, asd->self_test_execution_status);
- devkit_disks_device_set_drive_ata_smart_self_test_execution_percent_remaining
- (device, asd->self_test_execution_percent_remaining);
- devkit_disks_device_set_drive_ata_smart_short_and_extended_self_test_available
- (device, asd->short_and_extended_test_available);
- devkit_disks_device_set_drive_ata_smart_conveyance_self_test_available
- (device, asd->conveyance_test_available);
- devkit_disks_device_set_drive_ata_smart_start_self_test_available
- (device, asd->start_test_available);
- devkit_disks_device_set_drive_ata_smart_abort_self_test_available
- (device, asd->abort_test_available);
- devkit_disks_device_set_drive_ata_smart_short_self_test_polling_minutes
- (device, asd->short_test_polling_minutes);
- devkit_disks_device_set_drive_ata_smart_extended_self_test_polling_minutes
- (device, asd->extended_test_polling_minutes);
- devkit_disks_device_set_drive_ata_smart_conveyance_self_test_polling_minutes
- (device, asd->conveyance_test_polling_minutes);
- }
-
- collect_attrs_data.attributes = g_ptr_array_new ();
- collect_attrs_data.has_bad_attributes = FALSE;
- if (sk_disk_smart_parse_attributes (d, ata_smart_collect_attrs, &collect_attrs_data) != 0) {
- if (context != NULL)
- throw_error (context,
- DEVKIT_DISKS_ERROR_FAILED,
- "Error parsing ATA SMART attributes: %m");
- g_ptr_array_free (collect_attrs_data.attributes, TRUE);
- goto out;
- }
-
- devkit_disks_device_set_drive_ata_smart_has_bad_attributes (device, collect_attrs_data.has_bad_attributes);
- devkit_disks_device_set_drive_ata_smart_attributes_steal (device, collect_attrs_data.attributes);
+ if (sk_disk_smart_get_overall (d, &overall) != 0)
+ overall = -1;
+ devkit_disks_device_set_drive_ata_smart_status (device, overall);
+ devkit_disks_device_set_drive_ata_smart_blob_steal (device, blob, blob_size);
+ blob = NULL;
/* emit change event since we've updated the smart data */
drain_pending_changes (device, FALSE);
if (context != NULL)
dbus_g_method_return (context);
- /* store the (time_collected, disk_id, blob) tupple in our database if not simulating */
- if (!data->simulation) {
- db = devkit_disks_daemon_local_get_ata_smart_db (device->priv->daemon);
- devkit_disks_ata_smart_db_add_entry (db,
- device,
- time_collected,
- is_failing,
- is_failing_valid,
- (num_bad_sectors > 0),
- collect_attrs_data.has_bad_attributes,
- temperature_mkelvin / 1000.0,
- power_on_mseconds / 1000,
- blob,
- blob_size);
- }
-
out:
g_free (blob);
if (d != NULL)
argv,
NULL,
drive_ata_smart_refresh_data_completed_cb,
- drive_ata_smart_refresh_data_data_new (simuldata != NULL),
- (GDestroyNotify) drive_ata_smart_refresh_data_unref)) {
+ NULL,
+ NULL)) {
goto out;
}
/*--------------------------------------------------------------------------------------------------------------*/
-static gboolean
-ata_smart_historical_data_cb (time_t time_collected,
- gboolean is_failing,
- gboolean is_failing_valid,
- gboolean has_bad_sectors,
- gboolean has_bad_attributes,
- gdouble temperature_kelvin,
- guint64 power_on_seconds,
- const void *blob,
- gsize blob_size,
- gpointer user_data)
-{
- GPtrArray *array = user_data;
- GValue elem = {0};
- SkDisk *d;
- AtaSmartCollectAttrsData collect_attrs_data;
-
- d = NULL;
-
- if (sk_disk_open (NULL, &d) != 0) {
- g_warning ("Unable to open a SkDisk");
- goto out;
- }
-
- if (sk_disk_set_blob (d, blob, blob_size) != 0) {
- g_warning ("Error parsing blob: %s", strerror (errno));
- goto out;
- }
-
- collect_attrs_data.attributes = g_ptr_array_new ();
- collect_attrs_data.has_bad_attributes = FALSE;
- if (sk_disk_smart_parse_attributes (d, ata_smart_collect_attrs, &collect_attrs_data) != 0) {
- g_warning ("Error parsing ATA SMART attributes: %m");
- }
-
- g_value_init (&elem, ATA_SMART_HISTORICAL_SMART_DATA_STRUCT_TYPE);
- g_value_take_boxed (&elem, dbus_g_type_specialized_construct (ATA_SMART_HISTORICAL_SMART_DATA_STRUCT_TYPE));
- dbus_g_type_struct_set (&elem,
- 0, time_collected,
- 1, is_failing,
- 2, is_failing_valid,
- 3, has_bad_sectors,
- 4, has_bad_attributes,
- 5, temperature_kelvin,
- 6, power_on_seconds,
- 7, collect_attrs_data.attributes,
- G_MAXUINT);
-
- g_ptr_array_foreach (collect_attrs_data.attributes, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (collect_attrs_data.attributes, TRUE);
-
- g_ptr_array_add (array, g_value_get_boxed (&elem));
-
- out:
- if (d != NULL)
- sk_disk_free (d);
- return FALSE;
-}
-
-static void
-devkit_disks_device_drive_ata_smart_get_historical_data_authorized_cb (DevkitDisksDaemon *daemon,
- DevkitDisksDevice *device,
- DBusGMethodInvocation *context,
- const gchar *action_id,
- guint num_user_data,
- gpointer *user_data_elements)
-{
- guint64 since = *((guint64*) user_data_elements[0]);
- guint64 until = *((guint64*) user_data_elements[1]);
- guint64 spacing = *((guint64*) user_data_elements[2]);
- GPtrArray *array;
- DevkitDisksAtaSmartDb *db;
-
- db = devkit_disks_daemon_local_get_ata_smart_db (device->priv->daemon);
-
- array = g_ptr_array_new ();
-
- devkit_disks_ata_smart_db_get_entries (db,
- device,
- since,
- until,
- spacing,
- ata_smart_historical_data_cb,
- array);
-
- dbus_g_method_return (context, array);
-
- g_ptr_array_foreach (array, (GFunc) g_value_array_free, NULL);
- g_ptr_array_free (array, TRUE);
-}
-
-gboolean
-devkit_disks_device_drive_ata_smart_get_historical_data (DevkitDisksDevice *device,
- guint64 since,
- guint64 until,
- guint64 spacing,
- DBusGMethodInvocation *context)
-{
- if (!device->priv->drive_ata_smart_is_available) {
- throw_error (context,
- DEVKIT_DISKS_ERROR_FAILED,
- "Device does not support ATA SMART");
- goto out;
- }
-
- if (until == 0)
- until = time (NULL);
-
- if (since > until) {
- throw_error (context, DEVKIT_DISKS_ERROR_FAILED, "Malformed time range (since > until)");
- goto out;
- }
-
- devkit_disks_daemon_local_check_auth (device->priv->daemon,
- device,
- "org.freedesktop.devicekit.disks.drive-ata-smart-retrieve-historical-data",
- "DriveAtaSmartGetHistoricalData",
- TRUE,
- devkit_disks_device_drive_ata_smart_get_historical_data_authorized_cb,
- context,
- 3,
- g_memdup (&since, sizeof (guint64)), g_free,
- g_memdup (&until, sizeof (guint64)), g_free,
- g_memdup (&spacing, sizeof (guint64)), g_free);
-
- out:
- return TRUE;
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------*/
-
static void
drive_ata_smart_initiate_selftest_completed_cb (DBusGMethodInvocation *context,
DevkitDisksDevice *device,
int n;
char *argv[10];
GError *error;
+ const gchar *job_name;
+
+ if (g_strcmp0 (test, "short") == 0) {
+ job_name = "DriveAtaSmartSelftestShort";
+ } else if (g_strcmp0 (test, "extended") == 0) {
+ job_name = "DriveAtaSmartSelftestExtended";
+ } else if (g_strcmp0 (test, "conveyance") == 0) {
+ job_name = "DriveAtaSmartSelftestConveyance";
+ } else {
+ throw_error (context,
+ DEVKIT_DISKS_ERROR_FAILED,
+ "Malformed test");
+ goto out;
+ }
n = 0;
argv[n++] = PACKAGE_LIBEXEC_DIR "/devkit-disks-helper-ata-smart-selftest";
error = NULL;
if (!job_new (context,
- "DriveAtaSmartInitiateSelftest",
+ job_name,
TRUE,
device,
argv,
## Process this file with automake to produce Makefile.in
+NULL =
+
INCLUDES = \
-I$(top_builddir)/src -I$(top_srcdir)/src \
-DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
$(DISABLE_DEPRECATED) \
$(AM_CPPFLAGS)
+devkit_disks_CFLAGS = \
+ $(LIBATASMART_CFLAGS) \
+ $(NULL)
+
devkit_disks_LDADD = \
+ $(LIBATASMART_LIBS) \
$(DBUS_GLIB_LIBS) \
$(POLKIT_DBUS_LIBS)
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include <atasmart.h>
+
#include "devkit-disks-daemon-glue.h"
#include "devkit-disks-device-glue.h"
#include "devkit-disks-marshal.h"
double job_percentage)
{
if (job_in_progress) {
- g_print (" job underway: %s", job_id);
+ g_print (" job underway: %s", job_id);
if (job_percentage >= 0)
g_print (", %3.0lf%% complete", job_percentage);
if (job_is_cancellable)
g_print (", initiated by uid %d", job_initiated_by_uid);
g_print ("\n");
} else {
- g_print (" job underway: no\n");
+ g_print (" job underway: no\n");
}
}
g_print ("removed: %s\n", object_path);
}
-#define ATA_SMART_ATTRIBUTE_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
- G_TYPE_UINT, \
- G_TYPE_STRING, \
- G_TYPE_UINT, \
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_UCHAR, G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
- G_TYPE_UINT, G_TYPE_UINT64, \
- dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), \
- G_TYPE_INVALID))
-
-#define ATA_SMART_HISTORICAL_SMART_DATA_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
- G_TYPE_UINT64, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_BOOLEAN, \
- G_TYPE_DOUBLE, \
- G_TYPE_UINT64, \
- dbus_g_type_get_collection ("GPtrArray", ATA_SMART_DATA_ATTRIBUTE_STRUCT_TYPE), \
- G_TYPE_INVALID))
-
#define LSOF_DATA_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \
G_TYPE_UINT, \
G_TYPE_UINT, \
guint optical_disc_num_sessions;
gboolean drive_ata_smart_is_available;
- gboolean drive_ata_smart_is_failing;
- gboolean drive_ata_smart_is_failing_valid;
- gboolean drive_ata_smart_has_bad_sectors;
- gboolean drive_ata_smart_has_bad_attributes;
- gdouble drive_ata_smart_temperature_kelvin;
- guint64 drive_ata_smart_power_on_seconds;
guint64 drive_ata_smart_time_collected;
- guint drive_ata_smart_offline_data_collection_status;
- guint drive_ata_smart_offline_data_collection_seconds;
- guint drive_ata_smart_self_test_execution_status;
- guint drive_ata_smart_self_test_execution_percent_remaining;
- gboolean drive_ata_smart_short_and_extended_self_test_available;
- gboolean drive_ata_smart_conveyance_self_test_available;
- gboolean drive_ata_smart_start_self_test_available;
- gboolean drive_ata_smart_abort_self_test_available;
- guint drive_ata_smart_short_self_test_polling_minutes;
- guint drive_ata_smart_extended_self_test_polling_minutes;
- guint drive_ata_smart_conveyance_self_test_polling_minutes;
- GValue drive_ata_smart_attributes;
+ gchar *drive_ata_smart_status;
+ gchar *drive_ata_smart_blob;
+ gsize drive_ata_smart_blob_size;
char *linux_md_component_level;
int linux_md_component_num_raid_devices;
else if (strcmp (key, "drive-ata-smart-is-available") == 0)
props->drive_ata_smart_is_available = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-is-failing") == 0)
- props->drive_ata_smart_is_failing = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-is-failing-valid") == 0)
- props->drive_ata_smart_is_failing_valid = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-has-bad-sectors") == 0)
- props->drive_ata_smart_has_bad_sectors = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-has-bad-attributes") == 0)
- props->drive_ata_smart_has_bad_attributes = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-temperature-kelvin") == 0)
- props->drive_ata_smart_temperature_kelvin = g_value_get_double (value);
- else if (strcmp (key, "drive-ata-smart-power-on-seconds") == 0)
- props->drive_ata_smart_power_on_seconds = g_value_get_uint64 (value);
else if (strcmp (key, "drive-ata-smart-time-collected") == 0)
props->drive_ata_smart_time_collected = g_value_get_uint64 (value);
- else if (strcmp (key, "drive-ata-smart-offline-data-collection-status") == 0)
- props->drive_ata_smart_offline_data_collection_status = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-offline-data-collection-seconds") == 0)
- props->drive_ata_smart_offline_data_collection_seconds = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-self-test-execution-status") == 0)
- props->drive_ata_smart_self_test_execution_status = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-self-test-execution-percent-remaining") == 0)
- props->drive_ata_smart_self_test_execution_percent_remaining = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-short-and-extended-self-test-available") == 0)
- props->drive_ata_smart_short_and_extended_self_test_available = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-conveyance-self-test-available") == 0)
- props->drive_ata_smart_conveyance_self_test_available = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-start-self-test-available") == 0)
- props->drive_ata_smart_start_self_test_available = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-abort-self-test-available") == 0)
- props->drive_ata_smart_abort_self_test_available = g_value_get_boolean (value);
- else if (strcmp (key, "drive-ata-smart-short-self-test-polling-minutes") == 0)
- props->drive_ata_smart_short_self_test_polling_minutes = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-extended-self-test-polling-minutes") == 0)
- props->drive_ata_smart_extended_self_test_polling_minutes = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-conveyance-self-test-polling-minutes") == 0)
- props->drive_ata_smart_conveyance_self_test_polling_minutes = g_value_get_uint (value);
- else if (strcmp (key, "drive-ata-smart-attributes") == 0) {
- g_value_copy (value, &(props->drive_ata_smart_attributes));
+ else if (strcmp (key, "drive-ata-smart-status") == 0)
+ props->drive_ata_smart_status = g_strdup (g_value_get_string (value));
+ else if (strcmp (key, "drive-ata-smart-blob") == 0) {
+ GArray *a = g_value_get_boxed (value);
+ g_free (props->drive_ata_smart_blob);
+ props->drive_ata_smart_blob = g_memdup (a->data, a->len);
+ props->drive_ata_smart_blob_size = a->len;
}
else if (strcmp (key, "linux-md-component-level") == 0)
g_strfreev (props->drive_media_compatibility);
g_free (props->drive_media);
- g_value_unset (&(props->drive_ata_smart_attributes));
+ g_free (props->drive_ata_smart_status);
+ g_free (props->drive_ata_smart_blob);
g_free (props->linux_md_component_level);
g_free (props->linux_md_component_uuid);
const char *ifname = "org.freedesktop.DeviceKit.Disks.Device";
props = g_new0 (DeviceProperties, 1);
- g_value_init (&(props->drive_ata_smart_attributes),
- dbus_g_type_get_collection ("GPtrArray", ATA_SMART_ATTRIBUTE_STRUCT_TYPE));
prop_proxy = dbus_g_proxy_new_for_name (bus,
"org.freedesktop.DeviceKit.Disks",
return FALSE;
}
-static const gchar *
-print_available (gboolean available)
+static gboolean
+has_colors (void)
{
- if (available)
- return "available";
- else
- return "not available";
-}
+ static gboolean ret = FALSE;
+ static gboolean checked = FALSE;
-static const gchar *
-get_ata_smart_offline_status (guint offline_status)
-{
- const gchar *ret;
-
- switch (offline_status) {
- case 0: ret = "never collected"; break;
- case 1: ret = "successful"; break;
- case 2: ret = "in progress"; break;
- case 3: ret = "suspended"; break;
- case 4: ret = "aborted"; break;
- case 5: ret = "fatal"; break;
- default: ret = "unknown"; break;
+ if (checked)
+ return ret;
+
+ if (isatty (STDOUT_FILENO)) {
+ ret = TRUE;
}
+ checked = TRUE;
+
return ret;
}
+static void
+begin_highlight (void)
+{
+ if (has_colors ())
+ g_print ("\x1B[1;31m");
+}
+
+static void
+end_highlight (void)
+{
+ if (has_colors ())
+ g_print ("\x1B[0m");
+}
+
static const gchar *
-get_ata_smart_self_test_status (guint self_test_status)
+ata_smart_status_to_desc (const gchar *status,
+ gboolean *out_highlight)
{
- const gchar *ret;
-
- switch (self_test_status) {
- case 0: ret = "success or never"; break;
- case 1: ret = "aborted"; break;
- case 2: ret = "interrupted"; break;
- case 3: ret = "fatal"; break;
- case 4: ret = "error (unknown)"; break;
- case 5: ret = "error (electrical)"; break;
- case 6: ret = "error (servo)"; break;
- case 7: ret = "error (read)"; break;
- case 8: ret = "error (handling)"; break;
- case 15: ret = "in progress"; break;
- default: ret = "unknown"; break;
+ const gchar *desc;
+ gboolean highlight;
+
+ highlight = FALSE;
+ if (g_strcmp0 (status, "GOOD") == 0) {
+ desc = "Good";
+ } else if (g_strcmp0 (status, "BAD_ATTRIBUTE_IN_THE_PAST") == 0) {
+ desc = "Disk was used outside of design parameters in the past";
+ } else if (g_strcmp0 (status, "BAD_SECTOR") == 0) {
+ desc = "Disk has a few bad sectors";
+ } else if (g_strcmp0 (status, "BAD_ATTRIBUTE_NOW") == 0) {
+ desc = "Disk is being used outside of design parameters";
+ highlight = TRUE;
+ } else if (g_strcmp0 (status, "BAD_SECTOR_MANY") == 0) {
+ desc = "Disk reports many bad sectors";
+ highlight = TRUE;
+ } else if (g_strcmp0 (status, "BAD_STATUS") == 0) {
+ desc = "Disk failure is imminent";
+ highlight = TRUE;
+ } else {
+ desc = status;
}
- return ret;
+ if (out_highlight != NULL)
+ *out_highlight = highlight;
+
+ return desc;
}
static gchar *
switch (unit) {
default:
- case 0:
- case 1:
+ case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN:
+ case SK_SMART_ATTRIBUTE_UNIT_NONE:
ret = g_strdup_printf ("%" G_GUINT64_FORMAT, pretty_value);
break;
- case 2:
+ case SK_SMART_ATTRIBUTE_UNIT_MSECONDS:
if (pretty_value > 1000 * 60 * 60 * 24) {
- ret = g_strdup_printf ("%.3g days", pretty_value / 1000.0 / 60.0 / 60.0 / 24.0);
+ ret = g_strdup_printf ("%3.1f days", pretty_value / 1000.0 / 60.0 / 60.0 / 24.0);
} else if (pretty_value > 1000 * 60 * 60) {
- ret = g_strdup_printf ("%.3g hours", pretty_value / 1000.0 / 60.0 / 60.0);
+ ret = g_strdup_printf ("%3.1f hours", pretty_value / 1000.0 / 60.0 / 60.0);
} else if (pretty_value > 1000 * 60) {
- ret = g_strdup_printf ("%.3g mins", pretty_value / 1000.0 / 60.0);
+ ret = g_strdup_printf ("%3.1f mins", pretty_value / 1000.0 / 60.0);
} else if (pretty_value > 1000) {
- ret = g_strdup_printf ("%.3g secs", pretty_value / 1000.0);
+ ret = g_strdup_printf ("%3.1f secs", pretty_value / 1000.0);
} else {
ret = g_strdup_printf ("%d msec", (gint) pretty_value);
}
break;
- case 3:
+ case SK_SMART_ATTRIBUTE_UNIT_SECTORS:
ret = g_strdup_printf ("%" G_GUINT64_FORMAT " sectors", pretty_value);
break;
- case 4:
+ case SK_SMART_ATTRIBUTE_UNIT_MKELVIN:
ret = g_strdup_printf ("%.3gC / %.3gF",
pretty_value / 1000.0 - 273.15,
(pretty_value / 1000.0 - 273.15) * 9.0 / 5.0 + 32.0);
return ret;
}
-static gboolean
-has_colors (void)
+static void
+print_ata_smart_attr (SkDisk *d, const SkSmartAttributeParsedData *a, void *user_data)
{
- static gboolean ret = FALSE;
- static gboolean checked = FALSE;
-
- if (checked)
- return ret;
-
- if (isatty (STDOUT_FILENO)) {
- ret = TRUE;
+ const gchar *assessment;
+ const gchar *type;
+ const gchar *updates;
+ gchar *current_str;
+ gchar *worst_str;
+ gchar *threshold_str;
+ gchar *pretty;
+
+ pretty = get_ata_smart_unit (a->pretty_unit, a->pretty_value);
+
+ if (!a->good_now_valid) {
+ assessment = " n/a ";
+ } else {
+ if (!a->good_now) {
+ assessment = " FAIL ";
+ } else {
+ if (a->good_in_the_past_valid && !a->good_in_the_past) {
+ assessment = "FAIL_PAST";
+ } else {
+ assessment = " good ";
+ }
+ }
}
- checked = TRUE;
+ if (a->online)
+ updates = "Online ";
+ else
+ updates = "Offline";
- return ret;
-}
+ if (a->prefailure)
+ type = "Pre-fail";
+ else
+ type = "Old-age ";
-static void
-begin_highlight (void)
-{
- if (has_colors ())
- g_print ("\x1B[1;31m");
-}
+ if (a->current_value_valid)
+ current_str = g_strdup_printf ("%3d", a->current_value);
+ else
+ current_str = g_strdup ("n/a");
-static void
-end_highlight (void)
-{
- if (has_colors ())
- g_print ("\x1B[0m");
+ if (a->worst_value_valid)
+ worst_str = g_strdup_printf ("%3d", a->worst_value);
+ else
+ worst_str = g_strdup ("n/a");
+
+ if (a->threshold_valid)
+ threshold_str = g_strdup_printf ("%3d", a->threshold);
+ else
+ threshold_str = g_strdup ("n/a");
+
+ if (a->warn)
+ begin_highlight ();
+
+ g_print (" %-27s %s|%s|%s %s %-11s %s %s\n",
+ a->name,
+ current_str,
+ worst_str,
+ threshold_str,
+ assessment,
+ pretty,
+ type,
+ updates);
+
+ if (a->warn)
+ end_highlight ();
+
+ g_free (current_str);
+ g_free (worst_str);
+ g_free (threshold_str);
+ g_free (pretty);
}
static void
do_show_info (const char *object_path)
{
guint n;
- guint m;
DeviceProperties *props;
struct tm *time_tm;
time_t time;
strftime (time_buf, sizeof time_buf, "%c", time_tm);
g_print ("Showing information for %s\n", object_path);
- g_print (" native-path: %s\n", props->native_path);
- g_print (" device: %" G_GINT64_MODIFIER "d:%" G_GINT64_MODIFIER "d\n",
+ g_print (" native-path: %s\n", props->native_path);
+ g_print (" device: %" G_GINT64_MODIFIER "d:%" G_GINT64_MODIFIER "d\n",
props->device_major,
props->device_minor);
- g_print (" device-file: %s\n", props->device_file);
+ g_print (" device-file: %s\n", props->device_file);
for (n = 0; props->device_file_by_id[n] != NULL; n++)
- g_print (" by-id: %s\n", (char *) props->device_file_by_id[n]);
+ g_print (" by-id: %s\n", (char *) props->device_file_by_id[n]);
for (n = 0; props->device_file_by_path[n] != NULL; n++)
- g_print (" by-path: %s\n", (char *) props->device_file_by_path[n]);
- g_print (" detected at: %s\n", time_buf);
- g_print (" system internal: %d\n", props->device_is_system_internal);
- g_print (" removable: %d\n", props->device_is_removable);
- g_print (" has media: %d", props->device_is_media_available);
+ g_print (" by-path: %s\n", (char *) props->device_file_by_path[n]);
+ g_print (" detected at: %s\n", time_buf);
+ g_print (" system internal: %d\n", props->device_is_system_internal);
+ g_print (" removable: %d\n", props->device_is_removable);
+ g_print (" has media: %d", props->device_is_media_available);
if (props->device_media_detection_time != 0) {
time = (time_t) props->device_media_detection_time;
time_tm = localtime (&time);
g_print (" (detected at %s)", time_buf);
}
g_print ("\n");
- g_print (" detects change: %d\n", props->device_is_media_change_detected);
- g_print (" detection by polling: %d\n", props->device_is_media_change_detection_polling);
- g_print (" detection inhibitable: %d\n", props->device_is_media_change_detection_inhibitable);
- g_print (" detection inhibited: %d\n", props->device_is_media_change_detection_inhibited);
- g_print (" is read only: %d\n", props->device_is_read_only);
- g_print (" is mounted: %d\n", props->device_is_mounted);
+ g_print (" detects change: %d\n", props->device_is_media_change_detected);
+ g_print (" detection by polling: %d\n", props->device_is_media_change_detection_polling);
+ g_print (" detection inhibitable: %d\n", props->device_is_media_change_detection_inhibitable);
+ g_print (" detection inhibited: %d\n", props->device_is_media_change_detection_inhibited);
+ g_print (" is read only: %d\n", props->device_is_read_only);
+ g_print (" is mounted: %d\n", props->device_is_mounted);
g_print (" mount paths: ");
for (n = 0; props->device_mount_paths != NULL && props->device_mount_paths[n] != NULL; n++) {
if (n != 0)
g_print ("%s", props->device_mount_paths[n]);
}
g_print ("\n");
- g_print (" mounted by uid: %d\n", props->device_mounted_by_uid);
- g_print (" presentation hide: %d\n", props->device_presentation_hide);
- g_print (" presentation nopolicy: %d\n", props->device_presentation_nopolicy);
- g_print (" presentation name: %s\n", props->device_presentation_name);
- g_print (" presentation icon: %s\n", props->device_presentation_icon_name);
- g_print (" size: %" G_GUINT64_FORMAT "\n", props->device_size);
- g_print (" block size: %" G_GUINT64_FORMAT "\n", props->device_block_size);
+ g_print (" mounted by uid: %d\n", props->device_mounted_by_uid);
+ g_print (" presentation hide: %d\n", props->device_presentation_hide);
+ g_print (" presentation nopolicy: %d\n", props->device_presentation_nopolicy);
+ g_print (" presentation name: %s\n", props->device_presentation_name);
+ g_print (" presentation icon: %s\n", props->device_presentation_icon_name);
+ g_print (" size: %" G_GUINT64_FORMAT "\n", props->device_size);
+ g_print (" block size: %" G_GUINT64_FORMAT "\n", props->device_block_size);
print_job (props->job_in_progress,
props->job_id,
props->job_initiated_by_uid,
props->job_is_cancellable,
props->job_percentage);
- g_print (" usage: %s\n", props->id_usage);
- g_print (" type: %s\n", props->id_type);
- g_print (" version: %s\n", props->id_version);
- g_print (" uuid: %s\n", props->id_uuid);
- g_print (" label: %s\n", props->id_label);
+ g_print (" usage: %s\n", props->id_usage);
+ g_print (" type: %s\n", props->id_type);
+ g_print (" version: %s\n", props->id_version);
+ g_print (" uuid: %s\n", props->id_uuid);
+ g_print (" label: %s\n", props->id_label);
if (props->device_is_linux_md_component) {
g_print (" linux md component:\n");
- g_print (" RAID level: %s\n", props->linux_md_component_level);
- g_print (" num comp: %d\n", props->linux_md_component_num_raid_devices);
- g_print (" uuid: %s\n", props->linux_md_component_uuid);
- g_print (" home host: %s\n", props->linux_md_component_home_host);
- g_print (" name: %s\n", props->linux_md_component_name);
- g_print (" version: %s\n", props->linux_md_component_version);
- g_print (" holder: %s\n",
+ g_print (" RAID level: %s\n", props->linux_md_component_level);
+ g_print (" num comp: %d\n", props->linux_md_component_num_raid_devices);
+ g_print (" uuid: %s\n", props->linux_md_component_uuid);
+ g_print (" home host: %s\n", props->linux_md_component_home_host);
+ g_print (" name: %s\n", props->linux_md_component_name);
+ g_print (" version: %s\n", props->linux_md_component_version);
+ g_print (" holder: %s\n",
g_strcmp0 (props->linux_md_component_holder, "/") == 0 ? "(none)" : props->linux_md_component_holder);
- g_print (" state: ");
+ g_print (" state: ");
for (n = 0;
props->linux_md_component_state != NULL && props->linux_md_component_state[n] != NULL;
n++) {
}
if (props->device_is_linux_md) {
g_print (" linux md:\n");
- g_print (" state: %s\n", props->linux_md_state);
- g_print (" RAID level: %s\n", props->linux_md_level);
- g_print (" uuid: %s\n", props->linux_md_uuid);
- g_print (" home host: %s\n", props->linux_md_home_host);
- g_print (" name: %s\n", props->linux_md_name);
- g_print (" num comp: %d\n", props->linux_md_num_raid_devices);
- g_print (" version: %s\n", props->linux_md_version);
- g_print (" degraded: %d\n", props->linux_md_is_degraded);
- g_print (" sync action: %s\n", props->linux_md_sync_action);
+ g_print (" state: %s\n", props->linux_md_state);
+ g_print (" RAID level: %s\n", props->linux_md_level);
+ g_print (" uuid: %s\n", props->linux_md_uuid);
+ g_print (" home host: %s\n", props->linux_md_home_host);
+ g_print (" name: %s\n", props->linux_md_name);
+ g_print (" num comp: %d\n", props->linux_md_num_raid_devices);
+ g_print (" version: %s\n", props->linux_md_version);
+ g_print (" degraded: %d\n", props->linux_md_is_degraded);
+ g_print (" sync action: %s\n", props->linux_md_sync_action);
if (strcmp (props->linux_md_sync_action, "idle") != 0) {
- g_print (" complete: %3.01f%%\n", props->linux_md_sync_percentage);
- g_print (" speed: %" G_GINT64_FORMAT " bytes/sec\n", props->linux_md_sync_speed);
+ g_print (" complete: %3.01f%%\n", props->linux_md_sync_percentage);
+ g_print (" speed: %" G_GINT64_FORMAT " bytes/sec\n", props->linux_md_sync_speed);
}
g_print (" slaves:\n");
for (n = 0; props->linux_md_slaves[n] != NULL; n++)
- g_print (" %s\n", props->linux_md_slaves[n]);
+ g_print (" %s\n", props->linux_md_slaves[n]);
}
if (props->device_is_luks) {
g_print (" luks device:\n");
- g_print (" holder: %s\n", props->luks_holder);
+ g_print (" holder: %s\n", props->luks_holder);
}
if (props->device_is_luks_cleartext) {
g_print (" cleartext luks device:\n");
- g_print (" backed by: %s\n", props->luks_cleartext_slave);
- g_print (" unlocked by: uid %d\n", props->luks_cleartext_unlocked_by_uid);
+ g_print (" backed by: %s\n", props->luks_cleartext_slave);
+ g_print (" unlocked by: uid %d\n", props->luks_cleartext_unlocked_by_uid);
}
if (props->device_is_partition_table) {
g_print (" partition table:\n");
- g_print (" scheme: %s\n", props->partition_table_scheme);
- g_print (" count: %d\n", props->partition_table_count);
+ g_print (" scheme: %s\n", props->partition_table_scheme);
+ g_print (" count: %d\n", props->partition_table_count);
}
if (props->device_is_partition) {
g_print (" partition:\n");
- g_print (" part of: %s\n", props->partition_slave);
- g_print (" scheme: %s\n", props->partition_scheme);
- g_print (" number: %d\n", props->partition_number);
- g_print (" type: %s\n", props->partition_type);
+ g_print (" part of: %s\n", props->partition_slave);
+ g_print (" scheme: %s\n", props->partition_scheme);
+ g_print (" number: %d\n", props->partition_number);
+ g_print (" type: %s\n", props->partition_type);
g_print (" flags: ");
for (n = 0; props->partition_flags[n] != NULL; n++)
g_print (" %s", (char *) props->partition_flags[n]);
g_print ("\n");
- g_print (" offset: %" G_GINT64_FORMAT "\n", props->partition_offset);
- g_print (" size: %" G_GINT64_FORMAT "\n", props->partition_size);
- g_print (" label: %s\n", props->partition_label);
- g_print (" uuid: %s\n", props->partition_uuid);
+ g_print (" offset: %" G_GINT64_FORMAT "\n", props->partition_offset);
+ g_print (" size: %" G_GINT64_FORMAT "\n", props->partition_size);
+ g_print (" label: %s\n", props->partition_label);
+ g_print (" uuid: %s\n", props->partition_uuid);
}
if (props->device_is_optical_disc) {
g_print (" optical disc:\n");
- g_print (" blank: %d\n", props->optical_disc_is_blank);
- g_print (" appendable: %d\n", props->optical_disc_is_appendable);
- g_print (" closed: %d\n", props->optical_disc_is_closed);
- g_print (" num tracks: %d\n", props->optical_disc_num_tracks);
- g_print (" num audio tracks: %d\n", props->optical_disc_num_audio_tracks);
- g_print (" num sessions: %d\n", props->optical_disc_num_sessions);
+ g_print (" blank: %d\n", props->optical_disc_is_blank);
+ g_print (" appendable: %d\n", props->optical_disc_is_appendable);
+ g_print (" closed: %d\n", props->optical_disc_is_closed);
+ g_print (" num tracks: %d\n", props->optical_disc_num_tracks);
+ g_print (" num audio tracks: %d\n", props->optical_disc_num_audio_tracks);
+ g_print (" num sessions: %d\n", props->optical_disc_num_sessions);
}
if (props->device_is_drive) {
g_print (" drive:\n");
- g_print (" vendor: %s\n", props->drive_vendor);
- g_print (" model: %s\n", props->drive_model);
- g_print (" revision: %s\n", props->drive_revision);
- g_print (" serial: %s\n", props->drive_serial);
- g_print (" detachable: %d\n", props->drive_can_detach);
- g_print (" can spindown: %d\n", props->drive_can_spindown);
- g_print (" rotational media: %d\n", props->drive_is_rotational);
- g_print (" ejectable: %d\n", props->drive_is_media_ejectable);
- g_print (" media: %s\n", props->drive_media);
- g_print (" compat: ");
+ g_print (" vendor: %s\n", props->drive_vendor);
+ g_print (" model: %s\n", props->drive_model);
+ g_print (" revision: %s\n", props->drive_revision);
+ g_print (" serial: %s\n", props->drive_serial);
+ g_print (" detachable: %d\n", props->drive_can_detach);
+ g_print (" can spindown: %d\n", props->drive_can_spindown);
+ g_print (" rotational media: %d\n", props->drive_is_rotational);
+ g_print (" ejectable: %d\n", props->drive_is_media_ejectable);
+ g_print (" media: %s\n", props->drive_media);
+ g_print (" compat: ");
for (n = 0; props->drive_media_compatibility[n] != NULL; n++)
g_print (" %s", (char *) props->drive_media_compatibility[n]);
g_print ("\n");
if (props->drive_connection_interface == NULL || strlen (props->drive_connection_interface) == 0)
- g_print (" interface: (unknown)\n");
+ g_print (" interface: (unknown)\n");
else
- g_print (" interface: %s\n", props->drive_connection_interface);
+ g_print (" interface: %s\n", props->drive_connection_interface);
if (props->drive_connection_speed == 0)
- g_print (" if speed: (unknown)\n");
+ g_print (" if speed: (unknown)\n");
else
- g_print (" if speed: %" G_GINT64_FORMAT " bits/s\n", props->drive_connection_speed);
+ g_print (" if speed: %" G_GINT64_FORMAT " bits/s\n", props->drive_connection_speed);
/* ------------------------------------------------------------------------------------------------- */
if (!props->drive_ata_smart_is_available) {
- g_print (" ATA SMART: not available\n");
+ g_print (" ATA SMART: not available\n");
} else if (props->drive_ata_smart_time_collected == 0) {
- g_print (" ATA SMART: Data not collected\n");
+ g_print (" ATA SMART: Data not collected\n");
} else {
- GPtrArray *p;
+ SkDisk *d;
time = (time_t) props->drive_ata_smart_time_collected;
time_tm = localtime (&time);
strftime (time_buf, sizeof time_buf, "%c", time_tm);
- g_print (" ATA SMART: Updated at %s\n", time_buf);
- if (props->drive_ata_smart_is_failing_valid) {
- if (!props->drive_ata_smart_is_failing)
- g_print (" assessment: PASSED\n");
- else {
- g_print (" assessment: ");
- begin_highlight ();
- g_print ("FAILING");
- end_highlight ();
- g_print ("\n");
- }
-
- } else {
- g_print (" assessment: Unknown\n");
- }
-
- if (props->drive_ata_smart_has_bad_sectors) {
- begin_highlight ();
- g_print (" bad sectors: Yes\n");
- end_highlight ();
- } else {
- g_print (" bad sectors: None\n");
- }
-
- if (props->drive_ata_smart_has_bad_attributes) {
- begin_highlight ();
- g_print (" attributes: One ore more attributes exceed threshold\n");
- end_highlight ();
- } else {
- g_print (" attributes: Within threshold\n");
- }
+ g_print (" ATA SMART: Updated at %s\n", time_buf);
- if (props->drive_ata_smart_temperature_kelvin < 0.1) {
- g_print (" temperature: Unknown\n");
+ if (props->drive_ata_smart_status == NULL || strlen (props->drive_ata_smart_status) == 0) {
+ g_print (" overall assessment: UNKNOWN\n");
} else {
- gdouble celcius;
- gdouble fahrenheit;
- celcius = props->drive_ata_smart_temperature_kelvin - 273.15;
- fahrenheit = 9.0 * celcius / 5.0 + 32.0;
- g_print (" temperature: %.3g\302\260 C / %.3g\302\260 F\n", celcius, fahrenheit);
- }
-
- if (props->drive_ata_smart_power_on_seconds == 0) {
- g_print (" power on hours: Unknown\n");
- g_print (" powered on: Unknown\n");
- } else {
- gchar *power_on_text;
- guint val;
-
- val = props->drive_ata_smart_power_on_seconds;
-
- if (val > 60 * 60 * 24) {
- power_on_text = g_strdup_printf ("%.3g days", val / 60.0 / 60.0 / 24.0);
- } else {
- power_on_text = g_strdup_printf ("%.3g hours", val / 60.0 / 60.0);
- }
-
- g_print (" powered on: %s\n", power_on_text);
- g_free (power_on_text);
- }
-
-
- g_print (" offline data: %s (%d second(s) to complete)\n", get_ata_smart_offline_status (props->drive_ata_smart_offline_data_collection_status), props->drive_ata_smart_offline_data_collection_seconds);
- g_print (" self-test status: %s (%d%% remaining)\n", get_ata_smart_self_test_status (props->drive_ata_smart_self_test_execution_status), props->drive_ata_smart_self_test_execution_percent_remaining);
- g_print (" ext./short test: %s\n", print_available (props->drive_ata_smart_short_and_extended_self_test_available));
- g_print (" conveyance test: %s\n", print_available (props->drive_ata_smart_conveyance_self_test_available));
- g_print (" start test: %s\n", print_available (props->drive_ata_smart_start_self_test_available));
- g_print (" abort test: %s\n", print_available (props->drive_ata_smart_abort_self_test_available));
- g_print (" short test: %3d minute(s) recommended polling time\n", props->drive_ata_smart_short_self_test_polling_minutes);
- g_print (" ext. test: %3d minute(s) recommended polling time\n", props->drive_ata_smart_extended_self_test_polling_minutes);
- g_print (" conveyance test: %3d minute(s) recommended polling time\n", props->drive_ata_smart_conveyance_self_test_polling_minutes);
- g_print ("===============================================================================\n");
- g_print (" Attribute Current/Worst/Threshold Status Value Type Updates\n");
- g_print ("===============================================================================\n");
- p = g_value_get_boxed (&(props->drive_ata_smart_attributes));
- for (m = 0; m < p->len; m++) {
- GValue elem = {0};
- guint id;
- gchar *name;
- guint flags;
- gboolean online, prefailure;
- guchar current;
- gboolean current_valid;
- guchar worst;
- gboolean worst_valid;
- guchar threshold;
- gboolean threshold_valid;
- gboolean good, good_valid;
- guint pretty_unit;
- guint64 pretty_value;
- gchar *pretty;
- const gchar *assessment;
- const gchar *type;
- const gchar *updates;
+ const gchar *status_desc;
gboolean do_highlight;
- GArray *raw_data;
-
- g_value_init (&elem, ATA_SMART_ATTRIBUTE_STRUCT_TYPE);
- g_value_set_static_boxed (&elem, p->pdata[m]);
-
- dbus_g_type_struct_get (&elem,
- 0, &id,
- 1, &name,
- 2, &flags,
- 3, &online,
- 4, &prefailure,
- 5, ¤t,
- 6, ¤t_valid,
- 7, &worst,
- 8, &worst_valid,
- 9, &threshold,
- 10, &threshold_valid,
- 11, &good,
- 12, &good_valid,
- 13, &pretty_unit,
- 14, &pretty_value,
- 15, &raw_data,
- G_MAXUINT);
-
- pretty = get_ata_smart_unit (pretty_unit, pretty_value);
-
- do_highlight = FALSE;
- if (!good_valid)
- assessment = " n/a";
- else if (good)
- assessment = "good";
- else {
- assessment = "FAIL";
- do_highlight = TRUE;
- }
-
- if (online)
- updates = "Online ";
- else
- updates = "Offline";
- if (prefailure)
- type = "Prefail";
- else
- type = "Old-age";
+ status_desc = ata_smart_status_to_desc (props->drive_ata_smart_status, &do_highlight);
if (do_highlight)
begin_highlight ();
-
- g_print (" %-27s %3d/%3d/%3d %s %-11s %s %s\n",
- name,
- current,
- worst,
- threshold,
- assessment,
- pretty,
- type,
- updates);
-
+ g_print (" overall assessment: %s\n", status_desc);
if (do_highlight)
end_highlight ();
+ }
+ if (sk_disk_open (NULL, &d) == 0) {
+ if (sk_disk_set_blob (d,
+ props->drive_ata_smart_blob,
+ props->drive_ata_smart_blob_size) == 0) {
+ g_print ("===============================================================================\n");
+ g_print (" Attribute Current|Worst|Threshold Status Value Type Updates\n");
+ g_print ("===============================================================================\n");
+
+ sk_disk_smart_parse_attributes (d,
+ print_ata_smart_attr,
+ NULL);
+ }
+ sk_disk_free (d);
+ }
- g_free (pretty);
- g_array_free (raw_data, TRUE);
- g_value_unset (&elem);
- }
}
/* ------------------------------------------------------------------------------------------------- */