Systemd

如何在另一個單元執行時停止一個單元

  • May 3, 2017

我目前正在嘗試使用borg設置自動備份。為此,我編寫了一個 oneshot systemd 使用者服務(稱為 borgbackup.service),我計劃通過計時器啟動它。

Borg 還可以將備份儲存庫掛載為虛擬文件系統,我希望始終掛載我的備份。我已經為我稱為 borgmount.service 的服務編寫了另一個使用者服務。但是,在安裝儲存庫時無法創建備份。

我目前對這個問題的解決方案包括我的 borgbackup.service 中的這些行,用於在備份之前和之後停止和重新啟動掛載服務。

ExecStartPre=/usr/bin/systemctl --user stop borgmount.service
ExitStart=/bin/sh -c "borg create ::$(date) --exclude-caches --keep-tag-files"
ExecStopPost=/usr/bin/systemctl --user start borgmount.service

這看起來很醜陋,並且沒有考慮到 borgmount.service 單元在備份開始時所處的狀態(可能它被停止和禁用)。

有一個更好的方法嗎?

不是一個完美的解決方案,而是ExecStartPre您可以使用Conflicts.

衝突=

以空格分隔的單位名稱列表。配置負需求依賴項。如果一個單位在另一個單位上有一個 Conflicts= 設置,啟動前者將停止後者,反之亦然。請注意,此設置獨立於 After= 和 Before= 排序依賴項並與之正交。

您可以將其與ExecStopPost檢查是否啟用衝突的方法結合使用:

ExecStopPost=/usr/bin/systemctl is-enabled borgmount.service && /usr/bin/systemctl --user start borgmount.service

如果您不熟悉&&操作符,則如果第一個命令成功,則將執行第二個命令。systemctl is-enabled啟用該單元時返回 0。

仍然沒有涵蓋服務啟用和停止的案例,但您可能仍然可以處理更複雜ExecStopPost甚至確定狀態的ExecStartPre. 太糟糕systemd了沒有Interupts指令或類似的指令,僅在單元執行時停止另一個單元。


除了 anExecStartPost你還可以指定Conflicts=inborgmount.service而不是 running 只是systemctl start borgbackup.service你可以 run systemctl start borgbackup.service borgmount.service,但這需要記住同時執行兩者。


另一種選擇(可能是最乾淨的)是Conflicts在這兩個服務中使用,並創建一個包含這兩個服務的新備份目標。

borgbackup.service需要:

Before=borgmount.service確保它首先執行

WantedBy=${NEW_TARGET}確保執行新目標會導致它執行。

borgmount.service需要:

WantedBy=${NEW_TARGET},您可以在一個單元中指定多個WantedBy指令。

然後您可以使用systemctl start ${NEW_TARGET}.

這個方法的好處是,如果borgmount.service沒有啟用它就不會在 中執行${NEW_TARGET},如果你想在不執行的情況下觸發備份,borgmount.service你可以borgbackup.service自己呼叫 。

引用自:https://unix.stackexchange.com/questions/337357