Este artículo lo guía a través de la configuración manual para la hibernación en Fedora Linux 36 Workstation usando BTRFS y está basado en unesencia por eloylp en github.
Objetivo y justificación
La hibernación almacena el estado de tiempo de ejecución actual de su máquina, de hecho, el contenido de su RAM, en el disco y realiza un apagado limpio. En el próximo arranque, este estado se restaura del disco a la memoria de modo que todo, incluidos los programas abiertos, esté como lo dejó.
Fedora La estación de trabajo utiliza ZRAM. Este es un enfoque sofisticado para intercambiar usando compresión dentro de una porción de su RAM para evitar los archivos de intercambio más lentos en el disco. Desafortunadamente, esto significa que no tiene espacio persistente para mover su RAM durante la hibernación cuando apaga su máquina.
Cómo funciona
La técnica configura systemd y dracut para almacenar y restaurar el contenido de su RAM en un archivo de intercambio temporal en el disco. El archivo de intercambio se crea justo antes y se elimina justo después de la hibernación para evitar problemas con ZRAM. No se recomienda un archivo de intercambio persistente junto con ZRAM, ya que crea algunos problemas confusos que comprometen la estabilidad de sus sistemas.
Una palabra sobre compatibilidad y expectativas.
Es posible que la hibernación que sigue a esta guía no funcione perfectamente en su(s) máquina(s) en particular. Debido a las posibles deficiencias de ciertos controladores, es posible que experimente fallas como wifi o pantalla que no funcionan después de reanudar la hibernación. En ese caso, no dude en comunicarse con la sección de comentarios delesencia en githubo pruebe los consejos de la sección de resolución de problemas al final de este artículo.
Los cambios introducidos en este artículo están vinculados a las unidades systemd hibernation.service e hibernation.target y, por lo tanto, no se ejecutarán por sí solos ni interferirán con su sistema si no inicia una hibernación. Dicho esto, si no funciona, aún agrega una pequeña hinchazón que es posible que desee eliminar.
Hibernación en Fedora Puesto de trabajo
El primer paso es crear un subvolumen btrfs para contener el archivo de intercambio.
$ btrfs subvolume create /swap
Para calcular el tamaño de su archivo de intercambio, use swapon para obtener el tamaño de su dispositivo zram.
$ swapon NAME TYPE SIZE USED PRIO /dev/zram0 partition 8G 0B 100
En esto example la máquina tiene 16G de RAM y un dispositivo zram de 8G. ZRAM almacena aproximadamente el doble de la cantidad de RAM del sistema comprimida en una parte de su RAM. Deja que eso se hunda por un momento. Esto significa que, en total, la memoria de esta máquina puede contener 8G * 2 + 8G de RAM, lo que equivale a 24G de datos sin comprimir. Cree y configure el archivo de intercambio usando los siguientes comandos.
$ touch /swap/swapfile # Disable Copy On Write on the file $ chattr +C /swap/swapfile $ fallocate --length 24G /swap/swapfile $ chmod 600 /swap/swapfile $ mkswap /swap/swapfile
Modifique la configuración de dracut y reconstruya su initramfs para incluir el
reanudar el módulo, para que luego pueda restaurar el estado en el arranque.
$ cat <<-EOF | sudo tee /etc/dracut.conf.d/resume.conf add_dracutmodules+=" resume " EOF $ dracut -f
Para configurar grub para que le diga al kernel que se reanude desde la hibernación usando el archivo de intercambio, necesita el UUID y el desplazamiento físico.
Use el siguiente comando para determinar el UUID del archivo de intercambio y tome nota.
$ findmnt -no UUID -T /swap/swapfile dbb0f71f-8fe9-491e-bce7-4e0e3125ecb8
Calcule el desplazamiento correcto. Para hacer esto, lamentablemente necesitará gcc y elfuente de la herramienta btrfs_map_physical, que calcula el desplazamiento físico del archivo de intercambio en el disco. Invoque gcc en el directorio en el que colocó la fuente y ejecute la herramienta.
$ gcc -O2 -o btrfs_map_physical btrfs_map_physical.c $ ./btrfs_map_physical /path/to/swapfile FILE OFFSET EXTENT TYPE LOGICAL SIZE LOGICAL OFFSET PHYSICAL SIZE DEVID PHYSICAL OFFSET 0 regular 4096 2927632384 268435456 1 <4009762816> 4096 prealloc 268431360 2927636480 268431360 1 4009766912 268435456 prealloc 268435456 3251634176 268435456 1 4333764608 536870912 prealloc 268435456 3520069632 268435456 1 4602200064 805306368 prealloc 268435456 3788505088 268435456 1 4870635520 1073741824 prealloc 268435456 4056940544 268435456 1 5139070976 1342177280 prealloc 268435456 4325376000 268435456 1 5407506432 1610612736 prealloc 268435456 4593811456 268435456 1 5675941888
El primer valor en la columna COMPENSACIÓN FÍSICA es el relevante. en lo anterior example es4009762816.
Tome nota del tamaño de página que obtiene de getconf PAGESIZE.
Calcule el kernel resume_offset a través de la división del desplazamiento físico por el tamaño de la página. En esto example eso es 4009762816 / 4096 = 978946.
Actualice su archivo de configuración de grub y agregue los parámetros de línea de cmd del núcleo resume y resume_offset.
grubby --args="resume=UUID=dbb0f71f-8fe9-491e-bce7-4e0e3125ecb8 resume_offset=2459934" --update-kernel=ALL
El archivo de intercambio creado solo se usa en la etapa de hibernación del apagado y arranque del sistema, por lo tanto, no está configurado en fstab. Las unidades Systemd controlan este comportamiento, así que cree las dos unidades hibernate-preparation.service e hibernate-resume.service.
$ cat <<-EOF | sudo tee /etc/systemd/system/hibernate-preparation.service [Unit] Description=Enable swap file and disable zram before hibernate Before=systemd-hibernate.service [Service] User=root Type=oneshot ExecStart=/bin/bash -c "/usr/sbin/swapon /swap/swapfile && /usr/sbin/swapoff /dev/zram0" [Install] WantedBy=systemd-hibernate.service EOF $ systemctl enable hibernate-preparation.service $ cat <<-EOF | sudo tee /etc/systemd/system/hibernate-resume.service [Unit] Description=Disable swap after resuming from hibernation After=hibernate.target [Service] User=root Type=oneshot ExecStart=/usr/sbin/swapoff /swap/swapfile [Install] WantedBy=hibernate.target EOF $ systemctl enable hibernate-resume.service
Systemd realiza comprobaciones de memoria en el inicio de sesión y la hibernación. Para evitar problemas al mover la memoria de un lado a otro entre swapfile y zram, deshabilite algunos de ellos.
$ mkdir -p /etc/systemd/system/systemd-logind.service.d/ $ cat <<-EOF | sudo tee /etc/systemd/system/systemd-logind.service.d/override.conf [Service] Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1 EOF $ mkdir -p /etc/systemd/system/systemd-hibernate.service.d/ $ cat <<-EOF | sudo tee /etc/systemd/system/systemd-hibernate.service.d/override.conf [Service] Environment=SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1 EOF
Reinicie su máquina para que los cambios surtan efecto. La siguiente configuración de SELinux no funcionará si no reinicia primero.
A SELinux todavía no le gustarán los intentos de hibernación. Cambie eso con una nueva política. Un enfoque fácil aunque “bruto” es iniciar la hibernación y usar el registro de auditoría de este intento fallido a través de audit2allow. El siguiente comando fallará y lo regresará a un indicador de inicio de sesión.
systemctl hibernate
Una vez que haya iniciado sesión nuevamente, verifique el registro de auditoría, compile una política e instálela. La opción -b filtra las entradas del registro de auditoría del último arranque. La opción -M compila todas las reglas filtradas en un módulo, que luego se instala usando semodule -i.
$ audit2allow -b #============= systemd_sleep_t ============== allow systemd_sleep_t unlabeled_t:dir search; $ cd /tmp $ audit2allow -b -M systemd_sleep $ semodule -i systemd_sleep.pp
Verifique que la hibernación esté funcionando a través de systemctl hibernate nuevamente. Después de reanudar, verifique que ZRAM sea de hecho el único dispositivo de intercambio activo.
$ swapon NAME TYPE SIZE USED PRIO /dev/zram0 partition 8G 0B 100
Ahora tiene la hibernación configurada.
Integración de hibernación de GNOME Shell
Es posible que desee agregar un botón de hibernación a la sección “Apagar / Cerrar sesión” de GNOME Shell. Mira la extensiónBotón de estado de hibernaciónpara hacerlo
Solución de problemas
Un primer lugar para solucionar cualquier problema es a través de journalctl -b. Eche un vistazo al final del registro, después de intentar hibernar, para identificar las entradas de registro que le indiquen qué podría estar mal.
Otra fuente de información sobre errores es la herramienta Informe de problemas. Especialmente problemas, que no son comunes pero son más específicos de su configuración de hardware. Mírelo antes y después de intentar la hibernación y vea si surge algo. Haga un seguimiento de cualquier problema a través de BugZilla y vea si otros experimentan problemas similares.
Revertir los cambios
Para revertir los cambios realizados anteriormente, siga esta lista de verificación:
- eliminar el archivo de intercambio
- eliminar el subvolumen de intercambio
- elimine la configuración de dracut y reconstruya dracut
- elimine los argumentos cmdline del kernel a través de grubby –remove-args=
- deshabilitar y eliminar los servicios de preparación y reanudación de la hibernación
- elimine las anulaciones de systemd para systemd-logind.service y systemd-hibernation.service
- elimine el módulo SELinux a través de semodule -r systemd_sleep
Créditos y recursos adicionales
Este artículo es un esfuerzo comunitario basado principalmente en el trabajo de eloylp. Como autor de este artículo, me gustaría dejar en claro que participé en la discusión para avanzar en la esencia detrás de esto, pero muchas más mentes contribuyeron para que esto funcione. Asegúrese de revisar eldiscusión en github.
Ya existen algunos libros de jugadas y scripts de shell de Ansible para automatizar el proceso descrito en esta guía. Para example echa un vistazo a los scripts de shell porKrokwenySuresteo el libro de jugadas ansible desí
Ver elwiki del arcopara obtener la guía completa sobre cómo calcular el desplazamiento del archivo de intercambio.