本来我的电脑上就装了个 Fedora ,后来发现不用来工作的话 Linux 真是诸事不宜,所以决定装一个 Windows 8.1 。于是我就要缩减 Fedora 的空间。我的硬盘大概是这么划分的:

/dev/sda1 => /boot
/dev/sda2 => vg_centos

LVM:
    vg_centos/lv_root
    vg_centos/lv_home
    vg_centos/lv_swap

当然我要把 lv_home 缩减掉,缩减 Logical Volume 真的很容易,而且很快:

[root@centos ~]# umount /dev/vg_centos/lv_home
[root@centos ~]# lvreduce --resize --size -50G /dev/vg_centos/lv_home
fsck from util-linux-ng 2.17.2
/dev/mapper/vg_centos-lv_home: 11/4890624 files (0.0% non-contiguous), 352957/19548160 blocks
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/mapper/vg_centos-lv_home to 6440960 (4k) blocks.
The filesystem on /dev/mapper/vg_centos-lv_home is now 6440960 blocks long.

  Reducing logical volume lv_home to 24.57 GiB
  Logical volume lv_home successfully resized

然后我要缩减 /dev/sda2 上面的 vg_centos

[root@centos ~]# pvresize -v --setphysicalvolumesize 76.51G /dev/sda2
    Using physical volume(s) on command line
    Archiving volume group "vg_centos" metadata (seqno 5).
    /dev/sda2: Pretending size is 160453099 not 265312256 sectors.
    Resizing volume "/dev/sda2" to 265312256 sectors.
    Resizing physical volume /dev/sda2 from 0 to 19586 extents.
  /dev/sda2: cannot resize to 19586 extents as later ones are allocated.
  0 physical volume(s) resized / 1 physical volume(s) not resized

竟然失败了!后来了解了一下 lvm 才知道原来是因为 /dev/sda2 上末尾的 Physical Extent 已经被分配了,所以无法缩减。具体 PE 是怎么分布的可以这么查看:

[root@centos ~]# pvdisplay -m
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               vg_centos
  PV Size               126.51 GiB / not usable 3.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              32386
  Free PE               12800
  Allocated PE          19586
  PV UUID               aKoPna-pM0d-Ed9Q-HXSB-xsyv-2ona-dEfjhY

  --- Physical Segments ---
  Physical extent 0 to 12799:
    Logical volume      /dev/vg_centos/lv_root
    Logical extents     0 to 12799
  Physical extent 12800 to 19089:
    Logical volume      /dev/vg_centos/lv_home
    Logical extents     0 to 6289
  Physical extent 19090 to 31889:
    FREE
  Physical extent 31890 to 32385:
    Logical volume      /dev/vg_centos/lv_swap
    Logical extents     0 to 495

可以看出来,由于刚刚缩减的是中间的 lv_home ,所以空出来的 PE 就在中间,自然无法缩减。我 Google 了一下,发现在 askubuntu 上面大多是说重建 swap ,觉得好麻烦。不过后来看到一篇pvmove 搞定的文章,觉得这个比较科学,于是就这么做了:

[root@centos ~]# pvmove /dev/sda2:31890-32385 /dev/sda2:19090-31889 --alloc anywhere
  /dev/sda2: Moved: 0.4%
  /dev/sda2: Moved: 45.4%
  /dev/sda2: Moved: 90.3%
  /dev/sda2: Moved: 100.0%

如果是远程的机子的话,还是用 screen 挂着比较保险,移动 2GiB 的空间用了大概一两分钟吧。

然后就可以缩减 pv 了。

[root@centos ~]# pvresize -v --setphysicalvolumesize 76.51G /dev/sda2
    Using physical volume(s) on command line
    Archiving volume group "vg_centos" metadata (seqno 8).
    /dev/sda2: Pretending size is 160453099 not 265312256 sectors.
    Resizing volume "/dev/sda2" to 265312256 sectors.
    Resizing physical volume /dev/sda2 from 0 to 19586 extents.
    Updating physical volume "/dev/sda2"
    Creating volume group backup "/etc/lvm/backup/vg_centos" (seqno 9).
  Physical volume "/dev/sda2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
[root@centos ~]# pvdisplay -m
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               vg_centos
  PV Size               76.51 GiB / not usable 1.24 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              19586
  Free PE               0
  Allocated PE          19586
  PV UUID               aKoPna-pM0d-Ed9Q-HXSB-xsyv-2ona-dEfjhY

  --- Physical Segments ---
  Physical extent 0 to 12799:
    Logical volume      /dev/vg_centos/lv_root
    Logical extents     0 to 12799
  Physical extent 12800 to 19089:
    Logical volume      /dev/vg_centos/lv_home
    Logical extents     0 to 6289
  Physical extent 19090 to 19585:
    Logical volume      /dev/vg_centos/lv_swap
    Logical extents     0 to 495

大功告成,可以装 Windows 了!不得不说 Linux 真的很赞,连磁盘操作都可以在线进行!