套用至 SUSE Linux Enterprise Server 15 SP3

15 systemd 精靈

systemd 負責啟始化系統,它的程序 ID 為 1。systemd 由核心直接啟動,訊號 9 (通常會終止程序) 對它不起作用。所有其他程式或由 systemd 直接啟動,或由它的其中一個子程序啟動。systemd 取代了 System V init 精靈,並且透過支援 init 程序檔與 System V init 完全相容。

systemd 的主要優點是透過平行化服務啟動,大大加快了開機速度。另外,systemd 僅在確實需要服務時才會啟動該服務。即不會在開機時無條件啟動精靈,而是在第一次需要時才會啟動。systemd 還支援核心控制群組 (cgroup)、建立快照和還原系統狀態。如需詳細資訊,請造訪 http://www.freedesktop.org/wiki/Software/systemd/

15.1 systemd 概念

以下幾節介紹 systemd 背後的概念。

systemd 是適用於 Linux 的系統和工作階段管理員,它與 System V 及 LSB init 程序檔相容。systemd 的主要功能包括:

  • 平行化能力

  • 使用通訊端和 D-Bus 啟用來啟動服務

  • 依需求啟動精靈

  • 使用 Linux cgroup 追蹤程序

  • 建立快照和還原系統狀態

  • 維護掛接點和自動掛接點

  • 實作事務相關型複雜的服務控制邏輯

15.1.1 單位檔案

單位組態檔案包含有關以下項目的資訊:服務、通訊端、裝置、掛接點、自動掛接點、交換檔案或分割區、啟動目標、監控的檔案系統路徑、受 systemd 控制和監督的計時器、暫時系統狀態快照、資源管理片段,或一組外部建立的程序。

單位檔案systemd 用於表示下列項目的通用術語:

  • 服務:  程序相關資訊 (例如執行精靈);檔案名以 .service 結尾

  • 目標:  用於將單位分組以及在啟動期間用作同步點;檔案名以 .target 結尾

  • 插槽:  IPC 或網路插槽或檔案系統 FIFO 的相關資訊,適用於插槽型啟動 (如 inetd);檔案名以 .socket 結尾

  • 路徑:  用於觸發其他單位 (例如,在檔案變更時執行服務);檔案名以 .path 結尾

  • 計時器:  受控計時器的相關資訊,適用於計時器型啟動;檔案名以 .timer 結尾

  • 掛接點:  通常由 fstab 產生器自動產生;檔案名以 .mount 結尾

  • 自動掛接點:  檔案系統自動掛接點的相關資訊;檔案名以 .automount 結尾

  • Swap:  用於記憶體分頁之交換裝置或檔案相關資訊;檔案名以 .swap 結尾

  • 裝置:  sysfs/udev(7) 裝置樹中所展示之裝置的相關資訊;檔案名以 .automount 結尾

  • 範圍/片段:  分階層管理程序群組之資源的概念;檔案名以 .scope/.slice 結尾

如需 systemd 單位檔案的詳細資訊,請參閱 http://www.freedesktop.org/software/systemd/man/systemd.unit.html

15.2 基本用法

System V init 系統使用若干個指令來處理服務 - init 程序檔、insservtelinit 及其他。systemd 可簡化服務管理,因為對於大部分處理服務的任務,只需記住一條指令:systemctl。它使用 指令加子指令表示法,與 gitzypper 相似:

systemctl GENERAL OPTIONS SUBCOMMAND SUBCOMMAND OPTIONS

如需完整的手冊,請參閱 man 1 systemctl

提示
提示:終端機輸出和 Bash 補齊

如果輸出進入終端機 (而不是進入管線或檔案之類),systemd 指令依預設會將長輸出傳送到頁面巡覽區。使用 --no-pager 選項可關閉切換模式。

systemd 還支援 bash 補齊,允許您輸入子指令的頭幾個字母,然後按 →|。此功能僅可用於 bash 外圍程序,並且需要安裝套件 bash-completion

15.2.1 管理正在執行系統中的服務

用於管理服務的子指令與透過 System V init 管理服務的子指令相同 (startstop、...)。下面列出了服務管理指令的通用語法:

systemd
systemctl reload|restart|start|status|stop|... MY_SERVICE(S)
System V init
rcMY_SERVICE(S) reload|restart|start|status|stop|...

systemd 可讓您一次管理多個服務。它不是像 System V init 那樣依次執行 init 程序檔,而是執行類似如下的指令:

tux > sudo systemctl start MY_1ST_SERVICE MY_2ND_SERVICE

若要列出系統上所有可用的服務:

tux > sudo systemctl list-unit-files --type=service

下表列出了 systemd 和 System V init 最重要的服務管理指令:

表格 15.1︰ 服務管理指令

任務

systemd 指令

System V init 指令

啟動: 

start
start

停止: 

stop
stop

重新啟動:  關閉服務,然後啟動這些服務。如果某項服務並未執行,則會將其啟動。

restart
restart

有條件地重新啟動:  如果服務目前正在執行中,則予以重新啟動。對於未在執行中的服務,則不執行任何動作。

