Power management (Português)/Suspend and hibernate (Português) - ArchWiki

Jump to content

# Power management (Português)/Suspend and hibernate (Português)

From ArchWiki
< Power management (Português)
Status de tradução: Este artigo é uma tradução de Power management/Suspend and hibernate. Data da última tradução: 2025-06-23. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

Artigos relacionados

- systemd
- Gestão de energia
- Wakeup triggers
- swap

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)

Nota Apesar de ser possível usar a interface do kernel diretamente, do qual é mais rápida por não desempenhar nenhum manuseio extra do espaço de usuário, é aconselhável que se use uma interface de alto nível. Ao usar uma, há mais eficácia em proporcionar verificações de segurança adicionais, assim como também em fornecer os mecanismos de hook pré e pós suspensão para configurar apropriadamente o relógio de hardware, restaurar conexões sem fio, etc.

É 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)

Nota O objetivo de uma interface de alto nível é fornecer binários/scripts que podem ser chamados para efetuar suspensão/hibernação e formas de executar trabalho extra de preparação/limpeza nestes processos. Para ver sobre como automaticamente adentrar em um estado de sono ao acionar botões de energia, ao clicar em menus, ou com eventos de abertura/fechamento de tampa em notebooks/laptops, procure por mais detalhes na página de Gestão de energia#Eventos ACPI.

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 pelo `HibernateDelaySec` 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 pelo `SuspendEstimationSec` 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).

Dica systemd versão 256 oferece suporte para automaticamente selecionar a operação mais apropriada de sono com o novo comando `systemctl sleep`. Por padrão, `suspend-then-hibernate` é usado e o sistema pode recorrer e trocar para o `suspend` ou então `hibernate`, se caso não houver suporte. Veja systemctl(1) para mais informações.

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.

Dica S0ix deveria supostamente fornecer economias de energia idênticas ou melhores do que o estado S3. Veja as postagens em inglês antigas do blog da Intel: Como alcançar os estados S0ix no Linux, Solução de problemas S0ix no Linux e Eficiência do modo ocioso no Linux: Um estudo de caso para verificar a possibilidade de fazer funcionar adequadamente. Para a devida depuração, usuários de sistemas com Intel podem usar S0ixSelftestTool, enquanto que usuários de sistemas com AMD podem usar amd-debug-tools.

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

Estados de sono suportados em mem_sleep
string de mem_sleep | Estado de sono
--- | ---
s2idle | suspender para ocioso
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).

Nota A última solução acima pode causar problemas. Por conta que fabricantes pararam de corrigir bugs com o estado S3 do ACPI desde o momento que tais fabricantes regularizaram a escolha do sistema operacional Windows, e os mesmos são encorajados a usar "Modern standby" por padrão; se caso o sistema de fábrica foi propositalmente não informado, então provavelmente o hardware está de alguma forma com defeito.

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 início do 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.

Nota

- 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 com o hook `systemd` é usado o mecanismo de retorno ao sistema já é providenciado. Não é necessária a inclusão de outros hooks.

- Quando um initramfs baseado em busybox é usado, cujo é o padrão, a adiçã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 hook `resume` deve ser colocado depois do hook `udev`. 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 como `encrypt`, `lvm2`, etc.

### 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).

Nota Para um dispositivo de bloco stacked (empilhado/em camadas), como no caso de um armazenamento criptografado (LUKS), em RAID ou em LVM, o parâmetro `resume=` deve apontar para o dispositivo desbloqueado/mapeado (do qual contêm o sistema de arquivos com o arquivo swap, se caso usado. Veja também a dica abaixo).

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

Dica O comando a seguir poderá ser útil para identificar o dispositivo do qual retém o arquivo swap: `findmnt -no UUID -T arquivo_swap`

### Mudando o algoritmo de compressão de imagem para hibernação

A partir do Linux versão 6.9 [5], o algoritmo de compressão de imagem para a hibernação pode ser alterado. A compressão padrão é selecionada baseada na opção de tempo de compilação `CONFIG_HIBERNATION_DEF_COMP`, mas o mesmo pode ser sobrescrito durante o tempo de inicialização e no tempo de execução do sistema.

Diferentes algoritmos de compressão possuem características distintas e pode ser um benefício para a hibernação usar qualquer um deles, especialmente quando um algoritmo secundário (LZ4) oferece melhor velocidade de descompressão se comparado a um algoritmo padrão (LZO), do qual em troca reduz o tempo de restauração da imagem de hibernação.

Você pode sobrescrever o algoritmo padrão de duas formas:

1) Ao passar `hibernate.compressor` como um parâmetro de kernel:

    hibernate.compressor=lzo
    hibernate.compressor=lz4

2) Ao especificar o algoritmo no tempo de execução do sistema:

    # echo lzo > /sys/module/hibernate/parameters/compressor

    # echo lz4 > /sys/module/hibernate/parameters/compressor

Atualmente `lzo` e `lz4` são os algoritmos suportados, sendo o LZO o padrão.

### Preservando arquivo swap para hibernação com zram

Dica Ao invés do setup a seguir, que envolve múltiplos espaços swap, zswap pode ser usado para estabelecer um comportamento similar.

É possível resolver o problema de hibernação com um swap sob uso exclusivo do 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 [6], 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`).

Nota

- 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%.

Atenção Não use TRIM em volumes de provisionamento fino que são designados para hibernação, isto é, não use `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, habilite o zswap e 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 hibernate.target

    [Service]
    User=%I
    Type=simple
    ExecStart=/usr/local/bin/ssh-connect.sh

    [Install]
    WantedBy=suspend.target hibernate.target

Ative `user-suspend@usuario.service` e/ou `user-resume@usuario.service` para as mudanças terem efeito.

