From 52930f30ae8dc2c9dd1f64d2df654d9f1a1afb8a Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Thu, 21 Jan 2021 22:01:08 +0000 Subject: [PATCH] Refactor load_proc_partitions_info_cache() a bit (#131) 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 --- include/Proc_Partitions_Info.h | 2 + src/Proc_Partitions_Info.cc | 93 ++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 45 deletions(-) diff --git a/include/Proc_Partitions_Info.h b/include/Proc_Partitions_Info.h index 23b4348a..5769fb98 100644 --- a/include/Proc_Partitions_Info.h +++ b/include/Proc_Partitions_Info.h @@ -39,6 +39,8 @@ public: private: static void initialize_if_required(); static void load_proc_partitions_info_cache(); + static bool is_whole_disk_device_name(const Glib::ustring& name); + static bool proc_partitions_info_cache_initialized ; static std::vector device_paths_cache ; }; diff --git a/src/Proc_Partitions_Info.cc b/src/Proc_Partitions_Info.cc index f3aa77fc..dc94ec0e 100644 --- a/src/Proc_Partitions_Info.cc +++ b/src/Proc_Partitions_Info.cc @@ -61,66 +61,69 @@ void Proc_Partitions_Info::load_proc_partitions_info_cache() if ( proc_partitions ) { std::string line ; - Glib::ustring device; while ( getline( proc_partitions, line ) ) { - // Pre-populate BlockSpecial cache with major, minor numbers of - // all names found from /proc/partitions. Glib::ustring name = Utils::regexp_label( line, "^[[:blank:]]*[[:digit:]]+[[:blank:]]+[[:digit:]]+[[:blank:]]+[[:digit:]]+[[:blank:]]+([[:graph:]]+)$" ); if ( name == "" ) continue; + + // Pre-populate BlockSpecial cache to avoid stat() call for all + // entries from /proc/partitions. unsigned long maj; unsigned long min; if ( sscanf( line.c_str(), "%lu %lu", &maj, &min ) != 2 ) continue; BlockSpecial::register_block_special( "/dev/" + name, maj, min ); - // Recognise only whole disk device names, excluding partitions, - // from /proc/partitions and save in this cache. - - //Whole disk devices are the ones we want. - //Device names without a trailing digit refer to the whole disk. - device = Utils::regexp_label( name, "^([^0-9]+)$" ); - - //Recognize /dev/md* devices (Linux software RAID - mdadm). - //E.g., device = /dev/md127, partition = /dev/md127p1 - if ( device == "" ) - device = Utils::regexp_label( name, "^(md[0-9]+)$" ); - - //Recognize /dev/mmcblk* devices. - //E.g., device = /dev/mmcblk0, partition = /dev/mmcblk0p1 - if ( device == "" ) - device = Utils::regexp_label( name, "^(mmcblk[0-9]+)$" ); - - // Recognise /dev/nvme*n* devices - // (Non-Volatile Memory Express devices. SSD type devices which - // plug directly into PCIe sockets). - // E.g., device = /dev/nvme0n1, partition = /dev/nvme0n1p1 - if ( device == "" ) - device = Utils::regexp_label( name, "^(nvme[0-9]+n[0-9]+)$" ); - - //Device names that end with a #[^p]# are HP Smart Array Devices (disks) - // E.g., device = /dev/cciss/c0d0, partition = /dev/cciss/c0d0p1 - // (linux-x.y.z/Documentation/blockdev/cciss.txt) - //Device names for Compaq SMART2 Intelligent Disk Array - // E.g., device = /dev/ida/c0d0, partition = /dev/ida/c0d0p1 - // (linux-x.y.z/Documentation/blockdev/cpqarray.txt) - //Device names for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID - // E.g., device = /dev/rd/c0d0, partition = /dev/rd/c0d0p1 - // (linux-x.y.z/Documentation/blockdev/README.DAC960) - if ( device == "" ) - device = Utils::regexp_label( name, "^([a-z]+/c[0-9]+d[0-9]+)$" ); - - if ( device != "" ) - { - //add potential device to the list - device_paths_cache.push_back( "/dev/" + device ); - } + // Save recognised whole disk device names for later returning as + // the default GParted partitionable devices. + if (is_whole_disk_device_name(name)) + device_paths_cache.push_back("/dev/" + name); } proc_partitions .close() ; } } -}//GParted + +// True only for whole disk device names which GParted will present by default as +// partitionable. +bool Proc_Partitions_Info::is_whole_disk_device_name(const Glib::ustring& name) +{ + // Match ordinary whole disk device names. + // E.g.: device = sda (partition = sda1) + if (Utils::regexp_label(name, "^([^0-9]+)$") != "") + return true; + + // Match Linux software RAID (mdadm) device names. + // E.g.: device = md127 (partition = md127p1) + if (Utils::regexp_label(name, "^(md[0-9]+)$") != "") + + // Match SD/MMC card whole disk devices names. + // E.g.: device = mmcblk0 (partition = mmcblk0p1) + if (Utils::regexp_label(name, "^(md[0-9]+)$") != "") + return true; + + // Match NVME (Non-Volatile Memory Express) whole disk device names. + // E.g.: device = nvme0n1 (partition = nvme0n1p1) + if (Utils::regexp_label(name, "^(nvme[0-9]+n[0-9]+)$") != "") + return true; + + // Match hardware RAID controller whole disk device names. + // * HP Smart Array (linux-x.y.z/Documentation/scsi/hpsa.rst). + // E.g.: device = cciss/c0d0 (partition = cciss/c0d0p1) + // * Compaq SMART2 Intelligent Disk Array + // (linux-x.y.z/Documentation/admin-guide/devices.txt) + // E.g.: device = ida/c0d0 (partition = ida/c0d0p1) + // * Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID + // (linux-x.y.z/Documentation/admin-guide/devices.txt) + // E.g.: device = rd/c0d0 (partition = rd/c0d0p1) + if (Utils::regexp_label(name, "^([a-z]+/c[0-9]+d[0-9]+)$") != "") + return true; + + return false; +} + + +} //GParted