目录
- 场景描述
- 摘要
- 步骤1:缩小文件系统和逻辑卷(FS 和 LV)
- 附:本节参考资料
- 步骤2:缩小物理卷(PV)
- 附:本节参考资料
- 步骤3:缩小分区(Partition)
- 步骤3:安装 CentOS
- 步骤4:安装 grub 并设置启动菜单
- 附:本节参考资料
场景描述
- 笔记本电脑上一直用的是 Ubuntu 18.04,现在想装 CentOS 8 作为双系统;
- 之前不了解 LVM 也不熟悉分区,Ubuntu 基本上是按照安装引导程序的默认设置安装的,一个分区独占了整块硬盘(460 G 左右);
- 一开始以为非常简单,拿着 CentOS 的 live USB 打算直接安装,但安装引导程序提示没有足够的空间了;
- 大家都推荐用 GParted 来缩小分区,但是试了一下,没成功。
摘要
经过前后两三天的倒腾,终于成功装好。各个步骤如下:
- 重新划分硬盘分区。为此,需要依次缩小现有的文件系统(file system)、逻辑卷(logical volume)、物理卷(physical volume)和分区(partition),实际只用了3步,因为文件系统和逻辑卷是同时缩小的;
- 新建分区,在新分区上安装 CentOS。此时开机会自动 boot 到 CentOS,Ubuntu 回不去了;
- 使用 live USB 为 Ubuntu 重新安装 grub 并修改参数,最终实现可以通过开机 grub 菜单选择进入 Ubuntu 或者 CentOS 系统。
步骤1:缩小文件系统和逻辑卷(FS 和 LV)
使用 lsblk
命令可以清楚地看到硬盘的分区情况,并且也看到我的 Ubuntu 是建立在逻辑卷上的(TYPE
列为 lvm
):
doudou@doudou-Aspire-E1-471G:~$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
(...)
sda 8:0 0 465.8G 0 disk
└─sda1 8:1 0 465.8G 0 part
├─ubuntu--vg-root 253:2 0 464.8G 0 lvm /
└─ubuntu--vg-swap_1 253:3 0 976M 0 lvm
使用 df
命令查看 Ubuntu 系统所占空间大小和剩余空间:
doudou@doudou-Aspire-E1-471G:~$ df -h
Filesystem Size Used Avail Use% Mounted on
(...)
/dev/mapper/ubuntu--vg-root 465G 9.8G 455G 3% /
可以看到 ubuntu--vg-root
逻辑卷实际只占了 9.8 G 空间。下面缩小 ubuntu--vg-root
逻辑卷,为安装 CentOS腾出空间。
使用 lvreduce
命令缩小逻辑卷 ubuntu--vg-root
的大小,其中 --resizefs
标识是说,在缩小逻辑卷的同时也缩小文件系统,--size -350G
表示缩小 350 G。
doudou@doudou-Aspire-E1-471G:~$ sudo lvreduce --resizefs --size -350G /dev/ubuntu-vg/root
Do you want to unmount "/" ? [Y|n] n
fsadm: Cannot proceed with mounted filesystem "/".
/sbin/fsadm failed: 1
Filesystem resize failed.
shell 提示在文件系统挂载的情况下,是无法改变文件系统大小的(逻辑卷大小是可以改的),不过在系统运行时显然是不能卸载 /
的(虽然我还没试过在上面选 y
…)。
因此,这一步需要使用 live USB 进行,找一个 Ubuntu 的镜像写入 USB(如果是 mac,推荐 balenaEtcher 这个工具),然后使用 USB 引导系统,选择 “Try Ubuntu”,然后打开命令行,重复上面的命令:
ubuntu@ubuntu:~$ sudo lvreduce --resizefs --size -350G /dev/ubuntu-vg/root
这一次应该就能顺利完成了,检查一下:
ubuntu@ubuntu:~$ sudo lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
root centos-vg -wi-a----- 114.80g
swap centos-vg -wi-a----- 976.00m
附:本节参考资料
如果不太了解 LVM,推荐下面这两篇文章,能够快速理解 LVM 的概念:
这一步骤的相关命令来自 How do I shrink the root logical volume (LV) on LVM?
步骤2:缩小物理卷(PV)
上一步只是缩小了逻辑卷的大小,如果使用 vgs
命令展示逻辑卷组信息,会发现逻辑卷组的大小还是没变:
ubuntu@ubuntu:~$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ubuntu-vg 1 2 0 wz--n- <465.80g 350.24g
使用 pvs
展示物理卷信息:
ubuntu@ubuntu:~$ sudo pvs
PV VG Fmt Attr PSize PFree
/dev/sda1 ubuntu-vg lvm2 a-- <465.80g 350.24g
这个时候如果直接缩小分区,还是会造成数据损失(事实上我就是在这一步直接缩小分区了,后来连 CentOS 都装好了,但命令行只要涉及分区或者 LVM 的操作都在提示 Warning
信息,促使我发现了这个问题,缩小了物理卷之后就好了,并且我很侥幸地居然没有造成数据损失)。
下面使用 pvresize
来缩小物理卷, --setphysicalvolumesize 128G
将物理卷大小设置为 128 G:
ubuntu@ubuntu:~$ sudo pvresize --setphysicalvolumesize 128G /dev/sda1
但是这里会遇到 /dev/sda1: cannot resize to xxxxx extents as later ones are allocated.
错误。通过 pvs
的 --segments
标识可以直观地看到原因:
ubuntu@ubuntu:~$ sudo pvs -v --segments /dev/sda1
PV VG Fmt Attr PSize PFree Start SSize LV Start Type PE Ranges
/dev/sda1 ubuntu-vg lvm2 a-- <465.80g 350.24g 0 xxxx root 0 linear /dev/sda1:0-(xxxx-1)
/dev/sda1 ubuntu-vg lvm2 a-- <465.80g 350.24g xxxx yyyy 0 free
/dev/sda1 ubuntu-vg lvm2 a-- <465.80g 350.24g zzzz 244 swap_1 0 linear /dev/sda1:zzzz-jjjj
中间具体的数值我忘记了,用 xxxx
、yyyy
、zzzz
和 jjjj
替代。
总之,问题在于刚才缩小 root
逻辑卷所空余出来的空间在 swap_1
逻辑卷所占空间之前,而缩小物理卷只能从后缩小,会发现后面的空间其实是被 swap_1
占着呢,所以报错了。
可以用 pvmove
命令来移动 PE,解决这个问题,其中的 /dev/sda1:zzzz-jjjj
对应的就是 swap_1
的区间:
sudo pvmove --alloc anywhere /dev/sda1:zzzz-jjjj
根据我找到的参考资料,这样做应该能够解决问题,但在我的情况下还是报错。在尝试了很久未果之后,无奈我只好索性删除并重新创建了 swap_1
逻辑卷,反正交换空间里也没有数据。重新创建的 swap_1
逻辑卷(名字不能变,/etc/fstab
靠这个名字挂载)就自动接在 root
逻辑卷之后了。
(后来我第二次遇到了同样的问题,使用上面的 pvmove
命令就成功解决了。)
这个问题解决之后,重新运行上面的 sudo pvresize --setphysicalvolumesize 128G /dev/sda1
命令,即可缩小物理卷。
现在使用 vgs
命令可以看到:
ubuntu@ubuntu:~$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
ubuntu-vg 1 2 0 wz--n- <128.00g 65.24g
附:本节参考资料
How to reduce Volume Group size in LVM?
步骤3:缩小分区(Partition)
这一步就比较简单了,使用 Ubuntu live USB 里自带的 GParted 工具可以很直观地改变分区大小。
在我的例子里,上面已经提到,我在分区前忘了缩小物理卷,所以这一步使用 GParted 分区会报错,而且我当时没有找到问题。于是我使用 fdisk
命令强行进行了缩小分区,成功是成功了,但也导致了后面装好 CentOS 之后的 Warning
提示。好在最后问题还是得到了解决。
步骤3:安装 CentOS
这一步也没什么好说的,不过感觉 CentOS 的安装引导程序比较难用。
还有,CentOS竟然要求 /boot
不能使用 LVM 分区,于是还得单独为 /boot
划分一个分区。最后的分区变成了这样:
ubuntu@ubuntu:~$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
(...)
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 128G 0 part
│ ├─ubuntu--vg-root 253:2 0 114.8G 0 lvm /
│ └─ubuntu--vg-swap_1 253:3 0 976M 0 lvm
├─sda2 8:2 0 300M 0 part
└─sda3 8:3 0 115.8G 0 part
├─centos--vg-root 253:0 0 114.8G 0 lvm
└─centos--vg-swap 253:1 0 976M 0 lvm
步骤4:安装 grub 并设置启动菜单
CentOS 是装好了,但现在开机就自动引导到了 CentOS,Ubuntu 连影都见不着了。
下面还是需要借助 Ubuntu 的 live USB,首先挂载 Ubuntu 的文件系统:
ubuntu@ubuntu:~$ sudo mount /dev/mapper/ubuntu--vg-root /mnt/
上面这个命令将 Ubuntu 的文件系统挂载到了 /mnt
,也就是说,现在的 /mnt/
目录下就是之前在 Ubuntu 系统上的 /
下的内容了。
安装 grub:
ubuntu@ubuntu:~$ sudo grub-install –-root-directory=/mnt/ /dev/sda
现在重启计算机,从硬盘引导。但在我的例子中,开机时还是没有出现 grub 菜单,直接跳到了 CentOS…
别着急,下面还是借助 Ubuntu 的 live USB,按照上面的方法挂载 Ubuntu 的文件系统到 /mnt
下,然后修改 /etc/default/grub
文件:
ubuntu@ubuntu:~$ sudo vi /mnt/etc/default/grub
将下面两项:
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
修改为:
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10
再次重启计算机,可以在 grub 菜单上选择引导系统了,大功告成!