systemd

 systemdLinux下的一種init軟件,由Lennart Poettering帶頭開發,並在LGPL 2.1及其後續版本許可證下開源發佈。其開發目標是提供更優秀的框架以表示系統服務間的依賴關係,並依此實現系統初始化時服務的並行啓動,同時達到降低Shell系統開銷的效果,最終代替現在常用的System VBSD風格init程序。
   傳統的
System V是串行啓動,即在啓動下一個腳本前,上一個腳本必須執行完,這樣在啓動時間上會有很大的浪費。在這個時間就是金錢的年代,這種啓動方式必將被淘汰。  首先Ubuntu 最先造反,啓用了自己的upstart啓動方式,upstart基於事件觸發,但還是串行啓動,但是對於沒有必要的服務就不會啓動。
    這時 systemd出現了,主要優點就是並行啓動,節約啓動時間,systemd作者曾口出狂言,最快2秒啓動
    相比以前的
System V啓動方式有以下優化:
  • 採用Socket激活式與總線激活式服務,以提高相互依賴的各服務的並行運行性能;
  • cgroups代替PID來追蹤進程,以此即使是兩次fork之後生成的守護進程也不會脫離systemd的控制 
 
一:傳統的啓動是內核啓動完後,首先執行的第一個進程是/sbin/init。
    如果要以systemd方式啓動,則首先讓內核
執行的第一個進程是/lib/systemd/systemd或者/usr/lib/systemd/systemd.
    方法是在
grub界面輸入init=/lib/systemd/systemd

二:systemd啓動後,首先會去三個目錄下找相應的配置文件,按優先級從高到底爲/etc/systemd/,/usr/lib/systemd/
    和
/lib/systemd/,優先級高的配置文件會覆蓋優先級低的配置文件

