Implement resize/move operation of encrypted file systems (#774818)

Moving of closed LUKS is simply enabled by luks .move capability being
set and requires no further coding.

Resizing of encrypted file systems requires both the LUKS mapping and
encrypted file system within to be resized in the right order for both
shrinking and growing.  To keep the code simple split resizing of plain
and encrypted into separate functions.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
This commit is contained in:
Mike Fleetwood 2016-12-05 11:37:18 +00:00 committed by Curtis Gedak
parent ee1b2257d2
commit 828f0d8ab3
4 changed files with 112 additions and 13 deletions

View File

@ -137,9 +137,20 @@ private:
bool resize( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail ) ;
bool resize_encryption( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail );
bool resize_plain( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail );
bool resize_move_partition( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail ) ;
bool shrink_encryption( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail );
bool maximize_encryption( const Partition & partition,
OperationDetail & operationdetail );
bool shrink_filesystem( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail );

View File

@ -30,6 +30,7 @@ public:
FS get_filesystem_support();
bool is_busy( const Glib::ustring & path );
void set_used_sectors( Partition & partition );
bool resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition );
};
} //GParted

View File

@ -2576,31 +2576,81 @@ bool GParted_Core::resize( const Partition & partition_old,
return false ;
}
bool success = true;
if ( partition_new.filesystem == FS_LUKS )
return resize_encryption( partition_old, partition_new, operationdetail );
else
return resize_plain( partition_old, partition_new, operationdetail );
}
bool GParted_Core::resize_encryption( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail )
{
const Partition & filesystem_ptn_new = partition_new.get_filesystem_partition();
Sector delta = partition_new.get_sector_length() - partition_old.get_sector_length();
if ( filesystem_ptn_new.filesystem == FS_LINUX_SWAP )
{
// LUKS is resized, but linux-swap is recreated, not resized
if ( delta < 0LL ) // shrink
{
return shrink_encryption( partition_old, partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail )
&& recreate_linux_swap_filesystem( filesystem_ptn_new, operationdetail );
}
else if ( delta > 0LL ) // grow
{
return resize_move_partition( partition_old, partition_new, operationdetail )
&& maximize_encryption( partition_new, operationdetail )
&& recreate_linux_swap_filesystem( filesystem_ptn_new, operationdetail );
}
}
const Partition & filesystem_ptn_old = partition_old.get_filesystem_partition();
if ( delta < 0LL ) // shrink
{
return check_repair_filesystem( filesystem_ptn_old, operationdetail )
&& shrink_filesystem( filesystem_ptn_old, filesystem_ptn_new, operationdetail )
&& shrink_encryption( partition_old, partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail );
}
else if ( delta > 0LL ) // grow
{
return check_repair_filesystem( filesystem_ptn_old, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail )
&& maximize_encryption( partition_new, operationdetail )
&& maximize_filesystem( filesystem_ptn_new, operationdetail );
}
return true;
}
bool GParted_Core::resize_plain( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail )
{
if ( partition_new.filesystem == FS_LINUX_SWAP )
{
// linux-swap is recreated, not resize
success = resize_move_partition( partition_old, partition_new, operationdetail )
&& recreate_linux_swap_filesystem( partition_new, operationdetail );
return success;
// linux-swap is recreated, not resized
return resize_move_partition( partition_old, partition_new, operationdetail )
&& recreate_linux_swap_filesystem( partition_new, operationdetail );
}
Sector delta = partition_new.get_sector_length() - partition_old.get_sector_length();
if ( delta < 0LL ) // shrink
{
success = check_repair_filesystem( partition_new, operationdetail )
&& shrink_filesystem( partition_old, partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail );
return check_repair_filesystem( partition_new, operationdetail )
&& shrink_filesystem( partition_old, partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail );
}
else if ( delta > 0LL ) // grow
{
success = check_repair_filesystem( partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail )
&& maximize_filesystem( partition_new, operationdetail );
return check_repair_filesystem( partition_new, operationdetail )
&& resize_move_partition( partition_old, partition_new, operationdetail )
&& maximize_filesystem( partition_new, operationdetail );
}
return success;
return true;
}
bool GParted_Core::resize_move_partition( const Partition & partition_old,
@ -2807,6 +2857,24 @@ bool GParted_Core::resize_move_partition( const Partition & partition_old,
return return_value ;
}
bool GParted_Core::shrink_encryption( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail )
{
operationdetail.add_child( OperationDetail( _("shrink encryption volume") ) );
bool success = resize_filesystem_implement( partition_old, partition_new, operationdetail );
operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
return success;
}
bool GParted_Core::maximize_encryption( const Partition & partition, OperationDetail & operationdetail )
{
operationdetail.add_child( OperationDetail( _("grow encryption volume to fill the partition") ) );
bool success = resize_filesystem_implement( partition, partition, operationdetail );
operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
return success;
}
bool GParted_Core::shrink_filesystem( const Partition & partition_old,
const Partition & partition_new,
OperationDetail & operationdetail )

View File

@ -101,4 +101,23 @@ void luks::set_used_sectors( Partition & partition )
}
}
bool luks::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
{
LUKS_Mapping mapping = LUKS_Info::get_cache_entry( partition_new.get_path() );
if ( mapping.name.empty() )
// Only active device-mapper encryption mappings can be resized.
return false;
Glib::ustring size = "";
if ( ! fill_partition )
// Cryptsetup resize takes the size of the encryption mapping, not the
// size of the underlying block device. Both device-mapper and cryptsetup
// always work in units of 512 byte sectors regardless of the actual
// device sector size.
size = "--size " + Utils::num_to_str( ( partition_new.get_byte_length() - mapping.offset ) / 512LL ) + " ";
return ! execute_command( "cryptsetup -v " + size + "resize " + mapping.name,
operationdetail, EXEC_CHECK_STATUS );
}
} //GParted