lvmteam / lvm2

Mirror of upstream LVM2 repository
https://gitlab.com/lvmteam/lvm2
GNU General Public License v2.0
133 stars 73 forks source link

wrong dev_size after pvresize #158

Closed frostschutz closed 2 months ago

frostschutz commented 2 months ago

For some reason after pvresize the dev_size comes out wrong and pvdisplay shows "not usable 1.00 MiB" even though it is in use.

Create a test VG:

# lsblk /dev/loop0
NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0   7:0    0  17M  0 loop
# vgcreate test /dev/loop0
  Physical volume "/dev/loop0" successfully created.
  Volume group "test" successfully created
# pvdisplay /dev/loop0
  --- Physical volume ---
  PV Name               /dev/loop0
  VG Name               test
  PV Size               17.00 MiB / not usable 0
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              4
  Free PE               4
  Allocated PE          0
  PV UUID               dpW8Hm-89uy-ZV10-xbeI-q56j-1ocZ-76VQIa
# cp /etc/lvm/backup/test test.good

Use pvresize on it (17M -> 15M -> 17M):

pvresize /dev/loop0 --setphysicalvolumesize 15M
pvresize /dev/loop0

Result:

# pvdisplay /dev/loop0
  --- Physical volume ---
  PV Name               /dev/loop0
  VG Name               test
  PV Size               17.00 MiB / not usable 1.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              4
  Free PE               4
  Allocated PE          0
  PV UUID               dpW8Hm-89uy-ZV10-xbeI-q56j-1ocZ-76VQIa
# cp /etc/lvm/backup/test test.bad
# diff -U 100 test.good test.bad
[…]
    physical_volumes {

        pv0 {
            id = "dpW8Hm-89uy-ZV10-xbeI-q56j-1ocZ-76VQIa"
            device = "/dev/loop0"   # Hint only

            status = ["ALLOCATABLE"]
            flags = []
-           dev_size = 34816    # 17 Megabytes
+           dev_size = 32768    # 16 Megabytes
            pe_start = 2048
            pe_count = 4    # 16 Megabytes
        }
    }

So for some reason the dev_size is recorded as 16M but it still uses 16M in physical extents plus 1M in metadata.

pvresize -v shows the correct dev_size 34816 sectors but then says "No change".

# pvresize -v /dev/loop0
  Resizing volume "/dev/loop0" to 34816 sectors.
  No change to size of physical volume /dev/loop0.
  Updating physical volume "/dev/loop0"
  Archiving volume group "test" metadata (seqno 5).
  Physical volume "/dev/loop0" changed
  Creating volume group backup "/etc/lvm/backup/test" (seqno 6).
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
zkabelac commented 2 months ago

There is no problem as such - dev_size present usable volume size rounded to 'extent' after 'pvresize. You still have 4 extents (pe_count).

Theoretically lvm2 could write 'full' size - but there is no bug - 'dev_size' just needs to fit into 'physical' device .

frostschutz commented 2 months ago

It's confusing, if nothing else. The message "not usable X" suggests you can reduce the device size by X. But if you actually did that, you'd have killed the last PE and lost data, since it's actually in use. Now if you want to align partition size to LVM you have to do your own math instead of relying on lvm.

zkabelac commented 2 months ago

Well it's more confusing since there is PV VG LV. 'Extent size' is a property that is set by 'vgcreate' - so 'standalone' pvcreate can use 'all the space' since at that moment it's not known how much space will be 'used'.

So in this case - if there would be NO vg - the 'pvresize' would restore full size. However when there is known 'extent_size' with the VG - 'pvresize' will resize to the 'necessary' minimal usable size.

Basically there are some valid reasons for this logic.

It would be probably much better to disclose and how lvm2 can emit something more usable for your case.

Also you really should be using 'pvs -o+xxxxx' with more flags for easy 'parsing' - instead of getting things out of 'pvdisplay'

For 'real' physical device size - you should use 'blockdev --getsize64' or 'pvs -o+dev_size'