ここ数年はLinuxデスクトップで生活しているが、たまにユーザー環境へログインできなくなることがあった。
症状
これまで何の問題もなく動いていたが、再起動した後に突然ログインできなくなる。gdm を使っているけれども、パスワード入力のあと何のエラーもなくパスワード再入力画面に戻る。このとき、パスワードを間違えると「認証に失敗しました」のようなエラーになるのでパスワードは合っていると思われる。
root ではログインできるので、ログインした後に systemd-journald のログをみると以下のような行が記録される。
$ journalctl --since=today systemd-homed[532]: lufia: changing state inactive → activating-for-acquire systemd-homework[2917]: Provided password unlocks user record. systemd-homework[2917]: Home directory /home/lufia exists, is not mounted but populated, refusing. systemd-homed[532]: Activation failed: Device or resource busy
systemd-homed では一般的に /home/$USER は空のディレクトリで、ログインしたとき各種ストレージ方式ごとに必要なファイルをホームディレクトリとしてマウントする。例えば /home/$USER.home (LUKSストレージの場合)や /home/$USER.homedir (ディレクトリ方式の場合)を /home/$USER にマウントすることになる。
なのでログインする時点では /home/$USER は空であるはずが、エラーメッセージには /home/lufia が空ではないのでマウントに失敗したとあり、実際に /home/lufia 以下には空のディレクトリが作られていた。この謎のファイルは消しても一定時間で復活する状態だった。
fsck -f
でディスクの検査をしても何もエラーは検出されない。
原因
以下の条件が揃えば同様の症状になる。
- systemd-homedでユーザーを管理している
- Dockerが動作している
- /home/$USER 以下のファイルをボリュームマウントしたdockerコンテナが再起動時に残っている
Dockerはボリュームマウントしたとき、ディレクトリがなければ作成する。Dockerコンテナ実行時は /home/$USER にホームディレクトリがマウントされているので問題なく参照できるが、Linuxを再起動したときはまだユーザーがログインしていないので空のディレクトリになっている。そこでDockerは残っているコンテナを復活させようとして、/home/$USER 以下にファイルを作ってしまう。そうすると、実際にログインしたときは /home/$USER 以下に(Dockerが作成した)ファイルが存在するため、マウントできずエラーになってしまう。
対処方法
この状況になった場合は、root などでログインしたあと以下の手順を実行する。
- Dockerに残っているボリュームマウントしているコンテナを止める
または
- docker.service を止める
- /home/$USER に残っているファイルを消す
- $USER でログインして docker.service を開始する
感想
Dockerも systemd-homed も、それぞれは意図した動作をしているだけなので、困りますね。