diff --git a/include/drive.h b/include/drive.h index f1e28ab..4432ce7 100644 --- a/include/drive.h +++ b/include/drive.h @@ -45,6 +45,7 @@ private: double d32TaskPercentage = 0U; // in percent for Shred (1 to 100) time_t u32TimestampTaskStart = 0U; // unix timestamp for duration of an action time_t u32TaskDuration = 0U; // time needed to complete the task + string desiredSmartctlCommand; //command used to gather S.M.A.R.T. values from drive struct { @@ -77,6 +78,7 @@ public: uint32_t getPowerOnHours(void); // in hours uint32_t getPowerCycles(void); uint32_t getTemperature(void); // in Fahrenheit, just kidding: degree Celsius + void checkFrozenDrive(void); void setDriveSMARTData(string modelFamily, @@ -100,6 +102,9 @@ public: void setActionStartTimestamp(); time_t getActionStartTimestamp(); + void setSmartcltCommand(string cmd); + string getSmartcltCommand(void); + void calculateTaskDuration(); time_t getTaskDuration(); }; diff --git a/src/drive.cpp b/src/drive.cpp index 1ca3e61..43cd793 100644 --- a/src/drive.cpp +++ b/src/drive.cpp @@ -161,6 +161,15 @@ time_t Drive::getActionStartTimestamp() return this->u32TimestampTaskStart; } +void Drive::setSmartcltCommand(string cmd) +{ + this->desiredSmartctlCommand = cmd; +} +string Drive::getSmartcltCommand(void) +{ + return this->desiredSmartctlCommand; +} + void Drive::calculateTaskDuration() { time_t u32localtime; diff --git a/src/smart.cpp b/src/smart.cpp index 339d94f..d739333 100644 --- a/src/smart.cpp +++ b/src/smart.cpp @@ -27,27 +27,62 @@ void SMART::readSMARTData(Drive *drive) modelName.clear(); serial.clear(); - string sSmartctlCommands[] = {" --json -a ", " --json -d sntjmicron -a ", " --json -d sntasmedia -a ", " --json -d sntrealtek -a ", " --json -d sat -a "}; - - for (string sSmartctlCommand : sSmartctlCommands) + if (drive->getSmartcltCommand().empty()) { - string sCMD = ("smartctl"); - sCMD.append(sSmartctlCommand); - sCMD.append(drive->getPath()); - const char *cpComand = sCMD.c_str(); + // No working Smartctl command is known --> try all + string sSmartctlCommands[] = {" --json -a ", " --json -d sntjmicron -a ", " --json -d sntasmedia -a ", " --json -d sntrealtek -a ", " --json -d sat -a "}; - // Logger::logThis()->info(cpComand); + 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"); - size_t len = 0U; // length of found line + // Logger::logThis()->info(cpComand); + + FILE *outputfileSmart = popen(cpComand, "r"); + size_t len = 0U; // length of found line + char *cLine = NULL; // found line + uint8_t status = 255U; + + while ((getline(&cLine, &len, outputfileSmart)) != -1) + { + string sLine = string(cLine); + + SMART::parseExitStatus(sLine, status); + SMART::parseModelFamily(sLine, modelFamily); + SMART::parseModelName(sLine, modelName); + SMART::parseSerial(sLine, serial); + SMART::parseCapacity(sLine, capacity); + SMART::parseErrorCount(sLine, errorCount); + SMART::parsePowerOnHours(sLine, powerOnHours); + SMART::parsePowerCycles(sLine, powerCycles); + SMART::parseTemperature(sLine, temperature); + } + + pclose(outputfileSmart); + + if (status == 0U) + { + // Found S.M.A.R.T. data with this command + // Logger::logThis()->info("Found S.M.A.R.T. data with this command"); + drive->setSmartcltCommand(sCMD); + break; + } + } + } + else + { + // A working Smartctl command is known + FILE *outputfileSmart = popen(drive->getSmartcltCommand().c_str(), "r"); + size_t len = 0U; // length of found line char *cLine = NULL; // found line - uint8_t status = 255U; while ((getline(&cLine, &len, outputfileSmart)) != -1) { string sLine = string(cLine); - SMART::parseExitStatus(sLine, status); SMART::parseModelFamily(sLine, modelFamily); SMART::parseModelName(sLine, modelName); SMART::parseSerial(sLine, serial); @@ -59,13 +94,6 @@ void SMART::readSMARTData(Drive *drive) } pclose(outputfileSmart); - - if (status == 0U) - { - // Found S.M.A.R.T. data with this command - // Logger::logThis()->info("Found S.M.A.R.T. data with this command"); - break; - } } drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycles, temperature); // write data in drive