Compare commits

...

2 Commits

Author SHA1 Message Date
Hangbin Liu 747d5a6607 1.31-17 2023-07-25 02:30:07 +00:00
Xin Long 48dd71b9d6 1.31-16
Resolves: rhbz#2148852

Signed-off-by: Xin Long <lxin@redhat.com>
2022-12-07 16:35:27 -05:00
9 changed files with 705 additions and 6 deletions

1
.libteam.metadata Normal file
View File

@ -0,0 +1 @@
338f2bae08e143bc3f7a84317ddc3053cff2691d libteam-1.31.tar.gz

View File

@ -0,0 +1,105 @@
From ffc6a52bd285a476b547312012078af69220574b Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 10 Oct 2022 18:37:31 +0200
Subject: [PATCH] teamd: stop iterating callbacks when a loop restart is
requested
A crash was observed:
Added loop callback: dbus_watch, 0x560d279e4530
Added loop callback: dbus_watch, 0x560d279e4580
...
Removed loop callback: dbus_watch, 0x560d279e4580
Removed loop callback: dbus_watch, 0x560d279e4530
Aug 31 11:54:11 holaprdel kernel: traps: teamd[557] general protection fault ip:560d26469a55 sp:7ffd43ca9650 error:0 in teamd[560d26463000+16000]
Traceback (from a different run than above):
Core was generated by `/usr/bin/teamd -o -n -U -D -N -t team0 -gg'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00005600ac090a55 in teamd_run_loop_do_callbacks (ctx=0x5600ad9bac70, fds=0x7fff40861250, lcb_list=0x5600ad9bad58) at /usr/src/debug/libteam-1.31-14.el9.x86_64/teamd/teamd.c:321
321 list_for_each_node_entry_safe(lcb, tmp, lcb_list, list) {
(gdb) bt
#0 0x00005600ac090a55 in teamd_run_loop_do_callbacks (ctx=0x5600ad9bac70, fds=0x7fff40861250, lcb_list=0x5600ad9bad58) at /usr/src/debug/libteam-1.31-14.el9.x86_64/teamd/teamd.c:321
#1 teamd_run_loop_run (ctx=0x5600ad9bac70) at /usr/src/debug/libteam-1.31-14.el9.x86_64/teamd/teamd.c:415
#2 0x00005600ac08d8cb in teamd_start (p_ret=<synthetic pointer>, ctx=<optimized out>) at /usr/src/debug/libteam-1.31-14.el9.x86_64/teamd/teamd.c:1557
#3 main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/libteam-1.31-14.el9.x86_64/teamd/teamd.c:1876
(gdb) print *lcb
Cannot access memory at address 0x9dd29944fb7e97fc
(gdb) print *tmp
Cannot access memory at address 0x9dd29944fb7e9804
(gdb)
What has happened is that libdbus called the remove_watch callback twice
in a single go, causing two callbacks being destroyed in one iteration
of teamd_run_loop_do_callbacks()'s list_for_each_node_entry_safe().
This basically turns the _safe() variant of the macro unhelpful, as tmp
points to stale data anyway.
Let's use the unsafe variant then, and terminate the loop once
teamd_loop_callback_del() asks for main loop's attention via
teamd_run_loop_restart(). If there are other callbacks pending an action,
they will get their turn in the next main loop iteration.
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
teamd/teamd.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/teamd/teamd.c b/teamd/teamd.c
index b310140..a89b702 100644
--- a/teamd/teamd.c
+++ b/teamd/teamd.c
@@ -309,16 +309,28 @@ static void teamd_run_loop_set_fds(struct list_item *lcb_list,
}
}
+static int teamd_check_ctrl(struct teamd_context *ctx)
+{
+ int ctrl_fd = ctx->run_loop.ctrl_pipe_r;
+ struct timeval tv;
+ fd_set rfds;
+
+ FD_ZERO(&rfds);
+ FD_SET(ctrl_fd, &rfds);
+ tv.tv_sec = tv.tv_usec = 0;
+
+ return select(ctrl_fd + 1, &rfds, NULL, NULL, &tv);
+}
+
static int teamd_run_loop_do_callbacks(struct list_item *lcb_list, fd_set *fds,
struct teamd_context *ctx)
{
struct teamd_loop_callback *lcb;
- struct teamd_loop_callback *tmp;
int i;
int events;
int err;
- list_for_each_node_entry_safe(lcb, tmp, lcb_list, list) {
+ list_for_each_node_entry(lcb, lcb_list, list) {
for (i = 0; i < 3; i++) {
if (!(lcb->fd_event & (1 << i)))
continue;
@@ -339,6 +351,16 @@ static int teamd_run_loop_do_callbacks(struct list_item *lcb_list, fd_set *fds,
teamd_log_dbg(ctx, "Failed loop callback: %s, %p",
lcb->name, lcb->priv);
}
+
+ /*
+ * If there's a control byte ready, it's possible that
+ * one or more entries have been removed from the
+ * callback list and restart has been requested. In any
+ * case, let the main loop deal with it first so that
+ * we know we're safe to proceed.
+ */
+ if (teamd_check_ctrl(ctx))
+ return 0;
}
}
return 0;
--
2.31.1

View File

@ -0,0 +1,29 @@
From 8e6b8db540299209f28505e7578a6d0ffeba4c38 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 10:51:25 +0800
Subject: [PATCH 10/15] utils/team2bond: add lacp_active support
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/utils/team2bond b/utils/team2bond
index 111b83b..7fc4a48 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -63,7 +63,10 @@ def convert_runner_opts(runner_opts):
elif runner_opts['name'] == 'lacp':
bond_opts = "mode=802.3ad"
if 'active' in runner_opts:
- print("# Warn: option runner.active: %r is not supported by bonding" % runner_opts['active'])
+ if runner_opts['active']:
+ bond_opts += ",lacp_active=1"
+ else:
+ bond_opts += ",lacp_active=0"
if 'fast_rate' in runner_opts:
if runner_opts['fast_rate']:
bond_opts += ",lacp_rate=1"
--
2.38.1

View File

@ -0,0 +1,39 @@
From 6bf7990d35900c033df03cd76c25b7986deb833f Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 10:59:21 +0800
Subject: [PATCH 11/15] utils/team2bond: support missed_max
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index 7fc4a48..e6e4f0d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -153,6 +153,12 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
if 'target_host' in link_watch_opts:
arp_target.append(link_watch_opts['target_host'])
+ if 'missed_max' in link_watch_opts:
+ if exist_opts.find('arp_missed_max') >= 0:
+ print("# Warn: duplicated arp_missed_max detected, bonding supports only one.")
+ else:
+ bond_opts += ",arp_missed_max=" + str(link_watch_opts['missed_max'])
+
if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
if exist_opts.find('arp_validate') >= 0:
@@ -172,8 +178,6 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
if 'init_wait' in link_watch_opts:
print("# Warn: option link_watch.init_wait: %d is not supported by bonding" % link_watch_opts['init_wait'])
- if 'missed_max' in link_watch_opts:
- print("# Warn: option link_watch.missed_max: %d is not supported by bonding" % link_watch_opts['missed_max'])
if 'source_host' in link_watch_opts:
print("# Warn: option link_watch.source_host: %s is not supported by bonding" % link_watch_opts['source_host'])
if 'vlanid' in link_watch_opts:
--
2.38.1

View File

@ -0,0 +1,54 @@
From 54255e65e8734635374ee62eb3a8b118f79b568b Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 11:18:43 +0800
Subject: [PATCH 12/15] utils/team2bond: support link watch in ports
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index e6e4f0d..ef4210d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -224,18 +224,20 @@ def convert_opts(bond_name, team_opts, exec_cmd):
bond_opts += convert_link_watch(link_watch_opts, arp_target, bond_opts)
elif isinstance(team_opts['link_watch'], dict):
bond_opts += convert_link_watch(team_opts['link_watch'], arp_target, bond_opts)
- # Check link watch in team ports if we don't have global link_watch
- elif 'ports' in team_opts:
+ # Check link watch in team ports, we asume it's a dict only?
+ if 'ports' in team_opts:
for iface in team_opts['ports']:
- if 'link_watch' in team_opts['ports'][iface]:
+ if ('link_watch' in team_opts['ports'][iface] and
+ isinstance(team_opts['ports'][iface]['link_watch'], dict)):
bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], arp_target, bond_opts)
- else:
- print("Warn: No link_watch in team config file, use miimon=100 by default")
- bond_opts += ",miimon=100"
if arp_target:
bond_opts += ",arp_ip_target=" + " ".join(arp_target)
+ if bond_opts.find("miimon") == -1 and bond_opts.find("_target") == -1:
+ print("Warn: No link_watch in team config file, use miimon=100 by default")
+ bond_opts += ",miimon=100"
+
if exec_cmd:
subprocess.run(['nmcli', 'con', 'add', 'type', 'bond', 'ifname',
bond_name, 'bond.options', bond_opts])
@@ -252,9 +254,6 @@ def setup_ports(bond_name, team_opts, exec_cmd):
if 'ports' in team_opts:
for iface in team_opts['ports']:
bond_ports.append(iface)
- if 'link_watch' in team_opts['ports'][iface] and \
- 'link_watch' in team_opts:
- print("# Warn: Option link_watch in interface %s will be ignored as we have global link_watch set!" % iface)
if 'queue_id' in team_opts['ports'][iface]:
print("# Warn: Option queue_id: %d on interface %s is not supported by NM yet, please see rhbz:1949127" %
(team_opts['ports'][iface]['queue_id'], iface))
--
2.38.1

View File

@ -0,0 +1,98 @@
From 519f8529ac0bc5b19199ec8a2e83a06e88c078b0 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 11:33:17 +0800
Subject: [PATCH 13/15] utils/team2bond: add ns_ip6_target support
Rename variable arp_target to target_hosts as we will store both IPv4
and IPv6 address.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index ef4210d..f337906 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -111,9 +111,9 @@ def convert_runner_opts(runner_opts):
return bond_opts
-# arp_target is used to store multi targets
-# exist_opts is used to check if there are duplicated arp_intervals
-def convert_link_watch(link_watch_opts, arp_target, exist_opts):
+# target_hosts is used to store multi targets
+# exist_opts is used to check if there are duplicated options
+def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
bond_opts=""
if 'name' not in link_watch_opts:
print("Error: no link_watch.name in team config file!")
@@ -139,20 +139,20 @@ def convert_link_watch(link_watch_opts, arp_target, exist_opts):
print("# Warn: duplicated downdelay detected, bonding supports only one.")
else:
bond_opts += ",downdelay=" + str(link_watch_opts['delay_down'])
- elif link_watch_opts['name'] == 'arp_ping':
+ elif link_watch_opts['name'] == 'arp_ping' or link_watch_opts['name'] == 'nsna_ping':
if exist_opts.find("miimon") >= 0:
print("# Warn: detecte arp_interval(arp_ping) setting, but miimon(ethtool) already set, will ignore.")
return bond_opts
+ if 'target_host' in link_watch_opts and link_watch_opts['target_host'] not in target_hosts:
+ target_hosts.append(link_watch_opts['target_host'])
+
if 'interval' in link_watch_opts:
if exist_opts.find('arp_interval') >= 0:
print("# Warn: duplicated arp_interval detected, bonding supports only one.")
else:
bond_opts += ",arp_interval=" + str(link_watch_opts['interval'])
- if 'target_host' in link_watch_opts:
- arp_target.append(link_watch_opts['target_host'])
-
if 'missed_max' in link_watch_opts:
if exist_opts.find('arp_missed_max') >= 0:
print("# Warn: duplicated arp_missed_max detected, bonding supports only one.")
@@ -217,22 +217,32 @@ def convert_opts(bond_name, team_opts, exec_cmd):
print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" % team_opts['mcast_rejoin']['count'])
# The link_watch maybe a dict or list
- arp_target = list()
+ target_hosts = list()
if 'link_watch' in team_opts:
if isinstance(team_opts['link_watch'], list):
for link_watch_opts in team_opts['link_watch']:
- bond_opts += convert_link_watch(link_watch_opts, arp_target, bond_opts)
+ bond_opts += convert_link_watch(link_watch_opts, target_hosts, bond_opts)
elif isinstance(team_opts['link_watch'], dict):
- bond_opts += convert_link_watch(team_opts['link_watch'], arp_target, bond_opts)
+ bond_opts += convert_link_watch(team_opts['link_watch'], target_hosts, bond_opts)
# Check link watch in team ports, we asume it's a dict only?
if 'ports' in team_opts:
for iface in team_opts['ports']:
if ('link_watch' in team_opts['ports'][iface] and
isinstance(team_opts['ports'][iface]['link_watch'], dict)):
- bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], arp_target, bond_opts)
-
- if arp_target:
- bond_opts += ",arp_ip_target=" + " ".join(arp_target)
+ bond_opts += convert_link_watch(team_opts['ports'][iface]['link_watch'], target_hosts, bond_opts)
+
+ if target_hosts:
+ arp_targets = list()
+ ns_targets = list()
+ for target in target_hosts:
+ if target.find(':') == -1:
+ arp_targets.append(target)
+ else:
+ ns_targets.append(target)
+ if arp_targets:
+ bond_opts += ",arp_ip_target=" + " ".join(arp_targets)
+ if ns_targets:
+ bond_opts += ",ns_ip6_target=" + " ".join(ns_targets)
if bond_opts.find("miimon") == -1 and bond_opts.find("_target") == -1:
print("Warn: No link_watch in team config file, use miimon=100 by default")
--
2.38.1

View File

@ -0,0 +1,81 @@
From dea184d3aa8a6038977494ddd4ae6c540317fb72 Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 14:00:11 +0800
Subject: [PATCH 14/15] utils/team2bond: Add queue_id support
Adding bond ports in the option check logic. There is no need to do it in
another loop, then we can remove the bond_ports variable.
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index f337906..2f5d868 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -263,10 +263,11 @@ def setup_ports(bond_name, team_opts, exec_cmd):
if 'ports' in team_opts:
for iface in team_opts['ports']:
- bond_ports.append(iface)
+ port_options = ["ifname", iface, "master", bond_name]
+
if 'queue_id' in team_opts['ports'][iface]:
- print("# Warn: Option queue_id: %d on interface %s is not supported by NM yet, please see rhbz:1949127" %
- (team_opts['ports'][iface]['queue_id'], iface))
+ port_options.append("bond-port.queue-id")
+ port_options.append(str(team_opts['ports'][iface]['queue_id']))
if 'lacp_prio' in team_opts['ports'][iface]:
print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
(team_opts['ports'][iface]['lacp_prio'], iface))
@@ -289,23 +290,21 @@ def setup_ports(bond_name, team_opts, exec_cmd):
primary['name'] = iface
primary['sticky'] = True
- for port in bond_ports:
- ret = subprocess.run(['nmcli', '-g', 'general.type', 'dev', 'show', port],
- stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- if ret.returncode != 0:
- print("# Warn: Get dev %s type failed, will use type ethernet by default" % port)
- if_type = 'ethernet'
- elif ret.stdout.find(b'ethernet') != 0:
- print("# Warn: %s is not a ethernet device, please make sure the type is correct" % port)
- if_type = str(ret.stdout, 'utf-8').strip()
- else:
- if_type = str(ret.stdout, 'utf-8').strip()
+ ret = subprocess.run(['nmcli', '-g', 'general.type', 'dev', 'show', iface],
+ stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ if ret.returncode != 0:
+ print("# Warn: Get dev %s type failed, will use type ethernet by default" % iface)
+ if_type = 'ethernet'
+ elif ret.stdout.find(b'ethernet') != 0:
+ print("# Warn: %s is not a ethernet device, please make sure the type is correct" % iface)
+ if_type = str(ret.stdout, 'utf-8').strip()
+ else:
+ if_type = str(ret.stdout, 'utf-8').strip()
- if exec_cmd:
- subprocess.run(['nmcli', 'con', 'add', 'type', if_type,
- 'ifname', port, 'master', bond_name])
- else:
- print('nmcli con add type %s ifname %s master %s' % (if_type, port, bond_name))
+ if exec_cmd:
+ subprocess.run(['nmcli', 'con', 'add', 'type', if_type] + port_options)
+ else:
+ print('nmcli con add type %s %s' % (if_type, " ".join(port_options)))
if lacp_key != 0:
if exec_cmd:
@@ -314,6 +313,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
else:
print('nmcli con mod bond-' + bond_name \
+ ' +bond.options "ad_user_port_key=' + str(lacp_key) + '"')
+
if primary['name']:
if exec_cmd:
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
--
2.38.1

View File

@ -0,0 +1,278 @@
From 8b682b86dfd4ac142724151f4489063dbecc5bda Mon Sep 17 00:00:00 2001
From: Hangbin Liu <haliu@redhat.com>
Date: Fri, 24 Mar 2023 15:57:36 +0800
Subject: [PATCH 15/15] utils/team2bond: update python code format
Signed-off-by: Hangbin Liu <haliu@redhat.com>
---
utils/team2bond | 114 ++++++++++++++++++++++++++----------------------
1 file changed, 62 insertions(+), 52 deletions(-)
diff --git a/utils/team2bond b/utils/team2bond
index 2f5d868..2032c1d 100755
--- a/utils/team2bond
+++ b/utils/team2bond
@@ -6,40 +6,42 @@ import subprocess
import json
import sys
+
def handle_cmd_line():
parser = OptionParser()
- parser.add_option('--config', dest='config', default = '',
- help = "convert the team JSON format configuration file " \
- + "to NetworkManager connection profile, please use " \
- + "'teamdctl TEAM config dump [actual]' to dump the config file." \
- + " Note the script only convert config file. IP " \
+ parser.add_option('--config', dest='config', default='',
+ help="convert the team JSON format configuration file "
+ + "to NetworkManager connection profile, please use "
+ + "'teamdctl TEAM config dump [actual]' to dump the config file."
+ + " Note the script only convert config file. IP "
+ "address configurations still need to be set manually.")
- parser.add_option('--rename', dest='rename', default = '',
- help = "rename the default team interface name." \
- + " Careful: firewall rules, aliases interfaces, etc., " \
- + "will break after the renaming because the tool " \
+ parser.add_option('--rename', dest='rename', default='',
+ help="rename the default team interface name."
+ + " Careful: firewall rules, aliases interfaces, etc., "
+ + "will break after the renaming because the tool "
+ "will only change the config file, nothing else.")
group = OptionGroup(parser, 'Dangerous Options',
- "Caution: You need to dump the team configuration " \
- "file first and then delete old team device to avoid " \
+ "Caution: You need to dump the team configuration "
+ "file first and then delete old team device to avoid "
"device name conflicts.")
- group.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default = False,
- help = "exec nmcli and add the connections directly " \
- + "instead of printing the nmcli cmd to screen. " \
- + "This parameter is NOT recommended, it would be good " \
- + "to double check the cmd before apply.")
+ group.add_option('--exec-cmd', dest='exec_cmd', action='store_true', default=False,
+ help="exec nmcli and add the connections directly "
+ + "instead of printing the nmcli cmd to screen. "
+ + "This parameter is NOT recommended, it would be good "
+ + "to double check the cmd before apply.")
parser.add_option_group(group)
(options, args) = parser.parse_args()
if subprocess.run(['nmcli', '-v'], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL).returncode != 0:
- print("Warn: NetworkManager is needed for this script!");
+ print("Warn: NetworkManager is needed for this script!")
sys.exit(1)
return options
+
def convert_runner_opts(runner_opts):
bond_opts = ""
@@ -50,14 +52,14 @@ def convert_runner_opts(runner_opts):
elif runner_opts['name'] == 'activebackup':
bond_opts = "mode=active-backup"
if 'hwaddr_policy' in runner_opts:
- if runner_opts['hwaddr_policy'] == 'same_all':
- bond_opts += ",fail_over_mac=none"
- elif runner_opts['hwaddr_policy'] == 'by_active':
- bond_opts += ",fail_over_mac=active"
- elif runner_opts['hwaddr_policy'] == 'only_active':
- bond_opts += ",fail_over_mac=follow"
- else:
- print("# Warn: invalid runner.hwaddr_policy: " + runner_opts['hwaddr_policy'])
+ if runner_opts['hwaddr_policy'] == 'same_all':
+ bond_opts += ",fail_over_mac=none"
+ elif runner_opts['hwaddr_policy'] == 'by_active':
+ bond_opts += ",fail_over_mac=active"
+ elif runner_opts['hwaddr_policy'] == 'only_active':
+ bond_opts += ",fail_over_mac=follow"
+ else:
+ print("# Warn: invalid runner.hwaddr_policy: " + runner_opts['hwaddr_policy'])
elif runner_opts['name'] == 'loadbalance':
bond_opts = "mode=balance-tlb"
elif runner_opts['name'] == 'lacp':
@@ -73,7 +75,7 @@ def convert_runner_opts(runner_opts):
else:
bond_opts += ",lacp_rate=0"
if 'sys_prio' in runner_opts:
- bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
+ bond_opts += ",ad_actor_sys_prio=" + str(runner_opts['sys_prio'])
if 'min_ports' in runner_opts:
bond_opts += ",min_links=" + str(runner_opts['min_ports'])
if 'agg_select_policy' in runner_opts:
@@ -83,7 +85,7 @@ def convert_runner_opts(runner_opts):
bond_opts += ",ad_select=count"
else:
print("# Warn: Option runner.agg_select_policy: %s is not supported by bonding" %
- runner_opts['agg_select_policy'])
+ runner_opts['agg_select_policy'])
sys.exit(1)
else:
print("Error: Unsupported runner.name: %s for bonding" % runner_opts['name'])
@@ -92,14 +94,14 @@ def convert_runner_opts(runner_opts):
if 'tx_hash' in runner_opts:
print("# Warn: tx_hash ipv4, ipv6, tcp, udp, sctp are not supported by bonding")
if 'vlan' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=vlan+srcmac"
+ bond_opts += ",xmit_hash_policy=vlan+srcmac"
if 'eth' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=layer2"
+ bond_opts += ",xmit_hash_policy=layer2"
if 'l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']:
- bond_opts +="+3"
- elif ('l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash']) \
- and 'l4' in runner_opts['tx_hash']:
- bond_opts +=",xmit_hash_policy=layer3+4"
+ bond_opts += "+3"
+ elif (('l3' in runner_opts['tx_hash'] or 'ip' in runner_opts['tx_hash'])
+ and 'l4' in runner_opts['tx_hash']):
+ bond_opts += ",xmit_hash_policy=layer3+4"
if 'tx_balancer' in runner_opts:
if 'name' in runner_opts['tx_balancer']:
@@ -107,14 +109,15 @@ def convert_runner_opts(runner_opts):
bond_opts += ",tlb_dynamic_lb=1"
if 'balancing_interval' in runner_opts['tx_balancer']:
print("# Warn: option runner.tx_balancer.balancing_interval: %d is not supported by bonding" %
- runner_opts['tx_balancer']['balancing_interval'])
+ runner_opts['tx_balancer']['balancing_interval'])
return bond_opts
+
# target_hosts is used to store multi targets
# exist_opts is used to check if there are duplicated options
def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
- bond_opts=""
+ bond_opts = ""
if 'name' not in link_watch_opts:
print("Error: no link_watch.name in team config file!")
sys.exit(1)
@@ -159,8 +162,8 @@ def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
else:
bond_opts += ",arp_missed_max=" + str(link_watch_opts['missed_max'])
- if 'validate_active' in link_watch_opts and link_watch_opts['validate_active'] and \
- 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']:
+ if ('validate_active' in link_watch_opts and link_watch_opts['validate_active'] and
+ 'validate_inactive' in link_watch_opts and link_watch_opts['validate_inactive']):
if exist_opts.find('arp_validate') >= 0:
print("# Warn: duplicated arp_validate detected, bonding supports only one.")
else:
@@ -177,20 +180,25 @@ def convert_link_watch(link_watch_opts, target_hosts, exist_opts):
bond_opts += ",arp_validate=backup"
if 'init_wait' in link_watch_opts:
- print("# Warn: option link_watch.init_wait: %d is not supported by bonding" % link_watch_opts['init_wait'])
+ print("# Warn: option link_watch.init_wait: %d is not supported by bonding" %
+ link_watch_opts['init_wait'])
if 'source_host' in link_watch_opts:
- print("# Warn: option link_watch.source_host: %s is not supported by bonding" % link_watch_opts['source_host'])
+ print("# Warn: option link_watch.source_host: %s is not supported by bonding" %
+ link_watch_opts['source_host'])
if 'vlanid' in link_watch_opts:
- print("# Warn: option link_watch.vlanid: %d is not supported by bonding" % link_watch_opts['vlanid'])
+ print("# Warn: option link_watch.vlanid: %d is not supported by bonding" %
+ link_watch_opts['vlanid'])
if 'send_always' in link_watch_opts:
- print("# Warn: option link_watch.send_always: %r is not supported by bonding" % link_watch_opts['send_always'])
+ print("# Warn: option link_watch.send_always: %r is not supported by bonding" %
+ link_watch_opts['send_always'])
else:
print("# Error: Option link_watch.name: %s is not supported by bonding" %
- link_watch_opts['name'])
+ link_watch_opts['name'])
sys.exit(1)
return bond_opts
+
def convert_opts(bond_name, team_opts, exec_cmd):
bond_opts = ""
@@ -214,7 +222,8 @@ def convert_opts(bond_name, team_opts, exec_cmd):
if 'count' in team_opts['mcast_rejoin']:
bond_opts += ",resend_igmp=" + str(team_opts['mcast_rejoin']['count'])
if 'interval' in team_opts['mcast_rejoin']:
- print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" % team_opts['mcast_rejoin']['count'])
+ print("# Warn: option mcast_rejoin.interval: %d is not supported by bonding" %
+ team_opts['mcast_rejoin']['count'])
# The link_watch maybe a dict or list
target_hosts = list()
@@ -252,12 +261,12 @@ def convert_opts(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'add', 'type', 'bond', 'ifname',
bond_name, 'bond.options', bond_opts])
else:
- print('nmcli con add type bond ifname ' + bond_name \
+ print('nmcli con add type bond ifname ' + bond_name
+ ' bond.options "' + bond_opts + '"')
+
def setup_ports(bond_name, team_opts, exec_cmd):
primary = {'name': "", 'prio': -2**63, 'sticky': False}
- bond_ports = []
lacp_key = 0
prio = 0
@@ -270,7 +279,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
port_options.append(str(team_opts['ports'][iface]['queue_id']))
if 'lacp_prio' in team_opts['ports'][iface]:
print("# Warn: Option lacp_prio: %d on interface %s is not supported by bonding" %
- (team_opts['ports'][iface]['lacp_prio'], iface))
+ (team_opts['ports'][iface]['lacp_prio'], iface))
if 'lacp_key' in team_opts['ports'][iface]:
if lacp_key == 0:
lacp_key = team_opts['ports'][iface]['lacp_key']
@@ -279,14 +288,14 @@ def setup_ports(bond_name, team_opts, exec_cmd):
print("# Warn: Option lacp_key: Invalid value %d for port %s" % (lacp_key, iface))
else:
print("# Warn: Option lacp_key: already has one key %d, ignore the new one %d" %
- (lacp_key, team_opts['ports'][iface]['lacp_key']))
+ (lacp_key, team_opts['ports'][iface]['lacp_key']))
if 'prio' in team_opts['ports'][iface]:
prio = int(team_opts['ports'][iface]['prio'])
if prio > primary['prio'] and primary['sticky'] is False:
primary['name'] = iface
primary['prio'] = prio
- if 'sticky' in team_opts['ports'][iface] and \
- team_opts['ports'][iface]['sticky']:
+ if ('sticky' in team_opts['ports'][iface] and
+ team_opts['ports'][iface]['sticky']):
primary['name'] = iface
primary['sticky'] = True
@@ -311,7 +320,7 @@ def setup_ports(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
'+bond.options', "ad_user_port_key=" + str(lacp_key)])
else:
- print('nmcli con mod bond-' + bond_name \
+ print('nmcli con mod bond-' + bond_name
+ ' +bond.options "ad_user_port_key=' + str(lacp_key) + '"')
if primary['name']:
@@ -319,9 +328,10 @@ def setup_ports(bond_name, team_opts, exec_cmd):
subprocess.run(['nmcli', 'con', 'mod', 'bond-' + bond_name,
'+bond.options', "primary=" + primary['name']])
else:
- print('nmcli con mod bond-' + bond_name \
+ print('nmcli con mod bond-' + bond_name
+ ' +bond.options "primary=' + primary['name'] + '"')
+
def main():
options = handle_cmd_line()
team_opts = dict()
@@ -358,4 +368,4 @@ def main():
print("### After this, IP addresses, routes, and so on, need to be configured.")
if __name__ == '__main__':
- main()
+ main()
--
2.38.1

View File

@ -1,6 +1,6 @@
Name: libteam
Version: 1.31
Release: 15%{?dist}
Release: 17%{?dist}
Summary: Library for controlling team network device
License: LGPLv2+
URL: http://www.libteam.org
@ -14,6 +14,13 @@ Patch5: 0005-Revert-teamd-Disregard-current-state-when-considerin.patch
Patch6: 0006-utils-team2bond-do-not-add-miimon-if-already-exist.patch
Patch7: 0007-utils-team2bond-do-not-add-updelay-downdelay-if-alre.patch
Patch8: 0008-teamd-do-no-remove-the-ports-on-shutdown-with-N.patch
Patch9: 0009-teamd-stop-iterating-callbacks-when-a-loop-restart-i.patch
Patch10: 0010-utils-team2bond-add-lacp_active-support.patch
Patch11: 0011-utils-team2bond-support-missed_max.patch
Patch12: 0012-utils-team2bond-support-link-watch-in-ports.patch
Patch13: 0013-utils-team2bond-add-ns_ip6_target-support.patch
Patch14: 0014-utils-team2bond-Add-queue_id-support.patch
Patch15: 0015-utils-team2bond-update-python-code-format.patch
BuildRequires: gcc
BuildRequires: jansson-devel
@ -35,27 +42,27 @@ to control team network devices.
%package devel
Summary: Libraries and header files for libteam development
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: libteam = %{version}-%{release}
%package doc
Summary: API documentation for libteam and libteamd
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: libteam = %{version}-%{release}
%description doc
This package contains libteam and libteamd API documentation
%package -n teamd
Summary: Team network device control daemon
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: libteam = %{version}-%{release}
%package -n teamd-devel
Summary: Libraries and header files for teamd development
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: teamd = %{version}-%{release}
%package -n network-scripts-teamd
Summary: teamd legacy network service support
Requires: network-scripts
Supplements: (%{name} and network-scripts)
Supplements: (teamd and network-scripts)
%description devel
The libteam-devel package contains the header files and libraries
@ -146,6 +153,13 @@ install -p -m 755 utils/team2bond $RPM_BUILD_ROOT%{_bindir}/team2bond
%{_sysconfdir}/sysconfig/network-scripts/ifdown-TeamPort
%changelog
* Fri Jul 14 2023 Hangbin Liu <haliu@redhat.com> - 1.31-17
- Update team2bond to latest version (RHEL-783)
* Tue Dec 06 2022 Long Xin <lxin@redhat.com> - 1.31-16
- fix the Requires package name for teamd-devel
- teamd: stop iterating callbacks when a loop restart is requested (rhbz#2148852)
* Mon Dec 05 2022 Long Xin <lxin@redhat.com> - 1.31-15
- teamd: do no remove the ports on shutdown with -N (rhbz#2148854)