2022-05-14 14:06:16 +02:00
/**
* @ file shred . cpp
* @ brief shred drive
* @ author hendrik schutter
* @ date 03.05 .2020
*/
# include "../include/reHDD.h"
const static char * randomsrc = ( char * ) " /dev/urandom " ;
Shred : : Shred ( )
{
}
Shred : : ~ Shred ( )
{
}
/**
* \ brief shred drive with shred
* \ param pointer of Drive instance
* \ return void
*/
int Shred : : shredDrive ( Drive * drive , int * ipSignalFd )
{
# ifdef DRYRUN
2022-08-20 16:09:40 +02:00
Logger : : logThis ( ) - > info ( " Shred-Task started - Drive: " + drive - > getSerial ( ) ) ;
2022-05-14 14:06:16 +02:00
for ( int i = 0 ; i < = 500 ; i + + )
{
if ( drive - > state ! = Drive : : SHRED_ACTIVE )
{
2022-05-15 15:17:49 +02:00
return 0 ;
2022-05-14 14:06:16 +02:00
}
drive - > setTaskPercentage ( i + 0.05 ) ;
write ( * ipSignalFd , " A " , 1 ) ;
usleep ( 20000 ) ;
}
# endif
# ifndef DRYRUN
const char * cpDrivePath = drive - > getPath ( ) . c_str ( ) ;
//open random source
randomSrcFileDiscr = open ( randomsrc , O_RDONLY | O_LARGEFILE ) ;
if ( randomSrcFileDiscr = = - 1 )
{
2022-05-15 15:17:49 +02:00
std : : string errorMsg ( strerror ( randomSrcFileDiscr ) ) ;
Logger : : logThis ( ) - > error ( " Shred-Task: Open random source failed! " + errorMsg + " - Drive: " + drive - > getSerial ( ) ) ;
2022-05-14 14:06:16 +02:00
perror ( randomsrc ) ;
cleanup ( ) ;
return - 1 ;
}
//open disk
driveFileDiscr = open ( cpDrivePath , O_RDWR | O_LARGEFILE ) ;
if ( driveFileDiscr = = - 1 )
{
2022-05-15 15:17:49 +02:00
std : : string errorMsg ( strerror ( driveFileDiscr ) ) ;
Logger : : logThis ( ) - > error ( " Shred-Task: Open drive failed! " + errorMsg + " - Drive: " + drive - > getSerial ( ) ) ;
2022-05-14 14:06:16 +02:00
perror ( cpDrivePath ) ;
cleanup ( ) ;
return - 1 ;
}
this - > ulDriveByteSize = getDriveSizeInBytes ( driveFileDiscr ) ;
2022-06-30 00:32:13 +02:00
drive - > sShredSpeed . chronoShredTimestamp = std : : chrono : : system_clock : : now ( ) ; ; //set inital timestamp for speed metric
unsigned long ulSpeedMetricBytesWritten = 0U ; //uses to calculate speed metric
2022-05-14 14:06:16 +02:00
# ifdef LOG_LEVEL_HIGH
Logger : : logThis ( ) - > info ( " Shred-Task: Bytes-Size of Drive: " + to_string ( this - > ulDriveByteSize ) + " - Drive: " + drive - > getSerial ( ) ) ;
# endif
for ( unsigned int uiShredIterationCounter = 0U ; uiShredIterationCounter < SHRED_ITERATIONS ; uiShredIterationCounter + + )
{
2022-05-15 15:17:49 +02:00
unsigned long ulDriveByteCounter = 0U ; //used for one shred-iteration to keep track of the current drive position
uint32_t u32ChunkDimensionIndex = 0U ;
2022-08-20 16:09:40 +02:00
2022-05-14 14:06:16 +02:00
if ( uiShredIterationCounter = = ( SHRED_ITERATIONS - 1 ) )
{
//last shred iteration --> overwrite with zeros instead with random data
2022-05-15 15:17:49 +02:00
memset ( caChunk , 0U , CHUNK_DIMENSION * CHUNK_SIZE ) ;
2022-05-14 14:06:16 +02:00
}
while ( ulDriveByteCounter < ulDriveByteSize )
{
2022-05-15 15:17:49 +02:00
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
}
2022-05-14 14:06:16 +02:00
if ( ( ulDriveByteSize - ulDriveByteCounter ) < CHUNK_SIZE )
{
iBytesToShred = ( ulDriveByteSize - ulDriveByteCounter ) ;
}
else
{
iBytesToShred = CHUNK_SIZE ;
}
2022-05-15 15:17:49 +02:00
int iByteShredded = write ( driveFileDiscr , caChunk [ u32ChunkDimensionIndex ] , iBytesToShred ) ;
2022-05-14 14:06:16 +02:00
if ( iByteShredded < = 0 )
{
2022-05-15 15:17:49 +02:00
std : : string errorMsg ( strerror ( iByteShredded ) ) ;
Logger : : logThis ( ) - > error ( " Shred-Task: Write to drive failed! " + errorMsg + " - Drive: " + drive - > getSerial ( ) ) ;
2022-05-14 14:06:16 +02:00
perror ( " unable to write random data " ) ;
cleanup ( ) ;
return - 1 ;
}
2022-05-15 15:17:49 +02:00
u32ChunkDimensionIndex = ( u32ChunkDimensionIndex + 1 ) % CHUNK_DIMENSION ;
2022-05-14 14:06:16 +02:00
ulDriveByteCounter + = iByteShredded ;
2022-05-14 15:21:14 +02:00
ulDriveByteOverallCount + = iByteShredded ;
d32Percent = this - > calcProgress ( ) ;
2022-06-30 00:32:13 +02:00
ulSpeedMetricBytesWritten + = iByteShredded ;
2022-05-14 14:06:16 +02:00
# ifdef LOG_LEVEL_HIGH
2022-05-14 15:21:14 +02:00
Logger : : logThis ( ) - > info ( " Shred-Task: ByteCount: " + to_string ( ulDriveByteCounter ) + " - iteration: " + to_string ( ( uiShredIterationCounter + 1 ) ) + " - progress: " + to_string ( d32Percent ) + " - Drive: " + drive - > getSerial ( ) ) ;
2022-05-14 14:06:16 +02:00
# endif
2022-05-14 15:21:14 +02:00
if ( ( d32Percent - d32TmpPercent ) > = 0.01 )
2022-05-14 14:06:16 +02:00
{
2022-06-30 00:32:13 +02:00
//set shred percantage
2022-05-14 14:06:16 +02:00
drive - > setTaskPercentage ( d32TmpPercent ) ;
d32TmpPercent = d32Percent ;
2022-06-30 00:32:13 +02:00
//set metrics for calculating shred speed
std : : chrono : : time_point < std : : chrono : : system_clock > chronoCurrentTimestamp = std : : chrono : : system_clock : : now ( ) ;
drive - > sShredSpeed . u32ShredTimeDelta = ( chronoCurrentTimestamp - drive - > sShredSpeed . chronoShredTimestamp ) . count ( ) ;
drive - > sShredSpeed . chronoShredTimestamp = std : : chrono : : system_clock : : now ( ) ;
drive - > sShredSpeed . ulWrittenBytes = ulSpeedMetricBytesWritten ;
ulSpeedMetricBytesWritten = 0U ;
//signal process in shreding
2022-05-14 14:06:16 +02:00
write ( * ipSignalFd , " A " , 1 ) ;
}
if ( drive - > state ! = Drive : : SHRED_ACTIVE )
{
drive - > setTaskPercentage ( 0 ) ;
d32Percent = 0.00 ;
d32TmpPercent = 0.00 ;
ulDriveByteCounter = 0U ;
Logger : : logThis ( ) - > info ( " Aborted shred for: " + drive - > getModelName ( ) + " - " + drive - > getSerial ( ) ) ;
cleanup ( ) ;
return - 1 ;
}
2022-05-15 15:17:49 +02:00
} //end one chunk write
2022-05-14 14:06:16 +02:00
if ( 0 ! = iRewindDrive ( driveFileDiscr ) )
{
cleanup ( ) ;
return - 1 ;
}
2022-05-15 15:17:49 +02:00
} //end one shred iteration
2022-05-14 14:06:16 +02:00
# ifdef ZERO_CHECK_ALERT
2022-05-14 15:21:14 +02:00
drive - > u32DriveChecksumAferShredding = uiCalcChecksum ( driveFileDiscr , drive , ipSignalFd ) ;
2022-05-14 14:06:16 +02:00
# ifdef LOG_LEVEL_HIGH
if ( drive - > u32DriveChecksumAferShredding ! = 0 )
{
Logger : : logThis ( ) - > info ( " Shred-Task: Checksum not zero: " + to_string ( drive - > u32DriveChecksumAferShredding ) + " - Drive: " + drive - > getSerial ( ) ) ;
}
else
{
Logger : : logThis ( ) - > info ( " Shred-Task: Checksum zero: " + to_string ( drive - > u32DriveChecksumAferShredding ) + " - Drive: " + drive - > getSerial ( ) ) ;
}
# endif
# endif
# endif
2022-05-15 15:17:49 +02:00
cleanup ( ) ;
2022-05-14 14:06:16 +02:00
if ( drive - > state = = Drive : : SHRED_ACTIVE )
{
drive - > bWasShredded = true ;
drive - > state = Drive : : NONE ;
drive - > setTaskPercentage ( 0.0 ) ;
Logger : : logThis ( ) - > info ( " Finished shred for: " + drive - > getModelName ( ) + " - " + drive - > getSerial ( ) ) ;
}
return 0 ;
}
/**
* \ brief calc shredding progress in %
* \ param current byte index of the drive
* \ param current shred iteration
* \ return double percentage
*/
2022-05-14 15:21:14 +02:00
double Shred : : calcProgress ( )
2022-05-14 14:06:16 +02:00
{
unsigned int uiMaxShredIteration = SHRED_ITERATIONS ;
# ifdef ZERO_CHECK_ALERT
uiMaxShredIteration + + ; //increment because we will check after SHRED_ITERATIONS the drive for non-zero bytes
# endif
2022-05-14 15:21:14 +02:00
return ( double ) ( ( ( double ) ulDriveByteOverallCount ) / ( ( double ) this - > ulDriveByteSize * uiMaxShredIteration ) ) * 100.0f ;
2022-05-14 14:06:16 +02:00
}
int Shred : : iRewindDrive ( fileDescriptor file )
{
if ( 0 ! = lseek ( file , 0L , SEEK_SET ) )
{
perror ( " unable to rewind drive " ) ;
return - 1 ;
}
else
{
return 0 ;
}
}
unsigned long Shred : : getDriveSizeInBytes ( fileDescriptor file )
{
unsigned long ulDriveSizeTmp = lseek ( file , 0L , SEEK_END ) ;
if ( 0 ! = iRewindDrive ( file ) )
{
ulDriveSizeTmp = 0U ;
}
# ifdef DEMO_DRIVE_SIZE
ulDriveSizeTmp = DEMO_DRIVE_SIZE ;
# endif
return ulDriveSizeTmp ;
}
2022-05-14 15:21:14 +02:00
unsigned int Shred : : uiCalcChecksum ( fileDescriptor file , Drive * drive , int * ipSignalFd )
2022-05-14 14:06:16 +02:00
{
unsigned int uiChecksum = 0 ;
unsigned long ulDriveByteCounter = 0U ;
while ( ulDriveByteCounter < ulDriveByteSize )
{
int iBytesToCheck = 0 ;
if ( ( ulDriveByteSize - ulDriveByteCounter ) < CHUNK_SIZE )
{
iBytesToCheck = ( ulDriveByteSize - ulDriveByteCounter ) ;
}
else
{
iBytesToCheck = CHUNK_SIZE ;
}
int iReadBytes = read ( file , caChunk , iBytesToCheck ) ;
for ( int iReadBytesCounter = 0U ; iReadBytesCounter < iReadBytes ; iReadBytesCounter + + )
{
2022-05-15 15:17:49 +02:00
uiChecksum + = caChunk [ 0 ] [ iReadBytesCounter ] ;
2022-05-14 14:06:16 +02:00
}
ulDriveByteCounter + = iReadBytes ;
2022-05-15 15:17:49 +02:00
ulDriveByteOverallCount + = iReadBytes ;
2022-05-14 15:21:14 +02:00
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
2022-05-15 15:17:49 +02:00
if ( ( d32Percent - d32TmpPercent ) > = 0.9 )
2022-05-14 15:21:14 +02:00
{
drive - > setTaskPercentage ( d32TmpPercent ) ;
d32TmpPercent = d32Percent ;
write ( * ipSignalFd , " A " , 1 ) ;
}
2022-05-14 14:06:16 +02:00
}
return uiChecksum ;
}
void Shred : : cleanup ( )
{
close ( driveFileDiscr ) ;
close ( randomSrcFileDiscr ) ;
}