一般的なTrueOS

一般的なTrueOS

新しく起動したプロセスの親プロセスを設定したいのですが可能ですか?

たとえば、ログインマネージャを介して新しいデスクトップ環境セッションを開始すると仮定すると、プロセスツリーは次のようになります。

init
 \- login-manager
     \- de-session

これで、セッションで起動する必要がある最も重要なアプリケーションを起動するスクリプトがあり、さまざまな理由でDEを自動起動マネージャに移行する代わりにスクリプトとして保持したいと思います。次のようになります。

#!/usr/bin/env

application1 &
application2 &
application3 &

セッションの開始時にこのコマンドを自動的に実行した後、プロセスツリーは次のようになります。

init
 |- application1
 |- application2
 |- application3
 \- login-manager
     \- de-session

しかし、私が実際にしたいのは、セッションでこれらのプロセスを次のように「再定義」することです。

init
 \- login-manager
     \- de-session
         |- application1
         |- application2
         \- application3

それでは、他のプロセスで「親プロセスをリセット」する方法はありますか?

答え1

一部のシステムでは、プロセスを次のように表示できます。子供用収穫機これにより、initすべての子孫に対して孤児プロセスを採用する役割を担うことができます。

LinuxではPR_SET_CHILD_SUBREAPER prctl()

したがって、次のように始めることができますde-session(Linuxの値はここにハードコードされていますPR_SET_CHILD_SUBREAPER)。

perl -e 'require "syscall.ph";
         syscall(&SYS_prctl,36,1) >= 0 or die "cannot set subreaper: $!";
         exec("de-session");'

ただし、de-session生成されたことのないプロセスからSIGCHLD信号を受信すると混乱する可能性があります。あなたのプロセスinitはこれらの問題に対処するように設計されていますが、あなたのものではないかもしれないので、継承したくないプロセスの終了を決して認めないので、de-sessionゾンビ軍が発生する可能性があります。de-session

答え2

実際、わずか1年前、私はTrueOS(以前のPC-BSD)を使ってこれを行いました。

一般的なTrueOS

デフォルトのTrueOSでは、pcdmサービスはグラフィカルユーザーインターフェースを実行します。

  • Mewburnシステムは、寿命が短いrcこのスクリプトを実行します。/usr/local/etc/rc.d/pcdm
  • PCDMdSpawnという無限ループとやや複雑なシェルスクリプトは、というプログラムを実行するようにxinit指示しますPCDM-session
  • PCDM-session/tmpで作成されるデスクトップセレクタとログインプログラムです/usr/local/share/PCDM/pcdm-sessiondbus-daemonまた、通信するデスクトップバスに関する情報が渡されないと、スーパーユーザーとして実行されることがサイドストリップされ孤児になります。
  • /usr/local/share/PCDM/pcdm-session以前に作成されたスクリプトへのリンクです。sh /tmp/PCDM-session.blah
  • シェルスクリプトはすべての項目を順番に実行します$HOME/.xprofile。ここではすべてのエントリが分岐し、選択したデスクトップのセッションが実行されますgpg-agent(ログインしたユーザーとして実行され、他のプロセスが分離されます)。dbus-launchdbus-daemon

これにより、ブランチされたすべてのアイテム($HOME/.xprofileすべてのアイテムの実行で/usr/local/share/pcbsd/xstartup/)とデスクトップセッションプロセスで開始され、後でブランチとシャットダウンの両親(たとえば、)で孤立したthunderbirdアイテムの両方に対して非常に汚れたプロセスツリーが作成されます。すべてのD-Busブローカーもあまり良くありません。多くの場合、プロセス#1を親プロセスIDとして使用します。名前を付けても作業を簡単にするのに役立ちません。 pcdm電話PCDMd電話PCDM-session電話pcdm-session電話。PCDM-session.blah

私はこれが不必要に複雑であることをTrueOSの人々に知らせようとしています。PCDM-session、特に上記の説明から省略したプログラムの完全に不要な隠し追加、破損したサービスマネージャです。 )

local-reaperそして、userenvノッシュツールセットから

存在するNoshツールセットという小さなチェーンローディングユーティリティがありますlocal-reaper。唯一の使命は、自分自身を次に表示(または表示解除)することです。代理死神次に、同じプロセスで別のプログラムイメージをチェーンロードします。

Linuxには関係ありません。サブハーベスタメカニズムは、複数のオペレーティングシステムで使用できます。。 Linux および FreeBSD/TrueOS/DragonFlySBD で実行され、固定システムコール番号などはありません。 ☺

noshツールセットにもuserenvツールがありますsetuidgid。これらが実際にやったすべてTrueOSpcdm-sessionプログラムは、DBUS_SESSION_BUS_ADDRESSユーザー固有のデスクトップバスエージェントを指すように変数を設定することを含む、これを行います。完全なTrueOSpcdm-sessionプログラムは実際には次のように置き換えることができます。

#!/bin/sh -
実行>>"$5" 2>&1
chown -v -h -- "$1" "${XAUTHORITY}"
実装する\
ローカルリッパーtrue \
setuidgid --"$1" 追加\
usenv --set-path --set-other --set-tools --set-timezone --set-locale --set-xdg \
ブー「$4」

local-reaper活用

