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
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
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
Missed when adding partition naming at creation time in enhancement:
Bug 746214 - Partition naming enhancements
starting with this commit:
f804bc3244
Allow partition naming on busy partitions (#746214)
There were a few cases of creating a local string variable from a
literal and then passing the variable to execute_command() like this:
Glib::ustring cmd = "whatever";
Utils::execute_command( cmd, ... );
This creates an unnecessary local variable. Instead pass the string
literal directly to Utils::execute_command() like this:
Utils::execute_command( "whatever", ... );
This also make the code a little bit more grep friendly.
No other commands run by GParted are niced, so stop nicing commands run
from the DMRaid module.
I think nicing of possibly long running file system modification
commands would have made virtually no difference because "nice -n 19"
lowered the CPU priority, but such command would be I/O bound.
History:
Nicing of file system modification commands was added by this commit
from 2006-08-21:
82e6f6b132
added nice -n 19, so that all extensive filesystem operations will be
Nicing of DMRaid operations was copied into the DMRaid module when it
was added here in 2009-03-14:
5865c92dc0
Added new class for dmraid support
Nicing was removed from file system modification commands with this
commit from 2013-02-22:
52a2a9b00a
Reduce threading (#685740)
Bug 788007 - Remove minor bits of legacy from DMRaid module
The -P option was first added to dmraid-1.0.0.rc15 released 2006-09-17
[1]. dmraid-1.0.0.rc16 (a later release) was included in Debian 6 and
Ubunbu 12.04 LTS. dmraid-1.0.0.rc13 was included in RedHat/CentOS 5
however the -P option was back ported into RedHat/CentOS 5.1.
All of these distributions are so old as to be no longer supported and
yet they provided the dmraid -P option. Therefore backward
compatibility for dmraid without the -P option is no longer required.
So remove it.
[1] old dmraid source code releases
http://people.redhat.com/heinzm/sw/dmraid/src/old/
Bug 788007 - Remove minor bits of legacy from DMRaid module
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()
Shell fragments must be properly quoted and escaped to prevent execution
of unintended commands derived from user controllable data. For
example:
$ printf '#!/bin/sh\necho test > out\n' > script.sh
$ chmod +x script.sh
$ truncate -s 20M 'jfs;script.sh'
$ mkfs.jfs -q 'jfs;script.sh'
$ ls -l out
ls: cannot access out: No such file or directory
$ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'
$ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'
$ ls -l out
-rw-r--r-- 1 root root 5 Sep 12 23:11 out
$ cat out
test
What is happening is that jfs::set_used_sectors() is using the device
name 'jfs;script.sh' without quoting it and passing it to the shell to
execute like this:
sh -c 'echo dm | jfs_debugfs jfs;script.sh'
which the shell duly executes as these two commands:
echo dm | jfs_debugfs jfs
script.sh
This could be a security related issue as "sh -c" is able to execute
arbitrary shell commands from the argument if if contains shell special
characters. Use Glib::shell_quote() [1] to quote and escape file names
and whole commands passed to the shell.
[1] Glib::shell_quote(const std::string & unquoted_string)
https://developer.gnome.org/glibmm/stable/group__ShellUtils.html
"Quotes a string so that the shell (/bin/sh) will interpret the
quoted string to mean unquoted_string.
If you pass a filename to the shell, for example, you should first
quote it with this function."
Bug 787203 - Correctly quote and escape arguments of external programs
passed to execute_command()
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
Add double quote (") to the list of prohibited FAT label characters,
previously missed [1][2].
Also add single quote (') because mlabel encoded it in a way that both
Windows and blkid don't understand, although mlabel can correctly decode
it itself.
# export MTOOLS_SKIP_CHECK=1
# mlabel ::"MIKE'S" -i /dev/sdf1
# mlabel -s :: -i /dev/sdf1
Volume label is MIKE'S (abbr=MIKE_S~1???)
# blkid -o value -s LABEL /dev/sdf1
MIKE_S~1???
(8-bit characters in the above output have been replaced with
question marks (?) just to keep this commit message as 7-bit ASCII).
Finally exclude ASCII control characters below SPACE (0x00 to 0x1F) as
they also cause mlabel to ask a question and wait for input in the same
way that prohibited characters do. As discussed in the previous commit
[1] the only way to stop GParted waiting forever is to manually kill
mlabel with signal 9 (KILL).
# mlabel ::"^A" -i /dev/sdf1
Long file name "^A" contains illegal character(s).
a)utorename A)utorename-all r)ename R)ename-all
s)kip S)kip-all q)uit (aArRsSq):
[1] 584137b32b
Remove prohibited characters from FAT16/32 labels (#755608)
[2] Microsoft TechNet: Label
https://technet.microsoft.com/en-us/library/bb490925.aspx
Bug 787202 - Update list of prohibited fat label characters
So far GParted is still loading the default non-reversible encoded
labels from blkid in the initial loading of the FS_Info module cache.
This encoded label is used to match LABEL=<label> when reading
/etc/fstab, via the get_path_by_label() call, so works for ASCII only
labels. This prevents GParted enabling the "mount on >" partition menu
item when non-ASCII labels are used.
To fix this:
1) Stop reading the labels the wrong way.
Via the blkid command used to initially load the FS_Info module cache
and is subject to default non-reversible encoding of non-printable
ASCII bytes.
2) Read all the labels the right way, but only when needed.
Only when /etc/fstab file contains LABEL=<label> and
get_path_by_label() is called, read all the labels from blkid without
encoding them via run_blkid_update_cache_one_label().
3) Return label from the cache.
get_label() returns the cached label, loading it into the cache first
if needed with run_blkid_update_cache_one_label().
In the worst case scenario of having a LABEL=<label> in /etc/fstab blkid
will be run for every partition containing a recognised file system to
read the label. On my desktop with 5 hard drives, 4 SWRaid arrays and
31 recognised file systems running 'blkid -o value -s LABEL ...' 31
times took 0.074 seconds of a total scan time of 9.072 seconds. Less
that 1% of the total scanning time. When LABEL=<label> is not used in
/etc/fstab individual blkid executions are only used to read labels for
file systems where there is no file system specific tool available
reducing the impact further. Blkid itself caches the data in it's
blkid.tab cache file rather than reading all file systems on each
invocation. Also the Linux file system cache will already contain the
blkid executable file, needed libraries files and the blkid.tab cache
file itself. Hence why repeated execution of blkid is so fast.
Further to the updated comment in set_partition_label_and_uuid().
Matching LABEL=<label> from /etc/fstab uses the label obtained from
blkid run in the C locale so this kind of assumes it returns the label
correctly and it does for my limited testing on Unicode enabled
desktops. Just not sure if it would be true for all cases in all
locales compared to the FS specific command run in the users default
locale.
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
Move the code which reads the Unicode label from FS_Info::get_label()
into new function run_blkid_update_cache_one_label() which also replaces
the non-reversibly encoded copy loaded during the initial cache load.
This is mainly a bit of code refactoring ready for the following change.
It deliberately keeps the initial loaded labels so that reading
/etc/fstab and decoding LABEL=<label> to block special device names via
FS_Info::get_path_by_label() continues to works, at least for ASCII only
labels.
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
For file systems which don't provide a specific tool to read labels
(exfat, f2fs, hfs, hfsplus, udf and ufs) or when the tools aren't
installed for any other file system, reading labels falls back to using
the blkid command. Blkid encodes non-ASCII bytes in it's output [1].
For example blkid reports a short Unicode label like this:
# blkid /dev/sdb12
/dev/sdb12: LABEL="M-PM-^ZM-PM->M-QM-^HM-PM-:M-PM-0" TYPE="hfsplus"
This shows encoding using 'M-' for bytes above 127 and caret '^' for
control characters. Unfortunately neither 'M-' or '^' are encoded by
blkid so it is impossible to distinguish between the original label
containing either of these sequences or encoded non-printable bytes.
See this Bugzilla's bug 786502 entry for more details. Unfortunately
this makes the default output format from blkid unsuitable for reading
Unicode character labels.
Instead instruct blkid to print values without encoding them using the
'-o value' option. This just produces a list of new line separated
values without being able to identify which TYPE, UUID or LABEL belongs
to which device. So query just the label for each block device one at
a time. This method has the advantage of also working with all versions
of blkid, from version 1.0.0 (12-Feb-2003) in CentOS 5 to the latest
version 2.30.1 (20-Jul-2017) in Fedora 26.
# blkid -o value -s LABEL /dev/sdb12 | hexdump -C
00000000 d0 9a d0 be d1 88 d0 ba d0 b0 0a |...........|
0000000b
(Using hexdump -C just so that this commit message only contains ASCII
characters).
Therefore this commit changes FS_Info::get_label() to query blkid as
shown above. Note that GParted_Core::set_partition_label_and_uuid()
only calls get_label() when there is no file system specific tool
available (or the tool failed).
The FS_Info cache still contains copies of the labels subject to blkid
encoding, and that will be addressed in following commits.
[1] blkid.c v2.30.1 safe_print()
https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/misc-utils/blkid.c?h=v2.30.1#n111
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
Automake build of libraries creates .dirstamp files. First added by
this commit:
81b104928b
Add building of Google Test libraries (#781978)
Mark .dirstamp as to be ignored by GIT.
GParted fails to display when run under Wayland [1][2][3]. This is
because by intentional design Wayland doesn't allow applications with
root privileges access to the display [4].
As an interim workaround make the gparted shell wrapper use xhost to
grant root access to the X11 server if root doesn't already have access,
but only when configured. Granting root access must be explicitly
enabled when building GParted like this:
./configure --enable-xhost-root
It defaults to disabled. When gpartedbin binary ends the shell wrapper
revokes root access only if it granted such access.
[1] GNOME Bug 776437 - GParted fails to run as root under Wayland
https://bugzilla.gnome.org/show_bug.cgi?id=776437
[2] Ubuntu Bug 1652282 - GParted does not work in GNOME on Wayland
https://bugs.launchpad.net/ubuntu/+source/gparted/+bug/1652282
[3] Fedora Bug 1397103 - gparted not working under Wayland
https://bugzilla.redhat.com/show_bug.cgi?id=1397103
[4] Common Fedora 25 bugs
Running graphical apps with root privileges (e.g. gparted) does not
work on Wayland
https://fedoraproject.org/wiki/Common_F25_bugs#wayland-root-apps
Bug 776437 - GParted fails to run as root under Wayland
On CentOS 6 with polkit version 0.96 pkexec fails to execute gparted
shell wrapper as root like this:
$ env | grep DISPLAY
DISPLAY=:0.0
$ sh -x /usr/local/bin/gparted
...
+ pkexec /usr/local/bin/gparted
(gpartedbin:8011): Gtk-WARNING **: cannot open display:
This is because polkit didn't support setting the DISPLAY environment
variable to allow execution of X11 applications until the introduction
of the allow_gui annotation by this commit in polkit 0.102:
https://cgit.freedesktop.org/polkit/commit/?id=7850d27017fed1834268a852350ae85381fbb110
Bug 38769 - pkexec: Support running X11 apps
Make configure only use pkexec version 0.102 or higher as the privilege
escalation program. Otherwise configure falls back to checking for the
other privilege escalation programs as it did before.
Bug 776437 - GParted fails to run as root under Wayland
Only install the GParted polkit action file when pkexec is being used as
the root privilege escalation program.
Bug 776437 - GParted fails to run as root under Wayland
An action file is always needed with polkit to describe the privileged
actions that are available to the subject (client program). For GParted
the only available action is to run the gparted shell script as root.
Note that the polkit action file will be installed into location
$(prefix)/share/polkit-1/actions. This is required by the GNU Coding
Standards [1] and to prevent 'make distcheck' from failing [2]. However
polkit only uses /usr/share/polkit-1/actions for it's action files [3].
This dilemma was discussed in this Bugzilla bug 776437 and on the
general Automake discussion email list [4]. The solution is to simply
document in the README file that a manual additional installation step
may be required.
The action file is marked as translatable with the underscore (_) of the
_description and _message tags identifying the string to be translated.
Use of INTLTOOL_POLICY_RULE in Makefile.am to merge translations into
the polkit action file necessitates increasing the minimum version of
intltool to 0.36.0 where it was first introduced in intltool.m4. This
will prevent GParted building on RedHat/CentOS 5 which only has intltool
0.35.0. But that doesn't matter because RedHat/CentOS 5 reached end of
life on 31st March 2017.
[1] GNU Coding Standards, 7.2.5 Variables for Installation Directories
https://www.gnu.org/prep/standards/standards.html#Directory-Variables
[2] Automake Manual, 27.10 Installing to Hard-Coded Locations
https://www.gnu.org/software/automake/manual/automake.html#Hard_002dCoded-Install-Paths
"My package needs to populate the installation directory of another
package at install-time. I can easily compute that installation
directory in configure, but if I install files therein,
'make distcheck' fails. How else should I do?"
[3] polkit(8), Declaring Actions
https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html#polkit-declaring-actions
"A mechanism need to declare a set of actions in order to use
polkit. Actions correspond to operations that clients can request
the mechanism to carry out and are defined in XML files that the
mechanism installs into the /usr/share/polkit-1/actions directory."
[4] Not installing to hard-coded locations vs polkit's fixed location
http://lists.gnu.org/archive/html/automake/2017-08/msg00015.html
Bug 776437 - GParted fails to run as root under Wayland
Many of the distributions (confirmed for Arch Linux, Debian, Fedora,
OpenSUSE, RedHat/CentOS and Ubuntu but likely many others too) are now
using polkit as the mechanism to authorise privileged actions, including
using it to authorise GParted to run as root in their packages of
GParted. Therefore make the GParted configure script check for the
pkexec command.
Use pkexec with the --disable-internal-agent option when available,
preventing pkexec using it's own textual authentication agent. When
running GParted from a desktop icon or menu there is no terminal with
which to interact with the textual authentication agent to it can't be
used. The desktop's graphical agent must be running. This matches how
some distributions already use polkit in their own packages of GParted.
Required actions file will be added in the next commit.
polkit(8)
https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html
pkexec(1)
https://www.freedesktop.org/software/polkit/docs/latest/pkexec.1.html
Bug 776437 - GParted fails to run as root under Wayland
Now that the gparted script is intended to be run by ordinary users, as
well as root, install it into directory $prefix/bin rather than
$prefix/sbin.
Bug 776437 - GParted fails to run as root under Wayland
Move calling of the privilege escalation program which allows a normal
user to run GParted as root from the desktop file into the gparted
wrapper script. This is in preparation for further changes needed to
grant root access to the X11 display under Wayland.
Don't introduce yet another script so that there aren't two different
names to run GParted by for normal users and root. Using the same
gparted name but placing two different scripts at /usr/bin/gparted and
/usr/sbin/gparted is not possible because on Arch Linux /usr/sbin is a
symbolic link to /usr/bin.
Frequently asked questions, Does Arch follow the FHS?
https://wiki.archlinux.org/index.php/Frequently_asked_questions#Does_Arch_follow_the_FHS.3F
"Arch Linux follows the file system hierarchy for operating systems
using the systemd service manager. See file-hierarchy(7) for an
explanation of each directory along with their designations. In
particular, /bin, /sbin, and /usr/sbin are symbolic links to
/usr/bin, and /lib (and /lib64 if applicable) are symbolic links to
/usr/lib".
Bug 776437 - GParted fails to run as root under Wayland
When udftools are not installed and the mkudffs program isn't found
GParted would report this error during startup:
# ./gpartedbin
======================
libparted : 3.1
======================
Failed to execute child process "mkudffs" (No such file or directory)
Only run mkudffs to check for an old version when the program is found.
Bug 786050 - GParted reports failed to execute child process "mkudffs"
when it is not installed