Move busy detection of SWRaid members into the new module (#756829)
Add active attribute to the cache of SWRaid members. Move parsing of /proc/mdstat to discover busy SWRaid members into the cache loading code. New parsing code is a little different because it is finding all members of active arrays rather than determining if a specific member is active. Bug 756829 - SWRaid member detection enhancements
This commit is contained in:
parent
5f02bcf463
commit
0ce9857380
|
@ -30,18 +30,26 @@
|
|||
namespace GParted
|
||||
{
|
||||
|
||||
struct SWRaid_Member
|
||||
{
|
||||
Glib::ustring member;
|
||||
bool active;
|
||||
};
|
||||
|
||||
class SWRaid_Info
|
||||
{
|
||||
public:
|
||||
static void load_cache();
|
||||
static bool is_member( const Glib::ustring & member_path );
|
||||
static bool is_member_active( const Glib::ustring & member_path );
|
||||
|
||||
private:
|
||||
static void set_command_found();
|
||||
static void load_swraid_info_cache();
|
||||
static SWRaid_Member & get_cache_entry_by_member( const Glib::ustring & member_path );
|
||||
|
||||
static bool mdadm_found;
|
||||
static std::vector<Glib::ustring> swraid_info_cache;
|
||||
static std::vector<SWRaid_Member> swraid_info_cache;
|
||||
};
|
||||
|
||||
}//GParted
|
||||
|
|
|
@ -181,7 +181,6 @@ public:
|
|||
static Glib::ustring get_filesystem_software( FILESYSTEM filesystem ) ;
|
||||
static bool kernel_supports_fs( const Glib::ustring & fs ) ;
|
||||
static bool kernel_version_at_least( int major_ver, int minor_ver, int patch_ver ) ;
|
||||
static bool swraid_member_is_active( const Glib::ustring & path ) ;
|
||||
static Glib::ustring format_size( Sector sectors, Byte_Value sector_size ) ;
|
||||
static Glib::ustring format_time( std::time_t seconds ) ;
|
||||
static double sector_to_unit( Sector sectors, Byte_Value sector_size, SIZE_UNIT size_unit ) ;
|
||||
|
|
|
@ -1857,7 +1857,7 @@ bool GParted_Core::is_busy( FILESYSTEM fstype, const Glib::ustring & path )
|
|||
busy = is_dev_mounted( path ) ;
|
||||
|
||||
//Custom checks for recognised but other not-supported file system types
|
||||
busy |= ( fstype == FS_LINUX_SWRAID && Utils::swraid_member_is_active( path ) ) ;
|
||||
busy |= ( fstype == FS_LINUX_SWRAID && SWRaid_Info::is_member_active( path ) );
|
||||
}
|
||||
|
||||
return busy ;
|
||||
|
|
|
@ -19,19 +19,25 @@
|
|||
#include "../include/Utils.h"
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
||||
// Data model:
|
||||
// mdadm_found - Is the "mdadm" command available?
|
||||
// swraid_info_cache - Vector of /dev entries of members in Linux Software RAID arrays.
|
||||
// swraid_info_cache - Vector of member information in Linux Software RAID arrays.
|
||||
// E.g.
|
||||
// ["/dev/sda1", "/dev/sda2", ...]
|
||||
// //member , active
|
||||
// [{"/dev/sda1", true },
|
||||
// {"/dev/sda2", true },
|
||||
// {"/dev/sda6", false},
|
||||
// {"/dev/sdb6", false}
|
||||
// ]
|
||||
|
||||
// Initialise static data elements
|
||||
bool SWRaid_Info::mdadm_found = false;
|
||||
std::vector<Glib::ustring> SWRaid_Info::swraid_info_cache;
|
||||
std::vector<SWRaid_Member> SWRaid_Info::swraid_info_cache;
|
||||
|
||||
void SWRaid_Info::load_cache()
|
||||
{
|
||||
|
@ -41,13 +47,22 @@ void SWRaid_Info::load_cache()
|
|||
|
||||
bool SWRaid_Info::is_member( const Glib::ustring & member_path )
|
||||
{
|
||||
for ( unsigned int i = 0 ; i < swraid_info_cache.size() ; i ++ )
|
||||
if ( member_path == swraid_info_cache[i] )
|
||||
return true;
|
||||
const SWRaid_Member & memb = get_cache_entry_by_member( member_path );
|
||||
if ( memb.member == member_path )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SWRaid_Info::is_member_active( const Glib::ustring & member_path )
|
||||
{
|
||||
const SWRaid_Member & memb = get_cache_entry_by_member( member_path );
|
||||
if ( memb.member == member_path )
|
||||
return memb.active;
|
||||
|
||||
return false; // No such member
|
||||
}
|
||||
|
||||
// Private methods
|
||||
|
||||
void SWRaid_Info::set_command_found()
|
||||
|
@ -113,12 +128,67 @@ void SWRaid_Info::load_swraid_info_cache()
|
|||
std::vector<Glib::ustring> devices;
|
||||
Utils::split( devices_str, devices, "," );
|
||||
for ( unsigned int j = 0 ; j < devices.size() ; j ++ )
|
||||
swraid_info_cache.push_back( devices[j] );
|
||||
{
|
||||
SWRaid_Member memb;
|
||||
memb.member = devices[j];
|
||||
memb.active = false;
|
||||
swraid_info_cache.push_back( memb );
|
||||
}
|
||||
}
|
||||
else
|
||||
line_type = LINE_TYPE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
// Set which SWRaid members are active.
|
||||
std::string line;
|
||||
std::ifstream input( "/proc/mdstat" );
|
||||
if ( input )
|
||||
{
|
||||
// Read /proc/mdstat extracting members for active arrays, marking them
|
||||
// active in the cache. Example fragment of /proc/mdstat:
|
||||
// md1 : active raid1 sdb1[0] sdb2[1]
|
||||
// 1047552 blocks super 1.2 [2/2] [UU]
|
||||
while ( getline( input, line ) )
|
||||
{
|
||||
if ( line.find( " : active " ) != std::string::npos )
|
||||
{
|
||||
// Found a line for an active array. Split into space
|
||||
// separated fields.
|
||||
std::vector<Glib::ustring> fields;
|
||||
Utils::tokenize( line, fields, " " );
|
||||
for ( unsigned int i = 0 ; i < fields.size() ; i ++ )
|
||||
{
|
||||
Glib::ustring::size_type index = fields[i].find( "[" );
|
||||
if ( index != Glib::ustring::npos )
|
||||
{
|
||||
// Field contains an "[" so got a short
|
||||
// kernel device name of a member. Mark
|
||||
// as active.
|
||||
Glib::ustring mpath = "/dev/" +
|
||||
fields[i].substr( 0, index );
|
||||
SWRaid_Member & memb = get_cache_entry_by_member( mpath );
|
||||
if ( memb.member == mpath )
|
||||
memb.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Perform linear search of the cache to find the matching member.
|
||||
// Returns found cache entry or not found substitute.
|
||||
SWRaid_Member & SWRaid_Info::get_cache_entry_by_member( const Glib::ustring & member_path )
|
||||
{
|
||||
for ( unsigned int i = 0 ; i < swraid_info_cache.size() ; i ++ )
|
||||
{
|
||||
if ( member_path == swraid_info_cache[i].member )
|
||||
return swraid_info_cache[i];
|
||||
}
|
||||
static SWRaid_Member memb = {"", false};
|
||||
return memb;
|
||||
}
|
||||
|
||||
} //GParted
|
||||
|
|
33
src/Utils.cc
33
src/Utils.cc
|
@ -401,39 +401,6 @@ bool Utils::kernel_version_at_least( int major_ver, int minor_ver, int patch_ver
|
|||
return result ;
|
||||
}
|
||||
|
||||
//Report whether the device is an active member of a Linux Software RAID array
|
||||
bool Utils::swraid_member_is_active( const Glib::ustring & path )
|
||||
{
|
||||
//Read /proc/mdstat and look for the device name on an active RAID array
|
||||
// line. Example line: "md1 : active raid1 sda1[2] sdb1[3]"
|
||||
// ^^^^^^
|
||||
// needle
|
||||
// Strip "/dev/" prefix and search for device name with surrounding
|
||||
// " " and "[" to avoid substring matches.
|
||||
if ( path .substr( 0, 5 ) != "/dev/" )
|
||||
return false ;
|
||||
|
||||
bool member_active = false ;
|
||||
Glib::ustring needle = " " + path .substr( 5 ) + "[" ;
|
||||
std::string line ;
|
||||
std::ifstream input( "/proc/mdstat" ) ;
|
||||
if ( input )
|
||||
{
|
||||
while ( getline( input, line ) )
|
||||
{
|
||||
if ( line .find( " : active " ) != std::string::npos
|
||||
&& line .find( needle ) != std::string::npos )
|
||||
{
|
||||
member_active = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
input .close() ;
|
||||
}
|
||||
|
||||
return member_active ;
|
||||
}
|
||||
|
||||
Glib::ustring Utils::format_size( Sector sectors, Byte_Value sector_size )
|
||||
{
|
||||
std::stringstream ss ;
|
||||
|
|
Loading…
Reference in New Issue