Desde hace algunos meses me venía mordiendo un bug extraño en la máquina de trabajo donde a partir del kernel linux 2.6.39 e incluyendo la versión 3.0.0 el sistema se bloqueaba al inicio (el clásico freeze on boot) justo después del mensaje
Waiting for /dev to be fully populated
Y luego de eso, nada. Curioso, ya que con 2.6.38 el arranque iba de lo más normal, además que el equipo es un clon de los más comunes:
Procesador: Intel(R) Pentium(R) D CPU 2.80GHz
Motherboard: Intel Corp. D102GGC2
VGA: ATI Technologies Inc RC410 [Radeon Xpress 200]
Memoria: 1 GB
Obviamente a esa altura del arranque no hay muchos dispositivos disponibles, por lo que logs como para diagnóstico no tenía ninguno, así que por un tiempo desistí la investigación y me mantuve con el 2.6.38, ya que había que trabajar.
El primer sospechoso fue naturalmente udev, al fin y al cabo era el emisor del último mensaje que veía en pantalla. Diagnosticar problemas con udev es, digamos, un poco tedioso. Si leen el manual de udev encontrarán que en /etc/udev/udev.conf puede establecerse la variable udev_log en err, info o debug para definir la prioridad de los mensajes que serán mostrados en pantalla. Una vez hecho el cambio basta con reiniciar el equipo para ver los mensajes de información o diagnóstico correspondientes.Pero recientemente, aprovechando un día que llegué demasiado temprano, le dediqué unos minutos a este inconveniente que ya me tenía incómodo.
Desde ya es todo un pergamino de eventos el que va sucediendo en el arranque. Tantos eventos (y sin logging ni forma de recuperar los que ya pasaron) que me resultó imposible encontrar un patrón extraño o una pista siquiera de qué es lo que estaba sucediendo. Opté entonces por el clásico diagnóstico del pobre: conociendo dónde almacena udev las reglas (/lib/udev/rules.d/), fui desactivando las reglas y reiniciando el sistema tras cada cambio. Si el sistema continuaba el arranque luego del mensaje “Waiting for /dev …” entonces las reglas activadas eran inocentes; si no, alguna de las reglas activadas es la culpable. En algunos inicios no tenía gráfica, en otros no tenía disco, y en la mayoría ni siquiera teclado.
Una especie de búsqueda dicotómica me llevó, en pocos reinicios, a encontrar el archivo presuntamente culpable: 80-drivers.rules. Incluso llegué a determinar que la línea responsable era la séptima. Sin embargo el avance no fue mucho, ya que esta línea carga un montón de módulos en el kernel entre los cuales estan los de teclado y ratón: se ampliaba la lista de sospechosos.
Hasta acá, apenas si moví un paso, pero al menos llegaba a arrancar y controlar el sistema mediante SSH. Entonces un gran compañero de laburo (hat tip a Leandro), iluminado por el conocimiento (o quizá cansado de mis improperios) me recomendó: “¿y si probás cargando los módulos que faltan, uno a uno?”.
Entonces iniciamos el diagnóstico del pobre parte II. Haciendo un diff casero entre el lsmod del equipo iniciando con kernel 2.6.38 y uno iniciando con kernel 2.6.39 (sin 80-drivers.rules) llegamos a una lista de unos doce o quince módulos faltantes. Allí, tan cerca, login ssh y a probar cada uno de los módulos… pcspkr, evdev, psmouse, snd_hda_intel, todos cargaban bien… parport, fuse, ok… processor… chan! ahí se tildó todo.
AHA! El módulo processor! Pero ¿qué función cumple ese módulo? O mejor, ¿por qué sigue andando el sistema sin él?. Bueno, resulta que es el ACPI Processor Driver, que no es realmente necesario pero maneja cuestiones útiles tales como los estados de energía del procesador. Si lo recuerdan ACPI ya nos viene dando dolores de cabeza desde hace bastante.
Ya con esos datos, una búsqueda en Google reveló un dato fundamental, aunque se ve que no es nuevo: en ciertos equipos el sistema se cuelga a menos que uno cargue el módulo processor con el parámetro nocst=1.
Así que, de momento, agregué la línea
processor.nocst=1
a los parámetros de inicio del sistema y con eso estoy andando actualmente. ¿A qué se debe el bug? Ni idea, habría que hacer un bisect entre las versiones de kernel 2.6.38 y 2.6.39 para determinar cual es el commit jodido. En cualquier caso, queda como tarea para vacaciones…