diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/ifaddrs.c | 31 |
2 files changed, 37 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog index 8fbcb8b133..6256913526 100644 --- 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] diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index e43f39f9e3..6c0f6b3dce 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -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; |