add smart status information

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=1107708
This commit is contained in:
Volker Lanz 2010-03-26 15:06:33 +00:00
parent 39e366c69f
commit 28efbee2ec
9 changed files with 315 additions and 24 deletions

View File

@ -37,6 +37,7 @@ find_package(KDE4 REQUIRED)
find_package(MSGFMT REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(BLKID REQUIRED blkid)
pkg_check_modules(LIBATASMART REQUIRED libatasmart)
find_package(LIBPARTED REQUIRED)
add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})

View File

@ -36,7 +36,7 @@ kde4_add_kcfg_files(partitionmanagerprivate_SRCS config.kcfgc)
kde4_add_library(partitionmanagerprivate SHARED ${partitionmanagerprivate_SRCS})
target_link_libraries(partitionmanagerprivate libfatlabel ${KDE4_KDECORE_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} ${UUID_LIBRARIES} ${BLKID_LIBRARIES} ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS})
target_link_libraries(partitionmanagerprivate libfatlabel ${KDE4_KDECORE_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} ${UUID_LIBRARIES} ${BLKID_LIBRARIES} ${LIBATASMART_LIBRARIES} ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS})
install(TARGETS partitionmanagerprivate ${INSTALL_TARGETS_DEFAULT_ARGS})

View File

@ -41,7 +41,8 @@ Device::Device(const QString& name, const QString& devicenode, qint32 heads, qin
m_SectorsPerTrack(numSectors),
m_Cylinders(cylinders),
m_SectorSize(sectorSize),
m_IconName(iconname.isEmpty() ? "drive-hardisk" : iconname)
m_IconName(iconname.isEmpty() ? "drive-hardisk" : iconname),
m_SmartStatus(devicenode)
{
}

View File

@ -23,6 +23,8 @@
#include "util/libpartitionmanagerexport.h"
#include "core/smartstatus.h"
#include <QString>
#include <QObject>
#include <qglobal.h>
@ -68,6 +70,8 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Device : public QObject
void setIconName(const QString& name) { m_IconName = name; }
const QString& iconName() const { return m_IconName; } /**< @return suggested icon name for this Device */
const SmartStatus& smartStatus() const { return m_SmartStatus; }
protected:
void setPartitionTable(PartitionTable* ptable) { m_PartitionTable = ptable; }
@ -80,6 +84,7 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT Device : public QObject
qint32 m_Cylinders;
qint32 m_SectorSize;
QString m_IconName;
SmartStatus m_SmartStatus;
};
#endif

89
src/core/smartstatus.cpp Normal file
View File

@ -0,0 +1,89 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "core/smartstatus.h"
#include <kdebug.h>
#include <QString>
#include <atasmart.h>
#include <errno.h>
SmartStatus::SmartStatus(const QString& device_path) :
m_DevicePath(device_path),
m_InitSuccess(false),
m_Status(false),
m_Temp(-99),
m_BadSectors(-99),
m_PowerCycles(-99),
m_PoweredOn(-99)
{
SkDisk* skDisk = NULL;
SkBool skSmartStatus = false;
uint64_t mkelvin = 0;
uint64_t skBadSectors = 0;
uint64_t skPoweredOn = 0;
uint64_t skPowerCycles = 0;
if (sk_disk_open(devicePath().toLocal8Bit(), &skDisk) < 0)
{
kDebug() << "smart disk open failed for " << devicePath() << ": " << strerror(errno);
return;
}
if (sk_disk_smart_status(skDisk, &skSmartStatus) < 0)
{
kDebug() << "getting smart status failed for " << devicePath() << ": " << strerror(errno);
sk_disk_free(skDisk);
return;
}
setStatus(skSmartStatus);
if (sk_disk_smart_read_data(skDisk) < 0)
{
kDebug() << "reading smart data failed for " << devicePath() << ": " << strerror(errno);
sk_disk_free(skDisk);
return;
}
if (sk_disk_smart_get_temperature(skDisk, &mkelvin) < 0)
kDebug() << "getting temp failed for " << devicePath() << ": " << strerror(errno);
else
setTemp((mkelvin - 273150) / 100);
if (sk_disk_smart_get_bad(skDisk, &skBadSectors) < 0)
kDebug() << "getting bad sectors failed for " << devicePath() << ": " << strerror(errno);
else
setBadSectors(skBadSectors);
if (sk_disk_smart_get_power_on(skDisk, &skPoweredOn) < 0)
kDebug() << "getting powered on time failed for " << devicePath() << ": " << strerror(errno);
else
setPoweredOn(skPoweredOn);
if (sk_disk_smart_get_power_cycle(skDisk, &skPowerCycles) < 0)
kDebug() << "getting power cycles failed for " << devicePath() << ": " << strerror(errno);
else
setPowerCycles(skPowerCycles);
sk_disk_free(skDisk);
setInitSuccess(true);
}

