detect frozen drives and show that the user

This commit is contained in:
Hendrik Schutter 2020-09-11 17:18:53 +02:00
parent 5f593682e2
commit 67b8e302be
7 changed files with 103 additions and 15 deletions

View File

@ -18,7 +18,8 @@ public:
SHRED_SELECTED, SHRED_SELECTED,
SHRED_ACTIVE, SHRED_ACTIVE,
DELETE_SELECTED, DELETE_SELECTED,
DELETE_ACTIVE DELETE_ACTIVE,
FROZEN
} state; } state;
bool bWasShredded = false; bool bWasShredded = false;
@ -34,9 +35,11 @@ private:
uint32_t u32ErrorCount = 0U; uint32_t u32ErrorCount = 0U;
uint32_t u32PowerOnHours = 0U; //in hours uint32_t u32PowerOnHours = 0U; //in hours
uint32_t u32PowerCycles = 0U; uint32_t u32PowerCycles = 0U;
time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100) double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
private:
void setTimestamp();
protected: protected:
@ -54,6 +57,7 @@ public:
uint32_t getErrorCount(void); uint32_t getErrorCount(void);
uint32_t getPowerOnHours(void); //in hours uint32_t getPowerOnHours(void); //in hours
uint32_t getPowerCycles(void); uint32_t getPowerCycles(void);
void checkFrozenDrive(void);
void setDriveSMARTData( string modelFamily, void setDriveSMARTData( string modelFamily,
string modelName, string modelName,

View File

@ -8,15 +8,13 @@
#ifndef REHDD_H_ #ifndef REHDD_H_
#define REHDD_H_ #define REHDD_H_
//#define DRYRUN #define DRYRUN
// Drive handling Settings
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond #define WORSE_HOURS 19200 //mark drive if at this limit or beyond
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond #define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
#define SHRED_ITERATIONS 1 #define SHRED_ITERATIONS 1
#define FROZEN_TIMEOUT 5 //After this timeout (minutes) the drive will be marked as frozen
#define READ 0
#define WRITE 1
// Logger Settings // Logger Settings
#define LOG_PATH "./reHDD.log" #define LOG_PATH "./reHDD.log"
@ -30,6 +28,10 @@
#define LOG_LEVEL_LOW //log only user actions and tasks #define LOG_LEVEL_LOW //log only user actions and tasks
#endif #endif
//IPC pipes
#define READ 0
#define WRITE 1
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <fstream> #include <fstream>
@ -82,6 +84,7 @@ private:
static void ThreadScannDevices(); static void ThreadScannDevices();
static void ThreadUserInput(); static void ThreadUserInput();
static void ThreadShred(); static void ThreadShred();
static void ThreadCheckFrozenDrives();
static void handleArrowKey(TUI::UserInput userInput); static void handleArrowKey(TUI::UserInput userInput);
static void handleEnter(); static void handleEnter();
static void handleESC(); static void handleESC();

View File

@ -56,10 +56,11 @@ private:
static WINDOW *createOverViewWindow( int iXSize, int iYSize); static WINDOW *createOverViewWindow( int iXSize, int iYSize);
static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive); static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive);
static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart); static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart,string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected); static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected);
static WINDOW *createSystemStats(int iXSize, int iYSize, int iYStart); static WINDOW *createSystemStats(int iXSize, int iYSize, int iYStart);
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate); static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB); static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial);
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY); void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);

View File

@ -91,6 +91,7 @@ void Drive::setTaskPercentage(double d32TaskPercentage)
if(d32TaskPercentage <= 100) if(d32TaskPercentage <= 100)
{ {
this->d32TaskPercentage = d32TaskPercentage; this->d32TaskPercentage = d32TaskPercentage;
this->setTimestamp(); //set timestamp for this progress for detecting a frozen drive
} }
} }
double Drive::getTaskPercentage(void) double Drive::getTaskPercentage(void)
@ -125,4 +126,24 @@ void Drive::setDriveSMARTData( string modelFamily,
u32ErrorCount = errorCount; u32ErrorCount = errorCount;
u32PowerOnHours = powerOnHours; u32PowerOnHours = powerOnHours;
u32PowerCycles = powerCycle; u32PowerCycles = powerCycle;
}
void Drive::setTimestamp()
{
time(&this->u32Timestamp);
}
void Drive::checkFrozenDrive(void)
{
time_t u32localtime;
time(&u32localtime);
if((u32localtime - this->u32Timestamp) >= (FROZEN_TIMEOUT*60) && (this->u32Timestamp > 0))
{
Logger::logThis()->warning("Drive Frozen: " + this->getModelName() + " " + this->getSerial());
this->bWasDeleteted = false;
this->bWasShredded = false;
this->state = Drive::FROZEN;
}
} }

View File

