teamd: fix possible race in master ifname callback (#4109)
- What I did Ported a fix from libteam master to our master. Fixes #4070 Fixes #3649 - How I did it Applied patch jpirko/libteam@c723737 from upstream. - How to verify it Build image for your DUT and warm-reboot your DUT 10 times. Check that all PortChannels are up and no error messages in teamd.log
This commit is contained in:
parent
9ea38c417c
commit
6c2801b846
@ -0,0 +1,101 @@
|
|||||||
|
From c0eb9e4bfe1c6a0e77f02b1459d91498c1a3dcff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Pavel Shirshov <pavelsh@microsoft.com>
|
||||||
|
Date: Tue, 4 Feb 2020 09:39:08 -0800
|
||||||
|
Subject: [PATCH 1/1] teamd: fix possible race in master ifname callback
|
||||||
|
|
||||||
|
---
|
||||||
|
teamd/teamd.h | 2 ++
|
||||||
|
teamd/teamd_link_watch.c | 13 ++++++++++---
|
||||||
|
teamd/teamd_per_port.c | 24 +++++++++++++++++++-----
|
||||||
|
3 files changed, 31 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/teamd/teamd.h b/teamd/teamd.h
|
||||||
|
index 418214d..1ce120e 100644
|
||||||
|
--- a/teamd/teamd.h
|
||||||
|
+++ b/teamd/teamd.h
|
||||||
|
@@ -334,6 +334,8 @@ int teamd_port_remove_all(struct teamd_context *ctx);
|
||||||
|
void teamd_port_obj_remove_all(struct teamd_context *ctx);
|
||||||
|
int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport,
|
||||||
|
bool *enabled);
|
||||||
|
+int teamd_port_enabled_check(struct teamd_context *ctx,
|
||||||
|
+ struct teamd_port *tdport, bool *enabled);
|
||||||
|
int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport);
|
||||||
|
int teamd_port_check_enable(struct teamd_context *ctx,
|
||||||
|
struct teamd_port *tdport,
|
||||||
|
diff --git a/teamd/teamd_link_watch.c b/teamd/teamd_link_watch.c
|
||||||
|
index 62f8267..e4b3d3f 100644
|
||||||
|
--- a/teamd/teamd_link_watch.c
|
||||||
|
+++ b/teamd/teamd_link_watch.c
|
||||||
|
@@ -423,9 +423,16 @@ static int link_watch_refresh_forced_send(struct teamd_context *ctx)
|
||||||
|
int err;
|
||||||
|
|
||||||
|
teamd_for_each_tdport(tdport, ctx) {
|
||||||
|
- err = teamd_port_enabled(ctx, tdport, &port_enabled);
|
||||||
|
- if (err)
|
||||||
|
- return err;
|
||||||
|
+ err = teamd_port_enabled_check(ctx, tdport, &port_enabled);
|
||||||
|
+ if (err) {
|
||||||
|
+ /* Looks like the options are not ready for this port.
|
||||||
|
+ * This can happen when called from
|
||||||
|
+ * link_watch_port_master_ifindex_changed(). Skip this
|
||||||
|
+ * for now, let it be handled by future call of
|
||||||
|
+ * link_watch_enabled_option_changed().
|
||||||
|
+ */
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
__set_forced_send_for_port(tdport, port_enabled);
|
||||||
|
if (port_enabled)
|
||||||
|
enabled_port_count++;
|
||||||
|
diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c
|
||||||
|
index a87e809..d10cfb2 100644
|
||||||
|
--- a/teamd/teamd_per_port.c
|
||||||
|
+++ b/teamd/teamd_per_port.c
|
||||||
|
@@ -395,19 +395,21 @@ int teamd_port_remove_ifname(struct teamd_context *ctx, const char *port_name)
|
||||||
|
return teamd_port_remove(ctx, tdport);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport,
|
||||||
|
- bool *enabled)
|
||||||
|
+int __teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport,
|
||||||
|
+ bool *enabled, bool may_fail)
|
||||||
|
{
|
||||||
|
struct team_option *option;
|
||||||
|
|
||||||
|
option = team_get_option(ctx->th, "np", "enabled", tdport->ifindex);
|
||||||
|
if (!option) {
|
||||||
|
- teamd_log_err("%s: Failed to find \"enabled\" option.",
|
||||||
|
- tdport->ifname);
|
||||||
|
+ if (!may_fail)
|
||||||
|
+ teamd_log_err("%s: Failed to find \"enabled\" option.",
|
||||||
|
+ tdport->ifname);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
if (team_get_option_type(option) != TEAM_OPTION_TYPE_BOOL) {
|
||||||
|
- teamd_log_err("Unexpected type of \"enabled\" option.");
|
||||||
|
+ if (!may_fail)
|
||||||
|
+ teamd_log_err("Unexpected type of \"enabled\" option.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -415,6 +417,18 @@ int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int teamd_port_enabled(struct teamd_context *ctx, struct teamd_port *tdport,
|
||||||
|
+ bool *enabled)
|
||||||
|
+{
|
||||||
|
+ return __teamd_port_enabled(ctx, tdport, enabled, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int teamd_port_enabled_check(struct teamd_context *ctx,
|
||||||
|
+ struct teamd_port *tdport, bool *enabled)
|
||||||
|
+{
|
||||||
|
+ return __teamd_port_enabled(ctx, tdport, enabled, true);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int teamd_port_prio(struct teamd_context *ctx, struct teamd_port *tdport)
|
||||||
|
{
|
||||||
|
int prio;
|
||||||
|
--
|
||||||
|
2.17.1.windows.2
|
||||||
|
|
@ -9,3 +9,4 @@
|
|||||||
0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch
|
0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch
|
||||||
0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch
|
0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch
|
||||||
0011-teamd-Disregard-current-state-when-considering-port-.patch
|
0011-teamd-Disregard-current-state-when-considering-port-.patch
|
||||||
|
0011-teamd-fix-possible-race-in-master-ifname-callback.patch
|
||||||
|
Loading…
Reference in New Issue
Block a user