try-restart
try-restart

重新載入:  指示服務重新載入它們的組態檔案,而不中斷操作。使用案例:指示 Apache 重新載入修改過的 httpd.conf 組態檔案。請注意,並非所有服務都支援重新載入。

reload
reload

重新載入或重新啟動:  如果服務支援重新載入,則重新載入服務,否則重新啟動服務。如果某項服務並未執行,則會將其啟動。

reload-or-restart
n/a

有條件地重新載入或重新啟動:  如果服務支援重新載入,則重新載入服務,否則重新啟動那些目前正在執行的服務。對於未在執行中的服務,則不執行任何動作。

reload-or-try-restart
n/a

取得詳細的狀態資訊:  列出服務狀態的相關資訊。systemd 指令顯示詳細資料,例如描述、可執行檔、狀態、cgroup 及服務發出的最新訊息 (請參閱第 15.6.9 節 「服務除錯」)。使用 System V init 顯示的詳細資料級別因服務而異。

status
status

取得簡要的狀態資訊:  顯示服務是否處於使用中狀態。

is-active
status

15.2.2 永久啟用/停用服務

上一節中提及的服務管理指令可讓您操作目前工作階段的服務。systemd 還可讓您永久啟用或停用服務,使之可以按要求自動啟動,或者始終無法使用。此操作可以透過 YaST 或在指令行上執行。

15.2.2.1 在指令行上啟用/停用服務

下表列出了 systemd 和 System V init 用於啟用和停用服務的指令:

重要
重要:服務啟動

在指令行上啟用服務時,服務不會自動啟動。系統將其排定為下一次系統啟動或執行層級/目標變更時啟動。若要在啟用服務之後立即啟動它,請明確執行 systemctl start MY_SERVICErc MY_SERVICE start

表格 15.2︰ 用於啟用和停用服務的指令

任務

systemd 指令

System V init 指令

啟用: 

systemctl enable MY_SERVICE(S)

insserv MY_SERVICE(S)chkconfig -a MY_SERVICE(S)

停用: 

systemctl disable MY_SERVICE(S).service

insserv -r MY_SERVICE(S)chkconfig -d MY_SERVICE(S)

檢查:  顯示是否已啟用某個服務。

systemctl is-enabled MY_SERVICE

chkconfig MY_SERVICE

重新啟用:  與重新啟動服務相似,此指令先停用服務,然後再啟用該服務。若要使用服務的預設值重新啟用服務,可使用此任務。

systemctl reenable MY_SERVICE

遮罩:  停用某項服務之後,仍然可以手動啟動它。若要徹底停用服務,您需要予以遮罩。使用須謹慎。

systemctl mask MY_SERVICE

取消遮罩:  遮罩某項服務之後,惟有先將其取消遮罩,才能再次予以使用。

systemctl unmask MY_SERVICE

15.3 系統啟動和目標管理

啟動和關閉系統的整個程序由 systemd 維護。依此觀點,核心可以視為背景程序,以維護所有其他程序,並根據其他程式的要求來調整 CPU 時間和硬體存取。

15.3.1 目標與執行層級的比較

使用 System V init 時,系統將開機進入 執行層級。執行層級定義了系統的啟動方式,以及在所執行的系統中可以使用哪些服務。執行層級標有編號;最常見的執行層級是 0 (關閉系統)、3 (多重使用者,包含網路) 和 5 (多重使用者,包含網路及顯示管理員)。

systemd 使用所謂的目標單位引入新的概念。不過,它仍然與執行層級概念完全相容。目標單位是有名稱而不是有編號的,它有多個作用。例如,目標 local-fs.targetswap.target 掛接本地檔案系統和交換空間。

目標 graphical.target 提供包含網路和顯示管理員功能的多重使用者系統,與執行層級 5 相當。複雜的目標,例如 graphical.target 透過結合其他目標的子集用作 中繼目標。因為 systemd 能夠組合現有目標,便於建立自訂目標,因此提供了極大的靈活性。

下列清單顯示了最重要的 systemd 目標單位。如需完整清單,請參閱 man 7 systemd.special

選取的 systemd 目標單位
default.target

預設開機的目標。這並非 真實目標,而是一個符號連結,指向 graphic.target 之類的另一個目標。可透過 YaST 永久變更 (請參閱第 15.4 節 「使用 YaST 管理服務」)。若要為某個工作階段變更它,請在開機提示處使用核心參數 systemd.unit=MY_TARGET.target

emergency.target

在主控台上啟動緊急外圍程序。請僅在開機提示符處以如下格式使用它:systemd.unit=emergency.target

graphical.target

啟動包含網路、多重使用者支援和顯示管理員功能的系統。

halt.target

關閉系統。

mail-transfer-agent.target

啟動傳送和接收郵件所需的所有服務。

multi-user.target

啟動包含網路的多重使用者系統。

reboot.target

系統重新開機。

rescue.target

啟動不包含網路的單一使用者系統。

為了保持與 System V init 執行層級系統的相容,systemd 提供了名為 runlevelX.target 的特殊目標,對應於編號為 X 的相應執行層級。

