Update LVM2Device sizes if the LVM2Device size is smaller than the PhysicalVolume size#61
Update LVM2Device sizes if the LVM2Device size is smaller than the PhysicalVolume size#61
Conversation
…ysicalVolume size
|
@tuttimann I did find a issue in our lvm implementation, I believe this is also the issue you came accross in fox-it/dissect#93 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #61 +/- ##
==========================================
+ Coverage 77.62% 77.73% +0.10%
==========================================
Files 29 29
Lines 2337 2344 +7
==========================================
+ Hits 1814 1822 +8
+ Misses 523 522 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
dissect/volume/lvm/metadata.py
Outdated
| device.size = max(self.dev_size * self.vg.extent_size, device.size) | ||
| else: | ||
| device.size = max(self.pe_start + (self.pe_count * self.vg.extent_size * SECTOR_SIZE), device.size) |
There was a problem hiding this comment.
Shouldn't we change the code that utilizes this size instead of correcting it on the LVM2Device object? Now if you manually inspect the device.size after attaching, its value will not reflect the reality of that's in the header.
There was a problem hiding this comment.
It does seem it updates the pv_header to this size with the pvck tool if it detects this discrepancy. Although, it is correct it doesn't correctly represent what is inside the pv_header that the LVM2Device uses even if that size is wrong / too small.
As an alternative, to avoid misrepresenting the data inside the LVM2Device we could adjust LVM2Device.open to accept a pv_size = 0 by default. So it picks the actual pv_size when opening a LVM2Device.
As it will only read as far as was specified by the LVM2Device while there is more data available.
In code it would look a bit like:
class LVM2Device:
def open(self, pv_size: int = 0):
size = max(pv_size, self.size)
# Use size for opening the stream and specifying the length.
...
class PhysicalVolume:
@property
def size(self):
"""Return the physical volume size in bytes"""
...Where pv.size gets passed to LVM2Device.open inside segment.open()
It takes the pv size of the PhysicalVolume and uses it when opening the device
the size of the LVM2Device has been manually changed. While the test functions as intended, you can't use a loopback device to mount the file itself
dissect/volume/lvm/physical.py
Outdated
|
|
||
| def open(self) -> BinaryIO: | ||
| def open(self, pv_size: int = 0) -> BinaryIO: | ||
| # Use pv_size if the physical |
| if self.dev_size: | ||
| return self.dev_size * self.vg.extent_size | ||
| # The size of the stripes on this device + the offset where it starts | ||
| return (self.pe_start + self.pe_count * self.vg.extent_size) * SECTOR_SIZE |
There was a problem hiding this comment.
Ignorance on my part, but why does the offset factor into the size?
There was a problem hiding this comment.
it is the size of the whole physical device. This includes the metadata that is before this specific region
| @@ -0,0 +1,3 @@ | |||
| version https://git-lfs.github.com/spec/v1 | |||
There was a problem hiding this comment.
Do you have the script used to construct this somewhere?
(could be helpful in the future, no biggie)
There was a problem hiding this comment.
I created a script to create it, and adjusted the tests.
I didn't adjust the crc value of the label header. So this file won't behave like a lvm disk once mounted with losetup
dissect/volume/lvm/metadata.py
Outdated
| def size(self) -> int: | ||
| """Return the size of the physical volume in bytes. | ||
|
|
||
| This can sometimes be larger than what the LVM2Device dictates, but the VolumeGroup overwrites it: |
There was a problem hiding this comment.
As in, the VolumeGroup overrides it?
Maybe change "but" to "in which case"
There was a problem hiding this comment.
Yes, the volume group can override what it actually is it seems.
This seems to be the cause of fox-it/dissect#93
Where it, assumedly, tried to read beyond the LVM2Device disk size where it could not reach.
TODO