@ -52,6 +52,7 @@ void reHDD::app_logic(void)
thread thDevices(ThreadScannDevices); //start thread that scanns for drives thread thDevices(ThreadScannDevices); //start thread that scanns for drives
thread thUserInput(ThreadUserInput); //start thread that reads user input thread thUserInput(ThreadUserInput); //start thread that reads user input
thread thCheckFrozenDrives(ThreadCheckFrozenDrives); //start thread that checks timeout for drives
while(1) while(1)
{ {
@ -60,15 +61,14 @@ void reHDD::app_logic(void)
FD_SET(fdShredInformPipe[0], &selectSet); FD_SET(fdShredInformPipe[0], &selectSet);
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL); select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
mxScannDrives.lock();
if( FD_ISSET(fdNewDrivesInformPipe[0], &selectSet)) if( FD_ISSET(fdNewDrivesInformPipe[0], &selectSet))
{ {
char dummy; char dummy;
read (fdNewDrivesInformPipe[0],&dummy,1); read (fdNewDrivesInformPipe[0],&dummy,1);
mxScannDrives.lock();
filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector
printDrives(&vecDrives); printDrives(&vecDrives);
mxScannDrives.unlock();
} }
if (FD_ISSET(fdShredInformPipe[0], &selectSet)) if (FD_ISSET(fdShredInformPipe[0], &selectSet))
@ -77,9 +77,11 @@ void reHDD::app_logic(void)
read (fdShredInformPipe[0],&dummy,1); read (fdShredInformPipe[0],&dummy,1);
} }
ui->updateTUI(&vecDrives, u8SelectedEntry); ui->updateTUI(&vecDrives, u8SelectedEntry);
mxScannDrives.unlock();
} //endless loop } //endless loop
thDevices.join(); thDevices.join();
thUserInput.join(); thUserInput.join();
thCheckFrozenDrives.join();
} }
Drive* reHDD::getSelectedDrive() Drive* reHDD::getSelectedDrive()
@ -110,6 +112,25 @@ void reHDD::ThreadScannDevices()
} }
} }
void reHDD::ThreadCheckFrozenDrives()
{
while(true)
{
mxScannDrives.lock();
for(auto it = begin(vecDrives); it != end(vecDrives); ++it)
{
if(it->state == Drive::SHRED_ACTIVE)
{
it->checkFrozenDrive();
}
}
mxScannDrives.unlock();
sleep(5); //sleep 5 sec
}
}
void reHDD::ThreadUserInput() void reHDD::ThreadUserInput()
{ {
while(true) while(true)

View File

@ -21,6 +21,7 @@ struct tfnge_stream
}; };
static struct tfnge_stream tfnge; static struct tfnge_stream tfnge;
#endif
Shred::Shred() Shred::Shred()
{ {
@ -34,7 +35,7 @@ Shred::~Shred()
} }
#endif
/** /**
* \brief shred drive with shred * \brief shred drive with shred
* \param pointer of Drive instance * \param pointer of Drive instance
@ -51,7 +52,6 @@ void Shred::shredDrive(Drive* drive, int* ipSignalFd)
} }
drive->setTaskPercentage(i+0.05); drive->setTaskPercentage(i+0.05);
write(*ipSignalFd, "A",1); write(*ipSignalFd, "A",1);
usleep(20000); usleep(20000);
} }
#endif #endif

View File

@ -111,6 +111,10 @@ void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
} }
break; break;
case Drive::FROZEN:
dialog=createFrozenWarning(70, 16, ((stdscrX)-(int)(stdscrX/2)-35),(int)(stdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial());
wrefresh(dialog);
break;
default: default:
break; break;
} }
@ -276,11 +280,11 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
string sLine01 = "reHDD - hard drive refurbishing tool"; string sLine01 = "reHDD - hard drive refurbishing tool";
string sLine02 = "Version: beta X.X.X"; string sLine02 = "Version: beta X.X.X";
string sLine03 = "Available under GPL 3.0"; string sLine03 = "Available under GPL 3.0";
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD"; string sLine04 = "https://git.mosad.xyz/localhorst/reHDD";
string sLine05 = "Delete: Wipe format table - this is NOT secure"; string sLine05 = "Delete: Wipe format table - this is NOT secure";
string sLine06 = "Shred: Overwite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure"; string sLine06 = "Shred: Overwite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure";
uint16_t u16Line = 5; uint16_t u16Line = 5;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str()); mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
@ -395,6 +399,40 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri
return newWindow; return newWindow;
} }
WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
box(newWindow, ACS_VLINE, ACS_HLINE);
string sHeader = "Drive " + sPath + " is frozen";
string sLine01 = "Please detach this drive and check it manually:";
string sLinePath = "Path: " +sPath;
string sLineModelFamlily = "ModelFamily: " + sModelFamily;
string sLineModelName = "ModelName: " + sModelName;
string sLineSerial = "Serial: " + sSerial;
string sLine02 = "reHDD was not able to write data to the drive.";
string sLine03 = "This can be caused by an malfunctioning drive.";
centerTitle(newWindow, sHeader.c_str());
uint16_t u16Line = 2;
mvwaddstr(newWindow,u16Line++, 3, sLine01.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, 3, sLinePath.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineModelFamlily.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineModelName.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLineSerial.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, 3, sLine02.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLine03.c_str());
return newWindow;
}
void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY) void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
{ {
struct MenuState menustate; struct MenuState menustate;