从 Manjaro 迁移到 Arch Linux
今天我把系统换成了 Arch Linux,用的是 Btrfs 文件系统,套上 LUKS 加密(加密包括
/boot
)。由于我已经在虚拟机里面实验过整个过程,所以今天的安装过程非常顺利,一共只用了一两个小时。
- 2021-03-25 更新:增加了 redshift 无法使用 geoclue 一节
- 2021-04-18 更新:增加了 将
~/.cache
单独分为一个子卷 一节
背景
前几天用 btrfs-convert
把我的 Manjaro 的文件系统换成了 Btrfs,然后继续开发我的
Btrfs 快照管理工具 dosnap。奇怪的是,在出错的时候(如 panic!
)程序不会退出
,而是直接卡住。这还不是最致命的,过了几秒钟我发现我的 polybar 不见了,然后发现我的家目录里少了一些东西,包括 ~/.config
。还好我之前有做快照,可以直接用
rsync
恢复数据。但是在我的一个 Arch Linux 虚拟机中程序如果出错会正确退出。不知道是为什么,可能是 btrfs-convert
的什么 bug。然后就想到用 Arch 虚拟机也有很长时间了,于是打算直接把物理机也换到 Arch Linux 上来。
备份
可以使用 Btrfs 的 send/receive 功能进行备份。注意备份的移动硬盘也需要是 Btrfs 文件系统。先对各个子卷做只读快照,然后对每个快照进行 btrfs send
:
sudo btrfs send /mnt/_snapshots/${SNAPSHOT_NAME?} | sudo btrfs receive ${EXTERNAL_DRIVE?}
然后再记录一下安装过的软件:
pacman -Qe >${EXTERNAL_DRIVE?}/pacman-qe
安装
启动 archiso,然后调整一下终端字体
setfont ter-v28b
Installation Guide
打开 installation guide,一直做到 Partition the disks 之前。
由于磁盘已经分区,所以不需要再分区了。直接上 LUKS 并格式化为 Btrfs。注意需要用 luks1,因为 GRUB 目前还不支持 LUKS2。
cryptsetup --type luks1 luksFormat /dev/nvme0n1p4
cryptsetup open /dev/nvme0n1p4 archlinux
mkfs.btrfs -L archlinux /dev/mapper/archlinux
然后创建子卷并挂载分区
mount /dev/mapper/archlinux /mnt
btrfs subv create /mnt/@
btrfs subv create /mnt/@home
btrfs subv create /mnt/@opt
btrfs subv create /mnt/@var
umount /mnt
opt='noatime,ssd,space_cache=v2,compress=zstd'
mount -o $opt,subvol=@ /dev/mapper/archlinux /mnt
mkdir /mnt/{efi,var,home,opt}
mount /dev/nvme0n1p1 /mnt/efi
mount -o $opt,subvol=@home /dev/mapper/archlinux /mnt/home
mount -o $opt,subvol=@opt /dev/mapper/archlinux /mnt/opt
mount -o $opt,subvol=@var /dev/mapper/archlinux /mnt/var
对 /var/log/journal
禁用 CoW:
mkdir -p /mnt/var/log/journal
chattr +C /mnt/var/log/journal
然后从 installation guide 的 Installation 一节开始继续一直做到结尾,记得要在 pacstrap
的时候加上 btrfs-progs
。
额外的操作
安装到这里还需一些额外的操作。更改 /etc/mkinitcpio.conf
的 BINARIES
,然后在
HOOKS
中的 filesystems
之前加入 encrypt
:
BINARIES=(/usr/bin/btrfs)
HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)
然后重新生成 initramfs
mkinitcpio -P
更改 /etc/default/grub
中的内核命令行,这里我还顺便打开了 cgroup v2。
PARTUUID
可以使用 blkid
命令查看。
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet systemd.unified_cgroup_hierarchy=1"
GRUB_CMDLINE_LINUX="cryptdevice=PARTUUID=xxx:archlinux"
同步家目录
新建用户,并从备份中用 rsync 把家目录同步回来:
# run as wang
rsync -a ${EXTERNAL_DRIVE?}/home-snap/wang/* ~
rsync -a ${EXTERNAL_DRIVE?}/home-snap/wang/.* ~
安装软件包
安装我自己常用的软件
cd ~/.dotfiles/weirane-dotfiles-deps
makepkg -si
用下面的命令查看有哪些之前安装过而不在本机上的包,然后选择要安装的包并安装。
comm -23 <(cut -d' ' -f1 ${EXTERNAL_DRIVE?}/pacman-qe | sort) \
<(pacman -Qq | sort) | less
配置
下面进行一些增加安全性或者便携性的配置。
加密 swap
为防止关机后 swap 中残留明文的内存数据,需要将 swap 加密。我不需要 hibernation,所以参考 ArchWiki,将以下内容加入 /etc/crypttab
:
swap PARTUUID=xxx /dev/urandom swap,cipher=aes-xts-plain64,size=512
将原来 /etc/fstab
中 swap 的一行改为
/dev/mapper/swap none swap defaults 0 0
Key in initramfs
可以在 initramfs 中放一个 LUKS key,这样在开机的时候就不需要输两次 LUKS 密码了。我一般将 key 放在 /etc
中。注意要调整 key file 和装有 key file 的 initramfs 的权限。
sudo dd bs=512 count=4 if=/dev/urandom of=/path/to/key
sudo cryptsetup luksAddKey /dev/nvme0n1p4 /path/to/key
chmod 000 /path/to/key
chmod -R g-rwx,o-rwx /boot
把 key 加入 /etc/mkinitcpio.conf
中的 FILES
:
FILES=(/path/to/key)
改 /etc/default/grub
中的内核命令行,加入 cryptkey=rootfs:/path/to/key
:
GRUB_CMDLINE_LINUX="cryptdevice=PARTUUID=xxx:archlinux cryptkey=rootfs:/path/to/key"
最后重新生成 initramfs 和 GRUB config
sudo mkinitcpio -P
sudo grub-mkconfig -o /boot/grub/grub.cfg
解决问题
xbacklight
进入图形界面后发现 polybar 中的亮度模块没有显示,xbacklight
命令没有输出。参考
ArchWiki 之后发现应该安装 xf86-video-intel
并将下面的配置写入
/etc/X11/xorg.conf.d/20-xbacklight.conf
:
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "Backlight" "intel_backlight"
EndSection
redshift 无法使用 geoclue
运行 redshift
有如下报错
Trying location provider `geoclue2'...
Using provider `geoclue2'.
Using method `randr'.
Waiting for initial location to become available...
Unable to start GeoClue client: GDBus.Error:org.freedesktop.DBus.Error.AccessDenied: 'redshift' disallowed, no agent for UID 1000.
Access to the current location was denied by GeoClue!
Make sure that location services are enabled and that Redshift is permitted
to use location services. See https://github.com/jonls/redshift#faq for more
information.
Unable to get location from provider.
查阅 ArchWiki,将以下内容写入
~/.config/systemd/user/geoclue-agent.service
[Unit]
Description=redshift needs to get a (geo)clue
[Service]
ExecStart=/usr/lib/geoclue-2.0/demos/agent
[Install]
WantedBy=default.target
运行命令 systemctl --user enable --now geoclue-agent.service
之后就可以使用
redshift 了。
将 ~/.cache
单独分为一个子卷
我现在对我的家目录每两小时进行快照,用了一段时间后发现每个快照都有至少 30 MB 的 exclusive data。比较后发现主要是 ~/.cache
中的数据,所以想把它单独分为一个子卷。
登出当前用户,并在 tty 登陆 root 用户。把 ~/.cache
这个目录空出来,并创建子卷
cd /home/wang
mv .cache .cache2
btrfs subv create /home/wang/.cache
然后把数据复制回来,再恢复权限。
cp -a --reflink .cache2/* .cache
chown wang:wang .cache
rm -r .cache2
分开 ~/.cache
之后每两小时快照的 exclusive data 基本上在 20 MB 之下,效果还可以。
总结
整个过程挺顺利的,现在应该只剩一些之前在 /etc
中的配置没来得及同步了。由于家目录是直接 rsync
过来的,所以所有的数据都还在,家目录中的程序的配置也没有丢失,
firefox 等程序也不需要重新登录或者进行其它的配置。