When composing a resize operation on an open encryption mapping, use the
existing LUKS password dialog to prompt for the passphrase, if and only
if 'cryptsetup resize' will prompt and GParted doesn't already have a
password. 'cryptsetup resize' will prompt for a LUKS passphrase when
the passphrase was stored in the kernel keyring service,
key_loc == KEYLOC_KeyRing. See the previous commit "Capture LUKS
mapping master encryption key location (#59)" for more details.
As commented in the code GParted specifically doesn't support the case
where the LUKS passphrase is changed while GParted is running and it
knew the old passphrase. When resizing an open encryption mapping
GParted will just pass the old out of date passphrase it knows and the
resize will fail like this:
# cryptsetup status sdb2_crypt | egrep 'type|key location'
type: LUKS2
key location: keyring
# dmsetup table --target crypt
sdb2_crypt: 0 491520 crypt aes-xts-plain64 :64:logon:cryptsetup:3d040240-97ba-4559-af98-72c3be500498-d0 0 8:18 32768
# echo -n oldpassword | cryptsetup -v --size 491520 resize sdb2_crypt
No key available with this passphrase.
Command failed with code -2 (no permission or bad passphrase).
# echo $?
2
To work around this either close and restart GParted or close and reopen
the encryption mapping. The former because GParted doesn't save
passwords across a restart so will prompt and the latter because GParted
will use the wrong old passphrase to try to open the mapping and then
prompt for the correct passphrase until successfully opened.
Closes#59 - Resize of LUKS2 encrypted file system fails with "Nothing
to read on input"
ISSUE OVERVIEW
When GParted tries to resize an open LUKS encryption mapping and the
volume (master) key was stored in the kernel keyring service [1] it
fails like this:
Check and repair file system ([Encrypted] ext4) on /dev/...(ERROR)
+ calibrate /dev/sdd1 (SUCCESS)
+ check file system on /dev/mapper/sdd1_crypt for errors...(SUCCESS)
+ grow encryption volume to fill the partition (ERROR)
+ cryptsetup -v resize 'sdd1_crypt' (ERROR)
Command failed with code -1 (wrong or missing parameters).
Nothing to read on input.
This error occurs with cryptsetup >= 2.0, kernel >= 4.10 and LUKS2
format because the crypt Device-Mapper target no longer has the volume
key so cryptsetup resize prompts for a passphrase, but GParted doesn't
provide it.
THIS COMMIT
Additionally capture the location of the volume (master) key location
for active encryption mappings. Do this the using the same method that
cryptsetup uses [2][3]. Namely if the first character of the KEY is a
":" then the key *was* stored in the kernel keyring service, otherwise
it *is* store in the Device-Mapper crypt target as previously.
# echo -n badpassword | cryptsetup luksFormat --type luks1 /dev/sdb1 -
# echo -n badpassword | cryptsetup luksOpen /dev/sdb1 sdb1_crypt
# cryptsetup status sdb1_crypt | egrep 'type|key location'
type: LUKS1
key location: dm-crypt
# echo -n badpassword | cryptsetup luksFormat --type luks2 /dev/sdb2 -
# echo -n badpassword | cryptsetup luksOpen /dev/sdb2 sdb2_crypt
# cryptsetup status sdb2_crypt | egrep 'type|key location'
type: LUKS2
key location: keyring
# dmsetup table --target crypt
sdb1_crypt: 0 520192 crypt aes-xts-plain64 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0 8:17 4096
sdb2_crypt: 0 491520 crypt aes-xts-plain64 :64:logon:cryptsetup:3d040240-97ba-4559-af98-72c3be500498-d0 0 8:18 32768
^
First character of the KEY field --------------'
[1] Integration with the kernel keyring service
https://gitlab.com/cryptsetup/cryptsetup/blob/v2.0.0/docs/Keyring.txt
"
Starting with cryptsetup 2.0 we load [Volume Key] VK in kernel
keyring by default for LUKSv2 devices ...
In summary, the key description visible in dm-crypt table line is a
reference to VK that usually no longer exists in kernel keyring
service if you used cryptsetup to for device activation.
"
[2] cryptsetup/v2.3.5/lib/libdevmapper.c:_dm_target_query_crypt()
https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/lib/libdevmapper.c#L2031
if (key_[0] == ':')
*act_flags |= CRYPT_ACTIVATE_KEYRING_KEY;
[3] cryptsetup/v2.3.5/src/cryptsetup.c:action_status()
https://gitlab.com/cryptsetup/cryptsetup/-/blob/v2.3.5/src/cryptsetup.c#L839
log_std(" key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt");
Closes#59 - Resize of LUKS2 encrypted file system fails with "Nothing
to read on input"
get_disk() is the wrapper around libparted's ped_disk_new() which reads
a disk label from the specified device and if successful creates the in
memory PedDisk object to represent it. In the case that libparted
doesn't recognise a disk label or a file system, having get_disk() go
and destroy the passed in PedDevice object via parameter lp_device is
very unexpected behaviour hence describing it as a coding landmine.
BACKGROUND
1. Early on GParted only worked with devices with valid disk labels.
FileSystem.h:open_device_and_disk() required both ped_device_get()
and ped_disk_new() to succeed or neither to succeed.
2. Commit [1] added support for devices which didn't yet have a disk
label. open_device_and_disk() had default parameter strict=true
added. While scanning strict=false was passed which allowed
open_device_and_disk() to return success if only ped_device_get()
succeeded and ped_disk_new() failed when the disk was empty. All
other times open_device_and_disk() was called with default
strict=true, still requiring both or neither to succeed.
3. Commit [2] added support for whole disk file systems. The now named
get_device_and_disk() had it's functionality split between
get_device() and get_disk(). This result in the code landmine being
left behind: get_disk() destroying the passed device object if
default parameter strict=true and no disk label or file system was
detected.
ANALYSIS
1. Since support for whole disk file systems [2] all current calls to
get_device_and_disk() let the strict parameter default to true and
are only called on known partitions within disk labels when applying
a change to that partition. Therefore they don't care about the
behaviour of get_disk(), just that get_device_and_disk() maintains
that both ped_device_get() and ped_disk_new() succeed or neither
succeed.
2. Two direct calls to get_disk() where the strict parameter defaults to
true, from calibrate_partition() and erase_filesystem_signatures(),
only do so on known partitions within disk labels as part of applying
a change to that partition. Therefore ped_disk_new() will succeed
and so PedDevice isn't deleted when not wanted.
3. The two remaining direct calls to get_disk() where the strict
parameter is explicitly set to false, from set_device_from_disk() and
detect_filesystem_in_encryption_mapping(), are when scanning. As the
pass strict=false they don't allow the PedDevice deletion to occur if
no recognised disk label is found.
FIX
Remove the strict parameter from get_disk() and get_device_and_disk() as
it's no longer needed. Remove the code landmine by removing the side
affect of destroying the PedDevice object if a disk label isn't found.
Make sure get_device_and_disk() maintains the all or nothing behaviour.
Also don't pass lp_device by reference to a pointer to get_disk() so the
code can't change where lp_device points.
[1] 038c5c5d99
P (special thanks to mantiena-baltix for bringing this issue to my
[2] 51ac4d5648
Split get_device_and_disk() into two (#743181)
Closes#152 - GParted crashed when trying to probe an encrypted
partition containing content that libparted doesn't
recognise
As discussed in the previous commit "Don't crash probing libparted
unrecognised encrypted file system (#152)", detect_filesystem() accepted
a NULL lp_device pointer and dereferenced it leading to the crash.
Document the requirement for lp_device parameter to be non-NULL via an
assert and also correctly const the parameters.
This forces needing to const the lp_partition parameter to
get_partition_path() too. Also assert it's non-NULL requirement.
Closes#152 - GParted crashed when trying to probe an encrypted
partition containing content that libparted doesn't
recognise
To avoid making set_luks_partition() more complicated extract the file
system detection portion into a new function.
Closes 148 - Encrypted file systems are no longer recognised
Since changes for issue #131 "GParted hangs when non-named device is
hung" FS_Info cache is initialised, cleared and loaded via one call to
load_cache_for_paths(). It runs blkid for named or found disk devices
and associated found partitions from /proc/partitions, rather than
running blkid and letting it report for all block devices.
To avoid the possibility of using blkid on an encryption mapping on a
non-specified and possibly hung block device GParted can't just specify
all encryption mappings. Instead only encryption mappings which belong
to the above identified block devices should be probed. That requires
identifying LUKS encryption data in the block devices first so will
require subsequently loading additional data into the FS_Info cache and
running blkid again.
To accommodate this make the FS_Info cache incrementally loadable,
rather than doing everything in a single call to load_cache_for_paths().
Have a separate clear_cache() call which initialises and clears the
cache and make load_cache_for_paths() just run blkid and insert data for
the named paths.
Closes 148 - Encrypted file systems are no longer recognised
... in class Dialog_Partition_New and slightly refactor the code in
build_filesystems_combo() method which sets it.
Change the name from first_creatable_fs to default_fs to be more
immediately obvious what the variable represents. As default_fs is used
to index the items in the combo_filesystem derived ComboBox, make it's
type an int to match the type of the parameter passed to
Gtk::ComboBox::set_active() [1]. Initialise default_fs to -1 (no
selection) in the class constructor [2], which also allows removal of
local variable set_first just used to track whether first_creatable_fs
had been assigned yet or not.
[1] gtkmm: Gtk::ComboBox Class Reference, set_active()
https://developer.gnome.org/gtkmm/stable/classGtk_1_1ComboBox.html#a4f23cf08e85733d23f120935b235096d
[2] C++ FAQ / Should my constructors use "initialization lists" or
"assignment"?
https://isocpp.org/wiki/faq/ctors#init-lists
"Type" was rather a generic name. Use "combo_type_changed" which makes
it clear that the boolean parameter indicates whether a change to
combo_type or one of the other ComboBoxes triggered this callback.
Extract call to GLib's g_utf8_get_char_validated() and the associated
workaround to also read NUL characters into a separate function to make
PipeCapture::OnReadable() a little smaller and simpler, so easier to
understand.
Add max_len > 0 clause into get_utf8_char_validated() like this:
if (uc == UTF8_PARTIAL && max_len > 0)
so that the NUL character reading workaround is only applied when
max_len specifies the maximum number of bytes to read, rather than
when -1 specifies reading a NUL termination string. This makes
get_utf8_char_validated() a complete wrapper of
g_utf8_get_char_validated() [1], even though GParted always specifies
the maximum number of bytes to read.
No longer describe the inability to read NUL characters as a bug [2]
since the GLib author's said it wasn't [3].
[1] GLib Reference Manual, Unicode Manipulation Functions,
g_utf8_get_char_validated ()
https://developer.gnome.org/glib/stable/glib-Unicode-Manipulation.html#g-utf8-get-char-validated
[2] 8dbbb47ce2
Workaround g_utf8_get_char_validate() bug with embedded NUL bytes
(#777973)
[3] Bug 780095 - g_utf8_get_char_validated() stopping at nul byte even
for length specified buffers
https://bugzilla.gnome.org/show_bug.cgi?id=780095#18
"If g_utf8_get_char_validated() encounters a nul byte in the
middle of a string of given longer length, it returns -2,
indicating a partial gunichar. That is not the obvious
behaviour, but since g_utf8_get_char_validated() has been API
for a long time, the behaviour cannot be changed.
"
Closes#136 - 1.2.0: test suite is failing in test_PipeCapture
Also with exfatprogs 1.1.0 [1], tune.exfat and exfatlabel gained the
capability to report and set the exFAT Volume Serial Number [2][3][4].
This is what blkid and therefore GParted reports as the UUID.
Report serial number:
# tune.exfat -i /dev/sdb1
exfatprogs version : 1.1.0
volume serial : 0x772ffe5d
# echo $?
0
# blkid /dev/sdb1
/dev/sdb1: LABEL="test exfat" UUID="772F-FE5D" TYPE="exfat" PTTYPE="dos"
Set serial number:
# tune.exfat -I 0xf96ef190 /dev/sdb1
exfatprogs version : 1.1.0
New volume serial : 0xf96ef190
# echo $?
0
tune.exfat exists in earlier releases of exfatprogs so check it has the
capability by searching for "Set volume serial" in the help output
before enabling this capability.
# tune.exfat
exfatprogs version : 1.1.0
Usage: tune.exfat
-l | --print-label Print volume label
-L | --set-label=label Set volume label
-i | --print-serial Print volume serial
-L | --set-serial=value Set volume serial
-V | --version Show version
-v | --verbose Print debug
-h | --help Show help
(Note the cut and paste error reporting the set volume serial flag as
'-L' rather than actually '-S').
[1] exfatprogs-1.1.0 version released
http://github.com/exfaoprogs/exfatprogs/releases/tag/1.1.0
[2] [tools][feature request] Allow To Change Volume Serial Number ("ID")
#138https://github.com/exfatprogs/exfatprogs/issues/138
[3] exfatlabel:add get/set volume serial option
b4d9c9eeb5
[4] exFAT file system specification, 3.1.11 VolumeSerialNumber Field
https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#3111-volumeserialnumber-fieldCloses!67 - Add support for reading exFAT usage and updating the UUID
exfatprogs 1.1.0 released 2021-02-09 [1] has gained support for
reporting file system usage [2][3] so add that capability to GParted.
It works like this:
# dump.exfat /dev/sdb1 | egrep 'Volume Length\(sectors\):|Sector Size Bits:|Sector per Cluster bits:|Free Clusters:'
Volume Length(sectors): 524288
Sector Size Bits: 9
Sector per Cluster bits: 3
Free Clusters: 23585
Unfortunately dump.exfat returns a non-zero status on success so that
can't be used to check for failure:
# dump.exfat /dev/sdb1
exfatprogs version : 1.1.0
-------------- Dump Boot sector region --------------
Volume Length(sectors): 524288
...
# echo $?
192
dump.exfat only writes errors to stderr, so use this to identify failure:
# dump.exfat /dev/sdb1 1> /dev/null
# echo $?
192
# dump.exfat /dev/zero 1> /dev/null
invalid block device size(/dev/zero)
bogus sector size bits : 0
# echo $?
234
[1] exfatprogs-1.1.0 version released
http://github.com/exfaoprogs/exfatprogs/releases/tag/1.1.0
[2] [feature request] File system usage reporting
https://github.com/exfatprogs/exfatprogs/issues/139
[3] exfatprogs: add dump.exfat
7ce9b2336bCloses!67 - Add support for reading exFAT usage and updating the UUID
This method is now only called from one location in the code so put it's
two lines of code there.
Closes#131 - GParted hangs when non-named device is hung
Now we always want to run blkid naming all paths, ensure the FS_Info
cache is explicitly loaded first. Report an error if not done so and
remove the cache loading code from running blkid without naming all
paths. Fewer code paths to consider and reason about.
Closes#131 - GParted hangs when non-named device is hung
Again on Fedora 31 with a slightly different disk layout to the previous
commit. sdb is partitioned with 1 empty partition and sdc remains
completely empty:
# lsblk -o name,maj:min,rm,size,ro,type,fstype,label,mountpoint
NAME MAJ:MIN RM SIZE RO TYPE FSTYPE LABEL MOUNTPOINT
sda 8:0 0 20G 0 disk
|-sda1 8:1 0 1G 0 part ext4 /boot
\-sda2 8:2 0 19G 0 part LVM2_member
|-fedora-root 253:0 0 17G 0 lvm ext4 /
\-fedora-swap 253:1 0 2G 0 lvm swap [SWAP]
sdb 8:16 0 8G 0 disk
\-sdb1 8:17 0 1G 0 part
sdc 8:32 0 8G 0 disk
sr0 11:0 1 1024M 0 rom
# blkid -v
blkid from util-linux 2.34 (libblkid 2.34.0, 14-Jun-2019)
# blkid /dev/sda /dev/sda1 /dev/sda2 /dev/sdb /dev/sdb1 /dev/sdc
/dev/sda: PTUUID="5012fb1f" PTTYPE="dos"
/dev/sda1: UUID="3cd48816-7817-4636-9fec-5f1afe76c1b2" TYPE="ext4" PARTUUID="5012fb1f-01"
/dev/sda2: UUID="PH94ej-C8xU-bnMJ-UIh8-ZimI-4B7f-dHlZxh" TYPE="LVM2_member" PARTUUID="5012fb1f-02"
/dev/sdb: PTUUID="1d120b57" PTTYPE="dos"
/dev/sdb1: PARTUUID="1d120b57-01"
Stracing GParted shows these executions of blkid:
# strace -f -q -bexecve -eexecve ./gpartedbin 2>&1 1> /dev/null | egrep -v 'ENOENT|SIGCHLD'
...
[pid 160040] execve("/usr/sbin/blkid", ["blkid", "/dev/sda", "/dev/sda1", "/dev/sda2", "/dev/sdb", "/dev/sdb1", "/dev/sdc"], 0xa4e1b0 /* 32 vars */ <detached ...>
[pid 160041] execve("/usr/sbin/blkid", ["blkid", "/dev/sdc"], 0xa4e1b0 /* 32 vars */ <detached ...>
...
On Fedora 31 with blkid from util-linux 2.34 it reports information for
sdb (partitioned drive) and sdb1 (empty partition) with only no
information for sdc (empty whole disk drive). Hence no FS_Info cache
entry and re-execution of blkid just for sdc.
On older CentOS 7 with the same disk layout blkid reports this:
# blkid -v
blkid from util-linux 2.23.2 (libblkid 2.23.0, 25-Apr-2013)
# blkid /dev/sda /dev/sda1 /dev/sda2 /dev/sdb /dev/sdb1 /dev/sdc
/dev/sda: PTTYPE="dos"
/dev/sda1: UUID="e7d559e4-3e1d-4fbc-b034-3fdeb498f44d" TYPE="xfs"
/dev/sda2: UUID="B7ODFx-BfTE-hq7N-UlrF-f5ML-CPRe-klSy26" TYPE="LVM2_member"
/dev/sdb: PTTYPE="dos"
And stracing GParted shows these executions of blkid:
# strace -f -q -bexecve -eexecve ./gpartedbin 2>&1 1> /dev/null | egrep -v 'ENOENT|SIGCHLD'
...
[pid 1889] execve("/sbin/blkid", ["blkid", "/dev/sda", "/dev/sda1", "/dev/sda2", "/dev/sdb", "/dev/sdb1", "/dev/sdc"], 0x10b8b10 /* 26 vars */ <detached ...>
[pid 1890] execve("/sbin/blkid", ["blkid", "/dev/sdb1"], 0x10b8b10 /* 26 vars */ <detached ...>
[pid 1891] execve("/sbin/blkid", ["blkid", "/dev/sdc"], 0x10b8b10 /* 26 vars */ <detached ...>
...
This time on CentOS 7 with blkid from util-linux 2.23.2 it reports
information for only sdb (partitioned drive), but not sdb1 (empty
partition) or sdc (empty whole disk drive). Hence no FS_info cache
entries and re-execution of blkid for both sdb1 and sdc.
GParted needs blkid identification of file system images, LVM Logical
Volumes or any other partitions named on the command line which it
wouldn't normally scan [1]. Now every name of interest is passed to
blkid, additional executions of blkid won't get any extra information
and are redundant. Therefore remove this unnecessary code.
Note that these last 2 commits remove creation of "blank" cache entries
(just block special with blank fstype and other attributes) when blkid
reports no information for a particular path. Those entry were needed
to suppress unnecessary additional execution of blkid. However now that
blkid is only executed once (excluding querying the label) this is no
longer necessary. All the getter functions return suitable blank values
when no cache entry is found.
[1] e8f0504b13
Make sure that FS_Info cache is loaded for all named paths (#787181)
Closes#131 - GParted hangs when non-named device is hung
A user reported that GParted would hang at "scanning all devices...",
when a fully working disk was named on the command line, but another
device on the machine was hung.
This can be replicated like this:
(on Ubuntu 20.04 LTS for it's NBD support)
1. Export and import NBD:
# truncate -s 1G /tmp/disk-1G.img
# nbd-server -C /dev/null 9000 /tmp/disk-1G.img
# nbd-client localhost 9000 /dev/nbd0
2. Hang the NBD server and therefore /dev/nbd0:
# killall -STOP nbd-server
3. Run GParted:
$ gparted /dev/sda
Tracing GParted shows that execution of blkid never returns.
# strace -f -tt -q -bexecve -eexecve ./gpartedbin 2>&1 1> /dev/null | fgrep -v ENOENT
...
[pid 37823] 13:56:24.814139 execve("/usr/sbin/mkudffs", ["mkudffs", "--help"], 0x55e2a3f2d230 /* 20 vars */ <detached ...>
[pid 37814] 13:56:24.829246 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=37823, si_uid=0, si_status=1, si_utime=0, si_stime=0} ---
[pid 37825] 13:56:25.376796 execve("/usr/sbin/blkid", ["blkid", "-v"], 0x55e2a3f2d230 /* 20 vars */ <detached ...>
[pid 37824] 13:56:25.380824 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=37825, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
[pid 37826] 13:56:25.402512 execve("/usr/sbin/blkid", ["blkid"], 0x55e2a3f2d230 /* 20 vars */ <detached ...>
Tracking of blkid shows that it hangs on either the open of or first
read from /dev/nbd0.
# strace blkid
...
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=4560, ...}) = 0
lstat("/dev/nbd0", {st_mode=S_IFBLK|0660, st_rdev=makedev(0x2b, 0), ...}) = 0
stat("/dev/nbd0", {st_mode=S_IFBLK|0660, st_rdev=makedev(0x2b, 0), ...}) = 0
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=4560, ...}) = 0
lstat("/dev/nbd0", {st_mode=S_IFBLK|0660, st_rdev=makedev(0x2b, 0), ...}) = 0
access("/dev/nbd0", F_OK) = 0
stat("/dev/nbd0", {st_mode=S_IFBLK|0660, st_rdev=makedev(0x2b, 0), ...}) = 0
openat(AT_FDCWD, "/sys/dev/block/43:0", O_RDONLY|O_CLOEXEC) = 4
openat(4, "dm/uuid", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
close(4) = 0
openat(AT_FDCWD, "/dev/nbd0", O_RDONLY|O_CLOEXEC
Clean up:
1. Resume NBD server:
# killall -CONT nbd-server
2. Delete NBD setup:
# nbd-client -d /dev/nbd0
# killall nbd-server
# rm /tmp/disk-1G.img
Fix this by making GParted specify the whole disk device and partition
names that it is interested in to blkid, rather than letting blkid scan
and report all block devices. Do this both when GParted determines the
devices for itself and when they are named on the command line.
Also update example blkid command output being parsed and cache value
with this change to how blkid is executed.
Closes#131 - GParted hangs when non-named device is hung
GParted already always reads /proc/partitions for whole disk device
names no matter whether it uses whole disk devices named on the command
line, from /proc/partitions or from libparted. As /proc/partitions
lists all the block devices that the kernel knows about, and therefore
all the possible ones blkid could probe, so use it to provide partition
names and device to partition mapping. See code comments for more
details about the assumptions the /proc/partition parsing code makes and
the fact that these are confirmed by examining the Linux kernel source.
This commit just adds debugging to print the existing vector of
validated devices GParted shows in the UI and the vector with all
partitions added, ready for but not yet passed to blkid.
# ./gpartedbin
...
DEBUG: device_paths=["/dev/sda","/dev/sdb"]
DEBUG: device_and_partition_paths=["/dev/sda","/dev/sda1","/dev/sda2","/dev/sdb","/dev/sdb1"]
Also demonstrating that this continues to support named devices,
including file system image files [1].
# truncate -s 256M /tmp/ext4.img
# mkfs.ext4 /tmp/ext4.img
# ./gpartedbin /dev/sda /tmp/ext4.img
...
DEBUG: device_paths=["/dev/sda","/tmp/ext4.img"]
DEBUG: device_and_partition_paths=["/dev/sda","/dev/sda1","/dev/sda2","/tmp/ext4.img"]
[1] e8f0504b13
Make sure that FS_Info cache is loaded for all named paths (#787181)
Closes#131 - GParted hangs when non-named device is hung
Put whole disk device name matching code into a helper function to make
the /proc/partition parsing code easier to understand.
Closes#131 - GParted hangs when non-named device is hung
Now FS_Info::load_cache() and ::load_cache_for_paths() are nearly next
to each other, merge them together to simplify the code a little. This
makes the special case to ensure that file system images named on the
command line were queried by blkid and loaded into the FS_Info cache [1]
become the normal cache loading method. Already passing all discovered
or named devices to load_cache_for_paths() is also a step on the way to
doing it for all devices and partitions of interest.
Just need to ensure that load_cache_for_paths() always loads the cache
as load_cache() did, rather than only when it hadn't already been
loaded. Otherwise GParted will only ever run blkid and load the cache
once at startup and not on each refresh.
[1] e8f0504b13
Make sure that FS_Info cache is loaded for all named paths (#787181)
Closes#131 - GParted hangs when non-named device is hung
With exfatprogs (https://github.com/exfatprogs/exfatprogs) installed the
following operations on exFAT file systems are supported:
- Creation
- Checking
- Labelling
As of the current exfatprogs 1.0.4 the following are not supported:
- Reading usage
- Resizing
- Updating the UUID
Closes!30 - Add exFAT support
std::vector<> is no longer used in TreeView_Detail.h since this commit
replaced them:
fae909897e
Use PartitionVector class throughout the code (#759726)
Seems to be referring to how Fill_Label_Device_Info() worked in the
past, but from history before the beginning of the GIT repository.
Remove out of date comment.
Name the structure member to 'fsname' used to store strings like "ext2"
etc. This is equivalent to what was previously done in this commit:
a9f08ddc7d
Rename local variable to fsname in get_filesystem() (#741430)
Closes!52 - Rename members and variables currently named 'filesystem'
Previously made this change:
175d27c55d
Rename enum FILESYSTEM to FSType
Now complete the renaming exercise of members and variables currently
named 'filesystem'.
Closes!52 - Rename members and variables currently named 'filesystem'
This is not strictly necessary as members are already recognised using
blkid since this commit earlier in the sequence "Recognise ATARAID
members (#75)". However it makes sure active members are recognised
even if blkid is not available and matches how file system detection
queries the SWRaid_Info module.
Closes#75 - Errors with GPT on RAID 0 ATARAID array
This matches how the array device is displayed as the mount point for
mdadm started ATARAID members by "Display array device as mount point of
mdadm started ATARAID members (#75)" earlier in this patchset.
Extend the DMRaid module member cache to save the array device name and
use as needed to display as the mount point.
Closes#75 - Errors with GPT on RAID 0 ATARAID array
Again this is to stop GParted allowing overwrite operations being
performed on an ATARAID member while the array is actively using the
member. This time for dmraid started arrays using the kernel DM (Device
Mapper) driver.
The DMRaid module already uses dmraid to report active array names:
# dmraid -sa -c
isw_ecccdhhiga_MyArray
To find active members in this array, (1) use udev to lookup the kernel
device name:
# udevadm info --query=name /dev/mapper/isw_ecccdhhiga_MyArray
dm-0
(2) list the member names exposed by the kernel DM driver through the
/sys file system.
# ls /sys/block/dm-0/slaves
sdc sdd
# ls -l /sys/block/dm-0/slaves
lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata3/host2/target2:0:0/2:0:0:0/block/sdc
lrwxrwxrwx 1 root root 0 Nov 24 09:52 sdc -> ../../../../pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdd
Closes#75 - Errors with GPT on RAID 0 ATARAID array
The previous commit, made mdadm recognised IMSM and DDF type ATARAID
members get displayed as "linux-raid" (Linux Software RAID array
member). This was because of query method 1 in detect_filesystems().
Fix this now by exposing and using the fstype of the member from the
SWRaid_Info cache.
Closes#75 - Errors with GPT on RAID 0 ATARAID array
Since mdadm release 3.0 (2009-06-02) [1] it has also supported external
metadata formats IMSM (Intel Matrix Storage Manager) and DDF, previously
only managed by dmraid.
A number of distributions have switched to use mdadm and kernel MD
(Multiple Devices) driver for managing these Firmware / BIOS / ATARAID
arrays. These include: Fedora >= 14 [2], RHEL / CentOS >= 6 [3],
SLES >= 12 [4], Ubuntu >= 16.04 LTS.
Therefore additionally parse members in these ATARAID arrays included in
mdadm output, and when activated using the kernel MD driver, in file
/proc/mdstat. Add fstype to the SWRaid_Info cache records to
distinguish members apart. So far the rest of the GParted code
continues to treat all members as FS_LINUX_SWRAID. This will be
resolved in following commits.
Note that this in no way affects how GParted shows and partitions the
array device itself, even those managed by dmraid and use the GParted
DMRaid module. It only affects how GParted shows the member drives
themselves.
[1] mdadm ANNOUNCE-3.0 file
https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git/tree/ANNOUNCE-3.0?h=mdadm-3.0
[2] Fedora 14, Storage Administration Guide, 12.5. Linux RAID Subsystem
https://docs.fedoraproject.org/en-US/Fedora/14/html/Storage_Administration_Guide/raid-subsys.html
"... Fedora 14 uses mdraid with external metadata to access ISW /
IMSM (Intel firmware RAID) sets. mdraid sets are configured and
controlled through the mdadm utility."
[3] RHEL 6, Storage Administration Guide, 17.3. Linux RAID Subsystem
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/storage_administration_guide/raid-subsys
"mdraid also supports other metadata formats, known as external
metadata. Red Hat Enterprise Linux 6 uses mdraid with external
metadata to access ISW / IMSM (Intel firmware RAID) sets. mdraid
sets are configured and controlled through the mdadm utility."
[4] SUSE Linux Enterprise Server 12 Release Notes, 7.2.3 Driver for IMSM
and DDF
https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12/#fate-316007
"For IMSM and DDF RAIDs the mdadm driver is used unconditionally."
Closes#75 - Errors with GPT on RAID 0 ATARAID array
PATCHSET OVERVIEW
A user had a Firmware / BIOS / ATARAID array of 2 devices configured as
a RAID 0 (stripe) set. On top of that was a GPT with the OS partitions.
GParted displays the following errors on initial load and subsequent
refresh:
Libparted Error
(-) Invalid argument during seek for read on /dev/sda
[ Retry ] [ Cancel ] [ Ignore ]
Libparted Error
(-) The backup GPT table is corrupt, but the
primary appears OK, so that will be used.
[ Ok ] [ Cancel ]
This is an Intel Software RAID array which stores metadata at the end of
each member device, and so the first 128 KiB stripe of the set is stored
in the first 128 KiB of the first member device /dev/sda which includes
the GPT for the whole RAID 0 device. Hence when libparted reads member
device /dev/sda it finds a GPT describing a block device twice it's
size and in results the above errors when trying to read the backup GPT.
A more dangerous scenario occurs when using 2 devices configured in an
Intel Software RAID 1 (mirrored) set with GPT on top. On refresh
GParted display this error for both members, /dev/sda and /dev/sdb:
Libparted Warning
/!\ Not all of the space available to /dev/sda appears to be used,
you can fix the GPT to use all of the space (an extra 9554
blocks) or continue with the current setting?
[ Fix ] [ Ignore ]
Selecting [Fix] gets libparted to re-write the backup GPT to the end of
the member device, overwriting the ISW metadata! Do that twice and both
copies of the metadata are gone!
Worked example of this more dangerous mirrored set case. Initial setup:
# dmraid -s
*** Group superset isw_caffbiaegi
--> Subset
name : isw_caffbiaegi_MyMirror
size : 16768000
stride : 128
type : mirror
status : ok
subsets: 0
devs : 2
spares : 0
# dmraid -r
/dev/sda: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0
/dev/sdb: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0
# wipefs /dev/sda
offset type
---------------------------------------------
0x200 gpt [partition table]
0x1fffffc00 isw_raid_member [raid]
Run GParted and click [Fix] on /dev/sda. Now the first member has gone:
# dmraid -s
*** Group superset isw_caffbiaegi
--> *Inconsistent* Subset
name : isw_caffbiaegi_MyMirror
size : 16768000
stride : 128
type : mirror
status : inconsistent
subsets: 0
devs : 1
spares : 0
# dmraid -r
/dev/sdb: isw, "isw_caffbiaegi", GROUP, ok, 16777214 sectors, data@ 0
# wipefs /dev/sda
offset type
---------------------------------------------
0x200 gpt [partition table]
Click [Fix] on /dev/sdb. Now all members of the array are gone:
# dmraid -s
no raid disks
# dmraid -r
no raid disks
# wipefs /dev/sdb
offset type
---------------------------------------------
0x200 gpt [partition table]
So GParted must not run libparted partition table scanning on the member
devices in ATARAID arrays. Only on the array device itself.
In terms of the UI GParted must show disks which are ATARAID members as
whole disk devices with ATARAID member content and detect array busy
status to avoid allowing active members from being overwritten while in
use.
THIS COMMIT
Recognise ATARAID member devices and display in GParted as whole device
"ataraid" file systems. Because they are recognised as whole device
content ("ataraid" file systems) this alone stops GParted running the
libparted partition table scanning and avoids the above errors.
The list of dmraid supported formats is matched by the signatures
recognised by blkid:
$ dmraid -l
asr : Adaptec HostRAID ASR (0,1,10)
ddf1 : SNIA DDF1 (0,1,4,5,linear)
hpt37x : Highpoint HPT37X (S,0,1,10,01)
hpt45x : Highpoint HPT45X (S,0,1,10)
isw : Intel Software RAID (0,1,5,01)
jmicron : JMicron ATARAID (S,0,1)
lsi : LSI Logic MegaRAID (0,1,10)
nvidia : NVidia RAID (S,0,1,10,5)
pdc : Promise FastTrack (S,0,1,10)
sil : Silicon Image(tm) Medley(tm) (0,1,10)
via : VIA Software RAID (S,0,1,10)
dos : DOS partitions on SW RAIDs
$ fgrep -h _raid_member util-linux/libblkid/src/superblocks/*.c
.name = "adaptec_raid_member",
.name = "ddf_raid_member",
.name = "hpt45x_raid_member",
.name = "hpt37x_raid_member",
.name = "isw_raid_member",
.name = "jmicron_raid_member",
.name = "linux_raid_member",
.name = "lsi_mega_raid_member",
.name = "nvidia_raid_member",
.name = "promise_fasttrack_raid_member",
.name = "silicon_medley_raid_member",
.name = "via_raid_member",
As they are all types of Firmware / BIOS / ATARAID arrays, report all
members as a single "ataraid" file system type. (Except for
"linux_raid_member" in the above blkid source listing which is Linux
Software RAID).
Closes#75 - Errors with GPT on RAID 0 ATARAID array
GParted_Core::FILESYSTEMS and ::FILESYSTEM_MAP and the methods that
query and manipulate them are self-contained. Therefore move them into
a separate SupportedFileSystems module.
Also having a single class maintaining all FileSystem interface objects
will make testing all the file system types much easier as there will be
no need to duplicate this functionality in the test.
Closes!49 - Add file system interface tests
To match the renaming performed as part of Bug 741424 "Add support for
GPT partition names". In particular this is most closely similar to:
d480800600
Rename enum to OPERATION_LABEL_FILESYSTEM (#741424)
After the previous commit the lp_device structure pointer parameter is
only used to provide sector_size. Just pass that instead.
Closes!46 - Whole device FAT32 file system reports device busy warning
from mlabel
Closes#16 - "invalid argument for seek()" error on very small (<=40KiB)
drives
GParted_Core::useable_device() doesn't change the pointed to PedDevice
structure. Pass it as const so the compiler enforces this.
Closes!46 - Whole device FAT32 file system reports device busy warning
from mlabel
The last distribution to include the separate 'udevinfo' command was
RHEL / CentOS 5 with udev 095. All supported distributions have much
newer versions of udev and instead have the 'udevadm' command.
A user reported that GParted was slow to refresh on FAT32 file systems:
"can take very long, up to several minutes; can be reproduced by running
dosfsck manually". This is because the file system was large and almost
full, and GParted performs a file system check just to to report the
file system usage.
Created a 4 GiB FAT32 file system and almost filled it with 4 KiB files,
just over 970,000 files.
# df -k /mnt/2
Filesystem 1K-blocks Used Available Used% Mounted on
/dev/sdb2 4186108 39155384 270724 94% /mnt/2
# df -i /mnt/2
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sdb2 0 0 0 - /mnt/2
# find /mnt/2 -type f -print | wc -l
971059
# find /mnt/2 -type d -print | wc -l
1949
Testing performance of the current fsck.fat:
# time fsck.fat -n -v /dev/sdb2 | \
> egrep 'bytes per logical sector|bytes per cluster|sectors total|clusters$'
512 bytes per logical sector
4096 bytes per cluster
8388608 sectors total
/dev/sdb2: 973008 files, 978846/1046527 clusters
real 0m11.552s
user 0m2.183s
sys 0m7.547s
Free sectors in the file system according to fsck.fat:
(1046527 - 978846) * 4096 / 512 = 541448 sectors
Repeating this test while also using 'blktrace /dev/sdb2' and Ctrl-C
around the test in a separate terminal, reports these numbers of I/Os
being performed:
Read requests Read bytes
15,563 165 MiB
Prior to this commit [1] from 0.0.9, GParted used libparted's
ped_file_system_get_resize_constraint() to report the minimum size to
which a FAT* file system can be resized. Use this test program [2] to
performance test this method:
# time ./fscons /dev/sdb2
dev=/dev/sdb2
sector_size=512
min_size=7909522
max_size=8388608
real 0m2.673s
user 0m0.070s
sys 0m1.834s
Free sectors in the file system according to libparted
ped_file_system_get_resize_constraint():
8388608 - 7909522 = 479086 sectors
blktrace reports these numbers of I/Os being performed:
Read requests Read bytes
7,821 71 MiB
So using libparted resize constraint is a bit faster but is still
reading too much data and is really too slow. Also when testing GParted
using this libparted method against a corrupted FAT32 file system, on
every refresh, one popup dialog is displayed for each error libparted
detects with the file system, each of which needs acknowledgement.
Example popup:
Libparted Error
\DIRNAME\FILENAME.EXT is 107724k, but is has 1920
clusters (122880k).
[ Cancel ][ Ignore ]
There could be a huge number of such errors in a corrupted file system.
Not really suitable for use by GParted.
Test the performance of mtools' minfo command to report the file system
figures:
# time minfo -i /dev/sdb2 :: | \
> egrep 'sector size:|cluster size:|small size:|big size:|free clusters='
sector size: 512 bytes
cluster size: 8 sectors
small size: 0 sectors
big size: 8388608 sectors
free clusters=67681
real 0m0.013s
user 0m0.004s
sys 0m0.019s
Free sectors in the file system according to minfo:
67681 * 8 = 541448 sectors
blktrace reports these numbers of I/Os being performed by minfo:
Read requests Read bytes
1 16 KiB
This matches with minfo just reading information from the BPB (BIOS
Parameter Block) [3] from sector 0 and the FS Information Sector [4]
usually in sector 1. Note that the free cluster figure reported by
minfo comes from the FS Information Sector because it only reports it
for FAT32 file systems, not for FAT16 file systems. Scanning the File
Allocation Table (FAT) [5] to count free clusters is exactly what mdir,
without the '-f' (fast) flag, does. Test the performance of mdir:
# export MTOOLS_SKIP_CHECK=1
# time mdir -i /dev/sdb2 ::/ | fgrep 'bytes free'
277 221 376 bytes free
real 0m0.023s
user 0m0.011s
sys 0m0.023s
Free sectors in the file system according to mdir:
277221376 / 512 = 541448 sectors
blktrace reports these number of I/Os being performed by mdir:
Read requests Read bytes
5 448 KiB
So minfo and mdir together provide the needed information and are 2 to 3
orders of magnitude faster because they only read the needed BPB and FAT
data from the drive. Use these together to read the file system usage.
[1] 61cd0ce778
lots of stuff and cleanups, including fixing getting used/unused
space of hfs/hfs+/fat16/fat32
[2] fscons.c
/* FILE: fscons.c
* SYNOPSIS: Report libparted's FS resize limits.
* BUILD: gcc -o fscons fscons.c -lparted -lparted-fs-resize
*/
int main(int argc, const char *argv[])
{
PedDevice* dev = NULL;
PedDisk* tab = NULL;
PedPartition* ptn = NULL;
PedFileSystem* fs = NULL;
PedConstraint* cons = NULL;
if (argc != 2)
{
fprintf(stderr, "Usage: fscons BLOCKDEV\n");
exit(1);
}
dev = ped_device_get(argv[1]);
if (dev == NULL)
{
fprintf(stderr, "ped_device_get(\"%s\") failed\n", argv[1]);
exit(1);
}
printf("dev=%s\n", dev->path);
printf("sector_size=%ld\n", dev->sector_size);
tab = ped_disk_new(dev);
if (tab == NULL)
{
fprintf(stderr, "ped_disk_new(dev) failed\n");
exit(1);
}
ptn = ped_disk_get_partition_by_sector(tab, 0);
if (ptn == NULL)
{
fprintf(stderr, "ped_disk_get_partition(tab, 0) failed\n");
exit(1);
}
fs = ped_file_system_open(&ptn->geom);
if (fs == NULL)
{
fprintf(stderr, "ped_file_system_open(&ptn->geom) failed\n");
exit(1);
}
cons = ped_file_system_get_resize_constraint(fs);
if (cons == NULL)
{
fprintf(stderr, "ped_file_system_get_resize_constraint(fs) failed\n");
exit(1);
}
printf("min_size=%ld\n", cons->min_size);
printf("max_size=%ld\n", cons->max_size);
ped_constraint_destroy(cons);
ped_file_system_close(fs);
ped_disk_destroy(tab);
ped_device_destroy(dev);
return 0;
}
[3] Design of the FAT file system, BIOS Parameter Block
https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#BIOS_Parameter_Block
[4] Design of the FAT file system, FS Information Sector
https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#FS_Information_Sector
[5] Design of the FAT file system, File Allocation Table
https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system#File_Allocation_Table
Bug 569921 - dosfsck -n delays device scan
Move snap_to_*() method calls from the point when all operations are
added to the list, to earlier when Resize/Move, Paste (into new) and
Create New dialogs are composing the new partition objects. In
particular for the Resize/Move operation, to just before updating the
file system usage.
This change finally resolves this bug.
Because of the dialog call chains into Dialog_Base_Partition,
snap_to_alignment() must be added into:
* Dialog_Base_Partition::prepare_new_partition() for the Resize/Move and
Paste (into new) dialogs; and
* Dialog_Partition_New::Get_New_Partition() for the Create New dialog.
Closes#48 - Error when moving locked LUKS-encrypted partition
The current device has to be passed to the dialog constructors and then
on to the Dialog_Base_Constructor. Note that the Dialog_Partition_New
constructor is already passed the current device, however it still needs
to pass it on to Dialog_Base_Constructor.
This is ready so that snap_to_*() methods can access the current device
when they are called from within these dialogs.
* Pass Parameter to Base Class Constructor while creating Derived class
Object
https://stackoverflow.com/questions/16585856/pass-parameter-to-base-class-constructor-while-creating-derived-class-objectCloses#48 - Error when moving locked LUKS-encrypted partition
None of the snap_to_*() methods report any errors so remove the unused
error parameter and return value.
Closes#48 - Error when moving locked LUKS-encrypted partition
PATCHSET OVERVIEW
A user had 2 adjacent partitions which were aligned to multiples of
33553920 bytes (32 MiB - 512 bytes), not MiB or cylinders. As far as
GParted is concerned this is not aligned. The second partition
contained closed LUKS encrypted data. Recreate this setup with:
# truncate -s 200G /tmp/disk.img
# losetup -f --show /tmp/disk.img
/dev/loop0
# sfdisk -u S /dev/loop0 << EOF
65535 2162655 83
2228190 78904140 83
EOF
# partprobe /dev/loop0
# echo -n badpassword | cryptsetup luksFormat /dev/loop0p2 -
When trying to move the second LUKS encrypted partition to the right by
any amount, with the default MiB alignment, GParted displays this error
dialog and fails to even queue the operation:
Could not add this operation to the list
A partition with used sectors (78907392) greater than its
length (78905344) is not valid
[ OK ]
Overview of the steps involved:
1. The Resize/Move dialog composed a new partition to start a whole
multiple of MiB after the end of the previous non-aligned partition.
The new partition also had it's size increased to a whole multiple of
MiB, to 78907392 sectors (38529 MiB) which was 1.59 MiB larger than
before. Neither the start or end of the new partition are aligned at
this point.
2. Win_GParted::activate_resize() applied the change back to the closed
LUKS partition object, additionally making the used sectors equal to
the partition size.
(To match the fact that when opened the LUKS mapping it will
automatically fill the new larger partition size).
3. GParted_Core::snap_to_mebibyte() then aligned the partition start and
end to whole MiB boundaries, reducing the partition size in the
process to 78905344 (38528 MiB).
4. GParted_Core::snap_to_alignment() reported the error saying that it
couldn't add the operation to the list because it was invalid to have
the file system used sectors larger than the partition size.
Fix this by having the snap to alignment adjustments applied before the
dialogs update any associated file system usage. Specifically the
Resize/Move, Paste (into new) and Create New dialogs as these are the
only ones which either create or modify partition boundaries.
Validation done by snap_to_alignment() will continue to occur at the
current point when the operation is added to the list.
THIS COMMIT
snap_to_alignment() is doing two different jobs, it is (1) optionally
adjusting the new partition boundaries for MiB or Cylinder alignment;
and (2) checking that the partition boundaries and file system usage are
valid.
Split those into two different functions (1) snap_to_alignment() and
(2) valid_partition(). For now valid_partition() still calls
snap_to_alignment() so there is no functional change with this commit.
Closes#48 - Error when moving locked LUKS-encrypted partition
With the same case as from the previous commit, the very long "Mounted
on ..." text is now wrapped, but the text may not be left justified.
Slowly adjust the dialog width and see how the text wrapping is updated
to fit the size adjustment but the text is centred rather than left
justified.
This is because setting the halign property to Gtk::ALIGN_START does not
guarantee left alignment of text for wrapped or ellipsized Gtk::Labels.
Use the xalign property instead.
To set the xalign property there is a method in the GtkMisc (Gtk::Misc)
base class:
gtk_misc_set_alignment (Gtk::Misc::set_alignment)
However, GtkMisc (Gtk::Misc) was deprecated in Gtk 3.14 (Gtkmm 3.14)
and in Gtk 3.16 (gtkmm 3.16) set_alignment() was replaced with the
introduction of two new methods:
gtk_label_set_xalign (Gtk::Label::set_xalign)
gtk_label_set_yalign (Gtk::Label::set_yalign)
Add a check for Gtkmm method Gtk::Label::set_xalign() in configure.ac
and use it when available.
References:
[1] Gtk3 Reference Documentation - gtk_misc_set_alignment()
https://developer.gnome.org/gtk3/stable/GtkMisc.html#gtk-misc-set-alignment
"gtk_misc_set_alignment has been deprecated since version 3.14 and
should not be used in newly-written code. Use GtkWidget's alignment
("halign" and "valign") and margin properties or GtkLabel's
"xalign" and "yalign" properties."
[2] Gtkmm 3.16 Gtk::Misc Class Reference, set_alignment() method
https://developer.gnome.org/gtkmm/3.16/classGtk_1_1Misc.html#a52b2675874cf46a3097938756b9fe9e8
[3] GNOME BugZilla - EmptyBoxes: instructions_label's alignment is off
https://bugzilla.gnome.org/show_bug.cgi?id=735841
[4] Gtk commit from 2014-09-16:
GtkLabel: add x/yalign properties
https://gitlab.gnome.org/GNOME/gtk/commit/d39424fc
[5] Gtk3 Reference Documentation - gtk_label_set_xalign()
https://developer.gnome.org/gtk3/stable/GtkLabel.html#gtk-label-set-xalign
[6] Gtkmm 3.16 Gtk::Label Class Reference, set_xalign() method
https://developer.gnome.org/gtkmm/3.16/classGtk_1_1Label.html#acee7d4e87d7cc14080a7b8ded5f84e5eCloses!40 - Limit wrapping labels
Gtk::Table was deprecated in Gtk 3.4.0. Replace with Gtk::Grid.
This commit makes the change for Dialog_Partition_Info.
Closes!25 - Modern Gtk3 - part 1
Gtk::Table was deprecated in Gtk 3.4.0. Replace with Gtk::Grid.
This commit makes the change for Dialog_Base_Partition.
Closes!25 - Modern Gtk3 - part 1
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2. Replace with
plain Gtk::Box.
This commit makes the change for Dialog_Partition_Info.{h,cc}.
Closes!25 - Modern Gtk3 - part 1
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2. Replace with
plain Gtk::Box.
This commit makes the change for Dialog_Base_Partition.{h,cc}.
Closes!25 - Modern Gtk3 - part 1
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2. Replace with
plain Gtk::Box.
This commit makes the change for HBoxOperations.{h,cc}.
Closes!25 - Modern Gtk3 - part 1
Gtk::HBox and Gtk::VBox were deprecated in Gtkmm 3.2 [1]. Replace with
plain Gtk::Box.
This commit makes the change for Win_GParted.{h,cc}.
[1] Gtkmm 3.2.0 NEWS file (actually first included in gtkmm 3.1.6
unstable)
https://gitlab.gnome.org/GNOME/gtkmm/blob/3.2.0/NEWS#L91
Gtk:
* All H* or V* specialized classes have been deprecated, to
match the deprecations in the GTK+ C API. You should now
set the orientation instead.
This includes HBox, VBox, HButtonBox, VButtonBox, HPaned,
VPaned, HScale, VScale, HSeparator, VSeparator, HScrollbar and
VScrollbar.
Closes!25 - Modern Gtk3 - part 1
The Gdk::RGBA data type was introduced to replace Gdk::Color in
Gtkmm 3.0 [1], with Gdk::Color being deprecated in Gtkmm 3.10 [2].
With this commit we make the change to Gdk::RGBA data type which is the
modern replacement to Gdk::Color. Gdk::RGBA can be used almost as a
drop in replacement because it keeps most of the Gdk::Color interface.
Also, this commit removes the C Gtk call introduced during the
port-to-gtk3 patchset by commit:
5379352766
repare-for-gtk3: Prepare for removal of Gtk::Widget::modify_fg() (#7)
[1] Gtkmm 3.0.1 NEWS file
https://gitlab.gnome.org/GNOME/gtkmm/blob/3.0.1/NEWS#L48
* RGBA replaces Color, though Color still exists because it is
used by TextView. We hope to deprecated Color completely in
gtkmm 3.2.
[2] Gtkmm 3.10.0 NEWS file
https://gitlab.gnome.org/GNOME/gtkmm/blob/3.10.0/NEWS#L127
Gdk:
* Deprecate Color.
Closes!25 - Modern Gtk3 - part 1
Mostly add, but also remove, #includes so both DialogFeatures.h and .cc
include exactly the header files each needs to get the definitions they
use.
Header file #include guards are there to specifically enable this.
To better reflect that it is loading the supported actions for one file
system into the treeview, just like it's parent load_filesystems() is
initiating the loading for all the file systems.
Open the File System Support dialog, either add or remove some file
system specific commands used by GParted and press the
[Rescan For Supported Actions] button. The supported actions don't
change. However after just closing and reopening the dialog, the
supported actions do reflect the added or removed file system specific
commands.
Bisected to this commit:
4d6d464664
Display "other" in the File System Support dialog (!13)
The problem is that commit made a subset copy of the
GParted_Core::FILESYSTEMS vector, obtained from get_filesystems(), so
when the rescan ran and the FILESYSTEMS vector was updated with new
supported actions, the dialog still displayed the original subset copy,
so didn't reflect the changed supported actions.
Fix by passing a reference to the GParted_Core::FILESYSTEMS vector,
obtained from get_filesystems(), and perform the necessary filtering
inside the dialog, like before the above faulty commit. Additionally
finding and adding "other" file system to the end of the list.
Closes!38 - Fixes for minor issues with File System Support rescanning
Having a member variable named 't' which is used to share state in a
Dialog_Progress object between on_signal_show() and on_cancel() methods
is horrible. Rename to something more meaningful.
Also initialise m_curr_op in the constructor's initialisation list,
rather than later when first used in on_signal_show(). Not strictly
required, but avoids this POD (Plain Old Data) member variable being
undefined in the Dialog_Progress object between construction and when
on_signal_show() previously assigned to it for the first time and
started using it.
* C++ FAQ / Should my constructors use "initialization lists" or
"assignment"?
https://isocpp.org/wiki/faq/ctors#init-lists
Writes the starting device overview information of all known devices to
the top of the saved details HTML. This is so that hopefully we don't
need to additionally ask users for their disk layouts via 'fdisk -l',
'parted print' and 'lsblk' when the saved details file is provided.
Also moves the equals separators "==================" from below to
above each operation so the each section is separated.
Bug 639176 - Save partition layout to gparted_details.htm
Some icon themes only provide large icons for stock items. This can
cause problems like overly large icons appearing in the GParted UI.
Found on Kubuntu 16.04 LTS with default breeze icon theme.
Be compatible with these icon themes by forcing scaling of stock icons
to the requested size.
Icons are used either by Gtk::Image widgets, or Gtk::CellRendererPixbuf
objects for comboboxes/treeviews. For Gtk::Image widgets we add
Utils::mk_image() that constructs Gtk::Image widgets and then sets the
pixel-size property. For Gtk::CellRendererPixbuf we add
Utils::mk_pixbuf() that first loads a Gdk::Pixbuf and then scales if
needed.
Closes#39 - After GTK3 port icons are too big on KDE
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
Now that GParted requires Gtk3 there is no need to use floating point
numbers for compatibility with Gtk <= 2.22. Replace with symbolic
alignment constants.
Relevant commit history:
* 6efa623401
Add optional yalign argument to Utils::mk_label() method
* be2689ad25
Stop using deprecated widget alignment enumerators (#652044)
It is not creating a dialog (a pop-up window managed by GParted code
itself). It is launching independent yelp program to display the help,
so remove the "_dialog" from the name to avoid any possible confusion.
In Gtk3 the progress bar height is fixed and defined by the CSS theme in
use. Changing the widget allocation size does nothing, it is always
rendered the same way.
In many themes, including Adwaita, the progressbar is very, very thin.
Provide custom CSS to specify a height of 8 pixels.
The CSS source string has to be differentiated for Gtk pre and post
3.20, because Gtk 3.20 introduced some breaking changes in the way CSS
is handled.
References:
[1] Migrating from GTK+ 2.x to GTK+ 3 - Parsing of custom resources
https://developer.gnome.org/gtk3/stable/gtk-migrating-GtkStyleContext-parsing.html
[2] Gtk3 Reference Documentation - Changes in GTK+ 3.20
https://developer.gnome.org/gtk3/stable/ch32s10.html
[3] Gnome/HowDoI - Custom Style
https://wiki.gnome.org/HowDoI/CustomStyleCloses#7 - Port to Gtk3
There is a bug affecting Gtk+ 3.22.8 to 3.22.30 in which destroying a
GtkComboBox when it is not hidden results in this message:
Gtk-CRITICAL **: gtk_widget_is_drawable: assertion 'GTK_IS_WIDGET (widget)' failed
This happens in GParted when some dialogs are closed, for example the
Create New Partition and Create Partition Table dialogs. To work around
the issue we call Gtk::Dialog::hide() in the destructors of our dialog
classes.
The issue was fixed in Gtk 3.24.0.
* Gtk 3.22.8 was released in February 2017.
* Gtk 3.24.0 was released in September 2018.
References:
[1] Gtk Issue - GtkComboBox::private::popup_window can be NULL
https://gitlab.gnome.org/GNOME/gtk/issues/125
[2] Gtk commit - combobox: popdown() the menu during unmap()
7401794de6
[3] Gtk commit - Check for NULL priv->popup_window in
gtk_combo_box_popdown()
aa5d926c84Closes#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area in the Create new Partition
dialog and the Resize/Move dialog.
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area contained in the main
application window (also called the DrawingAreaVisualDisk).
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
In Gtk2 widgets draw themselves in response to the expose event signal.
In Gtk3 widgets draw themselves in response to the GtkWidget::draw
signal, and the signal handler gets a Cairo context as an argument.
Convert Gtk::DrawingArea rendering code to respond to the
GtkWidget::draw signal.
This commit is specific to the drawing area in the Partition Info
dialog.
Reference:
[1] Migrating from GTK+ 2.x to GTK+ 3 - "The GtkWidget::draw signal":
https://developer.gnome.org/gtk3/stable/ch26s02.html#id-1.6.3.4.11Closes#7 - Port to Gtk3
Starting from Gtkmm3 Gdk::Cursor objects cannot be constructed directly,
but instead you have to get a smart pointer to an instance by calling
the static member function Gdk::Cursor::create().
Gdk::Cursor::create() returns a Glib::RefPtr<Gdk::Cursor> object.
Gtkmm3 always uses Glib::RefPtr<Gdk::Cursor> in its interface and never
plain Gdk::Cursor.
Reference:
[1] Programming with gtkmm3, Changes in gtkmm3:
https://developer.gnome.org/gtkmm-tutorial/3.24/changes-gtkmm3.html.en
"... Gdk::Cursor are now used via Glib::RefPtr."
Closes#7 - Port to Gtk3
Now that we are compiling against Gtkmm3 there are missing declarations
of Gtkmm identifiers due to changes in Gtkmm internal header structure.
All we have to do is bring back the declarations by including the
appropriate headers where needed.
Add necessary Gtkmm header includes.
Closes#7 - Port to Gtk3
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
GParted uses Gtk::Menu_Helpers::MenuList helper class to access
individual menu items. This helper class made it easy to navigate menu
items by index.
Gtk::Menu_Helpers::MenuList was removed in the switch from Gtkmm2 to
Gtkmm3 [1]. Instead, use a separate std::map<Gtk::MenuItem*> to keep
track of individual Gtk::MenuItem objects.
Reference:
[1] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
c8e47b0db5Closes#7 - Port to Gtk3
Gtk::Menu_Helpers::Element class and subclasses help in Gtk::MenuItem
widgets and also automate tasks like registering keyboard accelerators
when parented to a top-level window [1][2].
Gtk::Menu_Helpers::Element class and subclasses were removed in Gtkmm3
[3]. Provide compatible implementations under the namespace
GParted::Menu_Helpers.
References:
[1] gtkmm: Gtk::Menu_Helpers Namespace Reference
https://developer.gnome.org/gtkmm/2.24/namespaceGtk_1_1Menu__Helpers.html
[2] gtkmm: Gtk::Menu_Helpers::Element Class Reference
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1Menu__Helpers_1_1Element.html
[3] Gtkmm 3 commit "MenuShell: Remove items()." removed the code
c8e47b0db5Closes#7 - Port to Gtk3
All the other modules are in the GParted namespace, except for main()
which has to be in the global namespace, so put these in the GParted
namespace too.
Closes!20 - Minor namespace and scope operator tidy-ups
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
Third commit in a series to convert Gdk::GC based drawing to Cairo based
drawing. This specific commit makes the transition for the graphical
partition visualizer widget that is used in the main application window.
Closed!17 - Gtk2 modernisation
Second commit in a series to convert Gdk::GC based drawing to Cairo
based drawing. This specific commit makes the transition for the
graphical partition info widget that is used in the "Information about"
dialog.
Closes!17 - Gtk2 modernisation
C++ initialises static member variables before main() is called.
Therefore the static members of:
struct Slots
{
static Gtk::TreeModelColumn<Glib::ustring> text;
static Gtk::TreeModelColumn<bool> sensitive;
private:
static Gtk::TreeModel::ColumnRecord record_;
};
are constructed before Gtk::Main() is called in main(). However the
Gtkmm documentation specifically says that they must be constructed
afterwards [1].
Resolve this by using the Construct On First Use Idiom [2] to delay
initialisation until the slots are first used. Normally this idiom uses
static local objects, however it is being applied to class static
objects here because the objects are accessed in many methods. The
downside of this approach is that the objects are never destructed,
which memory analysers like Valgrind could see as a memory leak, but
that is actually deliberate. That leak can be removed once we can use
C++11 and std::unique_ptr.
[1] gtkmm: Gtk::TreeModelColumnRecord Class Reference
https://developer.gnome.org/gtkmm/2.24/classGtk_1_1TreeModelColumnRecord.html#details
"Neither TreeModel::ColumnRecord nor the TreeModelColumns contain
any real data - they merely describe what C++ type is stored in
which column of a TreeModel, and save you from having to repeat that
type information in several places.
Thus TreeModel::ColumnRecord can be made a singleton (as long as you
make sure it's instantiated after Gtk::Main), even when creating
multiple models from it.
"
[2] C++ FAQ / How do I prevent the "static initialization order
problem"?
https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-useCloses!17 - Gtk2 modernisation
Final part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.
This specific commit renames the signal handler callback to match the
previously renamed combobox widget variable names.
Closes!17 - Gtk2 modernisation
Third part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.
This specific commit is about file system combobox.
Closes!17 - Gtk2 modernisation
Second part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.
This specific commit is about partition type combobox.
Closes!17 - Gtk2 modernisation
First part in a series of commits to replace Gtk::OptionMenu widgets
with GParted::OptionComboBox.
This specific commit is about partition alignment combobox.
Closes!17 - Gtk2 modernisation