403Webshell
Server IP : 134.236.49.22  /  Your IP : 216.73.216.114
Web Server : Apache/2.2.15 (Fedora)
System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686
User : apache ( 48)
PHP Version : 5.3.3
Disable Function : NONE
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/system-config-lvm/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/system-config-lvm/lvm_model.py
import os
import sys
import string
import re
from lvmui_constants import *
from BlockDeviceModel import *
from execute import execWithCapture, execWithCaptureErrorStatus, execWithCaptureStatus, ProgressPopup
import gettext
_ = gettext.gettext

from PhysicalVolume import *
from LogicalVolume import *
from VolumeGroup import *
from Segment import *
from ExtentBlock import *
from Multipath import Multipath

import Filesystem
import Fstab

from utilities import follow_links_to_target


#Column names for PVS calls
P_NAME_COL=0
P_VG_NAME_COL=1
P_FMT_COL=2
P_ATTR_COL=3
P_SIZE_COL=4
P_FREE_COL=5
P_PE_COUNT_COL=6
P_PE_ALLOC_COL=7

#Column names for PVS calls
L_NAME_COL=0
L_VG_NAME_COL=1
L_ATTR_COL=2
L_SIZE_COL=3

#Column names for lvdisplay calls
LV_PATH_COL=0
LV_VGNAME_COL=1

UNUSED=_("Unused") 
UNUSED_SPACE=_("Unused Space")

UNMOUNTED=_("Unmounted")
SEG_START_COL = 2
SEG_END_COL = 4
GIG=1000000000.00
VGS_OPTION_STRING="vg_name,vg_sysid,vg_fmt,vg_attr,vg_size,vg_free,vg_extent_count,vg_free_count,vg_extent_size,max_pv,pv_count,max_lv,lv_count,vg_uuid"


PVS_OPTION_STRING="pv_name,vg_name,pv_size,pv_used,pv_free,pv_pe_count,pv_pe_alloc_count,pv_attr,pv_uuid"


VG_NAME=_("Volume Group Name:   ")
VG_SYSID=_("System ID:   ")
VG_FMT=_("Format:   ")
VG_ATTR=_("Attributes:   ")
VG_SIZE=_("Volume Group Size:   ")
VG_FREE=_("Available Space:   ")
VG_EXTENT_COUNT=_("Total Number of Extents:   ")
VG_FREE_COUNT=_("Number of Free Extents:   ")
VG_EXTENT_SIZE=_("Extent Size:   ")
MAX_PV=_("Maximum Allowed Physical Volumes:   ")
PV_COUNT=_("Number of Physical Volumes:   ")
MAX_LV=_("Maximum Allowed Logical Volumes:   ")
LV_COUNT=_("Number of Logical Volumes:   ")
VG_UUID=_("VG UUID:   ")

LV_NAME=_("Logical Volume Name:   ")
LV_SIZE=_("Logical Volume Size:   ")
LV_SEG_COUNT=_("Number of Segments:   ")
LV_STRIPE_COUNT=_("Number of Stripes:   ")
LV_STRIPE_SIZE=_("Stripe Size:   ")
LV_ATTR=_("Attributes:   ")
LV_UUID=_("LV UUID:   ")

UV_PARTITION_TYPE=_("Partition Type:   ")
UV_SIZE=_("Size:   ")
UV_MOUNT_POINT=_("Mount Point:   ")
UV_MOUNTPOINT_AT_REBOOT=_("Mount Point when Rebooted:   ")
UV_FILESYSTEM=_("File System:   ")

PV_NAME=_("Physical Volume Name:   ")
PV_SIZE=_("Physical Volume Size:   ")
PV_USED=_("Space Used:   ")
PV_FREE=_("Space Free:   ")
PV_PE_COUNT=_("Total Physical Extents:   ")
PV_PE_ALLOC_COUNT=_("Allocated Physical Extents:   ")
PV_ATTR=_("Attributes:   ")
PV_UUID=_("PV UUID:   ")

NOT_INITIALIZABLE=_("Not initializable:")
EXTENDED_PARTITION=_("Extended partition")
#Translator: the line below refers to a standard linux swap partition.
SWAP_IN_USE=_("Swap partition currently in use")
FOREIGN_BOOT_PARTITION=_("Foreign boot partition")
AUTOPARTITION_FAILURE=_("Autopartition failure")

VG_NAME_IDX = 0
VG_SYSID_IDX = 1
VG_FMT_IDX = 2
VG_ATTR_IDX = 3
VG_SIZE_IDX = 4
VG_FREE_IDX = 5
VG_EXTENT_COUNT_IDX = 6
VG_FREE_COUNT_IDX = 7
VG_EXTENT_SIZE_IDX = 8
MAX_PV_IDX = 9
PV_COUNT_IDX = 10
MAX_LV_IDX = 11
LV_COUNT_IDX = 12
VG_UUID_IDX = 13

