mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 05:32:14 +00:00
Enhances the --exclude option to match devices by their underlying block
device ID (major/minor), allowing persistent identifiers in /dev/disk/by-id/ and /dev/disk/by-path/ to be used safely. Legacy string-based matching is preserved.
This commit is contained in:
123
src/device.c
123
src/device.c
@@ -50,6 +50,119 @@
|
||||
int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount );
|
||||
char* trim( char* str );
|
||||
|
||||
/*
|
||||
* Resolve a device path (including /dev/disk/by-* symlinks) to its
|
||||
* underlying block device id (dev_t).
|
||||
*
|
||||
* Returns 0 on success and fills *out_rdev.
|
||||
* Returns -1 on error or if the path is not a block device.
|
||||
*/
|
||||
static int nwipe_path_to_rdev( const char* path, dev_t* out_rdev )
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if( path == NULL || out_rdev == NULL )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* stat() follows symlinks by default, which is what we want for
|
||||
* persistent names in /dev/disk/by-id, /dev/disk/by-path, etc.
|
||||
*/
|
||||
if( stat( path, &st ) != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !S_ISBLK( st.st_mode ) )
|
||||
{
|
||||
/* Not a block device node. */
|
||||
errno = ENOTBLK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out_rdev = st.st_rdev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether a candidate device node should be excluded based on the
|
||||
* --exclude list. Matching is done primarily by device identity
|
||||
* (major/minor via st_rdev), so persistent names like /dev/disk/by-id/*
|
||||
* are safe. We keep legacy string-based matching as a fallback.
|
||||
*
|
||||
* Returns 1 if the candidate should be excluded, 0 otherwise.
|
||||
*/
|
||||
static int nwipe_is_excluded_device( const char* candidate_devnode )
|
||||
{
|
||||
dev_t cand_rdev;
|
||||
int have_cand_rdev;
|
||||
int i;
|
||||
|
||||
/* Try to resolve the candidate device to a dev_t. */
|
||||
have_cand_rdev = ( nwipe_path_to_rdev( candidate_devnode, &cand_rdev ) == 0 );
|
||||
|
||||
for( i = 0; i < MAX_NUMBER_EXCLUDED_DRIVES; i++ )
|
||||
{
|
||||
const char* ex = nwipe_options.exclude[i];
|
||||
dev_t ex_rdev;
|
||||
int have_ex_rdev;
|
||||
const char* base;
|
||||
|
||||
/* Empty slot in the exclude array. */
|
||||
if( ex == NULL || ex[0] == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* First try: both candidate and exclude entry resolve to block
|
||||
* devices; compare device ids (major/minor).
|
||||
*/
|
||||
have_ex_rdev = ( nwipe_path_to_rdev( ex, &ex_rdev ) == 0 );
|
||||
if( have_cand_rdev && have_ex_rdev && ex_rdev == cand_rdev )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s excluded as per command line option -e", candidate_devnode );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback 1: exact string match. This keeps compatibility with
|
||||
* older usage like --exclude=/dev/sda or --exclude=/dev/mapper/cryptswap1.
|
||||
*/
|
||||
if( strcmp( candidate_devnode, ex ) == 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s excluded as per command line option -e", candidate_devnode );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback 2: match against the basename only, so that an
|
||||
* exclude entry like "sda" still works even if the full path is
|
||||
* /dev/sda.
|
||||
*/
|
||||
base = strrchr( candidate_devnode, '/' );
|
||||
if( base != NULL )
|
||||
{
|
||||
base++;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = candidate_devnode;
|
||||
}
|
||||
|
||||
if( strcmp( base, ex ) == 0 )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s excluded as per command line option -e", candidate_devnode );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int terminate_signal;
|
||||
|
||||
int nwipe_device_scan( nwipe_context_t*** c )
|
||||
@@ -138,16 +251,12 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
|
||||
|
||||
bus = 0;
|
||||
|
||||
/* Check whether this drive is on the excluded drive list ? */
|
||||
idx = 0;
|
||||
while( idx < MAX_NUMBER_EXCLUDED_DRIVES )
|
||||
/* Check whether this drive is on the excluded drive list. */
|
||||
if( nwipe_is_excluded_device( dev->path ) )
|
||||
{
|
||||
if( !strcmp( dev->path, nwipe_options.exclude[idx++] ) )
|
||||
{
|
||||
nwipe_log( NWIPE_LOG_NOTICE, "Device %s excluded as per command line option -e", dev->path );
|
||||
/* Already logged inside nwipe_is_excluded_device(). */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the user has specified using the --nousb option
|
||||
* that all USB devices should not be displayed or wiped whether
|
||||
|
||||
@@ -789,6 +789,8 @@ void display_help()
|
||||
puts( " --exclude=/dev/sdc" );
|
||||
puts( " --exclude=/dev/sdc,/dev/sdd" );
|
||||
puts( " --exclude=/dev/sdc,/dev/sdd,/dev/mapper/cryptswap1\n" );
|
||||
puts( " --exclude=/dev/disk/by-id/ata-XXXXXXXX" );
|
||||
puts( " --exclude=/dev/disk/by-path/pci-0000:00:17.0-ata-1\n" );
|
||||
puts( "" );
|
||||
exit( EXIT_SUCCESS );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user