From: Peter Pentchev Date: Tue, 9 Jun 2009 14:28:17 +0000 (+0000) Subject: Merge trunk rev. 3768 and 3772: fix the too-many-open-files problem. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a3c72d9deb07c9648fdac91395e28c05187fd162;p=people%2Fms%2Fdma.git Merge trunk rev. 3768 and 3772: fix the too-many-open-files problem. --- diff --git a/patches/22-openfiles.patch b/patches/22-openfiles.patch new file mode 100644 index 0000000..ddbcd99 --- /dev/null +++ b/patches/22-openfiles.patch @@ -0,0 +1,112 @@ +Handle the "too many open files" error gracefully, retrying. + +--- a/dma.c ++++ b/dma.c +@@ -79,6 +79,7 @@ + static uid_t uid; + static FILE *scanfile; + static struct strlist seenmsg[16][16]; ++static int morefiles; + + static int open_locked(const char *, int); + +@@ -1311,15 +1312,21 @@ + char *queueid; + char *queuefn; + off_t hdrlen; +- int fd, locked, seenit; ++ int fd, locked, seenit, inmore; + + LIST_INIT(&queue->queue); + ++ inmore = morefiles; ++ if (morefiles) { ++ morefiles = 0; ++ } else { ++ seen_init(); ++ } ++ + spooldir = opendir(config->spooldir); + if (spooldir == NULL) + err(1, "reading queue"); + +- seen_init(); + while ((de = readdir(spooldir)) != NULL) { + sender = NULL; + queuef = NULL; +@@ -1335,12 +1342,22 @@ + if (asprintf(&queuefn, "%s/%s", config->spooldir, de->d_name) < 0) + goto fail; + seenit = seen(de->d_name); ++ if (inmore && seenit) { ++ free(queuefn); ++ continue; ++ } + locked = 0; + fd = open_locked(queuefn, O_RDONLY|O_NONBLOCK); + if (fd < 0) { + /* Ignore locked files */ +- if (errno != EWOULDBLOCK) ++ if (errno != EWOULDBLOCK) { ++ if (errno == EMFILE || errno == ENFILE) { ++ morefiles = 1; ++ free(queuefn); ++ break; ++ } + goto skip_item; ++ } + if (!nolock || seenit) + continue; + fd = open(queuefn, O_RDONLY); +@@ -1425,12 +1442,15 @@ + static void + run_queue(struct queue *queue) + { +- struct qitem *it; ++ struct qitem *it, *other; + + if (LIST_EMPTY(&queue->queue)) + return; + + it = go_background(queue); ++ LIST_FOREACH(other, &queue->queue, next) ++ if (other->queuef != it->queuef && other->queuef != NULL) ++ close(fileno(other->queuef)); + deliver(it); + /* NOTREACHED */ + } +@@ -1450,6 +1470,8 @@ + ID\t: %s%s\n\ + From\t: %s\n\ + To\t: %s\n--\n", it->queueid, it->locked? "*": "", it->sender, it->addr); ++ if (it->queuef != NULL) ++ close(fileno(it->queuef)); + } + } + +@@ -1571,16 +1593,21 @@ + if (argc != 0) + errx(1, "sending mail and displaying queue is" + " mutually exclusive"); +- load_queue(&lqueue, 1); +- show_queue(&lqueue); ++ do { ++ load_queue(&lqueue, 1); ++ if (!LIST_EMPTY(&lqueue.queue)) ++ show_queue(&lqueue); ++ } while (morefiles); + return (0); + } + + if (doqueue) { + if (argc != 0) + errx(1, "sending mail and queue pickup is mutually exclusive"); +- load_queue(&lqueue, 0); +- run_queue(&lqueue); ++ do { ++ load_queue(&lqueue, 0); ++ run_queue(&lqueue); ++ } while (morefiles); + return (0); + } + diff --git a/patches/series b/patches/series index b5a5c8a..ce0e157 100644 --- a/patches/series +++ b/patches/series @@ -19,3 +19,4 @@ 19-ignore-options.patch 20-parse-recipient.patch 21-smtp-auth.patch +22-openfiles.patch