Short answer:
Use bsdtar
or GNU tar
(version 1.29 or later) to create archives, and GNU tar
(version 1.26 or later) to extract them on another box.
Long answer: There are some requirements for this to work.
First, Linux must be at least kernel 3.1 (Ubuntu 12.04 or later would do), so it supports SEEK_HOLE
functionality.
Then, you need tar utility that can support this syscall. GNU tar
supports it since version 1.29 (released on 2016/05/16, it should be present by default since Ubuntu 18.04), or bsdtar
since version 3.0.4 (available since Ubuntu 12.04) - install it using sudo apt-get install bsdtar
.
While bsdtar
(which uses libarchive
) is awesome, unfortunately, it is not very smart when it comes to untarring - it stupidly requires to have at least as much free space on target drive as untarred file size, without regard to holes. GNU tar
will untar such sparse archives efficiently and will not check this condition.
This is log from Ubuntu 12.10 (Linux kernel 3.5):
$ dd if=/dev/zero of=1tb seek=1T bs=1 count=1
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.000143113 s, 7.0 kB/s
$ time bsdtar cvfz sparse.tar.gz 1tb
a 1tb
real 0m0.362s
user 0m0.336s
sys 0m0.020s
# Or, use gnu tar if version is later than 1.29:
$ time tar cSvfz sparse-gnutar.tar.gz 1tb
1tb
real 0m0.005s
user 0m0.006s
sys 0m0.000s
$ ls -l
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz
-rw-rw-r-- 1 autouser autouser 134 Nov 7 01:43 sparse-gnutar.tar.gz
$
Like I said above, unfortunately, untarring with bsdtar
will not work unless you have 1TB free space. However, any version of GNU tar
works just fine to untar such sparse.tar
:
$ rm 1tb
$ time tar -xvSf sparse.tar.gz
1tb
real 0m0.031s
user 0m0.016s
sys 0m0.016s
$ ls -l
total 8
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz