Conceptos

El directorio /usr nació de un disco lleno, y Linux ha tardado medio siglo en pagar la factura

Por Equipo Cloud Privado · · 12 min de lectura
Dos discos, uno lleno que se desborda al otro rotulado /usr, y a la derecha /bin como enlace hacia /usr/bin

Un vistazo en 30 segundos

  • Hacia 1971, Ken Thompson y Dennis Ritchie pasaron Unix a un PDP-11 con dos discos RK05 de 1,5 MB. El primero era la raíz del sistema y el segundo, montado en /usr, guardaba las carpetas de los usuarios. Cuando el sistema dejó de caber en el primero, siguió creciendo en el segundo. De ahí salen /usr/bin y /usr/lib.
  • La historia la contó Rob Landley en 2010, en la lista de correo de BusyBox. Es un relato posterior y muy verosímil, no un acta de la época.
  • El disco desapareció hace décadas, pero las rutas se quedaron. Juntarlas es lo que se llama merged-/usr: /bin, /sbin y /lib pasan a ser enlaces simbólicos hacia sus equivalentes dentro de /usr.
  • Un matiz que se suele contar mal: merged-/usr es obligatorio en Debian desde la versión 12 (bookworm, 2023), no desde la 13. Lo que ha cerrado Debian 13 es la mudanza de los ficheros de cada paquete a su sitio real, que costó más de 1.500 horas de trabajo.
  • En la práctica, si administras Debian 13 o Proxmox VE 9, hay una consecuencia que rompe scripts: dpkg -S /bin/bash funcionaba en Debian 12 y en Debian 13 ya no encuentra nada. Ahora la pregunta buena es dpkg -S /usr/bin/bash.

Quien haya abierto una terminal de Linux se ha cruzado con la duplicidad sin pararse a pensarla. Hay un /bin y un /usr/bin, un /lib y un /usr/lib, un /sbin y un /usr/sbin. Durante años la explicación oficial fue más o menos esta: en la raíz va lo imprescindible para arrancar y en /usr va todo lo demás. Suena a diseño. No lo es. O no lo fue al principio.

La explicación más conocida es bastante más prosaica. Tiene que ver con un disco que se llenó en 1971. Y lo curioso no es que aquello pasara, porque cualquiera habría hecho lo mismo, sino que la solución de emergencia haya sobrevivido más de cincuenta años y que deshacerla haya costado a Debian seis años de discusiones, un comité técnico, una moratoria y un buen puñado de actualizaciones rotas.

Tres megas y un disco lleno

El relato viene de un correo que Rob Landley, que mantuvo BusyBox durante años, envió el 9 de diciembre de 2010 a la lista del proyecto. Alguien preguntaba por qué BusyBox repartía sus enlaces entre cuatro directorios, kill en /bin y killall en /usr/bin, y Landley respondió con una clase de historia. OSnews la recogió en 2012 y desde entonces es la versión que circula.

Según Landley, Thompson y Ritchie crearon Unix en un PDP-7 en 1969 y hacia 1971 pasaron a un PDP-11 con un par de discos RK05 de 1,5 megabytes cada uno. El primero era la raíz del sistema. El segundo, montado en /usr, guardaba los directorios personales de los usuarios, y de ahí viene el nombre: usr de user, no de Unix System Resources, que es una reinterpretación muy posterior.

Cuando el sistema operativo dejó de caber en el primer disco, lo dejaron desbordarse al segundo. Replicaron allí la estructura, bin, lib, tmp, y empezaron a escribir en esas carpetas nuevas porque en el disco original ya no había sitio. Cuando llegó un tercer disco lo montaron en /home, trasladaron allí a los usuarios y dejaron que el sistema ocupara los dos primeros enteros. Tres megas en total.

De ahí salió además una regla que tenía todo el sentido: al arrancar, el sistema tiene que ser capaz de montar el segundo disco en /usr. Así que lo necesario para llegar hasta ese punto, empezando por el propio mount, no podía vivir en /usr/bin. Esa es la semilla del «en la raíz va lo imprescindible para arrancar».

Conviene tratar el relato con el cuidado que merece. Es la reconstrucción que hizo Landley casi cuarenta años después, no una nota de Thompson o de Ritchie escrita en 1971 explicando su decisión. Encaja con el hardware de la época y con la estructura que conocemos, y nadie la ha desmentido, pero no hay un acta de aquella reunión, si es que hubo reunión.

Por qué la separación no murió cuando dejó de hacer falta

El propio Landley daba en ese correo tres razones por las que la separación había dejado de tener sentido antes incluso de que existiera Linux:

  • El arranque temprano ya lo resuelve otra pieza. Hoy lo hace el initramfs, un sistema temporal en memoria que monta lo necesario antes de pasar el control al sistema real. El problema del huevo y la gallina de 1971 tiene otra solución.
  • Las bibliotecas compartidas atan las dos mitades. En los setenta todo se enlazaba de forma estática y cada disco tenía cierta independencia. Con bibliotecas compartidas, lo que hay en /lib y lo que hay en /usr/bin tiene que casar, o nada funciona. Separarlas en dos particiones no aporta nada.
  • Los discos crecieron. Hacia 1990 un disco doméstico ya pasaba de los 100 MB, y poco después apareció el software para redimensionar particiones.

Pero una ruta no se jubila porque deje de tener sentido. Se jubila cuando nadie depende de ella, y de /bin/sh depende medio mundo. Con los años, además, fueron apareciendo justificaciones nuevas para la separación que ya existía: la raíz para lo que venía de AT&T y /usr para lo que añadía el fabricante, /usr montado en solo lectura o compartido por red entre varias máquinas, /usr/local para lo propio de cada instalación y, cuando /usr/local se quedó corto, /opt. Cada capa tenía su lógica. Ninguna volvía a la original.

Qué es merged-/usr

La solución que han adoptado las grandes distribuciones es sencilla de explicar. Todo el sistema vive dentro de /usr y los directorios antiguos de la raíz pasan a ser enlaces simbólicos:

Ruta de siempreEn un sistema merged-/usr
/binenlace a /usr/bin
/sbinenlace a /usr/sbin
/libenlace a /usr/lib
/lib64 (en amd64)enlace a /usr/lib64

Así, /bin/bash y /usr/bin/bash son el mismo fichero y las rutas que tiene grabadas el software viejo siguen funcionando. Fedora lo hizo en 2012, con la versión 17, y Arch en 2013. Debian lo convirtió en el formato por defecto de las instalaciones nuevas en Debian 10 (buster, julio de 2019).

Por qué entonces le ha costado tanto a Debian es la parte interesante. Mover directorios es fácil. Lo difícil es que el gestor de paquetes entienda que dos rutas distintas son ya el mismo sitio.

Dos nombres para un mismo fichero

dpkg lleva la cuenta de qué fichero pertenece a qué paquete por su ruta. Si un paquete dice que instaló /bin/foo, para dpkg eso es /bin/foo, y /usr/bin/foo es otra cosa distinta. En un sistema fusionado, sin embargo, las dos rutas son el mismo fichero. Debian llama a eso aliasing, y de ahí salen casi todos los problemas.

El más grave es la pérdida de ficheros al actualizar. Imagina que una biblioteca pasa de /lib a /usr/lib y, a la vez, cambia de paquete. El paquete nuevo instala /usr/lib/libfoo.so. Después, dpkg retira el paquete viejo y borra lo que según sus registros le pertenecía, /lib/libfoo.so. Pero en un sistema fusionado esa ruta apunta al mismo fichero que acaba de instalar el paquete nuevo. Resultado: la biblioteca desaparece a mitad de la actualización, según el orden en que dpkg desempaquete y retire cada paquete.

No es teoría. En febrero de 2020 los desarrolladores de Debian ya discutían en su lista si seguía teniendo sentido instalar libgcrypt en /lib en vez de en /usr/lib, precisamente por este riesgo. Y el fallo #993755 dejó el caso de manual: al saltar de Debian 10 directamente a una versión posterior, /usr/bin/perl dejaba de encontrar libcrypt.so.1, la configuración de libc6 fallaba y dpkg se quedaba sin poder seguir, porque sus propios scripts dependen de Perl. Las notas de Debian 12 lo recogen con el mensaje de error literal y dejan claro que ese salto de dos versiones no está soportado.

La documentación técnica del proceso, la DEP-17 que impulsó Helmut Grohne y que se aceptó en marzo de 2023, enumera doce clases de problemas: pérdida de ficheros al moverlos, disparadores que no se ejecutan, desvíos (diversions) que dejan de tener efecto, alternativas en conflicto, directorios vacíos que se borran o enlaces esenciales que desaparecen. Cada uno pedía un arreglo distinto.

Seis años de transición, con fechas

Puesta en orden, la secuencia explica por qué se tardó tanto:

FechaQué pasó
Julio de 2019Debian 10 instala merged-/usr por defecto en las instalaciones nuevas. Las antiguas se quedan como estaban.
Febrero de 2021El Comité Técnico resuelve que Debian 12 solo admitirá el formato fusionado.
Agosto de 2021debhelper 13.4 empieza a instalar las unidades de systemd en /usr/lib/systemd. Un mes después, la versión 13.5.2 lo revierte.
Octubre de 2021El Comité Técnico pide dejar de mover ficheros de paquetes concretos de la raíz a /usr «al menos por ahora». Es la moratoria.
Marzo de 2023Se acepta la DEP-17 con el plan para resolver el aliasing.
Junio de 2023Sale Debian 12: merged-/usr pasa a ser obligatorio y los sistemas antiguos se convierten al actualizar.
Agosto a noviembre de 2023debhelper aprende a reconocer unidades bajo /usr (13.11.6) y luego a instalarlas allí (13.11.8). La moratoria se levanta por fases.
Agosto de 2024Los fallos pendientes de la mudanza pasan a ser críticos para la publicación: o se arreglan o el paquete no entra en Debian 13.
Agosto de 2025Sale Debian 13, con los ficheros de cada paquete ya registrados en su ubicación física real, dentro de /usr.
Diciembre de 2025Grohne da por terminada la transición: más de 1.500 horas de trabajo de la comunidad, 700 de ellas pagadas por Freexian.

La moratoria se entiende mejor con el problema de la pérdida de ficheros delante. Si cada mantenedor movía sus ficheros a /usr por su cuenta, en versiones distintas y sin herramientas preparadas, cada mudanza podía provocar el fallo anterior en algún sistema. Así que el comité pidió parar, preparar primero la infraestructura y mover después todo de forma coordinada. No era un paso atrás. Era no empezar la casa por el tejado.

El caso de systemd que tardó casi dos años

Hay un episodio que resume bien la dificultad, porque no fue técnico sino de gobierno.

El 2 de octubre de 2021, Ferenc Wágner abrió el fallo #995569 contra debhelper: dh_installsystemd no hacía caso de las unidades de systemd que el proyecto original dejaba en /usr/lib/systemd/system. Solo miraba en /lib/systemd/system. El efecto era que esos servicios no se habilitaban, arrancaban ni paraban al instalar o actualizar el paquete, como sí pasaba con los demás.

Recordemos que debhelper ya había intentado ese cambio en agosto y había tenido que revertirlo en septiembre. Su mantenedor, Niels Thykier, contestó que no pensaba tocarlo hasta que el Comité Técnico aclarase cómo quería resolver la transición. Añadir esa función facilitaba que cada mantenedor moviera sus ficheros a /usr por su cuenta, justo lo que el comité estaba a punto de desaconsejar, y no quería invertir en algo que quizá tuviera que deshacer otra vez.

El 20 de febrero de 2023, Michael Biebl, uno de los mantenedores de systemd en Debian, puso cifras al problema en el fallo #1031695: 35 paquetes de Debian unstable instalaban 78 unidades en /usr/lib/systemd/system que dh_installsystemd ignoraba. Ojo, el fallo no era de systemd, que llevaba años leyendo unidades de las dos rutas. Estaba en las herramientas de empaquetado de Debian.

El arreglo lo firmó Helmut Grohne en agosto de 2023 (debhelper 13.11.6, publicado el día 28). El mensaje del cambio lo aclara: la herramienta pasa a reconocer las unidades bajo /usr, pero no mueve nada. La mudanza de verdad llegó en noviembre, con la 13.11.8, y la documentación actual de dh_installsystemd ya da usr/lib/systemd/system como destino.

