Raspbian を含めた Linux、Unix 系 OS の場合、デバイス名(/dev/mmcblk0p1 とか /dev/sda2 とかいうやつ)は、システムが、つながれていることを認識した順序で規則に基づいて自動的に割り振るので、起動時につながれている機器構成が変わると、デバイス名も変わってしまいます。これによって、システムが起動しなくなったりするトラブルは広く知られていて、また、そういったトラブルを避ける設定ファイルの書き方なども、広く提唱されています。
Raspbian の場合も、現行の Strech バージョンになってから、以下の箇所でデフォルトの指定方法が変更になっていました。
- /boot/cmdline.txt 内の root= の指定
- /etc/fstab 内の第 1 フィールド(fs spec)
どちらも、PARTUUID を使った指定になっています。PARTUUID っていうのは、本来は GPT パーティションテーブルを持ったブロックデバイス(USB メモリやハードディスクなど)のパーティションに割り振られる ID ですが、従来からの MBR パーティションテーブルを使ったブロックデバイスでも擬似的に生成されるので、使えます。
これ、意図的に変更したりデバイス間でコピーしたりもできるのですが、基本的には一意に割り振られる ID なので、デバイスの指定にこれを使っておけば、システム上の機器構成が変わることにより起動しなくなるようなトラブルを避けることができます。
良いことばかりではない …
これで全てがうまくいくのかというと、新たな問題もあります。
PARTUUID っていうのは、ファイルシステムを作り直す、つまり、パーティションをフォーマットすると、変わります。当然ながら、故障して、物理的なデバイスを交換したような場合にも、変わります。先にも申し上げたとおり、PARTUUID 自体は変更できるし、バックアップの作成と復元に dd コマンドを使うような場合には、ディスク内に書き込まれている PARTUUID ごと記録・回復されるので、そのまま使うことはできます。また、たとえ PARTUUID が変わるようなことがあっても、基本的には、先の 2 箇所、/boot/cmdline.txt と /etc/fstab を変更すれば済む話なので、通常の使用環境においては、こちらを使った方がメリットが多いという判断もあるのでしょう。
ただ、テスト環境などで、本来、一意であるべき PARTUUID を複製していると、逆に思わぬところでトラブルになりかねないですし、テスト環境構築などのために頻繁に dd で micro SD カードに書き込んでいたりすると、micro SD カードのダメージが大きいし、時間もかかります。テスト以外の運用においても、dd でのバックアップ・復元というのは、バックアップ元と先のわずかな容量の違いなどで、回復できないようなこともあります。
というわけで、やっぱり、バックアップや回復には、tar や dump・restore の方を使いたい。物理的なデバイスを交換したり、パーティションのサイズ変更といった作業を行っても、そのまま使えるようにしたい。
そう、/dev にあるデバイス名を使った指定というのは、実媒体を隠蔽して仮想化しているところにメリットがあると思うのです。
というわけで USB ポートの認識順序調査です
前置きが長くなっていますが、/etc/fstab の方は、PARTLABEL なんていう指定方法も可能になっていて、バックアップからの回復後の書き換えを避けることができます。残るのは、/boot/cmdline.txt の方です。ここに指定するのは、ルートファイルシステムになるデバイスだけです。逆に言えば、ルートファイルシステムになるデバイスさえ、機器の構成変更の影響を受けないポートに接続しておけば、/dev の中のデバイス名の指定でも、問題が出ないはずです。というわけで、USB ポートが、実際にどういう順序で認識されるのか、調査してみました。最も優先されるポートにルートファイルシステム用のデバイスを接続しておけば、他のポートで別のデバイスを付けたり外したりしても、ルートファイルシステムのデバイスは /dev/sda で変わらないハズです。もちろん、実際のファイルシステムは /dev/sda1 とか /dev/sda2 … になりますが、パーティション番号はつなぎ変えても変わらないですから、永続的に使えるはずです。
調査方法
Raspberry Pi Model 3B+ の場合、4 つの USB ポートがあるわけですが、ここ全てに USB メモリーをつなげておいて、どこがどういったデバイス名になるか調べます。呼び方は、向かって見た位置に統一します。
USB メモリーを 4 本用意して、どれだかわからなくならないように、とりあえず、マスキングテープを貼って、「右上」「右下」「左上」「左下」と書いておきました。
OS から見てどれがどれだか判るように、それぞれの USB メモリーにボリュームラベルを付けました。この作業は Windows から行いました。
それぞれを、それぞれの USB ポートに接続するわけですが、ポートの間隔の問題で、直接は挿せなかったので、延長ケーブルを使いました。なんか、家の中から短めの延長ケーブルをかき集めてきたので、物が揃っていないのは、ご勘弁を。長さはどれも 1m 以内くらいの短いものです。キーボードとマウスは、Bluetooth 接続のものを使いました。
とりあえず、本体基板に Raspbian のインストールされた micro SD カードを挿して、起動してみました。ターミナルより、以下のようにコマンドを入力しました。
pi@raspberrypi-000:~/Desktop/work $ lsblk -o name,label
結果です。
NAME LABEL
sda
└─sda1 LOWER-RIGHT
sdb
└─sdb1 UPPER-LEFT
sdc
└─sdc1 UPPER-RIGHT
sdd
└─sdd1 LOWER-LEFT
mmcblk0
├─mmcblk0p1 boot
└─mmcblk0p2 rootfs
ということで、順序としては、
- 右下
- 左上
- 右上
- 左下
となりました。マジか … なんか、並びがバラバラじゃん(笑)。
一応、何回かやってみましたが、再現性がありました。ただ、テストした個体においては、変わるようなことはなさそうでしたが、これが、設計によるものなのか、個体における特徴なのかは、ナゾです。できれば、他の個体でも、調査したかったのですが、テストに使える個体が 1 つしかないので、また、機会ができたらということにします。
ちなみに、micro SD カードを USB カードリーダーに挿して、USB ポートの方につなぐと、名前は mmcblk … ではなく sd … になります。デバイス名が変わったのに起動できるのは、PARTUUID で指定されているからですね。
NAME LABEL
sda
├─sda1 boot
└─sda2 rootfs
で、このシステムが入ったデバイスを、USB ポートの中に混在させたらどうなるかも、調べてみました。1 つずつ、挿し替えています。
右下
NAME LABEL
sda
├─sda1 boot
└─sda2 rootfs
sdb
└─sdb1 UPPER-LEFT
sdc
└─sdc1 UPPER-RIGHT
sdd
└─sdd1 LOWER-LEFT
左上
NAME LABEL
sda
└─sda1 LOWER-RIGHT
sdb
├─sdb1 boot
└─sdb2 rootfs
sdc
└─sdc1 UPPER-RIGHT
sdd
└─sdd1 LOWER-LEFT
右上
NAME LABEL
sda
└─sda1 LOWER-RIGHT
sdb
└─sdb1 UPPER-LEFT
sdc
├─sdc1 boot
└─sdc2 rootfs
sdd
└─sdd1 LOWER-LEFT
左下
NAME LABEL
sda
└─sda1 LOWER-RIGHT
sdb
└─sdb1 UPPER-LEFT
sdc
└─sdc1 UPPER-RIGHT
sdd
├─sdd1 boot
└─sdd2 rootfs
というわけで、起動デバイスの位置によって、デバイス名が変わってしまうことはありませんでした。
結論
USB ポートにルートファイルシステムに使うデバイスをつなぐときは、向かって右下のポートに挿しておけば安全と考えられます。ただし、個体差があるのかどうかは、不明です。
余談 …
実は、USB ポートからの起動の調査中に、起動しないことが何度かありました。何回かやっていると起動したので、全てのポートについて結果を出すことができました。最初、ポートによってタイミングの問題があるのかとも思ったのですが、どうも、Raspberry Pi の給電能力の問題っぽいです。USB メモリーとはいえ、4 本挿して電力消費のピークが重なると、Raspberry Pi にとっては、重荷みたいでした。USB メモリーが 3.0 対応の製品なのが影響しているかもしれませんし、起動時には書き込みも発生するからかもしれません。1 本だけ挿したときは、問題なく起動しますし、外部電源の USB ハブを噛ませた時も、確実に起動しました。ただ、間にハブを噛ませれば、当然ながら、デバイスの認識順序が変わり、結果、デバイス名も変わります。
コメント
コメントを投稿