Display progress of XFS file system specific copy operation (#760709)
XFS uses a file system specific method to copy the partition using "xfsdump | xfsrestore". Monitor progress by periodically querying the destination file system usage and comparing to the source file system usage. Use 0.5 seconds as the polling interval to match that used by the internal block copying algorithm. NOTE: The number of used blocks in the source and destination file system will be very close but may not match exactly. I have seen an XFS copy finish with the following progress text: 1.54 GiB of 1.50 GiB copied (-00:00:02 remaining) Allow the progress bar to overrun like this as it is informing the user that it actually copied a little more data and took a little longer than expected. Needs these two previous commits to correctly round and format the negative time remaining: Fix rounding of negative numbers (#760709) Fix formatting of negative time values (#760709) Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific copy methods
This commit is contained in:
parent
b0bd465098
commit
809a7e0954
|
@ -20,7 +20,11 @@
|
|||
#define GPARTED_XFS_H
|
||||
|
||||
#include "../include/FileSystem.h"
|
||||
#include "../include/OperationDetail.h"
|
||||
#include "../include/Partition.h"
|
||||
#include "../include/Utils.h"
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
@ -40,6 +44,12 @@ public:
|
|||
Partition & dest_part,
|
||||
OperationDetail & operationdetail ) ;
|
||||
bool check_repair( const Partition & partition, OperationDetail & operationdetail ) ;
|
||||
|
||||
private:
|
||||
bool copy_progress( OperationDetail * operationdetail );
|
||||
|
||||
Byte_Value src_used; // Used bytes in the source FS of an XFS copy operation
|
||||
Glib::ustring dest_mount_point; // Temporary FS mount point of an XFS copy operation
|
||||
};
|
||||
|
||||
} //GParted
|
||||
|
|
52
src/xfs.cc
52
src/xfs.cc
|
@ -17,7 +17,12 @@
|
|||
|
||||
|
||||
#include "../include/xfs.h"
|
||||
#include "../include/OperationDetail.h"
|
||||
#include "../include/Partition.h"
|
||||
#include "../include/ProgressBar.h"
|
||||
#include "../include/Utils.h"
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
@ -223,7 +228,7 @@ bool xfs::copy( const Partition & src_part,
|
|||
if ( src_mount_point .empty() )
|
||||
return false ;
|
||||
|
||||
Glib::ustring dest_mount_point = mk_temp_dir( "dest", operationdetail ) ;
|
||||
dest_mount_point = mk_temp_dir( "dest", operationdetail );
|
||||
if ( dest_mount_point .empty() )
|
||||
{
|
||||
rm_temp_dir( src_mount_point, operationdetail ) ;
|
||||
|
@ -233,6 +238,14 @@ bool xfs::copy( const Partition & src_part,
|
|||
success &= ! execute_command( "mount -v -t xfs -o noatime,ro " + src_part.get_path() +
|
||||
" " + src_mount_point, operationdetail, EXEC_CHECK_STATUS );
|
||||
|
||||
// Get source FS used bytes, needed in progress update calculation
|
||||
Byte_Value fs_size;
|
||||
Byte_Value fs_free;
|
||||
if ( Utils::get_mounted_filesystem_usage( src_mount_point, fs_size, fs_free, error ) == 0 )
|
||||
src_used = fs_size - fs_free;
|
||||
else
|
||||
src_used = -1LL;
|
||||
|
||||
if ( success )
|
||||
{
|
||||
success &= ! execute_command( "mount -v -t xfs " + dest_part.get_path() +
|
||||
|
@ -240,9 +253,23 @@ bool xfs::copy( const Partition & src_part,
|
|||
|
||||
if ( success )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail.get_progressbar();
|
||||
sigc::connection c;
|
||||
if ( src_used > 0LL )
|
||||
{
|
||||
progressbar.start( (double)src_used, PROGRESSBAR_TEXT_COPY_BYTES );
|
||||
// Get xfs::copy_progress() called every 500 ms to update progress
|
||||
c = Glib::signal_timeout().connect(
|
||||
sigc::bind<OperationDetail*>( sigc::mem_fun( *this, &xfs::copy_progress ),
|
||||
&operationdetail ),
|
||||
500 );
|
||||
}
|
||||
success &= ! execute_command( "sh -c 'xfsdump -J - " + src_mount_point +
|
||||
" | xfsrestore -J - " + dest_mount_point + "'",
|
||||
operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
|
||||
c.disconnect();
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
|
||||
success &= ! execute_command( "umount -v " + dest_part.get_path(), operationdetail,
|
||||
EXEC_CHECK_STATUS );
|
||||
|
@ -264,4 +291,27 @@ bool xfs::check_repair( const Partition & partition, OperationDetail & operation
|
|||
EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE );
|
||||
}
|
||||
|
||||
//Private methods
|
||||
|
||||
// Report progress of XFS copy. Monitor destination FS used bytes and track against
|
||||
// recorded source FS used bytes.
|
||||
bool xfs::copy_progress( OperationDetail * operationdetail )
|
||||
{
|
||||
ProgressBar & progressbar = operationdetail->get_progressbar();
|
||||
Byte_Value fs_size;
|
||||
Byte_Value fs_free;
|
||||
Byte_Value dst_used;
|
||||
if ( Utils::get_mounted_filesystem_usage( dest_mount_point, fs_size, fs_free, error ) != 0 )
|
||||
{
|
||||
if ( progressbar.running() )
|
||||
progressbar.stop();
|
||||
// Failed to get destination FS used bytes. Remove this timed callback early.
|
||||
return false;
|
||||
}
|
||||
dst_used = fs_size - fs_free;
|
||||
progressbar.update( (double)dst_used );
|
||||
operationdetail->signal_update.emit( *operationdetail );
|
||||
return true;
|
||||
}
|
||||
|
||||
} //GParted
|
||||
|
|
Loading…
Reference in New Issue