Jugando con una instalación de Devuan decidí habilitar los backports de Jessie, desde los cuales instalé un kernel Linux que tiene un bug de Debian por el cual no bootea (no inicia). En este artículo voy a explicar las alternativas al momento de reparar un sistema GNU/Linux (basado en Debian) que no inicia. Específicamente, cómo solucionar problemas con un kernel Linux que no bootea.

Luego de haber ejecutado apt-get update && apt-get upgrade && apt-get dist-upgrade para actualizar el kernel Linux de mi sistema Devuan desde el repositorio de backports de Debian Jessie, el sistema falló al iniciar. La pantalla casi en blanco, con el cursor en la esquina superior izquierda, pero sin titilar:

En estos casos muchos usuarios pueden entrar en pánico, sin embargo no es algo tan grave. En la mayoría de las distribuciones GNU/Linux, cuando se instala un nuevo kernel no se desinstala el kernel utilizado actualmente, sino que se guardan los anteriores (típicamente se mantienen 3 ó 5 kernels Linux instalados).

Entonces es simple poner el sistema nuevamente en funcionamiento, sólo basta con bootear con el kernel anterior (o alguno de los anteriores).

Si no se recuerda exactamente la versión de alguno de los kernels anteriores (es necesario saberla para saber qué imagen de Linux seleccionar para bootear), se puede utilizar un LiveCD (por ejemplo SliTaz), montar el sistema raíz o partición /boot y examinar las versiones de Linux disponibles:

En la captura, se observa que el sistema posee las versiones de Linux (archivos vmlinuz, config e initrd.img) "3.16.0-4-586", "4.6.0-0.bpo.1-686" y "4.7.0-0.bpo.1-686", siendo esta última la que falla al iniciar.

Por lo tanto, es posible reiniciar el sistema, y bootear la versión 4.6.

En el menú del gestor de inicio GRUB2, presionar la tecla 'e' para editar la configuración de inicio del sistema:

En la línea "linux" (imagen del kernel a iniciar), cambiar 4.7 por 4.6. Luego, en la línea "initrd" (imagen de disco en RAM inicial que contiene las utilidades para montar al sistema de archivos raíz) realizar la misma modificación. En la captura se observa cómo se han modificado ambas líneas, a excepción del mensaje (el cual no tiene importancia para el caso).

Al finalizar la edición, presionar la tecla F10 para comenzar el proceso de boot:

El sistema inicia correctamente con el kernel anterior.

Posibles soluciones

Ahora bien, haber iniciado el sistema con el kernel anterior no soluciona el problema, es necesario intentar hacer algo para que el nuevo kernel funcione. Veamos cuales son todas las posibles alternativas para tratar de descubrir el problema.

Pero antes de comenzar es importante descartar problemas con el controlador de video. No es lo mismo una pantalla negra que una pantalla donde se vea al menos un cursor (esté parpadeando o no). En caso de llegar a una pantalla en blanco, comprobar si la combinación de teclas Ctrl+Alt+Del (reiniciar el sistema) responde. También probar teclas que modifiquen las luces de teclado (esto puede dar indicios sobre qué está pasando).

Habilitar los mensajes de debug del kernel

Para tratar de tener un mejor diagnóstico de por qué no inicia este kernel, lo primero a hacer es eliminar la palabra "quiet" en la línea "linux" (si es que existe) de la configuración de GRUB2, o mejor cambiarla por "debug", para obtener más información por pantalla. Esto puede dar un buen indicio de por qué está fallando.

Además, es importante saber desde qué repositorio viene este kernel, pues es muy raro que falle una pieza tan crítica (la más importante) en una distribución GNU/Linux. Utilizar el siguiente comando:

# apt-cache showpkg linux-image-4.7.0-0.bpo.1-686

En este caso es un kernel que proviene de los backports de Jessie:

root@devuan:/home/emi# apt-cache showpkg linux-image-4.7.0-0.bpo.1-686
Package: linux-image-4.7.0-0.bpo.1-686
Versions:
4.7.8-1~bpo8+1 (/var/lib/apt/lists/ar.mirror.devuan.org_merged_dists_jessie-backports_main_binary-i386_Packages) (/var/lib/dpkg/status)
 Description Language:
                 File: /var/lib/apt/lists/ar.mirror.devuan.org_merged_dists_jessie-backports_main_binary-i386_Packages
                  MD5: 7fa644ee87a93f7ea534cf8c3ab8401b

