Commit Graph

735 Commits

Author SHA1 Message Date
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 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
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 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 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
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 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 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 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 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 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 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 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 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 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 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
Mike Fleetwood d1441ce6a9 Drop compose subdir (#46)
It's no longer used so drop it.

Closes #46 - Drop compose subdir
2019-03-27 16:45:22 +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 454ac64d19 Pass message parameters by reference to 2 Partition methods (#788813)
Note that this almost certainly has no performance benefit what so ever
because the methods are implicitly defined as inline [1][2] and the
compiler will have simply inlined the method bodies thus avoiding having
to construct copies of the passed parameters.

Do this anyway as constant objects are typically passed by reference
[3].  Also C++'s std::vector::push_back() [4] takes a const reference
parameter so update the kind of equivalent push_back_message() to take
a const reference parameter too.

[1] C++ reference / inline specifier
    https://en.cppreference.com/w/cpp/language/inline

        A function defined entirely inside a class/struct/union
        definition, whether it's a member function or a non-member
        friend function, is implicitly an inline function.

[2] When should I write the keyword 'inline' for a function/method?
    https://stackoverflow.com/questions/1759300/when-should-i-write-the-keyword-inline-for-a-function-method/1759575#1759575

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

[4] C++ reference / std::vector::push
    https://en.cppreference.com/w/cpp/container/vector/push_back

        void push_back(const T& value);

Bug 788813 - gparted-0.30.0/include/Partition.h:137]: performance
             problem
2019-03-23 11:13:30 -06: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
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 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 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 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 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 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
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
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