aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-03-05 20:32:32 +0000
committerUlrich Drepper <drepper@redhat.com>2007-03-05 20:32:32 +0000
commit0b3b1a0ce81276e92b25f71a11602ae1dd014015 (patch)
tree7a6c81787f7e9894d396b6e34655ad77cb0e2789
parentc1c5e654bcf7884e79c7911001b496ca7f43c1a9 (diff)
downloadglibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.zip
glibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.tar.gz
glibc-0b3b1a0ce81276e92b25f71a11602ae1dd014015.tar.bz2
* 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.
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c31
2 files changed, 37 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8fbcb8b..6256913 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 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;