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, 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]