From 3bd478d6d2c415b9a22622af973fdee9b1718422 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Jul 2008 20:05:21 +0200 Subject: remove SmartKit code and UI code --- Makefile | 13 +- SmartKit.conf | 14 -- gnome-disk-health.glade | 644 ----------------------------------------------- gnome-disk-health.vala | 494 ------------------------------------ smartkitd.vala | 647 ------------------------------------------------ 5 files changed, 2 insertions(+), 1810 deletions(-) delete mode 100644 SmartKit.conf delete mode 100644 gnome-disk-health.glade delete mode 100644 gnome-disk-health.vala delete mode 100644 smartkitd.vala diff --git a/Makefile b/Makefile index 1e4b1d5..e3ed42b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CFLAGS=-pipe -Wall -W -O0 -g -I. LIBS= -all: skdump sktest smartkitd gnome-disk-health gnome-disk-health.ui +all: skdump sktest skdump: smart.o skdump.o $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -9,14 +9,5 @@ skdump: smart.o skdump.o sktest: smart.o sktest.o $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -smartkitd: smart.c smartkitd.vala - valac --save-temps -g -o $@ --vapidir=. --pkg=smart --pkg=hal --pkg=dbus-glib-1 --Xcc=-I. $^ - -gnome-disk-health: gnome-disk-health.vala - valac --save-temps -g -o $@ --pkg=gtk+-2.0 --pkg=dbus-glib-1 $^ - -gnome-disk-health.ui: gnome-disk-health.glade - gtk-builder-convert $< $@ - clean: - rm -f skdump sktest *.o smartkitd gnome-disk-health gnome-disk-health.ui + rm -f skdump sktest *.o diff --git a/SmartKit.conf b/SmartKit.conf deleted file mode 100644 index d74019a..0000000 --- a/SmartKit.conf +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/gnome-disk-health.glade b/gnome-disk-health.glade deleted file mode 100644 index a1a122f..0000000 --- a/gnome-disk-health.glade +++ /dev/null @@ -1,644 +0,0 @@ - - - - - - 5 - Disk Health - GTK_WIN_POS_CENTER_ON_PARENT - drive-harddisk - GDK_WINDOW_TYPE_HINT_DIALOG - False - - - True - 2 - - - True - True - - - True - 12 - - - True - - - True - 0 - 0 - 12 - 12 - 6 - 64 - drive-harddisk - - - False - - - - - True - 12 - 5 - 2 - 6 - 6 - - - True - 0 - label - - - 1 - 2 - 4 - 5 - - - - - True - 0 - label - - - 1 - 2 - 3 - 4 - - - - - True - 0 - label - - - 1 - 2 - 2 - 3 - - - - - True - 0 - label - - - 1 - 2 - 1 - 2 - - - - - True - 0 - label - - - 1 - 2 - - - - - True - 1 - <b>Firmware:</b> - True - - - 4 - 5 - GTK_FILL - - - - - True - 1 - <b>Serial Number:</b> - True - - - 3 - 4 - GTK_FILL - - - - - True - 1 - <b>Model:</b> - True - - - 2 - 3 - GTK_FILL - - - - - True - 1 - <b>Size:</b> - True - - - 1 - 2 - GTK_FILL - - - - - True - 1 - <b>Path:</b> - True - - - GTK_FILL - GTK_FILL - - - - - 1 - - - - - False - - - - - True - - - False - 1 - - - - - True - 24 - - - True - Disk health functionality available (S.M.A.R.T.) - - - False - - - - - True - Disk is healthy. - - - False - 1 - - - - - True - A few sectors have been reallocated. - - - False - 2 - - - - - True - Current disk temperature is 40°C. - - - False - 3 - - - - - True - The disk has been powered on for 3.1 months. - - - False - 4 - - - - - 16 - 2 - - - - - - - True - Summary - - - tab - False - - - - - True - 12 - 6 - - - True - 0 - S.M.A.R.T. Attributes: - - - False - - - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - - - True - True - - - - - 1 - - - - - True - True - - - True - 7 - 2 - 6 - 6 - - - True - 0 - n/a - - - 1 - 2 - 6 - 7 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Verdict:</b> - True - - - 6 - 7 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - 5 - 6 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - 4 - 5 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - 3 - 4 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - 0 - n/a - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Type:</b> - True - - - 5 - 6 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Threshold:</b> - True - - - 4 - 5 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Worst Value:</b> - True - - - 3 - 4 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Current Value:</b> - True - - - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>ID:</b> - True - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - True - 1 - <b>Name:</b> - True - - - GTK_FILL - GTK_FILL - - - - - - - True - Explanation - - - label_item - - - - - False - 2 - - - - - 1 - - - - - True - Details - - - tab - 1 - False - - - - - True - 12 - 16 - - - True - 6 - - - True - - - - - True - True - True - Start Self-Test - 0 - - - False - 1 - - - - - False - - - - - True - Self-test functionality available. Approximate run-time is 120 min. - GTK_JUSTIFY_CENTER - True - - - False - 1 - - - - - 2 - - - - - True - Self-Test - - - tab - 2 - False - - - - - 1 - - - - - True - GTK_BUTTONBOX_EDGE - - - True - True - True - gtk-refresh - True - 0 - - - - - True - True - True - gtk-close - True - 0 - - - 1 - - - - - False - GTK_PACK_END - - - - - - diff --git a/gnome-disk-health.vala b/gnome-disk-health.vala deleted file mode 100644 index a3fcd4d..0000000 --- a/gnome-disk-health.vala +++ /dev/null @@ -1,494 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ - -/*** - This file is part of SmartKit. - - Copyright 2008 Lennart Poettering - - SmartKit is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 2.1 of the - License, or (at your option) any later version. - - SmartKit 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with SmartKit. If not, If not, see - . -***/ - -using DBus; -using GLib; -using Gtk; - - -public DiskHealth disk_health; - -public class DiskHealth : Gtk.Builder { - - string uifile = "gnome-disk-health.ui"; - - public bool create_widgets(string disk_string) { - test = null; - - try { - add_from_file (uifile); - Gtk.Widget window = (Gtk.Widget) get_object("DiskHealthDialog"); - - Gtk.TreeView tree_view = (Gtk.TreeView) get_object ("attributeTreeView"); - - /* id, name, text, icon, current, worst, threshold, type, verdict */ - list_store = new Gtk.ListStore(9, typeof(uint8), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string)); - - tree_view.set_model(list_store); - - tree_view.insert_column_with_attributes (-1, null, new Gtk.CellRendererPixbuf(), "icon-name", 3, null); - tree_view.insert_column_with_attributes(-1, "Name", new Gtk.CellRendererText(), "text", 1, null); - - Gtk.CellRenderer cell = new Gtk.CellRendererText(); - cell.set("xalign", 1.0, null); - tree_view.insert_column_with_attributes (-1, "Value", cell, "text", 2, null); - - if (!setup_connection(disk_string)) - return false; - - if (!fill_in_data()) - return false; - - setup_refresh_timer(); - - window.show_all(); - window.destroy += Gtk.main_quit; - - ((Gtk.Button) get_object("closeButton")).clicked += Gtk.main_quit; - - ((Gtk.Button) get_object("refreshButton")).clicked += refresh; - - ((Gtk.Button) get_object("selfTestButton")).clicked += selfTest; - - } catch (GLib.Error e) { - stderr.printf("Failed to create main window: %s\n", e.message); - return false; - } - - return true; - } - - private DBus.Connection connection; - private dynamic DBus.Object manager; - private DBus.ObjectPath dbus_path; - private dynamic DBus.Object disk; - private Gtk.ListStore list_store; - private string test; - - public bool setup_connection(string disk_string) { - try { - connection = DBus.Bus.get(DBus.BusType.SYSTEM); - - manager = connection.get_object("net.poettering.SmartKit", "/", "net.poettering.SmartKit.Manager"); - - DBus.ObjectPath p; - - try { - p = manager.getDiskByPath(disk_string); - } catch (DBus.Error e) { - try { - p = manager.getDiskByUDI(disk_string); - } catch (DBus.Error e) { - return false; - } - } - - stderr.printf("Using D-Bus path %s\n", p); - - disk = connection.get_object("net.poettering.SmartKit", p, "net.poettering.SmartKit.Disk"); - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - return false; - } - - return true; - } - - public void refresh() { - try { - disk.readSmartData(true); - fill_in_data(); - setup_refresh_timer(); - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - } - } - - public uint refresh_time; - public uint refresh_timer = 0; - - public void setup_refresh_timer() { - - uint t; - - if (refresh_time <= 0) - t = 5*60; - else if (refresh_time == 1) - t = 5; /* if 1 min is request, we do 10s - * instead, since we know that - * the minimal value is 1min */ - else - t = refresh_time*60; - - if (t > 5*60) - t = 5*60; - - stderr.printf("Setting wakeup to %u (%u)\n", t, refresh_time); - - disk_health = this; - - if (refresh_timer > 0) - Source.remove(refresh_timer); - refresh_timer = Timeout.add_seconds(t, - () => { - stderr.printf("Woke up\n"); - disk_health.refresh(); - return false; - }); - } - - public void selfTest() { - try { - disk.startSelfTest(test); - refresh(); - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - } - } - - public bool fill_in_data() { - - try { - ((Gtk.Label) get_object("pathLabel")).set_label(disk.getPath()); - ((Gtk.Label) get_object("sizeLabel")).set_label(pretty_size(disk.getSize())); - - bool b = disk.isIdentifyAvailable(); - - if (b) { - ((Gtk.Label) get_object("modelLabel")).set_label(disk.getIdentifyModel()); - ((Gtk.Label) get_object("serialLabel")).set_label(disk.getIdentifySerial()); - ((Gtk.Label) get_object("firmwareLabel")).set_label(disk.getIdentifyFirmware()); - } else { - ((Gtk.Label) get_object("modelLabel")).set_label("n/a"); - ((Gtk.Label) get_object("serialLabel")).set_label("n/a"); - ((Gtk.Label) get_object("firmwareLabel")).set_label("n/a"); - } - - if (b) - b = disk.isSmartAvailable(); - - if (b) - return fill_in_smart_data(); - else - return fill_in_no_smart_data(); - - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - return false; - } - } - - public bool fill_in_no_smart_data() { - - ((Gtk.Label) get_object("smartLabel")).set_markup("Disk health functionality (S.M.A.R.T.) is not available."); - ((Gtk.Label) get_object("healthLabel")).set_label(""); - ((Gtk.Label) get_object("badSectorsLabel")).set_label(""); - ((Gtk.Label) get_object("temperatureLabel")).set_label(""); - ((Gtk.Label) get_object("powerOnLabel")).set_label(""); - - return fill_in_no_self_test_data(); - } - - public string format_pretty(uint64 value, string unit) { - - switch (unit) { - - case "mseconds": - - if (value >= (uint64)1000*60*60*24*365) - return "%0.1f years".printf(((double) value)/(1000.0*60*60*24*365)); - else if (value >= (uint64) 1000*60*60*24*30) - return "%0.1f months".printf(((double) value)/(1000.0*60*60*24*30)); - else if (value >= 1000*60*60*24) - return "%0.1f days".printf(((double) value)/(1000.0*60*60*24)); - else if (value >= 1000*60*60) - return "%0.1f h".printf(((double) value)/(1000.0*60*60)); - else if (value >= 1000*60) - return "%0.1f min".printf(((double) value)/(1000.0*60)); - else if (value >= 1000) - return "%0.1f s".printf(((double) value)/(1000.0)); - else - return "%llu ms".printf(value); - - case "mkelvin": - return "%0.1f °C".printf(((double) value - 273150) / 1000); - - case "sectors": - return "%llu sectors".printf(value); - - case "none": - return "%llu".printf(value); - - } - - return "n/a"; - - } - - public bool fill_in_smart_data() { - try { - - ((Gtk.Label) get_object("smartLabel")).set_label("Disk health functionality (S.M.A.R.T.) is available."); - - bool b = disk.checkSmartStatus(); - - if (b) - ((Gtk.Label) get_object("healthLabel")).set_label("The disk reports to be healthy."); - else - ((Gtk.Label) get_object("healthLabel")).set_label("The disk reports that it has already failed or is expected to fail in the next 24h."); - - DBus.ObjectPath[] attrs = disk.getAttributes(); - - uint64 temp = 0; - uint64 rsc = 0; - uint64 rec = 0; - uint64 cps = 0; - uint64 ou = 0; - uint64 pon = 0; - - list_store.clear(); - - foreach (DBus.ObjectPath a in attrs) { - dynamic DBus.Object attribute; - uint8 id; - bool good, online, prefailure; - string name; - uint64 pretty_value; - string pretty_unit; - uint8 current, worst, threshold; - - attribute = connection.get_object("net.poettering.SmartKit", a, "net.poettering.SmartKit.Attribute"); - - /* id, name, text, icon, current, worst, threshold, type, verdict */ - - id = attribute.getId(); - name = attribute.getName(); - pretty_value = attribute.getPrettyValue(); - pretty_unit = attribute.getPrettyUnit(); - good = attribute.isGood(); - current = attribute.getCurrentValue(); - worst = attribute.getWorstValue(); - threshold = attribute.getThreshold(); - online = attribute.isOnline(); - prefailure = attribute.isPrefailure(); - - Gtk.TreeIter iter; - list_store.append(out iter); - list_store.set(iter, - 0, id, - 1, name, - 2, format_pretty(pretty_value, pretty_unit), - 3, good ? "dialog-ok" : "dialog-warning", - 4, "%u".printf(current), - 5, "%u".printf(worst), - 6, "%u".printf(threshold), - 7, "%s/%s".printf(online ? "Online" : "Offline", prefailure ? "Prefailure" : "Old Age"), - 8, good ? "OK" : "FAILURE", - -1); - - if (name == "reallocated-sector-count") - rsc = pretty_value; - if (name == "reallocated-event-count") - rec = pretty_value; - if (name == "current-pending-sector") - cps = pretty_value; - if (name == "offline-uncorrectable") - ou = pretty_value; - - if (name == "temperature-celsius-1" || - name == "temperature-celsius-2" || - name == "airflow-temperature-celsius") - if (pretty_value > temp) - temp = pretty_value; - - if (name == "power-on-minutes" || - name == "power-on-seconds" || - name == "power-on-hours") - pon = pretty_value; - } - - uint64 sectors = cps + ou + (rsc > rec ? rsc : rec); - if (sectors > 0) - ((Gtk.Label) get_object("badSectorsLabel")).set_markup("Warning: The disk reports to have %llu bad sectors.".printf(sectors)); - else - ((Gtk.Label) get_object("badSectorsLabel")).set_label("The disk reports to have no bad sectors."); - - if (temp > 0) - ((Gtk.Label) get_object("temperatureLabel")).set_label("The current temperature of the disk is %0.1f °C.".printf((double) (temp - 273150) / 1000)); - else - ((Gtk.Label) get_object("temperatureLabel")).set_label(""); - - - if (pon > 0) - ((Gtk.Label) get_object("powerOnLabel")).set_label("The disk has been powered on for %s.".printf(format_pretty(pon, "mseconds"))); - else - ((Gtk.Label) get_object("powerOnLabel")).set_label(""); - - bool a = disk.getStartTestAvailable(); - b = disk.getConveyanceTestAvailable(); - bool c = disk.getShortAndExtendedTestAvailable(); - - if (a && (b || c)) - return fill_in_self_test_data(c, b); - else - return fill_in_no_self_test_data(); - - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - return false; - } - } - - public bool fill_in_self_test_data(bool sae, bool c) { - try { - bool show_percent = false; - string text; - - string state = disk.getSelfTestExecutionStatus(); - - switch (state) { - case "success-or-never": - text = "The previous self-test completed without error or no self-test has ever been run."; - break; - case "aborted": - text = "The previous self-test was aborted by the user."; - break; - case "interrupted": - text = "The previous self-test was interrupted by the host with a hardware or software reset."; - break; - case "fatal": - text = "A fatal error or unknown test error occurred while the device was executing the previous self-test and the device was unable to complete the self-test."; - break; - case "error-unknown": - text = "The previous self-test completed having a test element that failed."; - break; - case "error-electrical": - text = "The previous self-test completed having the electrical element of the test failed."; - break; - case "eror-servo": - text = "The previous self-test completed having the servo (and/or seek) test element of the test failed."; - break; - case "error-read": - text = "The previous self-test completed having the read element of the test failed."; - break; - case "error-handling": - text = "The previous self-test completed having a test element that failed and the device is suspected of having handling damage."; - break; - case "inprogress": - text = "Self-test in progress..."; - show_percent = true; - break; - - default: - text = "Unknown state"; - break; - } - - ((Gtk.Label) get_object("selfTestLabel")).set_label(text); - - if (show_percent) { - uint percent = disk.getSelfTestExecutionPercentRemaining(); - - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_fraction((double) (100-percent)/100); - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_text("%u%% remaining".printf(percent)); - } else { - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_fraction(0.0); - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_text("n/a"); - } - - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_sensitive(show_percent); - - if (state == "inprogress") { - ((Gtk.Button) get_object("selfTestButton")).set_label("Abort Self-Test"); - bool b = disk.getAbortTestAvailable(); - ((Gtk.Button) get_object("selfTestButton")).set_sensitive(b); - - this.test = "abort"; - - if (sae) - this.refresh_time = disk.getShortTestPollingMinutes(); - else - this.refresh_time = disk.getConveyanceTestPollingMinutes(); - - - } else { - uint saet, ct; - - ((Gtk.Button) get_object("selfTestButton")).set_label("Start Self-Test"); - ((Gtk.Button) get_object("selfTestButton")).set_sensitive(true); - - if (sae) - this.test = "short"; - else - this.test = "conveyance"; - - this.refresh_time = 0; - } - - } catch (DBus.Error e) { - stderr.printf("D-Bus error: %s\n", e.message); - return false; - } - - return true; - } - - public bool fill_in_no_self_test_data() { - ((Gtk.Label) get_object("selfTestLabel")).set_label("Self-test functionality is not available."); - ((Gtk.Button) get_object("selfTestButton")).set_sensitive(false); - ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_sensitive(false); - - test = null; - return true; - } - - public static string pretty_size(uint64 size) { - - if (size >= (uint64)1024*(uint64)1024*(uint64)1024*(uint64)1024) - return "%0.1f TiB".printf((double) size/1024/1024/1024/1024); - else if (size >= (uint64)1024*(uint64)1024*(uint64)1024) - return "%0.1f GiB".printf((double) size/1024/1024/1024); - else if (size >= (uint64)1024*(uint64)1024) - return "%0.1f MiB".printf((double) size/1024/1024); - else if (size >= (uint64)1024) - return "%0.1f KiB".printf((double) size/1024); - else - return "%u B".printf((uint) size); - } - - - public static int main (string[] args) { - Gtk.init(ref args); - - if (args.length != 2) { - stderr.printf("Please specify device to check health for.\n"); - return 1; - } - - var dh = new DiskHealth(); - - if (dh.create_widgets(args[1])) - Gtk.main (); - - return 0; - } -} diff --git a/smartkitd.vala b/smartkitd.vala deleted file mode 100644 index 1cbc41e..0000000 --- a/smartkitd.vala +++ /dev/null @@ -1,647 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ - -/*** - This file is part of SmartKit. - - Copyright 2008 Lennart Poettering - - SmartKit is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 2.1 of the - License, or (at your option) any later version. - - SmartKit 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with SmartKit. If not, If not, see - . -***/ - -using GLib; -using DBus; -using Hal; -using Smart; - -errordomain Error { - SYSTEM, - NOT_FOUND, - SLEEPING, - UNKNOWN_TEST, - UNKNOWN_THRESHOLD, - UNKNOWN_UNIT -} - -[DBus (name = "net.poettering.SmartKit.Attribute")] -public interface AttributeAPI { - public abstract uint8 getId() throws Error; - public abstract string getName() throws Error; - public abstract string getPrettyUnit() throws Error; - public abstract uint8 getThreshold() throws Error; - public abstract bool isOnline() throws Error; - public abstract bool isPrefailure() throws Error; - public abstract bool isGood() throws Error; - public abstract uint8 getCurrentValue() throws Error; - public abstract uint8 getWorstValue() throws Error; - public abstract uint64 getPrettyValue() throws Error; -} - -[DBus (name = "net.poettering.SmartKit.Disk")] -public interface DiskAPI { - - public abstract string getPath() throws Error; - public abstract string getUDI() throws Error; - - public abstract uint64 getSize() throws Error; - - public abstract bool checkSleepMode() throws Error; - - public abstract bool isIdentifyAvailable() throws Error; - public abstract string getIdentifySerial() throws Error; - public abstract string getIdentifyFirmware() throws Error; - public abstract string getIdentifyModel() throws Error; - - public abstract bool isSmartAvailable() throws Error; - public abstract bool checkSmartStatus() throws Error; - public abstract void readSmartData(bool wakeup) throws Error; - - public abstract void startSelfTest(string test) throws Error; - public abstract void abortSelfTest() throws Error; - - public abstract string getOfflineDataCollectionStatus() throws Error; - public abstract uint getTotalOfflineDataCollectionSeconds() throws Error; - - public abstract string getSelfTestExecutionStatus() throws Error; - public abstract uint getSelfTestExecutionPercentRemaining() throws Error; - - public abstract bool getConveyanceTestAvailable() throws Error; - public abstract bool getShortAndExtendedTestAvailable() throws Error; - public abstract bool getStartTestAvailable() throws Error; - public abstract bool getAbortTestAvailable() throws Error; - - public abstract uint getShortTestPollingMinutes() throws Error; - public abstract uint getExtendedTestPollingMinutes() throws Error; - public abstract uint getConveyanceTestPollingMinutes() throws Error; - - public abstract DBus.ObjectPath[] getAttributes() throws Error; -} - -[DBus (name = "net.poettering.SmartKit.Manager")] -public interface ManagerAPI { - public abstract DBus.ObjectPath getDiskByUDI(string udi) throws Error; - public abstract DBus.ObjectPath getDiskByPath(string path) throws Error; - public abstract DBus.ObjectPath[] getDisks() throws Error; -} - -string clean_path(string s) { - var builder = new StringBuilder (); - string t; - - for (int i = 0; i < s.size(); i++) - if (s[i].isalnum() || s[i] == '_') - builder.append_unichar(s[i]); - else - builder.append_unichar('_'); - - return builder.str; -} - - -public class Attribute : GLib.Object, AttributeAPI { - public string dbus_path; - - public Disk disk { get; construct; } - public DBus.Connection connection { get; construct; } - - public uint8 _id; - public string name; - public SmartAttributeUnit pretty_unit; - public uint8 threshold; - public bool threshold_valid; - public bool online; - public bool prefailure; - public bool good; - public uint8 current_value; - public uint8 worst_value; - public uint64 pretty_value; - - Attribute(Disk disk, DBus.Connection connection) { - this.connection = connection; - this.disk = disk; - } - - public void set(SmartAttributeParsedData a) { - _id = a.id; - name = a.name; - pretty_unit = a.pretty_unit; - threshold = a.threshold; - threshold_valid = a.threshold_valid; - online = a.online; - prefailure = a.prefailure; - good = a.good; - current_value = a.current_value; - worst_value = a.worst_value; - pretty_value = a.pretty_value; - } - - public void install() { - this.dbus_path = "%s/%s".printf(disk.dbus_path, clean_path(name)); - - stderr.printf("Registering D-Bus path %s\n", this.dbus_path); - this.connection.register_object(this.dbus_path, this); - } - - public uint8 getId() throws Error { - return _id; - } - - public string getName() throws Error { - return name; - } - - public string getPrettyUnit() throws Error { - switch (pretty_unit) { - - case SmartAttributeUnit.UNKNOWN: - return "unknown"; - case SmartAttributeUnit.NONE: - return "none"; - case SmartAttributeUnit.MSECONDS: - return "mseconds"; - case SmartAttributeUnit.SECTORS: - return "sectors"; - case SmartAttributeUnit.MKELVIN: - return "mkelvin"; - default: - throw new Error.UNKNOWN_UNIT("Unit unknown %i.", pretty_unit); - } - } - - public uint8 getThreshold() throws Error { - if (!threshold_valid) - throw new Error.UNKNOWN_THRESHOLD("Threshold unknown."); - - return threshold; - } - - public bool isOnline() throws Error { - return online; - } - - public bool isPrefailure() throws Error { - return prefailure; - } - - public bool isGood() throws Error { - return good; - } - - public uint8 getCurrentValue() throws Error { - return current_value; - } - - public uint8 getWorstValue() throws Error { - return worst_value; - } - - public uint64 getPrettyValue() throws Error { - return pretty_value; - } -} - -public class Disk : GLib.Object, DiskAPI { - public Smart.Disk disk; - public string dbus_path; - - public string path { get; construct; } - public string udi { get; construct; } - public DBus.Connection connection { get; construct; } - - public List attributes; - - Disk(DBus.Connection connection, string path, string udi) { - this.connection = connection; - this.path = path; - this.udi = udi; - } - - public void open() throws Error { - - if (Smart.Disk.open(this.path, out this.disk) < 0) - throw new Error.SYSTEM("open() failed"); - - weak Smart.IdentifyParsedData *d; - - if (this.disk.identify_parse(out d) >= 0) - this.dbus_path = "/disk/%s/%s".printf(clean_path(d->model), clean_path(d->serial)); - else - this.dbus_path = "/disk/%s".printf(clean_path(this.path)); - - stderr.printf("Registering D-Bus path %s\n", this.dbus_path); - this.connection.register_object(this.dbus_path, this); - - this.disk.smart_read_data(); - - populate_attributes(); - } - - private void attribute_callback(void* disk, SmartAttributeParsedData a) { - foreach (Attribute attr in attributes) - if (attr._id == a.id) { - attr.set(a); - return; - } - - Attribute attr; - - attr = new Attribute(this, this.connection); - attr.set(a); - attr.install(); - attributes.append(#attr); - } - - public void populate_attributes() { - this.disk.smart_parse_attributes(attribute_callback); - } - - public string getPath() throws Error { - return this.path; - } - - public string getUDI() throws Error { - return this.udi; - } - - public uint64 getSize() throws Error { - uint64 s; - - if (this.disk.get_size(out s) < 0) - throw new Error.SYSTEM("get_size() failed: %s", Smart.strerror(Smart.errno)); - - return s; - } - - public bool checkSleepMode() throws Error { - bool awake; - - if (this.disk.check_sleep_mode(out awake) < 0) - throw new Error.SYSTEM("check_sleep_mode() failed: %s", Smart.strerror(Smart.errno)); - - return awake; - } - - public bool isIdentifyAvailable() throws Error { - bool available; - - if (this.disk.identify_is_available(out available) < 0) - throw new Error.SYSTEM("identify_is_available() failed: %s", Smart.strerror(Smart.errno)); - - return available; - } - - public string getIdentifySerial() throws Error { - weak Smart.IdentifyParsedData *d; - - if (this.disk.identify_parse(out d) < 0) - throw new Error.SYSTEM("identify_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->serial; - } - - public string getIdentifyFirmware() throws Error { - weak Smart.IdentifyParsedData *d; - - if (this.disk.identify_parse(out d) < 0) - throw new Error.SYSTEM("identify_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->firmware; - } - - public string getIdentifyModel() throws Error { - weak Smart.IdentifyParsedData *d; - - if (this.disk.identify_parse(out d) < 0) - throw new Error.SYSTEM("identify_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->model; - } - - public bool isSmartAvailable() throws Error { - bool available; - - if (this.disk.smart_is_available(out available) < 0) - throw new Error.SYSTEM("smart_is_available() failed: %s", Smart.strerror(Smart.errno)); - - return available; - } - - public bool checkSmartStatus() throws Error { - bool good; - - if (this.disk.smart_status(out good) < 0) - throw new Error.SYSTEM("smart_status() failed: %s", Smart.strerror(Smart.errno)); - - return good; - } - - public void readSmartData(bool wakeup) throws Error { - bool awake; - - if (!wakeup) { - if (this.disk.check_sleep_mode(out awake) < 0) - throw new Error.SYSTEM("check_sleep_mode() failed: %s", Smart.strerror(Smart.errno)); - - if (!awake) - throw new Error.SLEEPING("Disk is in sleep mode"); - } - - if (this.disk.smart_read_data() < 0) - throw new Error.SYSTEM("smart_read_data() failed: %s", Smart.strerror(Smart.errno)); - - populate_attributes(); - } - - public void startSelfTest(string test) throws Error { - SmartSelfTest t; - - switch (test) { - case "short": - t = SmartSelfTest.SHORT; - break; - case "extended": - t = SmartSelfTest.EXTENDED; - break; - case "conveyance": - t = SmartSelfTest.CONVEYANCE; - break; - default: - throw new Error.UNKNOWN_TEST("Test %s not known", test); - } - - if (this.disk.smart_self_test(t) < 0) - throw new Error.SYSTEM("smart_self_test() failed: %s", Smart.strerror(Smart.errno)); - } - - public void abortSelfTest() throws Error { - - if (this.disk.smart_self_test(SmartSelfTest.ABORT) < 0) - throw new Error.SYSTEM("smart_self_test() failed: %s", Smart.strerror(Smart.errno)); - - } - - public string getOfflineDataCollectionStatus() throws Error { - weak SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - switch (d->offline_data_collection_status) { - case SmartOfflineDataCollectionStatus.NEVER: - return "never"; - case SmartOfflineDataCollectionStatus.SUCCESS: - return "success"; - case SmartOfflineDataCollectionStatus.INPROGRESS: - return "inprogress"; - case SmartOfflineDataCollectionStatus.SUSPENDED: - return "suspended"; - case SmartOfflineDataCollectionStatus.ABORTED: - return "aborted"; - case SmartOfflineDataCollectionStatus.FATAL: - return "fatal"; - default: - return "unknown"; - } - } - - public uint getTotalOfflineDataCollectionSeconds() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->total_offline_data_collection_seconds; - } - - public string getSelfTestExecutionStatus() throws Error { - weak SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - switch (d->self_test_execution_status) { - case SmartSelfTestExecutionStatus.SUCCESS_OR_NEVER: - return "success-or-never"; - case SmartSelfTestExecutionStatus.ABORTED: - return "aborted"; - case SmartSelfTestExecutionStatus.INTERRUPTED: - return "interrupted"; - case SmartSelfTestExecutionStatus.FATAL: - return "fatal"; - case SmartSelfTestExecutionStatus.ERROR_UNKNOWN: - return "error-unknown"; - case SmartSelfTestExecutionStatus.ERROR_ELECTRICAL: - return "error-electrical"; - case SmartSelfTestExecutionStatus.ERROR_SERVO: - return "error-servo"; - case SmartSelfTestExecutionStatus.ERROR_READ: - return "error-read"; - case SmartSelfTestExecutionStatus.ERROR_HANDLING: - return "error-handling"; - case SmartSelfTestExecutionStatus.INPROGRESS: - return "inprogress"; - default: - return "unknown"; - } - } - - public uint getSelfTestExecutionPercentRemaining() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->self_test_execution_percent_remaining; - } - - public bool getConveyanceTestAvailable() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->conveyance_test_available; - } - - public bool getShortAndExtendedTestAvailable() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->short_and_extended_test_available; - } - - public bool getStartTestAvailable() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->start_test_available; - } - - public bool getAbortTestAvailable() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->abort_test_available; - } - - public uint getShortTestPollingMinutes() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->short_test_polling_minutes; - } - - public uint getExtendedTestPollingMinutes() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->extended_test_polling_minutes; - } - - public uint getConveyanceTestPollingMinutes() throws Error { - weak Smart.SmartParsedData *d; - - if (this.disk.smart_parse(out d) < 0) - throw new Error.SYSTEM("smart_parse() failed: %s", Smart.strerror(Smart.errno)); - - return d->conveyance_test_polling_minutes; - } - - public DBus.ObjectPath[] getAttributes() throws Error { - DBus.ObjectPath[] p = new DBus.ObjectPath[attributes.length()]; - - int i = 0; - foreach (Attribute a in attributes) { - p[i++] = new DBus.ObjectPath(a.dbus_path); - } - - return p; - } - - -/* public uint64 size { */ -/* get { */ -/* uint64 s; */ -/* this.disk.get_size(out s); */ -/* return s; */ - -/* } */ -/* } */ -} - -public class Manager : GLib.Object, ManagerAPI { - public DBus.Connection connection { get; construct; } - public List disks; - - public DBus.RawConnection raw_connection; - public Hal.Context hal_context; - - Manager(DBus.Connection connection) { - this.connection = connection; - } - - public void start() throws Error { - DBus.RawError err; - - this.connection.register_object("/", this); - - this.raw_connection = DBus.RawBus.get(DBus.BusType.SYSTEM, ref err); - - this.hal_context = new Hal.Context(); - this.hal_context.set_dbus_connection(this.raw_connection); - - string[] haldisks = this.hal_context.find_device_by_capability("storage", ref err); - - foreach (string udi in haldisks) { - string bdev = this.hal_context.device_get_property_string(udi, "block.device", ref err); - - stderr.printf("Found device %s\n", bdev); - - try { - Disk disk = new Disk(this.connection, bdev, udi); - disk.open(); - this.disks.append(#disk); - } catch (Error e) { - stderr.printf("Failed to open disk %s: %s\n", bdev, e.message); - } - } - } - - public DBus.ObjectPath getDiskByUDI(string udi) throws Error { - - foreach (Disk d in this.disks) - if (d.udi == udi) - return new DBus.ObjectPath(d.dbus_path); - - throw new Error.NOT_FOUND("Device not found"); - } - - public DBus.ObjectPath getDiskByPath(string path) throws Error { - foreach (Disk d in this.disks) - if (d.path == path) - return new DBus.ObjectPath(d.dbus_path); - - throw new Error.NOT_FOUND("Device not found"); - } - - public DBus.ObjectPath[] getDisks() throws Error { - DBus.ObjectPath[] p = new DBus.ObjectPath[disks.length()]; - - int i = 0; - foreach (Disk d in disks) { - p[i++] = new DBus.ObjectPath(d.dbus_path); - } - - return p; - } - -} - -int main() { - - try { - var c = DBus.Bus.get(DBus.BusType.SYSTEM); - - dynamic DBus.Object bus = c.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus"); - - uint request_name_result = bus.RequestName("net.poettering.SmartKit", (uint) 0); - - if (request_name_result == DBus.RequestNameReply.PRIMARY_OWNER) { - - MainLoop loop = new MainLoop(null, false); - Manager manager = new Manager(c); - - manager.start(); - - stdout.printf("Started\n"); - loop.run(); - } - - } catch (Error e) { - stderr.printf("Error: %s\n", e.message); - return 1; - } - - return 0; -} -- cgit