Wed, Aug 08, 2018 at 10:56:52AM CEST, liuhangbin(a)gmail.com wrote:
When we add port to new active-backup teams with multi threads. After
the port is set to link up and trigger function obj_input_newlink(),
it's possible that there is no master index in rtnl link info. So the
team slave's master_ifindex is not updated.
On the other hand, the port is up and trigger functions like
- teamd_link_watch_check_link_up()
- teamd_event_port_link_changed()
- ab_event_watch_port_link_changed()
- ab_link_watch_handler()
- teamd_for_each_tdport()
- teamd_get_next_tdport()
- teamd_port_present()
Here the teamd_port_present() failed as the port master ifindex is not
update to team ifindex yet. Finally we get nothing and no active port
is set.
Here is the reproducer:
\#bin/bash
if [ -z $1 ] || [ -z $2 ]; then
echo "Usage: $0 iface1 iface2"
exit 1
else
iface1=$1
iface2=$2
fi
WAIT=2
COUNT=0
start_team()
{
local num=$1
local iface=$2
teamd -o -n -U -d -t team$num -c '{"runner": {"name":
"activebackup"},"link_watch": {"name":
"ethtool"}}' -gg
teamdctl team$num port add $iface
}
while :; do
echo "-----------------------------------------------------------"
let "COUNT++"
echo "Loop $COUNT"
teamd -k -t team1
teamd -k -t team2
sleep "$WAIT"
start_team 1 $iface1 &
start_team 2 $iface2 &
sleep "$WAIT"
if teamdctl team1 state | grep -q "active port: $iface1" && \
teamdctl team2 state | grep -q "active port: $iface2"; then
echo "Pass"
else
echo "FAIL"
exit 1
fi
done
Failure as follows:
]# teamdctl teamX state dump
"runner": {
"active_port": ""
},
Currently we only reproduced this with active-backup mode(I could reproduce it
in VM easily, but hard to reproduce it on physical machines).
Fix it by adding a new teamd_event_watch_ops port_master_ifindex_changed for
active-backup mode.
V2: update commit description from Jamie Bainbridge's reply.
v3: update description and reproducer.
Signed-off-by: Hangbin Liu <liuhangbin(a)gmail.com>
applied, thanks!