Subsecciones

- 5.3.1 Instalación del kernel de openMosix
  - Opciones del kernel de openMosix
  - Errores más frecuentes al compilar e instalar el kernel
- 5.3.2 Instalación de las herramientas de área de usuario
  - Configurando las herramientas de área de usuario
  - Otras opciones de configuración
  - Errores frecuentes en la compilación e instalación de las herramientas
- 5.3.3 Configurando la topología del cluster
  - Configuración automática de topología
  - Configuración manual de topología
  - El script de inicialización
  - Migrando tareas
- 5.3.4 Las herramientas de área de usuario
  - Monitorizando el cluster
  - Configurando los nodos en openMosix
  - Controlando los nodos con `mosctl`
  - Forzando migraciones
  - Recomendando nodos de ejecución
  - openMosixView
- 5.3.5 Optimizando el cluster
  - Ayudando al algoritmo de equilibrado de carga
  - Modificando las estadísticas de carga
  - Programando openMosix
  - Planes futuros de openMosix
  - Ficheros en /proc/hpc
  - Ficheros en /proc/hpc/admin
  - Ficheros de configuración e información de cada proceso
  - Ficheros de configuración e información de cada nodo

# 5.3 INSTALACIÓN DE UN CLUSTER OPENMOSIX

Puede construirse físicamente un cluster openMosix de la misma forma que se construye un cluster Beowulf. Por otro lado, desde el punto de vista del programario, la construcción de un cluster openMosix es distinta.

La construcción de un cluster openMosix se compone de varios pasos.

1. el primero es compilar e instalar un kernel con soporte openMosix;
2. el segundo, compilar e instalar las herramientas de área de usuario.
3. El tercer paso es configurar los demonios del sistema para que cada máquina del cluster siga el comportamiento que esperamos,
4. y el cuarto paso es crear el fichero del mapa del cluster. Este cuarto paso sólo es necesario si no usamos la herramienta de autodetección de nodos.

## 5.3.1 Instalación del kernel de openMosix

El primer paso para instalar el kernel de openMosix es descargar el tarball. No es conveniente usar la versión del kernel del CVS, ya que suele no ser muy estable. Puede descargarse el tarball del parche del kernel de openMosix de la dirección en SourceForge5.5.

En las fechas en las que se escribe este capítulo, la versión del kernel openMosix para el kernel de Linux 2.4.20 va por su versión 2.

Una vez descargado el parche del kernel openMosix habrá que descomprimirlo:

`gunzip openMosix-2.4.20-2.gz`

Después de descargar el parche openMosix, habrá que descargar el kernel de Linux. Un posible sitio para descargarlo es http://www.kernel.org .

Hay que descargar el kernel correspondiente a la versión del parche que hemos descargado. Esto quiere decir que un parche 2.4.X-Y valdrá para el kernel 2.4.X. Por ejemplo, el parche 2.4.20-2 sólo puede ser aplicado sobre el kernel 2.4.20.

Una vez descargado el kernel de Linux lo descomprimimos:

`tar -zxf linux-2.4.20.tar.gz`

Movemos el directorio donde hemos descomprimido el kernel a linux-openmosix:

`mv linux-2.4.20 linux-openmosix`

y aplicamos el parche de openMosix:

`patch -p0 openMosix-2.4.20-2`

Entramos en el directorio del kernel de Linux:

`cd linux-openmosix`

Y lanzamos el menú de configuración del kernel:

`make menuconfig`

para la configuración a través de menús con ncurses, o:

`make xconfig`

para la configuración a través de X-Window.

### Opciones del kernel de openMosix

El siguiente paso para configurar el kernel de openMosix es entrar en la opción `openMosix` -la primera opción del menú principal de la pantalla de configuración del kernel-. Allí encontraremos un menú con todas las opciones propias de openMosix. Estas opciones son:

openMosix process migration support: Esta opción permite activar el soporte a la migración de procesos en openMosix. Esto incluye tanto la migración forzada por el administrador como la migración transparente automática de procesos, el algoritmo de equilibrado de carga y el Memory Ushering. Si no activamos esta opción, no tenemos openMosix. Por ello, si estamos leyendo este documento, nos interesa tener esta opción activada.

Support clusters with a complex network topology: Las máquinas que pertenecen al cluster openMosix pueden pertenecer a la misma red IP, estando conectadas por un hub o por un switch. En este caso, en openMosix consideramos que la topología de la red es simple, lo que permite realizar algunas modificaciones en los algoritmos de calculo de la función de coste del algoritmo de equilibrado de carga que hacen muchísimo más eficiente su cálculo. También mejora la eficiencia del algoritmo de colecta automática de información del cluster. Si tenemos todas las máquinas del cluster conectadas a través de hubs o switchs -es decir, que un paquete openMosix nunca necesitará pasar por un router- podemos aumentar sensiblemente el rendimiento de nuestro cluster desactivando esta opción.

Maximum network-topology complexity to support (2-10): Si activamos la opción anterior, aparecerá esta opción. En esta opción se nos pregunta cuantos niveles de complejidad hay entre las dos máquinas más lejanas del cluster, entendiendo por niveles de complejidad el número de routers intermedios más uno. Si ponemos un número más alto de la cuenta, no tendremos todo el rendimiento que podríamos tener en nuestro cluster. Si ponemos un número más bajo de la cuenta, no podrán verse entre sí las máquinas que tengan más routers intermedios que los indicados en este parámetro menos uno.

Stricter security on openMosix ports: Esta opción permite un chequeo adicional sobre los paquetes recibidos en el puerto de openMosix, y unas comprobaciones adicionales del remitente. Aunque esto suponga una pequeña pérdida de rendimiento, permite evitar que mediante el envio de paquetes quebrantados se pueda colgar un nodo del cluster. De hecho, hasta hace poco tiempo se podía colgar un nodo del antiguo proyecto Mosix sólo haciéndole un escaneo de puertos UDP. Salvo que tengamos mucha seguridad en lo que estamos haciendo, debemos activar esta opción de compilación.

Level of process-identity disclosure (0-3): Este parámetro indica la información que va a tener el nodo de ejecución real de la tarea sobre el proceso remoto que está ejecutando. Aquí debemos destacar que esta información siempre estará disponible en el nodo raíz -en el nodo en el que se originó la tarea-; limitamos la información sólo en el nodo en el que se ejecuta la tarea si este es distinto del nodo raíz. Este es un parámetro de compromiso: valores más bajos aseguran mayor privacidad, a cambio de complicar la administración. Valores más altos hacen más cómoda la administración del cluster y su uso, pero en algunos escenarios pueden violar la política de privacidad del departamento o de la empresa.

Un 0 significa que el nodo remoto que ejecuta el proceso migrado no tiene ninguna información relativa al proceso migrado que se ejecuta en dicho nodo. Este modo paranoico hace la administración del cluster realmente complicada, y no hay ninguna razón objetiva para recomendarlo.

Un 1 significa que el nodo remoto que ejecuta el proceso migrado tiene como única información el PID del proceso. Este es un modo paranoico, pero que permite al menos al administrador del cluster saber con un poco de más comodidad qué es lo que está pasando en caso de problemas. Es un nodo útil cuando usamos máquinas no dedicadas que estén en los despachos de los usuarios del cluster, y no queremos protestas entre los usuarios del cluster sobre quién está haciendo más uso del cluster.

Un 2 significa que el nodo remoto que ejecuta el proceso migrado conoce PID , el usuario propietario y el grupo propietario del proceso. Este es un modo útil en clusters dedicados y no dedicados cuando sabemos que no va a haber discusiones entre los usuarios porque alguien use los recursos del cluster más de la cuenta. Es una buena opción si tenemos nodos no dedicados en despachos de usuarios donde cualquier usuario no tiene cuentas en las máquinas de los otros, para asegurar una cantidad razonable de privacidad.

Un 3 significa que en el nodo remoto que ejecuta el proceso migrado se tiene exactamente la misma información de los procesos migrados que de los procesos locales. Esto significa que para la información de los procesos el sistema se comporta realmente como un sistema SSI. Este modo es recomendable en los escenarios donde todos los usuarios tienen cuentas en todas las máquinas del cluster, con lo que mantener la privacidad del espacio de procesos ya es de por si imposible, y bloquear esta información solo complica el uso y la administración del cluster. Este es el escenario más habitual de uso de un cluster, por lo que en caso de dudas es mejor que usemos este nivel de privacidad. De cualquier forma, cualquier proceso puede variar su nivel particular de privacidad grabando desde el propio proceso su nuevo nivel de privacidad en el archivo /proc/self/disclosure.

