SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor

Rocky, Alma: update nào cần reboot?

dnf update có thể vẫn chạy kernel và library cũ. Dùng needs-restarting để biết lúc nào cần reboot máy, restart service hay không cần làm gì.

Bản cập nhật nào cần reboot trên Rocky Linux và AlmaLinux

Trên Rocky Linux và AlmaLinux, dnf update ghi các file mới vào disk rồi dừng lại. Kernel mà bạn đã boot vẫn tiếp tục chạy. Mỗi process đã mở một library vẫn dùng bản sao mà nó đã mở, vì Linux giữ file cũ trên disk cho đến khi process cuối cùng đang giữ file đó thoát. Vì vậy, máy có thể báo không còn update nào khả dụng trong khi vẫn chạy code mà các bản cập nhật đó đã thay thế. Điều này không khác nhau giữa hai distribution, vì cả hai đều build lại cùng các source của Red Hat. Việc chọn Rocky hay Alma phụ thuộc vào cam kết tương thích và hỗ trợ CPU, không phụ thuộc vào bất kỳ điều gì được đề cập ở đây. Các command bên dưới cũng giống các command mà một máy CentOS từng dùng. Đây không phải là sự trùng hợp: cả hai project được xây dựng để thay thế CentOS sau thông báo về Stream năm 2020.

Bản cập nhật nào cần reboot và bản cập nhật nào chỉ cần restart service là câu hỏi bạn phải hỏi chính máy đó. Command trả lời câu hỏi này là needs-restarting. Các bản cập nhật được chia thành 3 nhóm. Kernel và một danh sách ngắn các package core cần reboot toàn bộ máy. Các bản cập nhật library thông thường cần restart những service đang sử dụng chúng. Mọi thứ khác đã được áp dụng ngay khi RPM hoàn tất.

Cài đặt needs-restarting

needs-restarting là một DNF plugin. Plugin này nằm trong dnf-plugins-core, một gói đã có sẵn trên hầu hết hệ thống Rocky và Alma. Lệnh /usr/bin/needs-restarting là một wrapper nhỏ nằm trong yum-utils, gói này cũng có tên dnf-utils.

sudo dnf install -y yum-utils
needs-restarting --help

Cả hai cách gọi đều chạy cùng một code, vì wrapper gọi DNF subcommand:

needs-restarting -r
dnf needs-restarting -r

Cả hai package đều đến từ repository riêng của distribution, nên bạn không cần bật EPEL hoặc repository CRB cho việc này.

Dòng Rocky Linux 10 và AlmaLinux 10 vẫn chạy DNF 4. Tính đến 2026-10-09, cả hai repository BaseOS đều có dnf 4.20.0 cùng với dnf-plugins-core 4.7.0 và yum-utils, nhưng không có package dnf5. Vì vậy, needs-restarting trên các hệ thống này chính là dnf-plugins-core plugin được mô tả trong trang này, và toàn bộ nội dung bên dưới vẫn áp dụng như cũ. Điều này bao gồm cả -r, thành phần tạo thông báo cần reboot và exit code của lệnh, vì vậy hãy giữ nó trong các script của bạn.

Tầng 1: các bản cập nhật cần reboot

Chạy bước kiểm tra reboot trước. Bước này chỉ đọc RPM database và thời điểm boot của hệ thống, không đọc gì khác, nên chạy nhanh và không cần root.

needs-restarting -r

Khi không có thay đổi quan trọng nào kể từ lần boot, lệnh in ra 2 dòng:

No core libraries or services have been updated since boot-up.
Reboot should not be necessary.

Khi có thay đổi, lệnh in ra Core libraries or services have been updated since boot-up:, tiếp theo là tên các package tìm thấy, rồi:

Reboot is required to fully utilize these updates.
More information: https://access.redhat.com/solutions/27943

Exit code chứa cùng kết quả: 0 khi không cần reboot, 1 khi cần reboot. Đây là phần bạn dùng để viết script.

if ! needs-restarting -r >/dev/null; then
  logger -t updates "reboot pending on $(hostname -s)"
