nobodd.disk
The nobodd.disk
module contains the DiskImage
class which is
the primary entry point for handling disk images. Constructed with a filename
(or file-like object which provides a valid fileno()
method),
the class will attempt to determine if MBR or GPT style partitioning is
in use. The DiskImage.partitions
attribute can then be queried to
enumerate, or access the data of, individual partitions:
>>> from nobodd.disk import DiskImage
>>> img = DiskImage('gpt_disk.img')
>>> img
<DiskImage file=<_io.BufferedReader name='gpt_disk.img'> style='gpt' signature=UUID('733b49a8-6918-4e44-8d3d-47ed9b481335')>
>>> img.style
'gpt'
>>> len(img.partitions)
4
>>> img.partitions
DiskPartitionsGPT({
1: <DiskPartition size=8388608 label='big-part' type=UUID('ebd0a0a2-b9e5-4433-87c0-68b6b72699c7')>,
2: <DiskPartition size=204800 label='little-part1' type=UUID('ebd0a0a2-b9e5-4433-87c0-68b6b72699c7')>,
5: <DiskPartition size=4194304 label='medium-part' type=UUID('ebd0a0a2-b9e5-4433-87c0-68b6b72699c7')>,
6: <DiskPartition size=204800 label='little-part2' type=UUID('ebd0a0a2-b9e5-4433-87c0-68b6b72699c7')>,
})
Note that partitions are numbered from 1 and that, especially in the case of MBR, partition numbers may not be contiguous: primary partitions are numbered 1 through 4, but logical partitions may only exist in one primary partition, and are numbered from 5. Hence it is entirely valid to have partitions 1, 5, and 6:
>>> from nobodd.disk import DiskImage
>>> img = DiskImage('test-ebr.img')
>>> img.style
'mbr'
>>> len(img.partitions)
3
>>> list(img.partitions.keys())
[1, 5, 6]
>>> img.partitions[1]
<DiskPartition size=536870912 label='Partition 1' type=12>
>>> img.partitions[5]
<DiskPartition size=536870912 label='Partition 5' type=131>
>>> img.partitions[6]
<DiskPartition size=1070596096 label='Partition 6' type=131>
GPT partition tables may also have non-contiguous numbering, although this
is less common in practice. The DiskPartition.data
attribute can be
used to access the content of the partition as a buffer object (see
memoryview
).
DiskImage
- class nobodd.disk.DiskImage(filename_or_obj, sector_size=512, access=1)[source]
Represents a disk image, specified by filename_or_obj which must be a
str
orPath
naming the file, or a file-like object.If a file-like object is provided, it must have a
fileno
method which returns a valid file-descriptor number (the class usesmmap
internally which requires a “real” file).The disk image is expected to be partitioned with either an MBR partition table or a GPT. The partitions within the image can be enumerated with the
partitions
attribute. The instance can (and should) be used as a context manager; exiting the context will call theclose()
method implicitly.If specified, sector_size is the size of sectors (in bytes) within the disk image. This defaults to 512 bytes, and should almost always be left alone. The access parameter controls the access used when constructing the memory mapping. This defaults to
mmap.ACCESS_READ
for read-only access. If you wish to write to file-systems within the disk image, change this tommap.ACCESS_WRITE
. You may also usemmap.ACCESS_COPY
for read-write mappings that don’t actually affect the underlying disk image.Note
Please note that this library provides no means to re-partition disk images, just the ability to re-write files within FAT partitions.
- close()[source]
Destroys the memory mapping used on the file provided. If the file was opened by this class, it will also be closed. This method is idempotent and is implicitly called when the instance is used as a context manager.
Note
All mappings derived from this one must be closed before calling this method. By far the easiest means of arranging this is to consistently use context managers with all instances derived from this.
- property partitions
Provides access to the partitions in the image as a
Mapping
of partition number toDiskPartition
instances.Warning
Disk partition numbers start from 1 and need not be contiguous, or ordered.
For example, it is perfectly valid to have partition 1 occur later on disk than partition 2, for partition 3 to be undefined, and partition 4 to be defined between partition 1 and 2. The partition number is essentially little more than an arbitrary key.
In the case of MBR partition tables, it is particularly common to have missing partition numbers as the primary layout only permits 4 partitions. Hence, the “extended partitions” scheme numbers partitions from 5. However, if not all primary partitions are defined, there will be a “jump” from, say, partition 2 to partition 5.
- property signature
The identifying signature of the disk. In the case of a GPT partitioned disk, this is a
UUID
. In the case of MBR, this is a 32-bit integer number.
- property style
The style of partition table in use on the disk image. Will be one of the strings, ‘gpt’ or ‘mbr’.
DiskPartition
- class nobodd.disk.DiskPartition(mem, label, type)[source]
Represents an individual disk partition within a
DiskImage
.Instances of this class are returned as the values of the mapping provided by
DiskImage.partitions
. Instances can (and should) be used as a context manager to implicitly close references upon exiting the context.- close()[source]
Release the internal
memoryview
reference. This method is idempotent and is implicitly called when the instance is used as a context manager.
- property data
Returns a buffer (specifically, a
memoryview
) covering the contents of the partition in the owningDiskImage
.
Internal Classes
You should not need to use these classes directly; they will be instantiated
automatically when querying the DiskImage.partitions
attribute
according to the detected table format.
- class nobodd.disk.DiskPartitionsGPT(mem, sector_size=512)[source]
Provides a
Mapping
from partition number toDiskPartition
instances for a GPT.mem is the buffer covering the whole disk image. sector_size specifies the sector size of the disk image, which should almost always be left at the default of 512 bytes.
- class nobodd.disk.DiskPartitionsMBR(mem, sector_size=512)[source]
Provides a
Mapping
from partition number toDiskPartition
instances for a MBR.mem is the buffer covering the whole disk image. sector_size specifies the sector size of the disk image, which should almost always be left at the default of 512 bytes.