Hibernación en Fedora Puesto de trabajo

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 de

Ver elwiki del arcopara obtener la guía completa sobre cómo calcular el desplazamiento del archivo de intercambio.

Actualizaciones del boletín

Ingrese su dirección de correo electrónico a continuación para suscribirse a nuestro boletín