USBからSATAへ - 起動時にパーティションテーブルを読み取れない

USBからSATAへ - 起動時にパーティションテーブルを読み取れない

USBで接続されたSATAディスクが接続された状態でシステムが起動すると、Linuxは明らかにディスクのパーティションを認識しません。これにより、パーティション(およびファイルシステム)が表示されなくなり、パーティションを再スキャン(partprobe、blockdev --rereadptなど)したり、UASモジュールを再ロードしたり、ドライブを取り外して再挿入する必要があります。問題のディスクをESPとルートファイルシステムを含むブートデバイスとして使用したい場合は、実現できません。

いくつかの実験をしました。結果:

  1. ホストがオンラインでUASモジュールがロードされているディスクを挿入します。 ->働く
  2. ホストがオンラインでUASモジュールとusb_storageモジュールがロードされていない状態でディスクを挿入します。 ->働く
  3. ディスクを挿入したら、別のドライブからシステムを起動します - >失敗する パーティションが検出されませんでした。安定化するのに十分な時間を与えた後、次のことが観察された。興味深いことに、UASモジュールとusb_storageモジュールがロードされ、/sys/class/block/sdaが存在しました。いいえそれをリストすると、/proc/partitionsもそうではありません。
    1. この状態でUASモジュールをアンロードして再ロードします - >働く(lsblkにリストされ、/dev/sda{1,2}が生成され、すべてが「正常」です。)
    2. また、この状態から始めて、blockdev --rereadpt ->を介してパーティションを再検索します。働く
    3. カーネルコマンドラインを介してUASモジュールをプリロードしたり、プリロードせずにテストを繰り返すと、同じ結果が表示されます。
  4. ディスクを挿入した後、同じディスクからシステムを起動しようとします - >失敗する(システムを起動できません。回復シェルに削除されました。)
    1. シェルに入れてみてくださいblockdev --rereadpt- >働く
    2. カーネルコマンドラインを介して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

関連情報