Man page - daemon(7)

Packages contains this manual

Available languages:

en zh_TW zh_CN de

Manual

DAEMON

NAME
描 述
傳 統 的 SysV守 護 程 序
新 型 守 護 程 序
啟 動
系 統 啟 動 時 啟 動
基 於 套 接 字 的 啟 動
基 於 D-Bus 的 啟 動
基 於 裝 置 的 啟 動
基 於 路 徑 的 啟 動
基 於 定 時 器 的 啟 動
其 他 啟 動 方 式
與 SYSTEMD 整 合
編 寫 systemd 單 元 檔 案
安 裝 service 單 元 檔 案
移 植 已 有 的 守 護 程 序
放 置 守 護 程 序 的 資 料
參 見
NOTES


NAME

daemon - 編 寫 與 打 包 系 統 守 護 程 序

描 述

"守 護 程 序 "的 意 思 是 在 後 臺 執 行 的 服 務 程 序 , 常 用 於 監 督 系 統 的 執 行 或 者 提 供 某 種 功 能 。 在 傳 統 的 SysV Unix 系 統 上 , 多 個 守 護 程 序 必 須 嚴 格 按 照 特 定 的 順 序 依 次 啟 動 。 在 "新 型 "的 systemd (1) 系 統 上 , 守 護 程 序 的 啟 動 順 序 非 常 簡 單 且 非 常 強 大 。 本 手 冊 同 時 解 說 了 上 述 兩 種 不 同 的 啟 動 方 案 , 並 特 別 推 薦 了 應 該 包 含 在 systemd 系 統 中 的 守 護 程 序 。

傳 統 的 SysV守 護 程 序

傳 統 的 SysV守 護 程 序 在 啟 動 的 時 候 , 應 該 在 初 始 化 階 段 執 行 下 面 的 步 驟 :

1. 關 閉 除 STDIN STDOUT STDERR 之 外 的 所 有 檔 案 描 述 符

2. 重 置 所 有 訊 號 處 理 器

3. 重 置 所 有 訊 號 掩 碼

4. 清 理 環 境 變 數 (重 置 一 部 分 , 移 除 一 部 分 )

5. 呼 叫 fork() 建 立 一 個 後 臺 程 序

6. 在 子 程 序 中 呼 叫 setsid() 從 終 端 脫 離 並 建 立 一 個 獨 立 的 會 話

7. 在 子 程 序 中 再 一 次 呼 叫 fork() 以 確 保 守 護 程 序 永 遠 無 法 獲 取 任 何 終 端 。

8. 第 一 個 子 程 序 主 動 退 出 , 只 有 第 二 個 子 程 序 (實 際 的 守 護 程 序 )保 持 執 行 , 並 且 以 init(PID=1) 為 父 程 序 。

9. 守 護 程 序 (第 二 個 子 程 序 )將 STDIN STDOUT STDERR 連 線 到 /dev/null 虛 擬 裝 置

10. 守 護 程 序 將 umask 設 為 0

11. 守 護 程 序 將 當 前 目 錄 切 換 到 根 目 錄 (/)

12. 守 護 程 序 將 自 身 的 PID記 錄 到 例 如 /run/foobar.pid 這 樣 的 檔 案 中

13. 守 護 程 序 丟 棄 自 己 不 需 要 的 許 可 權 (如 果 可 以 )

14. 守 護 程 序 通 知 最 初 的 父 程 序 : 初 始 化 工 作 已 完 成

15. 最 初 的 父 程 序 自 身 退 出

注 意 , 這 些 步 驟 對 於 下 文 講 述 的 新 型 守 護 程 序 是 不 需 要 的 , 除 非 為 了 刻 意 相 容 傳 統 的 SysV系 統 。

新 型 守 護 程 序

Linux 系 統 上 的 新 型 守 護 程 序 更 容 易 被 監 控 也 更 容 易 實 現 。

守 護 程 序 無 需 實 現 前 文 所 描 述 的 複 雜 步 驟 , 即 可 直 接 在 systemd 提 供 的 乾 淨 的 上 下 文 環 境 中 執 行 :

環 境 變 數 已 經 被 清 理 、 訊 號 處 理 器 與 訊 號 掩 碼 已 經 被 重 置 、 沒 有 遺 留 的 檔 案 描 述 符 、 守 護 程 序 自 動 在 其 專 屬 的 會 話 中 執 行 、 標 準 輸 入 (STDIN)已 被 連 線 到 /dev/null 虛 擬 裝 置 (除 非 另 有 配 置 )、 標 準 輸 出 (STDOUT)與 標 準 錯 誤 (STDERR)已 被 連 線 到 systemd-journald.service (8) 日 誌 服 務 (除 非 另 有 配 置 )、 umask 已 經 被 重 置 ... 等 等

