Re: [BUG] IMAP hibernation fails on FreeBSD 15.x with "Invalid peer_dev_major value"
Jordan Ostrev via dovecot <[email protected]>
| Newsgroups | gmane.mail.imap.dovecot |
|---|---|
| Message-ID | <[email protected]> |
Hi Timo, Just wanted to let you know that the mail/dovecot24 port I proposed — including the hibernate patch you provided — was officially committed to the main FreeBSD ports tree today. Thanks again for your help! Best regards, Jordan > On 6 Aug 2026, at 1:31, Jordan Ostrev <[email protected]> wrote: > > Hi Timo, > I tested your patch on FreeBSD 15.x and can confirm that it completely resolves the issue. > Test scenario: > > 1. Connected via telnet localhost 143, authenticated, selected INBOX, and issued A03 IDLE. > 2. Verified via doveadm who that after the hibernation timeout, the session successfully transitioned from imap to imap-hibernate ([email protected] 1 imap-hibernate (PID) (127.0.0.1)). > 3. Sent a test email from an external server — the hibernated session woke up instantly, received the real-time notification (* 4297 EXISTS), and returned to the imap service without dropping the connection. > 4. Checked the system logs — no more Invalid peer_dev_major value errors. > > Everything works as expected - tested it more than once to hibernate. Thanks for the fix! > You can follow what happens with FreeBSD PR on https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=286695. It will be great if you can follow the thread. > > KR, > Jordan > > PS. > > A02 SELECT INBOX > * FLAGS (\Answered \Flagged \Deleted \Seen \Draft unknown-1 unknown-2 unknown-4 unknown-8 unknown-5 unknown-7 unknown-3 unknown-10 $NotJunk NotJunk $Forwarded Forwarded $Junk Junk $label1 JunkRecorded $MailFlagBit0 NonJunk) > * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft unknown-1 unknown-2 unknown-4 unknown-8 unknown-5 unknown-7 unknown-3 unknown-10 $NotJunk NotJunk $Forwarded Forwarded $Junk Junk $label1 JunkRecorded $MailFlagBit0 NonJunk \*)] Flags permitted. > * 4296 EXISTS > * 0 RECENT > * OK [UNSEEN 1] First unseen. > * OK [UIDVALIDITY 1610577026] UIDs valid > * OK [UIDNEXT 95301] Predicted next UID > * OK [HIGHESTMODSEQ 16189] Highest > A02 OK [READ-WRITE] Select completed (0.006 + 0.000 + 0.005 secs). > A03 IDLE > + idling > * OK Still here > * OK Still here > * OK Still here > * OK Still here > * OK Still here > * OK Still here > * 4297 EXISTS > * 1 RECENT > * 4297 FETCH (FLAGS (\Recent $NotJunk NotJunk)) > * OK Still here > * OK Still here > * OK Still here > * OK Still here > * OK Still here > * OK Still here > > # doveadm who > username # service (pids) (ips) > [email protected] 3 imap (4315 5394 3153) (46.10.221.52) > [email protected] 1 imap-hibernate (4351) (127.0.0.1) > > # doveadm who > username # service (pids) (ips) > [email protected] 4 imap (4315 5632 5394 3153) (46.10.221.52 127.0.0.1) > > and here it goes again to hibernate 2nd time: > # doveadm who > username # service (pids) (ips) > [email protected] 4 imap (7247 6707 5999 3153) (46.10.221.52) > [email protected] 1 imap-hibernate (6686) (127.0.0.1) > > > Telnet session never disconnected or frozen somehow. > > > # cat /usr/ports/mail/dovecot24/files/patch-src_imap_imap-client-hibernate.c > --- src/imap/imap-client-hibernate.c.orig 2026-08-05 21:51:45 UTC > +++ src/imap/imap-client-hibernate.c > @@ -62,7 +62,8 @@ static void imap_hibernate_write_cmd(struct client *cl > str_append_tabescaped(cmd, user->set->unexpanded_mail_log_prefix); > str_printfa(cmd, "\tidle_notify_interval=%u", > client->set->imap_idle_notify_interval); > - if (fstat(client->fd_in, &peer_st) == 0) { > + if (fstat(client->fd_in, &peer_st) == 0 && > + peer_st.st_dev != (dev_t)-1) { > str_printfa(cmd, "\tpeer_dev_major=%lu\tpeer_dev_minor=%lu\tpeer_ino=%llu", > (unsigned long)major(peer_st.st_dev), > (unsigned long)minor(peer_st.st_dev), > > > >> On 6 Aug 2026, at 0:46, Jordan Ostrev <[email protected]> wrote: >> >> Hi, >> >> I'm not a kernel developer, but I checked how FreeBSD handles socket stats (soo_stat() in sys/kern/sys_socket.c). On FreeBSD, fstat() on a socket returns st_dev = NODEV and st_ino = 0. Since st_ino is always 0 for sockets, it isn't unique or usable for verification either. >> So your proposed patch to skip the entire check when st_dev == (dev_t)-1 is indeed the right approach. >> >> KR, >> Jordan >> >> >>> On 5 Aug 2026, at 23:56, Timo Sirainen <[email protected]> wrote: >>> >>> Hi, >>> >>> I'm mainly wondering if the device is NODEV, is the inode still usable or is that also some 0 or -1? This is likely a simpler patch, but it also removes the inode check also, which isn't good if it would be usable: >>> >>> diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c >>> index cb640c3695..191b0cfef9 100644 >>> --- a/src/imap/imap-client-hibernate.c >>> +++ b/src/imap/imap-client-hibernate.c >>> @@ -62,7 +62,10 @@ static void imap_hibernate_write_cmd(struct client *client, string_t *cmd, >>> str_append_tabescaped(cmd, user->set->unexpanded_mail_log_prefix); >>> str_printfa(cmd, "\tidle_notify_interval=%u", >>> client->set->imap_idle_notify_interval); >>> - if (fstat(client->fd_in, &peer_st) == 0) { >>> + /* e.g. FreeBSD returns NODEV as sockets' st_dev, which can't be >>> + used for verifying that the fd is the expected one. */ >>> + if (fstat(client->fd_in, &peer_st) == 0 && >>> + peer_st.st_dev != (dev_t)-1) { >>> str_printfa(cmd, "\tpeer_dev_major=%lu\tpeer_dev_minor=%lu\tpeer_ino=%llu", >>> (unsigned long)major(peer_st.st_dev), >>> (unsigned long)minor(peer_st.st_dev), >> > _______________________________________________ dovecot mailing list -- [email protected] To unsubscribe send an email to [email protected]