Create the kernel with a -openmosix extension: Si activamos esta opción, el nombre simbólico del kernel llevará la extensión -openmosix. Esto es importante a la hora de buscar y enlazar los módulos. Debemos activar esta opción si, teniendo la misma versión de kernel base y de kernel para openMosix, queremos que los módulos del kernel openMosix y los módulos del kernel antiguo no sean compartidos. En nuestro caso significa que si activamos esta opción podemos tener un kernel 2.4.20 en el sistema y un kernel openMosix 2.4.20-2 al mismo tiempo, y que cada uno tendrá sus módulos por separado y guardados en directorios distintos. En principio, es una buena idea activar esta opción para evitar problemas de efectos laterales con un kernel ya existente en el sistema.

openMosix File-System: Si activamos esta opción podremos usar el sistema de ficheros oMFS, por lo que debemos activar esta opción sólo si vamos a usar el oMFS.

Poll/Select exceptions on pipes: Esta opción es interesante, aunque separa a openMosix de una semántica SSI pura. En Unix, un proceso que escriba en un pipe en principio no es interrumpido si otro proceso abre el mismo pipe para leer o ya lo tenía abierto y lo cierra. Activando esta opción nos separamos de Posix: un proceso escritor en un pipe puede recibir una excepción cuando otro proceso abra un pipe para leer dicho pipe, y puede recibir también una excepción si el pipe se queda sin lectores.

Activamos el lanzamiento de la excepción de lectura del pipe con la llamada al kernel ioctl(pipefd, TCSBRK, 1), y activamos la señal de que el último lector ha cerrado el pipe con ioctl(pipefd, TCSBRK, 2). Por último, podemos tener una estimación aproximada de la cantidad de información que los procesos lectores han pedido leer de un pipe en particular con la llamada al sistema ioctl(pipefd, TIOCGWINSZ, 0). Esta llamada no da un valor exacto, y puede equivocarse -pensemos que nos da apenas una estimación a la baja-. Por lo tanto, en caso de equivocación de la llamada, suele ser porque el proceso lector lee más de lo estimado. Aunque activemos esta opción, por defecto, el envío de estas excepciones está desactivado para todos los procesos, y cada proceso que quiera usar estas excepciones debe activar su posibilidad con `ioctl`. En principio no activamos esta opción, salvo que queramos usarla para nuestros propios programas.

Disable OOM Killer (NEW): Las últimas versiones del kernel de Linux incluyen una característica bastante discutida: el OOM Killer. Esta opción nos permite inhabilitar el OOM Killer, y evitar los problemas que este suele causar. En caso de duda, es recomendable habilitar esta opción -es decir, inhabilitar el OOM Killer-.

Por último, no debemos olvidar que todos los nodos del cluster deben tener el mismo tamaño máximo de memoria, o si no las tareas no migrarán. Para ello, entramos en la opción Processor type and features, y en la opción High Memory Support asignamos el mismo valor a todos los nodos del cluster.

Después de esto, nuestro kernel estará listo para poder usar openMosix. Ahora seleccionamos las opciones adicionales del kernel que coincidan con nuestro hardware y el uso que le queramos dar a nuestro Linux, grabamos la configuración y hacemos:

`make dep`

lo que calcula las dependencias entre partes del kernel -qué se compila y qué no se compila, entre otras cosas-. Después limpiamos el kernel de restos de compilaciones anteriores, que pudieran tener una configuración distinta:

`make clean`

Compilamos el kernel:

`make bzImage`

Compilamos los módulos:

`make modules`

Instalamos los módulos:

`make modules_install`

y ahora copiamos el nuevo kernel en el directorio /boot:

`cp arch/i386/boot/bzImage /boot/kernelopenMosix`

por último, creamos una entrada en lilo.conf para el nuevo kernel; por ejemplo:

    image=/boot/kernelopenMosix
            label=om
            root=/dev/hda1
            initrd=/boot/initrd.img
            append=" devfs=mount"
            read-only

donde /dev/hda1 es el dispositivo de bloques donde encontramos el directorio raíz de Linux; en nuestro sistema puede cambiar. Compilamos la tabla del LILO con el comando:

`lilo`

y listo. Ya tenemos un kernel listo para poder usarlo en un nodo openMosix.

### Errores más frecuentes al compilar e instalar el kernel

Los errores más frecuentes a la hora de configurar el kernel de openMosix son:

Las aplicaciones no migran de todos los nodos a todos los nodos: La causa de este error suele ser que hemos olvidado poner en todas las máquinas el mismo tamaño máximo de memoria.

El parche no se aplica correctamente: Tenemos que usar un vanilla kernel, es decir, un kernel tal y como Linus Torvalds lo distribuye. Particularmente, los kernels que vienen con las distribuciones de Linux no valen ya que están demasiado parcheados.

No existe el directorio/proc/hpc: O no hemos arrancado con el kernel openMosix, o se nos ha olvidado activar la primera opción de openMosix process migration support al compilar el kernel.

Uso la ultimísima versión del gcc, y el kernel de openMosix no compila: No es un problema de openMosix, es un problema del kernel de Linux. Cualquier versión de gcc que compile el kernel de Linux compila el kernel de openMosix; y casi todas las distribuciones de Linux modernas traen un paquete con una versión del backend de gcc para compilar el kernel de Linux.

Además de estos problemas, tendremos los problemas habituales de instalar un kernel nuevo: olvidarnos de ejecutar el comando lilo, olvidarnos de instalar los módulos... de cualquier forma, si sabemos recompilar el kernel e instalar un kernel nuevo no tendremos ningún problema con el kernel de openMosix.

## 5.3.2 Instalación de las herramientas de área de usuario

Para configurar e instalar correctamente las herramientas de área de usuario no es necesario recompilar el kernel de openMosix; pero es fundamental tener descargado el kernel de openMosix, ya que necesitaremos sus cabeceras para compilar correctamente las herramientas de área de usuario.

El primer paso para instalar las herramientas de área de usuario del proyecto openMosix es descargarlas. Podemos descargar las herramientas de área de usuario de http://www.orcero.org/irbis/openmosix .

Podemos descargar también las herramientas de área de usuario de Sourceforge.

Descargamos la última versión -en la fecha en la que se escribe este documento, la última versión de las herramientas de área de usuario son las 0.2.4-. La descomprimimos con:

`tar -zxf openMosixUserland-0.2.4.tgz`

entramos en el directorio creado:

`cd openMosixUserland-0.2.4`

y, antes de cualquier otro paso, leemos el archivo de instalación:

`cat Installation | more`

para la 0.2.4, la información que tenemos en el es la misma que veremos en este capítulo; pero versiones posteriores de las herramientas de área de usuario pueden tener opciones de configuración distintas.

### Configurando las herramientas de área de usuario

El paso siguiente para configurar las herramientas de área de usuario será editar el archivo configuration con nuestro editor de textos favorito. Hay una opción que debemos modificar obligatoriamente si queremos recompilar openMosix, y otras opciones que no debemos tocar salvo que estemos muy seguros de lo que queremos hacer.

Para una instalación estándar de openMosix en los directorios estándares apenas debemos modificar el valor de la variable OPENMOSIX. Esta variable debe contener el camino completo absoluto -no el camino relativo- del kernel de openMosix. Por ejemplo, /usr/src/openmosix es un camino válido, y /home/irbis/openMosix/linux-openmosix también lo es. ../../linux-openmosix no es un camino válido, ya que es un camino relativo, y debe ser un camino absoluto.

En casi todos los casos, ahora solo tenemos que hacer:

`make all`

y los Makefile que acompañan a openMosix se encargarán del resto: compilarán e instalarán las herramientas de área de usuario de openMosix y sus páginas del manual. A pesar de que el código nuevo tiene muy pocos warnings y no tiene errores -al menos, que se sepa-, el código antiguo heredado de Mosix esta programado de una forma muy poco ortodoxa -por decirlo de una forma educada-, por lo que hay activadas todas las opciones de warning para buscar los errores existentes en el código y eliminarlos.

Una vez que la ejecución del make all esté terminada, las herramientas de área de usuario estarán instaladas y bien configuradas.

### Otras opciones de configuración

La opción que hemos visto es la única que deberemos modificar manualmente en condiciones normales. Pero hay otras opciones que pueden ser interesantes para algunos usuarios con necesidades muy específicas. Otras opciones del archivo configuration son:

MONNAME: nombre del programa monitor de openMosix. El programa monitor del proyecto Mosix se llamaba `mon`, lo que era un problema ya que compartía nombre con una herramienta muy común en Linux de monitoramiento del sistema. La gente de Debian lo solucionó cambiando el nombre de la aplicación para Debian de `mon` a `mmon`; pero en openMosix la aplicación la llamamos `mosmon`. En principio, es recomendable dejarlo en `mosmon`, salvo que por razones de compatibilidad inversa con algun script de Mosix queramos llamar a esta aplicación `mon` o `mmon`.

CC: Nombre del compilador de C. Casi siempre es `gcc`.

INSTALLBASEDIR: Ruta completa absoluta donde está el directorio raíz del sistema de ficheros donde queremos instalar openMosix. Casi siempre es / .

