manageiq-smartstate 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +31 -0
  3. data/.rspec +0 -1
  4. data/.whitesource +3 -0
  5. data/Gemfile +1 -1
  6. data/README.md +1 -2
  7. data/lib/MiqVm/MiqRhevmVm.rb +1 -0
  8. data/lib/MiqVm/MiqVm.rb +0 -7
  9. data/lib/blackbox/VmBlackBox.rb +1 -0
  10. data/lib/db/MiqBdb/MiqBdb.rb +1 -0
  11. data/lib/db/MiqBdb/MiqBdbBtree.rb +1 -0
  12. data/lib/db/MiqBdb/MiqBdbHash.rb +1 -0
  13. data/lib/db/MiqBdb/MiqBdbPage.rb +1 -0
  14. data/lib/disk/DiskProbe.rb +2 -1
  15. data/lib/disk/modules/MiqLargeFile.rb +1 -0
  16. data/lib/fs/ntfs/attrib_file_name.rb +1 -0
  17. data/lib/fs/ntfs/attrib_standard_information.rb +1 -0
  18. data/lib/manageiq/smartstate/version.rb +1 -1
  19. data/lib/metadata/MIQExtract/MIQExtract.rb +1 -0
  20. data/lib/metadata/ScanProfile/ScanProfilesBase.rb +1 -0
  21. data/lib/metadata/VmConfig/GetNativeCfg.rb +1 -0
  22. data/lib/metadata/VmConfig/VmConfig.rb +1 -0
  23. data/lib/metadata/VmConfig/ovfConfig.rb +1 -0
  24. data/lib/metadata/VmConfig/vmcConfig.rb +1 -0
  25. data/lib/metadata/VmConfig/xmlConfig.rb +1 -6
  26. data/lib/metadata/linux/LinuxInitProcs.rb +1 -0
  27. data/lib/metadata/linux/LinuxOSInfo.rb +1 -0
  28. data/lib/metadata/linux/LinuxPackages.rb +1 -0
  29. data/lib/metadata/linux/LinuxSystemd.rb +1 -0
  30. data/lib/metadata/linux/LinuxUsers.rb +1 -0
  31. data/lib/metadata/linux/MiqConaryPackages.rb +1 -0
  32. data/lib/metadata/linux/MiqRpmPackages.rb +1 -0
  33. data/lib/metadata/util/md5deep.rb +1 -0
  34. data/lib/metadata/util/win32/Win32Accounts.rb +1 -0
  35. data/lib/metadata/util/win32/Win32EventLog.rb +1 -0
  36. data/lib/metadata/util/win32/Win32Services.rb +1 -0
  37. data/lib/metadata/util/win32/Win32Software.rb +1 -0
  38. data/lib/metadata/util/win32/Win32System.rb +1 -0
  39. data/lib/metadata/util/win32/fleece_hives.rb +1 -0
  40. data/lib/metadata/util/win32/ms-registry.rb +1 -0
  41. data/lib/metadata/util/win32/remote-registry.rb +1 -0
  42. data/manageiq-smartstate.gemspec +4 -5
  43. metadata +7 -32
  44. data/.travis.yml +0 -15
  45. data/lib/MiqVm/miq_scvmm_vm.rb +0 -39
  46. data/lib/Scvmm/miq_hyperv_disk.rb +0 -274
  47. data/lib/Scvmm/miq_scvmm_parse_powershell.rb +0 -75
  48. data/lib/Scvmm/miq_scvmm_vm_ssa_info.rb +0 -135
  49. data/lib/disk/modules/MSCommon.rb +0 -354
  50. data/lib/disk/modules/MSVSDiffDisk.rb +0 -85
  51. data/lib/disk/modules/MSVSDiskProbe.rb +0 -61
  52. data/lib/disk/modules/MSVSDynamicDisk.rb +0 -36
  53. data/lib/disk/modules/MSVSFixedDisk.rb +0 -39
  54. data/lib/disk/modules/VhdxDisk.rb +0 -629
  55. data/lib/disk/modules/VhdxDiskProbe.rb +0 -46
  56. data/lib/metadata/VmConfig/xmlMsHyperVConfig.rb +0 -41
