pppd: Retry registering interface when on rtnetlink -EBUSY error
authorPali Rohár <pali@kernel.org>
Sat, 7 Aug 2021 17:48:01 +0000 (19:48 +0200)
committerPali Rohár <pali@kernel.org>
Thu, 18 Aug 2022 23:20:14 +0000 (01:20 +0200)
Due to workaround in kernel module ppp_generic.ko in function
ppp_nl_newlink(), kernel may return -EBUSY error to prevent possible
mutex deadlock. In this case userspace needs to retry its request.

Proper way would be to fix kernel module to order requests and mutex
locking, so prevent deadlock in kernel and so never return this error to
userspace. Until it happens we need retry code in userspace.

Signed-off-by: Pali Rohár <pali@kernel.org>
pppd/sys-linux.c

index dc3b4d658de4770c32a95900d9f811b4c7fc5878..7beb977484f5ddca6859e10f79dcab039e26ea9c 100644 (file)
@@ -864,7 +864,14 @@ static int make_ppp_unit_rtnetlink(void)
     nlreq.ifli.ifid.ifdata[0].rta.rta_type = IFLA_PPP_DEV_FD;
     nlreq.ifli.ifid.ifdata[0].ppp.ppp_dev_fd = ppp_dev_fd;
 
-    resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
+    /*
+     * See kernel function ppp_nl_newlink(), which may return -EBUSY to prevent
+     * possible deadlock in kernel and ask userspace to retry request again.
+     */
+    do {
+        resp = rtnetlink_msg("RTM_NEWLINK/NLM_F_CREATE", NULL, &nlreq, sizeof(nlreq), NULL, NULL, 0);
+    } while (resp == -EBUSY);
+
     if (resp) {
         /*
          * Linux kernel versions prior to 4.7 do not support creating ppp