Class: MiqVolumeManager

Inherits:
Object
  • Object
show all
Defined in:
lib/VolumeManager/MiqVolumeManager.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pVols) ⇒ MiqVolumeManager

Returns a new instance of MiqVolumeManager.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 58

def initialize(pVols)
  @logicalVolumes     = []         # visible logical volumes
  @physicalVolumes    = []         # visible physical volumes
  @hiddenVolumes      = []         # hidded volumes (in volume groups)
  @allPhysicalVolumes = []         # all physical volumes
  @vgHash             = nil               # volume groups hashed by name
  @rootTrees          = nil               # the MiqMountManager objects using this MiqVolumeManager object
  @vdlConnection      = nil               # connection for remote vmdk access.

  lvmPvHdrHash = {}                 # physical volume header list, for lvm
  pVols.each do |pv|
    pvh = LdmScanner.scan(pv) || Lvm2Scanner.labelScan(pv)
    if pvh
      pvh.diskObj = pv                # add reference to the pv's open disk object to the pv header
      lvmPvHdrHash[pvh.pv_uuid] = pvh # this physical volume in an LVM volume group
      @hiddenVolumes << pv            # so it's a hidden volume
      $log.info "MiqVolumeManager: #{pvh.lvm_type} metadata detected on PV: #{pv.dInfo.fileName}, partition: #{pv.partNum}"
    else
      @physicalVolumes << pv          # this physical volume is not in an LVM volume group
      $log.debug "MiqVolumeManager: No LVM metadata detected on PV: #{pv.dInfo.fileName}, partition: #{pv.partNum}"
    end
    @allPhysicalVolumes << pv
  end

  @vgHash = {}
  (lvmPvHdrHash)
  
  @vgHash.each_value { |vg| @logicalVolumes.concat(vg.getLvs) }

  @lvHash = {}
  @logicalVolumes.each do |lvdObj|
    lv    = lvdObj.dInfo.lvObj
    lvName  = lv.lvName
    vgName  = lv.vgObj.vgName

    @lvHash["/dev/#{vgName}/#{lvName}"] = lvdObj
  end

  @visibleVolumes = @logicalVolumes + @physicalVolumes
end

Instance Attribute Details

#allPhysicalVolumesObject (readonly)

Returns the value of attribute allPhysicalVolumes.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def allPhysicalVolumes
  @allPhysicalVolumes
end

#diskFileNamesObject (readonly)

Returns the value of attribute diskFileNames.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def diskFileNames
  @diskFileNames
end

#hiddenVolumesObject (readonly)

Returns the value of attribute hiddenVolumes.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def hiddenVolumes
  @hiddenVolumes
end

#logicalVolumesObject (readonly)

Returns the value of attribute logicalVolumes.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def logicalVolumes
  @logicalVolumes
end

#lvHashObject (readonly)

Returns the value of attribute lvHash.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def lvHash
  @lvHash
end

#physicalVolumesObject (readonly)

Returns the value of attribute physicalVolumes.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def physicalVolumes
  @physicalVolumes
end

#rootTreesObject

Returns the value of attribute rootTrees.



10
11
12
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 10

def rootTrees
  @rootTrees
end

#vgHashObject (readonly)

Returns the value of attribute vgHash.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def vgHash
  @vgHash
end

#visibleVolumesObject (readonly)

Returns the value of attribute visibleVolumes.



11
12
13
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 11

def visibleVolumes
  @visibleVolumes
end

Class Method Details

.fromNativePvsObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 13

