「Systemd」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
190行目: 190行目:
 
=== ユニットファイルの編集 ===
 
=== ユニットファイルの編集 ===
   
パッケージに入っているユニットファイルを編集する方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインスニペットを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。{{ic|systemctl edit}} でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:
+
パッケージに入っているユニットファイルを編集する方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインファイルを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。{{ic|systemctl edit}} でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:
   
 
# systemctl daemon-reload
 
# systemctl daemon-reload

2017年5月31日 (水) 15:00時点における版

関連記事

プロジェクトウェブページ より:

systemd は Linux 環境の基本構成スイートであり、SysV や LSB init スクリプトと互換性のある、Linux 用のシステム・サービスマネージャです。systemd はサービスの起動を積極的に並行化します。また、ソケットや D-Bus のアクティベーションを使用してサービスを起動し、必要なデーモンの開始を行うことができ、Linux の cgroups によるプロセス管理ができます。システム状態のスナップショット作成と復元、(自動) マウントポイントの管理、煩雑な依存関係に基づいたサービスのコントロールを処理します。systemd は sysvinit の代替として SysV や LSB init スクリプトをサポートしています。init としての機能以外にも、ログデーモンやホストネーム・時刻・ロケールなどシステムの基本設定を制御するユーティリティ、ログイン中のユーザーから実行中のコンテナや仮想マシン、システムアカウントまで管理する機能、ネットワーク設定や時刻同期あるいは名前解決などを管理するシンプルなデーモンも含まれています。
ノート: systemd が Arch に採用された理由については、フォーラムへのこの投稿をご覧ください。

目次

systemctl の基本的な使い方

systemd を管理したり内部情報を見るために使うメインのコマンドが systemctl です。システムの状態を確かめたりシステムやサービスを管理するために使うのは使い方の一部です。詳しくは man 1 systemctl を見て下さい。

ヒント:
  • systemctl コマンドに -H <user>@<host> を渡すと、リモートの systemd と対話できます。SSH を利用してリモートの systemd インスタンスに繋ぐのに使われます。
  • systemctl の公式グラフィカルフロントエンドとして systemadm が存在します。公式リポジトリからインストールできる systemd-ui に入っています。
  • Plasma を使っている場合 systemd-kcm をインストールすることで systemctl のグラフィカルフロントエンドを使えます。モジュールをインストールすると System administration の下に設定が追加されます。

システムの状態を分析する

システムの状態を表示:

$ systemctl status

実行中のユニットを一覧する:

$ systemctl

または:

$ systemctl list-units

失敗したユニットを一覧する:

$ systemctl --failed

実行可能なユニットファイルは /usr/lib/systemd/system//etc/systemd/system/ にあります (後者が優先的に使われます)。インストールされたユニットを一覧するには:

$ systemctl list-unit-files

ユニットを使う

ユニットには、例えば、サービス (.service) やマウントポイント (.mount)、デバイス (.device)、ソケット (.socket) などがあります。

systemctl を使うとき、一般的には拡張子 (suffix) を含むユニットファイルの完全な名前を指定する必要があります。例えば、sshd.socket のように。しかし、以下のような場合には省略形が存在します:

  • 拡張子が指定されない場合、systemctlは .service とみなします。例えば netctlnetctl.service は同じように扱われます。
  • マウントポイントは自動的に対応する .mount ユニットとして扱われます。例えば、/home を指定することは home.mount の指定と同じです。
  • マウントポイントと同じく、デバイスも自動的に対応する .device ユニットとして扱われます。従って、/dev/sda2 の指定は dev-sda2.device と同じです。

詳細は man systemd.unit を見てください。

ノート: ユニットによっては名前に @ 記号が含まれていることがあります (例: name@string.service): これは、そのサービスがテンプレートユニットの インスタンス であることを意味しており、テンプレートユニットのファイル名には string の部分が含まれていません (例: name@.service)。stringinstance identifier と呼ばれ、systemctl コマンドでテンプレートユニットを実行するときに指定する引数と似ています: ユニットファイルの中の %i が置き換えられます。 正確に言うと、name@.suffix テンプレートユニットのインスタンスを作成する前にsystemdname@string.suffix というファイル名のユニットが存在しないか確認します。ただし名前の"衝突"が発生するのは極めて稀で、@ 記号を含むユニットファイルは大抵テンプレートです。そういう決まりです。また、テンプレートユニットが instance identifier を付けられずに呼ばれたときは、%i が置き換えられないため実行失敗になります。
ヒント:
  • 以下のコマンドのほとんどは複数のユニットを指定することが可能です、詳しくは man systemctl を参照。
  • パッケージには様々な目的のユニットが入っています。パッケージをインストールしたら、pacman -Qql package | grep -Fe .service -e .socket でサービスを確認することができます。

いますぐユニットを実行:

# systemctl start unit

いますぐユニットを停止:

# systemctl stop unit

ユニットを再始動:

# systemctl restart unit

ユニットに設定を再読み込みするように通知:

# systemctl reload unit

ユニットの状態を表示(動いているかどうかなど):

$ systemctl status unit

有効化(起動時に自動で実行するよう設定)されているかどうか表示:

$ systemctl is-enabled unit

起動時に実行されるように有効化する:

# systemctl enable unit

システム起動時に実行されないように無効化する:

# systemctl disable unit

ユニットをマスクすることで起動しないようにできます:

# systemctl mask unit

ユニットのマスクを解除:

# systemctl unmask unit

ユニットに関連する(ユニットファイルによってサポートされている)マニュアルページを参照する:

$ systemctl help unit

systemd をリロードし、新しい、もしくは変化のあったユニットをスキャンする:

# systemctl daemon-reload
ヒント: systemd 220 から、--now スイッチを使うことで enable で指定したユニットをすぐに起動して、disablemask したユニットを停止できるようになりました。

電源管理

電源管理には polkit が必要です。 ローカルの systemd-logind のユーザーセッション中で、他のセッションがアクティブでなければ、ルート権限なしで以下のコマンドが使えます。そうでなければ (他のユーザが tty でログインしている場合など)、systemd は自動的に root のパスワードを要求するでしょう。

再起動:

$ systemctl reboot

シャットダウンしてパワーオフ:

$ systemctl poweroff

サスペンド(待機):

$ systemctl suspend

ハイバネート(休止):

$ systemctl hibernate

ハイブリッドスリープ (もしくは suspend-to-both):

$ systemctl hybrid-sleep

ユニットファイルの書き方

systemd の ユニットファイル の構文は XDG の Desktop Entry Specification である .desktop から影響を受けています。そして .desktop は Microsoft Windows の .ini ファイルからインスパイアされています。ユニットファイルは2つの場所に配置されます。優先度が低い方から説明すると:

  • /usr/lib/systemd/system/: インストールしたパッケージに含まれているユニット
  • /etc/systemd/system/: システムの管理者がインストールしたユニット
ノート:
  • ユーザーモードsystemd を動作させたときにロードされるパスは完全に異なります。
  • systemd ユニットの名前に使うことができるのは ASCII 英数字とアンダーバー、ピリオドだけです。他の文字列は "\x2d" エスケープに置き換える必要があります。詳しくは man systemd.unitman systemd-escape を見て下さい。

依存関係を解決する

systemd ではユニットファイルを適切に書くことで依存関係を解決します。一番典型的なケースは、ユニット A が走る前に、ユニット A がユニット B を必要としている場合です。この場合、A[Unit] セクションに Requires=BAfter=B を加えます。依存が必然ではない場合、代わりに Wants=BAfter=B を加えます。Wants=Requires=After= を含まないことに注意してください、もし After= を明記しなかったときは、2つのユニットは並行して実行されます。

基本的に、依存関係はターゲットではなくサービスに配置します。例えば、network.target はネットワークインターフェースを設定する全てのサービスによって使われるので、network.target が起動し終わってからあなたのカスタムユニットを起動させる順番にします。

タイプ

カスタムサービスファイルを書くときにどのスタートアップタイプを使うべきか考える必要があります。タイプは [Service] セクションの Type= パラメータで設定します。より詳しい説明は man systemd.service を見て下さい。

  • Type=simple (デフォルト): systemd はプロセスを起動した時点でサービスが立ち上がったとみなします。プロセスをフォークすることはできません。ソケットアクティベーション以外で他のサービスが必要な場合に、このタイプを使ってはいけません。
  • Type=forking: 起動したプロセスが一旦フォークし、親プロセス側が終了したときに、 systemd はサービスが立ち上がったとみなします。このタイプでなくてもかまわないとき以外は、古典的なデーモンにはこのタイプを使って下さい。また PIDFile= を指定することで systemd はメインプロセスの情報を追い続けます。
  • Type=oneshot: シングルジョブを行い終了するスクリプト用のタイプです。また RemainAfterExit=yes を設定することで systemd はプロセスが終了した後もサービスがアクティブだとみなします。
  • Type=notify: Type=simple と同じですが、利用可能になったときにデーモンが systemd に信号を送るように条件がつけられます。この通知のリファレンス実装は libsystemd-daemon.so によって提供されています。
  • Type=dbus: 指定の BusName が DBus のシステムバスに乗ったときに使うことができるサービス。
  • Type=idle: idle の挙動は Type=simple と非常に似ています。ただし、サービスバイナリの実行は全てのジョブが処理されるまで待たされます。これを使えば、コンソールに状態を出力するシェルサービスで、出力が混じってしまうのを避けることができます。

ユニットファイルの編集

パッケージに入っているユニットファイルを編集する方法は2つあります: 新しいユニットファイルで完全に置き換えるか、ドロップインファイルを作成して既存のユニットファイルに上書きして適用させるかです。どちらの方法でも、変更を加えた後はユニットをリロードする必要があります。systemctl edit でユニットを編集するか (自動でユニットがリロードされます) または次のコマンドで全てのユニットをリロードしてください:

# systemctl daemon-reload
ヒント:
  • systemd-delta を使うことでどのファイルが上書きされ、どこが変更されたのか調べることができます。
  • ユニットファイルや関連するドロップインスニペットの中身を見るには systemctl cat unit を使います。
  • 公式リポジトリから vim-systemd をインストールすることで、Vimsystemd ユニットファイルのシンタックスハイライトが可能です。

ユニットファイルを置き換える

ユニットファイル /usr/lib/systemd/system/unit を置き換えたいときは、/etc/systemd/system/unit ファイルを作成してユニットを再有効することでシンボリックリンクをアップデートします:

# systemctl reenable unit

もしくは、次を実行:

# systemctl edit --full unit

このコマンドはテキストエディタで /etc/systemd/system/unit を開いて (ファイルが存在しない場合はインストールされているユニットがコピーされます)、編集を終えた時に自動的にユニットをリロードします。

ノート: Pacman は元のユニットファイルが更新されても置き換えられたユニットファイルをアップデートしません。そのため、この方法ではシステムメンテナンスが多少厄介になります。この理由があるために、次のセクションで説明する方法の方が推奨されます。

ドロップインファイル

ユニットファイル /usr/lib/systemd/system/unit のドロップインファイルを作成するには、/etc/systemd/system/unit.d/ という名のディレクトリ (例: /etc/systemd/system/httpd.service.d/) を作成してその中に *.conf を配置します。このファイルを使ってオプションを上書きしたり追加してください。systemd*.conf ファイルをパースして元のユニットファイルの一番上に設定を適用します。

ドロップインファイルを作成する一番簡単な方法は次のコマンドを実行することです:

# systemctl edit unit

テキストエディタで /etc/systemd/system/unit.d/override.conf ファイルが開かれ (必要であればファイルが作成されます)、編集を終えた時に自動でユニットがリロードされます。

初期状態にリバート

systemctl edit を使って変更したユニットを元に戻したい場合、以下のコマンドを実行:

# systemctl revert unit

サンプル

例えば、ユニットに依存するデーモンを追加したい場合、以下のファイルを作成することができます:

/etc/systemd/system/<unit>.d/customdependency.conf
[Unit]
Requires=<new dependency>
After=<new dependency>

oneshot タイプでないユニットの ExecStart ディレクティブを置き換えるには、以下のファイルを作成します:

/etc/systemd/system/unit.d/customexec.conf
[Service]
ExecStart=
ExecStart=new command
ノート: ExecStart は置き換える前に空白にする必要があるので注意してください ([1])。タイマーの OnCalendar など複数回指定できるアイテムも同じです。

サービスが自動的に再起動されるようにするには:

/etc/systemd/system/unit.d/restart.conf
[Service]
Restart=always
RestartSec=30

ターゲット

Systemd ではランレベルに似たものとしてターゲットを使っています。ただしその挙動には少し違いがあります。それぞれのターゲットはナンバリングされる代わりに名前がつけられ、ある特定の目的のために作られ、複数のターゲットを同時に有効にできるようになっています。ターゲットによっては、他のターゲットのサービスを全て引継ぎ、そこにサービスを追加するよう実装されています。一般的な SystemVinit ランレベルに擬態する systemd ターゲットもあり、親しみのある telinit RUNLEVEL コマンドを使って使用するターゲットを切り替えることが可能です。

現在のターゲットを獲得

systemd では runlevel の代わりに次のコマンドが使われます:

$ systemctl list-units --type=target

カスタムターゲットを作る

標準の Fedora インストールではランレベルごとに特定の目的が設定されています; 0, 1, 3, 5, 6 のランレベルには特定の sytemd ターゲットと一対一の対応関係が存在します。残念ながら、ユーザー定義のランレベル (2 や 4 など) で同じことをする良い方法はありません。もしあなたがそうしたいならば、既に存在しているランレベルをベースに新しい systemd ターゲット/etc/systemd/system/<your target> として作り (/usr/lib/systemd/system/graphical.target がサンプルになるかもしれません)、/etc/systemd/system/<your target>.wants ディレクトリを作って、有効にしたいサービスに /usr/lib/systemd/system/ からシンボリックリンクを貼ることが示唆されています。

ターゲット表

SysV ランレベル systemd ターゲット 説明
0 runlevel0.target, poweroff.target システムを停止。
1, s, single runlevel1.target, rescue.target シングルユーザーモード。
2, 4 runlevel2.target, runlevel4.target, multi-user.target ユーザー定義・サイト指定ランレベル。デフォルトでは、3 と同一。
3 runlevel3.target, multi-user.target マルチユーザー、非グラフィカル。一般的にマルチコンソールやネットワークを介してログインするのに使われます。
5 runlevel5.target, graphical.target マルチユーザー、グラフィカル。通常、ランレベル 3 の全てのサービスにグラフィカルログインを付加。
6 runlevel6.target, reboot.target 再起動
emergency emergency.target 緊急シェル

現在のターゲットを変更する

systemd ではターゲットは"ターゲットユニット"を通して扱うことができます。ターゲットを変えるには次のようにします:

# systemctl isolate graphical.target

これは現在のターゲットを変えるだけで、次の起動時には影響がありません。SysVinit での、telinit 3telinit 5 のようなコマンドと同じです。

起動時のデフォルトターゲットを変更する

標準のターゲットは default.target で、デフォルトで (昔のランレベル 5 に大体対応している) graphical.target にエイリアスされています。起動時のデフォルトターゲットを変更するには、以下のカーネルパラメータのどれかをブートローダに加えてください:

ヒント: .target 拡張子は省くことができます。
  • systemd.unit=multi-user.target (昔のランレベル 3 とほぼ同じ)。
  • systemd.unit=rescue.target (昔のランレベル 1 とほぼ同じ)。

また、ブートローダには修正を加えずに default.target を変えることもできます。systemctl を使います:

# systemctl set-default multi-user.target

以前に設定した default.target を上書きできるようにするには、force オプションを使って下さい:

# systemctl set-default -f multi-user.target

このコマンドの効果は systemctl によって出力されます; 新しいデフォルトターゲットのシンボリックリンクは /etc/systemd/system/default.target に作成されます。

一時ファイル

