diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2023-01-16 08:14:38 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2023-01-26 09:24:04 +0100 |
commit | 09eb729d599c468e2192a2dd9ad25134bd1aaeea (patch) | |
tree | bc5caed9e15fdda2c164b31b406c3913bbf579e2 | |
parent | a2345c318d479410c3cef2bb88b371fa608af809 (diff) |
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:
<info> [1670321010.2952] platform-linux: netlink[rtnl]: read: too many netlink events. Need to resynchronize platform cache
<warn> [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)
-rw-r--r-- | src/libnm-platform/nm-linux-platform.c | 35 |
1 files changed, 24 insertions, 11 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) { + 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; - goto retry; - } - if (NM_IN_SET(seq_result, WAIT_FOR_NL_RESPONSE_RESULT_RESPONSE_OK, -EEXIST, -EADDRINUSE)) { - /* */ + 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; } |