예제 #1
0
 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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
 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)
예제 #7
0
    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
예제 #8
0
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))