Reinstalar el kernel

Tal vez parezca zonzo (muy al estilo Windows), pero no hay que descartar reinstalar el kernel. Habiendo iniciado con el kernel anterior, ejecutar:

# apt-get purge linux-image-4.7.0-0.bpo.1-686
# apt-get install linux-image-4.7.0-0.bpo.1-686

Para reinstalar el kernel.

Revisar cuidadosamente la salida del gestor de paquetes (especialmente en el momento en que se genera la nueva imagen initrd) ya que puede haberse pasado por alto algún error en la instalación previa.

Reconfigurar el kernel

Una alternativa para regenerar la imagen initrd sin reinstalar el kernel, consiste en reconfigurar el paquete:

# dpkg-reconfigure linux-image-4.7.0-0.bpo.1-686

Esto lanza la regeneración de la imagen initrd, si es que el problema es causado porque está corrupta.

Revisar el log del gestor de paquetes

Es recomendable revisar el log del gestor de paquetes APT, el cual se encuentra en el archivo /var/log/apt/term.log, para el caso en que se hayan pasado por alto errores durante la instalación/actualización del kernel.

Algunas veces el kernel falla al intentar cargar un módulo y se puede descubrir revisando dicho log. Por ejemplo:

Your kernel headers for kernel 4.7.0-0.bpo.1-686 cannot be found at
/lib/modules/4.7.0-0.bpo.1-686/build or /lib/modules/4.7.0-0.bpo.1-686/source.

En este caso se observa que cierto módulo requiere las cabeceras del kernel, lo cual se soluciona de forma sencilla:

# apt-get install linux-headers-4.7.0-0.bpo.1-all
# apt-get install --reinstall linux-image-4.7.0-0.bpo.1-686

Verificar la integridad de la imagen initrd

Una posibilidad es que la imagen de disco inicial esté corrupta o no se pueda extraer. Verificar el algoritmo de compresión utilizado para la misma utilizando file:

emi@devuan:~$ file /boot/initrd.img-4.7.0-0.bpo.1-686
/boot/initrd.img-4.7.0-0.bpo.1-686: gzip compressed data, last modified: Fri Dec 16 09:32:51 2016, from Unix

Verificar si es posible extraerla. Para ello se debe recurrir a la herramienta cpio.

Crear un directorio temporal donde extraer el contenido de la imagen initrd:

emi@devuan:~$ mkdir -p /tmp/initrd
emi@devuan:~$ cd /tmp/initrd

Extraer el contenido de la imagen (en este caso con zcat, pues está comprimida con GZIP):

emi@devuan:/tmp/initrd$ zcat /boot/initrd.img-4.7* | cpio -idmv 2>/dev/null

Luego es posible verificar sus archivos, por ejemplo el contenido del script de inicio:

emi@devuan:/tmp/initrd$ file init
init: POSIX shell script, ASCII text executable
emi@devuan:/tmp/initrd$ file sbin/init
sbin/init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=6948872c0e5c6e1933b25bc2ae3eb8b4f9bdac19, stripped
emi@devuan:/tmp/initrd$ head init
#!/bin/sh

echo "Loading, please wait..."

# Default PATH differs between shells, and is not automatically exported
# by klibc dash.  Make it consistent.
export PATH=/sbin:/usr/sbin:/bin:/usr/bin