如果您要知道目前的目標,請使用指令:systemctl get-default

表格 15.3︰ System V 執行層級和 systemd 目標單位

System V 執行層級

systemd 目標

用途

0

runlevel0.targethalt.targetpoweroff.target

關閉系統

1, S

runlevel1.targetrescue.target

單一使用者模式

2

runlevel2.targetmulti-user.target

本地多重使用者,不包含遠端網路

3

runlevel3.targetmulti-user.target

完整的多重使用者,包含網路

4

runlevel4.target

未使用/使用者定義

5

runlevel5.targetgraphical.target

完整的多重使用者,包含網路及顯示管理員

6

runlevel6.targetreboot.target

系統重新開機

重要
重要:systemd 會忽略 /etc/inittab

System V init 系統中的執行層級在 /etc/inittab 中設定。systemd 使用此組態。如需如何建立您自己的可開機目標的指示,請參閱第 15.5.4 節 「建立自訂目標」

15.3.1.1 用於變更目標的指令

請使用下列指令來操作目標單位:

任務

systemd 指令

System V init 指令

變更目前的目標/執行層級

systemctl isolate MY_TARGET.target

telinit X

變更為預設目標/執行層級

systemctl default

取得目前的目標/執行層級

systemctl list-units --type=target

對於 systemd,通常會有多個作用中目標。該指令列出目前處於使用中狀態的所有目標。

who -r

runlevel

永久性變更預設的執行層級

使用服務管理員或執行下列指令:

ln -sf /usr/lib/systemd/system/ MY_TARGET.target /etc/systemd/system/default.target

使用服務管理員或變更以下行

id: X:initdefault:

(位於 /etc/inittab 中)

變更目前開機程序的預設執行層級

在開機提示的選項中輸入下列文字:

systemd.unit= MY_TARGET.target

在開機提示中輸入所需的執行層級編號。

顯示目標/執行層級的相依性

systemctl show -p "Requires" MY_TARGET.target

systemctl show -p "Wants" MY_TARGET.target

Requires 會列出硬相依性 (必須解析的相依性),而 Wants 則列出軟相依性 (可行時解析的相依性)。

15.3.2 系統啟動除錯

systemd 針對系統啟動過程提供了分析方法。您可以查看所有服務及其狀態的清單 (而不必剖析 /var/log/)。systemd 還允許您掃描啟動程序,以瞭解每項服務耗費多長時間啟動。

15.3.2.1 檢視服務的啟動情況

若要檢閱自從系統開機以來已啟動的完整服務清單,請輸入指令 systemctl。這將列出所有使用中的服務,如下方所述 (已縮短)。若要獲得特定服務的詳細資訊,請使用 systemctl status MY_SERVICE

範例 15.1︰ 列出作用中的服務
root # systemctl
UNIT                        LOAD   ACTIVE SUB       JOB DESCRIPTION
[...]
iscsi.service               loaded active exited    Login and scanning of iSC+
kmod-static-nodes.service   loaded active exited    Create list of required s+
libvirtd.service            loaded active running   Virtualization daemon
nscd.service                loaded active running   Name Service Cache Daemon
chronyd.service             loaded active running   NTP Server Daemon
polkit.service              loaded active running   Authorization Manager
postfix.service             loaded active running   Postfix Mail Transport Ag+
rc-local.service            loaded active exited    /etc/init.d/boot.local Co+
rsyslog.service             loaded active running   System Logging Service
[...]
LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

161 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

若要限制為輸出無法啟動的服務,請使用 --failed 選項:

範例 15.2︰ 列出失敗的服務
root # systemctl --failed
UNIT                   LOAD   ACTIVE SUB    JOB DESCRIPTION
apache2.service        loaded failed failed     apache
NetworkManager.service loaded failed failed     Network Manager
plymouth-start.service loaded failed failed     Show Plymouth Boot Screen

[...]

15.3.2.2 啟動時間除錯

為了對系統啟動時間除錯,systemd 提供了 systemd-analyze 指令。它會顯示總啟動時間以及按啟動時間排序的服務清單,還可以產生 SVG 圖,其中顯示各服務相對於其他服務所耗費的啟動時間。

列出系統啟動時間
root # systemd-analyze
Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms
列出服務啟動時間
root # systemd-analyze blame
    15.000s backup-rpmdb.service
    14.879s mandb.service
     7.646s backup-sysconfig.service
     4.940s postfix.service
     4.921s logrotate.service
     4.640s libvirtd.service
     4.519s display-manager.service
     3.921s btrfsmaintenance-refresh.service
     3.466s lvm2-monitor.service
     2.774s plymouth-quit-wait.service
     2.591s firewalld.service
     2.137s initrd-switch-root.service
     1.954s ModemManager.service
     1.528s rsyslog.service
     1.378s apparmor.service
    [...]
服務啟動時間圖
root # systemd-analyze plot > jupiter.example.com-startup.svg

15.3.2.3 檢視完整的啟動程序