def self.fromNativePvs
  return nil unless Sys::Platform::IMPL == :linux

  msg_pfx = "MiqVolumeManager.fromNativePvs"

  bdevs = `pvdisplay -c | cut -d: -f1`.tr(" \t", "").split("\n")
  ldevs = `lvdisplay -c | cut -d: -f1`.tr(" \t", "").split("\n")
  bdevs -= ldevs
  bda = []

  bdevs.each do |bd|
    next if bd == "unknowndevice"
    $log.debug "#{msg_pfx}: Opening PV = #{bd}"

    diskInfo = OpenStruct.new
    diskInfo.rawDisk = true
    diskInfo.fileName = bd

    begin
      disk = MiqDisk.new(RawDisk, diskInfo, 0)
    rescue StandardError, NoMemoryError, SignalException => err
      $log.warn "#{msg_pfx}: Could not open PV: #{bd}"
      $log.warn err.to_s
      $log.debug err.backtrace.join("\n")
      next
    end

    raise "#{msg_pfx}: Failed to open disk: #{diskInfo.fileName}" unless disk
    bda << disk

    if $log.debug?
      $log.debug "#{msg_pfx}: Block device: #{bd}"
      $log.debug "#{msg_pfx}: \tDisk type: #{disk.diskType}"
      $log.debug "#{msg_pfx}: \tDisk partition type: #{disk.partType}"
      $log.debug "#{msg_pfx}: \tDisk block size: #{disk.blockSize}"
      $log.debug "#{msg_pfx}: \tDisk start LBA: #{disk.lbaStart}"
      $log.debug "#{msg_pfx}: \tDisk end LBA: #{disk.lbaEnd}"
      $log.debug "#{msg_pfx}: \tDisk start byte: #{disk.startByteAddr}"
      $log.debug "#{msg_pfx}: \tDisk end byte: #{disk.endByteAddr}"
    end
  end

  new(bda)
end

Instance Method Details

#closeObject



99
100
101
102
103
104
105
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 99

def close
  $log.info "MiqVolumeManager.close called"
  @logicalVolumes     = @logicalVolumes.clear
  @physicalVolumes    = @physicalVolumes.clear
  @hiddenVolumes      = @hiddenVolumes.clear
  @vgHash             = nil
end

#closeAllObject



117
118
119
120
121
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 117

def closeAll
  $log.info "MiqVolumeManager.closeAll called"
  closePvols
  close
end

#closePvolsObject

Physical volumes are opened by the client, so the client should be responsible for closing them. These methods are provided as a convienience when the volume manager is instantiated through fromNativePvs().



112
113
114
115
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 112

def closePvols
  @allPhysicalVolumes.each(&:close)
  @allPhysicalVolumes.clear
end

#lvToXml(doc = nil) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 215

def lvToXml(doc = nil)
  doc = MiqXml.createDoc(nil) unless doc

  lvs = doc.add_element 'logical'
  @logicalVolumes.each do |dobj|
    lvObj = dobj.dInfo.lvObj
    name = lvObj.driveHint.blank? ? lvObj.lvName : lvObj.driveHint
    lv = lvs.add_element('volume',               "name"         => name,
                                                 "type"         => dobj.diskType,
                                                 "size"         => dobj.size,
                                                 "uid"          => lvObj.lvId,
                                                 "volume_group" => lvObj.vgObj.vgName,
                                                 "drive_hint"   => lvObj.driveHint,
                                                 "volume_name"  => lvObj.lvName,)

    if @rootTrees && @rootTrees.length > 0
      fs = @rootTrees[0].fileSystems.find { |f| f.fs.dobj.dInfo.lvObj && f.fs.dobj.dInfo.lvObj.lvName == lvObj.lvName }
      unless fs.nil?
        lv.add_attributes("filesystem" => fs.fs.fsType,
                          "free_space" => fs.fs.freeBytes,
                          "used_space" => dobj.size - fs.fs.freeBytes)
      end
    end
  end
  doc
end

#parseLvmMetadata(pvHdrs) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 123

def (pvHdrs)
  pvHdrs.each_value do |pvh|
    if pvh.lvm_type == "LVM2"
      $log.debug "MiqVolumeManager.parseLvmMetadata: parsing LVM2 metadata"
      pvh.mdList.each do |md|
        Lvm2MdParser.(md) if $log.debug?
        parser = Lvm2MdParser.new(md, pvHdrs)
        next if @vgHash[parser.vgName]
        @vgHash[parser.vgName] = parser.parse
        # @vgHash[parser.vgName].dump
      end
    elsif pvh.lvm_type == "LDM"
      $log.debug "MiqVolumeManager.parseLvmMetadata: parsing LDM metadata"
      parser = LdmMdParser.new(pvh, pvHdrs)
      next if @vgHash[parser.vgName]
      @vgHash[parser.vgName] = parser.parse
    else
      $log.debug "MiqVolumeManager.parseLvmMetadata: unknown metadata type #{pvh.lvm_type}"
      next
    end
  end
