Swap, swapfile e hibernación en GNU/Linux
Una duda generalizada en la comunidad linuxera es el uso de la swap (ya sea como partición de disco o como archivo) y sus implicancias en la hibernación del sistema. Este artículo pretende aclararlas.
Hace algunos días se produjo una más que interesante y amistosa discusión en el grupo de Telegram de la Comunidad JuncoTIC. Si bien es un tema que he explicado más de una vez en mis cursos y clases, la verdad es que los amigos del grupo me pusieron en duda, y eso no tiene precio, te obliga a investigar, a realizar experimentos, a usar el método científico para encontrar evidencias que justifiquen tus argumentos. Aquí les resumo las conclusiones a las que llegamos.
El tema fue swap, swapfile e hibernación. Básicamente, la duda sobre la relación entre el tamaño de la partición de intercambio swap, y la función de hibernación del sistema operativo, y, además, si es necesario disponer de una partición de swap para poder realizar la hibernación. Para incorporar más complejidad, se sumó el concepto de archivo swap, o swapfile, y si podía considerarse como partición swap a la hora de hibernar la computadora.
La swap (espacio de intercambio)
La memoria swap, o memoria de intercambio, es una porción de memoria persistente (*) que se utiliza en los sistemas operativos para permitir a las aplicaciones correr cuando la disponibilidad de memoria RAM física es escasa.
En otras palabras, cuando vamos ejecutando aplicaciones en nuestra computadora, se van cargando páginas en memoria RAM que permiten a dichas aplicaciones su ejecución. Estas páginas corresponden con datos, variables, archivos, instrucciones binarias, etc.
Las aplicaciones sí o sí necesitan cargar datos en memoria RAM para poder ejecutarse. Ahora, si disponemos de poca RAM (o muchas aplicaciones abiertas) necesitaremos más memoria para poder ejecutar aplicaciones nuevas. Como la memoria no es infinita, la swap, o espacio de intercambio, permite «volcar» parte de esa RAM, a través de diversas políticas (páginas menos usadas, páginas más viejas, etc) a un almacenamiento persistente (*) como un disco.
Este espacio de almacenamiento persistente (*) se denomina espacio de intercambio, o de swap, y puede ser una partición, o un archivo, llamado archivo de intercambio, o swap file.
Cabe aclarar que, a fines prácticos, para el sistema operativo es indistinto si estamos usando una partición swap o un archivo swap, o incluso, si usamos otros mecanismos de memoria swap (*). Todos ellos son considerados de forma transparente como «espacio de intercambio».
La hibernación y la suspensión
Cuando uno suspende el sistema, éste pasa a un modo de bajo consumo en el que se apagan los discos, y la mayoría de los dispositivos de hardware, y sólo se le da alimentación eléctrica a la memoria RAM para que no pierda su contenido. Al iniciar nuevamente la computadora se reactivarán los dispositivos, y tendremos el sistema en el mismo estado en el que quedó cuando suspendimos.
La hibernación, por su parte, va un poco más allá. Es un mecanismo por el cual un sistema operativo se «suspende» y genera una imagen del contenido de la memoria RAM, y lo escribe en el almacenamiento persistente, es decir, en el disco.
Para poder hibernar es necesario que el espacio de intercambio o swap sea de al menos el tamaño de la memoria RAM. Si bien he leído que si el sistema tiene poca carga puede hibernarse en una swap de menor tamaño que la RAM, no es recomendable ni aplicable a todos los casos. Por otro lado, para sistemas con memorias grandes (sobre los 32 o 64GiB) no es recomendable hibernar. Sobre el tamaño de la swap puede ampliarse información acá.
Las preguntas (y las respuestas)
Teniendo en cuenta esto, surgen algunas preguntas: ¿En qué parte del disco se escribe esta imagen? ¿En la partición swap? ¿en un archivo en otra parte del disco? ¿Sirve un archivo swap a este propósito? Si no tengo swap: ¿puedo hibernar el sistema?.
Luego de algunas investigaciones y experimentos, llegamos a la conclusión de que para poder hibernar el sistema es necesario un espacio de intercambio, ya que la hibernación genera una imagen del estado de la memoria RAM y lo escribe en este espacio de intercambio o swap de manera persistente.
A su vez, este espacio de intercambio puede ser la clásica partición de swap, o un archivo swapfile, es indistinto (o casi, ver más adelante), como mencioné, para el sistema operativo es totalmente transparente en alto nivel si el espacio de intercambio está almacenado en un archivo en disco, o es una partición con su sistema de archivo swap propio.
Los fundamentos
Una de las razones por las que llegamos a la conclusión planteada fue un experimento que realicé en una vieja máquina virtual Debian que disponía de una partición swap.
Primero, inicié la computadora para analizar el estado de los discos:
- Una partición principal, /dev/sda1, de 14GiB, montando el sistema de archivos raíz.
- Una partición de intercambio, /dev/sda5, con sistema de archivos swap, de 2GiB aproximadamente.
El experimento fue muy sencillo:
- Iniciar la computadora normalmente.
- Hibernar y reiniciar para verificar que el sistema de hibernación estuviera funcionando correctamente.
- Hibernar nuevamente y reiniciar utilizando un sistema live para verificar el estado de la swap sin modificarla.
- Borrar el contenido de la partición swap y reiniciar.
- Verificar cómo inicia el sistema
En el punto 5 podíamos sacar dos conclusiones:
- Si el sistema iniciaba normalmente (de cero), significaba que efectivamente toda la información de hibernación se había almacenado en la partición de swap.
- Si el sistema iniciaba en el estado de hibernación, significaba que la imagen de hibernación se había almacenado en otro lugar del disco, no en la swap.
La conclusión ahora es obvia: la información de hibernación se había guardado en la partición de swap, ya que al formatearla el sistema inició como si nada hubiera pasado: un inicio limpio.
No obstante, me sorprendí con algunos resultados.
Al iniciar el sistema previamente hibernado, y desde un medio live (usé la iso de un xubuntu si mal no recuerdo) la partición de swap del sistema instalado no figuraba ya como «linux-swap» como suele denominarse al sistema de archivos de intercambio, sino que hacía referencia a la hibernación, o «suspensión a disco» (suspend-to-disk).
En Gparted la partición de swap figuraba como «linux-suspend«:
Ante la duda, recurrí a parted para verificarlo, y efectivamente, aquí figuraba como «swsusp«:
Ya que tenía el Gparted abierto, lo utilicé para darle formato «linux-swap» a la partición de intercambio, y reinicié el ordenador virtual. Como dije, el arranque fue limpio, como si nunca hubiera suspendido.
¿linux-suspend? ¿swsusp?
Esto sí me sorprendió, así que ya tenía la punta del ovillo para ahondar en la búsqueda, y me di con una página de FAQ de la documentación del núcleo Linux en la que explica el proceso completo de suspend-to-disk (hibernación) y resume (restauración de la imagen). A saber:
- Suspensión:
- Solicitamos la hibernación en un sistema en ejecución.
- Se detienen los procesos de usuario.
- Se congelan/detienen los dispositivos para que no interfieran con el estado de la imagen de hibernación (snapshot).
- Se crea la imagen de hibernación: se copia el contenido completo de la memoria RAM con las interrupciones desactivadas.
- Se vuelven a activar los dispositivos.
- Se escribe la imagen generada dentro del espacio de intercambio o swap.
- Se suspenden todos los dispositivos, y se apaga el sistema.
- Restauración:
- Se enciende la computadora.
- El sistema verifica si debe iniciar normalmente o desde hibernación (lo detecta por el tipo de formato de la partición swap).
- Si es hibernación, congela/detiene todos los dispositivos para que no interfieran con la restauración de la imagen de hibernación.
- Se restaura la imagen de hibernación desde la swap hacia la memoria RAM.
- Se reactivan los dispositivos nuevamente.
- Se reactivan todos los procesos de usuario en su estado original.
Como datos adicionales e interesantes de esta documentación se pueden rescatar:
- Solamente puede hibernarse a una partición swap única o activa, es decir, si disponemos de varias particiones swap, se utilizará una sola para hibernar, por lo que deberá contar con el tamaño apropiado.
- Dije antes que se puede utilizar indistintamente una partición swap como un archivo swap, y si bien esto es cierto, en el caso de ser un swapfile debe especificarse en la línea de opciones de arranque de Linux en el gestor de arranque las opciones «resume=» y «resume_offset=», de lo contrario el sistema iniciará normalmente. Para profundizar este punto es recomendable leer esta documentación.
- Si en el momento de la hibernación teníamos montado un disco externo o cualquier sistema de archivos extraíble, como un pendrive usb, y este no fue montado con la opción «sync», puede causar pérdidas de datos en buffer que no fueron volcados al dispositivo.
- Puede hibernarse el sistema a un volumen lógico LVM, aunque hay que tener algunas configuraciones adicionales presentes.
- Existe algo denominado «suspend2«, que es un fork de suspend, que extendería su funcionalidad para dar soporte a dispositivos SMB y NFS, lo que permitiría almacenar la imagen de hibernación en sistemas de archivos remotos.
Otra documentación interesante es el libro «Linux Kernel in a Nutshell: A Desktop Quick Reference», de Greg Kroah-Hartman. En la sección de opciones de inicio de Linux menciona las opciones «resume
» y «noresume
«. La primera, como mencioné, permite especificar el dispositivo en el que se encuentra la imagen de hibernación a restaurar durante el inicio del sistema, y la segunda desactiva la hibernación (si la hubiera), y transforma el espacio de intercambio swap de suspensión (swap-suspend /swsusp) en un espacio de intercambio swap común y corriente a ser utilizado… digamos, una forma «elegante» de limpiar la swap, no tan «manual» como mi experimento 😛
Otra fuente interesante es un artículo publicado en el blog de gentoo linux.
Finalmente, en la conversación en el grupo de Telegram de la Comunidad JuncoTIC compartimos una noticia de Ubuntu, no tan nueva, pero que también generaba dudas: Ubuntu abandonaba el esquema de partición de swap, y pasaba a usar swapfile, un archivo de intercambio (como Windows). La verdad, no he probado un ubuntu nuevo para comprobar esto, pero de igual manera, esto no implica que Ubuntu no pueda hibernar porque no disponga de una partición swap, puede hacerlo sin problemas en un swapfile.
(*) Swap en RAM y el Flisol2020
Generalmente cuando se menciona la swap se habla de un espacio de intercambio persistente, pero no siempre esto es así, ya que existen herramientas como zram o zswap que permiten emular ese espacio de intercambio mediante una fracción comprimida dentro de la misma memoria RAM.
Claro está que si disponemos de una swap en ram, ya sea con zram o zswap, al hibernar la computadora el sistema almacenará la imagen de hibernación en una fracción de memoria volátil, y no podrá ser recuperada.
Swap… ¡sigamos aprendiendo!
En fin, ya planteé las conclusiones y las fuentes en el artículo. La verdad es que aprendí mucho investigando y realizando pruebas, y todo por la duda que planteó uno de mis alumnos.
La conclusión ahora es: uno nunca deja de aprender, y poner en duda lo que sabemos nos obliga a profundizar y pruebas, y a adquirir nuevos conocimientos… así que: ¡bienvenida la curiosidad que nos lleva a preguntarnos y cuestionarnos todo! 😀
Fuentes (enlazadas en el artículo)
https://opensource.com/article/19/2/swap-space-poll
https://www.kernel.org/doc/Documentation/power/swsusp.txt
https://www.kernel.org/doc/Documentation/power/swsusp-and-swap-files.txt
https://www.suspend2.net/
Linux Kernel in a Nutshell
https://wiki.gentoo.org/wiki/Suspend_and_hibernate#Suspend_to_disk
https://www.redeszone.net/2016/12/19/ubuntu-17-04-cambiara-la-particion-swap-fichero-intercambio/