I am trying to write several directories to a tape. Each directory with one tar command.
So I have the following sample file/directory structure:
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
I rewind and erase the tape, which I expect it is like using a blank tape.
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
Then I want to write three tar files (I think they are called files when stored to tape) with three tar commands. One command for each directory (foo1, foo2 and foo3). So I do:
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
As I have been using /dev/nsa0
I expect to have three tar files stored in the tape.
Now I want to recover the three files from the tape into another directory I do:
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
Why do I have to type twice tar xvf /dev/nsa0
to extract foo2
and foo3
?
If I try to add another directory at the end of the tape I do:
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 %
Why foo4
is not extracted?
As an additional test I eject the tape, reinsert it and try to extract the four directories, this is what I have to do:
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
Why do I have to repeat the tar commands, twice in the case of foo2
and foo3
and three times in the case of foo4
?
I am using FreeBSD12.1 and an IBM DDS4 (STD2401LW / Tc4200-236) SCSI Tape Drive.
EDIT>
Following schily's answer, I can get the tar files extracted in order. The only remaining issue would be understanding why mt eom
to later add foo4
tar file still requires two mt fsf
instead of just one.
After reinserting the tape:
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 %
EDIT>
This is what mt status
return right at the position that allows to extract foo4
. The commands are executed right after inserting the tape:
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 %
Best Answer
The behavior is related to the EOF handling of the tape driver.
This handling differs between operating systems and it may help to read the related Solaris man page:
http://schillix.sourceforge.net/man/man7i/mtio.7i.html
that explains a difference between the Solaris handling and the old BSD behavior.
From this explanation, I would expect the old BSD behavior to cause a read after an EOF situation to skip the file mark and to return the first record from the next file on tape. This seems to be what you expect.
It seems that the observed behavior on BSD is between the documented SVr4 behavior and the old BSD behavior, but I guess that there is a way to make things work on both Solaris and current BSD:
call tar to read the first tape file
after that, the tape is positioned at the end of the first tape file, which is just before the file mark...
call
mt fsf
to skip the file markcall tar to read the next file on tape.
From the rest of the discussion, it seems that FreeBSD writes an additional filemark, when
mt rewind
is called after a write operation has been applied.The command
mt eom
will position the tape after the final double filemark and when another write operation takes place, this happens after the double filemark resultng in an empty tape file before that final write.A tape with three files looks this way:
If you like to append a fourth tape file, you need to call:
to position the tape after the thirf filemark. If you then start writing, this overwrites the fourth filemark and if you then rewind again, you have this tape layout: