On 2023-10-03 12:24, Dag-Erling Smørgrav wrote:
Matthias Apitz <g...@unixarea.de> writes:
I have on my poudriere build host a ports tree and wanted to move it to
the host where the resulting packages are installed:
root@jet:/usr/local/poudriere/ports # du -sh ports20230806
397M ports20230806
root@jet:/usr/local/poudriere/ports # tar cf p.tar ports20230806
root@jet:/usr/local/poudriere/ports # ls -lh p.tar
-rw-r--r-- 1 root wheel 672M Oct 3 18:00 p.tar
already the size of the tar file is somewhat magic; but if you un-tar it
on the other host I will get:
[guru@c720-1400094 ~]$ ls -lh p.tar
-rw-r--r-- 1 guru wheel 672M 3 oct. 18:00 p.tar
[guru@c720-1400094 ~]$ tar xf p.tar
[guru@c720-1400094 ~]$ du -sh ports20230806
1,2G ports20230806
How this is possible?
Most files in the ports tree are very small. On disk, each file gets
rounded up to the nearest multiple of the filesystem block size, which
could be as small as 512 bytes or as large as 8 kB (or even more in
pathological cases). In a tarball, they get rounded up to the nearest
multiple of 512 bytes plus an additional 512 bytes per file for
metadata.
For instance, your average distinfo file (of which there are 30k in the
ports tree) is only 200-250 bytes long, but it occupies 512 bytes on an
FFS filesystem, 1 kB in a tarball, and 4 kB on a typical ZFS filesystem.
As an interesting side note to this, if ZFS is able to compress the file
to under 112 bytes, ZFS will not allocate a sector, but instead store
the file in an "embedded blockpointer", basically using the space it
would normally store the LBAs and checksum of the file, to store the
actual file data, resulting in a file that appears to use 0 bytes of
space, because it entirely fits in the indirect block that would have
pointed to the block itself.
Note that if the target system is FreeBSD 14 or newer, you can simply
mount the tarball (`sudo mount -rt tarfs p.tar /usr/ports`).
DES
--
Allan Jude