INSTALLEXTRADIR: Ruta completa absoluta donde está el directorio donde están los directorios con las aplicaciones del sistema y su documentación donde queremos instalar openMosix. Casi siempre es /usr .

INSTALLMANDIR: Ruta completa absoluta donde está el directorio donde están las páginas del manual donde queremos instalar openMosix. Casi siempre es /usr/man .

CFLAGS: Opciones de compilación en C para las herramientas de área de usuario. Las opciones -i./, -i/usr/include y -i$(OPENMOSIX)/include son obligatorias; el resto la pondremos según nuestro interés particular -las opciones por defecto que encontramos en el archivo de configuración son válidas, y debemos mantenerlas salvo que haya una buena razón para no hacerlo-.

### Errores frecuentes en la compilación e instalación de las herramientas

Hay un conjunto de errores en la instalación de las herramientas de área de usuario que debemos conocer bien, ya que son objeto de frecuentes preguntas en la lista de correos. Estos errores son:

Las herramientas de área de usuario no compilan: ¿Hemos puesto correctamente el valor de la variable `OPENMOSIX` en el archivo configuration? ¿Esta variable realmente apunta al kernel de openMosix? ¿Es realmente el kernel de openMosix, o un kernel normal? Recordemos que la variable `OPENMOSIX` debe ser forzosamente un camino absoluto. Por último, ¿tenemos instalado un compilador de C?

Error This is not Mosix! Este error se da cuando usamos las herramientas de área de usuario del proyecto Mosix sobre un kernel normal, o sobre un kernel openMosix. También se da si usamos el `setpe` de una versión de las herramientas de área de usuario anterior a la 0.2.4 sobre un kernel que no tiene soporte openMosix. Si es este último caso, es muy recomendable usar una versión de herramientas de área de usuario 0.2.4 o posterior; la 0.2.4 es conocida por ser realmente estable, y no hay ninguna razón objetiva para usar una versión anterior. En cualquier otro caso, recordemos que las herramientas de área de usuario del proyecto Mosix no son libres; y que, de cualquier forma, no funcionan en openMosix.

Error This is not openMosix! Este error se da cuando usamos las herramientas de área de usuario de openMosix en un equipo que no está usando un kernel con soporte openMosix. O estamos usando las herramientas de área de usuario de openMosix sobre un kernel Mosix, o no hemos arrancado con el kernel nuevo, o el kernel nuevo no tiene soporte a migración de procesos openMosix.

## 5.3.3 Configurando la topología del cluster

Una vez que ya tenemos instalado nuestro kernel de openMosix y nuestras utilidades de área de usuario de openMosix, el siguiente paso que daremos será configurar la topología del cluster.

Para configurar la topología del cluster openMosix tenemos dos procedimientos distintos.

1. El primero es el procedimiento tradicional, consistente en un archivo por nodo donde se especifican las IPs de todos los nodos del cluster.
2. El segundo procedimiento consiste en emplear el demonio de autodetección de nodos.

Cada procedimiento tiene sus ventajas y sus inconvenientes.

La configuración tradicional manual tiene como inconveniente que es más laboriosa en clusters grandes: cada vez que queramos introducir un nodo nuevo en el cluster, debemos tocar el archivo de configuración de todos los nodos de dicho cluster para actualizar la configuración. Este método nos permite, por otro lado, tener topologías arbitrariamente complejas y grandes; también es el método más eficiente.

El segundo método para configurar los nodos de un cluster openMosix es usar el demonio de detección automática de nodos, el omdiscd. Este método es el más cómodo, ya que el cluster casi se configura solo. Por otro lado, tiene dos pegas:

1. la primera, que todas las máquinas del cluster deben estar en el mismo segmento físico. Esto impide que el demonio de autodetección pueda ser usado en redes muy complejas.
2. La segunda, que todos los nodos cada cierto tiempo deben mandar un paquete de broadcast a todos los otros nodos de la red para escanear los nodos openMosix de la red.

Para pocos nodos, estos paquetes no afectan al rendimiento; pero en caso de clusters de tamaño medio o grande, la pérdida de rendimiento puede ser crítica.

Realmente el demonio de autodetección de nodos no detecta nodos openMosix, sino que detecta otros demonios de autodetección de nodos. Esto significa en la práctica que el demonio de autodetección de nodos no es capaz de detectar nodos openMosix configurados mediante el método manual. Tampoco debemos mezclar los dos tipos de configuración en el cluster, ya que esto nos dará bastantes dolores de cabeza en la configuración de la topología.

### Configuración automática de topología

La forma automática de configurar la topología de un cluster openMosix es mediante un demonio recientemente Incorporado en las herramientas de área de usuario, que permite la detección automática de nodos del cluster.

El nombre del demonio es omdiscd. Para ejecutarlo, si hemos instalado correctamente las herramientas de área de usuario, basta con hacer:

`omdiscd`

y este programa creará automáticamente una lista con las máquinas existentes en la red que tienen un demonio de autodetección de nodos válido y funcionando correctamente, e informará al kernel openMosix de estas máquinas para que las tenga en cuenta.

Podemos consultar la lista generada por el demonio de autodetección de nodos con el comando:

`showmap`

este comando muestra una lista de los nodos que han sido dados de alta en la lista de nodos local al nodo que ejecuta el demonio omdiscd. Cuidado, ya que el hecho de que un nodo sea reconocido por un segundo no implica el caso recíproco: alguno de los nodos de la lista pueden no habernos reconocido aún como nodo válido del cluster.

Podemos informar a openMosix sobre por cual de los interfaces de red queremos mandar el paquete de broadcast. Esto es especialmente interesante en el caso particular de que el nodo donde lanzaremos el demonio de autodetección de nodos no tenga una ruta por defecto definida, caso en el que omdiscd parece fallar para algunos usuarios; aunque hay otros escenarios donde también es necesario controlar manualmente por que interfaz de red se manda el paquete de broadcast. Para forzar a omdiscd a mandar la información por un interfaz en particular tenemos que usar la opción `-i`. Por ejemplo, llamamos al demonio de autodetección de nodos en este caso con el comando:

`omdiscd -i eth0,eth2`

lo que significa que mandaremos el paquete de broadcast por `eth0` y por `eth2`, y solamente por estos dos interfaces de red.

Otro caso particular que es interesante conocer es el de algunas tarjetas PCMCIA que por un error en el driver del kernel no sean capaces de recibir correctamente los paquetes de broadcast -existen algunas así en el mercado-. La única solución que podemos tener en la actualidad es poner el interfaz de dicha tarjeta con un mal driver en modo promiscuo, con lo que la tarjeta leerá y analizará todos los paquetes, incluidos los de broadcast; y el así el kernel podrá acceder a dichos paquetes de broadcast. No es un problema del código de openMosix, sino de los drivers de algunas tarjetas; pero el demonio de autodetección de nodos lo sufre directamente. Ponemos la tarjeta con un driver que tenga problemas con los paquetes de broadcast en modo promiscuo con:

`ifconfig eth0 promisc`

suponiendo que `eth0` es nuestro interfaz de red. En otro caso, sustituiremos `eth0` por nuestro interfaz de red. En caso de que el ordenador tenga varios interfaces de red, usamos esta instrucción con todos aquellos interfaces por los que esperamos recibir paquetes de openMosix -puede ser más de un interfaz- y que tengan este problema. Sólo root puede poner en modo promiscuo un interfaz.

Para verificar con comodidad la autodetección viendo que hace el demonio de autodetección de nodos, podemos lanzarla en primer plano con la opción `-n`, con la sintaxis:

`omdiscd -n`

así se lanzará en primer plano, y veremos en todo momento lo que está pasando con el demonio.

Otro modificador que es interesante conocer en algunos escenarios es `-m`. Lleva como parámetro un único número entero, que será el TTL de los paquetes de broadcast que enviemos a otros demonios de autodetección de nodos.

Se aconseja pues que usemos la herramienta de detección automática de nodos sólo para clusters de prueba. A pesar de el gran interés que han mostrado Moshe Bar y Martin Hoy en ella, al hacerle pruebas algunas veces no ha detectado todos los nodos. Es una herramienta aún experimental, y esto es algo que no debemos olvidar.

Finalmente debemos destacar que este demonio debe ser lanzado en todos los nodos del cluster, o en ninguno de ellos. Mezclar los dos mecanismos de configuración de la topología de un cluster en el mismo cluster no es una buena idea.

### Configuración manual de topología

El sistema de autodetección tiene muchos problemas que lo hacen inconveniente para determinadas aplicaciones. No funciona si hay algo entre dos nodos que bloquee los paquetes de broadcast, puede sobrecargar la red si tenemos muchos nodos en el cluster, supone un demonio más que debe correr en todos los nodos del cluster, lo que complica la administración; y, quizás lo más importante, aún es software beta y no siempre detecta todos los nodos. Por todo ello, muchas veces un fichero compartido de configuración, común a todos los nodos, es la solución más simple a nuestro problema.

