Skip to content

Commit

Permalink
Merge pull request martijnvanbrummelen#498 from ggruber/master
Browse files Browse the repository at this point in the history
improved SCSI disk handling
  • Loading branch information
PartialVolume authored Oct 17, 2023
2 parents 7d2517a + 53d91f4 commit 7ce28ce
Show file tree
Hide file tree
Showing 13 changed files with 815 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +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 logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c 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 PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c
nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c 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 PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c hddtemp_scsi/hddtemp.h hddtemp_scsi/scsi.h hddtemp_scsi/scsicmds.h hddtemp_scsi/get_scsi_temp.c hddtemp_scsi/scsi.c hddtemp_scsi/scsicmds.c
nwipe_LDADD = $(PARTED_LIBS) $(LIBCONFIG)
7 changes: 7 additions & 0 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#define CONTEXT_H_

#include "prng.h"
#ifndef __HDDTEMP_H__
#include "hddtemp_scsi/hddtemp.h"
#endif /* __HDDTEMP_H__ */

typedef enum nwipe_device_t_ {
NWIPE_DEVICE_UNKNOWN = 0, // Unknown device.
Expand Down Expand Up @@ -104,6 +107,7 @@ typedef struct nwipe_context_t_
struct stat device_stat; // The device file state from fstat().
nwipe_device_t device_type; // Indicates an IDE, SCSI, or Compaq SMART device in enumerated form (int)
char device_type_str[14]; // Indicates an IDE, SCSI, USB etc as per nwipe_device_t but in ascii
int device_is_ssd; // 0 = no SSD, 1 = is a SSD
char device_serial_no[21]; // Serial number(processed, 20 characters plus null termination) of the device.
int device_target; // The device target.

Expand Down Expand Up @@ -133,6 +137,8 @@ typedef struct nwipe_context_t_
u64 throughput; // Average throughput in bytes per second.
char throughput_txt[13]; // Human readable throughput.
u64 verify_errors; // The number of verification errors across all passes.
int templ_has_hwmon_data; // 0 = no hwmon data available, 1 = hwmon data available
int templ_has_scsitemp_data; // 0 = no scsitemp data available, 1 = scsitemp data available
char temp1_path[MAX_HWMON_PATH_LENGTH]; // path to temperature variables /sys/class/hwmon/hwmonX/ etc.
int temp1_crit; // Critical high drive temperature, 1000000=unitialised, millidegree celsius.
int temp1_highest; // Historical highest temperature reached, 1000000=unitialised, millidegree celsius.
Expand All @@ -148,6 +154,7 @@ typedef struct nwipe_context_t_
int temp1_flash_rate_counter; // used by the gui for timing the flash rate
int temp1_flash_rate_status; // 0=blank 1=visible
time_t temp1_time; // The time when temperature was last checked, seconds since epoch
struct disk* templ_disk; // Pointer to disk structure for hddtemp SCSI routines
int wipe_status; // Wipe finished = 0, wipe in progress = 1, wipe yet to start = -1.
char wipe_status_txt[10]; // ERASED, FAILED, ABORTED, INSANITY
int spinner_idx; // Index into the spinner character array
Expand Down
32 changes: 28 additions & 4 deletions src/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
int r;
char tmp_serial[21];
nwipe_device_t bus;
int is_ssd;
int check_HPA; // a flag that indicates whether we check for a HPA on this device

bus = 0;
Expand All @@ -150,7 +151,7 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
if( nwipe_options.nousb )
{
/* retrieve bus and drive serial number, HOWEVER we are only interested in the bus at this time */
r = nwipe_get_device_bus_type_and_serialno( dev->path, &bus, tmp_serial );
r = nwipe_get_device_bus_type_and_serialno( dev->path, &bus, &is_ssd, tmp_serial );

/* See nwipe_get_device_bus_type_and_serialno() function for meaning of these codes */
if( r == 0 || ( r >= 3 && r <= 6 ) )
Expand Down Expand Up @@ -265,7 +266,8 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
trim( (char*) next_device->device_serial_no );

/* if we couldn't obtain serial number by using the above method .. try this */
r = nwipe_get_device_bus_type_and_serialno( next_device->device_name, &next_device->device_type, tmp_serial );
r = nwipe_get_device_bus_type_and_serialno(
next_device->device_name, &next_device->device_type, &next_device->device_is_ssd, tmp_serial );

/* If serial number & bus retrieved (0) OR unsupported USB bus identified (5) */
if( r == 0 || r == 5 )
Expand Down Expand Up @@ -359,6 +361,14 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
check_HPA = 1;
break;
}
if( next_device->device_is_ssd )
{
strcpy( next_device->device_type_str + 4, "-SSD" );
}
else
{
strcpy( next_device->device_type_str + 4, " " );
}

if( strlen( (const char*) next_device->device_serial_no ) )
{
Expand Down Expand Up @@ -458,10 +468,10 @@ char* trim( char* str )
return str;
}

int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, char* serialnumber )
int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, int* is_ssd, char* serialnumber )
{
/* The caller provides a string that contains the device, i.e. /dev/sdc, also a pointer
* to a integer (bus type) and thirdly a 21 byte
* to an integer (bus type), another pointer to an integer (is_ssd), and finally a 21 byte
* character string which this function populates with the serial number (20 characters + null terminator).
*
* The function populates the bus integer and serial number strings for the given device.
Expand Down Expand Up @@ -804,6 +814,20 @@ int nwipe_get_device_bus_type_and_serialno( char* device, nwipe_device_t* bus, c
}
}
}
if( strstr( result, "rotation rate:" ) != 0 )
{
/* strip any leading or trailing spaces and left justify, +15 is the length of "Rotation Rate:" */
trim( &result[15] );
for( idx = 15; result[idx]; idx++ )
{
result[idx] = tolower( result[idx] );
}

if( strncmp( &result[15], "solid state device", 19 ) == 0 )
{
*is_ssd = 1;
}
}
}