新 型 守 護 程 序 只 需 要 遵 守 如 下 要 求 :

1. 收 到 SIGTERM 訊 號 後 關 閉 程 序 並 確 保 乾 淨 的 退 出

2. 收 到 SIGHUP 訊 號 後 重 新 載 入 配 置 檔 案 (若 需 要 )

3. 主 守 護 程 序 在 退 出 時 應 該 按 照 LSB recommendations for SysV init scripts [1] 的 要 求 返 回 恰 當 的 退 出 碼 , 以 便 於 systemd 判 斷 服 務 的 退 出 狀 態 。

4. 若 可 行 , 在 初 始 化 的 最 後 一 步 , 透 過 D-Bus 建 立 程 序 的 控 制 介 面 , 並 在 D-Bus 上 註 冊 一 個 匯 流 排 名 稱 。

5. 提 供 一 個 .service 單 元 檔 案 , 包 含 如 何 啟 動 /停 止 /維 護 該 服 務 的 配 置 。 詳 見 systemd.service (5) 手 冊 。

6. 儘 可 能 依 賴 於 systemd 的 資 源 控 制 與 許 可 權 剝 奪 功 能 (CPU與 記 憶 體 佔 用 /檔 案 訪 問 等 等 ), 而 不 要 自 己 實 現 它 們 。 詳 見 systemd.exec (5) 手 冊 。

7. 若 使 用 了 D-Bus , 則 強 烈 推 薦 使 用 基 於 D-Bus 的 啟 動 機 制 。 這 樣 做 有 許 多 好 處 : 守 護 程 序 可 以 按 需 延 遲 啟 動 ; 可 以 和 依 賴 於 它 的 程 序 並 行 啟 動 (提 升 啟 動 速 度 ); 守 護 程 序 可 以 在 失 敗 時 被 自 動 重 啟 而 不 丟 失 D-Bus總 線 上 的 請 求 (詳 見 下 文 )

8. 若 守 護 程 序 透 過 套 接 字 提 供 服 務 , 則 強 烈 推 薦 使 用 基 於 套 接 字 的 啟 動 機 制 (詳 見 下 文 )。 這 樣 做 有 許 多 好 處 : 守 護 程 序 可 以 按 需 延 遲 啟 動 ; 可 以 和 依 賴 於 它 的 程 序 並 行 啟 動 (提 升 啟 動 速 度 ); 對 於 無 狀 態 協 議 (例 如 syslog, DNS), 守 護 程 序 可 以 在 失 敗 時 被 自 動 重 啟 而 不 丟 失 套 接 字 上 的 請 求 (詳 見 下 文 )

9. 若 可 能 , 守 護 程 序 應 該 透 過 sd_notify (3) 介 面 通 知 systemd "啟 動 已 完 成 "或 "狀 態 已 更 新 "這 樣 的 訊 息 。

10. 不 要 使 用 syslog() 記 錄 日 誌 , 只 需 簡 單 的 使 用 fprintf() 向 STDERR 輸 出 日 誌 即 可 。 如 果 必 須 指 明 日 誌 等 級 , 則 可 以 在 日 誌 的 行 首 加 上 類 似 "<4>" 這 樣 的 字 首 即 可 (這 裡 表 示 4級 "WARNING")。 詳 見 sd-daemon (3) 與 systemd.exec (5) 手 冊 。

上 述 要 求 與 Apple MacOS X Daemon Requirements [2] 類 似 , 但 並 不 完 全 相 同 。

啟 動

systemd 提 供 了 多 種 啟 動 機 制 (見 下 文 ), 而 服 務 單 元 也 經 常 同 時 使 用 其 中 的 幾 種 。 例 如 bluetoothd.service 可 以 在 插 入 藍 牙 硬 體 時 被 啟 動 , 也 可 以 在 某 程 序 訪 問 其 D-Bus 介 面 時 被 啟 動 。 又 如 列 印 服 務 可 以 在 IPP埠 有 流 量 接 入 時 被 啟 動 , 也 可 以 在 插 入 印 表 機 硬 體 時 被 啟 動 , 還 可 以 在 有 檔 案 進 入 印 表 機 spool 目 錄 時 被 啟 動 。 甚 至 對 於 必 須 在 系 統 啟 動 時 無 條 件 啟 動 的 服 務 , 為 了 儘 可 能 併 發 啟 動 , 也 應 該 使 用 某 些 啟 動 機 制 。 如 果 某 守 護 程 序 實 現 了 一 個 D-Bus 服 務 或 者 監 聽 一 個 套 接 字 , 那 麼 使 用 基 於 D-Bus 或 基 於 套 接 字 的 啟 動 機 制 , 將 允 許 該 程 序 與 其 客 戶 端 同 時 並 行 啟 動 (從 而 加 快 啟 動 速 度 )。 因 為 所 有 的 通 訊 渠 道 都 已 事 先 建 立 , 並 且 不 會 丟 失 任 何 客 戶 端 請 求 , 同 時 D-Bus 匯 流 排 或 者 核 心 會 將 客 戶 端 請 求 排 入 佇 列 等 候 , 直 到 完 成 啟 動 。

