reboot in linux

在 linux 系統中如何重開機,是的,就是 reboot 指令,但為什麼 reboot 不是一個執行檔,而是一個 soft link?
$ which reboot
/sbin/reboot
$ ll /sbin/reboot
lrwxrwxrwx 1 root root 14 二 5 2020 /sbin/reboot -> /bin/systemctl*


更令人訝異的是,shutdown 指令也是一個 soft link,而且還指向同一個檔案!
$ which shutdown
/sbin/shutdown
$ ll /sbin/shutdown
lrwxrwxrwx 1 root root 14 二 5 2020 /sbin/shutdown -> /bin/systemctl


連到同一個檔案是無所謂,但為什麼反應會不一樣?如何作到的?



神奇的 systemd

在使用 systemd 的 linux 系統中,reboot、shutdown、halt、poweroff、… 等命令是指向 systemctl 的 soft link,執行 reboot 相當於執行 systemctl reboot,而 systemctl reboot 會切換到 systemd-reboot.service。
執行 reboot 相當於執行 systemctl reboot,這個應該是比較容易做到的,systemctl 在執行時,只要把 soft link 的名稱拿來當參數使用即可。
至於 systemctl reboot 如何切換到 systemd-reboot.service,這個就不好說了,當作 systemctl 的程式設定吧。

查看 systemd-reboot.service 的狀況:
$ systemctl status systemd-reboot.service
● systemd-reboot.service - Reboot
Loaded: loaded (/lib/systemd/system/systemd-reboot.service; static; vendor preset: enabled)
Active: inactive (dead)
Docs: man:systemd-halt.service(8)

繼續查看 systemd-reboot.service 的內容:
$ cat /lib/systemd/system/systemd-reboot.service
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.

[Unit]
Description=Reboot
Documentation=man:systemd-halt.service(8)
DefaultDependencies=no
Requires=shutdown.target umount.target final.target
After=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/bin/systemctl --force reboot

如此可以看到,原來下了 reboot 指令之後,最後執行的是:
/bin/systemctl --force reboot


同樣的道理,執行 poweroff 相當於執行 systemctl poweroff,而 systemctl poweroff 會切換到 systemd-poweroff.service。
依同樣的方式追縱,可以看到下了 shutdown 指令之後,最後執行的是:
/bin/systemctl --force poweroff



shutdown.target umount.target final.target

在 systemd-reboot.service 的內容中,有以下這行,又是什麼意思呢?
After=shutdown.target umount.target final.target

它表示 ExecStart=/bin/systemctl --force reboot 這個指令,必需要在 shutdown.target umount.target final.target 執行完畢之後。

shutdown.target umount.target final.target 又是什麼東西呢?
$ systemctl status shutdown.target
● shutdown.target - Shutdown
Loaded: loaded (/lib/systemd/system/shutdown.target; static; vendor preset: enabled)
Active: inactive (dead)
Docs: man:systemd.special(7)

沒說明什麼東西,但至少說有 doc 可以查:man systemd.special

可以查到好東西呀,總比憑空想像來得好:
shutdown.target
A special target unit that terminates the services on system shutdown.

Services that shall be terminated on system shutdown shall add Conflicts= dependencies to this unit for their service unit, which is implicitlydone when DefaultDependencies=yes is set (the default).

umount.target
A special target unit that unmounts all mount and automount points on system shutdown.

Mounts that shall be unmounted on system shutdown shall add Conflicts dependencies to this unit for their mount unit, which is implicitly donewhen DefaultDependencies=yes is set (the default).

final.target
A special target unit that is used during the shutdown logic and may be used to pull in late services after all normal services are already terminated and all mounts unmounted.

有了 doc 的說明,踏實很多了,就這麼相信吧~。



Reference

systemd 关机流程 以及 自定义systemd 关机脚本和服务


文字內容 或 影像內容 部份參考、引用自網路,如有侵權,請告知,謝謝。
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 silverwind1982 的頭像
    silverwind1982

    拾人牙慧

    silverwind1982 發表在 痞客邦 留言(0) 人氣()