Systemd-tmpfiles は /usr/lib/tmpfiles.d//etc/tmpfiles.d/ 下にある設定ファイルを読み、通常 /run/tmp などのディレクトリに存在している一時ファイル・ディレクトリの作成、内容の消去、削除などを行います。それぞれの設定ファイル名は /etc/tmpfiles.d/<program>.conf です。/usr/lib/tmpfiles.d/ に同名の設定ファイルがある場合上書きされます。

tmpfiles は一時ファイルを必要とするデーモンのサービスファイルに同梱されます。例えば Samba デーモンは /run/samba を一時ディレクトリとして使用するため、正しいパーミッションに設定されていることを期待します。これを表す tmpfile は以下のようになります:

/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root

tmpfiles は起動時にファイルに値を書き込むのにも使われることがあります。例えば、/etc/rc.local を使って USB デバイスからの wakeup を無効化する echo USBE > /proc/acpi/wakeup は、tmpfile では以下のように書けます:

/etc/tmpfiles.d/disable-usb-wake.conf
w /proc/acpi/wakeup - - - - USBE

詳細は systemd-tmpfiles(8)tmpfiles.d(5) の man ページを参照してください。

ノート: systemd-tmpfiles-setup サービスは適切なモジュールがロードされる前に実行されることがあるので、/sys にオプションを設定するのにこの方法は使えません。このため設定したいオプションのパラメータをモジュールが持っているか確認するには modinfo module を使い、オプションを設定は /etc/modprobe.d 下の設定ファイルを使って下さい。もしくはデバイスが現れたときにすぐ適切な属性を設定する udev ルールを書いて下さい。

タイマー

タイマーは ".timer" で終わる名前を持つユニット設定ファイルで、時間に基づく実行を行うために、systemd で制御・管理するタイマーの情報をエンコードしています。systemd/タイマー を参照してください。

ノート: タイマーは cron の機能をほぼ全て置き換えることができます。詳しくは、systemd/タイマー#cron を置き換える を参照してください。

マウント

systemd は System V init を置き換えるため、/etc/fstab に指定されたマウントも処理します。fstab の通常機能だけでなく、x-systemd. が前に付く特殊なマウントオプションを利用することが可能です。拡張機能を使用する具体的な例として Fstab#systemd による自動マウント には必要に応じて自動マウントする方法が書かれています。拡張機能のドキュメントは [2] を参照してください。

Journal

systemd は、バージョン 38 から自前のログシステムである journal を搭載しています。従って、syslog デーモンを起動する必要はもはやありません。ログを読むには:

# journalctl

デフォルトで (/etc/systemd/journald.conf 内で Storage=auto に設定されているとき)、journal は /var/log/journal/ へ書き込みを行います。Arch Linux では /var/log/journal/ ディレクトリは systemd の一部であり、あなたや何らかのプログラムがディレクトリを削除した場合、systemd は自動で再作成しませんが、systemd のアップデートがあるとディレクトリは作りなおされます。それまでログは代わりに /run/systemd/journal に書き込まれます。ただし再起動時にこのログは消失してしまいます。

ヒント: /var/log/journal/btrfs ファイルシステムに存在する場合、ディレクトリの Copy-on-Write を無効にするべきです。詳しくは Btrfs#コピーオンライト (CoW) を読んで下さい。

Systemd ジャーナルはメッセージをプライオリティレベルファシリティで分類します。古典的な Syslog プロトコルと対応しています (RFC 5424)。

プライオリティレベル

メッセージの重要度は syslog の重大度コード (systemd ではプライオリティと呼ばれます) を使って示されます RFC 5424 Section 6.2.1:

重大度 キーワード 説明
0 Emergency emerg システムは利用不可能 重大なカーネルのバグ/systemd によってコアダンプが作成された。アプリケーションが使用するレベルではありません。
1 Alert alert 即時対応が必要 重要なサブシステムが機能していない/データが消失している。
kernel: BUG: unable to handle kernel paging request at ffffc90403238ffc
2 Critical crit 緊急状態 クラッシュ/コアダンプ。systemd-coredump[25319]: Process 25310 (plugin-containe) of user 1000 dumped core。X11 などのシステムにとって重要なアプリケーションが機能を失っている。
3 Error err エラー状態 重大度は低いエラー: kernel: usb 1-3: 3:1: cannot get freq at ep 0x84,
systemd[1]: Failed unmounting /var., libvirtd[1720]: internal error: Failed to initialize a valid firewall backend)。
4 Warning warning エラーが発生する前に対応が必要 ルートファイルシステム以外のファイルシステムの空き領域が 1GB しかない。org.freedesktop. Notifications[1860]: (process:5999): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale
5 Notice notice 通常ではないイベントが発生しているがエラー状態ではない systemd[1]: var.mount: Directory /var to mount over is not empty, mounting anyway, gcr-prompter[4997]: Gtk: GtkDialog mapped without a transient parent. This is discouraged
6 Informational info 何も対応が必要な通常のメッセージ lvm[585]: 7 logical volume(s) in volume group "archvg" now active
7 Debug debug アプリケーションをデバッグするのに役立つ情報 kdeinit5[1900]: powerdevil: Scheduling inhibition from ":1.14" "firefox" with cookie 13 and reason "screen"

上記のレベルで問題が確認できない場合、上下のプライオリティレベルも調べてみてください。厳しくルールが決められているわけではありません。発生する確率が高いエラーは開発者によってプライオリティが低く設定されている可能性があります。逆に、緊急度が高いメッセージが大量に出力されることもありますが、必ずしも切羽詰まった状況を表しているとは限りません。

ファシリティ

メッセージを出力したプログラムのタイプは syslog のファシリティコードで指定されます RFC 5424 Section 6.2.1:

ファシリティコード キーワード 説明 情報
0 kern カーネルメッセージ
1 user ユーザーレベルメッセージ
2 mail メールシステム 詳しくは man mail) を見てください。
3 daemon システムデーモン systemd やサブシステムを含む全てのデーモン
4 auth セキュリティ/認証メッセージ ファシリティ10もあります。
5 syslog syslogd の内部メッセージ syslogd 用のファシリティなので systemd は使用していません (ファシリティ3を使います)。
6 lpr ラインプリンターサブシステム (旧式のサブシステム)
7 news ネットワークニュースサブシステム (旧式のサブシステム)
8 uucp UUCP サブシステム (旧式のサブシステム)
9 クロックデーモン systemd-timesyncd
10 authpriv セキュリティ/認証メッセージ ファシリティ4もあります。
11 ftp FTP デーモン
12 - NTP サブシステム
13 - log audit
14 - log alert
15 cron スケジューリングデーモン
16 local0 ローカル使用 0 (local0)
17 local1 ローカル使用 1 (local1)
18 local2 ローカル使用 2 (local2)
19 local3 ローカル使用 3 (local3)
20 local4 ローカル使用 4 (local4)
21 local5 ローカル使用 5 (local5)
22 local6 ローカル使用 6 (local6)
23 local7 ローカル使用 7 (local7)

意味のあるファシリティは次の7つになります: 0, 1, 3, 4, 9, 10, 15。

フィルタリング

journalctl を使って出力にフィルタをかけることができます。表示したりフィルタリングをするメッセージが大量にある場合、かなり時間がかかります。コマンドの出力は相当の時間がたってから表示されるかもしれません。

ヒント: journal はバイナリ形式で保存されますが、保存されるメッセージの中身に修正は加わりません。このため、systemd をインストールしていない環境でリカバリなどをするために、strings を使って回覧することが可能です。コマンドの例: $ strings /mnt/arch/var/log/journal/af4967d77fba44c6b093d0e9862f6ddd/system.journal | grep -i message

例:

  • 起動時からの全てのメッセージを表示:
    # journalctl -b
    場合によっては最新のブートメッセージではなく、以前のブートのメッセージを読みたいことがあります (例えば復旧できないシステムクラッシュが起こった場合)。-b フラグに任意のパラメータを付けることでメッセージをオフセットして読むことが可能です: journalctl -b -0 は最新のブートのメッセージを、journalctl -b -1 は一つ前のブートのメッセージを表示し journalctl -b -2 は二つ前、と続きます。詳しくは man 1 journalctl を見て下さい、セマンティックスはより強力です。
  • 特定の日付 (任意で時間も指定可能) からのメッセージを全て表示:
    # journalctl --since="2012-10-30 18:17:16"
  • 20分前からのメッセージを全て表示:
    # journalctl --since "20 min ago"
  • 新しいメッセージを表示:
    # journalctl -f
  • 特定の実行ファイルによる全てのメッセージを表示:
    # journalctl /usr/lib/systemd/systemd
  • 特定のプロセスによる全てのメッセージを表示:
    # journalctl _PID=1
  • 特定のユニットによる全てのメッセージを表示:
    # journalctl -u netcfg
  • カーネルのリングバッファを表示:
    # journalctl -k
  • プライオリティレベルがエラー・クリティカル・アラートのメッセージだけを表示:
    # journalctl -p err..alert
    journalctl -p 3..1 と数字を使うこともできます。journalctl -p 3 のようにひとつだけ指定した場合、指定されたプライオリティよりも高いレベルのメッセージも表示されます。
  • syslog の facility をフィルタリングすることで auth.log と同等の内容を表示:
    # journalctl SYSLOG_FACILITY=10

詳しくは man 1 journalctl, man 7 systemd.journal-fields や Lennart のブログ記事 を見て下さい。

ヒント: デフォルトで、journalctl は画面からはみ出る行を切り詰めますが、場合によっては、折り返しが有効になっていたほうが読みやすいことがあります。SYSTEMD_LESS 環境変数によってこれを制御することができ、less (デフォルトのページャ) に渡すオプションを指定します。デフォルトは FRSXMK (詳しくは man 1 lessman 1 journalctl を参照) です。

S オプションを省くことで、出力は折り返されるようになります。例えば、以下のように journalctl を起動してください:

$ SYSTEMD_LESS=FRXMK journalctl
この挙動をデフォルトに設定したいならば、~/.bashrc~/.zshrc でこの変数を export してください。

journal のサイズ制限

journal が永続的(不揮発性)の場合、デフォルトではファイルシステムの容量の 10% に制限されます (4 GiB が上限)。例えば、/var/log/journal が 20GiB の root パーティションにのっている場合、2GiB がログデータの上限になります。/etc/systemd/journald.confSystemMaxUse を変更すれば、最大サイズを変更できます。例えば制限を 50Mib にする場合、適切な行を次のようにアンコメント・編集します:

SystemMaxUse=50M

上記のように設定ファイルを編集する代わりにドロップインスニペットを使用する方法もあります。その場合 [Journal] ヘッダーを使って以下のように記述してください:

/etc/systemd/journald.conf.d/00-journal-size.conf
[Journal]
SystemMaxUse=50M

詳細は man journald.conf を参照してください。

ジャーナルファイルを手動で消去

journal のファイルは /var/log/journal に存在します。rm で消去することもできますが、journalctl を使って消去することも可能です。例:

  • 使用ディスク容量が 100M 以下になるまで journal ファイルを削除する:
    # journalctl --vacuum-size=100M
  • 2週間以上前のデータを含んでいる journal ファイルを削除する:
    # journalctl --vacuum-time=2weeks

詳しくは man journalctl を見て下さい。

journald と syslog の結合

古典的な syslog との互換性は、すべてのメッセージがソケット /run/systemd/journal/syslog に転送されることで実現されます。syslog を使うには、/dev/log/ の代わりにこのソケットを指定します (公式アナウンス)。

systemd 216 からオーバーヘッドを減らすために journald.conf のソケットの転送はデフォルトで無効になっています (ForwardToSyslog=no)。rsyslogsyslog-ng (3.6 以降) は 自力で journal からメッセージを取得するためです。

設定の詳細は Syslog-ng#概要, Syslog-ng#syslog-ng と systemd journal, rsyslog を見て下さい。

journald を /dev/tty12 に転送する

ドロップインディレクトリ /etc/systemd/journald.conf.d を作成して、ディレクトリの中に fw-tty12.conf ファイルを作成してください:

/etc/systemd/journald.conf.d/fw-tty12.conf
[Journal]
ForwardToConsole=yes
TTYPath=/dev/tty12
MaxLevelConsole=info

次を実行して journald を再起動してください:

# systemctl restart systemd-journald

別のジャーナルを指定して表示

ライブ環境から起動して本番環境を修復する場合など、トラブルが発生した他のシステムのログを確認する必要があるような場合、/mnt などにディスクをマウントしてから、ジャーナルのパスを -D/--directory で指定することができます:

$ journalctl -D /mnt/var/log/journal -xe

SysVinit/initscripts からの移行

ノート:
  • systemdsystemd-sysvcompat2012-10-13 以降のインストールメディアではデフォルトでインストールされます。このセクションは未だに sysvinitinitscripts を使っている Arch Linux システムに向けて書かれています。
  • Arch Linux を VPS で動かしている場合、Virtual Private Server を参照してください。

移行前に考慮すべきこと

  • 本家のホームページ で、systemd についてざっと読んでください。
  • systemd の journal システムは、syslog を置き換えることができますが、この2つは共存できます。#Journal を見て下さい。
  • systemd は cronacpidxinetd の機能の一部を代替できますが、あなたが望まない限り伝統的なデーモンを使うのを止める必要はありません。
  • インタラクティブな initscript は sytemd では動きません。特に、起動時に netcfg-menu を使うことはできません (FS#31377)。

インストール

  1. 公式リポジトリから systemdインストールしてください。
  2. カーネルパラメータに次を加えます: init=/usr/lib/systemd/systemd
  3. 完了したら、必要なサービスを systemctl enable <service_name>.service を使って有効にできます (大雑把に言うと DAEMONS 行にサービスを追加するのと同じです)。
  4. システムを再起動し、systemd がアクティブになっていることを次のコマンドで確認します: cat /proc/1/commsystemd の文字が返ってくるはずです。
  5. systemd であなたのホストネームを設定します: hostnamectl set-hostname myhostname または /etc/hostname
  6. initscriptssysvinit をシステムから削除し systemd-sysvcompat をインストールしてください。
  7. もう必要なくなった init=/usr/lib/systemd/systemd パラメータを削除してください。systemd-sysvcompat がデフォルトの init になります。

initscripts のエミュレーション

伝統的な Arch の設定ファイルは initscripts パッケージによって使われています。systemd と initscripts がインストールされていて、systemd によってシステムが動いている時、systemd は以下のことを行います:

  1. /etc/rc.confDAEMONS 行をパースし、ブート時にデーモンを起動します
  2. ブート中に /etc/rc.local を実行します
  3. シャットダウン中に /etc/rc.local.shutdown を実行します

Initscripts のエミュレーションはユーザーが systemd に移行するのを手助けする過渡期の手段として存在しています、そして最終的には取り除かれる予定です。ネイティブな systemd は設定の中心として rc.conf を使いません、/etc/rc.conf が使えなくなる前にネイティブの systemd 設定ファイルを使うことを推奨します。

ノート: /etc/rc.local を置換するには、起動時に実行したいもののカスタムサービスファイルを書くことを推奨します。このセクションに方法を記述しています。
ノート: Ctrl+Alt+Del で再起動しないように /etc/inittab で設定していた場合、root で systemctl mask ctrl-alt-del.target を実行して systemd でも再設定する必要があります。
警告: systemd (197-4 以降) と initscripts 両方をインストールしていて、/etc/rc.local が存在する場合、(systemd 197-4 から getty@tty1.service が rc-local.service を待たなくなり、getty が起動できなくなるために) ブートプロセスが終了しません。/etc/rc.local を削除するか名前を変えて下さい。

DAEMONS 行からの移行

純粋な systemd セットアップのためには、完全に /etc/rc.conf ファイルを削除して systemctl だけを使ってサービスを有効にしなくてはなりません。/etc/rc.confDAEMONS 行のそれぞれの <service_name> に対して次を実行します:

# systemctl enable <service_name>.service
ヒント: 一般的に使われるデーモンの initscripts と systemd の比較表がここにあります。

<service_name>.service が存在しない場合:

  • ほとんどの場合、systemd は違う名前を使っています。例えば、crond init デーモンは cronie.service に、alsa init デーモンは alsa-store.servicealsa-restore.service になっています。他にも network デーモンは、他のサービスファイルに置き換わっています (詳しくはネットワーク設定を見て下さい)。
  • サービスファイルが systemd にない場合。その場合、起動中にサービスを作動させるのに rc.conf を使いつづける必要があります。
ヒント: パッケージの中身を見て、どのサービス名でデーモン起動スクリプトが含まれているのか見ることができます。例:
$ pacman -Ql cronie
[...]
cronie /etc/rc.d/crond                            #DAEMONS 行で使われるデーモン initscript ("純粋な" systemd では使われません)
[...]
cronie /usr/lib/systemd/system/cronie.service     #対応する systemd のデーモンサービス
[...]
  • 最後に、サービスによっては、ユーザーの操作で有効にする必要がないものがあります。例えば、dbus.servicedbus-core がインストールされると自動で有効にされます。alsa-store.servicealsa-restore.service も systemd によって自動で有効にされます。利用できるサービスと状態をチェックするには systemctl コマンドを使います: systemctl status <service_name>

追加情報

  • カーネルパラメータに quiet を設定している場合、それを削除することで、起動中に何が起こっているかわかりやすくなります。
  • systemd を使っていてユーザーにグループ (sys, disk, lp, network, video, audio, optical, storage, scanner, power, etc.) を設定する必要はほとんどありません。グループは機能を破壊することさえあります。例えば、audio グループは高速なユーザー切り替えやアプリケーションのソフトウェアミキシングを無効にします。全ての PAM ログインは logind セッションを提供します。オーディオ/ビデオデバイスに POSIX ACL を通して権限を与えたり、udisks を使ってリムーバルディスクのマウントなどの操作を行います。

Tips and tricks

インストールされたユニットをデフォルトで有効にする

Arch Linux の /usr/lib/systemd/system-preset/99-default.preset には disable * と記述されています。systemctl プリセットがデフォルトで全てのユニットを無効化するようになり、新しいパッケージがインストールされたときも、ユーザーが手動でユニットを有効化する必要があります。

自動的に有効化させたい場合、/etc/systemd/system-preset/99-default.preset から /dev/null にシンボリックリンクを作成して設定ファイルを上書きしてください。systemctl プリセットの設定ディレクトリで指定しないかぎり、インストールされた全てのユニットが有効化されるようになります。詳しくは systemd.preset の man ページを参照。

ノート: デフォルトで全てのユニットを有効化すると、パッケージに(互いに両立しない)複数のユニットが含まれている場合に問題が生じます。systemctl プリセットはディストリビューションやシステム管理者によって使われることを意図されて作られています。衝突するユニットが有効化されてしまう場合、systemd.preset の man ページに書かれているように、プリセットの設定ファイルを使ってどちらか片方を明示的に無効化させる必要があります。

アプリケーション環境のサンドボックス化

ユニットファイルをサンドボックスとして作成して堅牢な仮想環境にアプリケーションやプロセスを分離させることが可能です。systemd は名前空間ケイパビリティのホワイトリスト・ブラックリスト、Cgroups を活用して 実行環境を設定 しプロセスをコンテナ化します。

既存の systemd ユニットファイルを使ってアプリケーションをサンドボックス化するには strace, stderr, journalctl などでエラーや出力を確認しながら試行錯誤が必要です。まずは上流のドキュメントを検索して先例がないか確認すると良いでしょう。

CapabilityBoundingSet では許可されるケイパビリティのホワイトリストを定義できますが、特定のケイパビリティをブラックリストに追加する用途で使うこともできます。例: CapabilityBoundingSet=~ CAP_SYS_ADMIN

トラブルシューティング

systemd のエラーを調査する

例えば、systemd-modules-load サービスのエラーを調べるとします:

1. 起動に失敗している systemd サービスを探しましょう:

$ systemctl --failed
systemd-modules-load.service   loaded failed failed  Load Kernel Modules

2. Ok, systemd-modules-load サービスに問題が発生していることがわかりました。詳しく見てみましょう:

$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules
   Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
   Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
     Docs: man:systemd-modules-load.service(8).
           man:modules-load.d(5)
  Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)

Process ID が載っていない場合は、systemctl restart systemd-modules-load で失敗したサービスを再実行してください。

3. エラーを細かく調べるためのプロセス ID (PID) を入手しました。Process ID を使って (ここでは: 15630) 以下のコマンドを実行してください:

$ journalctl _PID=15630
-- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'blacklist usblp'
Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'install usblp /bin/false'

4. カーネルモジュールに間違った設定がなされているようです。よって /etc/modules-load.d/ 下の設定を見てみましょう:

$ ls -Al /etc/modules-load.d/
...
-rw-r--r--   1 root root    79  1. Dez 2012  blacklist.conf
-rw-r--r--   1 root root     1  2. Mär 14:30 encrypt.conf
-rw-r--r--   1 root root     3  5. Dez 2012  printing.conf
-rw-r--r--   1 root root     6 14. Jul 11:01 realtek.conf
-rw-r--r--   1 root root    65  2. Jun 23:01 virtualbox.conf
...

5. エラーメッセージ Failed to find module 'blacklist usblp' はおそらく blacklist.conf 内に間違った設定があることを示しています。手順 3 で見つけたオプションの前に # を挿入して無効化してみましょう:

