The timed progress tracking callback for execution of xfs copy follows
this pattern:
sigc::connection c;
...
c = Glib::signal_timeout().connect( ... sigc::mem_fun( *this, &xfs::copy_progress ) ..., 500 /*ms*/ );
... execute_command( ... );
c.disconnect();
As with output progress tracking callbacks for ext2/3/4 and ntfs file
system specific commands, pass the callback slot and a flag into
execute_command() and connect the timed callback inside. This
simplified the pattern to:
... execute_command( ...|EXEC_PROGRESS_TIMED,
static_cast<TimedSlot>( sigc::mem_fun( *this, &xfs::copy_progress ) ) );
NOTE:
The type of sigc::mem_fun() doesn't allow the compiler to choose between
the two overloaded variants of execute_command() with the fourth
parameter of either (full types without typedefs of StreamSlot and
TimedSlot respectively):
sigc::slot<void, OperationDetail *> stream_progress_slot
sigc::slot<bool, OperationDetail *> timed_progress_slot
Therefore have to cast the result of all callback slots to the relevant
type. Hence:
static_cast<StreamSlot>( sigc::mem_fun( *this, &{CLASS}::{NAME}_progress ) )
static_cast<TimedSlot>( sigc::mem_fun( *this, &xfs::copy_progress ) )
References:
* [sigc] Functor not resolving between overloaded methods with
different slot types
https://mail.gnome.org/archives/libsigc-list/2016-February/msg00000.html
* Bug 306705 - Can't overload methods based on different slot<>
parameters.
https://bugzilla.gnome.org/show_bug.cgi?id=306705
Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
copy methods
For the relevant stream from a file system specific command being
tracked, there were 2 callbacks attached: update_command_output() and
update_command_progress(). When called, update_command_progress() just
emitted signal_progress to call the file system specific progress
tracker callback. Like this:
signal_update.emit() -> update_command_output()
-> update_command_progress()
signal_progress.emit() -> {CLASS}::{NAME}_progress()
Instead just connect the file system specific progress tracker callback
directly to signal_update and bypass the unnecessary
update_command_progress() method and the signal_progress signal. Like
this:
signal_update.emit() -> update_command_output()
-> {CLASS}::{NAME}_progress()
Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
copy methods
All the output progress tracking callbacks for execution of ext2/3/4 and
ntfs file system specific commands followed this pattern:
sigc::connection c = signal_progress.connect( sigc::mem_fun( *this, &ext2::..._progress ) );
bool success = ! execute_command( ... );
c.disconnect();
return success;
Instead, pass the callback slot and a flag into execute_command() and
connect the callback inside. This simplifies the pattern to:
return ! execute_command( ...|EXEC_PROGRESS_STDOUT,
sigc::mem_fun( *this, &ext2::..._progress ) );
Note that as the progress tracking callbacks are only registered against
updates to the relevant stream from the tracked commands they won't be
called when the other stream is updated any more.
Also note that signal_progress is a member of the FileSystem class and
derived objects so lives as long as GParted is running, therefore the
progress tracking callbacks need explicitly disconnecting at the end of
execute_command(). However signal_update is a member of the PipeCapture
class of which the output and error local variables in execute_command()
are types. Therefore there is no need to explicitly disconnect the
signal_update callbacks as they will be destructed along with the
callback slots when they go out of scope at the end of the
execute_command() method.
Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
copy methods
Lots of files which use the Partition class relied on the declaration
being included via other header files. This is bad practice.
Add #include "Partition.h" into every file which uses the Partition
class which doesn't already include it. Header file #include guards are
specifically to allow this.
Capture and parse the progress reports of ntfsresize and resize2fs and
update the dialog progress bar.
Bug 467925 - gparted: add progress bar during operation
There has been an undocumented rule that external commands displayed in
the operation details, as part of file system manipulations, only get a
time and check mark displayed when multiple commands are needed, and not
otherwise. (GParted checks whether all commands are successful or not
regardless of whether a check mark is displayed in the operation details
or not).
EXCEPTION 1: btrfs resize
Since the following commit [1] from 2013-02-22, GParted stopped
displaying the timing for the btrfs resize command in the operation
details. It being part of a multi-command sequence to perform the step.
This is because FileSystem::execute_command() since the commit can only
check the exit status for zero / non-zero while timing and checking the
command status but btrfs resize needs to consider some non-zero statuses
as successful.
[1] 52a2a9b00a
Reduce threading (#685740)
EXCEPTION 2: ext2/3/4 move and copy using e2image
When use of e2image was added [2] the single command steps were timed
and check.
[2] 86111fe12a
Use e2image to move/copy ext[234] file systems (#721516)
EXCEPTION 3: fat16/32 write label and UUID
Uses Utils::execute_command() rather than FileSystem::execute_command()
so can be separately changed. See the following commit for resolution
of the final commands not yet timed and check mark displayed.
CHANGE:
Lets make a simpler rule of always displaying the time and a check mark
for all external commands displayed in the operation details. However
this makes several of the other single command actions need special exit
status handling because zero success, non-zero failure is not correct
for every case. Specifically affects resizing of reiserfs and check
repair of ext2/3/4, fat16/32, jfs and reiserfs.
After this change all external commands run as file system actions must
follow one of these two patterns of using the EXEC_CHECK_STATUS flag or
separately calling FileSystem::set_status() to register success or
failure of the command:
exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...);
or:
exit_status = execute_command(cmd, od, ...);
bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...);
set_status(od, success );
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
Change the two optional boolean parameters into a single optional flags
parameter which uses symbolically defined names. Makes reading the
execute_command() calls much easier to understand. (Implemented as bit
field using the same technique as used for Glib::SpawnFlags [1]).
This changes the calls thus:
execute_command(cmd, od) -> (cmd, od)
execute_command(cmd, od, false) -> (cmd, od, EXEC_NONE) // [2]
execute_command(cmd, od, true ) -> (cmd, od, EXEC_CHECK_STATUS)
execute_command(cmd, od, false, true) -> (cmd, od, EXEC_CANCEL_SAFE)
execute_command(cmd, od, true , true) ->
(cmd, od, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE)
[1] SpawnFlags bitwise operators in
/usr/include/glibmm-2.4/glibmm/spawn.h.
[2] False and EXEC_NONE are the default values for the optional third
parameter before and after this change respectively and both mean
the same. This is being used in btrfs::resize() and being kept for
now despite it being the default.
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
Use of execute_command_timed() was removed by this commit from
2013-02-22:
52a2a9b00a
Reduce threading (#685740)
Bug 754684 - Updates to FileSystem:: and Utils::execute_command()
functions
The function never modifies any member variables so make it a const
member function.
(FileSystem::get_custom_text() is a virtual function so can't be made
static).
GParted's primary inbuilt busy detection method is "is the partition
mounted?". A custom method is used for LVM2 PV because its not a
mounted file system.
Make busy detection selectable per file system type.
.fs.busy = FS::NONE (default)
No busy detection.
.fs.busy = FS::GPARTED
Use internal GParted method which checks if the partition is
mounted.
.fs.busy = FS:EXTERNAL
Call the file system type's member function is_busy().
LVM2 PV busy detection changes from a special case to just electing to
call the lvm2_pv::is_busy() method. Linux Software RAID remains a
special case because it's only recognised, but not otherwise supported.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
This is part of parent bug:
Bug #721455 - Obsolete info in license text on multiple modules
and GNOME Goal:
https://wiki.gnome.org/Initiatives/GnomeGoals/Proposals
* verify all source files to make sure they have a license and a
copyright, and that both are up-to-date
Bug #721565 - License text contains obsolete FSF postal address
Include guards need to be unique within GParted code and all included
library header files.
http://en.wikipedia.org/wiki/Include_guard#Difficulties
Use this model for all include guards:
#ifndef GPARTED_FILE_NAME_H
#define GPARTED_FILE_NAME_H
...
#endif /* GPARTED_FILE_NAME_H */
Closes Bug #539297 - Make include guards unique
Many filesystems do not implement some of their methods, but had to provide
dummy implementations. Remove all of the dummy implementations and instead
just provide one in the base FileSystem class.
Interested operations can now connect a signal to their OperationDetail
to be notified of a cancelation request. The internal copy/move code
will now cleanly stop on cancelation, allowing the partition to be
rolled back to its previous state. This makes canceling a move
perfectly safe.
After clicking cancel, the button changes to "Force Cancel" and is
disabled for 5 seconds. Operations that are safe to cancel will do so
and those that are not will continue to run. Clicking force cancel
asks operations to cancel, even if doing so is unsafe. For the
internal copy/move algorithm, canceling is always safe because an
error results in a rollback operation. Canceling the rollback is
unsafe. For external commands, filesystem modules may indicate
that the command is safe to cancel or not. Canceled commands will
be terminated with SIGINT.
As a result of the new safe cancel vs force cancel distinction, the
scary warning about cancl causing corruption has been moved to
after clicking the force cancel button.
Part of Bug #601239 - Please allow 'Cancel after current operation'
Win_Gparted and Dialog_Progress were creating threads to perform most
functions in the background. Most of the time, the only reason the
threads blocked was to execute an external command. The external command
execution has been changed to spawn the command asynchronously and wait
for completion with a nested main loop. While waiting for completion,
the pipe output is captured via events. In the future, this will allow
for it to be parsed in real time to obtain progress information.
Those tasks in GParted_Core that still block now spawn a background thread
and wait for it to complete with a nested main loop to avoid hanging the
gui.
Part of Bug #685740 - Refactor to use asynchronous command execution
This commit only adds a remove() method to every file system and an
optional call to it in the relevant operations. All remove() methods
are no operations and not enabled.
The remove() method provides explicit controlled removal of a file
system before the partition is deleted or overwritten by being formatted
or pasted into. When implemented, it appears as an extra step in the
relevant operation. The file system specific remove() method is
explicitly allowed to fail and stop the operations currently being
applied.
This is different to the existing erase_filesystem_signatures() which
wipes any previous file system signatures immediately before a new file
system is written to ensure there is no possibility of the partition
containing two or more different file system signatures. It never fails
or reports anything to the user.
NOTE:
Most file systems should NOT implement a remove() method as it will
prevent recovery from accidental partition deletion.
Bug #670171 - Add LVM PV read-write support
Update file system specific implementations to set the size and free
space, thus allowing the unallocated space in the partition to be
calculated, for the following unmounted file systems:
btrfs, ext2, ext3, ext4, fat16, fat32, jfs, nilfs2, ntfs, reiserfs,
reiser4, xfs
Bug #499202 - gparted does not see the difference if partition size
differs from filesystem size
Add the ability to set a new random UUID on file systems that provide
the appropriate tools to perform this action.
Update the help manual to include this new functionality. Also add
reference links to "setting a partition label" and "changing a
partition UUID" in the "copying and pasting a partition" section.
This patch does not include setting the UUID on an NTFS file system.
Bug #667278 - Add support for setting UUID
Bug #608308 - fix documentation - Copying and Pasting a Partition
There is a lot of commonality and code repetition for resizing of file
systems which can only be resized while mounted. Resizing of btrfs, jfs
and xfs all follow the pattern: mkdir, mount, resize, umount and rmdir.
Copying an xfs file system also uses a similar pattern, but for the
source and destination xfs file systems simultaneously.
Add three helper functions to the FileSystem class which implement
common tasks, allowing mounted file system resizing to be implemented
more simply.
Also add a function to the Utils class which checks whether the kernel
supports a file system. It handles the case of non-loaded modules,
which currently leads to reporting the growing of jfs and xfs as
unsupported.
Restore copyright entries by original author to those of his last
known repository commit titled "released gparted-0.3.4 on
LarryT's request." on Feb 25, 2007.
Add my own copyright entries for files in which I changed source
code. Files in which I only made spelling changes do not have my
copyright entry added.
* added support for reading volumelabels. Atm we only read ext2/3, but
the infrastructure for adding the other filesystems is in place.
It's simply a matter of finding the right commands and parsing the
output. (see #338528 for more info)
* include/FileSystem.h,
include/GParted_Core.h,
src/FileSystem.cc,
src/GParted_Core.cc,
src/ext2.cc,
src/ext3.cc,
src/ntfs.cc,
src/reiserfs.cc: removed cylindersize buffering during resize from
the filesystems. It is not needed anymore now we calculate the new
position before calling this.
Also added some extra progressfeedback in the core
* wrap mount/umount/swapon/swapoff instead of implementing it
ourselves (#330641)
* moved execute_command() to Utils and made the filesystems use it. All
in all this decreased the size of the binary with 10% and made stuff
more readable.
* correct partitiontype of destination is now set while copying
* resizing now return correct status (sometimes it would report
succes even when some of the suboperationes failed)
* fixed some issues with resizing and cylindersizes.
* removed Execute_Command() and replaced it by execute_command().
The latter uses Glib::spawn_sync instead of popen().
also made the filesystems call execute_command rather than calling
Glib::spawn_sync themselves.
* added detailed progressfeedback. It still needs some polishing, but
is already far better then the old situation. And what's more, it's
finally threadsafe :p
* hmmz, lots of shimmery internals..
Instead of using a boolean to indicate support for certain
features i now use and enum (NONE, LIBPARTED, EXTENDED).
This allowed me to clean up some stuff that annoyed me ;)
Still.. the core could use a bit more love...
* include/FileSystem.h: cleanups
* include/GParted_Core.h,
src/GParted_Core.cc: correct partitiontype is now set after creation
or conversion. (#322281)
* The Filesystemclasses: Changed 'bool Create( const Glib::ustring & device_path, const Partition & new_partition )'
to 'bool Create( const Partition & new_partition )'. Since i now use external tools for all filesystems, the partitionpath will suffice.
* added support for jfs (create, copy, grow) and hfs (create, copy)
* fixed a bug in copying xfs filesystems.
* fixed a number of small bugs/annoying issues.
* include/FileSystem.h,
src/FileSystem.cc: Execute_Command() now returns exit status of executed command
* the filesystemclasses: returnvalue (bool) is now set according to the return status of the command
* Harddisks without disklabel are now properly initizalized and shown in the menu. When one tries to create a new partition on
such a disk a dialog pops up with some blabla about disklabels and offers to create a disklabel. sweet :P (special thanks to mantiena-baltix
for bringing this issue to my attention)
* fixed minor annoyance with refreshing detailed deviceinfo after a 'deep refresh'
* Again way too many chances to create a detailed entry (i'm glad i'm the only dev atm :P ).
Resizing of ext2/3 works perfect now. I've even tested it on the partition holding my SG seasons =)
Implemented checking of filesystems (only internally used atm).
Done some overall tweaking, finetuning etc.. release 0.0.7 is getting shape.
* Rewrote a large part of gparteds internal code. Filesystemssupport is now much more separated from the rest of gparted and
adding support for other filesystems should be a piece of cake now (hope that's true :P)
It still needs a lot of love, but the foundations are laid =)