HPA_DCO_003 - Add HPA,DCO capability

1. For devices that support HPA/DCO (not NVMe) nwipe
displays the HPA status, it toggles every two seconds
the size and the temperature i.e "[  1TB][ 35C]" with
the HPA status such as [HPA disabled], [HPA ENABLED!],
[HPA unknown]. The HPA ENABLED is highlighted with red
text and a white background. HPA_disabled is standard
white text on blue background.

More code to follow, a new option to be added, HPA, disable/enable
which will disable the HPA and shut down the system. On manually
powering back up the HPA should be reported as disabled.

Then lots of testing.
This commit is contained in:
PartialVolume
2023-02-28 23:48:17 +00:00
parent 7ccb68675b
commit 8abab96a3e
8 changed files with 124 additions and 38 deletions

View File

@@ -157,13 +157,16 @@ typedef struct nwipe_context_t_
time_t end_time; // End time of wipe
u64 fsyncdata_errors; // The number of fsyncdata errors across all passes.
char PDF_filename[256]; // The filename of the PDF certificate/report.
int HPA_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked
int HPA_status; // 0 = No HPA found/disabled, 1 = HPA detected, 2 = Unknown, unable to checked,
// 3 = Not applicable to this device
u64 HPA_reported_set; // the 'HPA set' value reported hdparm -N, i.e the first value of n/n
u64 HPA_reported_real; // the 'HPA real' value reported hdparm -N, i.e the second value of n/n
int DCO_status; // 0 = No DCO found, 1 = DCO detected, 2 = Unknown, unable to checked
u64 DCO_reported_real_max_sectors; // real max sectors as reported by hdparm --dco-identify
u64 HPA_size; // The size of the host protected area in sectors
char HPA_size_text[NWIPE_DEVICE_SIZE_TXT_LENGTH]; // Human readable size bytes, KB, MB, GB ..
int HPA_display_toggle_state; // 0 or 1 Used to toggle between "[1TB] [ 33C]" and [HDA STATUS]
time_t HPA_toggle_time; // records a time, then if for instance 3 seconds has elapsed the display changes
/*
* Identity contains the raw serial number of the drive

View File

@@ -376,14 +376,15 @@ int create_pdf( nwipe_context_t* ptr )
pdf_set_font( pdf, "Helvetica" );
/*********************
* Populate HPA status
* Populate HPA status (and size if not applicable, NVMe and VIRT)
*/
if( !strcmp( c->device_type_str, "NVME" ) )
if( !strcmp( c->device_type_str, "NVME" ) || !strcmp( c->device_type_str, "VIRT" ) )
{
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable to NVME" );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "Not applicable to NVME" );
snprintf( HPA_status_text, sizeof( HPA_status_text ), "Not applicable to %s", c->device_type_str );
pdf_set_font( pdf, "Helvetica-Bold" );
pdf_add_text( pdf, NULL, HPA_status_text, 12, 95, 190, PDF_DARK_GREEN );
snprintf( HPA_size_text, sizeof( HPA_size_text ), "Not applicable to %s", c->device_type_str );
pdf_add_text( pdf, NULL, HPA_size_text, 12, 360, 190, PDF_DARK_GREEN );
pdf_set_font( pdf, "Helvetica" );
}
else

View File

@@ -288,6 +288,18 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
}
}
/* Initialise the variables that toggle the [size][temp c] with [HPA status]
*/
next_device->HPA_toggle_time = time( NULL );
next_device->HPA_display_toggle_state = 0;
/* Initialise the HPA variables for this device
*/
next_device->HPA_reported_set = 0;
next_device->HPA_reported_real = 0;
next_device->DCO_reported_real_max_sectors = 0;
next_device->HPA_status = HPA_NOT_APPLICABLE;
/* All device strings should be 4 characters, prefix with space if under 4 characters
* We also set a switch for certain devices to check for the host protected area (HPA)
*/

117
src/gui.c
View File

