web-dev-qa-db-ja.com

/ var / run / user / $ UIDはPIDファイルの新しい/ var / runですか?

/var/runの下にPIDファイルを作成するアプリケーション(rootとしてサービスとして実行)があります。しかし、私はこれがもはやベストプラクティスではなくなったかどうか疑問に思っています。

Linux-/ var/runの代わりにpidファイルを格納する別の場所 で、2012年に尋ねられた質問者は、PIDファイルを/var/runに配置するかどうかを尋ねます。ただし、これは主にsystemdが登場する前であり、systemdオペレーティングシステムが/var/runから/runに移行した(systemd " API File Systems の1つとして)== "および systemdファイル階層の要件 )にリストされています。

Lennart Poettering(およびその他)によるXDG Base Directory Specificationのようなものは、「ユーザー固有の非必須ランタイムファイルおよびその他のファイル」の他の場所について話しますオブジェクト(ソケット、名前付きパイプなど)など)。 systemd file-hierarchyマニュアルページ も同様です。

そして、私が他で読んだことは、/var/run/user/$UIDがsystemdオペレーティングシステムでのそのようなもののnew標準の場所であるという印象を与えます。

  • https://unix.stackexchange.com/questions/162900/ の回答では、「プロセスの実行に使用されるファイル」について説明しています。プログラムがrootとして実行されている場合、/ var/run/user/0が適切な場所になることを示唆していますが、この投稿では、アクティブなセッションがなくなったときにディレクトリが削除/クリアされたとも表示されます。これはサービスなので、本当に正しい場所ですか?
  • https://github.com/systemd/systemd/issues/735#issuecomment-126309537 は、コマンドライン引数--pid-file /run/user/1000/uzbl/event/pidを使用してsystemdによって呼び出されたプロセスを示しています
  • https://lists.debian.org/debian-user/2015/10/msg01315.html 、Debian Usersメーリングリストのディスカッションには、「完全なFreedesktop Monty」がPIDファイル "specif [ies] /run/user for that"。

他の多くの例を見つけることができます。

では、/var/run/user/$UIDを使用するようにアプリケーションを変更する必要がありますか?これはサービス(アクティブセッションなし)なので、pam_systemdはディレクトリをクリア/削除しますか?または$XDG_RUNTIME_DIR?これはsystemd固有のものですか?それとも、すべてのUnicesにまたがる新しい標準ですか?

Systemdオペレーティングシステムでのベストプラクティス今日は何ですか? other(non-systemdですが、Unixのような)オペレーティングシステムにも一般的に当てはまりますか?

9
TSG

あなたが尋ねる:

/ var/run/user/$ UIDはPIDファイルの新しい/ var/runですか?

簡単な答えは「いいえ」です。

そして、長い答えはまだ「いいえ」です。

または、大声で明確に言うと:従来のPIDファイルは/run/user/$UID/(別名/var/run/user/$UID/)を下回ってはなりません。 /run/はセッションサービスの完全に異なる目的を果たすので、通常どおり/run/package/または/run/user/$UID/にそれらを保持します。

ご参考までに:

  • @Daniel Bが指摘したように、今日の/var/runは、/runを指すソフトリンクです。これはsystemdに固有のものではなく、今日のほとんどのシステムで見られます。古いシステムとの互換性を維持したい場合は、2つの解決策があります。/var/run/の代わりに/run/を使用するか、誰かに/runのソフトリンクを作成して、そのような古いシステムの/var/runを指すようにします。

  • /run/user/$UID/は、systemd-logindを実行しているシステムに固有であることに注意してください。また、古いシステムではサポートされていません。

まだ知らない人のために詳細に入るには:

サービスには、システムサービス、ユーザーサービス、セッションサービスの3種類があります。 3つのタイプはすべて、バックグラウンドまたはフォアグラウンドで実行できるため、6つのバリエーションがあります。

フォアグラウンドシステムサービスは、従来は/etc/inittabによって開始されていましたが、現在はsystemdを使用して、/etc/init/を介して開始されています。フォアグラウンドシステムサービスは、initによって制御されるため、通常はPIDファイルを必要とせず、失敗した場合は再生成できます。

