是否可以仅重新启动用户空间?比如关闭内核之前的所有内容,然后从 PID 1 重新启动?
我想对我的根 btrfs 文件系统进行快照,并在该快照上快速启动。
答案1
您可能受到 macOSlaunchctl reboot userspace
功能的启发;遗憾的是systemd
缺少此功能(systemd
可以使用 重新启动自身systemctl daemon-reexec
,但这不会终止所有子项),但是reboot userspace
通过使用kexec
Linux 内核的功能,您可以获得比 macOS 更好的结果。
它的作用是终止所有用户空间进程以及所有内核线程,然后重新启动当前加载的(甚至用户指定的备用)内核,从而有效地从引导加载程序将初始化传递给内核的那一刻开始,减去通过重新启动所需的硬件重置阶段。
来自kexec(8)
手册页:
DESCRIPTION
kexec is a system call that enables you to load and boot into another
kernel from the currently running kernel. kexec performs the function
of the boot loader from within the kernel. The primary difference be‐
tween a standard system boot and a kexec boot is that the hardware ini‐
tialization normally performed by the BIOS or firmware (depending on
architecture) is not performed during a kexec boot. This has the effect
of reducing the time required for a reboot.
有一个红宝石脚本kexec
如果您不想学习 kexec 参数,它可以简化使用,它会解析 grub 配置文件并允许您选择甚至不同的内核,但请注意,它似乎不理解 Fedora 的新功能引导加载程序规范kexec
配置文件,在这种情况下,您必须使用裸工具执行操作。
作为参考,以下是在 EFI 上的 Ubuntu 22.04 上运行 kexec-reboot 的输出
$ sudo kexec-reboot -iv
Read GRUB configuration from /boot/grub/grub.cfg
Select a kernel to stage:
1: Ubuntu
2: Ubuntu, with Linux 5.19.0-35-generic
3: Ubuntu, with Linux 5.19.0-35-generic (recovery mode)
4: Ubuntu, with Linux 5.15.0-67-generic
5: Ubuntu, with Linux 5.15.0-67-generic (recovery mode)
6: Ubuntu, with Linux 5.15.0-58-generic
7: Ubuntu, with Linux 5.15.0-58-generic (recovery mode)
Your selection: 1
Staging Ubuntu
Staging kernel Ubuntu
Unloading previous kexec target, if any
Running /sbin/kexec -l /boot/vmlinuz-5.19.0-35-generic
--append='root=UUID=9e994b93-047b-46a6-9a71-51dfcb4e9598 ro intel_iommu=on iommu=pt
i915.enable_gvt=1 zswap.enabled=1 zswap.compressor=zstd resume=/dev/disk/by-
uuid/01b394fe-b29e-499c-a722-5f8d56cec3cd quiet splash $vt_handoff' --initrd=/boot
/initrd.img-5.19.0-35-generic
添加-r
到同时重新启动
API 调用本身指出文件系统未卸载,但是 kexec 工具似乎还调用关闭序列减去重新启动计算机的部分,从而同步文件系统,因此您的服务和进程应该像正常关闭一样正常终止。
答案2
记住你正在运行的内容(老实说,它实际上并没有告诉你你真正在运行的内容,请参阅systemd:如何获取运行目标
systemctl get-default
切换到单用户模式:
systemctl isolate rescue.target
您可能想终止一些剩余的进程。
切换回您最初的模式(通常是graphical.target
):
systemctl isolate graphical.target
您还可以使用init 1
and theninit 5
仍受支持。