From 09eb729d599c468e2192a2dd9ad25134bd1aaeea Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 16 Jan 2023 08:14:38 +0100 Subject: [PATCH] platform: retry link change on RESULT_FAILED_RESYNC Sometimes the buffer space of the netlink socket runs out and we lose the response to our link change: [1670321010.2952] platform-linux: netlink[rtnl]: read: too many netlink events. Need to resynchronize platform cache [1670321010.3467] platform-linux: do-change-link[2]: failure changing link: internal failure 3 With 3 above being WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC. Let's try harder. https://bugzilla.redhat.com/show_bug.cgi?id=2154350 (cherry picked from commit b8738002edd34c975b387d961458d2864c93c3ba) --- src/libnm-platform/nm-linux-platform.c | 37 +++++++++++++++++--------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 10c94933eb..b798d12d2a 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -7896,19 +7896,25 @@ do_change_link(NMPlatform *platform, WaitForNlResponseResult seq_result = WAIT_FOR_NL_RESPONSE_RESULT_UNKNOWN; gs_free char *errmsg = NULL; char s_buf[256]; - int result = 0; - NMLogLevel log_level = LOGL_DEBUG; - const char *log_detail = ""; + int result; + NMLogLevel log_level; + const char *log_detail; gs_free char *log_detail_free = NULL; const NMPObject *obj_cache; if (!nm_platform_netns_push(platform, &netns)) { log_level = LOGL_ERR; log_detail = ", failure to change network namespace"; + result = -NME_UNSPEC; goto out; } retry: + result = -NME_UNSPEC; + log_level = LOGL_WARN; + log_detail = ""; + nm_clear_g_free(&log_detail_free); + nle = _netlink_send_nlmsg_rtnl(platform, nlmsg, &seq_result, &errmsg); if (nle < 0) { log_level = LOGL_ERR; @@ -7926,13 +7932,19 @@ retry: nm_assert(seq_result); - if (NM_IN_SET(seq_result, -EOPNOTSUPP) && nlmsg_hdr(nlmsg)->nlmsg_type == RTM_NEWLINK) { - nlmsg_hdr(nlmsg)->nlmsg_type = RTM_SETLINK; - goto retry; - } - if (NM_IN_SET(seq_result, WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK, -EEXIST, -EADDRINUSE)) { - /* */ + log_level = LOGL_DEBUG; + result = 0; + } else if (NM_IN_SET(seq_result, -EOPNOTSUPP) && nlmsg_hdr(nlmsg)->nlmsg_type == RTM_NEWLINK) { + nlmsg_hdr(nlmsg)->nlmsg_type = RTM_SETLINK; + + log_level = LOGL_INFO; + log_detail = ", will try SETLINK instead of NEWLINK"; + result = -EAGAIN; + } else if (seq_result == WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC) { + log_level = LOGL_INFO; + log_detail = ", due to lost synchronization"; + result = -EAGAIN; } else if (NM_IN_SET(seq_result, -ESRCH, -ENOENT)) { log_detail = ", firmware not found"; result = -NME_PL_NO_FIRMWARE; @@ -7956,9 +7968,6 @@ retry: } else if (seq_result == -EAFNOSUPPORT) { log_level = LOGL_DEBUG; result = -NME_PL_OPNOTSUPP; - } else { - log_level = LOGL_WARN; - result = -NME_UNSPEC; } out: @@ -7967,6 +7976,10 @@ out: ifindex, wait_for_nl_response_to_string(seq_result, errmsg, s_buf, sizeof(s_buf)), log_detail); + + if (result == -EAGAIN) + goto retry; + return result; }