Workaround not so old wipefs only erasing 1 of 3 vfat signatures (#688882)

Before util-linux 2.21.0, released Feb 2012, wipefs only cleared one of
the three vfat (fat16/fat32) signatures it can be detected by each time
wipefs was run.  Also if a nilfs2 file system was created before all
three signatures were cleared the partition was still recognised as a
vfat file system, albeit a corrupted one, rather than as a nilfs2 file
system.

Old wipefs clearing vfat signatures:
    # wipefs --version
    wipefs from util-linux 2.20.1
    # wipefs -a /dev/sda7
    8 bytes were erased at offset 0x52 (vfat)
    they were: 46 41 54 33 32 20 20 20
    # wipefs -a /dev/sda7
    1 bytes were erased at offset 0x0 (vfat)
    they were: eb
    # wipefs -a /dev/sda7
    2 bytes were erased at offset 0x1fe (vfat)
    they were: 55 aa

New wipefs clearing vfat signatures:
    # wipefs --version
    wipefs from util-linux 2.21.2
    # wipefs -a /dev/sda12
    8 bytes were erased at offset 0x00000052 (vfat): 46 41 54 33 32 20 20 20
    1 bytes were erased at offset 0x00000000 (vfat): eb
    2 bytes were erased at offset 0x000001fe (vfat): 55 aa

Workaround by calling "wipefs -a" three times if the output indicated
only one vfat signature was cleared.

Bug #688882 - Improve clearing of file system signatures
This commit is contained in:
Mike Fleetwood 2013-02-17 15:13:34 +00:00 committed by Curtis Gedak
parent 797f0b8eeb
commit 6982f68e21
2 changed files with 38 additions and 9 deletions

View File

@ -179,6 +179,8 @@ private:
OperationDetail & operationdetail ) ;
FileSystem* set_proper_filesystem( const FILESYSTEM & filesystem ) ;
bool erase_filesystem_signatures( const Partition & partition, OperationDetail & operationdetail ) ;
bool wipe_filesystem_signatures( const Glib::ustring & device_path,
OperationDetail & operationdetail, Glib::ustring & output ) ;
bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
//general..

View File

@ -3130,21 +3130,27 @@ bool GParted_Core::filesystem_resize_disallowed( const Partition & partition )
bool GParted_Core::erase_filesystem_signatures( const Partition & partition, OperationDetail & operationdetail )
{
bool success = true ;
if ( ! Glib::find_program_in_path( "wipefs" ) .empty() )
{
Glib::ustring output ;
operationdetail .add_child( OperationDetail(
String::ucompose( _("clear old file system signatures in %1"),
partition .get_path() ) ) ) ;
OperationDetail & od = operationdetail .get_last_child() ;
Glib::ustring output, error ;
Glib::ustring command = "wipefs -a " + partition .get_path() ;
od .add_child( OperationDetail( command, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
int exit_status = Utils::execute_command( command, output, error, true ) ;
if ( ! output .empty() )
od .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
if ( ! error .empty() )
od .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
od .set_status( exit_status == 0 ? STATUS_SUCCES : STATUS_N_A ) ;
success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
//Before util-linux 2.21.0, released Feb 2012, wipefs only erased 1 of
// the 3 vfat (fat16/fat32) signatures each time it was called. If only
// one vfat signature was wiped, found "(vfat)" only once in the output,
// execute wipefs 2 more time.
Glib::ustring::size_type p1 = output .find( "(vfat)" ) ;
if ( p1 != Glib::ustring::npos
&& output .find( "(vfat)", p1+6 ) == Glib::ustring::npos )
{
success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
success &= wipe_filesystem_signatures( partition .get_path(), od, output ) ;
}
}
//Linux kernel doesn't maintain buffer cache coherency between the whole disk
@ -3182,9 +3188,30 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
}
ped_device_destroy( lp_device ) ;
}
operationdetail .get_last_child() .set_status( success ? STATUS_SUCCES : STATUS_N_A ) ;
return true ;
}
bool GParted_Core::wipe_filesystem_signatures( const Glib::ustring & path,
OperationDetail & operationdetail, Glib::ustring & output )
{
bool success ;
Glib::ustring error ;
Glib::ustring command = "wipefs -a " + path ;
operationdetail .add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) ) ;
int exit_status = Utils::execute_command( command, output, error, true ) ;
if ( ! output .empty() )
operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
if ( ! error .empty() )
operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
success = ( 0 == exit_status ) ;
operationdetail .get_last_child() .set_status( success ? STATUS_SUCCES : STATUS_N_A ) ;
return success ;
}
bool GParted_Core::update_bootsector( const Partition & partition, OperationDetail & operationdetail )
{
//only for ntfs atm...