web-dev-qa-db-ja.com

systemd-tmpfilesを実行するsystemd .serviceファイルを書き込む方法

ブートプロセス中にsystemdディストリビューションでsystemd-tmpfiles --createを実行する必要があります。そのため、このジョブを実行するsystemd .serviceファイルを作成する必要があります。

この質問では、私が必要とするものとその理由に関するすべての詳細を読むことができます。 systemd-tmpfilesの仕組み

私はそれについてのいくつかのドキュメントを読み、次のテストを書いています:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

systemd-tmpfilesは単純なプログラムではなく、systemd自体なので、わかりません。システムを壊したくありません。

正しい.serviceファイルに関するヒントはありますか?

16
eang

[これはsystemd-tmpfilesの問題に直接対処していませんが、この特定のケースでは、echoを使用した方がよいことをすでに認識していると思います。]

まず、「multi-user.target」は、使用したい場合とそうでない場合があります。 SysVスタイルの初期化のものからのランレベルの概念に精通している場合、マルチユーザーは、GUIではなくコンソールから起動するマルチユーザーシステムであるランレベル3と同等のsystemdです。 Xで起動するランレベル5に相当するものは、graphical.targetです。デフォルトは/etc/systemd/system(および/lib/systemd/systemのシンボリックリンクによって決定されます。/etcのシンボリックリンクは/libのシンボリックリンクを上書きします)と呼ばれますdefault.target、lsを使用して、それが指している場所を見つけます。

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

この場合、systemctl get-defaultは「multi-user.target」を通知します。通常のLinuxデスクトップの場合、graphical.targetになります。デフォルトのランレベル/ターゲットが何であるかに関係なく、作成しているブートサービスを開始する場合、これは実際には重要ではありません。その場合、default.targetを使用するだけで、エイリアスが何であるかを気にする必要はありません。ただし、マルチユーザーを使用していて、デフォルトがグラフィカルである場合、サービスは発生しません。

サービスによっては、これを開始したい、より適切で具体的なターゲットまたはサービスがある場合があります。あなたの他の質問に基づいて、default.targetはおそらく問題ありません。注として、「ターゲット」と「サービス」の違いは、サービスには実際にプロセスを実行する[Service]セクションが含まれていることです。ターゲットは、さまざまな "depends"および "requires"ディレクティブを介してサービスをグループ化する方法にすぎません。他のターゲットやサービスをトリガーする以外には何もしません。

サービスがいつ開始するかは、他のサービスがサービスに明示的に依存するものによって決まります。ブートプロセスの後半で実行したい、このような単純なスタンドアロンイベントの場合、次のディレクティブの組み合わせを使用できます。

[Unit]
Requires=local-fs.target
After=local-fs.target 

[Install]
WantedBy=default.target

「インストール」セクションは、サービスがインストールされるときに使用されます。 "WantedBy ="は、このサービスに含めるターゲットを指定します。つまり、そのターゲットがそうする場合に実行されます。特定の依存関係がない場合は、ユニットをより早くではなく後で実行することは、通常何が起こっているかを調べ、依存関係または前提条件として使用するものを選択することの問題である可能性があります。

区別するには:依存性ユニットがアクティブ化するために必要なものを意味し、prerequisiteはユニットの前に実行する必要があるものを意味しますif使用されていますが、必須ではありません。これらの用語は私のものですが、これはsystemdのドキュメントで使用されている重要な違いです。特に、必要な依存関係は、ユニットが次の場合に開始されることが保証されているという意味で、ただし、この要件は開始される順序には影響しません。つまり、依存関係である何かが実際に後で開始される可能性があります(そしてはい、それはあなたのユニットが最初に開始されるかもしれないことを意味するので、依存関係が成功することは保証されません).

上記のlocal-fs.targetRequiresは、ユニットが他に含まれていない可能性があるシステムで使用され、Afterと組み合わせる場合を除いて、少し無意味な場合があります。ユニットはそれ以降に起動することが保証されていることを意味します-したがって、Requiresなしで実行できます(依存しないユニットの後に起動するようにユニットを設定できます)。ここでの例は、概念と、依存関係と実行順序の違いを紹介するためだけのものです。一方が他方を決定するわけではありません。

「後で開始」は、前提条件が特定のポイントに到達したことを意味するわけではないことに注意してください。たとえば、リモートファイルシステムのマウントに関するものであり、これがユニットにとって重要である場合、RequiresとおそらくAfterを確立するサービスを使用する必要がありますが、実際のプロセスが必要です。リモートファイルシステムにまだアクセスできない場合に備えて、適切なエラー処理を実行しています(たとえば、アクセスできるまでループでスリープすることにより)。

この例では、「hello world」をコンソールにエコーします。サービス自体は[Service]セクションで説明されています。

[Service]
Type=simple
ExecStart=/usr/local/bin/helloworld

コマンドには絶対パスが必要です。私が/usr/bin/echo "hello world"だけを使用しなかった理由は、機能しないためです(出力は/ dev/nullに送られると思います)。echo "hello world" > /dev/consoleを実行するサービスは、 ExecStartコマンドシェルによって実行されないであるため、ExecStartディレクティブでシェルリダイレクトを使用することはできません。しかし、あなたはそうすることができます:/ usr/local/bin/helloworldはecho "hello world" > /dev/consoleという1行のシェルスクリプトです。1

Type=simpleに注意してください。これはhelloworldの動作には問題ありませんが、1秒以上かかるようなものがある場合は、最初にバックグラウンドにフォークする必要があります(たとえば、&で起動スクリプト)を使用し、Type=forkingを使用します。 「タイプ」パラメータの詳細はman systemd.serviceで説明されており、何をしようとしているかに関係なく、その部分を読む必要があります。

完全で最小限のサービスファイルは、これら3つのセクション([Unit][Service]、および[Install])のみです。インストールするには、ファイルまたはファイルへのシンボリックリンクを/ etc/systemd/systemまたは/ usr/lib/systemd/systemに配置し、次のようにします。

systemctl --system enable helloworld

ln -s ...と表示されます。これはサービスを実行するのではなく、前述のように起動時に実行するように構成するだけです。

一言で言えばそれだけです。 man systemd.unitman systemd.serviceには詳細があります(これらすべてのインデックスがman systemd.directivesにあります)。


  1. [Service]ブロックのStandardOutputおよびStandardErrorパラメーターを使用して出力をリダイレクトできます。man systemd.execを参照してください。
31
goldilocks

Systemd-tmpfilesサービスの場合:ディストリビューションに同梱する必要がありますが、サービスファイルは pstream git-repository からいつでも取得できます

2
SimonPe