Commit Graph

1271 Commits

Author SHA1 Message Date
Mike Fleetwood a681f9f637 Replace 32-bit member variable "index" with wider local variables (#764658)
The previous commit (Fix crash reading NTFS usage when there is no
/dev/PTN entry) identified that the FileSystem member variable "index"
is too small on 64-bit machines.  Also this member variable stores no
FileSystem class information and was being used as a local variable.

Replace with local variables of the of the correct type, wide enough to
store the npos not found value.

Bug 764658 - GParted crashes when reading NTFS usage when there is no
             /dev/PTN entry
2016-04-07 09:56:00 -06:00
Mike Fleetwood 366152e449 Fix crash reading NTFS usage when there is no /dev/PTN entry (#764658)
On a 64-bit distribution, with an NTFS file system in a partition
without a /dev entry then GParted will crash when attempting to read
the file system usage.  Not having a /dev entry for the partition is
rare and only known to occur for the disk devices used within Fake RAID
(dmraid) arrays, and then only on Ubuntu 12.04 LTS.  Other/newer
distributions do create /dev entries for partitions found on disk
devices within Fake RAID arrays.

Create mirror Fake RAID array:
    # dmraid -f isw -C MyArray --type 1 --disk /dev/sdc,/dev/sdd
    # dmraid -ay

Create NTFS partition on the Fake RAID array.  On refresh GParted
crashes:
    # ./gpartedbin
    (gpartedbin:590): glibmm-ERROR **:
    unhandled exception (type std::exception) in signal handler:
    what: basic_string::assign

Without a /dev/sdc1 device entry the ntfsresize command reports this:
    # ntfsresize --info --force --no-progress-bar /dev/sdc1
    ntfsresize v2015.3.14 (libntfs-3g)
    ERROR(2): Failed to check '/dev/sdc1' mount state: No such file or directory
    Probably /etc/mtab is missing. It's too risky to continue. You might try
    an another Linux distro.

The problem code in ntfs::set_used_sectors():
    145         index = output.find( "Cluster size" );
    146         if ( index == output.npos ||
    147              sscanf( output.substr( index ).c_str(), "Cluster size       : %Ld", &S ) != 1 )
As "Cluster size" did not exist in the output find() returned the not
found token of string::npos [1], which in a 64-bit environment is
represented by 2^64-1 [2].  However it was saved in the variable index
of type unsigned integer, which is only a 32-bit integer, thus
truncating it to 2^32-1.  Therefore the comparison failed and sscanf()
tried to parse the output starting at offset 2^32-1 which resulted in
the crash.

Introduced by commit:
    324d99a172
    Record file system block size where known (#760709)

Fix by following the same pattern of the other comparisons in
ntfs::set_used_sectors() which checks if index is less than the output
length.

References:
[1] std::string::find
    http://www.cplusplus.com/reference/string/string/find/
[2] std::string::npos
    http://www.cplusplus.com/reference/string/string/npos/
(Note that Glib::ustring is derived from std::string in the Standard C++
library and provides a compatible interface).

Bug 764658 - GParted crashes when reading NTFS usage when there is no
             /dev/PTN entry
2016-04-07 09:56:00 -06:00
Mike Fleetwood 2bb78cf8dc Limit FAT32 maximum volume size to 2 TiB
GParted is allowing creation of a FAT32 formatted partition of any size.
However with a 512 byte sector size the maximum volume size of a FAT32
file system is reported to be 2 TiB.
* Wikipedia: File Allocation Table / FAT32
  https://en.wikipedia.org/wiki/File_Allocation_Table#FAT32
  "The boot sector uses a 32-bit field for the sector count, limiting
  the FAT32 volume size to 2 TB for a sector size of 512 bytes and 16 TB
  for a sector size of 4,096 bytes."
* Microsoft: Default cluster size for NTFS, FAT, and exFAT / Default
  cluster sizes for FAT32
  https://support.microsoft.com/en-us/kb/140365

Trying to create a FAT32 file system in a partition larger than 2 TiB
results in unallocated space being left after the file system.

Nuances:
[1] Larger sector sizes allow larger maximum volume sizes up to 16 TiB
    with 4096 byte sectors.
[2] mkdosfs/mkfs.fat has an -S SECTOR_SIZE option which allows changing
    the "logical" sector size of the file system allowing the maximum
    volume to be proportionally increased.
[3] mkfs.fat appears to have an signed overflow bug when the size of the
    partition is larger than maximum signed 32-bit integer of logical(?)
    sectors.  (2 TiB for a sector size of 512 bytes).  It reports the
    partition size as minus size and creates a 1 TiB file system.

GParted wants a single maximum file system size and the code is not
ready for a differing maximum file system size for different sector
sizes.

In fat16::create() could specify larger "logical" sector sizes to
mkfs.fat when the partition is larger than 2 TiB to allow maximum volume
size to be increased further.  However that will take a lot of cross
platform testing to ensure that all sorts of devices support "logical"
sector sizes other than 512 bytes on devices with a hardware sector size
of 512 bytes.  This is too much effort.

Therefore implement a single FAT32 maximum volume size of 2 TiB.

Bug 763896 - GParted not restricting creation of FAT32 volume to maximum
             size of 2 TiB
2016-03-19 10:38:36 -06:00
Mike Fleetwood 1358a5f4fe Use a single progress bar for the internal block copy operation (#762367)
As part of the internal block copy operation 5 initial ranges of blocks
are copied using different block sizes to determine the fastest.  Then
the remainder is copied using the fastest block size.  Each of these
copies reports progress independently, so during the benchmarking phase
the progress bar flashes 5 times as it goes from 0 to 100% in a fraction
of a second, before showing the progress of the remainder.

This looks bad, so report a single progress bar for all the ranges of
blocks copied in a single copy operation.

Already have variables done and length which track progress within each
copied range; and total_done which records amount copied in previous
ranges.  Just add total_length to allow overall progress to be reported.

Bug 762367 - Use a single progress bar for the whole of the internal
             copy operation
2016-02-23 10:41:20 -07:00
Mike Fleetwood 2f2280e3d5 Update internal block copy, total_done after last progress report (#762367)
Previously total_done was updated in copy_thread() after copying of the
blocks, but importantly before the last call to set_progress_info() to
update the progress bar.  Having total_done varying during the copy of a
single range of blocks, single call to copy_blocks::copy(), is an
impediment to being able to report a single progress bar across the
whole internal copy operation.

Move updating of total_done to copy() immediately after copy_thread()
completes.

Bug 762367 - Use a single progress bar for the whole of the internal
             copy operation
2016-02-23 10:41:19 -07:00
Mike Fleetwood 6d28a62077 Display progress of NTFS file system specific copy operation (#762366)
Copying of ntfs is performed using ntfsclone, which writes progress
indication to standard output like this:

    # ntfsclone -f /dev/sdb2 /dev/sdb1 2> /dev/null
    NTFS volume version: 3.1
    Cluster size       : 4096 bytes
    Current volume size: 21474832384 bytes (21475 MB)
    Current device size: 21474836480 bytes (21475 MB)
    Scanning volume ...
    100.00 percent completed
    Accounting clusters ...
    Space in use       : 1832 MB (8.5%)
    Cloning NTFS ...
    100.00 percent completed
    Syncing ...

Add ntfsclone progress tracker for ntfsclone command.  Deliberately
doesn't stop the progress bar.  See comment in ntfs::clone_progress()
for the explanation.

Bug 762366 - Add progress bar to NTFS file system specific copy method
2016-02-23 10:02:03 -07:00
Mike Fleetwood 822028b504 Always be explicit when emitting a signal by calling emit()
Mostly the code is explicit and calls the emit() method when emitting a
signal [1], like this:
    signal_name.emit();

However there are a few cases which use the function call operator on
the signal object [2], like this:
    signal_name();

The behaviour is identical [3] but it is preferred to be explicit that a
signal callback is being initiated, and it also makes them much easier
to search for too.

[1] List explicit emit() signal calls
        fgrep '.emit(' src/*.cc

[2] List function call operator emitted signals
        egrep "`sed -n '/sigc::signal/s/.*sigc::signal.*> *\([a-zA-Z_]*\).*/\1/p' include/*.h | tr '\n' '|' | sed 's/\(.*\).$/[^a-zA-Z_](\1)\\\(/'`" src/*.cc

[3] Quote from the libsigc++ Reference Manual, class sigc::signal
    https://developer.gnome.org/libsigc++/stable/classsigc_1_1signal7.html#ab37db0ecc788824d0baa3c301efc8dcd

        result_type sigc::signal<...>::operator()(...)

        Triggers the emission of the signal (see emit())
2016-02-12 09:09:57 -07:00
Mike Fleetwood 2a55c65876 Leave commands with progress bars shown in the applying dialog (#760709)
For non-progress tracked external commands the command being executed is
displayed in the Apply pending operations dialog, just below the top
pulsing progress bar.  However for progress tracked external commands
the description of the parent operation detail is displayed instead.

Example 1: non-progress tracked xfs check repair:

                                                               TreePath
    Check and repair file system (xfs) on /dev/sdc1            0
    + calibrate /dev/sdc1                                      0:0
    + check file system on /dev/sdc1 for errors and (if po...  0:1
      + xfs_repair -v /dev/sdc1                                0:1:0
        + [empty stdout]                                       0:1:0:0
        + [stderr]Phase 1 - find and verify superblock...      0:1:0:1

"xfs_repair -v /dev/sdc1" (TreePath 0:1:0) is shown because it is the
latest updated operation detail which is timed (set to status
executing).

Example 2: progress tracked ext4 copy using e2image:

                                                               TreePath
    Copy /dev/sdc2 to /dev/sdc3                                0
    + calibrate /dev/sdc2                                      0:0
    + check file system on /dev/sdc2 for errors and (if po...  0:1
    + set partition type on /dev/sdc3                          0:2
    + copy file system of /dev/sdc2 to /dev/sdc3               0:3
      + e2image -ra -p /dev/sdc2 /dev/sdc3                     0:3:0
        + [stdout]Scanning inodes...                           0:3:0:0
        + [stderr]e2image 1.42.9 (28-Dec-2013)...              0:3:0:1

"copy file system of /dev/sdc2 to /dev/sdc3" (TreePath 0:3) is shown
because that operation detail is also timed and it is being constantly
updated by the progress bar updates via it.

Change execute_command() to update the progress bar via the operation
detail it creates to hold the command being executed, instead of the
parent operation detail, to resolve the above.  Also replaces calling
operationdetail.get_last_child() throughout the method.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 075154b4e8 Simplify XFS copy specific code progress bar usage (#760709)
Remove starting and stopping the progress bar in xfs::copy().  The
progress bar will be automatically started in xfs::copy_progress()
callback when run_progressbar() is called; and automatically stopped in
FileSystem::execute_command() when it calls stop_progress() at the end.

Note that this will now not initialise the progress bar from zero
immediately that the XFS copy is started, but instead 0.5 seconds into
the copy when xfs::copy_progress() timed callback is called for the
first time.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 438b35aed9 Connect timed progress tracking callbacks inside execute_command() (#760709)
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
2016-02-12 09:09:57 -07:00
Mike Fleetwood e67bbe906f Remove the unnecessary signal_progress (#760709)
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
2016-02-12 09:09:57 -07:00
Mike Fleetwood c00927c23d Connect output progress tracking callbacks inside execute_command() (#760709)
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
2016-02-12 09:09:57 -07:00
Mike Fleetwood 27e30a570f Remove unused OperationDetail members (#760709)
Remove unused members: fraction and progress_text from the
OperationDetail class now that the ProgressBar class has superseded
their use.  This also allows removal of timer_global member from the
copy_blocks class.  Timer_global was only used to track the elapsed time
copying blocks and allow the remaining time to be estimated and written
into progress_text.  The ProgressBar class also does this itself
internally.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood b1313281bd Simplify use of the progress bar via OperationDetail (#760709)
Most of the file system specific command progress trackers followed this
pattern:

    void {CLASS}::{NAME}_progress( OperationDetail *operationdetail )
    {
            ProgressBar & progressbar = operationdetail->get_progressbar();
            // parse output for progress and target values
            if ( // have progress and target values )
            {
                    if ( ! progressbar.running() )
                            progressbar.start( target );
                    progressbar.update( progress );
                    operationdetail->signal_update( *operationdetail );
            }
            else if ( // found progress finished )
            {
                    if ( progressbar.running() )
                            progressbar.stop();
                    operationdetail->signal_update( *operationdetail );
            }
    }

That is a lot of repetition handling progress bar updates and
OperationDetail object update signalling.  Remove the need for direct
access to the single ProgressBar object and provide these two
OperationDetail methods instead:
    // Start and update in one
    run_progressbar( progress, target, optional text_mode );
    stop_progressbar();

Now the file system specific command progress trackers can become:

    void {CLASS}::{NAME}_progress( OperationDetail *operationdetail )
    {
            // parse output for progress and target values
            if ( // have progress and target values )
            {
                    operationdetail->run_progressbar( progress, target );
            }
            else if ( // found progress finished )
            {
                    operationdetail->stop_progressbar();
            }
    }

Make ProgressBar::get_progressbar() a private method to enforce use of
the new way to access the progress bar via the run_progress() and
stop_progressbar() methods.  Then make the Dialog_Progress a friend
class to OperationDetail so that the Apply pending operations dialog can
still access the single ProgressBar object for its querying needs.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 32622f4d57 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
2016-02-12 09:09:57 -07:00
Mike Fleetwood 965d88d197 Call any FS specific progress trackers for stderr updates too (#760709)
So far the signal_progress callback slot was only emitted when standard
output from the file system specific command was updated.  This was okay
as all the commands until now wrote their progress information to
stdout.  However e2image writes its progress information to stderr,
therefore also emit signal_progress when stderr is updated too.

This does mean that the file system specific *_progress() tracking
callbacks will be called when either of the OperationDetail objects
containing stdout or stderr are updated.  Therefore the trackers may be
called when there is no update to the stream from which it is parsing
the progress information.  This is not a problem as the tracker will
just update the progress bar with the same information it already has.
Also it won't happen much as only e2image is known to write to both
streams, and then only one line to stdout and the updated progress
information to stderr.  This is just an observation and not an issue
which needs coding around.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 324d99a172 Record file system block size where known (#760709)
Record the file system block size in the Partition object.  Only
implemented for file systems when set_used_sectors() method has already
parsed the value or can easily parse the value from the existing
executed command(s).

Needed for ext2/3/4 copies and moves performed using e2image so that
they can be tracked in bytes by the ProgressBar class as e2image reports
progress in file system block size units.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 809a7e0954 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
2016-02-12 09:09:57 -07:00
Mike Fleetwood b0bd465098 Fix formatting of negative time values (#760709)
... to display a negative sign before the hours, minutes and seconds.
Before:
    Utils::format_time(-1)   = "00:00:0-1"
    Utils::format_time(-119) = "00:0-1:0-59"
After:
    Utils::format_time(-1)   = "-00:00:01"
    Utils::format_time(-119) = "-00:01:59"

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 7049a8bc44 Fix rounding of negative numbers (#760709)
Utils::round() was doing +0.5 then truncate.  Correct for positive
values.  Wrong for negative values.
E.G.
    Utils::round(-1.4)
        = trunc(-1.4 + 0.5)
        = trunc(-0.9)
        = 0
Round of -1.4 is definitely not 0.  Fix this for negative values by
subtracting 0.5 then truncating.

Reference:
    How can I convert a floating-point value to an integer in C?
    https://www.cs.tut.fi/~jkorpela/round.html

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood af0ed90d49 Fix ntfs resize progress tracker matching spurious text (#760709)
When the ntfs resize operation had almost completed, percentage complete
was >= 99.9%, the progress tracker was passing 0.04 (4%) to the progress
bar.  After reading the next chunk of output from the ntfsresize command
the last line contained this text:
    "  4)  set the bootable flag for the partit"

End of the ntfsresize command output for context:
    Relocating needed data ...
    100.00 percent completed
    Updating $BadClust file ...
    Updating $Bitmap file ...
    Updating Boot record ...
    Syncing device ...
    Successfully resized NTFS on device '/dev/sdd4'.
    You can go on to shrink the device for example with Linux fdisk.
    IMPORTANT: When recreating the partition, make sure that you
      1)  create it at the same disk sector (use sector as the unit!)
      2)  create it with the same partition type (usually 7, HPFS/NTFS)
      3)  do not make it smaller than the new NTFS filesystem size
      4)  set the bootable flag for the partition if it existed before
    Otherwise you won't be able to access NTFS or can't boot from the disk!
    If you make a mistake and don't have a partition table backup then you
    can recover the partition table by TestDisk or Parted's rescue mode.

This was occurring because *scanf() can't actually report failure to
match fixed text after conversion of the last variable.  See code
comment in ntfs::resize_progress() for more details.  Fix by using
.find() instead to match the required "percent completed" explicit text
of the progress information when it appears on the last line.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:57 -07:00
Mike Fleetwood 9f7a38e6b3 Update ntfs resize progress tracker to use the new ProgressBar (#760709)
Adapt the ntfs resize progress tracker to use the new ProgressBar class.
Also make it track 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
2016-02-12 09:09:56 -07:00
Mike Fleetwood 97f836869f Update ext2 fsck progress tracker to use the new ProgressBar (#760709)
Adapt the ext2 fsck progress tracker to use the new ProgressBar class.
Also make it track when the text progress bar has completely 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
2016-02-12 09:09:56 -07:00
Mike Fleetwood ac949e3003 Update ext2 create progress tracker to use the new ProgressBar (#760709)
Adapt the ext2 create file system progress tracker to used the new
ProgressBar class.  Also make it track when the text progress indicator
completes 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
2016-02-12 09:09:56 -07:00
Mike Fleetwood 608060f82d Update ext2 resize progress tracker to use the new ProgressBar (#760709)
Adapt the ext2 resize progress tracker to the new ProgressBar class.
Also update the progress function to track when text progress bars have
completely 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
2016-02-12 09:09:56 -07:00
Mike Fleetwood b0d9d2de7e Display progress from the single ProgressBar in the GUI (#760709)
Change the Applying pending operations dialog so that it takes it source
of progress from the single ProgressBar object, rather than the fraction
value in every OperationDetail object.  Also remove ProgressBar
debugging now that it is being used to drive the UI.

NOTE:
This temporarily causes the existing file system specific progress bars
to not be shown because they still update via the fraction member in
each OperationDetail object, rather than the new ProgressBar.  This will
be corrected in following commits.

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:56 -07:00
Mike Fleetwood c3669c3a96 Add a single ProgressBar for all OperationDetail objects (#760709)
1) Multiple progress bars

The OperationDetail class contains member fraction which is used to feed
data to the current operation progress bar shown in the Applying pending
operations dialog.  Dialog_Progress::on_signal_update() gets called for
every updated OperationDetail object and depending on whether fraction
is > 0.0 or not, switches between showing a growing or pulsing progress
bar.  This leads to the conclusion that every OperationDetail object
currently being updated is effectively driving the single on screen
progress bar with different data.

The Copy_Blocks code is careful to update text and faction in a single
OperationDetail object and everything is good.  The on screen progress
bar is switched into growing mode and then grows to 100%.

Since external command output is updated in real time [1] there are two
OperationDetail objects, one for stdout and one for stderr, which are
updated whenever data is read from the relevant stream.  Also now that
progress is interpreted from some external command output [2][3][4] a
separate OperationDetail object is getting updated with the progress
fraction.  (Actually the grandparent OperationDetail of the ones
receiving stdout and stderr updates as used by the file system specific
*_progress() methods).  In the normal case of an external command
which is reporting it's progress two OperationDetails are constantly
being updated together, the OperationDetail object tracking stdout and
it's grandparent receiving progress fraction updates.  This causes the
the code in Dialog_Progress::on_signal_update() to constantly switch
between growing and pulsing progress bar mode.  The only reason this
doesn't flash the progress bar is because the stdout OperationDetail
object is updated first and before the 100 ms timeout fires to pulse the
bar, it's grandparent is updated with the new fraction to keep growing
the bar instead.

2) Common code

The Copy_Blocks code currently tracks the progress of blocks copied
against target amount, which it has to do anyway.  That information is
then used to generate the text and fraction to update into the
OperationDetail object and drive the on screen progress bar.  This same
level of tracking is wanted for the XFS and ext2/3/4 file system
specific copy methods.

Conclusion and solution

Having multiple sources of progress bar data is a problem and makes it
clear that there must be only one source of progress data.  Also some
code can be shared for tracking the amount of blocks copied and
generating the display.

Therefore have a single ProgressBar object which is used everywhere.

This commit

It just creates a single ProgressBar object which is available via all
OperationDetail objects and Copy_Blocks is updated accordingly.  Note
that the ProgressBar still contains debugging and that the GUI progress
bar of the current operation is still driven via the fraction member in
any OperationDetail object.

Referenced commits:

[1] 52a2a9b00a
    Reduce threading (#685740)

[2] ae434579e1
    Display progress for e2fsck (#467925)
[3] baea186138
    Display progress for mke2fs (#467925)
[4] 57b028bb8e
    Display progress during resize (#467925)

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:56 -07:00
Mike Fleetwood 0ca8ed7369 Write a generic progress bar class (#760709)
Write a generic progress bar class.  Has the following features:
* Has separate progress and target numbers, rather than a single
  completion fraction, to enable the the next feature.
* Optionally generates text reporting the amount of data copied using
  the progress and target numbers like this:
      "1.00 MiB of 16.00 MiB copied"
* After running for 5 seconds, also add estimated remaining time.
  (Waits to allow the data copying rate to settle down a little before
  estimating the remaining time).  Looks like this:
      "1.00 MiB of 16.00 MiB copied (00:01:59) remaining)"

The ProgressBar class is not driving the visual progress bar yet.  It
has just been added into the internal block copy algorithm and generates
debug messages showing the progress bar is operating correctly.
Debugging looks like this:

    DEBUG: ProgressBar::start(target=2.0636e+09, text_mode=PROGRESSBAR_TEXT_COPY_BYTES)
    DEBUG: ProgressBar::update(progress=1.30023e+08) m_fraction=0.0630081 m_text="124.00 MiB of 1.92 GiB copied"
    DEBUG: ProgressBar::update(progress=2.67387e+08) m_fraction=0.129573 m_text="255.00 MiB of 1.92 GiB copied"
    DEBUG: ProgressBar::update(progress=4.0475e+08) m_fraction=0.196138 m_text="386.00 MiB of 1.92 GiB copied"
    ...
    DEBUG: ProgressBar::update(progress=1.13351e+09) m_fraction=0.549289 m_text="1.06 GiB of 1.92 GiB copied (00:00:04 remaining)"
    DEBUG: ProgressBar::update(progress=1.26249e+09) m_fraction=0.611789 m_text="1.18 GiB of 1.92 GiB copied (00:00:04 remaining)"
    DEBUG: ProgressBar::update(progress=1.39041e+09) m_fraction=0.67378 m_text="1.29 GiB of 1.92 GiB copied (00:00:03 remaining)"
    ...
    DEBUG: ProgressBar::update(progress=1.97552e+09) m_fraction=0.957317 m_text="1.84 GiB of 1.92 GiB copied (00:00:00 remaining)"
    DEBUG: ProgressBar::update(progress=2.0636e+09) m_fraction=1 m_text="1.92 GiB of 1.92 GiB copied"
    DEBUG: ProgressBar::stop()

Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
             copy methods
2016-02-12 09:09:56 -07:00
Mike Fleetwood ee6dcf5a96 Simplify code in Display_Info() by making use of Glib::build_path()
Simplify code in Dialog_Partition_Info::Dialog_Info() which was open
coding concatenating together a vector of strings with a new line
between each.  Replace with Glib::build_path(), as used elsewhere in
this method and other code.
2016-01-29 13:41:41 -07:00
Mike Fleetwood 40c2cdda0b Prevent incorrect no usage values warning for luks/unknown (#760080)
Create and open a LUKS mapping but don't create any file system within.

    # cryptsetup luksFormat /dev/sdb5
    # cryptsetup luksOpen /dev/sdb5 sdb5_crypt

GParted was incorrectly reporting this warning:

    Unable to read the contents of this file system!
    Because of this some operations may be unavailable.
    The cause might be a missing software package.
    The following list of software packages is required for luks file
    system support:  dmsetup.

This is even though the usage figures for the on disk LUKS encryption
are fully known.  See luks::set_used_sectors().

This was occurring because derived PartitionLUKS::set_usage_known()
was checking usage figures for the outer LUKS and the inner encrypted
file system, unknown in this case.  Correct when displaying figures in
the UI, but not correct in GParted_Core::set_used_sectors() when only
checking the outer LUKS usage figures were set correctly.  Fix this.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood 974668104d Remove LUKS unsupported warning (#760080)
Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood ad4191475a Rename file system from "crypt-luks" to "luks" (#760080)
The name of the format is Linux Unified Key Setup, or just LUKS.
https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood 2d910494d3 Display messages for encrypted file systems (#760080)
At the moment any messages for an encrypted file system aren't shown,
only messages from the outer PartitionLUKS object are shown.  Also in
Win_GParted::activate_paste() the selected Partition object, possibly
a derived PartitionLUKS, is cloned and the messages cleared.

Therefore a set of accessor methods must be provided to query and modify
partition messages.  Messages will be stored in the Partition object to
which they are added and retrieved from all.  So in the case of a
derived PartitionLUKS they will be retrieved from the messages vector of
the PartitionLUKS object itself and the messages vector for the
encrypted file system it contains.

To replace code like this in GParted_Core:

    partition_temp->messages = messages;

We might naturally provide a set_messages() method which assigns the
messages vector and is used like this:

    partition_temp->set_messages( messages );

However on a PartitionLUKS object what should set_messages() do?  By the
name it will replace any existing messages in the PartitionLUKS object
itself, but what should happen to the messages for the contained
encrypted Partition object?  Should they be cleared or left alone?
Rather than implement set_messages() with unclear semantics implement
append_messages(), which in the PartitionLUKS object case will clearly
leave any messages for the contained encrypted Partition object alone.
Append_messages() is then used to add messages as the Partition or
PartitionLUKS objects when populating the data in GParted_Core.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood f91d7e19dd Add encryption section into the Information dialog (#760080)
For LUKS formatted partitions add an encryption section into the
Information dialog and display the type of encryption, path, UUID and
status of the encryption.

The file system section continues to display appropriate file system
details, including the partition graphic with the file system specific
border colour and correct usage.  The details will either be of a plain
file system, an encrypted file system, or nothing when there is no open
dm-crypt mapping, leaving the encrypted file system inaccessible.
Should there be LUKS encryption directly within LUKS encryption then the
details of the inner encryption will be displayed in the file system
section.  However this configuration will not be further supported by
GParted.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood cb24aa4be1 Display usage of encrypted file systems (#760080)
There is already the set of methods in the Partition class to report the
file system usage.  Virtualise them and provide PartitionLUKS specific
implementations to calculate the usage of a file system wrapped in LUKS
encryption.

See the ascii art and comment in PartitionLUKS.cc for the details of
those calculations.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood 38a790d745 Display the label of encrypted file systems (#760080)
LUKS headers don't provide any concept of label.  Also there is already
the method Partition::get_filesystem_label() for getting the *file
system* label, so virtualise it and provide an appropriate
implementation to get the label of an encrypted file system represented
within a derived PartitionLUKS object.  This causes the label to be
displayed correctly in the main window.

It also happens to display the encrypted file system label in the
Information dialog for a LUKS formatted partition.  However the whole
Information dialog will be addressed differently in a following commit.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood b45af51a92 Display GUI column Mount Point correctly for encrypted file systems (#760080)
For open dm-crypt mappings get the Mount Point value from the encrypted
file system Partition object.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood a58e85d193 Display encrypted file system colour correctly in the disk graphic (#760080)
In the main window disk graphic, when there is an open dm-crypt mapping,
display the colour of the encrypted file system.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood cb3cc505ce Display "[Encrypted] FSTYPE" in the File System column (#760080)
In the File System column in the GUI, when there is an open dm-crypt
mapping, display the colour square for the encrypted file system within
and the text as "[Encrypted] FSTYPE".  For closed mappings nothing can
be known about the encrypted file system within so continue to display a
purple square and the text "[Encrypted]".

Looks like:

    Partition        | File System
      ...
      /dev/sdb3        # ext4
    v /dev/sdb4    *   # extended
        /dev/sdb5      # [Encrypted]
        /dev/sdb6  *   # [Encrypted] unknown
        /dev/sdb7  *   # [Encrypted] ext4

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:41 -07:00
Mike Fleetwood 6e294dda05 Remove Partition::color member (#760080)
Partition object represents a region of a disk and the file system
within.  GParted always displays the colour base of the type of the file
system.  Therefore remove the color member and always look it up from
the type of the file system as needed.

This makes one less member that will need virtual accessor methods with
different handling in the derived PartitionLUKS class.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood c9a2986fb9 Populate encrypted Partition member inside PartitionLUKS (#760080)
When there exists an open dm-crypt mapping, populate the encrypted
Partition object representing the encrypted file system.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 99ff0c7628 Add PartitionLUKS class and create objects (#760080)
Absolute minimum implementation of a PartitionLUKS class which can be
constructed, polymorphically copied and destroyed.  Contains an
"encrypted" member of type Partition to represent the encrypted file
system within the LUKS format.

Create PartitionLUKS objects instead of base Partition objects when a
LUKS formatted partition is found.  Only the base Partition object
member values have been populated, and the "encrypted" member remains
blank at this point.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 9fee0c57ea Refactor set_used_sectors() to be called per partition (#760080)
This is the equivalent change as made to set_mountpoints() in an earlier
commit.  Change GParted_Core::set_used_sectors() from being called with
a vector of partitions and processing them all to being called per
partition.  This is in preparation for calling set_used_sectors() on a
single Partition object inside a PartitionLUKS object.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood e9b893b4cb Populate active LUKS mountpoints with /dev/mapper/NAME entry (#760080)
Populate the canonical device name, /dev/mapper/NAME, used to access the
encrypted file system into the mount points of the Partition object.
This is the equivalent of what is already done for the Volume Group name
and SWRaid Array device.

This does get displayed in the Mount Point column in the main window,
which isn't wanted.  However the data will be needed when displaying
details of the encryption mapping in the Information dialog.  Both will
be dealt with in following commits.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 1b731b93d7 Refactor set_mountpoints() to be called per partition (#760080)
Previously GParted_Core::set_mountpoints() was called with a vector of
partitions and processed them all.  Now make set_mountpoints() process a
single partition and push the calls to it down one level from
set_devices_thread() into set_device_partitions() and
set_device_one_partition().  This is in preparation for having an
encrypted file system represented as a Partition object inside a
PartitionLUKS object and needing to call set_mountpoints() for the inner
single Partition object.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 132091269c Implement demand loading of LUKS_Info cache (#760080)
Only load the LUKS_Info cache of active dm-crypt mappings when the first
LUKS partition is encountered.  Not needed from a performance point of
view as the longest that I have ever seen "dmsetup table --target crypt"
take to run is 0.05 seconds.  Just means that the dmsetup command is
only run when there are LUKS partitions and the information is needed.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 317114ffcb Populate LUKS partition usage (#760080)
Populate the used, unused and unallocated figures in the Partition
object for a LUKS formatted partition.  See comment in
luks::set_used_sectors() for the rational of what is used, unused and
unallocated.

As that rational mentions, a LUKS header does not store the size of the
encrypted data and is assumed to extend to the end of the partition by
the tools which start the mapping.

An underlying block device of 128 MiB (131072 KiB).
    # sfdisk -s /dev/sde
    131072

An active LUKS mapping at offset 2 MiB (4096 512-byte sectors) and
length 126 MiB (129024 KiB, 258048 512-byte sectors).
    # sfdisk -s /dev/mapper/sde_crypt
    129024
    # cryptsetup status sde_crypt
    /dev/mapper/sde_crypt is active.
      type:  LUKS1
      cipher:  aes-cbc-essiv:sha256
      keysize: 256 bits
      device:  /dev/sde
      offset:  4096 sectors
      size:    258048 sectors
      mode:    read/write

No size/length reported when dumping the LUKS header, just (payload)
offset.
    # cryptsetup luksDump /dev/sde
    LUKS header information for /dev/sde

    Version:        1
    Cipher name:    aes
    Cipher mode:    cbc-essiv:sha256
    Hash spec:      sha1
    Payload offset: 4096
    MK bits:        256
    MK digest:      7f fb ba 40 7e ba e4 3b 2f c6 d0 93 7b f7 05 49 7b 72 d4 ad
    MK salt:        4a 5b 54 f9 7b 67 af 6e ef 16 31 0a fe d9 7e 5f
                    c3 66 dc 8a ed e0 07 f4 45 c3 7c 1a 8d 7d ac f4
    MK iterations:  37750
    UUID:           0a337705-434a-4994-a842-5b4351cb3778
    ...

Shrink the LUKS mapping to 64 MiB (65536 KiB, 131072 512-byte sectors).
    # cryptsetup resize --size 131072 sde_crypt
    # sfdisk -s /dev/mapper/sde_crypt
    65536
    # cryptsetup status sde_crypt
    /dev/mapper/sde_crypt is active.
      type:  LUKS1
      cipher:  aes-cbc-essiv:sha256
      keysize: 256 bits
      device:  /dev/sde
      offset:  4096 sectors
      size:    131072 sectors
      mode:    read/write

Stop and start the LUKS mapping.
    # cryptsetup luksClose sde_crypt
    # cryptsetup luksOpen /dev/sde sde_crypt

The size of the LUKS mapping is back to 126 MiB (129024 KiB, 258048
512-byte sectors), extending to the end of the partition.
    # sfdisk -s /dev/mapper/sde_crypt
    129024
    # cryptsetup status sde_crypt
    /dev/mapper/sde_crypt is active.
      type:  LUKS1
      cipher:  aes-cbc-essiv:sha256
      keysize: 256 bits
      device:  /dev/sde
      offset:  4096 sectors
      size:    258048 sectors
      mode:    read/write

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 317e444056 Add loading of LUKS mapping offset and length (#760080)
Also load the starting offset and length of the active dm-crypt mapping
into the LUKS_Info module from the dmsetup output.  This provides the
location and size of the encrypted data within the underlying block
device.

Note that dmsetup reports in units of 512 bytes sectors [1], the GParted
LUKS_Info module uses bytes and GParted Partition objects work in device
sector size units.  However the actual sector size of a dm-crypt mapping
[2] is the same as that of the underlying block device [3].

    # modprobe scsi_debug dev_size_mb=128 sector_size=4096
    # fgrep scsi_debug /sys/block/*/device/model
    /sys/block/sdd/device/model:scsi_debug
    # parted /dev/sde print
    Error: /dev/sde: unrecognised disk label
    Model: Linux scsi_debug (scsi)
    Disk /dev/sde: 134MB
[3] Sector size (logical/physical): 4096B/4096B
    Partition Table: unknown

    # cryptsetup luksFormat /dev/sde
    # cryptsetup luksOpen /dev/sde sde_crypt
    # parted /dev/mapper/sde_crypt print
    Error: /dev/mapper/sde_crypt: unrecognised disk label
    Model: Linux device-mapper (crypt) (dm)
    Disk /dev/mapper/sde_crypt: 132MB
[2] Sector size (logical/physical): 4096B/4096B
    Partition Table: unknown

    # cryptsetup status sde_crypt
    /dev/mapper/sde_crypt is active.
      type:  LUKS1
      cipher:  aes-cbc-essiv:sha256
      keysize: 256 bits
      device:  /dev/sde
      offset:  4096 sectors
      size:    258048 sectors
      mode:    read/write
    # dmsetup table --target crypt
    ...
    sde_crypt: 0 258048 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:64 4096

[1] Both cryptsetup and dmsetup report the offset as 4096 and the size/
length as 258048.  128 MiB / (4096+258048) = 512 byte units, even on a
4096 byte sector size device.

Update debugging of LUKS to this:

    # ./gpartedbin
    ======================
    libparted : 2.4
    ======================
    DEBUG: /dev/sdb5: LUKS closed
    DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt, offset=2097152, length=534773760
    /dev/sde: unrecognised disk label
    DEBUG: /dev/sde: LUKS open mapping /dev/mapper/sde_crypt, offset=2097152, length=132120576

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood ae57f3cd4e Prevent Mount/Umount operation being available for LUKS (#760080)
The code currently allows attempting to mount and unmount a LUKS
partition.  It is nonsense to directly try to mount and unmount a LUKS
partition and obviously doesn't work.  For read-only LUKS support there
is no need to attempt to apply this to the encrypted file system within.
Therefore prevent these operations for LUKS partitions.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood e86e7b91b2 Prevent crypt-luks appearing in the Create New dialog and Format menu (#760080)
This patchset is adding read-only LUKS support.  Creation of LUKS is
planned to be a tick box adding encryption in the Create New Partition
dialog.  Therefore remove the greyed out crypt-luks entry in the Create
New Partition dialog and the Format menu.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 070d734e57 Add busy detection of LUKS mapping (#760080)
Provide a minimal implementation of a luks file system class which only
does busy detection.

NOTE:
For now, read-only LUKS support, a LUKS partition will be busy when a
dm-crypt mapping exists.  Later when read-write LUKS support is added
GParted will need to look at the busy status of the encrypted file
system within the open LUKS partition and map LUKS partition busy status
to encryption being open or closed.

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood b77a6be76b Add initial loading of LUKS mapping details (#760080)
Load basic details of active Device-mapper encryption mappings from the
kernel.  Use dmsetup active targets.

    # cryptsetup luksFormat /dev/sdb5
    # cryptsetup luksFormat /dev/sdb6
    # cryptsetup luksOpen /dev/sdb6 sdb6_crypt
    # ls -l /dev/mapper/sdb6_crypt /dev/dm-0
    lrwxrwxrwx. 1 root root 7 Nov 15 09:03 /dev/mapper/sdb6_crypt -> ../dm-0
    brw-rw----. 1 root disk 253, 0 Nov 15 09:03 /dev/dm-0
    # ls -l /dev/sdb6
    brw-rw----. 1 root disk 8, 22 Nov 15 09:02 /dev/sdb6
    # dmsetup table --target crypt
    sdb6_crypt: 0 1044480 crypt aes-cbc-essiv:sha256 0000000000000000000000000000000000000000000000000000000000000000 0 8:22 4096

So far just load the mapping name and underlying block device reference
(path or major, minor pair).

Note that all supported kernels appear to report the underlying block
device as major, minor pair in the dmsetup output.  Underlying block
device paths are added to the cache when found during a search to avoid
stat(2) call on subsequent searches for the same path.

Prints debugging to show results, like this:

    # ./gpartedbin
    ======================
    libparted : 2.4
    ======================
    DEBUG: /dev/sdb5: LUKS closed
    DEBUG: /dev/sdb6: LUKS open mapping /dev/mapper/sdb6_crypt

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood 1b55dfad5b Move DEV_MAPPER_PATH from DMRaid.h to Utils.h (#760080)
Renamed from DEV_MAP_PATH to DEV_MAPPER_PATH.  Moved so that the
constant is logically intended for use outside of the DMRaid class.

Also specifically make the string constant have external linkage, rather
than the default internal (static) linkage for constants, so that there
is only one copy of the variable in the program, rather than one copy in
each compilation unit which included DMRaid.h.  Namely DMRaid.cc and
GParted_Core.cc.

References:
[1] Proper way to do const std::string in a header file?
    http://stackoverflow.com/questions/10201880/proper-way-to-do-const-stdstring-in-a-header-file
[2] What is external linkage and internal linkage in C++
    http://stackoverflow.com/questions/1358400/what-is-external-linkage-and-internal-linkage-in-c/1358796#1358796

Bug 760080 - Implement read-only LUKS support
2016-01-29 13:41:40 -07:00
Mike Fleetwood cd64d6503b Remove unused Partition(path) constructor
History:

1) The constructor was added by commit:

    6d8b169e73
    2006-03-14 21:37:47
    changed the way devices and partitions store their devicepaths.  Instead of

2) Removed from most of the file system specific ::Copy() methods by
   commit:

    ad9f2126e7
    2006-03-19 15:30:20
    fixed issues with copying (see also #335004) cleanups + added FIXME added

3) Removed from GParted_Core::copy() method by commit:

    7bb7e8a84f
    2006-05-23 22:17:34
    Use ped_device_read and ped_device_write instead of 'dd' to copy

4) Finally removed from the last place in xfs::Copy() method by commit:

    e414b71b73
    2012-01-11 19:49:13
    Update xfs resize and copy to use new helper functions

The Partition(path) constructor is no longer used.  Remove.
2016-01-26 10:11:36 -07:00
Mike Fleetwood 24fa553385 Remove unnecessary sector_size parameter from Get_New_Partition methods
The sector_size parameter is unnecessary as the value can be retrieved
from the sector size of the selected Partition object on which the
create new, copy & paste or resize/move operation is being performed.

For the create new and resize/move operations it is trivial as the
existing unallocated or in use Partition object on which the operation
is being perform already contains the correct sector size.  For the copy
& paste operation, which can copy across disk devices of different
sector sizes, we merely have to use the sector size of the existing
selected (destination) Partition object rather than copied (source)
Partition object.  Hence these relevant lines in the new code:

    Dialog_Partition_Copy::set_data(selected_partition, copied_partition)
        new_partition = copied_partition.clone();
        ...
        new_partition->sector_size = selected_partition.sector_size;
2016-01-26 10:11:35 -07:00
Mike Fleetwood 3b3d8e44b6 Stop relying on specific values of PED_PARTITION_* enum
The expressions used in the call to Set() were comparing
lp_partition->type to 0 for the type parameter and passing it as a bool
for the inside_extended parameter.  Libparted lp_partition->type is
actually an enumeration.  The code was only working because of the
specific values assigned to the symbolic names, PED_PARTITION_NORMAL = 0
and PED_PARTITION_EXTENDED is non-zero (true).

Make the code use the symbolic names and not depend on the actual
enumeration values, which should be considered changeable and private to
libparted.
2016-01-26 10:11:35 -07:00
Mike Fleetwood 7870a92b80 Add FILESYSTEM_MAP[FS_UNALLOCATED] entry
When displaying an unallocated partition
Win_GParted::set_valid_operations() calls GParted_Core::get_fs() with
parameter FS_UNALLOCATED.

Before this change, get_fs() would fail to find file system capabilities
set for FS_UNALLOCATED and construct a not supported capabilities set
and return that.

Afterwards, find_supported_filesystems() creates a not supported
capabilities set from the NULL pointer for FS_UNALLOCATED and adds this
entry into the FILESYSTEMS vector.  Then get_fs() finds that not
supported capabilities set for FS_UNALLOCATED in the FILESYSTEMS vector
and returns that.

This makes no functional difference.  It just seems right as other
unsupported but used file system types have entries in FILESYSTEM_MAP.
2016-01-26 10:11:35 -07:00
Mike Fleetwood 1a4cefb960 Initialise all struct FS members
The struct FS constructor initialised every member *except* filesystem
and busy.  Then in *most* cases after declaring struct FS, assignments
followed like this:
    FS fs;
    fs.filesystem = FS_BTRFS;
    fs.busy       = FS::GPARTED;
But member busy wasn't always initialised.

Add initialisation of members filesystem and busy to the struct FS
constructor.  Specify optional parameter to the constructor to set the
filesystem member, or when left off filesystem is initialised to
FS_UNKNOWN.
2016-01-26 10:11:35 -07:00
Mike Fleetwood 49664f3ca3 Simplify GParted_Core::get_fs()
get_fs() used to work by (1) returning the supported capabilities of the
requested file system found in the FILESYSTEMS vector; (2) if not found
return the supported capabilities for file system FS_UNKNOWN; and (3)
if that wasn't found either, create a not supported capabilities set for
FS_UNKNOWN and return that.

This is more complicated that required.  Also the not supported
capabilities set, as created by struct FS() constructor, is the same as
that created in file_supported_filesystems() local variable fs_notsupp.

Simplify get_fs() just using a single not found code path returning a
not supported capabilities set.
2016-01-26 10:11:35 -07:00
Mike Fleetwood 320e166c03 Implement and use virtual Partition copy constructor clone() (#759726)
Final step for full polymorphic handling of Partition objects is to
implement a virtual copy constructor.  C++ doesn't directly support
virtual copy constructors, so instead use the virtual copy constructor
idiom [1].  (Just a virtual method called clone() which is implemented
in every polymorphic class and creates a clone of the current object and
returns a pointer to it).

Then replace all calls to the (monomorphic) Partition object copy
constructor throughout the code, except in the clone() implementation
itself, with calls to the new virtual clone() method "virtual copy
constructor".

Also have to make the Partition destructor virtual too [2][3] so that
the derived class destructor is called when deleting using a base class
pointer.  C++ supports this directly.

[1] Wikibooks: More C++ Idioms / Virtual Constructor
    https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor

[2] When to use virtual destructors?
    http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors

[3] Virtuality
    Guideline #4: A base class destructor should be either public and
    virtual, or protected and nonvirtual
    http://www.gotw.ca/publications/mill18.htm

Bug 759726 - Implement Partition object polymorphism

SQUASH: When first using pointers to Partition and calling delete
2016-01-26 10:11:35 -07:00
Mike Fleetwood 656e1709ff Replace all Partition object copy assignment (#759726)
Copy assignment of Partition objects is now only performed in a few
places in the Operation and OperationResizeMove classes when updating
the displayed PartitionVector.  (From Refresh_Visual() when each
operation is visually applied to the display_partitions vector; the
new_partition from the operation is copy assigned over the top of the
relevant existing partition in the display_partitions vector).

In general polymorphic copy assignment is complicated [1], and is now
unnecessary given the above limited use.  All that is needed is a way to
polymorphically replace one Partition object with another in a
PartitionVector.

First, prevent further use of Partition object copy assignment by
providing a private declaration and no implementation, so the compiler
enforces this.  Second implement and use PartitionVector method
replace_at() which replaces a pointer to one Partition object with
another at the specified index in the PartitionVector.

[1] The Assignment Operator Revisited
    [Section:] Virtual assignment
    http://icu-project.org/docs/papers/cpp_report/the_assignment_operator_revisited.html

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 4a6cbcd0f1 Use pointer to Partition in Dialog_Base_Partition and derived classes (#759726)
Now use a pointer to the Partition object in Dialog_Base_Partition class
and derived classes, Dialog_Partition_{Copy,New,Resize_Move}.  This is
equivalent to how the Partition objects are managed in the Operation and
derived classes.

The Partition object is allocated and copy constructed in each derived
classes' set_data() method, called from each constructor and deallocated
in the destructors.  Considering the remaining Big 3, these classes are
never copy constructed or copy assigned so provide private definitions
and no implementations so the compiler enforces this.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 9f4e6909c5 Stop unnecessarily coping a Partition in Dialog_Rescue_Data (#759726)
The code in on_view_clicked() copy constructed a Partition object and
then in the following 3 lines only read a couple of public member
variables from the new copy.

Making a copy of the partition is unnecessary.  Change to just creating
a constant reference to the Partition instead.

(It would also be an impediment to polymorphically using Partition
objects, except for the fact that gpart doesn't recognise LUKS
signatures so will never have to create a PartitionLUKS object).

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 4d8578646c Change methods to use Partition pointers locally (#759726)
A number of methods in GParted_Core and Win_GParted were using local
Partition objects.  Change them into pointers so that Partition object
polymorphism can be implemented.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood ea8ab702f7 Change copied_partition into a pointer (#759726)
Change Win_GParted::copied_partition from Partition object which is
copied by value into a pointer to a Partition object object which is
allocated, copy constructed and deleted.  Required as part of the
polymorphic implementation of Partitions.

As before when managing the lifetime of pointers to objects in a class
the Big 3 of destructor, copy constructor and copy assignment operator
need to be considered.  A destructor is added to finally delete
copied_partition.  A single Win_GParted object is only ever created and
destroyed in main().  The class is never copy constructed or copy
assigned.  Make the compiler enforce this with private declarations and
no implementations.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood b516b1093c Use pointers to Partitions in Operation classes (#759726)
Operation classes now internally use pointers to Partition objects and
take on management of their lifetimes.  As before, with the
PartitionVector class, when storing pointers in a class the Big 3 of
destructor, copy constructor and copy assignment operator also have to
be considered.

First, all the Partition objects are allocated in the derived Operation*
class parameterised constructors and freed in the associated
destructors.  However the Operation classes are never copy constructed
or copy assigned; they are only ever created and destroyed.  Only
pointers to the derived Operations are copied into the vector of pending
operations.  Therefore the copy construtor and copy assignment operator
aren't needed.  To enforce this provide inaccessible private
declarations without any implementation so that the compiler will
enforce this [1][2].

This example code fragment:
 1  OperationCheck o1( device, partition );
 2  OperationCheck o2 = o1;
 3  o2 = o1;
Does these OperationCheck calls:
 1  Implemented parameterised construtor,
 2  Disallowed copy constructor,
 3  Disallowed copy assignment

Trying to compile the above code would fail with errors like these:
    ../include/OperationCheck.h: In member function 'void GParted::Win_GParted::activate_check()':
    ../include/OperationCheck.h:36:2: error: 'GParted::OperationCheck::OperationCheck(const GParted::OperationCheck&)' is private
      OperationCheck( const OperationCheck & src );              // Not implemented copy constructor
      ^
    test.cc:2:21: error: within this context
      OperationCheck o2 = o1;
                          ^

    ../include/OperationCheck.h:37:19: error: 'GParted::OperationCheck& GParted::OperationCheck::operator=(const GParted::OperationCheck&)' is private
      OperationCheck & operator=( const OperationCheck & rhs );  // Not implemented copy assignment operator
                       ^
    test.cc:3:4: error: within this context
      o2 = o1;
         ^

[1] Disable copy constructor
    http://stackoverflow.com/questions/6077143/disable-copy-constructor
[2] Disable compiler-generated copy-assignment operator [duplicate]
    http://stackoverflow.com/questions/7823845/disable-compiler-generated-copy-assignment-operator

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 6fd37c0745 Protect partition members within Operation classes (#759726)
The Operation classes contain partition objects which are copied by
value.  Need to replace these with pointers to Partition objects instead
and manage their lifetimes so that they can be used polymorphically.

First step is to protect the partition members partition_new,
partition_original, and for OperationCopy class only, partition_copied
within the Operation classes and provide accessor methods.

get_partition_new() and get_partition_original() accessors are
implemented in the Operation base class so all derived classes get an
implementation.  get_partition_new() is also virtual so that
OperationCheck and OperationDelete can override the implementation and
assert that they don't use partition_new.  get_partition_copied() is
provided for the OperationCopy class only so can only be accessed via an
OperationCopy type variable.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 504a2d8393 Remove copy constructing add item methods from PartitionVector (#759726)
Remove PartitionVector push_back() and insert() methods which copy
construct Partitions objects into the vector.  All the code has already
been changed to dynamically allocate Partition objects and use the
adoption variants of these methods named, push_back_adopt() and
insert_adopt().  Remove the no longer used methods.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood f6b45a0429 Use Partition pointer adoption everywhere when adding items into a PartitionVector (#759726)
Replace all the current code which uses push_back() and insert() of a
local Partition object and gets it copy constructed into a
PartitionVector.  Instead allocate a Partition object on the heap and
adopt a pointer into the PartitionVector using push_back_adopt() and
insert_adopt().

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 2a2a99b2bf Consolidate down to a single insert_unallocated() implementation (#759726)
GParted_Core and Operation classes both have an insert_unallocated()
method which do the same thing with very nearly identical code.  Both
methods insert unallocated partitions into the vector of partitions
within the specified range of sectors to fill in any gaps larger than
1 MiB.  The only difference was how the two methods got the device path;
the GParted_Core class method got it via a parameter and the Operation
class method got it by calling get_path() on its device member variable.
The GParted_Core insert_unallocated() method gets called during device
scanning and the Operation one gets called when constructing the visual
for a pending operation.

Consolidate down to a single insert_unallocated() implementation by
making the Operation class method call the GParted_Core class method.
Make the GParted_Core class method static and public so that it can be
called using the class name from outside the class.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood fdbd86f1ea Add adoption methods for adding items into a PartitionVector (#759726)
The current code uses push_back() and insert() to copy Partition objects
into the vector of pointers.  This has a few issues:
1) Unnecessary copying of Partition objects;
2) Hides the nature of the PartitionVector class as a manager of
   pointers to Partition objects by providing copy semantics to add
   items.  It is generally better to be explicit;
3) C++ doesn't provide polymorphic copy construction directly, but this
   is easily worked around by following the Virtual Constructor idiom
   [1], which would allow PartitionLUKS derived class objects to be
   copied into the vector.

Add push_back_adopt() and insert_adopt() methods which add a pointer to
a Partition object into the PartitionVector adopting ownership.

[1] Wikibooks: More C++ Idioms / Virtual Constructor
    https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Virtual_Constructor

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 06b8a3a14a Use pointers to Partitions in PartitionVector class (#759726)
The PartitionVector class is now internally using pointers to Partition
objects and taking on management of their lifetimes.  It therefore has
to implement the Big 3: destructor, copy constructor and copy assignment
operator [1][2].  This is because the implicitly-defined copy
constructor and assignment operator perform memberwise "shallow copying"
and the destructor does nothing.  This not correct for classes which
contain non-class types such as raw pointers.

The semantics of the interface still copies each Partition object into
the PartitionVector when they are added with push_back() and insert().

Note that a PartitionVector object is explicitly copy assigned in
Win_GParted::Refresh_Visual().  They are also implicitly copied when
(1) the implementing vector is resized larger to allow it to hold more
pointers to Partition objects than it previously had capacity for; and
(2) a Partition object is copied including the logicals PartitionVector
member.

[1] The rule of three/five/zero
    http://en.cppreference.com/w/cpp/language/rule_of_three
[2] Rule of Three
    https://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 48d898ebfd Include Partition.h header everywhere it's used
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.
2016-01-26 10:11:35 -07:00
Mike Fleetwood fae909897e Use PartitionVector class throughout the code (#759726)
Replace all occurrences of std::vector<Partition> with PartitionVector.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 81337141d7 Stop returning vector of partitions from Dialog_Rescue_Data class (#759726)
get_partitions() method was returning a vector of partitions.  However
the calling code only needed to know whether any partitions were found
or not.  Replace with found_partitions() method reporting the needed
boolean.

Now use of std::vector<Partition> partitions is hidden within the
Dialog_Rescue_Data class implementation.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:34 -07:00
Curtis Gedak 0ec726111d Update copyright year 2016-01-18 09:28:01 -07:00
Mike Fleetwood bfb6a3800d Fix displaying partition names also as file system labels in some cases (#759972)
GParted was also displaying the GPT partition names as the file system
labels for some type of file systems.

Create 2 empty partitions on a GPT partitioned disk and name them like
this.  Then create a hfsplus file system with an empty label.  (Actually
single space character but blkid treats it as empty.  Can't use GParted
for this because when no label is specified mkfs.hfsplus sets the label
to "untitled").

    # sgdisk -p /dev/sdb
    /dev/sdb: 4194304 sectors, 2.0 GiB
    Logical sector size: 512 bytes
    ...
    Number  Start (sector)    End (sector)  Size       Code  Name
       1            2048          526335   256.0 MiB   8300  empty partition
       2          526336         1050623   256.0 MiB   8300  hfsplus partition
    # mkfs.hfsplus -v " " /dev/sdb2

Even though only the GPT partition names are set to "SOMETHING
partition", GParted will display them as the file system labels too.
Also in the Information dialog for the empty partition a file system
UUID is displayed as well even though none exists.

Blkid output looks like this:

    # blkid -V
    blkid from util-linux 2.27.1  (libblkid 2.27.0, 02-Nov-2015)
    # blkid | grep /dev/sdb
    /dev/sdb1: PARTLABEL="empty partition" PARTUUID="bf3d2085-65b7-4ae6-97da-5ff968ad7d2c"
    /dev/sdb2: UUID="2c893037-ff76-38f2-9158-2352ef5dc8de" TYPE="hfsplus" PARTLABEL="hfsplus partition" PARTUUID="457e9c2b-e4f2-4235-833b-28208592aaac"

With blkid from util-linux >= 2.22, released September 2012, it is
including additional PARTLABEL and PARTUUID name and value pairs for
GPT partitions [1].  The FS_Info module regular expressions used to
match the file system LABEL and UUID names also happen to match these
new PARTLABEL and PARTUUID names too.  Hence this bug when GParted has
to fall back to using the FS_Info module to read the file system label,
when there is no working file system specific method.  Effects: exfat,
f2fs, hfs, hfsplus, ufs, unknown.

Fix by requiring all the regular expressions used to search the blkid
output to also match the space character in front of the name.

[1] Util-linux 2.22 Release Notes
    https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/Documentation/releases/v2.22-ReleaseNotes?h=v2.22

Bug 759972 - GParted displays partition names also as file system labels
             with new blkid for some file systems
2016-01-01 11:18:40 -07:00
Mike Fleetwood c249b7286d Fix temporary path name of new partitions (#759488)
In the UI new partitions were being named "unallocated" instead of
"New Partition #1", etc.  Also deleting a new partition not yet created
deletes all new partitions from the operation list because it matches
by name only and they were all named "unallocated".  Broken by this
recent commit:

    762cd1094a
    Return class member from Dialog_Partition_New::Get_New_Partition() (#757671)

Prior to this commit in the create new partition dialog code did these
relevant steps:
    Dialog_Partition_New::Get_New_Partition()
        Partition part_temp;
        ...
        part_temp.Set(..., "New Partition #%1", ...);

Create local Partition object using default constructor which calls
Partition::Reset() and clears the paths vector.  It then calls Set()
which appends the new name making the vector:
    paths = ["New Partition #%1"]

After the above commit the code did these steps:
    Dialog_Partition_New::Dialog_Partition_New(..., selected_partition, ...)
        set_data(..., selected_partition, ...);
            new_partition = selected_partition;

    Dialog_Partition_New::Get_New_Partition(...)
        new_partition.Set(..., "New Partition #%1", ...);

New_partition is copied from the selected unallocated partition in which
the new partition will be created.  So new_partition is now named
"unallocated".  Then the Set() call appends the new name making the
vector:
    paths = ["unallocated", "New Partition #%1"]

As get_path() returns the first name in the paths vector the path name
changed from "New Partition #%1" to "unallocated" causing this bug.

Fix by resetting the new_partition object to clear all vestiges of it
being a copy of the selected unallocated partition, Reset() call, before
then calling Set().  This then appends the new name to an empty vector
making it contain just the required new name:
    paths = ["New Partition #%1"]

Bug 759488 - Pending create partitions are all getting named
             "unallocated"
2015-12-18 09:35:28 -07:00
Phillip Susi ae434579e1 Display progress for e2fsck (#467925)
Parse output and update progress bar.

Bug 467925 - gparted: add progress bar during operation
2015-12-14 10:42:04 -07:00
Phillip Susi baea186138 Display progress for mke2fs (#467925)
Bug 467925 - gparted: add progress bar during operation
2015-12-14 10:42:04 -07:00
Phillip Susi 57b028bb8e Display progress during resize (#467925)
Capture and parse the progress reports of ntfsresize and resize2fs and
update the dialog progress bar.

Bug 467925 - gparted: add progress bar during operation
2015-12-14 10:42:04 -07:00
Curtis Gedak 5b0465e9a3 Make about dialog website link non-clickable (#758131)
To avoid security implications of invoking a web browser with root
privileges, make the about dialog website link into a non-clickable
label.

The set_website_label() method has been available since gtkmm 2.6.
https://developer.gnome.org/gtkmm/stable/classGtk_1_1AboutDialog.html#aa3d04115d068363be314414899703caa

Bug 758131 - Don't run GUI as root (Was: [wayland] gparted fails to
             start under wayland)
2015-11-20 17:49:19 +00:00
Mike Fleetwood 2c4df87a2c Return reference from Get_New_Partition() (#757671)
Return newly constructed partition object by reference rather than by
copy from the Copy, Resize/Move and New dialog classes.  This is another
case of stopping copying partition objects in preparation for using
polymorphic Partition objects.  In C++ polymorphism has to use pass by
pointer and reference and not pass by value, copying, to avoid object
slicing.

The returned reference to the partition is only valid until the dialog
object containing the new_partition member is destroyed.  This is okay
because in all three cases the returned referenced partition is copied
into a context with new lifetime expectations before the dialog object
is destroyed.

Case 1: GParted_Core::activate_paste()
    Referenced new_partition is copied in the OperationCopy constructor
    before the dialog object goes out of scope.

    Operation * operation = new OperationCopy( ...,
                                               dialog.Get_New_Partition( ... ),
                                               ... );

Case 2: GParted_Core::activate_new()
    Referenced new_partition is copied in the OperationCreate
    constructor before the dialog object goes out of scope.

    Operation * operation = new OperationCreate( ...,
                                                 dialog.Get_New_Partition( ... ) );

Case 3: GParted_Core::activate_resize()
    Temporary partition object is copied from the referenced
    new_partition before the dialog object goes out of scope.

    Partition part_temp = dialog.Get_New_Partition( ... );

Bug 757671 - Rework Dialog_Partition_New::Get_New_Partition() a bit
2015-11-11 10:12:18 -07:00
Mike Fleetwood 762cd1094a Return class member from Dialog_Partition_New::Get_New_Partition() (#757671)
Replace the use of local Partition variable with class member in
preparation for Dialog_Partition_New::Get_New_Partition() being changed
to return the new partition object by reference instead of by value.
    part_temp -> new_partition

Bug 757671 - Rework Dialog_Partition_New::Get_New_Partition() a bit
2015-11-11 10:12:18 -07:00
Mike Fleetwood c86b258475 Create unallocated space within new extended partition after aligning boundaries (#757671)
When creating a new extended partition, the unallocated space within it
was being created before adjusting the partition boundaries for
alignment reasons.  This must be wrong.  Move creation of the
unallocated space to after adjusting the partition boundaries for
alignment reasons.  First introduced by this commit:

    a30f991ca5
    Fix size reduced by 1 MiB when created after cylinder aligned partition

Also added a big FIXME comment explaining how further adjustments are
still made by snap_to_alignment() to the partition boundaries including
a test case where this too late adjustment causes overlapping boundaries
and apply to fail.

Bug 757671 - Rework Dialog_Partition_New::Get_New_Partition() a bit
2015-11-11 10:12:18 -07:00
Mike Fleetwood 451c2eac43 Rename parameter to selected_partition in Dialog_Partition_New methods (#757671)
This is just to make the parameter name in the Dialog_Partition_New
constructor and set_data() method match the name of the equivalent
parameter in the Dialog_Partition_Copy and Dialog_Partition_Resize_Move
classes.  (All three classes inherit from Dialog_Base_Partition and have
similar interfaces).

Bug 757671 - Rework Dialog_Partition_New::Get_New_Partition() a bit
2015-11-11 10:12:18 -07:00
Mike Fleetwood 6e97a63f49 Always use blkid file system detection before libparted (#757781)
Blkid recognises many more file system types and RAID member signatures
than libparted.  GParted already uses blkid detection instead of or
before libparted for whole disk devices [1] and for ext4 detection [2]
(only required with libparted < 1.9.0).  Also GParted could only use
blkid detection on non-512 byte sector devices [3] before libparted was
fixed in version 3.2 [4].  Blkid was documented as a mandatory
requirement from GParted 0.24.0 [5].

Util-linux package, of which blkid command is a part, is a core piece of
Linux software which is very actively maintained and used by lots of
other packages.  Parted package is much less active and has added
detection of fewer file systems and doesn't recognise any RAID members.

In cases of multiple signatures within a partition blkid and libparted
can report different results leading to confusion and issues for
GParted.  This was the primary reason for bug 688882 "Improve clearing
of file system signatures" and a number of other changes to GParted.
Also as the mount command links with libblkid it uses it's detection
when telling the kernel the type of a file system to be mounted.

There aren't any current issues with GParted's file system detection but
given the above argument, switch to using blkid before libparted for
file system detection.  Only falling back to libparted when blkid
doesn't report a result, notably for extended partitions.  Order of
information sources for detection is now:
 1) mdadm (for SWRaid members)
 2) blkid
 3) libparted
 4) GParted internal code

References:

[1] f8faee6377
    Avoid whole disk FAT being detected as MSDOS partition table (#743181)

[2] 533eb1bc03
    Added support for ext4 file systems

[3] 9e5e9f5627
    Enhance file system detection to use FS_Info method - blkid

[4] http://git.savannah.gnu.org/cgit/parted.git/commit/?id=80678bdd957cf49a9ccfc8b88ba3fb8b4c63fc12
    Fix filesystem detection on non 512 byte sectors

[5] 749a249571
    Document blkid command as a mandatory requirement (#753436)

Bug 757781 - Always use blkid file system detection before libparted
2015-11-10 09:44:36 -07:00
Mike Fleetwood 52183058ef Correct inclusion of Operation* headers in GParted_Core.cc
The GParted_Core code only interacts with derived Operation* objects
through the Operation base class interface and in one case the
OperationCopy class.  Therefore include Operation.h and OperationCopy.h
headers and no others.
2015-11-02 10:03:45 -07:00
Mike Fleetwood 32b5106aa1 Add clearing of ZFS labels
ZFS labels were not cleared by GParted when clearing old file system
signatures.

    # wget https://git.kernel.org/cgit/utils/util-linux/util-linux.git/plain/tests/ts/blkid/images-fs/zfs.img.bz2
    # bzip2 -dc zfs.img.bz2 > /dev/sdb1
    [In GParted format to cleared /dev/sdb1]
    # blkid /dev/sdb1
    /dev/sdb1: LABEL="tank" UUID="1782036546311300980" UUID_SUB="13179280127379850514" TYPE="zfs_member"

Update to also zero all 4 ZFS labels.

NOTE:
GParted now writes a little over 1 MiB when clearing old file system
signatures.  As this is performed in the main thread the UI is not able
to respond during this action.  Testing this on a range of USB flash
keys and hard drives found the slowest normal time to write this was
0.25 seconds, with an occasional outlier up to 2.8 seconds from a USB
flash key.  This is considered acceptable.
2015-11-02 10:03:45 -07:00
Mike Fleetwood eec78cd2b2 Stop over rounding up of signature zeroing lengths (#756829)
Following the previous commit "Add erasing of SWRaid metadata 0.90 and
1.0 super blocks (#756829)" signature zeroing specified to write 4 KiB
of zeros at position end - 64 KiB, aligned to 64 KiB.  Example operation
details from formatting a 1 GiB partition to cleared:

    Format /dev/sdb8 as cleared
    + calibrate /dev/sdb8
    + clear old file system signatures in /dev/sdb8
      + write 68.00 KiB of zeros as byte offset 0
      + wite 4.00 KiB of zeros at byte offset 67108864
      + wite 64.00 KiB of zeros at byte offset 1073676288
      + write 8.00 KiB of zeros at byte offset 1073733632
      + flush operating system cache of /dev/sdb

However it actually wrote 64 KiB.  This is because the rounding /
alignment was also applied to the zeroing length.  Before this commit
rounding / alignment was always less than or equal to the length so this
wasn't seen before.  Instead just apply device sector size rounding up
to the length.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood 743968ef68 Add clearing of SWRaid metadata 0.90 and 1.0 super blocks (#756829)
The super blocks for Linux Software RAID arrays using metadata types
0.90 and 1.0 are stored at the end of the partition and not currently
cleared by GParted.

Create a SWRaid array, stop it and format it to cleared using GParted.
The signature remains.

    # mdadm --create /dev/md1 --level=linear --raid-devices=1 --force --metadata=1.0 /dev/sdb1
    # mdadm --stop /dev/md1
    [In GParted format to cleared /dev/sdb1]
    # blkid /dev/sdb1
    /dev/sdb1: UUID="8ac947a7-063f-2266-5f2a-e5d178198139" UUID_SUB="49bd51d4-4c54-fb16-a45e-bd795f783f59" LABEL="rockover:1" TYPE="linux_raid_member"

As fixed in other cases before [1][2] it is necessary to clear all
signatures before formatting as a new file system to prevent recognition
issues.  For example now format the partition as a FAT32 file system.
Now there are two signatures and libparted reports one type and blkid
reports another.

    # mkdosfs -F 32 /dev/sdb1
    # blkid /dev/sdb1
    /dev/sdb1: UUID="8ac947a7-063f-2266-5f2a-e5d178198139" UUID_SUB="49bd51d4-4c54-fb16-a45e-bd795f783f59" LABEL="rockover:1" TYPE="linux_raid_member"
    # parted /dev/sdb print
    Model: ATA SAMSUNG SSD UM41 (scsi)
    Disk /dev/sdb: 8012MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type      File system  Flags
     1      1049kB  538MB   537MB   primary   fat32

(Deliberately avoided btrfs, ext2/3/4 and xfs as recent versions of
their mkfs tools clear other signatures first for the same reason).

[1] Bug 688882 - Improve clearing of file system signatures
[2] 3c75f3f5b1
    Use wipefs to clear old signatures before creating new file systems (#688882)

Update erase_filesystem_signatures() to also zero the necessary sectors
to clear SWRaid metadata 0.90 and 1.0 super blocks.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood a86f28bc32 Handle unusual case of missing mdadm but SWRaid arrays active (#756829)
If the installation is unusual / broken such that the mdadm command is
not found but there are active SWRaid arrays, provide a fallback with
some of the information.  In this case populate the cache with details
only available from /proc/mdstat.  Information will be limited to active
arrays only and their members.  No UUIDs or labels.  There will be no
information about inactive arrays and GParted will use it's normal
libparted and blkid identification for those devices and partitions.

As mdadm has gained the capability to manage Fake/BIOS RAID arrays they
also appear in /proc/mdstat when mdadm is used to start them.  Enhance
the parser of /proc/mdstat to only extract information for SWRaid arrays
with recognised metadata versions.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood bab1109d3d Ensure SWRaid_Info cache is loaded at least once (#756829)
Automatically load the cache of SWRaid information for the first time if
any of the querying methods are called before the first explicit
load_cache() call.  Means we can't accidentally use the class and
incorrectly find no SWRaid members when they do exist.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood f6c2f00df7 Populate member mount point with SWRaid array device (#756829)
Busy file systems are accessed via a mount point, LVM Physical Volumes
are activated via the Volume Group name and busy SWRaid members are
accessed via the array device, /dev entry.  Therefore choose to show the
array device in the mount point field for busy SWRaid members.

The kernel device name for an SWRaid array (without leading "/dev/") is
the same as used in /proc/mdstat and /proc/partitions.  Therefore the
array device (with leading "/dev/") displayed in GParted will match
between the mount point for busy SWRaid members and the array itself as
used in the device combo box.

    # cat /proc/mdstat
    Personalities : [raid1]
    md1 : active raid1 sda1[2] sdb1[3]
          524224 blocks super 1.0 [2/2] [UU]
    ...
    # cat /proc/partitions
    major minor  #blocks  name

       8        0   33554432 sda
       8        1     524288 sda1
    ...
       8       16   33554432 sdb
       8       17     524288 sdb1
    ...
       9        1     524224 md1
    ...

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood 7255c8af40 Use UUID and label of SWRaid arrays too (#756829)
In cases where blkid wrongly reports a file system instead of an SWRaid
member (sometimes confused by metadata 0.90/1.0 mirror array or old
version not recognising SWRaid members), the UUID and label are
obviously wrong too.  Therefore have to use the UUID and label returned
by the mdadm query command and never anything reported by blkid or any
file system specific command.

Example of blkid reporting the wrong type, UUID and label for /dev/sda1
and the correct values for /dev/sdb1:

    # blkid | egrep 'sd[ab]1'
    /dev/sda1: UUID="10ab5f7d-7d8a-4171-8b6a-5e973b402501" TYPE="ext4" LABEL="chimney-boot"
    /dev/sdb1: UUID="15224a42-c25b-bcd9-15db-60004e5fe53a" UUID_SUB="0a095e45-9360-1b17-0ad1-1fe369e22b98" LABEL="chimney:1" TYPE="linux_raid_member"

    # mdadm -E -s -v
    ARRAY /dev/md/1  level=raid1 metadata=1.0 num-devices=2 UUID=15224a42:c25bbcd9:15db6000:4e5fe53a name=chimney:1
       devices=/dev/sda1,/dev/sdb1
    ...
    ARRAY /dev/md127 level=raid1 num-devices=2 UUID=8dc7483c:d74ee0a8:b6a8dc3c:a57e43f8
       devices=/dev/sdb6,/dev/sda6
    ...

NOTES:
* In mdadm terminology the label is called the array name, hence name=
  parameter for array md/1 in the above output.
* Metadata 0.90 arrays don't support naming, hence the missing name=
  parameter for array md127 in the above output.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood 0ce9857380 Move busy detection of SWRaid members into the new module (#756829)
Add active attribute to the cache of SWRaid members.  Move parsing of
/proc/mdstat to discover busy SWRaid members into the cache loading
code.  New parsing code is a little different because it is finding all
members of active arrays rather than determining if a specific member is
active.

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood 5f02bcf463 Detect Linux SWRaid members by querying mdadm (#756829)
Detection of Linux SWRaid members currently fails in a number of cases:

1)  Arrays which use metadata type 0.90 or 1.0 store the super block at
    the end of the partition.  So file system signatures in at least
    linear and mirrored arrays occur at the same offsets in the
    underlying partitions.  As libparted only recognises file systems
    this is what is detected, rather than an SWRaid member.

    # mdadm -E -s -v
    ARRAY /dev/md/1  level=raid1 metadata=1.0 num-devices=2 UUID=15224a42:c25bbcd9:15db6000:4e5fe53a name=chimney:1
       devices=/dev/sda1,/dev/sdb1
    ...
    # wipefs /dev/sda1
    offset               type
    ----------------------------------------------------------------
    0x438                ext4   [filesystem]
                         LABEL: chimney-boot
                         UUID:  10ab5f7d-7d8a-4171-8b6a-5e973b402501

    0x1fffe000           linux_raid_member   [raid]
                         LABEL: chimney:1
                         UUID:  15224a42-c25b-bcd9-15db-60004e5fe53a

    # parted /dev/sda print
    Model: ATA VBOX HARDDISK (scsi)
    Disk /dev/sda: 34.4GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type      File system  Flags
     1      1049kB  538MB   537MB   primary   ext4         boot, raid
    ...

2)  Again with metadata type 0.90 or 1.0 arrays blkid may report the
    contained file system instead of an SWRaid member.  Have a single
    example of this configuration with a mirrored array containing the
    /boot file system.  Blkid reports one member as ext4 and the other as
    SWRaid!

    # blkid | egrep 'sd[ab]1'
    /dev/sda1: UUID="10ab5f7d-7d8a-4171-8b6a-5e973b402501" TYPE="ext4" LABEL="chimney-boot"
    /dev/sdb1: UUID="15224a42-c25b-bcd9-15db-60004e5fe53a" UUID_SUB="0a095e45-9360-1b17-0ad1-1fe369e22b98" LABEL="chimney:1" TYPE="linux_raid_member"

    Bypassing the blkid cache gets the correct result.

    # blkid -c /dev/null /dev/sda1
    /dev/sda1: UUID="15224a42-c25b-bcd9-15db-60004e5fe53a" UUID_SUB="d0460f90-d11a-e80a-ee1c-3d104dae7e5d" LABEL="chimney:1" TYPE="linux_raid_member"

    However this can't be used because if a user has a floppy configured
    in the BIOS but no floppy attached, GParted will wait for minutes as
    the kernel tries to access non-existent hardware on behalf of the
    blkid query.  See commit:
        18f863151c
        Fix long scan problem when BIOS floppy setting incorrect

3)  Old versions of blkid don't recognise SWRaid members at all so always
    report the file system when found.  Occurs with blkid v1.0 on
    RedHat / CentOS 5.

The only way I can see how to fix all these cases is to use the mdadm
command to query the configured arrays.  Then use this information for
first choice when detecting partition content, making the order: SWRaid
members, libparted, blkid and internal.

GParted shell wrapper already creates temporary blank udev rules to
prevent Linux Software RAID arrays being automatically started when
GParted refreshes its device information[1].  However an administrator
could manually stop or start arrays or change their configuration
between refreshes so GParted must load this information every refresh.
On my desktop with 4 internal hard drives and 3 testing Linux Software
RAID arrays, running mdadm adds between 0.20 and 0.30 seconds to the
device refresh time.

[1] a255abf343
    Prevent GParted starting stopped Linux Software RAID arrays (#709640)

Bug 756829 - SWRaid member detection enhancements
2015-11-02 10:03:45 -07:00
Mike Fleetwood 9d6ebb3dab Check usability of named device following a non-existent / invalid one (#756434)
When multiple devices are named on the command line and (after sorting
and removing duplicates) the device following a non-existent or invalid
one is not checked for usability [1].  In most situations this isn't
noticed as the device gets skipped at the "Searching ...  partitions"
step instead.  However as seen in bug 755495 and commit [2]
checking usability matters.

For example (on CentOS 6.5) a large sector disk device can be edited
when it follows a non-existent or invalid device named on the command
line:

    # modprobe scsi_debug dev_size_mb=128 sector_size=4096
    # fgrep scsi_debug /sys/block/*/device/model
    /sys/block/sdd/device/model:scsi_debug

    # ./gpartedbin /dev/does-not-exist /dev/sdd
    ======================
    libparted : 2.1
    ======================
    Could not stat device /dev/does-not-exist - No such file or directory.
    Device /dev/sdd has a logical sector size of 4096.  Not all parts of GNU Parted support this at the moment, and the working code is HIGHLY EXPERIMENTAL.

    /dev/sdd: unrecognised disk label

When erasing a device don't skip confirming the following device is
usable.

[1] Usable device as implemented by useable_device()
    Must not have a large sector size when GParted is built with an old
    version of libparted which doesn't support large sector sizes and
    must be able to read the first sector.

[2] 362b2db331
    Check disks named on the command line are safe to use too (#755495)

Bug 756434 - GParted dumps core when passing non-existent or invalid
             device on the command line
2015-10-15 09:39:49 -06:00
Mike Fleetwood bbf1a19cec Remove non-existent or invalid devices from those named (#756434)
A non-existent or invalid disk device named on the command line caused
two libparted dialogs to be displayed repeatedly on every refresh.  This
was because the device was only removed from the 'device_paths' vector
when it wasn't usable [1]; not when it didn't exist or was invalid, when
the libparted ped_device_get() call failed.  Fix this.

[1] Usable device as implemented by useable_device()
    Must not have a large sector size when GParted is built with an old
    version of libparted which doesn't support large sector sizes and
    must be able to read the first sector.

Bug 756434 - GParted dumps core when passing non-existent or invalid
             device on the command line
2015-10-15 09:39:19 -06:00
Mike Fleetwood 663807802f Prevent core dump with non-existent or invalid command line named device (#756434)
Naming a non-existent or invalid disk device on the command line causes
GParted to dump core.  Non-existent device looks like this:

    # ./gpartedbin /dev/does-not-exist
    ======================
    libparted : 2.4
    ======================
    Could not stat device /dev/does-not-exist - No such file or directory.
    Could not stat device /dev/does-not-exist - No such file or directory.
    Backtrace has 10 calls on stack:
      10: /lib64/libparted.so.0(ped_assert+0x31) [0x7fcfd10b3e61]
      9: /lib64/libparted.so.0(+0x3fdfc12a0c) [0x7fcfd10b4a0c]
      8: /home/mike/bin/gpartedbin-0.23.0-master-63-g23b5ba4() [0x455028]
      7: /home/mike/bin/gpartedbin-0.23.0-master-63-g23b5ba4() [0x455090]
      6: /home/mike/bin/gpartedbin-0.23.0-master-63-g23b5ba4() [0x4550d5]
      5: /home/mike/bin/gpartedbin-0.23.0-master-63-g23b5ba4() [0x46723f]
      4: /usr/lib64/libglibmm-2.4.so.1() [0x3ff5834a8d]
      3: /lib64/libglib-2.0.so.0() [0x3fe086a374]
      2: /lib64/libpthread.so.0() [0x3fdf407a51]
      1: /lib64/libc.so.6(clone+0x6d) [0x3fdf0e893d]
    Assertion (dev != NULL) at device.c:227 in function ped_device_open() failed.
    Aborted (core dumped)

And with an invalid device the output looks like this:

    # ./gpartedbin /dev/zero
    ======================
    libparted : 2.4
    ======================
    The device /dev/zero is so small that it cannot possibly store a file system or partition table.  Perhaps you selected the wrong device?
    Error fsyncing/closing /dev/zero: Invalid argument
    The device /dev/zero is so small that it cannot possibly store a file system or partition table.  Perhaps you selected the wrong device?
    Error fsyncing/closing /dev/zero: Invalid argument
    Backtrace has 10 calls on stack:
    ...
    [Same as above]

Bisected the cause to this commit from 2015-03-09 in GParted 0.22.0.  It
claimed to make no functional change.  That turned out not to be true.
    51ac4d5648
    Split get_device_and_disk() into two (#743181)

Fix by simply adding the missed if condition in get_device().

Bug 756434 - GParted dumps core when passing non-existent or invalid
             device on the command line
2015-10-15 09:38:49 -06:00