En openMosix llamamos a nuestro fichero /etc/openmosix.map. El script de arranque de openMosix -que estudiaremos más adelante- lee este archivo, y lo utiliza para informar al kernel de openMosix sobre cuales son los nodos del cluster.

El fichero /etc/openmosix.map contiene una lista con los rangos de direcciones IP que pertenecen al cluster. Además de indicar que rangos de direcciones IP pertenecen al cluster, nos permite asignar un número de nodo único a cada IP de la red. Este número será empleado internamente por el kernel de openMosix y por las herramientas de usuario; también lo emplearemos como identificador en comandos como `migrate` para referenciar de forma unívocamente cada nodo. Tanto el sistema de ficheros /proc/hpc como las herramientas de área de usuario usan estos números identificativos de nodo, en lugar de la IP, ya que un nodo del cluster openMosix puede tener más de una IP, y solo uno de estos números.

Cada linea del fichero /etc/openmosix.map corresponde a un rango de direcciones correlativas que pertenecen al cluster. La sintaxis de una linea es:

`numeronodo IP tamañorango`

donde `numeronodo` es el primer número de la primera IP del rango, `IP` es la primera IP del rango, y `tamañorango` es el tamaño del rango.

Por ejemplo, en el archivo /etc/openmosix.map con el contenido:

    1 10.1.1.100 16
    17 10.1.1.200 8

estamos diciendo que nuestro cluster openMosix tiene 24 nodos. En la primera linea decimos que los 16 nodos primeros, que comenzamos a numerar por el número 1, comienzan desde la IP 10.1.1.100; y continúan con 10.1.1.101, 10.1.1.102... así hasta 10.1.1.115.

En la segunda linea decimos que, comenzando por el nodo número 17, tenemos 8 nodos más; comenzando por la IP 10.1.1.200, 10.1.1.201...hasta la IP 10.1.1.207.

Podemos también Incluir comentarios en este fichero. A partir del carácter #, todo lo que siga en la misma linea del carácter # es un comentario. Por ejemplo, podemos escribir:

    # redes 10.1.1
     1 10.1.1.100 16 # Los 16 nodos del laboratorio
    17 10.1.1.200 8 # El core cluster

Este archivo es exactamente igual para openMosix que el archivo anterior.

La sintaxis de la declaración de la topología del cluster en el archivo /etc/openmosix.map necesita una explicación adicional cuando tenemos alguna máquina con más de una dirección IP. En este archivo deben aparecer todas las IPs que puedan enviar y recibir paquetes openMosix, y sólo ellas. Esto significa que no pondremos en este archivo las IPs que no se usen para enviar y recibir los mensajes; pero también supone un problema cuando una misma máquina puede enviar y recibir mensajes de openMosix por varias IPs distintas. No podemos poner varias entradas como las que hemos visto, ya que el identificador de nodo es único para cada nodo, independientemente del número de IPs que tenga un nodo.

Por todo esto, para solucionar el problema de que un nodo tenga varias direcciones IPs válidas en uso en el cluster openMosix, tenemos la palabra clave ALIAS, que usamos para indicar que la definición de la dirección IP asignada a un número identificador de nodo está replicada porque dicho identificador tiene más de una IP válida.

Lo vamos a ver más claro con un ejemplo. Supongamos, por ejemplo, que un nodo particular en el cluster descrito en el ejemplo anterior -el nodo 8- comparte simultáneamente una dirección de las 10.1.1.x y otra de las 10.1.2.x. Este segmento 10.1.2.x tiene a su vez más nodos openMosix con los que tenemos que comunicarnos. Tendríamos el fichero:

    # redes 10.1.1
     1 10.1.1.100 16 # Los 16 nodos del laboratorio
    17 10.1.1.200 8 # El core cluster

    # redes 10.1.2
    18 10.1.2.100 7
    8 10.1.2.107 ALIAS # Nodo de interconexion con la red 10.1.1
    25 10.1.2.108 100

es decir, estamos definiendo la IP del nodo 8 dos veces. La primera vez en la línea:

     1 10.1.1.100 16 # Los 16 nodos del laboratorio

y la segunda vez en la linea:

    8 10.1.2.107 ALIAS # Nodo de interconexion con la red 10.1.1

en la primera línea el nodo 8 está definido dentro del rango entre el nodo 1 y el nodo 16. En la Segunda línea vemos como decimos con ALIAS que el nodo 8, además de la IP ya definida, tiene una IP adicional: la IP 10.1.2.107.

Hay que destacar un concepto clave al usar ALIAS: tenemos que separar forzosamente la IP de la entrada ALIAS del rango donde esta ha sido definida. Por ejemplo, en el escenario anteriormente comentado es erróneo hacer:

    # redes 10.1.1
     1 10.1.1.100 16 # Los 16 nodos del laboratorio
    17 10.1.1.200 8 # El core cluster
    # redes 10.1.2
    18 10.1.2.100 108
    8 10.1.2.107 ALIAS # Nodo de interconexion con la red 10.1.1

Esto no funciona, ya que definimos un identificador para la IP 10.1.2.107 dos veces. Por ello, tenemos que resolver este escenario como en el ejemplo completo anteriormente comentado.

Por último, debemos recordar que todos los nodos del cluster openMosix deben tener el mismo archivo /etc/openmosix.map, y de que la dirección local 127.0.0.1, por lo tanto, jamás debe aparecer en el archivo /etc/openmosix.map, ya que los ficheros deben ser iguales; y, en caso de incluir la dirección IP local 127.0.0.1, cada archivo asignaría al mismo número distinto una máquina distinta.

### El script de inicialización

Podemos activar el archivo anteriormente citado con el comando `setpe` -más tarde veremos cómo hacerlo-; pero en openMosix tenemos un mejor procedimiento para configurar la topología del cluster: su script de inicialización.

En el directorio de instalación de las herramientas de área de usuario tenemos un subdirectorio llamado scripts. En este directorio tenemos un script que se llama openmosix, que es el script encargado de configurar nuestro nodo cuando este entre en el runlevel que determinemos, suponiendo scripts de configuración à la System V -que son los que usan casi todas las distribuciones modernas de Linux-. Para activarlo, entramos en el directorio scripts y hacemos:

`cp openmosix /etc/rc.d/init.d`

ahora tenemos que decidir en qué runlevels queremos lanzar openMosix. Si queremos lanzar openMosix en el runlevel 3, hacemos:

`ln -s /etc/rc.d/init.d/openmosix /etc/rc.d/rc3.d/S99openmosix`

y si queremos lanzarlo en el runlevel 5 hacemos:

`ln -s /etc/rc.d/init.d/openmosix /etc/rc.d/rc5.d/S99openmosix`

Si queremos lanzar openMosix al arrancar una máquina, debemos determinar cual es el runlevel de arranque del nodo. Para saber cual es el runlevel de arranque de nuestra máquina, hacemos:

`cat /etc/inittab | grep :initdefault:`

o

`cat /etc/inittab | grep id:`

saldrá algo como:

    id:5:initdefault:

en este caso, el runlevel de arranque será el 5, y será el runlevel donde tendremos que activar el script de openMosix como hemos visto anteriormente. Por otro lado, si sale:

    id:3:initdefault:

el runlevel de arranque será el 3, y usaremos el comando anteriormente estudiado para lanzar el script de inicialización en el runlevel 3.

La próxima vez que la máquina arranque, openMosix estará correctamente configurado. De cualquier forma, podemos en cualquier momento reiniciar la configuración de openMosix sin reiniciar la máquina haciendo:

`/etc/rc.d/init.d/openmosix restart`

### Migrando tareas

En principio, los procesos migrarán solos según el algoritmo de equilibrado automático de carga. Sin embargo, podemos tener interés en recomendar una migración, o en forzar que un proceso vuelva a su nodo raíz. Vamos a repasar las utilidades de área de usuario; y comenzaremos con la utilidad que permite controlar las migraciones: la utilidad `migrate`.

Esta utilidad nos permite solicitar la migración de un proceso determinado a un nodo determinado. Su sintaxis es:

`migrate PID numnodo`

donde `PID` es el PID del proceso, y `numnodo` el número del nodo al que queremos que el proceso migre. Si queremos forzar que el proceso migre a su nodo raíz, hacemos:

`migrate PID home`

por otro lado, si queremos que el proceso migre a un nodo indeterminado que el kernel de openMosix debe decidir según el algoritmo de equilibrado automático de carga, hacemos:

`migrate PID balance`

sólo puede solicitar la migración de una tarea root, el usuario propietario de la tarea y el usuario efectivo de la tarea. La migración es solo solicitada; y la tarea puede no migrar si hay alguna razón de fuerza mayor que impida la migración. Particularmente, la única migración de cualquier proceso que tendremos completa seguridad de que se realizará es la migración al nodo raíz con el parámetro home. Las otras pueden no ocurrir.

## 5.3.4 Las herramientas de área de usuario

### Monitorizando el cluster

