Trying to create an XFS file system causes the following error and
the create new xfs file system step to never complete.
# ./gpartedbin
======================
libparted : 2.4
======================
(gpartedbin:15572): 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 "mylabel" " /dev/sdb8')
Creation of XFS file systems was broken by the extra stray double quote
added to the command before the device name, by commit:
63aeb150ac
Rename member variables and methods in Partition class (#741424)
Bug 744108 - Creating an XFS file system never completes
Encountered this dialog:
Libparted Bug Found!
(-) Invalid argument during seek for read on /dev/md1
[ Retry ] [ Cancel ] [ Ignore ]
After investigation found that GParted was asking libparted to read from
sector -1. Libparted was actually reporting an error but GParted was
incorrectly displaying this as a bug. This was because setting the
dialog title was falling through from the error case to the bug case.
Fix this.
Also provide unique titles for all libparted exception types so that
they can all be distinguished.
* List of exceptions from libparted: enum _PedExceptionType
http://www.gnu.org/software/parted/api/group__PedException.html
Bug 743825 - gparted displaying dialog: libparted bug found!
Provide credit for patch to add support for GPT partition names.
Also indicate significant effort by Sinlu Bes while we tried different
ideas for how GPT partition name support should work.
Embedded devices (Android) use GPT partition names to identify
partitions, instead of file system labels. Add support for viewing and
changing them.
As partition names are used to provide unique identification they are
never copied when copying the contents of one partition to another.
Note that GNU/Linux uses file system labels, UUIDs or device names for
identification during the boot process and afterwards so while partition
names can be used, they are optional and purely for user information.
Bug 741424 - Add support for GPT partition names
This and the following few commits rename variables, methods, classes,
etc from *label_partition* to *label_filesystem* so that the code also
reflects that it is the label of the file system that is being modified
and to separate it from the name partition operation about to be added.
enum OPERATION_LABEL_PARTITION -> OPERATION_LABEL_FILESYSTEM
Bug 741424 - Add support for GPT partition names
Rename the Partition Label concept to File System Label throughout the
GUI. This is to better reflect that it is the label of the file system
that is being modified and to separate it from the Partition Name
concept about to be added.
Bug 741424 - Add support for GPT partition names
GParted reports used figure of active swap space from 4 KiB upwards,
actually 1 page, where as 'swapon -s' reports figures from 0 upwards.
This is because GParted is counting the 1 page swap space overhead as
used space.
# sfdisk -s /dev/sdb1
262144
# mkswap /dev/sdb1
# swapon /dev/sdb1
# swapon -s
Filename Type Size Used Priority
/dev/sdb1 partition 262140 0 -1
For this case GParted reports used as 4 KiB.
(ptn size - swap size = 262144 - 262140 = 4)
Instead make GParted report used figure without any overhead from 0
upwards, matching what 'swapon -s' reports.
Bug 742647 - Swap usage doesn't match figures reported by swapon -s
GParted's internal block copy has an off by one sector bug when the
source is before the destination; and the copy is performed backwards
from high block to low block. It is as though the source and
destination partitions were both one sector earlier on the disk.
In ASCII art it it looks like this:
Initial layout: x<--SRC--><--DST-->
Actually wrote: x<--SRC--
Should have written: <--SRC-->
Affects moving partitions too.
This bug has existed since commit:
bd9e16f22f
Thread the internal copy algorithm (#685740)
Effectively the last sector of the partition is missed and one sector
before the start of the partition is corrupted. Most of the time file
systems don't get around to using the very last sector so didn't notice.
Bug 742920 - GParted internal copy is overstepping partition boundaries
With reiser4progs 1.0.7 and earlier mkfs specifically checks for Linux
kernel 2.5 or 2.6. On Linux 3.x it fails with the following warning:
# mkfs.reiser4 --yes --label "" /dev/sdb1
Warn : Linux 3.13.0-39-generic is detected. Reiser4 does not support
such a platform. Use -f to force over.
# echo $?
8
This is fixed in reiser4progs 1.0.8 and later. From the reiser4progs
SourceForce README.txt:
. Do not ask for confirmation to work under Linux-3.X;
Found on Ubuntu 12.04 LTS and Ubuntu 14.04 LTS both with reiser4progs
1.0.7 and a Linux 3.x kernel.
Fix by adding "--force" flag to the mkfs command line.
Bug 742511 - Creation of reiser4 file systems fails with unsupported
warning
Split the resizing file system and resizing partition calls in
GParted_Core::resize() into separate grow and shrink code paths.
Note that this also changes the degenerative case of calling resize()
when the partition isn't changing size, for non-swap partitions, from a
file system check step to a successful no-op. This doesn't matter as my
testing never found resize() to be called when the partition isn't
changing size.
Also correct spelling of local variable success.
Bug 741211 - Remove unnecessary duplicate actions when resizing a
partition
Shrinking swap partition operation performs these steps:
Shrink /dev/sdb2 from 2.00 GiB to 1.00 GiB
+ calibrate /dev/sdb2
+ check file system on /dev/sdb2 for errors and (if possible) fix them
checking is not available for this file system
+ shrink file system
+ create new linux-swap file system
+ mkswap -L "test-swap" -U "bd381eba-5df7-42e2-8e0e-411e9701c995" /dev/sdb2
+ shrink partition from 2.00 GiB to 1.00 GiB
+ create new linux-swap file system
+ mkswap -L "test-swap" -U "bd381eba-5df7-42e2-8e0e-411e9701c995" /dev/sdb2
Resizing a linux-swap partition was partially special cased in
GParted_Core::resize(). Make it fully special cased so that it just
does the following steps. No more skipped file system checks or extra
resizing.
1) Resize partition,
2) Recreate linux-swap.
This existing call chain recreates the linux-swap:
GParted_Core::resize_filesystem()
linux_swap::resize()
A compound move and resize operation still performs unnecessary checks
and recreates of linux-swap, but less than before.
Bug 741211 - Remove unnecessary duplicate actions when resizing a
partition
Shrinking a partition performs a single file system check step, but
growing a partition still performs two file system checks.
Grow /dev/sda8 from 1.00 GiB to 10.00 GiB
+ calibrate /dev/sda8
+ check file system on /dev/sda8 for errors and (if possible) fix them
+ grow partition from 1.00 GiB to 10.00 GiB
+ check file system on /dev/sda8 for errors and (if possible) fix them
+ grow file system to fill the partition
This is a leftover from the early days of GParted when resizing a
partition used cylinder buffering and performed three file system
checks. See prior to commit:
d663c3c277
removed cylindersize buffering during resize from the filesystems.
Remove the second file system check when growing a partition.
Bug 741211 - Remove unnecessary duplicate actions when resizing a
partition
Simplify how the list of file system types is populated in the Create
New Partition dialog. Change from copying everything and removing
unwanted items to only copying required items. Makes the code simpler
and therefore easier to understand.
Only recognises ReFS file system. No other actions are supported.
Requires blkid from util-linux >= 2.24.
Bug #738471 - ReFS file system is not recognised
Use GParted_Core::supported_filesystem() to remove the need to
explicitly list the growing number of recognised, but otherwise
unsupported, file system signatures in multiple places.
Bug #738471 - ReFS file system is not recognised
Helper to check whether a recognised file system type is supported by
GParted or not. Supported means there is an implementation class and
will appear in the File System Support dialog.
Make supported_filesystem() a static member function so that it can be
called without a class object so that GParted_Core::GParted_Core()
initialiser isn't called multiple times. This requires FILESYSTEM_MAP
to become a static member variable too.
Bug #738471 - ReFS file system is not recognised
get_filesystem_object() takes a constant reference to a FILESYSTEM, but
FILESYSTEM is just an enumeration. So that's a pointer to a constant
int. Just pass by value instead.
RHEL / CentOS 5.6 and later officially support ext4 file system [1].
From RHEL / CentOS 5.3 ext4 file system was included as a technology
preview. Ext4 file system tools are in a separate package e4fsprogs,
using uniquely named commands. The standard e2fsprogs commands only
support ext2 and ext3 file systems.
# mkfs.ext4 /dev/sdb3
# tune2fs -l /dev/sdb3
tune2fs 1.39 (29-May-2006)
tune2fs: Filesystem has unsupported feature(s) while trying to open /dev/sdb3
Couldn't find valid filesystem superblock.
# echo $?
1
# tune4fs -l /dev/sdb3
tune4fs 1.41.12 (17-May-2010)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: ba4a9d58-7728-4b47-8a90-80e772615637
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
...
For ext4 only, search for the e4fsprogs specific commands first and the
standard e2fsprogs commands second.
[1] RHEL 5.6 Release Notes, 5. Filesystems and Storage
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/5.6_Release_Notes/ar01s05.html
Bug #738706 - GParted doesn't support ext4 on RHEL/CentOS 5.x
Automatic selection of the largest unallocated partition caused flashing
redraw of the partition graphic and partition list. Both the partition
graphic and partition list were being drawn blank then redrawn fully
populated. This only happened on some distributions including:
CentOS 5.10, 6.5, 7.0, Debian 6, Fedora 14, 20, Xubuntu 14.04 LTS. Did
not happen on: Kubuntu 12.04 LTS.
This is a workaround, not a complete fix. It moves automatic selection
of the largest unallocated partition to after processing of the GTK
Event loop in Refresh_Visual() which redraws the partition graphic and
partition list. These visuals are now drawn only once, fully populated,
however this draws them without the selected partition. The partition
selection is then drawn afterwards which causes the selection to flash
instead. This is significant improvement to the whole partition graphic
and partition list flashing when redrawn.
Bug #696149 - Double refresh of display introduced with default
unallocated space
The device combobox was getting drawn blank, then getting drawn again
with the selected device. This was happening because at the start of
Win_GParted::refresh_combo_devices() the GTK model behind the combobox,
liststore_devices, was cleared, changing the active item, causing the
combobox to get redrawn empty. After the GTK model had been repopulated
the active item was reset causing the comboxbox to get redrawn again,
now showing the selected device. Call flow:
Win_GParted::refresh_combo_devices()
liststore_devices->clear()
//Gtk::Combobox emits signal_change. Registered callbacks
//called.
Win_GParted::combo_devices_changed()
Win_GParted::Refresh_Visual()
...
...
combo_devices.set_active(current_device);
//Gtk::Combobox emits signal_change. Registered callbacks
//called.
Win_GParted::combo_devices_changed()
Win_GParted::Refresh_Visual()
...
This has always been the case, since the device combobox was first added
to GParted before version 0.1 by commit:
3a4b43e0ad
replaced deprecated OptionMenu with ComboBox ...
Fix by temporarily blocking the devices comboxbox from emitting
signal_changed while the GTK model behind the combobox is recreated.
However, since automatic selection of the largest free space was added
[1] in GParted 0.15.0, a more noticeable flashing redraw issue was
caused in which the partition graphic and partition list were both drawn
blank then redrawn fully populated. Some distributions were not
affected by this at all, some only experienced a single flash and others
suffered from two or more flashing redraws. Some affected
distributions: CentOS 5.10, 6.5, 7.0, Debian 6, Fedora 14, 19, 20,
Ubuntu 13.10, Xubuntu 14.04 LTS. Did not occur on Kubuntu 12.04 LTS.
[1] 5b53c12f6e
Select largest unallocated partition by default (#667365)
Bug #696149 - Double refresh of display introduced with default
unallocated space
Automake 1.13 and later generates the following warning when building
GParted from git:
$ ./autogen.sh
...
checking for automake >= 1.9...
testing automake-1.13... found 1.13.4
...
Running automake-1.13...
src/Makefile.am:1: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')
...
INCLUDES name has been depreciated since automake 1.7. GParted's
autogen.sh and configure.ac require at least automake 1.9. Therefore
replace automake variable INCLUDES with AM_CPPFLAGS.
Bug #735742 - automake warns INCLUDES is deprecated
Use AC_ARG_ENABLE() and AS_HELP_STRING() macros to improve handling of
the --disable-doc option.
Change the names, and sence, of the Autoconf and Automake definitions
used to control building of the help documentation. Reasons are:
(1) Switch from negative to positive statements which are more natural
to comprehend.
(2) Insert HELP in the names from *_DOC to *_HELP_DOC as they control
building of the documentation in the help subdirectory, not the
manual page in the doc directory.
Autoconf: HAVE_DISABLE_DOC -> ENABLE_HELP_DOC
Automake: DISABLE_DOC -> BUILD_HELP_DOC
Bug #734076 - Autodetect parted online partition resizing capability
Currently -lparted is passed to the linker by being hard coded in the
gpartedbin_LDFLAGS variable in src/Makefile.am and -lparted-fs-resize
by conditionally being appended to the gpartedbin_LDFLAGS.
Add an Autoconf AC_CHECK_LIB check for the parted library using it's
default action-if-found to extend LIBS. Update the existing
AC_CHECK_LIB check for the parted-fs-resize library so that the
overridden action-if-found also extends LIBS with -lparted-fs-resize.
These libraries are then assigned via the LIBS variable in the
generated Makefiles.
This matches how the other libraries, dl and uuid, were found in the
configure script and passed to the Makefiles.
Bug #734718 - Update Autoconf version specific libparted checks and
defines to feature specific ones
Remove HAVE_LIBPARTED_2_2_0_PLUS definition
Rename version specific #define HAVE_LIBPARTED_2_2_0_PLUS into two
separate feature specific names set as required:
Name Set when?
ENABLE_PT_REREAD_WORKAROUND (libparted < 2.2)
USE_LIBPARTED_LARGE_SECTOR_SUPPORT (libparted >= 2.2)
Using feature specific #defines is the standard Autoconf way and makes
the resultant conditional code easier to understand. Still have to
check the version of libparted though.
Bug #734718 - Update Autoconf version specific libparted checks and
defines to feature specific ones
Remove HAVE_LIBPARTED_3_0_0_PLUS definition
The #define only controls whether fat16 and fat32 file systems are moved
by libparted (for versions <= 2.4) or the GParted internal algorithm
(for libparted versions >= 3.0). See this commit for more details:
0fda1d011d
Enable new fs resize library available with parted-3.1 (#668281)
As nearly all other file system are moved using the GParted internal
algorithm, just always use it to move fat16 and fat32 file systems too.
Bug #734718 - Update Autoconf version specific libparted checks and
defines to feature specific ones
This patch changes the reading of the btrfs multi-device membership to
resolve issue 1/2 by ignoring the exit status from the 'btrfs filesystem
show' command and relying on parsing the required information to
determine success or failure.
Bug #733601 - Btrfs: Warnings and missing label with btrfs-progs 3.12
and 3.14
Patch 3/4 - btrfs::read_label()
This patch changes the btrfs file system usage reading code to resolve
issue 1/2 by ignoring the exit status from the 'btrfs filesystem show'
command and relying on parsing the required information to determine
success or failure.
Bug #733601 - Btrfs: Warnings and missing label with btrfs-progs 3.12
and 3.14
Issue 2/2 - GParted doesn't show label for mounted btrfs file systems
'btrfs filesystem show /dev/PTN' command is used to query details of a
btrfs file system including reading the file system label. When the
file system is mounted the label is no longer enclosed in single quotes,
but only when using btrfs-progs v3.12. This causes GParted to think the
label is blank when the file system is mounted and therefore no longer
display it.
File system label not enclosed in single quotes when mounted:
# fgrep sdb1 /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,relatime,space_cache 0 0
# btrfs filesystem show /dev/sdb1
Label: test1-btrfs uuid: 1f78fa38-2f85-41d3-9be6-ae0356ae9469
Total devices 1 FS bytes used 192.00KiB
devid 1 size 2.00GiB used 240.75MiB path /dev/sdb1
Btrfs v3.12
File system label enclosed in single quotes when unmounted:
# umount /dev/sdb1
# btrfs filesystem show /dev/sdb1
Label: 'test1-btrfs' uuid: 1f78fa38-2f85-41d3-9be6-ae0356ae9469
Total devices 1 FS bytes used 192.00KiB
devid 1 size 2.00GiB used 240.75MiB path /dev/sdb1
Btrfs v3.12
Removing the single quotes enclosing the label makes the output
identical to that from the older 'btrfs-show' command.
Fix by using a common parser to extract the label from both the
'btrfs filesystem show' and 'btrfs-show' commands which can read the
label with and without enclosing single quotes.
Patch 2/4 - btrfs::read_label()
This patch changes the btrfs file system label parsing code to resolve
issue 1/2 by ignoring the exit status from the 'btrfs filesystem show'
command and relying on parsing the required information to determine
success or failure. Issue 2/2 is also resolved as described above.
Bug #733601 - Btrfs: Warnings and missing label with btrfs-progs 3.12
and 3.14
Issue 1/2 - GParted shows warnings for mounted btrfs file systems
'btrfs filesystem show /dev/PTN' command is used to query details of a
btrfs file system. When the file system is mounted the command reports
failed exit status 1, but only when using btrfs-progs v3.14 and v3.14.1.
This causes GParted to: (1) report warnings from the failed commands for
a mounted btrfs file system, (2) fail to determine file system usage
figures and (3) fail to display the mount point and busy indicator for
non-mounting devices in multi-device btrfs file systems. The label is
also read using the secondary blkid method via the FS_Info cache.
Failed exit status 1 when the btrfs file system is mounted:
# fgrep sdb1 /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,space_cache 0 0
# btrfs filesystem show /dev/sdb1
Label: 'test1-btrfs' uuid: 033e6b07-ee6a-4620-a585-8580a2b83275
Total devices 1 FS bytes used 192.00KiB
devid 1 size 2.00GiB used 240.75MiB path /dev/sdb1
Btrfs v3.14.1
# echo $?
1
Successful exit status 0 when the btrfs file system is unmounted:
# umount /dev/sdb1
# btrfs filesystem show /dev/sdb1
Label: 'test1-btrfs' uuid: 033e6b07-ee6a-4620-a585-8580a2b83275
Total devices 1 FS bytes used 192.00KiB
devid 1 size 2.00GiB used 240.75MiB path /dev/sdb1
Btrfs v3.14.1
# echo $?
0
Fix by ignoring the exit status of the 'btrfs filesystem show' command
and rely on parsing the required information to determine success or
failure. The output from the older 'btrfs-show' command is almost
identical so the same code will parse it in all cases.
Patch 1/4 - btrfs::read_uuid()
This patch changes the secondary method used to read the btrfs UUID to
resolve issue 1/2 as described above.
Bug #733601 - Btrfs: Warnings and missing label with btrfs-progs 3.12
and 3.14
While one partition is busy, reformat another partition from the command
line. Afterwards parted/libparted still detects the original file
system and GParted shows errors from the file system specific tools
reporting the new file system doesn't exist. Only limitation is that
the new new file system must be recognised by libparted (or by GParted's
fallback file system signature detection).
Case #1, File system reformatting:
# parted /dev/sdb print
Model: ATA SAMSUNG SSD UM41 (scsi)
Disk /dev/sdb: 8012MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 2149MB 2147MB primary ext2
2 2149MB 4296MB 2147MB primary ext2
# mount | fgrep sdb
/dev/sdb1 on /mnt/1 type ext2 (rw)
# mkfs.xfs -f /dev/sdb2
# blkid /dev/sdb2
/dev/sdb2: UUID="c31823a2-b81b-46fa-8246-0a59695e4834" TYPE="xfs"
# parted /dev/sdb print
Model: ATA SAMSUNG SSD UM41 (scsi)
Disk /dev/sdb: 8012MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type File system Flags
1 1049kB 2149MB 2147MB primary ext2
2 2149MB 4296MB 2147MB primary ext2
# e2label /dev/sdb2
e2label: Bad magic number in super-block while trying to open /dev/sdb2
Couldn't find valid filesystem superblock.
# dumpe2fs /dev/sdb2
dumpe2fs 1.41.12 (17-May-2010)
dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb2
Couldn't find valid filesystem superblock.
Case #2, Removing device from multi-device btrfs:
# btrfs filesystem show /dev/sdb1
Label: none uuid: a05db434-efd5-4e8c-902f-05f89a88b610
Total devices 2 FS bytes used 156.00KB
devid 2 size 2.00GB used 512.00MB path /dev/sdb2
devid 1 size 2.00GB used 240.75MB path /dev/sdb1
# mount /dev/sdb1 /mnt/1
# btrfs device delete /dev/sdb2
# btrfs filesystem show /dev/sdb1
Label: none uuid: a05db434-efd5-4e8c-902f-05f89a88b610
Total devices 1 FS bytes used 92.00KB
devid 1 size 2.00GB used 714.25MB path /dev/sdb1
# btrfs filesystem show /dev/sdb2
and GParted reports this error for partition /dev/sdb2:
Unable to read the contents of this file system!
Because of this some operations may be unavailable.
The cause might be a missing software package.
The following list of software packages is required for btrfs
file system support: btrfs-tools.
This is another case of libparted reading from the whole disk device
(/dev/sdb) yet the file system tools use the partition specific block
device (/dev/sdb2), and the Linux buffer cache not providing cache
coherency. Previous scenario was fixed with:
797f0b8eeb
Flush device after wiping a file system (#688882)
This affects libparted 2.0 to 3.1 inclusive and is fixed by:
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
Revert "linux-commit: do not unnecessarily open partition device nodes"
Fix by calling ped_device_sync() to guarantee cache coherency for each
device during scanning.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
With linux 3.5 and later, the device used to mount a btrfs file system
is updated in /proc/mounts when the previous mounting device is removed
from the file system. Most recent distributions make /etc/mtab a
symbolic link to /proc/mounts. However some still have /etc/mtab as a
plain file only updated by mount and umount, thus showing the old device
name which is no longer part of the file system.
On Ubuntu 13.10, which has /etc/mtab as a plain file managed by mount
and umount:
# mkfs.btrfs /dev/sdb1
# mount /dev/sdb1 /mnt/1
# btrfs device add /dev/sdb2 /mnt/1
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: e47775a6-e5ad-4fb4-9ea4-1570aa5b4009
Total devices 2 FS bytes used 28.00KB
devid 2 size 2.00GB used 272.00MB path /dev/sdb2
# fgrep btrfs /proc/mounts
/dev/sdb2 /mnt/1 btrfs rw,relatime,space_cache 0 0
# ls -l /etc/mtab
-rw-r--r-- 1 root root 842 Apr 15 19:41 /etc/mtab
# fgrep btrfs /etc/mtab
/dev/sdb1 /mnt/1 btrfs rw 0 0
This causes GParted to report /dev/sdb1 as busy and mounted at /mnt/1
when it is no longer mounted. This effects recent releases of Ubuntu,
13.04, 13.10 and 14.04.
Either /etc/mtab is a symlink and is identical to /proc/mounts or
/etc/mtab is a plain file with wrong information. Fix by not reading
mounted file systems from /etc/mtab.
However old distributions only contain 'rootfs' and '/dev/root' device
names for the / (root) file system with '/dev/root' being a block device
rather than a symlink to the true device. For example from CentOS 5.x:
# fgrep ' / ' /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / ext3 rw,data=ordered 0 0
# ls -l /dev/root
brw------- 1 root root 8, 3 Jun 4 2013 /dev/root
This prevents identification, and therefore busy detection, of the
device containing the / (root) file system. Used to read /etc/mtab to
get the root file system device name.
# fgrep ' / ' /etc/mtab
/dev/sda3 / ext3 rw 0 0
# ls -l /dev/sda3
brw-r----- 1 root disk 8, 3 Jun 4 2013 /dev/sda3
As per commit:
409096f739
improved scanning for root mountpoint (/) ...
but, as discussed above, this contains an out of date device name after
the mounting device has been dynamically removed from a multi-device
btrfs, thus identifying the wrong device as busy. Instead fall back to
reading mounted file systems from the output of the mount command, but
only when required.
# mount | fgrep ' / '
/dev/sda3 on / type ext3 (rw)
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
In a number of cases there may be no btrfs device cache entry. Some of
the reasons why this can occur:
1) Mounting device removed from btrfs on linux <= 3.4 so old mount
point in /proc/mounts;
2) btrfs and btrfs-show commands don't exist;
3) btrfs or btrfs-show command returned non-zero exit status;
4) get_cache_entry() failed to parse output from btrfs filesystem show
or btrfs-show.
Without a valid btrfs device cache entry, busy detection for all member
devices fails. Search the GParted internal mounted partitions map as
the fallback busy detection method. This can only determine if the
mounting device is mounted or not, not any of the other members of a
multi-device btrfs file system.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
GParted doesn't specify the devid when resizing a btrfs file system, so
the kernel defaults to resizing devid 1. On a multi-device btrfs this
may not be the same partition which GParted is resizing. This will
result in file system truncation and corruption. Shrinking the wrong
partition example:
1) Create a btrfs file system spanning 2 partitions:
# mkfs.btrfs /dev/sdb1 /dev/sdb2
# btrfs filesystem show /dev/sdb1
Label: none uuid: 41654265-9840-45c4-aca1-55989da358d6
Total devices 2 FS bytes used 112.00KiB
devid 1 size 2.00GiB used 437.50MiB path /dev/sdb1
devid 2 size 2.00GiB used 417.50MiB path /dev/sdb2
2) Resize /dev/sdb2 down to 1 GiB using GParted. This command was
run:
btrfs filesystem resize 1048576K /tmp/gparted-ddyGRh
which resized devid 1 (/dev/sdb1) to 1 GiB:
# btrfs filesystem show /dev/sdb1
Label: none uuid: 41654265-9840-45c4-aca1-55989da358d6
Total devices 2 FS bytes used 256.00KiB
devid 1 size 1.00GiB used 437.50MiB path /dev/sdb1
devid 2 size 2.00GiB used 417.50MiB path /dev/sdb2
but GParted instead resized /dev/sdb2 to 1 GiB:
# sfdisk -s /dev/sdb1
2097152
# sfdisk -s /dev/sdb2
1048576
Even on a single device btrfs devid 1 may no longer exist if the file
system has had the initial device removed from it. Example:
1) Create a single btrfs file system, add a second device and
remove the first:
# mkfs.btrfs /dev/sdb1
# mount /dev/sdb1 /mnt/1
# btrfs device add /dev/sdb2 /mnt/1
# btrfs device remove /dev/sdb1 /mnt/1
# umount /mnt/1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 2cbf3ac3-1344-472a-a0c7-1476d23bdc9f
Total devices 1 FS bytes used 256.00KiB
devid 2 size 2.00GiB used 480.00MiB path /dev/sdb2
2) Again resize /dev/sdb2 down to 1 GiB using GParted. This
command was run:
btrfs filesystem resize 1048576K /tmp/gparted-ddyGRh
but it failed with:
ERROR: unable to resize 'tmp/gparted-lEyGaY' - No such device
A more informative error message was written to syslog:
# tail -1 /var/log/messages
Mar 12 14:15:01 localhost kernel: btrfs: resizer unable to find device 1
This is with Linux kernel 3.13.5 on Fedora 20, circa March 2014.
Fix by specifying the devid when resizing (part of) a btrfs file system.
Example command specifying devid 2:
btrfs filesystem resize 2:1048576K /tmp/1
This will always work because it is the kernel which interprets the
devid colon size parameter and has always done so since btrfs was first
added to the kernel in version 2.6.32 [1].
Reference:
[1] linux v2.6.32 fs/btrfs/ioctl.c btrfs_ioctl_resize()
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/btrfs/ioctl.c?id=v2.6.32#n578
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Currently GParted fails to report the usage of a multi-device btrfs file
system if it is mounted or if the used space is larger than the size of
an individual member device. When GParted does display usage figures it
also incorrectly reports the file system wide used figure against every
member device.
Mounted case:
statvfs() provides an FS size which is larger than any individual
device so is rejected. See:
GParted_Core::mounted_set_used_sectors()
Utils::get_mounted_filesystem_usage()
partition .set_sector_usage()
Unmounted case, FS used > device size:
FS used figure is larger than any individual device so free space is
calculated as a negative number and rejected. See:
btrfs::set_used_sectors()
Btrfs has a volume manager layer within the file system which allows it
to provide multiple levels of data redundancy, RAID levels, and use
multiple devices both of which can be changed while the file system is
mounted. To achieve this btrfs has to allocate space at two different
level: (1) chunks of 256 MiB or more at the volume manager level; and
(2) extents at the file data level.
References:
* Btrfs: Working with multiple devices
https://lwn.net/Articles/577961/
* Btrfs wiki: Glossary
https://btrfs.wiki.kernel.org/index.php/Glossary
This makes the question of how much disk space is being used in an
individual device a complicated question to answer. Further, the
current btrfs tools don't provide the required information.
Btrfs filesystem show only provides space usage information at the chunk
level per device. At the file extent level only a single figure for the
whole file system is provided. It also reports size of the data and
metadata being stored, not the larger figure of the amount of space
taken after redundancy is applied. So it is impossible to answer the
question of how much disk space is being used in an individual device.
Example output:
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 2 FS bytes used 156.00KB
devid 2 size 2.00GB used 512.00MB path /dev/sdb2
devid 1 size 2.00GB used 240.75MB path /dev/sdb1
Fix by guesstimating the per device used figure as the fraction of the
file system wide extent usage based on chunk usage per device.
Calculation:
ptn fs used = total fs used * devid used / sum devid used
Positives:
1) Per device used figure will correctly be between zero and allocated
chunk size.
Known inaccuracies:
[for single and multi-device btrfs file systems]
1) Btrfs filesystem show reports file system wide file extent usage
without considering redundancy applied to that data. (By default
btrfs stores two copies of metadata and one copy of data).
2) At minimum size when all data has been consolidated there will be a
few partly filled chunks of 256 MiB or more for data and metadata of
each storage profile (RAID level).
[for multi-device btrfs file systems only]
3) Data may be far from evenly distributed between the chunks on
multiple devices.
4) Extents can be and are relocated to other devices within the file
system when shrinking a device.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Linux can only show a single device name in /proc/mounts and /etc/mtab
for each mounted btrfs, even if it is a multi-device file system. So
GParted only shows a mount point for one of the devices in the btrfs, no
matter how many devices are part of the file system.
# mkfs.btrfs /dev/sdb1 /dev/sdb2
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 2 FS bytes used 156.00KB
devid 2 size 2.00GB used 512.00MB path /dev/sdb2
devid 1 size 2.00GB used 240.75MB path /dev/sdb1
# mount /dev/sdb1 /mnt/1
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted only shows the mount point for /dev/sdb1 as /mnt/1, but nothing
for /dev/sdb2.
Make GParted report the same mount point for all devices included in a
multi-device btrfs file system.
Add btrfs specific get_mount_device() method to report the mounting
device, if any, for the btrfs file system in the occupying the device in
question. Uses the existing cache of btrfs file system device
membership. Also extract common code from GParted_Core::
set_mountpoints() into set_mountpoints_helper().
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map). For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.
# btrfs filesystem show /dev/sdb1
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 2 FS bytes used 156.00KB
devid 2 size 2.00GB used 512.00MB path /dev/sdb2
devid 1 size 2.00GB used 240.75MB path /dev/sdb1
# mount /dev/sdb1 /mnt/1
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.
Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted. This uses a
cache which maps device membership in all btrfs file systems. The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.
WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4. This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.
# btrfs device delete /dev/sdb1 /mnt/1
# sync
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# btrfs filesystem show /dev/sdb1
# btrfs filesystem show /dev/sdb2
Label: none uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Fixed in linux 3.5 by commit:
Btrfs: implement ->show_devname
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Add static member function GParted_Core::is_dev_mounted() so that other
modules can determine if a particular partition contains a mounted file
system or not.
Make it a static member function so that it can be called without
needing the gparted_core object. Extend to make the group of
manipulated variables (mount_info, fstab_info) and manipulating
functions (init_maps(), read_mountpoints_from_file(),
read_mountpoints_from_file_swaps(), get_all_mountpoints()) static too.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Previous commit:
Make partition busy detection method selectable per file system
(#723842)
causes GParted to no longer detect an unknown mounted file system as
busy.
This is needed because there are many less popular file systems which
Linux can mount but GParted doesn't recognise, such as: Acorn ADFS,
AFFS, BeFS, BFS, etc. Encountering an unrecognised mounted device can
also occur with btrfs on Linux 3.4 and earlier when the mounting device
is deleted from a multi-device btrfs file system. Happens because
/proc/mounts continues to show the original mounting device even after
that device was deleted from the file system.
# mkfs.btrfs /dev/sdb1
# mount /dev/sdb1 /mnt/1
# btrfs device add /dev/sdb2 /mnt/1
# btrfs device delete /dev/sdb1 /mnt/1
# btrfs filesystem sync /mnt/1
# grep btrfs /proc/mounts
/dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
# blkid /dev/sdb1
# btrfs filesystem show /dev/sdb1
# blkid /dev/sdb2
/dev/sdb2: UUID="9c75647c-217a-4718-bcc7-f3ccd8cc7dc6" UUID_SUB="b5d43630-80d4-42ac-b406-185e97cd5bbe" TYPE="btrfs"
# btrfs filesystem show /dev/sdb2
Label: none uuid: 9c75647c-217a-4718-bcc7-f3ccd8cc7dc6
Total devices 1 FS bytes used 28.00KB
devid 2 size 2.00GB used 1.02GB path /dev/sdb2
Reinstate the search for mounted partitions for busy detection even for
unrecognised file system types.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
GParted's primary inbuilt busy detection method is "is the partition
mounted?". A custom method is used for LVM2 PV because its not a
mounted file system.
Make busy detection selectable per file system type.
.fs.busy = FS::NONE (default)
No busy detection.
.fs.busy = FS::GPARTED
Use internal GParted method which checks if the partition is
mounted.
.fs.busy = FS:EXTERNAL
Call the file system type's member function is_busy().
LVM2 PV busy detection changes from a special case to just electing to
call the lvm2_pv::is_busy() method. Linux Software RAID remains a
special case because it's only recognised, but not otherwise supported.
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
devid to btrfs filesystem resize)
Fragment of debugging and valgrind output:
D: tid=2193 main()
...
D: tid=2202 GParted_Core::set_devices_thread()
...
D: tid=2202 Utils::execute_command(command="dumpe2fs -h /dev/sda1", output, error, use_C_locale=1)
D: tid=2202 this=0x13fef4a0 PipeCapture::PipeCapture()
D: tid=2202 this=0x13fef4f0 PipeCapture::PipeCapture()
D: tid=2202 this=0x13fef4a0 PipeCapture::connect_signal()
D: sourceid=77
D: tid=2202 this=0x13fef4f0 PipeCapture::connect_signal()
D: sourceid=78
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D: signal_update.emit()
D: return true
D: tid=2193 data=0x13fef4f0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4f0 PipeCapture::OnReadable()
D: signal_update.emit()
D: return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D: signal_update.emit()
D: return true
D: tid=2193 data=0x13fef4f0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4f0 PipeCapture::OnReadable()
D: signal_eof.emit()
D: return false
D: (!rc) &(pc->sourceid)=0x13fef518
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D: signal_update.emit()
D: return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D: signal_update.emit()
D: return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D: signal_eof.emit()
D: tid=2202 this=0x13fef4f0 PipeCapture::~PipeCapture()
D: sourceid=0
D: tid=2202 this=0x13fef4a0 PipeCapture::~PipeCapture()
D: sourceid=77
D: return false
D: (!rc) &(pc->sourceid)=0x13fef4c8
==2193== Thread 1:
==2193== Invalid write of size 4
==2193== at 0x490580: GParted::PipeCapture::_OnReadable(_GIOChannel*, GIOCondition, void*) (PipeCapture.cc:56)
==2193== by 0x38662492A5: g_main_context_dispatch (gmain.c:3066)
==2193== by 0x3866249627: g_main_context_iterate.isra.24 (gmain.c:3713)
==2193== by 0x3866249A39: g_main_loop_run (gmain.c:3907)
==2193== by 0x3D7FD45C26: gtk_main (gtkmain.c:1257)
==2193== by 0x469743: GParted::GParted_Core::set_devices(std::vector<GParted::Device, std::allocator<GParted::Device> >&) (GParted_Core.cc:155)
==2193== by 0x4A78F1: GParted::Win_GParted::menu_gparted_refresh_devices() (Win_GParted.cc:1259)
==2193== by 0x4A7886: GParted::Win_GParted::on_show() (Win_GParted.cc:1253)
==2193== by 0x3D82B2009C: Gtk::Widget_Class::show_callback(_GtkWidget*) (widget.cc:3855)
==2193== by 0x3867210297: g_closure_invoke (gclosure.c:777)
==2193== by 0x3867221B86: signal_emit_unlocked_R (gsignal.c:3516)
==2193== by 0x386722A0F1: g_signal_emit_valist (gsignal.c:3330)
==2193== Address 0x13fef4c8 is not stack'd, malloc'd or (recently) free'd
==2193==
PipeCapture.cc (with debugging):
46 gboolean PipeCapture::_OnReadable( GIOChannel *source,
47 GIOCondition condition,
48 gpointer data )
49 {
50 std::cout << "D: tid=" << (long int)syscall(SYS_gettid) << " data=" << data << " PipeCapture::_OnReadable()" << std::endl;
51 PipeCapture *pc = static_cast<PipeCapture *>(data);
52 gboolean rc = pc->OnReadable( Glib::IOCondition(condition) );
53 if (!rc)
54 {
55 std::cout << "D: (!rc) &(pc->sourceid)=" << &(pc->sourceid) << std::endl;
56 pc->sourceid = 0;
57 }
58 return rc;
59 }
The use after free across threads only happens when an external program
is being executed from a thread other than the main() thread. This is
because by default glib registered callbacks are run by the glib main
loop, which is only called from the main() thread with Gtk::Main::run().
Event sequence:
tid=2193 tid=2202
main()
...
GParted_Core::set_devices()
Glib::Thread::create(... set_devices_thread ...)
Gtk::Main::run() GParted_Core::set_devices_thread()
...
Utils::execute_command("dumpe2fs ... /dev/sda1" ...)
Glib::spawn_async_with_pipes()
PipeCapture outputcapture(out, output)
outputcapture.connect_signal()
//Glib main loop runs callback
PipeCapture::_OnReadable()
pc->OnReadable()
//output read
signal_update.emit()
return true
...
//Glib main loop runs callback
PipeCapture::_OnReadable()
pc->OnReadable()
//eof reached
[1] signal_eof.emit()
return status.exit_status
[2] PipeCapture::~PipeCapture()
[3] return false
[4] pc->sourceid = 0
What is happening is that the PipeCapture destructor [2] is running in
the set_devices_thread() thread and freeing the object's memory as soon
as signal_eof.emit() [1] has been called. Then signal_eof.emit()
returns back to OnReadable() which then returns false [3] back to the
_OnReadable() callback function which then assigns 0 to sourceid member
variable [4] in the already freed object, detected by valgrind as:
Invalid write of size 4
at ... GParted::PipeCapture::_OnReadable(...) (PipeCapture.cc:56)
This is happening because PipeCapture member variable sourceid is being
saved, in a different thread, just so the _OnReadable() callback can be
removed. However a glib IOChannel callback, type GIOFunc(), returning
false will be automatically removed.
GLib Reference Manual 2.26 / IO Channels
https://developer.gnome.org/glib/2.26/glib-IO-Channels.html#GIOFunc
GIOFunc()
Returns : the function should return FALSE if the event source
should be removed
Therefore fix by just not saving the event sourceid at all, and not
calling g_source_remove() to manually remove the callback, but instead
letting glib automatically remove the callback when it returns false.
Bug #731752 - Write after free cross thread race in
PipeCapture::_OnReadable()
OperationDetail was storing its children in a std::vector. This means they
can be moved around in memory arbitrarily, going through indeterminate
lifetimes. This is generally a bad thing for any non trivial object and
in the case of OperationDetail, it created havoc with the way it maintains
pointers between parent/child objects for signal connections. It will now
keep only pointers to children in a std::vector instead, so their lifetime
can be controlled, fixing various crashes.
Bug 729139 - Refactor OperationDetail to address random behavior