add command line options to devkit-disks for refreshing ATA SMART data
authorDavid Zeuthen <davidz@redhat.com>
Wed, 8 Apr 2009 18:35:24 +0000 (14:35 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Wed, 8 Apr 2009 18:35:24 +0000 (14:35 -0400)
doc/man/devkit-disks.xml
src/devkit-disks-device.c
src/org.freedesktop.DeviceKit.Disks.Device.xml
tools/devkit-disks-bash-completion.sh
tools/devkit-disks.c

index 2402d8d..28d5a8d 100644 (file)
 
       <varlistentry>
         <term>
+          <option>--ata-smart-refresh</option>
+          <arg choice="plain"><replaceable>device_file</replaceable></arg>
+          <arg><option>--ata-smart-wakeup</option></arg>
+        </term>
+        <listitem>
+          <para>
+            Refreshes ATA SMART data for <replaceable>device_file</replaceable>. If the disk is
+            sleeping it will not be woken up unless <option>--ata-smart-wakeup</option> is passed.
+            will be used.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>--ata-smart-refresh</option>
+          <arg choice="plain"><replaceable>device_file</replaceable></arg>
+          <option>--ata-smart-simulate</option> <replaceable>blob</replaceable>
+        </term>
+        <listitem>
+          <para>
+            Read ATA SMART data from <replaceable>blob</replaceable> for <replaceable>device_file</replaceable>.
+            This can only be done by the super user and is typically used for testing that clients
+            relying on the ATA SMART data provided by DeviceKit-disks behave correctly.
+            The libatasmart git repository at
+            <ulink url="http://git.0pointer.de/?p=libatasmart.git;a=summary"/>
+            contains a collection of blobs from failing disks.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
           <option>--inhibit</option>
           <arg><option>-- program arg ...</option></arg>
         </term>
index 4ba6fd4..7151e5f 100644 (file)
@@ -7093,7 +7093,7 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
                                            const char *stdout,
                                            gpointer user_data)
 {
-        DriveRefreshAtaSmartDataData *data;
+        DriveRefreshAtaSmartDataData *data = user_data;
         gint rc;
         SkBool good;
         uint64_t num_bad_sectors;
@@ -7109,8 +7109,6 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
         AtaSmartCollectAttrsData collect_attrs_data;
         DevkitDisksAtaSmartDb *db;
 
-        data = user_data;
-
         d = NULL;
         blob = NULL;
 
@@ -7124,7 +7122,7 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
                         if (context != NULL)
                                 throw_error (context,
                                              DEVKIT_DISKS_ERROR_FAILED,
-                                             "Error retrieving S.M.A.R.T. data: no output",
+                                             "Error retrieving ATA SMART data: no output",
                                              WEXITSTATUS (status), stderr);
                 }
                 goto out;
@@ -7137,14 +7135,14 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
                         if (context != NULL) {
                                 throw_error (context,
                                              DEVKIT_DISKS_ERROR_ATA_SMART_WOULD_WAKEUP,
-                                             "Error retrieving S.M.A.R.T. data: %s",
+                                             "Error retrieving ATA SMART data: %s",
                                              stderr);
                         }
                 } else {
                         if (context != NULL) {
                                 throw_error (context,
                                              DEVKIT_DISKS_ERROR_FAILED,
-                                             "Error retrieving S.M.A.R.T. data: helper failed with exit code %d: %s",
+                                             "Error retrieving ATA SMART data: helper failed with exit code %d: %s",
                                              rc, stderr);
                         }
                 }
@@ -7257,19 +7255,21 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
         if (context != NULL)
                 dbus_g_method_return (context);
 
