require 'active_support/core_ext/object/try' class Lvm2MdParser HASH_START = '{' HASH_END = '}' ARRAY_START = '[' ARRAY_END = ']' STRING_START = '"' STRING_END = '"' attr_reader :vgName def initialize(mdStr, pvHdrs) @pvHdrs = pvHdrs # PV headers hashed by UUID @mda = mdStr.gsub(/#.*$/, "").gsub("[", "[ ").gsub("]", " ]").gsub('"', ' " ').delete("=,").gsub(/\s+/, " ").split(' ') @vgName = @mda.shift end # def initialize def parse vgHash = {} parseObj(vgHash, @vgName) vg = vgHash[@vgName] getVgObj(@vgName, vg) end # def parse def self.dumpMetadata(md) level = 0 md.lines do |line| line.strip! level -= 1 if line[0, 1] == HASH_END || line[0, 1] == ARRAY_END $log.debug((level > 0 ? " " * level : "") + line) level += 1 if line[-1, 1] == HASH_START || line[-1, 1] == ARRAY_START end end private def getVgObj(_vgName, vg) vgObj = VolumeGroup.new(vg['id'], @vgName, vg['extent_size'], vg['seqno']) vgObj.lvmType = "LVM2" vg["status"].each { |s| vgObj.status << s } vg["physical_volumes"].each { |pvName, pv| vgObj.physicalVolumes[pvName] = getPvObj(vgObj, pvName, pv) } unless vg["physical_volumes"].nil? vg["logical_volumes"].each { |lvName, lv| vgObj.logicalVolumes[lvName] = getLvObj(vgObj, lvName, lv) } unless vg["logical_volumes"].nil? vgObj end # def getVgObj def getPvObj(vgObj, pvName, pv) pvObj = PhysicalVolume.new(pv['id'].delete('-'), pvName, pv['device'], pv['dev_size'], pv['pe_start'], pv['pe_count']) # Add reference to volume group object to each physical volume object. pvObj.vgObj = vgObj dobj = @pvHdrs[pvObj.pvId].try(:diskObj) if dobj pvObj.diskObj = dobj dobj.pvObj = pvObj end pv["status"].each { |s| pvObj.status << s } pvObj end # def getPvObj def getLvObj(vgObj, lvName, lv) lvObj = LogicalVolume.new(lv['id'], lvName, lv['segment_count']) lvObj.vgObj = vgObj lv["status"].each { |s| lvObj.status << s } (1..lvObj.segmentCount).each { |seg| lvObj.segments << getSegObj(lv["segment#{seg}"]) } lvObj end # def getLvObj def getSegObj(seg) device_id = seg['device_id'].try(:to_i) segObj = LvSegment.new(seg['start_extent'], seg['extent_count'], seg['type'], seg['stripe_count'], device_id) segObj.thin_pool = seg['thin_pool'] if seg.key?('thin_pool') segObj.metadata = seg['metadata'] if seg.key?('metadata') segObj.pool = seg['pool'] if seg.key?('pool') seg['stripes'].each_slice(2) do |pv, o| segObj.stripes << pv segObj.stripes << o.to_i end unless seg['stripes'].nil? segObj end # def getSegObj def parseObj(parent, name) val = @mda.shift parent[name] = case val when HASH_START then parseHash when ARRAY_START then parseArray else parseVal(val) end end def parseVal(val) if val == STRING_START return parseString else return val end end def parseHash h = {} name = @mda.shift while name && name != HASH_END parseObj(h, name) name = @mda.shift end h end def parseArray a = [] val = @mda.shift while val && val != ARRAY_END a << parseVal(val) val = @mda.shift end a end def parseString s = '' word = @mda.shift while word && word != STRING_END s << word + " " word = @mda.shift end s.chomp(" ") end end # class Lvm2MdParser