Es la parte de estas transiciones que nunca sale en los titulares. Cambiar un directorio es una línea. Conseguir que el gestor de paquetes, las herramientas de construcción, los scripts de mantenimiento, el instalador y decenas de miles de paquetes lo entiendan sin romper una sola actualización es un proyecto de varios años.

Un matiz que suele contarse mal

Se lee a menudo que Debian 13 es la versión que hizo obligatorio merged-/usr. No es así, y la diferencia importa si administras servidores.

  • Debian 12 (bookworm) ya exige el formato fusionado. Las notas de publicación lo dicen en su apartado 5.1.14, «A merged-/usr is now required», y cualquier sistema antiguo se convierte al actualizar a esa versión.
  • Debian 13 (trixie) no cambia el aspecto del sistema de ficheros. Lo que hace es terminar la mudanza por dentro: cada paquete registra ya sus ficheros en su ruta física real, bajo /usr, en lugar de en la ruta de la raíz que ahora es solo un alias. Por eso Grohne escribe que una actualización de Debian 12 a 13 difícilmente tropezará con problemas de aliasing.

Si un servidor ha llegado a Debian 12, ya está fusionado. Lo que cambia con Debian 13 es cómo contesta dpkg, y eso sí puede romperte algo.

Qué cambia en un servidor con Debian 13 o Proxmox VE 9

Proxmox VE 9 y Proxmox Backup Server 4 están construidos sobre Debian 13, así que todo lo que sigue se aplica tal cual a sus nodos. Lo hemos comprobado con las imágenes oficiales de Debian 12.15 y 13.7.

1. Comprobar que el sistema está fusionado. Es un comando:

stat -c '%N' /bin /sbin /lib
# '/bin' -> 'usr/bin'
# '/sbin' -> 'usr/sbin'
# '/lib' -> 'usr/lib'

En un nodo amd64 aparecerá también /lib64. En arm64 no existe, así que no te extrañe si lo buscas en un nodo de Proxmox VE sobre ARM64 y no está.

2. dpkg -S ha cambiado de respuesta. Es la consecuencia más práctica y la que menos se cuenta. En Debian 12 los paquetes seguían registrando sus ficheros en la raíz. En Debian 13 los registran bajo /usr. El resultado es este:

ConsultaDebian 12Debian 13
dpkg -S /bin/bashbash: /bin/bashno path found
dpkg -S /usr/bin/bashno path foundbash: /usr/bin/bash

Cualquier script que averigüe de qué paquete viene un binario (un inventario, una comprobación de integridad, una regla de cumplimiento, un playbook que decide qué reinstalar) y que use la ruta antigua fallará en Debian 13 sin avisar de nada raro. Solo dirá que el fichero no pertenece a ningún paquete. Si tus herramientas hacen eso, la solución es resolver antes la ruta real, por ejemplo con dpkg -S "$(readlink -f /bin/bash)", o probar las dos. Es de lo primero que revisamos al auditar un servidor Linux heredado y de lo que conviene tener en cuenta si inventarías parches en una flota, como contamos en el post de PatchMon.

3. Software propio que da por hecho dos ficheros distintos. Las notas de Debian 12 lo advierten: el software ajeno a Debian que cuente con que /bin/nombre y /usr/bin/nombre sean dos ficheros diferentes no está soportado y hay que arreglarlo o quitarlo antes de actualizar. Es raro, pero pasa en instaladores antiguos de fabricantes y en scripts que copian un binario a una ruta «de respaldo».

4. Imágenes de contenedor: reconstruir, no actualizar dentro. Las mismas notas avisan de que los sistemas montados sobre una capa base que no se puede escribir directamente, como las imágenes de contenedor en varias capas con overlayfs, no se pueden convertir de forma segura con una actualización normal. Hay que actualizar la capa base por separado o sustituir la imagen. Traducido: si tienes imágenes construidas sobre un Debian 11 antiguo, no hagas apt full-upgrade dentro; reconstrúyelas desde la imagen base nueva. Lo mismo aplica a las imágenes OCI que ahora puede ejecutar Proxmox VE 9.2 como contenedores.