end

#parseLvmThinMetadataObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 146

def 
  @vgHash.each do |vgname, vg|
    $log.debug "MiqVolumeManager.parseLvmThinMetadata: setting LVM2 thin metadata"

    vg.thin_volumes.each do |tv|
      tv.thin_segments.each do |seg|
        seg.set_thin_pool_volume vg.logicalVolumes.values
      end
    end

    vg.thin_pool_volumes.each do |tpv|
      tpv.thin_pool_segments.each do |seg|
        seg. vg.logicalVolumes.values
        seg.set_data_volume     vg.logicalVolumes.values
      end
    end
  end
end

#pvToXml(doc = nil, hidden = false) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 176

def pvToXml(doc = nil, hidden = false)
  doc = MiqXml.createDoc(nil) unless doc

  if hidden
    vols = @hiddenVolumes
    volType = 'hidden'
  else
    vols = @physicalVolumes
    volType = 'physical'
  end

  pvs = doc.add_element volType
  vols.each do |dobj|
    pv = pvs.add_element('volume',               "controller"        => dobj.hwId,
                                                 "disk_type"         => dobj.diskType,
                                                 "location"          => dobj.partNum,
                                                 "partition_type"    => dobj.partType,
                                                 "size"              => dobj.size,
                                                 "virtual_disk_file" => dobj.dInfo.fileName,
                                                 "start_address"     => dobj.startByteAddr,)
    if @rootTrees && @rootTrees.length > 0
      pv.add_attribute("name", @rootTrees[0].osNames[dobj.hwId].to_s) if @rootTrees[0].osNames

      fs = @rootTrees[0].fileSystems.find { |f| f.fs.dobj.hwId == dobj.hwId }
      unless fs.nil?
        pv.add_attributes("filesystem" => fs.fs.fsType,
                          "free_space" => fs.fs.freeBytes,
                          "used_space" => dobj.size - fs.fs.freeBytes)
      end
    end

    if dobj.pvObj
      pv.add_attributes("volume_group" => dobj.pvObj.vgObj.vgName,
                        "uid"          => dobj.pvObj.pvId)
    end
  end
  doc
end

#toXml(doc = nil) ⇒ Object



165
166
167
168
169
170
171
172
173
174
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 165

def toXml(doc = nil)
  doc = MiqXml.createDoc(nil) unless doc

  vi = doc.add_element 'volumes'
  pvToXml(vi, false)
  pvToXml(vi, true)
  lvToXml(vi)
  vgToXml(vi)
  doc
end

#vgToXml(doc = nil) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/VolumeManager/MiqVolumeManager.rb', line 242

def vgToXml(doc = nil)
  doc = MiqXml.createDoc(nil) unless doc

  vgs = doc.add_element 'volume_groups'
  @vgHash.each do |vgn, vgo|
    pext = 0
    lext = 0

    vg = vgs.add_element('volume_group', {"name" => vgn})

    pvs = vg.add_element 'physical'
    vgo.physicalVolumes.each do |pvn, pvo|
      pvs.add_element('volume', "name"              => pvn,
                                "uid"               => pvo.pvId,
                                "controller"        => pvo.diskObj.hwId,
                                "os_name"           => pvo.device,
                                "physical_extents"  => pvo.peCount,
                                "virtual_disk_file" => pvo.diskObj.dInfo.fileName)
      pext += pvo.peCount
    end

    lvs = vg.add_element 'logical'
    vgo.logicalVolumes.each do |lvn, lvo|
      lvs.add_element('volume', "name" => lvn,
                                "uid"  => lvo.lvId)
      lvo.segments.each { |s| lext += s.extentCount }
    end

    vg.add_attributes("extent_size"      => vgo.extentSize,
                      "physical_extents" => pext,
                      "logical_extents"  => lext,
                      "free_extents"     => pext - lext)
  end if @vgHash
  doc
end