def close(self): """Close a VHD.""" if self._closed: return _call('vhd_close', ctypes.pointer(self.vhd_context)) self._closed = True self.vhd_context = None
def get_header(self): """Get the VHD header data.""" hdr = {} header = self.vhd_context.header for field, _ in header._fields_: val = getattr(header, field) if field == 'prt_name': buf_type = ctypes.c_char * 512 buf_p = ctypes.POINTER(buf_type)() ret = _call('vhd_header_decode_parent', ctypes.pointer(self.vhd_context), ctypes.pointer(header), ctypes.pointer(buf_p)) if ret: val = 'Cannot read parent name' else: val = buf_p.contents.value elif field == 'prt_uuid': val = utils.uuid_unparse(val) elif field == 'hdr_ver': val = VHDVersion(version=val) elif field == 'loc': val = self._get_locators(val) hdr[field] = val return hdr
def get_chain_depth(self): chain_len = ctypes.c_int() ret = _call("vhd_chain_depth", ctypes.pointer(self.vhd_context), ctypes.byref(chain_len)) if ret: raise exceptions.VHDException("Cannot compute chain depth. Err %d" % ret) return chain_len.value
def check(name, ignore_missing_primary_footers=False, ignore_parent_uuids=False, ignore_timestamps=False, skip_bat_overlap_check=False, check_parents=False, check_bitmaps=False): if name is None: raise exceptions.VHDUtilMissingArgument("'name' must be specified") if skip_bat_overlap_check and check_bitmaps: raise exceptions.VHDUtilMutuallyExclusiveArguments( "Cannot specify 'check_bitmaps' as True when " "'no_bat_overlap_check' is also True") o = VHDUtilCheckOptions() _set_bool_opt(o, 'ignore_footer', ignore_missing_primary_footers) _set_bool_opt(o, 'ignore_parent_uuid', ignore_parent_uuids) _set_bool_opt(o, 'ignore_timestamps', ignore_timestamps) _set_bool_opt(o, 'check_data', check_bitmaps) _set_bool_opt(o, 'no_check_bat', skip_bat_overlap_check) _set_bool_opt(o, 'collect_stats', False) list_head = ListHead() setattr(list_head, 'next', ctypes.pointer(list_head)) setattr(list_head, 'prev', ctypes.pointer(list_head)) vhd_check_ctx = VHDUtilCheckCtx() setattr(vhd_check_ctx, 'opts', o) setattr(vhd_check_ctx, 'stats', list_head) ret = _call('vhd_util_check_vhd', ctypes.pointer(vhd_check_ctx), ctypes.c_char_p(name)) if ret == 0: if check_parents: ret = _call('vhd_util_check_parents', ctypes.pointer(vhd_check_ctx), ctypes.c_char_p(name)) if ret != 0: raise exceptions.VHDUtilCheckError(errcode=ret.value)
def coalesce(name, output=None, ancestor=None, step_parent=None, sparse=False): """Coalesce the VHD given by 'name'. Exactly one of 'output', 'ancestor', or 'step_parent' is required. """ if name is None: raise exceptions.VHDUtilMissingArgument("'name' must be specified") def _f(x, y): if y: return x + 1 else: return x c = reduce(_f, [output, ancestor, step_parent], 0) if c != 1: raise exceptions.VHDUtilMutuallyExclusiveArguments( "Exactly one of 'output', 'ancestor', or 'step_parent' is required.") sparse_i = 0 if sparse: sparse_i = 1 ret = None if output: ret = _call('vhd_util_coalesce_out', ctypes.c_char_p(name), ctypes.c_char_p(output), ctypes.c_int(sparse_i), ctypes.c_int(0)) elif ancestor: ret = _call('vhd_util_coalesce_ancestor', ctypes.c_char_p(name), ctypes.c_char_p(ancestor), ctypes.c_int(sparse_i), ctypes.c_int(0)) elif step_parent: ret = _call('vhd_util_coalesce_parent', ctypes.c_char_p(name), ctypes.c_int(sparse_i), ctypes.c_int(0), ctypes.c_char_p(step_parent)) if ret != 0: raise exceptions.VHDUtilCoalesceError(errcode=ret.value)
def io_read(self, buf, cur_sec, num_secs): """Read sectors from a VHD into an aligned buffer.""" if not isinstance(buf, utils.AlignedBuffer): raise exceptions.VHDInvalidBuffer("buf argument should be a AlignedBuffer" " instance") ret = _call('vhd_io_read', ctypes.pointer(self.vhd_context), buf.get_pointer(), ctypes.c_ulonglong(cur_sec), ctypes.c_uint(num_secs)) if not ret: return errno = ctypes.get_errno() raise exceptions.VHDReadError("Error reading: %s" % errno)
def __init__(self, filename, flags=None): """Open a VHD.""" if flags is None: flags = 'rdonly' open_flags = 0 try: for flag in flags.split(','): open_flags |= VHD_OPEN_FLAGS[flag] except KeyError: valid_flags = ','.join(VHD_OPEN_FLAGS.iterkeys()) raise exceptions.VHDInvalidOpenFlag("Valid open flags are: %s" % valid_flags) self.filename = filename self.open_flags = flags self.vhd_context = VHDContext() ret = _call('vhd_open', ctypes.pointer(self.vhd_context), ctypes.c_char_p(filename), ctypes.c_int(open_flags)) if ret: raise exceptions.VHDOpenFailure("Error opening: %s" % ctypes.get_errno()) self._closed = False
def vhd_create(filename, size, disk_type=None, create_flags=None): """Create a new empty VHD file.""" if disk_type is None: disk_type = 'dynamic' if create_flags is None: create_flags = 0 try: disk_type = VHD_DISK_TYPES[disk_type] except KeyError: valid_disk_types = ','.join(VHD_DISK_TYPES.iterkeys()) raise exceptions.VHDInvalidDiskType("Valid disk types are: %s" % valid_disk_types) size = int(size) create_flags = int(create_flags) if size % VHD_SECTOR_SIZE: raise exceptions.VHDInvalidSize("size is not a multiple of %d" % VHD_SECTOR_SIZE) return _call('vhd_create', ctypes.c_char_p(filename), ctypes.c_ulonglong(size), ctypes.c_int(disk_type), ctypes.c_uint(create_flags))