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



commit 828f0d8ab37be5e37b8133dc8dece1cea274fb05
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Mon Dec 5 11:37:18 2016 +0000

    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

 include/GParted_Core.h |   11 ++++++
 include/luks.h         |    1 +
 src/GParted_Core.cc    |   94 +++++++++++++++++++++++++++++++++++++++++-------
 src/luks.cc            |   19 ++++++++++
 4 files changed, 112 insertions(+), 13 deletions(-)
---
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index 0fe09a0..1759fb6 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -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 );
diff --git a/include/luks.h b/include/luks.h
index b21569f..ea84de7 100644
--- a/include/luks.h
+++ b/include/luks.h
@@ -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
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index e29ed6b..22bf890 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -2576,31 +2576,81 @@ bool GParted_Core::resize( const Partition & partition_old,
                return false ;
        }
 
-       bool success = true;
-       if ( partition_new.filesystem == FS_LINUX_SWAP )
+       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
        {
-               // linux-swap is recreated, not resize
-               success =    resize_move_partition( partition_old, partition_new, operationdetail )
-                         && recreate_linux_swap_filesystem( partition_new, operationdetail );
+               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 success;
+       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 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 )
diff --git a/src/luks.cc b/src/luks.cc
index 2ec4ef7..1dbdbdf 100644
--- a/src/luks.cc
+++ b/src/luks.cc
@@ -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


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