Commit Graph

1864 Commits

Author SHA1 Message Date
Mike Fleetwood 8ae9abada4 Wait for udev change on /dev/DISK when erasing signatures (#83)
A user reported that formatting a whole disk device with a file system
failed like this:

    Format /dev/sdd as ext4                                    (ERROR)
    + calibrate /dev/sdd                                       (SUCCESS)
        path: /dev/sdd (device)
        start: 0
        end: 15633407
        size: 15633408 (7.45 GiB)
    + clear old file system signatures in /dev/sdd             (SUCCESS)
      + write 512.00 KiB of zeros at byte offset 0             (SUCCESS)
      + write 4.00 KiB of zeros at byte offset 67108864        (SUCCESS)
      + write 512.00 KiB of zeros at byte offset 8003780608    (SUCCESS)
      + write 4.00 KiB of zeros at byte offset 8004239360      (SUCCESS)
      + write 8.00 KiB of zeros at byte offset 8004296704      (SUCCESS)
      + flush operating system cache of /dev/sdd               (SUCCESS)
    + create new ext4 file system                              (ERROR)
      + mkfs.ext4 -F -O ^64bit -L '' '/dev/sdd'                (ERROR)
        mke2fs 1.44.1 (24-Mar-2018)
        /dev/sdd is apparently in use by the system; will not make a filesystem here!

Opening the whole disk block device exclusively causes mkfs.ext4 to
report that error like this:

    # python
    >>> import os
    >>> f = os.open('/dev/sdb',os.O_RDONLY|os.O_EXCL)
    >>> ^Z
    [1]+  Stopped                 python
    # mkfs.ext4 -F -O ^64bit -L '' '/dev/sdb'
    mke2fs 1.42.9 (28-Dec-2013)
    /dev/sdb is apparently in use by the system; will not make a filesystem here!
    # echo $?
    1

I have not been able to reproduce this error, but with debugging and
sleeping in GParted, stracing GParted and using 'udevadm monitor' to
watch udev events the following sequence of events is seen:

  gparted    |format(partition, operationdetail)
  gparted    |  erase_filesystem_signatures(partition, operationdetail)
  gparted    |    get_device(device_path="/dev/sdb", lp_device, flush=false)
  gparted    |      ped_device_get("/dev/sdb")
  libparted  |        open("/dev/sdb", O_RDONLY) = 11
  libparted  |        close(11)
  gparted    |    ped_device_open(lp_device)
  libparted  |      open("/dev/sdb", O_RDWR) = 11
  gparted    |    ped_device_sync(lp_device)
  libparted  |      ioctl(11, BLKFLSBUF)
  gparted    |    ped_device_close()
  libparted  |      close(11)
  udev(async)|        KERNEL change /devices/.../sdb (block)
  udev(async)|        UDEV   change /devices/.../sdb (block)
  gparted    |  set_partition_type(partition, operationdetail)
  gparted    |  create_filesystem(partition, operationdetail)
  gparted    |    ext2::create(partition, operationdetail)
  gparted    |      FileSystem::execute_command("mkfs.ext4 -F -O ^64bit -L '' '/dev/sdb')

So it is assumed that the processing of the udev change rule after
closing the block device in erase_filesystem_signatures() overlaps with
the execution mkfs.ext4 and causes the seen error.  Fix by waiting for
those udev events to complete as was previously done by commits [1][2]
[3].

Also note that this is specific to creating file systems on and
formatting unpartitioned whole disk devices because set_partition_type()
is a no-operation.  Where as on a partitioned device
set_partition_type() calls commit() which already waits for udev rules
to complete [3].

[1] 50c8924a8e4d9cc96a2ea45f13291114402affee
    Wait for udev to recreate /dev/PTN entries when querying partition
    FSs (!46)
[2] 4f6c312e3bc68cafb5e6035fd4a5b5bbbfcea992
    Wait for udev change on /dev/DISK when querying whole device FS
    (!46)
[3] 2f53876c0f
    Wait for the kernel and udev to settle partitions for a second time
    (#790418)

Closes #83 - /dev/sdd is apparently in use by the system; will not make
             a filesystem here!
2020-02-26 16:41:43 +00:00
Curtis Gedak 77de664881 Update copyright years 2020-01-20 09:56:07 -07:00
Mike Fleetwood 01826277e3 Rename TreeView_Detail::treeview_filesystems_Columns member to fsname (!52)
Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:38:01 +00:00
Mike Fleetwood e5b92a87f2 Rename DialogFeatures::treeview_filesystems_Columns member to fsname (!52)
Name the structure member to 'fsname' used to store strings like "ext2"
etc.  This is equivalent to what was previously done in this commit:
    a9f08ddc7d
    Rename local variable to fsname in get_filesystem() (#741430)

Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:38:01 +00:00
Mike Fleetwood f53c462c06 Rename create_format_menu_add_item() parameter of type FSType (!52)
Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:38:00 +00:00
Mike Fleetwood 2cbb867508 Rename set_device_partitions() local variable of type FSType (!52)
Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:38:00 +00:00
Mike Fleetwood c85fc66dcf Rename Utils method parameters of type FSType (!52)
Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:38:00 +00:00
Mike Fleetwood 58fb230fb0 Also rename FS.filesystem member to fstype (!52)
Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-04 07:37:19 +00:00
Mike Fleetwood b0f92be638 Rename Partition.filesystem member to fstype (!52)
Previously made this change:
    175d27c55d
    Rename enum FILESYSTEM to FSType

Now complete the renaming exercise of members and variables currently
named 'filesystem'.

Closes !52 - Rename members and variables currently named 'filesystem'
2019-12-03 13:24:44 +00:00
Mike Fleetwood 047a2481bb Stop requesting partition paths of free space and metadata
In GParted_Core::set_device_partitions() the partition path is being
queried from libparted.  However this is done before the switch
statement on the type of the partition, so is called for all libparted
partition objects including PED_PARTITION_FREESPACE and
PED_PARTITION_METADATA ones.  As libparted numbers these partition
objects as -1, it returns paths like "/dev/sda-1".

Additionally when using GParted, with it's default DMRaid handling, on a
dmraid started array this results in paths like
"/dev/mapper/isw_ecccdhhiga_MyArray-1" being passed to
is_dmraid_device() and make_path_dmraid_compatible().  Fortunately
make_path_dmraid_compatible() does nothing and returns the same name.
Call chain looks like:

    GParted_Core::set_device_partitions()
      get_partition_path(lp_partition)
        // where:
        // lp_partition->disk->dev->path = "/dev/mapper/isw_ecccdhhiga_MyArray"
        // lp_partition->type == PED_PARTITION_FREESPACE |
        //                       PED_PARTITION_METADATA
        //              ->num == -1
        ped_partition_get_path(lp_partition)
          return "/dev/mapper/isw_ecccdhhiga_MyArray-1"
        dmraid.is_dmraid_supported()
        dmraid.is_dmraid_device("/dev/mapper/isw_ecccdhhiga_MyArray-1")
          return true
        dmraid.make_path_dmraid_compatible("/dev/mapper/isw_ecccdhhiga_MyArray-1")
          return "/dev/mapper/isw_ecccdhhiga_MyArray-1"

Fix by moving the get_partition_path() call inside the switch statement
so that it is only called for PED_PARTITION_NORMAL,
PED_PARTITION_LOGICAL and PED_PARTITION_EXTENDED partition types.

Relevant commits:
*   53c49349f7
    Simplify logic in set_device_partitions method

*   81986c0990
    Ensure partition path name is compatible with dmraid (#622217)
2019-12-02 16:35:22 +00:00
Mike Fleetwood 21cad97dc7 Recognise ATARAID members started by dmraid (#75)
This is not strictly necessary as members are already recognised using
blkid since this commit earlier in the sequence "Recognise ATARAID
members (#75)".  However it makes sure active members are recognised
even if blkid is not available and matches how file system detection
queries the SWRaid_Info module.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood bb865aaaa4 Display array device as mount point of dmraid started ATARAID members (#75)
This matches how the array device is displayed as the mount point for
mdadm started ATARAID members by "Display array device as mount point of
mdadm started ATARAID members (#75)" earlier in this patchset.

Extend the DMRaid module member cache to save the array device name and
use as needed to display as the mount point.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood caec22871e Detect busy status of dmraid started ATARAID members (#75)
Again this is to stop GParted allowing overwrite operations being
performed on an ATARAID member while the array is actively using the
member.  This time for dmraid started arrays using the kernel DM (Device
Mapper) driver.

The DMRaid module already uses dmraid to report active array names:

    # dmraid -sa -c
    isw_ecccdhhiga_MyArray

To find active members in this array, (1) use udev to lookup the kernel
device name:

    # udevadm info --query=name /dev/mapper/isw_ecccdhhiga_MyArray
    dm-0

(2) list the member names exposed by the kernel DM driver through the
/sys file system.

    # ls /sys/block/dm-0/slaves
    sdc  sdd
    # ls -l /sys/block/dm-0/slaves
    lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata3/host2/target2:0:0/2:0:0:0/block/sdc
    lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdd

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood 425dfa3709 Enable basic supported actions for ATARAID members (#75)
When an ATARAID member is inactive allow basic supported actions of
copy and move to be performed like with other recognised but only basic
supported types.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood 1f1f44ff7a Prevent unmount of busy ATARAID members (#75)
Since earlier commit "Display array device as mount point of mdadm
started ATARAID members (#75)" GParted allows attempting to unmout a
busy ATARAID member as if it was a file system.  This is not a valid
thing to do, so disallow it.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood f6c86835eb Display array uuid of mdadm recognised ATARAID members (#75)
Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood 538c866d09 Display array device as mount point of mdadm started ATARAID members (#75)
This matches how other non-file systems are handled, by displaying the
access reference in the mount point column.  For LVM Physical Volumes
the Volume Group name is displayed [1] and for an active Linux Software
RAID array the array device is displayed [2].

[1] 8083f11d84
    Display LVM2 VGNAME as the PV's mount point (#160787)

[2] f6c2f00df7
    Populate member mount point with SWRaid array device (#756829)

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood 6e990ea48a Detect busy status of mdadm started ATARAID members (#75)
This stops GParted allowing overwrite operations (such as create
partition table or format with a whole device file system) being
performed on an ATARAID member while the array is actively using the
member.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood ef6794b7de Display correct type of mdadm recognised ATARAID members (#75)
The previous commit, made mdadm recognised IMSM and DDF type ATARAID
members get displayed as "linux-raid" (Linux Software RAID array
member).  This was because of query method 1 in detect_filesystems().

Fix this now by exposing and using the fstype of the member from the
SWRaid_Info cache.

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood 73bf8bef62 Parse ATARAID members from mdadm output and /proc/mdstat (#75)
Since mdadm release 3.0 (2009-06-02) [1] it has also supported external
metadata formats IMSM (Intel Matrix Storage Manager) and DDF, previously
only managed by dmraid.

A number of distributions have switched to use mdadm and kernel MD
(Multiple Devices) driver for managing these Firmware / BIOS / ATARAID
arrays.  These include: Fedora >= 14 [2], RHEL / CentOS >= 6 [3],
SLES >= 12 [4], Ubuntu >= 16.04 LTS.

Therefore additionally parse members in these ATARAID arrays included in
mdadm output, and when activated using the kernel MD driver, in file
/proc/mdstat.  Add fstype to the SWRaid_Info cache records to
distinguish members apart.  So far the rest of the GParted code
continues to treat all members as FS_LINUX_SWRAID.  This will be
resolved in following commits.

Note that this in no way affects how GParted shows and partitions the
array device itself, even those managed by dmraid and use the GParted
DMRaid module.  It only affects how GParted shows the member drives
themselves.

[1] mdadm ANNOUNCE-3.0 file
    https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/tree/ANNOUNCE-3.0?h=mdadm-3.0

[2] Fedora 14, Storage Administration Guide, 12.5. Linux RAID Subsystem
    https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/raid-subsys.html
    "...  Fedora 14 uses mdraid with external metadata to access ISW /
    IMSM (Intel firmware RAID) sets.  mdraid sets are configured and
    controlled through the mdadm utility."

[3] RHEL 6, Storage Administration Guide, 17.3. Linux RAID Subsystem
    https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/storage_administration_guide/raid-subsys
    "mdraid also supports other metadata formats, known as external
    metadata.  Red Hat Enterprise Linux 6 uses mdraid with external
    metadata to access ISW / IMSM (Intel firmware RAID) sets.  mdraid
    sets are configured and controlled through the mdadm utility."

[4] SUSE Linux Enterprise Server 12 Release Notes, 7.2.3 Driver for IMSM
    and DDF
    https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12/#fate-316007
    "For IMSM and DDF RAIDs the mdadm driver is used unconditionally."

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood aea6200d5f Recognise ATARAID members (#75)
PATCHSET OVERVIEW

A user had a Firmware / BIOS / ATARAID array of 2 devices configured as
a RAID 0 (stripe) set.  On top of that was a GPT with the OS partitions.
GParted displays the following errors on initial load and subsequent
refresh:

        Libparted Error
    (-) Invalid argument during seek for read on /dev/sda
                          [ Retry ] [ Cancel ] [ Ignore ]

        Libparted Error
    (-) The backup GPT table is corrupt, but the
        primary appears OK, so that will be used.
                              [  Ok  ] [ Cancel ]

This is an Intel Software RAID array which stores metadata at the end of
each member device, and so the first 128 KiB stripe of the set is stored
in the first 128 KiB of the first member device /dev/sda which includes
the GPT for the whole RAID 0 device.  Hence when libparted reads member
device /dev/sda it finds a GPT describing a block device twice it's
size and in results the above errors when trying to read the backup GPT.

A more dangerous scenario occurs when using 2 devices configured in an
Intel Software RAID 1 (mirrored) set with GPT on top.  On refresh
GParted display this error for both members, /dev/sda and /dev/sdb:

        Libparted Warning
    /!\ Not all of the space available to /dev/sda appears to be used,
        you can fix the GPT to use all of the space (an extra 9554
        blocks) or continue with the current setting?
                                                  [  Fix  ] [ Ignore ]

Selecting [Fix] gets libparted to re-write the backup GPT to the end of
the member device, overwriting the ISW metadata!  Do that twice and both
copies of the metadata are gone!

Worked example of this more dangerous mirrored set case.  Initial setup:

    # dmraid -s
    *** Group superset isw_caffbiaegi
    --> Subset
    name   : isw_caffbiaegi_MyMirror
    size   : 16768000
    stride : 128
    type   : mirror
    status : ok
    subsets: 0
    devs   : 2
    spares : 0

    # dmraid -r
    /dev/sda: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0
    /dev/sdb: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0

    # wipefs /dev/sda
    offset               type
    ---------------------------------------------
    0x200                gpt   [partition table]
    0x1fffffc00          isw_raid_member   [raid]

Run GParted and click [Fix] on /dev/sda.  Now the first member has gone:

    # dmraid -s
    *** Group superset isw_caffbiaegi
    --> *Inconsistent* Subset
    name   : isw_caffbiaegi_MyMirror
    size   : 16768000
    stride : 128
    type   : mirror
    status : inconsistent
    subsets: 0
    devs   : 1
    spares : 0

    # dmraid -r
    /dev/sdb: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0

    # wipefs /dev/sda
    offset               type
    ---------------------------------------------
    0x200                gpt   [partition table]

Click [Fix] on /dev/sdb.  Now all members of the array are gone:

    # dmraid -s
    no raid disks

    # dmraid -r
    no raid disks

    # wipefs /dev/sdb
    offset               type
    ---------------------------------------------
    0x200                gpt   [partition table]

So GParted must not run libparted partition table scanning on the member
devices in ATARAID arrays.  Only on the array device itself.

In terms of the UI GParted must show disks which are ATARAID members as
whole disk devices with ATARAID member content and detect array busy
status to avoid allowing active members from being overwritten while in
use.

THIS COMMIT

Recognise ATARAID member devices and display in GParted as whole device
"ataraid" file systems.  Because they are recognised as whole device
content ("ataraid" file systems) this alone stops GParted running the
libparted partition table scanning and avoids the above errors.

The list of dmraid supported formats is matched by the signatures
recognised by blkid:

    $ dmraid -l
    asr     : Adaptec HostRAID ASR (0,1,10)
    ddf1    : SNIA DDF1 (0,1,4,5,linear)
    hpt37x  : Highpoint HPT37X (S,0,1,10,01)
    hpt45x  : Highpoint HPT45X (S,0,1,10)
    isw     : Intel Software RAID (0,1,5,01)
    jmicron : JMicron ATARAID (S,0,1)
    lsi     : LSI Logic MegaRAID (0,1,10)
    nvidia  : NVidia RAID (S,0,1,10,5)
    pdc     : Promise FastTrack (S,0,1,10)
    sil     : Silicon Image(tm) Medley(tm) (0,1,10)
    via     : VIA Software RAID (S,0,1,10)
    dos     : DOS partitions on SW RAIDs

    $ fgrep -h _raid_member util-linux/libblkid/src/superblocks/*.c
            .name           = "adaptec_raid_member",
            .name           = "ddf_raid_member",
            .name           = "hpt45x_raid_member",
            .name           = "hpt37x_raid_member",
            .name           = "isw_raid_member",
            .name           = "jmicron_raid_member",
            .name           = "linux_raid_member",
            .name           = "lsi_mega_raid_member",
            .name           = "nvidia_raid_member",
            .name           = "promise_fasttrack_raid_member",
            .name           = "silicon_medley_raid_member",
            .name           = "via_raid_member",

As they are all types of Firmware / BIOS / ATARAID arrays, report all
members as a single "ataraid" file system type.  (Except for
"linux_raid_member" in the above blkid source listing which is Linux
Software RAID).

Closes #75 - Errors with GPT on RAID 0 ATARAID array
2019-12-02 16:35:22 +00:00
Mike Fleetwood af60f91f7f Add missing includes into jfs.cc 2019-11-14 17:12:06 +00:00
Mike Fleetwood 4b8d4be789 Remove unallocated space comment from HACKING file (!50)
The HACKING file should be hints for making changes to the code base and
associated processes.  A overview of how GParted handled unallocated
space was not that.  Also now the size of a JFS is accurately calculated
using JFS as an example of a file system with intrinsic unallocated
space is no longer valid.  Therefore removed from the HACKING file.
Instead add the original commit message as an extended comment to method
calc_significant_unallocated_sectors().

Closes !50 - Calculate JFS size accurately
2019-11-14 17:12:06 +00:00
Mike Fleetwood 2c0572e296 Calculate mounted JFS size accurately (!50)
With the same minimum sized 16 MiB JFS used in the previous commit, now
mounted, GParted once again reports 1.20 MiB of unallocated space.  This
is because the kernel JFS driver is also just reporting the size of the
Aggregate Disk Map (dmap) as the size of the file system [1].

Fix by reading the on disk JFS superblock to calculate the size of the
file system, but query the free space from the kernel using statvfs().
Need to query mounted JFS free space from the kernel because the on disk
dmap is not updated immediately so doesn't reflect recently used or
freed disk space.

For example, start with the 16 MiB JFS empty and mounted.

    # echo -e 'dmap\nx\nquit' | jfs_debugfs /dev/sdb1 | fgrep dn_nfree
    [2] dn_nfree:           0x00000000eaa   [10] dn_agwidth:        1
    # df -k /mnt/1
    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/sdb1          15152   136     15016   1% /mnt/1

Write 10 MiB of data to it:

    # dd if=/dev/zero bs=1M count=10 of=/mnt/1/file_10M
    10+0 records in
    10+0 records out
    1048760 bytes (10 MB, 10 MiB) copied, 0.0415676 s, 252 MB/s

Query the file system free space from the kernel and by reading the on
disk dmap figure:

    # df -k /mnt/1
    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/sdb1          15152 10376      4776  69% /mnt/1
    # echo -e 'dmap\nx\nquit' | jfs_debugfs /dev/sdb1 | fgrep dn_nfree
    [2] dn_nfree:           0x00000000eaa   [10] dn_agwidth:        1

    # sync
    # echo -e 'dmap\nx\nquit' | jfs_debugfs /dev/sdb1 | fgrep dn_nfree
    [2] dn_nfree:           0x00000000eaa   [10] dn_agwidth:        1

    # umount /mnt/1
    # echo -e 'dmap\nx\nquit' | jfs_debugfs /dev/sdb1 | fgrep dn_nfree
    [2] dn_nfree:           0x000000004aa   [10] dn_agwidth:        1

The kernel reports the updated usage straight away, but the on disk dmap
record doesn't get updated even by sync, only after unmounting.

This is the same fix as was previously done for EXT2/3/4 [2].

[1] Linux jfs_statfs() function
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/jfs/super.c?h=v3.10#n142

[2] 3828019030
    Read file system size for mounted ext2/3/4 from superblock (#683255)

Closes !50 - Calculate JFS size accurately
2019-11-14 17:12:06 +00:00
Mike Fleetwood e55d10b919 Calculate unmounted JFS size accurately (!50)
Create the smallest possible JFS (16 MiB) and GParted will report
1.2 MiB of unallocated space.  This is because the size of the Aggregate
Disk Map (dmap) was used as the size of the file system.  However after
reading the source code to mkfs.jfs, it separately accounts for the size
of the Log (Journal) and the FSCK Working Space.  The size of a JFS is
the sum of these 3 components added together.

Using the minimum 16 MiB JFS as an example:

    # jfs_debugfs /dev/sdb1
    jfs_debugfs version 1.1.15, 04-Mar-2011

    Aggregate Block Size: 4096

    > superblock
    [1] s_magic:            'JFS1'          [15] s_ait2.addr1:      0x00
    [2] s_version:          1               [16] s_ait2.addr2:      0x00000018
    [3] s_size:     0x0000000000007660           s_ait2.address:    24
    [4] s_bsize:            4096            [17] s_logdev:          0x00000000
    [5] s_l2bsize:          12              [18] s_logserial:       0x00000000
    [6] s_l2bfactor:        3               [19] s_logpxd.len:      256
    [7] s_pbsize:           512             [20] s_logpxd.addr1:    0x00
    [8] s_l2pbsize:         9               [21] s_logpxd.addr2:    0x00000f00
    [9] pad:                Not Displayed        s_logpxd.address:  3840
    [10] s_agsize:          0x00002000      [22] s_fsckpxd.len:     52
    [11] s_flag:            0x10200900      [23] s_fsckpxd.addr1:   0x00
                            JFS_LINUX       [24] s_fsckpxd.addr2:   0x00000ecc
            JFS_COMMIT      JFS_GROUPCOMMIT      s_fsckpxd.address: 3788
                            JFS_INLINELOG   [25] s_time.tv_sec:     0x5dbbdfa0
                                            [26] s_time.tv_nsec:    0x00000000
                                            [27] s_fpack:           'small_jfs'
    [12] s_state:           0x00000000
                 FM_CLEAN
    [13] s_compress:        0
    [14] s_ait2.len:        4

    display_super: [m]odify or e[x]it: x
    > dmap

    Block allocation map control page at block 16

    [1] dn_mapsize:         0x00000000ecc   [9] dn_agheigth:        0
    [2] dn_nfree:           0x00000000eaa   [10] dn_agwidth:        1
    [3] dn_l2nbperpage:     0               [11] dn_agstart:        341
    [4] dn_numag:           1               [12] dn_agl2size:       13
    [5] dn_maxlevel:        0               [13] dn_agfree:         type 'f'
    [6] dn_maxag:           0               [14] dn_agsize:         8192
    [7] dn_agpref:          0               [15] pad:               Not Displayed
    [8] dn_aglevel:         0
    display_dbmap: [m]odify, [f]ree count, [t]ree, e[x]it > x
    > quit

Values of interest:
    s_size        - Aggregate size in device (s_pbsize) blocks
    s_bsize       - Aggregate block (aka file system allocation) size in
                    bytes
    s_pbsize      - Physical (device) block size in bytes
    s_logpxd.len  - Log (Journal) size in Aggregate (s_bsize) blocks
    s_fsckpxd.len - FSCK Working Space in Aggregate (s_bsize) blocks
    dn_nfree      - Number of free (s_bsize) blocks in Aggregate

Calculation:
    file system size = s_size * s_pbsize
                     + s_logpxd.len * s_bsize
                     + s_fsckpxd.len * s_bsize
                     = 30304 * 512
                     + 256 * 4096
                     + 52 * 4096
                     =  16777216
                        (Exactly 16 MiB.  The size of the partition.)
    free space = dn_nfree * s_bsize
               = 3754 * 4096
               = 15376384

Rewrite JFS usage querying code to use this updated calculation.

[1] JFS Overview / How the Journaled File System cuts system restart
    times to the quick
    http://jfs.sourceforge.net/project/pub/jfs.pdf
[2] JFS Layout / How the Journaled File systems handles the on-disk
    layout
    http://jfs.sourceforge.net/project/pub/jfslayout.pdf
[3] mkfs.jfs source code
    http://jfs.sourceforge.net/project/pub/jfsutils-1.1.15.tar.gz
    mkfs/mkfs.c
    Selected lines from mkfs/mkfs.c
        create_aggregate(..., number_of_blocks, ..., logsize, ...)
            number_of_blocks -= fsck_wspace_length;
            aggr_superblock.s_size = number_of_blocks * (aggr_block_size / phys_block_size);
            aggr_superblock.s_bsize = aggr_block_size;
            aggr_superblock.s_pbsize = phys_block_size;
            PXDlength(&aggr_superblock.s_logpxd, logsize);
            PXDlength(&aggr_superblock.s_fsckpxd, fsck_wspace_length);
        main()
            number_of_bytes = bytes_on_device;
            number_of_blocks = number_of_bytes / agg_block_size;
            logsize = logsize_in_bytes / aggr_block_size;
            number_of_blocks -= logsize;
            create_aggregate(..., number_of_blocks, ..., logsize, ...);

Closes !50 - Calculate JFS size accurately
2019-11-14 17:12:06 +00:00
Mike Fleetwood 7be6d0967a Update name of the NILFS2 specific package
Upstream NILFS project calls the package nilfs-utils [1][2].  Arch Linux
/ CentOS / Fedora / OpenSUSE use the upstream name.  However Debian /
Ubuntu name it nilfs-tools [3] instead.

Document the needed software as:

    nilfs-utils / nilfs-tools

Upstream name first separated by slash from alternative names
distributions use.

[1] NILFS Download page
    https://nilfs.sourceforge.io/en/download.html
[2] NILFS Public Git Repositories
    https://nilfs.sourceforge.io/en/git_repos.html
[3] Debian package: nilfs-tools
    https://packages.debian.org/sid/nilfs-tools
2019-11-09 17:18:34 +00:00
Mike Fleetwood 7a7d0a2119 Avoid crash reading JFS usage on Fedora 30 (!49)(#794947)
Running JFS read usage test on Fedora 30 fails like this:

    $ ./test_SupportedFileSystems --gtest_filter='*ReadUsage/jfs'
...
    [ RUN      ] My/SupportedFileSystemsTest.CreateAndReadUsage/jfs
    unknown file: Failure
    C++ exception with description "std::bad_alloc" thrown in the test body.
    [  FAILED  ] My/SupportedFileSystemsTest.CreateAndReadUsage/jfs, where GetParam() = 17 (41833 ms)

However the same test passes on Fedora 29, Fedora 31 Beta, CentOS 7,
Debian 10 and Ubuntu 18.04 LTS.

Also running GParted on Fedora 30 crashes just the same when reading JFS
usage:

    # gparted
    GParted 1.0.0
    configuration --enable-libparted-dmraid --enable-online-resize
    libparted 3.2
    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc
    /usr/bin/gparted: line 202: 19218 Aborted                 (core dumped) $BASE_CMD

Running jfs_debugfs to query the file system usage the same way GParted
does produces an infinite amount of repeating output:

    # echo dm | jfs_debugfs /dev/sdb1

So jfs_debugfs gets stuck in an infinite loop inside the dmap subcommand
when it encounters EOF.  GParted and the read JFS usage test read this
output until memory is exhausted and crash.  This is exactly what was
happening in closed bug 794947.  Even installed jfsutils from Fedora 29
on Fedora 30 and visa versa.  jfs_debugfs still produced an infinite
amount of output on Fedora 30 and worked correctly on Fedora 29.  So
it's not the build of jfsutils, but something in the OS that is making
the difference!

Anyway fix by providing the instruction to exit from the dmap
subcommand, and quit from jfs_debugfs itself, like this:

    # echo -e 'dmap\nx\nquit' | jfs_debugfs /dev/sdb1

Bug 794947 - gparted hangs when sees JFS partition on discovering
             partitions
Closes !49 - Add file system interface tests
2019-11-09 17:18:34 +00:00
Mike Fleetwood 6d121ebb5d Split FILESYSTEMS and FILESYSTEM_MAP into separate module (!49)
GParted_Core::FILESYSTEMS and ::FILESYSTEM_MAP and the methods that
query and manipulate them are self-contained.  Therefore move them into
a separate SupportedFileSystems module.

Also having a single class maintaining all FileSystem interface objects
will make testing all the file system types much easier as there will be
no need to duplicate this functionality in the test.

Closes !49 - Add file system interface tests
2019-11-09 17:18:34 +00:00
Mike Fleetwood dae4deff39 Rename enumeration to MENU_LABEL_FILESYSTEM
To match the renaming performed as part of Bug 741424 "Add support for
GPT partition names".  In particular this is most closely similar to:
    d480800600
    Rename enum to OPERATION_LABEL_FILESYSTEM (#741424)
2019-10-03 15:36:06 +00:00
Mike Fleetwood a4c00e03e6 Drop use of long ago removed udevsettle
Separate udevsettle command was merged into udevadm back in udev 117
(released 2007-11-13) by:
    225cb03bd8
    udevadm: merge all udev tools into a single binary

The oldest supported distributions have these much newer versions of
udev:
  Distro             EOL        udevadm -V
  Debian 8           2020-Apr   215 (combined systemd and udev)
  RHEL / CentOS 7    2024-Jun   219 (combined systemd and udev)
  Ubuntu 16.04 LTS   2021-Apr   229 (combined systemd and udev)
2019-07-18 15:27:43 +00:00
Mike Fleetwood df65fbd468 Order internally detected signatures by increasing offset (!46)(#16)
Along with the previous patch "Avoid reading the same sector multiple
times in a row (!46)(#16)" internal detection of file system signatures
now reads the minimum number of sectors in increasing order.

As the code still considers the sector size, it now also reads less
sectors from devices with larger sectors to get all the signatures.  So
on a 512 byte sector device it maximally seeks to and reads from these
byte offsets:
    0, 512, 1024, 65536
and on a 4096 byte sector device, only from these byte offsets:
    0, 65536

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
Closes #16 - "invalid argument for seek()" error on very small (<=40KiB)
             drives
2019-07-18 15:27:43 +00:00
Mike Fleetwood 869ebb71ea Avoid reading the same sector multiple times in a row (!46)(#16)
GParted internal file system detection is reading the same sector
multiple times in a row.  Add an optimisation to only read a sector if
it is different to the previously read sector.

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
Closes #16 - "invalid argument for seek()" error on very small (<=40KiB)
             drives
2019-07-18 15:27:43 +00:00
Mike Fleetwood 5bb3415bcb Just pass sector size to detect_filesystem_internal() (!46)(#16)
After the previous commit the lp_device structure pointer parameter is
only used to provide sector_size.  Just pass that instead.

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
Closes #16 - "invalid argument for seek()" error on very small (<=40KiB)
             drives
2019-07-18 15:27:43 +00:00
Mike Fleetwood 228374fe50 Switch to POSIX open() in detect_filesystem_internal() (!46)(#16)
For every partitioned device that GParted scans it triggers a set of
udev change events from it's internal file system signature detection
function.  This is the sequence of events:

  gparted    |set_devices_thread(pdevices)  pdevices->["/dev/sdb"]
  gparted    |  ped_device_get("/dev/sdb")
  libparted  |      open("/dev/sdb", O_RDONLY) = 8
  libparted  |      close(8)
  gparted    |  useable_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |    open("/dev/sdb", O_RDONLY|O_NONBLOCK) = 8
  gparted    |    read(8, ...)
  gparted    |    close(8)
  gparted    |  set_device_from_disk(device, device_path="/dev/sdb")
  gparted    |    get_device(device_path="/dev/sdb", ..., flush=true)
  gparted    |      ped_device_get()
  gparted    |      flush_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |        ped_device_open()
  libparted  |          open("/dev/sdb", O_RDWR) = 8
  gparted    |        ped_device_sync()
  gparted    |        ped_device_close()
  libparted  |          close(8)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |        settle_device()
  gparted    |          Utils::execute_command("udevadm settle --timeout=1")
  gparted    |    detect_filesystem(lp_device, NULL, ...)  lp_device->path="/dev/sdb"
  gparted    |      detect_filesystem_internal(lp_device, NULL)  lp_device->path="/dev/sdb"
  gparted    |        ped_device_open()
  libparted  |          open("/dev/sdb", O_RDWR) = 8
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_close()
  libparted  |          close(8)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |    get_disk(lp_device, lp_disk, strict=false)
  gparted    |      ped_disk_new(lp_device)  lp_device->path="/dev/sdb"
  libparted  |        open("/dev/sdb", O_RDWR) = 8
  libparted  |        close(8)
  udev(async)|          KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|          KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|          KERNEL change /devices/.../sdb (block)
  udev(async)|          KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|          KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|          UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|          UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|          UDEV   change /devices/.../sdb (block)
  udev(async)|          UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|          UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |      settle_device()
  gparted    |        Utils::execute_command("udevadm settle --timeout=1")
  gparted    |    set_device_partitions()
  gparted    |      detect_filesystem()
  gparted    |      set_partition_label_and_uuid(partition)  partition.get_path()="/dev/sdb1"
  gparted    |        read_label()
  gparted    |          ext2::read_label()
  gparted    |            Utils::execute_command("e2label /dev/sdb1")

Note that the udev block device change events triggered in
detect_filesystem_internal() occur before the waited for ones in the
second commit "Wait for udev to recreate /dev/PTN entries when querying
partition FSs (!46)" in get_disk() so these were already waited for.

The call chain is:
    set_devices_thread()
        set_device_from_disk()
            detect_filesystem()
                detect_filesystem_internal()
                    ped_device_open()
                    ped_device_read()
                    ped_device_close()

This occurs because file system detection is performed on whole disk
devices, but the device contains a partition table, so blkid won't
report any content GParted accepts as a file system, so it tries it's
own internal detection.

Fix this by changing detect_filesystem_internal() to use POSIX open(),
read() and close() so the file can be opened read-only and udev change
events aren't triggered.

Note that when using detect_filesystem_internal() on a partition this
also changes the device it reads from.  Before it used libparted which
always reads from the whole disk device, now it reads from the partition
device.  This doesn't matter because GParted ensures the data is
consistent between them [2] and blkid reads from each partition device
which GParted already uses.

As the new code avoids using the libparted API, and just skips to the
next signature on lseek() and read() errors, it therefore won't generate
libparted exceptions such as this when scanning very small drives:
    Invalid argument during seek for read on /dev/PTN

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

[2] 3bea067596
    Flush devices when scanning to prevent reading stale signatures
    (#723842)

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
Closes #16 - "invalid argument for seek()" error on very small (<=40KiB)
             drives
2019-07-18 15:27:43 +00:00
Mike Fleetwood 7289d4c52a Pass unmodified parameter to useable_device() as const (!46)
GParted_Core::useable_device() doesn't change the pointed to PedDevice
structure.  Pass it as const so the compiler enforces this.

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
2019-07-18 15:27:43 +00:00
Mike Fleetwood e5898e5813 Switch to POSIX open() in useable_device() (!46)
For every device that GParted scans, it determines if it can be used by
attempting to read the first sector.  This is the sequence of events,
as reported in the previous two commit messages:

  gparted    |set_devices_thread(pdevices)  pdevices->["/dev/sdb"]
  ...
  gparted    |  useable_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |    ped_device_open()
  libparted  |      open("/dev/sdb", O_RDWR) = 8
  gparted    |    ped_device_read()
  gparted    |    ped_device_close()
  libparted  |      close(8)
  udev(async)|        KERNEL change /devices/.../sdb (block)
  ...
  udev(async)|        UDEV   change /devices/.../sdb (block)

Note that these udev block device change events occur before the ones
waited for in the first commit "Wait for udev change on /dev/DISK when
querying whole device FS (!46)" so these were already waited for.

So because libparted only opens devices read-write this triggers a set
of udev change events for the whole block device, and if the device is
partitioned, also remove and re-add events for all the partitions.

Switch to using POSIX open(), read() and close() calls so read-only
access can be specified to avoid the unnecessary udev change events.

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
2019-07-18 15:27:43 +00:00
Mike Fleetwood f170a1e542 Wait for udev to recreate /dev/PTN entries when querying partition FSs (!46)
After the previous fix, on my CentOS 7 VM, GParted is now often
reporting a warning that the /dev/PTN entry is missing when reading the
label of the file system in the first partition.  This happens
regardless of the file system type.

Example error for EXT4:
    e2label: No such file or directory while trying to open /dev/sdb1
    Couldn't find valid file system superblock.

Example error for XFS:
    /dev/sdb1: No such file or directory
    fatal error -- couldn't initialize XFS library

As with the case in the previous commit, GParted gets the label via
blkid instead.

Again with debugging and sleeping in GParted, stracing the GParted
thread GParted_Core::set_devices_thread() and using 'udevadm monitor' to
watch udev events the following sequence of events is observed:

  gparted    |set_devices_thread(pdevices)  pdevices->["/dev/sdb"]
  gparted    |  ped_device_get("/dev/sdb")
  libparted  |      open("/dev/sdb", O_RDONLY) = 8
  libparted  |      close(8)
  gparted    |  useable_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |    ped_device_open()
  libparted  |      open("/dev/sdb", O_RDWR) = 8
  gparted    |    ped_device_read()
  gparted    |    ped_device_close()
  libparted  |      close(8)
  udev(async)|        KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|        KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|        KERNEL change /devices/.../sdb (block)
  udev(async)|        KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|        KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|        UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|        UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|        UDEV   change /devices/.../sdb (block)
  udev(async)|        UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|        UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |  set_device_from_disk(device, device_path="/dev/sdb")
  gparted    |    get_device(device_path="/dev/sdb", ..., flush=true)
  gparted    |      ped_device_get()
  gparted    |      flush_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |        ped_device_open()
  libparted  |          open("/dev/sdb", O_RDWR) = 8
  gparted    |        ped_device_sync()
  gparted    |        ped_device_close()
  libparted  |          close(8)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |        settle_device()
  gparted    |          Utils::execute_command("udevadm settle --timeout=1")
  gparted    |    detect_filesystem(lp_device, NULL, ...)  lp_device->path="/dev/sdb"
  gparted    |      detect_filesystem_internal(lp_device, NULL)  lp_device->path="/dev/sdb"
  gparted    |        ped_device_open()
  libparted  |          open("/dev/sdb", O_RDWR) = 8
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_read()
  gparted    |        ped_device_close()
  libparted  |          close(8)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|            KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|            UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |    get_disk(lp_device, lp_disk, strict=false)
  gparted    |      ped_disk_new(lp_device)  lp_device->path="/dev/sdb"
  libparted  |        open("/dev/sdb", O_RDWR) = 8
  libparted  |        close(8)
  udev(async)|          KERNEL remove /devices/.../sdb/sdb1 (block)
  udev(async)|          KERNEL remove /devices/.../sdb/sdb2 (block)
  udev(async)|          KERNEL change /devices/.../sdb (block)
  udev(async)|          KERNEL add    /devices/.../sdb/sdb1 (block)
  udev(async)|          KERNEL add    /devices/.../sdb/sdb2 (block)
  udev(async)|          UDEV   remove /devices/.../sdb/sdb1 (block)
  udev(async)|          UDEV   remove /devices/.../sdb/sdb2 (block)
  udev(async)|          UDEV   change /devices/.../sdb (block)
  udev(async)|          UDEV   add    /devices/.../sdb/sdb1 (block)
  udev(async)|          UDEV   add    /devices/.../sdb/sdb2 (block)
  gparted    |    set_device_partitions()
  gparted    |      detect_filesystem()
  gparted    |      set_partition_label_and_uuid(partition)  partition.get_path()="/dev/sdb1"
  gparted    |        read_label()
  gparted    |          ext2::read_label()
  gparted    |            Utils::execute_command("e2label /dev/sdb1")

So in this case for a partitioned drive, libparted ped_disk_new() is
opening and closing the device read-write and triggering the udev remove
and add partition block special entries exactly when the label is trying
to be read from the first partition, causing the device missing error.
The call chain is:
    set_devices_thread()
        set_device_from_disk()
            get_disk()
                ped_disk_new()

Looking at the source for ped_disk_new() [1] it is calling
ped_device_open() and ped_device_close(), hence why it is opening the
device read-write and triggering the udev events.

Looking back at commit "Wait for udev to recreate /dev/PTN entries when
calibrating (#762941)" [2] and re-testing it, the udev events were also
caused by ped_disk_new() with this call chain:
    apply_operation_to_disk()
        calibrate_partition()
            get_disk()
                ped_disk_new()

Fix this probe case and keep the fix for the previous calibrate case by
moving the waiting for udev events from calibrate_partition() into
get_disk(), right after ped_disk_new().  The maximum wait time is
shortened to the shorter 1 second probing timeout to avoid the longer
10 second apply timeout in this probing case.  The calibrate case commit
message said "The longest I have seen udev take to do this is 0.80
seconds in a VM".

[1] parted/libparted/disk.c:ped_disk_new()
    http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/disk.c?id=v3.2#n169

[2] fd9013d5f6
    Wait for udev to recreate /dev/PTN entries when calibrating
    (#762941)

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
2019-07-18 15:27:43 +00:00
Mike Fleetwood 1382e0b828 Wait for udev change on /dev/DISK when querying whole device FS (!46)
GParted nearly always shows this warning against a whole disk device
FAT32 file system on my development VMs:
    plain floppy: device "/dev/sdb" busy (Resource temporarily
    unavailable): Cannot initialize '::'
    mlabel: Cannot initialize drive
However GParted does get the label via blkid instead.  Occasionally
everything works correctly and there is no warning.

Never found a similar error for any other file system on a whole disk
device.  The timing never seems to clash.

Remember that when a writable file descriptor of a disk device is
closed, udev events are triggered which update the kernel and /dev
entries for any partition changes.  (This is in addition to coding which
has always existed in the partitioning tools, including fdisk and
parted, to inform the kernel, but not create /dev entries, of partition
changes).

With debugging and sleeping in GParted, stracing the GParted thread
GParted_Core::set_devices_thread() and using 'udevadm monitor' to watch
udev events the following sequence of events is observed:

  gparted    |set_devices_thread(pdevices)  pdevices->["/dev/sdb"]
  gparted    |  ped_device_get("/dev/sdb")
  libparted  |      open("/dev/sdb", O_RDONLY) = 8
  libparted  |      close(8)
  gparted    |  useable_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |    ped_device_open()
  libparted  |      open("/dev/sdb", O_RDWR) = 8
  gparted    |    ped_device_read()
  gparted    |    ped_device_close()
  libparted  |      close(8)
  udev(async)|        KERNEL change /devices/.../sdb (block)
  udev(async)|        KERNEL change /devices/.../sdb (block)
  udev(async)|        UDEV   change /devices/.../sdb (block)
  udev(async)|        UDEV   change /devices/.../sdb (block)
  gparted    |  set_device_from_disk(device, device_path="/dev/sdb")
  gparted    |    get_device(device_path="/dev/sdb", ..., flush=true)
  gparted    |      ped_device_get()
  gparted    |      flush_device(lp_device)  lp_device->path="/dev/sdb"
  gparted    |        ped_device_open()
  libparted  |          open("/dev/sdb", O_RDWR) = 8
  gparted    |        ped_device_sync()
  gparted    |        ped_device_close()
  libparted  |          close(8)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            KERNEL change /devices/.../sdb (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  udev(async)|            UDEV   change /devices/.../sdb (block)
  gparted    |    set_device_one_partition()
  gparted    |      set_partition_label_and_uuid()
  gparted    |        read_label()
  gparted    |          fat16::read_label()
  gparted    |            Utils::execute_command("mlabel -s :: -i /dev/sdb")

This sequence of events only shows which close()s by libparted trigger
udev events.  It does not show that processing those events are
asynchronous and overlap with GParted executing mlabel, causing the
device busy error.

As libparted's ped_device_open() doesn't offer a way to specify that a
device will only be used for reading, it always opens it read-write
[1][2].  Hence this sequence in GParted_Core::flush_device():
    ped_device_open()
    ped_device_sync()
    ped_device_close()
always triggers udev change events on the whole disk device.  Fix by
waiting for those udev events to complete.

[1] libparted documentation, PedDevice, ped_device_open()
    https://www.gnu.org/software/parted/api/group__PedDevice.html#ga7c87bd06e76553c8ff3262b5e6ca256

[2] parted/libparted/arch/linux.c:linux_open()
    http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?id=v3.2#n1628

Closes !46 - Whole device FAT32 file system reports device busy warning
             from mlabel
2019-07-18 15:27:43 +00:00
Mike Fleetwood 3f15a66291 Drop use of long ago removed udevinfo
The last distribution to include the separate 'udevinfo' command was
RHEL / CentOS 5 with udev 095.  All supported distributions have much
newer versions of udev and instead have the 'udevadm' command.
2019-07-04 10:51:50 -06:00
Mike Fleetwood 5a52b44071 Switch to faster minfo and mdir to read FAT16/32 usage (#569921)
A user reported that GParted was slow to refresh on FAT32 file systems:
"can take very long, up to several minutes; can be reproduced by running
dosfsck manually".  This is because the file system was large and almost
full, and GParted performs a file system check just to to report the
file system usage.

Created a 4 GiB FAT32 file system and almost filled it with 4 KiB files,
just over 970,000 files.

    # df -k /mnt/2
    Filesystem     1K-blocks     Used Available Used% Mounted on
    /dev/sdb2        4186108 39155384    270724   94% /mnt/2
    # df -i /mnt/2
    Filesystem     Inodes IUsed IFree IUse% Mounted on
    /dev/sdb2           0     0     0     - /mnt/2
    # find /mnt/2 -type f -print | wc -l
    971059
    # find /mnt/2 -type d -print | wc -l
    1949

Testing performance of the current fsck.fat:

    # time fsck.fat -n -v /dev/sdb2 | \
    > egrep 'bytes per logical sector|bytes per cluster|sectors total|clusters$'
           512 bytes per logical sector
          4096 bytes per cluster
       8388608 sectors total
    /dev/sdb2: 973008 files, 978846/1046527 clusters

    real    0m11.552s
    user    0m2.183s
    sys     0m7.547s

Free sectors in the file system according to fsck.fat:
    (1046527 - 978846) * 4096 / 512 = 541448 sectors

Repeating this test while also using 'blktrace /dev/sdb2' and Ctrl-C
around the test in a separate terminal, reports these numbers of I/Os
being performed:
    Read requests   Read bytes
           15,563      165 MiB

Prior to this commit [1] from 0.0.9, GParted used libparted's
ped_file_system_get_resize_constraint() to report the minimum size to
which a FAT* file system can be resized.  Use this test program [2] to
performance test this method:

    # time ./fscons /dev/sdb2
    dev=/dev/sdb2
    sector_size=512
    min_size=7909522
    max_size=8388608

    real    0m2.673s
    user    0m0.070s
    sys     0m1.834s

Free sectors in the file system according to libparted
ped_file_system_get_resize_constraint():
    8388608 - 7909522 = 479086 sectors

blktrace reports these numbers of I/Os being performed:
    Read requests   Read bytes
            7,821       71 MiB

So using libparted resize constraint is a bit faster but is still
reading too much data and is really too slow.  Also when testing GParted
using this libparted method against a corrupted FAT32 file system, on
every refresh, one popup dialog is displayed for each error libparted
detects with the file system, each of which needs acknowledgement.
Example popup:

                     Libparted Error
    \DIRNAME\FILENAME.EXT is 107724k, but is has 1920
    clusters (122880k).

                                 [ Cancel ][ Ignore ]

There could be a huge number of such errors in a corrupted file system.
Not really suitable for use by GParted.

Test the performance of mtools' minfo command to report the file system
figures:

    # time minfo -i /dev/sdb2 :: | \
    > egrep 'sector size:|cluster size:|small size:|big size:|free clusters='
    sector size: 512 bytes
    cluster size: 8 sectors
    small size: 0 sectors
    big size: 8388608 sectors
    free clusters=67681

    real    0m0.013s
    user    0m0.004s
    sys     0m0.019s

Free sectors in the file system according to minfo:
    67681 * 8 = 541448 sectors

blktrace reports these numbers of I/Os being performed by minfo:
    Read requests   Read bytes
                1       16 KiB

This matches with minfo just reading information from the BPB (BIOS
Parameter Block) [3] from sector 0 and the FS Information Sector [4]
usually in sector 1.  Note that the free cluster figure reported by
minfo comes from the FS Information Sector because it only reports it
for FAT32 file systems, not for FAT16 file systems.  Scanning the File
Allocation Table (FAT) [5] to count free clusters is exactly what mdir,
without the '-f' (fast) flag, does.  Test the performance of mdir:

    # export MTOOLS_SKIP_CHECK=1
    # time mdir -i /dev/sdb2 ::/ | fgrep 'bytes free'
                            277 221 376 bytes free

    real    0m0.023s
    user    0m0.011s
    sys     0m0.023s

Free sectors in the file system according to mdir:
    277221376 / 512 = 541448 sectors

blktrace reports these number of I/Os being performed by mdir:
    Read requests   Read bytes
                5      448 KiB

So minfo and mdir together provide the needed information and are 2 to 3
orders of magnitude faster because they only read the needed BPB and FAT
data from the drive.  Use these together to read the file system usage.

[1] 61cd0ce778
    lots of stuff and cleanups, including fixing getting used/unused
    space of hfs/hfs+/fat16/fat32

[2] fscons.c
/* FILE:     fscons.c
 * SYNOPSIS: Report libparted's FS resize limits.
 * BUILD:    gcc -o fscons fscons.c -lparted -lparted-fs-resize
 */

int main(int argc, const char *argv[])
{
    PedDevice* dev = NULL;
    PedDisk* tab = NULL;
    PedPartition* ptn = NULL;
    PedFileSystem* fs = NULL;
    PedConstraint* cons = NULL;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: fscons BLOCKDEV\n");
        exit(1);
    }

    dev = ped_device_get(argv[1]);
    if (dev == NULL)
    {
        fprintf(stderr, "ped_device_get(\"%s\") failed\n", argv[1]);
        exit(1);
    }
    printf("dev=%s\n", dev->path);
    printf("sector_size=%ld\n", dev->sector_size);

    tab = ped_disk_new(dev);
    if (tab == NULL)
    {
        fprintf(stderr, "ped_disk_new(dev) failed\n");
        exit(1);
    }

    ptn = ped_disk_get_partition_by_sector(tab, 0);
    if (ptn == NULL)
    {
        fprintf(stderr, "ped_disk_get_partition(tab, 0) failed\n");
        exit(1);
    }

    fs = ped_file_system_open(&ptn->geom);
    if (fs == NULL)
    {
        fprintf(stderr, "ped_file_system_open(&ptn->geom) failed\n");
        exit(1);
    }

    cons = ped_file_system_get_resize_constraint(fs);
    if (cons == NULL)
    {
        fprintf(stderr, "ped_file_system_get_resize_constraint(fs) failed\n");
        exit(1);
    }
    printf("min_size=%ld\n", cons->min_size);
    printf("max_size=%ld\n", cons->max_size);

    ped_constraint_destroy(cons);
    ped_file_system_close(fs);
    ped_disk_destroy(tab);
    ped_device_destroy(dev);

    return 0;
}

[3] Design of the FAT file system, BIOS Parameter Block
    https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#BIOS_Parameter_Block

[4] Design of the FAT file system, FS Information Sector
    https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#FS_Information_Sector

[5] Design of the FAT file system, File Allocation Table
    https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#File_Allocation_Table

Bug 569921 - dosfsck -n delays device scan
2019-07-04 10:51:50 -06:00
Curtis Gedak 73f9a6f748 Add missing window title to Help Contents dialog (!45)
When GParted is configured with `--disable-doc` the help documentation
is neither built, nor installed.

With this configuration the Help -> Contents menu displays a message
dialog indicating the "Documentation is not available".

On GNOME 3 no title is shown; however, on some other graphic toolkits
/ window managers an unspecified title is shown.

For example on GParted Live with Fluxbox the following is displayed:

                         Unnamed
                         -------

               Documentation is not available

      This build of gparted is configured without documentation.
      Documentation is available at the project web site.
      https://gparted.org

                           OK

To address the unspecified title on non-GNOME 3 graphic toolkits, add
a title that works with and without GNOME 3.

Closes !45 - Add missing window title to Help Contents dialog
2019-06-12 15:26:54 +00:00
Mike Fleetwood 1d8cbd0125 Add missing Device.h include into GParted_Core and Win_GParted
The files GParted_Core.h, GParted_Core.cc and Win_GParted.cc all use the
Device type but don't include Device.h for it's definition.  Include it.
2019-06-11 15:55:02 +00:00
Mike Fleetwood 1ed8d909fc Replace partition boundary trimming with bug error messages (#48)
All the dialogs which compose new or modified partition boundaries
create those partitions within the boundaries of the device.  Therefore
trimming the partition boundaries to device boundaries never happens.
So replace this trimming with bug error reports.

Also add bug prefixes to the other error messages in
GParted_Core::valid_partition() too.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood e3b0558f62 White space layout update in snap_to_mebibyte/cylinder() (#48)
The previous commit moved the code from GParted_Core to
Dialog_Base_Partition class without making a single formatting change to
ensure the code was guaranteed to work the same within that larger
commit.  Now reformat the code to current layout standards.  Making it a
separate commit simplifies the effort for both changes and improves
bisectability.

Additionally to be sure there were no code changes,
Dialog_Base_Partition.cc was compiled to assembler code with and without
this change applied and the resultant assembler code compared.  There
were no differences in the generated assembler code.

Start with the make generated g++ command for compiling
Dialog_Base_Partition.o; (1) remove the '-g' flag as inserted debugging
directives do differ; and (2) replace '-c -o Dialog_Base_Partition.o'
with '-S -o Dialog_Base_Partition.s' to produce assembler output instead
of object code.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood 7c94b7d920 Snap partition boundaries before dialogs update FS usage (#48)
Move snap_to_*() method calls from the point when all operations are
added to the list, to earlier when Resize/Move, Paste (into new) and
Create New dialogs are composing the new partition objects.  In
particular for the Resize/Move operation, to just before updating the
file system usage.

This change finally resolves this bug.

Because of the dialog call chains into Dialog_Base_Partition,
snap_to_alignment() must be added into:
* Dialog_Base_Partition::prepare_new_partition() for the Resize/Move and
  Paste (into new) dialogs; and
* Dialog_Partition_New::Get_New_Partition() for the Create New dialog.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood 3222c8dd1a Pass the current device down to Dialog_Base_Partition class (#48)
The current device has to be passed to the dialog constructors and then
on to the Dialog_Base_Constructor.  Note that the Dialog_Partition_New
constructor is already passed the current device, however it still needs
to pass it on to Dialog_Base_Constructor.

This is ready so that snap_to_*() methods can access the current device
when they are called from within these dialogs.

* Pass Parameter to Base Class Constructor while creating Derived class
  Object
  https://stackoverflow.com/questions/16585856/pass-parameter-to-base-class-constructor-while-creating-derived-class-object

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood 4101b0961b Update file system usage last in prepare_new_partition() (#48)
Move setting of the new_partition object file system usage to after
everything else, specifically after free_space_before and strict_start.
This is because snap_to_*() use free_space_before and strict_start and
snap_to_alignment() is going to be called before the file system usage
is updated to avoid the error in this bug report.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood 14aa9276d4 Remove unused error reporting from snap_to_*() (#48)
None of the snap_to_*() methods report any errors so remove the unused
error parameter and return value.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Mike Fleetwood 406beaaed0 Separate partition alignment from validation (#48)
PATCHSET OVERVIEW

A user had 2 adjacent partitions which were aligned to multiples of
33553920 bytes (32 MiB - 512 bytes), not MiB or cylinders.  As far as
GParted is concerned this is not aligned.  The second partition
contained closed LUKS encrypted data.  Recreate this setup with:

    # truncate -s 200G /tmp/disk.img
    # losetup -f --show /tmp/disk.img
    /dev/loop0
    # sfdisk -u S /dev/loop0 << EOF
    65535 2162655 83
    2228190 78904140 83
    EOF
    # partprobe /dev/loop0
    # echo -n badpassword | cryptsetup luksFormat /dev/loop0p2 -

When trying to move the second LUKS encrypted partition to the right by
any amount, with the default MiB alignment, GParted displays this error
dialog and fails to even queue the operation:

    Could not add this operation to the list
    A partition with used sectors (78907392) greater than its
    length (78905344) is not valid
    [                       OK                               ]

Overview of the steps involved:

1. The Resize/Move dialog composed a new partition to start a whole
   multiple of MiB after the end of the previous non-aligned partition.
   The new partition also had it's size increased to a whole multiple of
   MiB, to 78907392 sectors (38529 MiB) which was 1.59 MiB larger than
   before.  Neither the start or end of the new partition are aligned at
   this point.

2. Win_GParted::activate_resize() applied the change back to the closed
   LUKS partition object, additionally making the used sectors equal to
   the partition size.
   (To match the fact that when opened the LUKS mapping it will
   automatically fill the new larger partition size).

3. GParted_Core::snap_to_mebibyte() then aligned the partition start and
   end to whole MiB boundaries, reducing the partition size in the
   process to 78905344 (38528 MiB).

4. GParted_Core::snap_to_alignment() reported the error saying that it
   couldn't add the operation to the list because it was invalid to have
   the file system used sectors larger than the partition size.

Fix this by having the snap to alignment adjustments applied before the
dialogs update any associated file system usage.  Specifically the
Resize/Move, Paste (into new) and Create New dialogs as these are the
only ones which either create or modify partition boundaries.
Validation done by snap_to_alignment() will continue to occur at the
current point when the operation is added to the list.

THIS COMMIT

snap_to_alignment() is doing two different jobs, it is (1) optionally
adjusting the new partition boundaries for MiB or Cylinder alignment;
and (2) checking that the partition boundaries and file system usage are
valid.

Split those into two different functions (1) snap_to_alignment() and
(2) valid_partition().  For now valid_partition() still calls
snap_to_alignment() so there is no functional change with this commit.

Closes #48 - Error when moving locked LUKS-encrypted partition
2019-06-11 15:55:02 +00:00
Curtis Gedak 6c9194869c Update copyright years 2019-05-29 09:46:10 -06:00
Mike Fleetwood 5e77368daa Fix reading NTFS usage after resize (#57)
After an NTFS file system has been resized the command GParted currently
uses to read the file system usage fails like this:

    # ntfsinfo --mft /dev/sdb1
    Volume is scheduled for check.
    Please boot into Windows TWICE, or use the 'force' option.
    NOTE: If you had not scheduled check and last time accessed this volume
    using ntfsmount and shutdown system properly, then init scripts in your
    distribution are broken. Please report to your distribution developers
    (NOT to us!) that init scripts kill ntfsmount or mount.ntfs-fuse during
    shutdown instead of proper umount.
    Failed to open '/dev/sdb1'.

Fix by added the '--force' flag as described in the error message.

Closes #57 - NTFS Resize results in Partition Information Warning on
             Refresh
2019-05-28 16:01:25 +00:00
Mike Fleetwood fbcf4b56bb Report errors correctly on failure to read NTFS usage (#57)
GParted uses ntfsinfo to read the NTFS file system usage.  However when
ntfsinfo fails with a non-zero exit status GParted reports stdout twice,
rather than stdout and stderr.  Correct this.

Closes #57 - NTFS Resize results in Partition Information Warning on
             Refresh
2019-05-28 16:01:25 +00:00
Luca Bacci 12f08d38b8 Set the xalign property for Gtk::Labels (!40)
With the same case as from the previous commit, the very long "Mounted
on ..." text is now wrapped, but the text may not be left justified.
Slowly adjust the dialog width and see how the text wrapping is updated
to fit the size adjustment but the text is centred rather than left
justified.

This is because setting the halign property to Gtk::ALIGN_START does not
guarantee left alignment of text for wrapped or ellipsized Gtk::Labels.

Use the xalign property instead.

To set the xalign property there is a method in the GtkMisc (Gtk::Misc)
base class:

  gtk_misc_set_alignment (Gtk::Misc::set_alignment)

However, GtkMisc (Gtk::Misc) was deprecated in Gtk 3.14 (Gtkmm 3.14)
and in Gtk 3.16 (gtkmm 3.16) set_alignment() was replaced with the
introduction of two new methods:

  gtk_label_set_xalign (Gtk::Label::set_xalign)
  gtk_label_set_yalign (Gtk::Label::set_yalign)

Add a check for Gtkmm method Gtk::Label::set_xalign() in configure.ac
and use it when available.

References:

[1] Gtk3 Reference Documentation - gtk_misc_set_alignment()
    https://developer.gnome.org/gtk3/stable/GtkMisc.html#gtk-misc-set-alignment
    "gtk_misc_set_alignment has been deprecated since version 3.14 and
    should not be used in newly-written code. Use GtkWidget's alignment
    ("halign" and "valign") and margin properties or GtkLabel's
    "xalign" and "yalign" properties."

[2] Gtkmm 3.16 Gtk::Misc Class Reference, set_alignment() method
    https://developer.gnome.org/gtkmm/3.16/classGtk_1_1Misc.html#a52b2675874cf46a3097938756b9fe9e8

[3] GNOME BugZilla - EmptyBoxes: instructions_label's alignment is off
    https://bugzilla.gnome.org/show_bug.cgi?id=735841

[4] Gtk commit from 2014-09-16:
    GtkLabel: add x/yalign properties
    https://gitlab.gnome.org/GNOME/gtk/commit/d39424fc

[5] Gtk3 Reference Documentation - gtk_label_set_xalign()
    https://developer.gnome.org/gtk3/stable/GtkLabel.html#gtk-label-set-xalign

[6] Gtkmm 3.16 Gtk::Label Class Reference, set_xalign() method
    https://developer.gnome.org/gtkmm/3.16/classGtk_1_1Label.html#acee7d4e87d7cc14080a7b8ded5f84e5e

Closes !40 - Limit wrapping labels
2019-05-15 16:11:21 +01:00
Luca Bacci 769d19e0f9 Set a default max_width_chars for wrapping Gtk::Labels (!40)
Opening the Partition Information dialog for a file system mounted on a
very long mount point, or on openSUSE which mounts the OS from 10 btrfs
subvolumes from the same partition, will cause the dialog to be very
wide as the "Mounted on ..." text is not wrapped.

Back in Gtk2, when width_chars / max_width_chars were not set, wrapping
labels had a default width beyond which text wrapped onto a new line
[1].

For Gtk3 this default width was first reworked a bit [2], and then was
removed for the very early Gtk3 3.0.10 release [3].

It is recommended that applications explicitly set default values,
otherwise wrapping labels never wrap when requesting their natural
allocation.

References:

[1] Gtk 2.24.32 source code - gtk/gtklabel.c:2975
    https://gitlab.gnome.org/GNOME/gtk/blob/2.24.32/gtk/gtklabel.c#L2975
        "This long string gives a good enough length for any line to
        have."

[2] Gtk commit from 2010-04-21:
    680d7762ba
    Make sure not to base the minimum size on "max-width-chars", only
    the natural size.
        "This string is just about long enough."

[3] Gtk commit from 2011-04-17:
    c8ce1106c1
    label: Don't try to guess a label's size

    People should use window default sizes or label
    width-chars/max-width-chars to find the ideal layout for a label
    instead of relying on magic.

Closes !40 - Limit wrapping labels
2019-05-15 07:36:08 +01:00
Luca Bacci eeffd50531 Request natural width in Gtk::ScrolledWindows for Gtk >= 3.22 (!39)
Before Gtk 3.22 GtkScrolledWindow propagated natural size to its
Children and so on to descendants.  In Gtk 3.22 this was changed to
always request the minimum size.  This was done because it is believed
to be a safer default (gives a better behaviour) in case of dynamic
content inside the scrolled window, that is, content that may change
allocated size. [1][2][3]

When the scrolled window content is not dynamic the natural size is
preferable because it gives a better looking layout and without any
downside.

In the case of GParted content which is not dynamic, so request the
scrolled windows to allocate children at natural sizes for Gtk >= 3.22.

The benefits of natural size allocation are evident in presence of
wrapping labels (for example inside the "Partition Info" dialog), that
with the minimum size request likely end up taking a very small width.

References:

[1] Gtk commit from 2016-08-31:
    GtkScrolledWindow: Make propagation of natural child sizes optional
    0984d1622d
    "Making propagation of child natural sizes mandatory (or default,
    even) was evidently a mistake as this causes dynamic content in a
    scrolled window to resize it's parent when the scrolled window is
    competing for space with an adjacent widget."

[2] Gtk 3.22 Reference Documentation -
    gtk_scrolled_window_set_propagate_natural_width
    https://developer.gnome.org/gtk3/3.22/GtkScrolledWindow.html#gtk-scrolled-window-set-propagate-natural-width

[3] Gtkmm 3.24 Gtk::ScrolledWindow Class Reference,
    set_propagate_natural_width() method
    https://developer.gnome.org/gtkmm/3.24/classGtk_1_1ScrolledWindow.html#a2d4cb945688ecb8739efd70b18742779

[4] Gtkmm 3.21.6 NEWS
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.21.6/NEWS
    "ScrolledWindow: Added get/set_propagate_natural_height/width() and
    the properties."

Closes !39 - Always request natural size inside Gtk::ScrolledWindow
2019-05-13 20:12:12 +00:00
Mike Fleetwood ad6d2b3890 Replace deprecated get_vbox() with get_content_area() (!25)
get_vbox() was deprecated in gtkmm 3.1.6 [1][2].  Switch to the
get_content_area() replacement.  Note that GParted already requires
gtkmm >= 3.4 as set in configure.ac.

[1] Gtkmm 3.1.6 NEWS
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.1.6/NEWS
    "Dialog: Deprecate get_vbox(), replacing with get_content_area(),
    to match the C function name."

[2] Gtkmm commit from 2011-06-13:
    Dialog: Deprecate get_vbox(), replacing with get_content_area().
    https://git.gnome.org/browse/gtkmm/commit/?id=5ccc289fa8e9b046c07f5ea234f5ced8c6356fc1

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 8902b0a260 Use Gtk::Grid for Dialog_Partition_Info (!25)
Gtk::Table was deprecated in Gtk 3.4.0.  Replace with Gtk::Grid.

This commit makes the change for Dialog_Partition_Info.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci d57d79b1c4 Use Gtk::Grid for Win_GParted pt2 (!25)
Gtk::Table was deprecated in Gtk 3.4.0.  Replace with Gtk::Grid.

This commit makes the change for Win_GParted / pt2.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 6e07fb051b Use Gtk::Grid for Win_GParted pt1 (!25)
Gtk::Table was deprecated in Gtk 3.4.0.  Replace with Gtk::Grid.

This commit makes the change for Win_GParted / pt1.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 28f133929d Use Gtk::Grid for Dialog_Base_Partition (!25)
Gtk::Table was deprecated in Gtk 3.4.0.  Replace with Gtk::Grid.

This commit makes the change for Dialog_Base_Partition.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 90b3e99554 Use Gtk::Grid for Dialog_Partition_New (!25)
Gtk::Table was deprecated in Gtk 3.4.0 [1].  Replace with Gtk::Grid.
Note that the meaning of the attachment parameters changed between
Gtk::Table::attach() [2] from left, right, top, bottom and
Gtk::Grid::attach() [3] to left, top, width, height.

This commit makes the change for Dialog_Base_Partition.

[1] Gtkmm 3.4 NEWS file (actually first included in gtkmm 3.3.2
    unstable)
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.4.0/NEWS#L162
        * Deprecate Gtk::Table in favour of Gtk::Grid.

[2] Gtkmm 3.4 Gtk::Table Class Reference, attach() method
    https://developer.gnome.org/gtkmm/3.4/classGtk_1_1Table.html#a28b6926e68337a51ba29f2b4dd69f087
        Deprecated: 3.4: Use Gtk::Grid::attach() with Gtk:Grid.  Note
        that the attach argument differ between those two function.

[3] Gtkmm 3.4 Gtk::Grid Class Reference, attach() method
    https://developer.gnome.org/gtkmm/3.4/classGtk_1_1Grid.html#a9c425e95660daff60a77fc0cafc18115

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 1bee0ddf26 Use Gtk::Separator (!25)
Gtk::HSeparator was deprecated in Gtkmm 3.2.  Replace with plain
Gtk::Separator.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 667af24c73 Use Gtk::Paned (!25)
Gtk::HPaned and Gtk::VPaned were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Paned.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 07fc4aefc3 Use Gtk::Box for Dialog_Progress (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_Progress.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci d780ca644e Use Gtk::Box for Dialog_Rescue_Data (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_Rescue_Data.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci cc6a085e60 Use Gtk::Box for DialogPasswordEntry (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for DialogPasswordEntry.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci c1f22e28a4 Use Gtk::Box for Dialog_Partition_Name (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_Partition_Name.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:05 +01:00
Luca Bacci 784a4977b1 Use Gtk::Box for Dialog_FileSystem_Label (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_FileSystem_Label.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci ca4c4160cc Use Gtk::Box for DialogFeatures (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for DialogFeatures.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci 85ab57fee6 Use Gtk::Box for Dialog_DiskLabel (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_DiskLabel.cc.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci 363868bf5c Use Gtk::Box for Dialog_Partition_Info (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_Partition_Info.{h,cc}.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci bfeb123462 Use Gtk::Box for Dialog_Base_Partition (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for Dialog_Base_Partition.{h,cc}.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci b0f455c702 Use Gtk::Box for HBoxOperations (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2.  Replace with
plain Gtk::Box.

This commit makes the change for HBoxOperations.{h,cc}.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci c02c3ee4b5 Use Gtk::Box for Win_GParted (!25)
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2 [1].  Replace with
plain Gtk::Box.

This commit makes the change for Win_GParted.{h,cc}.

[1] Gtkmm 3.2.0 NEWS file (actually first included in gtkmm 3.1.6
    unstable)
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.2.0/NEWS#L91
        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.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Luca Bacci 74bb981ed2 Use Gdk::RGBA (!25)
The Gdk::RGBA data type was introduced to replace Gdk::Color in
Gtkmm 3.0 [1], with Gdk::Color being deprecated in Gtkmm 3.10 [2].

With this commit we make the change to Gdk::RGBA data type which is the
modern replacement to Gdk::Color.  Gdk::RGBA can be used almost as a
drop in replacement because it keeps most of the Gdk::Color interface.

Also, this commit removes the C Gtk call introduced during the
port-to-gtk3 patchset by commit:
    5379352766
    repare-for-gtk3: Prepare for removal of Gtk::Widget::modify_fg() (#7)

[1] Gtkmm 3.0.1 NEWS file
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.0.1/NEWS#L48
        * RGBA replaces Color, though Color still exists because it is
          used by TextView.  We hope to deprecated Color completely in
          gtkmm 3.2.

[2] Gtkmm 3.10.0 NEWS file
    https://gitlab.gnome.org/GNOME/gtkmm/blob/3.10.0/NEWS#L127
        Gdk:
        * Deprecate Color.

Closes !25 - Modern Gtk3 - part 1
2019-04-27 12:03:04 +01:00
Mike Fleetwood 2c19a620b1 Update includes in DialogFeatures.h and .cc
Mostly add, but also remove, #includes so both DialogFeatures.h and .cc
include exactly the header files each needs to get the definitions they
use.

Header file #include guards are there to specifically enable this.
2019-04-22 21:51:30 +01:00
Mike Fleetwood 57e8ac50f4 Rename method to DialogFeatures::load_one_filesystem()
To better reflect that it is loading the supported actions for one file
system into the treeview, just like it's parent load_filesystems() is
initiating the loading for all the file systems.
2019-04-22 21:51:30 +01:00
Mike Fleetwood 4939b941dd Fix available Partition menu options not being updated on rescan (!38)
Select a partition and look at the available actions in the Partition
menu.  Then add or remove some commands which that particular file
system uses and rescan to detect those changes.  Open the Partition menu
again.  It doesn't reflect the changes of supported actions seen in the
File System Support dialog.  Select a different partition and then
select the original partition again.  Now the available actions in the
Partition menu reflect the changes of supported actions.

Have been testing by adding and removing /sbin/e2label to add and
remove EXT2/3/4 file system labelling support just because that feature
has existed for a very long time and EXT2/3/4 are displayed near the top
of the File System Support dialog.  Tested this minor issue existed as
far back as GParted 0.3.7.

Fix by simply also refreshing the valid operations to update the
Partition menu after updating the found file system specific commands.

Closes !38 - Fixes for minor issues with File System Support rescanning
2019-04-22 21:51:30 +01:00
Mike Fleetwood 7ea91bca61 Fix File System Support dialog not showing changes after rescan (!38)
Open the File System Support dialog, either add or remove some file
system specific commands used by GParted and press the
[Rescan For Supported Actions] button.  The supported actions don't
change.  However after just closing and reopening the dialog, the
supported actions do reflect the added or removed file system specific
commands.

Bisected to this commit:
    4d6d464664
    Display "other" in the File System Support dialog (!13)

The problem is that commit made a subset copy of the
GParted_Core::FILESYSTEMS vector, obtained from get_filesystems(), so
when the rescan ran and the FILESYSTEMS vector was updated with new
supported actions, the dialog still displayed the original subset copy,
so didn't reflect the changed supported actions.

Fix by passing a reference to the GParted_Core::FILESYSTEMS vector,
obtained from get_filesystems(), and perform the necessary filtering
inside the dialog, like before the above faulty commit.  Additionally
finding and adding "other" file system to the end of the list.

Closes !38 - Fixes for minor issues with File System Support rescanning
2019-04-22 21:51:28 +01:00
Mike Fleetwood 1b17264603 Stop checking for 'ntfslabel --new-serial' support
The oldest supported distributions have these versions of ntfs-3g /
ntfsprogs.

  Distro             EOL        ntfs-3g / ntfsprogs
- Debian 8           2020-Jun   2014.2.16AR.2
- RHEL / CentOS 7    2024-Jun   2017.3.23
- Ubuntu 14.04 LTS   2019-Apr   2013.1.13AR.1

The oldest version of ntfs-3g / ntfsprogs on Ubuntu 14.04 LTS includes
support for the --new-serial option.

    $ ntfslabel -V

    ntfslabel v2013.1.13AR.1 (libntfs-3g) - Display, or set, the label for an NTFS Volume.

    $ ntfslabel --help | grep -- --new-serial
            --new-serial   Set a new serial number

Therefore it is no longer necessary to check for this option as it is
always available.  The worst case scenario is that some how an old
version of ntfslabel is used which doesn't support this option.  In such
a case GParted goes from not supporting changing the UUID to claiming
support, but presumably it would fail with an error reporting unknown
option when applied.  Arguably better from an end user support point of
view.
2019-04-17 16:40:19 +00:00
Mike Fleetwood d795cccb1b Consolidate common if have ntfsresize command conditions 2019-04-17 16:40:19 +00:00
Mike Fleetwood ef4d4cb100 Switch to faster ntfsinfo to read NTFS usage (#47)
A user reported GParted was slow to refresh and timing ntfsresize to
query his file systems found that it was taking 4.7 seconds and 9.2
seconds for sizes 31.7 GiB and 49 GiB NTFS file systems respectively.
Almost 14 seconds just to read the usage.

Created a 4 GiB NTFS and filled it with as many 4 KiB files as possible,
just over 800,000 files.

    # df -k /mnt/2
    Filesystem     1K-blocks    Used Available Use% Mounted on
    /dev/sdb2        4194300 4193860       440 100% /mnt/2
    # df -i /mnt/2
    Filesystem     Inodes  IUsed IFree IUse% Mounted on
    /dev/sdb2      819640 808591 11049   99% /mnt/2

Testing perform of ntfsresize:

    # time ntfsresize --info --force --no-progress-bar /dev/sdb2 | \
    > egrep 'Current volume size|resize at|Cluster size'
    Cluster size       : 4096 bytes
    Current volume size: 4294963712 bytes (4295 MB)
    You might resize at 4294516736 bytes (freeing 450560 bytes).

    real    0m5.231s
    user    0m2.072s
    sys     0m3.014s

Computation of figures:
    Clusters per volume = 4294963712 / 4096 = 1048575.125
    Free clusters = (4294963712 - 4294516736) / 4096 = 109.125

Testing performance of ntfscluster, as used before this commit [1] from
GParted 0.3 in 2006:

    # time ntfscluster --force /dev/sdb2 | \
    > egrep 'bytes per cluster|bytes per volume|clusters per volume|clusters of free space'
    ...
    bytes per cluster       : 4096
    bytes per volume        : 4294963200
    clusters per volume     : 131071
    clusters of free space  : 110

    real    0m4.243s
    user    0m1.629s
    sys     0m2.587s

Note that the clusters per volume figure reported by ntfscluster is
wrong.  4294963200 / 4096 = 1048575, not 131071.

Testing performance using ntfsinfo:

    # time ntfsinfo --mft /dev/sdb2 | \
    egrep 'Cluster Size|Volume Size in Clusters|Free Clusters'
            Cluster Size: 4096
            Volume Size in Clusters: 1048575
            Free Clusters: 110 (0.0%)

    real    0m0.022s
    user    0m0.012s
    sys     0m0.018s

Repeating the above tests while also using 'btrace /dev/sdb2' and Ctrl-C
around each test via a separate terminal, reports these numbers of I/Os
being performed:
  Command      Read requests   Read bytes
- ntfsresize           2,695     1116 MiB
- ntfscluster          2,685     1116 MiB
- ntfsinfo                13     2208 KiB
No wonder that ntfsresize and ntfscluster take a long time, they read
just over 1 GiB of data from the 4 GiB file system, where as ntfsinfo
only reads just over 2 MiB.

Switch to using ntfsinfo to report file system usage.

[1] 9d956594d6
    replaced ntfscluster with ntfsresize (see #350789)

Closes #47 - GParted is slow refreshing NTFS file systems
2019-04-17 16:40:19 +00:00
Mike Fleetwood 8ea0b7ef13 Prefer enum to string comparison in set_partition_type() 2019-04-15 18:28:13 +00:00
Mike Fleetwood ab1381b1f4 Stop trying unneeded alternative libparted linux-swap names
With that same commit in parted 1.9 [1], libparted only recognised these
linux-swap names via deprecated aliases:
    linux-swap(old)
    linux-swap(new)
but does accept this name as a current alias:
    linux-swap
for:
    linux-swap(v1)

Demonstration:
    # parted -v
    parted (GNU parted) 2.1
    ...

    # parted /dev/sdc mkfs yes 1 "linux-swap(new)" unit s print
    ...
    [0] filesys.c:148 (ped_file_system_type_get(): File system alias linux-swap(new) is deprecated
    ...
    Number  Start  End       Size      Type     File system     Flags
     1      2048s  2099199s  2097152s  primary  linux-swap(v1)

    # parted /dev/sdc mkfs yes 1 "linux-swap" unit s print
    ...
    Number  Start  End       Size      Type     File system     Flags
     1      2048s  2099199s  2097152s  primary  linux-swap(v1)

Again as GParted now requires libparted 2.2 or later:
1) Stop using alternative "linux-swap(new)" name as that is deprecated
   by libparted.
2) Also stop using alternative "linux-swap(v1)" name as that code is
   never used because libparted recognised the GParted "linux-swap"
   name as a current alias.

[1] http://git.savannah.gnu.org/cgit/parted.git/commit/?id=cfafa4394998a11f871a0f8d172b13314f9062c2
    Rationalise linux-swap fs names, and add a "linux-swap" alias
2019-04-15 18:28:13 +00:00
Mike Fleetwood 40ec0deba8 Stop recognising retired libparted linux-swap names
With this commit in parted 1.8.3 [1], libparted changed from reporting
the name of Linux swap as:
    linux-swap
to reporting either:
    linux-swap(old)
    linux-swap(new)
Later with this commit in parted 1.9 [2], libparted stopped reporting
those names and reported these instead:
    linux-swap(v0)
    linux-swap(v1)

Demonstration:
    # mkswap /dev/sdc1
    Setting up swapspace version 1, size = 1048572 KiB
    no label, UUID=a2010834-003d-4bf2-9e94-58383fe20a26
    # blkid /dev/sdc1
    /dev/sdc1: UUID="a2010834-003d-4bf2-9e94-58383fe20a26" TYPE="swap"
    # parted -v
    parted (GNU parted) 2.1
    ...
    # parted /dev/sdc unit s print
    ...
    Number  Start  End       Size      Type     File system     Flags
     1      2048s  2099199s  2097152s  primary  linux-swap(v1)

As GParted now requires libparted 2.2 or later [3], remove recognition
for those no longer libparted reported linux-swap names.  Note that the
"swap" name is reported by blkid.

[1] http://git.savannah.gnu.org/cgit/parted.git/commit/?id=98a53fd115ca012edf226525b8d4be628454f99e
    Enable support for swsusp partitions, and the ability to
    differentiate between old and new versions of linux-swap partitions.
    Changed the swap_init signature and removed extra ped_geometry_read
    from _swap*_open.

[2] http://git.savannah.gnu.org/cgit/parted.git/commit/?id=cfafa4394998a11f871a0f8d172b13314f9062c2
    Rationalise linux-swap fs names, and add a "linux-swap" alias

[3] 8df975c7d1
    Increase minimum required libparted to 2.2 (!22)
2019-04-15 18:28:13 +00:00
Mike Fleetwood 4d9dc14b0e Set partition type when formatting to cleared (!36)
Formatting a partition to cleared over the top of LVM2 PV leaves the
"lvm" flag set on the partition; where as formatting with an actual file
system over the top of an LVM2 PV clears the "lvm" flag.  This is true
for both MSDOS and GPT partitioned drives.

Fix by setting the partition type when formatting to cleared too.

Closes !36 - Set partition type when clearing partition contents
2019-04-15 18:28:13 +00:00
Mike Fleetwood 6ad107bc3b Remove unnecessary #include from GParted_Core.cc 2019-04-11 10:06:36 -06:00
Mike Fleetwood ea7bd0d419 Rename Dialog_Progress member variable to m_curr_op
Having a member variable named 't' which is used to share state in a
Dialog_Progress object between on_signal_show() and on_cancel() methods
is horrible.  Rename to something more meaningful.

Also initialise m_curr_op in the constructor's initialisation list,
rather than later when first used in on_signal_show().  Not strictly
required, but avoids this POD (Plain Old Data) member variable being
undefined in the Dialog_Progress object between construction and when
on_signal_show() previously assigned to it for the first time and
started using it.

* C++ FAQ / Should my constructors use "initialization lists" or
  "assignment"?
  https://isocpp.org/wiki/faq/ctors#init-lists
2019-04-11 10:06:36 -06:00
Mike Fleetwood 22ce8a4c64 Rename for loop counter variables to normative 'i' in Dialog_Progress
Several for loops created counter variable t, hiding member variable of
the same name.  Rename those loop counter variables to the normative
name 'i'.

* Why do most of us use 'i' as a loop counter variable?
  https://softwareengineering.stackexchange.com/questions/86904/why-do-most-of-us-use-i-as-a-loop-counter-variable
2019-04-11 10:06:36 -06:00
Mike Fleetwood 63f578a94b Use CSS to turn off table borders once in saved details HTML 2019-04-11 10:06:36 -06:00
Mike Fleetwood 4ccee8063c Rename method to Dialog_Progress::write_operation_details()
And update comment about replacing '\n' to reflect what the code
actually does.
2019-04-11 10:06:36 -06:00
Mike Fleetwood f779002972 Additionally write partition information to saved details (#639176)
Bug 639176 - Save partition layout to gparted_details.htm
2019-04-11 10:06:36 -06:00
Mike Fleetwood edb3afac7b Write starting device overview information to saved details (#639176)
Writes the starting device overview information of all known devices to
the top of the saved details HTML.  This is so that hopefully we don't
need to additionally ask users for their disk layouts via 'fdisk -l',
'parted print' and 'lsblk' when the saved details file is provided.

Also moves the equals separators "==================" from below to
above each operation so the each section is separated.

Bug 639176 - Save partition layout to gparted_details.htm
2019-04-11 10:06:36 -06:00
Luca Bacci f252e677d4 Ensure icon sizes (#39)
Some icon themes only provide large icons for stock items.  This can
cause problems like overly large icons appearing in the GParted UI.
Found on Kubuntu 16.04 LTS with default breeze icon theme.

Be compatible with these icon themes by forcing scaling of stock icons
to the requested size.

Icons are used either by Gtk::Image widgets, or Gtk::CellRendererPixbuf
objects for comboboxes/treeviews.  For Gtk::Image widgets we add
Utils::mk_image() that constructs Gtk::Image widgets and then sets the
pixel-size property.  For Gtk::CellRendererPixbuf we add
Utils::mk_pixbuf() that first loads a Gdk::Pixbuf and then scales if
needed.

Closes #39 - After GTK3 port icons are too big on KDE
2019-04-06 11:42:28 +01:00
Mike Fleetwood 56596d680a Also write "Root privileges are required ..." message to stderr (!34)
To further help in diagnosing root authorisation issues by reporting the
error message to the terminal too.  Also set a failure exit status when
terminating with this error.

Example:
    $ ./gpartedbin
    GParted 0.33.0-git
    configuration --enable-online-resize
    libparted 3.2
    Root privileges are required for running GParted
    $ echo $?
    1

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood 68cdfe99d9 Print new info before "Root privileges are required ..." dialog (!34)
So that the new version and configuration information is displayed even
if the gpartedbin executable is run as a non-root user.  To help with
diagnosing root authorisation issues with the gparted shell wrapper
script.

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood 707aaea56f Remove now unused Dialog_Progress::signal_get_libparted_version (!34)
... and related GParted_Core::get_libparted_version() method.

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood c1c20854b4 Report the same information into saved operation details (!34)
For consistency save the 3 same lines of information into the saved
operation details.  None of the new 3 lines are subject to translation.
As this information is really for our benefit when supporting users
leaving them as English is OK.  Also "GParted" and "Libparted", as
previously used, are proper nouns so they were never changed as part of
any language translation.  See with:
    egrep -r '"(GParted|Libparted)"' po/

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood c626b4cea6 Display more version and configuration info to stdout when starting (!34)
So that we might get more information from users when helping them.
Starting GParted from the command line now looks like this:
    # ./gpartedbin
    GParted 0.33.0-git
    configuration --enable-online-resize
    libparted 3.2

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood a476b8cc2c Rename local variable to meaningful benchmark_copysize 2019-04-01 09:12:10 -06:00
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