一种方法是使用PID名称空间:
使用init=/some/cmd
as内核参数启动系统,在其中/some/cmd
将进程派生到新的名称空间(CLONE_NEWPID
)中并/sbin/init
在其中运行(它将在该新名称空间中具有PID 1,在根名称空间中具有pid 2),然后在父级中执行“程序”。
您可能想要一种以一种或另一种方式(例如TCP或ABSTRACT Unix套接字)控制程序的方法。
您可能希望将程序锁在内存中,并关闭对文件系统的大多数引用,以使其不依赖任何内容。
从系统的其余部分看不到该过程。该系统的其余部分实际上将像在容器中一样运行。
如果该进程终止,内核将出现恐慌,这将为您提供额外的保证。
不过,一个不方便的副作用是,我们不会在输出中看到内核线程ps
。
作为概念验证(使用此技巧在qemu虚拟机中引导系统的副本):
创建一个/tmp/init
像:
#! /bin/sh -
echo Starting
/usr/local/bin/unshare -fmp -- sh -c '
umount /proc
mount -nt proc p /proc
exec bash <&2' &
ifconfig lo 127.1/8
exec socat tcp-listen:1234,fork,reuseaddr system:"ps -efH; echo still running"
(您需要unshare
最新版本的util-linux(2.14))。上面我们使用的socat
是“程序”,它仅在端口1234的TCP连接上以输出回答ps -efH
。
然后以以下方式启动您的VM:
kvm -kernel /boot/vmlinuz-$(uname -r) -initrd /boot/initrd.img-$(uname -r) \
-m 1024 -fsdev local,id=r,path=/,security_model=none \
-device virtio-9p-pci,fsdev=r,mount_tag=r -nographic -append \
'root=r rootfstype=9p rootflags=trans=virtio console=ttyS0 init=/tmp/init rw'
然后,我们看到:
Begin: Running /scripts/init-bottom ... done.
Starting
[...]
root@(none):/# ps -efH
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 14:24 ? 00:00:00 bash
root 4 1 0 14:24 ? 00:00:00 ps -efH
root@(none):/# telnet localhost 1234
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
UID PID PPID C STIME TTY TIME CMD
root 2 0 0 14:24 ? 00:00:00 [kthreadd]
root 3 2 0 14:24 ? 00:00:00 [ksoftirqd/0]
[...]
root 1 0 2 14:24 ? 00:00:00 socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root 204 1 0 14:24 ? 00:00:00 /usr/local/bin/unshare -fmp -- sh -c umount /proc mount -nt proc p /proc exec bash <&2
root 206 204 0 14:24 ? 00:00:00 bash
root 212 206 0 14:25 ? 00:00:00 telnet localhost 1234
root 213 1 0 14:25 ? 00:00:00 socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root 214 213 0 14:25 ? 00:00:00 socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root 215 214 0 14:25 ? 00:00:00 sh -c ps -efH; echo still running
root 216 215 0 14:25 ? 00:00:00 ps -efH
still running
Connection closed by foreign host.
root@(none):/# QEMU: Terminated