バックグラウンドシステムサービスは、従来、ランレベルスクリプト/etc/rc.d/によって開始されていました。これらはバックグラウンドで実行されるため、通常はPIDファイルが必要です。したがって、実行するかどうかを制御することはできません。 PIDファイルは非常にエラーが発生しやすく(サービスが終了した後もPIDが空いている保証がないため)、rcスクリプトがサービスをシャットダウンする必要があるときに、開始されたサービスを再び見つけるために使用されます。これらのPIDファイルは、従来は/var/runにあり、現在は/run/package/にあります(または、パッケージごとに1つのファイルしかない場合は、/run/package.pidにあります)。

ユーザーサービスは、ユーザーが開始するサービスであり、ユーザーのセッションを超えて存続する必要があります。たとえば、Minecraftサーバー、または短命のセッションを使用してオンデマンドでトリガーされる長寿命のSAPクエリプロセスのようなものです。 /run/を使用できないため、システムサービスとは少し異なります。代わりに、/tmp/または$HOMEの下のディレクトリを使用する必要があります(これは、$HOMEが複数のコンピューター間で共有されるネットワーク共有である場合に問題になります)。

フォアグラウンドユーザーサービスは、多くの場合ttyを必要とするため、少し問題が発生することがあります。そのため、ユーザーがログアウトすると、サービスは終了します。したがって、Nohupscreenのように、ユーザーが行った後にそれらを有効にする方法は多数あります。しかし、socat tcp-connect:Host:port exec:service.sh,ptyのようなエキゾチックな亜種も存在する可能性があります。

フォアグラウンドユーザーサービスのもう1つのバリエーションは、ユーザーのcrontabに存在するcronジョブです。ただし、これらのcronジョブは、たとえば、1つのプロセスが時間を超えた場合でも、cronによる次の呼び出しが行われるときに、並行して実行されることが想定されていない場合、バックグラウンドサービスになることもあります。

バックグラウンドユーザーサービスには、バックグラウンドシステムサービスと同じ問題があります。これは、既に実行されているサービスを追跡し、既に実行されているサービスを制御する必要があるためです。過去には、誰もがファイルやディレクトリを作成できる/tmpを使用する必要があるため、これにより、ディレクトリトラバーサル攻撃などのさまざまな問題や修正が発生していました。

ただし、/run/user/$UID/はそのようなユーザーサービス用ではないため、これはまだ変更されていません。これは、セッションサービスに関するさらに困難な問題を解決するために設計されました。

セッションサービスは、通常、ユーザーがログインすると開始され、ユーザーがログアウトすると停止するサービスです。これは簡単に聞こえますが、ユーザーごとに許可される単一のセッションが複数ある場合は勢いが増します。解決するのが難しい質問は、「セッションはいつ本当に終了するのか」です。

セッションは最初のログインから始まります。それは理解しやすいです。ただし、このログインがログアウトしたときに必ずしも終了するわけではありません。したがって、セッションサービスは最初のログイン(またはそれ以降)で開始できますが、ユーザーの最後のセッションがログアウトするまで、実行を継続する必要があることがよくあります。

フォアグラウンドセッションサービスは通常、簡単なバリエーションです。グラフィカルログインで開始および終了するX-Windowdbusサービスのように。しかし、巨大なPDFの印刷を開始する場合は、このジョブを正常に完了するか、破片を残さずにきれいに終了する必要がありますか?

これらのタイプのセッションサービスは、バックグラウンドで実行し続ける必要があるか、サービスが突然停止した後にサービスが停止した後にクリーンアップする方法が必要です。そして、物事は私たちのモバイルの世界でしばしば死にます。モニターについて考えてみてください。モニターはいつでも接続および切断できます。コンピュータを再起動する必要はありません。しかし、すべての画面のプラグを抜くとどうなりますか?もちろん、X11は死にます。 X11セッションで実行されている一部のユーザーサービスの場合、これは予期せず発生します。おそらく、実行時間の長いタスクの途中です。

このディレクトリは最後のユーザーセッションが終了した後に自動的に消去されるため、ここで/run/user/$UID/が役立ちます。そのため、サービスは、/run/user/$UID/に格納されているすべてのものがユーザーの背後でクリーンアップされることを信頼できます。

したがって、すべてのセッション関連サービスはこのディレクトリを使用する必要があります。

