Commit Graph

177 Commits

Author SHA1 Message Date
Mike Fleetwood 0688662055 Identify libparted messages as either success or error (#790842)
All libparted messages were reported as informational, even for a step
which failed.  Instead identify libparted messages as either
informational or errors depending on whether this step was successful
or not respectively.

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

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 33a535390e Extract common code into new method get_lp_partition() 2017-10-03 08:22:19 -06:00
Mike Fleetwood 36804b9634 Implement maximize encryption volume as part of check repair operation (#774818)
Now that resizing of encrypted file systems is implemented add growing
of the open LUKS mapping as part of the check repair operation.

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

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

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

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

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
2017-01-14 08:49:58 -07:00
Mike Fleetwood fd426cf36e Create new method GParted_Core::set_device_from_disk() (#771244)
Move code from GParted_Core::set_devices_thread() performing top level
population of each Device object during the scan of the drives into new
set_device_from_disk() method.

Bug 771244 - gparted does not recognize the iso9660 file system in
             cloned Ubuntu USB boot drives
2017-01-06 10:47:11 -07:00
Mike Fleetwood 8979913a3f Remove "../include/" from GParted header #includes
It made the code look a little messy, is easily resolved in the build
system and made the dependencies more complicated than needed.  Each
GParted header was tracked via multiple different names (different
numbers of "../include/" prefixes).  For example just looking at how
DialogFeatures.o depends on Utils.h:

    $ cd src
    $ make DialogFeatures.o
    $ egrep ' [^ ]*Utils.h' .deps/DialogFeatures.Po
     ../include/DialogFeatures.h ../include/../include/Utils.h \
     ../include/../include/../include/../include/../include/../include/Utils.h \
     ../include/../include/../include/Utils.h \

After removing "../include/" from the GParted header #includes, just
need to add "-I../include" to the compile command via the AM_CPPFLAGS in
src/Makefile.am.  Now the dependencies on GParted header files are
tracked under a single name (with a single "../include/" prefix).  Now
DialogFeatures.o only depends on a single name to Utils.h:

    $ make DialogFeatures.o
    $ egrep ' [^ ]*Utils.h' .deps/DialogFeatures.Po
     ../include/DialogFeatures.h ../include/Utils.h ../include/i18n.h \
2016-12-12 13:15:34 -07:00
Mike Fleetwood 2740113dcb Refactor linux-swap recreation (#775932)
Linux-swap is recreated as part of copy, resize and move operations and
the code was special cased to implement that by calling the linux-swap
specific resize method.  However the displayed text always said "growing
file system" and then proceeded to recreate linux swap.  Example
operation:

    Copy /dev/sdb1 to /dev/sdb2
    ...
    + copy file system from /dev/sdb1 to /dev/sdb2
        Partition copy action skipped because linux-swap file system does not contain data
    + grow file system to fill the partition
      + create new linux-swap file system
        + mkswap -L"" -U "77d939ef-54d6-427a-a2bf-a053da7eed4c" /dev/sdb2
            Setting up swapspace version 1, size = 262140 KiB
            LABEL=, UUID=77d939ef-54d6-427a-a2bf-a053da7eed4c

Fix by writing recreate_linux_swap_filesystem() method with better
messaging and use everywhere maximise_filesystem() was previously used
to recreate linux-swap.  Also as this is a create step, erase the
partition first to prevent the possibility of any other file system
signatures being found afterwards.  Now the operation steps are more
reflective of what is actually being performed.

    Copy /dev/sdb1 to /dev/sdb2
    ...
    + copy file system from /dev/sdb1 to /dev/sdb2
        Partition copy action skipped because linux-swap file system does not contain data
    + clear old file system signatures in /dev/sdb2
    + create new linux-swap file system
      + mkswap -L"" -U "77d939ef-54d6-427a-a2bf-a053da7eed4c" /dev/sdb2
          Setting up swapspace version 1, size = 262140 KiB
          LABEL=, UUID=77d939ef-54d6-427a-a2bf-a053da7eed4c

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood a0158abbeb Refactor resizing file system apply methods (#775932)
resize_filesystem() was meeting two different needs:
1) when called with fill_partition = false it generated operation
   details;
2) when called from maximize_filesystem() with fill_partition = true it
   skipped generating any operation details;
then ran the switch statement to select the resize implementation.  So
extract the common switch statement into new method
resize_filesystem_implement().

Then observe that the only time resize_filesystem() was called to grow
the file system was when re-creating linux-swap.  Therefore change that
call to use maximize_filesystem() and rename to shrink_filesystem() and
modify the operation detail messages to match.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 0420159c1d Rename a few GParted_Core apply related methods (#775932)
Make the methods called below apply_operation_to_disk() follow a
standard naming convention:

 *  Contains "_partition"
    Uses libparted to query or change the partition in the disk label
    (partition table).
    E.g.:
        calibrate_partition()
        create_partition()
        delete_partition()
        name_partition()
        resize_move_partition()
        set_partition_type()

 *  Contains "_filesystem"
    Manipulates the file system within the partition, mostly using the
    FileSystem and derived class methods.
    E.g.:
        create_filesystem()
        remove_filesystem()
        label_filesystem()
        copy_filesystem()
        erase_filesystem_signatures()
        check_repair_filesystem()
        resize_filesystem()
        maximize_filesystem()

 *  Other
    Compound method calling multiple partition and file system related
    apply methods.
    E.g.:
        create()
        format()
        copy()
        resize_move()
        resize()
        move()

Rename:
    Delete()      -> delete_partition()
    change_uuid() -> change_filesystem_uuid()

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood 0b359a5490 Refactor GParted_Core::copy() (#775932)
Split out the switch statement selecting the copy implementation and
associated copy file system operation detail message into a separate
copy_filesystem() method, matching how a number of other operations are
coded.  This is why the previous copy_filesystem() methods needed
renaming.

Re-write the remaining copy() into if-operation-fails-return-false style
to simplify it.  Re-write final complicated conditional check repair and
maximise file system into separate positive if conditions for swap and
larger partition to make it understandable.

The min_size parameter to copy() was queried from the partition_src
parameter also passed to copy().  Drop the parameter and query inside
copy() instead.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood fd56d7be57 Rename copy_filesystem() methods (#775932)
Rename GParted_Core methods:
    copy_filesystem(4 params)  -> copy_filesystem_internal()
    copy_filesystem(5 params)  -> copy_filesystem_internal()
    copy_filesystem(10 params) -> copy_blocks()

See the following commit for the desire to do this.

Bug 775932 - Refactor mostly applying of operations
2016-12-12 13:15:34 -07:00
Mike Fleetwood d64283fd1a Remove left behind typedef GParted_Core::MountMapping
Left behind by:
    63ec73dfda
    Split mount_info and fstab_info maps into separate Mount_Info module
2016-09-14 09:48:33 -06:00
Mike Fleetwood 63ec73dfda Split mount_info and fstab_info maps into separate Mount_Info module
The GParted_Core::mount_info and GParted_Core::fstab_info maps and the
methods that manipulate them are self-contained.  Therefore move them to
a separate Mount_Info module and reduce the size of the monster
GParted_Core slightly.
2016-08-06 09:47:58 -06:00
Mike Fleetwood e4a8530b14 Overload is_dev_mounted() function (#767842)
Small optimisation which avoids constructing an extra BlockSpecial
object when determining if a btrfs member is mounted.  Rather than
extracting the name from the BlockSpecial object in
btrfs::get_mount_device() and re-constructing another BlockSpecial
object from that name in GParted_Core::is_dev_mounted(), pass the
BlockSpecial object directly.

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood a800ca8b68 Add BlockSpecial into mount_info and fstab_info (#767842)
On some distributions having btrfs on top of LUKS encrypted partitions,
adding a second device and removing the first device used to mount the
file system causes GParted to no longer be able to report the file
system as busy or the mount points themselves.

For example, on CentOS 7, create a single btrfs file system and mount
it.  The provided /dev/mapper/sdb1_crypt name is reported, via
/proc/mounts, as the mounting device:
    # cryptsetup luksFormat --force-password /dev/sdb1
    # cryptsetup luksOpen /dev/sdb1 sdb1_crypt
    # mkfs.btrfs -L encrypted-btrfs /dev/mapper/sdb1_crypt
    # mount /dev/mapper/sdb1_crypt /mnt/1

    # ls -l /dev/mapper
    total 0
    lrwxrwxrwx. 1 root root       7 Jul  2 14:15 centos-root -> ../dm-1
    lrwxrwxrwx. 1 root root       7 Jul  2 14:15 centos-swap -> ../dm-0
    crw-------. 1 root root 10, 236 Jul  2 14:15 control
    lrwxrwxrwx. 1 root root       7 Jul  2 15:14 sdb1_crypt -> ../dm-2
    # fgrep btrfs /proc/mounts
    /dev/mapper/sdb1_crypt /mnt/1 btrfs rw,seclabel,relatime,space_cache 0 0

Add a second device to the btrfs file system:
    # cryptsetup luksFormat --force-password /dev/sdb2
    # cryptsetup luksOpen /dev/sdb2 sdb2_crypt
    # btrfs device add /dev/mapper/sdb2_crypt /mnt/1

    # ls -l /dev/mapper
    ...
    lrwxrwxrwx. 1 root root       7 Jul  2 15:12 sdb2_crypt -> ../dm-3
    # btrfs filesystem show /dev/mapper/sdb1_crypt
    Label: 'encrypted-btrfs'  uuid: 45d7b1ef-820c-4ef8-8abd-c70d928afb49
            Total devices 2 FS bytes used 32.00KiB
            devid    1 size 1022.00MiB used 12.00MiB path /dev/mapper/sdb1_crypt
            devid    2 size 1022.00MiB used 0.00B path /dev/mapper/sdb2_crypt

Remove the first mounting device from the btrfs file system.  Now the
non-canonical name /dev/dm-3 is reported, via /proc/mounts, as the
mounting device:
    # btrfs device delete /dev/mapper/sdb1_crypt /mnt/1

    # btrfs filesystem show /dev/mapper/sdb2_crypt
    Label: 'encrypted-btrfs'  uuid: 45d7b1ef-820c-4ef8-8abd-c70d928afb49
            Total devices 1 FS bytes used 96.00KiB
            devid    2 size 1022.00MiB used 144.00MiB path /dev/mapper/sdb2_crypt
    # fgrep btrfs /proc/mounts
    /dev/dm-3 /mnt/1 btrfs rw,seclabel,relatime,space_cache 0 0
    # ls -l /dev/dm-3
    brw-rw----. 1 root disk 253, 3 Jul  2 15:12 /dev/dm-3

GParted loads the mount_info mapping from /proc/mounts and with it the
/dev/dm-3 name.  When GParted is determining if the encrypted btrfs file
system is mounted or getting the mount points it is using the
/dev/mapper/sdb2_crypt name.  Therefore no information is found and the
file system is incorrectly reported as unmounted.

Fix by changing mount_info and fstab_info to use BlockSpecial objects
instead of strings so that matching is performed by major, minor device
numbers rather than by string compare.  Note that as BlockSpecial
objects are used as the key of std::map [1] mappings operator<() [2]
needs to be provided to order the key values.

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

Bug 767842 - File system usage missing when tools report alternate block
             device names
2016-08-06 09:47:58 -06:00
Mike Fleetwood c9a2986fb9 Populate encrypted Partition member inside PartitionLUKS (#760080)
When there exists an open dm-crypt mapping, populate the encrypted
Partition object representing the encrypted file system.

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

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

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

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

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

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

Prints debugging to show results, like this:

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

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

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

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood fae909897e Use PartitionVector class throughout the code (#759726)
Replace all occurrences of std::vector<Partition> with PartitionVector.

Bug 759726 - Implement Partition object polymorphism
2016-01-26 10:11:35 -07:00
Mike Fleetwood 037020b116 Create new method GParted_Core::useable_device() (#755495)
Abstract code checking sector size and ensuring the first sector of a
candidate disk device can be read into new
GParted_Core::useable_device() method.

Bug 755495 - GParted allowing partitioning of large sector devices
             specified on the command line, when built with old
             libparted which doesn't support it
2015-10-08 13:00:01 -06:00
Curtis Gedak 1561d1ae7e Add libparted ped_file_system_resize thread to avoid blocking GUI (#737022)
Since GParted commit 52a2a9b "Reduce threading (#685740)", released in
GParted 0.15.0, application of operations occurs in the main thread
running the UI, therefore long running libparted actions such as
resizing a FAT16 or FAT32 file system hang the UI for as long as it take
to complete the operation.
https://git.gnome.org/browse/gparted/commit/?id=52a2a9b00a32996921ace055e71d0e09fb33c5fe

Though this problem exists for all libparted actions, it is particularly
noticeable when performing a large resize of fat16/fat32/hfs/hfs+ file
systems.

To address this significant cause of an unresponsive GUI, this
enhancement adds threading to the libparted ped_file_system_resize
function call.

Bug 737022 - UI hangs while running libparted operations such as
             FAT16/FAT32 resizing
2015-07-19 21:57:17 +01:00
Mike Fleetwood 54d0e3d056 Remember result of searching the PATH for the hdparm command (#751251)
Previously on every refresh for every device, GParted was searching the
PATH to discover if the hdparm command existed.  Stracing GParted showed
that calling Glib::find_program_in_path("hdparm") made the following OS
calls:
    access("/usr/lib64/qt-3.3/bin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
    access("/usr/local/sbin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
    access("/usr/local/bin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
    access("/sbin/hdparm", X_OK) = 0
    getuid()                    = 0
    stat("/sbin/hdparm", {st_mode=S_IFREG|0755, st_size=137, ...}) = 0
    stat("/sbin/hdparm", {st_mode=S_IFREG|0755, st_size=137, ...}) = 0

The Linux VFS is very fast but repeatedly doing this is wasteful.
Remember the result of searching the PATH for the hdparm command at
startup and refresh this when the [Rescan For Supported Actions] button
is pressed in the File System Support dialog.  This is the same as
GParted already does for file system specific commands and their
capabilities.

Bug 751251 - Show serial number in device information
2015-07-01 10:22:57 -06:00
Mike Fleetwood 4b72ecd44e Display device serial numbers (#751251)
Run "hdparm -I /dev/DISK" to get the hard drive serial number of
every device which has one and display it in the Device Information.
The displayed value can either be the actual serial number, "none" or
blank.  "none" means the device doesn't have a hard drive serial number,
such as for Linux software RAID arrays, BIOS fake RAID arrays or USB
flash drives.  Blank means something went wrong getting the serial
number.  Either it couldn't be found in the hdparm output or the hdparm
command wasn't installed.

Example real hard drive:
    # hdparm -I /dev/sda
    ...
    ATA device, with non-removable media
            Model Number:       SAMSUNG HM500JI
            Serial Number:      S1WFJDSZ123732
    ...

Example Linux software RAID array:
    # hdparm -I /dev/md127

    /dev/md127:
     HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device

On my desktop with 4 internal hard drives 2 Linux software RAID arrays
on those hard drives, 2 USB flash drives and 1 USB hard drive attached,
running hdparm 9 times added 0.07 seconds to the device refresh time.

Bug 751251 - Show serial number in device information
2015-07-01 10:22:47 -06:00
Mike Fleetwood d0580d5955 Rename two GParted_Core methods to detect_filesystem*()
Rename a couple of GParted_Core methods for consistency and to better
distinguish get_filesystem() from get_filesystems() which do completely
unrelated things.

  get_filesystem()                 -> detect_filesystem()
  recognise_filesystem_signature() -> detect_filesystem_internal()

Also make detect_filesystem() a static member method as it doesn't use
any member variables.  Requirement cascades to get_partition_path().
2015-05-07 08:01:43 -06:00
Mike Fleetwood 42cd956a54 Make GParted_Core methods flush_device(), get_device(), etc static
GParted_Core methods:
    flush_device()
    get_device()
    get_disk()
    get_device_and_disk()
    destroy_device_and_disk()
    commit()
    commit_to_os()
    settle_device()

This group of methods only call libparted API functions and run external
executables.  None of them access any GParted_Core member variables.
Make them all static member functions.
2015-05-07 08:01:43 -06:00
Mike Fleetwood df000a94a6 Tidy-up GParted_Core::init/fini_filesystems() function declarations
These member functions are only used within the GParted_Core class and
only operate on the static member variable FILESYSTEM_MAP.

Make both functions private and also make init_filesystems() static.
2015-05-07 08:01:43 -06:00
Mike Fleetwood 40820bada7 Fix memory leak of FileSystem objects in init_filesystems() (#749036)
The FileSystem objects stored in the FILESYSTEM_MAP are allocated once
using new in init_filesystems() but never deleted.

Valgrind output fragment:

    # valgrind --leak-check=full ./gparted
    ==29314== 353 (72 direct, 281 indirect) bytes in 1 blocks are definitely lost in loss record 6,287 of 6,905
    ==29314==    at 0x4A075FC: operator new(unsigned long) (vg_replace_malloc.c:298)
>>  ==29314==    by 0x46EDA5: GParted::GParted_Core::init_filesystems() (GParted_Core.cc:106)
    ==29314==    by 0x46EC5F: GParted::GParted_Core::GParted_Core() (GParted_Core.cc:96)
    ==29314==    by 0x4A74F4: GParted::Win_GParted::Win_GParted(std::vector<Glib::ustring, std::allocator<Glib::ustring> > const&) (Win_GParted.cc:51)
    ==29314==    by 0x4D600A: main (main.cc:56)
    ...
    ==29314== 161 (72 direct, 89 indirect) bytes in 1 blocks are definitely lost in loss record 6,119 of 6,905
    ==29314==    at 0x4A075FC: operator new(unsigned long) (vg_replace_malloc.c:298)
>>  ==29314==    by 0x46F50C: GParted::GParted_Core::init_filesystems() (GParted_Core.cc:124)
    ==29314==    by 0x46EC5F: GParted::GParted_Core::GParted_Core() (GParted_Core.cc:96)
    ==29314==    by 0x4A74F4: GParted::Win_GParted::Win_GParted(std::vector<Glib::ustring, std::allocator<Glib::ustring> > const&) (Win_GParted.cc:51)
    ==29314==    by 0x4D600A: main (main.cc:56)

GParted_Core.cc source:

   102  void GParted_Core::init_filesystems()
   103  {
   104          FILESYSTEM_MAP[ FS_UNKNOWN ]         = NULL ;
   105          FILESYSTEM_MAP[ FS_CLEARED ]         = NULL ;
>> 106          FILESYSTEM_MAP[ FS_BTRFS ]           = new btrfs() ;
   ...
>> 124          FILESYSTEM_MAP[ FS_XFS ]             = new xfs() ;
   125          FILESYSTEM_MAP[ FS_BITLOCKER ]       = NULL ;

Fix by deleting all FILESYSTEM_MAP pointers.  Note that delete on a NULL
pointer is defined by C++ as a safe do nothing operation.

    C++ FAQ / Do I need to check for null before delete p?
    https://isocpp.org/wiki/faq/freestore-mgmt#delete-handles-null

Fixing this reduces the valgrind reported definitely lost memory blocks
count from 25 down to 6.  19 FileSystem objects deleted and 19 memory
blocks no longer lost.

Bug 749036 - FileSystem objects are memory leaked in init_filesystems()
2015-05-07 08:01:43 -06:00
Mike Fleetwood 4d83d3723d Remove unused device parameter from a few GParted_Core methods
resize_move() and move() stopped using the device parameter in this
commit from 2006-07-23:
    d663c3c277
    removed cylindersize buffering during resize from the filesystems. It is

create() stopped using the device parameter in this commit from 2006-03-19:
    ad9f2126e7
    fixed issues with copying (see also #335004) cleanups + added FIXME added

For reference most other operation methods had the device parameter
removed in this earlier commit from 2005-12-07:
    642f0a145b
    from now on each partition has a reference to it's device. make use of new
2015-03-09 11:04:13 -06:00
Mike Fleetwood 9c1a833a0d Fix failure to recognise whole disk file systems in certain cases (#743181)
When the following conditions were met GParted would fail to recognise a
newly created whole disk device file system, and instead show an unknown
file system filling the disk:

1) Disk was previously partitioned and contained at least one partition.

2) Using libparted version 2.0 to 3.0 inclusive.

Initial status:
    # blkid | fgrep sdc
    # fgrep sdc /proc/partitions
       8       32  976762584 sdc
       8       33  104857600 sdc1
    # parted /dev/sdc
    GNU Parted 2.4
    Using /dev/sdc
    Welcome to GNU Parted! Type 'help' to view a list of commands.
    (parted) print
    Model: ATA ST1000LM024 HN-M (scsi)
    Disk /dev/sdc: 1000GB
    Sector size (logical/physical): 512B/4096B
    Partition Table: msdos

    Number  Start   End    Size   Type     File system  Flags
     1      1049kB  107GB  107GB  primary

When creating the loop partition table libparted would not inform the
kernel to delete the old partitions.  /proc/partitions still contained
the details of the old partitions.
    (parted) mktable loop
    Warning: The existing disk label on /dev/sdc will be destroyed and
    all data on this disk will be lost. Do you want to continue?
    Yes/No? Yes
    (parted) print
    Model: ATA ST1000LM024 HN-M (scsi)
    Disk /dev/sdc: 1000GB
    Sector size (logical/physical): 512B/4096B
    Partition Table: loop

    Number  Start  End  Size  File system  Flags

    (parted) quit
    # fgrep sdc /proc/partitions
       8       32  976762584 sdc
       8       33  104857600 sdc1

Creation of the whole disk device file system goes unnoticed by blkid
because the kernel and therefore blkid's cache have stale partition
information.
    # mkfs.xfs -f /dev/sdc
    # blkid | fgrep sdc

NOTE:
On a Linux Software RAID array, as opposed to a hard disk, blkid does
notice creation of the whole disk device file system.  However the
kernel still has old partition details.

This was fixed in libparted 3.1 by commit:

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=f5c909c0cd50ed52a48dae6d35907dc08b137e88
    libparted: remove has_partitions check to allow loopback partitions

Fix by deleting old partitions before creating the loop table when
compiled with a broken version of libparted.  The GParted UI provides
no feedback while a new partition table is created, and with some
versions of GTK the UI become unresponsive too, so it is important to be
as fast as possible.  Evaluated three different methods, deleting 15 and
22 MSDOS partitions on a physical 5400 RPM hard drive using libparted
2.4:

M1) Delete and commit one partition at a time.
    Takes up to 24 seconds to delete 15 partitions.  With 22 partitions
    libparted always reports finding some of the partitions busy and
    unable to inform the kernel about the modifications.
    Too slow and doesn't work.

M2) Delete all partitions in one go and commit once.
    Takes up to 1.4 seconds to delete either 15 or 22 partitions.  Never
    removes partitions 17 and higher from the kernel.
    Doesn't work.

M3) Write GPT table (letting libparted delete any old partitions).
    Takes up to 0.8 seconds to delete either 15 or 22 partitions.
    Fast and works.

Use method 3 - write a GPT table thus using libparted code to inform the
kernel of the old partition deletions.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood e7ed209020 Erase file system signatures before creating a partition table (#743181)
When writing "loop" partition table over the top of some whole disk
device file system types GParted continued to show those whole disk
device file systems rather than the virtual unknown partition from the
"loop" partition table.

This affected btrfs, jfs, reiser4 and reiserfs.  It occurred because of
several factors:
1) Libparted only zeroed the first and last 9.5 KiB (assuming 512 byte
   sectors) of the device before writing a new partition table.  See
   ped_disk_clobber().
2) These file systems have their super blocks and therefore signatures
   after the first 9.5 KiB.
3) Whole disk device file system detection is performed using blkid
   before checking for a libparted "loop" partition table.  See
   GParted_Core::set_devices_thread().

Ref:
libparted 3.2: disk.c:ped_disk_clobber()
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/disk.c?id=v3.2#n302

Fix by always erasing any possible file system signatures on the device
before creating a new "loop" partition table.

NOTE:
This is typically taking up to 0.5 seconds in my testing on a 5400 RPM
hard drive, during which time the GParted UI is hung and the create
partition table dialog shows the apply button pressed but no other
progress indication.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood 51ac4d5648 Split get_device_and_disk() into two (#743181)
get_device_and_disk() basically calls libparted to get a PedDevice
object representing a disk device and a PedDisk object representing a
partition table.  Re-implement get_device_and_disk() using two separate
functions, get_device() and get_disk(), to get one of these objects
each.

No functionality changes with this commit.  It enables future commits to
incrementally add support for whole disk devices into GParted without
needing libparted to recognise the contents and create a virtual "loop"
partition table.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood cbf8bd741d Display whole disk file systems via partition table "none" (#741430)
For file systems which libparted recognises, when found on the whole
disk device, it reports with partition table "loop" and a partition
covering the whole disk.  GParted duly displays this to the user.

For file systems which libparted doesn't recognise it reports
"unrecognised disk label".  As of the latest libparted 3.2, these file
system aren't recognised and can't currently be shown when on the whole
disk device:

    BitLocker, Crypt LUKS, exFAT, F2FS, LVM2 Physical Volume,
    Linux Software RAID, ReFS, Reiser 4

So only when libparted doesn't recognise a file system on the whole disk
device and GParted does, either via blkid or it's internal code, display
this with partition table "none".

Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
             drive
2015-03-09 10:17:22 -06:00
Mike Fleetwood ed827cf59a Create helper function set_partition_label_and_uuid() (#741430)
Move code which queries the file system label and UUID of a partition
into a separate helper function.

Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
             drive
2015-03-09 10:17:22 -06:00
Mike Fleetwood cb645b16cf Refactor GParted internal file system signature detection (#741430)
Refactor GParted internal file system signature detection to remove code
duplication.  There were 5 separate copies of code to: allocate a
buffer, open, read and close the device, free the buffer and compare the
signature.

Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
             drive
2015-03-09 10:17:22 -06:00
Michael Zimmermann 1f5841b4ad Add support for GPT partition names (#741424)
Embedded devices (Android) use GPT partition names to identify
partitions, instead of file system labels.  Add support for viewing and
changing them.

As partition names are used to provide unique identification they are
never copied when copying the contents of one partition to another.

Note that GNU/Linux uses file system labels, UUIDs or device names for
identification during the boot process and afterwards so while partition
names can be used, they are optional and purely for user information.

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 3630b9c83b Rename methods in GParted_Core and Win_GParted classes (#741424)
class GParted_Core:
    label_partition() -> label_filesystem()

class Win_GParted:
    allow_label_partition()    -> allow_label_filesystem()
    activate_label_partition() -> activate_label_filesystem()

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 8b4b73a8f3 Add supported_filesystem() predicate method (#738471)
Helper to check whether a recognised file system type is supported by
GParted or not.  Supported means there is an implementation class and
will appear in the File System Support dialog.

Make supported_filesystem() a static member function so that it can be
called without a class object so that GParted_Core::GParted_Core()
initialiser isn't called multiple times.  This requires FILESYSTEM_MAP
to become a static member variable too.

Bug #738471 - ReFS file system is not recognised
2014-10-30 09:55:01 -06:00
Mike Fleetwood e3a1b93a6d Pass by value to get_filesystem_object()
get_filesystem_object() takes a constant reference to a FILESYSTEM, but
FILESYSTEM is just an enumeration.  So that's a pointer to a constant
int.  Just pass by value instead.
2014-10-30 09:55:01 -06:00
Mike Fleetwood c1db9811e1 Use Autoconf check specifically for libparted-fs-resize (#734718)
Remove HAVE_LIBPARTED_3_1_0_PLUS definition and replace Autoconf
    check for libparted >= 3.1

Currently uses custom check which compiles an executable to check for
libparted version >= 3.1 to determine the availability of the library
parted-fs-resize and the need to include the header <parted/filesys.h>.

Change to use a direct Autoconf check to determine the availability of
the ped_file_system_resize() function in the parted-fs-resize library.
Remove inclusion of the header <parted/filesys.h> as it has always been
included via <parted/parted.h>, at least as far back as parted 1.8.0,
and even in parted 3.0 when ped_file_system_resize() and libparted file
system resize capability didn't exist.

Bug #734718 - Update Autoconf version specific libparted checks and
              defines to feature specific ones
2014-08-18 15:48:34 -06:00
Mike Fleetwood 3bea067596 Flush devices when scanning to prevent reading stale signatures (#723842)
While one partition is busy, reformat another partition from the command
line.  Afterwards parted/libparted still detects the original file
system and GParted shows errors from the file system specific tools
reporting the new file system doesn't exist.  Only limitation is that
the new new file system must be recognised by libparted (or by GParted's
fallback file system signature detection).

Case #1, File system reformatting:

    # parted /dev/sdb print
    Model: ATA SAMSUNG SSD UM41 (scsi)
    Disk /dev/sdb: 8012MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type     File system  Flags
     1      1049kB  2149MB  2147MB  primary  ext2
     2      2149MB  4296MB  2147MB  primary  ext2
    # mount | fgrep sdb
    /dev/sdb1 on /mnt/1 type ext2 (rw)

    # mkfs.xfs -f /dev/sdb2
    # blkid /dev/sdb2
    /dev/sdb2: UUID="c31823a2-b81b-46fa-8246-0a59695e4834" TYPE="xfs"
    # parted /dev/sdb print
    Model: ATA SAMSUNG SSD UM41 (scsi)
    Disk /dev/sdb: 8012MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type     File system  Flags
     1      1049kB  2149MB  2147MB  primary  ext2
     2      2149MB  4296MB  2147MB  primary  ext2
    # e2label /dev/sdb2
    e2label: Bad magic number in super-block while trying to open /dev/sdb2
    Couldn't find valid filesystem superblock.
    # dumpe2fs /dev/sdb2
    dumpe2fs 1.41.12 (17-May-2010)
    dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb2
    Couldn't find valid filesystem superblock.

Case #2, Removing device from multi-device btrfs:

    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: a05db434-efd5-4e8c-902f-05f89a88b610
            Total devices 2 FS bytes used 156.00KB
            devid    2 size 2.00GB used 512.00MB path /dev/sdb2
            devid    1 size 2.00GB used 240.75MB path /dev/sdb1

    # mount /dev/sdb1 /mnt/1
    # btrfs device delete /dev/sdb2
    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: a05db434-efd5-4e8c-902f-05f89a88b610
            Total devices 1 FS bytes used 92.00KB
            devid    1 size 2.00GB used 714.25MB path /dev/sdb1
    # btrfs filesystem show /dev/sdb2

and GParted reports this error for partition /dev/sdb2:
    Unable to read the contents of this file system!
    Because of this some operations may be unavailable.
    The cause might be a missing software package.
    The following list of software packages is required for btrfs
    file system support:  btrfs-tools.

This is another case of libparted reading from the whole disk device
(/dev/sdb) yet the file system tools use the partition specific block
device (/dev/sdb2), and the Linux buffer cache not providing cache
coherency.  Previous scenario was fixed with:

    797f0b8eeb
    Flush device after wiping a file system (#688882)

This affects libparted 2.0 to 3.1 inclusive and is fixed by:

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
    Revert "linux-commit: do not unnecessarily open partition device nodes"

Fix by calling ped_device_sync() to guarantee cache coherency for each
device during scanning.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 4b63e46a4e Fallback to reading mount command output instead of /etc/mtab (#723842)
With linux 3.5 and later, the device used to mount a btrfs file system
is updated in /proc/mounts when the previous mounting device is removed
from the file system.  Most recent distributions make /etc/mtab a
symbolic link to /proc/mounts.  However some still have /etc/mtab as a
plain file only updated by mount and umount, thus showing the old device
name which is no longer part of the file system.

On Ubuntu 13.10, which has /etc/mtab as a plain file managed by mount
and umount:

    # mkfs.btrfs /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # btrfs device add /dev/sdb2 /mnt/1
    # btrfs device delete /dev/sdb1 /mnt/1
    # sync
    # btrfs filesystem show /dev/sdb1
    # btrfs filesystem show /dev/sdb2
    Label: none  uuid: e47775a6-e5ad-4fb4-9ea4-1570aa5b4009
            Total devices 2 FS bytes used 28.00KB
            devid    2 size 2.00GB used 272.00MB path /dev/sdb2

    # fgrep btrfs /proc/mounts
    /dev/sdb2 /mnt/1 btrfs rw,relatime,space_cache 0 0
    # ls -l /etc/mtab
    -rw-r--r-- 1 root root 842 Apr 15 19:41 /etc/mtab
    # fgrep btrfs /etc/mtab
    /dev/sdb1 /mnt/1 btrfs rw 0 0

This causes GParted to report /dev/sdb1 as busy and mounted at /mnt/1
when it is no longer mounted.  This effects recent releases of Ubuntu,
13.04, 13.10 and 14.04.

Either /etc/mtab is a symlink and is identical to /proc/mounts or
/etc/mtab is a plain file with wrong information.  Fix by not reading
mounted file systems from /etc/mtab.

However old distributions only contain 'rootfs' and '/dev/root' device
names for the / (root) file system with '/dev/root' being a block device
rather than a symlink to the true device.  For example from CentOS 5.x:

    # fgrep ' / ' /proc/mounts
    rootfs / rootfs rw 0 0
    /dev/root / ext3 rw,data=ordered 0 0
    # ls -l /dev/root
    brw------- 1 root root 8, 3 Jun  4  2013 /dev/root

This prevents identification, and therefore busy detection, of the
device containing the / (root) file system.  Used to read /etc/mtab to
get the root file system device name.

    # fgrep ' / ' /etc/mtab
    /dev/sda3 / ext3 rw 0 0
    # ls -l /dev/sda3
    brw-r----- 1 root disk 8, 3 Jun  4  2013 /dev/sda3

As per commit:

    409096f739
    improved scanning for root mountpoint (/) ...

but, as discussed above, this contains an out of date device name after
the mounting device has been dynamically removed from a multi-device
btrfs, thus identifying the wrong device as busy.  Instead fall back to
reading mounted file systems from the output of the mount command, but
only when required.

    # mount | fgrep ' / '
    /dev/sda3 on / type ext3 (rw)

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood a086e115e5 Display mount points for multi-device btrfs file systems (#723842)
Linux can only show a single device name in /proc/mounts and /etc/mtab
for each mounted btrfs, even if it is a multi-device file system.  So
GParted only shows a mount point for one of the devices in the btrfs, no
matter how many devices are part of the file system.

    # mkfs.btrfs /dev/sdb1 /dev/sdb2
    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
            Total devices 2 FS bytes used 156.00KB
            devid    2 size 2.00GB used 512.00MB path /dev/sdb2
            devid    1 size 2.00GB used 240.75MB path /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # grep btrfs /proc/mounts
    /dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0

GParted only shows the mount point for /dev/sdb1 as /mnt/1, but nothing
for /dev/sdb2.

Make GParted report the same mount point for all devices included in a
multi-device btrfs file system.

Add btrfs specific get_mount_device() method to report the mounting
device, if any, for the btrfs file system in the occupying the device in
question.  Uses the existing cache of btrfs file system device
membership.  Also extract common code from GParted_Core::
set_mountpoints() into set_mountpoints_helper().

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood a0c0533e3e Add is_dev_mounted() to expose core partition is mounted test (#723842)
Add static member function GParted_Core::is_dev_mounted() so that other
modules can determine if a particular partition contains a mounted file
system or not.

Make it a static member function so that it can be called without
needing the gparted_core object.  Extend to make the group of
manipulated variables (mount_info, fstab_info) and manipulating
functions (init_maps(), read_mountpoints_from_file(),
read_mountpoints_from_file_swaps(), get_all_mountpoints()) static too.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood b1dc9e69e3 Make partition busy detection method selectable per file system (#723842)
GParted's primary inbuilt busy detection method is "is the partition
mounted?".  A custom method is used for LVM2 PV because its not a
mounted file system.

Make busy detection selectable per file system type.

    .fs.busy = FS::NONE  (default)
        No busy detection.

    .fs.busy = FS::GPARTED
        Use internal GParted method which checks if the partition is
        mounted.

    .fs.busy = FS:EXTERNAL
        Call the file system type's member function is_busy().

LVM2 PV busy detection changes from a special case to just electing to
call the lvm2_pv::is_busy() method.  Linux Software RAID remains a
special case because it's only recognised, but not otherwise supported.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 5f6656f267 Initialise file system objects only once
The code used to unnecessarily destroy and re-create the file system
objects on every scan for file system support tools.

Instead only create the file system objects once and just call each
object's get_filesystem_support() method on each rescan.
2014-04-23 10:25:56 -06:00
Mike Fleetwood 131098a797 Remove set_proper_filesystem() method
Prior to commit:

    1f3b11748e
    Remove GParted_Core::p_filesystem (#683149)

set_proper_filesystems() used to set GParted_Core::p_filesystem member
variable to one of the FileSystem objects, but that was just treating it
like a local variable.  After the commit local variables named
p_filesystem were used where required and set_proper_filesystem() became
a function which did nothing other than call get_filesystem_object().

Now remove set_proper_filesystem() altogether and use
get_filesystem_object() in its place.
2014-04-23 10:25:27 -06:00
Mike Fleetwood 67115eeff2 Remove unused member variable GParted_Core::buf 2014-04-23 09:54:20 -06:00