When the size of a logical volume is not aligned to the extent size of
the volume group, LVM2 will automatically align it by rounding up[1]:
Rounding up size to full physical extent 29.80 GiB
Rounding up size to full physical extent <3.82 GiB
Since we don't take that into account when we create a new volume or
set the size of an existing one, the size for the whole volume group
will be short by that amount and thus the creation of the last volume
will fail:
Volume group <uuid> has insufficient free space (975 extents): 977 required.
To fix this a new `AlignUp` method is added to the `MountpointCreator`
creator interface. It will align a given size to the requirements of
the implementing container, like e.g. `LVMVolumeGroup`. It is then
used by a new `alignEntityBranch` which takes a size and walks the
entity path, calling `AlignUp` for all entities that implement said
`MountpointCreator` interface; thus the resulting size should fullfil
the alignment requirement for all elements in the path.
NB: `PartitionTable` already had an `AlignUp` method.
Add a corresponding test.
[1]: 8686657664/lib/metadata/metadata.c (L1072)
Co-authored-by: Achilleas Koutsou <achilleas@koutsou.net>
Extract a `CreateLogicalVolume` method from `CreateMountpoint`
and implement the latter via the former. This makes it possible
to create a Logical Volume for an existing payload.
The `LVMVolumeGroup.Clone()` method could end up dereferencing a `nil`
pointer in the `lv` variable, if there would be a `nil` logical volume
in the LVM volume group. Such situation would be an error of its own.
There is no point in checking if the cloned logical volume is not `nil`
and casting it to another variable. The logic should check if the cloned
logical volume is `nil` and panic in such situation. The following code
can then cast the clone to a different variable without issues and there
is no risk of dereferencing a `nil` pointer.
Signed-off-by: Tomáš Hozza <thozza@redhat.com>
In LUKSContainer and LVMLogicalVolume we neglected to clone the Payload
which means we would modify the base PartitionTable when manipulating
the clone.
Re-introduce the VolumeContainer interface but with a different
meaning: it is supposed to be implemented by all container that
contain volumes and as a result have themselves a size, like eg
LVM2, LUKS2 and PartitionTable (the latter is not yet included).
The sole method on the interface for now is MetadataSize, which
should return the metadata for the container itself.
Use that new `VolumeContainer.MetadataSize` method when we up-
date the sizes of elements in `resizeEntitybranch`.
When creating a new logical volume via the `CreateVolume` method,
the logical volume name was left blank. Generate an name based
on the mountpoint.
We will detect collisions for names and will try to correct them
by attaching a suffix. We do give up after 100 attempts though.
Add a simple test for it.
All disk.Entitity types now implement Clone() which should return a
deep copy of the same object. Add the Clone() method to the entity
interface. The return type is Entity, but callers can assume it's
safe to convert back to the original type.
Co-Authored-By: Christian Kellner <christian@kellner.me>
Types to represent LVM2 setups with logical volumes being contained
in volume groups.
LVMVolumeGroup implements the following disk interfaces:
- Entity
- Container
- VolumeContainer
LVMLogicalVolume implements the following disk interfaces:
- Entity
- Container
- Sizeable
Co-Authored-By: Christian Kellner <christian@kellner.me>