manageiq-smartstate 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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