[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root

En este caso el script imprime por pantalla el mensaje "Loading, please wait..." al iniciar. Si se logra ver por pantalla, significa que el kernel pudo extraer la imagen initrd con éxito. Si no, puede que tal vez no. Si se han descartado problemas con el controlador de video, y no se logra ver este mensaje en ningún momento, es altamente probable que el kernel no haya podido (o nunca llegue al punto de) extraer la imagen initrd.

Una prueba consiste en iniciar un kernel anterior con la imagen del kernel que falla. De esta forma se podrá observar el mensaje del proceso de inicio init y el inicio del sistema (que eventualmente falla porque la imagen initrd no coincide con el kernel, y éste es incapaz de montar el sistema de archivos raíz por no encontrar los módulos necesarios).

Comprobar que el kernel cuente con soporte para el algoritmo de compresión de la imagen initrd

Luego de verificar la imagen initrd, comprobar que el kernel tenga soporte para el algoritmo de compresión que utiliza la misma. Basta con examinar la configuración del kernel:

root@devuan:/boot# grep _RD_ config-4.7.0-0.bpo.1-686
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y

El kernel soporta una variedad de algoritmos de compresión, entre los que se encuentra GZIP.

Recomprimir la imagen initrd utilizando otro algoritmo

No se pierde mucho intentando esta prueba simple. Extraer la imagen initrd y comprimirla nuevamente con otro algoritmo, por ejemplo XZ.

Extraer la imagen:

root@devuan:~# mkdir -p /tmp/initrd
root@devuan:~# cd /tmp/initrd
root@devuan:/tmp/initrd# zcat /boot/initrd.img-4.7.0-0.bpo.1-686 | cpio -idmv 2>/dev/null
root@devuan:/tmp/initrd# ls
bin  conf  etc  init  lib  run  sbin  scripts

Recomprimir la imagen utilizando el algoritmo XZ:

root@devuan:/tmp/initrd# find . | cpio -o -c | xz -9 > /boot/initrd.img-4.7.0-0.bpo.1-686.xz
281152 blocks
root@devuan:/tmp/initrd# ls -l /boot/initrd.img-*
-rw-r--r-- 1 root root 14795981 dic 15 08:17 /boot/initrd.img-3.16.0-4-586
-rw-r--r-- 1 root root 15916152 dic 15 07:57 /boot/initrd.img-4.6.0-0.bpo.1-686
-rw-r--r-- 1 root root 16239683 dic 16 09:32 /boot/initrd.img-4.7.0-0.bpo.1-686
-rw-r--r-- 1 root root 11799196 dic 16 11:08 /boot/initrd.img-4.7.0-0.bpo.1-686.xz
root@devuan:/tmp/initrd# file /boot/initrd.img-4.7.0-0.bpo.1-686.xz
/boot/initrd.img-4.7.0-0.bpo.1-686.xz: XZ compressed data

Luego, intentar bootear con esta nueva imagen. Si falla es posible comprobar su integridad intentando bootearla con un kernel anterior (aunque luego falle, tal como mencioné anteriormente).

Crear una nueva imagen initrd con mkinitramfs

Para descartar que la imagen esté incompleta (luego de haberla extraído y recomprimido) es posible regenerarla utilizando la herramienta mkinitramfs:

# mkinitramfs -o /boot/initrd.img-4.7.0-0.bpo.1-686.emi 4.7.0-0.bpo.1-686

El primer parámetro es el nombre de archivo destino. Se debe especificar la versión de kernel Linux correcta como segundo parámetro.

Intentar iniciar con esta nueva imagen.

Cambiar el nombre de dispositivo donde se encuentra el sistema de archivos raíz

Si el kernel falla al momento de montar el sistema de archivos raíz, es posible probar cambiar el nombre con el que se accede al dispositivo. A veces GRUB2 utiliza el UUID para identificar el dispositivo, en lugar del nombre de dispositivo en sí.

En la línea de configuración del kernel ("linux") de GRUB2, modificar la variable root=. Por ejemplo, cambiar root=UUID=... por root=/dev/sda1 (suponiendo que /dev/sda1 es el nombre de dispositivo que contiene a la partición raíz.

Compilar el kernel

La última alternativa consiste en compilar el kernel desde los fuentes. Examinar el tutorial oficial de Debian para recompilar el kernel (rebuild del paquete).

Verificar que no se trate de un bug no resuelto

Este debería ser tal vez el primer paso: verificar en las listas de correo de Debian que no se trate de un bug no resuelto. Pero lo dejo al final del artículo para reflejar mi experiencia. Luego de probar todo y más, justo antes de compilar el kernel, noté que la versión descargada por el comando apt-get source linux coincidía con una versión informada en el reporte de bug.

Moraleja de la historia: no habilitar los backports provenientes de versiones inestables. Mucho menos actualizar a un kernel proveniente de una versión inestable.

Referencias

man apt-cache
man apt-get
man dpkg-reconfigure
man file
man gzip
man zcat
man cpio
man xz

Debian Bug report logs - #841883 - linux-image-4.7.0-1-686: cannot boot with 4.7.8-1, stuck at loading initrd

How to unpack and repack an initial ramdisk (initrd/initramfs) image?

Solucionar "Possible missing firmware" en Debian


Tal vez pueda interesarte


Compartí este artículo