Module: VMWareDescriptor

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

Instance Method Summary collapse

Instance Method Details

#d_closeObject

Close all disks.



122
123
124
125
# File 'lib/disk/modules/VMWareDescriptor.rb', line 122

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
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/disk/modules/VMWareDescriptor.rb', line 4

def d_init
  # Check to see if a descriptor was not embedded.
  descriptor = dInfo.Descriptor
  if descriptor.nil?
    f = File.open(dInfo.fileName, "rb")
    descriptor = f.read; f.close
  end

  # Make sure this is a descriptor.
  desc, defs = parseDescriptor(descriptor, dInfo.fileName)
  raise "No disk definitions" if defs.size == 0
  # Make sure each disk is there.
  defs.each do|diskDef|
    raise "No disk file: #{diskDef['filename']}" unless File.exist?(diskDef['filename'])
  end

  # Init needed stff.
  self.diskType = "VMWare 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?('parentFileNameHint')
    @parentOstruct = OpenStruct.new

    # Get the parentFileNameHint and be sure it is relative to the descriptor file's directory
    parentFileName = Pathname.new(desc['parentFileNameHint'])
    if parentFileName.absolute?
      parentFileName = parentFileName.relative_path_from(Pathname.new(dInfo.fileName).dirname)
      $log.debug "VMWareDescriptor: Parent disk file is absolute. Using relative path [#{parentFileName}]" if $log
    end
    parentFileName = File.dirname(dInfo.fileName) + "/" + parentFileName.to_s.tr("\\", "/")
    $log.debug "VMWareDescriptor: Getting parent disk file [#{parentFileName}]" if $log

    @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 = diskDef['filename']
    thisO.offset = diskDef['offset']
    thisO.rawDisk = true if diskDef['type'].strip == 'FLAT'
    thisO.rawDisk = true if diskDef['type'].strip == 'VMFS'
    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



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/disk/modules/VMWareDescriptor.rb', line 71

def d_read(pos, len)
  # $log.debug "VMWareDescriptor.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 "VMWareDescriptor.d_read >> retBytes.length #{retBytes.length}" if $log && $log.debug?
  retBytes
end

#d_sizeObject

Return size in sectors.



128
129
130
131
132
# File 'lib/disk/modules/VMWareDescriptor.rb', line 128

def d_size
  total = 0
  @defs.each { |diskDef| total += diskDef['size'].to_i }
  total
end

#d_write(pos, buf, len) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/disk/modules/VMWareDescriptor.rb', line 99

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



67
68
69
# File 'lib/disk/modules/VMWareDescriptor.rb', line 67

def getBase
  @parent || self
end

#getDiskByteOffset(target) ⇒ Object

Get beginning byte offset of target disk.



150
151
152
153
154
155
156
157
# File 'lib/disk/modules/VMWareDescriptor.rb', line 150

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.



135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/disk/modules/VMWareDescriptor.rb', line 135

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