Должен ли я перезапустить после обновления pacman?

Ответы:

10

Если имеются обновления ядра, glibc или systemd, вы можете перезапустить их, чтобы использовались обновленные версии. Если у вас есть, скажем, обновления для вашего рабочего стола, достаточно простого выхода из системы.

schaiba
источник
11

Лучший способ - найти, какие программы / службы используют старые библиотеки, и перезапустить их. И вы можете достичь этого, перечислив все используемые файлы, используя 'lsof', и найдите те, которые имеют тип 'DEL'. DEL означает, что имя файла было удалено из файловой системы, но оно все еще застряло в памяти, потому что кто-то использует его.

Вот полная командная строка:

 sudo lsof +c 0 | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u
user576557
источник
2
После генерации этого списка сервисов и библиотек все еще не ясно, какие системные сервисы необходимо перезапустить. Следовательно, даже несмотря на то, что я знаю, какие процессы и библиотеки нуждаются в перезапуске, обычно нетривиально определить, какие службы перезапустить на основе этого списка.
bwv549
6

Единственная обязательная причина перезагрузки - это новое ядро ​​(и вы можете выполнить мягкую перезагрузку с помощью kexec). Подробности смотрите в https://wiki.archlinux.org/index.php/Kexec , вкратце:

  • загрузите новое ядро, initramfs и укажите загрузочную командную строку

    kexec -l /boot/new-kernel --initrd=/boot/new-initramfs --reuse-cmdline
    
  • вызвать kexec(использовать systemctlдля правильного выключения, kexec -eбудет выполняться непосредственно)

    systemctl kexec
    
  • Обратите внимание, что если вы создадите, kexec-load@.serviceкак описано в вики, при перезагрузке systemdавтоматически произойдет программная перезагрузка, kexecа не перезагрузка BIOS

Немного улучшенная версия, которая дает имена сервисов systemd:

PIDS="(lsof +c0 -n 2> /dev/null | grep 'DEL.*lib' | awk '{print $2}' | sort -u)"
for PID in $PIDS; do
    systemctl status $i
done | grep '●' | awk '{print $2}' | sort -u

или в одну строку:

for i in $(lsof +c0 -n 2> /dev/null | grep 'DEL.*lib' | awk '{print $2}' | sort -u); do systemctl status $i; done | grep '●' | awk '{print $2}' | sort -u

Обратите внимание, что есть некоторые проблемы:

  • systemctl daemon-reload должно быть выполнено до перезапуска чего-либо еще
  • если PID 1 ( systemdсам) необходимо перезапустить, это можно сделать с помощьюsystemctl daemon-reexec
  • systemctl restart dbus.service ломает некоторые другие сервисы, их нужно перезапустить после перезапуска dbus:
    • systemd сам: systemctl daemon-reexec
    • systemd-logind
    • systemd-machined
    • вероятно, другие systemd - * / другие сервисы, которые (интенсивно) используют dbus
  • Если вы подключены через SSH и SSH необходимо перезапустить, но systemctl restart sshdне перезапустите его, пока вы подключены, я вижу 2 варианта:
    • график systemctl restart sshdс использованием at/cron/systemdтаймеров
    • перезапустите, SSHиспользуя другую удаленную (безопасную) оболочку, такую ​​какmosh
  • запуск screen/tmuxможет также блокировать такие службы, как SSHперезапуск, самый простой способ - закрыть эти сеансы перед перезапуском служб.
  • как сказано в предыдущем ответе, может потребоваться выход из системы / вход в систему, особенно для графических сеансов
Мишель Гангэн
источник
1
Не могли бы вы улучшить ответ, объяснив, как используется kexec?
Руи Ф. Рибейро
0

Самый простой способ - сравнить версию работающего ядра с последним ядром на диске. Я нашел сценарий, который может сделать это легко.

Поскольку у меня установлено несколько ядер, я изменил скрипт, чтобы проверить только тот, который соответствует работающему ядру. Например, в настоящее время у меня установлены версии 4.9.79 и 4.14.16, поэтому мне нужно проверить /boot/vmlinuz-4.14-x86_64. К сожалению, это не сработает, когда я начну использовать версию 5.1, поэтому потребуется обновление (замените 4 на 3), или мне нужно найти более надежный способ.

Вот мой сценарий:

#!/bin/sh
NEXTLINE=0
FIND=""
CURRENT_KERNEL=`uname -r`
KERNEL_PATH="/boot/vmlinuz-${CURRENT_KERNEL:0:4}"
for I in `file $KERNEL_PATH*`; do
  if [ ${NEXTLINE} -eq 1 ]; then
    FIND="${I}"
    NEXTLINE=0
   else
    if [ "${I}" = "version" ]; then NEXTLINE=1; fi
  fi
done
    if [ ! "${FIND}" = "" ]; then
      if [ ! "${CURRENT_KERNEL}" = "${FIND}" ]; then
    echo "Boot required"
  else echo "No boot required"
  fi
fi
Орельен
источник