File indexing completed on 2024-04-21 16:19:52

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2021 Harald Sitter <sitter@kde.org>
0003 
0004 #include "instabilities.h"
0005 
0006 #include <KLocalizedString>
0007 
0008 #include <QMetaEnum>
0009 
0010 #include "smartdata.h"
0011 
0012 static QString smartCtlDataFailureToInstabilityString(SMART::Failure failure)
0013 {
0014     switch (failure) {
0015     case SMART::Failure::None:
0016     case SMART::Failure::CmdLineParse:
0017     case SMART::Failure::DeviceOpen:
0018     case SMART::Failure::InternalCommand:
0019         // These are kind of internal failures that the user cannot really
0020         // do anything about and they aren't necessarily indicative of
0021         // anything wrong with the drive.
0022         return {};
0023     case SMART::Failure::Disk:
0024         // This is reflected as failure.
0025         return {};
0026     case SMART::Failure::Prefail:
0027         return i18nc("@label", "Prefail attributes <= threshold.");
0028     case SMART::Failure::PastPrefail:
0029         return i18nc(
0030             "@label",
0031             "SMART status check returned 'DISK OK' but we found that some (usage or prefail) attributes have been <= threshold at some time in the past.");
0032     case SMART::Failure::ErrorsRecorded:
0033         return i18nc("@label", "The device error log contains records of errors.");
0034     case SMART::Failure::SelfTestErrors:
0035         return i18nc(
0036             "@label",
0037             "The device self-test log contains records of errors. [ATA only] Failed self-tests outdated by a newer successful extended self-test are ignored.");
0038     }
0039     Q_UNREACHABLE();
0040     return {};
0041 }
0042 
0043 QStringList Instabilities::from(const SMARTData &data)
0044 {
0045     QStringList list;
0046     const SMARTCtlData ctlData = data.m_smartctl;
0047     const auto failureEnum = QMetaEnum::fromType<SMART::Failure>();
0048     for (auto i = 0; i < failureEnum.keyCount(); ++i) {
0049         const auto fail = static_cast<SMART::Failure>(failureEnum.value(i));
0050         const bool flagSet = ctlData.failure().testFlag(fail);
0051         if (!flagSet) {
0052             continue;
0053         }
0054         const QString instability = smartCtlDataFailureToInstabilityString(fail);
0055         if (!instability.isEmpty()) {
0056             list << instability;
0057         }
0058     }
0059     return list;
0060 }