上面的指令行出了已啟動的服務及其啟動時間。如需更詳細的綜覽,請在開機提示符處指定以下參數,以指示 systemd 建立完整啟動程序的詳細記錄。

systemd.log_level=debug systemd.log_target=kmsg

現在,systemd 會將記錄訊息寫入核心環緩衝區。該緩衝區可透過 dmesg 檢視:

tux > dmesg -T | less

15.3.3 System V 相容性

Systemd 與 System V 相容,因此,您仍可以使用現有的 System V init 程序檔。但是,至少有一個已知問題會導致 System V init 程序檔不能立即與 systemd 配合使用:透過 init 程序檔中的 susudo 以其他使用者身分啟動服務會導致程序檔失敗,產生拒絕存取錯誤。

使用 susudo 變更使用者時,會啟動 PAM 工作階段。完成 init 程序檔後會終止此工作階段。因此,init 程序檔啟動的服務也會終止。若要解決此問題,請執行下列步驟:

  1. 建立與 init 程序檔同名、副檔名為 .service 的服務檔案包裝程式。

    [Unit]
    Description=DESCRIPTION
    After=network.target
    
    [Service]
    User=USER
    Type=forking1
    PIDFile=PATH TO PID FILE1
    ExecStart=PATH TO INIT SCRIPT start
    ExecStop=PATH TO INIT SCRIPT stop
    ExecStopPost=/usr/bin/rm -f PATH TO PID FILE1
    
    [Install]
    WantedBy=multi-user.target2

    以適當的值取代 UPPERCASE LETTERS 中寫入的所有值。

    1

    選擇性 — 僅當 init 程序檔啟動精靈時才使用。

    2

    multi-user.target 在開機到 graphical.target 時也會啟動 init 程序檔。如果只應在開機到顯示管理員時才將它啟動,請在此處使用 graphical.target

  2. 使用 systemctl start 應用程式啟動精靈。

15.4 使用 YaST 管理服務

基本服務管理也可以透過 YaST 服務管理員模組實現。該模組不僅支援啟動、停止、啟用和停用服務,還可用於顯示服務的狀態以及變更預設目標。若要啟動 YaST 模組,請選取「YaST ›  系統 ›  服務管理員」。

服務管理員
圖形 15.1︰ 服務管理員
變更預設系統目標

若要變更系統開機進入的目標,請從「預設系統目標」下拉方塊中選擇目標。最常用的目標是「圖形介面」 (啟動圖形登入畫面) 和「多重使用者」 (以指令行模式啟動系統)。

啟動或停止服務

從表中選取服務。狀態欄顯示它目前是正在執行 (作用中) 還是未在執行 (非作用中)。透過選擇啟動停止可切換其狀態。

如果啟動或停止服務,會變更其對目前執行中工作階段而言的狀態。若要在整個重新開機期間變更服務的狀態,您需要啟用或停用服務。

定義服務啟動行為

服務可以在開機時自動啟動,也可以手動啟動。從表中選取服務。啟動欄顯示它目前是手動啟動還是開機時啟動。透過選擇啟動模式可切換其狀態。

若要在目前工作階段中變更服務狀態,您需要依據上述方式啟動或停止服務。

檢視狀態訊息

若要檢視服務的狀態訊息,請從清單中選取該服務,然後選擇 顯示詳細資料。您看到的輸出與 systemctl -l status MY_SERVICE 指令產生的輸出完全相同。

15.5 自訂 systemd

下列各節列出了 systemd 自訂的一些範例。

警告
警告:防止您的自訂被覆寫

在自訂 systemd 時,請務必使用目錄 /etc/systemd/切勿使用 /usr/lib/systemd/。否則,systemd 下次更新時會覆寫您的變更。

15.5.1 自訂單位檔案

建議使用 systemctl edit SERVICE 指令來自訂單位檔案。此指令會啟動預設的文字編輯器,並建立一個在 /etc/systemd/system/NAME.service.d/ 中包含 override.conf 檔案的目錄。該指令還確定會向正在執行的 systemd 程序通知這些變更。

或者,您可以透過執行 systemctl edit --full SERVICE 來開啟原始檔案的副本進行編輯,而不是開啟一個空白檔案。編輯檔案時,請確定未移除任何現有區段。

下面將練習如何變更系統等待 MariaDB 啟動的時間。以 root 身分執行 systemctl edit --full mariadb.service。開啟的檔案如下所示:

[Unit]
Description=MySQL server
Wants=basic.target
Conflicts=mariadb.target
After=basic.target network.target

[Install]
WantedBy=multi-user.target
Alias=mysql.service

[Service]
Restart=on-abort
Type=notify
ExecStartPre=/usr/lib/mysql/mysql-systemd-helper  install
ExecStartPre=/usr/lib/mysql/mysql-systemd-helper  upgrade
ExecStart=/usr/lib/mysql/mysql-systemd-helper     start

# Configures the time to wait for start-up/stop
TimeoutSec=300

# Prevent writes to /usr, /boot, and /etc
ProtectSystem=full

# Prevent accessing /home, /root and /run/user
ProtectHome=true

UMask=007

