From 9565ef61abee7f799f459caf0b0f1b2384b54b8b Mon Sep 17 00:00:00 2001 From: Valerii Malov Date: Mon, 20 May 2019 22:22:01 +0300 Subject: [PATCH 1/3] Add support for smartmontools 7.0 user_capacity json output Summary: smartmontools 7.0 reports user capacity as an object that contains bytes and blocks value, instead of being an int that just contains bytes This should fix incorrect calculation of bad blocks threshold and incorrect display of "Overall" status Test Plan: run partitionmanager on a system that has smartmontools 7, open smart status overall status should be reported correctly Reviewers: stikonas Reviewed By: stikonas Differential Revision: https://phabricator.kde.org/D21311 --- src/core/smartparser.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/smartparser.cpp b/src/core/smartparser.cpp index 294691e..18d09bb 100644 --- a/src/core/smartparser.cpp +++ b/src/core/smartparser.cpp @@ -91,7 +91,15 @@ bool SmartParser::init() m_DiskInformation->setModel(smartJson[model_name].toString()); m_DiskInformation->setFirmware(smartJson[firmware].toString()); m_DiskInformation->setSerial(smartJson[serial_number].toString()); - m_DiskInformation->setSize(smartJson[user_capacity].toVariant().toULongLong()); + + if (smartJson[user_capacity].isObject()) { + // smartmontools 7.0+ + const auto user_capacity_object = smartJson[user_capacity].toObject(); + QString user_capacity_bytes = QStringLiteral("bytes"); + m_DiskInformation->setSize(user_capacity_object[user_capacity_bytes].toVariant().toULongLong()); + } else { + m_DiskInformation->setSize(smartJson[user_capacity].toVariant().toULongLong()); + } QJsonObject selfTest = smartJson[self_test].toObject(); QJsonObject selfTestStatus = selfTest[status].toObject(); From 6a3b1e02b6bfa5d96332dc889bdca469167243d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Wed, 5 Jun 2019 00:50:07 +0100 Subject: [PATCH 2/3] smart: obtain disk size in blocks. Also drop pre 7.0 support as any earlier version was not supported. --- src/core/smartattributeparseddata.cpp | 2 +- src/core/smartdiskinformation.cpp | 4 ++-- src/core/smartdiskinformation.h | 10 +++++----- src/core/smartparser.cpp | 14 +++++--------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/core/smartattributeparseddata.cpp b/src/core/smartattributeparseddata.cpp index b310a7b..8e16899 100644 --- a/src/core/smartattributeparseddata.cpp +++ b/src/core/smartattributeparseddata.cpp @@ -260,7 +260,7 @@ void SmartAttributeParsedData::verifySectors() if (prettyUnit() != SmartAttributeUnit::Sectors) return; - quint64 maxSectors = disk()->size() / 512ULL; + quint64 maxSectors = disk()->sectors(); if (prettyValue() == 0xFFFFFFFFULL || prettyValue() == 0xFFFFFFFFFFFFULL || (maxSectors > 0 && prettyValue() > maxSectors)) diff --git a/src/core/smartdiskinformation.cpp b/src/core/smartdiskinformation.cpp index 85a5dbb..30e1a6c 100644 --- a/src/core/smartdiskinformation.cpp +++ b/src/core/smartdiskinformation.cpp @@ -27,7 +27,7 @@ SmartDiskInformation::SmartDiskInformation() : m_ModelName(QString()), m_FirmwareVersion(QString()), m_SerialNumber(QString()), - m_Size(0), + m_Sectors(0), m_Temperature(0), m_BadSectors(0), m_PoweredOn(0), @@ -64,7 +64,7 @@ void SmartDiskInformation::updateOverall() return; } - quint64 sector_threshold = u64log2(size() / 512) * 1024; + quint64 sector_threshold = u64log2(sectors()) * 1024; if (badSectors() >= sector_threshold) { m_Overall = SmartStatus::Overall::BadSectorsMany; diff --git a/src/core/smartdiskinformation.h b/src/core/smartdiskinformation.h index dbf3d38..8b9c957 100644 --- a/src/core/smartdiskinformation.h +++ b/src/core/smartdiskinformation.h @@ -66,9 +66,9 @@ public: return m_SerialNumber; /**< @return the disk serial number */ } - quint64 size() const + quint64 sectors() const { - return m_Size; /**< @return disk size */ + return m_Sectors; /**< @return disk size */ } bool smartStatus() const @@ -127,9 +127,9 @@ public: m_SerialNumber = serial; } - void setSize(quint64 size) + void setSectors(quint64 numSectors) { - m_Size = size; + m_Sectors = numSectors; } void setPowerCycles(quint64 powerCycleCt) @@ -159,7 +159,7 @@ private: QString m_ModelName; QString m_FirmwareVersion; QString m_SerialNumber; - quint64 m_Size; + quint64 m_Sectors; quint64 m_Temperature; quint64 m_BadSectors; quint64 m_PoweredOn; diff --git a/src/core/smartparser.cpp b/src/core/smartparser.cpp index 18d09bb..f7a7377 100644 --- a/src/core/smartparser.cpp +++ b/src/core/smartparser.cpp @@ -64,6 +64,7 @@ bool SmartParser::init() QString status = QStringLiteral("status"); QString value = QStringLiteral("value"); QString user_capacity = QStringLiteral("user_capacity"); + QString blocks = QStringLiteral("blocks"); if (!smartJson.contains(device)) { qDebug() << "smart disk open failed for " << devicePath() << ": " << strerror(errno); @@ -91,15 +92,10 @@ bool SmartParser::init() m_DiskInformation->setModel(smartJson[model_name].toString()); m_DiskInformation->setFirmware(smartJson[firmware].toString()); m_DiskInformation->setSerial(smartJson[serial_number].toString()); - - if (smartJson[user_capacity].isObject()) { - // smartmontools 7.0+ - const auto user_capacity_object = smartJson[user_capacity].toObject(); - QString user_capacity_bytes = QStringLiteral("bytes"); - m_DiskInformation->setSize(user_capacity_object[user_capacity_bytes].toVariant().toULongLong()); - } else { - m_DiskInformation->setSize(smartJson[user_capacity].toVariant().toULongLong()); - } + + const auto user_capacity_object = smartJson[user_capacity].toObject(); + QString user_capacity_blocks = QStringLiteral("bytes"); + m_DiskInformation->setSectors(user_capacity_object[user_capacity_blocks].toVariant().toULongLong()); QJsonObject selfTest = smartJson[self_test].toObject(); QJsonObject selfTestStatus = selfTest[status].toObject(); From 9b45e25f817202edfc9f7f25f7ee95a4024c697b Mon Sep 17 00:00:00 2001 From: Harald Sitter Date: Mon, 3 Jun 2019 14:46:18 +0200 Subject: [PATCH 3/3] manually quit kauth's mainloop Summary: kauth helpers have a qcoreapplication started which auto-terminates after 10 seconds of idle time. this would be an added time out on top of our life time management that is not necessary. to prevent this additional delay simply quit the qapplication directly. this makes helper termination almost instantaneous even when the dbus client disappears due to crash or SIGINT, and largely removes the need to call stopHelper altogether. BUG: 408245 Test Plan: both partitionmanager and calamares instantly quit the helper no matter how the client process gets terminated other than that everything seems to work as before Reviewers: stikonas Differential Revision: https://phabricator.kde.org/D21559 --- src/util/externalcommandhelper.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/externalcommandhelper.cpp b/src/util/externalcommandhelper.cpp index 5be2ec7..feabfe8 100644 --- a/src/util/externalcommandhelper.cpp +++ b/src/util/externalcommandhelper.cpp @@ -20,6 +20,7 @@ #include "externalcommand_whitelist.h" #include +#include #include #include #include @@ -82,6 +83,11 @@ ActionReply ExternalCommandHelper::init(const QVariantMap& args) m_loop->exec(); reply.addData(QStringLiteral("success"), true); + // Also end the application loop started by KAuth's main() code. Our loop + // exits when our client disappears. Without client we have no reason to + // live. + qApp->quit(); + return reply; }