Add an agentx_retry call.
authormartijn <martijn@openbsd.org>
Fri, 14 Oct 2022 15:26:58 +0000 (15:26 +0000)
committermartijn <martijn@openbsd.org>
Fri, 14 Oct 2022 15:26:58 +0000 (15:26 +0000)
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
lib/libagentx/agentx.3
lib/libagentx/agentx.c
lib/libagentx/agentx.h
lib/libagentx/shlib_version

index 6eda2be..a5c8bf7 100644 (file)
@@ -4,6 +4,7 @@ agentx_log_info
 agentx_log_debug
 agentx
 agentx_connect
+agentx_retry
 agentx_read
 agentx_write
 agentx_wantwrite
index d45a3ae..aaa1443 100644 (file)
@@ -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 <martijn@openbsd.org>
 .\"
@@ -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 .
index 149cd7c..4902069 100644 (file)
@@ -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 <martijn@openbsd.org>
  *
@@ -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)
 {
index 8f338d4..fa6bcee 100644 (file)
@@ -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 <martijn@openbsd.org>
  *
@@ -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);