套用至 SUSE Linux Enterprise Server 12 SP5

13 systemd 精靈

程式 systemd 是程序 ID 為 1 的程序。負責以所需的方式啟始化系統。systemd 由核心直接啟動,訊號 9 (通常會終止程序) 對它不起作用。所有其他程式不是由 systemd 直接啟動,就是由它的子程序啟動。

SUSE Linux Enterprise Server 12 起,systemd 取代了常用的 System V init 精靈。systemd 與 System V init 完全相容 (透過支援 init 程序檔)。systemd 的其中一個主要優點在於它透過積極主動的平行服務啟動,使開機速度顯著加快。另外,systemd 僅在切實需要服務時才會啟動該服務。它在開機時不會無條件地啟動精靈,而是在第一次需要時予以啟動。systemd 還支援「核心控制群組」(cgroup),對系統狀態拍攝快照並還原等等。如需詳細資料,請參閱 http://www.freedesktop.org/wiki/Software/systemd/

13.1 systemd 概念

本節將詳細討論 systemd 背後的概念。

13.1.1 systemd 是什麼

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

  • 提供積極主動的平行化功能

  • 使用插槽及 D-Bus 啟用方式來啟動服務

  • 提供精靈的隨需啟動

  • 使用 Linux cgroup 追蹤程序

  • 支援對系統狀態拍攝快照並還原

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

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

13.1.2 單位檔案

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

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

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

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

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

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

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

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

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

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

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

如需有關 systemd.unit 的詳細資訊,請參閱 http://www.freedesktop.org/software/systemd/man/systemd.unit.html

13.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

13.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 程序檔,而是執行類似如下的指令︰

systemctl start MY_1ST_SERVICE MY_2ND_SERVICE

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

systemctl list-unit-files --type=service

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

表格 13.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 及服務發出的最新訊息 (請參閱第 13.6.9 節 「服務除錯」)。使用 System V init 顯示的詳細資料級別因服務而異。

status
status

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

is-active
status

13.2.2 永久啟用/停用服務

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

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

下表列出了 systemd 和 System V init 的啟用和停用指令︰

重要
重要:服務啟動

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

表格 13.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

13.3 系統啟動和目標管理

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

