ハードウェアエラーSSDからファイルを回復

ハードウェアエラーSSDからファイルを回復

私のSSDにある種のハードウェア障害があるため、まだ保証期間中なので修理できますが、そのサービスにはデータ復旧は含まれていません。ここから作業ファイルを収集しましたが、個人ファイルとプラグインがまだ残っているので、復元したいと思います。

問題は…帯域幅と総コピーサイズが問題のようです。読みすぎるとドライブがクラッシュする可能性があります。どこでも不良セクタ(エラー)を報告するか、オペレーティングシステム全体をシャットダウンしてください。そのため、メモリバッファに問題があると思われ、ドライブをホットスワップできるようにエンクロージャに入れました。もう1つの質問では、帯域幅制限のあるrsyncを使用することを検討しましたが、バッファを自分で消去または冷却できるようにコピープロセスに時間差を置く必要があると思います。

失われたデータを回復するには、スクリプトまたはツールが必要です。

答え1

不良セクタ(エラー)がどこでも報告されている

SSDには「セクタ」はありません。 「ブロック」はそうです。ドライブが故障していると報告している場合、これは機械的に何も失敗しないためです。

  1. ブロックのこれらのビットを取得するには、アドレスラインを確認してください。
  2. 「電圧読み出しベクトルを得た」を意味するメモリセルを読み出す。
  3. やや複雑なソフト入力エラー訂正コードを適用してビットに変換してみてください。
  4. (成功とデータ)または(エラー)を返します。
    1. これを復号しようとする試み(繰り返し)が成功すると、ある時点でゼロになるエラー用語(デコーダの「症候群」)が生成されます。
    2. ソフト値が実際には修正されず、エラーのない単語を生成するためにエラーが修正されるとエラーが発生します。

したがって、エラーが発生します。これは、コンテンツが読み取れないことを意味します。 「SSDはありません。間違った回復不能なデータ情報": 常に読みます。一部すべてがどんなに損傷していても、電圧が検査に合格していることを確認し、必要に応じて修正してください。そして可能。

だから:

どこでも不良セクタが報告されている

SSDを信頼する必要があります。 SSDは実際にデータを読み取ることができません。メモリセル(特定の電圧で充電された小さなコンデンサ)は損傷していませんが、「グローバルに」変更できる唯一のことは、アナログを変換するADCの基準電圧を「移動」することです。読み出し電圧をデジタル値に変換することは難しくなる。これにより、実際のメモリが良好であってもデコーダは誤ったソフト入力を受け取ります。

ただし、この電圧が発生します。同じ枠内でフラッシュチップ内のADCは、電源電圧などの変化に非常に弾力的でなければならないためです。

したがって、これは実際には熱問題であるか、またはある種のシリコンモードエラーであり得る。

どちらの方法でも、ドライブからデータをインポートするためにrsyncやファイルシステムレベルのツールを使用したくないようです。これを行うには、どのデータがどのファイルにあるかを理解するために、オペレーティングシステムが同じデータポイントに非常に頻繁にアクセスできる必要があります。

あなたがしなければならないことは、ブロックデバイスレベルのコピーを作成し、小さなステップで行うことです。たとえば、16MB をイメージファイルとして読み込みます。しばらくお待ちください。 16MBの読み取りなど。

ddこれは、チャンクを順番に読み込んだ後にwaitを呼び出し、次のチャンクを読み取るなどのループを使用するZSH / bashシェルスクリプトsleepまたはPythonの数行で実行できます。後で同じ時点で再開できるように、読み取りプロセスにエラーがあることを確認し、エラーが発生した場合はプロセスを中断することを忘れないでください。

実際にソリューションを準備する必要があるので:

#!/usr/bin/zsh
# Copyright 2022 Marcus Müller
# SPDX-License-Identifier: BSD-3-Clause
# Find the license text under https://spdx.org/licenses/BSD-3-Clause.html
# THIS SCRIPT IS UNTESTED AND COMES WITH NO WARRANTIES, FOLKS.

IN_DEVICE=/dev/yoursource_ssd
BACKUP_IMG=myimage
LOGFILE=broken_mbs.txt

# get size, round up to full MB
size_in_bytes=$(blockdev "${IN_DEVICE}")
size_in_MB=$(( ( ${size_in_bytes} + 2**20 - 1) / 2**20 ))
#check whether size > 0
if [[ ! ${size_in_MB} -gt 0 ]]; then
  logger -p user.crit "Nope, can't determine size of ${IN_DEVICE}. I'm outta here."
  echo "Failure on input" >&2
  exit -1
else
  logger -p user.info "Trying to back up ${IN_DEVICE}, size ${size_in_MB} MB"
fi

if fallocate -l "${size_in_MB}MiB" "${BACKUP_IMG}" ; then
  logger -p user.info "preallocated ${BACKUP_IMG}"
else
  logger -p user.crit "failed to preallocate ${BACKUP_IMG}"
  echo "failure on output" >&2
  exit -2
fi

failcounter=0
MB=$((2**20))
for i in {0..$((${size_in_MB}-1))}; do
  if \
    dd \
      "if=${IN_DEVICE}" \
      "of=${BACKUP_IMG}" \
      "ibs=${MB}" "obs=${MB}" \
      "skip=${i}" "seek=${i}" ; \
  then
    echo "backed up MB nr. ${i}"
  else
    failcounter=$(( ${failcounter} + 1 ))
    echo "${failcounter}. error: couldn't backup MB nr. $i" > &2
    echo "${i}" >> ${LOGFILE}
    logger -p user.err "couldn't backup MB nr. $i"
  fi
  sleep 0.5
done
echo "Got ${failcounter} failures"
exit ${failcounter}

関連情報