Pass device and partition names to blkid (#131)
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
This commit is contained in:
parent
75bda733bb
commit
8b35892ea5
|
@ -38,7 +38,7 @@ struct FS_Entry
|
|||
class FS_Info
|
||||
{
|
||||
public:
|
||||
static void load_cache_for_paths( const std::vector<Glib::ustring> &device_paths );
|
||||
static void load_cache_for_paths(const std::vector<Glib::ustring>& paths);
|
||||
static Glib::ustring get_fs_type( const Glib::ustring & path );
|
||||
static Glib::ustring get_label( const Glib::ustring & path, bool & found );
|
||||
static Glib::ustring get_uuid( const Glib::ustring & path );
|
||||
|
@ -49,9 +49,9 @@ private:
|
|||
static void initialize_if_required();
|
||||
static void set_commands_found();
|
||||
static const FS_Entry & get_cache_entry_by_path( const Glib::ustring & path );
|
||||
static void load_fs_info_cache();
|
||||
static void load_fs_info_cache(const std::vector<Glib::ustring>& paths);
|
||||
static void load_fs_info_cache_extra_for_path( const Glib::ustring & path );
|
||||
static bool run_blkid_load_cache( const Glib::ustring & path = "" );
|
||||
static bool run_blkid_load_cache(const std::vector<Glib::ustring>& paths);
|
||||
static void update_fs_info_cache_all_labels();
|
||||
static bool run_blkid_update_cache_one_label( FS_Entry & fs_entry );
|
||||
|
||||
|
|
|
@ -37,33 +37,32 @@ bool FS_Info::need_blkid_vfat_cache_update_workaround = true;
|
|||
// Vector of file system information.
|
||||
// E.g.
|
||||
// (Note BS(path) is a short hand for constructor BlockSpecial(path)).
|
||||
// //path , type , sec_type, uuid , have_label, label
|
||||
// [{BS("/dev/sda1") , "xfs" , "" , "f828ee8c-1e16-4ca9-b234-e4949dcd4bd1" , false , "" },
|
||||
// {BS("/dev/sda2") , "LVM2_member", "" , "p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG", false , "" },
|
||||
// {BS("/dev/block/8:2") , "LVM2_member", "" , "p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG", false , "" },
|
||||
// {BS("/dev/mapper/centos-root"), "xfs" , "" , "a195605d-22c1-422d-9213-1ed67f1eee46" , false , "" },
|
||||
// {BS("/dev/mapper/centos-swap"), "swap" , "" , "8d419cb6-c663-4db7-b91c-6bcef8418a4d" , false , "" },
|
||||
// {BS("/dev/sdb1") , "ext3" , "ext2" , "f218c3b8-237e-4fbe-92c5-76623bba4062" , true , "test-ext3" },
|
||||
// {BS("/dev/sdb2") , "vfat" , "msdos" , "9F87-1061" , true , "TEST-FAT16"},
|
||||
// {BS("/dev/sdb3") , "" , "" , "" , false , "" }
|
||||
// //path , type , sec_type, uuid , have_label, label
|
||||
// [{BS("/dev/sda") , "" , "" , "" , false , "" },
|
||||
// {BS("/dev/sda1"), "xfs" , "" , "f828ee8c-1e16-4ca9-b234-e4949dcd4bd1" , false , "" },
|
||||
// {BS("/dev/sda2"), "LVM2_member", "" , "p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG", false , "" },
|
||||
// {BS("/dev/sdb") , "" , "" , "" , false , "" },
|
||||
// {BS("/dev/sdb1"), "ext3" , "ext2" , "f218c3b8-237e-4fbe-92c5-76623bba4062" , true , "test-ext3" },
|
||||
// {BS("/dev/sdb2"), "vfat" , "msdos" , "9F87-1061" , true , "TEST-FAT16"},
|
||||
// {BS("/dev/sdb3"), "" , "" , "" , false , "" }
|
||||
// ]
|
||||
std::vector<FS_Entry> FS_Info::fs_info_cache;
|
||||
|
||||
|
||||
void FS_Info::load_cache_for_paths( const std::vector<Glib::ustring> &device_paths )
|
||||
void FS_Info::load_cache_for_paths(const std::vector<Glib::ustring>& paths)
|
||||
{
|
||||
set_commands_found();
|
||||
load_fs_info_cache();
|
||||
load_fs_info_cache(paths);
|
||||
fs_info_cache_initialized = true;
|
||||
|
||||
const BlockSpecial empty_bs = BlockSpecial();
|
||||
for ( unsigned int i = 0 ; i < device_paths.size() ; i ++ )
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
const FS_Entry & fs_entry = get_cache_entry_by_path( device_paths[i] );
|
||||
const FS_Entry& fs_entry = get_cache_entry_by_path(paths[i]);
|
||||
if ( fs_entry.path == empty_bs )
|
||||
{
|
||||
// Run "blkid PATH" and load entry into cache for missing entries.
|
||||
load_fs_info_cache_extra_for_path( device_paths[i] );
|
||||
load_fs_info_cache_extra_for_path(paths[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +164,8 @@ void FS_Info::initialize_if_required()
|
|||
if ( ! fs_info_cache_initialized )
|
||||
{
|
||||
set_commands_found();
|
||||
load_fs_info_cache();
|
||||
std::vector<Glib::ustring> empty;
|
||||
load_fs_info_cache(empty);
|
||||
fs_info_cache_initialized = true;
|
||||
}
|
||||
}
|
||||
|
@ -204,11 +204,12 @@ const FS_Entry & FS_Info::get_cache_entry_by_path( const Glib::ustring & path )
|
|||
return not_found;
|
||||
}
|
||||
|
||||
void FS_Info::load_fs_info_cache()
|
||||
|
||||
void FS_Info::load_fs_info_cache(const std::vector<Glib::ustring>& paths)
|
||||
{
|
||||
fs_info_cache.clear();
|
||||
// Run "blkid" and load entries into the cache.
|
||||
run_blkid_load_cache();
|
||||
run_blkid_load_cache(paths);
|
||||
|
||||
// (#771244) Ensure the cache has entries for all whole disk devices, even if
|
||||
// those entries are blank. Needed so that an ISO9660 image stored on a whole
|
||||
|
@ -228,7 +229,9 @@ void FS_Info::load_fs_info_cache()
|
|||
|
||||
void FS_Info::load_fs_info_cache_extra_for_path( const Glib::ustring & path )
|
||||
{
|
||||
bool entry_added = run_blkid_load_cache( path );
|
||||
std::vector<Glib::ustring> one_path;
|
||||
one_path.push_back(path);
|
||||
bool entry_added = run_blkid_load_cache(one_path);
|
||||
if ( ! entry_added )
|
||||
{
|
||||
// Ran "blkid PATH" but didn't find details suitable for loading as a
|
||||
|
@ -238,17 +241,19 @@ void FS_Info::load_fs_info_cache_extra_for_path( const Glib::ustring & path )
|
|||
}
|
||||
}
|
||||
|
||||
bool FS_Info::run_blkid_load_cache( const Glib::ustring & path )
|
||||
|
||||
bool FS_Info::run_blkid_load_cache(const std::vector<Glib::ustring>& paths)
|
||||
{
|
||||
// Parse blkid output line by line extracting mandatory field: path and optional
|
||||
// fields: type, sec_type, uuid. Label is not extracted here because of blkid's
|
||||
// default non-reversible encoding of non printable ASCII bytes.
|
||||
// Example command:
|
||||
// blkid /dev/sda /dev/sda1 /dev/sda2 /dev/sdb /dev/sdb1 /dev/sdb2 /dev/sdb3
|
||||
// Example output:
|
||||
// /dev/sda: PTUUID="5012fb1f" PTTYPE="dos"
|
||||
// /dev/sda1: UUID="f828ee8c-1e16-4ca9-b234-e4949dcd4bd1" TYPE="xfs"
|
||||
// /dev/sda2: UUID="p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG" TYPE="LVM2_member"
|
||||
// /dev/block/8:2: UUID="p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG" TYPE="LVM2_member"
|
||||
// /dev/mapper/centos-root: UUID="a195605d-22c1-422d-9213-1ed67f1eee46" TYPE="xfs"
|
||||
// /dev/mapper/centos-swap: UUID="8d419cb6-c663-4db7-b91c-6bcef8418a4d" TYPE="swap"
|
||||
// /dev/sdb: PTUUID="f57595e1-c0ae-40ee-be64-00851b2a9977" PTTYPE="gpt"
|
||||
// /dev/sdb1: LABEL="test-ext3" UUID="f218c3b8-237e-4fbe-92c5-76623bba4062" SEC_TYPE="ext2" TYPE="ext3" PARTUUID="71b3e059-30c5-492e-a526-9251dff7bbeb"
|
||||
// /dev/sdb2: SEC_TYPE="msdos" LABEL="TEST-FAT16" UUID="9F87-1061" TYPE="vfat" PARTUUID="9d07ad9a-d468-428f-9bfd-724f5efae4fb"
|
||||
// /dev/sdb3: PARTUUID="bb8438e1-d9f1-45d3-9888-e990b598900d"
|
||||
|
@ -257,8 +262,8 @@ bool FS_Info::run_blkid_load_cache( const Glib::ustring & path )
|
|||
return false;
|
||||
|
||||
Glib::ustring cmd = "blkid";
|
||||
if ( path.size() )
|
||||
cmd = cmd + " " + Glib::shell_quote( path );
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
cmd.append(" " + Glib::shell_quote(paths[i]));
|
||||
|
||||
Glib::ustring output;
|
||||
Glib::ustring error;
|
||||
|
|
|
@ -247,20 +247,10 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
|
|||
}
|
||||
}
|
||||
|
||||
std::cout << "DEBUG: device_paths=[";
|
||||
for (unsigned int i = 0; i < device_paths.size(); i++)
|
||||
std::cout << (i>0?",":"") << "\"" << device_paths[i] << "\"";
|
||||
std::cout << "]" << std::endl;
|
||||
|
||||
// Initialise and load caches needed for content discovery.
|
||||
const std::vector<Glib::ustring>& device_and_partition_paths =
|
||||
Proc_Partitions_Info::get_device_and_partition_paths_for(device_paths);
|
||||
std::cout << "DEBUG: device_and_partition_paths=[";
|
||||
for (unsigned int i = 0; i < device_and_partition_paths.size(); i++)
|
||||
std::cout << (i>0?",":"") << "\"" << device_and_partition_paths[i] << "\"";
|
||||
std::cout << "]" << std::endl;
|
||||
|
||||
// Initialise and load caches needed for content discovery.
|
||||
FS_Info::load_cache_for_paths(device_paths);
|
||||
FS_Info::load_cache_for_paths(device_and_partition_paths);
|
||||
Mount_Info::load_cache();
|
||||
LVM2_PV_Info::clear_cache();
|
||||
btrfs::clear_cache();
|
||||
|
|
Loading…
Reference in New Issue