Un enfoque podría ser usar espacios de nombres PID:
Arranque su sistema con un init=/some/cmd
parámetro como kernel, donde /some/cmd
bifurca un proceso en un nuevo espacio de nombres ( CLONE_NEWPID
) y se ejecuta /sbin/init
en él (tendrá PID 1 en ese nuevo espacio de nombres y pid 2 en el espacio de nombres raíz), luego en el padre, ejecute su " programa".
Probablemente desee una forma de controlar su programa de una forma u otra (TCP o ABSTRACT Unix socket, por ejemplo).
Probablemente querrás bloquear tu programa en la memoria y cerrar la mayoría de las referencias al sistema de archivos para que no dependa de nada.
Ese proceso no se verá desde el resto del sistema. El resto del sistema se ejecutará como en un contenedor.
Si ese proceso muere, el núcleo entrará en pánico, lo que le brinda una garantía adicional.
Sin embargo, un efecto secundario inconveniente es que no veremos los hilos del núcleo en la salida de ps
.
Como prueba de concepto (usando este truco para iniciar una copia de su sistema en una máquina virtual qemu):
Crea un me /tmp/init
gusta:
#! /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"
(necesita unshare
de una versión reciente de util-linux (2.14)). Arriba estamos usando socat
como el "programa" que solo responde en conexiones TCP en el puerto 1234 con la salida de ps -efH
.
Luego, inicie su VM como:
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'
Entonces, vemos:
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