Re: zic: fix PostgreSQL build failure on filesystems without hard link support

From: Vladlen Popolitov <v(dot)popolitov(at)postgrespro(dot)ru>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: zic: fix PostgreSQL build failure on filesystems without hard link support
Date: 2026-07-31 13:24:56
Message-ID: 5a2858f2547a9904dc891fa21fe1998f@postgrespro.ru
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Tom Lane писал(а) 2026-07-31 02:57:
> Vladlen Popolitov <v(dot)popolitov(at)postgrespro(dot)ru> writes:
>> PostgreSQL fails to build on filesystems that do not support hard
>> links
>> (e.g., exFAT, FAT32, some network filesystems). The build process
>> stops
>> with the following error during timezone data generation:
>> Can't link <target> to <linkname>: Invalid argument
>
> A question from the tzdb guys:
>
> * Does the 'symlink' system call have the same problem on this
> MS-Windows platform? Should zic worry about them as well? (But if so,
> why didn't zic complain to your users about symlink?)
>
> Also, it occurs to me to wonder if we're doing this to ourselves.
> Specifically, it looks like src/port/win32error.c's _dosmaperr
> will map ERROR_NOT_SUPPORTED to EINVAL, due to the lack of any
> table entry for ERROR_NOT_SUPPORTED. Can you confirm which
> underlying Windows error code is being returned?
>
> regards, tom lane

I have confirmed that the Windows error code returned by
CreateHardLinkA() on exFAT is ERROR_INVALID_FUNCTION (numeric value 1).
This code has no mapping in PostgreSQL's _dosmaperr(), which
falls back to returning EINVAL (errno == 22). This is why zic
receives EINVAL instead of ENOTSUP.

One more observation: Microsoft's documentation for CreateHardLinkA()
does
not list possible error codes. For most Windows API functions, the
documentation explicitly lists all error codes that the function can
return.
But for CreateHardLinkA(), this information is missing. Therefore, it is
unclear whether different error codes are returned for different failure
scenarios on Windows. This is different from the POSIX link() function,
which has a clearly defined set of error codes for each specific failure
case.
Also I see in man: Linux returns EPERM for unsupported filesystems,
FreeBSD returns EOPNOTSUPP. Neither returns ENOTSUP.

Regarding symlink(): PostgreSQL maps symlink to pgsymlink(), which is
implemented using NTFS junction points on Windows. Junction points work
only with directories, not files. Since zic needs to create symbolic
references to timezone data files, this mechanism is unsuitable, and
zic correctly excludes symlink support using #ifdef HAVE_SYMLINK.

--
Best regards,

Vladlen Popolitov.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Matheus Alcantara 2026-07-31 13:52:39 Re: hashjoins vs. Bloom filters (yet again)
Previous Message Bohyun Lee 2026-07-31 13:13:55 [Patch]The Case For WAL-Logging pg_upgrade