[gparted] Display progress of ext2/3/4 file system specific copy and move operations (#760709)



commit 32622f4d579998537584b513ea98ea446815f26b
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Sat Jan 16 12:13:02 2016 +0000

    Display progress of ext2/3/4 file system specific copy and move operations (#760709)
    
    Using e2image to copy a file system looks like this.  (Intermediate
    progress lines which are constantly overwritten are indicated with ">").
        # e2image -ra -p /dev/sdb4 /dev/sdb5
        e2image 1.42.13 (17-May-2015)
        Scanning inodes...
    >   Copying 0 / 276510 blocks (0%)
    >   Copying 8845 / 276510 blocks (3%)
    >   Copying 48433 / 276510 blocks (18%)
    >   Copying 77135 / 276510 blocks (28%)
    >   Copying 111311 / 276510 blocks (40%)
    >   Copying 137039 / 276510 blocks (50%)
    >   Copying 166189 / 276510 blocks (60%) 00:00:03 remaining at 108.20 MB/s
    >   Copying 190285 / 276510 blocks (69%) 00:00:03 remaining at 106.19 MB/s
    >   Copying 209675 / 276510 blocks (76%) 00:00:02 remaining at 102.38 MB/s
    >   Copying 238219 / 276510 blocks (86%) 00:00:01 remaining at 103.39 MB/s
    >   Copying 256692 / 276510 blocks (93%) 00:00:00 remaining at 100.27 MB/s
        Copied 276510 / 276510 blocks (100%) in 00:00:10 at 108.01 MB/s
    
    Note that the copying figures are reported in file system block size
    units and the progress information is written to stderr, hence needing
    these two previous commits:
        Record file system block size where known (#760709)
        Call any FS specific progress trackers for stderr updates too (#760709)
    
    Add progress tracking function for e2image command.  Also tracks when
    the text progress indicator has passed in the output so that the
    progress bar can be stopped as well as started when needed.
    
    Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
                 copy methods

 include/ext2.h |    4 ++++
 src/ext2.cc    |   48 ++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 42 insertions(+), 10 deletions(-)
---
diff --git a/include/ext2.h b/include/ext2.h
index edad76f..584bdf2 100644
--- a/include/ext2.h
+++ b/include/ext2.h
@@ -22,6 +22,7 @@
 #include "../include/FileSystem.h"
 #include "../include/OperationDetail.h"
 #include "../include/Partition.h"
+#include "../include/Utils.h"
 
 #include <glibmm/ustring.h>
 
@@ -61,6 +62,9 @@ private:
        void resize_progress( OperationDetail *operationdetail );
        void create_progress( OperationDetail *operationdetail );
        void check_repair_progress( OperationDetail *operationdetail );
+       void copy_progress( OperationDetail *operationdetail );
+
+       Byte_Value fs_block_size;  // Holds file system block size for the copy_progress() callback
 };
 
 } //GParted
diff --git a/src/ext2.cc b/src/ext2.cc
index 4fe5910..4df034f 100644
--- a/src/ext2.cc
+++ b/src/ext2.cc
@@ -265,25 +265,31 @@ bool ext2::move( const Partition & partition_new,
                  const Partition & partition_old,
                  OperationDetail & operationdetail )
 {
-       Sector distance;
-       Glib::ustring offset;
-       distance = partition_old.sector_start - partition_new.sector_start;
-       offset = Utils::num_to_str( llabs(distance) * partition_new.sector_size );
+       Sector distance = partition_old.sector_start - partition_new.sector_start;
+       Glib::ustring offset = Utils::num_to_str( llabs(distance) * partition_new.sector_size );
+       Glib::ustring cmd;
        if ( distance < 0 )
-               return ! execute_command( image_cmd + " -ra -p -o " + offset + " " + partition_new.get_path(),
-                                         operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
+               cmd = image_cmd + " -ra -p -o " + offset + " " + partition_new.get_path();
        else
-               return ! execute_command( image_cmd + " -ra -p -O " + offset + " " + partition_new.get_path(),
-                                         operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
+               cmd = image_cmd + " -ra -p -O " + offset + " " + partition_new.get_path();
 
+       fs_block_size = partition_old.fs_block_size;
+       sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::copy_progress ) );
+       bool success = ! execute_command( cmd, operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
+       c.disconnect();
+       return success;
 }
 
 bool ext2::copy( const Partition & src_part,
                  Partition & dest_part,
                  OperationDetail & operationdetail )
 {
-       return ! execute_command( image_cmd + " -ra -p " + src_part.get_path() + " " + dest_part.get_path(),
-                                 operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
+       fs_block_size = src_part.fs_block_size;
+       sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::copy_progress ) );
+       bool success = ! execute_command( image_cmd + " -ra -p " + src_part.get_path() + " " + 
dest_part.get_path(),
+                                         operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
+       c.disconnect();
+       return success;
 }
 
 //Private methods
@@ -378,4 +384,26 @@ void ext2::check_repair_progress( OperationDetail *operationdetail )
        }
 }
 
+void ext2::copy_progress( OperationDetail *operationdetail )
+{
+       ProgressBar & progressbar = operationdetail->get_progressbar();
+       Glib::ustring line = Utils::last_line( error );
+       // Text progress on the LAST LINE of STDERR looks like "Copying 146483 / 258033 blocks ..."
+       long long progress, target;
+       if ( sscanf( line.c_str(), "Copying %Ld / %Ld blocks", &progress, &target ) == 2 )
+       {
+               if ( ! progressbar.running() )
+                       progressbar.start( (double)(target * fs_block_size), PROGRESSBAR_TEXT_COPY_BYTES );
+               progressbar.update( (double)(progress * fs_block_size) );
+               operationdetail->signal_update( *operationdetail );
+       }
+       // Or when finished, on any line of STDERR, looks like "Copied 258033 / 258033 blocks ..."
+       else if ( error.find( "\nCopied " ) != error.npos )
+       {
+               if ( progressbar.running() )
+                       progressbar.stop();
+               operationdetail->signal_update( *operationdetail );
+       }
+}
+
 } //GParted


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