I wrote:
> Hah, I wondered if it might be something like that. Still, it's hard to
> see how this link() would fail any security check that didn't amount to
> disabling link() altogether. The UID and GID of the process, the old
> file, and the directory will all match --- so exactly what rule are we
> falling foul of? (Or IOW, this still seems like a kernel bug, though
> perhaps of a design rather than implementation kind.)
Ah, I found your thread on freebsd-hackers, and it looks like Konstantin
Belousov has the answer:
>> The sysctl indeed has an interesting interaction with the fact that the
>> created inode inherits gid from the parent directory. If you use it, you
>> must ensure that the directory group is in the group set of the process.
IOW, the problem is that you'd created $PGDATA with group "wheel", but
this wasn't a group that the initdb process belonged to. It's a bit
weird that of all the operations initdb had tried so far, only the
link() would fail, but there you have it.
Anyway the takeaway for us is that it's bad that the link() failure per
se didn't get logged; this might have been less mystifying if it was.
I've started a thread on pgsql-hackers about fixing the bootstrap-time
logging rules for that.
regards, tom lane