read random date in bulk to reduce syscalls

This commit is contained in:
Hendrik Schutter 2022-05-15 15:17:49 +02:00
parent 4fc44d9926
commit e49c1a231c
3 changed files with 78 additions and 48 deletions

View File

@ -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

View File

@ -17,11 +17,12 @@
#include <unistd.h>
#include <string.h>
#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;

View File

@ -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;
}