USBで接続されたSATAディスクが接続された状態でシステムが起動すると、Linuxは明らかにディスクのパーティションを認識しません。これにより、パーティション(およびファイルシステム)が表示されなくなり、パーティションを再スキャン(partprobe、blockdev --rereadptなど)したり、UASモジュールを再ロードしたり、ドライブを取り外して再挿入する必要があります。問題のディスクをESPとルートファイルシステムを含むブートデバイスとして使用したい場合は、実現できません。
いくつかの実験をしました。結果:
- ホストがオンラインでUASモジュールがロードされているディスクを挿入します。 ->働く
- ホストがオンラインでUASモジュールとusb_storageモジュールがロードされていない状態でディスクを挿入します。 ->働く
- ディスクを挿入したら、別のドライブからシステムを起動します - >失敗する
パーティションが検出されませんでした。安定化するのに十分な時間を与えた後、次のことが観察された。興味深いことに、UASモジュールとusb_storageモジュールがロードされ、/sys/class/block/sdaが存在しました。いいえそれをリストすると、/proc/partitionsもそうではありません。
- この状態でUASモジュールをアンロードして再ロードします - >働く(lsblkにリストされ、/dev/sda{1,2}が生成され、すべてが「正常」です。)
- また、この状態から始めて、blockdev --rereadpt ->を介してパーティションを再検索します。働く
- カーネルコマンドラインを介してUASモジュールをプリロードしたり、プリロードせずにテストを繰り返すと、同じ結果が表示されます。
- ディスクを挿入した後、同じディスクからシステムを起動しようとします - >失敗する(システムを起動できません。回復シェルに削除されました。)
- シェルに入れてみてください
blockdev --rereadpt
- >働く - カーネルコマンドラインを介してUASモジュールをプリロードしたり、プリロードせずにテストを繰り返すと、同じ結果が表示されます。
- シェルに入れてみてください
dmesg | grep sd
テストケース#3実行の出力(blockdev --rereadptが42秒で実行されます)ケース#4の出力は同じです。
[ 13.831953] sd 6:0:0:0: [sda] Read Capacity(10) failed: Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 13.831955] sd 6:0:0:0: [sda] Sense Key : Not Ready [current]
[ 13.831956] sd 6:0:0:0: [sda] Add. Sense: Logical unit is in process of becoming ready
[ 13.832435] sd 6:0:0:0: [sda] Test WP failed, assume Write Enabled
[ 13.832850] sd 6:0:0:0: [sda] Asking for cache data failed
[ 13.832853] sd 6:0:0:0: [sda] Assuming drive cache: write through
[ 15.038494] sd 6:0:0:0: [sda] Read Capacity(10) failed: Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 15.038497] sd 6:0:0:0: [sda] Sense Key : Not Ready [current]
[ 15.038498] sd 6:0:0:0: [sda] Add. Sense: Logical unit is in process of becoming ready
[ 15.039379] sd 6:0:0:0: [sda] Attached SCSI disk
[ 42.833001] sd 6:0:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/932 GiB)
[ 42.834148] sda: detected capacity change from 0 to 1000204886016
[ 42.956764] sda: sda1 sda2
どのようなヒントがありますか?デバイスの起動と準備に時間がかかり(メッセージ内Logical unit is in process of becoming ready
)、デバイスが準備されていない場合、エラーが発生した場合、または誤ったデータを取得した場合は、パーティション検索が発生する可能性があるとします。このスキャンがいつ発生したのか、どのサブシステムによってスキャンが発生したのかは不明です。 udevに関連していますか?他の可能な犯人はありますか?最初は、オンデマンドモジュールのロードにより、必要に応じて使用できなくなる可能性があると思いました。それで強制的にロードしようとしました。明らかに、これはカーネルコマンドラインにモジュール名を一覧表示することでできましたが、役に立たなかったのです。
rootwait
テスト済みrootdelay
です。どちらも問題を解決できませんでした。
私が面白いと思うのは、通常のUSBスティックです。働く意図した実行目的(ESPおよびルートファイルシステム)を提供します。また、BIOSはUSB接続のSATAディスクを検出し、UEFI実行可能ファイル(GRUB)を見つけて起動し、GRUBはここからカーネルを読み込み、起動します。
-
問題の背景:
2.5インチHDDをコンピュータに接続するために使用するUSB-SATAケーブルがあります。このシステムは、4つの内部SATAポートを備えた小型ホームサーバーで、すべてRAIDZメンバーディスク用です。外部ドライブを起動し、ここにルートファイルシステムをマウントする予定です。これまで、私は8GBのUSBスティックにESPとルートファイルシステムをインストールしましたが、うまくいきました。 USBスティックが可能だとわかりました。非常に一般的なルートファイルシステムが受信するワークロードを受信すると、ログがRAMにリダイレクトされ、基本プロセスを除くすべてが、ルートファイルシステムがZFSプール内のLXCコンテナで実行されている場合でも同様です。すぐにたわごとを安くするのは簡単です。
答え1
もう少し調査したところ、この問題に対するハッキーな解決策が見つかりました。 完璧とは距離が遠く、根本的な原因を解決することはできませんが、少なくともシステムを起動可能にします。
ハッカーはスクリプトを持っていますファイルシステムの初期化sleep
ルートマウントを試みる前、デバイス初期化後、実行前のある時点で実行されますblockdev --rereadpt
。
Debian ベースのシステムでは、次のファイルを挿入します/etc/initramfs-tools/scripts/local-top/rereadpt
。
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac
sleep 5
blockdev --rereadpt /dev/<yourdisknode>
/dev/sda
サイト環境に単一のSCSIディスクまたは他のロジックがある場合は、同様の名前を使用して/dev/disk/by-id/...
正しいドライブで再スキャンをトリガーできます。
アップデート:画像を再構築するたびに上記のスクリプトを実行したくない場合update-initramfs
(そうではありませんか??)省略できない開始prereqs
と断片case