調整 TimeoutSec 值並儲存變更。若要啟用變更,請以 root 身分執行 systemctl daemon-reload

如需詳細資訊,請參閱可使用 man 1 systemctl 指令呼叫的 man 頁面。

15.5.2 建立放入式檔案

若要對組態檔案進行微小變更,請使用所謂的放入式檔案。放入式檔案可讓您延伸單位檔案的組態,而不必編輯或覆寫單位檔案本身。

例如,若要變更位於 /usr/lib/systemd/system/FOOBAR.SERVICEFOOBAR 服務的單個值,請依照以下步驟操作:

  1. 建立名為 /etc/systemd/system/FOOBAR.service.d/ 的目錄。

    注意字尾為 .d。該目錄必須命名為要透過所放入之檔案修補的服務。

  2. 在該目錄中,建立 your_modification.conf 檔案。

    確保該檔案僅包含待修改值所在的行。

  3. 將您所做的變更儲存到檔案中。

注意
注意:避免名稱衝突

為避免放入式檔案與 SUSE 隨附檔案之間出現名稱衝突,建議在所有放入式檔案名稱前加上一個兩位數和一個破折號:例如,80-override.conf

以下範圍為保留值範圍:

  • 0-19,為 systemd 上游保留

  • 20-25,為 SUSE 隨附的 systemd 保留

  • 26-29,為 SUSE 套件 (systemd 除外) 保留

  • 50,為使用 systemctl set-property 建立的放入式檔案保留

請使用大於此範圍的兩位數,以確定 SUSE 隨附的任何放入式檔案都不會覆寫您自己的放入式檔案。

您可以使用 systemctl cat $UNIT 來列出並驗證考慮將哪些檔案納入單位組態。

15.5.3 xinetd 服務轉換為 systemd

SUSE Linux Enterprise Server 15 版本開始,移除了 xinetd 基礎架構。本節概述如何將現有的自訂 xinetd 服務檔案轉換為 systemd 通訊端。

對於每個 xinetd 服務檔案,您至少需要兩個 systemd 單位檔案:通訊端檔案 (*.socket) 和關聯的服務檔案 (*.service)。通訊端檔案告訴 systemd 要建立哪個通訊端,服務檔案告訴 systemd 要啟動哪個可執行檔。

以下面的 xinetd 服務檔案為例:

root # cat /etc/xinetd.d/example
service example
{
  socket_type = stream
  protocol = tcp
  port = 10085
  wait = no
  user = user
  group = users
  groups = yes
  server = /usr/libexec/example/exampled
  server_args = -auth=bsdtcp exampledump
  disable = no
}

若要將它轉換為 systemd,需要下面兩個相配的檔案:

root # cat /usr/lib/systemd/system/example.socket
[Socket]
ListenStream=0.0.0.0:10085
Accept=false

[Install]
WantedBy=sockets.target
root # cat /usr/lib/systemd/system/example.service
[Unit]
Description=example

[Service]
ExecStart=/usr/libexec/example/exampled -auth=bsdtcp exampledump
User=user
Group=users
StandardInput=socket

如需 systemd 的「通訊端」和「服務」檔案選項的完整清單,請參閱 systemd.socket 和 systemd.service 手冊頁 (man 5 systemd.socketman 5 systemd.service)。

15.5.4 建立自訂目標

在 System V init SUSE 系統上並未使用執行層級 4,便於管理員自行建立執行層級組態。systemd 可讓您建立任意個自訂目標。建議您在開始時先在 graphical.target 等現有的目標上調整。

  1. 將組態檔案 /usr/lib/systemd/system/graphical.target 複製到 /etc/systemd/system/MY_TARGET.target,並依據需要調整該檔案。

  2. 上一步中複製的組態檔案已涵蓋該目標的必要的 () 相依性。若要一併納入需要的 () 相依項,請建立目錄 /etc/systemd/system/MY_TARGET.target.wants

  3. 對每個需要的服務,建立從 /usr/lib/systemd/system 連到 /etc/systemd/system/MY_TARGET.target.wants 的符號連結。

  4. 設定好目標後,重新載入 systemd 組態以使新目標可用:

    tux > sudo systemctl daemon-reload

15.6 進階用法

下列各節涵蓋進階主題,適用於系統管理員。如需更為進階的 systemd 文件,請參閱 Lennart Pöttering 撰寫的適用於管理員的 systemd 相關系列文章,網址為 http://0pointer.de/blog/projects

15.6.1 清理暫存目錄