La herramienta usada para monitorizar un cluster openMosix es `mosmon`. Esta herramienta nos permite ver un gráfico de barras con la carga asociada a cada nodo del cluster. Esta información podríamos obtenerla haciendo un `top` en cada uno de los nodos, pero para clusters de más de ocho nodos la solución del `top` es inviable, y la solución de `mosmon` es especialmente buena.

`mosmon` es una utilidad especialmente interesante por varios puntos adicionales, que no todos sus usuarios conocen, y que lo hacen indispensable para cualquier administrador de sistemas: podemos ver las barras de forma horizontal y vertical, podemos listar todos los nodos definidos en el cluster, Estén o no activos, podemos ver el número de nodos activos y además, en caso de que el número de nodos sea mayor del que se puede ver en una pantalla, podemos con el cursor derecho y el cursor izquierdo movernos un nodo a la derecha o un nodo a la izquierda, con lo que podremos ver grandes cantidades de nodos en una pantalla cualquiera. Todo esto hace a `mosmon` una herramienta realmente imprescindible para el administrador del cluster.

De entre las opciones disponibles que podemos usar al llamar a `mosmon`, las más importantes son:

-d: incluye en el gráfico todos los nodos, incluso aquellos que están desactivados. Esta opción es muy útil, ya que así el administrador ve cuando entran en el cluster estos nodos desactivados.

-t: lista un el número de nodos activos del cluster. Esta opción es especialmente útil en clusters grandes o muy grandes, para hacernos una idea de cuantos nodos activo realmente tenemos -recordemos que en clusters realmente grandes, todos los días falla el hardware de algún nodo-.

Una vez que estamos dentro del programa `mosmon`, con la pulsación de algunas teclas podemos conseguir funciones extra. De entre las teclas activas de `mosmon`, destacamos:

d: lista también aquellos nodos que no están activos. Hace lo mismo que arrancar `mosmon` con la opción `-d`.

D: lista sólo aquellos nodos que están activos. Por ello, hace lo mismo que arrancar `mosmon` sin la opción `-d`.

h: muestra la ayuda de `mosmon`.

l: permite visualizar la carga de cada nodo. Este es el modo de visualización con el que arranca `mosmon`, por lo que esta opción se usa para volver a la visualización de carga después de haber cambiado la vista con `m`, `r`, `s`, `t` o `u`.

m: permite visualizar la memoria lógica usada por los procesos -lo que corresponde a suma de las memoria que los procesos creen que realmente usan- y la memoria total por cada máquina, en lugar de la carga. La barra corresponde con la memoria lógica ocupada, mientras que los `+`, sumados a la barra, corresponden a la memoria total. Los `+` corresponden a la suma entre la memoria libre y la memoria usada por cosas distintas de los procesos -kernel, Reservada por dispositivos hardware-. Puede ser menor O mayor que la memoria libre real, ya que por un lado varios procesos pueden compartir segmentos, lo que hace que la memoria física usada sea menor que la memoria lógica usada; por otro lado, el kernel y los dispositivos hacen que no toda la memoria no usada por los procesos esté realmente libre. Todas las cantidades se muestran en megabytes.

q: sale del programa `mosmon`.

r: permite visualizar la memoria física usada, la memoria libre y la memoria total por cada máquina, en lugar de la carga. La barra corresponde con la memoria física usada en un nodo, mientras que los `+` corresponden a la memoria libre. Por ello los `+`, sumados a la barra, corresponden a la memoria total. Todas las cantidades se muestran en megabytes.

s: permite ver las velocidades de los procesadores y el número de procesadores por cada máquina en lugar de la carga.

t: lista un el número de nodos activos del cluster, si no está visible, o desactiva la visión si se están viendo el número de nodos activos del cluster. Está relacionado con la opción de arranque `-t`.

u: permite ver el grado de utilización del procesador de cada nodo. En el caso de que el cuello de botella de un nodo esté en su procesador, este valor estará al 100%. Hay que destacar que un nodo puede estar saturado por muchas cosas, tales como acceso a disco o a swap, y no llegar dicho nodo al 100% de la utilización neta del procesador. Un valor por debajo del 100%, por lo tanto, significa que un procesador está infrautilizado, por lo que podría aceptar migraciones de entrada -aunque puede tener migraciones de salida del nodo de procesos que usen mucha memoria o mucho disco-.

Además de todo esto, la tecla Enter nos permite redibujar la pantalla, `p` hace lo mismo que el cursor izquierdo -mover la vista de nodos a la izquierda-, y `n` nos permite hacer lo mismo que el cursor derecho -mover la vista de nodos a la derecha-.

### Configurando los nodos en openMosix

La herramienta para configurar los nodos de un cluster openMosix es `setpe`. Esta herramienta es llamada por los scripts de inicialización y parada de openMosix, así como por numerosos scripts de openMosix y herramientas auxiliares. A pesar de que habitualmente no la llamaremos directamente, es interesante su estudio.

`setpe` se encarga de determinar la configuración de nodos del cluster. Su parámetro principal es el archivo donde estará especificado el mapa de nodos. `setpe` habitualmente es llamado de tres formas; la primera es con el modificador `-f nombrefichero`, que tomará como archivo de configuración `nombrefichero`. La segunda forma es pasando como parámetro `-`, en cuyo caso leerá el archivo de configuración de la entrada estándar. Esto es útil para hacer pruebas de configuración, o para hacer pipes de `setpe` con otras aplicaciones. Por último, puede ser llamado con un único parámetro, `-off`, para sacar el nodo del cluster.

De entre los parámetros de `setpe` destacamos:

-w: carga la configuración del fichero indicado con los parámetros especificados en dicho fichero sobre el kernel, si es posible hacerlo sin necesidad de reinicializar la parte de openMosix del kernel. Esto significa que sólo actualiza la configuración si el nodo no ejecuta ningún proceso de otro nodo, ni ningún proceso de el nodo local se ejecuta en un nodo remoto. En cualquiera de estos dos casos, `-w` dará un error y no actualizará la configuración.

-W: carga la configuración del fichero indicado con los parámetros especificados en dicho fichero sobre el kernel, cueste lo que cueste. Esto puede significar expulsar procesos y mandarlos a sus nodos de vuelta, asícomo traerse al nodo local todos los procesos remotos lanzados localmente. Internamente, con un `-W`, realmente `setpe` hace primero un `-off` -vemos más adelante cómo funciona -off-, y después hace un `-w`.

-c: realiza toda la operativa que realizaría `-w`, solo que no graba el resultado en el kernel. Esta opción es útil para verificar una configuración sin instalarla en la máquina.

Cualquiera de estas tres opciones puede ser acompañada por la opción `-g numero`. Si la utilizamos, `septe` informará al kernel que el número máximo de gateways que se interponen entre el nodo local y el más remoto de los nodos es, a lo sumo, `número`. Si no indicamos esta opción, simplemente no modificamos el parámetro del kernel de número máximo de gateways, quedando como estaba. El número máximo de gateways intermedio que podemos especificar es `2`.

Además de estas opciones, tenemos otras opciones interesantes de `setpe`. Estas son:

-r: lee la configuración del nodo actual, y la vuelca en la salida estándar, o en un archivo determinado con la opción `-f nombrearchivo`. Esta opción es muy útil para ver errores en la configuración en clusters muy grandes, en los que no hemos hecho un seguimiento de la configuración de todos y cada uno de sus nodos y hemos empleado cualquier mecanismo automatizado de configuración.

-off: esta opción desactiva openMosix en el nodo actual, es decir, bloquea las migraciones de salida de procesos locales, bloquea las migraciones de entrada de procesos remotos, manda las tareas que se ejecutan en el nodo actual de otros nodos de vuelta a sus nodos de origen, llama a los procesos remotos originados en el nodo local para que vuelvan, borra la tabla de nodos del nodo, y, por último, inhabilita openMosix en el nodo local.

### Controlando los nodos con `mosctl`

Del mismo modo que `setpe` nos permite ver la configuración de un nodo openMosix y configurarlo, `mosctl` nos permite editar el comportamiento de un nodo ya configurado, y verlo.

De entre las opciones del comando `mosctl`, destacamos:

block: en el nodo local, bloquea la entrada de los procesos generados en otro nodo.

noblock: deshace los efectos de `block`.

mfs: activa el soporte a MFS en openMosix.

nomfs: inhabilita el soporte a MFS en openMosix.

lstay: bloquea la migración automática hacia fuera de los procesos generados localmente.

nolstay: deshace los efectos de `lstay`.

stay: bloquea la migración automática hacia fuera de cualquier proceso.

nostay: deshace los efectos de `stay`.

quiet: el nodo local no informará a los otros nodos de su status.

noquiet: deshace los efectos de `quiet`.

Como vemos, todas estas opciones tienen un modificador que habilita alguna propiedad, y otro modificador que la inhabilita. Hay otros modificadores de un solo comando para mosctl, que son:

