Implement maximize encryption volume as part of check repair operation (#774818)

Now that resizing of encrypted file systems is implemented add growing
of the open LUKS mapping as part of the check repair operation.

Resizing an encrypted file system requires the LUKS mapping to be open
to access the file system within; therefore it also requires libparted
and kernel support for online partition resizing.  This limits resizing
to the latest distributions with libparted >= 3.2 and kernel >= 3.6.
However growing an open LUKS mapping as part of a check repair operation
doesn't require resizing the partition.  Therefore route via offline
grow of LUKS to avoid those extra, unnecessary requirement.  This does
mean that offline LUKS grow artificially requires cryptsetup, but that is
not really significant as even opening LUKS requires cryptsetup.

So now checking an encrypted file system on even the oldest
distributions does:
1) runs FSCK on the encrypted file system;
2) grows the encryption volume to fill the partition;
3) grows the file system to fill the encryption mapping.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
This commit is contained in:
Mike Fleetwood 2016-12-05 12:21:19 +00:00 committed by Curtis Gedak
parent e2aff7ba66
commit 36804b9634
3 changed files with 65 additions and 9 deletions

View File

@ -192,6 +192,8 @@ private:
Byte_Value total_done ) ;
bool check_repair_filesystem( const Partition & partition, OperationDetail & operationdetail ) ;
bool check_repair_maximize( const Partition & partition,
OperationDetail & operationdetail );
bool set_partition_type( const Partition & partition, OperationDetail & operationdetail ) ;

View File

@ -594,8 +594,8 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
operation->operation_detail )
&& check_repair_filesystem( operation->get_partition_original().get_filesystem_partition(),
operation->operation_detail )
&& maximize_filesystem( operation->get_partition_original().get_filesystem_partition(),
operation->operation_detail );
&& check_repair_maximize( operation->get_partition_original(),
operation->operation_detail );
break;
case OPERATION_CREATE:
@ -2920,6 +2920,21 @@ bool GParted_Core::maximize_encryption( const Partition & partition, OperationDe
}
operationdetail.add_child( OperationDetail( _("grow encryption volume to fill the partition") ) );
// Checking if growing is allowed is only relevant for the check repair operation
// to inform the user why the grow step is being skipped. For a resize/move
// operation these growing checks are merely retesting those performed to allow
// the operation to be queued in the first place. See
// Win_GParted::set_valid_operations().
if ( get_fs( partition.filesystem ).grow == FS::NONE )
{
operationdetail.get_last_child().add_child( OperationDetail(
_("growing is not available for this encryption volume"),
STATUS_NONE, FONT_ITALIC ) );
operationdetail.get_last_child().set_status( STATUS_N_A );
return true;
}
bool success = resize_filesystem_implement( partition, partition, operationdetail );
operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
return success;
@ -3427,6 +3442,38 @@ bool GParted_Core::check_repair_filesystem( const Partition & partition, Operati
return succes ;
}
bool GParted_Core::check_repair_maximize( const Partition & partition,
OperationDetail & operationdetail )
{
if ( partition.filesystem == FS_LUKS )
{
// Pretend that the LUKS partition is closed so that
// resize_filesystem_implement() checks the offline .grow capability
// rather than .online_grow so that maximising LUKS in the context of a
// check encrypted file system operation, which doesn't want to change the
// partition boundaries, can be performed even if libparted and/or the
// kernel aren't new enough to support online partition resizing.
// luks::resize() determines the open status of the LUKS mapping by
// querying the LUKS_Info module cache so doesn't care if the partition
// busy status is wrong.
Partition * temp_offline = partition.clone();
temp_offline->busy = false;
bool success = maximize_encryption( *temp_offline, operationdetail );
delete temp_offline;
temp_offline = NULL;
if ( ! success )
return false;
if ( partition.busy )
success = maximize_filesystem( partition.get_filesystem_partition(), operationdetail );
return success;
}
else
{
return maximize_filesystem( partition, operationdetail );
}
}
bool GParted_Core::set_partition_type( const Partition & partition, OperationDetail & operationdetail )
{
if ( partition.whole_device )

View File

@ -28,7 +28,6 @@ FS luks::get_filesystem_support()
fs.busy = FS::EXTERNAL;
fs.read = FS::EXTERNAL;
fs.grow = FS::EXTERNAL;
// Setting .copy is just for displaying in the File System Support dialog.
// (Copying of encrypted content is only performed while open).
@ -37,14 +36,22 @@ FS luks::get_filesystem_support()
fs.online_read = FS::EXTERNAL;
fs.move = FS::GPARTED;
#ifdef ENABLE_ONLINE_RESIZE
if ( ! Glib::find_program_in_path( "cryptsetup" ).empty() &&
Utils::kernel_version_at_least( 3, 6, 0 ) )
if ( ! Glib::find_program_in_path( "cryptsetup" ).empty() )
{
fs.online_grow = FS::EXTERNAL;
fs.online_shrink = FS::EXTERNAL;
}
// Offline grow doesn't require cryptsetup. However check repair
// encrypted file system routes it's grow online LUKS volume via offline
// grow to avoid also needing online partition resizing from libparted and
// the kernel, which it doesn't need.
fs.grow = FS::EXTERNAL;
#ifdef ENABLE_ONLINE_RESIZE
if ( Utils::kernel_version_at_least( 3, 6, 0 ) )
{
fs.online_grow = FS::EXTERNAL;
fs.online_shrink = FS::EXTERNAL;
}
#endif
}
return fs;
}