diff options
author | Eric Faurot <eric@cvs.openbsd.org> | 2011-11-07 11:14:11 +0000 |
---|---|---|
committer | Eric Faurot <eric@cvs.openbsd.org> | 2011-11-07 11:14:11 +0000 |
commit | 2f7e438913ef43d94258d65589028eacfa4b0c6d (patch) | |
tree | 84cf1fd5908b6867a9577350a524c7a374d0c8b4 /usr.sbin | |
parent | e30baf630d6c7222afb76ecf9ac7cf60dc2f6de6 (diff) |
Let the smtpd process handle the enqueueing of offline messages at
startup, rather than playing tricks with the runner. This will allow
further simplifications and improvements in the runner/queue.
ok gilles@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/smtpd/queue.c | 6 | ||||
-rw-r--r-- | usr.sbin/smtpd/ramqueue.c | 25 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 20 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 143 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 3 |
5 files changed, 91 insertions, 106 deletions
diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index c041225b4a9..9d18574c42f 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.109 2011/10/26 20:47:31 gilles Exp $ */ +/* $OpenBSD: queue.c,v 1.110 2011/11/07 11:14:10 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -196,10 +196,6 @@ queue_imsg(struct imsgev *iev, struct imsg *imsg) if (iev->proc == PROC_PARENT) { switch (imsg->hdr.type) { - case IMSG_PARENT_ENQUEUE_OFFLINE: - queue_pass_to_runner(iev, imsg); - return; - case IMSG_CTL_VERBOSE: log_verbose(*(int *)imsg->data); queue_pass_to_runner(iev, imsg); diff --git a/usr.sbin/smtpd/ramqueue.c b/usr.sbin/smtpd/ramqueue.c index ff95dfef1ed..570b0cf62fd 100644 --- a/usr.sbin/smtpd/ramqueue.c +++ b/usr.sbin/smtpd/ramqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ramqueue.c,v 1.24 2011/10/27 14:32:57 chl Exp $ */ +/* $OpenBSD: ramqueue.c,v 1.25 2011/11/07 11:14:10 eric Exp $ */ /* * Copyright (c) 2011 Gilles Chehade <gilles@openbsd.org> @@ -45,7 +45,6 @@ void ramqueue_insert(struct ramqueue *, struct envelope *, time_t); int ramqueue_host_cmp(struct ramqueue_host *, struct ramqueue_host *); void ramqueue_put_host(struct ramqueue *, struct ramqueue_host *); void ramqueue_put_batch(struct ramqueue *, struct ramqueue_batch *); -int ramqueue_load_offline(struct ramqueue *); static int ramqueue_expire(struct envelope *, time_t); static time_t ramqueue_next_schedule(struct envelope *, time_t); @@ -111,28 +110,6 @@ ramqueue_batch_first_envelope(struct ramqueue_batch *rq_batch) } int -ramqueue_load_offline(struct ramqueue *rqueue) -{ - char path[MAXPATHLEN]; - static struct qwalk *q = NULL; - - log_debug("ramqueue: offline queue loading in progress"); - if (q == NULL) - q = qwalk_new(PATH_OFFLINE); - while (qwalk(q, path)) { - imsg_compose_event(env->sc_ievs[PROC_QUEUE], - IMSG_PARENT_ENQUEUE_OFFLINE, PROC_PARENT, 0, -1, path, - strlen(path) + 1); - log_debug("ramqueue: offline queue loading interrupted"); - return 0; - } - qwalk_close(q); - q = NULL; - log_debug("ramqueue: offline queue loading over"); - return 1; -} - -int ramqueue_load(struct ramqueue *rqueue, time_t *nsched) { char path[MAXPATHLEN]; diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index cad84049f80..3ec10dcd932 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.122 2011/10/27 14:32:57 chl Exp $ */ +/* $OpenBSD: runner.c,v 1.123 2011/11/07 11:14:10 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -128,10 +128,6 @@ runner_imsg(struct imsgev *iev, struct imsg *imsg) stat_decrement(STATS_MTA_SESSION); return; - case IMSG_PARENT_ENQUEUE_OFFLINE: - /* runner_process_offline();*/ - return; - case IMSG_SMTP_ENQUEUE: e = imsg->data; if (imsg->fd < 0 || !bounce_session(imsg->fd, e)) { @@ -306,7 +302,6 @@ runner_timeout(int fd, short event, void *p) struct ramqueue_envelope *rq_evp; struct timeval tv; static int rq_done = 0; - static int rq_off_done = 0; time_t nsched; time_t curtm; @@ -317,15 +312,6 @@ runner_timeout(int fd, short event, void *p) if (rq_evp) nsched = rq_evp->sched; - - /* fetch one offline message at a time to prevent a huge - * offline queue from hogging the deliveries of incoming - * messages. - */ - if (! rq_off_done) - rq_off_done = ramqueue_load_offline(rqueue); - - /* load as many envelopes as possible from disk-queue to * ram-queue until a schedulable envelope is found. */ @@ -346,13 +332,13 @@ runner_timeout(int fd, short event, void *p) } if (rq_evp == NULL || - (rq_done && rq_off_done && ramqueue_is_empty(rqueue))) { + (rq_done && ramqueue_is_empty(rqueue))) { log_debug("runner: nothing to schedule, wake me up. zZzZzZ"); return; } /* disk-queues not fully loaded, no time for sleeping */ - if (!rq_done || !rq_off_done) + if (!rq_done) nsched = 0; else { nsched = nsched - curtm; diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 60fb1190e21..90d95a2b6e9 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.134 2011/10/26 20:47:31 gilles Exp $ */ +/* $OpenBSD: smtpd.c,v 1.135 2011/11/07 11:14:10 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -28,6 +28,7 @@ #include <sys/uio.h> #include <sys/mman.h> +#include <dirent.h> #include <err.h> #include <errno.h> #include <fcntl.h> @@ -54,7 +55,6 @@ static void parent_send_config_client_certs(void); static void parent_send_config_ruleset(int); static void parent_sig_handler(int, short, void *); static void forkmda(struct imsgev *, u_int32_t, struct deliver *); -static int parent_enqueue_offline(char *); static int parent_forward_open(char *); static int path_starts_with(char *, char *); static void fork_peers(void); @@ -62,25 +62,30 @@ static struct child *child_lookup(pid_t); static struct child *child_add(pid_t, int, int); static void child_del(pid_t); -static int queueing_add(char *); -static void queueing_done(void); +static void offline_scan(int, short, void *); +static int offline_add(char *); +static void offline_done(void); +static int offline_enqueue(char *); -struct queueing { - TAILQ_ENTRY(queueing) entry; +struct offline { + TAILQ_ENTRY(offline) entry; char *path; }; -#define QUEUEING_MAX 5 -static size_t queueing_running = 0; -TAILQ_HEAD(, queueing) queueing_q; +#define OFFLINE_READMAX 20 +#define OFFLINE_QUEUEMAX 5 +static size_t offline_running = 0; +TAILQ_HEAD(, offline) offline_q; + +static struct event offline_ev; +static struct timeval offline_timeout; + extern char **environ; void (*imsg_callback)(struct imsgev *, struct imsg *); struct smtpd *env = NULL; -int __b64_pton(char const *, unsigned char *, size_t); - static void parent_imsg(struct imsgev *iev, struct imsg *imsg) { @@ -126,17 +131,6 @@ parent_imsg(struct imsgev *iev, struct imsg *imsg) } } - if (iev->proc == PROC_QUEUE) { - switch (imsg->hdr.type) { - case IMSG_PARENT_ENQUEUE_OFFLINE: - if (! queueing_add(imsg->data)) - imsg_compose_event(iev, - IMSG_PARENT_ENQUEUE_OFFLINE, 0, 0, -1, - NULL, 0); - return; - } - } - if (iev->proc == PROC_MDA) { switch (imsg->hdr.type) { case IMSG_PARENT_FORK_MDA: @@ -383,14 +377,9 @@ parent_sig_handler(int sig, short event, void *p) case CHILD_ENQUEUE_OFFLINE: if (fail) - log_warnx("couldn't enqueue offline " + log_warnx("smtpd: couldn't enqueue offline " "message; smtpctl %s", cause); - else - log_debug("offline message enqueued"); - imsg_compose_event(env->sc_ievs[PROC_QUEUE], - IMSG_PARENT_ENQUEUE_OFFLINE, 0, 0, -1, - NULL, 0); - queueing_done(); + offline_done(); break; default: @@ -440,7 +429,7 @@ main(int argc, char *argv[]) log_init(1); - TAILQ_INIT(&queueing_q); + TAILQ_INIT(&offline_q); while ((c = getopt(argc, argv, "dD:nf:T:v")) != -1) { switch (c) { @@ -549,6 +538,12 @@ main(int argc, char *argv[]) bzero(&tv, sizeof(tv)); evtimer_add(&env->sc_ev, &tv); + /* defer offline scanning for a second */ + evtimer_set(&offline_ev, offline_scan, NULL); + offline_timeout.tv_sec = 1; + offline_timeout.tv_usec = 0; + evtimer_add(&offline_ev, &offline_timeout); + if (event_dispatch() < 0) fatal("event_dispatch"); @@ -880,51 +875,84 @@ forkmda(struct imsgev *iev, u_int32_t id, #undef error #undef error2 +static void +offline_scan(int fd, short ev, void *arg) +{ + DIR *dir = arg; + struct dirent *d; + int n = 0; + + if (dir == NULL) { + log_debug("smtpd: scanning offline queue..."); + if ((dir = opendir(PATH_SPOOL PATH_OFFLINE)) == NULL) + errx(1, "smtpd: opendir"); + } + + while((d = readdir(dir)) != NULL) { + if (d->d_type != DT_REG) + continue; + + offline_add(d->d_name); + + if ((n++) == OFFLINE_READMAX) { + evtimer_set(&offline_ev, offline_scan, dir); + offline_timeout.tv_sec = 0; + offline_timeout.tv_usec = 100000; + evtimer_add(&offline_ev, &offline_timeout); + return; + } + } + + log_debug("smtpd: offline scanning done"); + closedir(dir); +} + static int -parent_enqueue_offline(char *runner_path) +offline_enqueue(char *name) { - char path[MAXPATHLEN]; + char path[MAXPATHLEN]; struct user_backend *ub; struct user u; struct stat sb; pid_t pid; - log_debug("parent_enqueue_offline: path %s", runner_path); - - if (! bsnprintf(path, sizeof(path), "%s%s", PATH_SPOOL, runner_path)) - fatalx("parent_enqueue_offline: filename too long"); + strlcpy(path, PATH_SPOOL PATH_OFFLINE "/", sizeof path); + if (strlcat(path, name, sizeof path) >= sizeof path) + fatalx("smtpd: path name too long"); if (! path_starts_with(path, PATH_SPOOL PATH_OFFLINE)) - fatalx("parent_enqueue_offline: path outside offline dir"); + fatalx("smtpd: path outside offline dir"); + + log_debug("smtpd: enqueueing offline message %s", path); if (lstat(path, &sb) == -1) { if (errno == ENOENT) { - log_warn("parent_enqueue_offline: %s", path); + log_warn("smtpd: lstat: %s", path); return (0); } - fatal("parent_enqueue_offline: lstat"); + fatal("lstat"); } if (chflags(path, 0) == -1) { if (errno == ENOENT) { - log_warn("parent_enqueue_offline: %s", path); + log_warn("smtpd: chflags: %s", path); return (0); } - fatal("parent_enqueue_offline: chflags"); + fatal("chflags"); } ub = user_backend_lookup(USER_GETPWNAM); bzero(&u, sizeof (u)); errno = 0; if (! ub->getbyuid(&u, sb.st_uid)) { - log_warn("parent_enqueue_offline: getpwuid for uid %d failed", + log_warn("smtpd: getpwuid for uid %d failed", sb.st_uid); unlink(path); return (0); } if (! S_ISREG(sb.st_mode)) { - log_warnx("file %s (uid %d) not regular, removing", path, sb.st_uid); + log_warnx("smtpd: file %s (uid %d) not regular, removing", path, sb.st_uid); if (S_ISDIR(sb.st_mode)) rmdir(path); else @@ -933,7 +961,7 @@ parent_enqueue_offline(char *runner_path) } if ((pid = fork()) == -1) - fatal("parent_enqueue_offline: fork"); + fatal("offline_enqueue: fork"); if (pid == 0) { char *envp[2], *p, *tmp; @@ -988,43 +1016,43 @@ parent_enqueue_offline(char *runner_path) _exit(1); } - queueing_running++; + offline_running++; child_add(pid, CHILD_ENQUEUE_OFFLINE, -1); return (1); } static int -queueing_add(char *path) +offline_add(char *path) { - struct queueing *q; + struct offline *q; - if (queueing_running < QUEUEING_MAX) + if (offline_running < OFFLINE_QUEUEMAX) /* skip queue */ - return parent_enqueue_offline(path); + return offline_enqueue(path); q = malloc(sizeof(*q) + strlen(path) + 1); if (q == NULL) return (-1); q->path = (char *)q + sizeof(*q); memmove(q->path, path, strlen(path) + 1); - TAILQ_INSERT_TAIL(&queueing_q, q, entry); + TAILQ_INSERT_TAIL(&offline_q, q, entry); return (1); } static void -queueing_done(void) +offline_done(void) { - struct queueing *q; + struct offline *q; - queueing_running--; + offline_running--; - while(queueing_running < QUEUEING_MAX) { - if ((q = TAILQ_FIRST(&queueing_q)) == NULL) + while(offline_running < OFFLINE_QUEUEMAX) { + if ((q = TAILQ_FIRST(&offline_q)) == NULL) break; /* all done */ - TAILQ_REMOVE(&queueing_q, q, entry); - parent_enqueue_offline(q->path); + TAILQ_REMOVE(&offline_q, q, entry); + offline_enqueue(q->path); free(q); } } @@ -1211,7 +1239,6 @@ imsg_to_str(int type) CASE(IMSG_BATCH_CLOSE); CASE(IMSG_BATCH_DONE); - CASE(IMSG_PARENT_ENQUEUE_OFFLINE); CASE(IMSG_PARENT_FORWARD_OPEN); CASE(IMSG_PARENT_FORK_MDA); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index 2738b63b6bd..bf16fbbbe8d 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.247 2011/10/26 20:47:31 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.248 2011/11/07 11:14:10 eric Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -174,7 +174,6 @@ enum imsg_type { IMSG_BATCH_CLOSE, IMSG_BATCH_DONE, - IMSG_PARENT_ENQUEUE_OFFLINE, IMSG_PARENT_FORWARD_OPEN, IMSG_PARENT_FORK_MDA, |