/etc/modules-load.d/blacklist.conf
# blacklist usblp
# install usblp /bin/false

6. では、systemd-modules-load を起動してみることにします:

$ systemctl start systemd-modules-load

成功した場合、何も表示されないはずです。何かエラーが表示される場合は、手順 3 に戻って下さい。そして新しい PID を使って残った問題を解決してください。

全て問題ないならば、サービスが正しく起動したか次のコマンドで確認することができます:

$ systemctl status systemd-modules-load
systemd-modules-load.service - Load Kernel Modules
   Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
   Active: active (exited) since So 2013-08-25 12:22:31 CEST; 34s ago
     Docs: man:systemd-modules-load.service(8)
           man:modules-load.d(5)
 Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
Aug 25 12:22:31 mypc systemd[1]: Started Load Kernel Modules.

この種の問題は上のように解決できます。より詳しい調査をする場合は次のブート問題の診断を見て下さい。

ブート問題の診断

カーネルコマンドラインに次のパラメータをつけて起動してください: systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M

詳しくはブートデバッグ[3] を見て下さい。

特定のサービスの問題を診断

ある systemd サービスが上手く動作せず、どうなっているのか詳しい情報が欲しい場合、環境変数 SYSTEMD_LOG_LEVELdebug に設定してください。以下は systemd-networkd デーモンをデバッグモードで動かす例です:

# systemctl stop systemd-networkd
# SYSTEMD_LOG_LEVEL=debug /lib/systemd/systemd-networkd

もしくは同じようにサービスファイルを修正してください:

/lib/systemd/system/systemd-networkd.service
[Service]
...
Environment=SYSTEMD_LOG_LEVEL=debug
....

シャットダウン/再起動にものすごく時間がかかる

シャットダウンに非常に長い時間がかかる(もしくはフリーズする)場合、サービスが存在していないことが問題かもしれません。Systemd はサービスを kill する前に終了するのを待ちます。なにが原因か知るには この記事 を見て下さい。

短いプロセスがログを出力しない

journalctl -u foounit.service が短いプロセスについてなにも表示しない場合、かわりに PID を見て下さい。例えば、systemd-modules-load.service が失敗したとき、systemctl status systemd-modules-load によってそれが PID 123 として動いているとわかったら、その PID の journal の出力を見ることができます、journalctl -b _PID=123。journal の _SYSTEMD_UNIT_COMM などのメタデータは非同期に収集され /proc ディレクトリにプロセスが存在している時だけ表示されます。これを修正するには、SCM_CREDENTIALS のように、ソケット接続を使ってデータを流すようカーネルを変更する必要があります。

クラッシュしたアプリケーションのダンプのジャーナルを無効にする

/etc/systemd/coredump.conf ファイルを編集して次の行を追加してください:

Storage=none

そして設定をリロードしてください:

# systemctl daemon-reload

再起動やシャットダウン時のエラーメッセージ

cgroup : option or name mismatch, new: 0x0 "", old: 0x4 "systemd"

この警告は kernel/cgroup.c のカーネルコードから来ています:

       /* Don't allow flags or name to change at remount */
       if (((opts.flags ^ root->flags) & CGRP_ROOT_OPTION_MASK) ||
           (opts.name && strcmp(opts.name, root->name))) {
               pr_err("option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"\n",
                      opts.flags & CGRP_ROOT_OPTION_MASK, opts.name ?: "",
                      root->flags & CGRP_ROOT_OPTION_MASK, root->name);
               ret = -EINVAL;
               goto out_unlock;
       }

つまり、何かが cgroups を別の名前で再マウントしようとしてカーネルがそれに抵抗しているというわけです。ローカルの設定ファイルのエラーではなく、エラーメッセージ以外には何も症状が現れません。これが systemd のバグなのか、Arch の systemd パッケージに問題があるのかは判っていません [4]。2014年11月現在、Arch の systemd パッケージにバグレポートは送られていないようです。

watchdog watchdog0: watchdog did not stop!

このスレッドを見て下さい。

少しづつ起動時間が長くなっている

systemd-analyze を使用して、以前と比べて起動時間が明らかに伸びていると複数のユーザーが報告しています。systemd-analyze blame を使って NetworkManager が起動するのに異常に長い時間かかるようになったという報告もあります。

問題の原因として /var/log/journal が巨大になりすぎている可能性があります。そのような場合、フォルダ内のファイルを全て削除して journal のファイルサイズをここに書かれているように制限するよう設定すれば解決します(できればファイルを削除する前に、どこかに一時的にバックアップしてください)。

起動時に systemd-tmpfiles-setup.service の実行に失敗する

systemd 219 から、/usr/lib/tmpfiles.d/systemd.conf/var/log/journal 下のディレクトリに対して ACL 属性を指定しており、それによって、ジャーナルが存在するファイルシステムで ACL のサポートを有効にしなくてはならなくなっています。

/var/log/journal が存在するファイルシステムで ACL を有効化する方法はアクセス制御リスト#ACL の有効化を見て下さい。

systemctl enable で /etc/systemd/system にシンボリックリンクが作成されない

/etc/systemd/system/foo.service がシンボリックリンクの場合、systemctl enable foo.service を実行しても以下のエラーで失敗します:

Failed to issue method call: No such file or directory

これは systemd の 仕様 です。絶対パスで有効にすることで回避できます:

# systemctl enable /absolute/path/foo.service

参照