Por que 'journalctl --list-boots' não corresponde ao que 'uptime' e 'who -b' reportam?

1

Aqui está um script de teste que usei:

last_reboot=$(last reboot | grep 'still running' | awk '{for (i=5; i<=NF; i++) printf $i FS}' | awk '{for (i=1; i<=NF - 2; i++) printf $i FS}')
if [ "$last_reboot" ]; then
    date -d "$last_reboot" '+last reboot: %Y-%m-%d'
fi

days=$(uptime | awk '{print $3}')
hours=$(uptime | awk '{print $5}' | sed -E 's/,$//')
h=$(echo "$hours" | cut -d: -f 1)
m=$(echo "$hours" | cut -d: -f 2)
date -d "- $days days - $h hours - $m minutes" '+uptime: %Y-%m-%d'

who -b | awk '{print "who: " $3}'

journalctl --list-boots | awk '$1 == "0" {print "journalctl: " $4}'

Localmente, todas as quatro datas correspondem.

Eu corri em cerca de 10 servidores. last reboot não reporta nada (provavelmente, porque wtmp é rotacionado por logrotate ). uptime e who -b correspondência. E journalctl não. O que exatamente journalctl --list-boots reporta? Por que não pode corresponder ao que outras ferramentas relatam?

    
por x-yuri 05.12.2017 / 14:51

1 resposta

1

Os novos logs binários nos sistemas operacionais Linux não funcionam da mesma forma que os logs binários antigos.

Os logs binários antigos eram /var/log/wtmp e /var/log/btmp . Na inicialização do sistema, uma entrada seria gravada em wtmp com o nome de usuário reboot e, no encerramento, uma entrada seria gravada em wtmp com o nome de usuário shutdown . Encontrar as horas em que o sistema foi reinicializado foi uma questão de usar os comandos last reboot e last shutdown para imprimir essas entradas.

Os novos logs binários são o diário do systemd, e eles não possuem tais entradas.

Em vez disso, cada registro de diário tem um campo chamado código de inicialização . Você pode ver isso com a opção -o verbose para journalctl . Uma ID de boot é gerada pelo kernel no bootstrap, e systemd-journald aplica o ID de boot atual, retirado do kernel, para cada registro de log à medida que o adiciona ao diário.

Para implementar a funcionalidade list-boots , journalctl varre o diário inteiro , lendo os timestamps e os IDs de inicialização de todos os registros e anotando o mais antigo e os mais recentes timestamps associados a cada ID de inicialização exclusivo.

Assim, se partes do diário forem eliminadas, ou vice-versa, os tempos aparentes de inicialização e encerramento relatados por journalctl serão muito diferentes dos tempos reais de inicialização e desligamento.

/run/utmp é uma tabela de registros de login de terminal, com entradas especiais para inicialização e encerramento. Essas entradas são lidas por uptime e who -b . Eles são escritos por programas como systemd-update-utmp , um análogo do comando FreeBSD utx , que são executados como partes dos procedimentos de inicialização e encerramento. Eles não são executados em primeiro ou último lugar, pois os serviços relevantes não são (e de fato não podem ser) ordenados absolutamente em primeiro ou último lugar. Pode haver entradas de diário com o ID de inicialização relevante que precede o tempo em que systemd-update-utmp reboot é executado e entradas de diário semelhantes que são posteriores à hora em que systemd-update-utmp shutdown é executado.

Leitura adicional

por 05.12.2017 / 22:08