<s> """<STR_LIT>""" <EOL> import re <EOL> import stat <EOL> import os <EOL> import logging <EOL> import math <EOL> from ganeti import utils <EOL> from ganeti import errors <EOL> from ganeti import constants <EOL> from ganeti import objects <EOL> from ganeti import compat <EOL> from ganeti import serializer <EOL> from ganeti . storage import base <EOL> from ganeti . storage import drbd <EOL> from ganeti . storage . filestorage import FileStorage <EOL> from ganeti . storage . gluster import GlusterStorage <EOL> from ganeti . storage . extstorage import ExtStorageDevice <EOL> class RbdShowmappedJsonError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def _CheckResult ( result ) : <EOL> """<STR_LIT>""" <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . cmd , result . fail_reason , result . output ) <EOL> class LogicalVolume ( base . BlockDev ) : <EOL> """<STR_LIT>""" <EOL> _VALID_NAME_RE = re . compile ( "<STR_LIT>" ) <EOL> _PARSE_PV_DEV_RE = re . compile ( r"<STR_LIT>" ) <EOL> _INVALID_NAMES = compat . UniqueFrozenset ( [ "<STR_LIT:.>" , "<STR_LIT:..>" , "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> _INVALID_SUBSTRINGS = compat . UniqueFrozenset ( [ "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> def __init__ ( self , unique_id , children , size , params , dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> super ( LogicalVolume , self ) . __init__ ( unique_id , children , size , params , <EOL> dyn_params , * args ) <EOL> if not isinstance ( unique_id , ( tuple , list ) ) or len ( unique_id ) != <NUM_LIT:2> : <EOL> raise ValueError ( "<STR_LIT>" % str ( unique_id ) ) <EOL> self . _vg_name , self . _lv_name = unique_id <EOL> self . _ValidateName ( self . _vg_name ) <EOL> self . _ValidateName ( self . _lv_name ) <EOL> self . dev_path = utils . PathJoin ( "<STR_LIT>" , self . _vg_name , self . _lv_name ) <EOL> self . _degraded = True <EOL> self . major = self . minor = self . pe_size = self . stripe_count = None <EOL> self . pv_names = None <EOL> self . Attach ( ) <EOL> @ staticmethod <EOL> def _GetStdPvSize ( pvs_info ) : <EOL> """<STR_LIT>""" <EOL> assert len ( pvs_info ) > <NUM_LIT:0> <EOL> smallest = min ( [ pv . size for pv in pvs_info ] ) <EOL> return smallest / ( <NUM_LIT:1> + constants . PART_MARGIN + constants . PART_RESERVED ) <EOL> @ staticmethod <EOL> def _ComputeNumPvs ( size , pvs_info ) : <EOL> """<STR_LIT>""" <EOL> assert len ( pvs_info ) > <NUM_LIT:0> <EOL> pv_size = float ( LogicalVolume . _GetStdPvSize ( pvs_info ) ) <EOL> return int ( math . ceil ( float ( size ) / pv_size ) ) <EOL> @ staticmethod <EOL> def _GetEmptyPvNames ( pvs_info , max_pvs = None ) : <EOL> """<STR_LIT>""" <EOL> empty_pvs = filter ( objects . LvmPvInfo . IsEmpty , pvs_info ) <EOL> if max_pvs is not None : <EOL> empty_pvs = empty_pvs [ : max_pvs ] <EOL> return map ( ( lambda pv : pv . name ) , empty_pvs ) <EOL> @ classmethod <EOL> def Create ( cls , unique_id , children , size , spindles , params , excl_stor , <EOL> dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( unique_id , ( tuple , list ) ) or len ( unique_id ) != <NUM_LIT:2> : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" % <EOL> str ( unique_id ) ) <EOL> vg_name , lv_name = unique_id <EOL> cls . _ValidateName ( vg_name ) <EOL> cls . _ValidateName ( lv_name ) <EOL> pvs_info = cls . GetPVInfo ( [ vg_name ] ) <EOL> if not pvs_info : <EOL> if excl_stor : <EOL> msg = "<STR_LIT>" <EOL> else : <EOL> msg = "<STR_LIT>" % vg_name <EOL> base . ThrowError ( msg ) <EOL> pvs_info . sort ( key = ( lambda pv : pv . free ) , reverse = True ) <EOL> pvlist = [ pv . name for pv in pvs_info ] <EOL> if compat . any ( "<STR_LIT::>" in v for v in pvlist ) : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> current_pvs = len ( pvlist ) <EOL> desired_stripes = params [ constants . LDP_STRIPES ] <EOL> stripes = min ( current_pvs , desired_stripes ) <EOL> if excl_stor : <EOL> if spindles is None : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> ( err_msgs , _ ) = utils . LvmExclusiveCheckNodePvs ( pvs_info ) <EOL> if err_msgs : <EOL> for m in err_msgs : <EOL> logging . warning ( m ) <EOL> req_pvs = cls . _ComputeNumPvs ( size , pvs_info ) <EOL> if spindles < req_pvs : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> spindles , size , req_pvs ) <EOL> else : <EOL> req_pvs = spindles <EOL> pvlist = cls . _GetEmptyPvNames ( pvs_info , req_pvs ) <EOL> current_pvs = len ( pvlist ) <EOL> if current_pvs < req_pvs : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> size , current_pvs , req_pvs ) <EOL> assert current_pvs == len ( pvlist ) <EOL> stripes = current_pvs <EOL> if stripes > desired_stripes : <EOL> logging . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" , stripes , desired_stripes , current_pvs ) <EOL> else : <EOL> if stripes < desired_stripes : <EOL> logging . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" , desired_stripes , vg_name , current_pvs ) <EOL> free_size = sum ( [ pv . free for pv in pvs_info ] ) <EOL> if free_size < size : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , size , free_size ) <EOL> cmd = [ "<STR_LIT>" , "<STR_LIT>" % size , "<STR_LIT>" % lv_name ] <EOL> for stripes_arg in range ( stripes , <NUM_LIT:0> , - <NUM_LIT:1> ) : <EOL> result = utils . RunCmd ( cmd + [ "<STR_LIT>" % stripes_arg ] + [ vg_name ] + pvlist ) <EOL> if not result . failed : <EOL> break <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> return LogicalVolume ( unique_id , children , size , params , dyn_params , * args ) <EOL> @ staticmethod <EOL> def _GetVolumeInfo ( lvm_cmd , fields ) : <EOL> """<STR_LIT>""" <EOL> if not fields : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" ) <EOL> sep = "<STR_LIT:|>" <EOL> cmd = [ lvm_cmd , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" % sep , "<STR_LIT>" % "<STR_LIT:U+002C>" . join ( fields ) ] <EOL> result = utils . RunCmd ( cmd ) <EOL> if result . failed : <EOL> raise errors . CommandError ( "<STR_LIT>" % <EOL> ( result . fail_reason , result . output ) ) <EOL> data = [ ] <EOL> for line in result . stdout . splitlines ( ) : <EOL> splitted_fields = line . strip ( ) . split ( sep ) <EOL> if len ( fields ) != len ( splitted_fields ) : <EOL> raise errors . CommandError ( "<STR_LIT>" % <EOL> ( lvm_cmd , line ) ) <EOL> data . append ( splitted_fields ) <EOL> return data <EOL> @ classmethod <EOL> def GetPVInfo ( cls , vg_names , filter_allocatable = True , include_lvs = False ) : <EOL> """<STR_LIT>""" <EOL> if include_lvs : <EOL> lvfield = "<STR_LIT>" <EOL> else : <EOL> lvfield = "<STR_LIT>" <EOL> try : <EOL> info = cls . _GetVolumeInfo ( "<STR_LIT>" , [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , lvfield ] ) <EOL> except errors . GenericError , err : <EOL> logging . error ( "<STR_LIT>" , err ) <EOL> return None <EOL> if include_lvs : <EOL> info . sort ( key = ( lambda i : ( i [ <NUM_LIT:0> ] , i [ <NUM_LIT:5> ] ) ) ) <EOL> data = [ ] <EOL> lastpvi = None <EOL> for ( pv_name , vg_name , pv_free , pv_attr , pv_size , lv_name ) in info : <EOL> if filter_allocatable and pv_attr [ <NUM_LIT:0> ] != "<STR_LIT:a>" : <EOL> continue <EOL> if vg_names and vg_name not in vg_names : <EOL> continue <EOL> if lastpvi and lastpvi . name == pv_name : <EOL> if include_lvs and lv_name : <EOL> if not lastpvi . lv_list or lastpvi . lv_list [ - <NUM_LIT:1> ] != lv_name : <EOL> lastpvi . lv_list . append ( lv_name ) <EOL> else : <EOL> if include_lvs and lv_name : <EOL> lvl = [ lv_name ] <EOL> else : <EOL> lvl = [ ] <EOL> lastpvi = objects . LvmPvInfo ( name = pv_name , vg_name = vg_name , <EOL> size = float ( pv_size ) , free = float ( pv_free ) , <EOL> attributes = pv_attr , lv_list = lvl ) <EOL> data . append ( lastpvi ) <EOL> return data <EOL> @ classmethod <EOL> def _GetRawFreePvInfo ( cls , vg_name ) : <EOL> """<STR_LIT>""" <EOL> pvs_info = cls . GetPVInfo ( [ vg_name ] ) <EOL> if not pvs_info : <EOL> pv_size = <NUM_LIT:0.0> <EOL> free_pvs = <NUM_LIT:0> <EOL> num_pvs = <NUM_LIT:0> <EOL> else : <EOL> pv_size = cls . _GetStdPvSize ( pvs_info ) <EOL> free_pvs = len ( cls . _GetEmptyPvNames ( pvs_info ) ) <EOL> num_pvs = len ( pvs_info ) <EOL> return ( pv_size , free_pvs , num_pvs ) <EOL> @ classmethod <EOL> def _GetExclusiveStorageVgFree ( cls , vg_name ) : <EOL> """<STR_LIT>""" <EOL> ( pv_size , free_pvs , _ ) = cls . _GetRawFreePvInfo ( vg_name ) <EOL> return pv_size * free_pvs <EOL> @ classmethod <EOL> def GetVgSpindlesInfo ( cls , vg_name ) : <EOL> """<STR_LIT>""" <EOL> ( _ , free_pvs , num_pvs ) = cls . _GetRawFreePvInfo ( vg_name ) <EOL> return ( free_pvs , num_pvs ) <EOL> @ classmethod <EOL> def GetVGInfo ( cls , vg_names , excl_stor , filter_readonly = True ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> info = cls . _GetVolumeInfo ( "<STR_LIT>" , [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ] ) <EOL> except errors . GenericError , err : <EOL> logging . error ( "<STR_LIT>" , err ) <EOL> return None <EOL> data = [ ] <EOL> for vg_name , vg_free , vg_attr , vg_size in info : <EOL> if filter_readonly and vg_attr [ <NUM_LIT:0> ] == "<STR_LIT:r>" : <EOL> continue <EOL> if vg_names and vg_name not in vg_names : <EOL> continue <EOL> if excl_stor : <EOL> es_free = cls . _GetExclusiveStorageVgFree ( vg_name ) <EOL> assert es_free <= vg_free <EOL> vg_free = es_free <EOL> data . append ( ( float ( vg_free ) , float ( vg_size ) , vg_name ) ) <EOL> return data <EOL> @ classmethod <EOL> def _ValidateName ( cls , name ) : <EOL> """<STR_LIT>""" <EOL> if ( not cls . _VALID_NAME_RE . match ( name ) or <EOL> name in cls . _INVALID_NAMES or <EOL> compat . any ( substring in name for substring in cls . _INVALID_SUBSTRINGS ) ) : <EOL> base . ThrowError ( "<STR_LIT>" , name ) <EOL> def Remove ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . minor and not self . Attach ( ) : <EOL> return <EOL> result = utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" % <EOL> ( self . _vg_name , self . _lv_name ) ] ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> def Rename ( self , new_id ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( new_id , ( tuple , list ) ) or len ( new_id ) != <NUM_LIT:2> : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" % new_id ) <EOL> new_vg , new_name = new_id <EOL> if new_vg != self . _vg_name : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> ( self . _vg_name , new_vg ) ) <EOL> result = utils . RunCmd ( [ "<STR_LIT>" , new_vg , self . _lv_name , new_name ] ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , result . output ) <EOL> self . _lv_name = new_name <EOL> self . dev_path = utils . PathJoin ( "<STR_LIT>" , self . _vg_name , self . _lv_name ) <EOL> @ classmethod <EOL> def _ParseLvInfoLine ( cls , line , sep ) : <EOL> """<STR_LIT>""" <EOL> elems = line . strip ( ) . split ( sep ) <EOL> if len ( elems ) == <NUM_LIT:7> and elems [ - <NUM_LIT:1> ] == "<STR_LIT>" : <EOL> elems . pop ( ) <EOL> if len ( elems ) != <NUM_LIT:6> : <EOL> base . ThrowError ( "<STR_LIT>" , str ( elems ) ) <EOL> ( status , major , minor , pe_size , stripes , pvs ) = elems <EOL> if len ( status ) < <NUM_LIT:6> : <EOL> base . ThrowError ( "<STR_LIT>" , status ) <EOL> try : <EOL> major = int ( major ) <EOL> minor = int ( minor ) <EOL> except ( TypeError , ValueError ) , err : <EOL> base . ThrowError ( "<STR_LIT>" , str ( err ) ) <EOL> try : <EOL> pe_size = int ( float ( pe_size ) ) <EOL> except ( TypeError , ValueError ) , err : <EOL> base . ThrowError ( "<STR_LIT>" , err ) <EOL> try : <EOL> stripes = int ( stripes ) <EOL> except ( TypeError , ValueError ) , err : <EOL> base . ThrowError ( "<STR_LIT>" , err ) <EOL> pv_names = [ ] <EOL> if pvs != "<STR_LIT>" : <EOL> for pv in pvs . split ( "<STR_LIT:U+002C>" ) : <EOL> m = re . match ( cls . _PARSE_PV_DEV_RE , pv ) <EOL> if not m : <EOL> base . ThrowError ( "<STR_LIT>" , pvs ) <EOL> pv_names . append ( m . group ( <NUM_LIT:1> ) ) <EOL> return ( status , major , minor , pe_size , stripes , pv_names ) <EOL> @ classmethod <EOL> def _GetLvInfo ( cls , dev_path , _run_cmd = utils . RunCmd ) : <EOL> """<STR_LIT>""" <EOL> sep = "<STR_LIT:|>" <EOL> result = _run_cmd ( [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" % sep , <EOL> "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , dev_path ] ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> dev_path , result . fail_reason , result . output ) <EOL> out = result . stdout . splitlines ( ) <EOL> if not out : <EOL> base . ThrowError ( "<STR_LIT>" , str ( out ) ) <EOL> pv_names = set ( ) <EOL> for line in out : <EOL> ( status , major , minor , pe_size , stripes , more_pvs ) = cls . _ParseLvInfoLine ( line , sep ) <EOL> pv_names . update ( more_pvs ) <EOL> return ( status , major , minor , pe_size , stripes , pv_names ) <EOL> def Attach ( self ) : <EOL> """<STR_LIT>""" <EOL> self . attached = False <EOL> try : <EOL> ( status , major , minor , pe_size , stripes , pv_names ) = self . _GetLvInfo ( self . dev_path ) <EOL> except errors . BlockDeviceError : <EOL> return False <EOL> self . major = major <EOL> self . minor = minor <EOL> self . pe_size = pe_size <EOL> self . stripe_count = stripes <EOL> self . _degraded = status [ <NUM_LIT:0> ] == "<STR_LIT:v>" <EOL> self . pv_names = pv_names <EOL> self . attached = True <EOL> return True <EOL> def Assemble ( self ) : <EOL> """<STR_LIT>""" <EOL> result = utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" , self . dev_path ] ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , self . dev_path , result . output ) <EOL> def Shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def GetSyncStatus ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _degraded : <EOL> ldisk_status = constants . LDS_FAULTY <EOL> else : <EOL> ldisk_status = constants . LDS_OKAY <EOL> return objects . BlockDevStatus ( dev_path = self . dev_path , <EOL> major = self . major , <EOL> minor = self . minor , <EOL> sync_percent = None , <EOL> estimated_time = None , <EOL> is_degraded = self . _degraded , <EOL> ldisk_status = ldisk_status ) <EOL> def Open ( self , force = False , exclusive = True ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Close ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Snapshot ( self , snap_name = None , snap_size = None ) : <EOL> """<STR_LIT>""" <EOL> if not snap_name : <EOL> snap_name = self . _lv_name + "<STR_LIT>" <EOL> if not snap_size : <EOL> snap_size = self . size <EOL> snap = LogicalVolume ( ( self . _vg_name , snap_name ) , None , snap_size , <EOL> self . params , self . dyn_params ) <EOL> base . IgnoreError ( snap . Remove ) <EOL> vg_info = self . GetVGInfo ( [ self . _vg_name ] , False ) <EOL> if not vg_info : <EOL> base . ThrowError ( "<STR_LIT>" , self . _vg_name ) <EOL> free_size , _ , _ = vg_info [ <NUM_LIT:0> ] <EOL> if free_size < snap_size : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , snap_size , free_size ) <EOL> _CheckResult ( utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" % snap_size , "<STR_LIT>" , <EOL> "<STR_LIT>" % snap_name , self . dev_path ] ) ) <EOL> return ( self . _vg_name , snap_name ) <EOL> def _RemoveOldInfo ( self ) : <EOL> """<STR_LIT>""" <EOL> result = utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> self . dev_path ] ) <EOL> _CheckResult ( result ) <EOL> raw_tags = result . stdout . strip ( ) <EOL> if raw_tags : <EOL> for tag in raw_tags . split ( "<STR_LIT:U+002C>" ) : <EOL> _CheckResult ( utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" , <EOL> tag . strip ( ) , self . dev_path ] ) ) <EOL> def SetInfo ( self , text ) : <EOL> """<STR_LIT>""" <EOL> base . BlockDev . SetInfo ( self , text ) <EOL> self . _RemoveOldInfo ( ) <EOL> text = re . sub ( "<STR_LIT>" , "<STR_LIT:_>" , text ) <EOL> text = re . sub ( "<STR_LIT>" , "<STR_LIT:_>" , text ) <EOL> text = text [ : <NUM_LIT> ] <EOL> _CheckResult ( utils . RunCmd ( [ "<STR_LIT>" , "<STR_LIT>" , text , self . dev_path ] ) ) <EOL> def _GetGrowthAvaliabilityExclStor ( self ) : <EOL> """<STR_LIT>""" <EOL> pvs_info = self . GetPVInfo ( [ self . _vg_name ] ) <EOL> if not pvs_info : <EOL> base . ThrowError ( "<STR_LIT>" , self . dev_path ) <EOL> std_pv_size = self . _GetStdPvSize ( pvs_info ) <EOL> free_space = sum ( pvi . free - ( pvi . size - std_pv_size ) <EOL> for pvi in pvs_info <EOL> if pvi . name in self . pv_names ) <EOL> return free_space <EOL> def Grow ( self , amount , dryrun , backingstore , excl_stor ) : <EOL> """<STR_LIT>""" <EOL> if not backingstore : <EOL> return <EOL> if self . pe_size is None or self . stripe_count is None : <EOL> if not self . Attach ( ) : <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> full_stripe_size = self . pe_size * self . stripe_count <EOL> amount *= <NUM_LIT> <EOL> rest = amount % full_stripe_size <EOL> if rest != <NUM_LIT:0> : <EOL> amount += full_stripe_size - rest <EOL> cmd = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" % amount ] <EOL> if dryrun : <EOL> cmd . append ( "<STR_LIT>" ) <EOL> if excl_stor : <EOL> free_space = self . _GetGrowthAvaliabilityExclStor ( ) <EOL> if amount > free_space * <NUM_LIT> : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , self . dev_path , amount / <NUM_LIT> , <EOL> free_space ) <EOL> pvlist = list ( self . pv_names ) <EOL> else : <EOL> pvlist = [ ] <EOL> for alloc_policy in "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" : <EOL> result = utils . RunCmd ( cmd + [ "<STR_LIT>" , alloc_policy , self . dev_path ] + <EOL> pvlist ) <EOL> if not result . failed : <EOL> return <EOL> base . ThrowError ( "<STR_LIT>" , self . dev_path , result . output ) <EOL> def GetActualSpindles ( self ) : <EOL> """<STR_LIT>""" <EOL> assert self . attached , "<STR_LIT>" <EOL> return len ( self . pv_names ) <EOL> class PersistentBlockDevice ( base . BlockDev ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , unique_id , children , size , params , dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> super ( PersistentBlockDevice , self ) . __init__ ( unique_id , children , size , <EOL> params , dyn_params , * args ) <EOL> if not isinstance ( unique_id , ( tuple , list ) ) or len ( unique_id ) != <NUM_LIT:2> : <EOL> raise ValueError ( "<STR_LIT>" % str ( unique_id ) ) <EOL> self . dev_path = unique_id [ <NUM_LIT:1> ] <EOL> if not os . path . realpath ( self . dev_path ) . startswith ( "<STR_LIT>" ) : <EOL> raise ValueError ( "<STR_LIT>" % <EOL> os . path . realpath ( self . dev_path ) ) <EOL> if unique_id [ <NUM_LIT:0> ] != constants . BLOCKDEV_DRIVER_MANUAL : <EOL> raise ValueError ( "<STR_LIT>" % <EOL> unique_id [ <NUM_LIT:0> ] ) <EOL> self . major = self . minor = None <EOL> self . Attach ( ) <EOL> @ classmethod <EOL> def Create ( cls , unique_id , children , size , spindles , params , excl_stor , <EOL> dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> if excl_stor : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return PersistentBlockDevice ( unique_id , children , <NUM_LIT:0> , params , dyn_params , <EOL> * args ) <EOL> def Remove ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Rename ( self , new_id ) : <EOL> """<STR_LIT>""" <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> def Attach ( self ) : <EOL> """<STR_LIT>""" <EOL> self . attached = False <EOL> try : <EOL> st = os . stat ( self . dev_path ) <EOL> except OSError , err : <EOL> logging . error ( "<STR_LIT>" , self . dev_path , str ( err ) ) <EOL> return False <EOL> if not stat . S_ISBLK ( st . st_mode ) : <EOL> logging . error ( "<STR_LIT>" , self . dev_path ) <EOL> return False <EOL> self . major = os . major ( st . st_rdev ) <EOL> self . minor = utils . osminor ( st . st_rdev ) <EOL> self . attached = True <EOL> return True <EOL> def Assemble ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Open ( self , force = False , exclusive = True ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Close ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Grow ( self , amount , dryrun , backingstore , excl_stor ) : <EOL> """<STR_LIT>""" <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> def Import ( self ) : <EOL> """<STR_LIT>""" <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> class RADOSBlockDevice ( base . BlockDev ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , unique_id , children , size , params , dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> super ( RADOSBlockDevice , self ) . __init__ ( unique_id , children , size , params , <EOL> dyn_params , * args ) <EOL> if not isinstance ( unique_id , ( tuple , list ) ) or len ( unique_id ) != <NUM_LIT:2> : <EOL> raise ValueError ( "<STR_LIT>" % str ( unique_id ) ) <EOL> self . driver , self . rbd_name = unique_id <EOL> self . rbd_pool = params [ constants . LDP_POOL ] <EOL> self . major = self . minor = None <EOL> self . Attach ( ) <EOL> @ classmethod <EOL> def Create ( cls , unique_id , children , size , spindles , params , excl_stor , <EOL> dyn_params , * args ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( unique_id , ( tuple , list ) ) or len ( unique_id ) != <NUM_LIT:2> : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" % <EOL> str ( unique_id ) ) <EOL> if excl_stor : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> rbd_pool = params [ constants . LDP_POOL ] <EOL> rbd_name = unique_id [ <NUM_LIT:1> ] <EOL> cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , rbd_pool , <EOL> rbd_name , "<STR_LIT>" , "<STR_LIT:%s>" % size ] <EOL> result = utils . RunCmd ( cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> return RADOSBlockDevice ( unique_id , children , size , params , dyn_params , <EOL> * args ) <EOL> def Remove ( self ) : <EOL> """<STR_LIT>""" <EOL> rbd_pool = self . params [ constants . LDP_POOL ] <EOL> rbd_name = self . unique_id [ <NUM_LIT:1> ] <EOL> if not self . minor and not self . Attach ( ) : <EOL> return <EOL> self . Shutdown ( ) <EOL> cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , rbd_pool , rbd_name ] <EOL> result = utils . RunCmd ( cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> def Rename ( self , new_id ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Attach ( self ) : <EOL> """<STR_LIT>""" <EOL> self . attached = False <EOL> self . dev_path = self . _MapVolumeToBlockdev ( self . unique_id ) <EOL> try : <EOL> st = os . stat ( self . dev_path ) <EOL> except OSError , err : <EOL> logging . error ( "<STR_LIT>" , self . dev_path , str ( err ) ) <EOL> return False <EOL> if not stat . S_ISBLK ( st . st_mode ) : <EOL> logging . error ( "<STR_LIT>" , self . dev_path ) <EOL> return False <EOL> self . major = os . major ( st . st_rdev ) <EOL> self . minor = utils . osminor ( st . st_rdev ) <EOL> self . attached = True <EOL> return True <EOL> def _MapVolumeToBlockdev ( self , unique_id ) : <EOL> """<STR_LIT>""" <EOL> pool = self . params [ constants . LDP_POOL ] <EOL> name = unique_id [ <NUM_LIT:1> ] <EOL> rbd_dev = self . _VolumeToBlockdev ( pool , name ) <EOL> if rbd_dev : <EOL> return rbd_dev <EOL> map_cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , pool , name ] <EOL> result = utils . RunCmd ( map_cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> rbd_dev = self . _VolumeToBlockdev ( pool , name ) <EOL> if not rbd_dev : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , name ) <EOL> return rbd_dev <EOL> @ classmethod <EOL> def _VolumeToBlockdev ( cls , pool , volume_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> showmap_cmd = [ <EOL> constants . RBD_CMD , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> pool , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" <EOL> ] <EOL> result = utils . RunCmd ( showmap_cmd ) <EOL> if result . failed : <EOL> logging . error ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> raise RbdShowmappedJsonError <EOL> return cls . _ParseRbdShowmappedJson ( result . output , volume_name ) <EOL> except RbdShowmappedJsonError : <EOL> showmap_cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , pool ] <EOL> result = utils . RunCmd ( showmap_cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> return cls . _ParseRbdShowmappedPlain ( result . output , volume_name ) <EOL> @ staticmethod <EOL> def _ParseRbdShowmappedJson ( output , volume_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> devices = serializer . LoadJson ( output ) <EOL> except ValueError , err : <EOL> base . ThrowError ( "<STR_LIT>" % err ) <EOL> rbd_dev = None <EOL> for d in devices . values ( ) : <EOL> try : <EOL> name = d [ "<STR_LIT:name>" ] <EOL> except KeyError : <EOL> base . ThrowError ( "<STR_LIT>" , devices ) <EOL> if name == volume_name : <EOL> if rbd_dev is not None : <EOL> base . ThrowError ( "<STR_LIT>" , volume_name ) <EOL> rbd_dev = d [ "<STR_LIT>" ] <EOL> return rbd_dev <EOL> @ staticmethod <EOL> def _ParseRbdShowmappedPlain ( output , volume_name ) : <EOL> """<STR_LIT>""" <EOL> allfields = <NUM_LIT:5> <EOL> volumefield = <NUM_LIT:2> <EOL> devicefield = <NUM_LIT:4> <EOL> lines = output . splitlines ( ) <EOL> splitted_lines = map ( lambda l : l . split ( ) , lines ) <EOL> if not splitted_lines : <EOL> return None <EOL> field_cnt = len ( splitted_lines [ <NUM_LIT:0> ] ) <EOL> if field_cnt != allfields : <EOL> splitted_lines = map ( lambda l : l . split ( "<STR_LIT:\t>" ) , lines ) <EOL> if field_cnt != allfields : <EOL> base . ThrowError ( "<STR_LIT>" <EOL> "<STR_LIT>" , allfields , field_cnt ) <EOL> matched_lines = filter ( lambda l : len ( l ) == allfields and l [ volumefield ] == volume_name , <EOL> splitted_lines ) <EOL> if len ( matched_lines ) > <NUM_LIT:1> : <EOL> base . ThrowError ( "<STR_LIT>" , volume_name ) <EOL> if matched_lines : <EOL> rbd_dev = matched_lines [ <NUM_LIT:0> ] [ devicefield ] <EOL> return rbd_dev <EOL> return None <EOL> def Assemble ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Shutdown ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . minor and not self . Attach ( ) : <EOL> return <EOL> self . _UnmapVolumeFromBlockdev ( self . unique_id ) <EOL> self . minor = None <EOL> self . dev_path = None <EOL> def _UnmapVolumeFromBlockdev ( self , unique_id ) : <EOL> """<STR_LIT>""" <EOL> pool = self . params [ constants . LDP_POOL ] <EOL> name = unique_id [ <NUM_LIT:1> ] <EOL> rbd_dev = self . _VolumeToBlockdev ( pool , name ) <EOL> if rbd_dev : <EOL> unmap_cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT:%s>" % rbd_dev ] <EOL> result = utils . RunCmd ( unmap_cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> def Open ( self , force = False , exclusive = True ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Close ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def Grow ( self , amount , dryrun , backingstore , excl_stor ) : <EOL> """<STR_LIT>""" <EOL> if not backingstore : <EOL> return <EOL> if not self . Attach ( ) : <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> if dryrun : <EOL> return <EOL> rbd_pool = self . params [ constants . LDP_POOL ] <EOL> rbd_name = self . unique_id [ <NUM_LIT:1> ] <EOL> new_size = self . size + amount <EOL> cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , rbd_pool , <EOL> rbd_name , "<STR_LIT>" , "<STR_LIT:%s>" % new_size ] <EOL> result = utils . RunCmd ( cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> def Import ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . minor and not self . Attach ( ) : <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> rbd_pool = self . params [ constants . LDP_POOL ] <EOL> rbd_name = self . unique_id [ <NUM_LIT:1> ] <EOL> self . _UnmapVolumeFromBlockdev ( self . unique_id ) <EOL> cmd = [ constants . RBD_CMD , "<STR_LIT>" , "<STR_LIT>" , rbd_pool , rbd_name ] <EOL> result = utils . RunCmd ( cmd ) <EOL> if result . failed : <EOL> base . ThrowError ( "<STR_LIT>" , <EOL> result . fail_reason , result . output ) <EOL> return [ constants . RBD_CMD , "<STR_LIT>" , <EOL> "<STR_LIT>" , rbd_pool , <EOL> "<STR_LIT:->" , rbd_name ] <EOL> def Export ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . minor and not self . Attach ( ) : <EOL> base . ThrowError ( "<STR_LIT>" ) <EOL> rbd_pool = self . params [ constants . LDP_POOL ] <EOL> rbd_name = self . unique_id [ <NUM_LIT:1> ] <EOL> return [ constants . RBD_CMD , "<STR_LIT>" , <EOL> "<STR_LIT>" , rbd_pool , <EOL> rbd_name , "<STR_LIT:->" ] <EOL> def GetUserspaceAccessUri ( self , hypervisor ) : <EOL> """<STR_LIT>""" <EOL> if hypervisor == constants . HT_KVM : <EOL> return "<STR_LIT>" + self . rbd_pool + "<STR_LIT:/>" + self . rbd_name <EOL> else : <EOL> base . ThrowError ( "<STR_LIT>" % <EOL> hypervisor ) <EOL> def _VerifyDiskType ( dev_type ) : <EOL> if dev_type not in DEV_MAP : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" % dev_type ) <EOL> def _VerifyDiskParams ( disk ) : <EOL> """<STR_LIT>""" <EOL> missing = set ( constants . DISK_LD_DEFAULTS [ disk . dev_type ] ) - set ( disk . params ) <EOL> if missing : <EOL> raise errors . ProgrammerError ( "<STR_LIT>" % <EOL> missing ) <EOL> def FindDevice ( disk , children ) : <EOL> """<STR_LIT>""" <EOL> _VerifyDiskType ( disk . dev_type ) <EOL> device = DEV_MAP [ disk . dev_type ] ( disk . logical_id , children , disk . size , <EOL> disk . params , disk . dynamic_params , <EOL> disk . name , disk . uuid ) <EOL> if not device . attached : <EOL> return None <EOL> return device <EOL> def Assemble ( disk , children ) : <EOL> """<STR_LIT>""" <EOL> _VerifyDiskType ( disk . dev_type ) <EOL> _VerifyDiskParams ( disk ) <EOL> device = DEV_MAP [ disk . dev_type ] ( disk . logical_id , children , disk . size , <EOL> disk . params , disk . dynamic_params , <EOL> disk . name , disk . uuid ) <EOL> device . Assemble ( ) <EOL> return device <EOL> def Create ( disk , children , excl_stor ) : <EOL> """<STR_LIT>""" <EOL> _VerifyDiskType ( disk . dev_type ) <EOL> _VerifyDiskParams ( disk ) <EOL> device = DEV_MAP [ disk . dev_type ] . Create ( disk . logical_id , children , disk . size , <EOL> disk . spindles , disk . params , excl_stor , <EOL> disk . dynamic_params , <EOL> disk . name , disk . uuid ) <EOL> return device <EOL> DEV_MAP = { <EOL> constants . DT_PLAIN : LogicalVolume , <EOL> constants . DT_DRBD8 : drbd . DRBD8Dev , <EOL> constants . DT_BLOCK : PersistentBlockDevice , <EOL> constants . DT_RBD : RADOSBlockDevice , <EOL> constants . DT_EXT : ExtStorageDevice , <EOL> constants . DT_FILE : FileStorage , <EOL> constants . DT_SHARED_FILE : FileStorage , <EOL> constants . DT_GLUSTER : GlusterStorage , <EOL> } <EOL> """<STR_LIT>""" </s>
