Initialise partition content discovery caches a bit later (#131)

PATCHSET OVERVIEW

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 /usr/sbin/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 ...>

Tracing 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

Going to fix this by making GParted specify the 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.

THIS PATCH

Move the loading and initialising of caches used during content
discovery to after device and partition discovery and just before
content discovery.  Just makes the code ready for the next change.

Closes #131 - GParted hangs when non-named device is hung
This commit is contained in:
Mike Fleetwood 2021-01-19 19:28:59 +00:00 committed by Curtis Gedak
parent f5fb86dbd3
commit a8cd7a4e80

View file

@ -146,19 +146,14 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
{
std::vector<Device> &devices = *pdevices;
devices .clear() ;
// Initialise and load caches needed for device discovery.
BlockSpecial::clear_cache(); // MUST BE FIRST. Cache of name to major, minor
// numbers incrementally loaded when BlockSpecial
// objects are created in the following caches.
Proc_Partitions_Info::load_cache(); // SHOULD BE SECOND. Caches /proc/partitions and
// pre-populates BlockSpecial cache.
FS_Info::load_cache(); // SHOULD BE THRID. Caches file system details
// from blkid output.
DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
LVM2_PV_Info::clear_cache(); // Cache automatically loaded if and when needed
btrfs::clear_cache(); // Cache incrementally loaded if and when needed
SWRaid_Info::load_cache();
LUKS_Info::clear_cache(); // Cache automatically loaded if and when needed
Mount_Info::load_cache();
//only probe if no devices were specified as arguments..
if ( probe_devices )
@ -252,6 +247,14 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
}
}
// Initialise and load caches needed for content discovery.
FS_Info::load_cache(); // Cache of file system details from blkid.
Mount_Info::load_cache();
LVM2_PV_Info::clear_cache();
btrfs::clear_cache();
SWRaid_Info::load_cache();
LUKS_Info::clear_cache();
// Ensure all named paths have FS_Info blkid cache entries specifically so that
// command line named file system image files, which blkid can't otherwise know
// about, can be identified.