File indexing completed on 2023-09-24 09:38:13
0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0002 // SPDX-FileCopyrightText: 2020-2021 Harald Sitter <sitter@kde.org> 0003 0004 #include "smartdata.h" 0005 0006 #include <QJsonDocument> 0007 #include <QJsonObject> 0008 #include <QJsonValue> 0009 0010 #include "kded_debug.h" 0011 0012 SMARTStatus::SMARTStatus(const QJsonObject &object) 0013 : m_passed(object[QStringLiteral("passed")].toBool()) 0014 { 0015 // Should we decide to map the value. Its meaning is "defined" in 0016 // nvmeprint.cpp of smartmontools 0017 } 0018 SMARTCtlData::SMARTCtlData(const QJsonObject &object) 0019 : m_exitStatus(object[QStringLiteral("exit_status")].toInt(static_cast<int>(SMART::Failure::None))) 0020 { 0021 } 0022 0023 SMART::Failures SMARTCtlData::failure() const 0024 { 0025 return {static_cast<SMART::Failure>(m_exitStatus)}; 0026 } 0027 0028 SMARTData::SMARTData(const QJsonDocument &document) 0029 : m_smartctl(SMARTCtlData(document.object()[QStringLiteral("smartctl")].toObject())) 0030 , m_status(SMARTStatus(document.object()[QStringLiteral("smart_status")].toObject())) 0031 , m_device(document.object()[QStringLiteral("device")].toObject()[QStringLiteral("name")].toString()) 0032 , m_valid(checkValid(document)) 0033 { 0034 } 0035 0036 bool SMARTData::checkValid(const QJsonDocument &document) const 0037 { 0038 if (m_smartctl.failure() & SMART::Failure::CmdLineParse) { 0039 qCDebug(KDED) << "Command line error" << m_device << document.toJson(); 0040 return false; 0041 } 0042 if (m_smartctl.failure() & SMART::Failure::DeviceOpen) { 0043 qCDebug(KDED) << "Failed to open device" << m_device << document.toJson(); 0044 return false; 0045 } 0046 const bool hasSMARTStatus = document.object().contains(QStringLiteral("smart_status")); 0047 const bool internalCommandFailure = (m_smartctl.failure() & SMART::Failure::InternalCommand); 0048 if (!hasSMARTStatus && internalCommandFailure) { 0049 // VirtualBox drives return with InternalCommand problems and no SMART data. Consider the data invalid. 0050 // If we also have other failure codes we'll still want to consider the data valid as it might indicate 0051 // problems. 0052 qCDebug(KDED) << "Internal command problems resulted in no smart_status data" << m_device << document.toJson(); 0053 return false; 0054 } 0055 const bool noFailure = m_smartctl.failure() == SMART::Failures(); 0056 if (!hasSMARTStatus && noFailure) { 0057 // When SMART is disabled we may get a blob back but it will lack any information on the SMART status. 0058 // Unfortunately the fact that SMART was disabled (versus not available etc.) isn't codified in the JSON. 0059 // https://bugs.kde.org/show_bug.cgi?id=435699 0060 qCDebug(KDED) << "SMART support is either disabled or not supported on the device" << m_device << document.toJson(); 0061 return false; 0062 } 0063 0064 return true; 0065 }