bring: trae de vuelta a todos los procesos que se han generado localmente pero que se ejecutan en un nodo remoto. Además, internamente realiza primero la misma operación que `lstay`, y deja el estado en `lstay`. No retorna hasta que no han vuelto todos los procesos remotos generados localmente.

expel: manda de vuelta a sus nodos de origen a todos los nodos que se ejecutan en el nodo local pero fueron generados en un nodo remoto. Además, internamente realiza primero la misma operación que `block`, y deja el estado en `block`. No retorna hasta que no han salido todos los procesos remotos del nodo local.

Por ejemplo, para apagar ordenadamente un nodo en un cluster openMosix sin perder ningún proceso, debemos hacer:

`mosctl expel`

`mosctl bring`

Después de estos comandos, el nodo no aceptará ni que migren al nodo local procesos generados en un nodo externo, ni que ningún nodo local migre a otro nodo. Además, no se ejecutará ningún proceso remoto en el nodo local ni ningún proceso local en el nodo remoto. Es decir, nuestra máquina está desligada del cluster openMosix, por lo que si se apaga la máquina de un tirón de cable no afectará al resto del cluster.

Existen, además de estos, un conjunto de modificadores que tienen un parámetro adicional: el identificador de un nodo dentro del cluster. Estos modificadores permiten obtener información sobre cualquier nodo del cluster. Estos modificadores son:

getload nodo: siendo `nodo` un nodo válido en el cluster, este modificador nos devuelve la carga que actualmente tiene dicho nodo. Este parámetro de carga no corresponde al parámetro de carga del kernel al que estamos acostumbrados, sino al parámetro de carga que calcula openMosix y usa openMosix.

getspeed nodo: da la velocidad relativa de dicho nodo. Esta velocidad es relativa, y se supone que un Pentium-III a 1GHz es un procesador de 1000 unidades de velocidad.

getmem nodo: da la memoria lógica libre y la memoria lógica total de un nodo particular del cluster.

getfree nodo: da la memoria física libre y la memoria física total de un nodo particular del cluster. Como estudiamos anteriormente al hablar de `mosmon`, la memoria física libre y la memoria lógica libre pueden no coincidir.

getutil nodo: siendo `nodo` un nodo válido en el cluster, nos da el grado de uso de dicho nodo en el cluster. Discutimos el parámetro de grado de uso de un nodo al hablar del comando `mosmon`.

isup nodo: nos indica si el nodo indicado está activo o no.

getstatus nodo: nos dará el estado del nodo indicado. En este estado incluye también información sobre si el nodo permite migraciones de entrada, si permite migraciones de salida, si bloquea todas las migraciones, si está activo, y si está propagando información sobre su carga.

Por ultimo, tenemos un modificador que nos permite descubrir la IP y el identificador de nodo en openMosix asociado a un nodo en particular. Es:

`mosctl whois dirección`

y podemos tener como parámetro `dirección` el identificador de nodo, en cuyo caso este comando nos devolverá la IP, o la IP, en cuyo caso nos devolverá el identificador de nodo, o el nombre de la máquina, en cuyo caso nos devolverá el identificador de nodo. Este comando también nos indica si la máquina indicada no pertenece al cluster openMosix.

Si llamamos a `mosctl whois` sin ningún parámetro adicional, este comando nos devolverá el identificador del nodo local.

### Forzando migraciones

Para forzar una migración en un cluster openMosix, debemos usar el comando `migrate`.

El comando `migrate` toma dos parámetros: el primero es el PID del proceso que queremos hacer migrar, y el segundo parámetro es donde queremos que migre. Este segundo parámetro debe ser el identificador válido de un nodo en el cluster.

Existen, sin embargo, dos parámetros que podemos colocar en lugar del identificador válido de un nodo del cluster. Estos dos modificadores modelan dos casos especiales, y son:

home: fuerza a migrar a un proceso al nodo donde fue generado.

balance: fuerza a migrar a un proceso al nodo donde la migración suponga minimizar el desperdicio de recursos dentro del cluster openMosix. Es una forma de indicar que se evalúe el algoritmo de migración automática de carga de openMosix, pero dando preferencia a la migración del proceso del que hemos indicado el PID.

A la hora de lanzar esta migración, en caso de que el proceso sea un proceso lanzado en la máquina donde ejecutamos el comando `migrate`, debemos ser el administrador de la máquina, el usuario propietario del proceso, el usuario efectivo del proceso, miembro del grupo propietario del proceso o miembro del grupo efectivo del proceso.

Por otro lado, el administrador del sistema de un nodo cualquiera del cluster siempre puede lanzar este comando sobre cualquier proceso que se ejecute en dicho nodo, independientemente de que se haya generado en el nodo local o en un nodo remoto.

En principio, el proceso puede no migrar aunque le lancemos la orden `migrate`. En caso de que no migre, algunas veces recibiremos un mensaje de error avisando que el comando no funcionó, pero unas pocas veces no migrará, y no recibiremos dicho mensaje. Particularmente esto se da cuando forzamos una migración posible pero pésima: el proceso será mandado de vuelta al nodo local incluso antes de que salga, porque el algoritmo de optimización de carga considerará inaceptable la migración.

La única migración que realmente podemos forzar siempre es la de vuelta a casa, siempre que el nodo de origen no acepte salidas de su nodos con `mosctl lstay` y no bloqueemos la entrada en el nodo de destino con `mosctl block`.

### Recomendando nodos de ejecución

Cuando lanzamos un proceso, podemos indicar como se va a comportar frente a la migración, o donde preferimos que se ejecute. Para ello, contamos con el comando `mosrun`. Este comando no se suele llamar directamente, sino a través de un conjunto de scripts que facilitan su uso. Con este comando podemos transmitir a openMosix la información sobre qué hace el proceso, información que será fundamental para que openMosix minimice el desperdicio de recursos del cluster al mínimo. También podemos indicar un conjunto de nodos entre los cuales estará el nodo donde migrará el proceso después de lanzado, si esta migración es posible. En un sistema que no sea openMosix, `mosrun` lanza el proceso en la máquina local de forma correcta.

El comando `mosrun` siempre tiene la misma estructura de llamada:

`mosrun donde migracion tipo comando argumentos`

Donde los parámetros son:

`donde`: nodo al que el proceso va a migrar inmediatamente después de ser lanzado, si esto es posible.

`migracion`: si se bloquea o no el proceso en el nodo de destino.

`tipo`: tipo de proceso que se lanzará.

`comando`: nombre del proceso que se va a lanzar.

`argumentos`: argumentos del proceso que se va a lanzar

El modificador `donde` puede ser:

Un nodo de destino, al que el proceso migrará inmediatamente después de ser lanzado, si esto es posible.

-h, en cuyo caso será el nodo local.

-jlista: en este caso, inmediatamente después de lanzar el proceso, lo migrará a un nodo escogido aleatoriamente dentro de la lista de rangos `lista`. Esta lista es una lista de nodos y rangos, donde los rangos de nodos se determinan separando el menor y el mayor de rango por un guión. Por ejemplo, si indicamos el parámetro `-j1,4-6,8,19-21`, inmediatamente después de lanzar el proceso, de poder migrar el proceso, este migraría a un nodo aleatorio entre los nodos: 1,4,5,6,8,19,20 y 21.

El valor de la opción de `migracion` puede ser:

-l: el algoritmo de equilibrado automático de carga puede forzar una migración del proceso después de haber migrado dicho proceso al nodo de destino.

-L: una vez migrado al nodo de destino, el proceso se quedará en él y no podrá migrar de forma automática.

-k: el proceso heredará la propiedad de migrabilidad de su padre.

El valor de `tipo` es un dato muy importante que sirve de ayuda al algoritmo de migración automática de carga, y este puede ser:

-c: en un nodo de memoria infinita, el proceso tiene como cuello de botella la velocidad del procesador.

-i: en un nodo de memoria infinita, el proceso tiene como cuello de botella el acceso a disco.

Además de los modificadores anteriormente citados, con `mosrun` también podemos informar a openMosix sobre la forma en que openMosix debe mantener las estadísticas de uso de los recursos del sistema del proceso, datos fundamentales para que el algoritmo de equilibrado automático de carga tome decisiones correctas. Estos modificadores son:

-f: mantiene las estadísticas de uso de los recursos del sistema del proceso durante poco tiempo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que tienen durante su evolución comportamientos similares durante largos periodos de tiempo.

-s: mantiene las estadísticas de uso de los recursos del sistema del proceso a largo plazo. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que cambian constantemente de comportamiento.

-n: mantiene las estadísticas de uso de los recursos del sistema del proceso desde el principio del programa hasta su finalización. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores en procesos que están constantemente cambiando su comportamiento, y no podemos confiar en lo que hacían hace poco.

