dd if=/dev/zero of=image.img bs=512 count=$(( 4 * 1024 * 2 ))
sudo losetup /dev/loop1 image.img
sudo pvcreate /dev/loop1
sudo vgcreate vg_test /dev/loop1
sudo lvcreate --name lv_test1 vg_test
sudo losetup -d /dev/loop1
This page hosts a formal specification of Logical Volume Manager version 2 using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
import kaitai_struct_nim_runtime
import options
type
Lvm2* = ref object of KaitaiStruct
`pv`*: Lvm2_PhysicalVolume
`parent`*: KaitaiStruct
`sectorSizeInst`: int
`sectorSizeInstFlag`: bool
Lvm2_PhysicalVolume* = ref object of KaitaiStruct
`emptySector`*: seq[byte]
`label`*: Lvm2_PhysicalVolume_Label
`parent`*: Lvm2
Lvm2_PhysicalVolume_Label* = ref object of KaitaiStruct
`labelHeader`*: Lvm2_PhysicalVolume_Label_LabelHeader
`volumeHeader`*: Lvm2_PhysicalVolume_Label_VolumeHeader
`parent`*: Lvm2_PhysicalVolume
Lvm2_PhysicalVolume_Label_LabelHeader* = ref object of KaitaiStruct
`signature`*: seq[byte]
`sectorNumber`*: uint64
`checksum`*: uint32
`labelHeader`*: Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader
`parent`*: Lvm2_PhysicalVolume_Label
Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader* = ref object of KaitaiStruct
`dataOffset`*: uint32
`typeIndicator`*: seq[byte]
`parent`*: Lvm2_PhysicalVolume_Label_LabelHeader
Lvm2_PhysicalVolume_Label_VolumeHeader* = ref object of KaitaiStruct
`id`*: string
`size`*: uint64
`dataAreaDescriptors`*: seq[Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor]
`metadataAreaDescriptors`*: seq[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor]
`parent`*: Lvm2_PhysicalVolume_Label
Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor* = ref object of KaitaiStruct
`offset`*: uint64
`size`*: uint64
`parent`*: Lvm2_PhysicalVolume_Label_VolumeHeader
`dataInst`: string
`dataInstFlag`: bool
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor* = ref object of KaitaiStruct
`offset`*: uint64
`size`*: uint64
`parent`*: Lvm2_PhysicalVolume_Label_VolumeHeader
`rawDataInst`*: seq[byte]
`dataInst`: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea
`dataInstFlag`: bool
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea* = ref object of KaitaiStruct
`header`*: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader
`parent`*: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader* = ref object of KaitaiStruct
`checksum`*: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader
`signature`*: seq[byte]
`version`*: uint32
`metadataAreaOffset`*: uint64
`metadataAreaSize`*: uint64
`rawLocationDescriptors`*: seq[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor]
`parent`*: KaitaiStruct
`metadataInst`: seq[byte]
`metadataInstFlag`: bool
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor* = ref object of KaitaiStruct
`offset`*: uint64
`size`*: uint64
`checksum`*: uint32
`flags`*: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor_RawLocationDescriptorFlags
`parent`*: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor_RawLocationDescriptorFlags* = enum
raw_location_ignored = 1
proc read*(_: typedesc[Lvm2], io: KaitaiStream, root: KaitaiStruct, parent: KaitaiStruct): Lvm2
proc read*(_: typedesc[Lvm2_PhysicalVolume], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2): Lvm2_PhysicalVolume
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume): Lvm2_PhysicalVolume_Label
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label): Lvm2_PhysicalVolume_Label_LabelHeader
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_LabelHeader): Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label): Lvm2_PhysicalVolume_Label_VolumeHeader
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader], io: KaitaiStream, root: KaitaiStruct, parent: KaitaiStruct): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor
proc sectorSize*(this: Lvm2): int
proc data*(this: Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor): string
proc data*(this: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea
proc metadata*(this: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader): seq[byte]
##[
### Building a test file
```
dd if=/dev/zero of=image.img bs=512 count=$(( 4 * 1024 * 2 ))
sudo losetup /dev/loop1 image.img
sudo pvcreate /dev/loop1
sudo vgcreate vg_test /dev/loop1
sudo lvcreate --name lv_test1 vg_test
sudo losetup -d /dev/loop1
```
@see <a href="https://github.com/libyal/libvslvm/blob/main/documentation/Logical%20Volume%20Manager%20(LVM)%20format.asciidoc">Source</a>
]##
proc read*(_: typedesc[Lvm2], io: KaitaiStream, root: KaitaiStruct, parent: KaitaiStruct): Lvm2 =
template this: untyped = result
this = new(Lvm2)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
Physical volume
]##
let pvExpr = Lvm2_PhysicalVolume.read(this.io, this.root, this)
this.pv = pvExpr
proc sectorSize(this: Lvm2): int =
if this.sectorSizeInstFlag:
return this.sectorSizeInst
let sectorSizeInstExpr = int(512)
this.sectorSizeInst = sectorSizeInstExpr
this.sectorSizeInstFlag = true
return this.sectorSizeInst
proc fromFile*(_: typedesc[Lvm2], filename: string): Lvm2 =
Lvm2.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2): Lvm2_PhysicalVolume =
template this: untyped = result
this = new(Lvm2_PhysicalVolume)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
let emptySectorExpr = this.io.readBytes(int(Lvm2(this.root).sectorSize))
this.emptySector = emptySectorExpr
let labelExpr = Lvm2_PhysicalVolume_Label.read(this.io, this.root, this)
this.label = labelExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume], filename: string): Lvm2_PhysicalVolume =
Lvm2_PhysicalVolume.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume): Lvm2_PhysicalVolume_Label =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
let labelHeaderExpr = Lvm2_PhysicalVolume_Label_LabelHeader.read(this.io, this.root, this)
this.labelHeader = labelHeaderExpr
let volumeHeaderExpr = Lvm2_PhysicalVolume_Label_VolumeHeader.read(this.io, this.root, this)
this.volumeHeader = volumeHeaderExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label], filename: string): Lvm2_PhysicalVolume_Label =
Lvm2_PhysicalVolume_Label.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label): Lvm2_PhysicalVolume_Label_LabelHeader =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_LabelHeader)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
let signatureExpr = this.io.readBytes(int(8))
this.signature = signatureExpr
##[
The sector number of the physical volume label header
]##
let sectorNumberExpr = this.io.readU8le()
this.sectorNumber = sectorNumberExpr
##[
CRC-32 for offset 20 to end of the physical volume label sector
]##
let checksumExpr = this.io.readU4le()
this.checksum = checksumExpr
let labelHeaderExpr = Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader.read(this.io, this.root, this)
this.labelHeader = labelHeaderExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader], filename: string): Lvm2_PhysicalVolume_Label_LabelHeader =
Lvm2_PhysicalVolume_Label_LabelHeader.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_LabelHeader): Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
The offset, in bytes, relative from the start of the physical volume label header where data is stored
]##
let dataOffsetExpr = this.io.readU4le()
this.dataOffset = dataOffsetExpr
let typeIndicatorExpr = this.io.readBytes(int(8))
this.typeIndicator = typeIndicatorExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader], filename: string): Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader =
Lvm2_PhysicalVolume_Label_LabelHeader_LabelHeader.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label): Lvm2_PhysicalVolume_Label_VolumeHeader =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
Contains a UUID stored as an ASCII string. The physical volume identifier can be used to uniquely identify a physical volume. The physical volume identifier is stored as: 9LBcEB7PQTGIlLI0KxrtzrynjuSL983W but is equivalent to its formatted variant: 9LBcEB-7PQT-GIlL-I0Kx-rtzr-ynju-SL983W, which is used in the metadata.
]##
let idExpr = encode(this.io.readBytes(int(32)), "ascii")
this.id = idExpr
##[
Physical Volume size. Value in bytes
]##
let sizeExpr = this.io.readU8le()
this.size = sizeExpr
##[
The last descriptor in the list is terminator and consists of 0-byte values.
]##
block:
var i: int
while true:
let it = Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor.read(this.io, this.root, this)
this.dataAreaDescriptors.add(it)
if ((it.size != 0) and (it.offset != 0)) :
break
inc i
block:
var i: int
while true:
let it = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor.read(this.io, this.root, this)
this.metadataAreaDescriptors.add(it)
if ((it.size != 0) and (it.offset != 0)) :
break
inc i
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader =
Lvm2_PhysicalVolume_Label_VolumeHeader.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
The offset, in bytes, relative from the start of the physical volume
]##
let offsetExpr = this.io.readU8le()
this.offset = offsetExpr
##[
Value in bytes. Can be 0. [yellow-background]*Does this represent all remaining available space?*
]##
let sizeExpr = this.io.readU8le()
this.size = sizeExpr
proc data(this: Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor): string =
if this.dataInstFlag:
return this.dataInst
if this.size != 0:
let pos = this.io.pos()
this.io.seek(int(this.offset))
let dataInstExpr = encode(this.io.readBytes(int(this.size)), "ascii")
this.dataInst = dataInstExpr
this.io.seek(pos)
this.dataInstFlag = true
return this.dataInst
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor =
Lvm2_PhysicalVolume_Label_VolumeHeader_DataAreaDescriptor.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
The offset, in bytes, relative from the start of the physical volume
]##
let offsetExpr = this.io.readU8le()
this.offset = offsetExpr
##[
Value in bytes
]##
let sizeExpr = this.io.readU8le()
this.size = sizeExpr
proc data(this: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea =
if this.dataInstFlag:
return this.dataInst
if this.size != 0:
let pos = this.io.pos()
this.io.seek(int(this.offset))
let rawDataInstExpr = this.io.readBytes(int(this.size))
this.rawDataInst = rawDataInstExpr
let rawDataInstIo = newKaitaiStream(rawDataInstExpr)
let dataInstExpr = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea.read(rawDataInstIo, this.root, this)
this.dataInst = dataInstExpr
this.io.seek(pos)
this.dataInstFlag = true
return this.dataInst
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor =
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor.read(newKaitaiFileStream(filename), nil, nil)
##[
According to `[REDHAT]` the metadata area is a circular buffer. New metadata is appended to the old metadata and then the pointer to the start of it is updated. The metadata area, therefore, can contain copies of older versions of the metadata.
]##
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataAreaDescriptor): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
let headerExpr = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader.read(this.io, this.root, this)
this.header = headerExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea =
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea.read(newKaitaiFileStream(filename), nil, nil)
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader], io: KaitaiStream, root: KaitaiStruct, parent: KaitaiStruct): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
CRC-32 for offset 4 to end of the metadata area header
]##
let checksumExpr = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader.read(this.io, this.root, this)
this.checksum = checksumExpr
let signatureExpr = this.io.readBytes(int(16))
this.signature = signatureExpr
let versionExpr = this.io.readU4le()
this.version = versionExpr
##[
The offset, in bytes, of the metadata area relative from the start of the physical volume
]##
let metadataAreaOffsetExpr = this.io.readU8le()
this.metadataAreaOffset = metadataAreaOffsetExpr
let metadataAreaSizeExpr = this.io.readU8le()
this.metadataAreaSize = metadataAreaSizeExpr
##[
The last descriptor in the list is terminator and consists of 0-byte values.
]##
block:
var i: int
while true:
let it = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor.read(this.io, this.root, this)
this.rawLocationDescriptors.add(it)
if ((it.offset != 0) and (it.size != 0) and (it.checksum != 0)) :
break
inc i
proc metadata(this: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader): seq[byte] =
if this.metadataInstFlag:
return this.metadataInst
let pos = this.io.pos()
this.io.seek(int(this.metadataAreaOffset))
let metadataInstExpr = this.io.readBytes(int(this.metadataAreaSize))
this.metadataInst = metadataInstExpr
this.io.seek(pos)
this.metadataInstFlag = true
return this.metadataInst
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader =
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader.read(newKaitaiFileStream(filename), nil, nil)
##[
The data area size can be 0. It is assumed it represents the remaining available data.
]##
proc read*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor], io: KaitaiStream, root: KaitaiStruct, parent: Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor =
template this: untyped = result
this = new(Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor)
let root = if root == nil: cast[Lvm2](this) else: cast[Lvm2](root)
this.io = io
this.root = root
this.parent = parent
##[
The data area offset, in bytes, relative from the start of the metadata area
]##
let offsetExpr = this.io.readU8le()
this.offset = offsetExpr
##[
data area size in bytes
]##
let sizeExpr = this.io.readU8le()
this.size = sizeExpr
##[
CRC-32 of *TODO (metadata?)*
]##
let checksumExpr = this.io.readU4le()
this.checksum = checksumExpr
let flagsExpr = Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor_RawLocationDescriptorFlags(this.io.readU4le())
this.flags = flagsExpr
proc fromFile*(_: typedesc[Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor], filename: string): Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor =
Lvm2_PhysicalVolume_Label_VolumeHeader_MetadataArea_MetadataAreaHeader_RawLocationDescriptor.read(newKaitaiFileStream(filename), nil, nil)