如何在 systemd 上安全地卸载 /var /usr 而无需重新启动

如何在 systemd 上安全地卸载 /var /usr 而无需重新启动

我的虚拟机上有一台 Linux 服务器,由于第三方提供商的配置错误,重新启动确实会像关闭电源一样工作。我无权访问虚拟机配置。

安装系统的人搞乱了存储,并且不负责任地为每个目录安装了一个点(/var/home/usr等...),导致它们很容易对某些目录感到饥饿,而对另一些目录则感到空虚。

为了解决这个混乱,我正在重新组织挂载点,我能够通过执行mount --bind / /mnt以下操作来管理其中的大多数挂载点rsync,然后重新启动之后使用它们的进程umount

问题是systemd init 进程本身使用的/var和。/usrsystemd-remount-fs做这个伎俩吗?我怎么能这样呢?fstab进行简单的编辑就rsync足够了吗?会重启所有服务吗?

我知道哪些点确实需要针对我的情况进行单独的分区,但事实并非/var如此/usr

前提是我不能使用,umount -l因为我必须在重新安装分区后销毁分区,并且我想避免kexec由于不知道它是否会对这个配置错误的虚拟机产生相同的错误影响而无法再次启动它。

我计划为和 另一个或for建立一个压缩btrfs分区,并在它们几乎静态后将所有其他分区以尽可能小的所需空间放在一起。将来我可能会将它们与 root 放在一起并挂载 a以方便检测错误配置。我希望能够在不重新启动的情况下完成所有这一切,尽管我不知道我能做到。/var/logbtrfsxfs/var/lib/dockersquashfsoverlayfs

答案1

警告:这些操作风险极大,我对此不提供任何保证,建议您了解每一步并自行承担风险,如果不这样做,您可能会破坏您的系统,我对任何损害不承担任何责任因其使用而产生。

我已将所有服务器磁盘克隆到我的工作站上的本地虚拟机上,以便在不影响我的原始服务器的情况下尝试这些命令,如果您不确定是否可以执行相同的操作。经过广泛的研究和多次实验,我终于找到了解决方案。

一些系统使用initrd 上的 systemd,挂载目标 root 后,它会像使用 chroot 一样切换 systemd 环境,关闭所有服务,然后在新环境中重新启动。

我们可以利用此功能再次更改根目录,在其他磁盘上的克隆环境上执行此操作将释放系统在旧环境上持有的锁定,因此您可以安全地卸载这些点 - 事实上它几乎不会安装。但是这个克隆环境应该保证正确的配置以再次启动网络并提供 ssh 访问权限。如果没有,那就认为自己注定要失败。

重要的是,你有一个单独的分区,一旦你 chroot 到其他分区内的目录而不是设备本身,系统仍然可以保存父分区的设备,对于这个用例,我们应该考虑它的目的,它不会阻止任何。

如果您有未分配的可用空间,或者您能够缩小某些分区以便为克隆环境提供空间,建议您这样做。但是,如果您没有可用存储空间,并且有足够的内存,则可以创建虚拟内存挂载点。一旦在此过程中连接可能丢失,则不建议进行网络分区。

虚拟内存挂载点可以通过 来完成tmpfs,但它会导致您将此内存锁定在旧环境中,这样您就无法在没有 或 的情况下释放它rebootkexec更好的方法是使用zram,除了创建一个存储设备之外,它还会压缩数据,所以如果你写入5G数据,它实际上会比内存使用少得多,但你仍然需要足够的内存。

例如,如果7G足够,您可以按如下方式创建它:

sudo modprobe zram num_devices=4
echo 7G | sudo tee /sys/block/zram0/disksize
sudo mkfs.ext4 -m0 /dev/zram0

为克隆环境配置所需的分区后,它将如何工作:

mkdir /tmp/sys
sudo mount /dev/zram0 /tmp/sys # or the target device in place of zram0
# mount other separate partitions if required
sudo tar -cpSf - \
    --acls --xattrs --selinux \
    --exclude '/dev/*' \
    --exclude '/run/*' \
    --exclude '/sys/*' \
    --exclude '/proc/*' \
    --exclude '/tmp/*' \
    --exclude '/var/tmp/*' \
    --exclude '/var/run/*' \
    / |
    sudo tar -xvf - \
        --acls --xattrs --selinux \
        -C /tmp/sys

建议fstab在执行切换之前备份您的:

sudo cp -a /tmp/sys/etc/fstab /tmp/sys/etc/fstab-
sudo truncate -s0 /tmp/sys/etc/fstab

如果您打算更改某些设备作为内存的分区,swap建议首先禁用它:

sudo swapoff -a

然后,执行 chroot:

sudo mkdir /sysroot
sudo mount --rbind /tmp/sys /sysroot
sudo touch /etc/initrd-release
sudo systemctl --no-block isolate initrd-switch-root
# it will stop all other services (isolate) and call systemctl switch-root /sysroot

请注意,不需要绑定procdev就像您在执行 chroot 时通常所做的那样,systemd 会为您完成此操作。您可能失去了连接,如果您等待一段时间后仍然无法连接,请向您表示哀悼,您已经被浪费了。

不过,如果您很幸运并且现在能够连接,您就可以执行您想要的分区表更改。

调整设备路径和 uuid ( blkid) 以匹配新的非常重要:

sudo mv /etc/fstab- /etc/fstab
sudo vi /etc/fstab
sudo vi /etc/default/grub

完成更改后,您可以执行相同的策略来切换回真正的根设备,一旦完成,请不要忘记为新环境安装引导加载程序,以便在关机时再次恢复:

sudo grub2-install /dev/sda # or the intended bootable disk
sudo grub2-mkconfig -o /etc/grub2.cfg

一旦您切换回物理设备,如果您正在使用,zram可以通过以下方式释放内存:

echo 1 | sudo tee /sys/block/zram0/reset
sudo modprobe -r zram

请记住,这样做的风险由您自己承担。

相关内容