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



commit 36804b963444e487dfbe23e4b4de985f6c64a7bf
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Mon Dec 5 12:21:19 2016 +0000

    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

 include/GParted_Core.h |    2 +
 src/GParted_Core.cc    |   51 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/luks.cc            |   21 +++++++++++++------
 3 files changed, 65 insertions(+), 9 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index 1759fb6..e675202 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -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 ) ;
 
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 00f4ab0..c3c35a0 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -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 )
diff --git a/src/luks.cc b/src/luks.cc
index 1ae1033..aec2083 100644
--- a/src/luks.cc
+++ b/src/luks.cc
@@ -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;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]