系 統 啟 動 時 啟 動

傳 統 的 守 護 程 序 一 般 是 在 系 統 啟 動 時 透 過 SysV初 始 化 指 令 碼 自 動 啟 動 , systemd 也 支 援 這 種 啟 動 方 式 。

對 於 systemd 來 說 , 如 果 希 望 確 保 某 單 元 在 系 統 啟 動 時 自 動 啟 動 , 那 麼 最 佳 的 做 法 是 在 預 設 啟 動 目 標 (通 常 是 multi-user.target 或 graphical.target)的 .wants/ 目 錄 中 為 該 單 元 建 立 軟 連 結 。 參 見 systemd.unit (5) 手 冊 以 瞭 解 .wants/ 目 錄 , 參 見 systemd.special (7) 手 冊 以 瞭 解 上 述 兩 個 特 殊 的 啟 動 目 標 。

基 於 套 接 字 的 啟 動

為 了 儘 可 能 提 高 並 行 性 與 健 壯 性 , 以 及 簡 化 配 置 與 開 發 , 對 於 需 要 監 聽 套 接 字 的 服 務 , 強 烈 推 薦 使 用 基 於 套 接 字 的 啟 動 機 制 。 使 用 此 機 制 後 , 守 護 程 序 不 再 需 要 建 立 和 繫 結 套 接 字 , 而 是 由 systemd 接 管 這 個 工 作 。 systemd 將 會 根 據 單 元 檔 案 的 設 定 , 預 先 建 立 所 需 的 套 接 字 , 並 在 第 一 個 客 戶 端 請 求 接 入 的 時 候 啟 動 該 服 務 , 以 實 現 服 務 的 按 需 啟 動 。 該 機 制 的 好 處 還 在 於 , 預 先 建 立 好 套 接 字 之 後 , 所 有 使 用 此 套 接 字 通 訊 的 程 序 可 以 並 行 啟 動 (包 括 客 戶 端 和 服 務 端 )。 此 外 , 重 啟 服 務 只 會 導 致 丟 失 最 低 限 度 的 客 戶 端 連 線 , 甚 至 不 丟 失 任 何 客 戶 端 請 求 (例 如 對 於 DNS 或 syslog 這 樣 的 無 狀 態 協 議 )。 因 為 套 接 字 在 服 務 重 啟 期 間 始 終 保 持 有 效 並 且 可 被 訪 問 , 同 時 所 有 客 戶 端 請 求 也 都 被 排 入 佇 列 等 候 處 理 。

使 用 此 機 制 之 後 , 守 護 程 序 必 須 要 從 systemd 接 收 已 建 立 好 的 套 接 字 , 而 不 能 自 己 建 立 並 繫 結 套 接 字 。 關 於 如 何 使 用 該 機 制 , 參 見 sd_listen_fds (3) 與 sd-daemon (3) 手 冊 。 只 需 要 小 小 的 修 改 , 即 可 在 原 有 啟 動 機 制 的 基 礎 上 新 增 基 於 套 接 字 的 啟 動 機 制 , 至 於 如 何 移 植 , 詳 見 後 文 。

systemd 透 過 .socket 單 元 實 現 該 機 制 , 詳 見 systemd.socket (5) 手 冊 。 必 須 確 保 所 有 為 支 援 基 於 套 接 字 啟 動 而 建 立 的 監 聽 socket 單 元 都 被 包 含 在 sockets.target 中 。 建 議 在 socket 單 元 的 "[Install]" 小 節 加 入 WantedBy=sockets.target 設 定 , 以 確 保 在 啟 用 該 單 元 時 能 夠 自 動 新 增 上 述 依 賴 關 係 。 除 非 明 確 設 定 了 DefaultDependencies=no , 否 則 會 為 所 有 socket 單 元 隱 含 的 建 立 必 要 的 順 序 依 賴 。 有 關 sockets.target 的 解 釋 , 詳 見 systemd.special (7) 手 冊 。 如 果 某 socket 單 元 已 被 包 含 在 sockets.target 中 , 那 麼 不 建 議 在 其 中 再 新 增 任 何 額 外 的 依 賴 關 係 (例 如 multi-user.target 之 類 )。

