Collect statistics about the total number of probes sent for a link-watcher. Only count a probe if send() doesn't return an error. If send() returns an error (for example because the port is not currently active), do not count it.
Export the value as a string, because int in jansson is limited to 32-bits (and, in general, JSON implementations do not handle 64-bits values very well).
This is useful to monitor the arp_ping and nsna_ping link-watchers.
Signed-off-by: Daniele Di Proietto ddiproietto@google.com --- v1->v2: * Reword commit message to use imperative mood. * Only count probes that were effectively sent on the wire by checking the send() return value. --- teamd/teamd_link_watch.h | 7 +++++++ teamd/teamd_lw_arp_ping.c | 21 +++++++++++++++------ teamd/teamd_lw_nsna_ping.c | 7 +++++++ teamd/teamd_lw_psr.c | 27 +++++++++++++++++++++++++-- 4 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/teamd/teamd_link_watch.h b/teamd/teamd_link_watch.h index ea7ef87..9c404be 100644 --- a/teamd/teamd_link_watch.h +++ b/teamd/teamd_link_watch.h @@ -1,6 +1,8 @@ #ifndef _TEAMD_LINK_WATCH_H_ #define _TEAMD_LINK_WATCH_H_
+#include <stdint.h> + #include "teamd_state.h"
struct teamd_link_watch { @@ -40,6 +42,8 @@ struct lw_psr_port_priv { unsigned int missed_max; int sock; unsigned int missed; + uint64_t total_probes_sent; + bool probe_sent; bool reply_received; };
@@ -77,5 +81,8 @@ int lw_psr_state_missed_max_get(struct teamd_context *ctx, int lw_psr_state_missed_get(struct teamd_context *ctx, struct team_state_gsc *gsc, void *priv); +int lw_psr_state_total_probes_sent_get(struct teamd_context *ctx, + struct team_state_gsc *gsc, + void *priv);
#endif diff --git a/teamd/teamd_lw_arp_ping.c b/teamd/teamd_lw_arp_ping.c index c3d4710..153a2e8 100644 --- a/teamd/teamd_lw_arp_ping.c +++ b/teamd/teamd_lw_arp_ping.c @@ -296,15 +296,19 @@ static int lw_ap_send(struct lw_psr_port_priv *psr_ppriv) avp.vlanh.h_vlan_encapsulated_proto = htons(ETH_P_ARP); avp.vlanh.h_vlan_TCI = htons(ap_ppriv->vlanid); ll_bcast.sll_protocol = htons(ETH_P_8021Q); - return teamd_sendto(psr_ppriv->sock, &avp, sizeof(avp), - 0, (struct sockaddr *) &ll_bcast, - sizeof(ll_bcast)); + err = teamd_sendto(psr_ppriv->sock, &avp, sizeof(avp), + 0, (struct sockaddr *) &ll_bcast, + sizeof(ll_bcast)); } else { ll_bcast.sll_protocol = htons(ETH_P_ARP); - return teamd_sendto(psr_ppriv->sock, &ap, sizeof(ap), - 0, (struct sockaddr *) &ll_bcast, - sizeof(ll_bcast)); + err = teamd_sendto(psr_ppriv->sock, &ap, sizeof(ap), + 0, (struct sockaddr *) &ll_bcast, + sizeof(ll_bcast)); } + + if (!err) + psr_ppriv->probe_sent = true; + return err; }
static int lw_ap_receive(struct lw_psr_port_priv *psr_ppriv) @@ -477,6 +481,11 @@ static const struct teamd_state_val lw_ap_state_vals[] = { .type = TEAMD_STATE_ITEM_TYPE_INT, .getter = lw_psr_state_missed_get, }, + { + .subpath = "total_probes_sent", + .type = TEAMD_STATE_ITEM_TYPE_STRING, + .getter = lw_psr_state_total_probes_sent_get, + }, };
const struct teamd_link_watch teamd_link_watch_arp_ping = { diff --git a/teamd/teamd_lw_nsna_ping.c b/teamd/teamd_lw_nsna_ping.c index 9273462..b5648a7 100644 --- a/teamd/teamd_lw_nsna_ping.c +++ b/teamd/teamd_lw_nsna_ping.c @@ -227,6 +227,8 @@ static int lw_nsnap_send(struct lw_psr_port_priv *psr_ppriv) err = teamd_sendto(nsnap_ppriv->tx_sock, &nsp, sizeof(nsp), 0, (struct sockaddr *) &sendto_addr, sizeof(sendto_addr)); + if (!err) + psr_ppriv->probe_sent = true; return err; }
@@ -324,6 +326,11 @@ static const struct teamd_state_val lw_nsnap_state_vals[] = { .type = TEAMD_STATE_ITEM_TYPE_INT, .getter = lw_psr_state_missed_get, }, + { + .subpath = "total_probes_sent", + .type = TEAMD_STATE_ITEM_TYPE_STRING, + .getter = lw_psr_state_total_probes_sent_get, + }, };
const struct teamd_link_watch teamd_link_watch_nsnap = { diff --git a/teamd/teamd_lw_psr.c b/teamd/teamd_lw_psr.c index b0a41f4..d84e4a5 100644 --- a/teamd/teamd_lw_psr.c +++ b/teamd/teamd_lw_psr.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+#include <inttypes.h> +#include <stdio.h> #include <private/misc.h> #include "teamd.h" #include "teamd_link_watch.h" @@ -57,8 +59,11 @@ static int lw_psr_callback_periodic(struct teamd_context *ctx, int events, void if (err) return err; psr_ppriv->reply_received = false; - - return psr_ppriv->ops->send(psr_ppriv); + psr_ppriv->probe_sent = false; + err = psr_ppriv->ops->send(psr_ppriv); + if (!err && psr_ppriv->probe_sent) + psr_ppriv->total_probes_sent++; + return err; }
#define LW_SOCKET_CB_NAME "lw_socket" @@ -235,3 +240,21 @@ int lw_psr_state_missed_get(struct teamd_context *ctx, gsc->data.int_val = psr_ppriv->missed; return 0; } + +int lw_psr_state_total_probes_sent_get(struct teamd_context *ctx, + struct team_state_gsc *gsc, + void *priv) +{ + struct lw_common_port_priv *common_ppriv = priv; + struct lw_psr_port_priv *psr_ppriv = lw_psr_ppriv_get(common_ppriv); + char *str; + int err; + + err = asprintf(&str, "%"PRIu64, psr_ppriv->total_probes_sent); + if (err == -1) + return -ENOMEM; + + gsc->data.str_val.ptr = str; + gsc->data.str_val.free = true; + return 0; +}
Collect statistics about the total number of probes missed for a link-watcher. Only count a probe as missed if the previous send() hasn't failed. If the previous send() failed (for example, because the port is not currently active), do not count it as a missed probe. Do not reset the counter when the port becomes active.
Export the value as a string, because int in jansson is limited to 32-bits (and, in general, JSON implementations do not handle 64-bits values very well).
This is useful to monitor the arp_ping and nsna_ping link-watchers.
The preexisting "missed" counter is reset when the port becomes active and is incremented also when a probe was not effectively sent (for example, because the port was not active). These characteristics make the preexisting "missed" counter less useful for monitoring.
Signed-off-by: Daniele Di Proietto ddiproietto@google.com --- v1->v2: * Reword commit message to use imperative mood. --- teamd/teamd_link_watch.h | 4 ++++ teamd/teamd_lw_arp_ping.c | 5 +++++ teamd/teamd_lw_nsna_ping.c | 5 +++++ teamd/teamd_lw_psr.c | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+)
diff --git a/teamd/teamd_link_watch.h b/teamd/teamd_link_watch.h index 9c404be..3734322 100644 --- a/teamd/teamd_link_watch.h +++ b/teamd/teamd_link_watch.h @@ -43,6 +43,7 @@ struct lw_psr_port_priv { int sock; unsigned int missed; uint64_t total_probes_sent; + uint64_t total_probes_missed; bool probe_sent; bool reply_received; }; @@ -84,5 +85,8 @@ int lw_psr_state_missed_get(struct teamd_context *ctx, int lw_psr_state_total_probes_sent_get(struct teamd_context *ctx, struct team_state_gsc *gsc, void *priv); +int lw_psr_state_total_probes_missed_get(struct teamd_context *ctx, + struct team_state_gsc *gsc, + void *priv);
#endif diff --git a/teamd/teamd_lw_arp_ping.c b/teamd/teamd_lw_arp_ping.c index 153a2e8..feb8f03 100644 --- a/teamd/teamd_lw_arp_ping.c +++ b/teamd/teamd_lw_arp_ping.c @@ -486,6 +486,11 @@ static const struct teamd_state_val lw_ap_state_vals[] = { .type = TEAMD_STATE_ITEM_TYPE_STRING, .getter = lw_psr_state_total_probes_sent_get, }, + { + .subpath = "total_probes_missed", + .type = TEAMD_STATE_ITEM_TYPE_STRING, + .getter = lw_psr_state_total_probes_missed_get, + }, };
const struct teamd_link_watch teamd_link_watch_arp_ping = { diff --git a/teamd/teamd_lw_nsna_ping.c b/teamd/teamd_lw_nsna_ping.c index b5648a7..f7737f7 100644 --- a/teamd/teamd_lw_nsna_ping.c +++ b/teamd/teamd_lw_nsna_ping.c @@ -331,6 +331,11 @@ static const struct teamd_state_val lw_nsnap_state_vals[] = { .type = TEAMD_STATE_ITEM_TYPE_STRING, .getter = lw_psr_state_total_probes_sent_get, }, + { + .subpath = "total_probes_missed", + .type = TEAMD_STATE_ITEM_TYPE_STRING, + .getter = lw_psr_state_total_probes_missed_get, + }, };
const struct teamd_link_watch teamd_link_watch_nsnap = { diff --git a/teamd/teamd_lw_psr.c b/teamd/teamd_lw_psr.c index d84e4a5..03cc024 100644 --- a/teamd/teamd_lw_psr.c +++ b/teamd/teamd_lw_psr.c @@ -47,6 +47,8 @@ static int lw_psr_callback_periodic(struct teamd_context *ctx, int events, void psr_ppriv->missed = 0; } else { psr_ppriv->missed++; + if (psr_ppriv->probe_sent) + psr_ppriv->total_probes_missed++; if (psr_ppriv->missed > psr_ppriv->missed_max && link_up) { teamd_log_dbg(ctx, "%s: Missed %u replies (max %u).", tdport->ifname, psr_ppriv->missed, @@ -258,3 +260,21 @@ int lw_psr_state_total_probes_sent_get(struct teamd_context *ctx, gsc->data.str_val.free = true; return 0; } + +int lw_psr_state_total_probes_missed_get(struct teamd_context *ctx, + struct team_state_gsc *gsc, + void *priv) +{ + struct lw_common_port_priv *common_ppriv = priv; + struct lw_psr_port_priv *psr_ppriv = lw_psr_ppriv_get(common_ppriv); + char *str; + int err; + + err = asprintf(&str, "%"PRIu64, psr_ppriv->total_probes_missed); + if (err == -1) + return -ENOMEM; + + gsc->data.str_val.ptr = str; + gsc->data.str_val.free = true; + return 0; +}
Thu, Sep 02, 2021 at 02:02:10PM CEST, ddiproietto@google.com wrote:
Collect statistics about the total number of probes sent for a link-watcher. Only count a probe if send() doesn't return an error. If send() returns an error (for example because the port is not currently active), do not count it.
Export the value as a string, because int in jansson is limited to 32-bits (and, in general, JSON implementations do not handle 64-bits
Wait, that is not the reason to use string. Fix jansson first, then implement this with int.
libteam@lists.fedorahosted.org