dissect.vmfs.lvm

Module Contents

Classes

LVM

VMFS LVM implementation, supports LVM5 and LVM6.

Device

VMFS LVM device implementation.

Volume

Logical volume in a VMFS LVM.

VolumeStream

Read-only stream that allows reading from VMFS LVM volumes.

class dissect.vmfs.lvm.LVM(fh: BinaryIO | Device | list[BinaryIO] | list[Device])

VMFS LVM implementation, supports LVM5 and LVM6.

VMFS LVM is a logical volume manager that allows multiple physical devices to be combined into a single logical volume. Technically LVM supports multiple logical volumes, in fact LVM3 started with supporting 1024, later versions decreased it to 512. LVM6 only allows 1. In practice only one logical volume is ever used.

Provide this class with file-like objects for all devices that make up the LVM, then access the volumes attribute to get a list of logical volumes. A Volume can be opened for reading by calling Volume.open().

Parameters:

fh – A file-like object or a list of file-like objects that constitute an LVM.

devices: list[Device] = []

List of Device objects that make up the LVM.

volumes: list[Volume] = []

List of Volume objects that are in the LVM.

__repr__() str
class dissect.vmfs.lvm.Device(fh: BinaryIO)

VMFS LVM device implementation.

Represents a single device in the LVM.

LVM devices contain metadata that describes itself, the logical volumes and physical extents it contains.

The metadata roughly looks like the following pseudo-structure:

struct LVM_DeviceHeader {
    LVM_DevMetadata     devMeta;
    LVM_VolTableEntry   volTable[LVM_MAX_VOLUMES_PER_DEV];
    char                reserved[LVM_RESERVED_SIZE];
    LVM_SDTableEntry    sdTable[FS_PLIST_DEF_MAX_PARTITIONS];
    uint8               peBitmap[LVM_PE_BITMAP_SIZE];
    LVM_PETableEntry    peTable[LVM_PES_PER_BITMAP];
};

On versions prior to LVM6, it looks like the structure sizes are largely respected when calculating offsets to other tables. However, since LVM6 a specific field in LVM_DevMetadata is often used for this calculation. Because the real name of this field is unknown, we have decided to call it mdAlignment within this project, since it appears to be used in a similar way as in VMFS.

The device metadata (devMeta) starts at a fixed offset (0x00100000), but since LVM6 may reference extended metadata at other offsets. The volume table (volTable) starts after devMeta, which is 0x00100000 + LVM_SIZEOF_LVM_DEVMETA, where LVM_SIZEOF_LVM_DEVMETA is either 512 or since LVM6 the value of the mdAlignment field in the LVM_DevMetadata structure. Since LVM5 (I could not find evidence that LVM4 exists) there exists a sdTable, which is a table of device names, that starts at the end of the volume table. The peBitmap is a bitmap that describes which entries in the peTable are used, and starts at the end of the volTable/sdTable. The peTable is a table of physical extents, which starts at the end of the peBitmap. A pair of peBitmap and peTable repeats for numPEs times.

The device metadata LVM_DevMetadata contains information about the device, including some identifiers and number of volumes and physical extents. There are also timestamps when the device was created and last modified.

The volume descriptor LVM_VolDescriptor contains information about the logical volume, specific to that device. The LVM_VolMetadata structure contains metadata that is shared across all devices in the volume, but other fields in the descriptor are specific to that device (such as the first and last physical extent on that device).

The “SD table” (storage device? SCSI disk?) is a table of device names that are part of the volume, which is only present in LVM5 and later, and only on the first device in the LVM (internally referred to as “devZero”).

The physical extent descriptors (LVM_PEDescriptor) contain information about the physical extents on the device, including the logical offset, physical offset and length of the extent, as well as a reference to the volume it belongs to. A device can have multiple physical extents, and the logical volume is constructed from these physical extents across all devices in the LVM.

There can only be a maximum of 8 physical extent map/table pairs per metadata region (so 8 maps and 64k table entries). If more are needed, the device metadata will reference extended metadata regions, which are similarly laid out, but with a different offset. The extended metadata regions are linked together by the nextOffset field in the LVM_ExtDevMetadata structure.

Parameters:

fh – A file-like object of a LVM device.

fh
metadata
ext_metadata = []
major_version
minor_version
uuid
size
volumes
__repr__() str
class dissect.vmfs.lvm.Volume(uuid: str, snap_id: int, devices: list[Device])

Logical volume in a VMFS LVM.

Represents a logical volume that is constructed from one or more devices.

Parameters:
  • uuid – The UUID of the volume.

  • snap_id – The snapshot ID of the volume.

  • devices – A list of Device objects that make up the volume. Must contain at least one device.

uuid
snap_id
devices
size
generation
state
name
creation_ts
dataruns
__repr__() str
is_valid() bool

Check if the volume is valid and can be opened for reading.

open() VolumeStream

Open a read-only stream for the volume.

class dissect.vmfs.lvm.VolumeStream(volume: Volume)

Bases: dissect.util.stream.AlignedStream

Read-only stream that allows reading from VMFS LVM volumes.

Parameters:

volume – The Volume to provide a stream for.

volume
runs