记录缩小luks2加密分区
2019-08-27
Ideapad 720s 13arr是去年买来的。当时就已经删掉自带Windows操作系统,把整块SSD盘分给了Archlinux系统。然而想玩Steam游戏的时候,又想起了手上能用的也就这台能安装Windows。安装windows又需要磁盘空间,ssd没有空余空间了。
720s 13arr 自带的是东芝 256G硬盘,换算238.5G可用空间,目前用lsblk命令来看的话
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 238.5G 0 disk
├─nvme0n1p1 259:1 0 260M 0 part /boot
└─nvme0n1p2 259:2 0 238.2G 0 part
└─cryptroot 254:0 0 238.2G 0 crypt /
加密盘cryptroot已经格式化成btrfs了,所以先要做的第一件事就是缩小btrfs分区,缩小前尽量删除文件留下空闲空间。当然,不敢online操作,所以是在U盘的archlinux bootstrap环境。通过 btrfs filesystem usage --raw /
可以看到目前 Device size: 是 255782624768,执行 btrfs filesystem resize -48G /mnt ,由于btrfs cow特性,不知道啥时候真的执行了,等vmstat有大量读写之后再看 btrfs filesystem usage。这时候 Device size: 变成了 204243013632,但是lsblk设备大小还是不变的,接下来要缩小cryptroot设备的大小了,
通过lsblk -b 可以知道当前 cryptroot 的size还是255782624768,nvme0n1p2 是 255786819072,刚好匹配上 cryptsetup status cryptroot里offset sectors 8192跟size sectors 499575439的大小。
然后通过命令 cryptsetup resize cryptroot -b 398912136 缩小luks设备,398912136是通过 上面 204243013632/512,这样的话 cryptsetup status cryptroot 缩小后变成如下信息
type: LUKS2
cipher: aes-xts-plain64
keysize: 256 bits
key location: keyring
device: /dev/nvme0n1p2
sector size: 512
offset: 8192 sectors
size: 398912136 sectors
mode: read/write
flags: discards
接着是要重新分区,先不要急着fdisk重新分区,先备份分区表,fdisk -l 可以记录分区表offset,但是不能记录分区表开头的扇区记录,luks分区开头有signature标记。用dd工具先把分区的头部记录下来 dd if=/dev/nvme0n1 of=./luks2_sig bs=512 skip=534528 count=32768 ,534528 是通过 fdisk -l /dev/nvme0n1 看到的 luks所在分区的起始扇区,就先备份个16M吧。
然后才是fdisk /dev/nvme0n1 ,删除第二个分区会提示signature标记会丢失,上面已经备份分区头了,再重新添加第二个分区,起始扇区一样,最后扇区填 399454855 =((398912136 + 8192 + 534528) - 1)其中398912136是上面缩小luks设备的size sector,8192是offset sectors,534528是第二分区的起始扇区,最后要 -1 是因为fdisk的 end sector是算上本身的。
重新分区后 luks 分区头部的信息会丢失,需要把分区头部写回去 dd if=./luks2_sig of=/dev/nvme0n1 bs=512 seek=534528。
经过重新分区后的lsblk -b 如下
nvme0n1 259:0 0 256060514304 0 disk
├─nvme0n1p1 259:1 0 272629760 0 part /boot
└─nvme0n1p2 259:2 0 204247207936 0 part
└─cryptroot 254:0 0 204243013632 0 crypt /
btrfs check /dev/mapper/cryptroot 没有问题 重新把 mount -t btrfs -o ro /dev/mapper/cryptroot /mnt 检查文件都在,大功告成