Let's assume you've an LVM2 physical volume on the
/dev/sdb1
partition. The PE size is the usual 4MB (4194304 bytes) and the PV size displayed by
pvdisplay
is: 465.76 GiB / not usable 544.50 KiB. You take a look at how this space is distributed by running
pvdisplay -m --units b /dev/sdb1
and get ...
--- Physical volume ---
PV Name /dev/sdb1
VG Name vol01
PV Size 465.76 GiB / not usable 544.50 KiB
Allocatable yes
PE Size 4.00 MiB
Total PE 119234
Free PE 54858
Allocated PE 64376
PV UUID gdcshK-QPvL-3wiw-bWyY-FdO4-tr5N-gV78Op
--- Physical Segments ---
Physical extent 0 to 25599:
FREE
Physical extent 25600 to 89975:
Logical volume /dev/vol01/vm
Logical extents 114824 to 179199
Physical extent 89976 to 119233:
FREE
Let's try to get rid of the free space at the end of the PV. We see that the extents in the range 0 - 89975 are allocated, thus 89976 extents are in use. With a 4 MB extent size that's
89976 * 4194304 = 377386696704
bytes. Let's try to set the PV size to this:
# pvresize -v --setphysicalvolumesize 377386696704B /dev/sdb1
Using physical volume(s) on command line
Archiving volume group "vol01" metadata (seqno 26).
/dev/sdb1: Pretending size is 737083392 not 976766017 sectors.
Resizing physical volume /dev/sdb1 from 119234 to 89975 extents.
/dev/sdb1: cannot resize to 89975 extents as later ones are allocated.
0 physical volume(s) resized / 1 physical volume(s) not resized
What??? What the hell is going on here?
The answer is pretty simple, but both
pvdisplay
and
pvresize
"forget" to mention it: metadata.
The physical volume has some metadata on it which obviously requires some space. Now the "PV Size" (as reported by
pvdisplay
) must provide enough space for both the PV extents and the PV metadata. The latter can be checked on with
pvck
:
# pvck /dev/sdb1
Found label on /dev/sdb1, sector 1, type=LVM2 001
Found text metadata area: offset=4096, size=192512
So there's a 188 KB metadata section in our PV that we've to consider when we set/determine the PV size!
But the truth is not that simple.
I tried to decrease my PV's size gradually to find the smallest size it'd allow me to set.
When I was closing in on the limit, I hit something strange.
The following command still worked as expected:
# pvresize -v --setphysicalvolumesize 377387223040B /dev/sdb1
Using physical volume(s) on command line
Archiving volume group "vol01" metadata (seqno 33).
/dev/sdb1: Pretending size is 737084420 not 737085420 sectors.
No change to size of physical volume /dev/sdb1.
Resizing volume "/dev/sdb1" to 737084036 sectors.
Updating physical volume "/dev/sdb1"
Creating volume group backup "/etc/lvm/backup/vol01" (seqno 34).
Physical volume "/dev/sdb1" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
# pvdisplay -m --units b /dev/sdb1
--- Physical volume ---
PV Name /dev/sdb1
VG Name vol01
PV Size 377387026432 B / not usable 329728 B
Allocatable yes
PE Size 4194304 B
Total PE 89976
Free PE 25600
Allocated PE 64376
PV UUID gdcshK-QPvL-3wiw-bWyY-FdO4-tr5N-gV78Op
--- Physical Segments ---
Physical extent 0 to 25599:
FREE
Physical extent 25600 to 89975:
Logical volume /dev/vol01/vm
Logical extents 114824 to 179199
If I substract the not usable part from the total PV Size, I get the Total PE size:
377387026432 - 329728 = 377386696704 = 89976 * 4194304
. So far so good. (Although if you look carefully enough you'll see that I specified 377387223040 bytes for the new PV size and
pvdisplay
reported 377387026432 bytes. I guess
pvresize
rounds up or down the size specified on the commandline to a value that is close to a multiple of the PE Size + the metadata.)
But the next try resulted in something weird:
# pvresize -v --setphysicalvolumesize 377386895360B /dev/sdb1
Using physical volume(s) on command line
Archiving volume group "vol01" metadata (seqno 34).
/dev/sdb1: Pretending size is 737083780 not 737084036 sectors.
No change to size of physical volume /dev/sdb1.
Resizing volume "/dev/sdb1" to 737083396 sectors.
Updating physical volume "/dev/sdb1"
Creating volume group backup "/etc/lvm/backup/vol01" (seqno 35).
Physical volume "/dev/sdb1" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
# pvdisplay -m --units b /dev/sdb1
--- Physical volume ---
PV Name /dev/sdb1
VG Name vol01
PV Size 377386893312 B / not usable 194560 B
Allocatable yes
PE Size 4194304 B
Total PE 89976
Free PE 25600
Allocated PE 64376
PV UUID gdcshK-QPvL-3wiw-bWyY-FdO4-tr5N-gV78Op
--- Physical Segments ---
Physical extent 0 to 25599:
FREE
Physical extent 25600 to 89975:
Logical volume /dev/vol01/vm
Logical extents 114824 to 179199
Now substracting 194560 from 377386893312 results in 377386698752, which would stand for 89976.000488281 extents.
Or going the other way around: substract 377386696704 from 377386893312 and you get 196608 ... which is exactly 2 KB more than the
pvdisplay
reported unused area. Strange.
And if that was not enough ...
This time I tried to grow the PV:
# pvresize -v --setphysicalvolumesize 377386954752B /dev/sdb1
Using physical volume(s) on command line
Archiving volume group "vol01" metadata (seqno 35).
/dev/sdb1: Pretending size is 737083896 not 737083396 sectors.
No change to size of physical volume /dev/sdb1.
Resizing volume "/dev/sdb1" to 737083512 sectors.
Updating physical volume "/dev/sdb1"
Creating volume group backup "/etc/lvm/backup/vol01" (seqno 36).
Physical volume "/dev/sdb1" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
# pvdisplay -m /dev/sdb1 --units b
--- Physical volume ---
PV Name /dev/sdb1
VG Name vol01
PV Size 377386893312 B / not usable 135168 B
Allocatable yes
PE Size 4194304 B
Total PE 89976
Free PE 25600
Allocated PE 64376
PV UUID gdcshK-QPvL-3wiw-bWyY-FdO4-tr5N-gV78Op
--- Physical Segments ---
Physical extent 0 to 25599:
FREE
Physical extent 25600 to 89975:
Logical volume /dev/vol01/vm
Logical extents 114824 to 179199
The reported PV Size remained the same
and the not usable area shrunk. I guess there's some magic here at works ...
If we go back to the PV Size vs. Total PE size difference (i.e.
377386893312 - 377386696704 = 196608
) and compare this with the
pvck
output, we can probably assume that this is due to the 192512 byte metadata section which starts at offset=4096, so 192512 + 4096 = 196608.
It'd be interesting to see how the
not usable value is calculated by
pvdisplay
. From "outside" it certainly seems to be buggy.
To summarize what I've learned today about shrinking a PV:
- first run
pvdisplay -m
to get the PE Size and the last allocated/mapped PE number
- then run
pvck
to get the size of the metadata (and include the offset of the metadata too!)
- then calculate the new PV Size by:
Min. PV Size = (<last allocated PE number> + 1) * <PE Size> + <metadata size>
- then set the PV size by executing
pvresize -v --setphysicalvolumesize ...
P.S.: running
pvs
gives confirmation about the above assumptions.
# pvs --units b -o pv_all /dev/sdb1
1st PE PSize PFree Used Attr PE Alloc PV Tags #PMda
196608B 377386696704B 107374182400B 270012514304B a- 89976 64376 1
Comments
Thanks.. this was a simple
I was unlucky.. I wanted to resize to move some free space out of the pv, from the *start* of the lvm.. not knowing back then, this would be a problem, given one can "shuffle space within the lvm" pretty easily.... SIGH.... huge disappointment as I want to carve out 10 gb, out of hundreds of gigs... ffooobarrr ,)