mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 22:15:41 +00:00
Stage 1 temperature monitor feature.
Stage 1 adds the additional variables to the drive context and creates the temperature initialisation function, which associates a hwmonX directory with a block device. Also wrote the context update function, that reads hwmon for each drive context and writes the temperatures back to the context. Stage 2 commit to follow which will make changes within the GUI to call the update function every 60 seconds and display the temperature information.
This commit is contained in:
@@ -6,6 +6,5 @@ AM_LDFLAGS =
|
||||
# this lists the binaries to produce, the (non-PHONY, binary) targets in
|
||||
# the previous manual Makefile
|
||||
bin_PROGRAMS = nwipe
|
||||
nwipe_SOURCES = context.h isaac_rand/isaac_rand.c logging.h options.h prng.h nwipe.c gui.c isaac_rand/isaac_rand.h method.h pass.c device.c gui.h isaac_rand/isaac_standard.h mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c version.h
|
||||
nwipe_CFLAGS = $(PARTED_CFLAGS)
|
||||
nwipe_SOURCES = context.h isaac_rand/isaac_rand.c logging.h options.h prng.h version.h temperature.h nwipe.c gui.c isaac_rand/isaac_rand.h method.h pass.c device.c gui.h isaac_rand/isaac_standard.h mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c temperature.c
|
||||
nwipe_LDADD = $(PARTED_LIBS)
|
||||
|
||||
@@ -72,6 +72,9 @@ typedef struct nwipe_speedring_t_
|
||||
#define NWIPE_DEVICE_LABEL_LENGTH 200
|
||||
#define NWIPE_DEVICE_SIZE_TXT_LENGTH 7
|
||||
|
||||
// Arbitary length, so far most paths don't exceed about 25 characters
|
||||
#define MAX_HWMON_PATH_LENGTH 100
|
||||
|
||||
typedef struct nwipe_context_t_
|
||||
{
|
||||
/*
|
||||
@@ -124,6 +127,17 @@ typedef struct nwipe_context_t_
|
||||
pthread_t thread; // The ID of the thread.
|
||||
u64 throughput; // Average throughput in bytes per second.
|
||||
u64 verify_errors; // The number of verification errors across all passes.
|
||||
char temp1_path[MAX_HWMON_PATH_LENGTH]; // path to temperature variables /sys/class/hwmon/hwmon2/ etc.
|
||||
u64 temp1_crit; // Critical high drive temperature, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_highest; // Historical highest temperature reached, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_input; // drive temperature, -1=unitialised. -1=unitialised, millidegree celsius.
|
||||
u64 temp1_lcrit; // Critical low drive temperature, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_lowest; // Historically lowest temperature, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_max; // Maximum allowed temperature, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_min; // Miniumum allowed temperature, -1=unitialised, millidegree celsius.
|
||||
u64 temp1_monitored_wipe_max;
|
||||
u64 temp1_monitored_wipe_min;
|
||||
u64 temp1_monitored_wipe_avg;
|
||||
int wipe_status; // Wipe finished = 0, wipe in progress = 1, wipe yet to start = -1.
|
||||
int spinner_idx; // Index into the spinner character array
|
||||
char spinner_character[1]; // The current spinner character
|
||||
|
||||
@@ -30,5 +30,6 @@ int nwipe_get_device_bus_type_and_serialno( char*, nwipe_device_t*, char* );
|
||||
void strip_CR_LF( char* );
|
||||
void determine_disk_capacity_nomenclature( u64, char* );
|
||||
void remove_ATA_prefix( char* );
|
||||
char* trim( char* );
|
||||
|
||||
#endif /* DEVICE_H_ */
|
||||
|
||||
@@ -691,19 +691,8 @@ void nwipe_log_summary( nwipe_context_t** ptr, int nwipe_selected )
|
||||
idx_src = strlen( c[i]->device_name );
|
||||
idx_src--;
|
||||
|
||||
while( idx_dest >= 0 )
|
||||
{
|
||||
/* if the device name contains a / start prefixing spaces */
|
||||
if( c[i]->device_name[idx_src] == '/' )
|
||||
{
|
||||
device[idx_dest--] = ' ';
|
||||
continue;
|
||||
}
|
||||
if( idx_src >= 0 )
|
||||
{
|
||||
device[idx_dest--] = c[i]->device_name[idx_src--];
|
||||
}
|
||||
}
|
||||
nwipe_strip_path( device, c[i]->device_name );
|
||||
|
||||
nwipe_log( NWIPE_LOG_NOTIMESTAMP,
|
||||
"%s %s | %10llu | %10llu | %10llu",
|
||||
exclamation_flag,
|
||||
@@ -743,24 +732,8 @@ void nwipe_log_summary( nwipe_context_t** ptr, int nwipe_selected )
|
||||
* characters eg " sda", prefixed with space to 6 characters, note that
|
||||
* we are processing the strings right to left */
|
||||
|
||||
idx_dest = 6;
|
||||
device[idx_dest--] = 0;
|
||||
idx_src = strlen( c[i]->device_name );
|
||||
idx_src--;
|
||||
nwipe_strip_path( device, c[i]->device_name );
|
||||
|
||||
while( idx_dest >= 0 )
|
||||
{
|
||||
/* if the device name contains a / start prefixing spaces */
|
||||
if( c[i]->device_name[idx_src] == '/' )
|
||||
{
|
||||
device[idx_dest--] = ' ';
|
||||
continue;
|
||||
}
|
||||
if( idx_src >= 0 )
|
||||
{
|
||||
device[idx_dest--] = c[i]->device_name[idx_src--];
|
||||
}
|
||||
}
|
||||
extern int user_abort;
|
||||
|
||||
/* Any errors ? if so set the exclamation_flag and fail message,
|
||||
@@ -986,3 +959,28 @@ void convert_seconds_to_hours_minutes_seconds( u64 total_seconds, int* hours, in
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nwipe_strip_path( char* output, char* input )
|
||||
{
|
||||
int idx_dest;
|
||||
int idx_src;
|
||||
idx_dest = 6;
|
||||
output[idx_dest--] = 0;
|
||||
// idx_src = strlen( c[i]->device_name );
|
||||
idx_src = strlen( input );
|
||||
idx_src--;
|
||||
|
||||
while( idx_dest >= 0 )
|
||||
{
|
||||
/* if the device name contains a / start prefixing spaces */
|
||||
if( input[idx_src] == '/' )
|
||||
{
|
||||
output[idx_dest--] = ' ';
|
||||
continue;
|
||||
}
|
||||
if( idx_src >= 0 )
|
||||
{
|
||||
output[idx_dest--] = input[idx_src--];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,5 +47,6 @@ int nwipe_log_sysinfo();
|
||||
void nwipe_log_summary( nwipe_context_t**, int ); // This produces the wipe status table on exit
|
||||
void Determine_C_B_nomenclature( u64, char*, int );
|
||||
void convert_seconds_to_hours_minutes_seconds( u64, int*, int*, int* );
|
||||
int nwipe_strip_path( char*, char* );
|
||||
|
||||
#endif /* LOGGING_H_ */
|
||||
|
||||
20
src/nwipe.c
20
src/nwipe.c
@@ -41,6 +41,7 @@
|
||||
#include "device.h"
|
||||
#include "logging.h"
|
||||
#include "gui.h"
|
||||
#include "temperature.h"
|
||||
|
||||
#include <sys/ioctl.h> /* FIXME: Twice Included */
|
||||
#include <sys/shm.h>
|
||||
@@ -202,6 +203,16 @@ int main( int argc, char** argv )
|
||||
pthread_create( &nwipe_sigint_thread, &pthread_attr, signal_hand, &nwipe_thread_data_ptr );
|
||||
}
|
||||
|
||||
/* Makesure the drivetemp module is loaded, else drives hwmon entries won't appear in /sys/class/hwmon */
|
||||
if( system( "modprobe drivetemp" ) != 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_ERROR, "Unable to load module drivetemp, drive temperatures may not be available" );
|
||||
}
|
||||
else
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Module drivetemp loaded, drive temperatures available" );
|
||||
}
|
||||
|
||||
/* A context struct for each device has already been created. */
|
||||
/* Now set specific nwipe options */
|
||||
for( i = 0; i < nwipe_enumerated; i++ )
|
||||
@@ -223,6 +234,15 @@ int main( int argc, char** argv )
|
||||
/* The user must manually select devices. */
|
||||
c1[i]->select = NWIPE_SELECT_FALSE;
|
||||
}
|
||||
|
||||
/* Initialise temperature variables for device */
|
||||
nwipe_init_temperature( c1[i] );
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s hwmon path = %s", c1[i]->device_name, c1[i]->temp1_path );
|
||||
}
|
||||
|
||||
nwipe_update_temperature( c1[i] );
|
||||
}
|
||||
|
||||
/* Check for initialization errors. */
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef PRNG_H_
|
||||
#define PRNG_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* A chunk of random data. */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
215
src/temperature.c
Normal file
215
src/temperature.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* temperature.c: functions that populate the drive temperature variables
|
||||
* in each drives context structure.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
//#define _LARGEFILE64_SOURCE
|
||||
//#define _FILE_OFFSET_BITS 64
|
||||
#define _BSD_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "nwipe.h"
|
||||
#include "context.h"
|
||||
#include "method.h"
|
||||
#include "device.h"
|
||||
#include "prng.h"
|
||||
#include "options.h"
|
||||
#include "device.h"
|
||||
#include "logging.h"
|
||||
#include "temperature.h"
|
||||
|
||||
int nwipe_init_temperature( nwipe_context_t* c )
|
||||
{
|
||||
/* This function is called after each nwipe_context_t has been created.
|
||||
* It initialises the temperature variables in each context and then
|
||||
* constructs a path that is placed in the context that points to the
|
||||
* appropriate /sys/class/hwmon/hwmonX directory that corresponds with
|
||||
* the particular drive represented in the context structure.
|
||||
*/
|
||||
DIR* dir;
|
||||
DIR* dir2;
|
||||
const char dirpath[] = "/sys/class/hwmon";
|
||||
char dirpath_tmp[256];
|
||||
char dirpath_hwmonX[256];
|
||||
char device[256];
|
||||
char device_context_name[256];
|
||||
// const char dirpath[] = "/home/nick/mouse/hwmon1";
|
||||
struct dirent* dp;
|
||||
struct dirent* dp2;
|
||||
int match;
|
||||
|
||||
/* Why Initialise with 1000000? Because the GUI needs to know whether data
|
||||
* has been obtained so it can display appropriate information when a
|
||||
* device is unable to provide temperature data */
|
||||
|
||||
c->temp1_crit = 1000000;
|
||||
c->temp1_highest = 1000000;
|
||||
c->temp1_input = 1000000;
|
||||
c->temp1_lcrit = 1000000;
|
||||
c->temp1_lowest = 1000000;
|
||||
c->temp1_max = 1000000;
|
||||
c->temp1_min = 1000000;
|
||||
c->temp1_monitored_wipe_max = 1000000;
|
||||
c->temp1_monitored_wipe_min = 1000000;
|
||||
c->temp1_monitored_wipe_avg = 1000000;
|
||||
c->temp1_path[0] = 0;
|
||||
|
||||
/* Each hwmonX directory is processed in turn and once a hwmonX directory has been
|
||||
* found that is a block device and the block device name matches the drive
|
||||
* name in the current context then the path to ../hwmonX is constructed and written
|
||||
* to the drive context structure '* c'. This path is used in the nwipe_update_temperature
|
||||
* function to retrieve temperature data and store it in the device context
|
||||
*/
|
||||
|
||||
if( ( dir = opendir( dirpath ) ) != NULL )
|
||||
{
|
||||
while( ( dp = readdir( dir ) ) != NULL )
|
||||
{
|
||||
/* Does the directory start with 'hwmon' */
|
||||
|
||||
if( strstr( dp->d_name, "hwmon" ) != NULL )
|
||||
{
|
||||
strcpy( dirpath_tmp, dirpath );
|
||||
strcat( dirpath_tmp, "/" );
|
||||
strcat( dirpath_tmp, dp->d_name );
|
||||
strcpy( dirpath_hwmonX, dirpath_tmp );
|
||||
strcat( dirpath_tmp, "/device/block" );
|
||||
|
||||
/* Is this hardware monitor a block device ? i.e. does
|
||||
* /sys/class/hwmon/hwmonX/device/block exist?*/
|
||||
|
||||
if( ( dir2 = opendir( dirpath_tmp ) ) != NULL )
|
||||
{
|
||||
/* Read the device name */
|
||||
while( ( dp2 = readdir( dir2 ) ) != NULL )
|
||||
{
|
||||
/* Skip the '.' and '..' directories */
|
||||
if( dp2->d_name[0] == '.' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
strcpy( device, dp2->d_name );
|
||||
|
||||
/* Create a copy of the device name from the context but strip the path from it. */
|
||||
nwipe_strip_path( device_context_name, c->device_name );
|
||||
|
||||
/* Remove leading/training whitespace from a string and left justify result */
|
||||
trim( device_context_name );
|
||||
|
||||
/* Does the hwmon device match the device for this drive context */
|
||||
if( strcmp( device, device_context_name ) != 0 )
|
||||
{
|
||||
/* No, so try next hwmon device */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Match ! This hwmon device matches this context, so write the hwmonX path to the context
|
||||
*/
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s has \'hwmon\' temperature monitoring", device );
|
||||
|
||||
/* Copy the hwmon path to the drive context structure */
|
||||
strcpy( c->temp1_path, dirpath_hwmonX );
|
||||
}
|
||||
}
|
||||
closedir( dir2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir( dir );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nwipe_update_temperature( nwipe_context_t* c )
|
||||
{
|
||||
/* For the given drive context obtain the path to it's hwmon temperature settings
|
||||
* and read then write the temperature values back to the context. A numeric ascii to integer conversion is
|
||||
* performed. The temperaures should be updated no more frequently than every 60 seconds
|
||||
*/
|
||||
|
||||
char temperature_label[NUMBER_OF_FILES][20] = {
|
||||
"temp1_crit", "temp1_highest", "temp1_input", "temp1_lcrit", "temp1_lowest", "temp1_max", "temp1_min" };
|
||||
u64* temperature_pcontext[NUMBER_OF_FILES] = {
|
||||
|
||||
&( c->temp1_crit ),
|
||||
&( c->temp1_highest ),
|
||||
&( c->temp1_input ),
|
||||
&( c->temp1_lcrit ),
|
||||
&( c->temp1_lowest ),
|
||||
&( c->temp1_max ),
|
||||
&( c->temp1_min ) };
|
||||
|
||||
char path[256];
|
||||
char temperature[256];
|
||||
FILE* fptr;
|
||||
int idx;
|
||||
|
||||
for( idx = 0; idx < NUMBER_OF_FILES; idx++ )
|
||||
{
|
||||
/* Construct the full path including filename */
|
||||
strcpy( path, c->temp1_path );
|
||||
strcat( path, "/" );
|
||||
strcat( path, &( temperature_label[idx][0] ) );
|
||||
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "hwmon: path=%s", path );
|
||||
}
|
||||
|
||||
/* Open the file */
|
||||
if( ( fptr = fopen( path, "r" ) ) != NULL )
|
||||
{
|
||||
/* Acquire data until we reach a newline */
|
||||
fscanf( fptr, "%[^\n]", temperature );
|
||||
|
||||
/* Convert numeric ascii to binary integer */
|
||||
*( temperature_pcontext[idx] ) = atoi( temperature );
|
||||
|
||||
/* Divide by 1000 to get degrees celcius */
|
||||
*( temperature_pcontext[idx] ) = *( temperature_pcontext[idx] ) / 1000;
|
||||
|
||||
fclose( fptr );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "hwmon: Unable to open %s", path );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( nwipe_options.verbose )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE,
|
||||
"hwmon: %lluC, %lluC, %lluC, %lluC, %lluC, %lluC, %lluC",
|
||||
c->temp1_crit,
|
||||
c->temp1_highest,
|
||||
c->temp1_input,
|
||||
c->temp1_lcrit,
|
||||
c->temp1_lowest,
|
||||
c->temp1_max,
|
||||
c->temp1_min );
|
||||
}
|
||||
return;
|
||||
}
|
||||
30
src/temperature.h
Normal file
30
src/temperature.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*.
|
||||
* temperature.h: The header file for disk drive temperature sensing
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TEMPERATURE_H_
|
||||
#define TEMPERATURE_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "context.h"
|
||||
|
||||
int nwipe_init_temperature( nwipe_context_t* );
|
||||
void nwipe_update_temperature( nwipe_context_t* );
|
||||
|
||||
#define NUMBER_OF_FILES 7
|
||||
|
||||
#endif /* TEMPERATURE_H_ */
|
||||
Reference in New Issue
Block a user