基 於 D-Bus 的 啟 動

如 果 守 護 程 序 使 用 D-Bus 與 客 戶 端 通 訊 , 那 麼 它 應 該 使 用 基 於 D-Bus 的 啟 動 機 制 , 這 樣 當 客 戶 端 訪 問 其 D-Bus 介 面 時 , 該 服 務 將 被 自 動 啟 動 。 該 機 制 是 透 過 D-Bus service 檔 案 實 現 的 (不 要 與 普 通 的 單 元 檔 案 混 淆 )。 為 了 確 保 讓 D-Bus 使 用 systemd 來 啟 動 與 維 護 守 護 程 序 , 必 須 在 這 些 D-Bus service 檔 案 中 使 用 SystemdService= 指 明 其 匹 配 的 服 務 單 元 。 例 如 , 對 於 檔 名 為 org.freedesktop.RealtimeKit.service 的 D-Bus service 來 說 , 為 了 將 其 繫 結 到 rtkit-daemon.service 服 務 單 元 , 必 須 確 保 在 該 檔 案 中 設 定 了 SystemdService=rtkit-daemon.service 指 令 。 注 意 , 必 須 明 確 設 定 SystemdService= 指 令 , 否 則 當 服 務 單 元 同 時 使 用 多 種 啟 動 機 制 時 , 可 能 會 導 致 競 爭 條 件 的 出 現 。

基 於 裝 置 的 啟 動

用 於 管 理 特 定 型 別 硬 體 的 守 護 程 序 , 只 應 該 在 符 合 條 件 的 硬 體 變 為 可 用 或 者 被 插 入 時 , 才 需 要 啟 動 。 為 了 達 到 上 述 目 的 , 可 以 將 服 務 的 啟 動 /停 止 與 硬 體 的 插 入 /拔 出 事 件 繫 結 。 當 帶 有 "systemd" 標 籤 的 裝 置 出 現 在 sysfs/udev 裝 置 樹 中 時 , systemd 將 會 自 動 為 其 建 立 對 應 的 device 單 元 。 透 過 向 這 些 單 元 中 新 增 對 其 他 單 元 的 Wants= 依 賴 , 就 可 以 實 現 當 該 device 單 元 被 啟 動 (也 就 是 硬 體 被 插 入 )時 , 連 帶 啟 動 其 他 單 元 , 從 而 實 現 基 於 裝 置 的 啟 動 。 這 可 以 透 過 向 udev 規 則 庫 中 新 增 SYSTEMD_WANTS= 屬 性 來 實 現 , 詳 見 systemd.device (5) 手 冊 。 通 常 , 並 不 是 將 service 單 元 直 接 新 增 到 裝 置 的 Wants= 依 賴 中 , 而 是 透 過 專 用 的 target 單 元 間 接 新 增 。 例 如 , 不 是 將 bluetoothd.service 新 增 到 各 種 藍 牙 裝 置 的 Wants= 依 賴 中 , 而 是 將 bluetoothd.service 新 增 到 bluetooth.target 的 Wants= 依 賴 中 , 同 時 再 將 bluetooth.target 新 增 到 各 種 藍 牙 裝 置 的 Wants= 依 賴 中 。 透 過 引 入 bluetooth.target 這 個 抽 象 層 , 系 統 管 理 員 無 需 批 次 修 改 udev 規 則 庫 , 僅 透 過 systemctl enable|disable ... 命 令 修 改 bluetooth.target.wants/ 目 錄 中 的 軟 連 結 , 即 可 控 制 bluetoothd.service 的 使 用 。

基 於 路 徑 的 啟 動

對 於 處 理 spool 檔 案 或 目 錄 的 守 護 程 序 (例 如 列 印 服 務 )來 說 , 僅 在 spool 檔 案 或 目 錄 狀 態 發 生 變 化 或 者 內 容 非 空 時 , 才 需 要 啟 動 。 透 過 .path 單 元 實 現 的 、 基 於 路 徑 的 啟 動 機 制 正 好 適 用 於 這 種 場 合 , 詳 見 systemd.path (5) 手 冊 。

基 於 定 時 器 的 啟 動

對 於 週 期 性 的 操 作 (例 如 垃 圾 檔 案 清 理 或 者 網 路 對 時 ), 可 以 透 過 基 於 定 時 器 的 啟 動 機 制 來 實 現 。 這 種 機 制 透 過 .timer 單 元 實 現 , 詳 見 systemd.timer (5) 手 冊 。