fi

Exit code 1 ở đây là kết quả bình thường, không phải lỗi. Trong set -e, một needs-restarting -r không được kiểm tra sẽ kết thúc script ngay tại dòng đó. Vì vậy, ví dụ trên bọc lệnh này trong if.

Các package làm cho kết quả kiểm tra yêu cầu reboot nằm trong một danh sách ngắn được hard-code bên trong plugin. Trong các phiên bản hiện tại, danh sách này gồm kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon và microcode_ctl. Các bản build plugin cũ hơn có danh sách ngắn hơn một chút, nên hãy kiểm tra bản của bạn thay vì mặc định theo danh sách này.

Mỗi entry nằm trong danh sách vì một lý do có thể giải thích rõ ràng. Một package kernel mới chỉ ghi file vào /boot và /lib/modules, còn kernel đang chạy không thể tự thay thế khi vẫn đang chạy, nên thay đổi chỉ có hiệu lực sau khi boot kernel đó. Mọi process trên máy đều link đến glibc. Điều này có nghĩa là “restart các service bị ảnh hưởng” cũng sẽ bao gồm việc restart PID 1, và reboot là cách an toàn để thực hiện việc đó. dbus và dbus-broker xử lý mọi kết nối client trên hệ thống, nên dừng bus trên máy đang chạy sẽ làm gián đoạn các client đang kết nối với nó. linux-firmware và microcode_ctl được load khi boot. Trên VPS, phần microcode thường không tạo ra thay đổi nào bạn có thể quan sát được vì hypervisor host quản lý CPU vật lý.

Bạn có thể thêm package của riêng mình. Mọi file .conf bên dưới /etc/dnf/plugins/needs-restarting.d/ đều được đọc như một danh sách tên package, mỗi dòng một tên. Các tên đó sẽ được thêm vào danh sách package cần reboot.

echo 'openssl-libs' | sudo tee /etc/dnf/plugins/needs-restarting.d/openssl.conf

Đó là lựa chọn về policy, không phải cách khắc phục. Nó có nghĩa là: “khi thư viện TLS thay đổi, tôi muốn reboot thay vì phải tìm và xử lý mọi service đã map thư viện đó”.

Nguồn thực tế của gợi ý reboot

needs-restarting -r không so sánh version kernel đang chạy với kernel mới nhất đã cài. Nó so sánh timestamp. Với mỗi package trong danh sách core đó, nó đọc thời điểm cài đặt RPM rồi so sánh với thời điểm system boot. Nếu một core package được cài sau lần boot gần nhất, kết quả là "reboot required". Thời điểm boot được lấy từ UnitsLoadStartTimestamp của systemd qua D-Bus khi có thể. Nếu không, nó lấy giá trị muộn hơn giữa thời gian sửa đổi của /proc/1 và trường btime trong /proc/stat.

Cơ chế này có một hệ quả cần biết. Nếu bạn cài kernel, reboot, rồi máy lại khởi động bằng kernel cũ hơn vì boot default bị ghim, thời điểm cài đặt lúc này đã cũ hơn thời điểm boot và needs-restarting -r sẽ không còn cảnh báo. Nó đang trả lời đúng câu hỏi của chính nó. Nhưng đó không phải câu hỏi bạn đặt ra. Hãy kiểm tra kernel riêng.

uname -r
rpm -q --last kernel
sudo grubby --default-kernel

Command đầu tiên in ra kernel đang chạy. Dòng đầu tiên của rpm -q --last kernel là kernel được cài gần đây nhất. grubby --default-kernel in ra kernel mà bootloader sẽ chọn trong lần khởi động tiếp theo. Nếu 3 thông tin này không khớp, hãy sửa boot default trước khi reboot một máy mà bạn không thể truy cập qua console.

Tier 2: các bản cập nhật cần restart service

