Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libteam]: Add Warm-reboot startup mode for teamd #2155

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dockers/docker-teamd/teamd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function start_app {
rm -f /var/run/teamd/*
if [ "$(ls -A $TEAMD_CONF_PATH)" ]; then
for f in $TEAMD_CONF_PATH/*; do
teamd -f $f -d
teamd -f $f -d -N -o -w
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it mean it is already warm reboot? can we do without warm reboot?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for normal boot, we do not want enable warm reboot option here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but when we want to enable warm reboot it would be already late
We need to decide how to enable warm reboot logic after teamd start.

Copy link
Collaborator

@jipanyang jipanyang Oct 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done
fi
teamsyncd &
Expand Down
133 changes: 133 additions & 0 deletions src/libteam/0005-libteam-Add-warm_reboot-mode.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
diff --git a/libteam/ifinfo.c b/libteam/ifinfo.c
index 72155ae..b281677 100644
--- a/libteam/ifinfo.c
+++ b/libteam/ifinfo.c
@@ -55,6 +55,7 @@ struct team_ifinfo {
size_t hwaddr_len;
char orig_hwaddr[MAX_ADDR_LEN];
size_t orig_hwaddr_len;
+ bool is_orig_hwaddr_set;
char ifname[IFNAMSIZ];
uint32_t master_ifindex;
bool admin_state;
@@ -105,15 +106,17 @@ static void update_hwaddr(struct team_ifinfo *ifinfo, struct rtnl_link *link)
hwaddr_len = nl_addr_get_len(nl_addr);
if (ifinfo->hwaddr_len != hwaddr_len) {
ifinfo->hwaddr_len = hwaddr_len;
- if (!ifinfo->master_ifindex)
+ if (!ifinfo->is_orig_hwaddr_set)
ifinfo->orig_hwaddr_len = hwaddr_len;
set_changed(ifinfo, CHANGED_HWADDR_LEN);
}
hwaddr = nl_addr_get_binary_addr(nl_addr);
if (memcmp(ifinfo->hwaddr, hwaddr, hwaddr_len)) {
memcpy(ifinfo->hwaddr, hwaddr, hwaddr_len);
- if (!ifinfo->master_ifindex)
+ if (!ifinfo->is_orig_hwaddr_set) {
memcpy(ifinfo->orig_hwaddr, hwaddr, hwaddr_len);
+ ifinfo->is_orig_hwaddr_set = true;
+ }
set_changed(ifinfo, CHANGED_HWADDR);
}
}
diff --git a/teamd/teamd.c b/teamd/teamd.c
index c987333..10914b8 100644
--- a/teamd/teamd.c
+++ b/teamd/teamd.c
@@ -116,7 +116,8 @@ static void print_help(const struct teamd_context *ctx) {
" -D --dbus-enable Enable D-Bus interface\n"
" -Z --zmq-enable=ADDRESS Enable ZeroMQ interface\n"
" -U --usock-enable Enable UNIX domain socket interface\n"
- " -u --usock-disable Disable UNIX domain socket interface\n",
+ " -u --usock-disable Disable UNIX domain socket interface\n"
+ " -w --warm-reboot Warm-reboot startup mode\n",
ctx->argv0);
printf("Available runners: ");
for (i = 0; i < TEAMD_RUNNER_LIST_SIZE; i++) {
@@ -149,10 +150,11 @@ static int parse_command_line(struct teamd_context *ctx,
{ "zmq-enable", required_argument, NULL, 'Z' },
{ "usock-enable", no_argument, NULL, 'U' },
{ "usock-disable", no_argument, NULL, 'u' },
+ { "warm-reboot", no_argument, NULL, 'w' },
{ NULL, 0, NULL, 0 }
};

- while ((opt = getopt_long(argc, argv, "hdkevf:c:p:groNt:nDZ:Uu",
+ while ((opt = getopt_long(argc, argv, "hdkevf:c:p:groNt:nDZ:Uuw",
long_options, NULL)) >= 0) {

switch(opt) {
@@ -230,6 +232,9 @@ static int parse_command_line(struct teamd_context *ctx,
case 'u':
ctx->usock.enabled = false;
break;
+ case 'w':
+ ctx->warm_reboot = true;
+ break;
default:
return -1;
}
diff --git a/teamd/teamd.h b/teamd/teamd.h
index ef0fb1c..36b80de 100644
--- a/teamd/teamd.h
+++ b/teamd/teamd.h
@@ -125,6 +125,7 @@ struct teamd_context {
char * hwaddr;
uint32_t hwaddr_len;
bool hwaddr_explicit;
+ bool warm_reboot;
struct {
struct list_item callback_list;
int ctrl_pipe_r;
diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
index 81324de..56b8740 100644
--- a/teamd/teamd_runner_lacp.c
+++ b/teamd/teamd_runner_lacp.c
@@ -174,6 +174,7 @@ struct lacp_port {
struct lacp_port *agg_lead; /* leading port of aggregator.
* NULL in case this port is not selected */
enum lacp_port_state state;
+ bool lacpdu_received;
struct {
uint32_t speed;
uint8_t duplex;
@@ -1080,6 +1081,14 @@ static int lacpdu_send(struct lacp_port *lacp_port)
memcpy(lacpdu.hdr.ether_dhost, ll_slow.sll_addr, ll_slow.sll_halen);
lacpdu.hdr.ether_type = htons(ETH_P_SLOW);

+ if (lacp_port->ctx->warm_reboot && !lacp_port->lacpdu_received && !(lacp_port->actor.state & INFO_STATE_SYNCHRONIZATION)) {
+ /* don't send lacpdu update in warm-reboot mode unless we receive lacp pdu from the partner */
+ return 0;
+ } else {
+ /* we have syncronized with the partner. Now we can send lacp pdu any time */
+ lacp_port->lacpdu_received = true;
+ }
+
err = teamd_send(lacp_port->sock, &lacpdu, sizeof(lacpdu), 0);
return err;
}
@@ -1144,7 +1153,10 @@ static int lacp_callback_timeout(struct teamd_context *ctx, int events,
err = lacp_port_set_state(lacp_port, PORT_STATE_EXPIRED);
break;
case PORT_STATE_EXPIRED:
- err = lacp_port_set_state(lacp_port, PORT_STATE_DEFAULTED);
+ if (!lacp_port->ctx->warm_reboot) {
+ /* Don't transition into DEFAULT state in warm_reboot mode, which prevents port syncing */
+ err = lacp_port_set_state(lacp_port, PORT_STATE_DEFAULTED);
+ }
break;
case PORT_STATE_DEFAULTED:
case PORT_STATE_DISABLED:
@@ -1321,7 +1333,11 @@ static void lacp_port_removed(struct teamd_context *ctx,
{
struct lacp_port *lacp_port = priv;

- lacp_port_set_state(lacp_port, PORT_STATE_DISABLED);
+ if (!lacp_port->ctx->warm_reboot) {
+ /* Don't transition into DISABLED state in warm-reboot mode,
+ teamd will sends EXPIRED LACP PDU update in DISABLED state */
+ lacp_port_set_state(lacp_port, PORT_STATE_DISABLED);
+ }
teamd_loop_callback_del(ctx, LACP_TIMEOUT_CB_NAME, lacp_port);
teamd_loop_callback_del(ctx, LACP_PERIODIC_CB_NAME, lacp_port);
teamd_loop_callback_del(ctx, LACP_SOCKET_CB_NAME, lacp_port);
1 change: 1 addition & 0 deletions src/libteam/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
git apply ../0002-libteam-Temporarily-remove-redundant-debug-mes.patch
git apply ../0003-teamd-lacp-runner-will-send-lacp-update-right-after-.patch
git apply ../0004-libteam-Add-lacp-fallback-support-for-single-member-.patch
git apply ../0005-libteam-Add-warm_reboot-mode.patch
popd

# Obtain debian packaging
Expand Down