mirror of
https://gitlab.gnome.org/GNOME/gparted
synced 2024-10-30 09:08:28 +00:00
Switch to using lvs to identify active LVM LVs (#160787)
Previously used "dmsetup info" to directly list device-mapper mapping names in the kernel to identify active Logical Volumes. However GParted failed to recognise active LVs if the VGNAME contains any hyphens (-). This is because LVM encodes hyphens as double hyphens in the mapping name. To avoid having to duplicate the LVM hyphen encoding in GParted, switch to using "lvm lvs" to list LVs. # dmsetup info --columns --noheadings --separator , -o name GParted_VG1-lvol_00 GParted--VG2-lvol--00 # lvm lvs --noheadings --separator , -o lv_name,vg_name,lv_attr lvol_00,GParted_VG1,-wi-a- lvol-00,GParted-VG2,-wi-a- lvol-01,GParted-VG3,-wi--- .^. (-) not active, (a) or any other character considered active. Reference lvs(8). Bug #160787 - lvm support
This commit is contained in:
parent
72ac712024
commit
820242635a
2 changed files with 46 additions and 30 deletions
|
@ -43,14 +43,13 @@ public:
|
|||
bool has_active_lvs( const Glib::ustring & path ) ;
|
||||
private:
|
||||
void initialize_if_required() ;
|
||||
void set_commands_found() ;
|
||||
void set_command_found() ;
|
||||
void load_lvm2_pv_info_cache() ;
|
||||
Glib::ustring get_pv_attr( const Glib::ustring & path, unsigned int entry ) ;
|
||||
static bool lvm2_pv_info_cache_initialized ;
|
||||
static bool lvm_found ;
|
||||
static bool dmsetup_found ;
|
||||
static std::vector<Glib::ustring> lvm2_pv_cache ;
|
||||
static Glib::ustring dmsetup_info_cache ;
|
||||
static std::vector<Glib::ustring> lvm2_lv_cache ;
|
||||
};
|
||||
|
||||
}//GParted
|
||||
|
|
|
@ -27,11 +27,17 @@ enum PV_ATTRIBUTE
|
|||
PVATTR_PV_FREE = 2
|
||||
} ;
|
||||
|
||||
enum LV_ATTRIBUTE
|
||||
{
|
||||
LVATTR_LV_NAME = 0,
|
||||
LVATTR_VG_NAME = 1,
|
||||
LVATTR_LV_BITS = 2
|
||||
} ;
|
||||
|
||||
//Data model:
|
||||
// lvm2_pv_info_cache_initialized
|
||||
// - Has the cache been loaded let?
|
||||
// lvm_found - Is the "lvm" command available?
|
||||
// dmsetup_found - Is the "dmsetup" command available?
|
||||
// lvm2_pv_cache - String vector storing attributes of a PV.
|
||||
// Attributes are: pv_name,vg_name,pv_free.
|
||||
// Pv_free is the number of free bytes.
|
||||
|
@ -39,15 +45,18 @@ enum PV_ATTRIBUTE
|
|||
// ["/dev/sda6,vg_test,4022337536",
|
||||
// "/dev/sda8,vg_test2,5087690752",
|
||||
// "/dev/sda10,,2147483648"]
|
||||
// dmsetup_info_cache - String storing active LVs. E.g.
|
||||
// "vg_test-lvol1\nvg_test-lvol0\nvg_test2-lvol0\n"
|
||||
// lvm2_lv_cache - String vector storing attributes of an LV.
|
||||
// Attributes are: lv_name,vg_name,lv_attrs.
|
||||
// See lvs(8) for details of lv_attrs.
|
||||
// E.g.
|
||||
// ["lvol0,vg_test,-wi---",
|
||||
// "lvol0,vg_test2,-wi-a-"]
|
||||
|
||||
//Initialize static data elements
|
||||
bool LVM2_PV_Info::lvm2_pv_info_cache_initialized = false ;
|
||||
bool LVM2_PV_Info::lvm_found = false ;
|
||||
bool LVM2_PV_Info::dmsetup_found = false ;
|
||||
std::vector<Glib::ustring> LVM2_PV_Info::lvm2_pv_cache ;
|
||||
Glib::ustring LVM2_PV_Info::dmsetup_info_cache = "" ;
|
||||
std::vector<Glib::ustring> LVM2_PV_Info::lvm2_lv_cache ;
|
||||
|
||||
LVM2_PV_Info::LVM2_PV_Info()
|
||||
{
|
||||
|
@ -57,7 +66,7 @@ LVM2_PV_Info::LVM2_PV_Info( bool do_refresh )
|
|||
{
|
||||
if ( do_refresh )
|
||||
{
|
||||
set_commands_found() ;
|
||||
set_command_found() ;
|
||||
load_lvm2_pv_info_cache() ;
|
||||
lvm2_pv_info_cache_initialized = true ;
|
||||
}
|
||||
|
@ -70,8 +79,8 @@ LVM2_PV_Info::~LVM2_PV_Info()
|
|||
bool LVM2_PV_Info::is_lvm2_pv_supported()
|
||||
{
|
||||
if ( ! lvm2_pv_info_cache_initialized )
|
||||
set_commands_found() ;
|
||||
return ( lvm_found && dmsetup_found ) ;
|
||||
set_command_found() ;
|
||||
return ( lvm_found ) ;
|
||||
}
|
||||
|
||||
Glib::ustring LVM2_PV_Info::get_vg_name( const Glib::ustring & path )
|
||||
|
@ -106,9 +115,21 @@ bool LVM2_PV_Info::has_active_lvs( const Glib::ustring & path )
|
|||
//PV not yet included in any VG
|
||||
return false ;
|
||||
|
||||
Glib::ustring regexp = "^(" + vgname + ")-" ;
|
||||
Glib::ustring match = Utils::regexp_label( dmsetup_info_cache, regexp ) ;
|
||||
return ( match == vgname ) ;
|
||||
for ( unsigned int i = 0 ; i < lvm2_lv_cache .size() ; i ++ )
|
||||
{
|
||||
std::vector<Glib::ustring> lv_attrs ;
|
||||
Utils::split( lvm2_lv_cache [i], lv_attrs, "," ) ;
|
||||
if ( vgname == lv_attrs [LVATTR_VG_NAME] )
|
||||
{
|
||||
//5th "bit" is active status. E.g.
|
||||
// "-wi---" inactive, "-wi-a-" active, ...
|
||||
// Treat any non-hyphen character as active.
|
||||
if ( lv_attrs [LVATTR_LV_BITS] [4] != '-' )
|
||||
//LV in VG is active
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//Private methods
|
||||
|
@ -117,49 +138,45 @@ void LVM2_PV_Info::initialize_if_required()
|
|||
{
|
||||
if ( ! lvm2_pv_info_cache_initialized )
|
||||
{
|
||||
set_commands_found() ;
|
||||
set_command_found() ;
|
||||
load_lvm2_pv_info_cache() ;
|
||||
lvm2_pv_info_cache_initialized = true ;
|
||||
}
|
||||
}
|
||||
|
||||
void LVM2_PV_Info::set_commands_found()
|
||||
void LVM2_PV_Info::set_command_found()
|
||||
{
|
||||
//Set status of commands found
|
||||
//Set status of command found
|
||||
lvm_found = ( ! Glib::find_program_in_path( "lvm" ) .empty() ) ;
|
||||
dmsetup_found = ( ! Glib::find_program_in_path( "dmsetup" ) .empty() ) ;
|
||||
}
|
||||
|
||||
void LVM2_PV_Info::load_lvm2_pv_info_cache()
|
||||
{
|
||||
Glib::ustring output, error ;
|
||||
|
||||
//Load LVM2 PV attribute cache
|
||||
lvm2_pv_cache .clear() ;
|
||||
lvm2_lv_cache .clear() ;
|
||||
if ( lvm_found )
|
||||
{
|
||||
//The OS is expected to fully enable LVM, this scan does
|
||||
// not do the full job. It is included incase anything
|
||||
// is changed not using lvm commands.
|
||||
Utils::execute_command( "lvm vgscan", output, error, true ) ;
|
||||
//Output PV attributes, in PV_ATTRIBUTE order
|
||||
|
||||
//Load LVM2 PV attribute cache. Output PV attributes in
|
||||
// PV_ATTRIBUTE order
|
||||
if ( ! Utils::execute_command( "lvm pvs --config \"log{command_names=0}\" --nosuffix --noheadings --separator , --units b -o pv_name,vg_name,pv_free", output, error, true ) )
|
||||
{
|
||||
if ( output != "" )
|
||||
Utils::tokenize( output, lvm2_pv_cache, " \n" ) ;
|
||||
}
|
||||
}
|
||||
|
||||
//Load dmsetup info cache. This is a list of active LV names as
|
||||
//reported by the kernel's device-mapper driver.
|
||||
dmsetup_info_cache = "" ;
|
||||
if ( dmsetup_found )
|
||||
{
|
||||
if ( ! Utils::execute_command( "dmsetup info --columns --noheadings --separator , -o name", output, error, true ) )
|
||||
//Load LVM2 LV attribute cache. Output LV attributes in
|
||||
// LV_ATTRIBUTE order
|
||||
if ( ! Utils::execute_command( "lvm lvs --config \"log{command_names=0}\" --noheadings --separator , -o lv_name,vg_name,lv_attr", output, error, true ) )
|
||||
{
|
||||
Glib::ustring match = Utils::regexp_label( output, "^(No devices found).*" ) ;
|
||||
if ( match != "No devices found" )
|
||||
dmsetup_info_cache = output ;
|
||||
if ( output != "" )
|
||||
Utils::tokenize( output, lvm2_lv_cache, " \n" ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue