refresh SMART data on startup and every 30 minutes
authorDavid Zeuthen <davidz@redhat.com>
Sat, 3 May 2008 22:21:39 +0000 (18:21 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Sat, 3 May 2008 22:21:39 +0000 (18:21 -0400)
doc/TODO
src/devkit-disks-daemon.c
src/devkit-disks-device.c
src/org.freedesktop.DeviceKit.Disks.Device.xml

index 6005233..65056e6 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,65 +1,4 @@
 
-=====================
-Planned API additions
-=====================
-
-org.freedesktop.DeviceKit.Disks.Device.xml:
-
-    <!-- these properties are only set if the enclosing drive of the
-         device could be identified; drive-media-compatibility is a
-         whitespace separated list of media types; known media types
-         are
-
-           disc_cd_rom
-           disc_cd_r
-           disc_cd_rw
-           disc_dvd_rom
-           disc_dvd_r
-           disc_dvd_rw
-           disc_dvd_plus_r
-           disc_dvd_plus_rw
-           disc_dvd_ram
-           disc_bd_rom
-           disc_bd_r
-           disc_bd_re
-           disc_hddvd_rom
-           disc_hddvd_r
-           disc_hddvd_rw
-           flash_thumb_drive
-           flash_compact_flash
-           flash_memory_stick
-           flash_smart_media
-           flash_secure_digital
-           flash_mmc
-           floppy
-           floppy_zip
-           floppy_jaz
-
-         The drive-media-type property will only contain one of these
-         types. Known values for the drive-connection-type are
-
-           ata
-           sata
-           scsi
-           iscsi
-           usb
-           firewire
-
-         The property drive-connection-version may not be set.
-      -->
-    <property name="drive-vendor" type="s" access="read"/>
-    <property name="drive-model" type="s" access="read"/>
-    <property name="drive-revision" type="s" access="read"/>
-    <property name="drive-serial" type="s" access="read"/>
-    <property name="drive-removable" type="b" access="read"/>
-    <property name="drive-connection-type" type="s" access="read"/>
-    <property name="drive-connection-version" type="s" access="read"/>
-    <property name="drive-media-compatibility" type="s" access="read"/>
-    <property name="drive-media-is-available" type="b" access="read"/>
-    <property name="drive-media-type" type="s" access="read"/>
-    <property name="drive-media-disc-has-audio" type="b" access="read"/>
-    <property name="drive-media-disc-is-blank" type="b" access="read"/>
-
-    <!-- whether the device is currently mounted anf if so, where -->
-    <property name="state-is-mounted" type="b" access="read"/>
-    <property name="state-mount-point" type="s" access="read"/>
+- Need a way to stop polling for SMART data to avoid
+  breaking boxes with thousands of disks
+  - maybe default to polling if there's less than 20 drives
index 9ef6587..f92fb37 100644 (file)
@@ -87,6 +87,8 @@ struct DevkitDisksDaemonPrivate
         GHashTable        *map_object_path_to_device;
 
         GUnixMountMonitor *mount_monitor;
+
+        guint              smart_refresh_timer_id;
 };
 
 static void     devkit_disks_daemon_class_init  (DevkitDisksDaemonClass *klass);
@@ -349,6 +351,10 @@ devkit_disks_daemon_finalize (GObject *object)
                 g_object_unref (daemon->priv->devkit_client);
         }
 
+        if (daemon->priv->smart_refresh_timer_id > 0) {
+                g_source_remove (daemon->priv->smart_refresh_timer_id);
+        }
+
         G_OBJECT_CLASS (devkit_disks_daemon_parent_class)->finalize (object);
 }
 
@@ -624,6 +630,30 @@ out:
        return TRUE;
 }
 
+static gboolean
+refresh_smart_data (DevkitDisksDaemon *daemon)
+{
+        DevkitDisksDevice *device;
+        const char *native_path;
+        GHashTableIter iter;
+
+        g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_device);
+        while (g_hash_table_iter_next (&iter, (gpointer *) &native_path, (gpointer *) &device)) {
+                if (device->priv->drive_smart_is_capable) {
+                        char *options[] = {NULL};
+
+                        g_warning ("automatically refreshing SMART data for %s", native_path);
+                        devkit_disks_device_drive_smart_refresh_data (device, options, NULL);
+                }
+        }
+
+        /* update in another 30 minutes */
+        daemon->priv->smart_refresh_timer_id = g_timeout_add_seconds (30 * 60,
+                                                                      (GSourceFunc) refresh_smart_data,
+                                                                      daemon);
+        return FALSE;
+}
+
 
 static gboolean
 register_disks_daemon (DevkitDisksDaemon *daemon)
