Power management (Português)/Suspend and hibernate (Português)
Existem múltiplos métodos de suspensão disponíveis, notavelmente:
- Suspender para ocioso
- Chamado de S0ix pela Intel, Modern Standby (antes como "Connected Standby") pela Microsoft e S2Idle pelo kernel. Projetado para ser usado ao invés do estado de sono S3 em sistemas com este suporte, de forma que fornece economia de energia idêntica, mas que reduz drasticamente o tempo exigido para acordar o sistema. Dica: Enquanto o estado mencionado acima está sujeito a problemas com drenagem de bateria no Windows ou macOS, pelo fato que ambos os sistemas conseguem acordar dispositivos neste estado de sono para exercer atividade na rede, em contrapartida, o ecossistema de software no Linux atualmente não usa este recurso, e portanto deve permanecer inalterado.
- Suspender para RAM (conhecido por suspensão)
- Este estado de sono é definido pelo ACPI como S3. O funcionamento se baseia em cortar a energia da maior parte da máquina, exceto a RAM, da qual é necessária para restaurar o estado original. Por conta da grande economia de energia, é aconselhável que notebooks/laptops entrem automaticamente neste modo quando o computador estiver descarregando as baterias e com a tampa fechada (ou quando o usuário está inativo por um certo tempo).
- Suspender para o disco (conhecido por hibernação)
- O estado de sono S4, assim como foi definido pelo ACPI, salva o estado original da máquina dentro de um espaço swap e então desliga completamente a máquina. Quando a máquina volta a ligar, o estado é restaurado. Há zero consumo de energia até o momento que ocorra o retorno do sistema.
- Suspensão híbrida (conhecido por sono híbrido)
- É um híbrido entre suspender e hibernar, às vezes chamado de suspender para ambos. O sono híbrido salva o estado original em um espaço swap, porém não há desligamento da máquina, a suspensão invocada pelo sistema é a padrão. Se a bateria não estiver esgotada, o sistema pode retornar instantaneamente; se caso houver a perda de energia, o sistema pode retornar os dados pelo disco, que no caso é mais lento do que retornar pela RAM, mas o estado original da máquina não é perdido.
O kernel oferece funcionalidade básica, e há algumas interfaces de alto nível que proporcionam ajustes finos para lidar com drivers de hardware ou módulos de kernel problemáticos (por exemplo a reinicialização da placa de vídeo).
Interface do kernel (swsusp)
É possível informar diretamente o código interno de suspensão do software do kernel (swsusp), e com isso a máquina adentrar em um estado de suspensão; o método e estado exatos dependem do nível de suporte do hardware. Em kernels modernos, escrever apropriadamente strings para /sys/power/state
é o mecanismo primário para acionar a devida suspensão.
Veja a documentação do kernel se quiser explorar os detalhes.
Interface de alto nível (systemd)
systemd fornece comandos nativos para suspensão, hibernação e suspensão híbrida. Esta é a interface padrão usada em Arch Linux.
systemctl suspend
já é configurado para funcionar automaticamente no sistema. Por outro lado, para systemctl hibernate
funcionar você precisará seguir as instruções em #Hibernação.
Há também dois modos que integram-se com a suspensão e hibernação:
-
Suspensão híbrida:
systemctl hybrid-sleep
suspende o sistema com o uso de RAM e o uso de disco, portanto uma queda de energia não resulta em perda de dados. Esse modo também é chamado de suspender para ambos. -
Suspender então hibernar:
systemctl suspend-then-hibernate
inicialmente suspende o sistema para RAM pelo tempo mais longo possível, então o sistema é acordado com um alarme RTC (relógio em tempo real) e hiberna. O alarme RTC é definido peloHibernateDelaySec
em systemd-sleep.conf(5). O valor padrão é programado de acordo com uma medida aproximada do descarregamento da bateria para manter o sistema com no mínimo 5% de bateria, ou com até 2 horas sem fonte de carga. A estimativa é obtida de acordo com a mudança de nível da bateria após um tempo especificado peloSuspendEstimationSec
no arquivo systemd-sleep.conf(5), para isso o sistema acordará brevemente e calculará uma estimativa (a medição também é feita se o sistema for acordado manualmente da suspensão).
Veja a seção #Hooks de sono para informações adicionais ao configurar os hooks de suspensão/hibernação. E também veja systemctl(1), systemd-sleep(8) e systemd.special(7) para detalhes.
Mudando método de suspensão
Em caso de sistemas que a suspensão S0ix não fornece a mesma economia de energia como o estado de sono S3 comum, ou quando a conservação de energia é preferida para um tempo de retorno rápido da suspensão, é possível alterar o método de suspensão padrão.
Execute o seguinte comando para ver todos os métodos de suspensão que o hardware notifica ter suporte (o atual método em uso é sinalizado dentro dos colchetes) [1]:
$ cat /sys/power/mem_sleep
[s2idle] shallow deep
string de mem_sleep | Estado de sono |
---|---|
s2idle | |
shallow | suspensão em espera |
deep | suspender para RAM |
Se o seu hardware não notificar o status de sono deep
, verifique primeiro se a sua UEFI possui alguma configuração de estados de sono; geralmente em "Power" ou "Sleep state", ou nomes semelhantes pelas opções nomeadas como "Windows 10", "Windows and Linux" ou "S3/Modern standby support" para S0ix; e "Legacy", "Linux", "Linux S3" ou "S3 enabled" para estados de sono S3. Se ainda assim não houver correspondências, você pode manter o uso de s2idle
. Considere usar hibernação ou tente corrigir as tabelas DSDT (ou procure uma versão com patch online).
Confirme que o hardware não exibe problemas com o estado de sono S3 ao testar alguns ciclos de sono com o método de sono alterado:
# echo deep > /sys/power/mem_sleep
Se nenhum problema foi encontrado, então você pode mudar permanentemente pela diretiva MemorySleepMode em systemd-sleep.conf(5):
/etc/systemd/sleep.conf.d/mem-deep.conf
[Sleep] MemorySleepMode=deep
Ou pelo parâmetro de kernel mem_sleep_default=deep
.
Em contrapartida, firmwares danificados anunciam o suporte como sono deep
, enquanto que apenas s2idle
é suportado. Se este for o caso, um método alternativo ao usar s2idle
está disponível pela configuração do SuspendState
:
/etc/systemd/sleep.conf.d/freeze.conf
[Sleep] SuspendState=freeze
Hibernação
Para usar a hibernação você deve criar uma partição ou arquivo swap, configurar o initramfs, desta forma o processo de retorno será inicializado pelo espaço de usuário, e por fim especificar a localização do espaço swap de acordo com a disponibilidade de opções do initramfs. Pode ser feito, por exemplo, com a variável EFI HibernateLocation
definida pelo systemd ou pelo parâmetro de kernel resume
. Estas três etapas estão detalhadas abaixo.
- Veja dm-crypt/Criptografia de Swap#Com suporte a suspender para o disco ao usar criptografia.
- linux-hardened não tem suporte para hibernar, veja em FS#63648.
- Hibernação em um espaço swap com zram não é suportado, mesmo que o zram seja configurado para persistir em um dispositivo de armazenamento não volátil. O logind irá proteger contra as tentativas de hibernação em um espaço de swap sob uso do zam. Como uma alternativa, você pode criar múltiplos espaços swap, e então armazenar a memória em um arquivo swap enquanto outro espaço swap ativo é reservado para o zram. Veja detalhes na seção #Preservando arquivo swap para hibernação com zram.
Sobre tamanho de partição/arquivo swap
Mesmo que sua partição swap seja menor que a RAM, você ainda terá uma boa chance de hibernar de forma bem sucedida. Veja "image_size" na documentação do kernel para mais informações sobre este pseudo-arquivo image_size
em sysfs(5).
Por um lado, você pode diminuir o valor de /sys/power/image_size
, e desta forma a imagem de suspensão pode ser a menor possível (para pequenas partições de swap), ou por outro, você pode aumentar o valor e possivelmente acelerar o processo de hibernação. Para sistemas com uma grande quantidade de RAM, pequenos valores podem drasticamente aumentar a velocidade de volta da hibernação. É possível manter as alterações persistentes ao configurar por um arquivo temporário no systemd, como demonstrado em systemd#systemd-tmpfiles - arquivos temporários:
/etc/tmpfiles.d/hibernation_image_size.conf
# Path Mode UID GID Age Argument w /sys/power/image_size - - - - 0
A imagem de suspensão não pode gerar múltiplas partições e/ou arquivos de swap, a mesma deve caber completamente em uma partição de swap ou em um único arquivo swap. [2]
Configure o initramfs
- Quando um initramfs baseado em busybox é usado, cujo é o padrão, a definição do hook
resume
é um requisito, e o mesmo deve ser escrito em/etc/mkinitcpio.conf
. Independente da partição swap ser chamada pelo label (rótulo de disco) ou pelo UUID, a partição usa o nó de dispositivo referenciado pelo udev, e portanto o hookresume
deve ser colocado depois do hookudev
. O exemplo a seguir foi feito a partir da configuração de hooks pré-definida:
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)
- Lembre-se de gerar novamente o initramfs para as mudanças terem efeito.
- Nota: Se o armazenamento usado para o espaço swap for em camadas (stacked), como em dispositivos criptografados, RAID ou LVM, o dispositivo mapeado, ou seja, na camada final, deve estar disponível no início do espaço de usuário e antes do processo de retorno ser inicializado. Sendo assim, nestes determinados setups o hook
resume
deve ser colocado logo após de hooks comoencrypt
,lvm2
, etc.
- Quando um initramfs com o hook
systemd
é usado o mecanismo de retorno já é proporcionado, em vista disso não é necessário adicionar outros hooks.
Definindo o local de hibernação para o initramfs
Quando o sistema hiberna a imagem da memória, e incluindo o estado dos sistema de arquivos montados, é direcionada para um espaço swap. A localização para hibernar, portanto, deve estar disponível a partir do initramfs, isto é, o local deve estar definido antes que o sistema de arquivos do root seja montado para que o sistema consiga retornar da hibernação adequadamente.
Desde a versão 255 do systemd e da versão 38 de mkinitcpio, quando o sistema está rodando em modo UEFI, systemd-sleep(8) irá automaticamente escolher um espaço swap apropriado para hibernar. A informação do espaço swap usado é armazenada na variável EFI HibernateLocation
, e na próxima inicialização do sistema o systemd-hibernate-resume(8) faz a leitura da localização na variável EFI, realizando, então, o retorno do sistema. Significa que os passos abaixo só são necessários se o sistema estiver pelo modo legado (legacy), ou BIOS, ou se caso você quiser escolher um espaço swap diferente do que é automaticamente selecionado.
Especificando o local de hibernação manualmente
O parâmetro de kernel resume=dispositivo_swap
pode ser usado quando o dispositivo_swap seguir a nomeação persistente de dispositivo de bloco. Por exemplo:
resume=UUID=4209c845-f495-4c43-8a03-5363dd433153
resume="PARTLABEL=Swap partition"
-
resume=/dev/archGrupoVolume/archVolumeLogico
- usado se o swap estiver em um volume lógico LVM (configurar por UUID e Label devem funcionar da mesma forma).
Os parâmetros de kernel só irão ter efeito após reiniciar a máquina. Para hibernar de forma imediata obtenha os números maior e menor de volume do dispositivo pelo comando lsblk e ajuste (com echo) os valores de acordo com o mesmo formato maior:menor
em /sys/power/resume
.
Por exemplo, se o dispositivo swap for 8:3
:
# echo 8:3 > /sys/power/resume
Se estiver usando um arquivo swap, adicionalmente siga os processos em #Adquirindo o offset de um arquivo swap.
Adquirindo o offset de um arquivo swap
Ao usar um arquivo swap para hibernação, o dispositivo em bloco do qual o sistema de arquivos está deve ser especificado em resume=
, com a adição do offset físico do arquivo swap através do parâmetro de kernel resume_offset=
. [3].
Em sistemas de arquivos que não são Btrfs, o valor de resume_offset=
pode ser obtido executando filefrag -v arquivo_swap
. A saída é por um formato em tabela e o determinado valor exigido está na primeira linha da coluna physical_offset
.
Por exemplo:
# filefrag -v /swapfile
Filesystem type is: ef53 File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 0: 38912.. 38912: 1: 1: 1.. 22527: 38913.. 61439: 22527: unwritten 2: 22528.. 53247: 899072.. 929791: 30720: 61440: unwritten ...
Na demonstração acima o resume_offset=
é o primeiro valor: 38912
.
Alternativamente, para adquirir diretamente o valor do offset:
# filefrag -v arquivo_swap | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'
Em sistemas de arquivos Btrfs, não tente usar a ferramenta filefrag, pois o offset "físico" obtido por filefrag não é o valor real do physical offset fornecido pelo disco. Ao invés disto existe um espaço de endereçamento virtual no disco, com o objetivo de dar suporte a múltiplos dispositivos [4]. Nesta situação use o comando btrfs-inspect-internal(8). Como por exemplo:
# btrfs inspect-internal map-swapfile -r arquivo_swap
198122980
Para aplicar a mudança de maneira imediata (sem reiniciar o sistema), use echo para definir o resume offset em /sys/power/resume_offset
. Por exemplo, se o offset for 38912
:
# echo 38912 > /sys/power/resume_offset
findmnt -no UUID -T arquivo_swap
resume
deve apontar para o dispositivo desbloqueado/mapeado que contém o sistema de arquivos com o arquivo swap.
Preservando arquivo swap para hibernação com zram
É possível resolver o problema de hibernação com compressão em RAM (zram) ao gerenciar dois ou mais espaços swap ao mesmo tempo. systemd sempre irá ignorar dispositivos de bloco zram antes de acionar a hibernação [5], portanto manter os dois espaços ativados deve funcionar sem mais intervenções.
Depois de configurado o arquivo swap, siga a página do zram. Garanta que o zram tenha a maior prioridade de swap (por exemplo, pri=100
).
- Não crie uma swap unit sob demanda para hibernação, pois não há suporte oficial. Veja as issues de systemd em #16708 e #30083
- O kernel por conta própria é responsável pela reivindicação de páginas de memória anônima e a devida alocação no swap; não usar um espaço swap pode na realidade levar a um mau uso de memória. O usuário pode gerenciar prioridades de reivindicação de memória para certas aplicações na forma de
memory.low
, refinado pelos grupos de controle. De forma geral, isto é mais efetivo do que configurar o parâmetro swappiness. - Leia sobre o Gerenciamento de Swap na documentação do kernel e o artigo do Chris Down - Em defesa ao swap: equívocos comuns para mais detalhes.
Hibernação em volume LVM de provisionamento fino
A hibernação dentro de um volume LVM de provisionamento fino é possível, mas é necessário ter certeza que o volume está totalmente alocado. Se caso não estiver, retornar o sistema por este volume falhará, veja em FS#50703.
Você pode alocar por completo o volume LVM ao simplesmente encher o mesmo com diversos zeros. Como por exemplo:
# dd if=/dev/zero of=/dev/vg0/swap bs=1M status=progress
Para verificar se o volume está totalmente alocado use:
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert swap vg0 Vwi-aot--- 10.00g pool 100
Um volume com a plena distribuição de armazenamento irá mostrar que possui o uso de dados (Data%) em 100%.
discard
em /etc/fstab
e não atribua a opção -d
/--discard
em swapon. Caso contrário o espaço usado será desalocado.Desabilitando a escritura em disco (writeback) do zswap para que o espaço swap seja usado somente ao hibernar
Na versão 6.8 do Linux, o zswap recebeu a opção de desabilitar o writeback de acordo com o cgroup quando usada a configuração de unit do systemd MemoryZSwapWriteback
(veja systemd.resource-control(5) § Memory Accounting and Control) em todos os tipos de unit que a definição seja possível; a mesma desabilitará completamente a gravação em disco do zswap e permitirá usar o zswap efetivamente como zram, com o benefício adicional de suporte a hibernação.
Para evitar a criação manual de doze arquivos drop-in, de nível superior e por tipo (com os tipos de unit para o sistema e usuário: scope
, service
, slice
, socket
, mount
, swap
), instale zswap-disable-writebackAUR. Após a instalação reinicie o sistema para que as mudanças tenham efeito.
Tente realizar tarefas intensivas de uso de memória para confirmar que o zswap não está escrevendo nada para o disco.
# cat /sys/kernel/debug/zswap/written_back_pages
0
Hooks de sono
Units do systemd customizáveis
systemd inicia respectivamente suspend.target
, hibernate.target
, hybrid-sleep.target
ou suspend-then-hibernate.target
para cada estado de sono. Todos os targets mencionados são puxados pelo sleep.target
e qualquer um dos targets pode ser usado para invocar units personalizadas antes ou depois da suspensão/hibernação. Arquivos separados devem ser criados para ações de usuários e ações de root/sistema. Exemplos:
/etc/systemd/system/suspend@.service
[Unit] Description="Descrição de ações de suspensão do usuário" Before=sleep.target [Service] User=%I Type=forking Environment=DISPLAY=:0 ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop ExecStart=/usr/bin/sflock ExecStartPost=/usr/bin/sleep 1 [Install] WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit] Description="Descrição de ações de retorno do usuário" After=suspend.target [Service] User=%I Type=simple ExecStart=/usr/local/bin/ssh-connect.sh [Install] WantedBy=suspend.target
Ative user-suspend@usuario.service
e/ou user-resume@usuario.service
para as mudanças terem efeito.
ExecStartPost=/usr/bin/sleep 1
previne que isto ocorra.Para ações de root/sistema:
/etc/systemd/system/root-suspend.service
[Unit] Description="Ações de suspensão do sistema local" Before=sleep.target [Service] Type=simple ExecStart=-/usr/bin/pkill sshfs [Install] WantedBy=sleep.target
/etc/systemd/system/root-resume.service
[Unit] Description="Ações de retorno do sistema local" After=suspend.target [Service] Type=simple ExecStart=/usr/bin/systemctl restart mnt-media.automount [Install] WantedBy=suspend.target
Unit de suspensão/retorno agregado
Com o arquivo unit que junta os estados um único hook faz todo o trabalho para diferentes fases (suspensão/retorno) e para diferentes targets.
Exemplo e explicação:
/etc/systemd/system/wicd-sleep.service
[Unit] Description="Hook de sono Wicd" Before=sleep.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=-/usr/share/wicd/daemon/suspend.py ExecStop=-/usr/share/wicd/daemon/autoconnect.py [Install] WantedBy=sleep.target
-
RemainAfterExit=yes
: Logo que iniciado o serviço é considerado ativo até que seja explicitamente pedido o encerramento. O termo significa "Continuar-Depois-de-Saída". -
StopWhenUnneeded=yes
: O serviço ativo será parado se nenhum outro serviço ativo necessitar dele. No exemplo acima em específico, o mesmo será finalizado depois que sleep.target parar. O termo significa "Parar-Quando-Desnecessário". - Por conta de sleep.target ser puxado pelos suspend.target, hibernate.target e hybrid-sleep.target, além do fato que o próprio sleep.target é um serviço StopWhenUnneeded, é garantido que o hook inicie/pare apropriadamente para diferentes tarefas.
Hooks em /usr/lib/systemd/system-sleep
systemd-sleep inicia todos os executáveis em /usr/lib/systemd/system-sleep/
, e passa dois argumentos para cada um deles:
- Tanto
pre
quantopost
, dependendo se a máquina estará suspendendo (a dormir) ou retornando da suspensão (a acordar). -
suspend
,hibernate
ouhybrid-sleep
, dependendo de qual está sendo invocado.
A saída de qualquer script personalizado terá o registro em log feito pelo systemd-suspend.service, systemd-hibernate.service ou systemd-hybrid-sleep.service. Você poderá ver a saída no próprio sistema de registro do systemd, em journalctl:
# journalctl -b -u systemd-suspend.service
Um exemplo de um script personalizado para o sono seria:
/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh case $1/$2 in pre/*) echo "Going to $2..." ;; post/*) echo "Waking up from $2..." ;; esac
Lembre-se de marcar o script como executável.
Dicas e truques
Desabilitando o sono completamente
Ao usar um dispositivo que é, por exemplo, um servidor, suspender/hibernar pode não ser necessário ou até mesmo indesejável. Cada estado de sono pode ser desabilitado através do arquivo systemd-sleep.conf(5):
/etc/systemd/sleep.conf.d/disable-sleep.conf
[Sleep] AllowSuspend=no AllowHibernation=no AllowHybridSleep=no AllowSuspendThenHibernate=no
Tecnologia Intel Rapid Start (IRST)
A Tecnologia Intel Rapid Start é um método firmware de hibernação que permite hibernar a partir do sono e logo após um intervalo pré-definido ou de acordo com o estado de bateria. Este método pode ser mais rápido e mais confiável do que a hibernação regular, por conta de ser feito pelo firmware ao invés de ser feito a nível de sistema operacional. Geralmente é necessário habilitar pelo firmware e o mesmo precisa fornecer o suporte para configurar a duração após o evento de suspender/bateria acionar a hibernação. Entretanto em alguns dispositivos, apesar de terem o suporte IRST, o firmware por si só permite configurar pelos drivers Intel do Windows. Nestes casos o módulo de kernel intel-rst descrito abaixo deverá permitir configurar eventos pelo Linux.
Com a Tecnologia Intel Rapid Start (IRST) ativada, retornar da suspensão deep sleep demora cerca de "alguns segundos a mais do que retornar pelo estado S3, porém é muito mais rápido do que voltar através da hibernação".
Muitos sistemas com base na Intel possuem o suporte para IRST no firmware, todavia estes sistemas requerem uma partição especial ou um SSD (ao invés de um HDD). As implantações OEM do Windows podem já ter uma partição IRST pré-criada, da qual pode ser mantida durante o processo de instalação do Arch Linux (uma melhor opção ao contrário de limpar e reparticionar todo o SSD). A partição deve aparecer como não formatada e com tamanho igual a capacidade de RAM do sistema.
Se você pretende limpar e reparticionar todo o armazenamento (ou se você já fez isso) e planeja usar a tecnologia, então a partição IRST precisa ser recriada; isto pode ser feito ao definir uma nova partição vazia com o mesmo tamanho da RAM e ao configurar o tipo de partição para GUID D3BFE2DE-3DAF-11DF-BA40-E3A556D89593
em caso de uma partição GPT, ou para ID 0x84
em caso de uma partição MBR. Há também a possibilidade de ser preciso ativar o suporte para IRST nas configurações de firmware do sistema.
A duração do processo de hibernação IRST (ou seja, para copiar "todo o conteúdo da RAM para uma partição especial") depende da capacidade total de RAM no sistema e da velocidade do SSD, então o processo pode durar entre 20 a 60 segundos. Alguns sistemas podem indicar o processo concluído com uma indicação por LED, por exemplo a luz pode parar de piscar para indicar a conclusão.
Configurar os eventos de hibernação IRST no kernel Linux requer o CONFIG_INTEL_RST
, que pode estar integrado ao kernel (built-in) ou deve estar por meio de módulo. Ao carregar via modprobe intel_rst
, já é esperado que haja a criação por conta própria dos arquivos wakeup_events
e wakeup_time
dentro de /sys/bus/acpi/drivers/intel_rapid_start/*/
, e demais configurações podem ser igualmente ajustadas neste mesmo local.
Este módulo foi documentado de maneira sucinta, veja a fonte do código drivers/platform/x86/intel/rst.c para mais detalhes. Veja também as perguntas frequentes e o guia de usuários para a Tecnologia Intel Rapid Start.
Solução de problemas
ACPI_OS_NAME
Você talvez precise aplicar ajustes finos na sua tabela DSDT para fazer funcionar adequadamente. Veja em DSDT.
Suspensão/hibernação não funcionam, ou não de forma consistente
Existem vários relatos sobre a imensa dificuldade de diagnosticar/visualizar erros quando a tela fica totalmente escura ou de fazer qualquer coisa quando o sistema retorna da suspensão e/ou hibernação; estes problemas foram vistos tanto em notebooks/laptops quanto em desktops. Não é uma solução oficial, mas trocar para um kernel mais antigo, especialmente para o kernel LTS, provavelmente restaura o funcionamento.
O problema pode surgir quando há o uso do temporizador watchdog pelo hardware (desabilitado por padrão, veja RuntimeWatchdogSec=
em systemd-system.conf(5) § OPTIONS). Um temporizador bugado pode reiniciar o computador antes do sistema terminar de criar a imagem de hibernação.
Às vezes a tela pode ficar escura devido a inicialização do dispositivo a partir do initramfs. Remover qualquer módulo que talvez esteja em Mkinitcpio#MODULES, remover o hook kms
e reconstruir o initramfs possivelmente soluciona o problema, em especial com drivers gráficos que iniciam com o KMS. Inicializar tais dispositivos antes do sistema retornar pode causar inconsistências que previnem o sistema de voltar da hibernação; isto, no entanto, não afeta a volta pela RAM. Além do que foi mencionado aqui, dê uma olhada no artigo do blog a seguir: As melhores práticas para depurar problemas de suspensão.
Mover o driver de vídeo ATI para o novo driver AMDGPU pode também ajudar a solucionar transtornos com o processo do sistema ao hibernar ou ao acordar, e com isso o processo ser bem sucedido.
Para usuários de NVIDIA, adicionar à lista negra o módulo nvidiafb
talvez ajude. [7]
Notebooks/laptops com uma CPU Intel e que carregam o módulo intel_lpss_pci
para touchpad podem se deparar com pânicos de kernel ao retornar o sistema (tecla Caps Lock pisca incessantemente) [8]. O módulo precisa ser adicionado ao initramfs desta forma:
/etc/mkinitcpio.conf
MODULES=(... intel_lpss_pci ...)
E então gere novamente o initramfs.
Wake-on-LAN
Se o Wake-on-LAN está ativo, a interface da placa de rede irá consumir energia mesmo se o computador estiver em hibernação.
Sistema acorda instantaneamente da suspensão
Veja a página em inglês: Wakeup triggers#Instantaneous wakeup after suspending.
Sistema não desliga quando em hibernação
Ao hibernar o seu sistema, ele precisa desligar (logo depois de salvo o estado da máquina para o disco). Em alguns firmwares o estado de sono S4 não funciona apropriadamente, por exemplo ao invés do sistema desligar ele pode reiniciar ou permanecer ligado, mas sem resposta alguma. Se isto ocorrer, é instruído que você defina o HibernateMode
para shutdown
em sleep.conf.d(5):
/etc/systemd/sleep.conf.d/hibernatemode.conf
[Sleep] HibernateMode=shutdown
A configuração acima, e se demais configurações estiverem corretas, fará com que a invocação por systemctl hibernate
desligue a máquina adequadamente, incluindo o salvamento do estado original para o disco antes de desligar.
Sistema operacional não encontrado (ou iniciando errado) ao dar boot depois da hibernação
Isto pode ocorrer quando o disco de iniciação (de boot) é um disco externo; a situação é aparentemente causada por uma limitação própria da BIOS ou do próprio firmware. A BIOS ou o firmware tenta iniciar o sistema por um disco interno, contudo a hibernação foi feita por um sistema operacional em um disco externo (ou em outro dispositivo).
Defina HibernateMode=shutdown
como mostrado em #Sistema não desliga quando em hibernação para resolver o problema permanentemente. Se você já deslogou do seu sistema, você pode tentar reiniciar o sistema 4 vezes (espere até a mensagem de erro aparecer em cada uma das vezes), em algumas BIOS isto força um processo de boot normal, ou seja, logo em seguida de várias tentativas falhas o sistema volta para o estado padrão de boot.
Arquivo swap em /home
Se o arquivo swap estiver em /home/
, systemd-logind não conseguirá acessá-lo; será retornada uma mensagem com o aviso Call to Hibernate failed: No such file or directory
, ou de forma traduzida: Chamada para Hibernação falhou: Não há arquivo ou diretório
, e isto requer que o comando systemctl hibernate
seja executado com autenticação. Este tipo de configuração precisa ser evitada, pois não há suporte no upstream. Veja a issue do systemd 15354 para conhecer duas formas de contornar a situação.
Computador não acorda do sono em placas-mãe A520I e B550I
Em placas-mãe com chipsets A520i e B550i, o sistema não irá adentrar completamente no estado de sono ou sequer retornar. Sintomas incluem o sistema entrar no sono e o monitor desligar enquanto LEDs internos da placa-mãe ou LED do botão power continuam acessos. Consequentemente o sistema não irá conseguir trocar de estado e requer desligamento forçado. Se você estiver com um problema similar na AMD, primeiro tenha certeza que seu sistema está totalmente atualizado e verifique se o pacote microcode da AMD está instalado.
Verifique se a linha que começa com GPP0
possui o status ativo (enabled):
$ cat /proc/acpi/wakeup
Device S-state Status Sysfs node GP12 S4 *enabled pci:0000:00:07.1 GP13 S4 *enabled pci:0000:00:08.1 XHC0 S4 *enabled pci:0000:0b:00.3 GP30 S4 *disabled GP31 S4 *disabled PS2K S3 *disabled GPP0 S4 *enabled pci:0000:00:01.1 GPP8 S4 *enabled pci:0000:00:03.1 PTXH S4 *enabled pci:0000:05:00.0 PT20 S4 *disabled PT24 S4 *disabled PT26 S4 *disabled PT27 S4 *disabled PT28 S4 *enabled pci:0000:06:08.0 PT29 S4 *enabled pci:0000:06:09.0
Se estiver ativado, você pode executar o comando abaixo para desativar:
# echo GPP0 > /proc/acpi/wakeup
Agora teste com systemctl suspend
e deixe o sistema dormir. Depois de alguns segundos acorde o sistema. Se funcionou, você pode deixar o ajuste permanente ao criar um arquivo unit do systemd:
/etc/systemd/system/aciona-gpp0-para-corrigir-retorno.service
[Unit] Description="Desabilita GPP0 para resolver problema de suspensão" [Service] ExecStart=/bin/sh -c "/bin/echo GPP0 > /proc/acpi/wakeup" [Install] WantedBy=multi-user.target
Recarregue o sistema pelo daemon-reload e inicie/habilite a unit recém criada.
Alternativamente, você pode criar uma regra udev. Supondo que node em sysfs de GPP0 é pci:0000:00:01.1
, como é neste exemplo, execute udevadm info -a -p /sys/bus/pci/devices/0000\:00\:01.1
para que exiba-se as informações relevantes, e então crie uma regra udev como esta:
/etc/udev/rules.d/10-gpp0-acpi-fix.rules
KERNEL=="0000:00:01.1", SUBSYSTEM=="pci", DRIVERS=="pcieport", ATTR{vendor}=="0x1022", ATTR{device}=="0x1483", ATTR{power/wakeup}="disabled"
O daemon do udev já estará monitorando as mudanças no seu sistema por padrão. Se necessário, você poderá recarregar as regras manualmente.
Suspender a partir da tecla Fn correspondente em notebooks/laptops não funciona
Se apesar de configurado não funcionar o botão para acionar o evento de sono em logind.conf, e nem mesmo ao pressionar é emitido mensagens em syslog, então provavelmente logind não está monitorando o teclado [9]. Para resolver use:
# journalctl --grep="Watching system buttons"
Você provavelmente verá algo parecido com:
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event2 (Power Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event3 (Sleep Button) May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event4 (Video Bus)
Note que não há nenhum dispositivo de teclado sendo monitorado. Liste os dispositivos de teclado com:
# stat -c%N /dev/input/by-id/*-kbd
... /dev/input/by-id/usb-SIGMACHIP_USB_Keyboard-event-kbd -> ../event6 ...
Agora obtenha o ATTRS{name}
, parte do dispositivo pai do teclado [10]. Como um exemplo, na listagem acima o dispositivo está com o evento da entrada como /event6
, o mesmo pode ser usado para buscar o nome do respectivo atributo:
# udevadm info -a /dev/input/event6
... KERNEL=="event6" ... ATTRS{name}=="SIGMACHIP USB Keyboard"
Escreva uma regra personalizada para adicionar a tag "power-switch":
/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end" SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="SIGMACHIP USB Keyboard", TAG+="power-switch" LABEL="power_switch_my_end"
Depois de recarregar as regras udev e reiniciar systemd-logind.service
, você agora deverá ver o registro do evento sendo monitorado: Watching system buttons on /dev/input/event6
, pelo journal do logind.
Sistema congela por 60 segundos e acorda de novo ou é irresponsivo após acordar
Desde a versão 256 do systemd, o mesmo congela user.slice
antes de dormir. Esse processo pode falhar devido a bugs no kernel, ocorre em particular quando o KVM está em uso. [11][12]
Os logs irão conter avisos sobre a falha antes do sistema adormecer: Failed to freeze unit 'user.slice'
. Quando tal problema acontece, tentar fazer o login (ao iniciar outra sessão) poderá falhar com a mensagem: pam_systemd(process:session): Failed to create session: Job 9876 for unit 'session-6.scope' failed with 'frozen'
.
Para reverter temporariamente o estado como anteriormente, edite systemd-suspend.service
, systemd-hibernate.service
, systemd-hybrid-sleep.service
e systemd-suspend-then-hibernate.service
com o seguinte drop-in:
[Service] Environment=SYSTEMD_SLEEP_FREEZE_USER_SESSIONS=false