Khi RPM thay thế một shared library, nó unlink file cũ rồi ghi file mới. Một process đã map file cũ vẫn giữ inode cũ tồn tại và tiếp tục chạy code cũ. openssl-libs là trường hợp cần chú ý nhất: một bản sửa trong libcrypto chỉ có hiệu lực với web server sau khi web server đó restart.

sudo needs-restarting -s

Lệnh này liệt kê các systemd service có file của chính service đó, hoặc file của dependency, được cập nhật sau khi service khởi động. Dùng sudo. Nếu không có quyền root, tool này chỉ đọc được các mục /proc của process thuộc về bạn, nên kết quả bị thiếu mà không báo lỗi; danh sách ngắn trông như một tín hiệu tốt.

sudo needs-restarting
sudo needs-restarting --exclude-services

Lệnh đầu tiên in PID và command line của mọi process bị ảnh hưởng. Lệnh thứ hai loại các process đã được một systemd service quản lý, để lại login shell, các session tmux, cron job và mọi process bạn tự khởi chạy. Những process đó không tự restart.

Nếu một service trong danh sách cũng thuộc package cần reboot, tool sẽ in Warning: The following services should not be restarted but require a reboot: bên trên service đó. Hãy hiểu đúng theo nghĩa đen và reboot thay vì restart service.

Restart các service còn lại lần lượt từng service một, đồng thời kiểm tra từng service trước khi chuyển sang service tiếp theo.

sudo systemctl restart nginx
systemctl status nginx

Không pipe danh sách này vào systemctl restart. SSH session của chính bạn là lý do cần tránh việc đó. Trên họ RHEL, sshd.service được phát hành cùng KillMode=process, nên khi restart, nó sẽ gửi signal cho daemon đang listen nhưng để nguyên các process xử lý từng connection; session đang mở vẫn tiếp tục hoạt động. Xác nhận điều này trên máy của bạn bằng systemctl cat sshd | grep KillMode, và lần đầu luôn mở sẵn một session thứ hai.

Bạn cũng có thể tìm các process tương tự mà không cần DNF. Cách này hữu ích khi bạn muốn xem các file path liên quan:

sudo dnf install -y lsof
sudo lsof -n +c 0 2>/dev/null | grep -w DEL

DEL đánh dấu một file đã được map nhưng đã bị xóa khỏi disk. Đọc các path trước khi thực hiện thao tác. Các file tạm đã bị xóa và file được lưu trong memory cũng xuất hiện ở đây; chúng không phải là lý do để restart bất kỳ thứ gì.

Bậc 3: mọi thứ còn lại

Hầu hết bản cập nhật thuộc nhóm này và không cần làm gì thêm. Một package có các file chỉ được đọc khi command khởi động, như curl, tar, vim hoặc chính dnf, được áp dụng đầy đủ khi RPM hoàn tất, vì lần chạy tiếp theo sẽ đọc binary mới. Configuration file, script, tài liệu và data package cũng hoạt động như vậy. needs-restarting sẽ không đề cập đến bất kỳ package nào trong số đó. Sự im lặng này là kết quả đúng, không phải do bỏ sót phát hiện.

Điểm cần lưu ý duy nhất ở bậc này là thời gian tồn tại của process. Một process đã khởi động trước khi cập nhật vẫn tiếp tục chạy executable cũ cho đến khi thoát, dù package đó đơn giản đến đâu. Đó chính là mục đích của sudo needs-restarting --exclude-services.

Vì sao máy chạy dnf-automatic có thể giữ các bản sửa lỗi chưa áp dụng trong nhiều tuần

Đây là lúc sự khác biệt giữa 3 tầng không còn chỉ là lý thuyết. Cập nhật tự động với dnf-automatic cài package theo timer, còn thiết lập mặc định reboot trong /etc/dnf/automatic.conf là never. Với apply_updates = yes và reboot = never, máy có thể cài 6 bản cập nhật kernel và một bản sửa lỗi glibc trong 6 tuần nhưng vẫn chạy kernel và C library mà nó đã boot cùng ở tuần 0. Update log trông hoàn toàn bình thường. Hệ thống đang chạy không có những bản cập nhật đó.

