]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Retry with
authorUlrich Drepper <drepper@redhat.com>
Mon, 5 Mar 2007 20:32:32 +0000 (20:32 +0000)
committerUlrich Drepper <drepper@redhat.com>
Mon, 5 Mar 2007 20:32:32 +0000 (20:32 +0000)
a new netlink socket if NLMSG_ERR -EBUSY is seen after some MSG_TRUNC
message.

ChangeLog
sysdeps/unix/sysv/linux/ifaddrs.c

index 8fbcb8b133c00945a7921323c31c26b49c13734f..6256913526a2e4878da79a5d34de0d7dc296f1b5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-03-02  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Retry with
+       a new netlink socket if NLMSG_ERR -EBUSY is seen after some MSG_TRUNC
+       message.
+
 2007-03-01  Jakub Jelinek  <jakub@redhat.com>
 
        [BZ #4069]
index e43f39f9e3ed4c7d92397849d9f1855844431bc7..6c0f6b3dcedef2bbd029d71080b18b5e5e4988a0 100644 (file)
@@ -135,6 +135,7 @@ __netlink_request (struct netlink_handle *h, int type)
     return -1;
 
   size_t this_buf_size = buf_size;
+  size_t orig_this_buf_size = this_buf_size;
   if (__libc_use_alloca (this_buf_size))
     buf = alloca (this_buf_size);
   else
@@ -236,6 +237,36 @@ __netlink_request (struct netlink_handle *h, int type)
              struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
              if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
                errno = EIO;
+             else if (nlerr->error == -EBUSY
+                      && orig_this_buf_size != this_buf_size)
+               {
+                 /* If EBUSY and MSG_TRUNC was seen, try again with a new
+                    netlink socket.  */
+                 struct netlink_handle hold = *h;
+                 if (__netlink_open (h) < 0)
+                   {
+                     *h = hold;
+                     goto out_fail;
+                   }
+                 __netlink_close (&hold);
+                 orig_this_buf_size = this_buf_size;
+                 nlm_next = *new_nlm_list;
+                 while (nlm_next != NULL)
+                   {
+                     struct netlink_res *tmpptr;
+
+                     tmpptr = nlm_next->next;
+                     free (nlm_next);
+                     nlm_next = tmpptr;
+                   }
+                 *new_nlm_list = NULL;
+                 count = 0;
+                 h->seq++;
+
+                 if (__netlink_sendreq (h, type) < 0)
+                   goto out_fail;
+                 break;
+               }
              else
                errno = -nlerr->error;
              goto out_fail;