其 他 啟 動 方 式

在 其 他 作 業 系 統 上 還 存 在 著 其 他 的 啟 動 機 制 , 不 過 這 些 機 制 都 可 以 被 前 述 的 各 種 機 制 的 組 合 替 代 。 因 此 在 這 裡 不 再 贅 述 。

與 SYSTEMD 整 合

編 寫 systemd 單 元 檔 案

在 編 寫 單 元 檔 案 時 應 當 考 慮 下 列 建 議 :

1. 儘 可 能 不 用 Type=forking 。 若 非 用 不 可 , 則 必 須 正 確 設 定 PIDFile= 指 令 。 參 見 systemd.service (5) 手 冊 。

2. 若 守 護 程 序 在 D-Bus 上 註 冊 了 一 個 名 字 , 則 應 儘 可 能 使 用 Type=dbus

3. 設 定 一 個 易 於 理 解 的 Description=

4. 確 保 DefaultDependencies=yes , 除 非 該 單 元 必 須 在 系 統 啟 動 的 早 期 啟 動 或 者 必 須 在 系 統 關 閉 的 末 期 關 閉 。

5. 通 常 無 需 顯 式 定 義 依 賴 關 係 。 不 過 , 如 果 確 實 需 要 顯 式 定 義 依 賴 關 係 , 為 了 確 保 單 元 檔 案 不 侷 限 於 特 定 的 發 行 版 , 僅 應 該 依 賴 於 systemd.special (7) 中 列 出 的 單 元 以 及 自 身 所 屬 軟 體 包 中 提 供 的 單 元 。

6. 確 保 在 "[Install]" 小 節 中 包 含 完 整 的 啟 用 資 訊 (參 見 systemd.unit (5) 手 冊 )。 若 希 望 自 動 啟 動 該 單 元 , 則 應 該 設 定 WantedBy=multi-user.target WantedBy=graphical.target 若 希 望 自 動 啟 動 該 單 元 的 套 接 字 , 則 應 該 設 定 WantedBy=sockets.target 。 通 常 你 還 希 望 在 啟 用 該 單 元 時 , 一 起 啟 用 對 應 的 套 接 字 單 元 (假 定 為 foo.service), 因 此 還 應 該 設 定 Also=foo.socket

安 裝 service 單 元 檔 案

當 從 原 始 碼 編 譯 安 裝 ( make install )軟 體 包 時 , 其 中 的 系 統 服 務 單 元 檔 案 會 被 預 設 安 裝 到 pkg-config systemd --variable=systemdsystemunitdir 命 令 返 回 的 目 錄 中 (通 常 是 /usr/lib/systemd/system); 而 其 中 的 使 用 者 服 務 單 元 檔 案 會 被 預 設 安 裝 到 pkg-config systemd --variable=systemduserunitdir 命 令 返 回 的 目 錄 中 (通 常 是 /usr/lib/systemd/user); 但 並 不 應 該 使 用 systemctl enable ... 命 令 啟 用 它 們 。 當 從 包 管 理 器 安 裝 ( rpm -i )二 進 位 制 軟 體 包 時 , 其 中 的 單 元 檔 案 應 該 同 樣 安 裝 到 上 述 位 置 。 但 不 同 之 處 在 於 , 還 應 該 使 用 systemctl enable ... 命 令 啟 用 它 們 , 因 此 安 裝 的 單 元 有 可 能 會 在 開 機 時 自 動 啟 動 。

移 植 已 有 的 守 護 程 序

雖 然 systemd 相 容 傳 統 的 SysV 初 始 化 系 統 , 但 是 移 植 舊 有 的 守 護 程 序 可 以 更 好 的 利 用 systemd 的 先 進 特 性 。 建 議 對 舊 有 的 SysV 守 護 程 序 做 如 下 改 進 : ...[省 略 ]...

放 置 守 護 程 序 的 資 料

建 議 遵 守 file-hierarchy (7) 所 建 議 的 通 用 準 則 。

參 見

systemd (1), sd-daemon (3), sd_listen_fds (3), sd_notify (3), daemon (3), systemd.service (5), file-hierarchy (7)

NOTES

1.

LSB recommendations for SysV init scripts

http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html

2.

Apple MacOS X Daemon Requirements

https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html

本 頁 面 中 文 版 由 中 文 man 手 冊 頁 計 劃 提 供 。

翻 譯 人 員 : 金 步 國
金 步 國 作 品 集 : http://www.jinbuguo.com
中 文 man 手 冊 頁 計 劃 : https://github.com/man-pages-zh/manpages-zh