From: Erik Hugne erik.hugne@ericsson.com
Fix a bug where memory allocated for the 'links' list was not freed when a team port was removed, and an issue where per-port callback was not deleted when a team port is removed.
Signed-off-by: Erik Hugne erik.hugne@ericsson.com --- teamd/teamd_lw_tipc.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/teamd/teamd_lw_tipc.c b/teamd/teamd_lw_tipc.c index e86cd07..dffb9a2 100644 --- a/teamd/teamd_lw_tipc.c +++ b/teamd/teamd_lw_tipc.c @@ -170,7 +170,7 @@ static int lw_tipc_topsrv_subscribe(struct teamd_context *ctx, struct lw_tipc_po err = teamd_loop_callback_fd_add(ctx, LW_TIPC_TOPSRV_SOCKET, priv, lw_tipc_callback_socket, priv->topsrv_sock, - POLLIN); + TEAMD_LOOP_FD_EVENT_READ); if (err) { teamd_log_err("Failed to add socket callback"); err = -errno; @@ -214,18 +214,21 @@ static int lw_tipc_port_added(struct teamd_context *ctx, return 0; }
- - static void lw_tipc_port_removed(struct teamd_context *ctx, struct teamd_port *tdport, void *priv, void *creator_priv) { struct lw_tipc_port_priv *tipc_ppriv = priv; + struct tipc_link *link;
teamd_log_dbg("tipc port removed\n"); + teamd_loop_callback_del(ctx, LW_TIPC_TOPSRV_SOCKET, priv); close(tipc_ppriv->topsrv_sock); - while (tipc_ppriv->links.lh_first != NULL) - LIST_REMOVE(tipc_ppriv->links.lh_first, next); + while (!LIST_EMPTY(&tipc_ppriv->links)) { + link = LIST_FIRST(&tipc_ppriv->links); + LIST_REMOVE(link, next); + free(link); + } }
int lw_tipc_state_bearer_get(struct teamd_context *ctx,
From: Erik Hugne erik.hugne@ericsson.com
We introduce a more fine-grained approach to team port failover for the TIPC link watcher. Instead of waiting until the last link over a bearer goes down to trigger team port down, we do this immediately when the last link to a logical cluster is lost. This leverages the ability to group nodes into clusters with the <zone>.<cluster>.<node> addressing scheme in TIPC.
Signed-off-by: Erik Hugne erik.hugne@ericsson.com --- teamd/teamd_lw_tipc.c | 55 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 22 deletions(-)
diff --git a/teamd/teamd_lw_tipc.c b/teamd/teamd_lw_tipc.c index dffb9a2..5f05b4a 100644 --- a/teamd/teamd_lw_tipc.c +++ b/teamd/teamd_lw_tipc.c @@ -35,6 +35,7 @@ struct tipc_link { LIST_ENTRY(tipc_link) next; char name[TIPC_MAX_LINK_NAME]; + unsigned int peer; bool up; };
@@ -62,40 +63,50 @@ static int lw_tipc_load_options(struct teamd_context *ctx, return 0; }
+static bool lw_tipc_topology_check(struct lw_tipc_port_priv *priv, + unsigned int addr) +{ + struct tipc_link *l;
-static int lw_tipc_link_state_change(struct teamd_context *ctx, char *name, + LIST_FOREACH(l, &priv->links, next) { + if ((tipc_cluster(l->peer) == tipc_cluster(addr)) && l->up) + return true; + } + return false; +} + +static int lw_tipc_link_state_change(struct teamd_context *ctx, + struct tipc_sioc_ln_req *lnr, struct lw_tipc_port_priv *priv, bool link_up) { + bool path_ok; struct tipc_link *link; - struct teamd_port *tdport = priv->common.tdport; + struct lw_common_port_priv *ppriv = (struct lw_common_port_priv *)priv; + LIST_FOREACH(link, &priv->links, next) { - if (!strcmp(link->name, name)) { - teamd_log_info("tipc: link <%s> went %s.", name, - link_up ? "up" : "down"); - link->up = link_up; - if (!link_up && ((--(priv->active_links) == 0))) { - return teamd_link_watch_check_link_up(ctx, tdport, - (struct lw_common_port_priv *)priv, link_up); - } - goto link_up; - } + if (strcmp(link->name, lnr->linkname)) + continue; + link->up = link_up; + teamd_log_dbg("tipc: link <%s> went %s.", + lnr->linkname, link_up ? "up" : "down"); +check: + path_ok = lw_tipc_topology_check(priv, link->peer); + return teamd_link_watch_check_link_up(ctx, ppriv->tdport, ppriv, + path_ok); } if (!link_up) { teamd_log_err("tipc: received spurious down event for link <%s>", - name); + lnr->linkname); return -EINVAL; } - teamd_log_dbg("tipc: established new link <%s>", name); + teamd_log_dbg("tipc: established new link <%s>", lnr->linkname); link = malloc(sizeof(struct tipc_link)); - strcpy(link->name, name); + strcpy(link->name, lnr->linkname); link->up = link_up; + link->peer = lnr->peer; LIST_INSERT_HEAD(&priv->links, link, next); -link_up: - priv->active_links++; - return teamd_link_watch_check_link_up(ctx, tdport, - (struct lw_common_port_priv *)priv, - link_up); + goto check; }
static int lw_tipc_filter_events(struct lw_tipc_port_priv *tipc_ppriv, @@ -136,9 +147,9 @@ static int lw_tipc_callback_socket(struct teamd_context *ctx, int events, void * if (lw_tipc_filter_events(tipc_ppriv, &lnr)) return 0; if (event.event == htonl(TIPC_PUBLISHED)) - return lw_tipc_link_state_change(ctx, lnr.linkname, tipc_ppriv, true); + return lw_tipc_link_state_change(ctx, &lnr, tipc_ppriv, true); else if (event.event == htonl(TIPC_WITHDRAWN)) - return lw_tipc_link_state_change(ctx, lnr.linkname, tipc_ppriv, false); + return lw_tipc_link_state_change(ctx, &lnr, tipc_ppriv, false); tipc_cb_err: teamd_log_dbg("tipc: link state event error"); return -EINVAL;
Thu, Sep 04, 2014 at 04:36:16PM CEST, erik.hugne@ericsson.com wrote:
From: Erik Hugne erik.hugne@ericsson.com
Fix a bug where memory allocated for the 'links' list was not freed when a team port was removed, and an issue where per-port callback was not deleted when a team port is removed.
Signed-off-by: Erik Hugne erik.hugne@ericsson.com
Both applied. Sorry I missed this :/ Thanks.
libteam@lists.fedorahosted.org