Câu trả lời:
Cách tốt nhất là tìm chương trình / dịch vụ nào sử dụng các thư viện cũ và khởi động lại chúng. Và bạn có thể đạt được nó bằng cách liệt kê tất cả các tệp được sử dụng bằng cách sử dụng 'lsof' và tìm những tệp có loại 'DEL'. DEL có nghĩa là tên tệp đã bị xóa khỏi hệ thống tệp nhưng nó vẫn bị kẹt trong bộ nhớ vì ai đó sử dụng nó.
Đây là dòng lệnh đầy đủ:
sudo lsof +c 0 | grep 'DEL.*lib' | awk '1 { print $1 ": " $NF }' | sort -u
Lý do bắt buộc duy nhất để khởi động lại là một hạt nhân mới (và bạn có thể khởi động lại bằng cách sử dụng kexec). Xem https://wiki.archlinux.org/index.php/Kexec để biết chi tiết, tóm tắt:
tải kernel mới, initramfs và chỉ định cmdline khởi động
kexec -l /boot/new-kernel --initrd=/boot/new-initramfs --reuse-cmdline
gọi kexec
(sử dụng systemctl
để tắt máy đúng cách, kexec -e
sẽ thực thi trực tiếp)
systemctl kexec
Lưu ý rằng nếu bạn tạo kexec-load@.service
như được giải thích trong wiki, nếu bạn khởi động lại, systemd
sẽ tự động khởi động lại bằng cách sử dụng kexec
thay vì thực hiện khởi động lại bios
Phiên bản cải tiến nhỏ cung cấp tên dịch vụ 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
hoặc một dòng:
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
Lưu ý rằng có một số vấn đề:
systemctl daemon-reload
nên được thực hiện trước khi khởi động lại bất cứ điều gì khácsystemd
cần phải khởi động lại PID 1 , nó có thể được thực hiện bằng cách sử dụngsystemctl daemon-reexec
systemctl restart dbus.service
phá vỡ một số dịch vụ khác, chúng cần được khởi động lại sau khi khởi động lại dbus:
systemd
chinh no: systemctl daemon-reexec
systemd-logind
systemd-machined
dbus
systemctl restart sshd
sẽ không khởi động lại được miễn là bạn được kết nối, tôi thấy 2 tùy chọn:
systemctl restart sshd
sử dụng at/cron/systemd
bộ hẹn giờSSH
bằng cách sử dụng trình điều khiển từ xa (an toàn) khác, chẳng hạn nhưmosh
screen/tmux
cũng có thể chặn các dịch vụ như SSH
khởi động lại, cách dễ nhất là đóng các phiên này trước khi khởi động lại dịch vụMột cách dễ dàng là so sánh phiên bản của kernel đang chạy với kernel mới nhất trên đĩa. Tôi tìm thấy một kịch bản có thể làm điều đó một cách dễ dàng.
Khi tôi đã cài đặt một số hạt nhân, tôi đã sửa đổi tập lệnh để chỉ kiểm tra tập lệnh tương ứng với kernel đang chạy. Ví dụ: tôi hiện đã cài đặt phiên bản 4.9.79 và 4.14.16 và do đó cần kiểm tra /boot/vmlinuz-4.14-x86_64. Thật không may, điều này sẽ không hoạt động khi tôi bắt đầu sử dụng phiên bản 5.1, vì vậy sẽ cần một bản cập nhật (thay thế 4 bằng 3) hoặc tôi cần tìm một cách mạnh mẽ hơn.
Đây là kịch bản của tôi:
#!/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