From e2aff7ba6623c9312c05a532a687c6990ea14c6a Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Thu, 8 Dec 2016 23:11:18 +0000 Subject: [PATCH] Implement offline grow of encryption volumes (#774818) While a device-mapper encryption mapping can only be resized while active, a LUKS volume can inherently be grown while offline because it doesn't store a size and when started fills the partition. This doesn't even need the cryptsetup command to do the resizing (just to open the LUKS volume afterwards which GParted doesn't yet support). Implement offline growing of LUKS volumes. Bug 774818 - Implement LUKS read-write actions NOT requiring a passphrase --- src/GParted_Core.cc | 28 +++++++++++++++++++++++----- src/Win_GParted.cc | 4 ++-- src/luks.cc | 17 +++++++++++++++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index 829f2f49..00f4ab0a 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -2586,17 +2586,35 @@ bool GParted_Core::resize_encryption( const Partition & partition_old, const Partition & partition_new, OperationDetail & operationdetail ) { - if ( ! ( partition_old.filesystem == FS_LUKS && partition_old.busy ) ) + if ( partition_old.filesystem != FS_LUKS ) { operationdetail.add_child( OperationDetail( - GPARTED_BUG + ": " + _("partition does not contain open LUKS encryption for a resize encryption only step"), + GPARTED_BUG + ": " + _("partition does not contain LUKS encryption for a resize encryption only step"), STATUS_ERROR, FONT_ITALIC ) ); return false; } - const Partition & filesystem_ptn_new = partition_new.get_filesystem_partition(); Sector delta = partition_new.get_sector_length() - partition_old.get_sector_length(); + if ( ! partition_old.busy && delta < 0LL ) + { + operationdetail.add_child( OperationDetail( + GPARTED_BUG + ": " + _("impossible to shrink a closed LUKS encryption volume"), + STATUS_ERROR, FONT_ITALIC ) ); + return false; + } + + if ( ! partition_old.busy ) + { + // grow closed LUKS. + // maximize_encryption() is only called to display no action needed + // operation message generated in luks::resize() for this case. + return resize_move_partition( partition_old, partition_new, operationdetail ) + && maximize_encryption( partition_new, operationdetail ); + } + + const Partition & filesystem_ptn_new = partition_new.get_filesystem_partition(); + if ( filesystem_ptn_new.filesystem == FS_LINUX_SWAP ) { // LUKS is resized, but linux-swap is recreated, not resized @@ -2893,10 +2911,10 @@ bool GParted_Core::shrink_encryption( const Partition & partition_old, bool GParted_Core::maximize_encryption( const Partition & partition, OperationDetail & operationdetail ) { - if ( ! ( partition.filesystem == FS_LUKS && partition.busy ) ) + if ( partition.filesystem != FS_LUKS ) { operationdetail.add_child( OperationDetail( - GPARTED_BUG + ": " + _("partition does not contain open LUKS encryption for a maximize encryption only step"), + GPARTED_BUG + ": " + _("partition does not contain LUKS encryption for a maximize encryption only step"), STATUS_ERROR, FONT_ITALIC ) ); return false; } diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index 9d638748..e261947e 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -1256,10 +1256,10 @@ void Win_GParted::set_valid_operations() if ( selected_partition_ptr->filesystem != FS_LUKS && ( fs_cap.grow || fs_cap.shrink || fs_cap.move ) ) allow_resize( true ); - // Is moving this closed LUKS mapping permitted? + // Is growing or moving this closed LUKS mapping permitted? if ( selected_partition_ptr->filesystem == FS_LUKS && ! selected_partition_ptr->busy && - enc_cap.move ) + ( enc_cap.grow || enc_cap.move ) ) allow_resize( true ); // Is resizing an open LUKS mapping and the file system within // supported? diff --git a/src/luks.cc b/src/luks.cc index 1dbdbdf5..1ae10335 100644 --- a/src/luks.cc +++ b/src/luks.cc @@ -28,6 +28,7 @@ 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). @@ -105,8 +106,20 @@ bool luks::resize( const Partition & partition_new, OperationDetail & operationd { 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; + { + if ( ! fill_partition ) + { + // Can't shrink closed LUKS encryption. + return false; + } + else + { + operationdetail.add_child( OperationDetail( + _("Maximize closed LUKS encryption skipped because it will automatically fill the partition when opened"), + STATUS_NONE, FONT_ITALIC ) ) ; + return true; + } + } Glib::ustring size = ""; if ( ! fill_partition )