From 0ad7de435238e77b73f8e73ee93bc54385a0ae26 Mon Sep 17 00:00:00 2001 From: localhorst Date: Sun, 21 Apr 2024 12:57:05 +0200 Subject: [PATCH] support smartctl usb contoller options --- include/smart.h | 1 + src/smart.cpp | 161 +++++++++++++++++++++++++++++------------------- 2 files changed, 97 insertions(+), 65 deletions(-) diff --git a/include/smart.h b/include/smart.h index 37890f1..f7b9adb 100644 --- a/include/smart.h +++ b/include/smart.h @@ -20,6 +20,7 @@ public: private: SMART(void); + static uint8_t parseExitStatus(string sLine); static void parseModelFamily(string sLine); static void parseModelName(string sLine); static void parseSerial(string sLine); diff --git a/src/smart.cpp b/src/smart.cpp index a19fa67..9506cd6 100644 --- a/src/smart.cpp +++ b/src/smart.cpp @@ -21,7 +21,7 @@ uint32_t SMART::temperature = 0U; * \param pointer of Drive instance * \return void */ -void SMART::readSMARTData(Drive* drive) +void SMART::readSMARTData(Drive *drive) { modelFamily.clear(); modelName.clear(); @@ -32,19 +32,25 @@ void SMART::readSMARTData(Drive* drive) powerCycle = 0U; temperature = 0U; - size_t len = 0; //lenght of found line - char* cLine = NULL; //found line + string sSmartctlCommands[] = {" --json -a ", " --json -d sntjmicron -a ", " --json -d sntasmedia -a ", " --json -d sntrealtek -a "}; - string sCMD = ("smartctl --json -a "); - sCMD.append(drive->getPath()); - const char* cpComand = sCMD.c_str(); + for (string sSmartctlCommand : sSmartctlCommands) + { + string sCMD = ("smartctl"); + sCMD.append(sSmartctlCommand); + sCMD.append(drive->getPath()); + const char *cpComand = sCMD.c_str(); - FILE* outputfileSmart = popen(cpComand, "r"); + FILE *outputfileSmart = popen(cpComand, "r"); + size_t len = 0; // length of found line + char *cLine = NULL; // found line + uint8_t status = 255; - while ((getline(&cLine, &len, outputfileSmart)) != -1) + while ((getline(&cLine, &len, outputfileSmart)) != -1) { string sLine = string(cLine); + status = SMART::parseExitStatus(sLine); SMART::parseModelFamily(sLine); SMART::parseModelName(sLine); SMART::parseSerial(sLine); @@ -54,8 +60,35 @@ void SMART::readSMARTData(Drive* drive) SMART::parsePowerCycle(sLine); SMART::parseTemperature(sLine); } - pclose(outputfileSmart); - drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle, temperature); //wirte data in drive + + pclose(outputfileSmart); + + if (status == 0U) + { + //Found S.M.A.R.T. data with this command + break; + } + } + + drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle, temperature); // wirte data in drive +} + +/** + * \brief parse ExitStatus + * \param string output line of smartctl + * \return uint_8 exit status + */ +uint8_t SMART::parseExitStatus(string sLine) +{ + uint8_t exitStatus = -1; + string search("\"exit_status\": "); + size_t found = sLine.find(search); + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 1); + exitStatus = stol(sLine); + } + return exitStatus; } /** @@ -67,12 +100,12 @@ void SMART::parseModelFamily(string sLine) { string search("\"model_family\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 3); - sLine.erase(sLine.length()-3, 3); - modelFamily = sLine; - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 3); + sLine.erase(sLine.length() - 3, 3); + modelFamily = sLine; + } } /** @@ -84,12 +117,12 @@ void SMART::parseModelName(string sLine) { string search("\"model_name\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 3); - sLine.erase(sLine.length()-3, 3); - modelName = sLine; - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 3); + sLine.erase(sLine.length() - 3, 3); + modelName = sLine; + } } /** @@ -101,12 +134,12 @@ void SMART::parseSerial(string sLine) { string search("\"serial_number\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 3); - sLine.erase(sLine.length()-3, 3); - serial = sLine; - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 3); + sLine.erase(sLine.length() - 3, 3); + serial = sLine; + } } /** @@ -118,12 +151,12 @@ void SMART::parseCapacity(string sLine) { string search("\"bytes\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 2); - sLine.erase(sLine.length()-1, 1); - capacity = stol(sLine); - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 2); + sLine.erase(sLine.length() - 1, 1); + capacity = stol(sLine); + } } /** @@ -135,12 +168,12 @@ void SMART::parseErrorCount(string sLine) { string search("\"error_count_total\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ")+2); - sLine.erase(sLine.length()-2, 2); - errorCount = stol(sLine); - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 2); + sLine.erase(sLine.length() - 2, 2); + errorCount = stol(sLine); + } } /** @@ -152,13 +185,12 @@ void SMART::parsePowerOnHours(string sLine) { string search("\"hours\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 2); - sLine.erase(sLine.length()-1, 1); - powerOnHours = stol(sLine); - - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 2); + sLine.erase(sLine.length() - 1, 1); + powerOnHours = stol(sLine); + } } /** @@ -170,13 +202,12 @@ void SMART::parsePowerCycle(string sLine) { string search("\"power_cycle_count\": "); size_t found = sLine.find(search); - if (found!=string::npos) - { - sLine.erase(0, sLine.find(": ") + 2); - sLine.erase(sLine.length()-2, 2); - powerCycle = stol(sLine); - - } + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 2); + sLine.erase(sLine.length() - 2, 2); + powerCycle = stol(sLine); + } } /** @@ -188,17 +219,17 @@ void SMART::parseTemperature(string sLine) { string search("\"current\": "); size_t found = sLine.find(search); - if (found!=string::npos) + if (found != string::npos) + { + sLine.erase(0, sLine.find(": ") + 2); + sLine.erase(sLine.length() - 1, 2); + if (sLine == "{") { - sLine.erase(0, sLine.find(": ") + 2); - sLine.erase(sLine.length()-1, 2); - if(sLine == "{") - { - temperature = 0U; // this drive doesn't support temperatur - } - else - { - temperature = stol(sLine); - } + temperature = 0U; // this drive doesn't support temperature } + else + { + temperature = stol(sLine); + } + } }