Instalación Multi Arquitectura en Debian GNU/Linux: x86 y AMD64

2007-05-24 por Angel Abad, etiquetado como debian

Artículo traducido de: http://ornellas.apanela.com/dokuwiki/pub:multiarch

Introducción

Con la llegada de los sistemas que soportan la nueva arquitectura de AMD, los AMD64, llega un periodo de transición para algunas aplicaciones desarrolladas para la arquitectura de Intel IA-32 y que todavía no están portadas a AMD64. Así que muchas veces no es posible tener un sistema AMD64 puro al 100%, por la necesidad de ejecutar antiguas aplicaciones IA-32, tales como Flash, Skype o Opera.

En este escenario, es posible configurar un sistema que contenga las dos instalaciones completas, una por cada arquitectura y totalmente transparente para el usuario final. De esta manera, seremos capaces de disfrutar de las ventajas de la arquitectura de AMD y aún ser capaces de ejecutar todas las aplicaciones que son sólo para IA-32.

Es importante resaltar que este artículo se centra en sistemas Debian, aunque los conceptos aquí explicados son aplicables a cualquier distribución Linux.

Instalación

AMD64

En el ordenador se debe instalar un sistema completo AMD64. Este sistema debe tener un kernel capaz de ejecutar binarios de las dos arquitecturas (los kernels distribuidos por Debian son capaces). Simplemente haz la instalación como lo harías habitualmente.

IA-32

Un vez tengas instalado y funcionando el sistema con AMD64, el sistema IA-32 debe ser instalado en un directorio cualquiera. Se puede instalar desde el sistema AMD64 que se está ejecutando, con la ayuda de una aplicación llamada debootstrap. Esta utilidad ejecutará un proceso similar a lo que ocurre, por ejemplo, cuando instalas una Debian desde CD, pero en este caso no es necesario reiniciar o grabar un CD.

# mkdir /ia32
# debootstrap --arch i386 --verbose etch /ia32 http://ftp.fi.debian.org/debian

En el ejemplo, una Debian Etch IA-32 sera instalada bajo /ia32. Este directorio será el directorio root del nuevo sistema. Este no será el raiz del sistema AMD64 (/). Por ejemplo, /etc corresponde al sistema AMD64 y /ia32/etc al sistema IA-32.

El acceso al IA-32 será proporcionado gracias a chroot (se explica más abajo).

Configuración

Red

La configuración de la red debe ser compartida por los dos sistemas. Para conseguir esto, algunos ficheros dentro del chroot (IA-32) tienen que ser sobreescritos con enlaces simbólicos del raiz (AMD64), siguiendo la tabla de debajo:

Archivo Enlace Simbólico
/ia32/etc/hostname ../amd64/etc/hostname
/ia32/etc/hosts ../amd64/etc/hosts
/ia32/etc/hosts.allow ../amd64/etc/hosts.allow
/ia32/etc/hosts.deny ../amd64/etc/hosts.deny
/ia32/etc/resolv.conf ../amd64/etc/resolv.conf
/ia32/etc/networks ../amd64/etc/networks

Por ejemplo:

# ln -sf ../amd64/etc/hostname /ia32/etc/hostname

Esto hará un enlace simbólico de /ia32/etc/hostname a ../amd64/etc/hostname. No te preocupes por /ia32/amd64, se explicará más abajo.

Usuarios y Grupos

Es importante que las bases de datos de usuarios y grupo sean exactamente las mismas en los dos sistemas. Una manera simple (no prefecta) de hacer esto es sustituir los ficheros del chroot por enlaces simbólicos al sistema raiz (igual que la configuración de la red), como se ve en la tabla siguiente:

Archivo Enlace simbólico
/ia32/etc/passwd ../amd64/etc/passwd
/ia32/etc/shadow ../amd64/etc/shadow
/ia32/etc/group ../amd64/etc/group
/ia32/etc/gshadow ../amd64/etc/gshadow

Ejemplo:

# ln -sf ../amd64/etc/passwd /ia32/etc/passwd

Esto hará un enlace simbólico de /ia32/etc/passwd a ../amd64/etc/passwd. No te preocupes por /ia32/amd64, se explicará más abajo.

La mejor solución podría ser usar algún tipo de backend para base de datos de este tipo como por ejemplo, NIS, configurando el AMD64 como maestro y el IA-32 como esclavo, para el 100% de las bases de datos.

Una explicación de como hacer esto sería bien venida (o una solución mejor).

