Commit Graph

1864 Commits

Author SHA1 Message Date
Mike Fleetwood fc5cc1d3b4 Stop trying to access device '/dev/mapper/No RAID disks' (#786031)
Running GParted on AltLinux with dmraid installed but with no configured
RAID arrays produces this error:
    # gparted
    ...
    Could not stat device /dev/mapper/No RAID disks - No such file or directory.

Most distributions use dmraid 1.0.0.rc16 which reports no raid disks
like this:
    # dmraid -sa -c
    no raid disks
    # echo $?
    1

However AltLinux had the slightly older version, dmraid 1.0.0.rc14,
which reported no raid disks like this:
    # dmraid -sa -c
    No RAID disks
    # echo $?
    0

So because dmraid 1.0.0.rc14 reported success, exit status 0, and the
"No RAID disks" message was not in lower case, that text was considered
a disk device in a DMRaid array.  Fix by checking for "no raid disks" in
any case.

Bug 786031 - Could not stat device /dev/mapper/No RAID disks - No such
             file or directory
2019-04-01 09:12:10 -06:00
Mike Fleetwood 97ce96da03 Pass constant parameter by reference to load_operations() (#788814)
It is common C++ practice to pass a constant object by reference to
avoid constructing a duplicate object for pass by value [1].

[1] How to pass objects to functions in C++?
    https://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c/2139254#2139254

Bug 788814 - gparted-0.30.0/include/HBoxOperations.h:37]: performance
             problem
2019-03-31 09:29:05 -06:00
Luca Bacci 56d8533add Always show menu images (!32)
There is a GtkSetting [1] that controls whether images in menus are
shown or not.  On some distributions / desktops it is enabled by default
and on others it is disabled by default.  To force show images in menus
set the 'always-show-image' property to true in Gtk::ImageMenuItems [2].

References:

[1] Gtk3 Reference Documentation - Settings/gtk-menu-images
    https://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-menu-images

[2] Gtk3 Reference Documentation - GtkImageMenuItem
    https://developer.gnome.org/gtk3/stable/GtkImageMenuItem.html#gtk-image-menu-item-set-always-show-image

Closes !32 - Always show menu images
2019-03-28 12:01:41 +00:00
Mike Fleetwood e55b3c8544 Replace String::ucompose() with Glibmm equivalent (#46)
Glibmm has implemented a ustring::compose() set of methods [1] since
Glibmm 2.16, circa 2008.  So replace String::ucompose().  Note that
GParted already requires glibmm >= 2.32 as set in configure.ac.

This commit just replaces all the method calls.  Edit created by:
    sed -i 's|String::ucompose *|Glib::ustring::compose|' src/*.cc

[1] Glibmm Reference Manual, Glib::ustring Class, compose() method
    https://developer.gnome.org/glibmm/2.32/classGlib_1_1ustring.html#a64ff7ac3d9e9899c2910f1d831f8d500

Closes #46 - Drop compose subdir
2019-03-27 16:45:22 +00:00
Mike Fleetwood 415f502036 Recognise contribution by Antoine Viallon 2019-03-26 08:08:10 +00:00
Mike Fleetwood c9f47403b8 Raise the maximum F2FS label size to 127 characters (!29)
Fix to make mkfs.f2fs properly handle labels longer than 16 characters
was included in f2fs-tools 1.2.0 [1].  The oldest supported
distributions now include this release:
  Distro             EOL        f2fs-tools
- Debian 8           2020-Jun   1.4.0
- RHEL / CentOS 7    2024-Jun   1.4.1
- SLES 12            2027-Oct   Unknown
- Ubuntu 14.04 LTS   2019-Apr   1.2.0

Note that on Ubuntu 14.04 LTS blkid from util-linux 2.20.1 is too old to
recognise F2FS file systems, as 2.23 is required for F2FS support [2].

mkfs.f2fs claims the maximum label length is less than 512 characters,
but actually accepts 512 characters.

    # label=`head -c 1024 < /dev/zero | tr '\0' 'A'`
    # mkfs.f2fs -l `echo -n "$label" | cut -c1-513` /dev/sdb10

            F2FS-tools: mkfs.f2fs Ver: 1.4.0 (2014-09-18)

    Error: Volume Label should be less than      512 characters

    Usage: mkfs.f2fs [options] device [sectors]
    [options]:
      -a heap-based allocation [default:1]
      -d debug level [default:0]
      -e [extension list] e.g. "mp3,gif,mov"
      -l label
      -o overprovision ratio [default:5]
      -s # of segments per section [default:1]
      -z # of sections per zone [default:1]
      -t 0: nodiscard, 1: discard [default:1]
    sectors: number of sectors. [default: determined by device size]
    # echo $?
    1

    # mkfs.f2fs -l `echo -n "$label" | cut -c1-512` /dev/sdb10

            F2FS-tools: mkfs.f2fs Ver: 1.4.0 (2014-09-18)

    Info: Label = AAAAAAAAAAAA...[trimmed from 512 "A"s]...AAAAAAAAAAAA
    Info: sector size = 512
    Info: total sectors = 1048576 (in 512bytes)
    Info: zone aligned segment0 blkaddr: 256
    Info: Discarding device
    Info: This device doesn't support TRIM
    Info: format successful
    # echo $?
    0

    # blkid -V
    blkid from util-linux 2.25.2  (libblkid 2.25.0, 24-Oct-2014)
    # blkid /dev/sdb
    /dev/sdb10: LABEL="AAAAAAAAAAAA...[only 127 "A"s]...AAAAAAAAAAAA"
    UUID="f47f3fdc-dd91-4616-bb6d-0d643a884265" TYPE="f2fs"
    PARTUUID="3bb4bef8-9494-4e82-8dda-5d8edd9c60d9"

As blkid only reports the first 127 characters and is the only command
used for reading the label of an F2FS file system, use this as the new
increased limit.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git/commit/?id=9799d6364dc93e1fd259d812d4a50ed984a6456b
    mkfs: handle labels longer than 16 characters

[2] https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.23/v2.23-ReleaseNotes
    "add Flash-Friendly File System (f2fs) support  [Alejandro Martinez
    Ruiz]"

Closes !29 - Enhance F2FS support
2019-03-26 08:08:10 +00:00
Mike Fleetwood afbf56c1c2 Drop fsck.f2fs -y option not available before f2fs-tools 1.10.0 (!29)
On CentOS 7 with f2fs-tools 1.4.1, checking an F2FS file system fails
like this:
    # fsck.f2fs -f -y -a /dev/sdb3
    Info: Force to fix corruption
    fsck.f2fs: invalid option -- 'y'
            Error: Unknown option ?

    Usage: fsck.f2fs [options] device
    [options]:
      -a check/fix potential corruption, reported by f2fs
      -d debug level default:0]
      -f check/fix entire partition
      -t show directory tree [-d -1]
    # echo $?
    1

Turns out that the '-y' option was not available until f2fs-tools 1.10.0
and is identical to the existing '-f' option anyway [1], which GParted
already uses.  Just remove the '-y' option passed to fsck.f2fs.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git/commit/?id=55ee9e7202f84168f868d863da8ed1c4995a0e6d
    fsck.f2fs: add -y for generic fsck

Closes !29 - Enhance F2FS support
2019-03-26 08:08:10 +00:00
Mike Fleetwood 66a20ae9fa Handle missing FS size information before f2fs-tools 1.5.0 (!29)
Before this commit [1] first included in f2fs-tools 1.5.0, dump.f2fs
didn't report the total space used by the file system.  This causes F2FS
file system usage not be reported on older distributions, including
RHEL/CentOS 7 and Debian 8.

On CentOS 7:
    # rpm -q f2fs-tools
    f2fs-tools-1.4.1-2.el7.nux.x86_64
    # dump.f2fs -d 1 /dev/sdb3 | egrep 'sector size =|total.*sectors ='
    Info: sector size = 512
    Info: total sectors = 2097152 (in 512 bytes)

On Fedora 28:
    # rpm -q f2fs-tools
    f2f2-tools-1.10.0-1.fc28.x86_64
    # dump.f2fs -d 1 /dev/sdb2 | egrep -a 'sector size =|total.*sectors ='
    Info: sector size = 512
    Info: total sectors = 3145728 (1536 MB)
    Info: total FS sectors = 2621440 (1280 MB)

"total sectors" reports the size of the partition.
"total FS sectors" reports the size of the file system.

Cope with the file system size being missing.  Pass -1 as the file
system size to partition.set_sector_usage() in this case.  Note that
this means GParted won't be able to detect and report unallocated space
within the partition when using f2fs-tools < 1.5.0.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git/commit/?id=fea6162a6db9af527648262d9fbb0335a0cc5460
    fsck.f2fs: show total sectors consumed by filesystem

Closes !29 - Enhance F2FS support
2019-03-26 08:08:10 +00:00
Mike Fleetwood c74ad52046 Make F2FS usage parsing handle NULs in dump.f2fs output (!29)
On Fedora 28 with f2fs-tools 1.10.0, dump.f2fs is producing NUL
characters in it's output and this completely breaks the parsing code in
f2fs::set_used_sectors().  Glib::Regex, as used by
Utils::regexp_label(), just doesn't match any text after the first NUL
character from the output.

    # dump.f2fs -d 1 /dev/sdb1
    Info: Debug level = 1
    Info: [/dev/sdb1] Disk Model: VBOX HARDDISK   1.0 ^@^@^@^@^@^@^@^...
    Info: Segments per section = 1
    Info: Sections per zone = 1
    Info: sector size = 512
    Info: total sectors = 2097152 (1024 MB)
    ...

Grep thinks the output is binary too:

    # dump.f2fs -d 1 /dev/sdb1 | \
    > egrep 'valid_block_count|user_block_count|log_blocksize|sector size =|total FS sectors ='
    Binary file (standard input) matches

    # dump.f2fs -d 1 /dev/sdb1 | \
    > egrep --text 'valid_block_count|user_block_count|log_blocksize|sector size =|total FS sectors ='
    Info: sector size = 512
    log_blocksize                           [0x       c : 12]
    Info: total FS sectors = 2097152 (1024 MB)
    user_block_count                        [0x   36400 : 222208]
    valid_block_count                       [0x       2 : 2]

Re-write set_used_sectors() using string find() and sscanf() to be
similar to how a number of the other set_used_sectors() are written for
other file systems.

Closes !29 - Enhance F2FS support
2019-03-26 08:08:10 +00:00
Antoine Viallon e550509781 Enhance F2FS support (!29)
- Adds reading of file system usage
- Adds resize (grow) support
- Adds verify support

Closes !29 - Enhance F2FS support
2019-03-26 08:08:10 +00:00
Mike Fleetwood 45fd146fd0 Go back to symbolic label widget alignment constants
Now that GParted requires Gtk3 there is no need to use floating point
numbers for compatibility with Gtk <= 2.22.  Replace with symbolic
alignment constants.

Relevant commit history:

*   6efa623401
    Add optional yalign argument to Utils::mk_label() method

*   be2689ad25
    Stop using deprecated widget alignment enumerators (#652044)
2019-03-23 11:13:30 -06:00
Mike Fleetwood 0b5cfd3496 Stop checking for 'btrfs filesystem label' support (!26)
btrfs-progs 3.12 includes 'btrfs filesystem label /dev/PTN NEWLABEL'
functionality so stop checking for this before enabling setting the
label.

    $ btrfs version
    Btrfs v3.12
    $ btrfs filesystem label --help
    usage: btrfs filesystem label [<device>|<mount_point>] [<newlabel>]

        Get or change the label of a filesystem

        With one argument, get the label of filesystem on <device>.
        If <newlabel> is passed, set the filesystem label on <newlabel>.

    $ echo $?
    0

Worst case scenario is that some how an old version of the btrfs command
is used which doesn't support the labelling functionality.  Then this
commit would change GParted from disallowing labelling of a btrfs, to
allowing it, but presumably it would fail with an error from the btrfs
command reporting so.  Arguably better from a support point of view.

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood 05d9919afa Replace use of deprecated btrfsck (!26)
In btrfs-progs 3.12, btrfsck is a hard link to the multi-tool btrfs
executable.  When run as 'btrfsck' it just implements 'btrfs check'
[1][2][3][4].

In btrfs-progs 3.14.2 the btrfsck man page is re-added as a symlink to
the btrfs-check man page and reports that btrfsck is deprecated [5].

Therefore replace use of 'btrfsck' with 'btrfs check'.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=fac45410e9a783c187ae83d993d3bf3350d05149
    Btrfs-progs: Rename btrfsck.c -> cmds-check.c

[2] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=5956f752c66d5259bbb17a2dd47ee8c8cc0e5f4f
    Btrfs-progs: add btrfsck functionality to btrfs

[3] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=d5d2046ae3b216af22a8a37c940f2412ba519b6e
    Btrfs-progs: add btrfsck name detection to btrfs

[4] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=e31f6172aa1d6ec5d562f56086819a0f4bc8a914
    btrfs-progs: build btrsfck to keep compatibility

[5] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=fddeecb7d424d5bb1a93a19a5e537057a4a7f597
    btrfs-progs: doc: link btrfsck to btrfs-check

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood f697d1e7ce Stop using removed btrfsctl (!26)
That commit [1] also removed btrfsctl from btrfs-progs 3.12 so also stop
using it as a fallback.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=f243fcd1b2aa55ffadfbcc032c66dedbee56e79e
    Removing btrfsctl, btrfs-vol, btrfs-show

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood 3607ede307 Finish removal of btrfs-show (!26)
Remove use of btrfs-show from everywhere else in the btrfs module.

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood 9c40b7fff0 Stop using removed btrfs-show to read the label (!26)
This commit [1] from btrfs-progs 3.12 removed the previously deprecated
programs btrfsctl and btrfs-show.  As btrfs-progs 3.12 is now the
minimum requirement, remove support for those removed programs.

This commit is just removing the use of btrfs-show as a fallback to read
the label.

Note that 'btrfs-show /dev/PTN' didn't distinguish between a label of
"none" and no label.  Hence the logic in btrfs::read_label() to do with
matching the label "none", or matching the label with or without single
quotes.  Unfortunately as identified in this commit [2]
'btrfs filesystem show /dev/PTN' is subject to the same issue, but only
when the file system is mounted and only for btrfs-progs 3.12.  This was
fixed by this commit [3] from btrfs-progs 3.14.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=f243fcd1b2aa55ffadfbcc032c66dedbee56e79e
    Removing btrfsctl, btrfs-vol, btrfs-show

[2] eca732fb0c
    Update parsing of btrfs filesystem show for the label (#733601)

[3] https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=a156b967ed9bd606afa8dc402451abcf07226c17
    btrfs-progs: make filesystem show by label work

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood d7dbbe4979 Remove old workaround for btrfs resizing on Linux < 3.2 (!26)
PATCHSET OVERVIEW

The oldest supported distributions have these versions of the Linux
kernel and btrfs-progs:
  Distro             EOL        kernel    btrfs-progs
- RHEL / CentOS 7    2024-Jun   3.10.0    4.9.1
- Ubuntu 14.04 LTS   2019-Apr   4.4.0     3.12
- Debian 8           2020-Jun   3.16.0    3.17
- SLES 12            2027-Oct   3.12.28   3.16

Making the oldest supported packages be kernel 3.10 and btrfs-progs 3.12
allows the btrfs support code to be simplified by removing backward
compatibility.

THIS CHANGE

Remove old workaround for ignoring the error when resizing a btrfs to
the same size on Linux kernel < 3.2.

Also now that only exit status 0 is considered successful from btrfs
resize, the EXEC_CHECK_STATUS flag to execute_command() can be used,
rather than having to separately call set_status() afterwards.

Relevant commit history:
*   11d044dba0
    Don't ignore any errors resizing btrfs on Linux >= 3.2 (#669389)
*   a580abbc30
    Use newer btrfs multi-tool control command first

Closes !26 - Remove support for btrfs-progs < 3.12
2019-03-15 16:01:50 +00:00
Mike Fleetwood 2aae7b0688 Set title of Resize/Move dialog for an extended partition (#44)
The title has never been set in this case, and defaulted to the name of
the executable 'gpartedbin'.  Fix this.

Closes #44 - Title not set in Resize/Move dialog for extended partitions
2019-03-14 17:08:50 +00:00
Mike Fleetwood 8effaf4f22 Initialise local POD 'launched' variable in show_help()
'launched' local POD (Plain Old Data) variable was left uninitialised,
but was set in both the try and catch clauses.  Best practice is to
initialise when defined, so do that instead.  Cosmetic change.
2019-03-01 16:46:56 +00:00
Mike Fleetwood f5e870d6c4 Rename Win_GParted method to show_help()
It is not creating a dialog (a pop-up window managed by GParted code
itself).  It is launching independent yelp program to display the help,
so remove the "_dialog" from the name to avoid any possible confusion.
2019-03-01 16:46:56 +00:00
Mike Fleetwood e3ae8a6f26 Restore specific error message on failure to launch yelp
Originally, if the yelp command was not installed, attempting to display
help produced an error dialog with this message:
    Failed to execute child process "yelp" (No such file or directory)

However since this commit during the Gtk 3 port [1] the error message
became this less useful one:
    Operation not supported

Two attempts are made to display the GParted Manual, first using
gtk_show_uri() and second by executing the yelp command directly.  Prior
to the aforementioned commit [1] both methods returned the failure
reason using the same 'error' variable.  Hence reported the message
"Failed to execute child process "yelp" ..." from the second attempt.
However that commit had to re-code the second method as part of the Gtk
3 port and use a different error returning mechanism, thus the use of
different variable 'e'.  But the dialog was left reporting the message
from the original 'error' variable, thus reporting "Operation not
supported" message from the first attempt using gtk_show_uri().

Fix by again displaying the message from the second failure into the
error dialog.  Also make it very clear there are two error returning
variables by naming them 'error1' and 'error2_msg'.

[1] 2953778a4c
    port-to-gtk3: Use Gdk::AppLaunchContext to launch yelp (#7)
2019-03-01 16:46:56 +00:00
Mike Fleetwood 5aca85e4ad Launch help from GParted using the new GNOME 3 help: prefix (!24)
Update GParted to specify the GParted Manual using the new GNOME 3 way
with the 'help:' prefix to avoid yelp reporting this error:
    Document Not Found
    The URI 'ghelp:gparted' does not point to a valid page.

Closes !24 - Port to GNOME 3 yelp-tools documentation infrastructure
2019-03-01 16:46:56 +00:00
Mike Fleetwood d0281a3264 Remove left behind commented #includes from fat16.cc
According to the GIT history the lines were added by this commit:
    8d808c0b62
    gparted-0.3.6 - code recreation from Source Forge

Looking at the SVN history this commit actually fleshed out the
implementations of fat16::get_label() and fat32::get_label() and added
the commented #includes:
    https://sourceforge.net/p/gparted/svn/118
    Added read label support for fat16 and fat32 using mtools mlabel command
    2008-02-12

Then this SVN commit moved the mtools temporary file handling code into
Utils.cc, leaving behind the commented #includes:
    https://sourceforge.net/p/gparted/svn/124
    Added MTools temporary file handling functions
    2008-02-19

Finally this commit removed fat32.cc by merging the code with fat16.cc:
    519af1a7c0
    Combine duplicate code for fat16/32

So remove the left behind commented #includes from fat16.cc.
2019-02-20 16:15:17 +00:00
Mike Fleetwood 24d9599f66 Enable online resizing of extended partitions (!23)
A forum user had a case where they wanted to grow their in use root,
ext4 file system.  GParted supports this, but the partition was a
logical partition inside an extended partition and GParted doesn't
support resizing an extended partition while any contained logical
partitions are busy.

Example layout:

    Partition              File System   Mount Point
    /dev/sdb1              ntfs
    /dev/sdb2     [busy]
        /dev/sdb5 [busy]   ext4          /
    unallocated            unallocated

So just allow extended partitions to be resized online when online
partition resizing is available via libparted.

NOTE:
The block device that the Linux kernel provides for an extended
partition just maps to the first 1 KiB of the extended partition where
the Extended Boot Record is stored, and does not include any of the
contained logical partitions.  Therefore no application can care that
the extended partition is resized while a logical partition is in use
because it can't use the extended partition block device to access any
data.

The on disk layout looks like this:

    # fdisk -l /dev/sdb

    Disk /dev/sdb: 8589 MB, 8589934592 bytes, 16777216 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk label type: dos
    Disk identifier: 0x0007650e

       Device Boot      Start         End      Blocks   Id  System
    /dev/sdb1            2048     1050623      524288    7  HPFS/NTFS/exFAT
    /dev/sdb2         1050624     2101247      525312    5  Extended
    /dev/sdb5         1052672     2101247      524288   83  Linux

    # parted /dev/sdb unit s print free
    Model: ATA VBOX HARDDISK (scsi)
    Disk /dev/sdb: 16777216s
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags:

    Number  Start     End        Size       Type      File system  Flags
            63s       2047s      1985s                Free Space
     1      2048s     1050623s   1048576s   primary   ntfs
     2      1050624s  2101247s   1050624s   extended
     5      1052672s  2101247s   1048576s   logical   ext4
            2101248s  16777215s  14675968s            Free Space

The kernel's partition sizes from /sys/block/sdb/sdb${N}/{start,size}
shows extended partition 2 has a size of only 2 sectors:

    # for N in 1 2 5
    > do
    > echo -e "/dev/sdb${N}\tstart=`cat /sys/block/sdb/sdb${N}/start`\tsize=`cat /sys/block/sdb/sdb${N}/size`"
    > done
    /dev/sdb1       start=2048      size=1048576
    /dev/sdb2       start=1050624   size=2
    /dev/sdb5       start=1052672   size=1048576

The EBR read from the whole of extended partition 2 block device:

    # hexdump -C /dev/sdb2
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 86  |................|
    000001c0  06 41 83 cb 09 82 00 08  00 00 00 00 10 00 00 00  |.A..............|
    000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
    00000200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00000400

Closes !23 - Enable online resizing of extended partitions
2019-02-20 16:15:17 +00:00
Luca Bacci c091c9f458 Prevent the legend text making the features dialog too wide (#7)
With the Gtk3 port the File System Support dialog has become too wide
because the legend text is no longer wrapped.  Set the max-width-chars
property to specify the natural size of the widget in terms of
characters [1].  It is converted to pixels using the average character
width in the current font.

Also use PACK_EXPAND_WIDGET when adding the label to the box so that if
the dialog is resized extra space is used to increase the size of this
child widget [2].

[1] GNOME HowDoI / Labels
    https://wiki.gnome.org/HowDoI/Labels

[2] Gtkmm 3.0 Enums and Flags, enum Gtk::PackOptions
    "PACK_EXPAND_WIDGET  Space is expanded, with extra space filled by
    increasing the child widget size."
    https://developer.gnome.org/gtkmm/3.0/group__gtkmmEnums.html#ga83727a1b6fed51566dfd5c8e58890dba

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci bf39c221b8 Enable display of progress bar text when applying operations (#7)
In Gtk2 progress bars show optional text superimposed over the bar.  In
Gtk3 the text is not displayed by default, so set the show-text property
to re-enable this [1].

Also note that since Gtk 3.14.0 the optional text is not superimposed
over the progress bar, but instead displayed just above it [2][3][4].

References:

[1] Gtkmm 3.0 Gtk::ProgressBar Class Reference, set_show_text()
    "Sets whether the progressbar will show text superimposed over the
    bar."
    https://developer.gnome.org/gtkmm/3.0/classGtk_1_1ProgressBar.html#a0bfa6042f5d4b3509967abc2d8af57fe

[2] Commit - Update the design for progress bars
    74405cc964

[3] Bug 748784 - GtkProgressBar text cannot be superimposed on the
    progress bar
    https://bugzilla.gnome.org/show_bug.cgi?id=748784

[4] Gtkmm 3.18 Gtk:ProgressBar Class Reference, set_show_text()
    "Set whether the progress bar will show text next to the bar."
    https://developer.gnome.org/gtkmm/3.18/classGtk_1_1ProgressBar.html#a0bfa6042f5d4b3509967abc2d8af57fe

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci d626a636d3 Ensure SpinButtons have space to display 7 digits (#7)
In Gtk2 the up and down buttons in a SpinButton were smaller leaving
space for 7 digits before scrolling the entry.  In Gtk3 the up and down
buttons are much larger leaving only space for 4 digits.  This occurs in
the SpinButtons in the Dialog_Base_Partition class as displayed in the
New Partition, Paste and Resize/Move dialogs.

Set width-chars property of all Gtk::SpinButtons to ensure 7 digits can
be displayed before scrolling the entry.

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 6aba93d8c0 Change Gtk::ProgressBar appearance by providing custom CSS (#7)
In Gtk3 the progress bar height is fixed and defined by the CSS theme in
use.  Changing the widget allocation size does nothing, it is always
rendered the same way.

In many themes, including Adwaita, the progressbar is very, very thin.
Provide custom CSS to specify a height of 8 pixels.

The CSS source string has to be differentiated for Gtk pre and post
3.20, because Gtk 3.20 introduced some breaking changes in the way CSS
is handled.

References:

[1] Migrating from GTK+ 2.x to GTK+ 3 - Parsing of custom resources
    https://developer.gnome.org/gtk3/stable/gtk-migrating-GtkStyleContext-parsing.html

[2] Gtk3 Reference Documentation - Changes in GTK+ 3.20
    https://developer.gnome.org/gtk3/stable/ch32s10.html

[3] Gnome/HowDoI - Custom Style
    https://wiki.gnome.org/HowDoI/CustomStyle

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 6c47561bf6 Change packing of pulsebar in statusbar (#7)
The pulsebar looks very small and needs to be widened.  The pulsebar is
packed inside the statusbar so that it displays activity text on the
left side and the pulsebar on the right side.  Ideally we want the space
to be evenly divided for the textual messages and for the pulsebar
activity indicator.

For this we just have to set the 'homogeneous' property to TRUE for the
statusbar (note that GtkStatusBar inherits from GtkBox).

Also vertically align the pulsebar to the center of the statusbar.  This
is achieved setting the 'valign' property to Gtk::ALIGN_CENTER for the
pulsebar widget.

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 892f5542a4 Work around Gtk3 Gtk-CRITICAL messages when closing some dialogs (#7)
There is a bug affecting Gtk+ 3.22.8 to 3.22.30 in which destroying a
GtkComboBox when it is not hidden results in this message:

    Gtk-CRITICAL **: gtk_widget_is_drawable: assertion 'GTK_IS_WIDGET (widget)' failed

This happens in GParted when some dialogs are closed, for example the
Create New Partition and Create Partition Table dialogs.  To work around
the issue we call Gtk::Dialog::hide() in the destructors of our dialog
classes.

The issue was fixed in Gtk 3.24.0.

 * Gtk 3.22.8 was released in February 2017.
 * Gtk 3.24.0 was released in September 2018.

References:

[1] Gtk Issue - GtkComboBox::private::popup_window can be NULL
    https://gitlab.gnome.org/GNOME/gtk/issues/125

[2] Gtk commit - combobox: popdown() the menu during unmap()
    7401794de6

[3] Gtk commit - Check for NULL priv->popup_window in
    gtk_combo_box_popdown()
    aa5d926c84

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 392bbba534 Work around Gtkmm3 issue where menu accelerators are not shown (#7)
There is a bug in Gtkmm3 when setting accelerator keys on a
Gtk::MenuItem, the accelerator keys work but are not displayed when the
menu is drawn.  This happens for Gtk::MenuItems, including derived
objects, that are constructed with a non-default constructor.

All non-default constructors of Gtk::MenuItem, and subclasses, work by
creating themselves a Gtk::AccelLabel and packing it inside the menu
item.  But in Gtk3 GtkMenuItem are created with a GtkAccelLabel already
packed in as a child and that accel label should be used instead.

To workaround the issue we only use the default constructor for
Gtk::MenuItem and subclasses.  This is easy to do because we only have
to change the wrappers in MenuHelpers.cc.

This bug affects Gtkmm version 3.0.0 to 3.22.2 and was fixed in
Gtkmm 3.22.3.

 * Gtkmm 3.0.0 was released in April 2011
 * Gtkmm 3.22.3 was released in November 2018

References:

[1] Bug Report on the Gtkmm mailing list
    https://mail.gnome.org/archives/gtkmm-list/2018-February/msg00006.html

[2] Commit - Gtk::MenuItem: Fix add_accel_label()
    e5c8c2df67

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 244f4bcd22 Simplify code using Gtk::Container::get_children() (#7)
GParted uses Gtk::Container::get_children().  In Gtkmm2
Gtk::Container::get_children() returns a Glibmm intermediate container
[1].  Gtkmm3 dropped the use of Glibmm intermediate containers in favour
of STL containers [2][3].

Now that Gtk::Container::get_children() directly returns a std::vector<>
simplify the code.

References:

[1] Gtkmm 2.24 Gtk::Container Class Reference
    "Glib::ListHandle<Widget*> Gtk::Container::get_children()"
    https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Container.html#acd2f9b9ac16ba96178d3f5169b07f4d0

[2] Gtkmm 3.0 Gtk::Container Class Reference
    "std::vector<Widget*> Gtk::Container::get_children()"
    https://developer.gnome.org/gtkmm/3.0/classGtk_1_1Container.html#a3a2111e255cb5b72bd91a3be087cff27

[1] Programming with gtkmm3 / Changes in gtkmm3
    "11. We now use std::vector in several methods instead of the
    intermediate *Handle types to make the API clearer."
    https://developer.gnome.org/gtkmm-tutorial/3.0/changes-gtkmm3.html.en

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 0078cf01cc port-to-gtk3: Block Gtk::TreeSelection changed handler on tree model clear (#7)
Now GParted compiles with Gtkmm3, but we get a failed assertion doing
the following:
 * Select a device with more than 1 partition
 * Select a partition
 * Activate 'Refresh Devices' (or do any operation that causes it, like
   mount/unmount etc.)

This is the failed assertion:
    **
    ERROR:Win_GParted.cc:1152:void GParted::Win_GParted::set_valid_operations(): assertion failed: (valid_display_partition_ptr( selected_partition_ptr ))
    Aborted (core dumped)

Where is the problem?

Win_GParted::Refresh_Visual() calls TreeView_Detail::load_partitions()
to clear and refill the treeview.

The problem is in GParted::TreeView_Detail::load_partitions() at
TreeView_Detail.cc:91:
    treestore_detail->clear();

This activates TreeView_Detail::on_selection_changed() which in turn
activates Win_GParted::on_partition_selected() passing an old, stale
pointer as an argument.  This triggers the failed assertion.

Why does this happen with Gtk3 and not with Gtk2?

First a bit of background of GtkTreeView:

What happens to the selection in a GtkTreeView when the selected row
is removed?

With Gtk2 the selection simply becomes empty, so nothing is selected
afterwards.  With Gtk3 this was changed [1] and selection moves to an
adjacent row.

gtk_tree_store_clear() removes rows one by one.  While removing rows the
selection changed signal is emitted.  With Gtk2 it is emitted only one
time, to indicate that selection has become empty.  With Gtk3 it is
instead emitted several times, each time indicating that selection has
moved to the adjacent row.

The handler TreeView_Detail::on_selection_changed() only takes action
when the selection is not empty.  So with Gtk3 it really takes action
and activates Win_GParted::on_partition_selected() with a pointer to old
data.

What's the purpose of TreeView_Detail::on_selection_changed()?

Its task is to update the selection in the drawing area above the
TreeViewDetail, the DrawingAreaVisualDisk, so that the selected
partition stays in sync on the two widgets.

Fix by blocking the signal handler during the treeview clear.

Reference:
[1] Commit - treeview: Handle the case where the cursor row gets deleted
    1a2932ba29

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 2953778a4c port-to-gtk3: Use Gdk::AppLaunchContext to launch yelp (#7)
gdk_spawn_command_line_on_screen() is not present in Gtk3.  The
documentation from Gtkmm 2.24 states [1]:

    gdk_spawn_command_line_on_screen has been deprecated since version
    2.24 and should not be used in newly-written code.  This function is
    being removed in 3.0.  Use either g_spawn_command_line_sync(),
    g_spawn_command_line_async() or GdkAppLaunchContext instead.

g_spawn_command_line_sync() and g_spawn_command_line_async() are screen
/ display agnostic, as such we would loose functionality.  There is a
workaround, which involves setting the DISPLAY environment variable [2],
but it's a weak solution (and I don't know if it works on backends
other than X11).

GdkAppLaunchContext is an implementation of GIO's GAppLaunchContext that
handles launching an application in a graphical context [3].  Therefore
use GdkAppLaunchContext and GIO's GAppInfo.

GdkAppLaunchContext was introduced in Gtk2 version 2.14.  The C++
wrapper Gdk::AppLaunchContext was introduced only in Gtkmm3 version 3.4
[4].  Bump the minimum required version of Gtkmm to 3.4.0 for this
requirement.

GAppInfo was introduced in GLib version 2.16.  The C++ wrapper
Gio::AppInfo was introduced in Giomm version 2.16.  Note that the
minimum required version for glibmm is already 2.32.

[1] GDK 2 Reference Manual, GdkScreen, gdk_spawn_on_screen()
    https://developer.gnome.org/gdk2/2.24/GdkScreen.html#gdk-spawn-on-screen

[2] Migrating from GTK+ 2.x to GTK+ 3 - "Use GIO for launching applications"
    https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.7

[3] GDK 3 Reference Manual - "Application launching"
    https://developer.gnome.org/gdk3/stable/gdk3-Application-launching.html

[4] Gtkmm 3.4 Gdk::AppLaunchContext Class Reference, Detailed Description
    https://developer.gnome.org/gtkmm/3.4/classGdk_1_1AppLaunchContext.html#details

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 202e6e9034 port-to-gtk3: Use Gtk::CellLayout::get_cells() (#7)
GParted uses Gtk::TreeViewColumn::get_cell_renderers().  This is not
present in Gtkmm3.  Now Gtk::TreeViewColumn inherits from
Gtk::CellLayout and we have to use Gtk::CellLayout::get_cells() instead.

GtkCellLayout was introduced in Gtk2 version 2.18 as the common
interface for containers of cell renderers.

The C++ wrapper Gtk::CellLayout was introduced in Gtkmm2 version 2.18,
but Gtk::TreeViewColumn was never made to inherit from Gtk::CellLayout
to avoid breaking the API / ABI.  That change was made for Gtkmm3.

This is an excerpt from gtkmm/treeviewcolumn.h header in Gtkmm2:
  // TODO: Should be deprecated, but we cannot derive from CellLayout
  // without breaking API and ABI.

  /** Returns a list of all the cell renderers in the column,
   * in no particular order.
   *
   * @return A list of Gtk::CellRenderers.
   */
  Glib::ListHandle<CellRenderer*> get_cell_renderers();

Replace Gtk::TreeViewColumn::get_cell_renderers() with base class
method Gtk::CellLayout::get_cells().

Reference:

[1] Commit - "Deprecate get_cell_renderers implementations"
    6abc52a29d

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 21d8ad218e port-to-gtk3: Use draw signal in the partition resizer (#7)
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.

Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.

This commit is specific to the drawing area in the Create new Partition
dialog and the Resize/Move dialog.

Reference:

[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
    https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 93b1425549 port-to-gtk3: Use draw signal in the partition visualizer (#7)
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.

Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.

This commit is specific to the drawing area contained in the main
application window (also called the DrawingAreaVisualDisk).

Reference:

[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
    https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 4c1fe3bf7a port-to-gtk3: Use draw signal in the partition info dialog (#7)
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.

Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.

This commit is specific to the drawing area in the Partition Info
dialog.

Reference:

[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
    https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci e3f77966c9 port-to-gtk3: Use Gtk::Widget::render_icon_pixbuf() (#7)
In Gtk3/C, gtk_widget_render_icon() was deprecated in Gtk 3.0 [1].  In
Gtkmm3/C++, Gtk::Widget::render_icon() was abruptly removed from Gtkmm
3.0 and replaced with Gtk::Widget::render_icon_pixbuf() [2].

Gtk::Widget::render_icon() [3] had an optional 3rd parameter which
GParted never used.  Replace with Gtk::Widget::render_icon_pixbuf() [4].

References:

[1] GTK+ 3 Reference Manual, GtkWidget
    https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-render-icon
    "gtk_widget_render_icon has been deprecated since version 3.0 and
    should not be used in newly-written code."

[2] Gtkmm 3.0.0 NEWS file
    "... Removed render_icon(), adding render_icon_pixbuf()."
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.0.0/NEWS#L187

[3] Gtkmm 2.24 Gtk::Widget Class Reference, render_icon()
    https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Widget.html#a91efd1b5aed7c184506ddd5721710584

[4] Gtkmm 3.0 Gtk::Widget Class Reference, render_icon_pixbuf()
    https://developer.gnome.org/gtkmm/3.0/classGtk_1_1Widget.html#a28bbbd0c1717e58343df56f7f422b106

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 5fb58f8877 port-to-gtk3: Use Gdk::Cursor via Glib::RefPtr<> (#7)
Starting from Gtkmm3 Gdk::Cursor objects cannot be constructed directly,
but instead you have to get a smart pointer to an instance by calling
the static member function Gdk::Cursor::create().

Gdk::Cursor::create() returns a Glib::RefPtr<Gdk::Cursor> object.

Gtkmm3 always uses Glib::RefPtr<Gdk::Cursor> in its interface and never
plain Gdk::Cursor.

Reference:

[1] Programming with gtkmm3, Changes in gtkmm3:
    https://developer.gnome.org/gtkmm-tutorial/3.24/changes-gtkmm3.html.en
    "... Gdk::Cursor are now used via Glib::RefPtr."

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 29a21a5a4c port-to-gtk3: Rework Gtk header includes (#7)
In Gtk3 individual headers cannot be included directly in application
code, only the header <gtk/gtk.h> can be included (with a few exceptions
for some platform specific headers).

This has always been considered good practice even for Gtk2, though was
not a hard requirement.

In Gtk3 this is enforced by preprocessor checks.  Failure to do so
yields a preprocessor error and compilation fails:

  "error: Only <gtk/gtk.h> can be included directly."

Change specific Gtk header includes to:

  #include <gtk/gtk.h>

References:

[1] Migrating from GTK+ 2.x to GTK+ 3 - "Do not include individual headers"
    https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.3

[2] Commit - "Remove all traces of GDK_PIXBUF/GTK_DISABLE_SINGLE_INCLUDES"
    5e29973773

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 05da10775c port-to-gtk3: Rework Gtkmm header includes (#7)
Now that we are compiling against Gtkmm3 there are missing declarations
of Gtkmm identifiers due to changes in Gtkmm internal header structure.

All we have to do is bring back the declarations by including the
appropriate headers where needed.

Add necessary Gtkmm header includes.

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 4b87839502 port-to-gtk3: Rework Glibmm header includes (#7)
Now that we are compiling against Gtkmm3 there are missing declarations
of Glibmm identifiers due to changes in Gtkmm internal header structure.

All we have to do is bring back the declarations by including the
appropriate headers where needed.

Add necessary Glibmm header includes.

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 5379352766 prepare-for-gtk3: Prepare for removal of Gtk::Widget::modify_fg() (#7)
The Gtk::Widget::modify_fs() API was removed in Gtkmm3 [1] and also
there is no direct replacement.  GParted uses this in one place.  So
instead use the C gtk_widget_modify_fg() version that is still present
in Gtk3.

This is just a temporary change to port GParted to Gtk3.  In future this
will be replaced as part of the switch from Gdk::Color to Gtk::RGBA,
since Gdk::Color was deprecated in Gtkmm 3.10 [2].

Reference:

[1] ee432e2190
    commit message "... Remove the modify_*() methods, ..."

[2] Gtkmm 3.10 Gdk::Color Class Reference
    https://developer.gnome.org/gtkmm/3.10/classGdk_1_1Color.html#details
        Deprecated:
        Use Gdk::RGBA instead.

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 0d73ff83d9 prepare-for-gtk3: Prepare for removal of Gtk::Menu_Helpers::MenuList (#7)
GParted uses Gtk::Menu_Helpers::MenuList helper class to access
individual menu items.  This helper class made it easy to navigate menu
items by index.

Gtk::Menu_Helpers::MenuList was removed in the switch from Gtkmm2 to
Gtkmm3 [1].  Instead, use a separate std::map<Gtk::MenuItem*> to keep
track of individual Gtk::MenuItem objects.

Reference:
[1] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
    c8e47b0db5

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci eb30c959a6 prepare-for-gtk3: Prepare for removal of Gtk::Menu_Helpers::Element (#7)
Gtk::Menu_Helpers::Element class and subclasses help in Gtk::MenuItem
widgets and also automate tasks like registering keyboard accelerators
when parented to a top-level window [1][2].

Gtk::Menu_Helpers::Element class and subclasses were removed in Gtkmm3
[3].  Provide compatible implementations under the namespace
GParted::Menu_Helpers.

References:

[1] gtkmm: Gtk::Menu_Helpers Namespace Reference
    https://developer.gnome.org/gtkmm/2.24/namespaceGtk_1_1Menu__Helpers.html

[2] gtkmm: Gtk::Menu_Helpers::Element Class Reference
    https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Menu__Helpers_1_1Element.html

[3] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
    c8e47b0db5

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci a44d548a3a prepare-for-gtk3: Replace deprecated GDK_<KeyName> constants (#7)
During the switch from Gtk2 to Gtk3 keyname constants were renamed from
GDK_<KeyName> to GDK_KEY_<KeyName> [1].  This was done to avoid name
clashes in gobject-introspection and language bindings.  The new
constant names were also backported to Gtk 2.22 [2].

Make use of the new constant names.

References:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "Replace GDK_<keyname> with GDK_KEY_<keyname>"
    https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html#id-1.6.3.3.6

[2] Commit - "gdk: Prefix keys with _KEY by default"
    750c81f43d

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Luca Bacci 38d9d92013 prepare-for-gtk3: Remove calls to Gtk::Dialog::set_has_separator() (#7)
Originally in Gtk2, by default, dialogs showed a horizontal separator
between the content area and the action area (buttons).  GParted
explicitly called Gtk::Dialog::set_has_separator(false) for all it's
dialogs to remove the separator.

In Gtk2/Gtkmm2 2.22, separators were deprecated [1].  In Gtk3/Gtkmm3
separators in dialogs were removed altogether, including all the related
APIs [2][3][4].  Therefore remove all calls.

References:
[1] Commit - "Document separator-related api in GtkDialog as deprecated"
    6f6650e6cf

[2] Commit - "Remove separators from dialogs"
    d433a60611

[3] GTK+ 3.0.0 NEWS file
    https://gitlab.gnome.org/GNOME/gtk/blob/3.0.0/NEWS#L779
    "
    Overview of Changed from GTK+ 2.90.6 to 2.90.7
    ==============================================

    * Various deprecated APIs have been removed:
    ...
    - GtkDialog separators, including the GtkDialog::has-separator
      property, including setter/getter, the GTK_DIALOG_NO_SEPARATOR
      flag and the GtkMessageDialog::use-separator style property
    "

[4] Gtkmm 3.0.0 NEWS file
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.0.0/NEWS#406
    "
    * Dialog:
    - Remove get/set_has_separator() and property.
    - Constructors: Remove use_separator parameters.
    "

Closes #7 - Port to Gtk3
2019-02-11 08:57:18 +00:00
Mike Fleetwood 80d6394684 Remove deprecated Glib::thread_init() (!22)
Use of Glib::thread_init() was deprecated in glibmm 2.32 [1].  The
oldest supported distributions have these versions:
    Debian 8           glibmm 2.42.0
    RHEL / CentOS 7    glibmm 2.56.0
    SLES 12            glibmm 2.38.1
    Ubuntu 14.04 LTS   glibmm 2.39.93

Checking further the glibmm 2.32 reference manual says this about
Glib::thread_init() [2]:
    Initializes the GLib thread system.

    Deprecated:
    Calling thread_init() is no longer necessary and no longer has any
    effect.

However only some of the glibmm example programs had Glib::thread_init()
removed, others had it replaced by Glib::init() [3].  Again the glibmm
2.32 reference manual says this about Glib::init() [4]:
    Initialize glibmm.

    You may call this more than once.  You do not need to call this if
    you are using Glib::MainLoop or Gtk::Main, because they call it for
    you.

GParted does call Gtk::Main and test_PipeCapture does call
Glib::MainLoop.  Therefore just raise the minimum version to glibmm 2.32
and remove both calls to Glib::thread_init().

[1] Glibmm 2.32 NEWS file
    https://gitlab.gnome.org/GNOME/glibmm/blob/2.32.0/NEWS#L207

[2] glibmm 2.32, glibmm: Glib Namespace Reference, Glib::thread_init()
    https://developer.gnome.org/glibmm/2.32/namespaceGlib.html#ab26d01c776801f1fff00753e97af4fc7

[3] glibmm commit "Avoid use of deprecates API in tests and examples."
    3e0fbb22c0

[4] glibmm 2.32, glibmm: Glib Namespace Reference, Glib::init()
    https://developer.gnome.org/glibmm/2.32/namespaceGlib.html#ac90aee10d0b90e3d8a96a86b5394f87b

Closes !22 - Increase minimums to libparted 2.2 and glibmm 2.32
2019-01-21 16:41:31 +00:00
Mike Fleetwood 8df975c7d1 Increase minimum required libparted to 2.2 (!22)
Raise the minimum required version of GNU Parted from 1.7.1 to 2.2,
released 2010-02-16 [1][2].  The oldest supported distributions, also
with gtkmm >= 2.24, since commit [3], are:
    Debian 8           parted 3.2
    RHEL / CentOS 7    parted 3.1
    SLES 12            parted 3.1
    Ubuntu 14.04 LTS   parted 2.3

Raising the minimum required version allows removal of optional code
associated with these definitions:
*   USE_LIBPARTED_LARGE_SECTOR_SUPPORT
    Fallback code reporting ignored device with logical sector size
    other than 512 bytes.
*   ENABLE_PT_REREAD_WORKAROUND
    Fallback code re-attempting to inform the kernel of partition
    changes.

[1] GNU Parted 2.2 release announcement
    http://lists.gnu.org/archive/html/info-gnu/2010-02/msg00016.html

[2] NEWS file from GNU Parted 2.2
    http://git.savannah.gnu.org/cgit/parted.git/tree/NEWS?h=v2.2

[3] 8b42bab1ee
    modern-gtk2: Require Gtkmm version 2.24 (!17)

Closes !22 - Increase minimums to libparted 2.2 and glibmm 2.32
2019-01-21 16:41:31 +00:00
Mike Fleetwood c421bcbff6 Strip unnecessary scope from GParted::STAT_* (!20)
The code inconsistently uses GParted:: scope in front of STAT_*.

    $ fgrep 'GParted::STAT_' src/*.cc | wc -l
    3
    $ egrep '[^:]STAT_' src/*.cc | wc -l
    41

GParted:: scope resolution is unnecessary as all the code is inside the
GParted scope, except for main().  So remove it.

Closes !20 - Minor namespace and scope operator tidy-ups
2018-11-26 17:56:32 +00:00
Mike Fleetwood 2bbe7fcc45 Strip unnecessary scope from GParted::TYPE_* (!20)
The code inconsistently uses GParted:: scope in front of TYPE_*.

    $ fgrep 'GParted::TYPE_' src/*.cc | wc -l
    35
    $ egrep '[^:]TYPE_' src/*.cc | wc -l
    83

GParted:: scope resolution is unnecessary as all the code is inside the
GParted scope, except for main().  So remove it.

Closes !20 - Minor namespace and scope operator tidy-ups
2018-11-26 17:56:32 +00:00
Mike Fleetwood e0b6d2c65b Strip unnecessary scope from GParted::FS_* (!20)
The code inconsistently uses GParted:: scope in front of FS_*.

    $ fgrep 'GParted::FS_' src/*.cc | wc -l
    41
    $ egrep '[^:]FS_' src/*.cc | wc -l
    441

GParted:: scope resolution is unnecessary as all the code is inside the
GParted namespace, except for main().  So remove it.

Closes !20 - Minor namespace and scope operator tidy-ups
2018-11-26 17:56:32 +00:00
Mike Fleetwood 7f23761964 Strip unnecessary scope from GParted::FS::* (!20)
The code inconsistency uses GParted::FS::* and FS::*.

    $ fgrep 'GParted::FS::' src/*.cc | wc -l
    97
    $ egrep '[^:]FS::' src/*.cc | wc -l
    152

GParted:: scope resolution is unnecessary as all the code is inside the
GParted namespace, except for main().  So remove it.

Closes !20 - Minor namespace and scope operator tidy-ups
2018-11-26 17:56:32 +00:00
Mike Fleetwood 2c10dd2caa Put Frame_Resizer_{Base,Extended} modules into GParted namespace (!20)
All the other modules are in the GParted namespace, except for main()
which has to be in the global namespace, so put these in the GParted
namespace too.

Closes !20 - Minor namespace and scope operator tidy-ups
2018-11-26 17:56:32 +00:00
Mike Fleetwood b9d3638a12 Fix false usage figures for busy SWRAID members (#27)
Create an active Linux Software RAID member which is larger than /dev
virtual file system and GParted will report the usage figure of the /dev
virtual file system for the SWRAID member.

    # df -h /dev
    Filesystem      Size  Used Avail Use% Mounted on
    devtmpfs        732M     0  732M   0% /dev
    # sgdisk -n 1:1M:+1G /dev/sdb
    # mdadm --create --verbose /dev/md1 --level=linear --raid-devices=1 --force /dev/sdb1
    mdadm: Defaulting to version 1.2 metadata
    mdadm: array /dev/md1 started.

GParted reports the usage of /dev/sdb1 as:
    Partition  Mount Point  Size     Used   Unused     Unallocated
    /dev/sdb1  /dev/md1     1.00GiB  0.00B  731.04MiB  292.96MiB

However GParted should have reported the usage as "---" for unknown
because it isn't coded to query the size of the SWRAID member within a
partition.

The fault has been bisected to this commit:
    Extend un/mounting and usage reporting to unsupported file systems (!13)
    95903efb1f

What happens for busy Linux Software RAID array members:
*   GParted_Core::is_busy()
    has custom code to identify busy members.
*   GParted_Core::set_mountpoints()
    has custom code to add the array device name as the "mount point" of
    the member.
*   GParted_Core::set_used_sectors()
    falls into the else not a supported file system (because SWRAID
    doesn't have a derived FileSystem implementation class).
*   GParted_Core::mounted_set_used_sectors()
    is called to get the file system usage of mounted, but unsupported
    file systems, such as UFS and any others.
*   Utils::get_mounted_filesystem_usage()
    is called which queries the kernel using statvfs() and gets the file
    system usage of the /dev virtual file system because the array
    device name will always start /dev.

Fix by ensuring that GParted only asks the kernel for the usage of paths
which it knows are mount points of mounted file systems.  (As read from
/proc/mounts and cached in the Mount_Info module).  Also rename the
method, by inserting "_fs", to mounted_fs_set_used_sectors() to remind
us that it is for mounted *file systems* only.

Closes #27 - GParted may report incorrect usage for SWRAID partitions
             instead of unknown

S
2018-11-19 16:43:29 +00:00
Mike Fleetwood 4b341c8dd9 Recognise contribution by Luca Bacci 2018-11-12 21:50:42 +00:00
Luca Bacci 2fad309601 modern-gtk2: Use Cairo for drawing the partition visualizer (!17)
Third commit in a series to convert Gdk::GC based drawing to Cairo based
drawing.  This specific commit makes the transition for the graphical
partition visualizer widget that is used in the main application window.

Closed !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 7fd39932a3 modern-gtk2: Use Cairo for drawing the partition info (!17)
Second commit in a series to convert Gdk::GC based drawing to Cairo
based drawing.  This specific commit makes the transition for the
graphical partition info widget that is used in the "Information about"
dialog.

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci d17d129044 modern-gtk2: Use Cairo for drawing the partition resizer (!17)
GdkGC has been deprecated in the underlying C / GTK+ 2.22 library.  It
is less clearly stated but Gdk::GC is also deprecated in C++ / gtkmm.
Cairo based rendering should be used instead.
https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html
https://gitlab.gnome.org/GNOME/gtk/blob/2.22.0/NEWS#L124
https://developer.gnome.org/gtkmm/2.24/classGdk_1_1GC.html

First commit in a series to convert Gdk::GC based drawing to Cairo based
drawing.  This specific commit makes the transition for the graphical
partition resizing widget that is used in the "Create New Partition",
"Paste" creating new partition and "Resize/Move" dialogs.

Cairo is not pixel based but instead uses a continuous coordinate space.
To draw in a pixel aligned way follow the guidance in the Cairo FAQ.
https://www.cairographics.org/FAQ/#sharp_lines

Additional references:
https://developer.gnome.org/gdk2/stable/gdk2-Drawing-Primitives.html#gdk-draw-line
https://developer.gnome.org/gdk2/stable/gdk2-Drawing-Primitives.html#gdk-draw-rectangle

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci c602170faa modern-gtk2: Delay construction of Gtk::TreeModel* objects (!17)
C++ initialises static member variables before main() is called.
Therefore the static members of:
    struct Slots
    {
        static Gtk::TreeModelColumn<Glib::ustring> text;
        static Gtk::TreeModelColumn<bool> sensitive;
    private:
        static Gtk::TreeModel::ColumnRecord record_;
    };
are constructed before Gtk::Main() is called in main().  However the
Gtkmm documentation specifically says that they must be constructed
afterwards [1].

Resolve this by using the Construct On First Use Idiom [2] to delay
initialisation until the slots are first used.  Normally this idiom uses
static local objects, however it is being applied to class static
objects here because the objects are accessed in many methods.  The
downside of this approach is that the objects are never destructed,
which memory analysers like Valgrind could see as a memory leak, but
that is actually deliberate.  That leak can be removed once we can use
C++11 and std::unique_ptr.

[1] gtkmm: Gtk::TreeModelColumnRecord Class Reference
    https://developer.gnome.org/gtkmm/2.24/classGtk_1_1TreeModelColumnRecord.html#details

    "Neither TreeModel::ColumnRecord nor the TreeModelColumns contain
    any real data - they merely describe what C++ type is stored in
    which column of a TreeModel, and save you from having to repeat that
    type information in several places.

    Thus TreeModel::ColumnRecord can be made a singleton (as long as you
    make sure it's instantiated after Gtk::Main), even when creating
    multiple models from it.
    "

[2] C++ FAQ / How do I prevent the "static initialization order
    problem"?
    https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 6bfa95d427 modern-gtk2: Rename callback after OptionComboBox class switch (!17)
Final part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.

This specific commit renames the signal handler callback to match the
previously renamed combobox widget variable names.

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 48d2fd2120 modern-gtk2: Use OptionComboBox class for file system combobox (!17)
Third part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.

This specific commit is about file system combobox.

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci cf5e9c863f modern-gtk2: Use OptionComboBox class for partition type combobox (!17)
Second part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.

This specific commit is about partition type combobox.

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 83b98885f6 modern-gtk2: Use OptionComboBox class for alignment combobox (!17)
First part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.

This specific commit is about partition alignment combobox.

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 5407e8346b modern-gtk2: Introduce OptionComboBox class (!17)
Gtk::OptionMenu is a combobox type widget that is constructed from a
Gtk::Menu rather than a Gtk::TreeModel.  However Gtk::OptionMenu was
deprecated in gtkmm 2.4.1.

In GParted the Gtk::OptionMenu widget is used for:
- partition alignment combobox
- partition type combobox
- file system combobox

While they consist only of text we cannot use Gtk::ComboBoxText because
it doesn't expose functionality in its interface to make items inactive.

Create OptionComboBox helper class that builds a combobox consisting of
only text items, much like Gtk::ComboBoxText, but has the added
functionality to set items as inactive.

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1OptionMenu.html#details
https://gitlab.gnome.org/GNOME/gtkmm/blob/GTKMM_2_10_1/ChangeLog#L3515
bba503b047
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1ComboBoxText.html

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 430ac9240c modern-gtk2: Use Gtk::Widget::set_tooltip_text() (!17)
GParted was using Gtk::Tooltips widgets for tooltips, but they were
deprecated in gtkmm 2.12 in favour of Gtk::Tooltip widgets.  (Note the
spelling difference, with and without a trailing 's').

As GParted's tooltips are all text only continue to use the shortcut,
which is now Gtk::Widget::set_tooltip_text().

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Tooltips.html#details
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Tooltip.html#details
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.20.0/NEWS#L740

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 6a80ca8f7d modern-gtk2: Use Gtk::MenuItem::unset_submenu() (!17)
Gtk::MenuItem::remove_submenu() was deprecated in gtkmm 2.12.  Replace
with Gtk::MenuItem::unset_submenu() introduced in gtkmm 2.22.

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1MenuItem.html
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.22.0/NEWS#L24

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 511d597188 modern-gtk2: Use Gtk::AboutDialog::set_program_name() (!17)
Gtk::AboutDialog::set_name() was deprecated in gtkmm 2.12.  Replace with
Gtk::AboutDialog::set_program_name().

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1AboutDialog.html
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.20.0/NEWS#L741

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 3d6ee55606 modern-gtk2: Use Gtk::AlignmentEnum::ALIGN_START (!17)
Gtkmm 2.22 deprecated Gtk::AlignmentEnum::ALIGN_{LEFT,RIGHT,TOP,BOTTOM}
replacing with Gtk::AlignmentEnum::ALIGN_{START,END}.

References:
https://developer.gnome.org/gtkmm/2.24/group__gtkmmEnums.html#ga98983d4e80f67ffa5148dd554706ffac
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.22.0/NEWS#L14

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 197c88ad73 modern-gtk2: Use Gtk::TreeView::Column::get_first_cell() (!17)
Gtk::TreeView::Column::get_first_cell_renderer() was deprecated in
gtkmm 2.24.  Replace with Gtk::TreeView::Column::get_first_cell().

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1TreeViewColumn.html
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.24.0/NEWS#L64

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 3f18318304 modern-gtk2: Use Gtk::ComboBoxText::append() (!17)
Gtk::ComboBoxText::append_text() was deprecated in gtkmm 2.24.  Replace
with Gtk::ComboBoxText::append().

References:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1ComboBoxText.html
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.24.0/NEWS#L20

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci c0aa3dbfdf modern-gtk2: Always use Gtk::MessageDialog::get_message_area() (!17)
Remove check for Gtk::Messagedialog::get_message_area() and associated
fallback code as it is always available from gtkmm 2.22.

Reference:
https://gitlab.gnome.org/GNOME/gtkmm/blob/2.22.0/NEWS#L25

Closes !17 - Gtk2 modernisation
2018-11-12 21:50:42 +00:00
Luca Bacci 1f54ab6b12 Use Gtk::Viewport wrapper class
There is a GtkViewport wrapper class in gtkmm, Gtk::Viewport.  Make use
of that class instead of direct gtk calls.

Reference:
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Viewport.html
2018-11-12 21:50:42 +00:00
Mike Fleetwood dfb7d3e581 Enhance comment about the 3 levels of file system support
Add a little extra explaining how the file systems' supported actions
are determined.
2018-11-12 13:53:10 -07:00
Mike Fleetwood a0f97bfa19 Improve translation help for "unformatted" file system type 2018-11-12 13:53:04 -07:00
Mike Fleetwood 8a4f9ad205 Adjust shades of aquamarine, cyan and orange
The shades of aquamarine, cyan and orange didn't fit with the GNOME
32-colour palette.  Create a set of aquamarine, cyan and orange shades
which match the GNOME palette shades and update the colours of the
relevant file systems accordingly.
    Aquamarine Hilight (#97DFC7) -
    Aquamarine Medium  (#70D2B1) - NTFS
    Aquamarine Dark    (#3EA281) - REFS
    Aquamarine Shadow  (#1F7258) -
    Cyan Hilight       (#95E3E5) - EXTENDED
    Cyan Medium        (#6FCECE) -
    Cyan Dark          (#3C9899) -
    Cyan Shadow        (#166F70) -
    Orange Hilight     (#E59F6A) -
    Orange Medium      (#E58749) - BTRFS
    Orange Dark        (#C26825) - ZFS
    Orange Shadow      (#984F18) -

Note that the hues of aquamarine and cyan are quite close and for the
thin outlines of partitions used in GParted they aren't easy to
distinguish.  Hence also using different lightness to additionally
separate the colour for extended partitions from NTFS and ReFS file
systems.
2018-11-12 20:39:55 +00:00
Mike Fleetwood 69c1537a38 Recognise APFS (Apple File System) (#23)
Just add detection of APFS using GParted's internal magic string
detection.  It just matches 1 byte of the 2 byte object type and the
4 byte magic field found in the super block [1].  See code comment for
more details.

Blkid has just gained recognition of APFS with util-linux v2.33 released
06-Nov-2018 [2].

This will write enough for GParted's simple internal detection to find
APFS:
    # python -c '
    import sys
    sys.stdout.write("\0"*24 + "\1\0" + "\0"*6 + "NXSB")
    ' > /dev/sdb1

[1] Apple File System Reference
    https://developer.apple.com/support/apple-file-system/Apple-File-System-Reference.pdf

[2] [ANNOUNCE] util-linux v2.33
    https://marc.info/?l=linux-fsdevel&m=154150400305928&w=2

Closes #23 - GParted doesn't detect APFS (Apple File System)
2018-11-12 20:39:55 +00:00
Mike Fleetwood 893b67e2b8 Switch HFS and HFS Plus colours to a magenta range (#23)
Currently Linux Swap, Linux Suspend, and HFS use reds from the GNOME
32-colour palette with HFS Plus using serene red outside that palette.
    HFSPLUS       - Serene Red
    HFS           - Red Hilight
    LINUX_SWAP    - Red Medium
    LINUX_SUSPEND - Red Dark
                  - Red Shadow

Apple have a new file system, APFS (Apple File System), which is a
successor to HFS Plus [1][2].  With HFS Plus using a colour outside the
GNOME 32-colour palette and there not being enough distinct reds
available for a new file system, create a new range of magenta colours
which fit with the GNOME palette and use them for the group of Apple
file systems.
    Magenta Hilight (#D59FD4) - HFS
    Magenta Medium  (#B173B0) - HFSPLUS
    Magenta Dark    (#874986) - APFS
    Magenta Shadow  (#662C64) -

This commit just moves HFS and HFS Plus to their new magenta colours.

[1] About Apple File System
    https://developer.apple.com/documentation/foundation/file_system/about_apple_file_system

    "Overview
    Apple File System replaces HFS Plus as the default file system for
    iOS 10.3 and later, and for macOS High Sierra and later.  Apple File
    System offers improved file system fundamentals as well as several
    new features, including cloning, snapshots, space sharing, fast
    directory sizing, atomic safe-save, and sparse files.
    "

[2] Apple File System Reference
    https://developer.apple.com/support/apple-file-system/Apple-File-System-Reference.pdf

    "About Apple File System
    Apple File System is the default file format used on Apple
    platforms.  Apple File System is the successor to HFS Plus, so some
    aspects of its design intentionally follow HFS Plus to enable data
    migration from HFS Plus to Apple File System.  Other aspects of its
    design address limitations with HFS Plus and enable features such as
    cloning files, snapshots, encryption, and sharing free space between
    volumes.
    "

Closes #23 - GParted doesn't detect APFS (Apple File system)
2018-11-12 20:39:55 +00:00
Mike Fleetwood 39d3cd97c2 Disallow resizing btrfs if any of it's mount points are read-only (#10)
No other file system allows this, but btrfs allows simultaneous mounting
with different read-write permission.  Further, btrfs allows resizing
via read-write mounts, but not via read-only mounts.

    # mkfs.btrfs /dev/sdb1
    btrfs-progs v4.15.1
    ...
    Filesystem size:    512.00MiB
    ...
    Number of devices:  1
    Devices:
       ID        SIZE  PATH
        1   512.00MiB  /dev/sdb1

    # mount -o ro /dev/sdb1 /mnt/1
    # mount -o rw /dev/sdb1 /mnt/2
    # grep sdb1 /proc/mounts
    /dev/sdb1 /mnt/1 btrfs ro,relatime,space_cache,subvolid=5,subvol=/ 0 0
    /dev/sdb1 /mnt/2 btrfs rw,relatime,space_cache,subvolid=5,subvol=/ 0 0

    # btrfs filesystem resize 1:500M /mnt/1
    Resize '/mnt/1' of '1:500M'
    ERROR: unable to resize '/mnt/1': Read-only file system
    # echo $?
    1

    # btrfs file system resize 1:500M /mnt/2
    Resize '/mnt/2' of '1:500M'
    # echo $?
    0
    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: 74ccd37a-e665-4f25-b77e-a305b8a025e9
            Total devices 1 FS bytes used 128.00KiB
            devid    1 size 500.00MiB used 88.00MiB path /dev/sdb1

Also with the above order of the read-only mount listed in /proc/mounts
first and the read-write mount second, GParted again allows a resize
operational to be tried, but if fails just like before:

    Grow /dev/sdb1 from 512.00 MiB to 1.0 GiB                  (ERROR)
    * calibrate /dev/sdb1                                      (SUCCESS)
    * grow partition from 512.00 MiB to 1.00 GiB               (SUCCESS)
    * grow filesystem to fill the partition                    (ERROR)
      * btrfs filesystem resize 1:max '/mnt/1'                 (ERROR)
          Resize '/mnt/1 to '1:max'
          ERROR: unable to resize '/mnt/1': Read-only file system

What happened is that the Mount_Info module only stores single read-only
flag against the mounted block device, not for each mount point, and as
the first and second sdb1 lines from /proc/mounts were processed, the
MountEntry became:

  1st)   mount_info[BS("/dev/sdb1")] -> {true , ["/mnt/1"]
  2nd)   mount_info[BS("/dev/sdb1")] -> {false, ["/mnt/1", "/mnt/2"]

So GParted thought the file system was mounted read-write, but used the
first mount point, /mnt/1, which was mounted read-only.

This is a very unusual situation so unlikely to be encountered by users.
Fix simply and safely by treating the mounted block device as mounted
read-only if any of the mount points are mounted read-only, rather than
just the last processed mount point.

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood f8512506ae Prevent online resizing of file systems mounted read-only (#10)
Resizing a file system mounted read-only fails.  Example:

    # mkfs.btrfs /dev/sdb1
    # mount -o ro /dev/sdb1 /mnt/1

In GParted try to resize partition sdb1.  The operation fails like this:

    Grow /dev/sdb1 from 512.00 MiB to 1.00 GiB                 (ERROR)
    * calibrate /dev/sdb1                                      (SUCCESS)
    * grow partition from 512.00 MiB to 1.00 GiB               (SUCCESS)
    * grow filesystem to fill the partition                    (ERROR)
      * btrfs filesystem resize 1:max '/mnt/1'                 (ERROR)
          Resize '/mnt/1' of '1:max'
          ERROR: unable to resize '/mnt/1': Read-only file system

See GitLab issue for the testing results of attempting to online resize
all supporting file system while mounted read-only.  No file system
allows online resizing while mounted read-only, except for reiserfs.
    Issue #10 - Gparted fails to resize btrfs partition that is mounted
    read-only
    https://gitlab.gnome.org/GNOME/gparted/issues/10

Fix by preventing online resizing of *all* file systems mounted
read-only, including reiserfs.  Instead of displaying the resize dialog
in this case, display an information dialog explaining why the partition
can't be resized.  This is similar to what happens when attempting to
create a new partition on a disk without a partition table.  The new
dialog looks like:

    (!) Unable to resize read-only file system /dev/sdb1
        The file system can not be resized while it is mounted read-only.
        Either unmount the file system or remount it read-write.
                                                                   [ OK ]

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood c82883d6a7 Add and set read-only mount flag in the Partition object (#10)
Set the partition read-only mount flag at the same time as setting the
file system mount points.

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood 441b39347a Add parsing of read-only mount option into mount maps (#10)
Parse file system mount options string from file and mount command
output, extracting the setting for the read-only flag and storing in the
mount maps.  Read-only flag for swap space gets the struct MountEntry
constructor default of false.

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood f4994a2b63 Add read-only flag to mounted file system entries (#10)
Just updates the 2 maps in the Mount_Info module so that they also have
a read-only flag for each mount.  Ensure that when a struct MountEntry
is created the readonly bool POD (Plain Old Data) type is initialised by
the constructor.  Nothing yet sets or uses the flag.

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood df0d4c870b White space tidy-up of Utils::get_filesystem_string()
Use smart tab alignment, list cases in enumeration order and update
translation help for unallocated space.
2018-09-17 15:36:09 +00:00
Mike Fleetwood 18bac7c927 Replace open coding FS unknown usage check in prepare_new_partition()
Back when unallocated space handling was being added, this case was not
converted from open coding to using the provided method to check for
unknown file system usage.  Specifically this commit missed using
Partition::sector_usage_known() in
Dialog_Base_Partition::prepare_new_partition():

    7ebedc4bb3
    Don't show intrinsic unallocated space (#499202)

Fix it now.
2018-09-17 15:36:09 +00:00
Mike Fleetwood 9c35d91453 Refactor get_filesystem_object()
The function was using std::map::count() [1] to test if the file system
entry existed in the map before looking up the value using
std::map::operator[] to avoid having operator[] inserting elements which
don't exist [2].

Rewrite using std::map::find() [3] so that map is only searched once,
and so that it is more obvious what is happening without having to know
the subtleties of std::map::count() and ::operator[].

[1] std::map::count()
    http://www.cplusplus.com/reference/map/map/count/

    "Searches the container for elements with a key equivalent to k and
    returns the number of matches.

    Because all elements in a map container are unique, the function can
    only return 1 (if the element is found) or zero (otherwise).
    "

[2] std::map::operator[]
    http://www.cplusplus.com/reference/map/map/operator[]/

    "If k does not match the key of any element in the container, the
    function inserts a new element with that key and returns a reference
    to its mapped value.  Notice that this always increases the
    container size by one, even if no mapped value is assigned to the
    element (the element is constructed using its default constructor).
    "

[3] std::map::find
    http://www.cplusplus.com/reference/map/map/find/

    "Searches the container for an element with a key equivalent to k
    and returns an iterator to it if found, otherwise it returns an
    iterator to map::end.
    "
2018-09-17 15:36:09 +00:00
Mike Fleetwood d3ef32096a Re-assign UFS to be a basic supported file system (!13)
There is no prospect of there being ufs-tools on Linux.  The was a
project which did release ufs-tools version 0.1 in 2004, but has been
inactive since then.
    http://ufs-linux.sourceforge.net/

Copying and moving is now implemented for file systems in the basic
supported category.  Also mounting and unmounting of unsupported file
system and reporting their usage while mounted has been added.  This is
all the support that GParted has ever implemented for UFS.  Therefore
re-assign UFS as a basic supported file system as it looses no
functionality.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 95903efb1f Extend un/mounting and usage reporting to unsupported file systems (!13)
For unsupported (including basic supported) file systems, also record
the mount point(s) when mounted and from /etc/fstab when not.  This
allows mounted unsupported file systems to be unmounted and ones with
/etc/fstab entries to be mounted, just like fully supported file
systems.

Also for unsupported (again including basic supported) mounted file
systems query the kernel for the usage, just like is already done for
supported file systems.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 4c3f4e3459 Correctly preview unknown FS usage when pasting into an existing partition (!13)
When previewing copying a partition of unknown file system usage into an
existing partition, the usage still shows that of the overwritten file
system.  This affects existing supported file systems EXFAT, F2FS, MINIX
and UFS and the new basic supported one too, all for which GParted can't
read the file system usage.

Handle the case of the source file system usage being unknown and
explicitly set the copied usage to unknown too.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood f098cd414c Correctly preview unknown FS usage when pasting into a new partition (!13)
GParted previews copying a partition of unknown file system usage into a
new partition as 100% used.  This affects existing supported file
systems EXFAT, F2FS, MINIX and UFS and the new basic supported ones too,
all for which GParted can't read the file system usage.

When preparing the working new_partition object in the Copy / Paste
dialog, the maths for the known file system usage happened to convert
the figures of used = -1 and unused = -1 into set_sector_usage(-1, 0).
Those values passed to set_sector_usage() mean unable to query the file
system size so assume it fills the partition and unused is 0, hence 100%
used.

Fix this by specifically handling the copying of file systems with
unknown usage, setting the pasted file system usage to unknown too,
used = -1 and unused = -1.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 4d6d464664 Display "other" in the File System Support dialog (!13)
To display the supported actions for all basic supported file systems to
the users.

Prepare the list of file system actions in Win_GParted because calling
get_fs() for the "other" actions requires the gparted_core object and
load_filesystems() currently doesn't have access to it.  One alternative
would have been to make get_fs() and FILESYSTEMS static members of
GParted_Core class.  Another alternative would have been to pass the
gparted_core object to load_filesystems().  The chosen way seemed
simplest.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 9a66139eff Add "other" file system type (!13)
Want a single term under which the supported actions for all basic
supported file systems are displayed in the File System Support dialog.
"Unknown" isn't the correct adjective because the group includes
unknown, but also includes: BitLocker, GRUB2 core image, ISO9660, Linux
SWRaid, Linux Suspend, REFS and ZFS.  Add "other" file system type just
for displaying in the dialog.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 7a6dfb8a62 Enable copy and move for basic supported file systems (!13)
Add copy and move supported action set for each basic supported file
system.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood ba79ddaf72 Limit FILESYSTEM_MAP entries to supported and basic supported FSs (!13)
Introduce a third category of basic file system support to go along with
the existing full and none.  Use the file system's entry in
FILESYSTEM_MAP to determine the level of support.  See comment in
GParted_Core::init_filesystems() for details.

Add and remove FILESYSTEM_MAP NULL pointer entries as required, so that
only the file system types intended to have basic support have such
entries.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood f61481f3ae Separate unknown file system type from unsupported actions (!13)
PATCHSET OVERVIEW:

Forum user wanted to be able to move a partition with unknown content:
    Topic: Can't move/rezise partition on android device (unknown format)
    http://gparted-forum.surf4.info/viewtopic.php?id=17742

While GParted isn't going to be able to run any sort of file system
check on the unknown content there isn't any reason why such a partition
can't be copied or moved so long as the partition stays the same size.
GParted can just use it's existing internal block copy routine it uses
for copying and moving most partition content.  This is no different to
a few of the already supported file system types which don't have a
check-repair tool: exfat, f2fs, nilfs2, udf, ufs.

This patchset introduces a third category called basic file system
support to go along with the existing full and unsupported categories.
Basic supported file systems will just use GParted's inbuilt
capabilities to perform actions so they won't need a derived FileSystem
implementation class.  Unknown file systems along with all other
recognised, but otherwise unsupported, file systems will be assigned to
this new basic supported category.

THIS PATCH:

FS_UNKNOWN is used when GParted is unable to identify the contents of a
partition.  FS_UNKNOWN is also used to generate a file system support
set with no supported actions, in the FileSystem::FS::FS() constructor
and in GParted_Core::get_fs().

As support for operations on partitions with unknown content is being
added, the second usage will be confusing or even wrong.
FS( FS_UNKNOWN ) constructs the no supported actions set, yet GParted
will support some actions for the FS_UNKNOWN file system type.
Therefore add FS_UNSUPPORTED for the second usage.

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 4542f34fed White space tidy-up of Utils::get_color()
No functional change.  The code layout is old and a mess, not lining up
vertically.  Use more common code layout and spaces to align text
vertically.  List cases in enumeration order.  Identify each colour
choice as either in the GNOME palette (no marking), an extended shade to
a colour in the GNOME palette [+], or a colour outside the GNOME palette
[*].

There's lots of other switch statements just in Utils.cc which could do
with tidying up, but this is the one I am looking at now.
2018-08-25 08:39:30 +01:00
Mike Fleetwood 1c651de338 Switch FAT16/32 colours to Accent Greens from the GNOME palette
FAT16 was a fully saturated green (RGB #00FF00) and FAT32 was a little
darker.  These are out of character with the colours from the GNOME
palette for other file systems.  Change the colours to use near
alternative Accent Greens from the GNOME colour palette.  So now we have
the following file system colours, from light to dark:
    FAT16 - Accent Green Hilight
    FAT32 - Accent Green
    EXFAT - Accent Green Dark
    UDF   - Accent Green Shadow

Strictly speaking only Accent Green and Accent Green Dark are part of
the GNOME palette.  Accent Green Hilight and Accent Green Shadow are
extensions expanding the range of Accent Greens.

    GNOME Human Interface Design 2.2.1 / Visual Design / colour /
    https://developer.gnome.org/hig-book/2.32/design-color.html.en

    "Guidelines
    * Use the GNOME color palette.  If you need a darker or lighter
      shade, start from one of the colors from the palette and darken or
      lighten as needed.
    "
2018-08-24 20:22:21 +01:00
Mike Fleetwood 03e89b1289 Add support for minix file system (!12)
Util-linux package, at least as far back as version 2.23.2 as found on
CentOS 7, provides the mkfs.minix and fsck.minix commands.  Also blkid
from the same package, recognises minix file systems.

Create version 3 file systems because MINIX 3 [1] is the only supported
version and that reportedly uses version 3 of the file system [2].

[1] MINIX 3 / History
    https://en.wikipedia.org/wiki/MINIX_3#History

[2] Regarding MINIX 3 file system
    https://groups.google.com/forum/#!topic/minix3/3-TeHR_23X8

    "MINIX 3 uses Minix File System (MFS).  More precisely MFS V3."

Closes !12 - Add minix file system support
2018-08-24 20:22:08 +01:00
Mike Fleetwood 92f6946e24 Use one shade darker blue for EXT2/3/4 file systems (!12)
I see the MINIX file system as a kind of forerunner to EXT* because of
it's history [1].  No body uses the original EXT file system any more,
however the MINIX file system is still used by the MINIX 3 operating
system.  So use the same range of colours for MINIX and EXT2/3/4.  Use
one shade darker blue for EXT2/3/4, allowing MINIX to use the lightest
blue.  After adding MINIX support in the next patch, the colours will
become:
    MINIX - Blue Hilight
    EXT2  - Blue Medium
    EXT3  - Blue Dark
    EXT4  - Blue Shadow

[1] MINIX file system / History
    https://en.wikipedia.org/wiki/MINIX_file_system#History

    "When Linus Torvalds first started writing his Linux operating
    system kernel (1991), he was working on a machine running MINIX, and
    adopted its file system layout.  This soon proved problematic, since
    MINIX restricted filename lengths to fourteen characters (thirty in
    later versions), it limited partitions to 64 megabytes, and the file
    system was designed for teaching purposes, not performance.  The
    Extended file system (ext; April 1992) was developed to replace
    MINIX's, but it was only with the second version of this, ext2, that
    Linux obtained a commercial-grade file system.  As of 1994, the
    MINIX file system was "scarcely in use" among Linux users.
    "

Closes !12 - Add minix file system support
2018-08-24 20:21:58 +01:00
Mike Fleetwood ed17982eb3 Re-add getting EXT2/3/4 free space from dumpe2fs as a fallback (#8)
If an EXT2/3/4 file system needs checking, then resize2fs will report an
error, rather than report the minimum file system size.

    # mkfs.ext4 /dev/sdb11
    # resize2fs -P /dev/sdb11
    resize2fs 1.42.9 (28-Dec-2013)
    Estimated minimum size of the filesystem: 17012
    # debugfs -w -R "ssv state 0" /dev/sdb11
    # resize2fs -P /dev/sdb11
    resize2fs 1.42.9 (28-Dec-2013)
    Please run 'e2fsck -f /dev/sdb11' first.

    # echo $?
    1

This will prevent GParted reading the file system usage and in turn
GParted won't allow the file system to be shrunk.  Re-add the previous
method of reading the free space from dumpe2fs output as a fallback.

With this change, the worst case scenario is that GParted allows the
user to attempt to shrink an unclean EXT4 file system, smaller that that
which resize2fs allows and gets an error telling them so.  As part of
the failed shrink operation GParted will have checked the file system so
on refresh GParted will get the correct minimum size next time.

This scenario only seems to apply to unclean EXT4 file systems because
resize2fs has a larger minimum size that the free blocks would suggest
because of extra space requirements when resizing EXT4 file systems [1].

[1] e2fsprogs 1.44.3, resize/resize2fs.c:calculate_minimum_resize_size()
    https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/tree/resize/resize2fs.c?h=v1.44.3#n2946
    /*
     * For ext4 we need to allow for up to a flex_bg worth of
     * inode tables of slack space so the resize operation can be
     * guaranteed to finish.
     */

    /*
     * We need to reserve a few extra blocks if extents are
     * enabled, in case we need to grow the extent tree.  The more
     * we shrink the file system, the more space we need.
     *
     * The absolute worst case is every single data block is in
     * the part of the file system that needs to be evacuated,
     * with each data block needs to be in its own extent, and
     * with each inode needing at least one extent block.
     */

Closes #8 - Shrinking an EXT4 partition does not respect resize2fs
            limits
2018-08-01 19:03:01 +01:00
Mike Fleetwood fe83f6290f Use resize2fs -P to get minimum EXT2/3/4 FS size (#8)
A user reported GParted failed to shrink an EXT4 file system because
GParted tried to shrink it smaller than resize2fs reported minimum size.
Operation details were:

    Shrink /dev/sdc1 from 931.51 GiB to 605.00 GiB             (ERROR)
      calibrate /dev/sdc1                                      (SUCCESS)
        path: /dev/sdc1 (partition)
        start: 63
        end: 1953520064
        size: 1953520002 (931.51 GiB)
      check file system on /dev/sdc1 for errors and (if poss...(SUCCESS)
        e2fsck -f -y -v -C 0 '/dev/sdc1'                       (SUCCESS)
          ...
          158165624 blocks are used (64.77% of 244190000)
          ...
      shrink file system                                       (ERROR)
        resize2fs -p '/dev/sdc1' 634389176K                    (ERROR)
          resize2fs 1.44.2 (14-May-2018)
          resize2fs: New size smaller than minimum (171882113)

The GParted figures:
 *  Partition size    = 1953520064 (512b sectors) = 976760032 KiB
 *  FS size           = 244190000 (4K blocks)     = 976760000 KiB
 *  Used FS size      = 158165624 (4K blocks)     = 632662496 KiB
 *  Requested FS size                             = 634389176 KiB
The resize2fs figure:
 *  Minimum FS size   = 171882113 (4K blocks)     = 687528452 KiB

GParted uses the number of free blocks in the file system to determine
the minimum size it can shrink a file system to.  However resize2fs uses
it's own internally calculated minimum size and won't shrink a file
system below that size, as seen in the above details.  Resize2fs does
have a force flag, (-f) which overrides some safety checks which are
normally enforced, to allow it to try to shrink a file system smaller
than it's calculated minimum.  GParted currently doesn't use the force
flag and it seems unwise for it to start to do so.

So for unmounted EXT2/3/4 file systems, change GParted to use
'resize2fs -P' to get the minimum file system size, rather than using
the number of free blocks direct from the super block, as reported by
'dumpe2fs -h'.

Mounted file systems still use statvfs() to provide file system usage.
As mounted EXT2/3/4 file systems can't be shrunk the fact that statvfs()
produces different, possibly smaller than minimum, figures than those
from 'resize2fs -P' doesn't matter.

Closes #8 - Shrinking an EXT4 partition does not respect resize2fs
            limits
2018-08-01 19:02:41 +01:00
Mike Fleetwood ef8dbe8f4e Work in FS blocks until later while reading EXT2/3/4 usage (#8)
No functional change.  Just work in FS block sized units until as late
as possible in ext2::set_used_sectors(), before converting to device
sector size units.  This is to make the following change simpler and
easier to understand.

Closes #8 - Shrinking an EXT4 partition does not respect resize2fs
            limits
2018-07-31 07:02:52 +01:00
Mike Fleetwood 465bd61e26 Set FSType when constructing FS in luks::get_filesystem_support()
This is functionally identical, but is just to follow established coding
pattern [1] of specifying the FSType when constructing struct FS, rather
and setting it afterwards.  luks.cc was added after the aforementioned
commit, but was being developed in parallel so was created [2] following
the old coding pattern.

[1] 1a4cefb960
    Initialise all struct FS members

[2] 070d734e57
    Add busy detection of LUKS mapping (#760080)
2018-07-19 19:26:30 +00:00
Mike Fleetwood 03d47d4d02 Recognise additional GRUB2 core.img signatures (!5)
Bootinfoscript v0.77 (2018-06-10) added additional signatures to
recognise GRUB2 core.img by.  Commit:

    9a00c1a887
    Add more core.img diskboot signatures

Specifically the new signatures are:
    5256be63 - trustedgrub2 1.4
    5256be56 - diskboot.S with mjg TPM patches (e.g. in openSUSE
               Tumbleweed)

Add those signatures into GParted.

Closes !5 - Recognise additional GRUB2 core.img signatures
2018-07-19 19:26:29 +00:00
Mike Fleetwood 5892b72890 Fix LVM2 PV shrinking with lvm2 2.02.171 and later (#1)
Shrinking an LVM2 Physical Volume on CentOS 7 with the latest
lvm2 2.02.177 fails like this:

  Shrink /dev/sda9 from 1.00 GiB to 768.00 MiB
  * calibrate /dev/sda9
  * check file system on /dev/sda9 for errors and (if possib...(SUCCESS)
  * shrink file system                                         (ERROR)
    * lvm pvresize -v --setphysicalvolumesize 786432K '/dev/...(ERROR)
        0 physical volume(s) resized / 1 physical volume(s) not resized

        Wiping internal VG cache
        Wiping cache of LVM-capable devices
        /dev/sda9: Requested size 712.00 MiB is less than real size 1.00 GiB.  Proceed? [y/n]:[n]
        Physical Volume /dev/sda9 not resized.

This upstream change to lvm2 [1] makes pvresize prompt for confirmation
whenever the --setphysicalvolumesize option is used.  (The change was
included in lvm2 2.02.171 and later, which is used in recent
distributions.  The reporter found the issue on Ubuntu 18.04 LTS and I
reproduced the issue on RHEL/CentOS 7.5).  The set size option has to be
used when shrinking the PV before shrinking the partition therefore fix
this issue by adding lvm common option --yes when using the set size
option.

[1] https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=cbc69f8c693edf0d1307c9447e2e66d07a04bfe9
    pvresize: Prompt when non-default size supplied.

Closes #1 - Can't shrink LVM partition due to pvresize prompt
2018-06-21 20:04:18 +01:00
Mike Fleetwood a2af9d4a34 Clear previous LUKS unlock failure error before next attempt (#795617)
After a failed LUKS unlock attempt the password entry dialog shows the
error "Failed to open LUKS encryption".  Improve the user experience by
clearing that error message at the start of the next attempt to avoid
contradictory information with the main windows status of "Opening
encryption on $PARTITION" whilst performing the next unlock attempt.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-06-19 10:54:48 -06:00
Mike Fleetwood 1be7b8bc2e After LUKS unlock failure select failed password (#795617)
When the wrong LUKS password is entered and the [Unlock] button clicked,
the wrong password is left in the entry box and focus remains on the
[Unlocked] button.  Improve the user experience by selecting
(highlighting) the whole of the wrong password ready for deletion or
retyping and ensuring that the entry box always has focus.

Just for completeness also programmatically make the password entry box
have focus when the dialog box is created and first displayed, even
though it gets this by default.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-06-19 10:54:48 -06:00
Piotr Drąg fbe7a5ff44 Avoid unnecessary string change
Restore whitespace to previous version,
so no translations need to be updated.
2018-06-19 18:05:56 +02:00
Mike Fleetwood 672a2f9c71 Update URLs in the app to https://gparted.org (#796411)
We previously migrated our web site from http://gparted.org to
https://gparted.org under:
    bug 786707 - gparted.org does not use HTTPS

and updated URLs in the GParted Manual to match in commit:
    a8172ecb04
    Convert Manual links to HTTPS where possible and update version

Now update the URLs displayed in the GParted application too.

Bug 796411 - Enhancements request - URL links
2018-06-19 09:47:19 -06:00
Mike Fleetwood a9e85698f2 Rework scope of fat16:: and ntfs::Change_UUID_Warning vectors
The Change_UUID_Warning vectors were fat16 and ntfs class member
variables, but are only ever accessed in the get_custom_text() method.
Make them local variables in get_custom_text() instead.  Static so that
references to them can be returned.
2018-06-18 14:47:17 -06:00
Mike Fleetwood 32df1de163 Move the xfs_db -r flag to the start when reading XFS usage
I completely missed that when reading XFS file system size and usage it
was using the '-r' read-only flag to xfs_db because it was at the end of
the string on the following line of code.  Move it to the start of the
xfs_db command line, like it is when reading the file system label.
2018-06-18 10:15:33 -06:00
Mike Fleetwood eab54260a4 Simplify from Gtk::Table to HBox in Partition Name dialog
Same case as for FileSystem Label dialog before; the Partition Name
dialog only has a single line of just 2 widgets.  Therefore switch to a
simpler horizontal box widget to lay them out.
2018-06-18 10:15:33 -06:00
Mike Fleetwood f760c16ba6 Simplify from Gtk::Table to HBox in FileSystem Label dialog
The FileSystem Label dialog only has a single line of just 2 widgets; a
text label and entry box widget.  There is no need to use a multi-line
capable table to hold this.  Switch to a simpler horizontal box widget.

Note that this change is not related to porting to Gtk 3 and stopping
using deprecated APIs because both HBox [1] and Table [2] are deprecated
in Gtk 3.2 and Gtk 3.4 and replaced by Box with horizontal orientation
and Grid respectively.

[1] NEWS file from gtkmm 3.2, actually first released in gtkmm 3.1.6
    (unstable):
    https://git.gnome.org/browse/gtkmm/tree/NEWS?h=3.2.0#n91
        "Gtk:
        * All H* or V* specialized classes have been deprecated, to
          match the deprecations in the GTK+ C API. You should now
          set the orientation instead.
          This includes HBox, VBox, HButtonBox, VButtonBox, HPaned,
          VPaned, HScale, VScale,  HSeparator, VSeparator, HScrollbar
          and VScrollbar."

[2] NEWS file from gtkmm 3.4, actually first released in gtkmm 3.3.2
    (unstable):
    https://git.gnome.org/browse/gtkmm/tree/NEWS?h=3.4.0#n162
        "* Deprecate Gtk::Table in favour of Gtk::Grid."
2018-06-18 10:15:33 -06:00
Mike Fleetwood d948cbcb91 Make get_custom_text() and get_generic_text() return by reference
Replace return by value of const strings from
FileSystem::get_custom_text() and get_generic_text() because that
implies duplication of those strings.  Return a reference to constant
strings instead.
2018-06-18 10:15:33 -06:00
Mike Fleetwood aff99307d9 Recognise blkid identified BitLocker encrypted partitions (#795127)
Future util-linux release after v2.32 will include this commit for blkid
to recognise BitLocker encrypted partitions.  It is much better than
GParted's inbuilt detection.

    https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/commit/?id=136f89ce5ed8cd159a1c56b5a775dada2363ecd3
    libblkid: add BitLocker detection

Make GParted also recognise BitLocker encrypted partitions reported by
blkid.

Bug #795127 - Displayed Name is incorrect for bitlocker encrypted
              partitions
2018-06-18 10:15:33 -06:00
Robert Ancell 2d853b46c1 Fix null pointer check accidentally disabled (#796293)
Compiling (with new enough g++) produces this warning:

    PasswordRAMStore.cc: In member function 'void GParted::PWStore::erase_all()':
    PasswordRAMStore.cc:177:2: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
      if ( protected_mem != NULL );
      ^~
    PasswordRAMStore.cc:193:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
       memset( protected_mem, '\0', ProtectedMemSize );
       ^~~~~~

Looks like a stray semicolon...

Bug 796293 - Fix null pointer check accidentally disabled
2018-05-21 13:37:01 +01:00
Mike Fleetwood 957216f06c Change to insert or replace PasswordRAMStore::store() interface (#795617)
Replace the insert() method (which reports an error when inserting a
password with a key which already exists) with the store() method which
replaces or inserts the password depending on whether the key already
exists or not respectively.  There is also an optimisation that nothing
is changed if the password to be replaced is the same as the one already
stored.  The code in Win_GParted::open_encrypted_partition() is
simplified now it doesn't have to implement this pattern of behaviour
itself.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 1bbb81f920 Report LUKS unlock errors into the password dialog (#795617)
Reports generic GParted error "Failed to open LUKS encryption" on any
failure unlocking the partition.  Choosing not to display cryptsetup
reported errors because those messages and their translations are not
under GParted control.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 3d49fdc2e4 Stop copying password into insecure memory when getting entry (#795617)
The underlying C coded Gtk Entry widget is careful to zero memory after
use, allowing the widget to be safely used for password entry [1].
However the C++ method Gtk::Entry::get_text() just takes the underlying
C string from the Gtk Entry widget and copies it when constructing a
Glib::ustring for the return value [2].

So directly use the Gtk/C API to get the C string instead.

[1] https://git.gnome.org/browse/gtk+/tree/gtk/gtkentrybuffer.c?h=3.22.28#n92
    See function trash_area() which zeros memory and its use in
    gtk_entry_buffer_normal_insert_text(),
    gtk_entry_buffer_normal_delete_text() and
    gtk_entry_buffer_finalize().

[2] https://git.gnome.org/browse/gtkmm/tree/gtk/src/entry.hg?h=3.22.2#n104
    _WRAP_METHOD(Glib::ustring get_text() const, gtk_entry_get_text)

    https://git.gnome.org/browse/glibmm/tree/docs/internal/using_gmmproc.txt?h=2.46.1#n53
    _WRAP_METHOD(Glib::ustring METHOD const, FUNC) is processed to:
        Glib::ustring METHOD() const
        {
            return Glib::convert_const_gchar_ptr_to_ustring(
                FUNC(const_cast<GtkEntry*>(gobj())));
        }

    https://git.gnome.org/browse/glibmm/tree/glib/glibmm/utility.h?h=2.46.1#n82
        Glib::ustring convert_const_gchar_ptr_to_ustring(const char* str)
        {
            return (str) ? Glib::ustring(str) : Glib::ustring();
        }

    So Gtk::Entry::get_text() calls Glib::ustring() constructor which
    copies the C string to create the Glib::ustring object returned.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 307472489d Keep password dialog open until successful unlock or cancellation (#795617)
To keep password dialog open, just keep running it in a loop performing
LUKS mapping unlock attempts with the entered passphrase until it
succeeds or the dialog is cancelled or closed.  This is the same model
that is already used for the File Support System dialog and how the
[Rescan For Supported Actions] button is implemented.

Also any error from attempting to open the LUKS mapping is no longer
displayed in a separate error dialog or at all.  Will add some sort of
error reporting into the password entry dialog in a following commit.

Creates new method Win_GParted::open_encrypted_partition() which handles
the non UI parts of attempting to open an encrypted partition.  Running
"cryptsetup luksOpen" and updating the stored passphrase as needed.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood f4d47fe5a5 Add password entry dialog and attempt LUKS unlock once (#795617)
Initial addition of a password entry dialog.  Looks like:

    +------------------------------------------------+
    |           LUKS Passphrase /dev/sdb1            |
    +------------------------------------------------+
    | Enter LUKS passphrase to open /dev/sdb1        |
    | Passphrase:    [                             ] |
    |                                                |
    |                          [ Cancel ] [ Unlock ] |
    +------------------------------------------------+

A standard Gtk Dialog is used to accept the password once, with any
errors displayed in a separate error dialog afterwards.  This is poor UI
design.  A password dialog should remain open for all authentication
attempts and only close when successful or the dialog is cancelled or
closed.  This UI design issue will be improved in following commits.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood c47b1cdca1 Add closing LUKS mappings (#795617)
Implement Close Encryption partition menu item.

The Open Encryption action is not yet implemented and instead reports an
error detailing the open encryption command.  A dialog needs to be
written to accept the password entry and pass it to the open encryption
command.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood e4959c520f Add unimplemented open/close encryption to the partition menu (#795617)
Add new item to the partition menu to allow the user to open and close
the LUKS mapping.  However for now the menu item is always disabled and
there is no implementation behind it to actually open or close the LUKS
mapping.  Fragment of the partition menu is now:

    ...
    Format to       >
    -----------------
    Open Encryption      <- New menu item
    Mount
    -----------------
    Name Partition
    ...

Has to be two separate menu items to clearly represent to the user that
LUKS mappings and file system mounting are two separate busy states.
And also in the case of an open but unmounted file system to offer both
actions; close encryption and mount file system.

The text of the menu item automatically changes similarly to how it does
for the Mount/Unmount, Swapon/Swapoff, Activate/Deactivate item
depending on the state of the LUKS mapping.  For open LUKS mappings it
will show "Close Encryption" and for all other cases (closed LUKS
mapping or partition is not encrypted) "Open Encryption".  Again similar
to how the default of "Mount" is shown for unallocated and unknown
partitions.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood f898910e90 Rename some Win_GParted members to *toggle_fs_busy* (#795617)
In preparation for adding the ability to toggle the encryption busy
state (open/close the encryption volume), rename existing members to
reflect that they are related to changing the file system state.  (Swap
and LVM2 Physical Volumes are handled as file systems by GParted).

class Win_GParted renaming:
    MENU_TOGGLE_BUSY             -> MENU_TOGGLE_FS_BUSY
    allow_toggle_busy_state()    -> allow_toggle_fs_busy_state()
    toggle_busy_state()          -> toggle_fs_busy_state()
    check_toggle_busy_allowed()  -> check_toggle_fs_busy_allowed()

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 4d7e66eda0 Stop using shell when reading jfs file system usage (#795617)
Replace echoing "dm" into jfs_debugfs via a shell command to directly
writing "dm" to the input of the jfs_debug command.  One less use of the
shell.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 8dff80edc6 Add ability for small writes to stdin of child processes (#795617)
As discussed in "LUKS password handling, threats and preventative
measures" [1] GParted must be able to pass LUKS passphrases to
cryptsetup via standard input to avoid having to write passwords to the
file system and deal with additional security requirements.  Therefore
add a way to write input into created child processes.  For small
amounts of input, writing up to the pipe buffer capacity won't block
[2].  This is 64K on versions of Linux in any currently supported
distributions.

[1] LUKS password handling, threats and preventative measures
    https://bugzilla.gnome.org/show_bug.cgi?id=627701#c56

    GParted must not become a password manage so it must never save
    LUKS passwords to disk across separate invocations of GParted.
    ...

    GParted should avoid writing a temporary file containing the LUKS
    password as it introduces extra complexity with trying to safely
    handle and erase file content.  Instead GParted must
    programmatically pass the LUKS password via standard input to the
    cryptsetup command.

[2] pipe(7) manual page:

    Pipe capacity
        A pipe has a limited capacity.  If the pipe is full, then a
        write(2) will block or fail, depending on whether the O_NONBLOCK
        flag is set (see below).  ...

        In Linux versions before 2.6.11, the capacity of a pipe was the
        same as the system page size (e.g., 4096 bytes on i386).  Since
        Linux 2.6.11, the pipe capacity is 65536 bytes.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 9b52666bdb Simplify obtaining address of password memory for unit tests (#795617)
Use private access into the PasswordRAMStore class to directly obtain
the address of the locked memory, rather than inferring it from the
address of the first stored password.  This simplifies
PasswordRAMStoreTest::SetUpTestCase() and avoids encoding most of the
implementation knowledge that the first password will be stored at the
start of the protected memory.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood d2a2ebe4a1 Add unit testing of erasing all passwords (#795617)
Test that all passwords are zeroed by PasswordRAMStore::erase_all(), the
same method as used in the PasswordRAMStore destructor.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood e2cb8b3126 Split out erasing all passwords into a separate method (#795617)
Move zeroing of the locked memory into separate PWStore::erase_all()
private method.  Then use this in the PWStore destructor.  This is so
that zeroing of all passwords can be unit tested independently of
destructing the singleton PWStore object.

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood 04637a3426 Add PasswordRAMStore module (#795617)
Application level requirements for secure password management were set
out in "LUKS password handling, threats and preventative measures" [1].

The requirements are:
1) Passwords are stored in RAM and are not allowed to be paged to swap.
   (However hibernating with GParted still running will write all of RAM
   to swap).
2) Passwords are wiped from RAM when no longer needed.  When each
   password is no longer needed and when GParted closes.
3) Passwords are referenced by unique key.  Recommend using LUKS UUIDs
   as the unique key.
   (Each LUKS password should only ever need to be entered once for each
   execution of GParted.  Therefore the passwords can't be stored in any
   of the existing data structures such as Partitions or LUKS_Info cache
   because all of these are cleared and reloaded on each device
   refresh).

There seems to be two possible implementation methods: use an existing
library to provide secure memory handling, or write our own.
Libgcrypt [2] and libsodium [3] cryptographic libraries both provide
secure memory handling.  (Secure memory is quite simple really, some
virtual memory locked into RAM which is zeroed when no longer needed).
Linking to an encryption library just to provide secure memory seems
like using a sledge hammer to crack a nut.  Also because of requirement
(3) above a module is needed to "own" the pointers to the passwords in
the secure memory.  Managing the secure memory ourselves is probably no
more code that that needed to interface to libgcrypt.  Therefore handle
the secure memory ourselves.

So far the module is only compiled.  It is not used anywhere in GParted.

[1] LUKS password handling, threats and preventative measures
    https://bugzilla.gnome.org/show_bug.cgi?id=627701#c56

[2] libgcrypt general purpose cryptographic library, as used in GNU
    Privacy Guard
    https://gnupg.org/related_software/libgcrypt/

[3] libsodium crypto library
    https://download.libsodium.org/doc/

Bug 795617 - Implement opening and closing of LUKS mappings
2018-04-30 09:10:48 -06:00
Mike Fleetwood fc215d0c2e Increase minimum required gtkmm to 2.16.0 (#794253)
Increase the minimum required version of gtkmm to 2.16.0, thus allowing
removal of HAVE_GTK_SHOW_URI autoconf definition and associated fallback
code.

Bug 794253 - Desupport RHEL / CentOS 5 and raise minimum required
             versions to glibmm 2.14.0 and gtkmm 2.16.0
2018-03-26 10:16:45 -06:00
Mike Fleetwood 0ab2adb67f Increase minimum required gtkmm to 2.11.1 (#794253)
Increase the minimum required version of gtkmm to 2.11.1, thus allowing
removal of:
 *  HAVE_SET_DEFAULT_ICON_NAME autoconf definition and associated
    optional code.
 *  INSTALL_PIXMAPS_DIR automake conditional and associated make
    instructions.

This is reversing these 3 commits, except for the higher minimum gtkmm
version:
 1) a042107883
    Only use Gtk::Window::set_default_icon_name method when available (#695279)
 2) b09d6035cd
    Add fallback method for specifying GParted icon (#695279)
 3) d6baac2546
    Only install fallback icon when required (#695279)

Bug 794253 - Desupport RHEL / CentOS 5 and raise minimum required
             versions to glibmm 2.14.0 and gtkmm 2.16.0
2018-03-26 10:16:45 -06:00
Mike Fleetwood 07f58ed82b Raise minimum required glibmm version to 2.14.0 (#794253)
Increase the minimum required version of glibmm to 2.14.0, thus allowing
removal of the HAVE_GLIB_REGEX autoconf definition and associated
conditional code.  This is reversing commit, except for the new glibmm
minimum check:

    456932846b
    Implement fallback if Glib::Regex class is missing (#695279)

Bug 794253 - Desupport RHEL / CentOS 5 and raise minimum required
             versions to glibmm 2.14.0 and gtkmm 2.16.0
2018-03-26 10:16:45 -06:00
Mike Fleetwood de6e70d933 Simplify ext2::get_filesystem_support() with regard ext4 support (#794253)
E2fsprogs 1.41.0 (from 10 July 2008) first included ext4 support [1].
As RHEL / CentOS 6 is now the oldest supported distribution, and that
includes e2fsprogs 1.41.12 (from 22 August 2009) [2] all the e2fs
programs support ext4 so it is no longer necessary to also depend on
finding mkfs.ext4 before enabling each supported capability for ext4.
This makes the ext2::get_filesystem_support() look like all the others
in which each supported capability only depends on the presence of the
relevant file system specific command.

[1] Release notes for the e2fsprogs package / E2fsprogs 1.41.0
    http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.41.0

[2] pkgs.org > CentOS 6 > CentOS x86_64 > e2fsprogs
    https://centos.pkgs.org/6/centos-x86_64/e2fsprogs-1.41.12-23.el6.x86_64.rpm.html

Bug 794253 - Desupport RHEL / CentOS 5 and raise minimum required
             versions to glibmm 2.14.0 and gtkmm 2.16.0
2018-03-26 10:16:45 -06:00
Mike Fleetwood 6c4ab5dc28 Remove checks for e4fsprogs commands (#794253)
PATCHSET OVERVIEW:

As of 31 March 2017 RHEL / CentOS 5 reached the end of their support
[1][2].  Therefore remove code which supports them.  This makes RHEL /
CentOS 6 the oldest supported distribution.  So the minimum required
versions of glibmm and gtkmm can be increased dropping some autoconf
checks and conditional code supporting older versions of these
libraries.  This will undo the bulk of these these previous bug fixes:

* GParted 0.21.0
  Bug 738706 - Add support for ext4 on RHEL/CentOS 5.x

* GParted 0.16.1
  Bug 695279 - Fix GParted doesn't compile on RHEL / CentOS 5.9

[1] Red Hat Enterprise Linux Life Cycle
    https://access.redhat.com/support/policy/updates/errata#Life_Cycle_Dates

[2] Subject: CentOS Linux 5 EOL
    https://lists.centos.org/pipermail/centos-announce/2017-April/022350.html

THIS PATCH:

Remove checks for e4fsprogs commands, removing support for ext4 on
RHEL / CentOS 5.x.  This is reverting earlier commit:
    f672f68863
    Check for e4fsprogs commands for ext4 support on RHEL/CentOS 5.x (#738706)

Mkfs_cmd member variable is being kept as a convenience so that it is
created once rather than on each use.  Also note that as it is a
Glib::ustring type object, it's constructor will be called which will
initialise it to the empty string so it doesn't need initialising to the
empty string in the initialiser list of the ext2() constructor itself.

Bug 794253 - Desupport RHEL / CentOS 5 and raise minimum required
             versions to glibmm 2.14.0 and gtkmm 2.16.0
2018-03-26 10:16:45 -06:00
Curtis Gedak 3f3209c6ba Update copyright year 2018-03-19 10:05:34 -06:00
Mike Fleetwood 578ebf133e Add comment about needing to compute encryption overhead in activate_format()
To explain why just using the size of the LUKS header won't always be
correct.
2018-01-28 10:09:35 -07:00
Mike Fleetwood a3b47ca14a Move struct FS and FS_Limits into FileSystem.h
Struct FS and struct FS_Limits are strongly related to the FileSystem
class, both being return values from members and associated with storing
file system attributes.  Move their definitions from Utils.h into
FileSystem.h.
2018-01-28 10:09:35 -07:00
Mike Fleetwood 175d27c55d Rename enum FILESYSTEM to FSType
There are too many different types of things named "filesystem" in the
GParted code with the potential to cause confusion.  Namely:

    std::vector<FS> FILESYSTEMS
                              Vector of file system capabilities.

    class FileSystem          Base class interfacing to file system
                              specific executables for querying and
                              modification.

    enum FILESYSTEM           Symbolic constants representing each file
                              system type.

Many recent written or re-written functions already used a variable
named fstype.  Rename enum FILESYSTEM to enum FSType to clearly
distinguish it from the other things with very similar names.  Only
changing the name of the enumeration, not the name of variables of that
type too because that is a lot more lines of code and those can be
changed when the relevant code is re-written.
2018-01-28 10:09:35 -07:00
Mike Fleetwood 32c483c314 Fix cannot format error dialog which always reported the file system as encrypted
Try to format an existing partition with a file system which doesn't
fit.  The error dialog reporting the partition as too small or too large
always claimed the file system was encrypted, whether it was or not.
For example trying to format a 128 MiB partition as btrfs produces this
error dialog:

    (-) Cannot format this file system to [Encrypted] btrfs
        A [Encrypted] btrfs file system requires
        a partition of at least 256.00 MiB.
                                                   [  OK  ]

This commit:
    88136c96d7
    Extend functions generating encrypted file system string (#774818)
just completely missed handling the case for non-encrypted file systems
in Utils::get_filesystem_string().  Add the missed code.
2018-01-28 10:09:35 -07:00
Mike Fleetwood 46bf5a383e Extract common code into GParted_Core::get_filesystem_limits() (#787204)
There are multiple repetitions of the same code getting a FileSystem
object, checking for NULL and then calling the file system specific
get_filesystem_limits().  Extract that into a common function.

GParted_Core::get_filesystem_limits() can't use the file system from the
passed Partition object because that is the current file system which
will be different from the intended file system for new and format
operations.  So would look up the wrong derived FileSystem specific
object and call the wrong get_filesystem_limits().  Hence still needing
fstype as a separate parameter to pass the intended file system.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood ae2a8723b5 Set dynamic UDF file system size limits (#787204)
UDF file system minimum and maximum size limits are defined in terms of
numbers of file system blocks.  So when resizing an existing file system
compute the byte size limits from the existing UDF file system's block
size.  Alternatively when creating a new UDF file system use the
device's sector size as the multiplier instead.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 668957c0a4 Pass Partition object to get_filesystem_limits() (#787204)
As described in the previous commit, this is so that file system
specific implementations can dynamically determine size limits based on
Partition object attributes: such as the device sector size and the file
system block size.  (Assuming set_used_sectors() sets
partition.fs_block_size for the type of file system in question).

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood f8b38b7b31 Reorder code in Win_GParted::activate_paste() (#787204)
Background information about UDF is that when creating a file system
it's block size must match the underlying device's sector size.  For
optical media like CDs and DVDs that is 2K.  For hard drives that is
usually 512 bytes or 4K.  However if a UDF file system has been copied
from a device with a different sector size the UDF block size won't
match the sector size.  Linux will happily mount such UDF file system.

Therefore the derived udf::get_filesystem_limits() will need access to
the file system block size when determining the size limits of an
existing UDF file system being resized and use the device sector size
when a new UDF file system is being created.  All this can be queried
from an appropriate Partition object passed to get_filesystem_limits().
All the calls to get_filesystem_limits() have an appropriate Partition
object available already, except in Win_GParted::activate_reformat()
when composing a format operation.  Or more correctly
activate_reformat() constructs temp_ptn, a suitable Partition object,
including with fs_block_size member defaulting to -1 indicating not a
resize, but not until after the file system size limits had been checked
and get_filesystem_limits() called.

Therefore reorder the code in activate_paste() so that the file system
size limits are checked after the wanted Partition object has been
created.  No functional change with this commit.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood e234df6b2e Remove struct FS members .MIN & .MAX (#787204)
All the code has been switched to call get_filesystem_limits() and use
struct FS_Limits.  Remove struct FS members .MIN & .MAX.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood d5cd6ca349 Use struct FS_Limits in Win_GParted::activate_format() (#787204)
Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 8729556778 Use struct FS_Limits in GParted_Core::create() (#787204)
Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 4fa262d7e3 Switch to using struct FS_Limits inside Dialog_Partition_New (#787204)
Change Dialog_Partition_New to use a fs_limits rather than struct FS
and .MIN and .MAX.  No passing of struct FS_Limits required.  Just use
the FILESYSTEMS vector of struct FS to provide the file system type and
look up it's size limits each time the selection changes.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 53b7a75894 Query and pass struct FS_Limits into Dialog_Partition_Resize_Resize_Move (#787204)
Refactor Win_GParted::activate_resize() to query the file system size
limits using the new get_filesystem_limits() method and pass those
limits into the dialog class as struct FS_Limits.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood fe7b734792 Switch to using struct FS_Limits inside Dialog_Partition_Resize_Move (#787204)
Changes the internal code in Dialog_Partition_Resize_Move to use
fs_limits instead of fs.MIN and fs.MAX.  The limits are still passed
into the constructor via struct FS and it's members .MIN and .MAX but
immediately used to assign to fs_limits.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 285c24a82a Query and pass struct FS_Limits into Dialog_Partition_Copy (#787204)
Refactor Win_GParted::activate_paste() to query the file system size
limits using the new get_filesystem_limits() method and pass those
limits into the the dialog class as struct FS_Limits.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood fc436595fd Switch to using struct FS_Limits inside Dialog_Partition_Copy (#787204)
Adds working copy fs_limits member into common Dialog_Base_Partition
class.  Changes the internal code in Dialog_Partition_Copy class to use
fs_limits instead of fs.MIN and fs.MAX.  The limits are still passed
into the constructor via object of struct FS and it's members .MIN and
.MAX but immediately used to assign to the fs_limits member.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood aea0070799 Assign to duplicate FS_Limits (#787204)
Duplicate the assignment of file system size limits into
struct FS_Limits, matching the fixed values currently assigned to
struct FS members .MIN and .MAX.

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Pali Rohár 2f532be9f9 Use external tools udfinfo and udflabel for UDF file system (#792052)
Those external tools were introduced in version 2.0 of udftools package
and can show or change UDF label, UDF uuid and can provide information
needed for counting total/free sectors.

Bug 792052 - Add support for changing UDF label/uuid and show disk usage
2018-01-04 17:02:53 +00:00
Mike Fleetwood b04dbbc357 Rename function and reword text for rollback of failed file system move
To better reflect specifically that it is a failed (internally
implemented) file system move which is being rolled back.
2018-01-02 10:34:52 -07:00
Mike Fleetwood f54dd10707 Fix rollback when growing a partition by more than twice fails (#791875)
Attempt to grow a partition to more than twice it's size.  If committing
that change to the partition fails in such a way that the new larger
partition boundaries are not written to the disk drive then rolling back
will fail with libparted error:
    Can't have overlapping partitions.

Example operation details:

    Grow /dev/sdb8 from 1.00 GiB to 2.20 GiB
    * calibrate /dev/sdb8                                      (SUCCESS)
    * check file system on /dev/sdb8 for errors and (if poss...(SUCCESS)
    * grow partition from 1.00 GiB to 2.20 GiB                 (ERROR)
    * attempt to rollback failed change to the partition       (ERROR)
        original start: 7350272
        original end:   9447423
        original size:  2097152 (1.00 GiB)
      * libparted messages                                     (ERROR)
          Can't have overlapping partitions.

What happened is that resize_move_partition() passed the new Partition
object to resize_move_partition_implement() as the source partition for
the rollback, and than called ped_disk_partition_by_sector() with a
sector in the middle to identify the partition to be changed.  However
the new partition was never written to the drive so in the middle was
outside the old smaller partition.  Therefore libparted identified empty
space after the partition, rather than the partition itself, as the
intended target so when ped_disk_set_partition_geom() was called it
reported error "Can't have overlapping partitions" because it thought
another partition was being created with the same boundaries as the old
partition, rather than the boundaries of the old partition being
updated.

The same error also occurs when rolling back a failed partition change
as part of a move operation when the middle of the new partition falls
outside of the boundaries of the old partition.

Fix by making a temporary Partition object from the intersection of the
old and new partition boundaries just to be used to identify the
partition being changed to libparted.  As this is only rolling back a
single step adjusting the partition boundaries as part of a resize
and/or move operation, the old and new partition boundaries must
intersect (and in fact that intersection contains the file system data).

Bug 791875 - Rollback specific failed partition change steps
2018-01-02 10:34:52 -07:00
Mike Fleetwood 0b5bf83b22 Enable failed partition change rollback for selected steps (#791875)
The general rule is that:
1) For a partition change step BEFORE a file system change step,
   rollback on failure;
2) For a partition change step AFTER a file system change step, don't
   rollback on failure.

Examining every case where resize_move_partition() is called and whether
rollback on failure is wanted or not:

* In resize_move()
    Resize / move extended partition.  No associated file system change.
  NO ROLLBACK
    Just to keep possibly applied operation.

* #1 in move()
    Making all encompassing partition before moving file system.
  ROLLBACK
    To restore partition boundaries back to those of the file system.

* #2 in move()
    Recreating original partition boundaries after file system move
    failed or was cancelled and has been rolled back.
  NO ROLLBACK
    To keep updated partition boundaries to match restored file system
    data.

* #3 in move()
    Replacing all encompassing partition with final partition after
    successful file system move.
  NO ROLLBACK
    Keep new partition boundaries to match moved file system.

* #1 in resize_encryption()
    Making the partition larger before growing closed LUKS encrypted
    data.
  ROLLBACK
    Restore partition boundaries back to those of the closed LUKS
    encrypted data.

* #2 in resize_encryption()
    Shrinking the partition after open LUKS mapping has been shrunk, but
    before swap is re-created (smaller).
  NO ROLLBACK
    Difficult case because the partition shrink is in the middle of a
    LUKS shrink and a swap shrink (re-create).  If swap was actually
    shrunk like other types of file system, rather than re-created, then
    the operation sequence would be (1) shrink swap, (2) shrink LUKS
    encryption, (3) shrink partition.  In this hypothetical case and the
    actual case no rollback is preferred to try to keep the new
    partition boundaries match the shrunk open LUKS encryption mapping.

* #3 in resize_encryption()
    Grow the partition before growing open LUKS mapping and re-creating
    swap larger.
  ROLLBACK
    Restore partition boundaries back to those of the smaller open LUKS
    encryption mapping.

* #4 in resize_encryption()
    Shrink the partition after shrinking the file system and open LUKS
    encryption mapping.
  NO ROLLBACK
    Keep new smaller partition boundaries to match shrunk encrypted file
    system.

* #5 in resize_encryption()
    Grow the partition before growing the open LUKS encryption mapping
    and file system.
  ROLLBACK
    Restore partition boundaries back to those of the not yet grown
    encrypted file system.

* #1 in resize_plain()
    Resize partition before re-creating swap a different size.
  ROLLBACK
    Restore partition boundaries back to those of the not yet resized
    (re-created) swap space.

* #2 in resize_plain()
    Shrink partition after shrinking the file system.
  NO ROLLBACK
    Keep new smaller partition boundaries to match shrunk file system.

* #3 in resize_plain()
    Grow partition before growing the file system.
  ROLLBACK
    Restore partition boundaries back to those of the not yet grown
    file system.

Removes the default value from the rollback_on_fail parameter so
rollback or not has to be explicitly specified for every call of
resize_move_partition().

Bug 791875 - Rollback specific failed partition change steps
2018-01-02 10:34:52 -07:00
Mike Fleetwood 0f16703bbb Implement rollback of failed partition resize/move steps (#791875)
Even after implementing a fix for bug 790418 "Unable to inform the
kernel of the change message may lead to corrupted partition table"
GParted/libparted can still encounter errors informing the kernel of the
new partition layout.  This has been seen with GParted on CentOS 7 with
libparted 3.1.

In such a case the partition has been successfully written to the disk
but just informing the kernel failed.  This is a problem because when a
partition is being moved in advance of a file system move step, failure
to inform the kernel leaves the partition boundaries not matching the on
disk limits of the file system.  For a move to the left this leaves the
partition reported as unknown, apparently losing the user's data.

For example start with a 512 MiB partition containing an XFS file
system.  This is recognised by blkid and parted, hence also by GParted.

    # blkid /dev/sdb1
    /dev/sdb1: UUID=... TYPE="xfs" PARTUUID="37965980-01"
    # parted /dev/sdb unit s print
    Model: ATA VBOX HARDDISK (scsi)
    Disk /dev/sdb: 16777216s
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    Disk Flags:

    Number  Start     End       Size      Type     File system  Flags
     1      1048576s  2097151s  1048576s  primary  xfs

Now move the partition 100 MiB to the left and have it fail to inform
the kernel after the first partition change step.  Operation details:

    Move /dev/sdb1 to the left                                 (ERROR)
    * calibrate /dev/sdb1                                      (SUCCESS)
    * check file system on /dev/sdb1 for errors and (if poss...(SUCCESS)
    * grow partition from 512.00 MiB to 612.00 MiB             (ERROR)
        old start: 1048576
        old end: 2097151
        old size: 1048576 (512.00 MiB)
        requested start: 843776
        requested end: 2097151
        requested size: 1253376 (612.00 MiB)
      * libparted messages                                     (ERROR)
          Error informing the kernel about modifications to partition
          /dev/sdb1 -- Device or resource busy.  This means Linux won't
          know about any changes you made to /dev/sdb1 until you reboot
          -- so you shouldn't mount it or use it in any way before
          rebooting.  Failed to add partition 1 (resource temporarily
          unavailable)

Now because the start of the partition is 100 MiB before the start of
the file system, the file system is no longer recognised, and apparently
the user's data has been lost.

    # blkid /dev/sdb1
    /dev/sdb1: PARTUUID="37965980-01"
    # parted /dev/sdb unit s print
    ...
    Number  Start    End       Size      Type     File system  Flags
     1      843776s  2097151s  1253376s  primary

It doesn't matter why updating the partition failed, even if it was
because of an error writing to the disk.  Rollback of the change to the
partition should be attempted.  The worst case scenario is that rollback
of the change fails, which is the equivalent to how the code worked
before this patch set.

However in other cases where the partition boundaries are being updated
after a file system move or shrink step then the partition should be
updated to match the new location of the file system itself.  And no
rollback is wanted.  If the failure was only informing the kernel then
in fact the partition has actually been updated on disk after all.

So each partition resize/move step needs examining on a case by case
basis to decide if rolling back the change to the partition is wanted or
not.

This patch only adds partition change rollback into
resize_move_partition().  Rollback remains disabled until all cases are
examined in the following patch.

Bug 791875 - Rollback specific failed partition change steps
2018-01-02 10:34:52 -07:00
Mike Fleetwood 93ccc79e3a Extract common code into update_dmraid_entry() (#791875)
Extract common code which updates a DMRaid device mapper entry into a
sub-function.  This will also be needed when adding rollback of a
partition change on failure.

Bug 791875 - Rollback specific failed partition change steps
2018-01-02 10:34:52 -07:00
Mike Fleetwood 890d5a93a7 Extract code into resize_move_partition_implement() (#791875)
Extract the code which actually implements the partition change into a
sub-function ready for adding rollback of the change on failure.

Bug 791875 - Rollback specific failed partition change steps
2018-01-02 10:34:52 -07:00
Mike Fleetwood ff0360eb4f Match up OperationDetail creation and status setting for internal copy (#790842)
This is not required, but it is more logical to have an OperationDetail
object created and it's final status set in the same function rather
than split between caller and callee.  So move creation of
"copy %1 using a block size of %2" OperationDetail objects into
GParted_Core::copy().

Also introduces a couple of variables to remove some recomputation:
benchmark_od & remaining_length.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-12-11 13:53:09 -07:00
Mike Fleetwood e5ccb3b8bc Set OperationDetail status last during internal copy benchmarking (#790842)
Performing a copy or move operation which uses GParted's internal copy
routine triggered the new GParted bug message.  Example operation
details:

  Copy /dev/sdb8 to /dev/sdb (start at 4.51 GiB)               (SUCESSS)
  * calibrate /dev/sdb8                                        (SUCCESS)
  * check file system on /dev/sdb8 for errors and (if possib...(SUCCESS)
  * create empty partition                                     (SUCCESS)
  * set partition type on /dev/sdb9                            (SUCCESS)
  * copy file system from /dev/sdb8 to /dev/sdb9               (SUCCESS)
      using internal algorithm
      copy 1.00 GiB
    * finding optimal block size
      * copy 16.00 MiB using a block size of 1.00 MiB          (SUCCESS)
          16.00 MiB of 16.00 MiB copied
          GParted Bug: Adding more information to the result...(WARNING)
          0.797269 seconds
      * copy 16.00 MiB using a block size of 2.00 MiB          (SUCCESS)
      * copy 16.00 MiB using a block size of 4.00 MiB          (SUCCESS)
      * copy 16.00 MiB using a block size of 8.00 MiB          (SUCCESS)
      * copy 16.00 MiB using a block size of 16.00 MiB         (SUCCESS)
        optimal block size is 1.00 MiB
    * copy 944.00 MiB using a block size of 1.00 MiB           (SUCCESS)

This is because when performing the initial benchmarking copies the time
taken by each copy is added to the operation detail results in the
calling GParted_Core::copy_blocks() after the final status was set in
CopyBlocks::copy() with set_success_and_capture_errors().  Fix by
setting the final status in the parent function after adding the time to
the benchmark copies.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-12-11 13:53:09 -07:00
Mike Fleetwood c7ee9934f1 Make OperationDetail no_more_children bug message translatable (#790842)
To be consistent with all previous bug messages being translatable.

Also only mark the bug as a warning instead of an error because the bug
doesn't cause any disk drive operations to fail.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-12-04 13:32:21 -07:00
Mike Fleetwood 2f53876c0f Wait for the kernel and udev to settle partitions for a second time (#790418)
There is still another subtle issue.  When GParted_Core::commit() closes
the device, the kernel initiates a second set of events which removes
and re-adds the partitions again.  Need to wait for these to complete
to prevent any following step failing with missing partition device
nodes.

Bug 790418 - "Unable to inform the kernel of the change" message may
             lead to corrupted partition table
2017-11-29 12:58:48 -07:00
Mike Fleetwood f49f0bb2b8 Avoid libparted failing to inform the kernel about partition changes (#790418)
Operations involving modifications to a partition are sometimes failing
with a libparted error informing the kernel about modifications to
partitions.  For example I encountered these errors when just creating a
fourth partition on CentOS 7 in a VirtualBox VM.  Operation results:

    Create Primary Partition #1 (ext4, 4.73 GiB) on /dev/sdb   (ERROR)
    * create empty partition                                   (ERROR)
      * libparted messages                                     (ERROR)
        * Error informing the kernel about modification to partition
          /dev/sdb1 -- Device or resource busy.  This means Linux won't
          know about any changes you made to /dev/sdb1 until you reboot
          -- so you shouldn't mount it or use it in any way before
          rebooting.
        * Failed to add partition 1 (Resource temporarily unavailable)

Those two libparted messages were presented in "Libparted Error" dialogs
and [Cancel] was selected both times.

        Libparted Error
    (-) Error informing the kernel about modifications to partition
        /dev/sdb1 -- Device or resource busy.  This means Linux won't
        know about any changes you made to /dev/sdb1 until you reboot --
        so you shouldn't mount it or use it in any way before rebooting.
                                                   [ Cancel ] [ Ignore ]

        Libparted Error
    (-) Failed to add partition 1 (Resource temporarily unavailable)
                                                    [ Retry ] [ Cancel ]

This is the edited output showing GParted print debugging, stracing of
GParted and monitoring of udev events for this case.

    # ./gpartedbin /dev/sdb
    ======================
    libparted : 3.1
    ======================
    ...
     24.541604 +23.923435 create_partition()   start (new_partition, optdet, min_size=0)  new_partition.device_path="/dev/sdb"
     24.556101 +0.014497 create_partition()   type=PED_PARTITION_NORMAL
     24.556354 +0.000253 commit()             start (lp_disk)  lp_disk->dev->path="/dev/sdb"
    D: strace pid 18054.  Press [Return] to continue.
    ^Z
    [1]+  Stopped          ./gpartedbin /dev/sdb

    # udevadm monitor &
    [2] 18124
    monitor will print the received events for:
    UDEV - the event which udev sends out after rule processing
    KERNEL - the kernel uevent

    # strace -p 18054 -e open,ioctl,write,close &
    [3] 18129
    strace: Process 18054 attached

    # fg %1
    ./gpartedbin /dev/sdb
    128.175811 +103.619457 commit()             calling ped_disk_commit_to_dev(lp_disk) ...
    open("/dev/sdb", O_RDWR)                = 6
    ioctl(6, BLKFLSBUF)                     = 0
    write(6, "\372\270\0\20\216\320\274\0\260\270\0\0\216\330\216\300\373\276\0|\277\0\6\271\0\2\363\244\352!\6\0"..., 512) = 512
    ioctl(6, BLKFLSBUF)                     = 0
    close(6)
    128.181352 +0.005542 commit()             ped_disk_commit_to_dev(lp_disk) returned true
    128.181475 +0.000122 commit_to_os()       start (lp_disk, timeout=10)  lp_disk->dev->path="/dev/sdb"
    128.181527 +0.000052 commit_to_os()       calling ped_disk_commit_to_os(lp_disk) ...
    open("/dev/sdb", O_RDWR)                = 6
    ioctl(6, BLKFLSBUF)                     = 0
    open("/sys/block/sdb/ext_range", O_RDONLY) = 7
    close(7)                                = 0

    KERNEL[1158935.380543] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    KERNEL[1158935.380565] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[1158935.380578] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)

    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=1, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=2, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=3, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ...

    KERNEL[1158935.380977] change   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb (block)
    KERNEL[1158935.381296] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    KERNEL[1158935.381367] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[1158935.381432] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    KERNEL[1158935.382992] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)

    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=62, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=63, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ioctl(6, BLKPG, {BLKPG_DEL_PARTITION, flags=0, datalen=152, data={start=0, length=0, pno=64, devname="", volname=""}}) = -1 ENXIO (No such device or address)
    ioctl(6, BLKPG, {BLKPG_ADD_PARTITION, flags=0, datalen=152, data={start=1048576, length=1073741824, pno=1, devname="/dev/sdb1", volname=""}}) = -1 EBUSY (Device or resource busy)
    write(2, "Error informing the kernel about"..., 251) = 251
    Error informing the kernel about modifications to partition
    /dev/sdb1 -- Device or resource busy.  This means Linux won't know
    about any changes you made to /dev/sdb1 until you reboot -- so you
    shouldn't mount it or use it in any way before rebooting.

    UDEV  [1158935.384641] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    UDEV  [1158935.390203] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    UDEV  [1158935.390243] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [1158935.462866] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [1158935.469207] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [1158935.471512] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    UDEV  [1158935.492173] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)

    write(2, "Failed to add partition 1 (Resou"..., 60) = 60
    Failed to add partition 1 (Resource temporarily unavailable)
    close(6)

    KERNEL[1158955.730960] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    KERNEL[1158955.731095] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[1158955.731314] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    KERNEL[1158955.731397] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    KERNEL[1158955.731817] change   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb (block)
    KERNEL[1158955.731981] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    KERNEL[1158955.732166] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[1158955.732232] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    KERNEL[1158955.733955] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)

    148.533154 +20.351627 commit_to_os()       ped_disk_commit_to_os(lp_disk) returned false

    UDEV  [1158955.738262] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    UDEV  [1158955.738460] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [1158955.738525] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)

    148.537648 +0.004494 execute_command()    udevadm settle --timeout=10

    UDEV  [1158955.740864] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [1158955.760192] change   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb (block)
    UDEV  [1158955.801211] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [1158955.815262] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [1158955.815314] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    UDEV  [1158955.828134] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)

    148.630797 +0.093149 execute_command()              exit status 0
    148.630882 +0.000085 commit_to_os()                 return false
    D: stop strace pid 18054.  Press [Return] to continue.
    ^Z
    [1]+  Stopped          ./gpartedbin /dev/sdb

    # kill %3
    strace: Process 18054 detached
    [3]-  Done             strace -p 18054 -e open,ioctl,write,close

    # kill %2
    [2]   Done             udevadm monitor

    # fg %1
    ./gpartedbin /dev/sdb
    173.700143 +25.069261 commit()             return false
    173.700470 +0.000327 create_partition()   return false

What happens is that GParted calls ped_disk_commit_to_dev() which opens
the device, writes the updated partition table and closes the device.
When the device closes the kernel initiates asynchronous uevents and
user space udev rules which remove and re-add all the partitions.  In
the mean time GParted calls ped_disk_commit_to_os() to inform the kernel
of the changes to the partition table.  This involves opening the
device, using ioctl() to remove all possible partitions [1] and re-add
needed partitions.  It finds partitions 1 to 3 already removed and
accepts this along with all other non-existent partitions up to 64.
When it tries to re-add partition 1 the ioctl() BLKPG_ADD_PARTITION call
returns EBUSY.  Presumably because the partition is in use by udev which
is in the process of running the user space rules associated with
removing and re-adding it.  Then ped_disk_commit_to_os() closes the
device which initiates a second round of asynchronous uevents and user
space udev rules removing and re-adding all the partitions again.

So in summary the kernel and udev are removing and re-adding the
partitions exactly when libparted is trying to do exactly the same
thing!

[1] The algorithm in libparted 3.1 is to try to remove all possible
    partitions, 64 for this kernel, followed by re-adding the needed
    partitions.

    parted/libparted/arch/linux.c:_disk_sync_part_table()
    http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.1#n2541

Partprobe has had exactly the same issue with failing to inform the
kernel about modifications to the partition table [2].  This was fixed
in libparted post v3.2 release by this commit [3].

[2] rhbz#1339705 - ceph-disk prepare: Error: partprobe /dev/vdb failed :
    Error: Error informing the kernel about modifications to partition
    /dev/vdb1 -- Device or resource busy.

    https://bugzilla.redhat.com/show_bug.cgi?id=1339705

[3] partprobe: Open the device once for probing

    Previously there were 3 open/close pairs for the device, which may
    result in triggering extra udev actions. Instead, open it once at
    the start of process_dev and close it at the end.

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=cfafa4394998a11f871a0f8d172b13314f9062c2

Implement the same fix as implemented for partprobe.  Hold a file handle
open which libparted can use internally to avoid having to open() and
close() the device itself twice, once for each of the calls
ped_disk_commit_to_dev() and ped_disk_commit_to_os().  This avoids the
first close() initiating the kernel and udev to remove and re-add the
partitions exactly when ped_disk_commit_to_os() is trying to do the same
thing.

Bug 790418 - "Unable to inform the kernel of the change" message may
             lead to corrupted partition table
2017-11-29 11:37:26 -07:00
Mike Fleetwood f9ae35584b Remove left behind #include "ProgressBar.h"
The includes were missed being removed by this earlier refactoring
commit which reduced direct access to the single ProgressBar object:
    b1313281bd
    Simplify use of the progress bar via OperationDetail (#760709)
2017-11-26 10:53:52 -07:00
Mike Fleetwood 8c5c13d613 Rename OperationDetailStatus STATUS_N_A to STATUS_WARNING
Make the enumeration name match it's use as indicating a warning.  Also
spell SUCCESS correctly.  Follow on to icon variable names too.
2017-11-26 10:53:52 -07:00
Mike Fleetwood 0688662055 Identify libparted messages as either success or error (#790842)
All libparted messages were reported as informational, even for a step
which failed.  Instead identify libparted messages as either
informational or errors depending on whether this step was successful
or not respectively.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:24 -07:00
Mike Fleetwood b4cd5da4f7 Set the status last for the OperationDetails in mk/rm_temp_dir() (#790842)
Resizing any unmounted file system which has to be mounted to be resized
triggered the new GParted bug message.  However the operation did
complete successfully.  Example operation details:

  Grow /dev/sdb8 from 1.00 GiB to 1.50 GiB                     (SUCCESS)
  * calibrate /dev/sdb
  * check file system on /dev/sdb8 for errors and (if possib...(SUCCESS)
  * grow partition from 1.00 GiB to 1.50 GiB                   (SUCCESS)
  * grow file system to fill the partition                     (SUCCESS)
    * mkdir -v /tmp/gparted-wvH0Ez                             (SUCCESS)
      * GParted Bug: Adding another child after no_more_chil...(ERROR)
      * Created directory /tmp/gparted-wvH0Ez
    * mount -v -t btrfs '/dev/sdb8' '/tmp/gparted-wvH0Ez'      (SUCCESS)
    * btrfs filesystem resize 1:max '/tmp/gparted-wvH0Ez'      (SUCCESS)
    * umount -v '/tmp/gparted-wvH0Ez'                          (SUCCESS)
    * rmdir -v /tmp/gparted-wvH0Ez                             (SUCCESS)
      * GParted Bug: Adding another child after no_more_chil...(ERROR)
      * Removed directory /tmp/gparted-wvH0Ez

This is because set_success_and_capture_errors() was called first and
the child details added after.  Reverse this ordering to fix.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:19 -07:00
Mike Fleetwood 2040aabd22 Transition other code to callback error collection (#790842)
Transition all remaining code, DMRaid and file system code, to use the
new method of reporting success of a step and automatic error
collection.  None of this code calls libparted so can't generate any
libparted exceptions.  This is just for consistency so all code follows
the same pattern using set_success_and_capture_errors().

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood bf1e87ecf3 Refactor ntfs resize code (#790842)
Refactor nested if-then-else into a sequence of if fail return early.
Makes the code simpler to understand and converts separate
OperationDetail::set_status() calls for success or error into a single
call using ternary conditional matching how it is or was done everywhere
else.  This is also ready for status and error capture refactoring.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 76088a39de Transition code using libparted to callback error collection (#790842)
Transition GParted block copying code and partition manipulation code,
which uses libparted API, to the new method of reporting success of a
step and automatic error collection.  Libparted exceptions are now
reported with the step at which they occurred.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 0a78c39856 Allow child OperationDetails to emit error capture callback too (#790842)
Just copies the callback into each newly added child detail.  As there
are no more uses of set_success_and_capture_errors() yet, libparted
errors are still only captured once at the top-level of each operation.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 23939331f6 Capture libparted messages via callback at top-level only (#790842)
Replace the explicit adding of libparted exception messages with a
callback to do it instead, and fire the callback just once per operation
by only changing the very top-level OperationDetail to use the new
set_success_and_capture_errors().  Therefore this still produces exactly
the same operation details with libparted messages at the end of each
operation.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 2ed7feb2f5 Add mechanism to capture exception messages into an OperationDetail (#790842)
All code implementing a step of an operation follows this pattern:

    od.add_child(OperationDetail("Step heading"));
    od.get_last_child().add_child(OperationDetail("More details"));
    // Do step
    success = ...
    od.get_last_child().set_status(success ? STATUS_SUCCESS
                                           : STATUS_ERROR);

At this point any libparted messages reported via exceptions need to be
added into the OperationDetail tree.  Also adding further children into
the tree after collecting those errors needs to be prohibited (as much
as the previous patch prohibited it).

Add a new method which will replace the final set_status() call above
like this which set the status, captures the errors and flags that
further children shouldn't be added:

    ...
    od.get_last_child().set_success_and_capture_errors(status);

It emits a callback to capture the errors to provide flexibility and so
that the OperationDetail class doesn't have to get into the details of
how GParted_Core saves libparted exception messages.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:52:54 -07:00
Mike Fleetwood f8f9a72de6 Add mechanism to stop adding more child OperationDetails (#790842)
Want functionality to prevent further child details being added to an
OperationDetail.  This is so that the captured libparted error messages
are always the last child in the list, and more details (at that point
in the tree) can't be added.

For example we want GParted to report like this:

  Move /dev/sdb3 to the right and shrink it from 1.14 GiB to...(SUCCESS)
  ...
  * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
    * old start: 4464640
      old end: 6856703
      old size: 2392064 (1.14 GiB)
    * new start: 4464640
      new end: 6561791
      new size: 2097152 (1.00 GiB)
    * libparted messages                                       (INFO)
      * DEBUG: GParted generated synthetic libparted excepti...

and not like this:

  Move /dev/sdb3 to the right and shrink it from 1.14 GiB to...(SUCCESS)
  ...
  * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
    * old start: 4464640
      old end: 6856703
      old size: 2392064 (1.14 GiB)
    * libparted messages                                       (INFO)
      * DEBUG: GParted generated synthetic libparted excepti...
    * new start: 4464640
      new end: 6561791
      new size: 2097152 (1.00 GiB)

So actually preventing the addition of more child details would stop
users seeing information they should see.  So instead just report a bug
message into the operation details.  This doesn't stop anything, but the
bug message will be seen and allow us to fix GParted.

So far nothing is enforced.  This patch just adds the mechanism to
report a bug when a new child detail is added when prohibited.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:06:37 -07:00
Mike Fleetwood 3c1fdd14f4 Also stop OperationDetail execution timer when setting status to N/A (#790842)
PATCH SET SUMMARY:

Libparted exception messages are reported into the operation details at
the end of each separate operation.  For operations which involve
multiple steps of partition manipulation there is no way to identify
which exceptions occurred with which steps.

Example resize/move operation in which multiple libparted exceptions
were raised:

  Move /dev/sdb to the right and shrink it from 1.15 GiB to ...(ERROR)
  * calibrate /dev/sdb3                                        (SUCCESS)
  * check file system on /dev/sdb3 for errors and (if possib...(SUCCESS)
    * e2fsck -f -y -v -C 0 '/dev/sdb3'                         (SUCCESS)
  * shrink file system                                         (SUCCESS)
    * resize2fs -p 'dev/sdb3' 1048576K                         (SUCCESS)
  * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
  * check file system on /dev/sdb3 for errors and (if possib...(SUCCESS)
    * e2fsck -f -y -v -C 0 '/dev/sdb3'                         (SUCCESS)
  * grow partition from 1.00 GiB to 1.12 GiB                   (SUCCESS)
  * move file system to the right                              (SUCCESS)
    * e2image -ra -p -O 134217728 '/dev/sdb3'                  (SUCCESS)
  * shrink partition from 1.12 GiB to 1.00 GiB                 (ERROR)
  * libparted messages                                         (INFO)
    * DEBUG: GParted generated synthetic libparted exception...
    * Error informing the kernel about modifications to part...
    * Error informing the kernel about modifications to part...
    * DEBUG: GParted generated synthetic libparted exception...
    * DEBUG: GParted generated synthetic libparted exception...

But there is no way to know which of the libparted steps: 1 calibrate or
3 partition resize steps encountered which exceptions.

Fix this by reporting the libparted messages into the operation details
at the point at which they occur.  Then the above example would become:

  Move /dev/sdb to the right and shrink it from 1.15 GiB to ...(ERROR)
  * calibrate /dev/sdb3                                        (SUCCESS)
  * check file system on /dev/sdb3 for errors and (if possib...(SUCCESS)
    * e2fsck -f -y -v -C 0 '/dev/sdb3'                         (SUCCESS)
  * shrink file system                                         (SUCCESS)
    * resize2fs -p 'dev/sdb3' 1048576K                         (SUCCESS)
  * shrink partition from 1.14 GiB to 1.00 GiB                 (SUCCESS)
    * libparted messages                                       (INFO)
      * DEBUG: GParted generated synthetic libparted excepti...
  * check file system on /dev/sdb3 for errors and (if possib...(SUCCESS)
    * e2fsck -f -y -v -C 0 '/dev/sdb3'                         (SUCCESS)
  * grow partition from 1.00 GiB to 1.12 GiB                   (SUCCESS)
    * libparted messages                                       (INFO)
      * Error informing the kernel about modifications to pa...
      * Error informing the kernel about modifications to pa...
      * DEBUG: GParted generated synthetic libparted excepti...
  * move file system to the right                              (SUCCESS)
    * e2image -ra -p -O 134217728 '/dev/sdb3'                  (SUCCESS)
  * shrink partition from 1.12 GiB to 1.00 GiB                 (ERROR)
    * libparted messages                                       (ERROR)
      * DEBUG: GParted generated synthetic libparted excepti...

THIS PATCH:

Small change so that setting the status of an OperationDetail to N/A,
warning, also stops the execution timer if it was running.  Matching
what happens when the status is set to either success or error.

This is to avoid having to set status twice, first time just to stop the
timer, and second time to set it to the desired status when reporting a
warning.

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:06:37 -07:00
Mike Fleetwood 33a535390e Extract common code into new method get_lp_partition() 2017-10-03 08:22:19 -06:00
Mike Fleetwood 12dcebcb47 Calibrate whole disk device partitions again (#788308)
Fix up following switch from whole_device flag to TYPE_UNPARTITIONED.

Also calibrate the type for whole disk device partitions.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood bcd03e5c41 Restore Information dialog display of whole disk devices (#788308)
So they display as previously; as all grey in the graphic and with only
the correct attributes shown.

Fix up following switch from whole_device flag to TYPE_UNPARTITIONED.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood c1807ca504 Disallow formatting of unrecognised whole disk devices again (#788308)
Fix up following switch from whole_device flag to TYPE_UNPARTITIONED.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood b1967e7211 Allow Partition > New on unallocated whole disk devices again (#788308)
Fix up following switch from whole_device flag to TYPE_UNPARTITIONED.

Again use FS_UNALLOCATED to determine if a partition represents
unallocated space and creation of a new partition should be allowed.
This is so that trying to create a new partition on a whole disk device
shows the "No partition table found on device /dev/DEV" warning again.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood fa5ed1fb90 Select unallocated whole disk devices again (#788308)
After the change from whole_device flag to TYPE_UNPARTITIONED,
unallocated whole disk devices are no longer automatically selected
because the partition type is no longer TYPE_UNALLOCATED.  Fix by
checking for file system type FS_UNALLOCATED when identifying the
largest unallocated space.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood d5a20697c8 Display unrecognised whole disk devices as all grey again (#788308)
Following the switch from whole_device flag to TYPE_UNPARTITIONED,
unallocated space can be found in two partition types:
    TYPE_UNALLOCATED
    TYPE_UNPARTITIONED  (only when filesystem == FS_UNALLOCATED)

As the file system in both cases is FS_UNALLOCATED check for that when
determining whether a partition is unallocated or not.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood ea269cc929 Switch from whole_device flag to TYPE_UNPARTITIONED (#788308)
Remove whole_device flag and replace with new partition type
TYPE_UNPARTITIONED.  Minimally adapt the remaining code to compile and
run.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood 24123c4298 Update partition related checks in set_valid_operations() (#788308)
Update the partition can be named and partition flags can be managed
checks from being disallowed on unallocated partition types, to being
allowed on primary, logical and extended partition types.  This is in
preparation for the introduction of new unallocated partition type.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood 59185b133c Add FILESYSTEM_MAP[FS_EXTENDED] entry
Now when refreshing the devices, GParted_Core::read_label() calls
GParted_Core::get_fs() with parameter FS_EXTENDED.

Before this change, get_fs() would fail to find file system capabilities
set for FS_EXTENDED 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_EXTENDED and adds this
entry into the FILESYSTEMS vector.  Then get_fs() finds that not
supported capabilities set for FS_EXTENDED 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.

See this earlier commit doing the same thing:
    7870a92b80
    Add FILESYSTEM_MAP[FS_UNALLOCATED] entry
2017-10-03 08:22:19 -06:00
Mike Fleetwood 326df46af2 Remove some unnecessary extended partition checks from GParted_Core (#788308)
For example GParted_Core::read_label() is already called for empty
partitions where .filesystem = FS_UNKNOWN.  In that case get_fs()
returns an unsupported capability set with all capabilities set to
FS::NONE.  The same would be true extended partitions where .filesystem
= FS_EXTENDED too; get_fs() would return an unsupported capability set
with all capabilities set to FS::NONE.

Therefore the if not extended partition condition around the switch
statements is not necessary in GParted_Core::read_label(), read_uuid(),
label_filesystem() and change_uuid().  Remove.

This also achieves removal of some uses of partition type enumerations
in advance of the introduction of new partition type TYPE_UNPARTITIONED.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:19 -06:00
Mike Fleetwood 400864a65e Add and use Partition::set_unpartitioned() method (#788308)
PATCHSET OVERVIEW:

When unpartitioned drive read-write support was added this commit added
a whole_device flag:
   5098744f9a
   Add whole_device flag to the partition object (#743181)

Using a whole_device flags now seems not the correct way to model
unpartitioned drives.  GParted models an uninitialised drive as:
    .path         = _("uninitialized")
    .type         = TYPE_UNALLOCATED
    .whole_device = true
    .filesystem   = FS_UNALLOCATED
and a whole drive file system, using ext4 for example, as:
    .path         = "/dev/sdb"
    .type         = TYPE_PRIMARY
    .whole_device = true
    .filesystem   = FS_EXT4
No partitioning changed yet the type of the partition in the model
changed between TYPE_UNALLOCATED and TYPE_PRIMARY depending on whether
the whole drive contains a recognised file system or not.

The partition object describing a file system within a LUKS encryption
mapping is another case of the model not matching reality.
    .path         = /dev/mapper/crypt_sdb1_crypt
    .type         = TYPE_PRIMARY
    .whole_device = true
    .filesystem   = FS_EXT4
There is no partition table within the encryption mapping, the file
system fills it, but GParted records it as a primary partition.

Make TYPE_UNALLOCATED and TYPE_PRIMARY be reserved for representing
unallocated space and primary partitions within a partitioned disk drive
and introduce new TYPE_UNPARTITIONED for all cases of an unpartitioned
whole disk drive.

The GParted UI does differentiate between an unallocated whole disk
device and anything else by requiring a partition table to be created
first, even if that is just the loop partition table.  That
determination can simply look for the partition object containing file
system type FS_UNALLOCATED instead.

THIS PATCH:

Create set_unpartitioned() helper method to set a partition object to
represent a whole disk drive and use everywhere such an object is
modelled.  This matches what existing methods Set_Unallocated() and
indeed Set() do for unallocated space and any type of partition
respectively.

For now the partition type is still set to either TYPE_UNALLOCATED or
TYPE_PRIMARY so the rest of the code base remains the same.
TYPE_UNPARTITIONED will be introduced later.

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:06 -06:00
Mike Fleetwood f5d3f97c7a Pass string literals directly to execute_command()
There were a few cases of creating a local string variable from a
literal and then passing the variable to execute_command() like this:
    Glib::ustring cmd = "whatever";
    Utils::execute_command( cmd, ... );

This creates an unnecessary local variable.  Instead pass the string
literal directly to Utils::execute_command() like this:
    Utils::execute_command( "whatever", ... );
This also make the code a little bit more grep friendly.
2017-09-25 09:25:17 -06:00
Mike Fleetwood 25d2aa341c Stop nicing external commands run by the DMRaid module (#788007)
No other commands run by GParted are niced, so stop nicing commands run
from the DMRaid module.

I think nicing of possibly long running file system modification
commands would have made virtually no difference because "nice -n 19"
lowered the CPU priority, but such command would be I/O bound.

History:

Nicing of file system modification commands was added by this commit
from 2006-08-21:
    82e6f6b132
    added nice -n 19, so that all extensive filesystem operations will be

Nicing of DMRaid operations was copied into the DMRaid module when it
was added here in 2009-03-14:
    5865c92dc0
    Added new class for dmraid support

Nicing was removed from file system modification commands with this
commit from 2013-02-22:
    52a2a9b00a
    Reduce threading (#685740)

Bug 788007 - Remove minor bits of legacy from DMRaid module
2017-09-25 09:25:17 -06:00
Mike Fleetwood a89d55a6f0 Remove backward compatibility for dmraid without -P option (#788007)
The -P option was first added to dmraid-1.0.0.rc15 released 2006-09-17
[1].  dmraid-1.0.0.rc16 (a later release) was included in Debian 6 and
Ubunbu 12.04 LTS.  dmraid-1.0.0.rc13 was included in RedHat/CentOS 5
however the -P option was back ported into RedHat/CentOS 5.1.

All of these distributions are so old as to be no longer supported and
yet they provided the dmraid -P option.  Therefore backward
compatibility for dmraid without the -P option is no longer required.
So remove it.

[1] old dmraid source code releases
    http://people.redhat.com/heinzm/sw/dmraid/src/old/

Bug 788007 - Remove minor bits of legacy from DMRaid module
2017-09-25 09:25:17 -06:00
Pali Rohár 8fdc2c21a6 Correctly quote and escape arguments passed to external commands (#787203)
Trying to set a file system label to (including the double quotes):
    " --help "
fails.  For example labelling an ext4 file system would try to run this
command:
    # e2label /dev/sdb1 "" --help ""
    Usage: e2label device [newlabel]
    # echo $?
    1

Alternatively trying to create a file system with a label of just a
double quote also fails.  The Applying Pending Operations dialog waits
forever and won't cancel or force cancel.  Have to use the window
manager close window button to close the dialog.  Also GParted reports
this error to the console:
    (gpartedbin:9648): glibmm-CRITICAL **:
    unhandled exception (type Glib::Error) in signal handler:
    domain: g-shell-error-quark
    code  : 0
    what  : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2')

Command strings are parsed and split into argv array by function
Glib::shell_parse_argv() which calls internal glib function
tokenize_command_line() for shell tokenization.  It expects the command
string to be properly quoted and escaped and after tokenization, calls
g_shell_unquote() on every parsed argument.  So to prevent constructing
incorrect commands, every non-static string needs to be properly quoted.

GParted only puts labels and mount points into double quotes, but has
not escaped special characters in those values itself.  This patch
fixes all these problems by using Glib::shell_quote() on all variable
values.  Labels, mount points, paths and all others too.

Probably a better solution would be to use a new function which takes
argv array instead of one string with all the, correctly quoted and
escaped, arguments concatenated together.

Bug 787203 - Correctly quote and escape arguments of external programs
             passed to execute_command()
2017-09-21 20:00:26 +01:00
Pali Rohár f422052356 Correctly quote and escape command line argument passed to "sh -c" (#787203)
Shell fragments must be properly quoted and escaped to prevent execution
of unintended commands derived from user controllable data.  For
example:

    $ printf '#!/bin/sh\necho test > out\n' > script.sh
    $ chmod +x script.sh
    $ truncate -s 20M 'jfs;script.sh'
    $ mkfs.jfs -q 'jfs;script.sh'
    $ ls -l out
    ls: cannot access out: No such file or directory

    $ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'
    $ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'

    $ ls -l out
    -rw-r--r-- 1 root root 5 Sep 12 23:11 out
    $ cat out
    test

What is happening is that jfs::set_used_sectors() is using the device
name 'jfs;script.sh' without quoting it and passing it to the shell to
execute like this:
    sh -c 'echo dm | jfs_debugfs jfs;script.sh'
which the shell duly executes as these two commands:
    echo dm | jfs_debugfs jfs
    script.sh

This could be a security related issue as "sh -c" is able to execute
arbitrary shell commands from the argument if if contains shell special
characters.  Use Glib::shell_quote() [1] to quote and escape file names
and whole commands passed to the shell.

[1] Glib::shell_quote(const std::string & unquoted_string)
    https://developer.gnome.org/glibmm/stable/group__ShellUtils.html
    "Quotes a string so that the shell (/bin/sh) will interpret the
    quoted string to mean unquoted_string.

    If you pass a filename to the shell, for example, you should first
    quote it with this function."

Bug 787203 - Correctly quote and escape arguments of external programs
             passed to execute_command()
2017-09-21 20:00:26 +01:00
Pali Rohár e8f0504b13 Make sure that FS_Info cache is loaded for all named paths (#787181)
Naming a file system image file on the command line is shown by GParted
as unknown.

    $ truncate -s 100M /tmp/fat.img
    $ mkfs.vfat /tmp/fat.img
    $ sudo ./gpartedbin /tmp/fat.img

Currently the FS_Info cache is loaded for all devices reported by
blkid (plus all whole disk devices identified from /proc/partitions even
if blkid reports nothing).  However file system images named on the
command line are not queried so GParted can't identify them.

Fix by ensuring that the FS_Info blkid cache is loaded for all named
devices, including named file system image files.

Note that Mount_Info::load_cache() depends on the contents of the
FS_Info cache to lookup UUID= and LABEL= device names from /etc/fstab.
However only file systems in block devices can be mounted like this, and
never file system image files, so the fact that the cache may be
extended afterwards by FS_Info::load_cache_for_paths() does not matter.

History

Prior to version 0.22.0, when unpartitioned drive support was added,
GParted could recognise some file system image files using loop
partition handling in libparted.  However libparted before version 3.2
reported the loop partition name as the whole disk device name appended
with "1" so all the query commands were provided a non-existent name to
use.  Therefore no file system usage or the label was displayed.

Bug 787181 - Fix detection of file system images
2017-09-12 19:10:20 +01:00
Pali Rohár c3ad49d9da Update list of prohibited fat label characters (#787202)
Add double quote (") to the list of prohibited FAT label characters,
previously missed [1][2].

Also add single quote (') because mlabel encoded it in a way that both
Windows and blkid don't understand, although mlabel can correctly decode
it itself.

    # export MTOOLS_SKIP_CHECK=1
    # mlabel ::"MIKE'S" -i /dev/sdf1
    # mlabel -s :: -i /dev/sdf1
     Volume label is MIKE'S (abbr=MIKE_S~1???)
    # blkid -o value -s LABEL /dev/sdf1
    MIKE_S~1???

    (8-bit characters in the above output have been replaced with
    question marks (?) just to keep this commit message as 7-bit ASCII).

Finally exclude ASCII control characters below SPACE (0x00 to 0x1F) as
they also cause mlabel to ask a question and wait for input in the same
way that prohibited characters do.  As discussed in the previous commit
[1] the only way to stop GParted waiting forever is to manually kill
mlabel with signal 9 (KILL).

    # mlabel ::"^A" -i /dev/sdf1
    Long file name "^A" contains illegal character(s).
    a)utorename A)utorename-all r)ename R)ename-all
    s)kip S)kip-all q)uit (aArRsSq):

[1] 584137b32b
    Remove prohibited characters from FAT16/32 labels (#755608)

[2] Microsoft TechNet: Label
    https://technet.microsoft.com/en-us/library/bb490925.aspx

Bug 787202 - Update list of prohibited fat label characters
2017-09-07 13:23:59 +01:00
Mike Fleetwood 73fe1dbf5c Support /etc/fstab using Unicode labels as mount points (#786502)
So far GParted is still loading the default non-reversible encoded
labels from blkid in the initial loading of the FS_Info module cache.
This encoded label is used to match LABEL=<label> when reading
/etc/fstab, via the get_path_by_label() call, so works for ASCII only
labels.  This prevents GParted enabling the "mount on >" partition menu
item when non-ASCII labels are used.

To fix this:
1) Stop reading the labels the wrong way.
   Via the blkid command used to initially load the FS_Info module cache
   and is subject to default non-reversible encoding of non-printable
   ASCII bytes.
2) Read all the labels the right way, but only when needed.
   Only when /etc/fstab file contains LABEL=<label> and
   get_path_by_label() is called, read all the labels from blkid without
   encoding them via run_blkid_update_cache_one_label().
3) Return label from the cache.
   get_label() returns the cached label, loading it into the cache first
   if needed with run_blkid_update_cache_one_label().

In the worst case scenario of having a LABEL=<label> in /etc/fstab blkid
will be run for every partition containing a recognised file system to
read the label.  On my desktop with 5 hard drives, 4  SWRaid arrays and
31 recognised file systems running 'blkid -o value -s LABEL ...' 31
times took 0.074 seconds of a total scan time of 9.072 seconds.  Less
that 1% of the total scanning time.  When LABEL=<label> is not used in
/etc/fstab individual blkid executions are only used to read labels for
file systems where there is no file system specific tool available
reducing the impact further.  Blkid itself caches the data in it's
blkid.tab cache file rather than reading all file systems on each
invocation.  Also the Linux file system cache will already contain the
blkid executable file, needed libraries files and the blkid.tab cache
file itself.  Hence why repeated execution of blkid is so fast.

Further to the updated comment in set_partition_label_and_uuid().
Matching LABEL=<label> from /etc/fstab uses the label obtained from
blkid run in the C locale so this kind of assumes it returns the label
correctly and it does for my limited testing on Unicode enabled
desktops.  Just not sure if it would be true for all cases in all
locales compared to the FS specific command run in the users default
locale.

Bug 786502 - Support reading Unicode labels when file system specific
             tools aren't available
2017-09-02 13:25:26 -06:00
Mike Fleetwood b022c1e3a9 Update FS_Info cache with Unicode safe labels read from blkid (#786502)
Move the code which reads the Unicode label from FS_Info::get_label()
into new function run_blkid_update_cache_one_label() which also replaces
the non-reversibly encoded copy loaded during the initial cache load.

This is mainly a bit of code refactoring ready for the following change.
It deliberately keeps the initial loaded labels so that reading
/etc/fstab and decoding LABEL=<label> to block special device names via
FS_Info::get_path_by_label() continues to works, at least for ASCII only
labels.

Bug 786502 - Support reading Unicode labels when file system specific
             tools aren't available
2017-09-02 13:25:26 -06:00
Mike Fleetwood 1c984ae06d Support reading Unicode character labels via blkid (#786502)
For file systems which don't provide a specific tool to read labels
(exfat, f2fs, hfs, hfsplus, udf and ufs) or when the tools aren't
installed for any other file system, reading labels falls back to using
the blkid command.  Blkid encodes non-ASCII bytes in it's output [1].
For example blkid reports a short Unicode label like this:

    # blkid /dev/sdb12
    /dev/sdb12: LABEL="M-PM-^ZM-PM->M-QM-^HM-PM-:M-PM-0" TYPE="hfsplus"

This shows encoding using 'M-' for bytes above 127 and caret '^' for
control characters.  Unfortunately neither 'M-' or '^' are encoded by
blkid so it is impossible to distinguish between the original label
containing either of these sequences or encoded non-printable bytes.
See this Bugzilla's bug 786502 entry for more details.  Unfortunately
this makes the default output format from blkid unsuitable for reading
Unicode character labels.

Instead instruct blkid to print values without encoding them using the
'-o value' option.  This just produces a list of new line separated
values without being able to identify which TYPE, UUID or LABEL belongs
to which device.  So query just the label for each block device one at
a time.  This method has the advantage of also working with all versions
of blkid, from version 1.0.0 (12-Feb-2003) in CentOS 5 to the latest
version 2.30.1 (20-Jul-2017) in Fedora 26.

    # blkid -o value -s LABEL /dev/sdb12 | hexdump -C
    00000000  d0 9a d0 be d1 88 d0 ba  d0 b0 0a           |...........|
    0000000b

(Using hexdump -C just so that this commit message only contains ASCII
characters).

Therefore this commit changes FS_Info::get_label() to query blkid as
shown above.  Note that GParted_Core::set_partition_label_and_uuid()
only calls get_label() when there is no file system specific tool
available (or the tool failed).

The FS_Info cache still contains copies of the labels subject to blkid
encoding, and that will be addressed in following commits.

[1] blkid.c v2.30.1 safe_print()
    https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/misc-utils/blkid.c?h=v2.30.1#n111

Bug 786502 - Support reading Unicode labels when file system specific
             tools aren't available
2017-09-02 13:25:26 -06:00
Mike Fleetwood c353630312 Only execute mkudffs during detection when it is known to exist (#786050)
When udftools are not installed and the mkudffs program isn't found
GParted would report this error during startup:

    # ./gpartedbin
    ======================
    libparted : 3.1
    ======================
    Failed to execute child process "mkudffs" (No such file or directory)

Only run mkudffs to check for an old version when the program is found.

Bug 786050 - GParted reports failed to execute child process "mkudffs"
             when it is not installed
2017-08-10 10:04:20 -06:00
Mike Fleetwood a0c44d766d Refactor UDF label manipulation code (#784533)
Make especially the Volume Identifier length limit code simpler to
understand and therefore easier to maintain.

Bug 784533 - Add support for UDF file system
2017-07-30 09:50:09 +01:00
Pali Rohár 861bc8df5d Add support for long UDF labels and check for old versions of mkudffs (#784533)
UDF label is stored in the Logical Volume Identifier which has space for
either 126 Latin1 or 63 UCS-2 characters.  For compatibility reasons
with older versions of blkid, the possibly truncated UDF label is also
stored in the Volume Identifier which only has space for 30 Latin1 or 15
UCS-2 characters.

Because versions of mkudffs prior to 1.1 damage the label if it contains
non-ASCII characters, make sure GParted does not call such versions of
mkudffs with a non-ASCII character label.

Bug 784533 - Add support for UDF file system
2017-07-30 09:50:09 +01:00
Mike Fleetwood 62a7465fd2 Update AUTHORS file and Help > About > Credits
Provide credit for patch by Pali Rohár.
2017-07-10 19:17:05 +01:00
Mike Fleetwood 7feb84a219 Minor update of colour for exFAT
Colour for exFAT was a Sea Green.  This is close to Accent Green Dark
from the GNOME colour palette.  Use that instead.
2017-07-10 19:17:05 +01:00
Pali Rohár 5f327feb25 Add support for UDF file system (#784533)
Add support for detecting UDF file systems and formatting hard disks
with revision 2.01 UDF file systems using udftools.  Formatting optical
disks or any other media types is not supported yet.  Changing label or
UUID after formatting is not supported as the tools do not yet exist.

Bug 784533 - Add support for UDF file system
2017-07-10 19:17:05 +01:00
Pali Rohár 77ef2be089 Fix setting empty label when creating FAT16/32 file systems (#784564)
A FAT file system label in the partition boot sector should be set to
"NO NAME    " when the label is empty [1][2].  mkdosfs/mkfs.fat always
sets this to the label specified on the command line, even when the
label is blank [3].  Fix by not specifying the label when it is blank.

[1] The FAT File System, BIOS Parameter Block and Extended BIOS
    Parameter Block
    https://social.technet.microsoft.com/wiki/contents/articles/6771.the-fat-file-system.aspx#BPB_and_EBPB
[2] FAT16 File System, Volume Label
    http://www.maverick-os.dk/FileSystemFormats/FAT16_FileSystem.html#VolumeLabel
[3] mkfs.fat -n "" generates file system with invalid label
    https://github.com/dosfstools/dosfstools/issues/54

Bug 784564 - GParted calls mkfs.fat incorrectly when user does not specify label
2017-07-07 13:23:27 +01:00
Mike Fleetwood 59c8a7d6df Detect btrfstune change UUID capability again (#784467)
Btrfstune changed it's command line help output from being written on
stderr to being written on stdout in the following commit first included
in btrfs-progs 4.7.2 released 05-Sep-2016.  This breaks GParted
detection of the change UUID capability.  Found on the very latest
distributions: up to date Arch Linux and Fedora 26 Beta.  Fix this.

    https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/commit/?id=57d1cbd867311d99a2ae5e3cdcffd04
    btrfs-progs: print help test to stdout

Bug 784467 - No longer detecting btrfs change UUID capability
2017-07-03 09:21:50 -06:00
Mike Fleetwood 87ccf060ce Ensure internal detection requires second magic when needed (#783997)
Internal file system detection is broken for detection of LVM2 PVs
because it reports finding LVM2 PV even when only the first magic is
found.  Prepare a partition like this:
    # lvm pvcreate /dev/sdb1
    # hexdump -C /dev/sdb1 > hexdump-1.txt

Clear the second magic:
    # python
    f = open("/dev/sdb1","w")
    f.seek(0x218)
    f.write("\x00"*4)
    f.close()
    quit()

    # hexdump -C /dev/sdb1 > hexdump-2.txt
    # diff -u hexdump-[12].txt
     00000200  4c 41 42 45 4c 4f 4e 45  01 00 00 00 00 00 00 00  |LABELONE........|
    -00000210  58 69 83 e1 20 00 00 00  4c 56 4d 32 20 30 30 31  |Xi.. ...LVM2 001|
    +00000210  58 69 83 e1 20 00 00 00  00 00 00 00 20 30 30 31  |Xi.. ....... 001|
                                        ^^ ^^ ^^ ^^                       ^^^^
     00000220  52 4b 31 73 50 77 49 66  6a 72 55 4c 6a 4d 30 58  |RK1sPwIfjrULjM0X|

GParted still detects this as an LVM2 PV even though lvm and blkid do
not.

Correct logic error and only perform memcmp() with the second magic when
the second signature is non-NULL.

Bug 783997 - GParted detecting LVM2 PV regardless whether second magic
             matches or not
2017-06-20 10:03:31 -06:00
Mike Fleetwood 25780c611b Further improve speed of PipeCapture for non-watched output (#777973)
For large output a lot of time is used copying capturebuf to callerbuf
to provide a Glib::ustring copy of the buffer for the update callback.
However update callbacks are only used when commands are run to apply
operations by FileSystem::execute_command() and their output is
incrementally displayed in the UI.  Whereas update callbacks are never
used when commands are used to query information via
Utils::execute_command().

Stop performing interim copying of capturebuf to callerbuf when there
are no update callbacks registered as it is unnecessary.

Time to read portions of the recorded fsck.fat output via
fat16::set_used_sectors() and intermediate copies aren't required:

                     1 MiB     10 MiB   122 MiB
    old code :   0.074 sec   1.41 sec   210 sec [3:30]
    new code :   0.063 sec   0.56 sec     6.57 sec

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood 6f49f3049d Increase PipeCapture maximum read size to 64K (#777973)
For large output PipeCapture spends all it's time copying the capturebuf
to callerbuf to provide a consistent view for any registered update
callbacks.  This overhead is dependant of the size of the ever growing
captured output and the number of times OnReadable() is called.
Therefore increase the maximum read size to exponentially reduce this
overhead.

Time taken to read varying amounts of fsck.fat output with various
read buffer sizes:

                 1 MiB   10 MiB            122 MiB
    512b  :   0.60 sec   65 sec [1:05]   17262 sec [4:47:42]
    4096b :   0.19 sec   13 sec           2157 sec [  35:57]
    64K   :   0.07 sec    1.4 sec          210 sec [   3:30]

Note that this is only increasing the maximum size that can be read from
the output of the external command.  If the command produces it's output
slowly, such as the with progress reporting commands like mkfs.ext4,
then only the available number of bytes is read reporting the next
progress increment.  However if the command produces it's output
quickly, such as when testing this bug using a modified fsck.fat
concatenating the 122 MiB of pre-recorded output, then full buffer reads
are performed.

To ensure that a single call to OnReadable() couldn't block the UI too
long, the time taken for OnReadable() to process a full buffer of
various sizes was recorded as:

    512b  :   0.031 milliseconds
    4096b :   0.188 milliseconds
    64K   :   3.576 milliseconds

Adding this amount of processing time in the UI under normal
circumstances is not a problem.

As the captured output increases, the time taken by OnReadable() becomes
dominated by the time taken to copy the ever increasing capture buffer
to handle it's expansion and to copy it to the caller buffer for the
update callback.  At the end of the 122M captured fsck.fat output
OnReadable() takes 350 milliseconds per call.  This is not a problem
because this is an extreme case in which GParted is already hung and
increasing the buffer size is reducing the overall hang time from over
4 hours to a few minutes.

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood 8dbbb47ce2 Workaround g_utf8_get_char_validate() bug with embedded NUL bytes (#777973)
If PipeCapture reads a NUL byte in the middle of what is expected to be
a multi-byte UTF-8 character then PipeCapture either returns the
captured characters to the previous update or loops forever depending on
whether the end of the stream is encountered before the read buffer is
full or not.  This is equivalent to saying whether the NUL byte occurs
within the last 512 bytes of the output or not.

This is caused by a bug in g_utf8_get_char_validated() reporting that a
partial UTF-8 character has been found when the NUL byte is encountered
in the middle of a multi-byte character even though more bytes are
available in the length specified buffer.  g_utf8_get_char_validated()
is always stopping at the NUL byte assuming it is working with a NUL
terminated string.

Workaround this by checking for g_utf8_get_char_validated() claiming a
partial UTF-8 character has been found when in fact there are at least
enough bytes in the read buffer to instead determine that it is really
an invalid UTF-8 character.

Reference:
    Bug 780095 - g_utf8_get_char_validated() stopping at nul byte even
                 for length specified buffers
    https://bugzilla.gnome.org/show_bug.cgi?id=780095

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood 3a6a304c64 Workaround g_utf8_find_next_char() not incrementing past NUL char (#777973)
If PipeCapture reads a NUL character, a valid UTF-8 character, it causes
GParted to allocate all available memory and crash.  The while loop in
PipeCapture::OnReadable() loops forever reading the same NUL character
from readbuf because g_utf8_find_next_char() doesn't advance past it.
Hence an infinite number of NUL characters are added to the current
line, linevec.

Workaround this by checking for this failure case of
g_utf8_find_next_char() and increment past the NUL character.

This is actually a bug recently fixed in glib 2.49.3 released
2016-07-17.  References:

*   Bug 547200 - g_utf8_find_next_char() issues
    https://bugzilla.gnome.org/show_bug.cgi?id=547200

*   https://git.gnome.org/browse/glib/commit/?id=e0e652e4032a181d4f0b0a12aeddf0678b7a3c04
    Fix a corner-case in g_utf8_find_next_char

    In the case that *p is '\0', we should return p + 1, not p.
    This change allows to simplify g_utf8_find_next_char a bit.

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood b5b3d199f8 Improve the performance of PipeCapture for large output (#777973)
A user had a very corrupted FAT file system such that fsck.fat produced
122 MiB of output.  GParted has to read this output to get the file
system usage information.  However GParted takes more than 48 hours to
read the 122 MiB of output, while using 100% CPU time and is
unresponsive for the duration.

Modified fsck.fat to output just the first 1 MiB of output and used perf
to capture performance data from GParted reading that output:
    # perf -g -F 1999 -- ./gpartedbin
    # perf report --stdio
      67.84% Glib::ustring::replace      [4.23s]
      17.67% g_utf8_pointer_to_offset    [1.10s]
       8.48% g_utf8_offset_to_pointer    [0.53s]
    [  6.01% (everything else)       ]   [0.38s]
    [100.00% TOTAL                   ]   [6.24s]

And to read the first 10 MiB of output the performance figures are:
      92.95% Glib::ustring::replace      [257.44s]
       4.35% g_utf8_pointer_to_offset    [ 12.05s]
       2.13% g_utf8_offset_to_pointer    [  5.90s]
    [  0.58% (everything else)       ]   [  1.61s]
    [100.00% TOTAL                   ]   [277.00s]

See how the total time is increasing non-linearly, 44 times longer for
only 10 times as much data.  This is because of the exponential increase
in time spent in Glib::ustring::replace.

After a lot of experimentation I came to the conclusion that
Glib::ustrings are not appropriate for storing and editing large buffers
of data, sizes megabytes and above.  The issues are that iterators are
invalid after the content changes and replacing UTF-8 characters by
index gets exponentially slower as the size of the string increases.
Hence the > 48 hours of 100% CPU time to read and apply the line
discipline to the 122 MiB of fsck.fat output.  See code comment for a
more detailed description of the issues found.

Rewrote OnReadable() to use Glib::ustrings as little as possible.
Instead using buffers and vectors of fixed width data types allowing for
fast access using pointers and indexes (converted to pointers by the
compiler with simple arithmetic).  Again see code comment for a more
detailed description of the implementation.

Repeating the performance capture with the new code for the first 1 MiB
of fsck.fat output:
      63.34% memcpy                      [0.35s]
    [ 36.66% (everything else)       ]   [0.21s]
    [100.00% TOTAL                   ]   [0.56s]

And for the first 10 MiB of fsck.fat output:
      96.66% memcpy                      [63.60s]
    [  3.34% (everything else)       ]   [ 2.20s]
    [100.00% TOTAL                   ]   [65.80s]

Simple timings taken to read portions of the fsck.fat output (when not
using perf):

                   1 MiB    10 MiB      122 MiB
    old code :   6.2 sec   277 sec   > 48 hours
                            (4:37)
    new code :   0.6 sec    66 sec    17262 sec
                            (1:06)    (4:47:42)

Performance of the code is still non-linear because of the assignment
of the ever growing capturebuf to callerbuf for every block of input
read.  This is required to generate a consistent Glib::ustring copy of
the input for the update callback.  However this is much faster than
before, and I have a plan for further improvements.

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood a233e30efe Move initial clearing of output capture buffers into PipeCapture class (#777973)
Seems more logical to initially clear the output capture buffer in a
single location in the PipeCapture class which reads the command output
into said buffer, rather than each calling site before the PipeCapture
objects are constructed.

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood a03735ac6f Prevent core dump reading none UTF-8 data from external command (#777973)
A user had a very corrupted FAT file system and when GParted was reading
the file system usage it would core dump.  The tip of the stack trace
was:

    #0 Glib::ustring_Iterator<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator++()
       at /usr/include/glibmm-2.4/glibmm/ustring.h line 957
    #1 Glib::ustring_Iterator<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator++(int)
       at /usr/include/glibmm-2.4/glibmm/ustring.h line 965
    #2 GParted::PipeCapture::OnReadable(Glib::IOCondition)
       at PipeCapture.cc line 63
    #3 GParted::PipeCapture::_OnReadable(_GIOChannel*, GIOCondition, void*)
       at PipeCapture.cc line 45

GParted uses 'fsck.fat -n -v /dev/PTN' to get the file system usage.
However because the file system was so corrupted it was reporting every
file name as being damaged, including the file names being reported as
binary data.  PipeCapture::OnReadable() reads up to 512 bytes at a time
and then uses a Glib::ustring iterator to loop over the UTF-8
characters, but a Glib::ustring iterator is explicitly not capable of
reading binary data [1].  With invalid UTF-8 bytes the code continued to
read beyond the end of the string until GParted crashed with a
segmentation violation.

Fix by accessing the read string by index instead of by iterator.

[1] Quote from the Glib::ustring_Iterator<T> Class Template Reference:
    https://developer.gnome.org/glibmm/stable/classGlib_1_1ustring__Iterator.html

    "The Glib::ustring iterated over must contain only valid UTF-8 data.
    If it does not, operator++(), operator--() and operator*() may make
    accesses outside the bounds of the string."

Bug 777973 - Segmentation fault on bad disk
2017-06-02 11:47:35 -06:00
Mike Fleetwood 7c51b62958 Remove unused build definition GPARTED_DATADIR
Definition has been unused since this commit first released in GParted
0.5.0:
    c2d19a8ab4
    Replace gnome-open with gtk_show_uri (#600046)
2017-06-02 10:47:35 -06:00
Mike Fleetwood 69d1bbcf8f Remove old .cvsignore files
As the source code is managed in GIT and there is a .gitignore file in
the top level directory specifying file names to exclude from version
control, then the old per-directory .cvsignore files for CVS are
redundant.

Add the only missing and applicable entry from src/.cvsignore of '.libs'
to .gitignore and remove all the .cvsignore files.
2017-06-02 10:47:35 -06:00
Mike Fleetwood e0390d9cd8 Update comment with example LUKS_Info cache entry
Reflect the change made to the data model in commit:
    Use BlockSpecial in LUKS_Info module cache (#767842)
    7cd574cac5
2017-05-21 09:44:20 -06:00
Mike Fleetwood 6798c271c7 Quote mount point in Data Rescue dialog (#782681)
As before always quote use of mount points in command lines.

Bug 782681 - btrfs partitions mounted with whitespace cannot be resized
2017-05-21 09:44:20 -06:00
Mike Fleetwood 2025581029 Quote mount point when copying and resizing xfs (#782681)
Attempting to grow an already mounted xfs where the mount point
contained spaces failed like this:

    Grow /dev/sdb4 from 1.00 GiB to 1.50 GiB
    + calibrate /dev/sdb4
    + grow partition from 1.00 GiB to 1.50 GiB
    + grow file system to fill the partition
      + xfs_growfs /tmp/File System Label
        Usage: xfs_growfs [options] mountpoint
        ...

Apply the rule and quote all uses of mount points within command lines.
This is also applied to copying xfs file systems even though it was safe
because it only ever used GParted generated mount points.

Also for the xfs copy operation switch unmounting of partitions to
specify mount points instead of partitions.  This is just to be
consistent with how it is done in all the online file system resizing
code.

Bug 782681 - btrfs partitions mounted with whitespace cannot be resized
2017-05-21 09:44:20 -06:00
Mike Fleetwood 988dacfb1b Quote mount point when resizing nilfs2 (#782681)
The current nilfs2 resizing code is safe because it never passes a user
influenced mount point into a command line.  Regardless, apply the same
simple rule to always quote mount points when used in command lines.

WARNING:
Nilfs-resize is broken and can't actually resize a file system mounted
with spaces in the mount point anyway!

    # mkdir "/tmp/File System Label"
    # mount -v -t nilfs2 /dev/sdb3 "/tmp/File System Label"
    mount.nilfs2: started nilfs_cleanerd
    # nilfs-resize -v -y /dev/sdb3
    Error: cannot open NILFS on /dev/sdb3.
    # echo $?
    1
    # strace nilfs-resize -v -y /dev/sdb3
    ...
    stat("/dev/sdb3", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 19), ...}) = 0
    open("/dev/sdb3", O_RDONLY)             = 3
    ...
    open("/proc/mounts", O_RDONLY)          = 4
    read(4, "sysfs /sys sysfs rw,seclabel,nos"..., 1024) = 1024
    ...
    close(4)                                = 0
    open("/tmp/File\\040System\\040Label", O_RDONLY) = -1 ENOENT (No such file or directory)
    ...
    # fgrep /dev/sd /proc/mounts
    /dev/sda3 / ext4 rw,seclabel,relatime,data=ordered 0 0
    /dev/sda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0
    /dev/sdb3 /tmp/File\040System\040Label nilfs2 rw,relatime 0 0

So it looks like nilfs-resize (or a library it uses) can't decode the
octal characters '\040' used to encode spaces in the mount point as
reported in /proc/mounts.

Bug 782681 - btrfs partitions mounted with whitespace cannot be resized
2017-05-21 09:44:20 -06:00
Mike Fleetwood 3a10e30c3a Quote mount point when resizing jfs (#782681)
Attempting to grow an already mounted jfs where the mount point
contained spaces failed like this:

    Grow /dev/sdb2 from 1.00 GiB to 1.50 GiB
    + calibrate /dev/sdb2
    + grow partition from 1.00 GiB to 1.50 GiB
    + grow file system to fill the partition
      + mount -v -t jfs -o remount,resize /dev/sdb2 /tmp/File System Label
        Usage:
        mount [-lhV]
        mount -a [options]
        mount [options] [--source[ <source> | [--target] <directory>
        mount [options] <source> <directory>
        mount <operation> <mountpoint> [<target>]
        ...

Apply the rule to always enclose mount points within double quotes
within command lines.

Bug 782681 - btrfs partitions mounted with whitespace cannot be resized
2017-05-21 09:44:20 -06:00
Mike Fleetwood 618c1a202d Quote mount point when resizing btrfs (#782681)
A user had a btrfs file system mounted by automounter on a mount point
like "/mount/$USER/File System Label" which included white space
characters.  Resizing the file system while online failed like this:

    Grow /dev/sdb1 from 1.00 GiB to 1.50 GiB
    + calibrate /dev/sdb1
    + grow partition from 1.00 GiB to 1.50 GiB
    + grow file system to fill the partition
      + btrfs filesystem resize 1:max /mount/USER/File System Label
          btrfs filesystem resize: too many arguments
          usage: btrfs filesystem resize [devid:][+/-]<newsize>[kKmMgGtTpPeE]|[devid:]max <path>

So mount points not created by GParted should be considered under user
control and need quoting when used as parameters in command lines.
Strictly speaking, mount points created by GParted itself, by
FileSystem::mk_temp_dir(), are safe and don't need quoting.  However it
is simpler and safer just to quote all uses of mount points in command
lines, rather than risk missing some.

Bug 782681 - btrfs partitions mounted with whitespace cannot be resized
2017-05-21 09:44:20 -06:00
Mike Fleetwood 75131d85a5 Fix snap-to-alignment of operations creating partitions (#779339)
Using the default MiB alignment, creating an MSDOS logical partition
between two other existing logical partitions fails with this error
dialog:

    (-) <b>An error occurred while applying the operations</b>
        See the details for more information.
        <b>IMPORTANT</b>
        If you want support, you need to provide the saved details!
        See http://gparted.org/save-details.htm for more information.
                                                               [ OK ]

and these operation details:

    + libparted messages
      - Unable to satisfy all constraints on the partition.

This bug was introduced by this commit included in GParted 0.23.0:
    90e3ed68fc
    Shallow copy Device object into Operation object (#750168)

The commit message claimed that the deep copied Partition objects inside
the Device inside the Operation object are never accessed.  This turned
out not to be true.  Win_GParted::Add_Operation() uses them as part of
snap_to_alignment() which updates requested partition boundaries to
account for alignment requirements and the space needed for EBR
(Extended Boot Record) preceding logical partitions.

In this case the new logical partition was trying to be created over the
top of the EBR for the following logical partition because
snap_to_alignment() wasn't aware of its existence.

Fix by making Add_Operation() and snap_to_alignment() refer to the
current device, as displayed in the UI, rather than the shallow copy
included in the Operation object.  Hopefully now it is true that the
not copied vector of Partition objects in the Device object in each
Operation object are never accessed.

Bug 779339 - enforce at least 1 MiB "free space following"
2017-04-23 08:57:25 -06:00
Curtis Gedak 4a0931c50d Restore ability to grow primary w/unallocated space before extended (#778700)
A regression which prevented growing a primary partition that had
unallocated space between it and the following extended partition was
introduced with the following commit:

  Create and use general find_extended_partition() function
  aa98107706

To fix the regression, restore the logic that checked for a logical
partition before seeking the index of the extended partition.

Bug 778700 - Unable to grow partition even though unallocated space is
             adjacent
2017-02-17 12:40:46 +00:00
Refael Sheinker 925e505f77 Make the Name Partition dialog a bit bigger (#778003)
Increase the size of the Name Partition dialog, matching the change made
to the Label File System dialog in the previous commit.  The code for
the Name Partition dialog was basically copied from the Label File
System dialog.

Bug 778003 - The "Label File System" dialog is too small
2017-02-14 18:59:23 +00:00
Refael Sheinker d1ce653d1b Make "Label File System" dialog a bit bigger (#778003)
On Arch Linux with XFCE 4.12 and Fedora 24 with GNOME 3.20 and later;
the Label File System dialog is too small.  The problem is that the
label entry box clips the Cancel and OK buttons.

Stop specifying the dialog height, instead letting it fit the combined
height of all the widgets automatically.

Also make the dialog wider and the label entry box wider so that longer
device names can be shown in the title before they are truncated.

Bug 778003 - The "Label File System" dialog is too small
2017-02-14 18:59:23 +00:00
Curtis Gedak ad9aaa1dc3 Update copyright year 2017-02-14 10:00:41 -07:00
Mike Fleetwood 38857e09c7 Improve error message in check_repair_filesystem() (#774818)
Change the error message after it raised a question with the translators
and to better align with the operation only being described as a check
in the GParted Manual and in the application UI.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-02-07 12:31:49 -07:00
Piotr Drąg 2258b70cd9 Fix translator comments
They need to be exactly one line above a string to show up in .po files.
2017-01-28 01:04:42 +01:00
Mike Fleetwood aa98107706 Create and use general find_extended_partition() function
The Operation class already provided find_index_extended() method and
 was used in the Operation and derived classes where required.  It
returns the index to the extended partition in the PartitionVector
object, or -1 when no extended partition exists.

There were several cases of the same functionality being open coded in
GParted_Core and Win_GParted.  Therefore move the implementation to
find_extended_partition() in PartitionVector compilation unit and use
this implementation everywhere.
2017-01-14 08:49:58 -07:00
Mike Fleetwood 786a53b43c Replace 2 Win_GParted member variables with local variables
Member variables fs and gpart_output were used in just one method each
as local variables.  Replace them with local variables.
2017-01-14 08:49:58 -07:00
Mike Fleetwood fbd39b81e3 Fix for loop limit in fat16::sanitize_label()
Use the same uppercase_label string to determine the limit of the for
loop as is actually accessed.
2017-01-14 08:49:58 -07:00
Mike Fleetwood 0f76b8f8ff Remove unused clear_mountpoints parameter from add_mountpoint*()
The clear_mountpoints parameter has never been used since
add_mountpoint*() were first added [1][2].  clear_mountpoints() method
[3] is available to provide this functionality and used.  Therefore
removed unused parameter and code.

[1] add_mountpoints() added 2006-03-15
        9532c3cad1
        Made Partition::mountpoints private

[2] add_mountpoint() added 2011-12-16
        208083f11d84dbd4f186271a3cdbf5170db259f8b8
        Display LVM2 VGNAME as the PV's mount point (#160787)

[3] clear_mountpoint() added 2006-03-19
        ad9f2126e7
        fixed issues with copying (see also #335004) cleanups + added FIXME added
2017-01-14 08:49:58 -07:00
Mike Fleetwood 34185afbf1 Document new requirement on the cryptsetup command (#774818)
Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 5cd1f718a1 Add "Available online only" to the Supported Actions legend (#774818)
Shrinking LUKS encryption is only possible while the mapping is open and
active.  Therefore the File System Support dialog shows Cross + Tick for
this operation.  Add this new combination to the legend.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 86597b8672 Use virtual get_filessytem_string() in remaining operation descriptions (#774818)
Switch the remaining create and delete operation description generation
to use the virtual Partition get_filesystem_string() method.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood f1e3d42b56 Prevent deletion of open LUKS mappings (#774818)
At least until closing LUKS mappings is supported.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 36804b9634 Implement maximize encryption volume as part of check repair operation (#774818)
Now that resizing of encrypted file systems is implemented add growing
of the open LUKS mapping as part of the check repair operation.

Resizing an encrypted file system requires the LUKS mapping to be open
to access the file system within; therefore it also requires libparted
and kernel support for online partition resizing.  This limits resizing
to the latest distributions with libparted >= 3.2 and kernel >= 3.6.
However growing an open LUKS mapping as part of a check repair operation
doesn't require resizing the partition.  Therefore route via offline
grow of LUKS to avoid those extra, unnecessary requirement.  This does
mean that offline LUKS grow artificially requires cryptsetup, but that is
not really significant as even opening LUKS requires cryptsetup.

So now checking an encrypted file system on even the oldest
distributions does:
1) runs FSCK on the encrypted file system;
2) grows the encryption volume to fill the partition;
3) grows the file system to fill the encryption mapping.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood e2aff7ba66 Implement offline grow of encryption volumes (#774818)
While a device-mapper encryption mapping can only be resized while
active, a LUKS volume can inherently be grown while offline because it
doesn't store a size and when started fills the partition.  This doesn't
even need the cryptsetup command to do the resizing (just to open the
LUKS volume afterwards which GParted doesn't yet support).  Implement
offline growing of LUKS volumes.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood a1c1401285 Add bug checks into resize/move operation methods (#774818)
Ensure pre-conditions of always or never being passed a Partition object
containing an open LUKS encryption are met for resizing file system and
LUKS encryption methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 828f0d8ab3 Implement resize/move operation of encrypted file systems (#774818)
Moving of closed LUKS is simply enabled by luks .move capability being
set and requires no further coding.

Resizing of encrypted file systems requires both the LUKS mapping and
encrypted file system within to be resized in the right order for both
shrinking and growing.  To keep the code simple split resizing of plain
and encrypted into separate functions.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood ee1b2257d2 Preview resize/move operation of encrypted file systems (#774818)
Changing the Resize/Move dialog code to also handle PartitionLUKS
objects was considered too complicated.  Instead create an unencrypted
equivalent using clone_as_plain(), pass that to the Resize/Move dialog
and finally apply the change back using Partition*::resize().

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 08e4ba4eca Add Partition object resizing method Partition*::resize() (#774818)
Add a resize() method to both Partition and PartitionLUKS classes.  They
take a reference Partition object, and update the position, size and
file system usage of *this Partition to match.  This is ready for taking
a partition returned from Resize/Move dialog and applying the change.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 30a0f4506c Add specialist clone method PartitionLUKS::clone_as_plain() (#774818)
Implement a specialist PartitionLUKS clone method.  Creates a new
Partition object which has the same space usage as the source encrypted
file system, but is a plain file system.  Namely, the overhead of the
LUKS header has been added to the file system usage.  This is ready for
feeding this representation of the partition to the Resize/Move dialog.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood e2c70d5639 Enable resize/move for encrypted file systems (#774818)
A partition containing LUKS encryption can only be moved when closed and
the Device Mapper encryption mapping only exists to be resized when
open.  As GParted can't yet open or close LUKS encryption these
restrictions have to be adhered to when composing operations.  Also as
encrypted partitions are only being resized when open, additionally
libparted and the kernel have to both be capable of resizing a partition
while in use.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 89540fedd8 Add bug checks into copy operation methods (#774818)
Ensure pre-condition of never being passed a Partition object containing
an open LUKS encryption mapping is met for copy operation related
methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood e31fa783a8 Display LUKS copy capability (#774818)
Users will expect to see that copying of LUKS is available in the File
System Support dialog, even if technically what is implemented is
copying of the file system within an open encryption mapping.  There is
no other reason to do this change as these two previous commits have
fully enabled copying of encrypted content:
    Implement copy operation of encrypted file systems (#774814)
    Preview copy operation of encrypted file systems (#774818)

Set LUKS .copy capability so that the dialog shows copying availability,
but then disallow copying of closed LUKS.  (Checking for the capability
and performing copying the content of an open LUKS encryption mapping is
inherent in Win_GParted::set_valid_operations() and GParted_Core::copy()
in the way that they access the block device containing the file system,
whether encrypted or not).

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 56859e1d6d Implement copy operation of encrypted file systems (#774814)
Implement the copy operation by making the copy code work with the
Partition object directly containing the file system, instead of the
enclosing PartitionLUKS object containing the LUKS encryption mapping.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 4c70ec3aee Preview copy operation of encrypted file systems (#774818)
Implement composing of the copy paste operation for encrypted file
systems.

Copying a closed LUKS partition would duplicate the LUKS header
containing the UUID, passphrase and master encryption key.  From a
security point of view having additional copies of encrypted data with
the same master key is an extra risk, but it all depends on what is
going to happen with that copy.  The Cryptsetup FAQ [1] talks about how
to make a backup at the file system level and block level, preferring
file system level with separate encryption if needed.  It strongly
recommends separate encryption if the copy is removable or going
off-site [2].  Also in the case of cloning the data, cloning the LUKS
container is strongly discouraged [3].

Therefore copying of encrypted file systems will be implemented by
copying the file system inside an open LUKS encryption mapping and not
by copying a closed LUKS partition.

Also, while creating new LUKS encryption is not yet supported, copying
an encrypted file system into a new partition will not be permitted as
that will always decrypt the data.  An encrypted file system will be
allowed to be copied into an existing plain partition, decrypting the
data, or into an existing open encrypted partition, keeping it
encrypted.  Pasting over the top of a closed encrypted partition will
remove the LUKS encryption.  (This is planned to be removed when
creating and removing LUKS encryption is implemented as part of full
LUKS read-write support).

Remember that when pasting into an existing partition the file system
must fit within the available space and that encryption has overhead
from the LUKS header.  Therefore copying from a plain partition into a
partition of the same size with open an encryption mapping will not fit
for space reasons.

[1] The Cryptsetup FAQ, Backup and data Recovery section
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions

[2] 6.7 Does a backup compromise security?
"If you do network-backup or tape-backup, I strongly recommend to go the
filesystem backup path with independent encryption, as you typically
cannot reliably delete data in these scenarios, especially in a cloud
setting."

[3] 6.15 Can I clone a LUKS container?
"You can, but it breaks security, because the cloned container has the
same header and hence the same master key.  You cannot change the master
key on a LUKS container, even if you change the passphrase(s), the
master key stays the same. That means whoever has access to one of the
clones can decrypt them all, completely bypassing the passphrases.

The right way to do this is to first luksFormat the target container,
then to clone the contents of the source container, with both containers
mapped, i.e. decrypted.  You can clone the decrypted contents of a LUKS
container in binary mode, although you may run into secondary issues
with GUIDs in filesystems, partition tables, RAID-components and the
like. These are just the normal problems binary cloning causes.

Note that if you need to ship (e.g.) cloned LUKS containers with a
default passphrase, that is fine as long as each container was
individually created (and hence has its own master key). In this case,
changing the default passphrase will make it secure again."

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 35d57011e9 Add bug checks into format operation methods (#774818)
Ensure pre-condition of never being passed a Partition object containing
an open LUKS encryption mapping is met for format operation related
methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood a568e5365a Implement format operation on encrypted file systems (#774818)
Formatting an existing encrypted partition will format the file system
within the encrypted mapping.  Formatting over the top of a closed
encrypted partition will remove the encryption.  (The latter is planned
to be prevented when creating and removing LUKS encryption is
implemented as part of full LUKS read-write support).

Composing the format operation inside an open LUKS encryption mapping
also has to account for the size of that mapping and construct a
PartitionLUKS object containing the new file system.  Implementing the
operation itself is as simple as passing the Partition object directly
containing the file system, instead of the outer PartitionLUKS object.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 88136c96d7 Extend functions generating encrypted file system string (#774818)
Already have:
    Utils::get_filesystem_string(FS_EXT2)          -> "ext2"
    virtual Partition::get_filesystem_string()     -> "ext2"
    virtual PartitionLUKS::get_filesystem_string() -> "[Encrypted] ext2"
Add these:
    Utils::get_encrypted_string()                  -> "[Encrypted]"
    Utils::get_filesystem_string(false, FS_EXT2)   -> "ext2"
    Utils::get_filesystem_string(true, FS_EXT2)    -> "[Encrypted] ext2"

This is ready for use of Utils::get_filesystem_string(true, FS_EXT2)
when composing the preview of a format of an encrypted file system by
Win_GParted::activate_format().

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 112ddef9df Implement mount/umount of encrypted file systems (#774818)
Adapts the swapon/swapoff, activate/deactivate Volume Group and mount/
unmount file system code to work with the Partition object directly
containing the file system.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 313c5fcb1c Add bug checks into check operation methods (#774818)
Ensure pre-condition of never being passed a Partition object containing
an open LUKS encryption mapping is met for check operation related
methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood df05a9785f Implement check operation on encrypted file systems (#774818)
Just update the code describing and implementing the check operation.
No need to update the code composing the operation in
Win_GParted::activate_check() as that is incredibly simple, just cloning
the Partition object and doesn't need changing.

Note that for encrypted file systems this does:
1) runs FSCK on the encrypted file system;
2) grows the file system to fill the encrypted mapping.
At this time it does not grow the encryption mapping to fill the
partition.  That will be added after resize/move has been implemented.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 49c0564601 Add bug checks into label file system operation methods (#774818)
Ensure pre-condition of never being passed a Partition object containing
an open LUKS encryption mapping is met for label file system operation
related methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood ff4ac89ba2 Implement label operation on encrypted file systems (#774818)
Again, just need to change the code when composing, describing and
implementing the operation to query and set the Partition object
directly containing the file system, instead of the enclosing encryption
mapping to make it work.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 8e41a5f712 Display encrypted path in the calibration step (#774818)
For an encrypted file system the calibrate step now looks like:

    + calibrate /dev/sdb4
        path: /dev/sdb4 (partition)
        start: 6293504
        end: 8390655
        size: 2097152 (1.00 GiB)
        encryption path: /dev/mapper/sdb4_crypt

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 8984ccaf23 Add bug checks into change UUID operation methods (#774818)
Ensure pre-condition of never being passed a Partition object containing
an open LUKS encryption mapping is met for change UUID operation related
methods.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 3ba7128d55 Implement new UUID operation on encrypted file systems (#774818)
When composing, describing and implementing the operation just need the
code to query and set the Partition object directly containing the file
system, instead of the enclosing encryption mapping to make it work.

The operation details for setting a new UUID on an encrypted ext4 file
system become:

    Set a new random UUID on [Encrypted] ext4 file system on /dev/sdb4
    + calibrate /dev/sdb4
    + Set UUID on /dev/mapper/sdb4_crypt to a new, random value
      + tune2fs -U random /dev/mapper/sdb4_crypt
          tune2fs 1.41.12 (17-May-2010)

Also note the now documented rule in apply_operation_to_disk() which
says each operation must leave the status of the encryption mapping and
file system as it found it.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood bd6fc67afb Provide virtual Partition::get_filesystem_string() method (#774818)
Provide and use a single interface for getting the file system string
for display, regardless of whether the partition is encrypted or the
encryption mapping is active or not.

Example return values for get_filesystem_string() for different types
and states of Partition objects:
1)  Plain ext4 file system:          -> "ext4"
2)  Closed encrypted:                -> "[Encrypted]"
3)  Open encrypted ext4 file system: -> "[Encrypted] ext4"

This simplifies the code in TreeView_Detail::create_row() which sets the
file system type displayed in the main window.  The same method will
then also be used when setting the operation description as each
operation is updated to handle encrypted file systems.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood aa49b763e4 Remove virtual PartitionLUKS::get_filesystem_label() (#774818)
The previous commit changed how the code behind the main window
retrieved the file system label for display.  This is the relevant
changes in TreeView_Detail::create_row():

  + const Partition & filesystem_ptn = partition.get_filesystem_partition();
    ...
  - Glib::ustring temp_filesystem_label = partition.get_filesystem_label();
  + Glib::ustring temp_filesystem_label = filesystem_ptn.get_filesystem_label();
    treerow[treeview_detail_columns.label] = temp_filesystem_label;

In the case of an encrypted file system get_filesystem_label() is now
called on the Partition object directly rather than on the outer
Partition object containing the LUKS encryption.

The code behind the Information dialog always obtained and used the
Partition object directly containing the file system to call
get_filesystem_label() since read-only LUKS support was added.
Therefore the virtualised PartitionLUKS::get_filesystem_label() is no
longer needed, so remove it.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 53fd80e6ca Provide virtual Partition::get_filesystem_partition() method (#774818)
There are multiple cases of code wanting to work with the Partition
object directly containing the file system, regardless of whether it is
within a PartitionLUKS object or not.  The code had to do something
similar to this to access it:

    const Partition * filesystem_ptn = &partition;
    if ( partition.filesystem == FS_LUKS && partition.busy )
            filesystem_ptn = &dynamic_cast<const PartitionLUKS *>( &partition )->get_encrypted();
    ...
    // Access Partition object directly containing the file system
    filesystem_ptn-> ...

Implement and use virtual accessor get_filesystem_partition() which
allows the code to be simplified like this:

    const Partition & filesystem_ptn = partition.get_filesystem_partition();
    ...
    // Access Partition object directly containing the file system
    filesystem_ptn. ...

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood 2be136b9fd Display busy status of the file system within LUKS encryption (#774818)
In the main window, display the busy status of the file system only
according to whether it is mounted or not, ignoring the status of the
encryption mapping.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood b2190372d0 Ensure blkid FS_Info cache has entries for all whole disk devices (#771244)
More recent versions of blkid don't report an ISO9660 file system on the
whole disk device if partitions can be reports for embedded partitions.
However when querying the whole disk device directly then the expected
ISO9660 file system is reported.  For example on CentOS 7 with the
previous ISO images:

    # wget http://git.kernel.org/cgit/utils/util-linux/util-linux.git/plain/tests/ts/isosize/sample.iso.gz
    # dd if=/dev/zero bs=1M of=/dev/sdc
    # zcat sample.iso.gz | dd of=/dev/sdc

    # blkid -v
    blkid from util-linux 2.23.2  (libblkid 2.23.0, 25-Apr-2013)
    # blkid | fgrep /dev/sdc
    /dev/sdc1: UUID="2013-01-04-22-05-45-00" LABEL="ARCH_201301" TYPE="iso9660" PTTYPE="dos"
    # blkid /dev/sdc
    /dev/sdc: UUID="2013-01-04-22-05-45-00" LABEL="ARCH_201301" TYPE="iso9660" PTTYPE="dos"

    # wget http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso
    # dd if=/dev/zero bs=1M of=/dev/sdc
    # dd if=debian-8.6.0-amd64-netinst.iso bs=1M of=/dev/sdc

    # blkid | fgrep /dev/sdc
    /dev/sdc1: UUID="2016-09-17-14-23-48-00" LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660" PTTYPE="dos"
    /dev/sdc2: SEC_TYPE="msdos" UUID="17F3-1162" TYPE="vfat"
    # blkid /dev/sdc
    /dev/sdc: UUID="2016-09-17-14-23-48-00" LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660" PTTYPE="dos"

This behavioural difference with blkid is probably as a result of newer
versions of udev informing the kernel of the partitions embedded within
the ISO9660 image, and not directly as a result of a change in blkid
itself.  Older distributions don't have partition entries for the above
ISO images, but CentOS 7 (with udev 219) and later distributions do have
partition entries:

    # fgrep sdc /proc/partitions
       8       16    8388608 sdc
       8       17     252928 sdc1
       8       18        416 sdc2

Fix by ensuring that the blkid FS_Info cache has entries for whole disk
devices, even if each entry has all empty attributes because there is a
partition table and not a recognised file system.

Calling blkid on whole disk devices containing partition tables produces
output like this, with newer versions of blkid:

    # blkid /dev/sda
    /dev/sda: PTTYPE="dos"
    # blkid /dev/sdb
    /dev/sdb: PTTYPE="gpt"

This will be loaded into the FS_Info cache as a blank entry for the
device by run_blkid_load_cache().  There will be a path name but all the
other attributes will be blank because there are no TYPE, SEC_TYPE, UUID
or LABEL name value pairs.  With older versions of blkid no output is
produced at all.  In that case load_fs_info_cache_extra_for_path() will
create the same blank entry with just the path name defined.

Bug 771244 - gparted does not recognize the iso9660 file system in
             cloned Ubuntu USB boot drives
2017-01-06 12:21:50 -07:00
Mike Fleetwood 683dc9d1ab Only read partition table after not finding a whole disk file system (#771244)
ISO9660 images can contain embedded partitions which when encountered on
whole disk drives causes libparted to report various warnings and
errors.  For example on CentOS 6 with upgraded libparted 2.4 the
following errors and warnings are encountered with various ISO images.
(Deliberately using an older distribution with older blkid to avoid
another issue with blkid addressed in the following patch).

Libparted error message 1:
    # wget http://git.kernel.org/cgit/utils/util-linux/util-linux.git/plain/tests/ts/isosize/sample.iso.gz
    # dd if=/dev/zero bs=1M of=/dev/sdc
    # zcat sample.iso.gz | dd of=/dev/sdc

    # blkid -v
    blkid from util-linux-ng 2.17.2 (libblkid 2.17.0, 22-Mar-2010)
    # blkid | fgrep /dev/sdc
    /dev/sdc: LABEL="ARCH_201301" TYPE="iso9660"

    # ./gpartedbin /dev/sdc
    ======================
    libparted : 2.4
    ======================
    Invalid partition table - recursive partition on /dev/sdc.

    Libparted Error
    (-) Invalid partition table - recursive partition on /dev/sdc.
                                             [ Cancel ] [ Ignore ]

Libparted error message 2:
    # wget http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso
    # dd if=/dev/zero bs=1M of=/dev/sdc
    # dd if=debian-8.6.0-amd64-netinst.iso bs=1M of=/dev/sdc

    # blkid | fgrep /dev/sdc
    /dev/sdc: LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660"

    # ./gpartedbin /dev/sdc
    ======================
    libparted : 2.4
    ======================
    /dev/sdc contains GPT signatures, indicating that it has a GPT
    table.  However, it does not have a valid fake msdos partition
    table, as it should.  Perhaps it was corrupted -- possibly by a
    program that doesn't understand GPT partition tables.  Or perhaps
    you deleted the GPT table, and are now using an msdos partition
    table.  Is this a GPT partition table?

    Libparted Warning
    /!\ /dev/sdc contains GPT signatures, indicating that it has a GPT
        table.  However, it does not have a valid fake msdos partition
        table, as it should.  Perhaps it was corrupted -- possibly by a
        program that doesn't understand GPT partition tables.  Or
        perhaps you deleted the GPT table, and are now using an msdos
        partition table.  Is this a GPT partition table?
                                                         [ Yes ] [ No ]

These messages are because GParted is calling ped_disk_new() to attempt
to read the partition table even before it has tried to recognise the
ISO9660 file system on the whole disk drive.  Full call chain is:
    set_devices_thread()
        set_device_from_disk()
            get_device_and_disk()
                get_disk()
                    ped_disk_new()

Fix this by delaying the call to ped_disk_new() until after whole disk
drive recognition has been performed.  Replace combined
get_device_and_disk() with separate get_device() and only call
get_disk() after no whole disk drive file system has been recognised.
This is similar to how calibrate_partition() and
erase_filesystem_signatures() are structured to also handle whole disk
drive file systems.

Bug 771244 - gparted does not recognize the iso9660 file system in
             cloned Ubuntu USB boot drives
2017-01-06 12:21:40 -07:00
Mike Fleetwood fd426cf36e Create new method GParted_Core::set_device_from_disk() (#771244)
Move code from GParted_Core::set_devices_thread() performing top level
population of each Device object during the scan of the drives into new
set_device_from_disk() method.

Bug 771244 - gparted does not recognize the iso9660 file system in
             cloned Ubuntu USB boot drives
2017-01-06 10:47:11 -07:00
Curtis Gedak f762c0cc34 Add detection of iso9660 file system (#771244)
Requires blkid.

Note that FS_LUKS was also moved to more closely match the order in
include/Utils.h

Bug 771244 - gparted does not recognize the iso9660 file system in
             cloned Ubuntu USB boot drives
2017-01-06 10:47:11 -07:00
Michał Górny e4819fdd45 Include sys/sysmacros.h for major and minor macros (#776173)
Glibc 2.25 is deprecating <sys/types.h> including <sys/sysmacros.h>.
    https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=dbab6577c6684c62bd2521c1c29dc25c3cac966f
    Deprecate inclusion of <sys/sysmacros.h> by <sys/types.h>

Building on Fedora Rawhide with Glibc 2.24.90 produces these warnings:

    BlockSpecial.cc:64:13: warning: In the GNU C Library, "major" is defined
     by <sys/sysmacros.h>. For historical compatibility, it is
     currently defined by <sys/types.h> as well, but we plan to
     remove this soon. To use "major", include <sys/sysmacros.h>
     directly. If you did not intend to use a system-defined macro
     "major", you should undefine it after including <sys/types.h>.
       m_major = major( sb.st_rdev );
                 ^~~~~~~~~~~~~~~~~~~~

    BlockSpecial.cc:65:13: warning: In the GNU C Library, "minor" is defined
     by <sys/sysmacros.h>. For historical compatibility, it is
     currently defined by <sys/types.h> as well, but we plan to
     remove this soon. To use "minor", include <sys/sysmacros.h>
     directly. If you did not intend to use a system-defined macro
     "minor", you should undefine it after including <sys/types.h>.
       m_minor = minor( sb.st_rdev );
                 ^~~~~~~~~~~~~~~~~~~~

Code needing major and minor macros should include <sys/sysmacros.h>
directly.  As both Glibc and musl-libc have always provided this header
and GParted is a Linux only application, just always include the header
and don't bother with an autoconf check for its existence.

Bug 776173 - Missing sys/sysmacros.h #include, needed for experimental
             glibc versions
2017-01-04 10:58:44 +00:00
Mike Fleetwood c03c5d11dc Add lost "shrink file system" operation detail message (#775932)
The details for a file system shrink operation look like this with the
"shrink file system" message being missing:

    Shrink /dev/sdb1 from 128.00 MiB to 100.00 MiB
    + calibrate /dev/sdb1
    + check file system on /dev/sdb1 for errors and (if possible) fix them
      + e2fsck -f -y -v -C 0 /dev/sdb1
      + resize2fs -p /dev/sdb1 102400K
    + shrink partition from 128.00 MiB to 100.00 MiB

This earlier commit [1] in the series dropped the message while moving
code from resize_filesystem() to shrink_filesystem().  Re-add the
message back.

[1] a0158abbeb
    Refactor resizing file system apply methods (#775932)

Bug 775932 - Refactor mostly applying of operations
2016-12-16 14:22:54 -07:00
Mike Fleetwood 8373d36ed2 Improve comment about disallowing shrinking when the FS usage is unknown
Explain when and why shrinking file systems is disallowed.

Unnecessary history.  Check added in 2004-12-15:
    d100935b55
    :Set_Valid_Operations()

Comment later added in 2006-07-30:
    677a21f50a
    improved errorhandling a bit. At the initialscan we store errors/warnings
2016-12-12 13:15:34 -07:00
Mike Fleetwood 8979913a3f Remove "../include/" from GParted header #includes
It made the code look a little messy, is easily resolved in the build
system and made the dependencies more complicated than needed.  Each
GParted header was tracked via multiple different names (different
numbers of "../include/" prefixes).  For example just looking at how
DialogFeatures.o depends on Utils.h:

    $ cd src
    $ make DialogFeatures.o
    $ egrep ' [^ ]*Utils.h' .deps/DialogFeatures.Po
     ../include/DialogFeatures.h ../include/../include/Utils.h \
     ../include/../include/../include/../include/../include/../include/Utils.h \
     ../include/../include/../include/Utils.h \

After removing "../include/" from the GParted header #includes, just
need to add "-I../include" to the compile command via the AM_CPPFLAGS in
src/Makefile.am.  Now the dependencies on GParted header files are
tracked under a single name (with a single "../include/" prefix).  Now
DialogFeatures.o only depends on a single name to Utils.h:

    $ make DialogFeatures.o
    $ egrep ' [^ ]*Utils.h' .deps/DialogFeatures.Po
     ../include/DialogFeatures.h ../include/Utils.h ../include/i18n.h \
2016-12-12 13:15:34 -07:00
Mike Fleetwood 683b4da0e4 Update LVM2 PV activate/deactivate check in set_valid_operations()
Simplify conditions checking whether activate/deactivate of an LVM2 PV
is possible.  Excluding extended partition type was unnecessary as it
only matters that the file system type is LVM2 PV or not.

Also remove activate/deactivate from the comment above as that check
only determines if the busy state of file systems and swap space can be
toggled.
2016-12-12 13:15:34 -07:00
Mike Fleetwood 2740113dcb Refactor linux-swap recreation (#775932)
Linux-swap is recreated as part of copy, resize and move operations and
the code was special cased to implement that by calling the linux-swap
specific resize method.  However the displayed text always said "growing
file system" and then proceeded to recreate linux swap.  Example
operation:

    Copy /dev/sdb1 to /dev/sdb2
    ...
    + copy file system from /dev/sdb1 to /dev/sdb2
        Partition copy action skipped because linux-swap file system does not contain data
    + grow file system to fill the partition
      + create new linux-swap file system
        + mkswap -L"" -U "77d939ef-54d6-427a-a2bf-a053da7eed4c" /dev/sdb2
            Setting up swapspace version 1, size = 262140 KiB
            LABEL=, UUID=77d939ef-54d6-427a-a2bf-a053da7eed4c

Fix by writing recreate_linux_swap_filesystem() method with better
messaging and use everywhere maximise_filesystem() was previously used
to recreate linux-swap.  Also as this is a create step, erase the
partition first to prevent the possibility of any other file system
signatures being found afterwards.  Now the operation steps are more
reflective of what is actually being performed.

    Copy /dev/sdb1 to /dev/sdb2
    ...
    + copy file system from /dev/sdb1 to /dev/sdb2
        Partition copy action skipped because linux-swap file system does not contain data
    + clear old file system signatures in /dev/sdb2
    + create new linux-swap file system
      + mkswap -L"" -U "77d939ef-54d6-427a-a2bf-a053da7eed4c" /dev/sdb2
          Setting up swapspace version 1, size = 262140 KiB
          LABEL=, UUID=77d939ef-54d6-427a-a2bf-a053da7eed4c

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood a1c938b30d Properly check for file system online resize capabilities (#775932)
Resizing a file system only checked the .grow and .shrink support
capabilities of the file system, even when perform online resizing.
This wasn't a issue because .online_grow and .online_shrink were always
set from the offline .grow and .shrink capabilities respectively, but
only when online resizing was possible.

However the Device Mapper encryption mapping used for LUKS can only be
resized when online, and not when offline.  Therefore the correct
.online_grow and .online_shrink capabilities needs to be checked to
prevent a LUKS resize step failing as not implemented.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood a0158abbeb Refactor resizing file system apply methods (#775932)
resize_filesystem() was meeting two different needs:
1) when called with fill_partition = false it generated operation
   details;
2) when called from maximize_filesystem() with fill_partition = true it
   skipped generating any operation details;
then ran the switch statement to select the resize implementation.  So
extract the common switch statement into new method
resize_filesystem_implement().

Then observe that the only time resize_filesystem() was called to grow
the file system was when re-creating linux-swap.  Therefore change that
call to use maximize_filesystem() and rename to shrink_filesystem() and
modify the operation detail messages to match.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood a1c2454856 Make copying and moving swap depend on mkswap availability (#775932)
Attempting to copy or move linux-swap partition was possible when the
mkswap command was unavailable.  However as linux-swap is re-created as
part of these operations the mkswap command is a mandatory requirement.
Example copy operation results:

    Copy /dev/sdb1 to /dev/sdb2
    + calibrate /dev/sdb1
    + check file system on /dev/sdb1 for errors and (if possible) fix them
    + create empty partition
    + set partition type on /dev/sdb2
    + copy file system from /dev/sdb1 to /dev/sdb2           [SUCCESS]
        Partition copy action skipped because linux-swap file system does not contain data
    + grow file system to fill the partition                 [WARNING]
        growing is not available for this file system

Because mkswap was not available the grow action didn't re-create
the linux-swap so the newly copied partition is left without any content
and therefore reported as an unknown partition.

Fix by making copying and moving linux-swap depend on mkswap being
available.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 0420159c1d Rename a few GParted_Core apply related methods (#775932)
Make the methods called below apply_operation_to_disk() follow a
standard naming convention:

 *  Contains "_partition"
    Uses libparted to query or change the partition in the disk label
    (partition table).
    E.g.:
        calibrate_partition()
        create_partition()
        delete_partition()
        name_partition()
        resize_move_partition()
        set_partition_type()

 *  Contains "_filesystem"
    Manipulates the file system within the partition, mostly using the
    FileSystem and derived class methods.
    E.g.:
        create_filesystem()
        remove_filesystem()
        label_filesystem()
        copy_filesystem()
        erase_filesystem_signatures()
        check_repair_filesystem()
        resize_filesystem()
        maximize_filesystem()

 *  Other
    Compound method calling multiple partition and file system related
    apply methods.
    E.g.:
        create()
        format()
        copy()
        resize_move()
        resize()
        move()

Rename:
    Delete()      -> delete_partition()
    change_uuid() -> change_filesystem_uuid()

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 9a1841caaa Properly report specific move and resize errors as bugs (#775932)
The initial check in each of GParted_Core::resize() and move() check for
impossible conditions.  (See resize_move() where both functions are
called for confirmation).  The old messages could have suggested the
user somehow composed the operation incorrectly if they had ever been
seen.

Make it clear these failures are programming bugs, thus expecting the
user to raise a bug report should they ever be seen.  While for now the
checks are obviously impossible they document preconditions for the
functions.  More precondition checks are expected to be added later.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood d2fad35407 Refactor GParted_Core::move() (#775932)
Simplify the move() function.  Change it into an if-operation-fails-
return-false style and re-write the final overly complicated conditional
check repair and maximise file system.

The final condition said if the file system was linux-swap or the new
partition was larger, perform a check repair and maximize file system.
However this is a move only step with a check at the top of the move()
function ensuring the Partition objects are the same size.  So that
simplifies to only checking for linux-swap.  As the context is a move
and linux-swap is recreated, performing a check repair first is
unnecessary, so remove that too.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 7caebd2515 Make resize_move_partition() skip whole disk device partitions (#775932)
Make the logic at the resize_move_partition() call sites a little
simpler by not having to avoid calling it for whole disk device
partitions.  Make it a successful non-operation in that case.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 84acec3f91 Make check_repair_filesystem() skip mounted file systems (#775932)
Make the logic at the check_repair_filesystem() call sites a little
easier by not having to avoid calling it for online file systems.  The
function handles that itself as a silent non-operation.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 829bf0ccc1 Make set_partition_type() skip whole disk device partitions (#775932)
Make the logic at the set_partition_type() call sites a little simpler
by not having to avoid calling it for whole disk device Partition
objects.  Make set_partition_type() handle those itself as a silent
non-operation.

This is similar to how calibrate_partition() could be called on an
UNALLOCATED Partition object, and update_bootsector() is called on
non-NTFS file system Partition objects.  Both are successful and silent
non-operations.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 9f08875997 Make encrypted Partition objects look like whole disk device ones (#775932)
Until now an encryption mapping has been modelled as a Partition object
similar to a partition like this:
    .encrypted.device_path  = "/dev/sdb1"
    .encrypted.path         = "/dev/mapper/sdb1_crypt"
    .encrypted.whole_device = false
    .encrypted.sector_start = // start of the mapping in the partition
    .encrypted.sector_end   = // end of the mapping in the partition
However accessing device_path in the start to end sector range is not
equivalent to accessing the partition path as it doesn't provide access
to the encrypted data.  Therefore existing functions which read and
write partition data (GParted file system copying and signature erasure)
via libparted using the device_path won't work and will in fact destroy
the encrypted data.  This could be coded around with an extra case in
the device opening code, however it is not necessary.

An encrypted block special device /dev/mapper/CRYPTNAME looks just like
a whole disk device because it doesn't contain a partition and the file
system it contains starts at sector 0 and goes to the end.  Therefore
model an encryption mapping in the same way a whole disk device is
modelled as a Partition object like this:
    .encrypted.device_path  = "/dev/mapper/sdb1_crypt"
    .encrypted.path         = "/dev/mapper/sdb1_crypt"
    .encrypted.whole_device = true
    .encrypted.sector_start = 0
    .encrypted.sector_end   = // size of the encryption mapping - 1
Now GParted file system copy and erasure will just work without any
change.  Just need to additionally store the LUKS header size, which was
previous stored in the sector_start, for use in the
get_sectors_{used,unused,unallocated}() calculations.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 0b359a5490 Refactor GParted_Core::copy() (#775932)
Split out the switch statement selecting the copy implementation and
associated copy file system operation detail message into a separate
copy_filesystem() method, matching how a number of other operations are
coded.  This is why the previous copy_filesystem() methods needed
renaming.

Re-write the remaining copy() into if-operation-fails-return-false style
to simplify it.  Re-write final complicated conditional check repair and
maximise file system into separate positive if conditions for swap and
larger partition to make it understandable.

The min_size parameter to copy() was queried from the partition_src
parameter also passed to copy().  Drop the parameter and query inside
copy() instead.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood fd56d7be57 Rename copy_filesystem() methods (#775932)
Rename GParted_Core methods:
    copy_filesystem(4 params)  -> copy_filesystem_internal()
    copy_filesystem(5 params)  -> copy_filesystem_internal()
    copy_filesystem(10 params) -> copy_blocks()

See the following commit for the desire to do this.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood fed2595d6d Rename file and class to CopyBlocks (#775932)
Files were named Block_Copy and the class was named block_copy.  Change
to the primary naming convention of CamelCase class name and matching
file names.

Also make CopyBlocks::copy_block() a private method as it is only used
internally within the class.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood a5f2c9937b Refactor activate_mount_partition() and toggle_busy_state() (#775932)
These two methods had a lot of repeated and common code.  Both determine
if the partition has any pending operations, notify the user that
changing the busy status can not be performed, and report any errors
when changing the status.

Extract the common code into sub-functions check_toggle_busy_allowed()
and show_toggle_failure_dialog() to handle showing the message dialogs.
Also refactor toggle_busy_state() to make it clear that it handles 5
cases of swapon, swapoff, activate VG, deactivate VG and unmount file
system.

Also remove out of date comment near the top of toggle_busy_state()
stating there can only be pending operations for inactive partitions is
out of date.  Some file systems can be resized while online and
partition naming is allowed whatever the busy status of the file system.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood bfc16bd4a6 Refactor Win_GParted::unmount_partition() (#775932)
The primary reason to refactor unmount_partition() is to pass the
Partition object to be unmounted, rather than use member variable
selected_partition_ptr so that it doesn't have to handle the differences
between encrypted and non-encrypted Partition objects.  The calling
function can deal with that instead.  Then there were lots of small
reasons to change almost every other line too:
* Return success or failure rather than updating a passed pointer with
  the result.  Leftover from when the function used to be a separate
  thread:
      commit 52a2a9b00a
      Reduce threading (#685740)
* Pass updated error string by reference rather than by pointer.  Likely
  another leftover.
* Stop borrowing the updated error string as a local variable for the
  error output from the umount command.  Use new umount_error local
  variable instead.  Was bad practice making the code harder to
  understand.
* Rename failed_mountpoints to skipped_mountpoints to better reflect
  that it contains the mount points not attempted to be unmounted
  because two or more file systems are mounted at that point.
* Rename errors to umount_errors to better reflect it contains the
  errors from each failed umount command.
* Document the reason for mount points being skipped.
* Update the skipped mount points message to state definitely why they
  could not be unmounted rather than stating most likely.
* Simplify logic processing the error cases and return value.
* Made static because it no longer accesses any class members.
* Remove out dated "//threads.." comment from the header.  Another
  leftover from when the function use to be a separate thread.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:16 -07:00
Mike Fleetwood 43f2a4bd08 Reorder and rename params to TreeView_Detail::load_partitions()
Reorder the parameters into the same order in which they occur in the
row, i.e. Name first, then Mount Point and finally Label.  Rename local
variables in load_partitions(1 param) and parameters of
load_partitions(5 params) prefixing with "show_" to make it clearer the
variables track if that column will be displayed or not.
2016-12-02 10:06:01 -07:00
Mike Fleetwood 9e932ec7d0 Fix detection of empty mount point column for encrypted file systems (#775475)
create_row() populates the values for each row to be displayed in the UI
from the relevant Partition object.  However load_partitions(5 params)
independently decided if the Name, Mount Point and Label columns were
empty and should be displayed.

Getting the mount point value is more complex for encrypted file systems
because it has to call get_mountpoints() on the inner encrypted
Partition object.  load_partitions(5 params) didn't account for this.

Fix by making create_row() both copy the values into each row and at the
same time check if they are empty to decide if they should be displayed
or not.

Bug 775475 - Mount Point column displayed for encrypted file systems
             even when empty
2016-12-02 09:56:29 -07:00
Mike Fleetwood 6bacd6ae4d Fix slightly messed up comment in Win_GParted::on_show() (#771816)
Bug 771816 - GParted never exits if the main window is closed before the
             initial device load completes
2016-10-10 14:07:54 -06:00
Mike Fleetwood aeebee9c12 Prevent the UI hanging while gpart data rescue is running (#772123)
Running Device > Attempt Data Rescue... hangs the GParted UI for as long
as gpart takes to scan the whole disk device looking for file system
signatures.

Originally when gpart support was added by commit [1] a separate thread
was created to run gpart.  Then most threading was removed by commit [2]
which left gpart running in the main thread blocking the UI.

[1] ef37bdb7de
    Added support to lost data recovery using gpart

[2] 52a2a9b00a
    Reduce threading (#685740)

guess_partition_table() hand codes using Glib to run the gpart command
asynchronously reading standard output, but it just doesn't run the Gtk
main loop to process events, hence the UI hangs.  Instead just use
Utils::execute_command() which handles everything already.  It runs the
commands asynchronously, reading output and if being run in the main
thread also calls the Gtk main loop to keep the UI responsive.

Bug 772123 - GParted is unresponsive while gpart is running
2016-10-06 10:07:23 -06:00
Mike Fleetwood 7ea22f1190 Make GParted exit when closed before the initial load completes (#771816)
If the GParted main window is closed before the initial device load
completed gpartedbin never exits.  The main window closes but the
process sits there idle forever.  Subsequently running GParted reports
this error:
    # gparted
    The process gpartedbin is already running.
    Only one gpartedbin process is permitted.

If the user is running GParted from a desktop menu they will never see
this error so they will never know why GParted won't start any more.

More technically, it is if the main window is closed before the
Win_GParted::on_show() callback completes.

I assume the Gtk main loop doesn't setup the normal quit handling until
the on_show() callback finishes drawing the main window for the first
time.  Following this hint [1], move the initial device load from the
on_show() callback to immediately after it completes by using a run once
idle callback setup in on_show().

This looks exactly the same to the user except now gpartedbin exits when
the main window is closed during the initial device load.  Note that
GParted finished the device load before exiting.  This is exactly the
same as happens when exiting during subsequent device refreshes.

[1] How to know when a Gtk Window is fully shown?
    http://stackoverflow.com/questions/14663212/how-to-know-when-a-gtk-window-is-fully-shown

    "If you want to know when your main window appears the first time,
    it is far easier (and saner) add a g_idle_add after your show_all
    call."

Bug 771816 - GParted never exits if the main window is closed before the
             initial device load completes
2016-10-05 11:28:36 -06:00
Mike Fleetwood 770ce9a9e1 Line wrap file system status value in the Information dialog (#771693)
Again this is to handle a long list of mount points for a single
partition.  To prevent the file system status value of "Mounted on [list
of 20 mount points]" causing the dialog to become wider than the screen,
line wrap the text.  This instead makes the dialog taller, which already
automatically scrolls vertically as needed.

Bug 771693 - Mount Point column is wider than the screen on openSUSE
             using btrfs root with lots of mounted subvolumes
2016-10-05 10:53:21 -06:00
Mike Fleetwood 1f4f0a4b67 Show too wide Mount Point column with ellipsis (#771693)
openSUSE 42.1 with default btrfs root installation is heavily using
subvolumes.  (Think of btrfs as a storage pool and subvolumes as
individual file systems within the pool for a rough approximation).
Thus the root partition is mounted on many mount points:

    # df -k
    Filesystem     1K-blocks    Used Available Use% Mounted on
    ...
    /dev/sda2       19445760 5820080  13157104  31% /
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/libvirt/images
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/mysql
    /dev/sda2       19445760 5820080  13157104  31% /.snapshots
    /dev/sda2       19445760 5820080  13157104  31% /home
    /dev/sda2       19445760 5820080  13157104  31% /var/opt
    /dev/sda2       19445760 5820080  13157104  31% /usr/local
    /dev/sda2       19445760 5820080  13157104  31% /var/tmp
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/named
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/mariadb
    /dev/sda2       19445760 5820080  13157104  31% /var/spool
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/pgsql
    /dev/sda2       19445760 5820080  13157104  31% /var/lib/mailman
    /dev/sda2       19445760 5820080  13157104  31% /srv
    /dev/sda2       19445760 5820080  13157104  31% /opt
    /dev/sda2       19445760 5820080  13157104  31% /var/crash
    /dev/sda2       19445760 5820080  13157104  31% /tmp
    /dev/sda2       19445760 5820080  13157104  31% /boot/grub2/i386-pc
    /dev/sda2       19445760 5820080  13157104  31% /var/log
    /dev/sda2       19445760 5820080  13157104  31% /boot/grub2/x86_64-efi

As the Mount Point column contains all 20 mount points it makes the
column wider than the screen, requiring lots of horizontal scrolling to
see the following columns.  (Truncated to just 7 mounts in this
example here).

    Partition     | File System | Mount Point
      /dev/sda1 * | # swap      |
      /dev/sda2 * | # btrfs     | /, /.snapshots, /boot/grub2/i386-pc, /boot/grub2/x86_64-efi, /home, /opt, /srv

Fix by making the Mount Point column resizable and display truncated
text with ellipsis.  The column now takes the initial and minimum width
from the width of the "Mount Point" column header text.

    Partition     | File System | Mount Point     |   Size
      /dev/sda1 * | # swap      |                 |  1.45 GiB
      /dev/sda2 * | # btrfs     | /, /.snapsho... | 18.54 GiB

Bug 771693 - Mount Point column is wider than the screen on openSUSE
             using btrfs root with lots of mounted subvolumes
2016-10-05 10:53:21 -06:00
Mike Fleetwood 85b6858702 Remove remaining vestiges of coloured text from the partition list
This commit stopped setting the text colours in the Partition, File
System and Mount Point columns to avoid hard coding text colours making
them impossible to read when using GNOME's High Contrast Inverse theme:
    ff2a6c00dd
    Changes post gparted-0.3.6 - code recreation from Source Forge

    * src/TreeView_Detail.cc: Removed text_color hard coding
      - Removed hard coding of Partition and Filesystem text_color
        which was based on if partition was TYPE_UNALLOCATED.
      - Removed hard coding of Mount text_color which was based
        on if partition was busy.  Lock symbol provides this indicator.
      - Closes GParted bug #413810 - Don't hardcode text colour in
        partition list

Now remove the remaining vestiges left behind.  Remove the unused color
text and mount_text_color columns from the tree model.  Also remove
setting of the column attributes which set the colour of the text in the
tree view from those unused columns in the tree model.

Unnecessary history.  Added by:
    b179990dc9
    show greyed-out mountpoint of unmounted partitions in the treeview
    as an improved way to identify partitions
    Bug #333027 -  Displaying unmounted partitions' default mount points
    in grey

and by commit only in CVS history:
    Bart Hakvoort <...> 2004-08-22 15:06:45
    Made text in Partition column darkgrey for unallocated. this offers
    more visual difference between partitions and unallocated space
2016-10-05 10:53:21 -06:00
Mike Fleetwood c6d29aa7e8 Include extended partitions in the count of active partitions
Trying to create a new partition table on a device with active
partitions reports the number of active partitions in the error dialog.
However when there is a busy logical partition the number of reported
busy partitions will be one less than the number of partitions in the
main UI showing the busy symbol.

GParted considers extended partitions as busy when any of the logical
partitions it contains as busy.  Display in the main UI reflects this.

Fix Win_GParted::active_partitions_on_device_count() to not exclude
extended partitions from the count.
2016-10-05 09:59:15 -06:00
Mike Fleetwood 253c4d6416 Fix BlockSpecial comparison (#771670)
Found that in some cases usage of active encrypted swap was not working,
but only for the first encrypted swap partition.  This only failed on
the first Device Mapper device, dm-0:

    # ls -l /dev/mapper/ /dev/dm-*
    brw-rw---- 1 root disk 254, 0 Oct  4 20:58 /dev/dm-0
    brw-rw---- 1 root disk 254, 1 Oct  4 20:58 /dev/dm-1

    /dev/mapper/:
    total 0
    crw------- 1 root root 10,236 Oct  4 19:48 control
    lrwxrwxrwx 1 root root      7 Oct  4 20:58 sdb1_crypt -> ../dm-0
    lrwxrwxrwx 1 root root      7 Oct  4 20:58 sdb2_crypt -> ../dm-1

    # cat /proc/swaps
    Filename                        Type        Size    Used    Priority
    /dev/sda1                       partition   1524732 92356   -1
    /dev/dm-0                       partition   1046524 0       -2
    /dev/dm-1                       partition   1046524 0       -3

Was failing because the minor number of dm-0 was 0, causing BlockSpecial
operator==() to fall back to name comparison rather than major, minor
number, and GParted name /dev/mapper/sdb1_crypt doesn't match /dev/dm-0.

Found on openSUSE and Ubuntu which don't use LVM by default and don't
already have dm-0 used as an LVM Logical Volume which GParted doesn't
support.

The LINUX ALLOCATED DEVICES document [1] says block special device 0, 0
(major, minor) is not used "reserved as null device number".   (Not to
be confused with 1, 3 /dev/null the Null device).  All other
non-negative pairs are valid block special device numbers.  Therefore
update BlockSpecial operator==() accordingly; compare by major, minor
number when either is greater than 0 falling back to string compare
otherwise.  This still fits in with the BlockSpecial() constructor using
major, minor numbers 0, 0 to represent plain files.

[1] LINUX ALLOCATED DEVICES
    https://www.kernel.org/doc/Documentation/devices.txt

Bug 771670 - Usage of active encrypted swap is not shown
2016-10-05 09:59:15 -06:00
Mike Fleetwood 3966cc3e6f Implement usage reporting of active encrypted swap partitions (#771670)
GParted does not show the usage of active encrypted swap partitions,
instead showing partition warning "Unable to read the contents of this
file system! ...".  OS setup:

    # ls -l /dev/mapper/sdb4_crypt /dev/dm-3
    brw-rw----. 1 root disk 253, 3 Sep 14 07:26 /dev/dm-3
    lrwxrwxrwx. 1 root root      7 Sep 14 07:26 /dev/mapper/sdb4_crypt -> ../dm-3
    # mkswap -L encrypted_swap /dev/mapper/sdb4_crypt
    # swapon /dev/mapper/sdb4_crypt
    # cat /proc/swaps
    Filename                        Type        Size    Used    Priority
    /dev/sda2                       partition   2097148 237632  -1
    /dev/dm-3                       partition   1046524 0       -2

This is because the code was performing a string compare between the
canonical /dev/mapper/sdb4_crypt name GParted is using and the /dev/dm-3
name reported by the kernel via /proc/swaps.  Fix by creating
BlockSpecial objects from the names and compare those so that comparison
is done correctly using major, minor numbers.

Bug 771670 - Usage of active encrypted swap is not shown
2016-10-05 09:59:15 -06:00
Mike Fleetwood ab4040c547 Remove out of date comment from the end of set_devices_thread()
The comment became completely unnecessary with the transfer of
mount_info and fstab_info into separate Mount_Info module by commit:
    63ec73dfda
    Split mount_info and fstab_info maps into separate Mount_Info module

It was never necessary to clear one of the mappings at the end of the
device refresh because it was reloaded at the start of the next device
refresh anyway and it is only a small amount of memory.
2016-09-14 09:48:33 -06:00
Mike Fleetwood 8c870cf72f Stop showing duplicate mount points for unmounted encrypted file systems (#771323)
Have an unmounted file system within an open encrypted mapping and an
entry in /etc/fstab for the file system like this:

    # lsblk
    NAME           MAJ:MIN RM   SIZE RO TYPE   MOUNTPOINT
    ...
    sdb              8:16   0     8G  0 disk
    +-sdb1           8:17   0     1G  0 part
      +-sdb1_crypt 253:0    0  1022M  0 crypt
    # blkid | grep sdb1
    /dev/sdb1: TYPE="crypto_LUKS" ...
    /dev/mapper/sdb1_crypt: TYPE="ext4" ...
    # ls -l /dev/mapper/sdb1_crypt /dev/dm-0
    brw-rw----. 1 root disk 253, 0 Sep 12 19:09 /dev/dm-0
    lrwxrwxrwx. 1 root root      7 Sep 12 19:09 /dev/mapper/sdb1_crypt -> ../dm-0
    # grep sdb1 /etc/fstab
    /dev/mapper/sdb1_crypt   /mnt/1   ext4   defaults    0 0

The mount point will be shown twice for the partition:
    /mnt/1, /mnt/1

This is because add_node_and_mountpoint() adds two entries for both the
symbolic and real block special names:
    map["/dev/mapper/sdb1_crypt"] = ["/mnt/1"]
    map["/dev/dm-0"]              = ["/mnt/1"]
This was needed for the old code which used string compare to match
block devices so that the mount point could be looked up by either name.
However since bug 767842 introduced major, minor number comparison it
became unnecessary.  As both names refer to the same device the mount
point gets added twice to the same entry.  Hence display of the double
mount.
    map[BlockSpecial{"/dev/mapper/sdb1_crypt", 253, 0}] =
                                                    ["/mnt/1", "/mnt/1"]

It is always going to be the case that the symbolic link and real block
special names have the same major, minor numbers.  That was the
requirement of the BlockSpecial class and the reason for using stat() to
lookup the numbers.  Therefore adding entries for both names will always
add duplicate entries.  Fix by stop using realpath() to lookup the real
name and adding the duplicate entry.

Introduced by:
    a800ca8b68
    Add BlockSpecial into mount_info and fstab_info (#767842)

Bug 771323 - GParted is showing duplicate mount points for unmounted
             encrypted file systems
2016-09-14 09:48:33 -06:00
Mike Fleetwood e6f4b1c305 Remove no longer needed includes from GParted_Core.cc
No longer needed since commit:
    504eb04ddc
    Roll back (remove) code to recognize /dev/mapper/* devices, because ...
2016-08-06 09:47:58 -06:00
Mike Fleetwood 63ec73dfda Split mount_info and fstab_info maps into separate Mount_Info module
The GParted_Core::mount_info and GParted_Core::fstab_info maps and the
methods that manipulate them are self-contained.  Therefore move them to
a separate Mount_Info module and reduce the size of the monster
GParted_Core slightly.
2016-08-06 09:47:58 -06:00
Mike Fleetwood a94be2da05 Switch to static class interface for FS_Info
The FS_Info module has a pseudo multi-object interface and used the
constructor to load the cache.  However all the data in the class is
static.  An FS_Info object doesn't contain any member variables, yet was
needed just to call the member functions.

Make all the member functions static removing the need to use any
FS_Info objects and provide an explicit load_cache() method.
2016-08-06 09:47:58 -06:00
Mike Fleetwood 5055c0b638 Simplify whole device matching in load_proc_partitions_Info_cache()
Following earlier commit "Pre-populate BlockSpecial cache while reading
/proc/partitions (#767842)" load_proc_partitions_info_cache() has
extracted just the name field from each line of /proc/partitions.
Therefore simplify the regular expressions matching each type of whole
disk device to just matching in the name field rather than matching in
the whole line.
2016-08-06 09:47:58 -06:00
Mike Fleetwood 912766c2e1 Switch to a static interface for Proc_Partitions_Info
The Proc_Partitions_Info has a pseudo multi-object interface and uses
the constructor to load the cache.  However all the data in the class is
static.  A Proc_Partitions_Info object doesn't contain any member
variables, yet was needed just to call the member functions.

Make all the member functions static removing the need to use any
Proc_Partitions_Info objects and provide and explicit load_cache()
method.
2016-08-06 09:47:58 -06:00
Mike Fleetwood 91e5a0960e Remove remaining use of retired vol_id
Vol_id has been retired and removed from all supported distributions.
See earlier commit "Remove use of retired vol_id from FS_Info module
(#767842)" for more details.  Therefore remove it's use from GParted
entirely.
2016-08-06 09:47:58 -06:00
Mike Fleetwood 571304d2c6 Pre-populate BlockSpecial cache while reading /proc/partitions (#767842)
GParted is already reading /proc/partitions to get whole disk device
names.  The file also contains the major, minor device number of every
partition.  Use this information to pre-populate the cache in the
BlockSpecial class.

    # cat /proc/partitions
    major minor  #blocks  name

       8        0   20971520 sda
       8        1     512000 sda1
       8        2   20458496 sda2
    ...
       9        3    1047552 md3
     259        2     262144 md3p1
     259        3     262144 md3p2
    ...
     253        0   18317312 dm-0
     253        1    2097152 dm-1
     253        2    8383872 dm-2
     253        3    1048576 dm-3

Note that for Device-Mapper names (dm-*) the kernel is not using the
canonical user space names (mapper/*).  There is no harm in
pre-populating the cache with these names and will help if tools report
them too.  It is just that for DMRaid, LVM and LUKS, GParted uses the
canonical /dev/mapper/* names so will still have to call stat() once for
each such name.

For plain disks (sd*) and Linux Software RAID arrays (md*) the kernel
name is the common user space name too, therefore matches what GParted
uses and pre-populating does avoid calling stat() at all for these
names.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 003d6eff94 Cache looked up major, minor numbers in BlockSpecial class (#767842)
Creation of every BlockSpecial object used to result in a stat() OS
call.  On one of my test VMs debugging with 4 disks and a few partitions
on each, GParted refresh generated 541 calls to stat() in the
BlockSpecial(name) constructor.  However there were only 45 unique
names.  So on average each name was stat()ed approximately 12 times.

Cache the major, minor number associated with each name after starting
with a cleared cache for each GParted refresh.  This reduces these
direct calls to stat() to just the 45 unique names.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood ce8fb1dd91 Use BlockSpecial in FS_Info module cache (#767842)
The FS_Info cache is loaded from "blkid" output and compares block
special names.  Therefore switch to using BlockSpecial objects so that
comparisons are performed by the major, minor device number instead.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 23da3ab9a8 Parse FS_Info cache into fields while loading (#767842)
FS_Info module caches the output from blkid as a single string and uses
regular expressions to find the line matching the requested block
special file name.  This is not compatible with using BlockSpecial
objects to represent block special files, and perform matching by major,
minor device number.  Therefore parse the blkid output into a vector of
structures containing the needed fields, ready for switching to
BlockSpecial objects in the following patch.

Interface to the module remains unchanged.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 8aa34f7baa Remove use of retired vol_id from FS_Info module (#767842)
Vol_id was removed from udev 142, released 2009-05-13, and udev switched
to using blkid instead [1].  All currently supported distributions use
later versions of udev (or systemd after the udev merge), except for
RedHat / CentOS 5 with udev 095.  However RedHat / CentOS 5 does provide
blkid and vol_id is found in udev specific /lib/udev directory not on
the PATH.  Therefore effectively vol_id is not available on any
supported distribution and blkid is always available.  Therefore remove
use of vol_id from the FS_Info module.  Less code to refactor and test
in following changes.

[1] delete vol_id and require util-linux-ng's blkid
    http://git.kernel.org/cgit/linux/hotplug/udev.git/commit/?id=f07996885dab45102492d7f16e7e2997e264c725

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 2b013e494c Use BlockSpecial in SWRaid_Info module cache (#767842)
The SWRaid_Info cache is loaded from "mdadm" command output and
/proc/mdstat file.  It contains the member name which is used to access
the cache, therefore switch to using BlockSpecial objects so that
comparison is performed using the major, minor device number.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 7cd574cac5 Use BlockSpecial in LUKS_Info module cache (#767842)
The LUKS_Info module cache is loaded from "dmsetup" command and compares
block special files, therefore switch to using BlockSpecial objects so
that comparisons are performed by major, minor device number.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood e4a8530b14 Overload is_dev_mounted() function (#767842)
Small optimisation which avoids constructing an extra BlockSpecial
object when determining if a btrfs member is mounted.  Rather than
extracting the name from the BlockSpecial object in
btrfs::get_mount_device() and re-constructing another BlockSpecial
object from that name in GParted_Core::is_dev_mounted(), pass the
BlockSpecial object directly.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood abee66484f Use BlockSpecial objects in btrfs member cache (#767842)
There are no known errors which affect the remaining caches in GParted.
However those caches which compare block special devices will be changed
to use BlockSpecial objects so comparison is by major, minor device
number rather than by name.

Change btrfs member cache loaded from "btrfs filesystem show" output to
use BlockSpecial objects.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood a800ca8b68 Add BlockSpecial into mount_info and fstab_info (#767842)
On some distributions having btrfs on top of LUKS encrypted partitions,
adding a second device and removing the first device used to mount the
file system causes GParted to no longer be able to report the file
system as busy or the mount points themselves.

For example, on CentOS 7, create a single btrfs file system and mount
it.  The provided /dev/mapper/sdb1_crypt name is reported, via
/proc/mounts, as the mounting device:
    # cryptsetup luksFormat --force-password /dev/sdb1
    # cryptsetup luksOpen /dev/sdb1 sdb1_crypt
    # mkfs.btrfs -L encrypted-btrfs /dev/mapper/sdb1_crypt
    # mount /dev/mapper/sdb1_crypt /mnt/1

    # ls -l /dev/mapper
    total 0
    lrwxrwxrwx. 1 root root       7 Jul  2 14:15 centos-root -> ../dm-1
    lrwxrwxrwx. 1 root root       7 Jul  2 14:15 centos-swap -> ../dm-0
    crw-------. 1 root root 10, 236 Jul  2 14:15 control
    lrwxrwxrwx. 1 root root       7 Jul  2 15:14 sdb1_crypt -> ../dm-2
    # fgrep btrfs /proc/mounts
    /dev/mapper/sdb1_crypt /mnt/1 btrfs rw,seclabel,relatime,space_cache 0 0

Add a second device to the btrfs file system:
    # cryptsetup luksFormat --force-password /dev/sdb2
    # cryptsetup luksOpen /dev/sdb2 sdb2_crypt
    # btrfs device add /dev/mapper/sdb2_crypt /mnt/1

    # ls -l /dev/mapper
    ...
    lrwxrwxrwx. 1 root root       7 Jul  2 15:12 sdb2_crypt -> ../dm-3
    # btrfs filesystem show /dev/mapper/sdb1_crypt
    Label: 'encrypted-btrfs'  uuid: 45d7b1ef-820c-4ef8-8abd-c70d928afb49
            Total devices 2 FS bytes used 32.00KiB
            devid    1 size 1022.00MiB used 12.00MiB path /dev/mapper/sdb1_crypt
            devid    2 size 1022.00MiB used 0.00B path /dev/mapper/sdb2_crypt

Remove the first mounting device from the btrfs file system.  Now the
non-canonical name /dev/dm-3 is reported, via /proc/mounts, as the
mounting device:
    # btrfs device delete /dev/mapper/sdb1_crypt /mnt/1

    # btrfs filesystem show /dev/mapper/sdb2_crypt
    Label: 'encrypted-btrfs'  uuid: 45d7b1ef-820c-4ef8-8abd-c70d928afb49
            Total devices 1 FS bytes used 96.00KiB
            devid    2 size 1022.00MiB used 144.00MiB path /dev/mapper/sdb2_crypt
    # fgrep btrfs /proc/mounts
    /dev/dm-3 /mnt/1 btrfs rw,seclabel,relatime,space_cache 0 0
    # ls -l /dev/dm-3
    brw-rw----. 1 root disk 253, 3 Jul  2 15:12 /dev/dm-3

GParted loads the mount_info mapping from /proc/mounts and with it the
/dev/dm-3 name.  When GParted is determining if the encrypted btrfs file
system is mounted or getting the mount points it is using the
/dev/mapper/sdb2_crypt name.  Therefore no information is found and the
file system is incorrectly reported as unmounted.

Fix by changing mount_info and fstab_info to use BlockSpecial objects
instead of strings so that matching is performed by major, minor device
numbers rather than by string compare.  Note that as BlockSpecial
objects are used as the key of std::map [1] mappings operator<() [2]
needs to be provided to order the key values.

[1] std::map
    http://www.cplusplus.com/reference/map/map/
[2] std::map::key_comp
    http://www.cplusplus.com/reference/map/map/key_comp/

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood ab2d4f5ee6 Create BlockSpecial class and use in LVM2_PV_Info (#767842)
In some cases creating an LVM2 Physical Volume on top of a DMRaid array
reports no usage information and this partition 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 lvm2
    pv file system support: lvm2.

For example on Ubuntu 14.04 LTS (with GParted built with
--enable-libparted-dmraid) create an LVM2 PV in a DMRaid array
partition.  GParted uses this command:
    # lvm pvcreate -M 2 /dev/mapper/isw_bacdehijbd_MyArray0p2

But LVM reports the PV having a different name:
    # lvm pvs
      PV                                                VG   Fmt  Attr PSize PFree
      /dev/disk/by-id/dm-name-isw_bacdehijbd_MyArray0p2      lvm2 a--  1.00g 1.00g

This alternate name is loaded into the LVM2_PV_Info module cache.  Hence
when GParted queries partition /dev/mapper/isw_bacdehijbd_MyArray0p2 it
has no PV information against that name and reports unknown usage.

However they are actually the same block special device; major 252,
minor 2:
    # ls -l /dev/mapper/isw_bacdehijbd_MyArray0p2
    brw-rw---- 1 root disk 252, 2 Jul  2 11:09 /dev/mapper/isw_bacdehijbd_MyArray0p2

    # ls -l /dev/disk/by-id/dm-name-isw_bacdehijbd_MyArray0p2
    lrwxrwxrwx 1 root root 10 Jul  2 11:09 /dev/disk/by-id/dm-name-isw_bacdehijbd_MyArray0p2 -> ../../dm-2
    # ls -l /dev/dm-2
    brw-rw---- 1 root disk 252, 2 Jul  2 11:09 /dev/dm-2

To determine if two names refer to the same block special device their
major, minor numbers need to be compared, instead of string comparing
their names.

Implement class BlockSpecial which encapsulates the name and major,
minor numbers for a block special device.  Also performs comparison as
needed.  See bug 767842 comments 4 and 5 for further investigation and
decision for choosing to implement a class.

Replace name strings in the LVM2_PV_Info module with BlockSpecial
objects performing correct block special device comparison.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 0f4df8dfd1 Remove now unused Proc_Partitions_Info::get_alternate_paths() (#767842)
Now Device and Partition objects only have a single path,
get_alternate_paths() is never called.  Remove the method and population
of the private alternate_paths_cache member that went with it.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 40f39bdbe2 Rename Partition::add_path() to set_path() (#767842)
To reflect that there is now only a single path in the Partition object
now.  Also get rid of the now unneeded optional clear_paths parameter
which was only relevant when there was a vector of paths.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 54652b0d4e Update calibrate_partition() for single partition path (#767842)
Now that Partition objects only have a single path, rather than a list
of paths, stop performing unnecessary actions in calibrate_partitions()
which added alternate paths reported from libparted.  Just left with
setting the partition path name correctly, when the path name doesn't
exist.  Happens when the path is set to "Copy of /dev/SRC" when the
partition was newly created by a copy-paste into unallocated space
earlier in the sequence of operations now being applied.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 214255eda3 Simplify Partition object to a single path (#767842)
Change from a vector of paths to a single path member in the Partition
object.  Remove add_paths() and get_paths() methods.  Keep add_path()
and get_path().

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 1dc8a0c628 Rename Device::add_path() to set_path() (#767842)
To reflect that there is only a single path in the Device object now.
Also get rid of the now unneeded optional parameter which was only
relevant when there was a vector of paths.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood 902afaa010 Simplify Device object to a single path (#767842)
Background

GParted stored a list of paths for Device and Partition objects.  It
sorted this list [1][2] and treated the first specially as that is what
get_path() returned and was used almost everywhere; with the file system
specific tools, looked up in various *_Info caches, etc.

[1] Device::add_path(), ::add_paths()
[2] Partition::add_path(), ::add_paths()

Mount point display [3] was the only bit of GParted which really worked
with the path list.  Busy file system detection [4] just used the path
provided by libparted, or for LUKS /dev/mapper/* names.  It checked that
single path against the mounted file systems found from /proc/mounts,
expanded with additional block device names when symlinks were
encountered.

[3] GParted_Core::set_mountpoints() -> set_mountpoints_helper()
[4] GParted_Core::set_device_partitions() -> is_busy()
    GParted_Core::set_device_one_partition() -> is_busy()
    GParted_Core::set_luks_partition() -> is_busy()

Having the first path, by sort order, treated specially by being used
everywhere and virtually ignoring the others was wrong, complicated to
remember and difficult code with.  As all the additional paths were
virtually unused and made no difference, remove them.  The "improved
detection of mountpoins, free space, etc.." benefit from commit [5]
doesn't seem to exist.  Therefore simplify to a single path for Device
and Partition objects.

[5] commit 6d8b169e73
    changed the way devices and partitions store their device paths.
    Instead of holding a 'realpath' and a symbolic path we store paths
    in a list.  This allows for improved detection of mountpoins, free
    space, etc..

This patch

Simplify the Device object from a vector of paths to a single path.
Remove add_paths() and get_paths() methods.  Keep add_path() and
get_path() for now.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Natanael Copa 25209904a9 Fix sscanf modifier for long long (#768239)
POSIX says that %lld is the modifier for long long.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fscanf.html

This fixes wrong sizes with musl libc.

Bug 768239 - sizes are wrong with musl libc due to use of non-standard
             sscanf "%Ld" modifier
2016-07-01 15:37:01 +01:00
Mike Fleetwood 8ac3a0e4ad Recognise GRUB2 core.img (#766989)
Recognise GRUB2 core.img boot code written to a partition without a file
system.  Such setups are possible/likely with GPT partitioned disks as
there is a specific partition type reserved for it [1][2]:
    21686148-6449-6E6F-744E-656564454649  (BIOS Boot partition)

[1] GUID Partition Table, Partition types
    https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs

[2] BIOS boot partition
    https://en.wikipedia.org/wiki/BIOS_boot_partition

Bug 766989 - zfsonline support - need file system name support for ZFS
             type codes
2016-06-15 12:45:05 -06:00
Mike Fleetwood 3daf73a01b Prevent assert failure from OperationDelete::get_partition_new() (#767233)
Composing these operations caused GParted to abort on an assert failure:
(1) Delete an existing partition,
(2) Create a new partition,
(3) Delete new partition.

This is the equivalent issue as fixed in the previous commit, except with
the delete operation rather than the check operation:
    Prevent assert failure from OperationCheck::get_partition_new() (#767233)

    # ./gpartedbin
    ======================
    libparted : 2.4
    ======================
    **
    ERROR:OperationDelete.cc:41:virtual GParted::Partition& GParted::OperationDelete::get_partition_new(): assertion failed: (false)
    Aborted (core dumped)

    # gdb ./gpartedbin core.19232 --batch --quiet --ex backtrace -ex quit
    [New Thread 19232]
    [New Thread 19234]
    [Thread debugging using libthread_db enabled]
    Core was generated by `./gpartedbin'.
    Program terminated with signal 6, Aborted.
    #0  0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    64	  return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
    #0  0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    #1  0x000000361f233dc5 in abort () at abort.c:92
    #2  0x0000003620a67324 in g_assertion_message (domain=<value optimized out>, file=<value optimized out>, line=<value optimized out>, func=0x50fcc0 "virtual GParted::Partition& GParted::OperationDelete::get_partition_new()", message=0x1b55f60 "assertion failed: (false)") at gtestutils.c:1358
    #3  0x0000003620a678f0 in g_assertion_message_expr (domain=0x0, file=0x50fa68 "OperationDelete.cc", line=41, func=0x50fcc0 "virtual GParted::Partition& GParted::OperationDelete::get_partition_new()", expr=<value optimized out>) at gtestutils.c:1369
    #4  0x000000000049aa0d in GParted::OperationDelete::get_partition_new (this=0x1b321b0) at OperationDelete.cc:41
    #5  0x00000000004c6700 in GParted::Win_GParted::activate_delete (this=0x7ffc91403670) at Win_GParted.cc:2068
    ...

As before the crash is happened in Win_GParted::activate_delete() as it
was going through the list of operations removing those which applied to
the never created partition.  It came across the delete operation of an
existing partition and called get_partition_new().  As partition_new was
not set or used by the delete operation this asserted false and crashed
GParted.

Unlike the check operation case, the delete operation doesn't have a
partition afterwards.  (As GParted represents unallocated space with
partition objects then the delete operation could be populated with a
new partition by constructing the correctly merged unallocated space
partition object, but that is what OperationDelete::apply_to_visual()
does and having a place holder doesn't seem like the right thing to do).
Instead exclude delete operations, on existing partitions, when looking
for operations applying to this not yet created partition as they are
mutually exclusive.

Bug 767233 - GParted core dump on assert failure in
             OperationDelete::get_partition_new()
2016-06-05 13:14:34 -06:00
Mike Fleetwood 1f2a50544d Prevent assert failure from OperationCheck::get_partition_new() (#767233)
Composing these operations caused GParted to abort on an assert failure:
(1) Check an existing partition,
(2) Create a new partition,
(3) Delete new partition.

    # ./gpartedbin
    ======================
    libparted : 2.4
    ======================
    **
    ERROR:OperationCheck.cc:40:virtual GParted::Partition& GParted::OperationCheck::get_partition_new(): assertion failed: (false)
    Aborted (core dumped)

    # gdb ./gpartedbin core.8876 --batch --quiet --ex backtrace -ex quit
    [New Thread 8876]
    [New Thread 8879]
    [Thread debugging using libthread_db enabled]
    Core was generated by `./gpartedbin'.
    Program terminated with signal 6, Aborted.
    #0  0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    64	  return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
    #0  0x000000361f2325e5 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    #1  0x000000361f233dc5 in abort () at abort.c:92
    #2  0x0000003620a67324 in g_assertion_message (domain=<value optimized out>, file=<value optimized out>, line=<value optimized out>, func=0x50f400 "virtual GParted::Partition& GParted::OperationCheck::get_partition_new()", message=0x1d37a00 "assertion failed: (false)") at gtestutils.c:1358
    #3  0x0000003620a678f0 in g_assertion_message_expr (domain=0x0, file=0x50f1a8 "OperationCheck.cc", line=40, func=0x50f400 "virtual GParted::Partition& GParted::OperationCheck::get_partition_new()", expr=<value optimized out>) at gtestutils.c:1369
    #4  0x0000000000498e21 in GParted::OperationCheck::get_partition_new (this=0x1d1bb30) at OperationCheck.cc:40
    #5  0x00000000004c66ec in GParted::Win_GParted::activate_delete (this=0x7fff031c3e30) at Win_GParted.cc:2068
    ...

When Win_GParted::activate_delete() was stepping through the operation
list removing operations (2 & 3 in the above recreation steps) which
related to the new partition never to be created it called
get_partition_new() on all operations in the list.  This included
calling get_partition_new() on the check operation (1 in the above
recreation steps).  As partition_new was not set or used by the check
operation get_partition_new() asserted false and crashed GParted.

Fix by populating the partition_new member in OperationCheck objects,
thus allowing get_partition_new() to be called on the object.  As a
check operation doesn't change any partition boundaries or file system
attributes, just duplicate the new partition from the original
partition.

Bug 767233 - GParted core dump on assert failure in
             OperationDelete::get_partition_new()
2016-06-05 13:14:34 -06:00
Mike Fleetwood cc7e412bc6 Only enable ext4 64bit feature when required (#766910)
E2fsprogs version 1.43 always creates 64bit ext4 file systems by default
[1][2] regardless of the partition size.  Previously it only enabled the
64bit feature when required on ext4 volumes 16 TiB and larger.  Also
note that RHEL / CentOS 7 always create 64bit ext4 file systems by
default from e2fsprogs 1.42.9 [3].

(At least some versions of) Grub 2 and syslinux boot loaders don't work
with 64bit ext4 file systems [4][5][6].  For maximum boot loader
compatibility make GParted implement what mke2fs previously did, only
setting the 64bit feature on volumes 16 TiB and larger and clearing it
otherwise.  Only applied to mkfs.ext4 version 1.42 and later.

[1] Release notes, E2fsprogs 1.43 (May 17, 2016)
    http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.43

    "Mke2fs will now create file systems with the metadata_csum and
    64bit features enabled by default".

[2] http://git.kernel.org/cgit/fs/ext2/e2fsprogs.git/commit/?id=cd27af3ecb83e8fd1e3eaa14994284a1818c7c15
    mke2fs: enable the metadata_csum and 64bit features by default

[3] Comment 20 and 21 in Red Hat bug 1099237
    https://bugzilla.redhat.com/show_bug.cgi?id=1099237#c20

    "..., is rhel7 default behavior w.r.t. 64 bit really different from
    upstream ?

    Yes it is. This is what we have in RHEL7:
    Patch6: e2fsprogs-1.42.9-enable-64bit-feature-by-default.patch
    it fixed this bz: https://bugzilla.redhat.com/show_bug.cgi?id=982871
    and this is upstream proposal:
    http://www.spinics.net/lists/linux-ext4/msg42294.html"

[4] Grub 2 not working on Slackware with 64bit EXT4
    http://www.linuxquestions.org/questions/slackware-14/grub-mkconfig-error-in-slackware-current-64-bit-4175580544/

[5] Syslinux not working on Slackware with 64bit EXT4
    http://www.linuxquestions.org/questions/slackware-14/slackware64-current-5-20-2016-syslinux-booting-and-ext4-formatting-4175580324/

[6] Syslinux not working on RHEL 7 with 64bit EXT4
    Bug 1099237 - rhel7 ext4 defaults to 64 bit, which extlinux can't reliably read
    https://bugzilla.redhat.com/show_bug.cgi?id=1099237

Bug 766910 - Multiple boot loaders don't work on 64bit EXT4 file systems
2016-06-05 09:40:11 -06:00
Mike Fleetwood a13526bf41 Don't limit ext4 volume size when 64bit feature is available (#766910)
E2fsprogs 1.42 adds ext4 64bit feature [1] allowing volume sizes larger
than 16 TiB.  However only enable large volumes from e2fsprogs 1.42.9
when a large number of 64bit bugs were fixed [2].  (Also RHEL / CentOS 7
use e2fsprogs 1.42.9 and always enable 64bit feature by default).

[1] Release notes, E2fsprogs 1.42 (November 29, 2011)
    http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.42

    "This release of e2fsprogs has support for file systems > 16TB.
    Online resize requires kernel support which will hopefully be in
    Linux version 3.2.  Offline support is not yet available for > 16TB
    file systems, but will be coming".

[2] Release notes, E2fsprogs 1.42.9 (December 28, 2013)
    http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.42.9

    "Fixed a large number of bugs in resize2fs, e2fsck, debugfs, and
    libext2fs to correctly handle bigalloc and 64-bit file systems.
    There were many corner cases that had not been noticed in previous
    uses of these file systems, since they are not as common.  Some of
    the bugs could cause file system corruption or data loss, so users
    of 64-bit or bigalloc file systems are strongly urged to upgrade to
    e2fsprogs 1.42.9".

Bug 766910 - Multiple boot loaders don't work on 64bit EXT4 file systems
2016-06-05 09:40:11 -06:00
Mike Fleetwood af17808d08 Limit maximum ext2/3/4 volume size to just less than 16 TiB (#766910)
Maximum size of an ext2/3/4 volume is 2^32 - 1 blocks [1], ignoring ext4
with 64bit feature.  That is just under 16 TiB with a 4K block size.

    # truncate -s 16T /mnt/1/sparse.img
    # ls -l /mnt/1/sparse.img
    -rw-r--r--. 1 root root 17592186044416 May 28 19:33 /mnt/1/sparse.img
    # losetup /dev/loop0 /mnt/1/sparse.img
    # mkfs.ext3 /dev/loop0
    mke2fs 1.43 (17-May-2016)
    mkfs.ext3: Size of device (0x100000000 blocks) /dev/loop0 too big to be expressed
            in 32 bits using a blocksize of 4096.
    # losetup -d /dev/loop0
    #
    #
    # truncate -s $((16*1024**3-4))K sparse.img
    # ls -l /mnt/1/sparse.img
    -rw-r--r--. 1 root root 17592186040320 May 28 19:51 /mnt/1/sparse.img
    # losetup /dev/loop0 /mnt/1/sparse.img
    # mkfs.ext3 /dev/loop0
    mke2fs 1.43 (17-May-2016)
    Discarding device blocks: done
    Creating filesystem with 4294967295 4k blocks and 536870912 inodes
    Filesystem UUID: 9721d8d9-8711-499b-aae4-8ea4d9e16ca2
    Superblock backups stored on blocks:
            32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
            4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
            102400000, 214990848, 512000000, 550731776, 644972544, 1934917632,
            2560000000, 3855122432

    Allocating group tables: done
    Writing inode tables: done
    Creating journal (32768 blocks): done
    Writing superblocks and filesystem accounting information: done

    # losetup -d /dev/loop0
    # rm /mnt/1/sparse.img

Actually limit the maximum volume size to 1 MiB less than 16 TiB for
coding reasons explained in the FIXME comment.

[1] Ext4 Disk Layout, Blocks
    https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Blocks

Bug 766910 - Multiple boot loaders don't work on 64bit EXT4 file systems
2016-06-05 09:40:11 -06:00
Mike Fleetwood 3724421e30 Stop leaking PedGeometry object memory (#767009)
Calling libparted ped_geometry_new() creates a new PedGeometry object
from malloced memory, however the corresponding ped_geometry_destroy()
is never called to destroy the object and free the memory.

Perform a resize of a FAT file system when running GParted under
valgrind identifies several memory blocks leaked via ped_geometry_new()
from resize_move_filesystem_using_libparted().  One such example:

    # valgrind --track-origins=yes --leak-check=full ./gpartedbin
    ...
    ==32069== 32 bytes in 1 blocks are definitely lost in loss record 5,419 of 11,542
    ==32069==    at 0x4C29BFD: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==32069==    by 0x8ECD8C5: ped_malloc (libparted.c:231)
    ==32069==    by 0x8ED23C1: ped_geometry_new (geom.c:79)
    ==32069==    by 0x4764F3: GParted::GParted_Core::resize_move_filesystem_using_libparted(GParted::Partition const&, GParted::Partition const&, GParted::OperationDetail&) (GParted_Core.cc:2666)
    ==32069==    by 0x478007: GParted::GParted_Core::resize_filesystem(GParted::Partition const&, GParted::Partition const&, GParted::OperationDetail&, bool) (GParted_Core.cc:2990)
    ==32069==    by 0x478440: GParted::GParted_Core::maximize_filesystem(GParted::Partition const&, GParted::OperationDetail&) (GParted_Core.cc:3037)
    ==32069==    by 0x4769A0: GParted::GParted_Core::resize(GParted::Partition const&, GParted::Partition const&, GParted::OperationDetail&) (GParted_Core.cc:2746)
    ==32069==    by 0x47582B: GParted::GParted_Core::resize_move(GParted::Partition const&, GParted::Partition&, GParted::OperationDetail&) (GParted_Core.cc:2457)
    ==32069==    by 0x46DDB2: GParted::GParted_Core::apply_operation_to_disk(GParted::Operation*) (GParted_Core.cc:767)
    ...

There is also a leak of a PedGeometry object from
resize_move_partition().  Fix by calling ped_geometry_destroy() to
delete all the allocated PedGeometry objects and free the memory.

Bug 767009 - PedGeometry objects are memory leaked
2016-05-30 10:59:31 -06:00
Mike Fleetwood 29be7547cd Remove outdated comment fragment from activate_mount_partition()
Outdated by commit:
    6e97a63f49
    Always use blkid file system detection before libparted (#757781)
2016-05-20 09:25:48 -06:00
Mike Fleetwood ab923121de Replace whole path list after calibrate in apply_operation_to_disk() (#766349)
When replacing the list of paths for the other partition object involved
in either a Resize/Move or Format operation in apply_operation_to_disk()
should replace the whole list of partitions not just replace with the
first path.  Copy the whole path list is the correct action.  It makes
no material difference because secondary partition paths are only used
to discover mount points during refresh phase and not at the apply
phase, where only the primary path is used.

Bug 766349 - Resolve code ugliness with partition path getting set to
             "copy of /dev/SRC"
2016-05-20 09:25:35 -06:00
Mike Fleetwood b77fef0dd5 Stop relying on sort order when adding real paths in calibrate (#766349)
Quoting the relevant comments from GParted_Core::calibrate_partition():
    Re-add the real partition path from libparted.

    When creating a copy operation by pasting into unallocated space the
    list of paths for the partition object was set to
    ["Copy of /dev/SRC"] because the partition didn't yet exist before
    the operations were applied.  Additional operations on that new
    partition also got the list of paths set to ["Copy of /dev/SRC"].
    This re-adds the real path to the start of the list making it
    ["/dev/NEW", "Copy of /dev/SRC"].  This provides the real path for
    file system specific tools used during those additional operations
    such mkfs for the format operation or fsck and others for the
    resize/move operation.

    FIXME: Having this work just because "/dev/NEW" happens to sort
    before "Copy of /dev/SRC" is ugly!  Probably have a separate display
    path which can be changed at will without affecting the list of real
    paths for the partition.

Having a separate display path is overly complicated and unnecessary.
Just replace the list of paths with the real one reported by libparted
if it contained "Copy of /dev/SRC", determined by checking if the file
exists.  Otherwise continue to add the libparted name as an alternate
path.  Whole disk devices can never be named "Copy of /dev/SRC" because
they are not partitioned so never created or deleted by GParted, only
ever written to, hence don't need the extra exists test logic.

Bug 766349 - Resolve code ugliness with partition path getting set to
             "copy of /dev/SRC"
2016-05-20 09:20:02 -06:00
Mike Fleetwood 302cc8041e Stop overriding real path when pasting into existing partitions (#766349)
When composing a copy operation it always named the destination
partition as "copy of /dev/SRC".  For the case of pasting into
unallocated space creating a new partition this was the right thing to
do as the partition doesn't yet exist so the path is not yet known.
However for the case of pasting into an existing partition the path is
known and replacing it with "copy of /dev/SRC" is wrong.  No other
operation when operating on an existing partition changes it path.

Given a set of existing partitions, sdb1 to sdb4, compose a set of copy
operations as: copy sdb1 to sdb2, copy sdb2 to sdb3 and copy sdb3 to
sdb4.  The displayed partitions before being applied become:
    /dev/sdb1
    copy of /dev/sdb1
    copy of copy of /dev/sdb1
    copy of copy of copy of /dev/sdb1
And the pending operations are named:
    Copy /dev/sdb1 to /dev/sdb2
    Copy copy of /dev/sdb1 to /dev/sdb3
    Copy copy of copy of /dev/sdb1 to /sev/sdb4

This is perverse.  In the case of pasting into an existing partition
keep the real path name.  This keeps the partitions being displayed as:
    /dev/sdb1
    /dev/sdb2
    /dev/sdb3
    /dev/sdb4
And the pending operations named as:
    Copy /dev/sdb1 to /dev/sdb2
    Copy /dev/sdb2 to /dev/sdb3
    Copy /dev/sdb3 to /dev/sdb4
Much more understandable.

Also switch to an upper case "C" in "Copy of /dev/SRC" as the temporary
path name when pasting into unallocated space.  Finally update the
comment in calibrate_partition() to describe the remaining cases when
re-adding the path is still required.

Bug 766349 - Resolve code ugliness with partition path getting set to
             "copy of /dev/SRC"
2016-05-20 09:20:02 -06:00
Mike Fleetwood 94979a3805 Add symbolic constants SETTLE_DEVICE_*_MAX_WAIT_SECONDS
Make the code a little more self documenting by adding the symbolic
constants:
    SETTLE_DEVICE_APPLY_MAX_WAIT_SECONDS
    SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS
which highlight that settle_device() is called in two different
contexts, device probe and apply operations, with two different timeout
values.
2016-04-18 12:56:51 -06:00
Mike Fleetwood fd9013d5f6 Wait for udev to recreate /dev/PTN entries when calibrating (#762941)
File system specific commands sometimes fail reporting that the
partition specific /dev entry doesn't exist.  Example failing check
operation details:

    Check and repair file system (ext4) on dev/sdb4
      calibrate /dev/sdb4
        path: /dev/sdb4 (partition)
        start: 4196352
        end: 6293503
        size: 2097152 (1.00 GiB)
      check file system on /dev/sdb4 for errors and (if possible) fix them
        e2fsck -f -y -bv -C 0 /dev/sdb4
          e2fsck 1.42.9 (28-Dec-2013)
          e2fsck: No such file or directory while trying to open /dev/sdb4
          Possibly non-existent device?

This has been reproduced on CentOS 7.  Debugging shows that the
libparted calls used to re-read the partition details in
GParted_Core::calibrate_partition() leads to udev removing and re-adding
all the partition /dev entries for the disk.

    # udevadm monitor &
    # gpartedbin
    ...
     16.480662 +12.618659 calibrate_partition()          calling get_device("/dev/sdb", lp_device) ...
     16.483644 +0.002982 calibrate_partition()          get_device() returned
     16.483678 +0.000034 calibrate_partition()          calling get_disk(lp_device, lp_disk) ...
     16.618113 +0.134435 calibrate_partition()          get_disk() returned
    KERNEL[19275.707968] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
     16.618561 +0.000448 destroy_device_and_disk()      calling ped_disk_destroy(lp_disk) ...
     16.618584 +0.000023 destroy_device_and_disk()      ped_disk_destroy() returned
     16.618591 +0.000007 destroy_device_and_disk()      calling ped_device_destroy(lp_disk) ...
     16.618602 +0.000011 destroy_device_and_disk()      ped_device_destroy() returned
     16.618687 +0.000085 calibrate_partition()          return true
     16.618851 +0.000164 execute_command()              e2fsck -f -y -v -C 0 /dev/sdb4
    KERNEL[19275.708389] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[19275.708500] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    KERNEL[19275.708643] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    KERNEL[19275.768278] change   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb (block)
    KERNEL[19275.771171] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    KERNEL[19275.771360] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    KERNEL[19275.771542] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    KERNEL[19275.775858] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [19275.820153] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [19275.823152] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [19275.828275] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
     16.742735 +0.123884 execute_command()              exit status 8
    UDEV  [19275.841425] remove   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)
    UDEV  [19275.905478] change   /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb (block)
    UDEV  [19276.013580] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb3 (block)
    UDEV  [19276.034728] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb4 (block)
    UDEV  [19276.174840] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb1 (block)
    UDEV  [19276.237105] add      /devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/sdb2 (block)

So exactly when GParted is running the external e2fsck command, udev is
in the middle of removing and re-adding all the /dev partition entries
for the disk.  Hence the above failure reporting that /dev/sdb4 didn't
exist.  This error depends on the timing between GParted running the
external file system specific command and udev removing and re-adding
the entries, so sometimes it works and sometimes it fails.

Further debugging showed that simply opening and closing the whole disk
device read-write triggers the same removing and re-adding of all the
partition /dev entries with udev >= 219.  Opening the whole disk device
read-write is what libparted has always done until this post
libparted 3.2 patch to make it open read-only when probing:

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=44d5ae0115c4ecfe3158748309e9912c5aede92d
    libparted: Use read only when probing devices on linux (#1245144)

To fix this simply wait for udev devices to settle in
calibrate_partitions().  The longest I have seen udev take to do this is
0.80 seconds in a VM.  Wait up to 10 seconds as is done in commit() ->
commit_to_os(), also called when applying operations.

On configurations which don't have this issue execution of udevadm
settle, which will return immediately, adds at most 0.1 seconds to the
time taken for the calibrate step.  This won't be noticed in the time
taken of the operation details so there is no point in trying to avoid
executing udevadm settle when not needed.

Bug 762941 - Operations sometimes failing with: No such file or
             directory
2016-04-18 12:56:51 -06:00
Mike Fleetwood e0a208576d Minor tidyup in load_proc_partitions_info_cache()
Minor issues:
1) In the while loop reading from /proc/partitions into variable line,
   just after the sscanf() call the variable was re-purposed to hold the
   device name making the code unnecessarily hard to follow.
2) Variable c_str was a fixed sized buffer holding the device name read
   from /proc/partitions.
3) Variable c_str name provides no meaning as to what data it holds.
4) Return value from all the Utils::regexp_label() calls is converted
   from Glib::ustring to std::string to be stored in device variable.

Resolve by using Utils::regexp_label() to extract the device name from
each line in /proc/partitions and store in the variable device, already
used for this purpose and now changed to type Glib::ustring.
2016-04-07 10:05:40 -06:00
Mike Fleetwood d04826cc27 Use realpath() safely (#764369)
realpath(3) manual page says:

    BUGS
        The POSIX.1-2001 standard version of this function is broken by
        design, since it is impossible to determine a suitable size for
        the output buffer, resolved_path.  According to POSIX.1-2001 a
        buffer of size PATH_MAX suffices, but PATH_MAX need not be a
        defined constant, and may have to be obtained using pathconf(3).
        And asking pathconf(3) does not really help, since, on the one
        hand POSIX warns that the result of pathconf(3) may be huge and
        unsuitable for mallocing memory, and on the other hand
        pathconf(3) may return -1 to signify that PATH_MAX is not
        bounded.  The resolved_path == NULL feature, not standardized in
        POSIX.1-2001, but standardized in POSIX.1-2008, allows this
        design problem to be avoided.

The resolved_path == NULL feature of realpath() has existed as a Glibc
extension since realpath() was first added to Glibc 1.90, released in
June 1996.  Therefore it can be used unconditionally.

    https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fa0bc87c32d02cd81ec4d0ae00e0d943c683e6e1

Bug 764369 - Use realpath() safely
2016-04-07 10:05:40 -06:00
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