From 3602596b6eddfbabc88b0a7b005b8310724c7d22 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 8 Apr 2009 14:35:24 -0400 Subject: [PATCH] add command line options to devkit-disks for refreshing ATA SMART data --- doc/man/devkit-disks.xml | 33 ++++++++++++++++++ src/devkit-disks-device.c | 40 +++++++++++----------- src/org.freedesktop.DeviceKit.Disks.Device.xml | 5 ++- tools/devkit-disks-bash-completion.sh | 8 +++-- tools/devkit-disks.c | 47 +++++++++++++++++++++++++- 5 files changed, 107 insertions(+), 26 deletions(-) diff --git a/doc/man/devkit-disks.xml b/doc/man/devkit-disks.xml index 2402d8d..28d5a8d 100644 --- a/doc/man/devkit-disks.xml +++ b/doc/man/devkit-disks.xml @@ -156,6 +156,39 @@ + + device_file + + + + + Refreshes ATA SMART data for device_file. If the disk is + sleeping it will not be woken up unless is passed. + will be used. + + + + + + + + device_file + blob + + + + Read ATA SMART data from blob for device_file. + 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 + + contains a collection of blobs from failing disks. + + + + + + diff --git a/src/devkit-disks-device.c b/src/devkit-disks-device.c index 4ba6fd4..7151e5f 100644 --- a/src/devkit-disks-device.c +++ b/src/devkit-disks-device.c @@ -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 { diff --git a/src/org.freedesktop.DeviceKit.Disks.Device.xml b/src/org.freedesktop.DeviceKit.Disks.Device.xml index 0e70eaa..2d0d085 100644 --- a/src/org.freedesktop.DeviceKit.Disks.Device.xml +++ b/src/org.freedesktop.DeviceKit.Disks.Device.xml @@ -1038,9 +1038,8 @@ The option nowakeup can be passed to avoid spinning up the disk if it's in a low-power mode. - The option simulate= 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 simulate= can be used to pass a path to + a blob with libatasmart data to use instead of reading it from the disk. The simulate= option can only be used by the super user. diff --git a/tools/devkit-disks-bash-completion.sh b/tools/devkit-disks-bash-completion.sh index f373c30..e4fdbf5 100644 --- a/tools/devkit-disks-bash-completion.sh +++ b/tools/devkit-disks-bash-completion.sh @@ -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 diff --git a/tools/devkit-disks.c b/tools/devkit-disks.c index ffdbb49..9868876 100644 --- a/tools/devkit-disks.c +++ b/tools/devkit-disks.c @@ -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; -- 2.7.4