Iniciado

Para asegurar la trasnparencia de las operaciones dentro y fuera del chroot, algunos paths del sistema AMD64 deben ser remontados dentro del chroot IA-32. Esto también es necesario para iniciar algunos servicios dentro del sistema IA-32.

Para esto, crearemos dos ficheros de inicialización en el AMD64, que serán los responsables de iniciar algunos servicios del IA-32.

El primer fichero, lo crearemos en /etc/init.d/ia32S.sh (perteneciente a root con permisos 755), con el siguiente contenido:

#!/bin/bash

IA32_PATH="/ia32"
IA32_SERVICES="screen-cleanup xfree86-common sudo"

case "$1" in
  start)
    echo -n "Mounting IA-32 filesystems "
    for p in /dev /home /proc /root /sys /tmp /var/mail /var/tmp ; do
      mount -n -o rbind "$p" "$IA32_PATH""$p"
    done
    if [ ! -e "$IA32_PATH"/amd64 ] ; then
      mkdir "$IA32_PATH"/amd64
    fi
    mount -n -o rbind / "$IA32_PATH"/amd64
    echo OK
    echo "Starting IA-32 services..."
    for SERVICE in $IA32_SERVICES ; do
      dchroot -q -c ia32 "/etc/init.d/$SERVICE start"
    done
    echo "Finished starting IA-32 services."
    ;;
  *)
    echo "Error: Wrong usage." 1>&2
    exit 1
    ;;
esac

Y lo añadimos al sistema de inicio del AMD64:

update-rc.d ia32S.sh start 99 S .

Este script hará lo siguiente:

  • Remontará algunos directorios del AMD64 dentro del IA-32 (incluyendo el raiz / en /ia32/amd64).
  • Iniciar algunos servicios específicos dentro del chroot (la variable IA32_SERVICES).

Los directorios remontados aseguran que algunos sistemas de ficheros virtuales (como procfs y sysfs) existen dentro del IA-32, los directorios home son los mismos dentro y fuera del chroot, los directorios temporales son compartidos (en especial /tmp para permitir a las aplicaciones X11 acceder siempre a los mismos sockets Unix) y los usuarios acceden siempre a los mismos buzones de correo.

Los servicios iniciados (IA32_SERVICES) dependen de lo que tengamos instalado dentro del chroot. Los del ejemplo son simplemente para referencia. Debes mirar en /ia32/rcS.d y ver cuales aplicar a tu sistema. Los que no deben ser ejecutados son: mountvirtfs, bootlogd, keymap.sh, checkroot.sh, hwclockfirst.sh, ifupdown-clean, checkfs.sh, procps.sh, mountall.sh, mountvirtfs, ifupdown, hostname.sh, networking, mountnfs.sh, console-screen.sh, hwclock.sh, bootmisc.sh y urandom.

Algunos servicios deben ser ejecutados dentro del chroot (aparte del sistema AMD64) para asegurar que ciertas partes del sistema funcionan. En especial hay que ejecutar cron(8), ya que muchos rotados de logs son ejecutados por él. Para configurar estos servicios, crea el fichero /etc/init.d/ia32.sh (en el sistema AMD64, con usuario root y permisos 755) con el siguiente contenido:

#!/bin/bash

IA32_SERVICES="nullmailer atd cron"

case "$1" in
  start)
    echo "Starting IA-32 services..."
    for SERVICE in $IA32_SERVICES ; do
      dchroot -q -c ia32 "/etc/init.d/$SERVICE start"
    done
    echo "Finished starting IA-32 services."
    ;;
  stop)
    echo "Stopping IA-32 services..."
    for SERVICE in $IA32_SERVICES ; do
      dchroot -q -c ia32 "/etc/init.d/$SERVICE stop"
    done
    ;;
  *)
    echo "Error: Wrong usage." 1>&2
    exit 1
    ;;
esac

Y añadelo al inicio:

# update-rc.d ia32.sh defaults 99 1

La variable IA32_SERVICES debe contener los servicios que queremos/debemos iniciar. Es recomendable iniciar los servicios arriba mencionados siempre (nullmailer se verá después).

MTA

Para asegurarnos el envío de correo desde dentro y fuera del chroot, se puede configurar un MTA a eleción en el AMD64 (por ejemplo Postfix) y en el IA-32, usar nullmailer falso MTA. Nullmailer se configura para que haga relay con los mensajes al smarthost localhost (donde el Postfix del AMD64 estará escuchando en el puerto 25).

