update 2022/09/20: 请注意,如果你是 btrfs 用户,请先确认内核版本大于 5.0,然后创建一个非快照子卷并禁用写时复制用于存储交换文件。禁用CoW 的方法是:
# chattr +C /path/to/swapsubvolume
请务必确认这三点:内核版本大于 5.0;新子卷,非快照;禁用写时复制。
另外,下文中提到的 mkinitcpio 是用于 archlinux 的工具,用于制作 initramfs。在不同发行版中默认的使用工具会不同。以 Debian 为例,使用的是 initramfs-tools。你需要修改 /etc/initramfs/initramfs.conf 或者添加配置和钩子到 /etc/initramfs/conf.d 和 /etc/initramfs/conf-hooks.d,然后运行 update-initramfs -u 来重建并更新 initranfs 镜像。无论如何,所要做的就是让系统在引导阶段能够找到交换文件所处的位置,并能读出其中的数据以恢复到休眠前的状态。
同样的,如果你是 btrfs 用户,用 filefrag 得到的 physical_offset 也是不准确的。我非常建议阅读 archwiki 而不是我这篇可能过时的博文。
因为是电骡党,所以笔记本上塞满了各种文件,硬盘又不大,才 500G ,平时只能靠到处删文件才能维持日常的使用。。。。
当时装 Debian 的时候给交换分区划了 8G 空间,之后又加插了 8G 的内存,根本用不着,看着日常几百兆剩余的家目录,我开始觊觎交换空间了。。。。
相比于使用一个磁盘分区作为交换空间,使用交换文件可以更方便地随时调整大小或者移除。当磁盘空间有限(例如常规大小的SSD)时,使用交换文件更加理想。From Archlinux Wiki
首先建一个交换文件,一般使用 root 建在根目录,命名为swapfile:
# fallocate -l 512M /swapfile
fallocate 指令可以让您快速建立一个大文件,大小可以在 -l 后指定,当然也可以用 dd 指令,但讲道理没必要。
交换文件建好后需要修改权限,出于安全考虑,只要给使用者读写权限就可以了:
# chmod 600 /swapfile
之后格式化:
# mkswap /swapfile
最后启用交换文件:
# swapon /swapfile
当然,我的笔记本是要频繁开关机的,最好启动后自动启用交换文件,所以要在 /etc/fstab 中添加魔法语句
# vim /etc/fstab
添加内容:
/swapfile none swap defaults 0 0
如果要删除交换文件,需要先停用:
# swapoff -a
然后用世界闻名的 rm 命令:
# rm -rf /swapfile
不要忘了 /etc/fstab 上写的魔法语句。
看起来很麻烦,有没有自动化的工具?
有一种叫 systemd-swap 的神奇 package,你只要安装它,在 /etc/systemd/swap.conf 中启用 swapfu_enabled=1,然后 enable 一下:
# systemctl enable --now systemd-swap
然后它就开始干活了。。。
我也没用过,详细可见项目的 README.md
我电脑内存很大,要交换空间干啥?事实上,交换空间存在与否会影响系统的部分决策,如果你需要让你的计算机休眠就必须拥有交换空间,而且,内存爆炸的情况下交换空间说不定可以保命。。。。
上面有提休眠,如果使用交换文件休眠,要恢复系统得向内核添加参数 resume_offset=Swap_File_Offset
按我配置的例子:
# filefrag -v /swapfile Filesystem type is: ef53 File size of /swapfile is 536870912 (131072 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 0: 313344.. 313344: 1: 1: 1.. 30719: 313345.. 344063: 30719: unwritten 2: 30720.. 61439: 344064.. 374783: 30720: unwritten 3: 61440.. 92159: 374784.. 405503: 30720: unwritten 4: 92160.. 122879: 405504.. 436223: 30720: unwritten 5: 122880.. 131071: 436224.. 444415: 8192: last,unwritten,eof /swapfile: 1 extent found
得到 Swap_File_Offset 值:313344,对,就是第一行 physical_offset 底下那个值。
之后在 bootloader 中增加resume内核参数(我使用了 grub2):
# vim /etc/default/grub
在 GRUB_CMDLINE_LINUX_DEFAULT 这一条的引号里继续添加 resume=/dev/sda几 (sda几得看交换文件放在哪)和 resume_offset=313344,用空格隔开,看起来可能是这样:
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/sda1 resume_offset=313344"
然后更新 grub 配置:
# grub-mkconfig -o /boot/grub/grub.cfg
然后配置 initramfs的resume钩子:
# vim /etc/mkinitcpio.conf
在 HOOKS 行的 udev autodetect 之间添加 resume,(如果使用 lvm 分区,需要将 resume 放在 lvm 后面)完成后看起来大概是这样:
HOOKS="base udev resume autodetect modconf block filesystems keyboard fsck"
最后重新生成 initramfs 镜像:
mkinitcpio -p linux
重启,然后就可以使用了^_^
PS: systemd-swap 好像不能用于休眠
初版于 2017年11月19日 19:15