วิธีการหนึ่งอาจใช้เนมสเปซ PID:
บูตระบบของคุณด้วยinit=/some/cmd
พารามิเตอร์เคอร์เนลโดย/some/cmd
ให้กระบวนการในเนมสเปซใหม่ ( CLONE_NEWPID
) และทำงาน/sbin/init
ในมัน (มันจะมี PID 1 ในเนมสเปซใหม่นั้นและ pid 2 ในรูทเนมสเปซ) จากนั้นในพาเรนต์ โปรแกรม".
คุณอาจต้องการวิธีควบคุมโปรแกรมของคุณไม่ทางใดก็ทางหนึ่ง (เช่น TCP หรือ ABSTRACT Unix socket)
คุณอาจต้องการ mlock โปรแกรมของคุณในหน่วยความจำและปิดการอ้างอิงส่วนใหญ่ไปยังระบบไฟล์เพื่อให้ไม่ต้องพึ่งพาอะไร
กระบวนการดังกล่าวจะไม่เห็นจากส่วนที่เหลือของระบบ ส่วนที่เหลือของระบบจะมีผลในการทำงานเหมือนในภาชนะ
หากกระบวนการนั้นตายเคอร์เนลจะตื่นตระหนกซึ่งจะทำให้คุณได้รับการรับประกันเพิ่มเติม
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
ว่า "โปรแกรม" ซึ่งเป็นเพียงแค่คำตอบเกี่ยวกับการเชื่อมต่อ TCP บนพอร์ต 1234 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