Commit Graph

618 Commits

Author SHA1 Message Date
Mike Fleetwood 68cdfe99d9 Print new info before "Root privileges are required ..." dialog (!34)
So that the new version and configuration information is displayed even
if the gpartedbin executable is run as a non-root user.  To help with
diagnosing root authorisation issues with the gparted shell wrapper
script.

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

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

Closes !34 - Display more version and configuration information
2019-04-03 20:45:31 +00:00
Mike Fleetwood a476b8cc2c Rename local variable to meaningful benchmark_copysize 2019-04-01 09:12:10 -06:00
Mike Fleetwood e55b3c8544 Replace String::ucompose() with Glibmm equivalent (#46)
Glibmm has implemented a ustring::compose() set of methods [1] since
Glibmm 2.16, circa 2008.  So replace String::ucompose().  Note that
GParted already requires glibmm >= 2.32 as set in configure.ac.

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

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

Closes #46 - Drop compose subdir
2019-03-27 16:45:22 +00:00
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
Mike Fleetwood 8df975c7d1 Increase minimum required libparted to 2.2 (!22)
Raise the minimum required version of GNU Parted from 1.7.1 to 2.2,
released 2010-02-16 [1][2].  The oldest supported distributions, also
with gtkmm >= 2.24, since commit [3], are:
    Debian 8           parted 3.2
    RHEL / CentOS 7    parted 3.1
    SLES 12            parted 3.1
    Ubuntu 14.04 LTS   parted 2.3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

S
2018-11-19 16:43:29 +00:00
Mike Fleetwood dfb7d3e581 Enhance comment about the 3 levels of file system support
Add a little extra explaining how the file systems' supported actions
are determined.
2018-11-12 13:53:10 -07:00
Mike Fleetwood 69c1537a38 Recognise APFS (Apple File System) (#23)
Just add detection of APFS using GParted's internal magic string
detection.  It just matches 1 byte of the 2 byte object type and the
4 byte magic field found in the super block [1].  See code comment for
more details.

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

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

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

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

Closes #23 - GParted doesn't detect APFS (Apple File System)
2018-11-12 20:39:55 +00:00
Mike Fleetwood c82883d6a7 Add and set read-only mount flag in the Partition object (#10)
Set the partition read-only mount flag at the same time as setting the
file system mount points.

Closes #10 - Gparted fails to resize btrfs partition that is mounted
             read-only
2018-09-20 16:30:15 +00:00
Mike Fleetwood 9c35d91453 Refactor get_filesystem_object()
The function was using std::map::count() [1] to test if the file system
entry existed in the map before looking up the value using
std::map::operator[] to avoid having operator[] inserting elements which
don't exist [2].

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

THIS PATCH:

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

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

Closes !13 - Support copying and moving of unsupported partition content
2018-09-17 15:36:09 +00:00
Mike Fleetwood 03e89b1289 Add support for minix file system (!12)
Util-linux package, at least as far back as version 2.23.2 as found on
CentOS 7, provides the mkfs.minix and fsck.minix commands.  Also blkid
from the same package, recognises minix file systems.

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

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

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

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

Closes !12 - Add minix file system support
2018-08-24 20:22:08 +01:00
Mike Fleetwood 03d47d4d02 Recognise additional GRUB2 core.img signatures (!5)
Bootinfoscript v0.77 (2018-06-10) added additional signatures to
recognise GRUB2 core.img by.  Commit:

    9a00c1a887
    Add more core.img diskboot signatures

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

Add those signatures into GParted.

Closes !5 - Recognise additional GRUB2 core.img signatures
2018-07-19 19:26:29 +00:00
Mike Fleetwood aff99307d9 Recognise blkid identified BitLocker encrypted partitions (#795127)
Future util-linux release after v2.32 will include this commit for blkid
to recognise BitLocker encrypted partitions.  It is much better than
GParted's inbuilt detection.

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

Make GParted also recognise BitLocker encrypted partitions reported by
blkid.

Bug #795127 - Displayed Name is incorrect for bitlocker encrypted
              partitions
2018-06-18 10:15:33 -06:00
Mike Fleetwood 175d27c55d Rename enum FILESYSTEM to FSType
There are too many different types of things named "filesystem" in the
GParted code with the potential to cause confusion.  Namely:

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

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

    enum FILESYSTEM           Symbolic constants representing each file
                              system type.

Many recent written or re-written functions already used a variable
named fstype.  Rename enum FILESYSTEM to enum FSType to clearly
distinguish it from the other things with very similar names.  Only
changing the name of the enumeration, not the name of variables of that
type too because that is a lot more lines of code and those can be
changed when the relevant code is re-written.
2018-01-28 10:09:35 -07:00
Mike Fleetwood 46bf5a383e Extract common code into GParted_Core::get_filesystem_limits() (#787204)
There are multiple repetitions of the same code getting a FileSystem
object, checking for NULL and then calling the file system specific
get_filesystem_limits().  Extract that into a common function.

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

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

Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood 8729556778 Use struct FS_Limits in GParted_Core::create() (#787204)
Bug 787204 - Minimum and maximum size of the UDF partition/disk
2018-01-28 10:09:35 -07:00
Mike Fleetwood b04dbbc357 Rename function and reword text for rollback of failed file system move
To better reflect specifically that it is a failed (internally
implemented) file system move which is being rolled back.
2018-01-02 10:34:52 -07:00
Mike Fleetwood f54dd10707 Fix rollback when growing a partition by more than twice fails (#791875)
Attempt to grow a partition to more than twice it's size.  If committing
that change to the partition fails in such a way that the new larger
partition boundaries are not written to the disk drive then rolling back
will fail with libparted error:
    Can't have overlapping partitions.

Example operation details:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # kill %2
    [2]   Done             udevadm monitor

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

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

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

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

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

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

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

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

[3] partprobe: Open the device once for probing

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

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

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

Bug 790418 - "Unable to inform the kernel of the change" message may
             lead to corrupted partition table
2017-11-29 11:37:26 -07:00
Mike Fleetwood 8c5c13d613 Rename OperationDetailStatus STATUS_N_A to STATUS_WARNING
Make the enumeration name match it's use as indicating a warning.  Also
spell SUCCESS correctly.  Follow on to icon variable names too.
2017-11-26 10:53:52 -07:00
Mike Fleetwood 0688662055 Identify libparted messages as either success or error (#790842)
All libparted messages were reported as informational, even for a step
which failed.  Instead identify libparted messages as either
informational or errors depending on whether this step was successful
or not respectively.

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

Bug 790842 - Report libparted messages into operation details at the
             point at which they occur
2017-11-26 10:53:18 -07:00
Mike Fleetwood 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 12dcebcb47 Calibrate whole disk device partitions again (#788308)
Fix up following switch from whole_device flag to TYPE_UNPARTITIONED.

Also calibrate the type for whole disk device partitions.

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

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

Before this change, get_fs() would fail to find file system capabilities
set for FS_EXTENDED and construct a not supported capabilities set and
return that.

Afterwards, find_supported_filesystems() creates a not supported
capabilities set from the NULL pointer for FS_EXTENDED and adds this
entry into the FILESYSTEMS vector.  Then get_fs() finds that not
supported capabilities set for FS_EXTENDED in the FILESYSTEMS vector and
returns that.

This makes no functional difference.  It just seems right as other
unsupported but used file system types have entries in FILESYSTEM_MAP.

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

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

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

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

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

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

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

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

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

THIS PATCH:

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

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

Bug 788308 - Remove whole_device partition flag
2017-10-03 08:22:06 -06:00
Pali Rohár 8fdc2c21a6 Correctly quote and escape arguments passed to external commands (#787203)
Trying to set a file system label to (including the double quotes):
    " --help "
fails.  For example labelling an ext4 file system would try to run this
command:
    # e2label /dev/sdb1 "" --help ""
    Usage: e2label device [newlabel]
    # echo $?
    1

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

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

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

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

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

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

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

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

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

History

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

Bug 787181 - Fix detection of file system images
2017-09-12 19:10:20 +01:00