Freebsd

如何將幾個 tar 順序寫入磁帶?

  • August 20, 2020

我正在嘗試將多個目錄寫入磁帶。每個目錄都有一個 tar 命令。

所以我有以下範例文件/目錄結構:

user@host1:~/temp/original % find .
.
./foo1
./foo1/foo1.a
./foo1/foo1.b
./foo1/foo1.c
./foo1/foo1.1
./foo2
./foo2/foo2.a
./foo2/foo2.b
./foo2/foo2.c
./foo2/foo2.2
./foo3
./foo3/foo3.a
./foo3/foo3.b
./foo3/foo3.c
./foo3/foo3.3

我倒帶並擦除磁帶,我希望它就像使用空白磁帶一樣。

user@host1:~/temp/original % mt -f /dev/sa0 rewind
user@host1:~/temp/original % mt -f /dev/sa0 erase
user@host1:~/temp/original % mt -f /dev/sa0 rewind
user@host1:~/temp/original % mt -f /dev/sa0 status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   0     Calc Record Number: 0
Residual:    0  Reported File Number:   0 Reported Record Number: 0
Flags: BOP

然後我想用三個 tar 命令編寫三個 tar 文件(我認為它們在儲存到磁帶時稱為文件)。每個目錄(foo1、foo2 和 foo3)一個命令。所以我這樣做:

user@host1:~/temp/original % tar cvf /dev/nsa0 foo1
a foo1
a foo1/foo1.a
a foo1/foo1.b
a foo1/foo1.c
a foo1/foo1.1
user@host1:~/temp/original % tar cvf /dev/nsa0 foo2
a foo2
a foo2/foo2.a
a foo2/foo2.b
a foo2/foo2.c
a foo2/foo2.2
user@host1:~/temp/original % tar cvf /dev/nsa0 foo3
a foo3
a foo3/foo3.a
a foo3/foo3.b
a foo3/foo3.c
a foo3/foo3.3

正如我一直在使用/dev/nsa0的那樣,我希望在磁帶中儲存三個 tar 文件。

現在我想將磁帶中的三個文件恢復到另一個目錄中:

user@host1:~/temp/original % cd ../backup/
user@host1:~/temp/backup % mt -f /dev/sa0 rewind
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % mt -f /dev/nsa0 status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   2     Calc Record Number: 1
Residual:    0  Reported File Number:   2 Reported Record Number: 5
Flags: None

為什麼我必須輸入兩次tar xvf /dev/nsa0才能提取foo2foo3

如果我嘗試在磁帶末尾添加另一個目錄,我會:

user@host1:~/temp/original % mt -f /dev/nsa0 eom
user@host1:~/temp/original % tar cvf /dev/nsa0 foo4
a foo4
a foo4/foo4.a
a foo4/foo4.b
a foo4/foo4.c
a foo4/foo4.4
user@host1:~/temp/original % cd ..
user@host1:~/temp % cd backup/
user@host1:~/temp/backup % mt -f /dev/nsa0 rewind
user@host1:~/temp/backup % mt -f /dev/nsa0 fsf 3
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % 

為什麼foo4不提取?

作為附加測試,我彈出磁帶,重新插入並嘗試提取四個目錄,這就是我必須做的:

user@host1:~/temp/backup % mt -f /dev/nsa0 offline
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4

為什麼我必須重複 tar 命令,在 的情況下重複兩次,在 的情況下foo2重複 foo3三次foo4

我正在使用 FreeBSD12.1 和 IBM DDS4 (STD2401LW / Tc4200-236) SCSI 磁帶機。

編輯>按照 schily 的回答,我可以按順序提取 tar 文件。剩下的唯一問題是理解為什麼mt eom以後添加foo4tar 文件仍然需要兩個mt fsf而不是一個。

重新插入磁帶後:

user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo1/
x foo1/foo1.a
x foo1/foo1.b
x foo1/foo1.c
x foo1/foo1.1
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo2/
x foo2/foo2.a
x foo2/foo2.b
x foo2/foo2.c
x foo2/foo2.2
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo3/
x foo3/foo3.a
x foo3/foo3.b
x foo3/foo3.c
x foo3/foo3.3
user@host1:~/temp/backup % mt fsf
user@host1:~/temp/backup % tar xvf /dev/nsa0
user@host1:~/temp/backup % tar xvf /dev/nsa0
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4
user@host1:~/temp/backup %

編輯> 這是mt status在允許提取的位置返回的內容foo4。插入磁帶後立即執行命令:

user@host1:~/temp/backup % rm -rf *
user@host1:~/temp/backup % mt status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   0     Calc Record Number: 0
Residual:    0  Reported File Number:   0 Reported Record Number: 0
Flags: BOP
user@host1:~/temp/backup % echo $TAPE
/dev/nsa0
user@host1:~/temp/backup % mt fsf 4
user@host1:~/temp/backup % mt status
Drive: sa0: <SEAGATE DAT    9SP40-000 912L> Serial Number: HN0948V
---------------------------------
Mode      Density              Blocksize      bpi      Compression
Current:  0x24:DDS-2           variable       61000    enabled (DCLZ)
---------------------------------
Current Driver State: at rest.
---------------------------------
Partition:   0      Calc File Number:   4     Calc Record Number: 0
Residual:    0  Reported File Number:   4 Reported Record Number: 7
Flags: None
user@host1:~/temp/backup % tar xv
x foo4/
x foo4/foo4.a
x foo4/foo4.b
x foo4/foo4.c
x foo4/foo4.4
user@host1:~/temp/backup % 

該行為與磁帶驅動程序的 EOF 處理有關。

這種處理方式因作業系統而異,閱讀相關的 Solaris 手冊頁可能會有所幫助:

http://schillix.sourceforge.net/man/man7i/mtio.7i.html

這解釋了 Solaris 處理和舊 BSD 行為之間的區別。

從這個解釋中,我預計舊的 BSD 行為會導致在 EOF 情況後讀取以跳過文件標記並從磁帶上的下一個文件返回第一條記錄。這似乎是您所期望的。

似乎在 BSD 上觀察到的行為介於記錄的 SVr4 行為和舊的 BSD 行為之間,但我想有一種方法可以讓 Solaris 和目前的 BSD 都工作:

  • 呼叫 tar 讀取第一個磁帶文件
  • 之後,磁帶被定位在第一個磁帶文件的末尾,就在文件標記之前…
  • 呼叫mt fsf跳過文件標記
  • 呼叫 tar 讀取磁帶上的下一個文件。

從討論的其餘部分來看,FreeBSD 似乎寫入了一個額外的文件標記,當mt rewind在應用寫入操作後呼叫時。

該命令mt eom將磁帶定位在最後的雙文件標記之後,並且當另一個寫入操作發生時,這發生在雙文件標記之後,導致最後一次寫入之前的空磁帶文件。

包含三個文件的磁帶看起來是這樣的:

data1 FILEMARK data2 FILEMARK data3 FILEMARK FILEMARK

如果你想附加第四個磁帶文件,你需要呼叫:

mt fsf 3

將磁帶定位在 thirf 文件標記之後。如果你然後開始寫,這會覆蓋第四個文件標記,如果你再次倒帶,你有這個磁帶佈局:

data1 FILEMARK data2 FILEMARK data3 FILEMARK data4 FILEMARK FILEMARK

引用自:https://unix.stackexchange.com/questions/589146