2016-02-18 02:53:35 +03:00
# Copyright (C) 2015-2016 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from . automatedproperties import AutomatedProperties
from . import utils
2019-10-01 23:17:30 +03:00
from . utils import pv_obj_path_generate , vg_obj_path_generate , n , \
_handle_execute
2016-02-18 02:53:35 +03:00
import dbus
from . import cfg
2019-10-08 00:58:10 +03:00
from . cfg import VG_INTERFACE , VG_VDO_INTERFACE
2016-02-18 02:53:35 +03:00
from . import cmdhandler
from . request import RequestEntry
from . loader import common
from . state import State
from . import background
2022-09-08 23:38:31 +03:00
from . utils import round_size , mt_remove_dbus_objects , LvmBug , lvm_column_key
2016-06-28 20:07:21 +03:00
from . job import JobState
2016-02-18 02:53:35 +03:00
# noinspection PyUnusedLocal
def vgs_state_retrieve ( selection , cache_refresh = True ) :
rc = [ ]
if cache_refresh :
cfg . db . refresh ( )
2022-08-31 19:20:49 +03:00
try :
for v in cfg . db . fetch_vgs ( selection ) :
rc . append (
VgState (
v [ ' vg_uuid ' ] , v [ ' vg_name ' ] , v [ ' vg_fmt ' ] , n ( v [ ' vg_size ' ] ) ,
n ( v [ ' vg_free ' ] ) , v [ ' vg_sysid ' ] , n ( v [ ' vg_extent_size ' ] ) ,
n ( v [ ' vg_extent_count ' ] ) , n ( v [ ' vg_free_count ' ] ) ,
v [ ' vg_profile ' ] , n ( v [ ' max_lv ' ] ) , n ( v [ ' max_pv ' ] ) ,
n ( v [ ' pv_count ' ] ) , n ( v [ ' lv_count ' ] ) , n ( v [ ' snap_count ' ] ) ,
n ( v [ ' vg_seqno ' ] ) , n ( v [ ' vg_mda_count ' ] ) ,
n ( v [ ' vg_mda_free ' ] ) , n ( v [ ' vg_mda_size ' ] ) ,
n ( v [ ' vg_mda_used_count ' ] ) , v [ ' vg_attr ' ] , v [ ' vg_tags ' ] ) )
except KeyError as ke :
# Sometimes lvm omits returning one of the keys we requested.
key = ke . args [ 0 ]
2022-09-08 23:38:31 +03:00
if lvm_column_key ( key ) :
2022-08-31 19:20:49 +03:00
raise LvmBug ( " missing JSON key: ' %s ' " % key )
raise ke
2016-02-18 02:53:35 +03:00
return rc
def load_vgs ( vg_specific = None , object_path = None , refresh = False ,
emit_signal = False , cache_refresh = True ) :
2019-10-08 00:58:10 +03:00
return common ( vgs_state_retrieve , ( Vg , VgVdo , ) , vg_specific , object_path , refresh ,
2016-02-18 02:53:35 +03:00
emit_signal , cache_refresh )
# noinspection PyPep8Naming,PyUnresolvedReferences,PyUnusedLocal
class VgState ( State ) :
2019-01-17 00:41:27 +03:00
2016-02-18 02:53:35 +03:00
@property
2019-01-17 00:41:27 +03:00
def internal_name ( self ) :
2016-02-18 02:53:35 +03:00
return self . Name
2019-01-17 00:41:27 +03:00
@property
def lvm_id ( self ) :
return self . internal_name
2016-02-18 02:53:35 +03:00
def identifiers ( self ) :
2019-01-17 00:41:27 +03:00
return ( self . Uuid , self . internal_name )
2016-02-18 02:53:35 +03:00
def _lv_paths_build ( self ) :
rc = [ ]
for lv in cfg . db . lvs_in_vg ( self . Uuid ) :
( lv_name , meta , lv_uuid ) = lv
2019-01-17 00:41:27 +03:00
full_name = " %s / %s " % ( self . internal_name , lv_name )
2016-02-18 02:53:35 +03:00
gen = utils . lv_object_path_method ( lv_name , meta )
2016-06-10 20:03:04 +03:00
lv_path = cfg . om . get_object_path_by_uuid_lvm_id (
2016-02-18 02:53:35 +03:00
lv_uuid , full_name , gen )
rc . append ( lv_path )
return dbus . Array ( rc , signature = ' o ' )
def _pv_paths_build ( self ) :
rc = [ ]
for p in cfg . db . pvs_in_vg ( self . Uuid ) :
( pv_name , pv_uuid ) = p
2016-06-10 20:03:04 +03:00
rc . append ( cfg . om . get_object_path_by_uuid_lvm_id (
2016-02-18 02:53:35 +03:00
pv_uuid , pv_name , pv_obj_path_generate ) )
2016-08-25 02:31:15 +03:00
return rc
2016-02-18 02:53:35 +03:00
def __init__ ( self , Uuid , Name , Fmt ,
SizeBytes , FreeBytes , SysId , ExtentSizeBytes ,
ExtentCount , FreeCount , Profile , MaxLv , MaxPv , PvCount ,
LvCount , SnapCount , Seqno , MdaCount , MdaFree ,
MdaSizeBytes , MdaUsedCount , attr , tags ) :
utils . init_class_from_arguments ( self )
self . Pvs = self . _pv_paths_build ( )
self . Lvs = self . _lv_paths_build ( )
def create_dbus_object ( self , path ) :
if not path :
2016-06-10 20:03:04 +03:00
path = cfg . om . get_object_path_by_uuid_lvm_id (
2019-01-17 00:41:27 +03:00
self . Uuid , self . internal_name , vg_obj_path_generate )
2019-10-08 00:58:10 +03:00
if cfg . vdo_support :
return VgVdo ( path , self )
else :
return Vg ( path , self )
2016-02-18 02:53:35 +03:00
# noinspection PyMethodMayBeStatic
def creation_signature ( self ) :
return ( Vg , vg_obj_path_generate )
# noinspection PyPep8Naming
@utils.dbus_property ( VG_INTERFACE , ' Uuid ' , ' s ' )
@utils.dbus_property ( VG_INTERFACE , ' Fmt ' , ' s ' )
@utils.dbus_property ( VG_INTERFACE , ' SizeBytes ' , ' t ' , 0 )
@utils.dbus_property ( VG_INTERFACE , ' FreeBytes ' , ' t ' , 0 )
@utils.dbus_property ( VG_INTERFACE , ' SysId ' , ' s ' )
@utils.dbus_property ( VG_INTERFACE , ' ExtentSizeBytes ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' ExtentCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' FreeCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' Profile ' , ' s ' )
@utils.dbus_property ( VG_INTERFACE , ' MaxLv ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' MaxPv ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' PvCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' LvCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' SnapCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' Seqno ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' MdaCount ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' MdaFree ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' MdaSizeBytes ' , ' t ' )
@utils.dbus_property ( VG_INTERFACE , ' MdaUsedCount ' , ' t ' )
class Vg ( AutomatedProperties ) :
_Tags_meta = ( " as " , VG_INTERFACE )
_Pvs_meta = ( " ao " , VG_INTERFACE )
_Lvs_meta = ( " ao " , VG_INTERFACE )
_Writeable_meta = ( " b " , VG_INTERFACE )
_Readable_meta = ( " b " , VG_INTERFACE )
_Resizeable_meta = ( " b " , VG_INTERFACE )
_Exportable_meta = ( ' b ' , VG_INTERFACE )
_Partial_meta = ( ' b ' , VG_INTERFACE )
_AllocContiguous_meta = ( ' b ' , VG_INTERFACE )
_AllocCling_meta = ( ' b ' , VG_INTERFACE )
_AllocNormal_meta = ( ' b ' , VG_INTERFACE )
_AllocAnywhere_meta = ( ' b ' , VG_INTERFACE )
_Clustered_meta = ( ' b ' , VG_INTERFACE )
2019-01-17 00:41:27 +03:00
_Name_meta = ( ' s ' , VG_INTERFACE )
2016-02-18 02:53:35 +03:00
# noinspection PyUnusedLocal,PyPep8Naming
def __init__ ( self , object_path , object_state ) :
super ( Vg , self ) . __init__ ( object_path , vgs_state_retrieve )
self . set_interface ( VG_INTERFACE )
self . _object_path = object_path
self . state = object_state
@staticmethod
def fetch_new_lv ( vg_name , lv_name ) :
2016-09-16 22:00:14 +03:00
return cfg . om . get_object_path_by_lvm_id ( " %s / %s " % ( vg_name , lv_name ) )
2016-02-18 02:53:35 +03:00
@staticmethod
2017-02-02 01:37:03 +03:00
def handle_execute ( rc , out , err ) :
2019-10-01 23:17:30 +03:00
return _handle_execute ( rc , out , err , VG_INTERFACE )
2017-02-02 01:37:03 +03:00
@staticmethod
def validate_dbus_object ( vg_uuid , vg_name ) :
dbo = cfg . om . get_object_by_uuid_lvm_id ( vg_uuid , vg_name )
if not dbo :
2016-02-18 02:53:35 +03:00
raise dbus . exceptions . DBusException (
VG_INTERFACE ,
' VG with uuid %s and name %s not present! ' %
2017-02-02 01:37:03 +03:00
( vg_uuid , vg_name ) )
return dbo
@staticmethod
def _rename ( uuid , vg_name , new_name , rename_options ) :
# Make sure we have a dbus object representing it
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_rename (
uuid , new_name , rename_options ) )
2016-02-18 02:53:35 +03:00
return ' / '
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' sia {sv} ' , out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Rename ( self , name , tmo , rename_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
utils . validate_vg_name ( VG_INTERFACE , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _rename ,
( self . state . Uuid , self . state . lvm_id , name ,
rename_options ) , cb , cbe , False )
cfg . worker_q . put ( r )
@staticmethod
def _remove ( uuid , vg_name , remove_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
# Remove the VG, if successful then remove from the model
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_remove ( vg_name , remove_options ) )
2016-02-18 02:53:35 +03:00
return ' / '
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' ia {sv} ' , out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Remove ( self , tmo , remove_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _remove ,
( self . state . Uuid , self . state . lvm_id , remove_options ) ,
cb , cbe , False )
cfg . worker_q . put ( r )
@staticmethod
def _change ( uuid , vg_name , change_options ) :
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_change ( change_options , vg_name ) )
2016-02-18 02:53:35 +03:00
return ' / '
# TODO: This should be broken into a number of different methods
# instead of having one method that takes a hash for parameters. Some of
# the changes that vgchange does works on entire system, not just a
2019-01-14 18:11:06 +03:00
# specific vg, thus that should be in the Manager interface.
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' ia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Change ( self , tmo , change_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _change ,
( self . state . Uuid , self . state . lvm_id , change_options ) ,
cb , cbe , False )
cfg . worker_q . put ( r )
@staticmethod
def _reduce ( uuid , vg_name , missing , pv_object_paths , reduce_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
pv_devices = [ ]
# If pv_object_paths is not empty, then get the device paths
if pv_object_paths and len ( pv_object_paths ) > 0 :
for pv_op in pv_object_paths :
pv = cfg . om . get_object_by_path ( pv_op )
if pv :
pv_devices . append ( pv . lvm_id )
else :
raise dbus . exceptions . DBusException (
VG_INTERFACE ,
' PV Object path not found = %s ! ' % pv_op )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_reduce (
vg_name , missing , pv_devices , reduce_options ) )
2016-02-18 02:53:35 +03:00
return ' / '
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' baoia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Reduce ( self , missing , pv_object_paths , tmo , reduce_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _reduce ,
( self . state . Uuid , self . state . lvm_id , missing ,
pv_object_paths , reduce_options ) , cb , cbe , False )
cfg . worker_q . put ( r )
@staticmethod
def _extend ( uuid , vg_name , pv_object_paths , extend_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2016-02-18 02:53:35 +03:00
2017-02-02 01:37:03 +03:00
extend_devices = [ ]
2016-02-18 02:53:35 +03:00
2017-02-02 01:37:03 +03:00
for i in pv_object_paths :
pv = cfg . om . get_object_by_path ( i )
if pv :
extend_devices . append ( pv . lvm_id )
2016-02-18 02:53:35 +03:00
else :
raise dbus . exceptions . DBusException (
2017-02-02 01:37:03 +03:00
VG_INTERFACE , ' PV Object path not found = %s ! ' % i )
if len ( extend_devices ) :
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_extend (
vg_name , extend_devices , extend_options ) )
2016-02-18 02:53:35 +03:00
else :
raise dbus . exceptions . DBusException (
2017-02-02 01:37:03 +03:00
VG_INTERFACE , ' No pv_object_paths provided! ' )
2016-02-18 02:53:35 +03:00
return ' / '
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' aoia {sv} ' , out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Extend ( self , pv_object_paths , tmo , extend_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _extend ,
( self . state . Uuid , self . state . lvm_id , pv_object_paths ,
extend_options ) ,
cb , cbe , False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' o(tt)a(ott)ia {sv} ' ,
2016-06-28 20:07:21 +03:00
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
2016-02-18 02:53:35 +03:00
def Move ( self , pv_src_obj , pv_source_range , pv_dests_and_ranges ,
2016-06-28 20:07:21 +03:00
tmo , move_options , cb , cbe ) :
job_state = JobState ( )
r = RequestEntry (
tmo , background . move ,
( VG_INTERFACE , None , pv_src_obj , pv_source_range ,
pv_dests_and_ranges , move_options , job_state ) , cb , cbe , False ,
job_state )
cfg . worker_q . put ( r )
2016-02-18 02:53:35 +03:00
@staticmethod
def _lv_create ( uuid , vg_name , name , size_bytes , pv_dests_and_ranges ,
create_options ) :
# Make sure we have a dbus object representing it
pv_dests = [ ]
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2016-02-18 02:53:35 +03:00
2017-02-02 01:37:03 +03:00
if len ( pv_dests_and_ranges ) :
for pr in pv_dests_and_ranges :
pv_dbus_obj = cfg . om . get_object_by_path ( pr [ 0 ] )
if not pv_dbus_obj :
raise dbus . exceptions . DBusException (
VG_INTERFACE ,
' PV Destination ( %s ) not found ' % pr [ 0 ] )
2016-02-18 02:53:35 +03:00
2017-02-02 01:37:03 +03:00
pv_dests . append ( ( pv_dbus_obj . lvm_id , pr [ 1 ] , pr [ 2 ] ) )
2016-02-18 02:53:35 +03:00
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_lv_create (
vg_name , create_options , name , size_bytes , pv_dests ) )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' sta(ott)ia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def LvCreate ( self , name , size_bytes , pv_dests_and_ranges ,
tmo , create_options , cb , cbe ) :
"""
This one it for the advanced users that want to roll their own
: param name : Name of the LV
: param size_bytes : Size of LV in bytes
: param pv_dests_and_ranges : Optional array of PV object paths and
ranges
: param tmo : - 1 == Wait forever , 0 == return job immediately , > 0 ==
willing to wait that number of seconds before
getting a job
: param create_options : hash of key / value pairs
: param cb : Internal , not accessible by dbus API user
: param cbe : Internal , not accessible by dbus API user
: return : ( oo ) First object path is newly created object , second is
job object path if created . Each == ' / ' when it doesn ' t
apply .
"""
2016-02-18 03:27:57 +03:00
utils . validate_lv_name ( VG_INTERFACE , self . Name , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _lv_create ,
( self . state . Uuid , self . state . lvm_id ,
name , round_size ( size_bytes ) , pv_dests_and_ranges ,
create_options ) , cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _lv_create_linear ( uuid , vg_name , name , size_bytes ,
thin_pool , create_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_lv_create_linear (
vg_name , create_options , name , size_bytes , thin_pool ) )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' stbia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def LvCreateLinear ( self , name , size_bytes ,
thin_pool , tmo , create_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
utils . validate_lv_name ( VG_INTERFACE , self . Name , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _lv_create_linear ,
( self . state . Uuid , self . state . lvm_id ,
name , round_size ( size_bytes ) , thin_pool ,
create_options ) , cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _lv_create_striped ( uuid , vg_name , name , size_bytes , num_stripes ,
stripe_size_kb , thin_pool , create_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_lv_create_striped (
2017-02-02 01:37:03 +03:00
vg_name , create_options , name , size_bytes ,
2019-10-01 23:18:46 +03:00
num_stripes , stripe_size_kb , thin_pool ) )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' stuubia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def LvCreateStriped ( self , name , size_bytes , num_stripes ,
stripe_size_kb , thin_pool , tmo , create_options ,
cb , cbe ) :
2016-02-18 03:27:57 +03:00
utils . validate_lv_name ( VG_INTERFACE , self . Name , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry (
tmo , Vg . _lv_create_striped ,
( self . state . Uuid , self . state . lvm_id , name ,
round_size ( size_bytes ) , num_stripes , stripe_size_kb ,
thin_pool , create_options ) ,
cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _lv_create_mirror ( uuid , vg_name , name , size_bytes ,
num_copies , create_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_lv_create_mirror (
vg_name , create_options , name , size_bytes , num_copies ) )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' stuia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def LvCreateMirror ( self , name , size_bytes , num_copies ,
tmo , create_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
utils . validate_lv_name ( VG_INTERFACE , self . Name , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry (
tmo , Vg . _lv_create_mirror ,
( self . state . Uuid , self . state . lvm_id , name ,
round_size ( size_bytes ) , num_copies ,
create_options ) , cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _lv_create_raid ( uuid , vg_name , name , raid_type , size_bytes ,
num_stripes , stripe_size_kb , create_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_lv_create_raid (
2017-02-02 01:37:03 +03:00
vg_name , create_options , name , raid_type , size_bytes ,
2019-10-01 23:18:46 +03:00
num_stripes , stripe_size_kb ) )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' sstuuia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def LvCreateRaid ( self , name , raid_type , size_bytes ,
num_stripes , stripe_size_kb , tmo ,
create_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
utils . validate_lv_name ( VG_INTERFACE , self . Name , name )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _lv_create_raid ,
( self . state . Uuid , self . state . lvm_id , name ,
raid_type , round_size ( size_bytes ) , num_stripes ,
stripe_size_kb , create_options ) , cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _create_pool ( uuid , vg_name , meta_data_lv , data_lv ,
create_options , create_method ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2016-02-18 02:53:35 +03:00
# Retrieve the full names for the metadata and data lv
md = cfg . om . get_object_by_path ( meta_data_lv )
data = cfg . om . get_object_by_path ( data_lv )
2017-02-02 01:37:03 +03:00
if md and data :
2016-02-18 02:53:35 +03:00
new_name = data . Name
rc , out , err = create_method (
md . lv_full_name ( ) , data . lv_full_name ( ) , create_options )
2017-02-02 01:37:03 +03:00
2016-02-18 02:53:35 +03:00
if rc == 0 :
2016-11-02 01:52:18 +03:00
mt_remove_dbus_objects ( ( md , data ) )
2017-02-02 01:37:03 +03:00
Vg . handle_execute ( rc , out , err )
2016-02-18 02:53:35 +03:00
else :
msg = " "
if not md :
msg + = ' Meta data LV with object path %s not present! ' % \
( meta_data_lv )
if not data_lv :
msg + = ' Data LV with object path %s not present! ' % \
( meta_data_lv )
raise dbus . exceptions . DBusException ( VG_INTERFACE , msg )
2017-02-02 01:37:03 +03:00
return Vg . fetch_new_lv ( vg_name , new_name )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' ooia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def CreateCachePool ( self , meta_data_lv , data_lv , tmo , create_options ,
cb , cbe ) :
r = RequestEntry (
tmo , Vg . _create_pool ,
( self . state . Uuid , self . state . lvm_id , meta_data_lv ,
data_lv , create_options , cmdhandler . vg_create_cache_pool ) , cb , cbe )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' ooia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def CreateThinPool ( self , meta_data_lv , data_lv , tmo , create_options ,
cb , cbe ) :
r = RequestEntry (
tmo , Vg . _create_pool ,
( self . state . Uuid , self . state . lvm_id , meta_data_lv ,
data_lv , create_options , cmdhandler . vg_create_thin_pool ) , cb , cbe )
cfg . worker_q . put ( r )
@staticmethod
def _pv_add_rm_tags ( uuid , vg_name , pv_object_paths , tags_add ,
tags_del , tag_options ) :
pv_devices = [ ]
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2016-02-18 02:53:35 +03:00
2017-02-02 01:37:03 +03:00
# Check for existence of pv object paths
for p in pv_object_paths :
pv = cfg . om . get_object_by_path ( p )
if pv :
pv_devices . append ( pv . Name )
2016-02-18 02:53:35 +03:00
else :
raise dbus . exceptions . DBusException (
2017-02-02 01:37:03 +03:00
VG_INTERFACE , ' PV object path = %s not found ' % p )
2016-02-18 02:53:35 +03:00
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . pv_tag (
pv_devices , tags_add , tags_del , tag_options ) )
2017-02-02 01:37:03 +03:00
return ' / '
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' aoasia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def PvTagsAdd ( self , pvs , tags , tmo , tag_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
for t in tags :
utils . validate_tag ( VG_INTERFACE , t )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _pv_add_rm_tags ,
( self . state . Uuid , self . state . lvm_id ,
pvs , tags , None , tag_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' aoasia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def PvTagsDel ( self , pvs , tags , tmo , tag_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
for t in tags :
utils . validate_tag ( VG_INTERFACE , t )
2016-02-18 02:53:35 +03:00
r = RequestEntry (
tmo , Vg . _pv_add_rm_tags ,
( self . state . Uuid , self . state . lvm_id ,
pvs , None , tags , tag_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@staticmethod
def _vg_add_rm_tags ( uuid , vg_name , tags_add , tags_del , tag_options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2016-02-18 02:53:35 +03:00
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . vg_tag (
vg_name , tags_add , tags_del , tag_options ) )
2017-02-02 01:37:03 +03:00
return ' / '
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' asia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def TagsAdd ( self , tags , tmo , tag_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
for t in tags :
utils . validate_tag ( VG_INTERFACE , t )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _vg_add_rm_tags ,
( self . state . Uuid , self . state . lvm_id ,
tags , None , tag_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' asia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def TagsDel ( self , tags , tmo , tag_options , cb , cbe ) :
2016-02-18 03:27:57 +03:00
for t in tags :
utils . validate_tag ( VG_INTERFACE , t )
2016-02-18 02:53:35 +03:00
r = RequestEntry ( tmo , Vg . _vg_add_rm_tags ,
( self . state . Uuid , self . state . lvm_id ,
None , tags , tag_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@staticmethod
def _vg_change_set ( uuid , vg_name , method , value , options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * method ( vg_name , value , options ) )
2017-02-02 01:37:03 +03:00
return ' / '
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' sia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def AllocationPolicySet ( self , policy , tmo , policy_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_change_set ,
( self . state . Uuid , self . state . lvm_id ,
cmdhandler . vg_allocation_policy ,
policy , policy_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' tia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def MaxPvSet ( self , number , tmo , max_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_change_set ,
( self . state . Uuid , self . state . lvm_id ,
cmdhandler . vg_max_pv , number , max_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' ia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def UuidGenerate ( self , tmo , options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_change_set ,
( self . state . Uuid , self . state . lvm_id ,
cmdhandler . vg_uuid_gen , None , options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
def _attribute ( self , pos , ch ) :
2016-08-25 02:31:15 +03:00
return dbus . Boolean ( self . state . attr [ pos ] == ch )
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' tia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def MaxLvSet ( self , number , tmo , max_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_change_set ,
( self . state . Uuid , self . state . lvm_id ,
cmdhandler . vg_max_lv , number , max_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@staticmethod
def _vg_activate_deactivate ( uuid , vg_name , activate , control_flags ,
options ) :
# Make sure we have a dbus object representing it
2017-02-02 01:37:03 +03:00
Vg . validate_dbus_object ( uuid , vg_name )
2019-10-01 23:18:46 +03:00
Vg . handle_execute ( * cmdhandler . activate_deactivate (
' vgchange ' , vg_name , activate , control_flags , options ) )
2017-02-02 01:37:03 +03:00
return ' / '
2016-02-18 02:53:35 +03:00
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' tia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Activate ( self , control_flags , tmo , activate_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_activate_deactivate ,
( self . state . Uuid , self . state . lvm_id , True ,
control_flags , activate_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
@dbus.service.method (
dbus_interface = VG_INTERFACE ,
in_signature = ' tia {sv} ' ,
out_signature = ' o ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def Deactivate ( self , control_flags , tmo , activate_options , cb , cbe ) :
r = RequestEntry ( tmo , Vg . _vg_activate_deactivate ,
( self . state . Uuid , self . state . lvm_id , False ,
control_flags , activate_options ) ,
cb , cbe , return_tuple = False )
cfg . worker_q . put ( r )
2019-01-17 00:41:27 +03:00
@property
def Name ( self ) :
if ' : ' in self . state . Name :
return self . state . Name . split ( ' : ' ) [ 0 ]
return self . state . Name
2016-02-18 02:53:35 +03:00
@property
def Tags ( self ) :
return utils . parse_tags ( self . state . tags )
@property
def Pvs ( self ) :
2016-08-25 02:31:15 +03:00
return dbus . Array ( self . state . Pvs , signature = ' o ' )
2016-02-18 02:53:35 +03:00
@property
def Lvs ( self ) :
2016-08-25 02:31:15 +03:00
return dbus . Array ( self . state . Lvs , signature = ' o ' )
2016-02-18 02:53:35 +03:00
@property
def lvm_id ( self ) :
return self . state . lvm_id
@property
def Writeable ( self ) :
return self . _attribute ( 0 , ' w ' )
@property
def Readable ( self ) :
return self . _attribute ( 0 , ' r ' )
@property
def Resizeable ( self ) :
return self . _attribute ( 1 , ' z ' )
@property
def Exportable ( self ) :
return self . _attribute ( 2 , ' x ' )
@property
def Partial ( self ) :
return self . _attribute ( 3 , ' p ' )
@property
def AllocContiguous ( self ) :
return self . _attribute ( 4 , ' c ' )
@property
def AllocCling ( self ) :
return self . _attribute ( 4 , ' l ' )
@property
def AllocNormal ( self ) :
return self . _attribute ( 4 , ' n ' )
@property
def AllocAnywhere ( self ) :
return self . _attribute ( 4 , ' a ' )
@property
def Clustered ( self ) :
return self . _attribute ( 5 , ' c ' )
2019-10-08 00:58:10 +03:00
class VgVdo ( Vg ) :
# noinspection PyUnusedLocal,PyPep8Naming
def __init__ ( self , object_path , object_state ) :
super ( VgVdo , self ) . __init__ ( object_path , vgs_state_retrieve )
self . set_interface ( VG_VDO_INTERFACE )
self . _object_path = object_path
self . state = object_state
@staticmethod
def _lv_vdo_pool_create_with_lv ( uuid , vg_name , pool_name , lv_name ,
data_size , virtual_size , create_options ) :
Vg . validate_dbus_object ( uuid , vg_name )
Vg . handle_execute ( * cmdhandler . vg_create_vdo_pool_lv_and_lv (
vg_name , pool_name , lv_name , data_size , virtual_size ,
create_options ) )
return Vg . fetch_new_lv ( vg_name , pool_name )
@dbus.service.method (
dbus_interface = VG_VDO_INTERFACE ,
in_signature = ' ssttia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def CreateVdoPoolandLv ( self , pool_name , lv_name , data_size , virtual_size ,
tmo , create_options , cb , cbe ) :
utils . validate_lv_name ( VG_VDO_INTERFACE , self . Name , pool_name )
utils . validate_lv_name ( VG_VDO_INTERFACE , self . Name , lv_name )
r = RequestEntry ( tmo , VgVdo . _lv_vdo_pool_create_with_lv ,
( self . state . Uuid , self . state . lvm_id ,
pool_name , lv_name , round_size ( data_size ) ,
round_size ( virtual_size ) ,
create_options ) , cb , cbe )
cfg . worker_q . put ( r )
2020-01-06 13:28:41 +03:00
@staticmethod
def _vdo_pool_create ( uuid , vg_name , pool_lv , name , virtual_size , create_options ) :
Vg . validate_dbus_object ( uuid , vg_name )
# Retrieve the full name of the pool lv
pool = cfg . om . get_object_by_path ( pool_lv )
if not pool :
msg = ' LV with object path %s not present! ' % \
( pool_lv )
raise dbus . exceptions . DBusException ( VG_VDO_INTERFACE , msg )
Vg . handle_execute ( * cmdhandler . vg_create_vdo_pool (
pool . lv_full_name ( ) , name , virtual_size ,
create_options ) )
return Vg . fetch_new_lv ( vg_name , pool . Name )
@dbus.service.method (
dbus_interface = VG_VDO_INTERFACE ,
in_signature = ' ostia {sv} ' ,
out_signature = ' (oo) ' ,
async_callbacks = ( ' cb ' , ' cbe ' ) )
def CreateVdoPool ( self , pool_lv , name , virtual_size ,
tmo , create_options , cb , cbe ) :
utils . validate_lv_name ( VG_VDO_INTERFACE , self . Name , name )
r = RequestEntry ( tmo , VgVdo . _vdo_pool_create ,
( self . state . Uuid , self . state . lvm_id ,
pool_lv , name ,
round_size ( virtual_size ) ,
create_options ) , cb , cbe )
cfg . worker_q . put ( r )