5. El mensaje «System is tainted: unmerged-bin». Desde la versión 256, systemd considera que /usr/bin y /usr/sbin también deberían estar fusionados, y lo anota al arrancar. En Debian 13 verás ese aviso, porque Debian mantiene /usr/sbin aparte. Las notas de publicación son claras: hay que ignorarlo, y fusionar esos directorios a mano no está soportado y romperá actualizaciones futuras. Fedora sí dio ese paso en la versión 42, donde /usr/sbin ya es un enlace a bin. Es la siguiente capa de la misma historia, y en Debian aún no toca.

6. Si construyes tus propias imágenes de sistema. Proyectos como Yocto o Buildroot, que generan el sistema de ficheros pieza a pieza en lugar de instalar una distribución completa, tienen que decidir de forma explícita si el resultado va fusionado o no. Donde vive una biblioteca, un ejecutable o una unidad de systemd forma parte de la receta, y un script que funcione en uno de los dos formatos puede fallar en el otro.

Lo que nos llevamos

En 1971, usar el segundo disco cuando el primero se llenó era lo razonable. Lo sorprendente es la vida que tuvo después. El disco desapareció hace décadas, pero las rutas se quedaron y acabaron convertidas en un contrato implícito entre el sistema operativo, las aplicaciones y las herramientas que los administran. Deshacerlo en Debian ha costado seis años y más de mil quinientas horas.

La lectura práctica para quien opera servidores es parecida a la que sacamos con Go y los binarios estáticos: lo que parece un detalle de organización, una ruta, suele sostener más cosas de las que se ven. En las plataformas que gestionamos, antes de una actualización mayor revisamos qué scripts preguntan a dpkg por rutas de la raíz, qué imágenes de contenedor conviene reconstruir en lugar de actualizar y qué software de terceros da por hecho una estructura que ya no existe. Si tienes nodos de Proxmox VE 8 pendientes de pasar a la 9, o servidores Debian que llevan años sin tocar una versión mayor, cuéntanos cómo los tienes y lo planificamos contigo.

Preguntas frecuentes

¿Por qué existe /usr en Linux?

La explicación más aceptada es la de Rob Landley: hacia 1971, el Unix de Thompson y Ritchie corría en un PDP-11 con dos discos de 1,5 MB. El segundo estaba montado en /usr y guardaba las carpetas de los usuarios. Cuando el sistema dejó de caber en el primero, siguió creciendo en el segundo, replicando allí bin y lib. Es un relato de 2010, no un documento de la época.

¿Qué significa merged-/usr?

Es la organización del sistema de ficheros en la que /bin, /sbin, /lib y /lib64 dejan de ser directorios propios y pasan a ser enlaces simbólicos hacia /usr/bin, /usr/sbin, /usr/lib y /usr/lib64. Todo el sistema vive dentro de /usr y las rutas antiguas siguen funcionando.

¿Desde qué versión es obligatorio merged-/usr en Debian?

Desde Debian 12 (bookworm, junio de 2023). Debian 10 ya lo usaba por defecto en las instalaciones nuevas, y Debian 13 (trixie) completó la mudanza de los ficheros de cada paquete a su ubicación real dentro de /usr.

¿Por qué dpkg -S no encuentra /bin/bash en Debian 13?

Porque en Debian 13 los paquetes registran sus ficheros en la ruta física, /usr/bin/bash, y no en el alias de la raíz. dpkg -S /usr/bin/bash sí responde. Para scripts que tengan que funcionar en las dos versiones, lo más seguro es resolver primero la ruta real con readlink -f.

¿Afecta a Proxmox VE?

Sí. Proxmox VE 9 y Proxmox Backup Server 4 se basan en Debian 13, así que sus nodos están fusionados y dpkg se comporta como en Debian 13. Un nodo que venga de Proxmox VE 8 ya pasó por la conversión al actualizar a Debian 12.

¿Debo hacer caso al aviso «System is tainted: unmerged-bin»?

No. Lo emite systemd desde la versión 256 porque Debian mantiene /usr/bin y /usr/sbin separados. Debian recomienda ignorarlo y advierte de que fusionar esos directorios a mano no está soportado y romperá actualizaciones futuras.

Fuentes

El comportamiento de stat y dpkg -S lo hemos comprobado con las imágenes oficiales debian:12 (12.15) y debian:13 (13.7). La historia de 1971 es el relato de Rob Landley; la presentamos como tal.