API

Partclone and partimage images consist of three components, header (4 headers in partimage), bitmap and blocks of data. A description of the partclone image file format is available. Package imagebackup provides classes to read and process these three components.

Ntfsclone images do not contain a bitmap. They consist of a header and blocks of used blocks and counts of unused blocks of data.

PartClone, PartImage and NtfsClone

Classes PartClone, PartImage, and NtfsClone are instantiated with an open binary file and its file name, they read the header and - in case of PartClone and PartImage - also the bitmap of the image. If the file is not a supported image, they raise exception ImageBackupException.

from imagebackup.imagebackup import ImageBackupException
from imagebackup.partclone import PartClone
from imagebackup.partimage import PartImage
from imagebackup.ntfsclone import NtfsClone

with open('sda1.img', 'rb') as file:

   try:

       image = PartClone(file, 'sda1.img')

       print(image)

   except ImageBackupException as e:
       print('Failed to read image:', e)

If the image file can be opened, the header is printed and looks like this:

Partclone Header
================
partclone version 0.3.24
fs type           BTRFS
fs total size     274,994,298,880 (256.1 GB)
fs total blocks   16,784,320
fs used blocks    968,580 (14.8 GB)     used block count based on super-block
fs_used_bitmap    1,168,685 (17.8 GB)   used block count based on bitmap
fs block size     16384
image version     2
cpu bits          64
checksum mode     CRC32
checksum size     4
checksum blocks   64
checksum reseed   True
bitmap mode       BIT
header_crc32      0xae9d1efd
bitmap            2,098,040 bytes (2.0 MB)
bitmap_crc32      0x6dbca530
blocks_section    at 2,098,154 in img file
block_offset_size 1024
block_offsets     0 instances

The header can also be read from a pipe, a regular file is not necessary.

The bitmap represents each block with one bit and indicates whether the block is in use or not. Only if a block is in use its data is saved to the image file. There is not much besides the actual bitmap, just a checksum. The members block_offset_size and block_offsets have not been read from the image file. They implement indexing which allows to read data blocks from the image quickly and in an arbitray order.

Blocks

Once the header and bitmap have been read, we can read all used blocks from the partition. Method blockReader reads all used blocks in sequence:

imagebackup.imagebackup.ImageBackup.blockReader(self, progress_bar: bool = True, verify_crc: bool = False, fn: Callable[[int, bytes], None] | None = None) None

Reads all used blocks and verifies all checksums. If fn is not None it will be called for each block.

Parameters:
  • progress_bar (bool = True) – Whether or not to show progress bar while reading blocks; True by default.

  • verify_crc (bool = False) – Whether or not to compute and verify checksums while reading blocks; False by default.

  • fn (Optional[Callable[[int,bytes],None]] = None) – An optional function that is called with two parameters, the offset into the partition and the data for each block. None by default.

Here are two examples for its parameter fn, the function which is called with each block of data:

with open('/dev/sda1', 'rb+') as f_out:

    def write_block(offset: int, block: bytes) -> None:
        f_out.seek(offset)
        f_out.write(block)

    image.blockReader(fn=write_block)

The function is only called for used blocks. Unused blocks are not even stored in the image file. However, since method blockReader calls the function strictly in ascending order of the offset, unused blocks can be written as well. The following code fills them with 0xdeadbeef, a pattern that is easily recognized in hex dumps:

