CEIT y UPV/EHU : software libre y supercomputación

El área de Simulación del CEIT en colaboración con la Facultad de Informática de la Universidad del País Vasco (UPV/EHU) , acaba de publicar un paquete de scripts para distribuciones basadas en Debian que permite configurar de manera automática y en unos pocos minutos un cluster HPC tipo diskless. El trabajo, fruto de un Proyecto Fin de Carrera coordinado por ambos centros, es el resultado de un año de trabajo. El sistema está basado en los scripts de configuración del cluster de la distribución live PelicanHPC, añadiendo la característica de poder ser instalado en cualquier PC con sistema Debian (upstart o init). Además de todo lo anterior, este software está pensado para un uso remoto y por varios usuarios, siendo la utilización de estas características totalmente transparentes para los usuarios del cluster. Este desarrollo está disponible bajo licencia GPL desde la página del proyecto en SourceForge. Actualmente el desarrollo se centra en herramientas de monitorización y configuración del cluster, así como en el desarrollo de una API de alto nivel que permita a los investigadores no informáticos que usen el cluster abstraerse de las complicaciones de MPI.

Gracias a Denis Sánchez & José Miguel Alonso (EHU) y Diego Borro & Jairo Sánchez (CEIT) por la noticia (¡y por el proyecto!) 🙂

Ejecutar scp en background sin ssh-keys

Problema: tengo que lanzar una orden scp para copiar el contenido de un directorio en un servidorA a la misma ruta en el servidorB. Para ello, me conecto desde el PC de casa al servidorA por ssh y lanzo la orden. El problema radica en que no quiero dejar la terminal abierta en el ordenador de casa. Lo que quiero es darle la orden al servidorA y desconectar. Esto se puede hacer precediendo la orden con un nohup por delante y dejándolo en segundo plano… ¡pero scp pide password! Y si está en segundo plano no lo puedo teclear o_O

Solución: usar claves ssh (ssh-keys), de tal forma que se copia la clave ssh pública en el servidorB y a partir de ahi éste no le pedirá password al usuario conectándose desde servidorA. Ésto se puede hacer y no es demasiado complicado (en resumidas cuentas, se crea una pareja de clave pública-clave privada, se sube la clave pública al servidor B y se da la orden de aceptar al cliente que tenga la clave privada correspondiente, sin necesidad de password), pero me gustaría hacerlo de forma más sencilla, sin claves ssh ni necesidad de más configuraciones. Ésto último también se puede hacer, con screen, esa gran aplicación que poco o nada veo usar a la gente.

Recordemos el problema: quiero conectarme a servidorA y lanzar desde ahí una orden scp para copiar una serie de archivos de servidorA a servidorB. La copia de archivos durará mucho tiempo y no quiero tener la conexión abierta durante todo ese rato. El problema es: si corto la conexión, el scp se para. Para que no se pare, podría usar «nohup scp … &», pero scp pide password, y al lanzarlo en segundo plano (con &), no puedo teclearlo.
Así que vamos al grano, usaremos screen, así:

$ screen 
$ lanzo la orden scp

Salgo de screen, pero dejando la sesión abierta. ¿Cómo? Pulsando ctrl+a y luego d .
Ahora puedo cerrar la conexión ssh con serverA cuando quiera.

La próxima vez que conecte por ssh contra serverA puedo retomar la sesión que inicié con screen y ver cómo ha ido evolucionando. Para retomar la sesión, tecleamos:

$ screen -r

Parece más complejo de lo que es. Símplemente toma nota de este post para cuando lo necesites 😉

Por las noches veo zombies…

¿Qué es un proceso zombie (zombi según la DRAE) en Unix? Según la Wikipedia, es un proceso que ha completado su ejecución pero aún tiene una entrada en la tabla de procesos, permitiendo al proceso que le ha creado leer el estado de su salida. Metafóricamente, el proceso hijo ha muerto pero su «alma» (el valor de retorno de la operación) aún no ha sido recogida.

Vale. Y entonces, ¿qué es un proceso zombi? (como dirían mis alumnos tras una explicación «de libro») 🙂 Lo mejor es verlo con un ejemplo sencillito programado en C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
 pid_t pid;
 
