"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/Proc_Partitions_Info.cc" between
gparted-1.2.0.tar.gz and gparted-1.3.0.tar.gz

About: GParted is a graphical partition editor for creating, reorganizing, and deleting disk partitions (using GNU libparted).

Proc_Partitions_Info.cc  (gparted-1.2.0):Proc_Partitions_Info.cc  (gparted-1.3.0)
skipping to change at line 25 skipping to change at line 25
*/ */
#include "Proc_Partitions_Info.h" #include "Proc_Partitions_Info.h"
#include "BlockSpecial.h" #include "BlockSpecial.h"
#include "Utils.h" #include "Utils.h"
#include <glibmm/ustring.h> #include <glibmm/ustring.h>
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <stdio.h> #include <stdio.h>
#include <ctype.h>
namespace GParted namespace GParted
{ {
//Initialize static data elements //Initialize static data elements
bool Proc_Partitions_Info::proc_partitions_info_cache_initialized = false ; bool Proc_Partitions_Info::proc_partitions_info_cache_initialized = false ;
// Cache of all entries from /proc/partitions.
// E.g. [BlockSpecial("/dev/sda"), BlockSpecial("/dev/sda1"), BlockSpecial("/dev
/sda2"), ...]
std::vector<BlockSpecial> Proc_Partitions_Info::all_entries_cache;
// Cache of device names read from /proc/partitions that GParted will present by
default
// as partitionable.
// E.g. ["/dev/sda", "/dev/sdb", "/dev/md1"]
std::vector<Glib::ustring> Proc_Partitions_Info::device_paths_cache ; std::vector<Glib::ustring> Proc_Partitions_Info::device_paths_cache ;
void Proc_Partitions_Info::load_cache() void Proc_Partitions_Info::load_cache()
{ {
load_proc_partitions_info_cache(); load_proc_partitions_info_cache();
proc_partitions_info_cache_initialized = true; proc_partitions_info_cache_initialized = true;
} }
const std::vector<Glib::ustring> & Proc_Partitions_Info::get_device_paths() const std::vector<Glib::ustring> & Proc_Partitions_Info::get_device_paths()
{ {
initialize_if_required(); initialize_if_required();
return device_paths_cache; return device_paths_cache;
} }
// E.g. ["/dev/sda", "/tmp/fs.img"] -> ["/dev/sda", "/dev/sda1", "/dev/sda2", "/
tmp/fs.img"]
std::vector<Glib::ustring> Proc_Partitions_Info::get_device_and_partition_paths_
for(
const std::vector<Glib::ustring>& device_paths)
{
initialize_if_required();
std::vector<Glib::ustring> all_paths;
for (unsigned int i = 0; i < device_paths.size(); i++)
{
all_paths.push_back(device_paths[i]);
const std::vector<Glib::ustring>& part_paths = get_partition_path
s_for(device_paths[i]);
all_paths.insert(all_paths.end(), part_paths.begin(), part_paths.
end());
}
return all_paths;
}
// Private Methods // Private Methods
void Proc_Partitions_Info::initialize_if_required() void Proc_Partitions_Info::initialize_if_required()
{ {
if ( ! proc_partitions_info_cache_initialized ) if ( ! proc_partitions_info_cache_initialized )
{ {
load_proc_partitions_info_cache(); load_proc_partitions_info_cache();
proc_partitions_info_cache_initialized = true; proc_partitions_info_cache_initialized = true;
} }
} }
void Proc_Partitions_Info::load_proc_partitions_info_cache() void Proc_Partitions_Info::load_proc_partitions_info_cache()
{ {
device_paths_cache .clear() ; all_entries_cache.clear();
device_paths_cache.clear();
std::ifstream proc_partitions( "/proc/partitions" ) ; std::ifstream proc_partitions( "/proc/partitions" ) ;
if ( proc_partitions ) if ( proc_partitions )
{ {
std::string line ; std::string line ;
Glib::ustring device;
while ( getline( proc_partitions, line ) ) while ( getline( proc_partitions, line ) )
{ {
// Pre-populate BlockSpecial cache with major, minor numb
ers of
// all names found from /proc/partitions.
Glib::ustring name = Utils::regexp_label( line, Glib::ustring name = Utils::regexp_label( line,
"^[[:blank:]]*[[:digit:]]+[[:blank:]]+[[:digit:]] +[[:blank:]]+[[:digit:]]+[[:blank:]]+([[:graph:]]+)$" ); "^[[:blank:]]*[[:digit:]]+[[:blank:]]+[[:digit:]] +[[:blank:]]+[[:digit:]]+[[:blank:]]+([[:graph:]]+)$" );
if ( name == "" ) if ( name == "" )
continue; continue;
// Pre-populate BlockSpecial cache to avoid stat() call a
nd save
// all entries from /proc/partitions for device to partit
ion
// mapping.
unsigned long maj; unsigned long maj;
unsigned long min; unsigned long min;
if ( sscanf( line.c_str(), "%lu %lu", &maj, &min ) != 2 ) if ( sscanf( line.c_str(), "%lu %lu", &maj, &min ) != 2 )
continue; continue;
BlockSpecial::register_block_special( "/dev/" + name, maj , min ); BlockSpecial::register_block_special( "/dev/" + name, maj , min );
all_entries_cache.push_back(BlockSpecial("/dev/" + name)) ;
// Recognise only whole disk device names, excluding part // Save recognised whole disk device names for later retu
itions, rning as
// from /proc/partitions and save in this cache. // the default GParted partitionable devices.
if (is_whole_disk_device_name(name))
//Whole disk devices are the ones we want. device_paths_cache.push_back("/dev/" + name);
//Device names without a trailing digit refer to the whol
e 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 device
s which
// plug directly into PCIe sockets).
// E.g., device = /dev/nvme0n1, partition = /dev/nvme0n1p
1
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/ccis
s/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/c0
d0p1
// (linux-x.y.z/Documentation/blockdev/cpqarray.txt)
//Device names for Mylex DAC960/AcceleRAID/eXtremeRAID PC
I RAID
// E.g., device = /dev/rd/c0d0, partition = /dev/rd/c0d0
p1
// (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 );
}
} }
proc_partitions .close() ; proc_partitions .close() ;
} }
} }
}//GParted // True only for whole disk device names which GParted will present by default a
s
// 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;
}
// Return all partitions for a whole disk device.
// E.g. get_partitions_for("/dev/sda") -> ["/dev/sda1", "/dev/sda2"]
std::vector<Glib::ustring> Proc_Partitions_Info::get_partition_paths_for(const G
lib::ustring& device)
{
// Assumes that entries from /proc/partitions are:
// 1. Always ordered with whole device followed by any partitions for tha
t device.
// 2. Partition names are the whole device names appended with optional "
p" and
// partition number.
// This is confirmed by checking Linux kernel block/genhd.c:show_partitio
n()
// function which prints the content of /proc/partitions.
// https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/
block/genhd.c?h=v5.10.12#n1175
std::vector<Glib::ustring> partitions;
BlockSpecial bs = BlockSpecial(device);
// Find matching whole disk device entry from /proc/partitions cache.
unsigned int i = 0;
bool found_device = false;
for (; i < all_entries_cache.size(); i++)
{
if (bs == all_entries_cache[i])
{
found_device = true;
break;
}
}
if (! found_device)
return partitions; // Empty vector
// Find following partition entries from /proc/partitions cache.
for (i++; i < all_entries_cache.size(); i++)
{
if (is_partition_of_device(all_entries_cache[i].m_name, bs.m_name
))
partitions.push_back(all_entries_cache[i].m_name);
else
// No more partitions for this whole disk device.
break;
}
return partitions;
}
// True if and only if devname is a leading substring of partname and the remain
der
// consists of optional "p" and digits.
// E.g. ("/dev/sda1", "/dev/sda") -> true ("/dev/md1p2", "/dev/md1") -> true
bool Proc_Partitions_Info::is_partition_of_device(const Glib::ustring& partname,
const Glib::ustring& devname)
{
// Linux kernel function block/genhd.c:disk_name() formats device and par
tition
// names written to /proc/partitions.
// https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/
block/genhd.c?h=v5.10.12#n73
size_t devname_len = devname.length();
if (partname.compare(0, devname_len, devname) != 0)
return false;
size_t i = devname_len;
if (partname.length() <= i)
return false;
if (partname[i] == 'p')
i ++;
if (partname.length() <= i)
return false;
for (i++; i < partname.length(); i++)
{
if (! isdigit(partname[i]))
return false;
}
return true;
}
} //GParted
 End of changes. 10 change blocks. 
60 lines changed or deleted 44 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)