Commit Graph

160 Commits

Author SHA1 Message Date
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
Daniel Mustieles 3861b9257b Replace obsolete FSF postal address in copyright notices (#721565)
This is part of parent bug:
    Bug #721455 - Obsolete info in license text on multiple modules

and GNOME Goal:
    https://wiki.gnome.org/Initiatives/GnomeGoals/Proposals

    * verify all source files to make sure they have a license and a
      copyright, and that both are up-to-date

Bug #721565 -  License text contains obsolete FSF postal address
2014-01-26 10:53:23 +00:00
Mike Fleetwood 7b43d52720 Display partition table types in order (#711098)
In the Create Partition Table dialog display the entries in the combobox
in order.

Previously the default of MSDOS or GPT was moved to the first item in
the combobox.  Now the partition table types remain in order with just
either MSDOS or GPT being selected as as the default as required.

The partition table types are displayed in the order supplied by
libparted, which is alphabetic except with "loop" last.

Bug #711098 - Default partition table can not handle > 2 TiB disks
2014-01-06 10:45:00 +00:00
Phillip Susi 07bd72ba80 Default to GPT on disks >= 2 TiB (#711098)
MSDOS partition table is limited to addressing 2^32 sectors, limiting
disks using 512 byte sectors to 2 TiB in size.  Fdisk reports the
following warning on disks 2 TiB and larger.

    # truncate -s 2T /var/tmp/loop-2T
    # losetup /dev/loop0 /var/tmp/loop-2T
    # fdisk /dev/loop0

    WARNING: The size of this disk is 2.2 TB (2199023255552 bytes).
    DOS partition table format can not be used on drives for volumes
    larger than (2199023255040 bytes) for 512-byte sectors. Use parted(1) and GUID
    partition table format (GPT).

(Fdisk arguably reports this warning one sector too early.  Anyway for
safety and consistency GParted will use this limit too).  Continue to
use MSDOS as the default partition table type for disks smaller than 2
TiB and use GPT as the default for disks 2 TiB and larger.  This
maximises compatibility.

Also remove the advanced expander and always show the partition table
list box.

Bug #711098 - Default partition table can not handle > 2 TiB disks
2014-01-06 10:44:59 +00:00
Mike Fleetwood aed1fb58cf Remove unused read-only functionality from internal block copy
The read-only functionality is unused and the readonly parameter is
always false in copy_filesystem() and copy_blocks() methods.  This has
been the case since the copy simulation was dropped by commit:

    b9b4b2e55d
    Remove simulation pass ( read test ) on move
2013-06-05 10:57:39 -06:00
Mike Fleetwood 2b51d87147 Make include guards unique (#539297)
Include guards need to be unique within GParted code and all included
library header files.
    http://en.wikipedia.org/wiki/Include_guard#Difficulties

Use this model for all include guards:
    #ifndef GPARTED_FILE_NAME_H
    #define GPARTED_FILE_NAME_H
    ...
    #endif /* GPARTED_FILE_NAME_H */

Closes Bug #539297 - Make include guards unique
2013-06-05 10:57:39 -06:00
Mike Fleetwood 6c33a8f5ca Remove unused function copy_filesystem_simulation()
The function is no longer used after commit:

    b9b4b2e55d
    Remove simulation pass ( read test ) on move
2013-03-25 10:06:40 -06:00
Mike Fleetwood e218ba3358 Refactor and rename GParted_Core::open/close_device_and_disk()
These functions in GParted_Core:
    open_device()
    open_device_and_disk()
    close_disk()
    close_device_and_disk()
call the following functions in the libparted API:
    ped_device_get()
    ped_disk_new()
    ped_disk_destroy()
    ped_device_destroy()
which don't open or close anything.  Instead they allocate and
deallocate PedDevice and PedDisk memory structures which describe block
devices and partition tables respectively.

Rename functions:
    open_device_and_disk()  -> get_device_and_disk()
    close_device_and_disk() -> destroy_device_and_disk()
and merge open_device() and open_device() as each only wrapped one
libparted function and was only called from a single place.
2013-03-25 10:06:39 -06:00
Mike Fleetwood 2b7e469473 Remove use of wipefs to clear file system signatures (#688882)
The wipefs command has the following significant limitations which were
worked around in previous commits:

1)  Wasn't available in the earliest distributions supported by GParted;

2)  Had to be called 3 times to erase vfat (fat16/32) signatures in all
    but the most recent versions.

This meant we had all the code to clear file system signatures without
using the wipefs command as well as extra complexity of using wipefs
too.  So just remove use of the wipefs command.

Bug #688882 - Improve clearing of file system signatures
2013-03-25 10:06:39 -06:00
Mike Fleetwood 6982f68e21 Workaround not so old wipefs only erasing 1 of 3 vfat signatures (#688882)
Before util-linux 2.21.0, released Feb 2012, wipefs only cleared one of
the three vfat (fat16/fat32) signatures it can be detected by each time
wipefs was run.  Also if a nilfs2 file system was created before all
three signatures were cleared the partition was still recognised as a
vfat file system, albeit a corrupted one, rather than as a nilfs2 file
system.

Old wipefs clearing vfat signatures:
    # wipefs --version
    wipefs from util-linux 2.20.1
    # wipefs -a /dev/sda7
    8 bytes were erased at offset 0x52 (vfat)
    they were: 46 41 54 33 32 20 20 20
    # wipefs -a /dev/sda7
    1 bytes were erased at offset 0x0 (vfat)
    they were: eb
    # wipefs -a /dev/sda7
    2 bytes were erased at offset 0x1fe (vfat)
    they were: 55 aa

New wipefs clearing vfat signatures:
    # wipefs --version
    wipefs from util-linux 2.21.2
    # wipefs -a /dev/sda12
    8 bytes were erased at offset 0x00000052 (vfat): 46 41 54 33 32 20 20 20
    1 bytes were erased at offset 0x00000000 (vfat): eb
    2 bytes were erased at offset 0x000001fe (vfat): 55 aa

Workaround by calling "wipefs -a" three times if the output indicated
only one vfat signature was cleared.

Bug #688882 - Improve clearing of file system signatures
2013-03-25 10:06:39 -06:00
Mike Fleetwood 3c75f3f5b1 Use wipefs to clear old signatures before creating new file systems (#688882)
Previously the function erase_filesystem_signatures() was used to clear
file system signatures when a new partition was created and when an
existing partition was formatted with a file system.  However this was
only available with libparted <= 2.4 and then only for the file systems
which libparted supports.

Having multiple different file system signatures on a partition leads to
misidentification of file system.  For example creating a nilfs2 over
the top of a fat32 file system is detected as a fat32, not nilfs2.  This
shows that old file system signatures must be cleared before a new file
system is created.

Fix by always using "wipefs -a /dev/PARTITION" command to clear all old
file system signatures rather than libparted API calls.  Failure from
wipefs is only considered a warning so doesn't fail the file system
creation.  (This doesn't yet fully meet the "MUST be cleared"
requirement above.  Will be fully met later in this patchset).  Output
from the wipefs command is displayed as a new sub-step which looks like
this:

    v Format /dev/sda7 as xfs                            00:00:05
      > calibrate /dev/sda14                             00:00:01
      v clear old file system signatures in /dev/sda7    00:00:01  [NEW]
        > wipefs -a /dev/sda7                                      [NEW]
      > set partition type on /dev/sda7                  00:00:02
      v create new xfs file system                       00:00:01
        > mkfs.xfs -f -L "" /dev/sda7

Also signatures are only cleared immediately before a new file system is
written and not when an unformatted partition is created.  This allows
recovery from accidental partition deletion by re-creating the deleted
partition as unformatted.

Bug #688882 - Improve clearing of file system signatures
2013-03-25 10:06:39 -06:00
Phillip Susi 89de9a5026 Add proper cancel support (#601239)
Interested operations can now connect a signal to their OperationDetail
to be notified of a cancelation request.  The internal copy/move code
will now cleanly stop on cancelation, allowing the partition to be
rolled back to its previous state.  This makes canceling a move
perfectly safe.

After clicking cancel, the button changes to "Force Cancel" and is
disabled for 5 seconds.  Operations that are safe to cancel will do so
and those that are not will continue to run.  Clicking force cancel
asks operations to cancel, even if doing so is unsafe.  For the
internal copy/move algorithm, canceling is always safe because an
error results in a rollback operation.  Canceling the rollback is
unsafe.  For external commands, filesystem modules may indicate
that the command is safe to cancel or not.  Canceled commands will
be terminated with SIGINT.

As a result of the new safe cancel vs force cancel distinction, the
scary warning about cancl causing corruption has been moved to
after clicking the force cancel button.

Part of Bug #601239 - Please allow 'Cancel after current operation'
2013-03-11 18:40:31 -06:00
Phillip Susi bd9e16f22f Thread the internal copy algorithm (#685740)
Have the copy code create a background thread to do the actual copying so
that it won't block the main loop.

Part of Bug 685740 - Refactor to use asynchronous command execution
2013-03-11 18:40:31 -06:00
Phillip Susi 52a2a9b00a Reduce threading (#685740)
Win_Gparted and Dialog_Progress were creating threads to perform most
functions in the background.  Most of the time, the only reason the
threads blocked was to execute an external command.  The external command
execution has been changed to spawn the command asynchronously and wait
for completion with a nested main loop.  While waiting for completion,
the pipe output is captured via events.  In the future, this will allow
for it to be parsed in real time to obtain progress information.

Those tasks in GParted_Core that still block now spawn a background thread
and wait for it to complete with a nested main loop to avoid hanging the
gui.

Part of Bug #685740 - Refactor to use asynchronous command execution
2013-03-11 18:40:31 -06:00
Matthias Gehre 1f3b11748e Remove GParted_Core::p_filesystem (#683149)
Bug #683149 - Cleanup(?): Remove lp_device and lp_disk from GParted_Core
2012-11-11 11:47:59 +00:00
Matthias Gehre 52af838df2 Remove GParted_Core::fs (#683149)
Bug #683149 - Cleanup(?): Remove lp_device and lp_disk from GParted_Core
2012-11-11 11:47:59 +00:00
Matthias Gehre d2ced08355 Remove GParted_Core::partition_temp (#683149)
Bug #683149 - Cleanup(?): Remove lp_device and lp_disk from GParted_Core
2012-11-11 11:47:59 +00:00
Matthias Gehre a13bed6424 Remove GParted_Core::temp (#683149)
Bug #683149 - Cleanup(?): Remove lp_device and lp_disk from GParted_Core
2012-11-11 11:47:59 +00:00