@@ -44,6 +44,7 @@
#include "version.h"
#include "temperature.h"
#include "miscellaneous.h"
#include "hpa_dco.h"
#define NWIPE_GUI_PANE 8
@@ -742,48 +743,43 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
if( nwipe_options.method == &nwipe_verify_zero || nwipe_options.method == &nwipe_verify_one )
{
wprintw( main_window,
"[vrfy] %s %s [%s] ",
"[vrfy] %s %s ",
c[i + offset]->gui_device_name,
c[i + offset]->device_type_str,
c[i + offset]->device_size_text );
c[i + offset]->device_type_str );
}
else
{
wprintw( main_window,
"[wipe] %s %s [%s] ",
"[wipe] %s %s ",
c[i + offset]->gui_device_name,
c[i + offset]->device_type_str,
c[i + offset]->device_size_text );
c[i + offset]->device_type_str );
}
break;
case NWIPE_SELECT_FALSE:
/* Print an element that is not selected. */
wprintw( main_window,
"[ ] %s %s [%s] ",
"[ ] %s %s ",
c[i + offset]->gui_device_name,
c[i + offset]->device_type_str,
c[i + offset]->device_size_text );
c[i + offset]->device_type_str );
break;
case NWIPE_SELECT_TRUE_PARENT:
/* This element will be wiped when its parent is wiped. */
wprintw( main_window,
"[****] %s %s [%s] ",
"[****] %s %s ",
c[i + offset]->gui_device_name,
c[i + offset]->device_type_str,
c[i + offset]->device_size_text );
c[i + offset]->device_type_str );
break;
case NWIPE_SELECT_FALSE_CHILD:
/* We can't wipe this element because it has a child that is being wiped. */
wprintw( main_window,
"[----] %s %s [%s] ",
"[----] %s %s ",
c[i + offset]->gui_device_name,
c[i + offset]->device_type_str,
c[i + offset]->device_size_text );
c[i + offset]->device_type_str );
break;
case NWIPE_SELECT_DISABLED:
@@ -799,14 +795,72 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
} /* switch select */
/* Read the drive temperature values */
nwipe_update_temperature( c[i + offset] );
/* Toggle the [size][temp C] with [HDA Status]
*/
switch( c[i + offset]->HPA_display_toggle_state )
{
case 0:
wprintw( main_window, "[%s] ", c[i + offset]->device_size_text );
/* print the temperature */
wprintw_temperature( c[i + offset] );
/* Read the drive temperature values */
nwipe_update_temperature( c[i + offset] );
/* print the temperature */
wprintw_temperature( c[i + offset] );
break;
case 1:
switch( c[i + offset]->HPA_status )
{
case HPA_ENABLED:
wattron( main_window, COLOR_PAIR( 9 ) );
wprintw( main_window, "[HDA ENABLED!]" );
wattroff( main_window, COLOR_PAIR( 9 ) );
break;
case HPA_DISABLED:
wprintw( main_window, "[HDA disabled]" );
break;
case HPA_UNKNOWN:
wattron( main_window, COLOR_PAIR( 9 ) );
wprintw( main_window, "[HDA unknown ]" );
wattroff( main_window, COLOR_PAIR( 9 ) );
break;
case HPA_NOT_APPLICABLE:
wprintw( main_window, "[%s] ", c[i + offset]->device_size_text );
/* Read the drive temperature values */
nwipe_update_temperature( c[i + offset] );
/* print the temperature */
wprintw_temperature( c[i + offset] );
break;
default:
break;
}
}
if( c[i + offset]->HPA_toggle_time + 1 < time( NULL ) )
{
switch( c[i + offset]->HPA_display_toggle_state )
{
case 0:
c[i + offset]->HPA_display_toggle_state = 1;
break;
case 1:
c[i + offset]->HPA_display_toggle_state = 0;
break;
}
c[i + offset]->HPA_toggle_time = time( NULL );
}
/* print the drive model and serial number */
wprintw( main_window, "%s/%s", c[i + offset]->device_model, c[i + offset]->device_serial_no );
wprintw( main_window, " %s/%s", c[i + offset]->device_model, c[i + offset]->device_serial_no );
}
else
{
@@ -1278,8 +1332,11 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
* this change and exits the valid key hit loop so the windows can be updated */
getmaxyx( stdscr, stdscr_lines, stdscr_cols );
/* Update the selection window every 60 seconds specifically so that the drive temperatures are updated */
if( time( NULL ) > ( temperature_check_time + 60 ) )
/* Update the selection window every 1 second specifically
* so that the drive temperatures are updated and also the line toggle that
* occurs with the HPA status and the drive size & temperature.
*/
if( time( NULL ) > ( temperature_check_time + 1 ) )
{
temperature_check_time = time( NULL );
validkeyhit = 1;
@@ -3225,14 +3282,14 @@ void wprintw_temperature( nwipe_context_t* c )
{
/* blue on blue */
wattron( main_window, COLOR_PAIR( 12 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 12 ) );
}
else
{
/* red on blue */
wattron( main_window, COLOR_PAIR( 3 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 3 ) );
}
}
@@ -3245,7 +3302,7 @@ void wprintw_temperature( nwipe_context_t* c )
{
/* red on blue */
wattron( main_window, COLOR_PAIR( 3 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 3 ) );
}
else
@@ -3258,14 +3315,14 @@ void wprintw_temperature( nwipe_context_t* c )
{
/* blue on blue */
wattron( main_window, COLOR_PAIR( 12 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 12 ) );
}
else
{
/* black on blue */
wattron( main_window, COLOR_PAIR( 11 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 11 ) );
}
}
@@ -3277,13 +3334,13 @@ void wprintw_temperature( nwipe_context_t* c )
{
/* black on blue */
wattron( main_window, COLOR_PAIR( 11 ) );
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
wattroff( main_window, COLOR_PAIR( 11 ) );
}
else
{
/* Default white on blue */
wprintw( main_window, "[%dC] ", c->temp1_input );
wprintw( main_window, "[%dC]", c->temp1_input );
}
}
}
@@ -3291,6 +3348,6 @@ void wprintw_temperature( nwipe_context_t* c )
}
else
{
wprintw( main_window, "[--C] " );
wprintw( main_window, "[--C]" );
}
}

