sexta-feira, 20 de maio de 2016

Atenção: Cuidado ao utilizar o comando "halt" para desligar seu Raspberry Pi


Algum tempo atrás, um leitor que possui a expansão Pizula me atentou para o fato de que ao desligar o Raspberry Pi seu cooler disparava girando ao máximo. Algo um tanto estranho visto que não fazia muito sentido inicialmente, pois foram feitos testes de desligamento antes do lançamento da placa.

Uma das informações passadas é que ele utilizava o comando "halt" para desligar e quando fizemos os testes o cooler realmente continuava a girar.

Eu como velha guarda do Linux já sabia que haviam alguns efeitos diferentes ao utilizar "halt" e "shutdown" sempre utilizando esse último. Ao utilizar "halt" (Raspberry Pi 2B, Raspbian  baseado no Jessie),  o GPIO utilizado pelo PWM ficava em um estado que mantinha o cooler no máximo (e isso foi uma boa coisa por um lado, vocês irão entender abaixo). Isso não acontecia ao desligar a placa com o comando "shutdown -h now" e nem ao desligar a placa com "halt" no antigo Raspbian baseado no Debian Wheeze.

O Raspbian (Wheeze) utiliza o sistema de inicialização sysvinit, o halt é uma ferramenta dele. Antigamente o halt não deveria ser chamado diretamente, entretanto após a versão 2.74 (vide man page) do sysvinit, ao executar o halt ele chama o comando shutdown desde que o sistema não esteja em runlevel 0 ou 6. Ou seja, em um runlevel de multiusuário (nosso caso) executar halt tem praticamente o mesmo efeito que chamar shutdown. Em seu propósito original o halt não é um poweroff, ele não desliga a energia.

No Raspbian (Jessie) temos algumas diferenças, o sistema de inicialização foi trocado para o systemd, as ferramentas antes utilizadas no sysvinit existem somente como links para o comando systemctl. O systemd mantém esses links como compatibilidade e faz praticamente o que os comandos originais faziam. Mas ao utilizar o comando halt o systemd o processa de forma similar ao seu propósito original e no final espera o desligamento manual do sistema. Com isso a placa nunca chega à seu estado de baixa energia, onde o firmware da GPU ainda fica rodando com funções mínimas.

Só que a história não termina aqui pois também percebi algo mais "grave".


Houston, temos um problema


Grande parte dos testes aqui utilizam aquela fonte modificada com um amperímetro antes do conector micro USB, isso permite que eu sempre veja o consumo na hora dos testes.

Acontece que em meio aos testes percebi que ao desligar o Raspberry Pi com o comando "halt" mesmo sem nada ligado aos GPIOs (pizula por exemplo) acontecia isso:



Como demonstrado no vídeo, o consumo foi as alturas e isso tem uma explicação.

Com o sistema entrando em modo halt real (ao contrário do sysvinit atual) no final a cpu fica literalmente em loop. Sim! É um while(1); que consumirá 100% de um núcleo, consumindo aquela diferença de energia que vimos no vídeo.

Para quem usa sistemas com baterias isso iria ter um impacto bem negativo ao darem "halt" na placa. O SoC também continuará esquentando (a vantagem do cooler ligado) além de outros efeitos indesejáveis nos GPIOs.

O mesmo acontece com essa versão no Raspberry Pi Modelo B:


Felizmente a última atualização do Raspbian (Jessie) já não sofre mais desse "problema". As aspas são propositais pois o halt no systemd faz exatamente o que deve ser feito.

A correção feita na árvore do kernel utilizado no Raspberry Pi no dia 5 de abril alterou a forma como o estado halt é tratado. Agora a função chama diretamente machine_power_off() e consequentemente entrando no modo de baixo consumo.


Entretanto estamos falando aqui do sistema e o kernel oficial. Outras distribuições podem ter efeitos diferentes, portanto o melhor a fazer é evitar o halt e utilizar shutdown.

Meus agradecimentos ao Moisés pelo feedback.

Referência: https://github.com/raspberrypi/linux/commit/3ce05d6e2e4994e06ec73ff95969ae189681a8e8

7 comentários:

  1. Muito boa esta informação....
    Uma coisa que percebi (não sei se tem haver), antes eu utilizava este comando "halt" e meu cartão vivia corrompendo.
    Depois que passei a usar comando "shutdown", nunca mais tive este problema.

    ResponderExcluir
    Respostas
    1. Não cheguei a realizar investigações nessa parte, mas se aconteceu isso existe a chance de que algo realmente poderia estar influenciando.

      Excluir
  2. O mesmo acontece se utilizar "halt -p"? Sempre utilizo esse comando, o "-p" era necessário em desktops pra ele desligar a fonte ATX antigamente, por força do hábito uso o mesmo comando no raspb.

    ResponderExcluir
    Respostas
    1. Olá, com "halt -p" isso não ocorre pois esse comando chama o poweroff (-p).

      Excluir
  3. Uso o poweroff, que basicamente é um reboot --poweroff.
    Alguém problema?

    ResponderExcluir
    Respostas
    1. Olá, esse problema não ocorre ao utilizar o poweroff, pois o que esse comando faz originalmente é justamente desligar a energia.

      Excluir
  4. velha guarda do Linux usa na verdade o bom e velho init 0

    ResponderExcluir