]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
More tar portability adjustments.
authorThomas Munro <tmunro@postgresql.org>
Fri, 3 Apr 2026 22:13:18 +0000 (11:13 +1300)
committerThomas Munro <tmunro@postgresql.org>
Sat, 4 Apr 2026 00:54:21 +0000 (13:54 +1300)
For the three implementations that have caused problems so far:

* GNU and BSD (libarchive) tar both understand --format=ustar
* ustar doesn't support large UID/GID values, so set them to 0 to
  avoid a hard error from at least GNU tar
* OpenBSD tar needs -F ustar, and it appears to warn but carry
  on with "nobody" if a UID is too large
* -f /dev/null is a more portable way to throw away the output, since
  the default destination might be a tape device depending on build
  options that a distribution might change
* Windows ships BSD tar but lacks /dev/null, so ask perl for its name

Based on their manuals, the other two implementations the tests are
likely to encounter in the wild don't seem to need any special handling:

* Solaris/illumos tar uses ustar and replaces large UIDs with 60001
* AIX tar uses ustar (unless --format=pax) and truncates large UIDs

Backpatch-through: 18
Co-authored-by: Thomas Munro <thomas.munro@gmail.com>
Co-authored-by: Sami Imseih <samimseih@gmail.com> (large UIDs)
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> (earlier version)
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com> (OpenBSD)
Reviewed-by: Andrew Dunstan <andrew@dunslane.net> (Windows)
Discussion: https://postgr.es/m/3676229.1775170250%40sss.pgh.pa.us
Discussion: https://postgr.es/m/CAA5RZ0tt89MgNi4-0F4onH%2B-TFSsysFjMM-tBc6aXbuQv5xBXw%40mail.gmail.com

src/test/perl/PostgreSQL/Test/Utils.pm

index 120999f6ac933fe617722a17f1a2db9cf3455b45..81dbcab8257c9f6e3ab316480201409627063984 100644 (file)
@@ -1329,20 +1329,23 @@ sub tar_portability_options
        # GNU tar typically produces gnu-format archives, which we can read fine.
        # But some platforms configure it to default to posix/pax format, and
        # apparently they enable --sparse too.  Override that.
-       if (system("$tar --format=ustar -c -O /dev/null >/dev/null 2>/dev/null")
-               == 0)
+       #
+       # ustar format supports UIDs only up to 2^21 - 1 (2097151).  Override
+       # owner/group to avoid failures on systems where the running user's UID/GID
+       # exceeds that limit.
+       my $devnull = File::Spec->devnull();
+       if (system(
+                       "$tar --format=ustar --owner=0 --group=0 -cf $devnull $devnull 2>$devnull"
+               ) == 0)
        {
-               push(@tar_p_flags, "--format=ustar");
+               # GNU tar (Linux), BSD tar (FreeBSD, NetBSD, macOS, Windows)
+               push(@tar_p_flags, "--format=ustar", "--owner=0", "--group=0");
        }
-
-       # bsdtar also archives sparse files by default, but it spells the switch
-       # to disable that differently.
-       if (system("$tar --no-read-sparse -c - /dev/null >/dev/null 2>/dev/null")
-               == 0)
+       elsif (system("$tar -F ustar -cf $devnull $devnull 2>$devnull") == 0)
        {
-               push(@tar_p_flags, "--no-read-sparse");
+               # OpenBSD tar
+               push(@tar_p_flags, "-F", "ustar");
        }
-
        return @tar_p_flags;
 }