systemdが Failed to dissect: Input/output error って吐く
----- [2018/06/14 追記] -----
ArchWikiのGPD Pocketのページをよく見たら、ちゃんと載ってた。
ブートローダの設定をすればいいらしい。 さすがArchWiki、なんでも載っている…ッ!!
----- [追記ここまで] -----
systemctlを使ってserviceを enable/disable すると、enable/disable 自体はちゃんと成功しているんだけど、なんか見慣れないエラーが表示されてしまう。
$ sudo systemctl enable lightdm.service Created symlink /etc/systemd/system/display-manager.service -> /usr/lib/systemd/system/lightdm.service. [46494.337569] systemd-gpt-auto-generator[26889]: Failed to dissect: Input/output error
みたいな感じ。
結論からいうと、これはsystemd側の問題みたいで、すでにmasterに修正がmergeされている。 最新のv238にはまだこの修正は入っていないので、多分次の v239 になれば直ると思う。
- Issue: https://github.com/systemd/systemd/issues/5806
- PR: https://github.com/systemd/systemd/pull/8609
enable/disable自体は動いているし(symlinkはちゃんと生成/破棄される)、ディスクのマウントもfstabの情報で問題なくできていて、現状はこれによって何か問題が起きてる、という感じはない。
ので、とりあえず最新パッケージを待つので良さそう(Archであれば、AURのsytemd-git を使うって方法もありそうだけど、僕は待つことにした)。
修正済みだしどうせ待ってれば直るんだけど、せっかくググったりなんだりしたので、調べたことを自分用にメモしておく。 正直ほとんど理解できてないので、もしちゃんと知りたい場合は、IssueとPRを読みましょう…僕は何もわからん…何も…
発生する環境
- eMMCモデルのマシン
- systemd のversionが v238 以前
- blkidがインストールされている
僕の場合はGPD Pocket にArchを入れたところで、この問題に遭遇した。 GPD PocketはeMMCを採用していて、2018/06/10時点でのArchのcoreリポジトリのsystemdはv238。
systemdのバージョンは、次のコマンドで調べられる。
$ systemd-cat --version systemd 238 +PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN +PCRE2 default-hierarchy=hybrid
発生原因
systemd-gpt-auto-generator がパーティションを検出するときに、eMMCのbootエリアとRPMBエリアまで余計に検出してしまい、それがエラーに繋がっている(らしい)。
ちなみに、systemd-gpt-auto-generatorは、システムのパーティションを自動的に検出・マウントしてくれるソフトウェア(らしい)。 ただ、どうしてenalbe/disableするときもこいつが動いているのかはよく分からなかった。
eMMCは通常のユーザーデータ領域の他に、bootエリア2つとRPMB(Replay Protected Memory Block)エリアをもっている。 eMMCのディスクをマウントしてるシステムでlsblkすると、
$ lsbkl -o name,type NAME TYPE mmcblk0boot0 disk # Boot Area Partition 1 mmcblk0boot1 disk # Boot Area Partition 2 mmcblk0rpmb disk # RPMB Area mmcblk0 disk # User Data Area ├─mmcblk0p1 part # Partition 1 ├─mmcblk0p2 part # Partition 2 └─mmcblk0p3 part # Partition 3
といった形で表示される。
mmcblk0boot*
というのがbootエリアで、mmcblk0rpmb
がRPMBエリア。
(ただ、なぜか今の僕のGPD-Pocketはmmcblk0rpmbが表示されない。Ubuntuだった頃は確かにあったんだけど…)
systemd-gpt-auto-generatorは内部でkernelが列挙するパーティションとblkidが列挙するパーティションの数を突き合わせている(ここらへん)。
このときに、blkidはユーザーデータのパーティションのみを列挙するのに対し、kernelはブロックデバイスをすべて列挙してしまう。 kernelが列挙してきたeMMCのbootエリア、RPMBエリアも合わせてカウントしてしまうため、bootエリア・rpmbエリアの数だけパーティション数にズレが生じ、件のエラーが吐かれていた。
修正PRでは、kernelが列挙したディスクに対して、eMMCのbootエリア・RPMBエリアを無視する対応が入っている。
return (sysname && startswith(sysname, "mmcblk") && (endswith(sysname, "rpmb") || endswith(sysname, "boot0") || endswith(sysname, "boot1")));
今までeMMCは、なんとなくスマホやタブレットに使われてるってイメージが強かったんだけど、小型PCだと普通に載るようになってきたし、chrome-bookもeMMCモデルが多いみたい。 そういえばeMMC上にlinuxディストロをインストールしたのは初めてな気がする、以前Chromebookでarchを使ったときは、sdカードから起動してたし。
RPMBについても色々調べてみたんだけど、「大体わかった」と「いまいち理解しきれない」の中間くらいの感覚で、うまくまとめられなかった。
参考
- GitHub - systemd/systemd: ⚙️ 🐧 systemd System and Service Manager
- systemd-gpt-auto-generator: Failed to dissect: Input/output error (boot/rpmb context) · Issue #5806 · systemd/systemd · GitHub
- man of systemd-gpt-auto-generator
- Comparison between ATA and eMMC Devices - ADTEC Corporation
- 記憶装置および書き込み装置 - ekouhou.net
- rpmb対策 - 残業プログラマの雑記
- Intel Celeron N2806のeMMC(RPMB) | @knok blog
- Introduction to eMMC
- MMC – Gateworks