From 0b3b1a0ce81276e92b25f71a11602ae1dd014015 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 5 Mar 2007 20:32:32 +0000 Subject: * 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. --- ChangeLog | 6 ++++++ sysdeps/unix/sysv/linux/ifaddrs.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8fbcb8b..6256913 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-03-02 Jakub Jelinek + + * 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 [BZ #4069] diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index e43f39f..6c0f6b3 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; -- cgit v1.1