13.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 永久變更 (請參閱第 13.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

表格 13.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 使用此組態。如需如何建立您自己的可開機目標的指示,請參閱第 13.5.3 節 「建立自訂目標」

13.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 則列出軟相依性 (可行時解析的相依性)。

13.3.2 系統啟動除錯

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

13.3.2.1 檢閱服務啟動

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

範例 13.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
ntpd.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 選項︰

範例 13.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

[...]

13.3.2.2 啟動時間除錯

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

列出系統啟動時間
root # systemd-analyze
Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms
列出服務啟動時間
root # systemd-analyze blame
  6472ms systemd-modules-load.service
  5833ms remount-rootfs.service
  4597ms network.service
  4254ms systemd-vconsole-setup.service
  4096ms postfix.service
  2998ms xdm.service
  2483ms localnet.service
  2470ms SuSEfirewall2_init.service
  2189ms avahi-daemon.service
  2120ms systemd-logind.service
  1210ms xinetd.service
  1080ms ntp.service
[...]
    75ms fbset.service
    72ms purge-kernels.service
    47ms dev-vda1.swap
    38ms bluez-coldplug.service
    35ms splash_early.service
服務啟動時間圖
root # systemd-analyze plot > jupiter.example.com-startup.svg

13.3.2.3 檢閱完成的啟動程序

上述指令可用於檢閱已啟動的服務及其啟動所耗費的時間。如果您需要知道更多詳細資料,可以在開機提示中輸入下列參數,指示 systemd 詳細記錄完整的啟動程序︰

systemd.log_level=debug systemd.log_target=kmsg

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

dmesg -T | less

13.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 應用程式啟動精靈。

13.4 使用 YaST 管理 服務

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

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

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

啟動或停止服務

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

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

啟用或停用服務

從表中選取服務。已啟用欄顯示它目前是已啟用還是已停用。其狀態可透過選擇啟用/停用進行切換。

透過啟用或停用服務,可設定在開機期間是否啟動該服務 (已啟用已停用)。此設定不影響目前的工作階段。若要變更該服務在目前工作階段中的狀態,您需要予以啟動或停止。

檢視狀態訊息

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

警告
警告:錯誤的執行層級設定可能會造成系統損害

錯誤的執行層級設定可能會導致系統無法使用。在您套用變更之前,請務必確定您知道它們的後果。

13.5 自訂 systemd

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

警告
警告:避免覆寫自訂

請務必在 /etc/systemd/ 中而絕非 /usr/lib/systemd/ 中自訂。否則,下次更新 systemd 時會覆寫您的變更。

13.5.1 自訂服務檔案

systemd 服務檔案位於 /usr/lib/systemd/system 中。如果您要自訂服務檔案,請執行下列步驟︰

  1. 將要修改的檔案從 /usr/lib/systemd/system 複製到 /etc/systemd/system。保持檔案名稱不變。

  2. 根據需要修改 /etc/systemd/system 中的副本。

  3. 如需組態變更概觀,請使用 systemd-delta 指令。它會比較並識別哪些組態檔案覆寫其他組態檔案。如需詳細資料,請參閱 sleha-init man 頁面。

/etc/systemd 中修改過的檔案優先於 /usr/lib/systemd/system 中的原始檔案,前提是它們的檔案名稱相同。

13.5.2 建立 放入式檔案

如果您只想在組態檔案中新增若干行或修改一小部分,可以使用放入式檔案。放入式檔案可讓您延伸單位檔案的組態,而不必編輯或覆寫單位檔案本身。

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

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

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

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

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

  3. 將您所做的變更儲存到檔案中。它將用作原始檔案的延伸。

13.5.3 建立自訂目標

在 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/我的目標.target.wants 的符號連結。

  4. 目標設定完畢後,重新載入 systemd 組態以便能夠使用新目標︰

    systemctl daemon-reload

13.6 進階用法

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

13.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 計時器的狀態︰

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 2014-09-09 15:30:36 CEST; 1 weeks 6 days ago
   Docs: man:tmpfiles.d(5)
         man:systemd-tmpfiles(8)

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

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

13.6.2 系統記錄

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

13.6.3 快照

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

建立快照
systemctl snapshot MY_SNAPSHOT.snapshot
刪除快照
systemctl delete MY_SNAPSHOT.snapshot
檢視快照
systemctl show MY_SNAPSHOT.snapshot
啟動快照
systemctl isolate MY_SNAPSHOT.snapshot

13.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) 線上文件。

13.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 身分)︰

systemctl daemon-reload
systemctl enable before

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

systemctl daemon-reload

13.6.6 核心控制群組 (cgroup)

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

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

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

範例 13.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
  ├─ntpd.service
  │ └─1328 /usr/sbin/ntpd -p /var/run/ntp/ntpd.pid -g -u ntp:ntp -c /etc/ntp.conf
  ├─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

13.6.7 終止服務 (傳送信號)

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

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

SIGTERM 傳送給服務

SIGTERM 是傳送的預設信號。

systemctl kill MY_SERVICE
信號傳送給服務

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

systemctl kill -s SIGNAL MY_SERVICE
選取程序

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

systemctl kill -s SIGHUP --kill-who=main MY_SERVICE

13.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 仍會更新。

13.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 Jun 2012 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

Jun 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 參數︰

systemctl status ntp
systemctl --lines=20 status ntp
以附加模式顯示服務訊息

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

systemctl --follow status ntp
訊息輸出格式

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

short

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

verbose

完整輸出所有欄位。

cat

精簡輸出,不含時戳。

13.7 更多資訊

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

首頁

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

管理員的 systemd

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

列印此頁面