systemd 支援定期清理暫存目錄。將會自動移轉並啟用前一系統版本中的組態。tmpfiles.d (負責管理暫存檔案) 將從 /etc/tmpfiles.d/*.conf/run/tmpfiles.d/*.conf/usr/lib/tmpfiles.d/*.conf 檔案中讀取其組態。/etc/tmpfiles.d/*.conf 中的組態將會覆寫其他兩個目錄中的相關組態 (/usr/lib/tmpfiles.d/*.conf 是套件將其組態檔案儲存到的位置)。

組態格式為每個路徑一行,該行包含動作與路徑、(選擇性) 模式、擁有權、期限和引數欄位,具體視動作而定。以下範例將取消連結 X11 鎖定檔案:

Type Path               Mode UID  GID  Age Argument
r    /tmp/.X[0-9]*-lock

若要取得 tmpfile 計時器的狀態:

tux > sudo systemctl status systemd-tmpfiles-clean.timer
systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
 Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static)
 Active: active (waiting) since Tue 2018-04-09 15:30:36 CEST; 1 weeks 6 days ago
   Docs: man:tmpfiles.d(5)
         man:systemd-tmpfiles(8)

Apr 09 15:30:36 jupiter systemd[1]: Starting Daily Cleanup of Temporary Directories.
Apr 09 15:30:36 jupiter systemd[1]: Started Daily Cleanup of Temporary Directories.

如需處理暫存檔案的詳細資訊,請參閱 man 5 tmpfiles.d

15.6.2 系統記錄

第 15.6.9 節 「服務除錯」說明如何檢視給定服務的記錄訊息。然而,記錄的訊息顯示並不局限為服務記錄。您還可以存取和查詢 systemd 寫入的完整記錄訊息 — 亦即日誌。使用 journalctl 指令可顯示從最舊項目開始的完整記錄訊息。如需套用過濾器或變更輸出格式等選項的資訊,請參閱 man 1 journalctl

15.6.3 快照

您可以使用 isolate 子指令將 systemd 的目前狀態儲存到指定的快照,日後可以回復到該狀態。此功能在測試服務或自訂目標時非常有用,因為它允許您隨時回到定義的狀態。快照僅在目前工作階段中可用,重新開機時將自動刪除。快照名稱必須以 .snapshot 結尾。

建立快照
tux > sudo systemctl snapshot MY_SNAPSHOT.snapshot
刪除快照
tux > sudo systemctl delete MY_SNAPSHOT.snapshot
檢視快照
tux > sudo systemctl show MY_SNAPSHOT.snapshot
啟用快照
tux > sudo systemctl isolate MY_SNAPSHOT.snapshot

15.6.4 載入核心模組

使用 systemd,可透過 /etc/modules-load.d 中的組態檔案,在開機時自動載入核心模組。該檔案應命名為 MODULE.conf 並包含以下內容:

# load module MODULE at boot time
MODULE

如果某個套件安裝了用於載入核心模組的組態檔案,該檔案將安裝到 /usr/lib/modules-load.d。如果存在兩個同名的組態檔案,將優先使用 /etc/modules-load.d 中的組態檔案。

如需詳細資訊,請參閱 modules-load.d(5) 線上文件。

15.6.5 載入服務之前執行動作

使用 System V 時,需要在載入服務之前執行的 init 動作必須在 /etc/init.d/before.local 中指定。systemd 不再支援此程序。如果您需要在啟動服務之前執行動作,請執行以下步驟:

載入核心模組

/etc/modules-load.d 目錄中建立一個 drop-in 檔案 (如需語法,請參閱 man modules-load.d)

建立檔案或目錄,清理目錄,變更擁有權

/etc/tmpfiles.d 中建立一個 drop-in 檔案 (如需語法,請參閱 man tmpfiles.d)

其他任務

從以下範本建立一個系統服務檔案,例如 /etc/systemd/system/before.service

[Unit]
Before=NAME OF THE SERVICE YOU WANT THIS SERVICE TO BE STARTED BEFORE
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=YOUR_COMMAND
# beware, executable is run directly, not through a shell, check the man pages
# systemd.service and systemd.unit for full syntax
[Install]
# target in which to start the service
WantedBy=multi-user.target
#WantedBy=graphical.target

建立服務檔案後,應執行以下指令 (以 root 身分):

tux > sudo systemctl daemon-reload
tux > sudo systemctl enable before

每次修改服務檔案時,都需要執行:

tux > sudo systemctl daemon-reload

15.6.6 核心控制群組 (cgroup)

在傳統 System V init 系統上不一定能將程序明確指派給繁衍它的服務。有些服務 (例如 Apache) 會繁衍許多協力廠商程序 (例如 CGI 或 Java 程序),這些程序本身又會繁衍許多程序。這導致您很難明確指派,甚至根本無法明確指派。另外,服務在不當終止後,可能殘留部分子項保持活動狀態。

systemd 將每個服務放入它自己的 cgroup 中,從而解決此問題。cgroup 是一項核心功能,允許將程序及其所有子程序聚合至分層組織的群組中。systemd 根據相應的服務為每個 cgroup 命名。由於程序未經特許不得離開其 cgroup,因此這樣可以有效地使用服務名稱標記該服務繁衍的所有程序。

若要列出屬於服務的所有程序,請使用指令 systemd-cgls。結果類似於以下範例 (已縮短):

範例 15.3︰ 列出屬於某個服務的所有程序
root # systemd-cgls --no-pager
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
├─user.slice
│ └─user-1000.slice
│   ├─session-102.scope
│   │ ├─12426 gdm-session-worker [pam/gdm-password]
│   │ ├─15831 gdm-session-worker [pam/gdm-password]
│   │ ├─15839 gdm-session-worker [pam/gdm-password]
│   │ ├─15858 /usr/lib/gnome-terminal-server

[...]

└─system.slice
  ├─systemd-hostnamed.service
  │ └─17616 /usr/lib/systemd/systemd-hostnamed
  ├─cron.service
  │ └─1689 /usr/sbin/cron -n
  ├─postfix.service
  │ ├─ 1676 /usr/lib/postfix/master -w
  │ ├─ 1679 qmgr -l -t fifo -u
  │ └─15590 pickup -l -t fifo -u
  ├─sshd.service
  │ └─1436 /usr/sbin/sshd -D

[...]

如需 cgroup 的詳細資訊,請參閱Chapter 9, Kernel control groups

15.6.7 終止服務 (傳送訊號)

第 15.6.6 節 「核心控制群組 (cgroup)」中所述,在 System V init 系統中不一定能將程序指派給其父服務,導致難以終止服務及其所有子項。未終止的子程序將保留為廢止程序。

systemd 的概念是將每個服務限制在某個 cgroup 中,從而可以明確識別一個服務的所有子程序,因此可讓您將訊號傳送給這些程序中的每個程序。可使用 systemctl kill 將信號傳送給服務。如需可用信號清單,請參閱 man 7 signals

SIGTERM 傳送給服務

SIGTERM 是傳送的預設信號。

tux > sudo systemctl kill MY_SERVICE
SIGNAL 傳送給服務

可使用 -s 選項指定應傳送的信號。

tux > sudo systemctl kill -s SIGNAL MY_SERVICE
選取程序

依預設,kill 指令會將信號傳送給指定 cgroup 的 all 程序。您可以將傳送目標限制為 controlmain 程序。後者非常實用,如下例透過傳送 SIGHUP 強制服務重新載入其組態所示:

tux > sudo systemctl kill -s SIGHUP --kill-who=main MY_SERVICE

15.6.8 有關 D-Bus 服務的重要說明

D-Bus 服務是 systemd 用戶端與做為 pid 1 執行的 systemd 管理員之間進行通訊的訊息匯流排。雖然 dbus 是個獨立的精靈,但它也是 init 基礎架構的組成部分。

在執行中的系統中終止或重新啟動 dbus 的效果類似於嘗試終止或重新啟動 pid 1。此操作將中斷 systemd 用戶端與伺服器間的通訊,並使大部分 systemd 功能不可用。

因此,不建議也不支援終止或重新啟動 dbus

更新 dbus 或與 dbus 有關的套件需要重新開機。如果不確定是否需要重新開機,請執行 sudo zypper ps -s。如果 dbus 顯示在所列服務之中,則表明您需要將系統重新開機。

請記住,即使自動更新設定為跳過需要重新開機的套件,dbus 仍會更新。

15.6.9 服務除錯

依預設,systemd 的輸出不會太詳細。如果服務啟動成功,則不會產生任何輸出。如果啟動失敗,則會顯示簡短的錯誤訊息。不過,systemctl status 可讓您以不同方式對服務的啟動和作業進行除錯。

systemd 隨附自己的記錄機製 (日誌),可以記錄系統訊息,便於您一併顯示服務訊息與狀態訊息。status 指令的工作方式與 tail 相似,也可以採用不同的格式顯示記錄訊息,因此成為功能強大的除錯工具。

顯示服務啟動失敗訊息

每當服務啟動失敗時,使用 systemctl status MY_SERVICE 可獲得詳細的錯誤訊息:

root # systemctl start apache2
Job failed. See system journal and 'systemctl status' for details.
root # systemctl status apache2
   Loaded: loaded (/usr/lib/systemd/system/apache2.service; disabled)
   Active: failed (Result: exit-code) since Mon, 04 Apr 2018 16:52:26 +0200; 29s ago
   Process: 3088 ExecStart=/usr/sbin/start_apache2 -D SYSTEMD -k start (code=exited, status=1/FAILURE)
   CGroup: name=systemd:/system/apache2.service

Apr 04 16:52:26 g144 start_apache2[3088]: httpd2-prefork: Syntax error on line
205 of /etc/apache2/httpd.conf: Syntax error on li...alHost>
顯示最後 N 條服務訊息

status 子指令的預設行為是顯示服務發出的最近 10 條訊息。若要變更要顯示的訊息數,請使用 --lines=N 參數:

tux > sudo systemctl status chronyd
tux > sudo systemctl --lines=20 status chronyd
以附加模式顯示服務訊息

若要顯示服務訊息的 即時串流,請使用 --follow 選項,其工作方式與 tail -f 相似:

tux > sudo systemctl --follow status chronyd
訊息輸出格式

--output=模式參數可讓您變更服務訊息的輸出格式。最重要的可用模式如下:

short

預設格式。顯示記錄訊息及易於理解的時戳。

verbose

完整輸出所有欄位。

cat

精簡輸出,不含時戳。

15.7 systemd 計時器單位

與 cron 類似,systemd 計時器單位提供了一種在 Linux 上排程工作的機制。雖然 systemd 計時器單位的用途與 cron 相同,但其具備幾項優點。

  • 使用計時器單位排程的工作可以依賴於其他 systemd 服務。

  • 計時器單位被視為一般 systemd 服務,因此可以使用 systemctl 進行管理。

  • 計時器可以是即時計時器,也可以是單純計時器。

  • 時間單位會被記錄到 systemd 日誌中,使得更易於監控和疑難排解。

systemd 計時器單位透過 .timer 副檔名識別。

15.7.1 systemd 計時器類型

計時器單位可以使用單純計時器和即時計時器。

  • 與 cron 工作類似,即時計時器是依據行事曆事件觸發的。即時計時器使用選項 OnCalendar 進行定義。

  • 單純計時器將從某個特定起點開始經過指定時間後觸發。後者可以是系統開機或系統單位啟用事件。有幾個選項可用於定義單純計時器,包括 OnBootSecOnUnitActiveSecOnTypeSec。單純計時器不是永久的,每次重新開機後都將被重設。

15.7.2 systemd 計時器和服務單位

每個計時器單位都必須有一個其所控制的相應 systemd 單位檔案。也就是說,將由 .timer 檔案啟用並管理相應的 .service 檔案。使用計時器時,.service 檔案不需要 [Install] 區段,因為服務將由計時器管理。

15.7.3 具體範例

為了理解 systemd 計時器單位的基本知識,我們設定了一個觸發 foo.sh 外圍程序程序檔的計時器。

第一步是建立用於控制外圍程序程序檔的 systemd 服務單位。為此,請開啟一個新的文字檔案進行編輯,並新增以下服務單位定義:

[Unit]
Description="Foo shell script"

[Service]
ExecStart=/usr/local/bin/foo.sh

將檔案以名稱 foo.service 儲存到目錄 /etc/systemd/system/ 中。

接下來,開啟一個新的文字檔案進行編輯,並新增以下計時器定義:

[Unit]
Description="Run foo shell script"

[Timer]
OnBootSec=5min
OnUnitActiveSec=24h
Unit=foo.service

[Install]
WantedBy=multi-user.target

上述範例中的 [Timer] 區段指定了要觸發的服務 (foo.service) 以及觸發時間。在此範例中,選項 OnBootSec 指定了一個在系統開機後五分鐘觸發服務的單純計時器,而選項 OnUnitActiveSec 會在服務被啟用後 24 小時觸發服務 (即計時器將每天觸發一次服務)。最後,選項 WantedBy 指定應在系統達到多使用者目標時啟動計時器。

您也可以不指定單純計時器,而是使用選項 OnCalendar 指定即時計時器。下面的即時計時器定義從星期一 12:00 開始,每週觸發一次相關服務單位。

[Timer]
OnCalendar=weekly
Persistent=true

選項 Persistent=true 表示如果計時器錯過了上一次啟動時間 (例如,由於系統關閉),則會在計時器啟用後立即觸發服務。

選項 OnCalendar 還可以用於使用以下格式來定義觸發服務的具體日期和時間:DayOfWeek Year-Month-Day Hour:Minute:Second。下面的範例會在每天早上 5 點觸發服務:

OnCalendar=*-*-* 5:00:00

您可以使用星號指定任何值,使用逗號列出可能的值。使用由 .. 分隔的兩個值可表示一個連續的範圍。下面的範例會在每個月的星期五下午 6 點觸發服務:

OnCalendar=Fri *-*-1..7 18:00:00

若要在不同的時間觸發服務,您可以指定多個 OnCalendar 項目:

OnCalendar=Mon..Fri 10:00
OnCalendar=Sat,Sun 22:00

在上面的範例中,會在工作日的上午 10 點和週末的晚上 10 點觸發服務。

編輯好計時器單位檔案後,使用名稱 foo.timer 將其儲存到 /etc/systemd/system/ 目錄中。若要檢查所建立的單位檔案是否正確,請執行以下指令:

tux > sudo  systemd-analyze verify /etc/systemd/system/foo.*

如果指令未傳回任何輸出,則表示檔案成功通過驗證。

若要啟動計時器,請使用指令 sudo systemctl start foo.timer。若要在開機時啟用計時器,請執行指令 sudo systemctl enable foo.timer

15.7.4 管理 systemd 計時器

由於計時器被視為一般 systemd 單位,因此您可以使用 systemctl 來管理它們。您可以使用 systemctl start 啟動計時器,使用 systemctl enable 啟用計時器,依此類推。除此之外,您還可以使用指令 systemctl list-timers 列出所有作用中計時器。若要列出包括非作用中計時器在內的所有計時器,請執行指令 systemctl list-timers --all

15.8 更多資訊

如需 systemd 的詳細資訊,請參閱以下線上資源:

首頁

http://www.freedesktop.org/wiki/Software/systemd

適用於管理員的 systemd

Lennart Pöttering 是 systemd 的原著者之一,他撰寫了一系列部落格文章 (寫本章時已有 13 篇)。其網址為 http://0pointer.de/blog/projects

列印此頁面