-        /* store the (time_collected, disk_id, blob) tupple in our database */
-        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);
+        /* 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);
@@ -7338,7 +7338,7 @@ devkit_disks_device_drive_ata_smart_refresh_data (DevkitDisksDevice     *device,
 
         if (simuldata != NULL) {
                 n = 0;
-                argv[n++] = "echo";
+                argv[n++] = "base64"; /* provided by coreutils */
                 argv[n++] = (char *) simuldata;
                 argv[n++] = NULL;
         } else {
index 0e70eaa..2d0d085 100644 (file)
         <doc:doc><doc:summary>
             The option <doc:tt>nowakeup</doc:tt> can be passed to
             avoid spinning up the disk if it's in a low-power mode.
-            The option <doc:tt>simulate=</doc:tt> can be
-            passed to use the given string (which is in a format private to DeviceKit-disks) instead
-            of reading it from the disk.
+            The option <doc:tt>simulate=</doc:tt> can be used to pass a path to
+            a blob with libatasmart data to use instead of reading it from the disk.
             The <doc:tt>simulate=</doc:tt> option can only be used by the super user.
         </doc:summary></doc:doc>
       </arg>
index f373c30..e4fdbf5 100644 (file)
@@ -16,11 +16,15 @@ __devkit_disks() {
         COMPREPLY=($(compgen -W "$(devkit-disks --enumerate-device-files)" -- $cur))
     elif [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--unmount" ] ; then
         COMPREPLY=($(compgen -W "$(devkit-disks --enumerate-device-files)" -- $cur))
+    elif [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--ata-smart-refresh" ] ; then
+        COMPREPLY=($(compgen -W "$(devkit-disks --enumerate-device-files)" -- $cur))
+    elif [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--ata-smart-simulate" ] ; then
+        _filedir || return 0
     else
-        COMPREPLY=($(IFS=: compgen -S' ' -W "--dump:--inhibit-polling:--inhibit-all-polling:--enumerate:--enumerate-device-files:--monitor:--monitor-detail:--show-info:--help:--mount:--mount-fstype:--mount-options:--unmount:--unmount-options" -- $cur))
+        COMPREPLY=($(IFS=: compgen -W "--dump:--inhibit-polling:--inhibit-all-polling:--enumerate:--enumerate-device-files:--monitor:--monitor-detail:--show-info:--help:--mount:--mount-fstype:--mount-options:--unmount:--unmount-options:--ata-smart-refresh:--ata-smart-wakeup:--ata-smart-simulate" -- $cur))
     fi
 }
 
 ####################################################################################################
 
-complete -o nospace -F __devkit_disks devkit-disks
+complete -o filenames -F __devkit_disks devkit-disks
index ffdbb49..9868876 100644 (file)
@@ -67,6 +67,10 @@ static char         *opt_mount_fstype           = NULL;
 static char         *opt_mount_options          = NULL;
 static char         *opt_unmount                = NULL;
 static char         *opt_unmount_options        = NULL;
+static char         *opt_ata_smart_refresh      = NULL;
+static gboolean      opt_ata_smart_wakeup       = FALSE;
+static char         *opt_ata_smart_simulate     = NULL;
+
 
 static gboolean do_monitor (void);
 static void do_show_info (const char *object_path);
@@ -94,6 +98,40 @@ out:
 }
 
 static void
+do_ata_smart_refresh (const gchar *object_path,
+                      gboolean     wakeup,
+                      const gchar *simulate_path)
+{
+        DBusGProxy *proxy;
+        GError *error;
+        GPtrArray *options;
+
+        options = g_ptr_array_new ();
+        if (!wakeup)
+                g_ptr_array_add (options, g_strdup ("nowakeup"));
+        if (simulate_path != NULL)
+                g_ptr_array_add (options, g_strdup_printf ("simulate=%s", simulate_path));
+        g_ptr_array_add (options, NULL);
+
+       proxy = dbus_g_proxy_new_for_name (bus,
+                                           "org.freedesktop.DeviceKit.Disks",
+                                           object_path,
+                                           "org.freedesktop.DeviceKit.Disks.Device");
+        error = NULL;
+        if (!org_freedesktop_DeviceKit_Disks_Device_drive_ata_smart_refresh_data (proxy,
+                                                                                  (const char **) options->pdata,
+                                                                                  &error)) {
+                g_print ("Refreshing ATA SMART data failed: %s\n", error->message);
+                g_error_free (error);
+        } else {
+                do_show_info (object_path);
+        }
+
+        g_ptr_array_foreach (options, (GFunc) g_free, NULL);
+        g_ptr_array_free (options, TRUE);
+}
+
+static void
 do_mount (const char *object_path,
           const char *filesystem_type,
           const char *options)
@@ -1575,7 +1613,9 @@ main (int argc, char **argv)
 
                 { "unmount", 0, 0, G_OPTION_ARG_STRING, &opt_unmount, "Unmount the device given by the object path", NULL },
                 { "unmount-options", 0, 0, G_OPTION_ARG_STRING, &opt_unmount_options, "Unmount options separated by comma", NULL },
-
+                { "ata-smart-refresh", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_refresh, "Refresh ATA SMART data", NULL },
+                { "ata-smart-wakeup", 0, 0, G_OPTION_ARG_NONE, &opt_ata_smart_wakeup, "Wake up the disk if it is not awake", NULL },
+                { "ata-smart-simulate", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_simulate, "Inject libatasmart BLOB for testing", NULL },
                 { NULL }
         };
 
@@ -1699,6 +1739,11 @@ main (int argc, char **argv)
                 if (device_file == NULL)
                         goto out;
                 do_unmount (device_file, opt_unmount_options);
+        } else if (opt_ata_smart_refresh != NULL) {
+                device_file = device_file_to_object_path (opt_ata_smart_refresh);
+                if (device_file == NULL)
+                        goto out;
+                do_ata_smart_refresh (device_file, opt_ata_smart_wakeup, opt_ata_smart_simulate);
         } else {
                 gchar *usage;