Nota Como os bloqueadores de tela podem retornar antes da tela estar "bloqueada", a tela pode piscar ao retornar da suspensão. Adicionar um pequeno tempo de espera via `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 hibernate.target

    [Service]
    Type=simple
    ExecStart=/usr/bin/systemctl restart mnt-media.automount

    [Install]
    WantedBy=suspend.target hibernate.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

Nota Este método é considerado um hack do systemd de acordo com systemd-sleep(8). systemd-sleep irá sempre executar esses hooks simultaneamente ao invés de sequencialmente. Se quiser uma interface, que já foi claramente descrita, com suporte para ordenação de execução, veja a seção #Units do systemd customizáveis.

systemd-sleep inicia todos os executáveis em `/usr/lib/systemd/system-sleep/`, e passa dois argumentos para cada um deles:

1. Tanto `pre` quanto `post`, dependendo se a máquina estará suspendendo (a dormir) ou retornando da suspensão (a acordar).
2. `suspend`, `hibernate` ou `suspend-then-hibernate`, dependendo de qual está sendo invocado.

Uma variável de ambiente chamada `SYSTEMD_SLEEP_ACTION` será configurada e ela armazenará a ação do sono que está sendo processado. Isto é principalmente útil para suspend-then-hibernate, pois o valor da variável será `suspend`, `hibernate` ou, nos casos em que a hibernação falhar, `suspend-after-failed-hibernate`.

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

### Destravando automaticamente a sessão ao retornar o sistema em localizações confiáveis

Ao retornar o sistema, você pode automaticamente desbloqueá-lo ao estar conectado em certos dispositivos ou em uma rede de internet Wi-Fi confiável.

    /etc/local-scripts/resume-unlock.sh

    #! /usr/bin/bash
    # Desbloqueie a sessão se em uma localização segura

    function trusted() {
        # Verifique se conectado a rede de internet Wi-Fi de confiança
        [[ $(iwgetid -r) == ssid_da_sua_casa ]] \
            && return 0
        # Verifique se o dispositivo USB de confiança está conectado.
        #lsusb -d xxxx:xxxx && return 0

        return 1 # Não confiável
    }

    for (( i=0; i < 10; i++ )); do
        if trusted; then
            loginctl unlock-sessions
            exit
        fi
        sleep 0.5
    done

Configure o seu ambiente desktop para que o mesmo bloqueie a sessão ao retornar o sistema, e então crie o hook de sono para executar o script acima logo após o retorno. Você também irá precisar instalar wireless_tools para ler o SSID do Wi-Fi. Se você também quiser que seja testado com quais dispositivos USB estão conectados, retire o comentário na linha `lsusb -d ...` do script e preencha com o ID do seu dispositivo de confiança. Você pode adquirir o ID do seu dispositivo ao executar `lsusb`.

### 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.

Atenção A partição que pertence a Tecnologia Intel Rapid Start não é criptografada. "A Intel recomenda desabilitar a Tecnologia Intel Rapid Start se você está usando criptografia de disco baseada em software". [7]

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.

Dica O tempo de duração antes do IRST ter efeito (e que é depois da suspensão) pode ser ajustado 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.

### Mantendo o registro das alterações de carga da bateria durante os estados de sono no notebook/laptop

Para medir o consumo de energia em estados de suspensão, use o script Batenergy para mandar o log das mudanças de carga ao journal do sistema. Isto permite comparar o consumo de energia dos estados S3 / S0x ou para averiguar se é preciso uma regressão ou correções depois de uma atualização de BIOS ou de kernel. O script necessita do bc instalado para realizar os cálculos.

## 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. [8]

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) [9]. O módulo precisa ser adicionado ao initramfs desta forma:

    /etc/mkinitcpio.conf

    MODULES=(... intel_lpss_pci ...)

E então gere novamente o initramfs.

#### Erros de dispositivo USB

O sistema talvez falhe ao suspender por conta de um dispositivo USB. Você provavelmente verá o seguinte erro:

    PM: Some devices failed to suspend, or early wake event detected
    ...
    xhci_hcd 0000:02:00.0: PM: failed to suspend async: error -16

Ou de forma traduzida:

    Alguns dispositivos falharam ao suspender ou um evento prematuro para acordar foi detectado

lspci talvez te retorne mais informações sobre o dispositivo que falhou:

    $ lspci -s 02:00.0

    02:00.0 USB controller: Advanced Micro Devices, Inc. [AMD] 500 Series Chipset USB 3.1 XHCI Controller

Tente desconectar os dispositivos da entrada do computador.

### 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 [10]. 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 [11]. 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. [12][13]

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 ao comportamento antigo, 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

Entretanto, este drop-in por si só pode prevenir o sistema de dormir. [14]

### Hibernação e sistemas com inicialização múltipla

Se você está usando um sistema com inicialização múltipla (incluindo, mas não limitado somente ao dual boot com Windows) e deseja inicializar outro sistema enquanto o seu sistema principal Arch Linux está hibernando, você deve tomar uma precaução extra para não montar o sistema de arquivos que ainda está sendo utilizado pelo sistema de hibernação. Antes de tentar montar tal sistema de arquivos com outro sistema dentro, você deve garantir este sistema de arquivos seja desmontado antes de hiberná-lo. As configurações necessárias são feitas com #Hooks de sono.

Este ponto é particularmente relevante para a partição de sistema EFI, pois já é de se esperar que o ESP seja compartilhado entre múltiplos sistemas. Veja a seção marcada na página em inglês em EFI system partition#Hibernation and multi boot systems para conhecer estratégias de mitigação. Elas também podem ser adaptadas para outros sistemas de arquivos.

Category:

- Power management (Português)

Power management (Português)/Suspend and hibernate (Português)
Add topic