From 67d8ab44192c0cf7e54831adb628115b09b38c05 Mon Sep 17 00:00:00 2001 From: martijn Date: Fri, 14 Oct 2022 15:26:58 +0000 Subject: [PATCH] Add an agentx_retry call. If a session, agentcaps, region, index, or object doesn't properly open because of an error returned by the AgentX master it remained closed until a reconnect. This new function call walks the tree and tries to reopen everything in a closed state. OK sthen@ --- lib/libagentx/Symbols.list | 1 + lib/libagentx/agentx.3 | 13 ++++- lib/libagentx/agentx.c | 101 +++++++++++++++++++++++++++++++++++- lib/libagentx/agentx.h | 3 +- lib/libagentx/shlib_version | 2 +- 5 files changed, 115 insertions(+), 5 deletions(-) diff --git a/lib/libagentx/Symbols.list b/lib/libagentx/Symbols.list index 6eda2be8ae0..a5c8bf7c585 100644 --- a/lib/libagentx/Symbols.list +++ b/lib/libagentx/Symbols.list @@ -4,6 +4,7 @@ agentx_log_info agentx_log_debug agentx agentx_connect +agentx_retry agentx_read agentx_write agentx_wantwrite diff --git a/lib/libagentx/agentx.3 b/lib/libagentx/agentx.3 index d45a3ae885a..aaa14435cef 100644 --- a/lib/libagentx/agentx.3 +++ b/lib/libagentx/agentx.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: agentx.3,v 1.8 2022/03/31 17:27:15 naddy Exp $ +.\" $OpenBSD: agentx.3,v 1.9 2022/10/14 15:26:58 martijn Exp $ .\" .\" Copyright (c) 2020 Martijn van Duren .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 31 2022 $ +.Dd $Mdocdate: October 14 2022 $ .Dt AGENTX 3 .Os .Sh NAME @@ -24,6 +24,7 @@ .Nm agentx_log_debug , .Nm agentx , .Nm agentx_connect , +.Nm agentx_retry , .Nm agentx_read , .Nm agentx_write , .Nm agentx_wantwrite , @@ -95,6 +96,8 @@ .Ft void .Fn agentx_connect "struct agentx *sa" "int fd" .Ft void +.Fn agentx_retry "struct agentx *sa" +.Ft void .Fn agentx_read "struct agentx *sa" .Ft void .Fn agentx_write "struct agentx *sa" @@ -367,6 +370,12 @@ is ready for a write, the function .Fn agentx_write should be called. .Pp +If any of the session, agentcaps, region, index, or objects failed to enable +correctly +.Pq as can be seen by the admin through the logs +they can be retried through +.Fn agentx_retry. +.Pp .Fa sa can be freed via .Fn agentx_free . diff --git a/lib/libagentx/agentx.c b/lib/libagentx/agentx.c index 149cd7cf065..4902069d093 100644 --- a/lib/libagentx/agentx.c +++ b/lib/libagentx/agentx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: agentx.c,v 1.18 2022/10/14 15:20:33 martijn Exp $ */ +/* $OpenBSD: agentx.c,v 1.19 2022/10/14 15:26:58 martijn Exp $ */ /* * Copyright (c) 2019 Martijn van Duren * @@ -133,6 +133,7 @@ void (*agentx_wantwrite)(struct agentx *, int) = agentx_wantwritenow; static void agentx_reset(struct agentx *); static void agentx_free_finalize(struct agentx *); +static int agentx_session_retry(struct agentx_session *); static int agentx_session_start(struct agentx_session *); static int agentx_session_finalize(struct ax_pdu *, void *); static int agentx_session_close(struct agentx_session *, @@ -140,6 +141,7 @@ static int agentx_session_close(struct agentx_session *, static int agentx_session_close_finalize(struct ax_pdu *, void *); static void agentx_session_free_finalize(struct agentx_session *); static void agentx_session_reset(struct agentx_session *); +static int agentx_context_retry(struct agentx_context *); static void agentx_context_start(struct agentx_context *); static void agentx_context_free_finalize(struct agentx_context *); static void agentx_context_reset(struct agentx_context *); @@ -149,6 +151,7 @@ static int agentx_agentcaps_close(struct agentx_agentcaps *); static int agentx_agentcaps_close_finalize(struct ax_pdu *, void *); static void agentx_agentcaps_free_finalize(struct agentx_agentcaps *); static void agentx_agentcaps_reset(struct agentx_agentcaps *); +static int agentx_region_retry(struct agentx_region *); static int agentx_region_start(struct agentx_region *); static int agentx_region_finalize(struct ax_pdu *, void *); static int agentx_region_close(struct agentx_region *); @@ -229,6 +232,25 @@ agentx_connect(struct agentx *ax, int fd) agentx_finalize(ax, fd); } +void +agentx_retry(struct agentx *ax) +{ + struct agentx_session *axs; + + if (ax->ax_fd == -1) + return; + + TAILQ_FOREACH(axs, &(ax->ax_sessions), axs_ax_sessions) { + if (axs->axs_cstate == AX_CSTATE_OPEN) { + if (agentx_session_retry(axs) == -1) + return; + } else if (axs->axs_cstate == AX_CSTATE_CLOSE) { + if (agentx_session_start(axs) == -1) + return; + } + } +} + static void agentx_start(struct agentx *ax) { @@ -401,6 +423,26 @@ agentx_session(struct agentx *ax, uint32_t oid[], return axs; } +static int +agentx_session_retry(struct agentx_session *axs) +{ + struct agentx_context *axc; + +#ifdef AX_DEBUG + if (axs->axs_cstate != AX_CSTATE_OPEN) + agentx_log_axs_fatalx(axs, "%s: unexpected retry", __func__); +#endif + + TAILQ_FOREACH(axc, &(axs->axs_contexts), axc_axs_contexts) { + if (axc->axc_cstate == AX_CSTATE_OPEN) { + if (agentx_context_retry(axc) == -1) + return -1; + } else if (axc->axc_cstate == AX_CSTATE_CLOSE) + agentx_context_start(axc); + } + return 0; +} + static int agentx_session_start(struct agentx_session *axs) { @@ -628,6 +670,36 @@ agentx_context(struct agentx_session *axs, const char *name) return axc; } +static int +agentx_context_retry(struct agentx_context *axc) +{ + struct agentx_agentcaps *axa; + struct agentx_region *axr; + +#ifdef AX_DEBUG + if (axc->axc_cstate != AX_CSTATE_OPEN) + agentx_log_axc_fatalx(axc, "%s: unexpected retry", __func__); +#endif + + TAILQ_FOREACH(axa, &(axc->axc_agentcaps), axa_axc_agentcaps) { + if (axa->axa_cstate == AX_CSTATE_CLOSE) { + if (agentx_agentcaps_start(axa) == -1) + return -1; + } + } + TAILQ_FOREACH(axr, &(axc->axc_regions), axr_axc_regions) { + if (axr->axr_cstate == AX_CSTATE_OPEN) { + if (agentx_region_retry(axr) == -1) + return -1; + } else if (axr->axr_cstate == AX_CSTATE_CLOSE) { + if (agentx_region_start(axr) == -1) + return -1; + } + } + return 0; +} + + static void agentx_context_start(struct agentx_context *axc) { @@ -1076,6 +1148,33 @@ agentx_region(struct agentx_context *axc, uint32_t oid[], return axr; } +static int +agentx_region_retry(struct agentx_region *axr) +{ + struct agentx_index *axi; + struct agentx_object *axo; + +#ifdef AX_DEBUG + if (axr->axr_cstate != AX_CSTATE_OPEN) + agentx_log_axc_fatalx(axr->axr_axc, + "%s: unexpected retry", __func__); +#endif + + TAILQ_FOREACH(axi, &(axr->axr_indices), axi_axr_indices) { + if (axi->axi_cstate == AX_CSTATE_CLOSE) { + if (agentx_index_start(axi) == -1) + return -1; + } + } + TAILQ_FOREACH(axo, &(axr->axr_objects), axo_axr_objects) { + if (axo->axo_cstate == AX_CSTATE_CLOSE) { + if (agentx_object_start(axo) == -1) + return -1; + } + } + return 0; +} + static int agentx_region_start(struct agentx_region *axr) { diff --git a/lib/libagentx/agentx.h b/lib/libagentx/agentx.h index 8f338d44927..fa6bcee2d80 100644 --- a/lib/libagentx/agentx.h +++ b/lib/libagentx/agentx.h @@ -1,4 +1,4 @@ -/* $OpenBSD: agentx.h,v 1.6 2021/10/24 18:03:27 martijn Exp $ */ +/* $OpenBSD: agentx.h,v 1.7 2022/10/14 15:26:58 martijn Exp $ */ /* * Copyright (c) 2019 Martijn van Duren * @@ -55,6 +55,7 @@ extern void (*agentx_log_debug)(const char *, ...) struct agentx *agentx(void (*)(struct agentx *, void *, int), void *); void agentx_connect(struct agentx *, int); +void agentx_retry(struct agentx *); void agentx_read(struct agentx *); void agentx_write(struct agentx *); extern void (*agentx_wantwrite)(struct agentx *, int); diff --git a/lib/libagentx/shlib_version b/lib/libagentx/shlib_version index 1edea46de91..893819d18ff 100644 --- a/lib/libagentx/shlib_version +++ b/lib/libagentx/shlib_version @@ -1,2 +1,2 @@ major=1 -minor=0 +minor=1 -- 2.20.1