Systemd: como desligar sem realmente desligar

2

Estou configurando um dispositivo incorporado que executa o Debian Jessie para desligar quando um no-break sofrer uma falha de energia. Infelizmente, o bootloader do dispositivo reinicia o SO sempre que ele é encerrado, portanto, os comandos shutdown / halt são equivalentes a reiniciar.

Minha principal preocupação é proteger os dados nos discos rígidos anexos. Acho que minha melhor opção é matar o máximo de tarefas possível e depois esperar que a energia seja cortada. systemctl isolate emergency.target parece próximo do que eu quero, exceto que deixa os discos montados. Existe uma maneira de obter basicamente Systemd para final.target sem um comando real de desligamento / parada?

    
por Bethanie 17.03.2018 / 01:12

2 respostas

2

systemctl halt pode fazer o truque. Do manual:

halt
    Shut down and halt the system. This is mostly equivalent to
    systemctl start halt.target --job-mode=replace-irreversibly
    --no-block, but also prints a wall message to all users. This
    command is asynchronous; it will return after the halt operation is
    enqueued, without waiting for it to complete. Note that this
    operation will simply halt the OS kernel after shutting down,
    leaving the hardware powered on. Use systemctl poweroff for
    powering off the system (see below).
    
por 17.03.2018 / 01:19
0

Supondo que isso não seja apenas um problema com algum tipo de dispositivo watchdog, você pode tentar sequestrar o kexec target para o systemd. Isso é normalmente usado para carregar um kernel do kdump para despejar memória, mas você pode realmente configurar o alvo para fazer qualquer coisa.

Eu criei uma unidade systemd chamada kexec-sleep e coloquei em /etc/systemd/system/kexec-sleep.service (não tenho certeza se essas linhas Requires / After / Before estão certas, mas elas funcionaram para mim em um máquina virtual):

[Unit]
Description=Sleep forever at kexec
DefaultDependencies=no
Requires=umount.target
After=umount.target
Before=final.target

[Service]
Type=oneshot
ExecStart=/sbin/kexec-sleep
KillMode=none

[Install]
WantedBy=kexec.target

Isso chamará /sbin/kexec-sleep , que é apenas um script de shell (mostrado abaixo). Ele tenta remontar o sistema de arquivos raiz somente leitura, portanto, ele deve permanecer em um estado limpo até que o dispositivo seja desativado. Eu tenho alguns sleep s lá que são provavelmente mais longos do que o que você precisa, além de um prompt no final que permitirá que você reinicie sem precisar puxar o cabo de alimentação.

#!/bin/sh

stty sane < /dev/console       # enable automatic CRLF output on console
exec < /dev/console > /dev/console 2>&1  # redirect stdio to/from console
echo "Sleeping several seconds for processes to terminate..."
sleep 10
# kill some expected processes
killall dhclient
# sleep again...
sleep 5
echo "Processes still running:"
/bin/ps --ppid 2 -p 2 --deselect    # list non-kernel processes
echo "Attempting to remount root filesystem read-only..."
sync; sync; sync
mount -o remount,ro /
grep /dev/sda /proc/mounts
while true; do
    echo "System paused. Type 'reboot' to reboot"
    read -p '> ' entry
    if [ "$entry" = "reboot" ]; then
        /sbin/reboot -f
    fi
done

Depois de criar esses arquivos, execute chmod +x /sbin/kexec-sleep e systemctl enable kexec-sleep .

Para acionar isso em vez de um desligamento normal, execute systemctl kexec .

    
por 18.03.2018 / 00:36