Use newer btrfs multi-tool control command first
Btrfsctl and btrfs-show were depreciated in October 2011 and have been superseeded by the newer btrfs multi-tool control command. Use btrfs as first choice, falling back to btrfsctl and btrfs-show when not found.
This commit is contained in:
parent
7ba1d417c5
commit
a580abbc30
113
src/btrfs.cc
113
src/btrfs.cc
|
@ -22,24 +22,57 @@
|
||||||
namespace GParted
|
namespace GParted
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool btrfs_found = false ;
|
||||||
|
|
||||||
FS btrfs::get_filesystem_support()
|
FS btrfs::get_filesystem_support()
|
||||||
{
|
{
|
||||||
FS fs ;
|
FS fs ;
|
||||||
fs .filesystem = GParted::FS_BTRFS ;
|
fs .filesystem = GParted::FS_BTRFS ;
|
||||||
|
|
||||||
if ( ! Glib::find_program_in_path( "btrfs-show" ) .empty() )
|
|
||||||
{
|
|
||||||
fs .read = GParted::FS::EXTERNAL ;
|
|
||||||
fs .read_label = FS::EXTERNAL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! Glib::find_program_in_path( "mkfs.btrfs" ) .empty() )
|
if ( ! Glib::find_program_in_path( "mkfs.btrfs" ) .empty() )
|
||||||
fs .create = GParted::FS::EXTERNAL ;
|
fs .create = GParted::FS::EXTERNAL ;
|
||||||
|
|
||||||
if ( ! Glib::find_program_in_path( "btrfsck" ) .empty() )
|
if ( ! Glib::find_program_in_path( "btrfsck" ) .empty() )
|
||||||
fs .check = GParted::FS::EXTERNAL ;
|
fs .check = GParted::FS::EXTERNAL ;
|
||||||
|
|
||||||
//resizing of btrfs requires btrfsctl, mount, and umount
|
btrfs_found = ( ! Glib::find_program_in_path( "btrfs" ) .empty() ) ;
|
||||||
|
if ( btrfs_found )
|
||||||
|
{
|
||||||
|
//Use newer btrfs multi-tool control command. No need
|
||||||
|
// to test for filesystem show and filesystem resize
|
||||||
|
// sub-commands as they were always included.
|
||||||
|
|
||||||
|
fs .read = GParted::FS::EXTERNAL ;
|
||||||
|
fs .read_label = FS::EXTERNAL ;
|
||||||
|
|
||||||
|
//Resizing of btrfs requires mount, umount as well as
|
||||||
|
// btrfs filesystem resize
|
||||||
|
if ( ! Glib::find_program_in_path( "mount" ) .empty()
|
||||||
|
&& ! Glib::find_program_in_path( "umount" ) .empty()
|
||||||
|
&& fs .check
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fs .grow = FS::EXTERNAL ;
|
||||||
|
if ( fs .read ) //needed to determine a minimum file system size.
|
||||||
|
fs .shrink = FS::EXTERNAL ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Test for labelling capability in btrfs command
|
||||||
|
if ( ! Utils::execute_command( "btrfs filesystem label --help", output, error, true ) )
|
||||||
|
fs .write_label = FS::EXTERNAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Fall back to using btrfs-show and btrfsctl, which
|
||||||
|
// were depreciated October 2011
|
||||||
|
|
||||||
|
if ( ! Glib::find_program_in_path( "btrfs-show" ) .empty() )
|
||||||
|
{
|
||||||
|
fs .read = GParted::FS::EXTERNAL ;
|
||||||
|
fs .read_label = FS::EXTERNAL ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Resizing of btrfs requires btrfsctl, mount, and umount
|
||||||
if ( ! Glib::find_program_in_path( "btrfsctl" ) .empty()
|
if ( ! Glib::find_program_in_path( "btrfsctl" ) .empty()
|
||||||
&& ! Glib::find_program_in_path( "mount" ) .empty()
|
&& ! Glib::find_program_in_path( "mount" ) .empty()
|
||||||
&& ! Glib::find_program_in_path( "umount" ) .empty()
|
&& ! Glib::find_program_in_path( "umount" ) .empty()
|
||||||
|
@ -50,12 +83,6 @@ FS btrfs::get_filesystem_support()
|
||||||
if ( fs .read ) //needed to determine a minimum file system size.
|
if ( fs .read ) //needed to determine a minimum file system size.
|
||||||
fs .shrink = FS::EXTERNAL ;
|
fs .shrink = FS::EXTERNAL ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! Glib::find_program_in_path( "btrfs" ) .empty() )
|
|
||||||
{
|
|
||||||
//Test for labelling capability in btrfs command
|
|
||||||
if ( ! Utils::execute_command( "btrfs filesystem label --help", output, error, true ) )
|
|
||||||
fs .write_label = FS::EXTERNAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fs .check )
|
if ( fs .check )
|
||||||
|
@ -81,7 +108,12 @@ bool btrfs::check_repair( const Partition & partition, OperationDetail & operati
|
||||||
|
|
||||||
void btrfs::set_used_sectors( Partition & partition )
|
void btrfs::set_used_sectors( Partition & partition )
|
||||||
{
|
{
|
||||||
if ( ! Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) )
|
|
||||||
|
if ( btrfs_found )
|
||||||
|
exit_status = Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
|
||||||
|
else
|
||||||
|
exit_status = Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
|
||||||
|
if ( ! exit_status )
|
||||||
{
|
{
|
||||||
Glib::ustring size_label;
|
Glib::ustring size_label;
|
||||||
if ( ((index = output .find( "FS bytes" )) < output .length()) &&
|
if ( ((index = output .find( "FS bytes" )) < output .length()) &&
|
||||||
|
@ -148,6 +180,7 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
operationdetail .add_child( OperationDetail( str_temp, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
|
operationdetail .add_child( OperationDetail( str_temp, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
|
||||||
char dtemplate[] = "/tmp/gparted-XXXXXXXX" ;
|
char dtemplate[] = "/tmp/gparted-XXXXXXXX" ;
|
||||||
Glib::ustring dname = mkdtemp( dtemplate ) ;
|
Glib::ustring dname = mkdtemp( dtemplate ) ;
|
||||||
|
Glib::ustring str_size ;
|
||||||
if( dname .empty() )
|
if( dname .empty() )
|
||||||
{
|
{
|
||||||
//Failed to create temporary directory
|
//Failed to create temporary directory
|
||||||
|
@ -167,20 +200,36 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
if ( exit_status )
|
if ( exit_status )
|
||||||
{
|
{
|
||||||
//Build resize command
|
//Build resize command
|
||||||
str_temp = "btrfsctl" ;
|
|
||||||
if ( ! fill_partition )
|
if ( ! fill_partition )
|
||||||
{
|
str_size = Utils::num_to_str( floor( Utils::sector_to_unit(
|
||||||
str_temp += " -r " + Utils::num_to_str( floor( Utils::sector_to_unit(
|
|
||||||
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
|
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
str_temp += " -r max" ;
|
str_size = "max" ;
|
||||||
str_temp += " " + dname ;
|
|
||||||
|
if ( btrfs_found )
|
||||||
|
str_temp = "btrfs filesystem resize " + str_size + " " + dname ;
|
||||||
|
else
|
||||||
|
str_temp = "btrfsctl -r " + str_size + " " + dname ;
|
||||||
|
|
||||||
//Execute the command
|
//Execute the command
|
||||||
exit_status = execute_command( str_temp, operationdetail ) ;
|
exit_status = execute_command( str_temp, operationdetail ) ;
|
||||||
//Sometimes btrfsctl returns an exit status of 256 on successful resize.
|
//Resizing a btrfs file system for a second time to the
|
||||||
exit_status = ( exit_status == 0 || exit_status == 256 ) ;
|
// same size results in ioctl() returning -1 EINVAL
|
||||||
|
// (Invalid argument) from the kernel btrfs code.
|
||||||
|
// * Btrfs filesystem resize reports this as exit
|
||||||
|
// status 30:
|
||||||
|
// ERROR: Unable to resize '/MOUNTPOINT'
|
||||||
|
// * Btrfsctl -r reports this as exit status 1:
|
||||||
|
// ioctl:: Invalid argument
|
||||||
|
// WARNING:
|
||||||
|
// Ignoring these errors could mask real failures, but
|
||||||
|
// not ignoring them will cause partition shinks to
|
||||||
|
// fail on the second "grow file system to fill the
|
||||||
|
// partition" resize.
|
||||||
|
exit_status = ( exit_status == 0
|
||||||
|
|| ( btrfs_found && exit_status == 30<<8 )
|
||||||
|
|| ( ! btrfs_found && exit_status == 1<<8 )
|
||||||
|
) ;
|
||||||
|
|
||||||
//Always unmount the file system
|
//Always unmount the file system
|
||||||
str_temp = "umount -v " + dname ;
|
str_temp = "umount -v " + dname ;
|
||||||
|
@ -196,7 +245,22 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
|
|
||||||
void btrfs::read_label( Partition & partition )
|
void btrfs::read_label( Partition & partition )
|
||||||
{
|
{
|
||||||
if ( ! Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) )
|
if ( btrfs_found )
|
||||||
|
{
|
||||||
|
exit_status = Utils::execute_command( "btrfs filesystem show " + partition .get_path(), output, error, true ) ;
|
||||||
|
if ( ! exit_status )
|
||||||
|
{
|
||||||
|
partition .label = Utils::regexp_label( output, "^Label: '(.*)' uuid:" );
|
||||||
|
//Btrfs filesystem show encloses the label in single
|
||||||
|
// quotes or reports "none" without single quotes, so
|
||||||
|
// the cases are disginguishable and this regexp won't
|
||||||
|
// match the no label case.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exit_status = Utils::execute_command( "btrfs-show " + partition .get_path(), output, error, true ) ;
|
||||||
|
if ( ! exit_status )
|
||||||
{
|
{
|
||||||
Glib::ustring label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
|
Glib::ustring label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
|
||||||
//Btrfs-show reports "none" when there is no label, but
|
//Btrfs-show reports "none" when there is no label, but
|
||||||
|
@ -205,7 +269,8 @@ void btrfs::read_label( Partition & partition )
|
||||||
if ( label != "none" )
|
if ( label != "none" )
|
||||||
partition .label = label ;
|
partition .label = label ;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
if ( exit_status )
|
||||||
{
|
{
|
||||||
if ( ! output .empty() )
|
if ( ! output .empty() )
|
||||||
partition .messages .push_back( output ) ;
|
partition .messages .push_back( output ) ;
|
||||||
|
|
Loading…
Reference in New Issue