OK, thanks. The patch should remedy the problem. Since the error was in extending the mailbox (a step to prepare the mailbox for rewriting), it is likely that no damage was done to the mailbox. However, some message flag changes in that IMAP session were probably lost due to the quota error.

Essentially, imapd wanted to save those flags, and couldn't because of quota. Rather than abandoning the effort entirely, it reports the error and hopes that it is fixed so that it can save the changes later in the session.

However, the session got disconnected, and so imapd had to save changes and exit. But it got an error in saving the changes, and since the session was disconnected it had to save changes and then exit. ........

The effect of the patch is to give up after one effort to save changes after a disconnect. Once it longjmp()s to the "save changes and exit" code, any subsequent error-inducted longjmp() goes directly to exiting.

This problem is specific to traditional UNIX mailbox format.

On Sat, 3 Nov 2007, Kostik wrote:

Hello, Mark.

Yes, it is. It's happens with over quoted users only.
And this session is not has "active internet connections" already.

---
unix_rewrite() go to:
unix_pseudo (stream=0x8142738, hdr=0x8142848 "Unable to extend mailbox: Disk quota 
exceeded") at unix.c:1967
and unix_pseudo return 550

do: for (i = 1,flag = LOCAL->pseudo ? 1 : -1; i <= stream->nmsgs; i++) {
( in my case stream->nmsgs = 766)

if (!size && !mail_parameters (NIL,GET_USERHASNOLIFE,NIL)) {
_is FALSE_

if (ret = unix_extend (stream,size)) {
_is FALSE_

and we are go to:
return ret;                   /* return state from algorithm */
---

Thanks, Mark, I applied your patch. I can not simulate the loop manually.
Usually during the day I see one case.

=koc

MC> I think that something else may be happening.  Is the user over quota?

MC> The session must have autologged out, gotten a hangup signal, or
MC> encountered a fatal I/O error; otherwise it would not have state == LOGOUT
MC> with a stream still open.

MC> The loop should only take place if LOCAL->dirty is set, but unix_rewrite()
clears LOCAL->>dirty if it succeeded.

MC> Try the following patch and see if it remedies the loop.  It doesn't
MC> really address the problem that the mailbox couldn't be updated though.

MC> *** imapd.c~    2007-10-12 11:12:37.000000000 -0700
MC> --- imapd.c     2007-11-02 15:08:46.000000000 -0700
MC> ***************
MC> *** 378,383 ****
MC> --- 378,385 ----
MC>      }

MC>      if (setjmp (jmpenv)) {     /* die if a signal handler say so */
MC> +                               /* in case we get borked now */
MC> +     if (setjmp (jmpenv)) _exit (1);
MC>                                 /* need to close stream gracefully? */
MC>        if (stream && !stream->lock && (stream->dtb->flags & DR_XPOINT))
MC>          stream = mail_close (stream);

MC> On Fri, 2 Nov 2007, Kostik wrote:

Hello.

I am trace looping proc in GDB. And see, that it loop's in unix_check at
unix.c:822.

====================
0x0809dace in unix_check (stream=0x8142738) at unix.c:826
826     in unix.c
(gdb) where
#0  0x0809dace in unix_check (stream=0x8142738) at unix.c:826
#1  0x0809db29 in unix_close (stream=0x8142738, options=0) at unix.c:577
#2  0x080693fa in mail_close_full (stream=0x8142738, options=0) at mail.c:1354
#3  0x08051438 in main (argc=1, argv=0xbffffae4) at imapd.c:383
====================

Step-by-step debuging:

in 'unix_check'(unix.c:826) do:
step1: in 822 str: "unix_rewrite" return 0 and go to 'else'
step2: else unix_unlock (LOCAL->fd,stream,&lock);
step3: mail_unlock (stream);       /* unlock the stream */
step4: MM_NOCRITICAL (stream)
==> go to "mm_nocritical (s=0x8142738) at imapd.c:4419"

in 'mm_nocritical':
step5: if (!--critical && (state == LOGOUT)) {; _is TRUE_
step6: if (s && (stream != s) && !s->lock && (s->dtb->flags &
DR_XPOINT)); _is FALSE_
step7: longjmp (jmpenv,1);         /* die now */
==> go to "main (argc=1, argv=0xbffffae4) at imapd.c:382"

in 'main':
step8:  if (stream && !stream->lock && (stream->dtb->flags &
DR_XPOINT)); _is TRUE_
step9: stream = mail_close (stream);
==> go to "mail_close_full (stream=0x8142738, options=0) at mail.c:135"

in 'mail_close_full':
step10: if (stream) {; _is TRUE_
step11:    if (stream->dtb) (*stream->dtb->close) (stream,options);
==> go to: "unix_close (stream=0x0, options=0) at unix.c:571"

in  'unix_close':
step12: int silent = stream->silent;
step13: stream->silent = T;           /* go silent */
again
step14: int silent = stream->silent;
step15: stream->silent = T;           /* go silent */
again
step16: int silent = stream->silent;
and
step17:  if (options & CL_EXPUNGE) unix_expunge (stream,NIL,NIL); _is
FALSE_
step18:  else if (LOCAL->dirty) unix_check (stream);

AND WE AGIAN GO to:
unix_check (stream=0x8142738) at unix.c:816

It's looping. Does anybody can help?

=koc

K> Hello everyone!

K> We have imap-2006k.DEV.SNAP-0710261815 at Linux (Slackware_11 Linux
K> 2.4.35.3). And NFS(v3) mounted mailbox store with Disk quota enabled.

K> Imapd busy loop is:
K> ===| strace begin |==============================

uname({sys="Linux", node="gnome11", ...}) = 0
open("/var/virtual/online.ru/mail/W/Z/mivanov.lock.1193931164.28319.gnome11", 
O_WRONLY|O_CREAT|O_EXCL, 0666) = 0
close(0)                                = 0
link("/var/virtual/online.ru/mail/W/Z/mivanov.lock.1193931164.28319.gnome11", 
"/var/virtual/online.ru/mail/W/Z/mivanov.lock") = 0
stat64("/var/virtual/online.ru/mail/W/Z/mivanov.lock.1193931164.28319.gnome11", 
{st_mode=S_IFREG|0666, st_size=0, ...}) = 0
unlink("/var/virtual/online.ru/mail/W/Z/mivanov.lock.1193931164.28319.gnome11") 
= 0
umask(022)                              = 0
chmod("/var/virtual/online.ru/mail/W/Z/mivanov.lock", 0666) = 0
open("/var/virtual/online.ru/mail/W/Z/mivanov", O_RDWR) = 0
fstatfs(0, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=6690853, 
f_bfree=4189342, f_bavail=3854123, f_files=3352576, f_ffree=1626667, f_fsid={0,
0}, f_namelen=255, f_frsize=0}) = 0
fstat64(0, {st_mode=S_IFREG|0600, st_size=6840320, ...}) = 0
time(NULL)                              = 1193931164
time(NULL)                              = 1193931164
lseek(0, 6840320, SEEK_SET)             = 6840320
write(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65) = 65
 | 00000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........ |
 | 00010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........ |
 | 00020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........ |
 | 00030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ........ ........ |
 | 00040  00                                                .                 |
fsync(0)                                = -1 EDQUOT (Disk quota exceeded)
ftruncate(0, 6840320)                   = 0
fsync(0)                                = 0
time(NULL)                              = 1193931164
fstat64(0, {st_mode=S_IFREG|0600, st_size=6840320, ...}) = 0
utime("/var/virtual/online.ru/mail/W/Z/mivanov", [2007/11/01-18:32:44, 
2007/11/01-18:32:43]) = 0
fstatfs(0, {f_type="NFS_SUPER_MAGIC", f_bsize=32768, f_blocks=6690853, 
f_bfree=4189342, f_bavail=3854123, f_files=3352576, f_ffree=1626666, f_fsid={0,
0}, f_namelen=255, f_frsize=0}) = 0
unlink("/var/virtual/online.ru/mail/W/Z/mivanov.lock") = 0
close(0)                                = 0
lstat64("/var/virtual/online.ru/mail/W/Z/mivanov.lock", 0xbfffd0ac) = -1 ENOENT 
(No such file or directory)
umask(0)                                = 022
getpid()                                = 28319
time(NULL)                              = 1193931164

K> And again....
uname({sys="Linux", node="gnome11", ...}) = 0
K> ................

K> ===| strace end |==============================

K> Any other suggestions or troubleshooting ideas?
K> Thanks for your help!




-- Mark --

http://panda.com/mrc
Democracy is two wolves and a sheep deciding what to eat for lunch.
Liberty is a well-armed sheep contesting the vote.
_______________________________________________
Imap-uw mailing list
[email protected]
https://mailman1.u.washington.edu/mailman/listinfo/imap-uw

Reply via email to