De los Namespaces en Linux (I)
El namespace de pids
El identificador de proceso (PID) es un número empleado por el Kernel para referirse de manera unívoca a los procesos que corren en un máquina.
Los PIDs se emplean para interactuar con los procesos, por ejemplo, mediante el envío de señales o su repriorización con la utilidad nice.
Cada proceso tiene asignado un PID que es único (ningún otro proceso activo puede tener el mismo PID)
No obstante, con la introducción del namespace de PIDs (en Linux 2.6.24) esta situación ha variado.
En un ejemplo en Perl:
# Un proceso clona un proceso hijo y espera su terminación.
use strict;
use Eixo::Zone;
my $pid_hijo = Eixo::Zone->init(
init=>sub {
print “Soy el proceso hijo y (en mi namespace) tengo pid ” . &Eixo::Zone::getPid() . “\n“;
sleep (1);
exit (0);
}
);
print “Soy el proceso padre y mi hijo tiene pid $pid_hijo \n“;
waitpid($pid_hijo, 0);
Salida:
Soy el proceso padre y mi hijo tiene pid 26708 Soy el proceso hijo y (en mi namespace) tengo pid 1
¿Qué ha pasado?
a) Creación tradicional de un proceso hijo
Empecemos por una creación de hijo normal a través de fork.
El proceso hijo es una copia exacta de su padre que se inicia desde la llamada a fork().
b) Creación de un proceso hijo a través de clone
En el ejemplo de Perl, se ha empleado clone.
Esta llamada, entre otras cosas, nos permite crear nuevos namespaces a la hora de producir un proceso hijo.
Esto es, indicamos en la creación del hijo qué namespaces propios debe tener
Si le indicamos que cree su propio namespace para PIDs:
Ahora, nuestro proceso hijo «vive» en su propio namespace y tiene, por tanto, dos PIDs: uno en el espacio de su padre y otro en el suyo propio.
Para conocer su PID, un proceso realiza una llamada al Kernel: getpid().
Si el proceso hijo llama al Kernel para pedir su pid:
print “Soy el proceso hijo y (en mi namespace) tengo pid ” . &Eixo::Zone::getPid() . “\n“;
El Kernel devuelve el PID que el hijo tiene dentro de su namespace (PID = 1)
Es decir: El kernel contextualiza las llamadas de los procesos de acuerdo a su namespace
El proceso padre quiere esperar a que el proceso hijo termine su ejecución. Para ello, emplea la llamada a waitpid.
waitpid ($pid_hijo, 0);
¿Qué PID empleará?
Desde su punto de vista (desde su namespace) el PID del proceso hijo será el que recibió en la llamada a clone y ese será el que emplee para esperar.
Procesos con PID = 1
El primer proceso que entra en un namespace de PIDs recibirá (dentro del espacio) el PID 1.
Esto tiene importancia, así:
- El proceso se comporta, en cierto sentido, como el init del sistema
- Los procesos huérfanos dentro del namespace creado serán adoptados por este proceso y no por el init del sistema
- La llamada getppid(), desde dentro del namespace, para obtener el padre de este proceso devolverá siempre 0.
- Este proceso puede «matarse» normalmente terminando todo su árbol de procesos (y el namespace)
Pingback: 25 FEB :: XXI Betabeers Galicia [Coruña] - WeKCo - WeKAb Coworking Space
Pingback: Docker meetup | Blog prefapp