「Systemd/ユーザー」の版間の差分
(→環境変数) |
(同期) |
||
17行目: | 17行目: | ||
== 利用方法 == |
== 利用方法 == |
||
− | ユーザーがログインを行うと、systemd は自動的にユーザーサービスを管理する {{ic|systemd --user}} インスタンスを起動します。このプロセスは、そのユーザーにセッションが残っているかぎり生存し、ユーザーの最後のセッションが閉じられた時に終了します。[[#systemd のユーザーインスタンスを自動起動|systemd のユーザーインスタンスを自動起動]]している場合、インスタンスはブート時に起動し、終了し |
+ | ユーザーがログインを行うと、systemd は自動的にユーザーサービスを管理する {{ic|systemd --user}} インスタンスを起動します。このプロセスは、そのユーザーにセッションが残っているかぎり生存し、ユーザーの最後のセッションが閉じられた時に終了します。[[#systemd のユーザーインスタンスを自動起動|systemd のユーザーインスタンスを自動起動]]している場合、インスタンスはブート時に起動し、終了しません。ユーザーサービスを使うことで、ソケットアクティベーションやタイマー、システムの依存関係や cgroups によるプロセスの制限など、systemd の恩恵を最大限活用して、デーモンや自動化されたタスクを実行できます。 |
+ | |||
+ | ユーザーユニットはシステムサービスと同じように以下のディレクトリに配置されます (優先度が低い順): |
||
* {{ic|/usr/lib/systemd/user/}}: インストールしたパッケージに含まれているサービス |
* {{ic|/usr/lib/systemd/user/}}: インストールしたパッケージに含まれているサービス |
||
+ | * {{ic|~/.local/share/systemd/user/}}: ホームディレクトリにインストールしたパッケージのユニット |
||
* {{ic|/etc/systemd/user/}}: システムの管理者が配置する、全てのユーザーが使えるユーザーサービス |
* {{ic|/etc/systemd/user/}}: システムの管理者が配置する、全てのユーザーが使えるユーザーサービス |
||
* {{ic|~/.config/systemd/user/}}: ユーザーが配置する、そのユーザーのサービス |
* {{ic|~/.config/systemd/user/}}: ユーザーが配置する、そのユーザーのサービス |
||
26行目: | 29行目: | ||
{{Note| |
{{Note| |
||
− | * {{ic|systemd --user}} インスタンスはユーザーごとのプロセスであり、セッションごとのプロセスではないので注意してください。ソケットやステートファイルなどのユーザーサービスによって扱われるリソースはセッションごとではなくユーザーごとに割り振られる (ユーザーのホームディレクトリ上に存在する) というのが原則です。つまりユーザーサービスは全てセッションとは関係なく動作します。結果として、セッションの中で実行する必要があるプログラムはユーザーサービスの中で壊れてしまう可能性があります。systemd のユーザーセッションの扱い方は流動的であり確定していません。[https://mail.gnome.org/archives/desktop-devel-list/2014-January/msg00079.html] や [http://lists.freedesktop.org/archives/systemd-devel/2014-March/017552.html] が今後どうなるかのヒントになるでしょう。 |
+ | * バージョン206から、{{ic|systemd --user}} インスタンスはユーザーごとのプロセスであり、セッションごとのプロセスではないので注意してください。ソケットやステートファイルなどのユーザーサービスによって扱われるリソースはセッションごとではなくユーザーごとに割り振られる (ユーザーのホームディレクトリ上に存在する) というのが原則です。つまりユーザーサービスは全てセッションとは関係なく動作します。結果として、セッションの中で実行する必要があるプログラムはユーザーサービスの中で壊れてしまう可能性があります。systemd のユーザーセッションの扱い方は流動的であり確定していません。[https://mail.gnome.org/archives/desktop-devel-list/2014-January/msg00079.html] や [http://lists.freedesktop.org/archives/systemd-devel/2014-March/017552.html] が今後どうなるかのヒントになるでしょう。 |
* {{ic|systemd --user}} は {{ic|systemd --system}} プロセスとは別のプロセスを起動します。ユーザーユニットからシステムユニットに依存したり参照することはできません。 |
* {{ic|systemd --user}} は {{ic|systemd --system}} プロセスとは別のプロセスを起動します。ユーザーユニットからシステムユニットに依存したり参照することはできません。 |
||
}} |
}} |
||
34行目: | 37行目: | ||
Systemd のユーザーインスタンスはログイン時に自動で起動します。正しく起動していることを確認するには、次のコマンドを使います: {{ic|systemctl --user status}}。 |
Systemd のユーザーインスタンスはログイン時に自動で起動します。正しく起動していることを確認するには、次のコマンドを使います: {{ic|systemctl --user status}}。 |
||
+ | ユーザーサービスは全て {{ic|~/.config/systemd/user/}} に配置してください。ログイン時にサービスを実行したい場合は、自動実行したいサービスごとに {{ic|systemctl --user enable ''service''}} を実行してください。 |
||
− | {{Note|systemd のユーザーインスタンスが自動で実行されない場合 {{ic|/etc/pam.d/system-login}} ファイルを確認してください。このファイルには {{ic|-session optional pam_systemd.so}} というような行が含まれていなくてはなりません。''.pacnew'' ファイルが存在していないかチェックしてください。}} |
||
− | |||
− | ユーザーサービスは全て {{ic|~/.config/systemd/user}} に配置してください。ログイン時にサービスを実行したい場合は、自動実行したいサービスごとに {{ic|systemctl --user enable ''service''}} を実行してください。 |
||
− | |||
− | {{Note|バージョン 206 から、systemd のユーザーインスタンスの仕組みは変更されています。現在、デフォルトで {{ic|pam_systemd.so}} モジュールがユーザーインスタンスを起動します。手動で起動する必要はありません。{{AUR|user-session-units}} の {{ic|user-session@.service}} は廃止されました。この変更によって {{ic|systemd --user}} はユーザーセッションの外で実行されます。}} |
||
=== D-Bus === |
=== D-Bus === |
||
− | プログラムによっては [[D-Bus]] ユーザーメッセージバスを必要とすることがあります。D-Bus は伝統的に {{ic|dbus-launch}} によってデスクトップ環境の起動時に実行されていま |
+ | プログラムによっては [[D-Bus]] ユーザーメッセージバスを必要とすることがあります。D-Bus は伝統的に {{ic|dbus-launch}} によってデスクトップ環境の起動時に実行されていましたが、バージョン206から、systemd がユーザーのメッセージバスを管理するようになりました [https://www.archlinuxjp.org/news/d-bus-now-launches-user-buses/]。{{ic|dbus.socket}} や {{ic|dbus.service}} のユーザーユニットによって全てのセッションでユーザーごとに ''dbus-daemon'' が起動します。 |
− | |||
− | {{Note|将来 systemd から kdbus への移行がされることで、systemd はシステムとユーザーのメッセージバスのマネージャになります。}} |
||
− | |||
− | D-Bus を systemd サービスとして設定するには、以下を行う必要があります: |
||
− | |||
− | 1. dbus サーバーのサービスユニットとソケットユニットを {{ic|/etc/systemd/user/}} に追加: |
||
− | |||
− | {{hc|/etc/systemd/user/dbus.socket|<nowiki> |
||
− | [Unit] |
||
− | Description=D-Bus User Message Bus Socket |
||
− | |||
− | [Socket] |
||
− | ListenStream=%t/bus |
||
− | |||
− | [Install] |
||
− | WantedBy=sockets.target |
||
− | Also=dbus.service |
||
− | </nowiki>}} |
||
− | |||
− | {{hc|/etc/systemd/user/dbus.service|<nowiki> |
||
− | [Unit] |
||
− | Description=D-Bus User Message Bus |
||
− | Documentation=man:dbus-daemon(1) |
||
− | Requires=dbus.socket |
||
− | |||
− | [Service] |
||
− | ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation |
||
− | ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig |
||
− | |||
− | [Install] |
||
− | Also=dbus.socket |
||
− | </nowiki>}} |
||
− | |||
− | 2. 環境変数 {{ic|DBUS_SESSION_BUS_ADDRESS}} を設定。以下のファイルを作成して、{{ic|user@.service}} の設定ファイルを使うことで設定できます: |
||
− | |||
− | {{hc|/etc/systemd/system/user@.service.d/dbus.conf|<nowiki> |
||
− | [Service] |
||
− | Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/bus |
||
− | </nowiki>}} |
||
− | |||
− | {{Note|systemd 209 以前は {{ic|DBUS_SESSION_BUS_ADDRESS}} は上流の {{ic|user@.service}} ユニットで設定されていました。現在は異なります。kdbus への移行が完了したら、{{ic|pam_systemd.so}} によって変数が設定されるようになるから、というのが理由のようです。}} |
||
− | |||
− | 3. root で以下を実行してソケットを有効化: |
||
+ | {{Note|{{ic|/etc/systemd/user/}} や {{ic|~/.config/systemd/user/}} に手動でユニットを作成していた場合は、削除してもかまいません。}} |
||
− | # systemctl --global enable dbus.socket |
||
=== 環境変数 === |
=== 環境変数 === |
||
− | systemd のユーザーインスタンスは {{ic|.bashrc}} などに設定された[[環境変数]]を全く継承しません。systemd インスタンスに環境変数を設定する方法は |
+ | systemd のユーザーインスタンスは {{ic|.bashrc}} などに設定された[[環境変数]]を全く継承しません。systemd インスタンスに環境変数を設定する方法は複数存在します: |
# {{ic|/etc/systemd/user.conf}} で {{ic|DefaultEnvironment}} オプションを使う。全てのユーザーユニットに影響します。 |
# {{ic|/etc/systemd/user.conf}} で {{ic|DefaultEnvironment}} オプションを使う。全てのユーザーユニットに影響します。 |
||
− | # {{ic|/etc/systemd/system/user@.service.d/}} に設定ファイルを追加する。全てのユーザーユニットに影響します。 |
+ | # {{ic|/etc/systemd/system/user@.service.d/}} に設定ファイルを追加する。全てのユーザーユニットに影響します。[[#サービス例]]を参照。 |
# 適宜、{{ic|systemctl --user set-environment}} や {{ic|systemctl --user import-environment}} を使う。環境変数を設定した後に起動したユーザーユニットには影響しますが、既に起動しているユニットには影響しません。 |
# 適宜、{{ic|systemctl --user set-environment}} や {{ic|systemctl --user import-environment}} を使う。環境変数を設定した後に起動したユーザーユニットには影響しますが、既に起動しているユニットには影響しません。 |
||
+ | # [[D-Bus]] の {{ic|dbus-update-activation-environment --systemd --all}} コマンドを使う。{{ic|systemctl --user import-environment}} と同じ効果があり、D-Bus セッションに適用されます。コマンドはシェルの初期化ファイルの末尾に追加できます。 |
||
− | :: {{Tip|1=複数の変数を一度に設定するには、空白で区切った ''key=value'' ペアのリストを設定ファイルに書き込んで、{{ic|xargs systemctl --user set-environment < /path/to/file.conf}} をシェルのスタートアップファイルに追加してください。}} |
||
設定するべき変数としては {{ic|DISPLAY}} や {{ic|PATH}} などが考えられます。 |
設定するべき変数としては {{ic|DISPLAY}} や {{ic|PATH}} などが考えられます。 |
||
− | ==== |
+ | ==== サービス例 ==== |
+ | [[Systemd#ドロップインスニペット|ドロップイン]]ディレクトリ {{ic|/etc/systemd/system/user@.service.d/}} を作成して、その中に拡張子が {{ic|.conf}} のファイルを作成します (例: {{ic|local.conf}}): |
||
+ | {{hc|/etc/systemd/system/user@.service.d/local.conf|2= |
||
+ | [Service] |
||
+ | Environment="PATH=/usr/lib/ccache/bin/:$PATH" |
||
+ | Environment="EDITOR=nano -c" |
||
+ | Environment="BROWSER=firefox" |
||
+ | Environment="NO_AT_BRIDGE=1" |
||
+ | }} |
||
+ | ==== DISPLAY と XAUTHORITY ==== |
||
− | {{Note|1=systemd 219 から、セッションが開始したときに {{ic|$DISPLAY}} と {{ic|$XAUTHORITY}} を {{ic|systemd --user}} デーモンの環境にアップロードする X11 セッションアプレットが付属するようになりました。これによって systemd ユーザーサービスで X11 のアプリケーションを実行するときの互換性が向上しています ([http://cgit.freedesktop.org/systemd/systemd/tree/NEWS?id=v219#n194 ソース])。}} |
||
− | DISPLAY は X アプリケーションがどのディスプレイを使えばいいのか知るために使用されます。systemd ユニットから X アプリケーションを起動する |
+ | {{ic|DISPLAY}} は X アプリケーションがどのディスプレイを使えばいいのか知るために使用されます。{{ic|XAUTHORITY}} はユーザーの {{ic|.Xauthority}} ファイルのパスと、X サーバーにアクセスするのに必要な cookie を指定します。systemd ユニットから X アプリケーションを起動する場合、これらの変数を設定する必要があります。[https://github.com/systemd/systemd/blob/v219/NEWS#L194 バージョン 219] から、セッションが開始したときに {{ic|DISPLAY}} と {{ic|XAUTHORITY}} を {{ic|systemd --user}} デーモンの環境にアップロードする X11 セッションアプレット {{ic|/etc/X11/xinit/xinitrc.d/50-systemd-user.sh}} が systemd に付属するようになりました。これによって、X を標準の方法で起動しているかぎり、ユーザーサービスは {{ic|DISPLAY}} や {{ic|XAUTHORITY}} を使用することができるようになっています。 |
− | |||
− | {{hc|/etc/systemd/user.conf|<nowiki> |
||
− | ... |
||
− | DefaultEnvironment=DISPLAY=:0 |
||
− | ... |
||
− | </nowiki>}} |
||
− | |||
− | もしくは xinitrc スクリプトをインストールして適切な環境変数を取得することもできます: |
||
− | |||
− | {{hc|/etc/X11/xinit/xinitrc.d/import-display.sh|<nowiki> |
||
− | #!/bin/sh |
||
− | |||
− | systemctl --user import-environment DISPLAY XAUTHORITY |
||
− | </nowiki>}} |
||
==== PATH ==== |
==== PATH ==== |
||
167行目: | 117行目: | ||
{{Note|This is not a fundamental restriction imposed by logind, but the reason seems to be that xorg needs to know which session to take over, and right now it gets this information calling [http://www.freedesktop.org/wiki/Software/systemd/logind logind]'s {{ic|GetSessionByPID}} using its own pid as argument. See [http://lists.x.org/archives/xorg-devel/2014-February/040476.html this thread] and [http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/os-support/linux/systemd-logind.c xorg sources]. It seems likely that xorg could be modified to get the session from the tty it is attaching to, and then it could run unprivileged from a user service outside a session.}} |
{{Note|This is not a fundamental restriction imposed by logind, but the reason seems to be that xorg needs to know which session to take over, and right now it gets this information calling [http://www.freedesktop.org/wiki/Software/systemd/logind logind]'s {{ic|GetSessionByPID}} using its own pid as argument. See [http://lists.x.org/archives/xorg-devel/2014-February/040476.html this thread] and [http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/os-support/linux/systemd-logind.c xorg sources]. It seems likely that xorg could be modified to get the session from the tty it is attaching to, and then it could run unprivileged from a user service outside a session.}} |
||
+ | |||
+ | {{Warning|1=xorg 1.18 ではソケットアクティベーションが壊れているようです。クライアントからアクティベーションが実行されるとデッドロックが発生します。上流のバグレポート [https://bugs.freedesktop.org/show_bug.cgi?id=93072] を参照してください。回避策としては、ソケットアクティベーションを使わないで xorg サーバーを起動することで、サーバーが完全に起動するまでクライアントの接続を待機させることができます。X サーバーの起動を通知する機構は存在しません。}} |
||
以下がユーザーサービスから xorg を起動する方法です: |
以下がユーザーサービスから xorg を起動する方法です: |
||
207行目: | 159行目: | ||
{{Note|xorg はユーザーがログインしたのと同じ仮想ターミナルで起動する必要があります。そうでないと logind はセッションがアクティブになっていないと認識します。}} |
{{Note|xorg はユーザーがログインしたのと同じ仮想ターミナルで起動する必要があります。そうでないと logind はセッションがアクティブになっていないと認識します。}} |
||
− | 3. [[#DISPLAY|上]]で説明されているように {{ic|DISPLAY}} 環境変数を設定します。 |
+ | 3. [[#DISPLAY と XAUTHORITY|上]]で説明されているように {{ic|DISPLAY}} 環境変数を設定します。 |
4. 次に、display 0 と tty 2 で xorg のソケットアクティベーションを有効化します: |
4. 次に、display 0 と tty 2 で xorg のソケットアクティベーションを有効化します: |
||
250行目: | 202行目: | ||
=== X アプリケーションについての注意 === |
=== X アプリケーションについての注意 === |
||
− | ほとんどの X アプリは実行するのに {{ic|DISPLAY}} 変数を必要とします |
+ | ほとんどの X アプリは実行するのに {{ic|DISPLAY}} 変数を必要とします。systemd のユーザーインスタンスでこの変数を設定する方法は [[#DISPLAY と XAUTHORITY]] を見て下さい。 |
− | |||
− | {{hc|~/.config/systemd/user/parcellite.service|2= |
||
− | [Unit] |
||
− | Description=Parcellite clipboard manager |
||
− | |||
− | [Service] |
||
− | ExecStart=/usr/bin/parcellite |
||
− | '''Environment=DISPLAY=:0''' |
||
− | |||
− | [Install] |
||
− | WantedBy=mystuff.target |
||
− | }} |
||
== ユースケース == |
== ユースケース == |
||
283行目: | 223行目: | ||
}} |
}} |
||
+ | 上記の {{ic|mystuff.target}} と同じように、{{ic|cruft.target}} は tmux や screen が起動する前に実行する必要があるサービス (もしくは起動時に即座に起動させたいサービス)、例えば GnuPG デーモンのセッションなどを起動します。 |
||
− | {{ic|cruft.target}}, like {{ic|mystuff.target}} above, should start anything you think should run before tmux or screen starts (or which you want started at boot regardless of timing), such as a GnuPG daemon session. |
||
+ | 次にマルチプレクサセッションのサービスを作成してください。以下は tmux を使用して {{ic|/tmp/gpg-agent-info}} に情報を書き込む gpg-agent セッションを読み込むサービスの例です。また、DISPLAY を設定することで X を起動したときに X プログラムが実行できるようにしています。 |
||
− | You then need to create a service for your multiplexer session. Here is a sample service, using tmux as an example and sourcing a gpg-agent session which wrote its information to {{ic|/tmp/gpg-agent-info}}. This sample session, when you start X, will also be able to run X programs, since DISPLAY is set. |
||
{{bc|1= |
{{bc|1= |
||
326行目: | 266行目: | ||
</nowiki>}} |
</nowiki>}} |
||
− | {{Note| |
+ | {{Note|{{ic|[Install]}} セクションに {{ic|WantedBy}} を記述することで、{{ic|systemctl --user enable}} を使用した際に {{ic|~/.config/systemd/user/wm.target.wants/''window_manager''.service}} としてリンクが作成され、ログイン時に起動できるようになります。リンクは手動で作成するのではなく、サービスを有効化することを推奨します。}} |
== 参照 == |
== 参照 == |
||
* [https://bitbucket.org/KaiSforza/systemd-user-units/wiki/Home KaiSforza's bitbucket wiki] |
* [https://bitbucket.org/KaiSforza/systemd-user-units/wiki/Home KaiSforza's bitbucket wiki] |
||
* [https://github.com/zoqaeski/systemd-user-units Zoqaeski's units on Github] |
* [https://github.com/zoqaeski/systemd-user-units Zoqaeski's units on Github] |
||
− | * [https://github.com/grawity/systemd-user-units Collection of useful systemd user units] |
||
* [https://bbs.archlinux.org/viewtopic.php?id=167115 Forum thread about changes in systemd 206 user instances] |
* [https://bbs.archlinux.org/viewtopic.php?id=167115 Forum thread about changes in systemd 206 user instances] |
2016年3月2日 (水) 17:50時点における版
systemd はユーザーに systemd のインスタンスを実行させてサービスを管理できる機能を提供しています。これによって systemd がユーザーによって実行されている時、特定のディレクトリに入っているユニットをユーザーが起動・停止・有効化・無効化することが可能です。このことは root や特別なユーザーではなく普通のユーザーとして通常実行される mpd などのデーモン・サービスで重宝します。また、メールの取得などの作業を自動化することも可能です。さらに、多少の注意が必要ですが、ユーザーサービスから xorg やウィンドウマネージャを実行することもできます。
利用方法
ユーザーがログインを行うと、systemd は自動的にユーザーサービスを管理する systemd --user
インスタンスを起動します。このプロセスは、そのユーザーにセッションが残っているかぎり生存し、ユーザーの最後のセッションが閉じられた時に終了します。systemd のユーザーインスタンスを自動起動している場合、インスタンスはブート時に起動し、終了しません。ユーザーサービスを使うことで、ソケットアクティベーションやタイマー、システムの依存関係や cgroups によるプロセスの制限など、systemd の恩恵を最大限活用して、デーモンや自動化されたタスクを実行できます。
ユーザーユニットはシステムサービスと同じように以下のディレクトリに配置されます (優先度が低い順):
/usr/lib/systemd/user/
: インストールしたパッケージに含まれているサービス~/.local/share/systemd/user/
: ホームディレクトリにインストールしたパッケージのユニット/etc/systemd/user/
: システムの管理者が配置する、全てのユーザーが使えるユーザーサービス~/.config/systemd/user/
: ユーザーが配置する、そのユーザーのサービス
systemd のユーザーインスタンスが起動すると、default.target
ターゲットが立ち上がります。その後 systemctl --user
を使って手動で systemd のユーザーインスタンスを制御できるようになります。
基本設定
Systemd のユーザーインスタンスはログイン時に自動で起動します。正しく起動していることを確認するには、次のコマンドを使います: systemctl --user status
。
ユーザーサービスは全て ~/.config/systemd/user/
に配置してください。ログイン時にサービスを実行したい場合は、自動実行したいサービスごとに systemctl --user enable service
を実行してください。
D-Bus
プログラムによっては D-Bus ユーザーメッセージバスを必要とすることがあります。D-Bus は伝統的に dbus-launch
によってデスクトップ環境の起動時に実行されていましたが、バージョン206から、systemd がユーザーのメッセージバスを管理するようになりました [3]。dbus.socket
や dbus.service
のユーザーユニットによって全てのセッションでユーザーごとに dbus-daemon が起動します。
環境変数
systemd のユーザーインスタンスは .bashrc
などに設定された環境変数を全く継承しません。systemd インスタンスに環境変数を設定する方法は複数存在します:
/etc/systemd/user.conf
でDefaultEnvironment
オプションを使う。全てのユーザーユニットに影響します。/etc/systemd/system/user@.service.d/
に設定ファイルを追加する。全てのユーザーユニットに影響します。#サービス例を参照。- 適宜、
systemctl --user set-environment
やsystemctl --user import-environment
を使う。環境変数を設定した後に起動したユーザーユニットには影響しますが、既に起動しているユニットには影響しません。 - D-Bus の
dbus-update-activation-environment --systemd --all
コマンドを使う。systemctl --user import-environment
と同じ効果があり、D-Bus セッションに適用されます。コマンドはシェルの初期化ファイルの末尾に追加できます。
設定するべき変数としては DISPLAY
や PATH
などが考えられます。
サービス例
ドロップインディレクトリ /etc/systemd/system/user@.service.d/
を作成して、その中に拡張子が .conf
のファイルを作成します (例: local.conf
):
/etc/systemd/system/user@.service.d/local.conf
[Service] Environment="PATH=/usr/lib/ccache/bin/:$PATH" Environment="EDITOR=nano -c" Environment="BROWSER=firefox" Environment="NO_AT_BRIDGE=1"
DISPLAY と XAUTHORITY
DISPLAY
は X アプリケーションがどのディスプレイを使えばいいのか知るために使用されます。XAUTHORITY
はユーザーの .Xauthority
ファイルのパスと、X サーバーにアクセスするのに必要な cookie を指定します。systemd ユニットから X アプリケーションを起動する場合、これらの変数を設定する必要があります。バージョン 219 から、セッションが開始したときに DISPLAY
と XAUTHORITY
を systemd --user
デーモンの環境にアップロードする X11 セッションアプレット /etc/X11/xinit/xinitrc.d/50-systemd-user.sh
が systemd に付属するようになりました。これによって、X を標準の方法で起動しているかぎり、ユーザーサービスは DISPLAY
や XAUTHORITY
を使用することができるようになっています。
PATH
PATH
変数を .bashrc
や .bash_profile
で設定しても systemd では使うことができません。PATH
をカスタマイズしており、それを利用するアプリケーションを systemd ユニットから起動する予定があるなら、systemd 環境に PATH
を設定する必要があります。PATH
を .bash_profile
に設定している場合、以下を PATH
変数を設定した後の .bash_profile
に追加するのが systemd で PATH
を設定する一番簡単な方法です:
~/.bash_profile
systemctl --user import-environment PATH
systemd のユーザーインスタンスを自動起動
systemd のユーザーインスタンスはデフォルトでユーザーの最初のログイン時に実行され、ユーザーのセッションが閉じられた時に終了します。しかしながら、ブートした直後にインスタンスを起動して、セッションが閉じられてもユーザーインスタンスを実行し続ける方が、例えばセッションが開いてない時もユーザープロセスを実行したいときなどには便利です。linger を利用してこれを行います。特定のユーザーで linger を有効にするには以下のコマンドを使用:
# loginctl enable-linger username
Xorg と systemd
systemd ユニットの中で Xorg を実行する方法は複数存在します。以下の2つは、xorg プロセスで新しいユーザーセッションを起動するというのと、systemd のユーザーサービスから xorg を起動するという方法です。
ディスプレイマネージャを使わずに Xorg に自動ログイン
こちらを選択した場合、xorg サーバーでユーザーセッションを起動してその後ウィンドウマネージャなどを起動するために通常の ~/.xinitrc
を実行するシステムユニットを起動します。
D-Bus を適切に設定して xlogin-gitAUR をインストールする必要があります。
雛形のファイルから xinitrc を設定して、/etc/X11/xinit/xinitrc.d/
のファイルが読み込まれるようにしてください。~/.xinitrc
は実行したときに戻ってこないようにする必要があるため、最後のコマンドとして wait
を記述するか、(ウィンドウマネージャなど) exec
を追加して戻ってこないようにしてください。
セッションは自らの dbus デーモンを使用しますが、systemd ユーティリティは dbus.service
インスタンスに自動的に接続します。
最後に、(root で) xlogin を有効にして起動時に自動ログインするようにしてください:
# systemctl enable xlogin@username
ユーザーセッションが systemd の範囲の中に収まるようになってユーザーセッションの全てが問題なく動作するはずです。
systemd のユーザーサービスとしての Xorg
また、systemd のユーザーサービスの中から Xorg を実行することもできます。他の X 関連のユニットを Xorg などに依存させることができるという点では有利な一方、以下で説明するようにいくつか欠点が存在します。
バージョン 1.16 から xorg-server は systemd とのより良い統合を2つの手段で提供しています:
- デバイス管理を logind に委託することで、非特権でも実行することが可能に (このコミット など Hans de Goede のコミットを参照)。
- ソケットによってサービスを有効化することが可能に (このコミット を参照)。これによって systemd-xorg-launch-helper-gitAUR が不要に。
残念ながら、非特権モードで xorg を実行できるようにするには、セッションの中で xorg を実行する必要があります。そのため、今のところユーザーサービスとして xorg を実行するのには (1.16 以前と同じように) root 権限で実行する必要があるというハンディキャップがあり、1.16 で導入された非特権モードを活用することはできません。
以下がユーザーサービスから xorg を起動する方法です:
1. /etc/X11/Xwrapper.config
を編集して、xorg が root 権限を使ってどのユーザーでも動作するようにします:
/etc/X11/Xwrapper.config
allowed_users=anybody needs_root_rights=yes
2. 以下のユニットを ~/.config/systemd/user
に追加:
~/.config/systemd/user/xorg@.socket
[Unit] Description=Socket for xorg at display %i [Socket] ListenStream=/tmp/.X11-unix/X%i
~/.config/systemd/user/xorg@.service
[Unit] Description=Xorg server at display %i Requires=xorg@%i.socket After=xorg@%i.socket [Service] Type=simple SuccessExitStatus=0 1 ExecStart=/usr/bin/Xorg :%i -nolisten tcp -noreset -verbose 2 "vt${XDG_VTNR}"
${XDG_VTNR}
は xorg が起動する仮想ターミナルで、サービスユニットでハードコードするか、以下のコマンドを使って systemd 環境で設定します:
$ systemctl --user set-environment XDG_VTNR=1
3. 上で説明されているように DISPLAY
環境変数を設定します。
4. 次に、display 0 と tty 2 で xorg のソケットアクティベーションを有効化します:
$ systemctl --user set-environment XDG_VTNR=2 # So that xorg@.service knows which vt use $ systemctl --user start xorg@0.socket # Start listening on the socket for display 0
これで X アプリケーションを実行すると仮想ターミナル2で自動的に xorg が起動します。
XDG_VTNR
環境変数は .bash_profile
から systemd 環境に設定することができ、ウィンドウマネージャなど、あらゆる X アプリケーションを xorg@0.socket
に依存する systemd ユニットとして起動することが可能です。
ユーザーユニットを書く
サンプル
以下は mpd サービスのユーザーバージョンの例です。
~/.config/systemd/user/mpd.service
[Unit] Description=Music Player Daemon [Service] ExecStart=/usr/bin/mpd --no-daemon [Install] WantedBy=default.target
変数を使用したサンプル
以下は sickbeard.service
のユーザーバージョンの例で、SickBeard が特定のファイルを見つけられるようホームディレクトリの変数を使っています:
~/.config/systemd/user/sickbeard.service
[Unit] Description=SickBeard Daemon [Service] ExecStart=/usr/bin/env python2 /opt/sickbeard/SickBeard.py --config %h/.sickbeard/config.ini --datadir %h/.sickbeard [Install] WantedBy=default.target
man systemd.unit
に書かれているように、%h
変数はサービスを実行しているユーザーのホームディレクトリに置き換えられます。他にも systemd のマニュアルページで示されている変数が存在します。
X アプリケーションについての注意
ほとんどの X アプリは実行するのに DISPLAY
変数を必要とします。systemd のユーザーインスタンスでこの変数を設定する方法は #DISPLAY と XAUTHORITY を見て下さい。
ユースケース
永続的なターミナルマルチプレクサ
ウィンドウマネージャのセッションにログインする代わりに、ユーザーセッションでデフォルトで GNU Screen や Tmux などのターミナルマルチプレクサをバックグラウンドで実行したいということもあるでしょう。X ログインとログインを分割するのはディスプレイマネージャの代わりに TTY で起動したい場合にのみ有用です (その場合すべてを myStuff.target
で起動するように記述できます)。
上述のようなタイプのユーザーセッションを作成するには、wm.target
を作成する代わりに、multiplexer.target
を作成します:
[Unit] Description=Terminal multiplexer Documentation=info:screen man:screen(1) man:tmux(1) After=cruft.target Wants=cruft.target [Install] Alias=default.target
上記の mystuff.target
と同じように、cruft.target
は tmux や screen が起動する前に実行する必要があるサービス (もしくは起動時に即座に起動させたいサービス)、例えば GnuPG デーモンのセッションなどを起動します。
次にマルチプレクサセッションのサービスを作成してください。以下は tmux を使用して /tmp/gpg-agent-info
に情報を書き込む gpg-agent セッションを読み込むサービスの例です。また、DISPLAY を設定することで X を起動したときに X プログラムが実行できるようにしています。
[Unit] Description=tmux: A terminal multiplixer Documentation=man:tmux(1) After=gpg-agent.service Wants=gpg-agent.service [Service] Type=forking ExecStart=/usr/bin/tmux start ExecStop=/usr/bin/tmux kill-server Environment=DISPLAY=:0 EnvironmentFile=/tmp/gpg-agent-info [Install] WantedBy=multiplexer.target
Once this is done, systemctl --user enable
tmux.service
, multiplexer.target
and any services you created to be run by cruft.target
and you should be set to go! Activated user-session@.service
as described above, but be sure to remove the Conflicts=getty@tty1.service
from user-session@.service
, since your user session will not be taking over a TTY. Congratulations! You have a running terminal multiplexer and some other useful programs ready to start at boot!
ウィンドウマネージャ
systemd のサービスとしてウィンドウマネージャを実行するには、まず Xorg を systemd のユーザーサービスとして実行する必要があります。以下では awesome を例として使います:
~/.config/systemd/user/awesome.service
[Unit] Description=Awesome window manager After=xorg.target Requires=xorg.target [Service] ExecStart=/usr/bin/awesome Restart=always RestartSec=10 [Install] WantedBy=wm.target