2012-01-28 07:25:31 -07:00
|
|
|
/* Copyright (C) 2012 Mike Fleetwood
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "../include/LVM2_PV_Info.h"
|
|
|
|
|
|
|
|
namespace GParted
|
|
|
|
{
|
|
|
|
|
|
|
|
enum PV_ATTRIBUTE
|
|
|
|
{
|
|
|
|
PVATTR_PV_NAME = 0,
|
2012-02-09 07:30:29 -07:00
|
|
|
PVATTR_PV_FREE = 1,
|
|
|
|
PVATTR_VG_NAME = 2,
|
|
|
|
PVATTR_LV_NAME = 3,
|
|
|
|
PVATTR_LV_BITS = 4
|
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
2012-02-02 06:22:46 -07:00
|
|
|
} ;
|
|
|
|
|
2012-01-28 07:25:31 -07:00
|
|
|
//Data model:
|
|
|
|
// lvm2_pv_info_cache_initialized
|
|
|
|
// - Has the cache been loaded let?
|
|
|
|
// lvm_found - Is the "lvm" command available?
|
|
|
|
// lvm2_pv_cache - String vector storing attributes of a PV.
|
2012-02-09 07:30:29 -07:00
|
|
|
// Attributes are: pv_name,pv_free,vg_name,
|
|
|
|
// lv_name,lv_attr. Pv_free is the number of
|
|
|
|
// free bytes, see lvs(8) for details of
|
|
|
|
// lv_attrs.
|
2012-01-28 07:25:31 -07:00
|
|
|
// E.g.
|
2012-02-09 07:30:29 -07:00
|
|
|
// ["/dev/sda10,2147483648,,,",
|
|
|
|
// "/dev/sda11,2143289344,GParted-VG1,,",
|
|
|
|
// "/dev/sda12,1619001344,GParted-VG2,lvol0,-wi---",
|
|
|
|
// "/dev/sda12,1619001344,GParted-VG2,,",
|
|
|
|
// "/dev/sda13,830472192,GParted_VG3,lvol0,-wi-a-",
|
|
|
|
// "/dev/sda13,830472192,GParted_VG3,lvol1,-wi-a-",
|
|
|
|
// "/dev/sda13,830472192,GParted_VG3,,"]
|
|
|
|
|
2012-01-28 07:25:31 -07:00
|
|
|
|
|
|
|
//Initialize static data elements
|
|
|
|
bool LVM2_PV_Info::lvm2_pv_info_cache_initialized = false ;
|
|
|
|
bool LVM2_PV_Info::lvm_found = false ;
|
|
|
|
std::vector<Glib::ustring> LVM2_PV_Info::lvm2_pv_cache ;
|
|
|
|
|
|
|
|
LVM2_PV_Info::LVM2_PV_Info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LVM2_PV_Info::LVM2_PV_Info( bool do_refresh )
|
|
|
|
{
|
2011-12-11 16:17:52 -07:00
|
|
|
if ( do_refresh )
|
2012-01-28 07:25:31 -07: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
2012-02-02 06:22:46 -07:00
|
|
|
set_command_found() ;
|
2012-01-28 07:25:31 -07:00
|
|
|
load_lvm2_pv_info_cache() ;
|
2011-12-11 16:17:52 -07:00
|
|
|
lvm2_pv_info_cache_initialized = true ;
|
|
|
|
}
|
2012-01-28 07:25:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
LVM2_PV_Info::~LVM2_PV_Info()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LVM2_PV_Info::is_lvm2_pv_supported()
|
|
|
|
{
|
2011-12-11 16:17:52 -07:00
|
|
|
if ( ! lvm2_pv_info_cache_initialized )
|
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
2012-02-02 06:22:46 -07:00
|
|
|
set_command_found() ;
|
|
|
|
return ( lvm_found ) ;
|
2012-01-28 07:25:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Glib::ustring LVM2_PV_Info::get_vg_name( const Glib::ustring & path )
|
|
|
|
{
|
2011-12-11 16:17:52 -07:00
|
|
|
initialize_if_required() ;
|
2012-01-28 07:25:31 -07:00
|
|
|
return get_pv_attr( path, PVATTR_VG_NAME ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Return number of free bytes in the PV, or -1 for error.
|
|
|
|
Byte_Value LVM2_PV_Info::get_free_bytes( const Glib::ustring & path )
|
|
|
|
{
|
2011-12-11 16:17:52 -07:00
|
|
|
initialize_if_required() ;
|
2012-01-28 07:25:31 -07:00
|
|
|
Byte_Value free_bytes = -1 ;
|
|
|
|
Glib::ustring fb_str = get_pv_attr( path, PVATTR_PV_FREE ) ;
|
|
|
|
if ( fb_str != "" )
|
|
|
|
{
|
|
|
|
gchar * suffix ;
|
|
|
|
free_bytes = (Byte_Value) g_ascii_strtoll( fb_str .c_str(), & suffix, 10 ) ;
|
|
|
|
if ( free_bytes < 0 || ( free_bytes == 0 && suffix == fb_str ) )
|
|
|
|
//Negative number or conversion failed
|
|
|
|
free_bytes = -1 ;
|
|
|
|
}
|
|
|
|
return free_bytes ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Report if any LVs are active in the VG stored in the PV.
|
|
|
|
bool LVM2_PV_Info::has_active_lvs( const Glib::ustring & path )
|
|
|
|
{
|
2011-12-11 16:17:52 -07:00
|
|
|
initialize_if_required() ;
|
2012-01-28 07:25:31 -07:00
|
|
|
Glib::ustring vgname = get_pv_attr( path, PVATTR_VG_NAME ) ;
|
|
|
|
if ( vgname == "" )
|
|
|
|
//PV not yet included in any VG
|
|
|
|
return false ;
|
|
|
|
|
2012-02-09 07:30:29 -07:00
|
|
|
for ( unsigned int i = 0 ; i < lvm2_pv_cache .size() ; i ++ )
|
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
2012-02-02 06:22:46 -07:00
|
|
|
{
|
2012-02-09 07:30:29 -07:00
|
|
|
std::vector<Glib::ustring> pv_attrs ;
|
|
|
|
Utils::split( lvm2_pv_cache [i], pv_attrs, "," ) ;
|
|
|
|
if ( vgname == pv_attrs [PVATTR_VG_NAME] )
|
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
2012-02-02 06:22:46 -07:00
|
|
|
{
|
|
|
|
//5th "bit" is active status. E.g.
|
|
|
|
// "-wi---" inactive, "-wi-a-" active, ...
|
|
|
|
// Treat any non-hyphen character as active.
|
2012-02-09 07:30:29 -07:00
|
|
|
if ( pv_attrs [PVATTR_LV_BITS] .length() >= 5
|
|
|
|
&& pv_attrs [PVATTR_LV_BITS] [4] != '-' )
|
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
2012-02-02 06:22:46 -07:00
|
|
|
//LV in VG is active
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false ;
|
2012-01-28 07:25:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//Private methods
|
|
|
|
|
2011-12-11 16:17:52 -07:00
|
|
|
void LVM2_PV_Info::initialize_if_required()
|
|
|
|
{
|
|
|
|
if ( ! lvm2_pv_info_cache_initialized )
|
|
|
|
{
|
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
2012-02-02 06:22:46 -07:00
|
|
|
set_command_found() ;
|
2011-12-11 16:17:52 -07:00
|
|
|
load_lvm2_pv_info_cache() ;
|
|
|
|
lvm2_pv_info_cache_initialized = true ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
2012-02-02 06:22:46 -07:00
|
|
|
void LVM2_PV_Info::set_command_found()
|
2012-01-28 07:25:31 -07: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
2012-02-02 06:22:46 -07:00
|
|
|
//Set status of command found
|
2012-01-28 07:25:31 -07:00
|
|
|
lvm_found = ( ! Glib::find_program_in_path( "lvm" ) .empty() ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LVM2_PV_Info::load_lvm2_pv_info_cache()
|
|
|
|
{
|
|
|
|
Glib::ustring output, error ;
|
|
|
|
|
|
|
|
lvm2_pv_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 ) ;
|
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
2012-02-02 06:22:46 -07:00
|
|
|
|
|
|
|
//Load LVM2 PV attribute cache. Output PV attributes in
|
|
|
|
// PV_ATTRIBUTE order
|
2012-02-09 07:30:29 -07:00
|
|
|
if ( ! Utils::execute_command( "lvm pvs --config \"log{command_names=0}\" --nosuffix --noheadings --separator , --units b -o pv_name,pv_free,vg_name,lv_name,lv_attr", output, error, true ) )
|
2012-01-28 07:25:31 -07:00
|
|
|
{
|
|
|
|
if ( output != "" )
|
|
|
|
Utils::tokenize( output, lvm2_pv_cache, " \n" ) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-09 07:30:29 -07:00
|
|
|
//Return PV's nth attribute. Performs linear search of the cache and
|
|
|
|
// uses the first matching PV entry. Attributes are numbered 0 upward
|
|
|
|
// using PV_ATTRIBUTE enumeration.
|
2012-01-28 07:25:31 -07:00
|
|
|
Glib::ustring LVM2_PV_Info::get_pv_attr( const Glib::ustring & path, unsigned int entry )
|
|
|
|
{
|
|
|
|
for ( unsigned int i = 0 ; i < lvm2_pv_cache .size() ; i ++ )
|
|
|
|
{
|
|
|
|
std::vector<Glib::ustring> pv_attrs ;
|
|
|
|
Utils::split( lvm2_pv_cache [i], pv_attrs, "," ) ;
|
|
|
|
if ( path == pv_attrs [PVATTR_PV_NAME] )
|
|
|
|
{
|
|
|
|
if ( entry < pv_attrs .size() )
|
|
|
|
return pv_attrs [entry] ;
|
|
|
|
else
|
|
|
|
break ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "" ;
|
|
|
|
}
|
|
|
|
|
|
|
|
}//GParted
|