これを使用するには、次の3つの条件を満たすプロセスを見つける必要があります。

  • これは孤児プロセスの間接的な親プロセスでなければなりません。
  • 彼らは長く生きなければなりません。
  • 彼らは予期しなかった突然の子プロセスの獲得に適応する必要があります。

すべてのプロセスが適しているわけではありません。実際、PCDM-sessionプロセスが子リッパーとして適切であるかどうかを診断している間に、間違ったプロセスIDを待っていたTrueOSプログラムでバグが見つかりました。PCDM-session

私もTrueOSの人々にこのエラーについて話しました。 それは実際にキャラクター入力エラー。 )

幸いなことに、シェルプログラムはほぼ常にはい死神になるのに適しており、この木にはいくつかの樹皮プロセスがあります。知ってみるとこれも事実だxinit

強化されたプロセスツリー

では、何が起こるのでしょうか?はい。

  • 私は適切なサービスマネージャの指揮の下で問題を管理します。サーバー管理プロセスはそれ自体リッパー副官。
  • Service Managementはかなり短いシェルスクリプトを生成し、プロセスをサブリッパーにlocal-reaper true xinit …します。xinit
  • xinit実行するように指示されたら、シェルインタプリタが解釈されます。local-reaper true helper-scriptヘルプスクリプト第三の副死。
  • ヘルプスクリプト走るdbus-launch --exit-with-session PCDM-session。実行し続け、シェルインタプリタを実行し、PCDM-sessionプロセスが完了するのを待ちます。 dbus-launch分離された2つの補助プロセスを分割します。
  • PCDM-sessionデリゲートになることはできません。動作は変更されていません。/tmp任意の数値シェルスクリプトを並列に作成します/usr/local/share/PCDM/pcdm-session。しかし、デスクトップバス側処理のアンバンドリングは完了しました。
  • 変更されたバージョンは/usr/local/share/PCDM/pcdm-session自分自身を子リッパーとしてマークし、以前に作成されたスクリプトへのリンクを提供します。sh /tmp/PCDM-session.blah
  • シェルスクリプトはまだすべてを実行するため、すべてを$HOME/.xprofile実行し、/usr/local/share/pcbsd/xstartup/最後に選択したデスクトップのセッションを実行しますが、直接実行され、もはや通過しませんdbus-launch。実行を続け、シェルインタプリタを実行し、デスクトップセッションプロセスが完了するのを待ちます。

効果は次のとおりです。

  • 分岐されたすべてのスクリプトは、/usr/local/share/pcbsd/xstartup/実行中のプロセスの親エントリに再割り当てされます。sh /tmp/PCDM-session.blah
  • fork-and-exit-parentを介してデスクトップセッションプロセスの孫として実行されるようなデスクトップアプリケーションは、実行中のプロセスの親エントリthunderbirdに変更されます。sh /tmp/PCDM-session.blah
  • 分岐して分離された補助プロセスは再び親プロセスにdbus-launchなります。helper-script
  • dbus-daemonすべてが正しいサービス管理下でユーザーレベルのサービスとしてプロセスツリーの他の部分で実行されているユーザー固有のデスクトップバスエージェントを指すため、ユーザー側のプロセスから分岐することはありません。
  • 再び育てる以外は何もありませんxinit。サブハーベスターにする必要はないことがわかりました。

プロセスツリーはプロセス#1から始まり、次のようになります。

/sbin/システム管理者--
|-- cyclolog --最大ファイルサイズ 262144 --最大合計サイズ 1048576. (システム管理者)
`--サービスマネージャ(システムマネージャ)
  |-- ユーザー別管理者
  |-- cyclolog --最大ファイルサイズ 262144 --最大合計サイズ 1048576。
  `--サービスマネージャ
  |-- サイクログ JdeBP/ソケットサーバー/
  |-- サイクログ JdeBP/dbus-servers/
  |-- dbus-daemon --config-file ./per-user.conf --nofork --address=unix:path=/run/user/JdeBP//bus
  |-- /bin/sh - ./helper 実行
   `-- xinit /bin/exec local-reaper true ./helper セッション -- :0 -auth -retro
     |-- X:0 -auth -retro(Xorg)
     `-- /bin/sh - ./helper セッション
       |--PCDM-セッション-一度
       `--PCDM-セッション-一度|
       | `-- sh /tmp/PCDM-session.ca1015
       |-- /usr/local/bin/gpg-agent …
       | `--scdaemon --マルチサーバー
       |-- /usr/local/bin/lxsession -s LXDE
       |--オープンボックス--構成ファイル... |
       |-- lxpanel --プロファイルLXDE
       |-- pcmanfm --desktop --profile LXDE
       | `-- xscreensaver - スプラッシュなし
       |-- /usr/local/bin/python2.7 /usr/local/share/system-config-printer/applet.py
       |-- 人命救助トレイ
       |-- /usr/local/bin/pc-systemupdartray
       |-- 時代精神データセンター
       |-- コンピューターミキサー
       |-- PC インストールトレイ
       |-- /usr/local/libexec/menu-cache/menu-cached …
       | ``——サンダーバード
       |-- dbus-launch --exit-with-session PCDM-セッション-一度
       `-- /usr/local/bin/dbus-daemon --fork … --session

関連情報