Module: QcowDisk
- Defined in:
- lib/disk/modules/QcowDisk.rb
Constant Summary collapse
- QCOW_HEADER_PARTIAL =
BinaryStruct.new([ 'A4', 'magicNumber', 'N', 'version', ])
- SIZEOF_QCOW_HEADER_PARTIAL =
QCOW_HEADER_PARTIAL.size
- QCOW_HEADER_V1 =
BinaryStruct.new([ 'A4', 'magicNumber', 'N', 'version', 'N', 'backing_filename_offset_hi', 'N', 'backing_filename_offset_lo', 'N', 'backing_filename_size', 'N', 'mtime', 'N', 'size_hi', 'N', 'size_lo', 'C', 'cluster_bits', 'C', 'l2_bits', 'N', 'crypt_method', 'N', 'l1_table_offset_hi', 'N', 'l1_table_offset_lo', ])
- SIZEOF_QCOW_HEADER_V1 =
QCOW_HEADER_V1.size
- QCOW_HEADER_V2 =
BinaryStruct.new([ 'A4', 'magicNumber', 'N', 'version', 'N', 'backing_filename_offset_hi', 'N', 'backing_filename_offset_lo', 'N', 'backing_filename_size', 'N', 'cluster_bits', 'N', 'size_hi', 'N', 'size_lo', 'N', 'crypt_method', 'N', 'l1_size', 'N', 'l1_table_offset_hi', 'N', 'l1_table_offset_lo', 'N', 'refcount_table_offset_hi', 'N', 'refcount_table_offset_lo', 'N', 'refcount_table_clusters', 'N', 'number_of_snapshots', 'N', 'snapshots_offset_hi', 'N', 'snapshots_offset_lo', ])
- SIZEOF_QCOW_HEADER_V2 =
QCOW_HEADER_V2.size
- QCOW_HEADER_V3 =
BinaryStruct.new(QCOW_HEADER_V2.definition + [ 'Q', 'incompatible_features', 'Q', 'compatible_features', 'Q', 'autoclear_features', 'N', 'refcount_order', 'N', 'header_length' ])
- SIZEOF_QCOW_HEADER_V3 =
QCOW_HEADER_V3.size
- QCOW_OFLAG_COPIED =
indicate that the refcount of the referenced cluster is exactly one.
(1 << 63)
- QCOW_OFLAG_COMPRESSED =
indicate that the cluster is compressed (they never have the copied flag)
(1 << 62)
- LO63_MASK =
~QCOW_OFLAG_COPIED
- LO62_MASK =
~(QCOW_OFLAG_COPIED | QCOW_OFLAG_COMPRESSED)
- L1E_OFFSET_MASK =
0x00fffffffffffe00
- L2E_OFFSET_MASK =
0x00fffffffffffe00
- L2E_COMPRESSED_OFFSET_SIZE_MASK =
0x3fffffffffffffff
- L2E_PREALLOCATED_MASK =
0x1
- SECTOR_SIZE =
512
- ZLIB_WINDOW_BITS =
-12
- INCOMPATIBLE_FEATURES_MASK =
{ :dirty => 0x1, :corrupt => 0x2 }
- KNOWN_INCOMPATIBLE_FEATURES_MASK =
0x3
- COMPATIBLE_FEATURES_MASK =
{ :lazy_refcounts => 0x1 }
- AUTOCLEAR_FEATURES_MASK =
{ }
- HEADER_EXTENSION_TYPE_SIZE =
4
- HEADER_EXTENSION_LENGTH_SIZE =
4
- HEADER_EXTENSION_TYPES =
{ :end_of_header_extension_area => 0x00000000, :backing_file_format_name => 0xE2792ACA, :feature_table_name => 0x6803f857 }
Instance Method Summary collapse
- #backing_file_name ⇒ Object
- #cluster_sectors ⇒ Object
- #d_close ⇒ Object
- #d_init ⇒ Object
- #d_read(pos, len, _offset = 0) ⇒ Object
-
#d_size ⇒ Object
Disk size in sectors.
- #d_write(_pos, _buf, _len, _offset = 0) ⇒ Object
- #getBase ⇒ Object
- #total_sectors ⇒ Object
- #version ⇒ Object
Instance Method Details
#backing_file_name ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/disk/modules/QcowDisk.rb', line 162 def backing_file_name @backing_file_name ||= begin if backing_filename_offset > 0 file_handle.seek(backing_filename_offset, IO::SEEK_SET) backing_fname = file_handle.read(backing_filename_size) bfn = File. File.join(File.dirname(@filename), backing_fname) # # Check if the backing file is a logical volume from a direct lun volume group. # bfn_test = File. File.join(File.dirname(@filename), File.basename(bfn)) use_lv = false if (avm = @dInfo.applianceVolumeManager) use_lv = avm.lvHash.key?(bfn_test) end if (!File.symlink?(bfn) && !File.file?(bfn)) && use_lv bfn_test else bfn end else "" end end end |
#cluster_sectors ⇒ Object
188 189 190 |
# File 'lib/disk/modules/QcowDisk.rb', line 188 def cluster_sectors @cluster_sectors ||= 1 << (cluster_bits - 9) end |
#d_close ⇒ Object
145 146 147 148 149 150 151 |
# File 'lib/disk/modules/QcowDisk.rb', line 145 def d_close [@backing_file_handle, @file_handle].each do |h| next if h.nil? h.close h = nil end end |
#d_init ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/disk/modules/QcowDisk.rb', line 101 def d_init self.diskType = "QCOW" self.blockSize = SECTOR_SIZE if dInfo.mountMode.nil? || dInfo.mountMode == "r" dInfo.mountMode = "r" @fileMode = "r" elsif dInfo.mountMode == "rw" @fileMode = "r+" else raise "Unrecognized mountMode: #{dInfo.mountMode}" end @filename = dInfo.fileName @dOffset = dInfo.offset @downstreamDisk = dInfo.downstreamDisk self.diskType = "#{diskType}-#{@downstreamDisk.diskType}" if @downstreamDisk # Ensure all the disks in the chain are opened before we return (required to address RHEV SSA UID issues). backing_file_handle end |
#d_read(pos, len, _offset = 0) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/disk/modules/QcowDisk.rb', line 127 def d_read(pos, len, _offset = 0) pos += @dOffset if @dOffset return nil if pos >= @endByteAddr len = @endByteAddr - pos if (pos + len) > @endByteAddr sector_num, sector_offset = pos.divmod(SECTOR_SIZE) sector_count = ((pos + len - 1) / SECTOR_SIZE) - sector_num + 1 read_buf = read_sectors(sector_num, sector_count) buf = read_buf[sector_offset, len] buf end |
#d_size ⇒ Object
Disk size in sectors.
154 155 156 |
# File 'lib/disk/modules/QcowDisk.rb', line 154 def d_size uint64(header, 'size') / @blockSize end |
#d_write(_pos, _buf, _len, _offset = 0) ⇒ Object
141 142 143 |
# File 'lib/disk/modules/QcowDisk.rb', line 141 def d_write(_pos, _buf, _len, _offset = 0) raise "QcowDisk#d_write not implemented" end |
#getBase ⇒ Object
123 124 125 |
# File 'lib/disk/modules/QcowDisk.rb', line 123 def getBase self end |
#total_sectors ⇒ Object
192 193 194 |
# File 'lib/disk/modules/QcowDisk.rb', line 192 def total_sectors @total_sectors ||= size / SECTOR_SIZE end |
#version ⇒ Object
158 159 160 |
# File 'lib/disk/modules/QcowDisk.rb', line 158 def version @version ||= header['version'] end |