また、今日はdbusがあることに注意してください。したがって、サービスが実行されているかどうかを確認するためだけに、PIDファイルに依存する必要はありません。 「セッション」と呼ばれるものがあるので、これは特に当てはまります。これにより、共有メモリセグメントの使用や、/run/user/$UID/に存在できるロックファイルの使用など、処理が少し良くなります。

物事は簡単ではありません。さらに複雑にするために、screentmuxssh(シェルから分岐するもの)のように2つの側面があり、一方の側面はユーザーサービス(つまりデーモン)、反対側はセッションサービス(tty)です。それらは通常セッションにバインドされていますが、常にそうである必要はありません。たとえば、sshポート転送を使用してシェルを終了した場合、sshは、最後に転送されたポートが閉じるまで開いたままになります。他のポートがアクティブである限り、新しいポートを開くこともできます。このような「デュアル」サービスの場合、PIDファイルのようなものが役に立つ場合があり、この場合は/run/user/$UID/の下に存在する場合さえあります。

cronを使用してユーザーセッションを開くことができるため、おそらく/run/user/$UID/もcronjobsで使用できることに注意してください。ただし、この場合、/run/user/$UID/は、すべてのcronjobsが終了した後に再度クリーンアップの対象になります。これはおそらく、は、/tmp/にある場合とは異なり、他の場所に渡されたファイルが消えることを意味します。再起動するだけで、そこにあるファイルが無条件に削除されることになっているためです。)

要約すると:

適切に設計されたサービスがあれば、/run/user/$UID/にプレーンなPIDファイルが必要になることは決してありません。なぜなら、セッションサービス(このディレクトリを使用する唯一のサービス)は、たとえ実行されていても、制御を維持する方法(セッション)が非常に優れているからです。バックグラウンド。

したがって、サービスにPIDファイルが必要な場合は、/run/package//run/package.pid/tmp/package-$UID/などの結果になる可能性が高くなります。

ユーザーが完全にログオフするとすぐにファイルが消えることを確認したい場合にのみ、/run/user/$UID/を使用してください。また、rootユーザーは常にログインしているわけではないため、/run/user/0/がない可能性が高いことに注意してください。

また、/run/user/のすぐ下にディレクトリを作成しないでください。

うまくいけば、すべてがとても素敵で明確になりました。しかし、私は自白すべきことがいくつかあります。

私はあなたにうそをついた。そして私はこれを機知に富んだ方法で行いました(ただし、悪意はありません)。

systemd-logindの観点から)セッションはloginにバインドされているだけではありません。はい、もちろんloginに似たものが関係しますが、物事はかなり複雑です:

https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/

しかしながら:

  • ここでのこの投稿(短いが間違った話)では、あなたの質問に対する答えは「いいえ」です。

  • 幸いにも、セッションに関する長い(そして本当の)背景(リンクを参照)があっても、答えは「いいえ」のままです。

  • 非常に明確に定義された目的のためのごく少数の非常に特殊なケースについてのみ、PIDファイルを/run/user/$UID/に配置することを検討してください。

ごきげんよう。

10
Tino

systemd.exec マニュアルでは、RuntimeDirectoryオプションについて次のように述べています。

ディレクトリ名のリストを取ります。設定されている場合、指定された名前の1つ以上のディレクトリが、ユニットの起動時に/run(システムサービスの場合)または$XDG_RUNTIME_DIR(ユーザーサービスの場合)の下に作成され、ユニットの停止時に削除されます。 。

さらに、 pam_systemdのマニュアルページ で、$XDG_RUNTIME_DIR(強調鉱山)に関する次の情報を見つけることができます。

マシンのユーザーログイン時間にバインドされているユーザープライベートユーザー書き込み可能ディレクトリへのパス。これは、ユーザーが最初にログインしたときに自動的に作成され、ユーザーの最後のログアウト時に削除されます

これらの2つのマニュアルを使用すると、$XDG_RUNTIME_DIR(私のArchインストールでは/run/user/$UID)はシステムサービスにとって正しい選択ではないと推測できます。代わりに、通常は/runに配置されます(少なくともArchとGentooでは)。上記のように、RuntimeDirectoryでそれらを作成することも可能かもしれません。

/var/runは、最近の/runへのシンボリックリンクにすぎません。

0
Daniel B