Module: RhevmDescriptor

Defined in:
lib/disk/modules/RhevmDescriptor.rb

Instance Method Summary collapse

Instance Method Details

#buildFilename(parent_uuid) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/disk/modules/RhevmDescriptor.rb', line 159

def buildFilename(parent_uuid)
  parentFileName = Pathname.new(parent_uuid)
  if parentFileName.absolute?
    parentFileName = parentFileName.relative_path_from(Pathname.new(dInfo.fileName).dirname)
    $log.debug "#{self.class.name}: Parent disk file is absolute. Using relative path [#{parentFileName}]" if $log
  end
  File.join(File.dirname(dInfo.fileName), parentFileName.to_s.tr("\\", "/"))
end

#d_closeObject

Close all disks.



110
111
112
113
# File 'lib/disk/modules/RhevmDescriptor.rb', line 110

def d_close
  @parent.close unless @parent.nil?
  @disks.each(&:close)
end

#d_initObject



4
5
6
7
8
9
10
11
12
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
# File 'lib/disk/modules/RhevmDescriptor.rb', line 4

def d_init
  # Make sure this is a descriptor.
  desc, defs = parseDescriptor(dInfo.Descriptor)

  # Make sure each disk is there.
  defs.each do|diskDef|
    filename = buildFilename(diskDef[:filename])
    raise "No disk file: #{filename}" unless File.exist?(filename)
  end

  # Init needed stff.
  self.diskType = "Rhevm Descriptor"
  self.blockSize = 512
  @desc     = desc  # This disk descriptor.
  @defs     = defs  # Disk extent definitions.
  @ostructs = []    # Component OpenStructs for disk objects.
  @disks    = []    # Component MiqDisk objects (one for each disk).

  # If there's a parent parse it first (all subordinate disks need a ref to parent).
  if desc.key?(:puuid) && desc[:puuid] != '00000000-0000-0000-0000-000000000000'
    @parentOstruct = OpenStruct.new

    # Get the parentFileNameHint and be sure it is relative to the descriptor file's directory
    parentFileName = buildFilename(desc[:puuid])
    # puts "#{self.class.name}: Getting parent disk file [#{parentFileName}]"

    @parentOstruct.fileName = parentFileName
    @parentOstruct.mountMode = dInfo.mountMode
    @parentOstruct.hardwareId = dInfo.hardwareId if dInfo.baseOnly
    d = MiqDisk.getDisk(@parentOstruct)
    raise "MiqDisk#getDisk returned nil for parent disk #{@parentOstruct.fileName}" if d.nil?
    @parent = d
    return if dInfo.baseOnly
  end

  # Instance MiqDisks for each disk definition.
  defs.each do |diskDef|
    thisO = OpenStruct.new
    thisO.Descriptor = dInfo.Descriptor if dInfo.Descriptor
    thisO.parent = @parent
    thisO.fileName = buildFilename(diskDef[:filename])
    thisO.offset = diskDef[:offset]
    thisO.rawDisk = true if diskDef[:format].to_s.include?('RAW')
    thisO.mountMode = dInfo.mountMode
    @ostructs << thisO
    d = MiqDisk.getDisk(thisO)
    raise "MiqDisk#getDisk returned nil for component disk #{thisO.fileName}" if d.nil?
    @disks << d
  end
end

#d_read(pos, len) ⇒ Object



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
# File 'lib/disk/modules/RhevmDescriptor.rb', line 59

def d_read(pos, len)
  # $log.debug "RhevmDescriptor.d_read << pos #{pos} len #{len}" if $log && $log.debug?
  # Get start and end extents.
  dStart = getTargetDiskIndex((pos / @blockSize).ceil)
  dEnd   = getTargetDiskIndex(((pos + len) / @blockSize).ceil)

  if dStart == dEnd
    # Case: single extent.
    retBytes = @disks[dStart].d_read(pos, len, getDiskByteOffset(dStart))
  else
    # Case: span extents.
    retBytes = ""; bytesRead = 0
    dStart.upto(dEnd) do |diskIdx|
      readLen = @disks[diskIdx].d_size

      # Adjust length for start and end extents.
      readLen -= pos if diskIdx == dStart
      readLen -= (len - bytesRead) if diskIdx == dEnd

      # Read.
      retBytes << @disks[diskIdx].d_read(pos + bytesRead, readLen, getDiskByteOffset(diskIdx))
      bytesRead += readLen
    end
  end
  # $log.debug "RhevmDescriptor.d_read >> retBytes.length #{retBytes.length}" if $log && $log.debug?
  retBytes
end

#d_sizeObject

Return size in sectors.



116
117
118
# File 'lib/disk/modules/RhevmDescriptor.rb', line 116

def d_size
  @desc[:size].to_i
end

#d_write(pos, buf, len) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/disk/modules/RhevmDescriptor.rb', line 87

def d_write(pos, buf, len)
  dStart = getTargetDiskIndex((pos / @blockSize).ceil)
  dEnd   = getTargetDiskIndex(((pos + len) / @blockSize).ceil)

  # Case: single extent.
  return @disks[dStart].d_write(pos, buf, len, getDiskByteOffset(dStart)) if dStart == dEnd

  # Case: span extents.
  bytesWritten = 0
  dStart.upto(dEnd) do |diskIdx|
    writeLen = @disks[diskIdx].d_size

    # Adjust length for start and end extents.
    writeLen -= pos if diskIdx == dStart
    writeLen -= (len - bytesWritten) if diskIdx == dEnd

    # Write.
    bytesWritten += @disks[diskIdx].d_write(pos + bytesWritten, writeLen, getDiskByteOffset(diskIdx))
  end
  bytesWritten
end

#getBaseObject



55
56
57
# File 'lib/disk/modules/RhevmDescriptor.rb', line 55

def getBase
  @parent || self
end

#getDiskByteOffset(target) ⇒ Object

Get beginning byte offset of target disk.



136
137
138
139
140
141
142
143
# File 'lib/disk/modules/RhevmDescriptor.rb', line 136

def getDiskByteOffset(target)
  total = 0
  0.upto(@defs.size - 1) do|idx|
    break if idx == target
    total += @defs[idx]['size'].to_i
  end
  total * @blockSize
end

#getTargetDiskIndex(sector) ⇒ Object

Get target disk index based on sector number.



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/disk/modules/RhevmDescriptor.rb', line 121

def getTargetDiskIndex(sector)
  dIdx = -1; total = 0
  0.upto(@defs.size - 1) do|idx|
    total += @defs[idx][:size].to_i
    if total >= sector
      dIdx = idx
      break
    end
  end
  raise "Sector is past end of disk: #{sector}" if dIdx == -1
  raise "Disk object is nil for #{sector}" if @disks[dIdx].nil?
  dIdx
end

#parseDescriptor(descriptor) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/disk/modules/RhevmDescriptor.rb', line 145

def parseDescriptor(descriptor)
  desc = {}
  descriptor.each_line do |line|
    line.strip!
    break if line == 'EOF'
    next unless line.include?('=')
    key, *value = line.split('=')
    desc[key.downcase.to_sym] = value = value.join('=')
  end
  desc[:offset] = 0
  desc[:filename] = File.basename(dInfo.fileName)
  return desc, [desc]
end