三:systemd的配置文件又叫unit文件,主要有以下幾種

  1. service :守護進程的啓動、停止、重啓和重載是此類 unit 中最爲明顯的幾個類型。
  2. socket :此類 unit 封裝系統和互聯網中的一個 socket 。當下,systemd 支持流式、數據報和連續包的 AF_INET、AF_INET6、AF_UNIX socket 。也支持傳統的 FIFOs 傳輸模式。每一個 socket unit 都有一個相應的服務 unit 。相應的服務在第一個“連接”進入 socket 或 FIFO 時就會啓動(例如:nscd.socket 在有新連接後便啓動 nscd.service)。
  3. device :此類 unit 封裝一個存在於 Linux 設備樹中的設備。每一個使用 udev 規則標記的設備都將會在 systemd 中作爲一個設備 unit 出現。udev 的屬性設置可以作爲配置設備 unit 依賴關係的配置源。
  4. mount :此類 unit 封裝系統結構層次中的一個掛載點。
  5. automount :此類 unit 封裝系統結構層次中的一個自掛載點。每一個自掛載 unit 對應一個已掛載的掛載 unit (需要在自掛載目錄可以存取的情況下儘早掛載)。
  6. target :此類 unit 爲其他 unit 進行邏輯分組。它們本身實際上並不做什麼,只是引用其他 unit 而已。這樣便可以對 unit 做一個統一的控制。(例如:multi-user.target 相當於在傳統使用 SysV 的系統中運行級別5);bluetooth.target 只有在藍牙適配器可用的情況下才調用與藍牙相關的服務,如:bluetooth 守護進程、obex 守護進程等)
  7. snapshot :與 target unit 相似,快照本身不做什麼,唯一的目的就是引用其他 unit 。 

 四:systemd啓動的第一個unit文件爲/lib/systemd/system/下的default.target文件(這裏的default.target一般爲鏈接文
        件,這樣
default.target指向不同的文件,可達到不同的啓動等級

        例:
                可以看到,
default.target指向graphical.target這個文件,graphical.target表示圖形界面這個等級
                
graphical.target其內容如下: 
            

            Description=    :一些描述,顯示給用戶界面看的,可以是任何字符串,一般是關於服務的說明。

            Documentation=  :指定參考文檔的列表。
            
Requires=   :指定graphical.target依賴於multi-user.target這個服務,如果graphical.target被激活,那麼 Requires 後面
            的
multi-user.target服務也會被激活,反之,如果 Requires 後面的multi-user.target服務被停止或無法啓動,則graphical.target
            
服務也會停止。這個選項可以指定多次,那麼就要求所有指定的服務都被激活。
            After= :表示啓動完multi-user.target後,再啓動graphical.target。同時還有Before= :表示啓動完本服務後,再啓動Before後面
            的服務。

            Conflicts= :配置一個依賴衝突,當rescue.target服務啓動時,graphical.target服務停止,反過來,graphical.target服務啓動,
            那麼
rescue.targe就會停止。
            
Wants=    :相對弱化的 Requires= ,display-manager.target會被啓動,但如果無法啓動或無法添加到事務處理,並不影
            響
graphical.target服務做爲一個整體的啓動。
            
AllowIsolate= :布爾值。如果是真值,則此服務可以使用 systemctl isolate 命令進行操作。否則會拒絕此操作。默認值是假。
            Alias=  :在安裝使用應該使用的別名。名字必須和服務本身有同樣的後綴(即同樣的類型)。這個選項可以指定多次,所有的
            名字都起作用,當執行 systemctl enable 命令時,會建立相當的鏈接

五:常用的命令

        Description=   :一些描述,顯示給用戶界面看的,可以是任何字符串,一般是關於服務的說明。
 
        Documentation=  :指定參考文檔的列表,以空格分開的 URI 形式,如http://, https://, file:, info:, man:,這是有順序的,最好是先解釋這個服務的目的是什麼,然後是它是如何配置的,再然後是其它文件,這個選項可以多次指定,會將多行的合併,如果指定了一個空的,那麼會重置此項,前的配置不在起作用。
     
        Requires=   :指定此服務依賴的其它服務,如果本服務被激活,那麼 Requires 後面的服務也會被激活,反之,如果 Requires 後面的服務被停止或無法啓動,則本服務也會停止。這個選項可以指定多次,那麼就要求所有指定的服務都被激活。需要注意的是這個選項不影響啓動或停止的順序,啓動順序使用單句的 After= 和 Before= 來配置。例如,如果 foo.service 依賴  bar.serivce,但是隻配置了 Requires= 而沒有 After= 或 Before=,那麼 foo.service 啓動時會同時激活 foo.service 和 bar.service。通常使用 Wants= 代替 Requires= 是更好的選擇,因爲系統會更好的處理服務失敗的情況。注意,這種依賴關係,也可以在文件之外來處理,即使用 .requires/ 目錄,可以參看上面的說明。
 
        RequiresOverridable=     :類似上面的 Requires= ,不過這種情況下,只要用戶明確要求它啓動,纔會影響到被依賴的服務,不然服務出錯什麼的,不會影響被依賴服務的啓動。
 
        Requisite=RequisiteOverridable=  :分別類似上面的兩個,不過如果是這個指定服務沒有啓動,被依賴的服務會不啓動,立即失敗。
 
        Wants=    :相對弱化的 Requires= ,這裏列出的服務會被啓動,但如果無法啓動或無法添加到事務處理,並不影響本服務做爲一個整體的啓動。這是推薦的兩個服務關聯的方式。這種依賴也可以配置文件外,通過 .wants/ 目錄添加,具體可以看上面的說明。
 
        BindsTo= :和 Requires= 很像,但是這種情況,如果他後面列出的服務停止運行或崩潰之類的,本服務也會同時停止。
        PartOf=  :又一個類似 Requires= 的選項,但是限制在停止或重啓動服務,如果這裏列出的服務被停止或重啓動,那麼本服務也會停止或重啓動,注意這個依賴是意向,即本服務停止或重啓動,不會影響到這裏列出服務的運行狀態。
 
        Conflicts= :配置一個依賴衝突,如果配置了些項,那麼,當一個服務啓動時,或停止此處列出的服務,反過來,如果這裏列出的服務啓動,那麼本服務就會停止,即後啓動的才起作用。注意,此設置和 After= 和 Before= 是互相獨立的。如果服務 A 和 B 衝突,且在 B 啓動的時候同時啓動,那麼有可能會啓動失敗(兩都都是必需的)或修改以修復它(兩者之一或兩都都不是必需的),後一種情況,會將不需要的依賴刪除,或停止衝突。
 
        Before=After=  :配置服務間的啓動順序,比如一個 foo.service 包含了一行 Before=bar.service,那麼當他們同時啓動時,bar.service 會等待 foo.service 啓動完成後才啓動。注意這個設置和 Requires= 的相互獨立的,同時包含 After= 和 Requires= 也是常見的。此選項可以指定一次以上,這時是按順序全部啓動。
 
        OnFailure=       :列出一個或更多的服務,當本服務啓動狀態是 failed 的時候,激活這些服務。
 
        PropagatesReloadTo=ReloadPropagatedFrom=  :這兩個是列出一些服務,當其它服務 reload 時同時 reload 這個服務,或者反之。
 
        RequiresMountsFor=  :用空格分開的絕對路徑列表,是 Requires= 和 After= 添加的依賴中的 mount 文件需要訪問的指定的路徑。
        OnFailureIsolate=  :是一個布爾值,如果是真,那麼 OnFailure= 後面的服務會進入隔離模式,即所有不是它依賴的服務都會停止。如果只設置一個服務,可以放在 OnFailure= 後,默認值是假。
        IgnoreOnIsolate=    :一個布爾值.如果是真則當隔離其它服務時本服務不會停止(不明白隔離是什麼意思,大概在後面)。默認是假。

        IgnoreOnSnapshot=  :一個布爾值.如果是真則本服務不包含快照(snapshots)。對 device 和 snapshot 服務默認爲真,其它服務默認爲假。
        StopWhenUnneeded=  :一個布爾值。如果是真則當本服務不使用時會停止。 注意,爲了儘量減少 systemd 的工作,默認情況下是不會停止不使用的服務的,除非和其它服務衝突,或用戶明確要求停止。如果設置了這個選項,那麼如果沒有其它活動的服務需要此服務,它會自動停止。默認值是假。

        RefuseManualStart=RefuseManualStop=  :布爾值。如果設爲真值,則此服務只能間接的激活或停止。這種情況下,用戶直接啓動或停止此服務會被拒絕,只有做爲其它的服務依賴關係,由其它服務進行啓動或停止纔可以。這主要是爲了停止用戶誤操作。默認值是假。

        AllowIsolate=      :布爾值。如果是真值,則此服務可以使用 systemctl isolate 命令進行操作。否則會拒絕此操作。最好的辦法是不要動這處選項,除非目標服務的行爲類似於 SysV 啓動系統中的 runlevels。只是一種預防措施,避免系統無法使用的狀態。默認值是假。

        DefaultDependencies=  :布爾值。如果是真(默認值),一些本服務默認的依賴會隱式的建立,具體是哪些依賴,則於服務的類型決定。比如,對於普通的服務(.service類型),它會確保在系統基本服務啓動後才啓動本服務,會在系統關機前確保本服務已關閉。一般來說,只有早期開機服務和後期的關機服務,才需要把這個設成假。強烈對大多數普通服務,讓這個選項啓用即可。如果設成假,也不會禁用所有的隱式依賴,只是禁用那些非必要的。
 
        JobTimeoutSec=  :當一個客戶端等待本服務的某個 Job 完成時,所指定的超時時間。如果達到了限制的時間,此 Job 會取消運行,但服務不會更改狀態,包括進入“failed”狀態。除了設備服務(即.device類型),其它的默認值是0(即沒有超時設置)。注意,這個是獨立於特定服務所設置的超時設置的(比如對 .service 類型所設置的 Timeout=),它對服務本身沒有影響,但特定服務的設置是有影響的(能用來更改服務狀態)。
 
ConditionPathExists=ConditionPathExistsGlob=ConditionPathIsDirectory=ConditionPathIsSymbolicLink=ConditionPathIsMountPoint=ConditionPathIsReadWrite=ConditionDirectoryNotEmpty=,ConditionFileNotEmpty=ConditionFileIsExecutable=ConditionKernelCommandLine=ConditionVirtualization=ConditionSecurity=ConditionCapability=ConditionHost=ConditionACPower=,ConditionNull=  :這是一組類似的東西。檢測特定的條件是不是真值,如果不是真值,服務會略過啓動,但是它依賴的服務還是會正常運行的。這個條件測試失敗不會讓服務進入失敗狀態。條件是在服務開始運行時檢查的。
 
  ConditionPathExists= 是指定在服務啓動時檢查指定文件的存在狀態。如果指定的絕對路徑名不存在,這個條件的結果就是失敗。如果絕對路徑的帶有!前綴,則條件反轉,即只有路徑不存在時服務才啓動。
  ConditionPathExistsGlob= 類似上面的選項,但支持通配符。
  ConditionPathIsDirectory= 判斷指定路徑是不是目錄。
  ConditionPathIsSymbolicLink= 判斷指定路徑是不是鏈接。
  ConditionPathIsMountPoint= 判斷指定路徑是不是一個掛載點。
  ConditionPathIsReadWrite= 多年指定路徑是否可讀寫(即不是做爲只讀系統掛載的)
  ConditionDirectoryNotEmpty= 判斷指定目錄是否存在且不爲空。
  ConditionFileNotEmpty= 判斷指定文件是否是常規文件且不爲空(即大小不是0)。
  ConditionFileIsExecutable= 判斷指定文件是否是常規文件且可執行。
  類似的,ConditionKernelCommandLine=是判斷有沒有指定的內核命令行啓動參數(或帶有!反之),這個參數必須是一個單詞或用=分開的兩個單詞,前一種情況下,會尋找內核參數是否有此單詞或是賦值的左邊。後一種情況則必須是賦值的左右同時符合。
 
  ConditionVirtualization= 是判斷是不是在虛擬化環境下執行的服務。這可以是個布爾值以判斷是不是任意的虛擬化環境,或者下列的字符串之一: qemu, kvm, vmware, microsoft, oracle, xen, bochs, chroot, openvz, lxc, lxc-libvirt, systemd-nspawn,以判斷是不是特定的虛擬化環境,多重嵌套的虛擬化環境,只判斷最後一層。可以使用!進行反轉判斷。
 
  ConditionSecurity= 是判斷系統是否啓用了安全環境,當前僅能識別selinuxapparmor, 和 smack。可以使用!進行反轉判斷。
 
  ConditionCapability= 是判斷服務管理器綁定的 capability 是否存在。(可以查看其它部分的詳細信息。)設置爲 capability 的名字,比如 CAP_MKNOD。可以通過在前面加!反轉判斷。
 
  ConditionHost= 是判斷主機名 (hostname)或機器ID(machine ID)是否匹配。可以加!反轉。
 
  ConditionACPower= 是判斷機器是否在使用交流電源。如果設成 true,而只有至少連接一個交流電源時結果才爲真,反過來,設成 false,則不連接所有交流電源時才爲真。
 
  最後,ConditionNull= 是一個常量性質的判斷條件,它應該是布爾值,如果設成 false ,則條件永遠失敗,反過來則永遠成立。
 
  如果指定多個條件,則所有條件都需要成立(即條件之間是 AND 的關係)。條件前面可以加上 | 符號,這時條件變成一個觸發條件,服務定義了觸發條件,那麼在滿足其它非觸發條件和這個觸發條件的情況下,服務會至少執行一次。同時指定|和!前綴時,先處理|,後處理!。除了ConditionPathIsSymbolicLink=,其它條件均跟隨鏈接。如果這些條件指定爲空,則相當於重置,前面的任何設置都不再起作用。
        SourcePath=  :這個服務生成的配置文件所在的路徑,這主要是用在生成工具從外部配置文件的格式轉換到本地服務的配置格式中。因此,對一般的服務不要使用此選項。


 
服務文件還可能包含一個 [Install] 段,這個段的內容服務的安裝信息。它不在 systemd 的運行期間使用。只在使用 systemctl enable 和 systemctl disable 命令啓用/禁用服務時有用。
        Alias=  :在安裝使用應該使用的額外名字(即別名)。名字必須和服務本身有同樣的後綴(即同樣的類型)。這個選項可以指定多次,所有的名字都起作用,當執行 systemctl enable 命令時,會建立相當的鏈接。

        WantedBy=RequiredBy= :在 .wants/ 或 .requires/ 子目錄中爲服務建立相應的鏈接。這樣做的效果是當列表中的服務啓動,本服務也會啓動。 在  bar.service 中的 WantedBy=foo.service  和 Alias=foo.service.wants/bar.service 基本是一個意思。

        Also=  :當此服務安裝時同時需要安裝的附加服務。 如果用戶請求安裝的服務中配置了此項,則 systemctl enable 命令執行時會自動安裝本項所指定的服務。

在 [Install] 段使用這些字符串有特定含義: %n, %N, %p, %i, %U, %u, %m, %H, %b. 詳細信息看下一段。、

特殊字符串

許多設置支持使用特殊的字符串,可以在運行或加載時替換成特定的內容。下表是支持的字符串。

字符串 簡介 詳細信息
%n 完整的服務名稱  
%N 不轉義的完整服務名稱  
%p 前綴名 對於實例化的服務,這是前@前面的部分,對於其它的服務,是指去掉後綴(即類型)的部分。
%P 不轉義的前綴名  
%i 實例名稱 對於實例化的服務,這是指 @和後綴之間的部分。
%I 不轉義的實例名。  
%f 不轉義的文件名。 這可以不轉義的實例名(如果可用)或前綴名,帶有/前綴。
%c 服務的控制組路徑。?  
%r systemd 的根控制組路徑。?  
%R systemd 的根控制組路徑的父目錄。  
%t 運行時 Socket 目錄。 這可以是 /run (系統管理器) 或 $XDG_RUNTIME_DIR (用戶管理器).
%u 用戶名 這是服務配置的用戶或systemd運行實例的用戶(如果沒有配置的話)。
%U 用戶 UID 這是服務配置的用戶UID或systemd運行實例的用戶UID(如果沒有配置的話)
%h 用戶家目錄 這是服務配置的用戶家目錄或systemd運行實例的用戶家目錄(如果沒有配置的話)
%s 用戶Shell 這是服務配置的用戶shell或systemd運行實例的用戶shell(如果沒有配置的話)
%m 機器 ID 運行系統的機器 ID ,格式是一個字符串。
%b 啓動 ID 運行系統的啓動 ID ,格式是一個字符串。.
%H 主機名 運行系統的主機名。
%% 轉義 % 一個單百分號.

systemd 的手冊頁:http://www.freedesktop.org/software/systemd/man

fedora 的 systemd 說明頁面:http://fedoraproject.org/wiki/Packaging:Systemd,中文:https://fedoraproject.org/wiki/Systemd/zh-cn

unbuntu 的 systemd 說明頁面:https://wiki.edubuntu.org/systemd

arch 的 systemd 說明頁面:https://wiki.archlinux.org/index.php/Systemd/,中文:https://wiki.archlinux.org/index.php/Systemd_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

發佈了32 篇原創文章 · 獲贊 6 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章