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:
Mike Fleetwood 2012-02-02 13:22:46 +00:00 committed by Curtis Gedak
parent 72ac712024
commit 820242635a
2 changed files with 46 additions and 30 deletions

View File

@ -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

View File

@ -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" ) ;
}
}
}