我有一個情況。我本來應該運行 tar -x 從磁帶恢復 tar 文件,但我按了“c”並忘記將磁帶設置為唯讀。文件位於 fsf 位置 23,但磁帶有 27 個文件。我知道文件 23 丟失了,但是由於我按 ctrl+c 取消了 tar 命令,我是否仍然希望以某種方式恢復其他 tar 文件?我嘗試了 fsf過去的文件 23,但我得到的只是輸入/輸出錯誤。
我在想也許可以使用 dd 從文件 23 進行轉儲,然後獲取該文件並使用簽名文件恢復工具,例如 photorec。這可行嗎?
答案1
這個問題完全是特定於設備的,具體取決於驅動器硬體及其關聯的驅動程式。
當搞砸磁帶操作(例如中斷寫入)時,您可以輕鬆地在磁帶上製作不可讀的符號,甚至不可讀的延伸。您已經表明您的驅動程式無法讀取中止寫入留下的垃圾,因為mt fsf
僅發出一個 ioctl 要求驅動程式跳到下一個 EOF 標記。由於驅動程式返回 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
操作要求驅動程式透過纏繞文件標記來纏繞到磁帶的末端。如果您只是用 SIGINT (Ctrl-C) 終止 tar 程序來中斷磁帶寫入,那麼這應該可以正常工作。從 SCSI 磁帶驅動程式的角度來看,這看起來就像用戶空間程式關閉了檔案描述符,因此該位置應該有一個 EOF 標記,但沒有實際的「損壞」。
但是,如果此處發生其他情況和/或上述方法不起作用,您可以透過向磁帶驅動程式發送 SCSI 命令來要求磁帶驅動程式將空間分配到媒體末尾,從而獲得不同的結果。做。這與預設行為不同(即磁帶驅動程式透過在檔案上前移間距,以便它可以追蹤當前檔案編號(以在mt status
和等操作中報告mt tell
)。要配置此功能,您可以使用MT_ST_FAST_EOM
ioctl。我不知道如何從命令列進行設置,您可能需要創建一個小型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;
}
為了節省樣板,我假設磁帶設備已經在程式的標準輸出上開啟(即您像這樣運行它:)./myprog >"$TAPE"
。
我沒有測試過該程式碼,請謹慎使用。如果它告訴你的孩子他們可以養一隻小狗,請不要怪我。您可以使用另一個 C 程式來反轉設置,但如果不關心持續的服務可用性,您也可以簡單地重新啟動電腦。