mirror of
https://github.com/openbsd/src.git
synced 2024-12-22 16:42:56 -08:00
Better error handling when doing mrt dumps (e.g. when there is no more space
on the disk). Before the SE spinned and the RDE may even crash in these events. Found by Elisa Jasinska. OK henning@
This commit is contained in:
parent
739eccc272
commit
6236702d09
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mrt.c,v 1.64 2009/07/12 15:36:41 jsg Exp $ */
|
||||
/* $OpenBSD: mrt.c,v 1.65 2009/10/26 09:27:58 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -387,7 +387,7 @@ mrt_dump_upcall(struct rib_entry *re, void *ptr)
|
||||
}
|
||||
|
||||
void
|
||||
mrt_dump_done(void *ptr)
|
||||
mrt_done(void *ptr)
|
||||
{
|
||||
struct mrt *mrtbuf = ptr;
|
||||
|
||||
@ -541,6 +541,7 @@ mrt_write(struct mrt *mrt)
|
||||
if ((r = buf_write(&mrt->wbuf)) < 0) {
|
||||
log_warn("mrt dump aborted, mrt_write");
|
||||
mrt_clean(mrt);
|
||||
mrt_done(mrt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mrt.h,v 1.23 2009/06/29 12:22:16 claudio Exp $ */
|
||||
/* $OpenBSD: mrt.h,v 1.24 2009/10/26 09:27:58 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -303,7 +303,7 @@ void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t,
|
||||
struct peer *);
|
||||
void mrt_clear_seq(void);
|
||||
void mrt_dump_upcall(struct rib_entry *, void *);
|
||||
void mrt_dump_done(void *);
|
||||
void mrt_done(void *);
|
||||
void mrt_write(struct mrt *);
|
||||
void mrt_clean(struct mrt *);
|
||||
void mrt_init(struct imsgbuf *, struct imsgbuf *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rde.c,v 1.270 2009/10/12 15:19:30 claudio Exp $ */
|
||||
/* $OpenBSD: rde.c,v 1.271 2009/10/26 09:27:58 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@ -121,11 +121,12 @@ struct rde_dump_ctx {
|
||||
};
|
||||
|
||||
struct rde_mrt_ctx {
|
||||
struct mrt mrt;
|
||||
struct rib_context ribctx;
|
||||
struct mrt mrt;
|
||||
struct rib_context ribctx;
|
||||
LIST_ENTRY(rde_mrt_ctx) entry;
|
||||
};
|
||||
|
||||
struct mrt_head rde_mrts = LIST_HEAD_INITIALIZER(rde_mrts);
|
||||
LIST_HEAD(, rde_mrt_ctx) rde_mrts = LIST_HEAD_INITIALIZER(rde_mrts);
|
||||
u_int rde_mrt_cnt;
|
||||
|
||||
void
|
||||
@ -159,7 +160,8 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
|
||||
struct filter_set *set;
|
||||
struct nexthop *nh;
|
||||
struct rde_rib *rr;
|
||||
struct mrt *mrt, *xmrt;
|
||||
struct rde_mrt_ctx *mctx, *xmctx;
|
||||
struct mrt *mrt;
|
||||
void *newp;
|
||||
u_int pfd_elms = 0, i, j;
|
||||
int timeout;
|
||||
@ -288,9 +290,9 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
|
||||
timeout = 0;
|
||||
|
||||
i = PFD_PIPE_COUNT;
|
||||
LIST_FOREACH(mrt, &rde_mrts, entry) {
|
||||
if (mrt->wbuf.queued) {
|
||||
pfd[i].fd = mrt->wbuf.fd;
|
||||
LIST_FOREACH(mctx, &rde_mrts, entry) {
|
||||
if (mctx->mrt.wbuf.queued) {
|
||||
pfd[i].fd = mctx->mrt.wbuf.fd;
|
||||
pfd[i].events = POLLOUT;
|
||||
i++;
|
||||
}
|
||||
@ -326,20 +328,21 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
|
||||
if (pfd[PFD_PIPE_SESSION_CTL].revents & POLLIN)
|
||||
rde_dispatch_imsg_session(ibuf_se_ctl);
|
||||
|
||||
for (j = PFD_PIPE_COUNT, mrt = LIST_FIRST(&rde_mrts);
|
||||
j < i && mrt != 0; j++) {
|
||||
xmrt = LIST_NEXT(mrt, entry);
|
||||
if (pfd[j].fd == mrt->wbuf.fd &&
|
||||
for (j = PFD_PIPE_COUNT, mctx = LIST_FIRST(&rde_mrts);
|
||||
j < i && mctx != 0; j++) {
|
||||
xmctx = LIST_NEXT(mctx, entry);
|
||||
if (pfd[j].fd == mctx->mrt.wbuf.fd &&
|
||||
pfd[j].revents & POLLOUT)
|
||||
mrt_write(mrt);
|
||||
if (mrt->wbuf.queued == 0 &&
|
||||
mrt->state == MRT_STATE_REMOVE) {
|
||||
close(mrt->wbuf.fd);
|
||||
LIST_REMOVE(mrt, entry);
|
||||
free(mrt);
|
||||
mrt_write(&mctx->mrt);
|
||||
if (mctx->mrt.wbuf.queued == 0 &&
|
||||
mctx->mrt.state == MRT_STATE_REMOVE) {
|
||||
close(mctx->mrt.wbuf.fd);
|
||||
LIST_REMOVE(&mctx->ribctx, entry);
|
||||
LIST_REMOVE(mctx, entry);
|
||||
free(mctx);
|
||||
rde_mrt_cnt--;
|
||||
}
|
||||
mrt = xmrt;
|
||||
mctx = xmctx;
|
||||
}
|
||||
|
||||
rde_update_queue_runner();
|
||||
@ -352,10 +355,11 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
|
||||
if (debug)
|
||||
rde_shutdown();
|
||||
|
||||
while ((mrt = LIST_FIRST(&rde_mrts)) != NULL) {
|
||||
msgbuf_clear(&mrt->wbuf);
|
||||
close(mrt->wbuf.fd);
|
||||
LIST_REMOVE(mrt, entry);
|
||||
while ((mctx = LIST_FIRST(&rde_mrts)) != NULL) {
|
||||
msgbuf_clear(&mctx->mrt.wbuf);
|
||||
close(mctx->mrt.wbuf.fd);
|
||||
LIST_REMOVE(&mctx->ribctx, entry);
|
||||
LIST_REMOVE(mctx, entry);
|
||||
free(mrt);
|
||||
}
|
||||
|
||||
@ -2030,10 +2034,10 @@ rde_dump_mrt_new(struct mrt *mrt, pid_t pid, int fd)
|
||||
ctx->ribctx.ctx_count = RDE_RUNNER_ROUNDS;
|
||||
ctx->ribctx.ctx_rib = &ribs[id];
|
||||
ctx->ribctx.ctx_upcall = mrt_dump_upcall;
|
||||
ctx->ribctx.ctx_done = mrt_dump_done;
|
||||
ctx->ribctx.ctx_done = mrt_done;
|
||||
ctx->ribctx.ctx_arg = &ctx->mrt;
|
||||
ctx->ribctx.ctx_af = AF_UNSPEC;
|
||||
LIST_INSERT_HEAD(&rde_mrts, &ctx->mrt, entry);
|
||||
LIST_INSERT_HEAD(&rde_mrts, ctx, entry);
|
||||
rde_mrt_cnt++;
|
||||
rib_dump_r(&ctx->ribctx);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: session.c,v 1.298 2009/09/22 14:07:53 claudio Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.299 2009/10/26 09:27:58 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
|
||||
@ -189,7 +189,7 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
|
||||
struct passwd *pw;
|
||||
struct peer *p, **peer_l = NULL, *last, *next;
|
||||
struct network *net;
|
||||
struct mrt *m, **mrt_l = NULL;
|
||||
struct mrt *m, *xm, **mrt_l = NULL;
|
||||
struct filter_rule *r;
|
||||
struct pollfd *pfd = NULL;
|
||||
struct ctl_conn *ctl_conn;
|
||||
@ -345,9 +345,17 @@ session_main(struct bgpd_config *config, struct peer *cpeers,
|
||||
}
|
||||
|
||||
mrt_cnt = 0;
|
||||
LIST_FOREACH(m, &mrthead, entry)
|
||||
for (m = LIST_FIRST(&mrthead); m != NULL; m = xm) {
|
||||
xm = LIST_NEXT(m, entry);
|
||||
if (m->state == MRT_STATE_REMOVE) {
|
||||
mrt_clean(m);
|
||||
LIST_REMOVE(m, entry);
|
||||
free(m);
|
||||
continue;
|
||||
}
|
||||
if (m->wbuf.queued)
|
||||
mrt_cnt++;
|
||||
}
|
||||
|
||||
if (mrt_cnt > mrt_l_elms) {
|
||||
if ((newp = realloc(mrt_l, sizeof(struct mrt *) *
|
||||
|
Loading…
Reference in New Issue
Block a user