掘金 阅读 ( ) • 2024-04-16 19:32

实验目标

本次实验,我们面临的主要目标是构建一个稳定且可靠的系统环境,使其能够有效地管理和监控系统中的进程。核心任务是将systemd集成到我们的实验环境中,使其成为系统初始化过程的一部分,并负责管理系统中的服务和应用程序,包括/bin/bash。具体目标可以分解为以下几个关键点:

  1. 实现systemd作为主进程(PID 1): 在Linux系统中,PID 1的进程负责初始化系统并启动其他服务和应用程序。我们计划将systemd置于此核心角色中,以替代原先由bash承担的临时初始化任务。这一转变对于增强系统的稳定性和可管理性至关重要。
  2. 通过systemd监管/bin/bash 我们希望通过systemd来管理/bin/bash,确保当bash进程退出时,systemd能够立即启动一个新的shell实例。这将提升系统对错误的恢复能力,并保持用户界面的连续性,避免因单个shell的崩溃而影响整个系统。
  3. 创建和测试systemd服务单元: 为了实现对bash的有效管理,我们需要根据systemd的配置规则编写一个专门的服务单元文件。这个文件将定义如何启动、监控和重新启动bash进程,以及在什么情况下这些操作应该被执行。
  4. 模仿标准系统的启动过程: 我们的最终目标是在我们的实验环境中复现一个标准Linux系统的启动和运行过程。这包括完成必要的挂载操作、设置环境变量、启动关键服务,最终通过执行systemd来接管系统的进程管理。这样,我们不仅能够提高系统的稳定性,还能为后续添加更多的系统服务和特性打下坚实的基础。

实验过程

首先,我们把systemd和它的相关文件复制过来

cd myfilesystem
cp /bin/systemd bin/
cp /lib/systemd/systemd lib/systemd/
cp /bin/systemctl bin/

cp /lib/systemd/libsystemd-shared-249.so lib/systemd/
cp /lib/x86_64-linux-gnu/libseccomp.so.2 lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libapparmor.so.1 lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libcrypt.so.1 lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libip4tc.so.2 lib/x86_64-linux-gnu/
cp /lib/x86_64-linux-gnu/libseccomp.so.2 lib/x86_64-linux-gnu/

mkdir etc/systemd
mkdir lib/systemd
mkdir etc/systemd/system
mkdir lib/systemd/system
cp /lib/modules/6.5.0-26-generic/kernel/fs lib/modules/6.5.0-26-generic/kernel/ -r
cp /lib/systemd/system/default.target lib/systemd/system/
cp /lib/systemd/system/basic.target lib/systemd/system/
cp /lib/systemd/system/multi-user.target lib/systemd/system/
cp /lib/systemd/system/sysinit.target lib/systemd/system/

接下来,我们要在 /etc/systemd/system/ 目录下创建一个新的服务单元文件,在系统启动到多用户模式之后自动启动一个交互式的 Bash shell。该服务被设置为在 Bash 进程退出时自动重启,并通过强制分配一个终端来确保 Bash 可以以交互式模式运行,处理标准输入、输出和错误。

vim etc/systemd/system/bash.service
[Unit]
Description=Interactive Bash Shell
After=multi-user.target

[Service]
ExecStart=/bin/bash -i
Restart=always
StandardInput=tty-force
StandardOutput=tty
StandardError=tty

[Install]
WantedBy=multi-user.target

然后我们通过虚拟环境启动这个服务

chroot . bin/bash
systemctl enable bash.service
exit

接下来,修改我们的init文件,让systemd来接管PID1

vim init
#!/bin/sh 
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
modprobe mptspi
/lib/systemd/systemd-udevd
udevadm trigger --action=add
udevadm settle || true
mount /dev/sda3 /mnt/hd
exec /lib/systemd/systemd

最后,我们打包并更新grub,重启系统。

find . | cpio -o -H newc | gzip > /boot/my-initrd.img
update-grub

我们重新启动进入这个我们的小系统,这时候就获得了一个由systemd接管的bash,推出后能自动重新启动。