diff options
-rw-r--r-- | usr.sbin/smtpd/control.c | 123 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.c | 3 | ||||
-rw-r--r-- | usr.sbin/smtpd/parser.h | 3 | ||||
-rw-r--r-- | usr.sbin/smtpd/queue.c | 14 | ||||
-rw-r--r-- | usr.sbin/smtpd/runner.c | 14 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp.c | 12 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtp_session.c | 8 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpctl.c | 47 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.c | 63 | ||||
-rw-r--r-- | usr.sbin/smtpd/smtpd.h | 36 |
10 files changed, 310 insertions, 13 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c index 387751f1c02..2dafdf100b4 100644 --- a/usr.sbin/smtpd/control.c +++ b/usr.sbin/smtpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.10 2009/01/27 23:39:41 gilles Exp $ */ +/* $OpenBSD: control.c,v 1.11 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -58,6 +58,7 @@ void control_dispatch_mfa(int, short, void *); void control_dispatch_queue(int, short, void *); void control_dispatch_runner(int, short, void *); void control_dispatch_smtp(int, short, void *); +void control_dispatch_parent(int, short, void *); struct ctl_connlist ctl_conns; @@ -90,6 +91,7 @@ control(struct smtpd *env) { PROC_RUNNER, control_dispatch_runner }, { PROC_SMTP, control_dispatch_smtp }, { PROC_MFA, control_dispatch_mfa }, + { PROC_PARENT, control_dispatch_parent }, }; switch (pid = fork()) { @@ -162,7 +164,7 @@ control(struct smtpd *env) TAILQ_INIT(&ctl_conns); - config_peers(env, peers, 4); + config_peers(env, peers, 5); control_listen(env); event_dispatch(); control_shutdown(); @@ -346,6 +348,17 @@ control_dispatch_ext(int fd, short event, void *arg) messagep, sizeof(*messagep)); break; } + case IMSG_STATS: { + struct stats s; + + s.fd = fd; + imsg_compose(env->sc_ibufs[PROC_PARENT], IMSG_STATS, 0, 0, -1, &s, sizeof(s)); + imsg_compose(env->sc_ibufs[PROC_QUEUE], IMSG_STATS, 0, 0, -1, &s, sizeof(s)); + imsg_compose(env->sc_ibufs[PROC_RUNNER], IMSG_STATS, 0, 0, -1, &s, sizeof(s)); + imsg_compose(env->sc_ibufs[PROC_SMTP], IMSG_STATS, 0, 0, -1, &s, sizeof(s)); + + break; + } case IMSG_CTL_SHUTDOWN: /* NEEDS_FIX */ log_debug("received shutdown request"); @@ -461,6 +474,67 @@ badcred: } void +control_dispatch_parent(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + ibuf = env->sc_ibufs[PROC_PARENT]; + switch (event) { + case EV_READ: + if ((n = imsg_read(ibuf)) == -1) + fatal("imsg_read_error"); + if (n == 0) { + /* this pipe is dead, so remove the event handler */ + event_del(&ibuf->ev); + event_loopexit(NULL); + return; + } + break; + case EV_WRITE: + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + return; + default: + fatalx("unknown event"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatal("control_dispatch_parent: imsg_read error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_STATS: { + struct stats *s; + struct ctl_conn *c; + + s = imsg.data; + if ((c = control_connbyfd(s->fd)) == NULL) { + log_warn("control_dispatch_parent: fd %d not found", s->fd); + return; + } + + imsg_compose(&c->ibuf, IMSG_PARENT_STATS, 0, 0, -1, + &s->u.parent, sizeof(s->u.parent)); + + break; + } + default: + log_debug("control_dispatch_parent: unexpected imsg %d", + imsg.hdr.type); + break; + } + imsg_free(&imsg); + } + imsg_event_add(ibuf); +} + +void control_dispatch_lka(int sig, short event, void *p) { struct smtpd *env = p; @@ -694,6 +768,21 @@ control_dispatch_queue(int sig, short event, void *p) &ss->msg, sizeof(struct message)); break; } + case IMSG_STATS: { + struct stats *s; + struct ctl_conn *c; + + s = imsg.data; + if ((c = control_connbyfd(s->fd)) == NULL) { + log_warn("control_dispatch_queue: fd %d not found", s->fd); + return; + } + + imsg_compose(&c->ibuf, IMSG_QUEUE_STATS, 0, 0, -1, + &s->u.queue, sizeof(s->u.queue)); + + break; + } default: log_debug("control_dispatch_queue: unexpected imsg %d", imsg.hdr.type); @@ -740,6 +829,21 @@ control_dispatch_runner(int sig, short event, void *p) break; switch (imsg.hdr.type) { + case IMSG_STATS: { + struct stats *s; + struct ctl_conn *c; + + s = imsg.data; + if ((c = control_connbyfd(s->fd)) == NULL) { + log_warn("control_dispatch_runner: fd %d not found", s->fd); + return; + } + + imsg_compose(&c->ibuf, IMSG_RUNNER_STATS, 0, 0, -1, + &s->u.runner, sizeof(s->u.runner)); + + break; + } default: log_debug("control_dispatch_runner: unexpected imsg %d", imsg.hdr.type); @@ -786,6 +890,21 @@ control_dispatch_smtp(int sig, short event, void *p) break; switch (imsg.hdr.type) { + case IMSG_STATS: { + struct stats *s; + struct ctl_conn *c; + + s = imsg.data; + if ((c = control_connbyfd(s->fd)) == NULL) { + log_warn("control_dispatch_queue: fd %d not found", s->fd); + return; + } + + imsg_compose(&c->ibuf, IMSG_SMTP_STATS, 0, 0, -1, + &s->u.smtp, sizeof(s->u.smtp)); + + break; + } default: log_debug("control_dispatch_smtp: unexpected imsg %d", imsg.hdr.type); diff --git a/usr.sbin/smtpd/parser.c b/usr.sbin/smtpd/parser.c index ae1a886b307..54386cb678d 100644 --- a/usr.sbin/smtpd/parser.c +++ b/usr.sbin/smtpd/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.5 2009/01/04 22:35:09 gilles Exp $ */ +/* $OpenBSD: parser.c,v 1.6 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -72,6 +72,7 @@ static const struct token t_main[] = { static const struct token t_show[] = { {KEYWORD, "queue", SHOW_QUEUE, NULL}, {KEYWORD, "runqueue", SHOW_RUNQUEUE, NULL}, + {KEYWORD, "stats", SHOW_STATS, NULL}, {ENDTOKEN, "", NONE, NULL} }; diff --git a/usr.sbin/smtpd/parser.h b/usr.sbin/smtpd/parser.h index 7cf6e3bf94d..21d4e517b1b 100644 --- a/usr.sbin/smtpd/parser.h +++ b/usr.sbin/smtpd/parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.h,v 1.5 2009/01/04 22:35:09 gilles Exp $ */ +/* $OpenBSD: parser.h,v 1.6 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -23,6 +23,7 @@ enum actions { MONITOR, SHOW_QUEUE, SHOW_RUNQUEUE, + SHOW_STATS, PAUSE_MDA, PAUSE_MTA, PAUSE_SMTP, diff --git a/usr.sbin/smtpd/queue.c b/usr.sbin/smtpd/queue.c index 0b4d1857d4a..8e33f7333ce 100644 --- a/usr.sbin/smtpd/queue.c +++ b/usr.sbin/smtpd/queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.c,v 1.52 2009/01/29 12:43:25 jacekm Exp $ */ +/* $OpenBSD: queue.c,v 1.53 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -55,6 +55,8 @@ int queue_remove_layout_envelope(char *, struct message *); int queue_commit_layout_message(char *, struct message *); int queue_open_layout_messagefile(char *, struct message *); +struct s_queue s_queue; + void queue_sig_handler(int sig, short event, void *p) { @@ -157,6 +159,14 @@ queue_dispatch_control(int sig, short event, void *p) break; } + case IMSG_STATS: { + struct stats *s; + + s = imsg.data; + s->u.queue = s_queue; + imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); + break; + } default: log_debug("queue_dispatch_control: unexpected imsg %d", imsg.hdr.type); @@ -234,6 +244,8 @@ queue_dispatch_smtp(int sig, short event, void *p) messagep = imsg.data; ss.id = messagep->session_id; + s_queue.inserts++; + if (! queue_commit_incoming_message(messagep)) ss.code = 421; diff --git a/usr.sbin/smtpd/runner.c b/usr.sbin/smtpd/runner.c index 7e4ce43eae2..9acb8f94e75 100644 --- a/usr.sbin/smtpd/runner.c +++ b/usr.sbin/smtpd/runner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: runner.c,v 1.27 2009/01/29 12:43:25 jacekm Exp $ */ +/* $OpenBSD: runner.c,v 1.28 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -77,6 +77,8 @@ int runner_check_loop(struct message *); struct batch *batch_record(struct smtpd *, struct message *); struct batch *batch_lookup(struct smtpd *, struct message *); +struct s_runner s_runner; + void runner_sig_handler(int sig, short event, void *p) { @@ -138,6 +140,14 @@ runner_dispatch_control(int sig, short event, void *p) case IMSG_MTA_RESUME: env->sc_opts &= ~SMTPD_MTA_PAUSED; break; + case IMSG_STATS: { + struct stats *s; + + s = imsg.data; + s->u.runner = s_runner; + imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); + break; + } default: log_debug("queue_dispatch_control: unexpected imsg %d", imsg.hdr.type); @@ -185,6 +195,7 @@ runner_dispatch_queue(int sig, short event, void *p) switch (imsg.hdr.type) { case IMSG_RUNNER_UPDATE_ENVELOPE: { + s_runner.active--; queue_message_update(imsg.data); break; } @@ -860,6 +871,7 @@ batch_record(struct smtpd *env, struct message *messagep) } TAILQ_INSERT_TAIL(&batchp->messages, messagep, entry); + s_runner.active++; return batchp; } diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c index ee77f657380..2d10a710dd5 100644 --- a/usr.sbin/smtpd/smtp.c +++ b/usr.sbin/smtpd/smtp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp.c,v 1.17 2009/01/28 19:38:46 gilles Exp $ */ +/* $OpenBSD: smtp.c,v 1.18 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -48,6 +48,8 @@ void smtp_accept(int, short, void *); void session_timeout(int, short, void *); void session_auth_pickup(struct session *, char *, size_t); +struct s_smtp s_smtp; + void smtp_sig_handler(int sig, short event, void *p) { @@ -505,6 +507,14 @@ smtp_dispatch_control(int sig, short event, void *p) case IMSG_SMTP_RESUME: smtp_resume(env); break; + case IMSG_STATS: { + struct stats *s; + + s = imsg.data; + s->u.smtp = s_smtp; + imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); + break; + } default: log_debug("smtp_dispatch_control: unexpected imsg %d", imsg.hdr.type); diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 3e6e5fdf0f2..935bed2b676 100644 --- a/usr.sbin/smtpd/smtp_session.c +++ b/usr.sbin/smtpd/smtp_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp_session.c,v 1.46 2009/01/29 15:40:35 gilles Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.47 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -73,6 +73,8 @@ int session_set_path(struct path *, char *); void session_timeout(int, short, void *); void session_cleanup(struct session *); +extern struct s_smtp s_smtp; + struct session_timeout { enum session_state state; time_t timeout; @@ -743,6 +745,8 @@ session_init(struct listener *l, struct session *s) s->s_l = l; s->s_id = queue_generate_id(); + s_smtp.clients++; + strlcpy(s->s_hostname, "<unknown>", MAXHOSTNAMELEN); strlcpy(s->s_msg.session_hostname, s->s_hostname, MAXHOSTNAMELEN); imsg_compose(s->s_env->sc_ibufs[PROC_LKA], IMSG_LKA_HOST, 0, 0, -1, s, @@ -900,6 +904,8 @@ session_destroy(struct session *s) log_debug("session_destroy: killing client: %p", s); close(s->s_fd); + s_smtp.clients--; + if (s->s_bev != NULL) { bufferevent_free(s->s_bev); } diff --git a/usr.sbin/smtpd/smtpctl.c b/usr.sbin/smtpd/smtpctl.c index 42f150be901..dbebeaacc91 100644 --- a/usr.sbin/smtpd/smtpctl.c +++ b/usr.sbin/smtpd/smtpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpctl.c,v 1.7 2009/01/29 12:43:25 jacekm Exp $ */ +/* $OpenBSD: smtpctl.c,v 1.8 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -44,6 +44,7 @@ __dead void usage(void); int show_command_output(struct imsg*); +int show_stats_output(struct imsg *); int enqueue(int, char **); struct imsgname { @@ -168,6 +169,9 @@ connected: case RESUME_SMTP: imsg_compose(ibuf, IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); break; + case SHOW_STATS: + imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0); + break; case MONITOR: /* XXX */ break; @@ -201,6 +205,9 @@ connected: case RESUME_SMTP: done = show_command_output(&imsg); break; + case SHOW_STATS: + done = show_stats_output(&imsg); + break; case NONE: break; case MONITOR: @@ -234,3 +241,41 @@ show_command_output(struct imsg *imsg) } return (1); } + +int +show_stats_output(struct imsg *imsg) +{ + static int left = 4; + static struct s_parent s_parent; + static struct s_queue s_queue; + static struct s_runner s_runner; + static struct s_smtp s_smtp; + + switch (imsg->hdr.type) { + case IMSG_PARENT_STATS: + s_parent = *(struct s_parent *)imsg->data; + break; + case IMSG_QUEUE_STATS: + s_queue = *(struct s_queue *)imsg->data; + break; + case IMSG_RUNNER_STATS: + s_runner = *(struct s_runner *)imsg->data; + break; + case IMSG_SMTP_STATS: + s_smtp = *(struct s_smtp *)imsg->data; + break; + default: + errx(1, "show_stats_output: bad hdr type (%d)", imsg->hdr.type); + } + + left--; + if (left > 0) + return (0); + + printf("parent.uptime = %zd\n", time(NULL) - s_parent.start); + printf("queue.inserts = %zd\n", s_queue.inserts); + printf("runner.active = %zd\n", s_runner.active); + printf("smtp.clients = %zd\n", s_smtp.clients); + + return (1); +} diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 3d1d6dab8c5..96e1a9871f8 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.26 2009/01/28 19:38:46 gilles Exp $ */ +/* $OpenBSD: smtpd.c,v 1.27 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -53,6 +53,7 @@ void parent_dispatch_lka(int, short, void *); void parent_dispatch_mda(int, short, void *); void parent_dispatch_mfa(int, short, void *); void parent_dispatch_smtp(int, short, void *); +void parent_dispatch_control(int, short, void *); void parent_sig_handler(int, short, void *); int parent_open_message_file(struct batch *); int parent_mailbox_init(struct passwd *, char *); @@ -74,6 +75,7 @@ pid_t control_pid = 0; pid_t smtp_pid = 0; pid_t runner_pid = 0; +struct s_parent s_parent; int __b64_pton(char const *, unsigned char *, size_t); @@ -449,6 +451,60 @@ parent_dispatch_smtp(int fd, short event, void *p) } void +parent_dispatch_control(int sig, short event, void *p) +{ + struct smtpd *env = p; + struct imsgbuf *ibuf; + struct imsg imsg; + ssize_t n; + + ibuf = env->sc_ibufs[PROC_CONTROL]; + switch (event) { + case EV_READ: + if ((n = imsg_read(ibuf)) == -1) + fatal("imsg_read_error"); + if (n == 0) { + /* this pipe is dead, so remove the event handler */ + event_del(&ibuf->ev); + event_loopexit(NULL); + return; + } + break; + case EV_WRITE: + if (msgbuf_write(&ibuf->w) == -1) + fatal("msgbuf_write"); + imsg_event_add(ibuf); + return; + default: + fatalx("unknown event"); + } + + for (;;) { + if ((n = imsg_get(ibuf, &imsg)) == -1) + fatal("parent_dispatch_control: imsg_read error"); + if (n == 0) + break; + + switch (imsg.hdr.type) { + case IMSG_STATS: { + struct stats *s; + + s = imsg.data; + s->u.parent = s_parent; + imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, s, sizeof(*s)); + break; + } + default: + log_debug("parent_dispatch_control: unexpected imsg %d", + imsg.hdr.type); + break; + } + imsg_free(&imsg); + } + imsg_event_add(ibuf); +} + +void parent_sig_handler(int sig, short event, void *p) { int i; @@ -536,6 +592,7 @@ main(int argc, char *argv[]) struct event ev_sighup; struct timeval tv; struct peer peers[] = { + { PROC_CONTROL, parent_dispatch_control }, { PROC_LKA, parent_dispatch_lka }, { PROC_MDA, parent_dispatch_mda }, { PROC_MFA, parent_dispatch_mfa }, @@ -617,6 +674,8 @@ main(int argc, char *argv[]) setproctitle("parent"); SPLAY_INIT(&env.mdaproc_queue); + s_parent.start = time(NULL); + event_init(); signal_set(&ev_sigint, SIGINT, parent_sig_handler, &env); @@ -629,7 +688,7 @@ main(int argc, char *argv[]) signal_add(&ev_sighup, NULL); signal(SIGPIPE, SIG_IGN); - config_peers(&env, peers, 4); + config_peers(&env, peers, 5); evtimer_set(&env.sc_ev, parent_send_config, &env); bzero(&tv, sizeof(tv)); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index a1a49696ace..9ae8818cf55 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.61 2009/01/29 15:40:35 gilles Exp $ */ +/* $OpenBSD: smtpd.h,v 1.62 2009/01/29 21:59:15 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -180,6 +180,7 @@ enum imsg_type { IMSG_QUEUE_REMOVE_MESSAGE, IMSG_QUEUE_COMMIT_MESSAGE, IMSG_QUEUE_TEMPFAIL, + IMSG_QUEUE_STATS, IMSG_QUEUE_REMOVE_SUBMISSION, IMSG_QUEUE_MESSAGE_UPDATE, @@ -187,6 +188,7 @@ enum imsg_type { IMSG_QUEUE_MESSAGE_FILE, IMSG_RUNNER_UPDATE_ENVELOPE, + IMSG_RUNNER_STATS, IMSG_BATCH_CREATE, IMSG_BATCH_APPEND, @@ -195,6 +197,7 @@ enum imsg_type { IMSG_PARENT_MAILBOX_OPEN, IMSG_PARENT_MESSAGE_OPEN, IMSG_PARENT_MAILBOX_RENAME, + IMSG_PARENT_STATS, IMSG_PARENT_AUTHENTICATE, IMSG_PARENT_SEND_CONFIG, @@ -202,10 +205,13 @@ enum imsg_type { IMSG_MDA_PAUSE, IMSG_MTA_PAUSE, IMSG_SMTP_PAUSE, + IMSG_SMTP_STATS, IMSG_MDA_RESUME, IMSG_MTA_RESUME, - IMSG_SMTP_RESUME + IMSG_SMTP_RESUME, + + IMSG_STATS }; #define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) @@ -634,6 +640,32 @@ struct smtpd { SPLAY_HEAD(mdaproctree, mdaproc) mdaproc_queue; }; +struct s_parent { + time_t start; +}; + +struct s_queue { + size_t inserts; +}; + +struct s_runner { + size_t active; +}; + +struct s_smtp { + size_t clients; +}; + +struct stats { + int fd; + union u_stats { + struct s_parent parent; + struct s_queue queue; + struct s_runner runner; + struct s_smtp smtp; + } u; +}; + struct submit_status { u_int64_t id; int code; |