Une approche pourrait être d'utiliser des espaces de noms PID:
Démarrez votre système avec un init=/some/cmd
paramètre en tant que noyau, où /some/cmd
bifurque un processus dans un nouvel espace de noms ( CLONE_NEWPID
) et y s'exécute /sbin/init
(il aura PID 1 dans ce nouvel espace de noms et pid 2 dans l'espace de noms racine), puis dans le parent, exécutez votre " programme".
Vous voudrez probablement un moyen de contrôler votre programme d'une manière ou d'une autre (socket TCP ou ABSTRACT Unix par exemple).
Vous voudrez probablement verrouiller votre programme en mémoire et fermer la plupart des références au système de fichiers afin qu'il ne repose sur rien.
Ce processus ne sera pas vu du reste du système. Le reste du système fonctionnera en effet comme dans un conteneur.
Si ce processus meurt, le noyau panique, ce qui vous donne une garantie supplémentaire.
Cependant, un effet secondaire gênant est que nous ne verrons pas les threads du noyau dans la sortie de ps
.
Comme preuve de concept (en utilisant cette astuce pour démarrer une copie de votre système dans une machine virtuelle qemu):
Créez un /tmp/init
comme:
#! /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"
(vous avez besoin unshare
d'une version récente d'util-linux (2.14)). Ci-dessus, nous utilisons socat
comme le "programme" qui répond simplement sur les connexions TCP sur le port 1234 avec la sortie de ps -efH
.
Ensuite, démarrez votre machine virtuelle en tant que:
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'
Ensuite, nous voyons:
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