systemdはLinuxの起動時初期化処理(init)やサービスの管理を行うソフトウェア一式。
SysVinit(1988頃~) ⇒ Upstart(2006頃~) ⇒ systemd(2011頃~)
- サービス:systemdが起動したプロセスやプロセスのグループ。
- ユニット:1つのサービスとそれに関連する起動処理 (init) などをまとめたもので、以下をカプセル化している。
- システムサービス
- ソケットのリッスン
- init システムに関連するその他のオブジェクト
- systemdプロセス(/usr/lib/systemd/systemd)を開始
- /etc/systemd/system/default.target のシンボリックリンクを解決し、ターゲットを確認
- ターゲットに対して、依存関係/順序を持つサービスを自動で起動
//Ultra96V2 xlnx-6:/lib/systemd/system$ ls runlevel?.target runlevel0.target runlevel2.target runlevel4.target runlevel6.target runlevel1.target runlevel3.target runlevel5.target $ runlevel N 3 //uBuntu20.04 $ ls -l /usr/lib/systemd/system/runlevel?.target lrwxrwxrwx 1 root root 15 3月 2 21:58 /usr/lib/systemd/system/runlevel0.target -> poweroff.target lrwxrwxrwx 1 root root 13 3月 2 21:58 /usr/lib/systemd/system/runlevel1.target -> rescue.target lrwxrwxrwx 1 root root 17 3月 2 21:58 /usr/lib/systemd/system/runlevel2.target -> multi-user.target lrwxrwxrwx 1 root root 17 3月 2 21:58 /usr/lib/systemd/system/runlevel3.target -> multi-user.target lrwxrwxrwx 1 root root 17 3月 2 21:58 /usr/lib/systemd/system/runlevel4.target -> multi-user.target lrwxrwxrwx 1 root root 16 3月 2 21:58 /usr/lib/systemd/system/runlevel5.target -> graphical.target lrwxrwxrwx 1 root root 13 3月 2 21:58 /usr/lib/systemd/system/runlevel6.target -> reboot.target
ユニット
- ユニット:1つのサービスとそれに関連する起動処理 (init) などをまとめたもので、以下をカプセル化しています。
- システムサービス
- ソケットのリッスン
- init システムに関連するその他のオブジェクト
ユニットタイプ
タイプ | ファイル拡張子 | 説明 |
サービスユニット | .service | これが実行の主となるUnit。(=systemdが起動するプロセス) プロセスを起動・停止するUnit。 指定のバイナリを実行する(主にはデーモンの起動に使用する) .serviceのlifetimeはプロセスのlifetimeと同じ。 .serviceは.scopeや.sliceをカプセル化する事はできるが、運用上やらない。 .serviceは意味合い的に合うプロセスに紐付けるべき。 設定ファイルで定義 Unit記述 シェルコマンド実行のExecXxxがある |
ターゲットユニット | .target | “target”とは、システムが特定の状態に到達することを目指す(”target”を目指す)という意味 複数のUnitを列挙しておくと、それらのUnitが起動される。 target内には、Execディレクティブを含めれるが、実行可能コマンドを直接含むものではない。 設定ファイルで定義 Unit記述 |
自動マウントユニット | .automount | ファイルシステムの自動マウントポイントを定義する オートマウント処理を実施する(automountdの代替的な機能) |
マウントユニット | .mount | 指定のファイルシステムのマウントをする /etc/fsttabから自動生成 |
デバイスユニット | .device | カーネルが認識するデバイスファイル udevから通知されたデバイスを表す udevから自動生成 |
パスユニット | .path | 指定のファイルが作成されると、指定されたサービスを起動する |
スコープユニット | .scope | プロセスをグループ化する。 他のUnitをグループ化しない プロセス自体を生成しない。 .scopeは、dbus APIを使って生成される。 .scopeのlifetimeはグループ化したうちの全てが消えたら消滅する。 |
スライスユニット | .slice | .sliceは、.serviceや.scopeや他の.sliceをグループ化する。 プロセスを実行しない。 システムプロセスを管理する Unit記述 |
ソケットユニット | .socket | systemdがプロセス間の特定の通信ソケットをListen(監視)して、接続があるとプロセスに受け渡す(xinetdの代替的な機能) [Socket]セクションで検知してシェルコマンド実行 ListenStream=%t/bus ExecStartPost=-/bin/systemctl –user set-environment DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus |
スワップユニット | .swap | スワップ領域を有効にする /etc/fsttabから自動生成 |
タイマーユニット | .timer | 対応するserviceユニットの実行を管理する。cron の代替機能。 |
実行順序
systemdの実行順序
1. systemdプロセス開始(initプロセスでない)
2. default.targetユニットを実行(/etc/systemd/system以下のsymリンク)
3. リンク先のtargetを解析して、デフォルトターゲットを起動する。(/etc/systemd/system/graphical.targetやmuti-user.targetなど)
4. 解析結果により、必要なサービスを起動する(依存関係順に従いながら並列に)
SysVinit、Upstart、systemd違い
- SysVinit
- /etc/inittabに記述されたプロセスを順に起動
- システム初期化スクリプト/etc/rc.d/rc.sysinitを実行 ルートFSマウント等
- rcスクリプト/etc/rc.d/rcを実行 (/etc/init.d/<service> start)
- その他の定義、設定や、特定ランレベルの場合の処理
- /sbin/initがSysVinitの本体
- Upstart — SysVinitとの違いはイベント駆動型並列実行で短時間起動。 /etc/inittabは存在しない.
- /sbin/initがSysVinitの本体
- /etc/event.d か/ec/initにジョブ定義がある
- systemd
- /sbin/systemdがsystemdの本体
- 定義ファイル /etc/systemd/system/ (優先)or /usr/lib/systemd/system/
- Unitには
- 依存関係 A Unitを有効化するなら、B Unitも有効化する
- [Unit]セクション
- Wnats=、Requires=、Conflicts= オプション
- 「<Unit名>.wants」、「<Unit名>.requires」ディレクトリ内にUnitの設定ファイルへのシンボリックリンクを作成する
- Requiresは前提Unitの起動に失敗すると、元のUnitの起動を取りやめる。
- 順序関係 A Unitを有効化する前/後に、B Unitを有効化する。 [Unit]セクション。
- After=xxx.target yyy.target zzz.target
- 依存関係 A Unitを有効化するなら、B Unitも有効化する
- systemdが起動すると、/etc/systemd/system/default.target Unitが有効化されて、依存するUnitが有効化する。
- graphical.target runlevel5で起動するサービス
- multi-user.target runlevel3で起動するサービス
- rescue.target runlevel1で起動するサービス
- basic.target runlevelに依存せず起動するサービス
- sysinit.target rc.sysinitと同じ処理
- local-fs.target ファイルシステムのマウント処理
- swap.target swap領域の有効化
- デバイスの自動的に前提となるUnit
- bloetooth.target, printer.target, smartcard.target, sound.target
Unitファイル
- セクション
- オプションは全て『=』で値を設定する
- [Unit]:Unitの依存、順序関係
- 【オプション】
- Description:Unit説明
- Documentation:ドキュメントのURI
- Requires/Wants:このUnitと同時有効化が必要な前提Unit
- After::このユニットの先に起動するUnitを記述
- Before:このユニットの後に起動するUnitを記述
- ConditionPathIsDirectory
- AllowIsolate:yes/no
- 複数指定時は、半角スペースか行を変えてオプションから繰り返す
- [Install]:『systemctl enable/disable』コマンドに関する設定
- 【オプション】
- WantedBy:enable時にこのUnitの.Wantsディレクトリにシンボリックリンクを作成。
- RequiredBy:enable時にこのUnitの.Requiredディレクトリにシンボリックリンクを作成
- Also:このUnitがenable/disableされた時に同時にenable/disableするUnitを記述
- Alias:enable時に、このUnitの別名を設定(symリンクが作られる)
- Exec、ExecStart、Exec… :[Service]セクション参照
- [Service]:serviceタイプに固有の設定
- 【オプション】
- ExecStart:サービス起動時の実行コマンド(ExecXxxはイベントのようなもの)
- ExecReload:サービスリロード時の実行コマンド
- ExcecStop:サービス停止時の実行コマンド
- ExecStartPre/ExecStartPost:サービス起動前後実行のコマンド
- EnvironmentFile:環境変数を読み込むファイル
- KellMode:ExecStopで停止せずに残ったグループ内のプロセスの処理方法
- KillmMode=none:そのまま放置
- KillMode=process:メインプロセスが残っている場合は、SIGTERM/SIGKILLで停止。 その他の残プロセスは放置。
- KillMode=control-group:グループ内の全残プロセスをSIGTERM/SIGKILLで停止。
- Type:サービスプロセスの起動完了の判定方法。 (初期値:simple)
- Type=simple(推奨):指定コマンドがフォアグラウンドで実行を継続する場合。 コマンドを実行したら起動完了と判定する。
- Type=forking(非推奨):子プロセスをバックグラウンドで起動して、最初のコマンドは終了する場合。 最初のコマンドが終了したら起動完了と判定する。
- Type=oneshot:一度だけコマンドを実行するサービスの場合。 コマンドが終了したら起動完了と判定して、同時にサービスも終了下と認識する。(「RemainAfterExit=yes」を指定すると、コマンド終了後もサービスは起動したままと判定する。)
- Type=notify(推奨):systemdのライブラリ関数sd_notify()を使用する場合。 プロセスのプログラム内で、sd_notify()関数で起動完了を通知する必要あり。
- Type=dbus:D-Bus(プロセス間通信用(IPC:Inter Process Communication)メッセージバス)を利用するサービスの場合。BusNameで指定した接続名がD-Busに登録されると、サービス起動完了と判定する。
- PIDFile:fork型サービスのメインプロセス追跡用のPIDファイル
- BusName:D-Bus型サービスのbus接続名
- Restart:サービスプロセス異常終了時の再起動設定
- Restart=no:(初期値)
- Restart=always
- StartLimitInterval=10s:(初期値)
- StartLimitBurst=5:(初期値)
- PrivateTmp:このサービス専用の/tmpと/var/tmpを容易する
- ReadOnlyDirectories:指定のディレクトリ以下をReadOnlyにする
- InaccessibleDirectories:指定のディレクトリ以下をアクセス不可にする
- RootDirectory:指定のディレクトリをchrootする
- MemoryMax=1G
- slice:
- [slice]
- -.sliceはルートスライス
各Unitの定義ファイルに以下を書くと、muti-user.targetが起動すると、そのUnitも一緒に並列起動するようになる。 systemctl enableで自動起動するように設定しておく必要がある。 multi-user.targetで他のUnitを起動する場合は、『Wants=ユニット名』。
[Install] WantedBy=multi-user.target
cgroup確認
コントロールグループ
$ cat /proc/self/cgroup //現在のシェルのcgroup一覧 /proc/PID/cgroupで見れる $ systemd-cgtop //リソース使用量一覧 /etc/cgconfig.conf // このファイルでグループを定義できる
systemd関連コマンド
ターゲットに依存しているサービス一覧表示
$ pstree // process tree確認 systemdが大元であることがわかる。 $ systemctl cat sshd.service // 普通のcatの場合はフルパス指定。 これでファイルに書かれている内容確認。 $ systemctl show sshd.service // ファイルに書かれていない全てのProperty値も確認できる。 $ systemctl list-dependencies multi-user.target // Unit名を指定しなければTree形式で全ての依存を一覧できる $ systemctl list-dependencies <Unit名> // <Unit名>省略時はdefault.target $ systemctl list-dependencies <Unit名> --after $ systemctl list-dependencies <Unit名> --before $ systemctl list-unit-files --type=service //static WantedBy=指定なし。 $ systemctl list-unit-files -t service | grep enabled $ systemctl list-unit-files -t service | grep disabled $ sudo systemctl enable sshd.service // OS起動時に自動起動するよう設定 $ sudo systemctl start application.service // .service開始 $ sudo systemctl kill -s9 sshd.service // service 関連を全て停止 $ systemctl set-property user.slice IPAddressDeny=any //propertyを設定 $ systemd-cgls // Cgroupごと分けて表示 .serviceが実行したコマンドも表示 $ systemd-cgtop // Cgroupごとのリソース使用状況をリアルタイムに表示 $ systemd-analyze // 起動時間や起動順序が確認できる。 sudo dnf install systemd-analyze Startup finished in 5.483s (firmware) + 4.044s (loader) + 1.658s (kernel) + 6.310s (userspace) = 17.496s $ systemd-analyze blame // 各Unit起動時間表示 $ systemd-analyze critical-chain // 重要なUnitの起動順番(Chain)で表示(便利) $ systemd-analyze plot > systemd-analyze-plot.svg // 起動にかかった全てのUnitの時間などが下のようにグラフィカルに見れる。(超便利).svgのファイル名は何でもOK。 $ systemd-analyze dump $ sudo journalctl -xeu nfs-server.service | tail -30 // .serviceのログ表示 左の例は最後の30行表示
- systemctlコマンド
- status:Unitの状態表示
- start:Unitスタート
- stop:Unit停止
- restart:Unit再起動
- enable:システム起動時にUnitは自動スタート
- disable:システム起動時にUnitはスタートしない
- cat:Unit設定ファイル内容を表示
- get-default:デフォルトtarget表示
- isolate:Unitと依存するUnitをスタートし他のUnitはストップする。 現在のtarget変更時に使用
- list-units:activeなunitをすべて表示表示する。このコマンドがデフォルト。
- list-unit-files:インストールされているunitをすべて表示
- list-dependencies:Unitに依存しているサービス一覧表示(.targetの依存確認によく使う)
- reload, reload-or-restart
- is-active, is-enabled, is-failed:ユニットの状態を表示
- reboot, poweroff, set-default, get-default
- systemctlオプション
- -a, –all:停止中のUnitも全て表示
- -l, –full:Unit名等も省略せず表示
- -t, –type=:Unitタイプを指定して表示。 (複数指定 -t target, -t service)
- -no-pager:長いメッセージの場合、ページ待ち表示となるのをやめる。
systemd ログ
- Unitとして起動したdaemonプロセスの標準出力とrsyslogdへの出力をjournald(またはsystemd-journald.service)に送ります。
- journaldは/var/log/journal/にバイナリ形式で記録します。
- journalctlで表示
- -u <unit name> :指定したUnit関係のログ表示
- –since=”YYY-MM-DD hh:mm:ss” 以降のログ表示
- –unitl=
- -b:直前のサーバー起動以降のログ表示
- -f:新規のログを待って順次表示
- –no-pager
- -a:長いメッセージを省略しない
systemd確認方法
- systemdがPID 1として起動しているか確認
- 更に、/sbin/initがsystemdにsymlinkされていたら、完全にsystemd
xlnx-6: /run/systemd/generator$ ps -e|head -2 PID TTY TIME CMD 1 ? 00:00:13 systemd xlnx-6: /run/systemd/generator$ ls -la /sbin/init/home/peta/conf/my_bluetooth.sh lrwxrwxrwx 1 root root 22 Mar 9 2018 /sbin/init -> ../lib/systemd/systemd
Directories
ディストリビューションにより異なる。 default.targetは以下の場所にある。
- /lib/systemd/system/default.target —– linux-xlnx, uBuntu
- /etc/systemd/system/default.target
- /usr/lib/systemd/system/default.target
- uBuntu —– /usr/elc/lib/systemd/system/
- linux-xlnx —- /lib/systemd/system/
Unit定義ファイル
/usr/lib/systemd/system/
以下の設定ファイルを変更する際は、一旦、/etc/systemd/system/以下にコピーしてから変更するようにします。
- /usr/lib
- /systemd/user
- default.target
- basic.target
- bluetooth.target
- /sysctl.d
- 50-default.conf
- 50-pid-max.conf
- /sysusers.d
- basic.conf
- dbus.conf
- systemd-journal.conf
- systemd-network.conf
- systemd-resolve.conf
- systemd-timesync.conf
- /systemd/user
D-Bus
D-Bus は1台のコンピュータ上で動作する複数のプログラムの間で情報を交換するシステム(IPC:Inter Process Communication)。 パイプ、名前付きパイプ、シグナル、共有メモリ、Unix ソケット、ループバックソケット等のIPCを「OS や言語に依存しない」「柔軟で汎用性が高い」様に、freedesktop.orgで統一された。D-Busはメッセージをオブジェクト(或いはオブジェクトの機能)に届ける仕組み。
メッセージは、METHOD_CALL, METHOD_RETURN, ERROR, ,SIGNALの4つ。 METHOD_CALL, METHOD_RETURNは対で使われ、SIGNALは片道の一斉通知(デバイス検出、ネットワークエラー等)で使用できる。
ここが凄く纏まっているので参考にするのがいい。『D-Bus のはなし』
D-Busサーバに接続バス名一覧表示依頼
- サーバーに対して、–dest=org.freedesktop.DBusのルート階層/指定で
- org.freedesktop.DBus.ListNamesのMethodを送る。
dbus-send --print-reply --system --dest=org.freedesktop.DBus / --type=method_call org.freedesktop.DBus.ListNames
接続
Bus名(=サービス名=コネクション名等とも言われる)
[Service] Type=dbus BusName=fi.w1.wpa_supplicant1
メッセージの前半部分をインターフェース名と呼ぶ。 インターフェース名は慣習的に開発元のドメイン名+グループ名で構成されることが多い。
階層確認
Introspect Methodで、下の例ではorg.bluezサービスの、/org階層に問い合わせている。 ls /orgの様なもの。その階層に存在する<node>, <interface>, <method>, <arg> を確認できる。
dbus-send --print-reply --system --dest=org.bluez /org --type=method_call org.freedesktop.DBus.Introspectable.Introspect
Property
名前と値にセットで
D-Busプログラミング
プログラム用のdbusライブラリが用意されている。Pythonでhci0の電源をONにする場合は以下の様になる。 dbus-sendと同じ。 C言語ライブラリはlibdbus-1だが配列等の値の処理は非常に煩雑。
#!/usr/bin/python import sys import dbus bus = dbus.SystemBus() obj = bus.get_object('org.bluez', '/org/bluez/hci0'); interface = dbus.Interface(obj, 'org.freedesktop.DBus.Properties'); b = dbus.Boolean(1); interface.Set('org.bluez.Adapter1', 'Powered', b);
自作サービス作成
- システム起動時にシェルスクリプトを実行させたい場合等。
- /etc/systemd/systemに、
- サービス名.seivice拡張子ファイルを作り、
- 設定する
その他
コメント
『#』1行コメント。 行の先頭。
wifiの自動実行
- Ultra96V2のwifiiを起動時に実行するように変更してみました。
- 12行目をコメントアウトして13, 14行目を記述しています。
- %Iは外部から引数として取り込むみたいです。
- sys-subsystem-net-devices-%i.deviceが読み込まれたら、このwpa_supplicant-nl80211@.serviceが読み込まれます。
- PetaLinuxビルドやり直しで初期化されてしまうので、backupを取る事。
[Unit] Description=WPA supplicant daemon (interface- and nl80211 driver-specific version) Requires=sys-subsystem-net-devices-%i.device After=sys-subsystem-net-devices-%i.device Before=network.target Wants=network.target # NetworkManager users will probably want the dbus version instead. [Service] Type=simple #ExecStart=/usr/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-nl80211-%I.conf -Dnl80211 -i%I ExecStart=/usr/sbin/wpa_supplicant -c/etc/wilc_wpa_supplicant.conf -Dnl80211 -i%I ExecStartPost=sudo udhcpc -i %I ExecStartPost=echo *************** %i*************** %I ************ [Install] WantedBy=multi-user.target
enable化して、起動時自動的に起動するようにしておこう。
$ sudo systemctl enable wpa_supplicant-nl80211@wlan0.service Password: Created symlink /etc/systemd/system/multi-user.target.wants/wpa_supplicant-nl80211@wlan0.service -> /lib/systemd/system/wpa_supplicant-nl80211@.service.
Rebootして確かめたら、.serviceは立ち上がっていて、IPアドレスも取得していた。
$ systemctl status wpa_supplicant-nl80211@wlan0.service * wpa_supplicant-nl80211@wlan0.service - WPA supplicant daemon (interface- and nl80211 driver-specific version) Loaded: loaded (8;;file://xlnx-6.1/lib/systemd/system/wpa_supplicant-nl80211@.service/lib/systemd/system/wpa_supplicant-nl80211@.service8;;; enabled; preset: disabled) Active: active (running) since Fri 2023-06-23 05:09:22 UTC; 6min ago Process: 541 ExecStartPost=sudo udhcpc -i wlan0 (code=exited, status=0/SUCCESS) Main PID: 540 (wpa_supplicant) Tasks: 2 (limit: 1145) Memory: 12.6M CGroup: /system.slice/system-wpa_supplicant\x2dnl80211.slice/wpa_supplicant-nl80211@wlan0.service |-540 /usr/sbin/wpa_supplicant -c/etc/wilc_wpa_supplicant.conf -Dnl80211 -iwlan0 `-582 udhcpc -i wlan0
.confファイルは以下の様な感じです。 WPA2-PSK AES
ctrl_interface=/var/run/wpa_supplicant update_config=1 ap_scan=1 country=JP network={ ssid="Buffalo-G-CFC0" key_mgmt=WPA-PSK pairwise=CCMP group=CCMP #psk="kvjxxxxn7igkm" psk=9d4c...........................fde9b3f44 }
wpa_supplicant.service
wpa_supplicantのserviceは色々あるけど、wpa_supplicant-nl80211@.serviceがnl80211を必ず使い、@の後にデバイス名を入れると%I内部でとして取り込んでくれるのでUltra96V2の場合はwlan0を付けて使うようにします。
- wpa_supplicant.service – uses D-Bus, recommended for NetworkManager users.
- wpa_supplicant@.service – accepts the interface name as an argument and starts the wpa_supplicant daemon for this interface. It reads a /etc/wpa_supplicant/wpa_supplicant-interface.conf configuration file.
- wpa_supplicant-nl80211@.service – also interface specific, but explicitly forces the nl80211 driver (see below). The configuration file path is /etc/wpa_supplicant/wpa_supplicant-nl80211-interface.conf.
- wpa_supplicant-wired@.service – also interface specific, uses the wired driver. The configuration file path is /etc/wpa_supplicant/wpa_supplicant-wired-interface.conf.
Failedとなった時
nfs-server.serviceがfailedとなった時
$ sudo journalctl -xeu nfs-server.service //ログ確認。 しかしminicomではキレイに表示されないので、下の様にtxtにしてから表示がいい。 $ sudo journalctl -xeu nfs-server.service > a.txt // しかし以下が一番簡単 $ sudo journalctl -xeu nfs-server.service | tail -30
nfs-server.serviceを見ると、wpa_supplicant-nl80211@.serviceより前に呼ばれるのか後に呼ばれるのかわからず、念の為以下を付け足した。(PetaLinuxビルドやり直しで初期化されてしまうので、backupを取る事。)
[Unit] Description=NFS server and services DefaultDependencies=no Requires=network.target proc-fs-nfsd.mount Requires=nfs-mountd.service Wants=rpcbind.service After=local-fs.target After=network.target proc-fs-nfsd.mount rpcbind.service nfs-mountd.service After=wpa_supplicant-nl80211@.service //<-----追加 ConditionPathExists=/etc/exports
これしか表示されず何でFAILUREになったかわからない。
Jun 23 06:12:46 xlnx-6.1 systemd[1]: nfsserver.service: Control process exited, code=exited, status=1/FAILURE
ConditionPathExists=/etc/exports was not met とあるのでnfs-server.serviceを調べてみる。
$ systemctl status nfs-server.service * nfs-server.service - NFS server and services Loaded: loaded (8;;file://xlnx-6.1/lib/systemd/system/nfs-server.service/lib/systemd/system/nfs-server.service8;;; enabled; preset: enabled) Active: inactive (dead) Condition: start condition failed at Fri 2023-06-23 06:04:10 UTC; 20min ago `- ConditionPathExists=/etc/exports was not met
/etc/exportsはnfsサーバーとしてのnfsサーバー用のルートディレクトリの指定とアクセスの設定を記述する設定ファイルなので、このファイルが空だったので以下を書き込んだ。(PetaLinuxビルドやり直しでも残っていた)
/home/petalinux/nfs_svr_dir *(rw,async,no_subtree_check,no_root_squash,nohide,insecure)
動作しました。
xlnx-6: ~ $ systemctl status nfs-server.service * nfs-server.service - NFS server and services Loaded: loaded (8;;file://xlnx-6.1/lib/systemd/system/nfs-server.service/lib/systemd/system/nfs-server.service8;;; enabled; preset: enabled) Active: active (exited) since Fri 2023-06-23 07:06:16 UTC; 8s ago Process: 644 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS) Process: 645 ExecStart=/usr/sbin/rpc.nfsd $NFSD_OPTS $NFSD_COUNT (code=exited, status=0/SUCCESS) Main PID: 645 (code=exited, status=0/SUCCESS)
ちゃんと、wpa_supplicant-nl80211@wlan0.serviceが終わって、wpa_supplicant-nl80211@wlan0.serviceでbeforeと書かれている,network.targetが終わってから、nfs-server.serviceが始まっています。
*最初ディレクトリをフルパスでなく、~/nfs_svr_dirとしていましたが、エラーになり、systemctl status nfs-serrver.service では原因がわからず、$ sudo journalctl -xeu nfs-server.service –no-pager | tail -30 にすると、以下のメッセージがありました。 sudoでsystemctl startしているので、/root/nfs_srv_dirを探しに行っているのかもと思い、上記のように書き直したら動作しました。 上の場合は、sysテmctl statusで原因が分かりましたが、今回はjournalctlで原因が分かりました。 原因を見つけるには両方有効ですね。
コメント