def get_vhd_format(self, vhd_path): vhd_format = os.path.splitext(vhd_path)[1][1:].upper() device_id = vdisk_const.DEVICE_ID_MAP.get(vhd_format) # If the disk format is not recognised by extension, # we attempt to retrieve it by seeking the signature. if not device_id and os.path.exists(vhd_path): vhd_format = self._get_vhd_format_by_signature(vhd_path) if not vhd_format: raise exceptions.VHDException( _("Could not retrieve VHD format: %s") % vhd_path) return vhd_format
def _check_resize_needed(self, vhd_path, new_size): curr_size = self.get_vhd_size(vhd_path)['VirtualSize'] if curr_size > new_size: err_msg = _("Cannot resize image %(vhd_path)s " "to a smaller size. " "Image virtual size: %(curr_size)s, " "Requested virtual size: %(new_size)s") raise exceptions.VHDException(err_msg % dict( vhd_path=vhd_path, curr_size=curr_size, new_size=new_size)) elif curr_size == new_size: LOG.debug( "Skipping resizing %(vhd_path)s to %(new_size)s" "as it already has the requested size.", dict(vhd_path=vhd_path, new_size=new_size)) return False return True
def _get_internal_vhdx_size_by_file_size(self, vhd_path, new_vhd_file_size, vhd_info): """VHDX Size: Header (1MB) + Log + Metadata Region + BAT + Payload Blocks The chunk size is the maximum number of bytes described by a SB block. Chunk size = 2^{23} * SectorSize :param str vhd_path: VHD file path :param new_vhd_file_size: Size of the new VHD file. :return: Internal VHD size according to new VHD file size. """ try: with open(vhd_path, 'rb') as f: hs = vdisk_const.VHDX_HEADER_SECTION_SIZE bes = vdisk_const.VHDX_BAT_ENTRY_SIZE lss = vhd_info['SectorSize'] bs = self._get_vhdx_block_size(f) ls = self._get_vhdx_log_size(f) ms = self._get_vhdx_metadata_size_and_offset(f)[0] chunk_ratio = (1 << 23) * lss // bs size = new_vhd_file_size max_internal_size = ( bs * chunk_ratio * (size - hs - ls - ms - bes - bes // chunk_ratio) // (bs * chunk_ratio + bes * chunk_ratio + bes)) return max_internal_size - (max_internal_size % bs) except IOError as ex: raise exceptions.VHDException( _("Unable to obtain internal size from VHDX: " "%(vhd_path)s. Exception: %(ex)s") % { "vhd_path": vhd_path, "ex": ex })