@@ -738,7 +768,6 @@ register_disks_daemon (DevkitDisksDaemon *daemon)
         g_signal_connect (daemon->priv->mount_monitor, "mounts-changed", (GCallback) mounts_changed, daemon);
 
         return TRUE;
-
 error:
         return FALSE;
 }
@@ -784,6 +813,9 @@ devkit_disks_daemon_new (void)
         mounts_file_clean_stale (l);
         g_list_free (l);
 
+        /* initial refresh of SMART data */
+        refresh_smart_data (daemon);
+
         return daemon;
 }
 
index 6d1899a..b9a8204 100644 (file)
@@ -2287,6 +2287,9 @@ throw_error (DBusGMethodInvocation *context, int error_code, const char *format,
         va_list args;
         char *message;
 
+        if (context == NULL)
+                return TRUE;
+
         va_start (args, format);
         message = g_strdup_vprintf (format, args);
         va_end (args);
@@ -5295,6 +5298,7 @@ drive_smart_refresh_data_unref (DriveRefreshSmartDataData *data)
         g_free (data);
 }
 
+/* may be called with context==NULL */
 static void
 drive_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
                                        DevkitDisksDevice *device,
@@ -5541,11 +5545,13 @@ drive_smart_refresh_data_completed_cb (DBusGMethodInvocation *context,
         /* emit change event since we've updated the smart data */
         emit_changed (device);
 
-        dbus_g_method_return (context, passed, power_on_hours, temperature, last_self_test_result);
+        if (context != NULL)
+                dbus_g_method_return (context, passed, power_on_hours, temperature, last_self_test_result);
 out:
         ;
 }
 
+/* may be called with context==NULL */
 gboolean
 devkit_disks_device_drive_smart_refresh_data (DevkitDisksDevice     *device,
                                               char                 **options,
@@ -5558,8 +5564,12 @@ devkit_disks_device_drive_smart_refresh_data (DevkitDisksDevice     *device,
         const char *simulpath;
         gboolean nowakeup;
 
-        if ((pk_caller = devkit_disks_damon_local_get_caller_for_context (device->priv->daemon, context)) == NULL)
-                goto out;
+        pk_caller = NULL;
+        if (context != NULL) {
+                if ((pk_caller = devkit_disks_damon_local_get_caller_for_context (device->priv->daemon,
+                                                                                  context)) == NULL)
+                        goto out;
+        }
 
         if (!device->priv->info.device_is_drive) {
                 throw_error (context, DEVKIT_DISKS_DEVICE_ERROR_NOT_DRIVE,
@@ -5588,12 +5598,14 @@ devkit_disks_device_drive_smart_refresh_data (DevkitDisksDevice     *device,
         nowakeup = FALSE;
         for (n = 0; options[n] != NULL; n++) {
                 if (g_str_has_prefix (options[n], "simulate=")) {
-                        uid_t uid;
-                        if (!polkit_caller_get_uid (pk_caller, &uid) || uid != 0) {
-                                throw_error (context,
-                                             DEVKIT_DISKS_DEVICE_ERROR_GENERAL,
-                                             "Only uid 0 may use the simulate= option");
-                                goto out;
+                        if (context != NULL) {
+                                uid_t uid;
+                                if (!polkit_caller_get_uid (pk_caller, &uid) || uid != 0) {
+                                        throw_error (context,
+                                                     DEVKIT_DISKS_DEVICE_ERROR_GENERAL,
+                                                     "Only uid 0 may use the simulate= option");
+                                        goto out;
+                                }
                         }
                         simulpath = (const char *) options[n] + 9;
                 } else if (strcmp (options[n], "nowakeup") == 0) {
index 52ed3e5..ab08941 100644 (file)
             avoid spinning up the disk if it's in a low-power mode.
             The option <doc:tt>simulate=/path/to/smartctl-output</doc:tt> can be
             passed to read the given file instead of invoking <doc:tt>smartctl(8)</doc:tt> tool.
-            The <doc:tt>simulate=</doc:tt> can only be used by the super user.
+            The <doc:tt>simulate=</doc:tt> option can only be used by the super user.
         </doc:summary></doc:doc>
       </arg>
       <doc:doc>