升级pacman后是否应该重新启动?


Answers:


10

如果内核,glibc或systemd有更新,则可能需要重新启动,以便使用更新的版本。例如,如果您有桌面环境的更新,那么简单的注销/登录就足够了。


11

最好的方法是查找哪些程序/服务使用旧库并重新启动它们。您可以通过使用'lsof'列出所有使用的文件并找到具有'DEL'类型的文件来实现。DEL表示文件名已从文件系统中删除,但由于有人使用它而仍停留在内存中。

这是完整的命令行:

 sudo lsof +c 0 | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u

2
在生成服务和库列表之后,仍然不清楚哪些系统服务需要重新启动。因此,即使我知道哪些进程和库需要重新启动,但根据该列表确定要重新启动的服务通常也不是一件容易的事。
bwv549

6

重启的唯一强制原因是新内核(您可以使用kexec进行软重启)。简而言之,请参阅https://wiki.archlinux.org/index.php/Kexec以获取详细信息:

  • 加载新内核,initramfs并指定启动cmdline

    kexec -l /boot/new-kernel --initrd=/boot/new-initramfs --reuse-cmdline
    
  • 调用kexecsystemctl用于正确关闭,kexec -e将直接执行)

    systemctl kexec
    
  • 请注意,如果您kexec-load@.service按照Wiki中的说明创建一个,如果您重新启动,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使用另一个远程(安全)shell 重新启动,例如mosh
  • 运行screen/tmux可能还会阻止诸如SSH重新启动之类的服务,最简单的方法是在重新启动服务之前关闭这些会话
  • 如上一个答案所述,可能需要注销/登录,特别是对于图形会话

1
您是否介意改善解释kexec如何使用的答案?
Rui F Ribeiro

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.