Odpowiedzi:
Najlepszym sposobem jest znalezienie, które programy / usługi korzystają ze starych bibliotek i zrestartowanie ich. Możesz to osiągnąć, wyświetlając listę wszystkich używanych plików za pomocą „lsof” i znajdź te, które mają typ „DEL”. DEL oznacza, że nazwa pliku została usunięta z systemu plików, ale nadal utknęła w pamięci, ponieważ ktoś go używa.
Oto pełna linia poleceń:
sudo lsof +c 0 | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u
Jedynym obowiązkowym powodem ponownego uruchomienia jest nowe jądro (i można go ponownie uruchomić za pomocą kexec). Szczegółowe informacje można znaleźć na stronie https://wiki.archlinux.org/index.php/Kexec :
załaduj nowe jądro, initramfs i określ cmdline boot
kexec -l /boot/new-kernel --initrd=/boot/new-initramfs --reuse-cmdline
invoke kexec(użyj systemctldo prawidłowego zamknięcia, kexec -euruchomi się bezpośrednio)
systemctl kexec
Pamiętaj, że jeśli utworzysz kexec-load@.servicezgodnie z objaśnieniem na wiki, jeśli uruchomisz ponownie, systemdautomatycznie uruchomi się ponownie miękko, kexeczamiast przeprowadzać restart systemu BIOS
Trochę ulepszona wersja, która podaje nazwy usług systemowych:
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
lub jednowierszowy:
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
Pamiętaj, że istnieją pewne problemy:
systemctl daemon-reload powinien zostać wykonany przed ponownym uruchomieniem czegokolwiek innegosystemdsam) musi zostać zrestartowany, można to zrobić za pomocąsystemctl daemon-reexecsystemctl restart dbus.service psuje niektóre inne usługi, należy je zrestartować po restarcie dbus:
systemd samo: systemctl daemon-reexecsystemd-logindsystemd-machineddbussystemctl restart sshdnie uruchomi się ponownie tak długo, jak jesteś połączony, widzę 2 opcje:
systemctl restart sshdza pomocą at/cron/systemdtimerówSSHużywając innej zdalnej (bezpiecznej) powłoki, takiej jakmoshscreen/tmuxmoże również blokować usługi takie jak SSHponowne uruchomienie, najłatwiejszym sposobem jest zamknięcie tych sesji przed ponownym uruchomieniem usługProstym sposobem jest porównanie wersji uruchomionego jądra z najnowszym jądrem na dysku. Znalazłem skrypt, który może to zrobić z łatwością.
Ponieważ mam zainstalowane kilka jąder, zmodyfikowałem skrypt, aby sprawdzić tylko ten odpowiadający działającemu jądru. Na przykład mam obecnie zainstalowane wersje 4.9.79 i 4.14.16 i dlatego muszę sprawdzić /boot/vmlinuz-4.14-x86_64. Niestety, to nie zadziała, kiedy zacznę używać wersji 5.1, więc potrzebna będzie aktualizacja (zastąp 4 na 3) lub muszę znaleźć bardziej niezawodny sposób.
Oto mój skrypt:
#!/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