tar -c から部分的に上書きされたテープを回復する

tar -c から部分的に上書きされたテープを回復する

状況があります。テープから tar ファイルを回復するために tar -x を実行するはずでしたが、「c」を押してテープを読み取り専用にし忘れました。ファイルは fsf 位置 23 にありました。しかし、テープには 27 個のファイルがありました。ファイル 23 が失われたことはわかっていますが、Ctrl+C を押して tar コマンドをキャンセルしたので、他の tar ファイルを何とか回復できる可能性はありますか? ファイル 23 を超えて fsf を試しましたが、入出力エラーしか表示されません。

dd を使用してファイル 23 からダンプを実行し、このファイルを取得して、photorec などの署名ファイル回復ツールを使用することを考えていました。これは実行可能でしょうか?

答え1

この質問は、ドライブのハードウェアとそれに関連するドライバーに応じて、完全にデバイス固有です。

テープ操作を失敗すると (書き込みを中断するなど)、読み取り不可能なシンボルや、テープ上に読み取り不可能な領域が簡単に作成されてしまいます。 は、次mt fsfの EOF マークにスキップするようにドライバに要求する ioctl を発行するだけなので、中止された書き込みによって残されたジャンクを超えてドライバが読み取ることができないことは既に示しました。 ドライバは EIO を返すので、それ以上のことはおそらくできないでしょう。

このテープがあなたにとってどれほど重要かによって、次のステップはおそらく磁気テープ技術に熟練したフォレンジック復旧会社に送ることです。データはおそらくそこにありますが、ほとんどのドライバーはあなたがもたらしたマーカーの欠陥に対処する方法を知りません。

答え2

テープの反対側から読み取りを開始してみます。

#! /bin/sh
set -e
TAPE=/dev/... # change me, you must use a non-rewinding device.
export TAPE

# Wind to the end of the tape.
mt eod

# Rewind to the beginning of the last file and then list it.
# It's possible I misunderstood the way end-of-data is signaled
# on the tape and if so perhaps this command should be mt bsfm 2,
# in which case you can just combine this with the loop below.
# For context here you can look at the entry for MT_ST_TWO_FM
# in "man st".
mt bsfm 1
tar -f "$TAPE" -t

# We just read a file so we're  going to need to rewind over it
# and then rewind more to get to the beginning of the previous file.
# I forget whether tar leaves the tape at EOF or just after it. I'm
# assuming here just after, but if it leaves the tape at the EOF
# mark, the 2 on the next line would need to be a 1.
while mt bsfm 2 
do
  tar -f "$TAPE" -t
done

それはリストテープの最後からアクセスできるすべての tar アーカイブの内容。もちろん、テープの先頭にもアーカイブがありますが、それらはもっと簡単にリストできます。

while tar -f "$TAPE" -t
do
  true
done

このmt eod操作は、ファイルマークを過ぎてテープの最後まで巻き取るようにドライバーに要求します。テープへの書き込みを中断するために tar プロセスを SIGINT (Ctrl-C) で終了させただけであれば、これは問題なく動作するはずです。SCSI テープ ドライバーの観点からは、これはユーザー空間プログラムがファイル記述子を閉じたように見えるだけなので、その場所に EOF マークがあるはずですが、実際の「損傷」はありません。

ただし、ここで何か他のことが起こっていて、上記の方法が機能しない場合は、テープ ドライブに SCSI コマンドを送信して、テープ ドライバーにメディアの終わりまでスペースを入れるよう要求することで、異なる結果を得られる可能性があります。これは、デフォルトの動作 (テープ ドライバーがファイルを前方にスペースすることで、現在のファイル番号を追跡できるようにする (やなどの操作で報告する)) とは異なりますmt statusmt tellこれを構成するには、ioctl を使用しますMT_ST_FAST_EOM。コマンド ラインから設定する方法がわからないので、次のような小さな C プログラムを作成する必要があります。

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>

int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;
  struct mtop mt_cmd;
  mt_cmd.mt_op = MTSETDRVBUFFER;
  mt_cmd.mt_count = MT_ST_BOOLEANS | MT_ST_FAST_MTEOM;
  if (0 != ioctl(1, MTIOCTOP, &mt_cmd)) {
    perror("MTSETDRVBUFFER on stdout");
    return 1;
  }
  return 0;
}

定型文を節約するために、このプログラムではテープ デバイスがすでに stdout で開かれていると想定しました (つまり、次のように実行します) ./myprog >"$TAPE"

そのコードはテストしていませんので、注意して使用してください。もし、あなたの子供が子犬を飼ってもいいと伝えたとしても、私を責めないでください。別の C プログラムを使用して設定を元に戻すこともできますが、継続的なサービス可用性に問題がない場合は、単にマシンを再起動するだけでも同様に機能します。

関連情報