Hay también un conjunto de shell scripts que ayudan a no enfrentarse contra las complejidades de `mosrun` al lanzar una tarea en el uso diario del cluster, y que nos permiten realizar las tareas más frecuentes de `mosrun` de forma cómoda. Estas utilidades tienen siempre la misma sintaxis, que es:

`utilidad proceso argumentos`

Donde `utilidad` es el nombre del shell script, `proceso` el proceso que vamos a lanzar, y `argumentos` los argumentos del proceso que lanzaremos. Las utilidades que disponemos son:

cpujob: ejecuta un proceso, indicando a openMosix que si la memoria del nodo fuera infinita su cuello de botella sería el procesador.

iojob: ejecuta un proceso, indicando a openMosix que si la memoria del nodo fuera infinita su cuello de botella será el acceso a disco.

nomig: ejecuta un comando en el nodo local de forma que este no podrá migrar de forma automática.

nunhome: ejecuta un comando de forma que preferencialmente no migrará.

omrunon: ejecuta un proceso, e inmediatamente después lo migra, si es posible, al nodo especificado. La sintaxis de llamada es la de lanzar un proceso directamente desde línea de comando. Útil para lanzar un proceso desde línea de comandos recomendando un nodo de ejecución.

omsh: ejecuta un proceso, e inmediatamente después lo migra, si es posible, al nodo especificado. La sintaxis de llamada es la de `sh` como cuando lanzamos el proceso con `sh -c`, lo que lo hace especialmente útil para sustituir a sh en shell scripts.

fastdecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso durante poco tiempo. Esto hace que las `predicciones` de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que tienen durante su evolución comportamientos similares durante largos periodos de tiempo.

slowdecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso a largo plazo. Esto hace que las `predicciones` de openMosix sobre el comportamiento de un proceso sean mejores ante procesos que cambian constantemente de comportamiento.

nodecay: ejecuta un proceso, indicando a openMosix que mantenga las estadísticas de uso de los recursos del sistema del proceso desde el principio del programa hasta su finalización. Esto hace que las predicciones de openMosix sobre el comportamiento de un proceso sean mejores en procesos que están constantemente cambiando su comportamiento, y no podemos confiar en lo que hacían hace poco.

Como sucedía en el caso de `mosrun`, si lanzamos un proceso con una de estas utilidades en una máquina sin soporte openMosix habilitado, o con este mal configurado, el proceso se lanzará perfectamente de forma local.

### openMosixView

No podemos hablar de openMosix pasando por alto openMosixView, que es una cómoda y amigable aplicación de monitorización de un cluster openMosix.

openMosixView no está en las herramientas de área de usuario de openMosix por defecto. Y la razón es muy simple: las herramientas de área de usuario son lo mínimo que necesita cualquier administrador o usuario de openMosix para poder trabajar. Y en la mayor parte de las instalaciones de openMosix, la mayor parte de los nodos son cajas sin monitor, ratón o teclado con una instalación mínima de Linux, por lo que en principio openMosixView solo sería un problema para el administrador, que puede no tener interés en instalar las QT y KDE en una máquina que sólo va a servir procesos. A diferencia de las herramientas de área de usuario, que tienen una necesidad de bibliotecas y compiladores preinstalados mínima, openMosixView necesita muchas bibliotecas instaladas para ejecutarse y más aún para compilar, lo que hace poco práctico compilar y usar openMosixView en un nodo minimal.

Sin embargo, esto no quita que openMosixView sea una excelente herramienta de gran utilidad, y que todo administrador de openMosix podría tenerla instalada en la máquina desde la que inspecciona todo el cluster. Por ello, aunque no la haya incluido, recomiendo a todo administrador que se la descargue y la instale en los nodos que quiera utilizar como terminal gráfico del cluster.

## 5.3.5 Optimizando el cluster

### Ayudando al algoritmo de equilibrado de carga

El primer paso que podemos dar para mejorar aún más el rendimiento es ayudar al algoritmo de equilibrado de carga proveyéndole de más información sobre las características de los nodos que forman el cluster. En el caso de los clusters heterogéneos esto es fundamental; ya que queremos que los procesos migren preferentemente a los nodos más potentes, y que la migración libere a los nodos menos potentes.

Tal y como queda el cluster cuando acabamos de instalar openMosix, el cluster ya optimiza el aprovechamiento de recursos en un cluster homogéneo -es decir, en el que todas las máquinas son iguales en potencia-. Sin embargo, el aprovechamiento de los recursos en un cluster heterogéneo aún no llega al óptimo. Para solucionar esto, podemos modificar la potencia relativa que un nodo considera que tiene. En la fecha en la que se escribe este artículo no existe una herramienta de calibración automatizada, por lo que debemos hacer esto nodo a nodo con la herramienta manual de calibración, `mosctl`, con el modificador `setspeed`.

`mosctl` con el modificador `setspeed` es una herramienta que, ejecutada sobre un nodo, permite alterar el parámetro de la potencia computacional que un nodo cree que tiene. Junto con la información de la carga, el nodo transmite también este parámetro al resto de los nodos del cluster, por lo que cada nodo debe lanzar `mosctl setspeed` en algún punto de la ejecución de los scripts de inicialización si el cluster tiene máquinas distintas y queremos aprovechar el cluster al máximo.

Actualmente en openMosix empleamos como unidad una diezmilésima de la potencia de cálculo de un Pentium-III a 1.4GHz. Esto es una unidad arbitraria, ya que la potencia depende también de la velocidad de memoria, de si el bus es de 33MHz o de 66MHz, y de la tecnología de la memoria. Además, para algunas tareas un procesador de Intel es más rápido que uno de AMD, mientras que para otras el mismo procesador de AMD puede ser más rápido que el mismo procesador de Intel.

Actualmente lo mejor que podemos hacer es estimar a ojo cuanto puede ser el procesador de cada nodo más lento o rápido que un Pentium-III a 1.4GHz para el tipo de tareas que lanzaremos en el cluster; y después asignamos dicha potencia relativa de prueba para cada nodo, usando para ello el comando:

`mosctl setspeed valor`

donde `valor` es la potencia computacional del procesador así calculada.

Una vez que ya tenemos el cluster en pruebas o en producción, siempre podemos ajustar el valor para que el cluster tenga el comportamiento que queremos. En esta segunda etapa, por lo tanto, ajustamos los valores `a ojo` en valores empíricos: si notamos que un nodo suele estar demasiado cargado, le bajamos el factor de potencia de cómputo. Por otro lado, si notamos que un nodo suele estar desocupado mientras que los otros nodos trabajan demasiado, siempre podemos subir su potencia computacional estimada con este comando. Esto se puede hacer también con el cluster en producción, sin ningún problema adicional, usando el comando anteriormente citado.

Un truco habitual en openMosix es jugar con la potencia computacional estimada del nodo para mejorar la respuesta del cluster al usuario. Para ello, aumentamos un 10% de forma artificial la potencia computacional estimada de los nodos sin monitor ni teclado, que sólo se dedican al cálculo, mientras que bajamos un 10% la potencia computacional estimada de los nodos con monitor y teclado en los que el usuario lanza tareas. De hecho, en algunos nodos especí ficos que sabemos que van muy justos porque tienen ya problemas para responder a un usuario común, bajamos un 20% la potencia computacional estimada. Con esto estamos forzando a priori algunos sentidos de migraciones.

El desperdicio de recursos del cluster será ligeramente mayor, ya que estamos dando datos erróneos de forma intencionada al algoritmo de equilibrado automático de carga. A cambio, el usuario observará una mejor respuesta al teclado y al ratón, ya que los nodos de acceso con más frecuencia tendrán un porcentaje de procesador libre para responder a una petición instantánea del usuario, sobre todo con carga media en el cluster. De cualquier forma, este truco sólo es útil cuando tenemos un cluster mixto, con nodos dedicados y no dedicados.

### Modificando las estadísticas de carga

El subsistema de migración automática de procesos necesita información sobre como evoluciona el comportamiento del cluster. Esta información con el tiempo se tiene que descartar, ya que lo que pasaba en el cluster hace varias horas no debería afectar al comportamiento actual del cluster.

La información no se almacena de forma `eterna`. Se va acumulando de forma temporal, pero la importancia de los históricos de los sucesos va decreciendo según se van haciendo estas estadí sticas más antiguas. El hecho de mantener la información de los históricos durante un tiempo permite que los picos de comportamiento anómalo en el uso del cluster no nos enmascaren el comportamiento real del cluster. Pero, por otro lado, la información debe desaparecer con el tiempo, para evitar que tengamos en cuenta sucesos que ocurrieron hace mucho tiempo, pero que ahora no tienen importancia.

Hemos aprendimos como ajustar la estadí stica de los procesos, proceso por proceso. Sin embargo, ahora estamos hablando de un concepto distinto: ahora hablamos de la estadística de uso de los recursos de un nodo, y no de la estadística de un proceso en particular. Del mismo modo que en el artículo anterior aprendimos a ajustar el tiempo que se mantenían las estadísticas de un proceso, ahora veremos como se ajusta el parámetro para un nodo en concreto.

