From e49c1a231ccff94b6cb6bff9c2db2be5dc3c2b57 Mon Sep 17 00:00:00 2001 From: localhorst Date: Sun, 15 May 2022 15:17:49 +0200 Subject: [PATCH] read random date in bulk to reduce syscalls --- include/reHDD.h | 7 ++- include/shred.h | 9 ++-- src/shred.cpp | 110 ++++++++++++++++++++++++++++++------------------ 3 files changed, 78 insertions(+), 48 deletions(-) diff --git a/include/reHDD.h b/include/reHDD.h index b8b9cfa..08d2ac4 100644 --- a/include/reHDD.h +++ b/include/reHDD.h @@ -8,12 +8,12 @@ #ifndef REHDD_H_ #define REHDD_H_ -#define REHDD_VERSION "bV0.2.1" +#define REHDD_VERSION "bV0.2.2" // Drive handling Settings #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 SHRED_ITERATIONS 3 +#define SHRED_ITERATIONS 3U #define FROZEN_TIMEOUT 10 //After this timeout (minutes) the drive will be marked as frozen // Logger Settings @@ -23,14 +23,13 @@ #define SOFTWARE_VERSION "alpha" #define HARDWARE_VERSION "generic" -//#define LOG_LEVEL_HIGH //log everything, like drive scann thread +//#define LOG_LEVEL_HIGH //log everything, like drive scan thread #ifndef LOG_LEVEL_HIGH #define LOG_LEVEL_LOW //log only user actions and tasks #endif // Logic //#define DRYRUN //donĀ“t touch the drives -//#define DEMO_DRIVE_SIZE 1024*1024*256 // 256MB used for shredding only #define FROZEN_ALERT //show alert if drive is frozen #define ZERO_CHECK_ALERT //check drive after shred if all bytes are zero, show alert if this fails diff --git a/include/shred.h b/include/shred.h index 6306762..0937766 100644 --- a/include/shred.h +++ b/include/shred.h @@ -17,11 +17,12 @@ #include #include - #define CHUNK_SIZE 1024*1024*2 //amount of bytes that are overwritten at once -#define SHRED_ITERATIONS 3 //overwrite the drive multiple times, last time with zeros +#define CHUNK_DIMENSION 100U //amount of chunks are read at once from random source -//#define DEMO_DRIVE_SIZE 1024*1024*256 // 256MB +//#define DEMO_DRIVE_SIZE 1024*1024*256L // 256MB +//#define DEMO_DRIVE_SIZE 1024*1024*1024L // 1GB +#define DEMO_DRIVE_SIZE 1024*1024*1024*10L // 10GB typedef int fileDescriptor; @@ -38,7 +39,7 @@ public: private: fileDescriptor randomSrcFileDiscr; fileDescriptor driveFileDiscr; - unsigned char caChunk[CHUNK_SIZE]; + unsigned char caChunk[CHUNK_DIMENSION][CHUNK_SIZE]; unsigned long ulDriveByteSize; unsigned long ulDriveByteOverallCount = 0; //all bytes shredded in all iterations + checking -> used for progress calculation double d32Percent = 0.0; diff --git a/src/shred.cpp b/src/shred.cpp index 6031184..3e70e44 100644 --- a/src/shred.cpp +++ b/src/shred.cpp @@ -30,7 +30,7 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) { if(drive->state != Drive::SHRED_ACTIVE) { - return; + return 0; } drive->setTaskPercentage(i+0.05); write(*ipSignalFd, "A",1); @@ -45,6 +45,8 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) randomSrcFileDiscr = open(randomsrc, O_RDONLY | O_LARGEFILE); if (randomSrcFileDiscr == -1) { + std::string errorMsg(strerror(randomSrcFileDiscr)); + Logger::logThis()->error("Shred-Task: Open random source failed! " + errorMsg + " - Drive: " + drive->getSerial()); perror(randomsrc); cleanup(); return -1; @@ -54,6 +56,8 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) driveFileDiscr = open(cpDrivePath, O_RDWR | O_LARGEFILE); if (driveFileDiscr == -1) { + std::string errorMsg(strerror(driveFileDiscr)); + Logger::logThis()->error("Shred-Task: Open drive failed! " + errorMsg + " - Drive: " + drive->getSerial()); perror(cpDrivePath); cleanup(); return -1; @@ -67,17 +71,57 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) for (unsigned int uiShredIterationCounter = 0U; uiShredIterationCounter < SHRED_ITERATIONS; uiShredIterationCounter++) { - unsigned long ulDriveByteCounter = 0U; + unsigned long ulDriveByteCounter = 0U; //used for one shred-iteration to keep track of the current drive position + uint32_t u32ChunkDimensionIndex = 0U; if(uiShredIterationCounter == (SHRED_ITERATIONS-1)) { //last shred iteration --> overwrite with zeros instead with random data - memset(caChunk, 0U, CHUNK_SIZE); + memset(caChunk, 0U, CHUNK_DIMENSION*CHUNK_SIZE); } while (ulDriveByteCounter < ulDriveByteSize) { - int iBytesToShred = 0; + int iBytesToShred = 0; //Bytes that will be overwritten in this chunk-iteration + + if((u32ChunkDimensionIndex == 0U) && (uiShredIterationCounter != (SHRED_ITERATIONS-1))) + { + //read new chunks from random source if needed and this is NOT the last shred iteration + unsigned long ulBytesInChunkBuffer = 0U; + + while (ulBytesInChunkBuffer < CHUNK_DIMENSION*CHUNK_SIZE) + { + //read new random bytes + int iReadBytes = read(randomSrcFileDiscr, caChunk, ((CHUNK_DIMENSION*CHUNK_SIZE)-ulBytesInChunkBuffer)); + if (iReadBytes > 0) + { + ulBytesInChunkBuffer += iReadBytes; + } + else + { + std::string errorMsg(strerror(iReadBytes)); + Logger::logThis()->error("Shred-Task: Read from random source failed! " + errorMsg + " - Drive: " + drive->getSerial()); + perror("unable to read random data"); + cleanup(); + return -1;; + } + } //end chunk read +#ifdef LOG_LEVEL_HIGH + Logger::logThis()->info("Shred-Task: Read new random data - Drive: " + drive->getSerial()); +#endif +/* + int retFDataSync = fdatasync(driveFileDiscr); + if(retFDataSync != 0) + { + std::string errorMsg(strerror(retFDataSync)); + Logger::logThis()->error("Shred-Task: Flush drive failed! " + errorMsg + " - Drive: " + drive->getSerial()); + perror("unable to flush random data"); + cleanup(); + return -1; + } +*/ + + } if((ulDriveByteSize-ulDriveByteCounter) < CHUNK_SIZE) { @@ -88,37 +132,18 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) iBytesToShred = CHUNK_SIZE; } - if(uiShredIterationCounter != (SHRED_ITERATIONS-1)) - { - //NOT last shred iteration --> overwrite with random data - int iReadBytes = read(randomSrcFileDiscr, caChunk, iBytesToShred); - if (iReadBytes > 0) - { - iBytesToShred = iReadBytes; - } - else - { - perror("unable to read random data"); - cleanup(); - return -1;; - } - } - - int iByteShredded = write(driveFileDiscr, caChunk, iBytesToShred); + int iByteShredded = write(driveFileDiscr, caChunk[u32ChunkDimensionIndex], iBytesToShred); if(iByteShredded <= 0) { + std::string errorMsg(strerror(iByteShredded)); + Logger::logThis()->error("Shred-Task: Write to drive failed! " + errorMsg + " - Drive: " + drive->getSerial()); perror("unable to write random data"); cleanup(); return -1; } - if(fsync(driveFileDiscr) != 0) - { - perror("unable to flush random data"); - cleanup(); - return -1; - } + u32ChunkDimensionIndex = (u32ChunkDimensionIndex+1)%CHUNK_DIMENSION; ulDriveByteCounter += iByteShredded; ulDriveByteOverallCount += iByteShredded; d32Percent = this->calcProgress(); @@ -143,15 +168,24 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) cleanup(); return -1; } - - }//end one shred iteration - + }//end one chunk write + /* + int retFDataSync = fdatasync(driveFileDiscr); + if(retFDataSync != 0) + { + std::string errorMsg(strerror(retFDataSync)); + Logger::logThis()->error("Shred-Task: Flush drive failed! " + errorMsg + " - Drive: " + drive->getSerial()); + perror("unable to flush random data"); + cleanup(); + return -1; + } + */ if(0 != iRewindDrive(driveFileDiscr)) { cleanup(); return -1; } - } //end all shred iterations + } //end one shred iteration #ifdef ZERO_CHECK_ALERT drive->u32DriveChecksumAferShredding = uiCalcChecksum(driveFileDiscr, drive, ipSignalFd); @@ -168,6 +202,8 @@ int Shred::shredDrive(Drive* drive, int* ipSignalFd) #endif #endif + cleanup(); + if(drive->state == Drive::SHRED_ACTIVE) { drive->bWasShredded = true; @@ -236,29 +272,23 @@ unsigned int Shred::uiCalcChecksum(fileDescriptor file,Drive* drive, int* ipSign { iBytesToCheck = CHUNK_SIZE; } - int iReadBytes = read(file, caChunk, iBytesToCheck); - for (int iReadBytesCounter = 0U; iReadBytesCounter < iReadBytes; iReadBytesCounter++) { - uiChecksum += caChunk[iReadBytesCounter]; + uiChecksum += caChunk[0][iReadBytesCounter]; } ulDriveByteCounter += iReadBytes; - ulDriveByteOverallCount += ulDriveByteCounter; - + ulDriveByteOverallCount += iReadBytes; d32Percent = this->calcProgress(); - #ifdef LOG_LEVEL_HIGH Logger::logThis()->info("Shred-Task (Checksum): ByteCount: " + to_string(ulDriveByteCounter) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial()); #endif - - if((d32Percent-d32TmpPercent) >= 0.09) + if((d32Percent-d32TmpPercent) >= 0.9) { drive->setTaskPercentage(d32TmpPercent); d32TmpPercent = d32Percent; write(*ipSignalFd, "A",1); } - } return uiChecksum; }