/* close */
Expand Down
2 changes: 1 addition & 1 deletion src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ int nwipe_device_scan( nwipe_context_t*** c ); // Find devices that we can wipe
*/
int nwipe_device_get( nwipe_context_t*** c, char** devnamelist, int ndevnames ); // Get info about devices to wipe.

int nwipe_get_device_bus_type_and_serialno( char*, nwipe_device_t*, char* );
int nwipe_get_device_bus_type_and_serialno( char*, nwipe_device_t*, int*, char* );
void strip_CR_LF( char* );
void determine_disk_capacity_nomenclature( u64, char* );
void remove_ATA_prefix( char* );
Expand Down
12 changes: 12 additions & 0 deletions src/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,9 +826,21 @@ void nwipe_gui_select( int count, nwipe_context_t** c )

wprintw( main_window, "[%s] ", c[i + offset]->device_size_text );

// NOTE temporary timing code
clock_t t;
t = clock();

/* Read the drive temperature values */
nwipe_update_temperature( c[i + offset] );

// NOTE temporary timing code
t = clock() - t;
double time_taken = ( (double) t ) / CLOCKS_PER_SEC; // in seconds
nwipe_log( NWIPE_LOG_INFO,
"nwipe_update_temperature() took %f seconds for %s",
time_taken,
c[i + offset]->device_name );

/* print the temperature */
wprintw_temperature( c[i + offset] );

Expand Down
171 changes: 171 additions & 0 deletions src/hddtemp_scsi/get_scsi_temp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* get_scsi_temp.c: functions that populate the drive temperature variables
* in SCSI/SAS drives context structure.
* Routines from hddtemp are used here.
*
* Author: Gerold Gruber <[email protected]>
*
* 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 <assert.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"
#include "miscellaneous.h"
#include "hddtemp.h"
#include "scsi.h"

int scsi_get_temperature( struct disk * );

int nwipe_init_scsi_temperature( nwipe_context_t* c )
{

/* dsk anlegen, malloc */
struct disk *dsk = (struct disk *) malloc(sizeof(struct disk));

/* Check the allocation. */
if( !dsk )
{
nwipe_perror( errno, __FUNCTION__, "malloc" );
nwipe_log( NWIPE_LOG_FATAL, "Unable to get memory for disk struct for %s",
c->device_name );
exit( 1 ) ;
}

assert(dsk);

memset(dsk, 0, sizeof(*dsk));

/* save the dsk pointer for later use */
c->templ_disk = dsk;

/* initialize */
dsk->drive = c->device_name;
dsk->type = BUS_SCSI; /* we know this as we are only called in this case */

errno = 0;
dsk->errormsg[0] = '\0';
if( (dsk->fd = open(dsk->drive, O_RDONLY | O_NONBLOCK)) < 0) {
snprintf(dsk->errormsg, MAX_ERRORMSG_SIZE, "open: %s\n", strerror(errno));
dsk->type = ERROR;
return 1;
}

// sg_logs -t <device>
if( scsi_get_temperature( dsk ) == GETTEMP_SUCCESS )
{
c->temp1_input = dsk->value;
c->temp1_crit = dsk->refvalue;
c->temp1_lcrit = -40; /* just to give it a value with some kind of sense */
c->temp1_highest = dsk->value;
c->temp1_lowest = dsk->value;
c->temp1_min = dsk->value;
c->temp1_max = dsk->value;
}
else
{
nwipe_log( NWIPE_LOG_ERROR, "Can not read SCSI temperature for %s, %s",
dsk->drive, dsk->errormsg );
close( dsk->fd );
free( dsk );
c->templ_disk = NULL;
return 1;
}

return 0;
}


int nwipe_get_scsi_temperature( nwipe_context_t* c )
{
struct disk *dsk;

dsk = c->templ_disk;

if( c->templ_disk != NULL && c->templ_disk->fd != -1 )
{
if( scsi_get_temperature( dsk ) == GETTEMP_SUCCESS )
{
c->temp1_input = dsk->value;
if( c->temp1_max == NO_TEMPERATURE_DATA )
{
c->temp1_max = c->temp1_input;
}
else
{
if( c->temp1_input > c->temp1_max )
{
c->temp1_max = c->temp1_input;
c->temp1_highest = c->temp1_input;
}
}
if( c->temp1_min == NO_TEMPERATURE_DATA )
{
c->temp1_min = c->temp1_input;
}
else
{
if( c->temp1_input < c->temp1_min )
{
c->temp1_min = c->temp1_input;
c->temp1_lowest = c->temp1_input;
}
}
}
else
{
nwipe_log( NWIPE_LOG_ERROR, "Could not read SCSI temperature for %s, %s",
dsk->drive, dsk->errormsg );
return 2;
}
}
else
{
nwipe_log( NWIPE_LOG_INFO, "no SCSI temperature reading for %s", dsk->drive );
return 1;
}
return 0;
}

void nwipe_shut_scsi_temperature( nwipe_context_t* c )
{
if( c->templ_disk->fd != -1 )
{
close( c->templ_disk->fd );
}
if( c->templ_disk != NULL )
{
free( c->templ_disk );
}

return;
}
Loading

0 comments on commit 7ce28ce

Please sign in to comment.