View File

@@ -371,23 +371,31 @@ int hpa_dco_status( nwipe_context_t* ptr )
* to reset the HPA.
*/
/* If all three values match then there is no hidden disc area. HPA is disabled. */
if( ( c->HPA_reported_set == c->HPA_reported_real ) && c->DCO_reported_real_max_sectors == c->HPA_reported_set )
if( c->HPA_reported_set == c->HPA_reported_real && c->DCO_reported_real_max_sectors == c->HPA_reported_set
&& c->HPA_reported_set != 0 )
{
c->HPA_status = HPA_DISABLED;
}
else
{
/* If HPA set and DCO max sectors are equal it can also be considered that HPA is disabled */
if( c->HPA_reported_set == c->DCO_reported_real_max_sectors )
if( ( c->HPA_reported_set == c->DCO_reported_real_max_sectors ) && c->HPA_reported_set != 0 )
{
c->HPA_status = HPA_DISABLED;
}
else
{
if( c->HPA_reported_set != c->DCO_reported_real_max_sectors )
if( c->HPA_reported_set != c->DCO_reported_real_max_sectors && c->HPA_reported_set != 0 )
{
c->HPA_status = HPA_ENABLED;
}
else
{
if( !strcmp( c->device_type_str, "NVME" ) )
{
c->HPA_status = HPA_NOT_APPLICABLE;
}
}
}
}

View File

@@ -24,6 +24,7 @@
#define HPA_DISABLED 0
#define HPA_ENABLED 1
#define HPA_UNKNOWN 2
#define HPA_NOT_APPLICABLE 3
int hpa_dco_status( nwipe_context_t* );

View File

@@ -51,6 +51,7 @@
#include <parted/parted.h>
#include <parted/debug.h>
#include "version.h"
#include "hpa_dco.h"
int terminate_signal;
int user_abort;
@@ -351,6 +352,8 @@ int main( int argc, char** argv )
}
}
/* Initialise some of the variables in the drive contexts
*/
for( i = 0; i < nwipe_enumerated; i++ )
{
/* Set the PRNG implementation, which must always come after the function nwipe_gui_select ! */

View File

@@ -36,6 +36,7 @@
#include "device.h"
#include "logging.h"
#include "temperature.h"
#include "miscellaneous.h"
int nwipe_init_temperature( nwipe_context_t* c )
{