require "ostruct" require "disk/MiqDisk" require 'binary_struct' require 'VolumeManager/MiqLvm' class MiqNativeVolumeManager attr_accessor :rootTrees attr_reader :logicalVolumes, :physicalVolumes, :visibleVolumes, :hiddenVolumes, :allPhysicalVolumes, :vgHash, :wholeDisks, :diskInitErrors def initialize(vmCfg, _ost = nil) @logicalVolumes = [] # visible logical volumes @physicalVolumes = [] # visible physical volumes @hiddenVolumes = [] # hidded volumes (in volume groups) @allPhysicalVolumes = [] # all physical volumes @wholeDisks = [] # a list of open base disks @visibleVolumes = nil # logical and physical volumes that should eb checked for filesystems @vgHash = {} # volume groups hashed by name @lvHash = {} @rootTrees = nil # the MiqMountManager objects using this MiqVolumeManager object @diskFileNames = vmCfg.getDiskFileHash `vgdisplay -c 2> /dev/null`.each { |vgl| vg = getVg(vgl); @vgHash[vg.vgName] = vg } `lvdisplay -c 2> /dev/null`.each { |lvl| lv = getLv(lvl); @lvHash[lv.lvPath] = lv } vgNames = @vgHash.keys lvNames = @lvHash.keys hiddenDevNames = `pvdisplay -c 2> /dev/null`.split("\n").collect! { |p| p.lstrip.split(":", 2)[0] } if $log.debug? $log.debug "\nVolume Groups: (#{vgNames.class}: #{vgNames.length})" vgNames.each { |dn| $log.debug "\t#{dn}" } $log.debug "\nLogical Volumes: (#{lvNames.class}: #{lvNames.length})" lvNames.each { |dn| $log.debug "\t#{dn}" } $log.debug "\nHidden devs: (#{hiddenDevNames.class}: #{hiddenDevNames.length})" end physVolumes = openPhysicalVolumes(@diskFileNames) $log.debug "\nMiqNativeVolumeManager: physVolumes:" if $log.debug? physVolumes.each do |pv| if $log.debug? $log.debug "\t#{pv.devFile} => #{pv.dInfo.hardwareId} (SIG: #{pv.dInfo.diskSig})" $log.debug "\t\tPartition: #{pv.partNum}, Type: #{pv.partType}" end if hiddenDevNames.include?(pv.devFile) $log.debug "\t\t\tHIDDEN VOLUME" if $log.debug? hiddenVolumes << pv else @physicalVolumes << pv end @allPhysicalVolumes << pv end vgNames.each { |vgn| `vgchange -a y #{vgn}` } @logicalVolumes = openLogicalVolumes(lvNames) @visibleVolumes = @logicalVolumes + @physicalVolumes end def closeAll @wholeDisks.each(&:close) @logicalVolumes = [] @physicalVolumes = [] @hiddenVolumes = [] @wholeDisks = [] @vgHash = nil @ost.miqVim.closeVdlConnection(@vdlConnection) if @vdlConnection @volMgrPS.postMount end def openLogicalVolumes(lvnames) lvList = [] lvnames.each do |lvn| # # get MiqDisk object for each LV and add to lvList. # dInfo = OpenStruct.new dInfo.localDev = lvn dInfo.lvObj = @lvHash[lvn] dInfo.hardwareId = "" lvList << MiqDisk.getDisk(dInfo) end lvList end # def openLogicalVolumes def openPhysicalVolumes(diskFiles) pVolumes = [] $log.debug "openPhysicalVolumes: no disk files supplied." unless diskFiles # # Build a list of the VM's physical volumes. # diskFiles.each do |dtag, df| $log.debug "openPhysicalVolumes: processing disk file (#{dtag}): #{df}" dInfo = OpenStruct.new dInfo.localDev = df dInfo.hardwareId = dtag begin d = MiqDisk.getDisk(dInfo) # I am not sure if getting a nil handle back should throw an error or not. # For now I am just skipping to the next disk. (GMM) next if d.nil? rescue => err $log.error "Couldn't open disk file: #{df}" $log.error err.to_s $log.debug err.backtrace.join("\n") @diskInitErrors[df] = err.to_s next end @wholeDisks << d p = d.getPartitions if p.empty? # # If the disk has no partitions, the whole disk can be a single volume. # pVolumes << d else # # If the disk is partitioned, the partitions are physical volumes, # but not the whild disk. # pVolumes.concat(p) end end pVolumes end # def openPhysicalVolumes def getVg(vgl) vga = vgl.lstrip.split(":") (VolumeGroup.new(vga[16], vga[0])) end def getLv(lvl) lva = lvl.lstrip.split(":") lvPath = lva[0] vgName = lva[1] lvId = `lvdisplay -v #{lvPath} 2> /dev/null | grep "LV UUID"`.split(" ").last lv = LogicalVolume.new(lvId, File.basename(lvPath)) vg = @vgHash[vgName] lv.vgObj = vg lv.lvPath = lvPath vg.logicalVolumes[lv.lvName] = lv end end # class MiqNativeVolumeManager