PV_NAME_IDX = 0
PV_VG_NAME_IDX = 1
PV_SIZE_IDX = 2
PV_USED_IDX = 3
PV_FREE_IDX = 4
PV_PE_COUNT_IDX = 5
PV_PE_ALLOC_COUNT_IDX = 6
PV_ATTR_IDX = 7
PV_UUID_IDX = 8



LVS_HAS_ALL_OPTION = False
LVS_HAS_MIRROR_OPTIONS = False


class lvm_model:
  
  def __init__(self):
    global LVS_HAS_ALL_OPTION
    global LVS_HAS_MIRROR_OPTIONS
    
    out, status = execWithCaptureStatus(LVM_BIN_PATH, [LVM_BIN_PATH, 'lvs', '--config', "'log{command_names=0}'", '--all'])
    if status == 0:
      LVS_HAS_ALL_OPTION = True
    LVS_HAS_MIRROR_OPTIONS = LVS_HAS_ALL_OPTION
    
    self.__block_device_model = BlockDeviceModel()
    self.__VGs = {}
    self.__PVs = []
  
  def reload(self):
    progress = ProgressPopup(RELOAD_LVM_MESSAGE)
    progress.start()
    
    # clean-up everything
    self.__block_device_model = BlockDeviceModel()
    self.__VGs = {}
    self.__PVs = []
    
    # first query VolumeGroups
    self.__VGs = {}
    for vg in self.__query_VGs():
      self.__VGs[vg.get_name()] = vg
    
    # then query PVs
    self.__PVs = self.__query_partitions()
    
    # then query LVs
    self.__query_LVs()
    
    # then link all together
    self.__link_snapshots()
    self.__link_mirrors()
    
    # setup properties
    self.__set_VGs_props()
    self.__set_LVs_props() # has to come after link_mirrors
    self.__set_PVs_props()
    
    self.__add_unused_space()
    
    # debugging
    #for vg in self.__VGs.values():
    #  vg.print_out()
    #print '\n\nAll PVs'
    #for pv in self.__PVs:
    #  pv.print_out('')
    #sys.exit(0)
    
    progress.stop()
  
  def __query_partitions(self):
    parts = {} # PVs on a partition
    segs = []  # PVs on free space
    # get partitions from hard drives
    self.__block_device_model.reload()
    devs = self.__block_device_model.getDevices()
    # multipathing
    multipath_obj = Multipath()
    multipath_data = multipath_obj.get_multipath_data()
    for multipath in multipath_data:
      segments = []
      for path in multipath_data[multipath]:
        if path in devs:
          segments = devs[path]
          devs.pop(path)
      devs[multipath] = segments
    for devname in devs:
      self.__query_partitions2(devname, devs[devname], parts, segs)
    for pv in parts.values()[:]:
      devname = pv.getPartition()[0]
      if devname in multipath_data:
        parts.pop(pv.get_path())
        pv.removeDevname(devname)
        pv.setMultipath(devname)
        for path in multipath_data[devname]:
          pv.addDevname(path)
      for path in pv.get_paths():
        parts[path] = pv
    for pv in segs:
      devname = pv.getPartition()[0]
      if devname in multipath_data:
        pv.removeDevname(devname)
        pv.setMultipath(devname)
        for path in multipath_data[devname]:
          pv.addDevname(path)
    # disable swap partitions if in use
    result = execWithCapture('/bin/cat', ['/bin/cat', '/proc/swaps'])
    lines = result.splitlines()
    for line in lines:
      swap = line.split()[0]
      for multipath in multipath_data:
        if swap in multipath_data[multipath]:
          swap = multipath
      if swap in parts:
        parts[swap].initializable = False
        parts[swap].add_property(NOT_INITIALIZABLE, SWAP_IN_USE)
      for seg in segs:
        # swap could be a whole drive
        if swap == seg.get_path():
          seg.name = seg.extract_name(seg.get_path())
          seg.initializable = False
          seg.add_property(NOT_INITIALIZABLE, SWAP_IN_USE)
    # disable bootable partitions only if EXTended FS NOT on it (bootable flag is used by windows only)
    for path in parts:
      partition = parts[path].getPartition()[1]
      if partition.bootable:
        fs = self.__getFS(path)
        if re.match('.*ext[23].*', fs, re.I):
          # EXTended FS on it
          pass
        else:
          # some other filesystem on it
          parts[path].initializable = False
          parts[path].add_property(NOT_INITIALIZABLE, FOREIGN_BOOT_PARTITION)
    # disable unformated space, unless whole drive
    for seg in segs:
      if not seg.wholeDevice():
        # fdisk_wrapper not tested enough, so use it only on unpartitioned drives
        seg.initializable = False
        seg.add_property(NOT_INITIALIZABLE, _("Partition manually"))
    # merge parts with PVs
    for pv in self.__query_PVs():
      # assign unpartitioned drives, to PVs, if already used by LVM
      for seg in segs[:]:
        if pv.get_path() in seg.get_paths() or pv.get_path() == seg.getMultipath():
          pv.setPartition(seg.getPartition())
          pv.setMultipath(seg.getMultipath())
          for devname in seg.getDevnames():
            pv.addDevname(devname)
          pv.set_name(pv.extract_name(pv.get_path())) # overwrite Free Space label
          segs.remove(seg)
      # merge
      path = pv.get_path()
      if path in parts:
        old_pv = parts[path]
        pv.setPartition(old_pv.getPartition())
        pv.setMultipath(old_pv.getMultipath())
        for devname in old_pv.getDevnames():
          pv.addDevname(devname)
      else:
        # pv is not a partition, eg. loop device, or LV
        pass
      for path in pv.get_paths():
        parts[path] = pv
    # create return list
    pvs_list = list()
    for part in parts.values():
      if part not in pvs_list:
        pvs_list.append(part)
    for seg in segs:
      pvs_list.append(seg)
    # disable initialization of multipathed devices (for now)
    for pv in pvs_list:
      if len(pv.get_paths()) > 1:
        if pv.get_type() == UNINITIALIZED_TYPE:
          pv.add_property(NOT_INITIALIZABLE, _("Multipath device"))
          if pv.initializable:
            pv.initializable = False
            pv.add_property(_("Note:"), _("Initialize manually"))
    # all done
    return pvs_list
  def __query_partitions2(self, devname, segs, part_dictionary, seg_list):
    for seg in segs:
      if seg.id in ID_EXTENDS:
        self.__query_partitions2(devname, seg.children, part_dictionary, seg_list)
      # create pv
      pv = PhysicalVolume('/nothing', '', '', 0, 0, False, 0, 0)
      pv.setPartition((devname, seg))
      if seg.id == ID_EMPTY:
        seg_list.append(pv)
      else:
        if seg.id in ID_EXTENDS:
          # initialization of extended partition wipes all logical partitions !!!
          pv.initializable = False
          pv.add_property(NOT_INITIALIZABLE, EXTENDED_PARTITION)
        part_dictionary[pv.get_path()] = pv
  def __query_PVs(self):
    pvlist = list()
    arglist = list()
    arglist.append(LVM_BIN_PATH)
    arglist.append("pvs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append("--nosuffix")
    arglist.append("--noheadings")
    arglist.append("--units")
    arglist.append("g")
    arglist.append("--separator")
    arglist.append(",")
    arglist.append("-o")
    arglist.append("+pv_pe_count,pv_pe_alloc_count")
    result_string = execWithCapture(LVM_BIN_PATH, arglist)
    lines = result_string.splitlines()
    for line in lines:
      line = line.strip()
      words = line.split(",")
      path = words[P_NAME_COL]
      pv = PhysicalVolume(path, 
                          words[P_FMT_COL], 
                          words[P_ATTR_COL], 
                          words[P_SIZE_COL], 
                          words[P_FREE_COL],
                          True,
                          words[P_PE_COUNT_COL], 
                          words[P_PE_ALLOC_COL])
      pv.set_path(path)
      vgname = words[P_VG_NAME_COL]
      if vgname == '':
        pv.set_vg(None)
      else:
        self.__VGs[vgname].add_pv(pv)
      pvlist.append(pv)
    return pvlist
  
  def query_uninitialized(self):
    uninit_list = list()
    for part in self.__PVs:
      if part.get_type() == UNINITIALIZED_TYPE:
        uninit_list.append(part)
    return uninit_list
  
  def query_unallocated(self):
    unalloc_list = list()
    for pv in self.__PVs:
      if pv.get_type() == UNALLOCATED_TYPE:
        unalloc_list.append(pv)
    return unalloc_list
  
  def query_PVs(self):
    pv_list = list()
    for pv in self.__PVs:
      if pv.get_type() == PHYS_TYPE:
        pv_list.append(pv)
    return pv_list
  
  
  def query_PVs_for_VG(self, vgname):
    vg = self.__VGs[vgname]
    return vg.get_pvs().values()
  
    hotlist = list()
    pv_s = self.query_PVs()
    for pv in pv_s:
      if pv.get_vg() == vg:
        hotlist.append(pv)
    return hotlist
  
  def __query_VGs(self):
    vglist = list()
    arglist = list()
    arglist.append(LVM_BIN_PATH)
    arglist.append("vgs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append("--nosuffix")
    arglist.append("--noheadings")
    arglist.append("--units")
    arglist.append("b")
    arglist.append("--separator")
    arglist.append(",")
    arglist.append("-o")
    arglist.append("vg_name,vg_attr,vg_size,vg_extent_size,vg_free_count,max_lv,max_pv")
    
    result_string = execWithCapture(LVM_BIN_PATH,arglist)
    lines = result_string.splitlines()
    for line in lines:
      line = line.strip()
      words = line.split(",")
      
      extent_size = int(words[3])
      extents_total = int(words[2]) / extent_size
      extents_free = int(words[4])
      
      vgname = words[0].strip()
      
      max_lvs, max_pvs = int(words[5]), int(words[6])
      if max_lvs == 0:
        max_lvs = 256
      if max_pvs == 0:
        max_pvs = 256
      
      vg = VolumeGroup(vgname, words[1], extent_size, extents_total, extents_free, max_pvs, max_lvs)
      vglist.append(vg)
    return vglist
  
  
  def get_VGs(self):
    return self.__VGs.values()
  
  def get_VG(self, vgname):
    return self.__VGs[vgname]
  
  
  def get_VG_for_PV(self, pv):
    return pv.get_vg()
  
  def __query_LVs(self):
    if LVS_HAS_MIRROR_OPTIONS:
      LVS_OPTION_STRING="lv_name,vg_name,stripes,stripesize,lv_attr,lv_uuid,devices,origin,snap_percent,seg_start,seg_size,vg_extent_size,lv_size,mirror_log"
    else:
      LVS_OPTION_STRING="lv_name,vg_name,stripes,stripesize,lv_attr,lv_uuid,devices,origin,snap_percent,seg_start,seg_size,vg_extent_size,lv_size"
    LV_NAME_IDX         = 0
    LV_VG_NAME_IDX      = 1
    LV_STRIPES_NUM_IDX  = 2
    LV_STRIPE_SIZE_IDX  = 3
    LV_ATTR_IDX         = 4
    LV_UUID_IDX         = 5
    LV_DEVICES_IDX      = 6
    LV_SNAP_ORIGIN_IDX  = 7
    LV_SNAP_PERCENT_IDX = 8
    LV_SEG_START_IDX    = 9
    LV_SEG_SIZE_IDX     = 10
    LV_EXTENT_SIZE_IDX  = 11
    LV_SIZE_IDX         = 12
    LV_MIRROR_LOG_IDX   = 13
    
    self.__reload_logical_volumes_paths()
    
    arglist = list()
    arglist.append(LVM_BIN_PATH)
    arglist.append("lvs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")    
    arglist.append("--nosuffix")
    arglist.append("--noheadings")
    arglist.append("--units")
    arglist.append("b")
    arglist.append("--separator")
    arglist.append("\";\"")
    arglist.append("-o")
    arglist.append(LVS_OPTION_STRING)
    if LVS_HAS_ALL_OPTION:
      arglist.append("--all")
    result_string = execWithCapture(LVM_BIN_PATH, arglist)
    lines = result_string.splitlines()
    for line in lines:
      line = line.strip()
      words = line.split(';')
      vgname = words[LV_VG_NAME_IDX].strip()
      attrs = words[LV_ATTR_IDX].strip()
      uuid = words[LV_UUID_IDX].strip()
      extent_size = int(words[LV_EXTENT_SIZE_IDX])
      seg_start = int(words[LV_SEG_START_IDX]) / extent_size
      lv_size = int(words[LV_SIZE_IDX]) / extent_size
      seg_size = int(words[LV_SEG_SIZE_IDX]) / extent_size
      devices = words[LV_DEVICES_IDX]
      if LVS_HAS_MIRROR_OPTIONS:
        mirror_log = words[LV_MIRROR_LOG_IDX].strip()
      
      lvname = words[LV_NAME_IDX].strip()
      # remove [] if there (used to mark hidden lvs)
      lvname = lvname.lstrip('[')
      lvname = lvname.rstrip(']')
      
      vg = self.__VGs[vgname]
      vg_lvs = vg.get_lvs()
      lv = None
      if lvname not in vg_lvs:
        lv = LogicalVolume(lvname, self.__get_logical_volume_path(lvname, vg.get_name()), True, attrs, uuid)
        lv.set_extent_count(lv_size, lv_size)
        vg.add_lv(lv)
      lv = vg_lvs[lvname]
      
      segment = None
      devs = devices.split(',')
      if attrs[0] == 'm' or attrs[0] == 'M':
        # mirrored LV
        lv.set_mirror_log(mirror_log) # tmp, will get replaced with real one at __link_mirrors()
        segment = MirroredSegment(seg_start, seg_size)
        images = devs
        for image_name in images:
          idx = image_name.find('(')
          image_lv = LogicalVolume(image_name[:idx], None, True, None, None) # tmp, will get replaced with real one at __link_mirrors()
          segment.add_image(image_lv)
      elif len(devs) == 1:
        # linear segment
        segment = LinearSegment(seg_start, seg_size)
        idx = devs[0].find('(')
        pvpath = devs[0][:idx]
        ph_ext_beg = int(devs[0][idx+1:len(devs[0])-1])
        pv = None
        for pv_t in self.__PVs:
          if pv_t.get_path() == pvpath:
            pv = pv_t
            break
        extent_block = ExtentBlock(pv, lv, ph_ext_beg, seg_size)
        segment.set_extent_block(extent_block)
      else:
        # striped segment
        lv.set_stripes_num(int(words[LV_STRIPES_NUM_IDX]))
        stripe_size = int(words[LV_STRIPE_SIZE_IDX])
        segment = StripedSegment(stripe_size, seg_start, seg_size)
        stripe_id = 0
        for stripe in devs:
          idx = stripe.find('(')
          pvpath = stripe[:idx]
          ph_ext_beg = int(stripe[idx+1:len(stripe)-1])
          pv = None
          for pv_t in self.__PVs:
            if pv_t.get_path() == pvpath:
              pv = pv_t
              break
          extent_block = ExtentBlock(pv, lv, ph_ext_beg, seg_size/len(devs))
          segment.add_stripe(stripe_id, extent_block)
          stripe_id = stripe_id + 1
      
      lv.add_segment(segment)
      
      origin = words[LV_SNAP_ORIGIN_IDX].strip()
      if origin != '':
        # snapshot
        usage = float(words[LV_SNAP_PERCENT_IDX].strip())
        lv.set_snapshot_info(origin, usage) # set name for now, real LV will get set at __link_snapshots()
      
    # all LVs created  
  
  def __link_snapshots(self):
    for vgname in self.__VGs:
      vg = self.__VGs[vgname]
      snapshots = []
      lv_dict = vg.get_lvs()
      for lv in lv_dict.values():
        if lv.is_snapshot():
          snapshots.append(lv)
      for snap in snapshots:
        # find origin
        origin_name = snap.get_snapshot_info()[0]
        origin = lv_dict[origin_name]
        snap.set_snapshot_info(origin, snap.get_snapshot_info()[1]) # real object as origin
        origin.add_snapshot(snap)
    
  def __link_mirrors(self):
    for vgname in self.__VGs:
      vg = self.__VGs[vgname]
      lv_names = vg.get_lvs().keys()[:]
      for lvname in lv_names:
        if vg.get_lvs().has_key(lvname):
          lv = vg.get_lvs()[lvname]
          if lv.is_mirrored():
            # replace tmp lvs with real one
            # log
            #log_lv = vg.get_lvs()[lv.get_mirror_log()]
            #vg.get_lvs().pop(log_lv.get_name()) # remove log_lv from vg
            #lv.set_mirror_log(log_lv)
            mlog = lv.get_mirror_log()
            if mlog:
                log_lv = vg.get_lvs()[mlog]
                vg.get_lvs().pop(log_lv.get_name()) # remove log_lv from vg
                lv.set_mirror_log(log_lv)
            # images
            segment = lv.get_segments()[0]
            images_tmp = segment.get_images()[:] # copy
            segment.clear_images()
            for image_lv_tmp in images_tmp:
              # get real LV
              image_lv_real = vg.get_lvs()[image_lv_tmp.get_name()]
              # remove image_lv_real from vg
              vg.get_lvs().pop(image_lv_real.get_name())
              # rename it to mirror_name
              image_lv_real.set_name(lvname)
              # add it to the segment
              segment.add_image(image_lv_real)
    
  
  def __add_unused_space(self):
    #Now check if there is free space in Volume Groups
    #If there is free space, add an LV marked as 'unused' for that available space
    for vg in self.__VGs.values():
      if vg.get_extent_total_used_free()[2] == 0:
        continue
      lv_unused = LogicalVolume(UNUSED_SPACE, None, False, None, None)
      lv_unused.set_extent_count(vg.get_extent_total_used_free()[2], vg.get_extent_total_used_free()[2])
      vg.add_lv(lv_unused)
      segment_offset = 0
      # map unused extents on PVs to lv_unused
      for pv in vg.get_pvs().values():
        ext_total, ext_used, ext_free = pv.get_extent_total_used_free()
        if ext_free == 0:
          continue
        if len(pv.get_extent_blocks()) == 0:
          # nothing on PV
          segment = UnusedSegment(segment_offset, ext_free)
          segment_offset = segment_offset + ext_free
          extent = ExtentBlock(pv, lv_unused, 0, ext_free)
          segment.set_extent_block(extent)
          lv_unused.add_segment(segment)
          continue
        # fill in gaps
        ext_list = pv.get_extent_blocks()
        start1, size1 = 0, 0
        i = 0
        while i < len(ext_list):
          start2, size2 = ext_list[i].get_start_size()
          if (start1 + size1) == start2:
            start1, size1 = start2, size2
          else:
            # add extent block
            start_new = start1 + size1
            size_new = start2 - start_new
            segment = UnusedSegment(segment_offset, size_new)
            segment_offset = segment_offset + size_new
            extent = ExtentBlock(pv, lv_unused, start_new, size_new)
            segment.set_extent_block(extent)
            lv_unused.add_segment(segment)
            start1, size1 = ext_list[i].get_start_size()
          i = i + 1
        # add last one
        ext_list = pv.get_extent_blocks()
        last_ext = ext_list[len(ext_list) - 1]
        start_new = last_ext.get_start_size()[0] + last_ext.get_start_size()[1]
        size_new = ext_total - start_new
        if size_new != 0:
          segment = UnusedSegment(segment_offset, size_new)
          segment_offset = segment_offset + size_new
          extent = ExtentBlock(pv, lv_unused, start_new, size_new)
          segment.set_extent_block(extent)
          lv_unused.add_segment(segment)
    
  
  def pvmove_in_progress(self):
    LVS_OPTION_STRING="move_pv"
    arglist = list()
    arglist.append(LVM_BIN_PATH)
    arglist.append("lvs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append("--noheadings")
    arglist.append("-o")
    arglist.append('move_pv')
    if LVS_HAS_ALL_OPTION:
      arglist.append("--all")
    
    result_string = execWithCapture(LVM_BIN_PATH, arglist)
    lines = result_string.splitlines()
    for line in lines:
      if line.strip() != '':
        return True
    return False
  
  def get_logical_volume_path(self, lvname, vgname):
    self.__reload_logical_volumes_paths()
    return self.__get_logical_volume_path(lvname, vgname)
  def __get_logical_volume_path(self, lvname, vgname):
    vgname = vgname.strip()
    lvname = lvname.strip()
    return self.__lvs_paths[vgname + '`' + lvname]
  def __reload_logical_volumes_paths(self):
    self.__lvs_paths = {}
    arglist = [LVDISPLAY_BIN_PATH] #lvs does not give path info
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append('-c')
    if LVS_HAS_ALL_OPTION:
      arglist.append('-a')
    result_string = execWithCapture(LVDISPLAY_BIN_PATH,arglist)
    lines = result_string.splitlines()
    for line in lines:
      words = line.strip().split(":")
      vgname = words[LV_VGNAME_COL].strip()
      lvpath = words[LV_PATH_COL].strip()
      last_slash_index = lvpath.rfind("/") + 1
      lvname = lvpath[last_slash_index:]
      self.__lvs_paths[vgname + '`' + lvname] = lvpath
  
  def partition_UV(self, pv):
    if pv.needsFormat():
      try:
        (devname, seg) = pv.getPartition()
        fdisk_devname = None
        fdisk_devnames = self.__block_device_model.getDevices().keys()
        if devname in fdisk_devnames:
          fdisk_devname = devname
        else:
          # if pv has multipath info, devname doesn't have to be known to BlockDeviceModel
          # so find device it does :)
          multipath_object = Multipath()
          multipath_data = Multipath.get_multipath_data()
          # devname should be a multipath access point
          for path in multipath_data[devname]:
            if path in fdisk_devnames:
              fdisk_devname = path
        part = Partition(seg.beg, seg.end, ID_LINUX_LVM, None, False, seg.sectorSize)
        part_num = self.__block_device_model.add(fdisk_devname, part)
        self.__block_device_model.saveTable(fdisk_devname)
        new_part = self.__block_device_model.getPartition(fdisk_devname, part_num)
        pv.setPartition((devname, new_part))
      except BlockDeviceErr:
        self.__block_device_model.reload()
        raise CommandError('FATAL', AUTOPARTITION_FAILURE % devname)
    return pv.get_path()
  
  def __set_VGs_props(self):
    arglist = [LVM_BIN_PATH]
    arglist.append("vgs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append("--nosuffix")
    arglist.append("--noheadings")
    #arglist.append("--units")
    #arglist.append("g")
    arglist.append("--separator")
    arglist.append(",")
    arglist.append("-o")
    arglist.append(VGS_OPTION_STRING)
    vgs_output = execWithCapture(LVM_BIN_PATH,arglist)
    for vg in self.__VGs.values():
      vg.set_properties(self.__get_data_for_VG(vg, vgs_output))
  def __get_data_for_VG(self, vg, vgs_output):
    lines = vgs_output.splitlines()
    for line in lines:
      words = line.strip().split(",")
      if words[VG_NAME_IDX] == vg.get_name():
        break
    
    text_list = list()
    text_list.append(VG_NAME)
    text_list.append(words[VG_NAME_IDX])
    
    text_list.append(_("Clustered:   "))
    if vg.clustered():
      text_list.append(_("True"))
    else:
      text_list.append(_("False"))
    
    text_list.append(VG_SYSID)
    text_list.append(words[VG_SYSID_IDX])
    text_list.append(VG_FMT)
    text_list.append(words[VG_FMT_IDX])
    text_list.append(VG_ATTR)
    text_list.append(words[VG_ATTR_IDX])
    text_list.append(VG_SIZE)
    text_list.append(words[VG_SIZE_IDX])
    
    text_list.append(VG_FREE)
    text_list.append(words[VG_FREE_IDX])
    
    text_list.append(VG_EXTENT_COUNT)
    text_list.append(words[VG_EXTENT_COUNT_IDX])
    
    text_list.append(VG_FREE_COUNT)
    text_list.append(words[VG_FREE_COUNT_IDX])
    
    text_list.append(VG_EXTENT_SIZE)
    text_list.append(words[VG_EXTENT_SIZE_IDX])
    
    text_list.append(MAX_PV)
    #lvs reports 0 for sys max
    if words[MAX_PV_IDX] == "0":
      text_list.append("256")
    else:
      text_list.append(words[MAX_PV_IDX])
    
    text_list.append(PV_COUNT)
    text_list.append(words[PV_COUNT_IDX])
    
    text_list.append(MAX_LV)
    if words[MAX_LV_IDX] == "0":
      text_list.append("256")
    else:
      text_list.append(words[MAX_LV_IDX])
    
    text_list.append(LV_COUNT)
    text_list.append(words[LV_COUNT_IDX])
    
    text_list.append(VG_UUID)
    text_list.append(words[VG_UUID_IDX])
    
    return text_list
  
  def __set_LVs_props(self):
    for vg in self.__VGs.values():
      for lv in vg.get_lvs().values():
        if lv.is_used():
          lv.set_properties(self.__get_data_for_LV(lv))
  def __get_data_for_LV(self, lv):
    text_list = list()
    
    text_list.append(LV_NAME)
    text_list.append(lv.get_name())
    if lv.is_mirrored():
      text_list.append(_("Number of mirror images:"))
      text_list.append(str(len(lv.get_segments()[0].get_images())-1))
    if lv.has_snapshots():
      text_list.append(_("Snapshots:"))
      string = lv.get_snapshots()[0].get_name()
      for snap in lv.get_snapshots()[1:]:
        string = string + ', ' + snap.get_name()
      text_list.append(string)
    if lv.is_snapshot():
      text_list.append(_("Snapshot origin:"))
      text_list.append(lv.get_snapshot_info()[0].get_name())
    text_list.append(VG_NAME)
    text_list.append(lv.get_vg().get_name())
    text_list.append(LV_SIZE)
    text_list.append(lv.get_size_total_string())
    if lv.is_snapshot():
      text_list.append(_("Snapshot usage:"))
      text_list.append(str(lv.get_snapshot_info()[1]) + '%')
    text_list.append(LV_SEG_COUNT)
    text_list.append(str(len(lv.get_segments())))
    
    segment0 = lv.get_segments()[0]
    if segment0.get_type() == STRIPED_SEGMENT_ID:
      # striped
      text_list.append(LV_STRIPE_COUNT)
      text_list.append(str(len(segment0.get_stripes().values())))
      text_list.append(LV_STRIPE_SIZE)
      text_list.append(str(segment0.get_stripe_size()/1024) + KILO_SUFFIX)
    
    text_list.append(LV_ATTR)
    text_list.append(lv.get_attr())
    text_list.append(LV_UUID)
    text_list.append(lv.get_uuid())
    
    mount_point = self.getMountPoint(lv.get_path())
    if mount_point == None:
      mount_point = UNMOUNTED
    else:
      if mount_point == '/':
        mount_point = _("/   Root Filesystem")
    text_list.append(UV_MOUNT_POINT)
    text_list.append(mount_point)
    
    mountpoint_at_reboot = Fstab.get_mountpoint(lv.get_path())
    if mountpoint_at_reboot == '/':
      mountpoint_at_reboot = _("/   Root Filesystem")
    text_list.append(UV_MOUNTPOINT_AT_REBOOT)
    text_list.append(str(mountpoint_at_reboot))
    text_list.append(UV_FILESYSTEM)
    text_list.append(self.__getFS(lv.get_path()))
    
    return text_list
  
  def __set_PVs_props(self):
    arglist = list()
    arglist.append(LVM_BIN_PATH)
    arglist.append("pvs")
    arglist.append("--config")
    arglist.append("'log{command_names=0}'")
    arglist.append("--noheadings")
    arglist.append("--separator")
    arglist.append(",")
    arglist.append("-o")
    arglist.append(PVS_OPTION_STRING)
    pvs_output = execWithCapture(LVM_BIN_PATH,arglist)
    for pv in self.__PVs:
      pv.set_properties(self.__get_data_for_PV(pv, pvs_output))
  def __get_data_for_PV(self, pv, pvs_output):
    # anything that is in, place to the end
    end = pv.get_properties()
    text_list = list()
    
    if pv.get_type() == UNINITIALIZED_TYPE:
      # size
      size_string = pv.get_size_total_string()
      text_list.append(UV_SIZE)
      text_list.append(size_string)
      # partition type
      part = pv.getPartition()[1]
      partition_type = PARTITION_IDs[part.id]
      if part.id != ID_EMPTY and part.id != ID_UNKNOWN:
        partition_type = partition_type + ' (' + str(hex(part.id)) + ')'
      text_list.append(UV_PARTITION_TYPE)
      text_list.append(partition_type)
      # mount point
      mountPoints = []
      for path in pv.get_paths():
        mountPoint = self.getMountPoint(path)
        if mountPoint != None:
          if mountPoint == '/':
            mountPoint = _("/   Root Filesystem")
          mountPoints.append(mountPoint)
      if len(mountPoints) == 0:
        mountPoints = UNMOUNTED
      else:
        mount_list = mountPoints
        mountPoints = mount_list[0]
        for mountPoint in mount_list[1:]:
          mountPoints = mountPoints + ', ' + mountPoint
      text_list.append(UV_MOUNT_POINT)
      text_list.append(mountPoints)
      fstabMountPoints = []
      for path in pv.get_paths():
        mountPoint = Fstab.get_mountpoint(path)
        if mountPoint != None:
          if mountPoint == '/':
            mountPoint = _("/   Root Filesystem")
          fstabMountPoints.append(mountPoint)
      if len(fstabMountPoints) == 0:
        fstabMountPoints = _("None")
      else:
        mount_list = fstabMountPoints
        fstabMountPoints = mount_list[0]
        for mountPoint in mount_list[1:]:
          fstabMountPoints = fstabMountPoints + ', ' + mountPoint
      text_list.append(UV_MOUNTPOINT_AT_REBOOT)
      text_list.append(fstabMountPoints)
      # filesystem
      text_list.append(UV_FILESYSTEM)
      text_list.append(self.__getFS(path))
    else: # UNALLOCATED_TYPE || PHYS_TYPE
      lines = pvs_output.splitlines()
      for line in lines:
        words = line.strip().split(',')
        if words[PV_NAME_IDX] in pv.get_paths():
          break
      text_list.append(PV_NAME)
      text_list.append(words[PV_NAME_IDX])
      if words[PV_VG_NAME_IDX] == "":
        text_list.append(VG_NAME)
        text_list.append("---")
      else:
        text_list.append(VG_NAME)
        text_list.append(words[PV_VG_NAME_IDX])
      text_list.append(PV_SIZE)
      text_list.append(words[PV_SIZE_IDX])
      text_list.append(PV_USED)
      text_list.append(words[PV_USED_IDX])
      text_list.append(PV_FREE)
      text_list.append(words[PV_FREE_IDX])
      text_list.append(PV_PE_COUNT)
      text_list.append(words[PV_PE_COUNT_IDX])
      text_list.append(PV_PE_ALLOC_COUNT)
      text_list.append(words[PV_PE_ALLOC_COUNT_IDX])
      text_list.append(PV_ATTR)
      text_list.append(words[PV_ATTR_IDX])
      text_list.append(PV_UUID)
      text_list.append(words[PV_UUID_IDX])
      
    # append old props
    for prop in end:
      text_list.append(prop)
    
    try:
      # add scsi dev info
      device = pv.getDevnames()[0]
      devname = pv.extract_name(device)
      SCSI_ID_BIN = '/sbin/scsi_id'
      args = [SCSI_ID_BIN, '-g', '-i', '-u', '-s', '/block/' + devname]
      o, e, s = execWithCaptureErrorStatus(SCSI_ID_BIN, args)
      if s == 0:
        scsi_addr, scsi_id = o.strip().split()
        scsi_addr = scsi_addr.strip(':')
        text_list.append(_("SCSI Address:  "))
        text_list.append(scsi_addr)
        text_list.append(_("SCSI ID:  "))
        text_list.append(scsi_id)
    except:
      pass
    
    return text_list
  
  def __getFS(self, path):
    path_list = list()
    for pv in self.__PVs:
      if pv.get_path() == path:
        path_list.append(pv)
    if len(path_list) == 0:
      # nothing on a drive, maybe a LV, or a loopback device
      pass
    elif len(path_list) == 1:
      if path_list[0].getPartition() == None:
        # nothing on a drive, maybe a LV, or a loopback device
        pass
      # either a partition, a drive or free space
      if path_list[0].getPartition()[1].id == ID_EMPTY:
        # drive or free space
        # fixme - drive could have a filesystem on it
        return NO_FILESYSTEM
      else: 
        # partition
        pass
    else:
      # free space
      return NO_FILESYSTEM
    
    
    filesys = Filesystem.get_fs(path)
    if filesys.name == Filesystem.get_filesystems()[0].name:
      return NO_FILESYSTEM
    else:
      return filesys.name
  
  def getMountPoint(self, path):
    # follow links
    paths = [path]
    if follow_links_to_target(path, paths) == None:
      return None
    
    result = execWithCapture('/bin/cat', ['/bin/cat', '/proc/mounts', '/etc/mtab'])
    lines = result.splitlines()
    for line in lines:
      words = line.split()
      possible_path = words[0]
      if possible_path in paths:
        return words[1]
    return None
  
  def is_mirroring_supported(self):
    return LVS_HAS_MIRROR_OPTIONS


  
def lvm_conf_get_locking_type():
  conf = open('/etc/lvm/lvm.conf')
  
  lines = conf.readlines()
  for line in lines:
    words = line.split()
    if len(words) < 3:
      continue
    if words[0] == 'locking_type':
      if words[1] == '=':
        locking_type = int(words[2])
        return locking_type
  return None

Youez - 2016 - github.com/yon3zu
LinuXploit