Un approccio potrebbe essere quello di utilizzare gli spazi dei nomi PID:
Avvia il tuo sistema con un init=/some/cmd
parametro come kernel, in cui esegue il /some/cmd
fork di un processo in un nuovo spazio dei nomi ( CLONE_NEWPID
) e lo esegue /sbin/init
(avrà PID 1 in quel nuovo spazio dei nomi e pid 2 nello spazio dei nomi radice), quindi nel genitore, esegui il tuo " programma".
Probabilmente vorrai un modo per controllare il tuo programma in un modo o nell'altro (ad esempio socket TCP o ABSTRACT Unix).
Probabilmente vorrai bloccare il tuo programma in memoria e chiudere la maggior parte dei riferimenti al filesystem in modo che non faccia affidamento su nulla.
Questo processo non sarà visibile dal resto del sistema. Il resto del sistema funzionerà in effetti come in un contenitore.
Se quel processo si interrompe, il kernel sarà preso dal panico e ciò ti darà una garanzia in più.
Un effetto collaterale scomodo è che non vedremo i thread del kernel nell'output di ps
.
Come prova del concetto (usando questo trucco per avviare una copia del tuo sistema in una macchina virtuale qemu):
Crea un /tmp/init
like:
#! /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"
(è necessario unshare
da una versione recente di util-linux (2.14)). Sopra stiamo usando socat
come "programma" che risponde alle connessioni TCP sulla porta 1234 con l'output di ps -efH
.
Quindi avviare la macchina virtuale come:
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'
Quindi vediamo:
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