61
src/core/smartstatus.h Normal file
View File

@ -0,0 +1,61 @@
/***************************************************************************
* Copyright (C) 2010 by Volker Lanz <vl@fidra.de> *
* *
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#if !defined(SMARTSTATUS__H)
#define SMARTSTATUS__H
#include <qglobal.h>
#include <QString>
class SmartStatus
{
public:
SmartStatus(const QString& device_path);
public:
const QString& devicePath() const { return m_DevicePath; }
bool isValid() const { return m_InitSuccess; }
bool status() const { return m_Status; }
qint32 temp() const { return m_Temp; }
qint64 badSectors() const { return m_BadSectors; }
qint64 powerCycles() const { return m_PowerCycles; }
qint64 poweredOn() const { return m_PoweredOn; }
protected:
void setStatus(bool s) { m_Status = s; }
void setTemp(qint32 t) { m_Temp = t; }
void setInitSuccess(bool b) { m_InitSuccess = b; }
void setBadSectors(qint64 s) { m_BadSectors = s; }
void setPowerCycles(qint64 p) { m_PowerCycles = p; }
void setPoweredOn(qint64 t) { m_PoweredOn = t; }
private:
const QString m_DevicePath;
bool m_InitSuccess;
bool m_Status;
qint32 m_Temp;
qint64 m_BadSectors;
qint64 m_PowerCycles;
qint64 m_PoweredOn;
};
#endif

View File

@ -22,6 +22,7 @@
#include "core/device.h"
#include "core/partitiontable.h"
#include "core/smartstatus.h"
#include "util/capacity.h"
#include "util/helpers.h"
@ -40,7 +41,7 @@ DevicePropsDialog::DevicePropsDialog(QWidget* parent, Device& d) :
m_DialogWidget(new DevicePropsWidget(this))
{
setMainWidget(&dialogWidget());
setCaption(i18nc("@title:window", "Device properties: <filename>%1</filename>", device().deviceNode()));
setCaption(i18nc("@title:window", "Device Properties: <filename>%1</filename>", device().deviceNode()));
setupDialog();
setupConnections();
@ -100,6 +101,23 @@ void DevicePropsDialog::setupDialog()
dialogWidget().totalSectors().setText(KGlobal::locale()->formatNumber(device().totalSectors(), 0));
dialogWidget().type().setText(type);
if (device().smartStatus().isValid())
{
dialogWidget().smartStatus().setText(device().smartStatus().status()
? i18nc("@label SMART disk status", "good")
: i18nc("@label SMART disk status", "BAD"));
const QString temp = KGlobal::locale()->formatNumber(device().smartStatus().temp() / 10.0, 1);
dialogWidget().temperature().setText(i18nc("@label temperature in celsius", "%1° C", temp));
dialogWidget().badSectors().setText(KGlobal::locale()->formatNumber(device().smartStatus().badSectors(), 0));
dialogWidget().poweredOn().setText(KGlobal::locale()->formatDuration(device().smartStatus().poweredOn()));
dialogWidget().powerCycles().setText(KGlobal::locale()->formatNumber(device().smartStatus().powerCycles(), 0));
}
else
{
dialogWidget().smartStatus().setText(i18nc("@label", "(unknown)"));
dialogWidget().hideSmartLabels();
}
setMinimumSize(dialogWidget().size());
resize(dialogWidget().size());
}

View File

@ -57,6 +57,30 @@ class DevicePropsWidget : public QWidget, public Ui::DevicePropsWidgetBase
radioSectorBased().setVisible(false);
radioCylinderBased().setVisible(false);
}
QLabel& smartStatus() { Q_ASSERT(m_LabelSmartStatus); return *m_LabelSmartStatus; }
QLabel& temperature() { Q_ASSERT(m_LabelSmartTemperature); return *m_LabelSmartTemperature; }
QLabel& badSectors() { Q_ASSERT(m_LabelSmartBadSectors); return *m_LabelSmartBadSectors; }
QLabel& poweredOn() { Q_ASSERT(m_LabelSmartPoweredOn); return *m_LabelSmartPoweredOn; }
QLabel& powerCycles() { Q_ASSERT(m_LabelSmartPowerCycles); return *m_LabelSmartPowerCycles; }
QLabel& labelTemperature() { Q_ASSERT(m_LabelTextSmartTemperature); return *m_LabelTextSmartTemperature; }
QLabel& labelBadSectors() { Q_ASSERT(m_LabelTextSmartBadSectors); return *m_LabelTextSmartBadSectors; }
QLabel& labelPoweredOn() { Q_ASSERT(m_LabelTextSmartPoweredOn); return *m_LabelTextSmartPoweredOn; }
QLabel& labelPowerCycles() { Q_ASSERT(m_LabelTextSmartPowerCycles); return *m_LabelTextSmartPowerCycles; }
void hideSmartLabels()
{
temperature().setVisible(false);
badSectors().setVisible(false);
poweredOn().setVisible(false);
powerCycles().setVisible(false);
labelTemperature().setVisible(false);
labelBadSectors().setVisible(false);
labelPoweredOn().setVisible(false);
labelPowerCycles().setVisible(false);
}
};
#endif

View File

@ -6,12 +6,12 @@
<rect>
<x>0</x>
<y>0</y>
<width>609</width>
<height>397</height>
<width>576</width>
<height>496</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<item row="0" column="0" colspan="3">
<widget class="PartTableWidget" name="m_PartTableWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -36,7 +36,7 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -62,7 +62,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="2" column="2">
<widget class="QLabel" name="m_LabelType">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -75,19 +75,19 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="3" column="2">
<layout class="QHBoxLayout" name="m_TypeLayout">
<item>
<widget class="QRadioButton" name="m_RadioCylinderBased">
<property name="text">
<string>Cylinder Alignment</string>
<string>Cylinder alignment</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_RadioSectorBased">
<property name="text">
<string>Sector Based Alignment</string>
<string>Sector based alignment</string>
</property>
</widget>
</item>
@ -106,7 +106,7 @@
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item row="4" column="0" colspan="3">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -123,7 +123,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<item row="5" column="2">
<widget class="QLabel" name="m_LabelCapacity">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -139,14 +139,14 @@
<item row="6" column="0">
<widget class="QLabel" name="m_LabelTextTotalSectors">
<property name="text">
<string>Total Sectors:</string>
<string>Total sectors:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="6" column="2">
<widget class="QLabel" name="m_LabelTotalSectors">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -159,7 +159,7 @@
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<item row="7" column="0" colspan="3">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -176,7 +176,7 @@
</property>
</widget>
</item>
<item row="8" column="1">
<item row="8" column="2">
<widget class="QLabel" name="m_LabelCHS">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -192,14 +192,14 @@
<item row="9" column="0">
<widget class="QLabel" name="m_LabelTextSectorSize">
<property name="text">
<string>Logical Sector Size:</string>
<string>Logical sector size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="9" column="2">
<widget class="QLabel" name="m_LabelSectorSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -215,14 +215,14 @@
<item row="10" column="0">
<widget class="QLabel" name="m_LabelTextCylinderSize">
<property name="text">
<string>Cylinder Size:</string>
<string>Cylinder size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="10" column="2">
<widget class="QLabel" name="m_LabelCylinderSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -235,7 +235,7 @@
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<item row="11" column="0" colspan="3">
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -252,7 +252,7 @@
</property>
</widget>
</item>
<item row="12" column="1">
<item row="12" column="2">
<widget class="QLabel" name="m_LabelPrimariesMax">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -265,7 +265,99 @@
</property>
</widget>
</item>
<item row="13" column="0" colspan="2">
<item row="13" column="0" colspan="3">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="m_LabelTextSmartStatus">
<property name="text">
<string>SMART status:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="14" column="2">
<widget class="QLabel" name="m_LabelSmartStatus">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="m_LabelTextSmartTemperature">
<property name="text">
<string>Temperature:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="15" column="2">
<widget class="QLabel" name="m_LabelSmartTemperature">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="m_LabelTextSmartBadSectors">
<property name="text">
<string>Bad sectors:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="16" column="2">
<widget class="QLabel" name="m_LabelSmartBadSectors">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="m_LabelTextSmartPoweredOn">
<property name="text">
<string>Powered on for:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="17" column="2">
<widget class="QLabel" name="m_LabelSmartPoweredOn">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="m_LabelTextSmartPowerCycles">
<property name="text">
<string>Power cycles:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="18" column="2">
<widget class="QLabel" name="m_LabelSmartPowerCycles">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="19" column="0" colspan="3">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>