with open('sda1.vol', 'wb') as f_out:
    block_size  = image.blockSize()
    empty_block = bytes([0xde, 0xad, 0xbe, 0xef] * (block_size // 4))
    last_offset = 0

    def write_unused(offset: int) -> None:
        global last_offset
        while last_offset < offset:
            f_out.write(empty_block)
            last_offset += block_size

    def write_block(offset: int, block: bytes) -> None:
        global last_offset
        write_unused(offset)
        f_out.write(block)
        last_offset = offset + len(block)

    image.blockReader(fn=write_block)
    write_unused(image.totalBlocks() * block_size)

Note that write_block does not call f_out.seek anymore. In this scenario the output file is written sequentially.

BlockIO

There are situations where the blocks in an image file need to be read in random order. Class BlockIO allows random access to arbitrary ranges of bytes.

class imagebackup.blockio.BlockIO(image: ImageBackup)

This class fulfills read requests of disk data. It breaks these requests down into reads of full blocks from the image file.

Parameters:

image (imagebackup.imagebackup.ImageBackup) – image to read blocks from

Raises:

imagebackup.imagebackup.ImageBackupException – if the file is not a regular file.

getTotalSize() int

Return the total (used and unused blocks) size in bytes.

Returns:

size of partition.

read_data(offset: int, size: int) bytes

Read size bytes at offset.

Parameters:
  • offset (int) – offset in partition to read bytes from.

  • size (int) – the number of bytes to read at offset.

Returns:

no bytes if offset is negative, size bytes if entire range is within partition, fewer bytes otherwise.

The image file will not be read sequentially in this scenario. It has to be a regular file and must not be compressed.

from imagebackup.blockio import BlockIO

blockio = BlockIO(image)

# read 42 bytes at offset 100000 and dump them in hex
print(' '.join(f'{b:02x}' for b in blockio.read_data(offset=100000, size=42)))

Opening Image Files

Image files are usually compressed and may be split into smaller files named .aa, .ab, … This package contains functionality to detect and read split and compressed image files. All common compression algorithms - gzip, bzip2, zstandard, lz4, lzma, and xz - are supported.

imagebackup.utilities.uncompress(file: BufferedReader, errorOut: bool = False) Tuple[BufferedIOBase, str, str]

Handle compression if file is a compressed file. Return a triple consisting of possibly a new file to read uncompressed data from, the file name, and the compression used.

This function also deals with split files. If it is called with a file whose name ends with ‘aa’ and there exists also a file that ends in ‘ab’, this function will virtually concatenate aa, ab, … and uncompress the concatenated contents.

Parameters:
  • file (io.BufferedReader) – A binary file opened for reading.

  • errorOut (bool) – if True do not uncompress but raise exception.

Raises:

imagebackup.partimage.ImageBackupException – when file cannot be uncompressed or errorOut is set.

Returns:

A triple consisting of opened file, file name, and compression. The compression is represented as empty string for no compression, ‘gz’, ‘bz2’, ‘zstd’, ‘xz’, ‘lzma’, or ‘lz4’. Split files are reported along with the compression, ‘split’ and ‘zstd+split’ are possible values.

The parameter errorOut can be False when the caller is going to read the image sequentially. It must be True for random access since the seek method is prohibitively slow for compressed files. Split files are fully supported for random access.

Image files can also be opened in a generic manner where it either a partclone, partimage, or ntfsclone image and the caller does not need to know beforehand which kind it is.

imagebackup.main.readImage(f: BufferedReader, block_index_size: int, sequential: bool, fn: Callable[[BufferedIOBase], ImageBackup]) ImageBackup

Read an image file, uncompress compressed files if possible, check the first bytes of the file to determine image format.

Parameters:
  • file (io.BufferedIOBase) – A binary file opened for reading.

  • block_index_size (int) – is a parameter for the index; defaults to 1024 bits.

  • sequential (bool) – Whether or not the image is to be read sequentially. If so, this function will try to support compressed files; otherwise it will suggest a command to uncompress the image file.

  • fn (Callable[[io.BufferedIOBase],imagebackup.imagebackup.ImageBackup]) – A function that we call to read the backup image. The function takes a single argument, an open file, and returns an object derived from ImageBackup.

Raises:

imagebackup.imagebackup.ImageBackupException – Image not supported.

Returns:

A PartImage, PartClone, or NtfsClone instance.

There is no need to call uncompress; function readImage calls uncompress internally. This is an example for calling readImage:

from imagebackup.imagebackup import ImageBackup, ImageBackupException
from imagebackup.ntfsclone import NtfsClone
from imagebackup.main import readImage

with open('sda1.img', 'rb') as file:

   try:

       image = readImage(f=file,
                         block_index_size=ImageBackup.BLOCK_OFFSET_SIZE,
                         sequential=True,
                         fn=lambda f:NtfsClone(f))
       print(image)

   except ImageBackupException as e:
       print('Failed to read image:', e)

This piece of code will not only read ntfsclone images but also partclone and partimage files, even compressed and split ones.

Detailed API Documentation

Module imagebackup

imagebackup.imagebackup.BITS_SET = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8]

The number of bits set for each byte.

class imagebackup.imagebackup.BlockOffset(file_offset: int, cksum_offset: int)

This class is used in an index to compute the offset in the image file for a given block. This is used for image backups based on bitmaps.

cksum_offset: int

>= 0 and < ImageBackup.checksum_blocks

file_offset: int

offset into image file

class imagebackup.imagebackup.ImageBackup(file: BufferedIOBase, filename: str, block_offset_size: int)

Base class of PartClone, PartImage, and NtfsCLone. This base class stores the file, file name and bitmap and provides an index based on the bitmap.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

BLOCK_OFFSET_SIZE = 1024

Allocate an index for every 128 bytes; a reasonable default for indexing.

bitMap() bytes | None

Return the bitmap for image files that have bitmaps, None otherwise.

Returns:

bitmap or None.

blockInUse(block_no: int) bool

Returns True if block_no is in use, False otherwise.

Parameters:

block_no (int) – block number

Returns:

True if block_no is in use, False otherwise.

Raises:

imagebackup.imagebackup.ImageBackupException – if the block number is out of range.

blockReader(progress_bar: bool = True, verify_crc: bool = False, fn: Callable[[int, bytes], None] | None = None) None

Reads all used blocks and verifies all checksums. If fn is not None it will be called for each block.

Parameters:
  • progress_bar (bool = True) – Whether or not to show progress bar while reading blocks; True by default.

  • verify_crc (bool = False) – Whether or not to compute and verify checksums while reading blocks; False by default.

  • fn (Optional[Callable[[int,bytes],None]] = None) – An optional function that is called with two parameters, the offset into the partition and the data for each block. None by default.

blockSize() int

Return file system’s block size.

Returns:

size of file system block in bytes.

blocksSectionOffset() int

Return offset of Blocks section in image file.

Returns:

the offset of the very first in-use block in the image file.

buildBlockIndex(progress_bar: bool = True) None

Builds an index of available blocks. This is done unless the image is going to be read only sequentially.

Parameters:

progress_bar (bool = True) – ignored as we are builing the index from bitmap.

fsType() str

Return file system type.

Returns:

an upper-case string like ‘NTFS’ or ‘BTRFS’.

getBlockOffset(block_no: int) int | None

Return offset of block in image file or None if block is not in use.

Parameters:

block_no (int) – block number

Returns:

offset of block in image file if the block is in use, None otherwise.

Raises:

imagebackup.imagebackup.ImageBackupException – if the block number is out of range.

getFile() BufferedIOBase

Return open binary file.

Returns:

open binary file.

getFilename() str

Return name of open binary file.

Returns:

name of open binary file.

getTool() str

Return tool for image backups.

Returns:

string ‘ntfsclone’, ‘partclone’, or ‘partimage’.

totalBlocks() int

Return file system’s total number of blocks.

Returns:

file system’s total number of blocks.

totalSize() int

Return file system’s total size in bytes.

Returns:

file system’s total size in bytes.

updateFile(file: BufferedIOBase, filename: str)

Update file and filename.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

usedBlocks() int

Return file system’s number of blocks in use.

Returns:

file system’s number of blocks in use.

exception imagebackup.imagebackup.ImageBackupException(msg: str)

This exception is raised for any issues encountered with reading the backup image.

imagebackup.imagebackup.crc32(buffer: bytes, seed=4294967295) int

Compute crc32 for the given buffer.

Parameters:
  • buffer (bytes) – buffer to compute crc32 for.

  • seed (int) – seed to start crc32 computation from, default 0xffffffff.

Returns:

32-bit crc

imagebackup.imagebackup.reportSize(size: int) str

Report size in appropriate unit (B, KB, MB, GB, TB, …).

Parameters:

size (int) – Size in bytes to be reported.

Returns:

size as string notation with appropriate unit.

Module ntfsclone

class imagebackup.ntfsclone.ClusterIndex(cluster_size: int)

This class implements the lookup of its offset in the image file for a cluster number. Cluster ranges are stored in an array. Binary search in this array is used to look up a cluster’s offset in the image file.

Parameters:

cluster_size (int) – cluster size (block size)

append(range: ClusterRange) None

Insert a cluster range into the index.

Parameters:

range (ClusterRange) – cluster range

offset(cluster: int) int | None

Return the offset for given cluster in the image file if the cluster is used. For unused clusters, None is returned.

Parameters:

cluster (int) – cluster number

Returns:

offset of cluster in image file if the cluster is in use, None otherwise.

class imagebackup.ntfsclone.ClusterRange(used: bool, start: int, size: int, offset: int)

Cluster ranges are used for indexing.

end() int

Returns the cluster after the last one in this cluster range.

offset: int

For used clusters, the offset into the image file for cluster start, -1 for unused clusters.

size: int

Number of consecutive clusters in this range.

start: int

Starting cluster number.

used: bool

Are the clusters in this range used or unused?

class imagebackup.ntfsclone.NtfsClone(file: BufferedIOBase, filename: str)

“This Class reads and processes an ntfsclone image file. The constructor reads the header and raises exceptions if the file is not an ntfsclone file.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

Raises:

imagebackup.ntfsclone.NtfsCloneException – if the file is not an ntfsclone image.

bitMap() bytes | None

Return the bitmap for image files that have bitmaps, None otherwise.

Returns:

None.

blockInUse(block_no: int) bool

Returns True if block_no is in use, False otherwise.

Parameters:

block_no (int) – block number

Returns:

True if block_no is in use, False otherwise.

Raises:

imagebackup.ntfsclone.NtfsCloneException – if the block number is out of range.

blockReader(progress_bar: bool = True, verify_crc: bool = False, fn: Callable[[int, bytes], None] | None = None) None

Reads all used blocks. If fn is not None it will be called for each block.

Parameters:
  • progress_bar (bool = True) – Whether or not to show progress bar while reading blocks; True by default.

  • verify_crc (bool = False) – Whether or not to compute and verify checksums while reading blocks; False by default. Ignored as ntfsclone images don’t contain checksums.

  • fn (Optional[Callable[[int,bytes],None]] = None) – An optional function that is called with two parameters, the offset into the partition and the data for each block. None by default.

Raises:

imagebackup.ntfsclone.NtfsCloneException – if the image file is corrupted.

blockSize() int

Return file system’s block size.

Returns:

size of file system block in bytes.

buildBlockIndex(progress_bar: bool = True) None

Populates index self.cluster_index which is required for member function getBlockOffset(). This indexing is done unless the image is going to be read only sequentially.

Parameters:

progress_bar (bool = True) – whether to show a progress bar. ntfsclone images do not contain bitmaps. The entire image file needs to be read to index the blocks.

fsType() str

Return file system type.

Returns:

string ‘NTFS’.

getBlockOffset(block_no: int) int | None

Return offset of block in image file or None if block is not in use.

Parameters:

block_no (int) – block number

Returns:

offset of block in image file if the block is in use, None otherwise.

Raises:

imagebackup.ntfsclone.NtfsCloneException – if the block number is out of range.

getTool() str

Return tool for image backups.

Returns:

string ‘ntfsclone’.

totalBlocks() int

Return file system’s total number of blocks.

Returns:

file system’s total number of blocks.

totalSize() int

Return file system’s total size in bytes.

Returns:

file system’s total size in bytes.

usedBlocks() int

Return file system’s number of blocks in use.

Returns:

file system’s number of blocks in use.

exception imagebackup.ntfsclone.NtfsCloneException(s: str)

This exception is raised for issues encountered when reading ntfsclone images.

Module partclone

class imagebackup.partclone.PartClone(file: BufferedIOBase, filename: str, block_offset_size: int = 1024)

This class reads the header of a partclone image, checks for the supported version (version 2), compares the header’s crc32, reads the bitmap, and verifies the bitmap’s crc32.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

  • block_offset_size (int) – is a parameter for the index; defaults to 1024 bits.

Raises:

imagebackup.partclone.PartCloneException – if the file is not a partclone image.

bitMap() bytes

Return the bitmap.

Returns:

the bitmap that has been read from the image file.

blockReader(progress_bar: bool = True, verify_crc: bool = False, fn: Callable[[int, bytes], None] | None = None) None

Reads all used blocks and verifies all checksums. If fn is not None it will be called for each block.

Parameters:
  • file (io.BufferedReader) – A binary file opened for reading. This can be a regular file, a pipe, or a socket. This function will read the file sequentially.

  • progress_bar (bool = True) – Whether or not to show progress bar while reading blocks; True by default.

  • verify_crc (bool = False) – Whether or not to compute and verify checksums while reading blocks; False by default.

  • fn (Optional[Callable[[int,bytes],None]] = None) – An optional function that is called with two parameters, the offset into the partition and the data for each block. None by default.

Raises:

imagebackup.partclone.PartCloneException – if the image file is corrupted.

blockSize() int

Return file system’s block size.

Returns:

size of file system block in bytes.

blocksSectionOffset() int

Return offset of Blocks section in image file.

Returns:

the offset of the very first in-use block in the image file.

checksumBlocks() int

Return number of blocks preceeding a checksum.

checksumMode() int

Return checksum mode, 0 (no checksum) or 32 (crc32).

checksumReseed() bool

Reseed crc32 for next checksum or not.

checksumSize() int

Return checksum size (usually 4 bytes).

fsType() str

Return file system type, e.g. NTFS or BTRFS.”

Returns:

upper-case string, e.g. ‘NTFS’.

getEndian() str

Return ‘<’ or ‘>’ for struct.unpack.

getTool() str

Return tool for image backups.

Returns:

string ‘partclone’.

totalBlocks() int

Return file system’s total number of blocks.

Returns:

file system’s total number of blocks.

totalSize() int

Return file system’s total size in bytes.

Returns:

file system’s total size in bytes.

usedBlocks() int

Return file system’s number of blocks in use.

Returns:

file system’s number of blocks in use.

exception imagebackup.partclone.PartCloneException(s: str)

This exception is raised for any issues encountered with the partclone image.

Module partimage

class imagebackup.partimage.AfsInfoHeader(buffer: bytes)

Builds an AFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.AfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.BefsInfoHeader(buffer: bytes)

Builds a BEFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.BefsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.ExtInfoHeader(buffer: bytes)

Builds an EXT2/3 Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.ExtInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.FatInfoHeader(buffer: bytes)

Builds a FAT Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.FatInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.Header(kind: str, buffer: bytes)

Base of MainHeader, LocalHeader, and InfoHeader.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.HfsInfoHeader(buffer: bytes)

Builds an HFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.HfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.HpfsInfoHeader(buffer: bytes)

Builds an HPFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.HpfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.InfoHeader(buffer: bytes)

Base class for Info Headers.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.AfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.JfsInfoHeader(buffer: bytes)

Builds a JFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.JfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.LocalHeader(buffer: bytes)

Builds a Local Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.LocalHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

getBitmapSize() int

Return the size of the bitmap in bytes.

getBlockCount() int

Return the total number of blocks, used and unused blocks.

getBlockSize() int

Return size of one block in bytes, e.g. 512 or 8192.

getLabel() str

Return the label of the file system. Empty unless it had a label.

getUsedBlocks() int

Return the number of blocks that were in use when the image was saved.

class imagebackup.partimage.MainHeader(buffer: bytes)

Builds a Main Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.MainHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

getDateTime() datetime

Return date & time the image was written.

getDescription() str

Return a descripton for the backup image. Empty unless user provided one to partimage when the image was written.

getDevice() str

Return the device that was written, e.g. ‘/dev/sda1’.

getFilesystem() str

Return the file system that was saved, e.g. ‘fat32’ or ‘ext2’.

getPartitionSize() int

Return the size of the partitioon in bytes.

class imagebackup.partimage.NtfsInfoHeader(buffer: bytes)

Builds a NTFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.NtfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.PartImage(file: BufferedIOBase, filename: str, block_offset_size: int = 1024)

This class reads the headers of a partimage image, checks for the supported version (version 2), compares the headers’ crc32’s and reads the bitmap.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

  • block_offset_size (int) – is a parameter for the index; defaults to 1024 bits.

Raises:

imagebackup.partimage.PartImageException – if the file is not a partimage image.

blockReader(progress_bar: bool = True, verify_crc: bool = False, fn: Callable[[int, bytes], None] | None = None) None

Reads all used blocks and verifies all checksums. If fn is not None it will be called for each block.

Parameters:
  • progress_bar (bool = True) – Whether or not to show progress bar while reading blocks; True by default.

  • verify_crc (bool = False) – Whether or not to compute and verify checksums while reading blocks; False by default.

  • fn (Optional[Callable[[int,bytes],None]] = None) – An optional function that is called with two parameters, the offset into the partition and the data for each block. None by default.

Raises:

imagebackup.partimage.PartImageException – when the image is corrupted.

blockSize() int

Return file system’s block size.

Returns:

size of file system block in bytes.

blocksSectionOffset() int

Return offset of Blocks section in image file.

Returns:

the offset of the very first in-use block in the image file.

dispose_buffer(size: int) None

Remove size bytes of self.buffer. Increase self.address by size, checksum the first size bytes of self.buffer.

Parameters:

size (int) – Number of bytes to remove from buffer.

Raises:

imagebackup.partimage.PartImageException – when the image is corrupted.

fsType() str

Return file system type.

Returns:

an upper-case string like ‘NTFS’ or ‘BTRFS’.

getTool() str

Return tool for image backups.

Returns:

string ‘partimage’.

openNextVolume(got_size: int, need_size: int) None

partimage can write images to multiple volumes. This method is called upon prematurely encountered end-of-file and it tries to open the next volume.

Multiple volumes are only supported when the file is read sequentially, is not compressed and the files names end with “000”, “001”, “002”, …

Parameters:
  • got_size (int) – Number of bytes that were read from the partimage file.

  • need_size (int) – Number of bytes needed for a complete block or checksum.

Raises:

imagebackup.partimage.PartImageException – when the image is corrupted.

totalBlocks() int

Return file system’s total number of blocks.

Returns:

file system’s total number of blocks.

totalSize() int

Return file system’s total size in bytes.

Returns:

file system’s total size in bytes.

usedBlocks() int

Return file system’s number of blocks in use.

Returns:

file system’s number of blocks in use.

usedBlocksRange(idx: int) Tuple[int, int]

Returns a range of used blocks, a pair with the starting number and the number of consecutive used blocks. An initial starting number idx is provided by the caller. If that block is used, it will be returned along with the number of consecutive used blocks.

When all used blocks have been exhausted, (-1, 0) will be returned. There is an upper bound to the number of consecutive blocks computed: no more than max_block_range will be returned in a single call. This exact upper bound is necessary for the CRC checks to work properly.

exception imagebackup.partimage.PartImageException(s: str)

This exception is raised for any issues encountered with the partimage image.

class imagebackup.partimage.ReiserInfoHeader(buffer: bytes)

Builds a ReiserFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.ReiserInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.UfsInfoHeader(buffer: bytes)

Builds a UFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.UfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

class imagebackup.partimage.VolumeHeader(file: BufferedIOBase, filename: str)

Volume Header, the first 512 bytes of a partimage file.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

Raises:

imagebackup.partimage.PartImageException – if the file is not a partimage image.

getIdentifier() int

Number to uniquely identify an image spread over multiple volumes.

getVersion() str

Partimage version that wrote this image, e.g. ‘0.6.1’.

getVolumeNo() int

Volume number, zero-based, for images spread over multiple volumes.

class imagebackup.partimage.XfsInfoHeader(buffer: bytes)

Builds an XFS Info Header.

Parameters:

buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

imagebackup.partimage.XfsInfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

imagebackup.partimage.buildInfoHeader(filesystem: str, buffer: bytes) InfoHeader

Builds an info header for the given file system.

Parameters:
  • filesystem (str) – file system

  • buffer (bytes) – 16384 bytes of header plus 4 bytes CRC.

Returns:

derived class of InfoHeader

Raises:

imagebackup.partimage.PartImageException – when CRC does not match.

imagebackup.partimage.crcUpdate(buffer: bytes, crc: int) int

Compute crc32 for the given buffer.

Parameters:
  • buffer (bytes) – buffer to compute crc32 for.

  • crc (int) – seed to start crc32 computation from

Returns:

32-bit crc

Module blockio

class imagebackup.blockio.BlockIO(image: ImageBackup)

This class fulfills read requests of disk data. It breaks these requests down into reads of full blocks from the image file.

Parameters:

image (imagebackup.imagebackup.ImageBackup) – image to read blocks from

Raises:

imagebackup.imagebackup.ImageBackupException – if the file is not a regular file.

getTotalSize() int

Return the total (used and unused blocks) size in bytes.

Returns:

size of partition.

read_data(offset: int, size: int) bytes

Read size bytes at offset.

Parameters:
  • offset (int) – offset in partition to read bytes from.

  • size (int) – the number of bytes to read at offset.

Returns:

no bytes if offset is negative, size bytes if entire range is within partition, fewer bytes otherwise.

Module fuse

class imagebackup.fuse.ImageBackupFS(*args: Any, **kwargs: Any)

This class implements a FUSE filesystem on top of a backup image.

A single read-only file is shown under the moint point. Its file is derived from the image filename.

This file can be read and it refects the partition stored in the backup image. Unused (and hence not stored) blocks are returned as bytes of zeros.

This file represents a partition which can be mounted with the loop option to inspect or save its contents. Remember to mount it read-only.

Parameters:
imagebackup.fuse.assertRegularFile(file: BufferedIOBase, filename: str) None

Raise exception with appropriate message if file is not a regular file.

Parameters:
  • file (io.BufferedIOBase) – Binary file opened for input.

  • filename (str) – The open file’s name.

Returns:

nothing

Raises:

imagebackup.imagebackup.ImageBackupException – if the file is not a regular file.

imagebackup.fuse.fsckCmd(fsType: str) str

Return fsck command to check this filesystem.

Parameters:

fsType (str) – string obtained from method imagebackup.imagebackup.fsType()

Returns:

string that contains the command for a file system consistency check of a read-only partition.

imagebackup.fuse.isEmptyDirectory(path: str) str

Is argument an empty directory?

Parameters:

path (str) – argument of command line option -m/–mountpoint

Returns:

path if path is a directory in the file system and this directory is empty

Raises:

argparse.ArgumentTypeError – if path is not a directory in the file system or it is a directory but the directory is not empty.

imagebackup.fuse.mntType(fsType: str) str

Return file-system type for the mount command. The empty string can be returned to indicate that the mount command should be called without the -t option.

Parameters:

fsType (str) – string obtained from method imagebackup.imagebackup.fsType()

Returns:

string to use as type for the mount command. Empty string if mount needs to be called without the -t option.

imagebackup.fuse.runFuse(image: ImageBackup, mountpoint: str, debug: bool = False) None

Provide FUSE filesystem under given mountpoint. Generally, fork process and run the FUSE filesystem in the background process. If option debug is set, do not fork and run in the foreground writing debug messages.

Parameters:

Module utilities

class imagebackup.utilities.ConcatFiles(file: BufferedReader)

This class is instantiated with a file whose name ends in ‘aa’ and it concatenates split binary files.

Parameters:

file (io.BufferedReader) – A binary file opened for reading.

byOffset(offset: int) None

Look up a single individual file by offset.

This method performs a binary search and calls method newFile to update members cur_idx, cur, and cur_offset.

Parameters:

offset (int) – Index into the large unsplit file.

close() None

Close all individual files.

fileno() int

Return file descriptor that is currently active.

Returns:

integer file descriptor

property mode: str

Return the mode the file has been opened with.

Returns:

string ‘rb’

property name: str

Return file name that is currently active.

Returns:

file name.

newFile(idx: int)

Set a new single individual file as the active one.

This method modifies members cur_idx, cur, and cur_offset.

Parameters:

idx (int) – Index into member split_files.

peek(size: int = 1) bytes

Peek into file. Returns data in buffer that has not yet been returned with read.

Returns:

bytes of unread data

read(size: int | None = None) bytes

Read size bytes from file. When size is None, read all the rest of the file.

Returns:

size bytes or fewer if size bytes would read beyond end-of-file.

seek(pos: int, whence: int = 0) int

Seek to position in file.

Returns:

new position in file.

seekable() bool

Is this stream seekable?

Returns:

True

tell() int

Return current position in file.

Returns:

position in file.

class imagebackup.utilities.LRU(max_open)

This LRU keeps track of open files. Not more than max_open files will be open at any time. When a new file is opened, this class closes the least recently used file.

Parameters:

max_open (int) – The max number of open files.

insert(idx: int, sf: SplitFile) None

Split file sf at index idx is being used. Append it to lru. If it is already in lru, delete it first. It must become the most recently used entry.

Parameters:
  • idx (int) – Index of split file sf.

  • sf (SplitFile) – Split file sf.

remove(idx) None

Remove split file at index idx from lru. Close file if it is not already closed.

Parameters:
  • idx (int) – Index of split file sf.

  • sf (SplitFile) – Split file sf.

imagebackup.utilities.MAX_OPEN_SPLIT_FILES = 48

During the virtual concatenation of split files, we will not leave more than this many files open at any time. This limit is relevant for random access to split files; during sequential access we open them just one at a time.

class imagebackup.utilities.ReadZstd(file: BufferedReader)

This class is instantiated with a zstd-compressed file. This class adds method peek to an instance of zstandard.ZstdDecompressor.stream_reader. stream_reader does all the heavy lifting.

Parameters:

file (io.BufferedReader) – A binary file opened for reading.

close() None

Close file.

fileno() int

Return file descriptor of the compressed file.

Returns:

integer file descriptor

property mode: str

Return the mode the file has been opened with.

Returns:

string ‘rb’

property name: str

Return file name that we are reading from.

Returns:

file name.

peek(size: int = 1) bytes

Peek into file. Return data in buffer that has not yet been returned with read. The next read will return this data.

Returns:

bytes of unread data

read(size: int | None = None) bytes

Read size bytes from file. When size is None, read all the rest of the file.

Returns:

size bytes or fewer if size bytes would read beyond end-of-file.

seek(pos: int, whence: int = 0) int

Seek to position in file.

Returns:

new position in file.

seekable() bool

Is this stream seekable?

Returns:

True

tell() int

Return current position in file.

Returns:

position in file.

class imagebackup.utilities.SplitFile(offset: int, size: int, filename: str, file: BufferedReader | None)

This class represents an individual split file. Class ConcatFiles’ stores an array of `SplitFiles.

end() int
Returns:

offset of first byte of next single individual file.

file: BufferedReader | None

Open file or None; split files are opened and closed on demand.

filename: str

Name of this individual file.

offset: int

Offset into the unsplit virtual file where this individual file starts.

size: int

Number of bytes in this file.

imagebackup.utilities.compressedMsg(filename: str, compression: str) str

Formats the error message for compressed images encountered when reading image. Suggests appropiate command to uncompress them.

Parameters:
  • filename – File name of the compressed image.

  • compression – ‘gz’, ‘bz2’, ‘zstd’, ‘xz’, ‘lzma’, and ‘lz4’ are supported.

Returns:

A formatted error message.

imagebackup.utilities.isRegularFile(file: BufferedIOBase) bool

Is the open file a regular file and not for instance a pipe?

Parameters:

file (io.BufferedIOBase) – Binary file opened for input.

Returns:

True if file is a regular file, False otherwise.

imagebackup.utilities.isSplitFile(name: str) bool

Is the file a split file?

Parameters:

file (io.BufferedIOBase) – Binary file opened for input.

Returns:

True if name ends in aa and another file ab exists, False otherwise.

imagebackup.utilities.uncompress(file: BufferedReader, errorOut: bool = False) Tuple[BufferedIOBase, str, str]

Handle compression if file is a compressed file. Return a triple consisting of possibly a new file to read uncompressed data from, the file name, and the compression used.

This function also deals with split files. If it is called with a file whose name ends with ‘aa’ and there exists also a file that ends in ‘ab’, this function will virtually concatenate aa, ab, … and uncompress the concatenated contents.

Parameters:
  • file (io.BufferedReader) – A binary file opened for reading.

  • errorOut (bool) – if True do not uncompress but raise exception.

Raises:

imagebackup.partimage.ImageBackupException – when file cannot be uncompressed or errorOut is set.

Returns:

A triple consisting of opened file, file name, and compression. The compression is represented as empty string for no compression, ‘gz’, ‘bz2’, ‘zstd’, ‘xz’, ‘lzma’, or ‘lz4’. Split files are reported along with the compression, ‘split’ and ‘zstd+split’ are possible values.

Module main

imagebackup.main.indexSizeType(arg: str) int

Is argument an acceptable argument for vpartclone’s option –index_size?

Parameters:

arg (str) – string passed by user to -i/–index_size option.

Returns:

the index size as an int.

Raises:

argparse.ArgumentTypeError – if the argument is an invalid index size.

imagebackup.main.readImage(f: BufferedReader, block_index_size: int, sequential: bool, fn: Callable[[BufferedIOBase], ImageBackup]) ImageBackup

Read an image file, uncompress compressed files if possible, check the first bytes of the file to determine image format.

Parameters:
  • file (io.BufferedIOBase) – A binary file opened for reading.

  • block_index_size (int) – is a parameter for the index; defaults to 1024 bits.

  • sequential (bool) – Whether or not the image is to be read sequentially. If so, this function will try to support compressed files; otherwise it will suggest a command to uncompress the image file.

  • fn (Callable[[io.BufferedIOBase],imagebackup.imagebackup.ImageBackup]) – A function that we call to read the backup image. The function takes a single argument, an open file, and returns an object derived from ImageBackup.

Raises:

imagebackup.imagebackup.ImageBackupException – Image not supported.

Returns:

A PartImage, PartClone, or NtfsClone instance.

imagebackup.main.utility(fn: Callable[[BufferedIOBase], ImageBackup], args: Namespace) None

This function implements the common code of utilities vpartclone and vntfsclone.

Parameters:
imagebackup.main.vntfsclone()

Implements vntfsclone command; processes command-line argumments, reads image and mounts it as virtual partition.

imagebackup.main.vpartclone()

Implements vpartclone command; processes command-line argumments, reads image and mounts it as virtual partition.

imagebackup.main.vpartimage()

Implements vpartimage command; processes command-line argumments, reads image and mounts it as virtual partition.