if ((pid = fork()) < 0)
        exit(1);
else if (pid == 0)
        exit(0);
 
sleep(120);
exit(0);
}

Nota: para compilar, guarda el código anterior en prueba.c y compila así: gcc -o prueba prueba.c

En la línea 8 se hace un fork(), es decir, el proceso actual (padre) genera un nuevo proceso (hijo). Ambos son «idénticos» (mismo área de código, datos, mismos identificadores de canal abiertos, etc.) y se ejecutan en paralelo (sí, con una sola CPU ese paralelismo es una mera «ilusión óptica» 😉 . La instrucción fork() devuelve un identificador -1 si ha habido algún error en la creación del hijo. Si la génesis (proceso de formación del proceso hijo) fue correcta, en la línea 10 tanto el proceso padre como el proceso hijo preguntan por el identificador devuelto por fork(). Aquí sí que hay una diferencia: al proceso padre, el sistema operativo le devolverá el PID de su proceso hijo. Al proceso hijo, el s.o. le devolverá un 0.

Así que la línea 11 sólo será ejecutada por el proceso hijo. Y casualidades de la vida, esa línea es un exit(0). Así que el proceso hijo acaba de morir. Pero el proceso padre sigue, línea 13, y se suspende durante 2 minutos, desentendiéndose del hijo que acaba de morir. De hecho, el padre podría intentar recoger el resultado devuelto por el hijo (un 0) sincronizándose mediante una llamada al sistema wait(&resultado) pero no lo hace, está durmiendo la mona durante 2 minutos 🙂 Así que el proceso hijo, está «muerto», pero su «alma» (el resultado 0 que aún está disponible para el padre si éste lo quiere) aún no ha sido recibida por nadie. Así que el proceso hijo no ha terminado de morir «del todo». Está en modo zombie.

Podemos comprobarlo ejecutando «prueba» y pidiendo la lista de procesos:

$ ./prueba

Verás algo como lo siguiente:

$ ps auxww| grep prueba
juanan   12851  0.0  0.0   1624   296 pts/1    S+   14:58   0:00 ./prueba
juanan   12852  0.0  0.0      0     0 pts/1    Z+   14:58   0:00 [prueba] <defunct>
juanan   12862  0.0  0.0   3236   792 pts/2    R+   14:58   0:00 grep prueba

La (Z) es indicador de modo zombie en el proceso. El padre (PID=12851) está durmiendo (S).

Buscar un fichero creado entre dos fechas

Te acuerdas que creaste un fichero entre el 15 de Septiembre de 2008 y el 30 de Septiembre de ese mismo año. ¿Cómo lo puedes buscar en Linux? Fácil, usando el comando find y este truquito:

$ touch -d "15 sep 2008" /tmp/begin
$ touch -d "30 sep 2008" /tmp/end
$ find . -newer /tmp/begin -a ! -newer /tmp/end

Lo he necesitado varias veces y nunca me acordaba de la receta, así que la dejo aquí compartida para todos. ¡Que os aproveche!

sysv-rc-conf: configuración gráfica del arranque de servicios

sysv-rcVMWare y Tomcat. Dos grandes aplicaciones que se quedan lanzadas como servicios en mi portátil y que (en dicho PC) sólo uso de vez en cuando. La pereza de editar los enlaces de /etc/rcX.d y los scripts de arranque a pelo han hecho que se queden lanzados siempre (como dice BasaBuru, me hago mayor y ya no tiro tanto de consola). No conocía la herramienta sysv-rc-conf , una pequeña pero potente aplicación que permite, con un interfaz gráfico ncurses (hay que abrir una terminal, no es del todo gráfica :-), seleccionar los niveles de ejecución en los que se lanzarán los distintos servicios que tengamos instalados. Con la barra espaciadora deshabilitamos/habilitamos aquellos que nos interese y listo. Ahora, este PC arranca y se mueve algo más ligerito 🙂

$ sudo apt-get install sysv-rc-conf
$ sudo sysv-rc-conf