@@ -1,354 +0,0 @@
1
- require 'disk/modules/MiqLargeFile'
2
- require 'miq_unicode'
3
- require 'binary_struct'
4
- require 'memory_buffer'
5
- require 'Scvmm/miq_hyperv_disk'
6
-
7
- module MSCommon
8
- using ManageIQ::UnicodeString
9
-
10
- # NOTE: All values are stored in network byte order.
11
-
12
- FOOTER = BinaryStruct.new([
13
- 'a8', 'cookie', # Always 'conectix'.
14
- 'N', 'features', # Should be 2 or 3 (bit 0 is temp disk).
15
- 'N', 'version', # Major/Minor file format version.
16
- 'N', 'data_offset_hi', # Offset from beginning of file to next data struct (dyn & diff only, 0xffffffff for fixed).
17
- 'N', 'data_offset_lo',
18
- 'N', 'time_stamp', # Create time (sec since Jan 1 2000 12:00 AM in GMT).
19
- 'a4', 'creator_app', # Virtual PC = 'vpc ', Virtual Server = 'vs '.
20
- 'N', 'creator_ver', # Major/Minor ver of creator app.
21
- 'N', 'creator_host', # Creator host: Windows = 0x5769326b ('Wi2k'); Macintosh = 0x4d616320 ('Mac ').
22
- 'N', 'original_size_hi', # Original size of disk.
23
- 'N', 'original_size_lo',
24
- 'N', 'current_size_hi', # Current size of the disk.
25
- 'N', 'current_size_lo',
26
- 'N', 'disk_geometry', # CHS (byte sizes 2, 1, 1) values for disk.
27
- 'N', 'disk_type', # Disk subtype (Fixed, Dynamic or Differencing).
28
- 'N', 'checksum', # One's compliment of sum of struct minus this field.
29
- 'a16', 'unique_id', # UUID.
30
- 'C', 'saved_state', # If 1, system is in 'saved state'.
31
- ])
32
-
33
- HEADER = BinaryStruct.new([
34
- 'a8', 'cookie', # Always 'cxsparse'.
35
- 'Q', 'data_offset', # Unused, should be 0xffffffff.
36
- 'N', 'table_offset_hi', # Byte offset to the Block Allocation Table.
37
- 'N', 'table_offset_lo',
38
- 'N', 'header_ver', # Major/Minor header version.
39
- 'N', 'max_tbl_ent', # Max entries in the BAT.
40
- 'N', 'block_size', # Size of data section of a block, default 2M (0x00200000).
41
- 'N', 'checksum', # One's compliment sum of all fields minus this one.
42
- 'a16', 'parent_uuid', # Parent disk UUID (for differencing disk only).
43
- 'N', 'parent_tstamp', # MTime of parent disk (sec since Jan 1 2000 12:00 AM in GMT).
44
- 'N', 'reserved1', # reserved, should be 0.
45
- 'a512', 'parent_uname', # Parent disk filename in UNICODE (UTF-16).
46
- 'a24', 'parent_loc1', # Parent locator entries.
47
- 'a24', 'parent_loc2',
48
- 'a24', 'parent_loc3',
49
- 'a24', 'parent_loc4',
50
- 'a24', 'parent_loc5',
51
- 'a24', 'parent_loc6',
52
- 'a24', 'parent_loc7',
53
- 'a24', 'parent_loc8',
54
- ])
55
-
56
- PARENT_LOCATOR = BinaryStruct.new([
57
- 'a4', 'platform_code', # Platform specific format used for locator.
58
- 'N', 'data_space', # Number of sectors used to store locator.
59
- 'N', 'data_length', # Byte length of locator.
60
- 'N', 'reserved1', # Must be zero.
61
- 'N', 'data_offset_hi', # Absolute byte offset of locator.
62
- 'N', 'data_offset_lo',
63
- ])
64
-
65
- BAE_SIZE = 4
66
- SECTOR_LENGTH = 512
67
- FOOTER_LENGTH = 512
68
- HEADER_LOCATION = 512
69
- BLOCK_NOT_ALLOCATED = 0xffffffff
70
- SUPPORTED_HEADER_VERSION = 0x00010000
71
-
72
- def self.connect_to_hyperv(ostruct)
73
- connection = ostruct.hyperv_connection
74
- @network = ostruct.driveType == "Network"
75
- hyperv_disk = MiqHyperVDisk.new(connection[:host],
76
- connection[:user],
77
- connection[:password],
78
- connection[:port],
79
- @network)
80
- hyperv_disk.open(ostruct.fileName)
81
- hyperv_disk
82
- end
83
-
84
- def self.d_init_common(dInfo, file)
85
- @dInfo = dInfo
86
- @blockSize = SECTOR_LENGTH
87
- @file = file
88
-
89
- # Get file, footer & header, do footer verification.
90
- @footer = getFooter(@file, true)
91
- @header = getHeader(@footer, true)
92
- verifyFooterCopy(@footer)
93
-
94
- # Verify footer copy.
95
-
96
- # Verify format version number (must be 0x00010000).
97
- raise "Incompatible header version: 0x#{'%04x' % @header['header_ver']}" if @header['header_ver'] != SUPPORTED_HEADER_VERSION
98
-
99
- # Calc sectors per block, bytes in block sector bitmap & BAT loc.
100
- @secPerBlock = @header['block_size'] / @blockSize
101
- @blockSectorBitmapByteCount = @secPerBlock / 8
102
- if (bd = @blockSectorBitmapByteCount % 512) != 0
103
- @blockSectorBitmapByteCount = @blockSectorBitmapByteCount + 512 - bd
104
- end
105
- @batBase = getHiLo(@header, "table_offset")
106
- process_bae
107
- end
108
-
109
- def self.d_read_common(pos, len, parent = nil)
110
- # Get starting & ending block, sector & byte offset of read.
111
- blockStart, sectorStart, byteOffsetStart = blockPos(pos)
112
- blockEnd, sectorEnd, byteOffsetEnd = blockPos(pos + len - 1)
113
-
114
- # Loop on blocks (2M entities of storage).
115
- buf = ""
116
- (blockStart..blockEnd).each do |blockNum|
117
- # Loop on sectors (512 byte entities of storage).
118
- secStart = (blockNum == blockStart) ? sectorStart : 0
119
- secEnd = (blockNum == blockEnd) ? sectorEnd : @secPerBlock - 1
120
- (secStart..secEnd).each do |secNum|
121
- # If STARTING, need to skip to where data is
122
- if (blockStart == blockEnd) && (sectorStart == sectorEnd)
123
- byteOffset = byteOffsetStart
124
- thisLen = len
125
- elsif (blockNum == blockStart) && (secNum == sectorStart)
126
- byteOffset = byteOffsetStart
127
- thisLen = @blockSize - byteOffset
128
- # If ENDING, need to account for short read
129
- elsif (blockNum == blockEnd) && (secNum == sectorEnd)
130
- byteOffset = 0
131
- thisLen = len - buf.length
132
- raise "Internal Error: Calculated read more than sector: #{thisLen}" if thisLen > @blockSize
133
- # Read ENTIRE Sector in all other cases
134
- else
135
- byteOffset = 0
136
- thisLen = @blockSize
137
- end
138
-
139
- # If the allocation status of this sector is 0 return zeros.
140
- allocStat = getAllocStatus(blockNum, secNum)
141
- if allocStat == false
142
- if parent.nil?
143
- buf << MemoryBuffer.create(thisLen)
144
- else
145
- buf << parent.d_read(pos + buf.length, thisLen)
146
- end
147
- else
148
- @file.seek(getAbsSectorLoc(blockNum, secNum) + byteOffset, IO::SEEK_SET)
149
- buf << @file.read(thisLen)
150
- end
151
- end
152
- end
153
- buf
154
- end
155
-
156
- def self.d_write_common(pos, buf, len, parent = nil)
157
- # Get starting & ending block, sector & byte offset of read.
158
- blockStart, sectorStart, byteOffsetStart = blockPos(pos)
159
- blockEnd, sectorEnd, byteOffsetEnd = blockPos(pos + len - 1)
160
-
161
- # Loop on blocks (2M entities of storage).
162
- bytesWritten = 0
163
- (blockStart..blockEnd).each do |blockNum|
164
- # Loop on sectors (512 byte entities of storage).
165
- secStart = (blockNum == blockStart) ? sectorStart : 0
166
- secEnd = (blockNum == blockEnd) ? sectorEnd : @secPerBlock - 1
167
- (secStart..secEnd).each do |secNum|
168
- # If STARTING, need to skip to where data is
169
- if (blockStart == blockEnd) && (sectorStart == sectorEnd)
170
- byteOffset = byteOffsetStart
171
- thisLen = len
172
- elsif (blockNum == blockStart) && (secNum == sectorStart)
173
- byteOffset = byteOffsetStart
174
- thisLen = @blockSize - byteOffset
175
- # If ENDING, need to account for short read
176
- elsif (blockNum == blockEnd) && (secNum == sectorEnd)
177
- byteOffset = 0
178
- thisLen = len - bytesWritten
179
- raise "Internal Error: Calculated read more than sector: #{thisLen}" if thisLen > @blockSize
180
- # Read ENTIRE Sector in all other cases
181
- else
182
- byteOffset = 0
183
- thisLen = @blockSize
184
- end
185
-
186
- # If the allocation status of this sector is 0 then allocate it.
187
- allocStat = getAllocStatus(blockNum, secNum)
188
- allocSector(blockNum, secNum, pos + bytesWritten, parent) if allocStat == false
189
- @file.seek(getAbsSectorLoc(blockNum, secNum) + byteOffset, IO::SEEK_SET)
190
- bytesWritten += @file.write(buf[bytesWritten, thisLen], thisLen)
191
- end
192
- end
193
- bytesWritten
194
- end
195
-
196
- # Disk size in sectors.
197
- def self.d_size_common
198
- getHiLo(@footer, "current_size") / @blockSize
199
- end
200
-
201
- def self.getHiLo(hash, member)
202
- (hash["#{member}_hi"] << 32) + hash["#{member}_lo"]
203
- end
204
-
205
- # Needed by diff disk.
206
- def self.header
207
- @header
208
- end
209
-
210
- def self.getFooter(file, skip_check = false)
211
- # NOTE: Spec says that if checksum fails use the copy in the header.
212
- # If that fails then the disk is corrupt.
213
- file.seek(file.size - FOOTER_LENGTH, IO::SEEK_SET)
214
- @footerBuf = file.read(FOOTER_LENGTH)
215
- footer = FOOTER.decode(@footerBuf)
216
- # TODO: Find out why this checksum test is failing. For now don't call getFooter without skip_check set to "true"
217
- unless skip_check
218
- footerCsum = checksum(@footerBuf, 64)
219
- raise "Footer checksum doesn't match: got 0x#{'%04x' % footerCsum}, s/b 0x#{'%04x' % @footer['checksum']}" if footerCsum != footer['checksum']
220
- end
221
- footer
222
- end
223
-
224
- private
225
-
226
- def self.getHeader(footer, skip_check = false)
227
- hdrLoc = getHiLo(footer, "data_offset")
228
- hdrSiz = HEADER.size
229
- puts "VHD Header is mislocated: 0x#{'%04x' % hdrLoc} (s/b 0x0200)" if hdrLoc != HEADER_LOCATION && !skip_check
230
- @file.seek(hdrLoc, IO::SEEK_SET)
231
- buf = @file.read(hdrSiz)
232
- header = HEADER.decode(buf)
233
- # TODO: Find out why this checksum test is failing. For now don't call getHeader without skip_check set to "true"
234
- unless skip_check
235
- headerCsum = checksum(buf, 36)
236
- raise "Header checksum doesn't match: got 0x#{'%04x' % headerCsum}, s/b 0x#{'%04x' % @header['checksum']}" if headerCsum != header['checksum']
237
- end
238
- header
239
- end
240
-
241
- def self.verifyFooterCopy(footer)
242
- hdrLoc = getHiLo(footer, "data_offset")
243
- @file.seek(hdrLoc - FOOTER_LENGTH, IO::SEEK_SET)
244
- footer_copy = FOOTER.decode(@file.read(FOOTER_LENGTH))
245
- puts "Footer copy does not match header." if footer_copy != @footer
246
- end
247
-
248
- def self.blockPos(pos)
249
- rawSectorNumber, byteOffset = pos.divmod(@blockSize)
250
- blockNumber, secInBlock = rawSectorNumber.divmod(@secPerBlock)
251
- return blockNumber, secInBlock, byteOffset
252
- end
253
-
254
- def self.process_bae
255
- @file.seek(@batBase, IO::SEEK_SET)
256
- @bae = []
257
- 1.step(@header['max_tbl_ent'], 1) do |block_num|
258
- @bae << @file.read(BAE_SIZE).unpack('N')[0]
259
- end
260
- end
261
-
262
- def self.getBAE(blockNumber)
263
- @bae[blockNumber]
264
- end
265
-
266
- def self.putBAE(blockNum, bae)
267
- seekBAE(blockNum)
268
- @file.write([bae].pack('N'), BAE_SIZE)
269
- end
270
-
271
- def self.seekBAE(blockNum)
272
- batOffset = blockNum * BAE_SIZE + @batBase
273
- @file.seek(batOffset, IO::SEEK_SET)
274
- end
275
-
276
- def self.getAllocStatus(blockNum, sectorNum)
277
- sectorMask = seekAllocStatus(blockNum, sectorNum)
278
- return false if sectorMask == BLOCK_NOT_ALLOCATED
279
- sectorBitmap = @file.read(1).unpack('C')[0]
280
- sectorBitmap & sectorMask == sectorMask
281
- end
282
-
283
- def self.setAllocStatus(blockNum, sectorNum)
284
- sectorMask = seekAllocStatus(blockNum, sectorNum)
285
- sectorBitmap = @file.read(1).unpack('C')[0]
286
- sectorBitmap |= sectorMask
287
- @file.seek(-1, IO::SEEK_CUR)
288
- @file.write([sectorBitmap].pack('C'), 1)
289
- end
290
-
291
- def self.seekAllocStatus(blockNum, sectorNum)
292
- sectorByte, bitOffset = sectorNum.divmod(8)
293
- bae = getBAE(blockNum)
294
- return bae if bae == BLOCK_NOT_ALLOCATED
295
- @file.seek(bae * @blockSize + sectorByte, IO::SEEK_SET)
296
- 0x80 >> bitOffset
297
- end
298
-
299
- def self.getAbsSectorLoc(blockNum, sectorNum)
300
- getBAE(blockNum) * @blockSize + sectorNum * @blockSize + @blockSectorBitmapByteCount
301
- end
302
-
303
- def self.allocSector(blockNum, sectorNum, pos, parent)
304
- allocBlock(blockNum) if getBAE(blockNum) == BLOCK_NOT_ALLOCATED
305
- if parent.nil?
306
- buf = MemoryBuffer.create(@blockSize)
307
- else
308
- sector = pos.divmod(@blockSize)[0]
309
- buf = parent.d_read(sector, @blockSize)
310
- end
311
- setAllocStatus(blockNum, sectorNum)
312
- @file.seek(getAbsSectorLoc(blockNum, sectorNum), IO::SEEK_SET)
313
- @file.write(buf, buf.size)
314
- end
315
-
316
- def self.allocBlock(blockNum)
317
- # Alloc block.
318
- pos = @file.size - FOOTER_LENGTH
319
- sector = findFreeSector
320
- putBAE(blockNum, sector)
321
- # Write sector alloc bitmap.
322
- bmp = MemoryBuffer.create(@blockSectorBitmapByteCount)
323
- @file.seek(sector * @blockSize, IO::SEEK_SET)
324
- @file.write(bmp, bmp.size)
325
- # Footer has to move. Total size is 2048 + size of data blocks.
326
- pos += @secPerBlock * @blockSize
327
- @file.seek(pos, IO::SEEK_SET)
328
- @file.write(@footerBuf, @footerBuf.size)
329
- end
330
-
331
- def self.findFreeSector
332
- # Find a free disk sector with which to start a new block.
333
- if @freeSector.nil?
334
- seekBAE(0); ents = @header['max_tbl_ent']
335
- baes = @file.read(ents * BAE_SIZE).unpack("N#{ents}")
336
- baes.delete(BLOCK_NOT_ALLOCATED)
337
- raise "Disk full." if baes.size == @header['max_tbl_ent']
338
- @freeSector = baes.max
339
- end
340
- @freeSector += @secPerBlock
341
- raise "Disk full." if @freeSector > d_size_common / @blockSize
342
- @freeSector
343
- end
344
-
345
- def self.checksum(buf, skip_offset)
346
- csum = 0
347
- 0.upto(buf.size - 1) do|i|
348
- next if i >= skip_offset && i < skip_offset + 4
349
- csum += buf[i].to_i
350
- end
351
- # GRRRRR - convert to actual 32-bits.
352
- [~csum].pack('L').unpack('L')[0]
353
- end
354
- end # module
@@ -1,85 +0,0 @@
1
- # encoding: US-ASCII
2
-
3
- require 'disk/modules/MSCommon'
4
- require 'disk/modules/miq_disk_common'
5
-
6
- module MSVSDiffDisk
7
- def d_init
8
- self.diskType = "MSVS Differencing"
9
- self.blockSize = MSCommon::SECTOR_LENGTH
10
- fileMode = MiqDiskCommon.file_mode(dInfo)
11
- if dInfo.hyperv_connection
12
- @hyperv_connection = dInfo.hyperv_connection
13
- @ms_disk_file = MSCommon.connect_to_hyperv(dInfo)
14
- else
15
- @hyperv_connection = nil
16
- @ms_disk_file = MiqLargeFile.open(dInfo.fileName, fileMode) unless dInfo.baseOnly
17
- end
18
- MSCommon.d_init_common(dInfo, @ms_disk_file) unless dInfo.baseOnly
19
-
20
- # Get parent locators.
21
- @locators = []
22
- 1.upto(8) do|idx|
23
- @locators << MSCommon::PARENT_LOCATOR.decode(MSCommon.header["parent_loc#{idx}"])
24
- next if @locators[idx - 1]['platform_code'] == "\000\000\000\000"
25
- locator = @locators[idx - 1]
26
- if locator['platform_code'] == "W2ku"
27
- getParentPathWin(locator)
28
- getParent(locator)
29
- end
30
- end
31
- raise "No compatible parent locator found" if @parent == nil
32
- end
33
-
34
- def getBase
35
- @parent || self
36
- end
37
-
38
- # /////////////////////////////////////////////////////////////////////////
39
- # Implementation.
40
-
41
- def d_read(pos, len)
42
- MSCommon.d_read_common(pos, len, @parent)
43
- end
44
-
45
- def d_write(pos, buf, len)
46
- MSCommon.d_write_common(pos, buf, len, @parent)
47
- end
48
-
49
- def d_close
50
- @parent.close if @parent
51
- @ms_disk_file.close
52
- end
53
-
54
- def d_size
55
- total = 0
56
- total = @parent.d_size if @parent
57
- total += @ms_disk_file.size
58
- total
59
- end
60
-
61
- # /////////////////////////////////////////////////////////////////////////
62
- # // Helpers.
63
-
64
- private
65
-
66
- def getParent(locator)
67
- if locator.key?('fileName')
68
- @parent_ostruct = OpenStruct.new
69
- @parent_ostruct.fileName = locator['fileName']
70
- @parent_ostruct.driveType = dInfo.driveType
71
- @parent_ostruct.hyperv_connection = @hyperv_connection unless @hyperv_connection.nil?
72
- @parent = MiqDisk.getDisk(@parent_ostruct)
73
- end
74
- end
75
-
76
- def getParentPathWin(locator)
77
- buf = getPathData(locator)
78
- locator['fileName'] = buf.UnicodeToUtf8!
79
- end
80
-
81
- def getPathData(locator)
82
- @ms_disk_file.seek(MSCommon.getHiLo(locator, "data_offset"), IO::SEEK_SET)
83
- @ms_disk_file.read(locator['data_length'])
84
- end
85
- end
@@ -1,61 +0,0 @@
1
- # encoding: US-ASCII
2
-
3
- require 'Scvmm/miq_hyperv_disk'
4
- require 'disk/modules/MiqLargeFile'
5
- require 'disk/modules/MSCommon'
6
-
7
- module MSVSDiskProbe
8
- MS_MAGIC = "conectix"
9
-
10
- TYPE_FIXED = 2
11
- TYPE_DYNAMIC = 3
12
- TYPE_DIFF = 4
13
-
14
- MOD_FIXED = "MSVSFixedDisk"
15
- MOD_DYNAMIC = "MSVSDynamicDisk"
16
- MOD_DIFF = "MSVSDiffDisk"
17
-
18
- def self.probe(ostruct)
19
- return nil unless ostruct.fileName
20
- # If file not VHD then not Microsoft.
21
- # Allow ".miq" also.
22
- ext = File.extname(ostruct.fileName).downcase
23
- return nil if ext != ".vhd" && ext != ".avhd" && ext != ".miq"
24
-
25
- if ostruct.hyperv_connection
26
- ms_disk_file = connect_to_hyperv(ostruct)
27
- else
28
- # Get (assumed) footer.
29
- ms_disk_file = MiqLargeFile.open(ostruct.fileName, "rb")
30
- end
31
- footer = MSCommon.getFooter(ms_disk_file, true)
32
- ms_disk_file.close
33
-
34
- # Check for MS disk.
35
- return nil if footer['cookie'] != MS_MAGIC
36
-
37
- # Return module name to handle type.
38
- case footer['disk_type']
39
- when TYPE_FIXED
40
- return MOD_FIXED
41
- when TYPE_DYNAMIC
42
- return MOD_DYNAMIC
43
- when TYPE_DIFF
44
- return MOD_DIFF
45
- else
46
- raise "Unsupported MS disk: #{footer['disk_type']}"
47
- end
48
- end
49
-
50
- def self.connect_to_hyperv(ostruct)
51
- connection = ostruct.hyperv_connection
52
- network = ostruct.driveType == "Network"
53
- hyperv_disk = MiqHyperVDisk.new(connection[:host],
54
- connection[:user],
55
- connection[:password],
56
- connection[:port],
57
- network)
58
- hyperv_disk.open(ostruct.fileName)
59
- hyperv_disk
60
- end
61
- end
@@ -1,36 +0,0 @@
1
- require 'disk/modules/MSCommon'
2
- require 'disk/modules/miq_disk_common'
3
-
4
- module MSVSDynamicDisk
5
- def d_init
6
- self.diskType = "MSVS Dynamic"
7
- self.blockSize = MSCommon::SECTOR_LENGTH
8
- fileMode = MiqDiskCommon.file_mode(dInfo)
9
- @ms_disk_file = if dInfo.hyperv_connection
10
- MSCommon.connect_to_hyperv(dInfo)
11
- else
12
- MiqLargeFile.open(dInfo.fileName, fileMode)
13
- end
14
- MSCommon.d_init_common(dInfo, @ms_disk_file)
15
- end
16
-
17
- def getBase
18
- self
19
- end
20
-
21
- def d_read(pos, len)
22
- MSCommon.d_read_common(pos, len)
23
- end
24
-
25
- def d_write(pos, buf, len)
26
- MSCommon.d_write_common(pos, buf, len)
27
- end
28
-
29
- def d_close
30
- @ms_disk_file.close
31
- end
32
-
33
- def d_size
34
- MSCommon.d_size_common
35
- end
36
- end # module
@@ -1,39 +0,0 @@
1
- require 'disk/modules/MiqLargeFile'
2
- require 'disk/modules/miq_disk_common'
3
-
4
- module MSVSFixedDisk
5
- def d_init
6
- @diskType = "MSVSFixed"
7
- @blockSize = 512
8
-
9
- fileMode = MiqDiskCommon.file_mode
10
-
11
- if dInfo.hyperv_connection
12
- @ms_flat_disk_file = MSCommon.connect_to_hyperv(dInfo)
13
- else
14
- @ms_flat_disk_file = MiqLargeFile.open(dInfo.fileName, fileMode)
15
- end
16
- end
17
-
18
- def d_read(pos, len)
19
- @ms_flat_disk_file.seek(pos, IO::SEEK_SET)
20
- @ms_flat_disk_file.read(len)
21
- end
22
-
23
- def getBase
24
- self
25
- end
26
-
27
- def d_write(pos, buf, len)
28
- @ms_flat_disk_file.seek(pos, IO::SEEK_SET)
29
- @ms_flat_disk_file.write(buf, len)
30
- end
31
-
32
- def d_close
33
- @ms_flat_disk_file.close
34
- end
35
-
36
- def d_size
37
- File.size(dInfo.fileName)
38
- end
39
- end