Cách sửa là thêm 3 dòng vào /etc/dnf/automatic.conf:

[commands]
upgrade_type = security
apply_updates = yes
reboot = when-needed
reboot_command = "shutdown -r +5 'Rebooting after applying package updates'"

reboot chấp nhận never, when-changed và when-needed. never là giá trị mặc định và để bạn tự quyết định mọi việc. when-changed reboot sau mọi transaction làm thay đổi một package. Cách này đơn giản nhưng dễ dự đoán. when-needed hỏi DNF xem transaction vừa áp dụng có yêu cầu reboot hay không, nên một đêm cập nhật chỉ thay đổi userspace sẽ không reboot. reboot_command là thành phần thực sự chạy, còn giá trị mặc định sẽ cảnh báo cho người dùng đã đăng nhập trước 5 phút. Đặt random_sleep và lịch của timer để quá trình này diễn ra trong khoảng thời gian bạn có thể theo dõi máy khởi động lại.

Kiểm tra unit bạn đã enable bằng systemctl list-timers 'dnf-*'. dnf-automatic có nhiều biến thể được phát hành kèm theo và chúng không hoạt động giống nhau, nên chỉ nhìn vào file cấu hình thì không biết chính xác thành phần nào đang chạy.

Sau một lần chạy theo lịch, hãy hỏi trực tiếp máy thay vì chỉ xem log:

needs-restarting -r; echo "exit: $?"
uname -r
rpm -q --last kernel | head -1

Nếu không thể lập lịch reboot, live kernel patching trên VPS là một lựa chọn khác. Cách này áp dụng một số bản sửa lỗi kernel nhất định vào kernel đang chạy mà không cần reboot. Nó chỉ xử lý một phần các vấn đề của kernel và không xử lý glibc hoặc các service của bạn. Vì vậy, hãy xem đây là cách giãn thời điểm reboot, không phải cách loại bỏ hoàn toàn reboot. Khi cần reboot, hãy thực hiện có chủ đích và giữ phiên đăng nhập cho đến khi máy phản hồi, vì cập nhật kernel là nguyên nhân phổ biến nhất khiến máy không khởi động lại được. Đọc cách xử lý khi VPS không boot sau khi cập nhật kernel trước khi reboot một máy không có console access, đồng thời đưa bước kiểm tra reboot vào checklist bảo trì server định kỳ để bạn không chỉ nhớ đến việc này sau khi đã xảy ra incident.

Cùng một tác vụ trên Ubuntu và Debian

Một fleet hỗn hợp cần các lệnh tương đương. Trên Ubuntu và Debian, cờ reboot là một file chứ không phải một command: các package script tạo /run/reboot-required, còn /run/reboot-required.pkgs liệt kê những package đã yêu cầu file này, vì vậy [ -f /run/reboot-required ] là lệnh tương đương trực tiếp với needs-restarting -r. Tài liệu cũ hơn ghi /var/run/reboot-required. Đây là cùng một file vì /var/run là symlink đến /run. Phía service là needrestart, được cài mặc định trong các bản Ubuntu Server gần đây. Service này chạy trong apt upgrade và có thể chạy riêng bằng sudo needrestart -r l để liệt kê những gì cần restart mà không thay đổi gì. Khoảng trống trong cơ chế automatic update cũng giống như vậy, và cách khắc phục cũng vậy: unattended-upgrades trên Ubuntu nhận Unattended-Upgrade::Automatic-Reboot "true"; và Unattended-Upgrade::Automatic-Reboot-Time "02:00"; trong /etc/apt/apt.conf.d/50unattended-upgrades.