El comando que usamos para determinar el tiempo que se mantienen las estadísticas de un nodo es `mosctl`, con el modificador `setdecay`.

El uso de los recursos de un nodo en un cluster openMosix es una medida compuesta del uso de los recursos por los procesos que tienen un ritmo de decaída de la estadísticas lento, y el uso de los recursos por los procesos que tienen un ritmo de decaídas rápido. La sintaxis de la instrucción que determina el cálculo de la medida será:

`mosctl setdecay intervalo procentajelento porcentajerápido`

Donde `intervalo` será el intervalo en segundos entre recálculos de las estadísticas, `porcentajelento` el tanto por mil de uso que se almacena originado por procesos con decaída lenta de estadísticas, y `porcentajerápido` el tanto por mil que se almacena de procesos con decaída rápida de estadísticas.

Como lo hemos explicado aquíqueda un poco difícil de entender, asíque lo veremos con un ejemplo:

`mosctl setdecay 60 900 205`

Esto hace que las estadísticas históricas por nodo se recalculen cada 60 segundos. Se recalculan utilizando para acumular resultados como factor de ponderación un 90% para la carga de los procesos de decaída lenta de antes de los últimos 60 segundos, un 20,5% para la carga de los procesos de decaída rápida de antes de los últimos 60 segundos, y la carga del sistema de los últimos 60 segundos sin ponderación.

Esto nos permite hacer que las estadísticas por nodo -no por proceso- evolucionen a más velocidad -lo que mejora el aprovechamiento cuando la carga del cluster más frecuente son procesos largos y de naturaleza constante-, o que sean las estadí sticas más constantes en el tiempo -lo que mejora el aprovechamiento en clusters donde hay muchos procesos muy pequeños ejecutándose de forma aleatoria-.

Podemos también obtener la información de los parámetros de permanencia de históricos en un cluster openMosix para un nodo particular con el comando `mosctl` y el modificador `getdecay`. La sintaxis del comando es:

`mosctl getdecay`

### Programando openMosix

Para programar openMosix a bajo nivel -es decir, tomando el control del cluster y de la migración- podemos emplear tres mecanismos:

Hacer uso de las herramientas de área de usuario. Este es el mecanismo recomendado para scripts en Perl, o para usar en shell-scripts. Hacer uso del sistema de ficheros /proc. En Linux tenemos un sistema de ficheros virtual en /proc. Este sistema de ficheros no existe físicamente en el disco, y no ocupa espacio; pero los archivos y los directorios que en él nos encontramos nos modelan distintos aspectos del sistema, tales como la memoria virtual de cada proceso, la red, las interrupciones o la memoria del sistema, entre otras cosas. openMosix no puede ser menos, y también podemos obtener información sobre su comportamiento y darle órdenes a través de /proc. Este método de operación es ideal en cualquier lenguaje que no tiene un método cómodo para llamar a procesos externos, pero nos permite acceder con facilidad a archivos, leyendo y escribiendo su contenido. Este es el caso de la práctica totalidad de los lenguajes de programación compilados. Encontramos en los cuadros adjuntos algunos de los ficheros más importantes del /proc de openMosix que podemos tener interés en leer o escribir. Hacer uso de la biblioteca de openMosix. El área de usuario de openMosix incluye una biblioteca en C que puede ser utilizada para hacer todo aquello que pueden hacer las herramientas de área de usuario. Este mecanismo sólo funciona en C, pero es el más cómodo para los programadores en este lenguaje. No hablaremos más de él, aunque tenemos documentación disponible en el proyecto openMosix sobre como funciona. Las bibliotecas están obsoletas, y estoy trabajando en unas bibliotecas de área de usuario nuevas.

### Planes futuros de openMosix

En la fecha de la escritura de este artículo, el equipo de openMosix está trabajando en varias características nuevas de gran interés para la comunidad.

El equipo de área de kernel está trabajando en el porting de openMosix a IA64. Este porting está siendo subvencionado por HP, y supondrá el salto a los 64 bits de openMosix. Es un proyecto pensado para que openMosix sea un elemento clave en el campo de la industria.

Werner Almesberger ha desarrollado un parche para hacer los sockets migrables. El parche aún no está muy probado, aunque hablaremos de los sockets migrables bajo openMosix en el momento que este parche sea estable.

Por otro lado, David Santo Orcero está trabajando en una nueva biblioteca de área de usuario con soporte a semántica de grid. Tiene compatibilidad inversa con la biblioteca actual, por lo que tendremos SSI transparente también con la nueva biblioteca; pero para usar las nuevas características de grid sería necesario usar el nuevo API.

### Ficheros en /proc/hpc

Los ficheros y directorios y directorios más importantes que encontramos en /proc/hpc son:

/proc/hpc/admin: contiene algunos ficheros importantes de administración.

/proc/hpc/config: configuración del cluster openMosix.

/proc/hpc/gateways: número de saltos máximo entre redes para un paquete de openMosix.

/proc/hpc/nodes: directorio que contiene un subdirectorio por cada nodo del cluster, y que permite administrar el cluster desde cada nodo.

### Ficheros en /proc/hpc/admin

Los ficheros más importantes que tenemos en el directorio /proc/hpc/admin son:

/proc/hpc/admin/bring: si escribimos en este fichero un `1` desde un nodo, los procesos lanzados desde dicho nodo volverán al nodo raíz. /proc/hpc/admin/block: si escribimos en este fichero un `1` desde un nodo, bloqueamos la llegada al nodo de cualquier proceso que se haya generado en un nodo externo.

### Ficheros de configuración e información de cada proceso

En Linux, cada proceso tiene un subdirectorio en /proc, cuyo nombre es el PID del proceso, que contiene importante información del proceso. Si tenemos openMosix activado, encontraremos algunos ficheros adicionales para cada proceso en su directorio. De entre estos ficheros adicionales, destacamos:

/proc/PID/cantmove: si el fichero no puede migrar fuera del nodo, encontramos en este archivo la razón por la que el proceso no puede emigrar en el momento en el que se consulta este archivo. Esta condición puede cambiar si el proceso cambia su comportamiento, o entra/sale de modo virtual 8086.

/proc/PID/nmigs: número de veces que un proceso ha migrado. Si este número es demasiado alto, probablemente tenemos mal calibrado el cluster, y tenemos que aumentar el coste de migración.

/proc/PID/goto: si escribimos un número en este fichero, openMosix intentará que el proceso al que fichero `goto` le corresponda migre al nodo cuyo número de nodo sea el que hemos grabado en el fichero. Puede no migrar a donde hemos pedido que migre: la migración en este caso nunca es obligatoria, y el sistema, aunque hará lo que pueda por migrarlo, puede no hacerlo.

/proc/PID/where: dónde un proceso se está ejecutando en la actualidad. Observamos que mientras que /proc/PID/goto es de escritura, /proc/PID/where es de lectura.

### Ficheros de configuración e información de cada nodo

Al igual que tenemos un directorio por proceso desde el que podemos manipular cada proceso, tenemos un directorio por nodo desde el que podemos manipular cada nodo. Los directorios están en `/proc/hpc/nodes`, y tienen como nombre de directorio el número de nodo openMosix.

Los ficheros más importantes que encontramos dentro del directorio de cada nodo son:

/proc/hpc/nodes/identificadornodo/CPUs: El número de procesadores que tiene el nodo cuyo identificador es `identificadornodo`, si es un nodo con más de un procesador y además tiene el soporte SMP activado en el kernel. Dos veces el número de procesadores que tiene el nodo, si es un nodo con procesadores Pentium IV e hyperthreading activado. `1` en otro caso no listado anteriormente.

/proc/hpc/nodes/identificadornodo/load: Carga asociada al nodo cuyo identificador es `identificadornodo`.

/proc/hpc/nodes/identificadornodo/mem: memoria disponible lógica para openMosix en el nodo cuyo identificador es `identificadornodo`.

/proc/hpc/nodes/identificadornodo/rmem: memoria disponible física para openMosix en el nodo cuyo identificador es `identificadornodo`.

/proc/hpc/nodes/identificadornodo/tmem: memoria total de la máquina, libre o no, en el nodo cuyo identificador es `identificadornodo`.

`/proc/hpc/nodes/identificadornodo/speed`: potencia del nodo cuyo identificador es `identificadornodo`. Recordemos que es el valor que hemos dicho al nodo que tiene. No es un valor calculado, se lo damos nosotros como administradores del cluster. Es el valor de velocidad del que hablamos en este artículo.

/proc/hpc/nodes/identificadornodo/status: estado del nodo cuyo identificador es `identificadornodo`. Estudiamos los estados de un nodo con detalle en el artículo anterior.

/proc/hpc/nodes/identiciadornodo/util: coeficiente de utilización del nodo cuyo identificador es `identificadornodo`. Estudiamos el coeficiente de utilización de un nodo en el artículo anterior.