Para hacer esto, crea el fichero /etc/nullmailer/remotes (con usuario root y permisos 644) con unicamente la siguiente linea:

localhost

No debería haber más ficheros en /etc/nullmailer.

Notese que el directorio /var/spool/mail fue remontado dentro del chroot. Así que los usuarios podrán chequear su correo normalmente.

Asegurese de incluir nullmailer en el inicio de servicios del IA-32.

cront / at

Son interesantes porque los dos son programadores de tareas (inserte los dos en el inicio de servicios del IA-32). Esto asegura que se ejecutan las tareas de mantenimiento en los dos sistemas.

/etc/mtab de IA-32

El fichero /etc/mtab del IA-32 (/ia32/etc/mtab desde el sistema AMD64) es usado para almacenar información acerca de los sitemas de ficheros montados. Debe asegurarse de que este fichero es correcto, y la única manera es corregirlo manualmente para reflejar los sistemas de ficheros montados que se ven desde el sistema IA-32.

La manera mas fácil de hacer esto es configurando todo hasta el final de este artículo, reiniciar el sistema y chequear todo. Acceder al chroot con dchroot, verificar /proc/mounts para ver que está montado y corregir /etc/mtab. Para comprobar si funciona, use la herramienta df.

locate

Esta linea deberá ser corregida en el sistema AMD64:

PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /alex /var/spool /sfs /media /ia32/dev /ia32/home /ia32/proc /ia32/amd64 /ia32/root /ia32/sys /ia32/tmp /ia32/var/mail /ia32/var/tmp"

en el fichero /etc/updatedb.conf para evitar la recursividad en la base de datos de locate.

Igualmente, dentro del chroot IA-32:

PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /alex /var/spool /sfs
/media /amd64"
Acceder al chroot IA-32

El acceso al sistema IA-32 se consigue mediante un chroot. El comando chroot(8) (común en todas las distribuciones Linux) lo hace, pero unicamente para root. Las distribuciones Debian vienen una herramienta llamada dchroot que permite al administrador otorgar privilegios dentro de algunos chroots a usuarios normales.

La herramienta se configura mediante el fichero /etc/dchroot.conf. Añada la siguiente linea:

ia32 /ia32

Esto permitira a cualquier usuario del AMD64 (excepto root) acceder al chroot IA-32 en /ia32 con el comando:

$ dchroot -d -c ia32 [comando]

El [comando] será ejecutado dentro del chroot IA-32 en /ia32. El [comando] "verá" /ia32 como su directorio raiz. Por ello, todo ocurrirá como si estuviera pasando en un sistema IA-32 convencional, sin siquiera saber que otro sistema AMD64 completo está corriendo en la misma máquina. Sin el parametro [comando] obtendremos una Shell dentro del chroot.

Ahora puede instalar todo lo que necesite dentro del AMD64, y sólo unas pocas aplicaciones IA-32 dentro de su chroot IA-32. Simplemente asegurese de ejecutar el comando en el entorno adecuado!

Limitaciones

  • Como los dos sistemas utilizan el mismo kernel, todos los recursos del kernel (como los puertos de escucha TCP o UDP, ficheros abiertos, etc), son compartidos. No hay forma por ejemplo, de tener dos servidores web corriendo (uno en cada sistema) en el puerto 80. Cada uno deberá usar un puerto diferente.
  • Los nuevos puntos de montaje en el raiz del AMD64 no estarán diponibles automáticamente para las alicaciones ejecutadas dentro del chroot (p.e. un dvd montado). El administrador debe remontarlos manualmente dentro del chroot. Una posible solución sería el uso de udev o HAL para el montaje automático.
  • El software instalado dentro y fuera del chroot no tiene porque ser exactamente el mismo. Pero es interesante mantener las mismas versiones del software común en los dos sistemas para evitar problemas.
  • Las entradas del menú Debian, los menús FreeDesktop.org, los menús de Gnome o KDE son específicas de cada instalación. Sería interesante tener una aplicación que añadiese entradas de menú en el sistema AMD64 para las aplicaciones instaladas dentro del sistema IA-32 (y las llamase automáticamente dentro del chroot).
  • Desde el AMD64 es fácil llamar aplicaciones dentro del chroot (via dchroot). Pero no es posible ejecutar la operación inversa. Es decir, no funcionará por ejemplo, usando Iceweasel (Firefox) desde dentro del chroot, llamar al Evince instalado en el AMD64 para ver un pdf de un sitio web.