Các tình huống lỗi và những gì bạn sẽ thấy

  • needs-restarting: command not found có nghĩa là yum-utils chưa được cài đặt. Hãy cài đặt nó hoặc gọi dnf needs-restarting thay thế; lệnh này hoạt động ngay khi dnf-plugins-core có mặt.
  • Script dừng tại bước kiểm tra reboot mà không báo lỗi là do set -e trả về exit code 1. Mã này có nghĩa là “cần reboot”, vì vậy hãy xử lý mã này bằng nhánh điều kiện thay vì để nó kết thúc script.
  • needs-restarting -s không in gì ngay sau khi cập nhật library thường có nghĩa là bạn đã chạy lệnh này mà không có sudo. Nếu không có quyền root, lệnh chỉ nhìn thấy các process của chính bạn.
  • needs-restarting -r báo không cần reboot trong khi uname -r hiển thị phiên bản cũ có nghĩa là bạn đã boot bằng kernel cũ hơn. Lệnh kiểm tra so sánh thời điểm cài đặt với thời điểm boot, và cả hai thời điểm đó đều đã nằm trước lần boot hiện tại. Hãy xem grubby --default-kernel.
  • Một service xuất hiện lại trong lần chạy tiếp theo, chỉ vài phút sau khi bạn restart nó, thường là do một thành phần khác đang restart service hoặc unit không khởi động lại thành công. Hãy đọc systemctl status của unit đó trước khi restart lần thứ hai.

FAQ

dnf update có khởi động lại các service trên Rocky Linux không?

Theo nguyên tắc là không. Transaction ghi các file rồi kết thúc. Một số package có RPM scriptlet tự khởi động lại service của chính chúng khi upgrade, vì vậy hành vi phụ thuộc vào từng package, không phải một bảo đảm áp dụng toàn hệ thống. Hãy xem sudo needs-restarting -s là nguồn thông tin chính: nó liệt kê các service có file của chính chúng hoặc file của dependency đã thay đổi sau khi service khởi động, bất kể scriptlet đã làm gì.

Vì sao needs-restarting -r báo không cần reboot dù đã cài kernel mới hơn?

Vì lệnh này so sánh thời điểm cài RPM của một danh sách ngắn các core package với thời điểm system boot. Nó không bao giờ so sánh version kernel đang chạy với version kernel mới nhất đã cài. Nếu bạn cài kernel, reboot rồi hệ thống khởi động lại bằng kernel cũ hơn vì bootloader mặc định trỏ đến kernel đó, thời điểm cài sẽ cũ hơn thời điểm boot và kiểm tra sẽ không báo gì. Chạy uname -r, rpm -q --last kernel và sudo grubby --default-kernel để xem tình trạng thực tế.

Package nào kích hoạt gợi ý reboot trên Rocky và Alma?

Đó là một danh sách được hard-code bên trong plugin. Ở các version hiện tại, danh sách này gồm kernel, kernel-core, kernel-rt, glibc, linux-firmware, systemd, dbus, dbus-broker, dbus-daemon và microcode_ctl. Bạn có thể mở rộng danh sách này: đặt file .conf vào /etc/dnf/plugins/needs-restarting.d/, chứa tên package, mỗi tên một dòng. Các tên đó cũng được tính vào kết quả kiểm tra reboot.

dnf-automatic có thể tự reboot server không?

Có. Đặt reboot = when-needed trong section [commands] của /etc/dnf/automatic.conf. Khi đó, hệ thống chỉ reboot nếu transaction đã áp dụng yêu cầu reboot. when-changed reboot sau bất kỳ thay đổi package nào, còn never là giá trị mặc định. reboot_command điều khiển cách reboot. Giá trị mặc định của nó sẽ cảnh báo người dùng đang đăng nhập trước 5 phút. Chỉ bật tùy chọn này trên máy mà bạn có thể khôi phục quá trình boot, vì reboot không giám sát trên VPS không có quyền truy cập console là một tình huống lỗi nghiêm trọng.

needs-restarting có phát hiện process bên trong container không?

Không theo cách hữu ích. Lệnh này đối chiếu các process đang chạy với RPM database của host. Các package bên trong container image không có trong database đó, nên library cũ được tích hợp sẵn trong image sẽ không xuất hiện. Hãy rebuild image rồi redeploy. Phía host vẫn quan trọng: container runtime và kernel mà container dùng chung đều là package của host, nên chúng vẫn được phát hiện.