On 10/23/26 18:05, Sean C. Farley wrote:
Hello.
I just ran into this after upgrading from 14.5-STABLE to 15.1-STABLE. I
have not yet found out why it happens as I have other things needing
fixing, but it appears from running a test program that dup(0) is
returning 4 instead of 3 when imapd starts, which causes this to fail in
master/master.c:
I was just about completing the draft of a mail that showed the same
conclusion... you just beat me by a few minutes :)
Thanks to Marcin for pointing me to the relevant code fragment.
(Interestingly you say 14.5 works; I haven't had the chance to test this
version).
I modified the code like this:
/* we reserve fds for children to communicate with us, so they
better be available. */
for (fd = STATUS_FD; fd <= LISTEN_FD; fd++) {
syslog(LOG_CRIT,"Resetting fd %d (previously %m)",fd);
int closeret=close(fd);
syslog(LOG_CRIT,"Tried closing: ret=%d, %m",closeret);
int newfd=dup(0);
if (newfd != fd) fatalf(2, "couldn't dup fd 0: %m (newfd=%d)",newfd);
}
Now I get:
Oct 23 15:42:21 test master[34885]: Resetting fd 3 (previously No error: 0)
Oct 23 15:42:21 test master[34885]: Tried closing: ret=-1, Bad file descriptor
Oct 23 15:42:21 test master[34885]: couldn't dup fd 0: Bad file descriptor
(newfd=5)
Oct 23 15:42:21 test master[34885]: exiting
Oct 23 15:42:21 test root[34889]: /etc/rc: WARNING: failed to start cyrus_imapd
So:
_ close on fd 3 (STATUS_FD) fails; errno shows it's because there's no
fd 3. Fine.
_ dup actually works, but doesn't return 3; instead it returns 5! (It's
4 in your report, but the important thing is it's not 3).
This is strange, since dup(2) clearly states:
The new descriptor returned by the call is the lowest
numbered descriptor currently not in use by the process.
As you noticed, that is only happening during the jail startup and not
when the service is started manually. In my case, I am using the base
jail command and not ezjail.
I had ruled ezjail out too.
I am attaching a simple workaround for the startup script, but it is not
the solution. The workaround is duplicating stdin to file descriptor 3,
which placates that test because 3 can be closed and returned in the
dup(0) call.
This is curious!
From your explanation it seems it's "close" that, when given a
nonexistent fd, sort of burns it?
Still investigating...
bye & Thanks
av.