From: Jakub Jelinek <jakub@redhat.com>
To: Ulrich Drepper <drepper@redhat.com>
Cc: Glibc hackers <libc-hacker@sources.redhat.com>
Subject: [PATCH] Better fix for ifaddrs
Date: Wed, 14 Mar 2007 18:16:00 -0000 [thread overview]
Message-ID: <20070314182000.GK1826@sunsite.mff.cuni.cz> (raw)
Hi!
David Miller said kernel guarantees that netlink requests are split into at
most page sized chunks.
This patch removes again all the MSG_TRUNC handling and instead uses page
sized buffer. I believe a page should be ok with alloca/VLA always, so I
have removed even the use_malloc etc. stuff, if you think I should use
__libc_use_alloca even for this, please let me know.
Tested on ia64 with 80 interfaces.
2007-03-14 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/ifaddrs.c (__netlink_request): Revert
2005-06-13, 2007-02-27 and 2007-03-02 changes. Use page sized buffer.
* sysdeps/unix/sysv/linux/check_pf.c (make_request): Use page sized
buffer.
--- libc/sysdeps/unix/sysv/linux/check_pf.c.jj 2007-01-03 11:04:37.000000000 +0100
+++ libc/sysdeps/unix/sysv/linux/check_pf.c 2007-03-13 18:16:12.000000000 +0100
@@ -1,5 +1,5 @@
/* Determine protocol families for which interfaces exist. Linux version.
- Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -80,8 +80,9 @@ make_request (int fd, pid_t pid, bool *s
*seen_ipv6 = false;
bool done = false;
- char buf[4096];
- struct iovec iov = { buf, sizeof (buf) };
+ size_t buf_size = __getpagesize ();
+ char buf[buf_size];
+ struct iovec iov = { buf, buf_size };
struct in6ailist
{
struct in6addrinfo info;
--- libc/sysdeps/unix/sysv/linux/ifaddrs.c.jj 2007-03-13 17:42:17.000000000 +0100
+++ libc/sysdeps/unix/sysv/linux/ifaddrs.c 2007-03-13 18:17:06.000000000 +0100
@@ -122,37 +122,17 @@ int
__netlink_request (struct netlink_handle *h, int type)
{
struct netlink_res *nlm_next;
- struct netlink_res **new_nlm_list;
- static volatile size_t buf_size = 4096;
- char *buf;
+ size_t buf_size = __getpagesize ();
+ char buf[buf_size];
struct sockaddr_nl nladdr;
struct nlmsghdr *nlmh;
ssize_t read_len;
bool done = false;
- bool use_malloc = false;
if (__netlink_sendreq (h, type) < 0)
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
- {
- buf = malloc (this_buf_size);
- if (buf != NULL)
- use_malloc = true;
- else
- goto out_fail;
- }
-
- struct iovec iov = { buf, this_buf_size };
-
- if (h->nlm_list != NULL)
- new_nlm_list = &h->end_ptr->next;
- else
- new_nlm_list = &h->nlm_list;
+ struct iovec iov = { buf, buf_size };
while (! done)
{
@@ -166,54 +146,13 @@ __netlink_request (struct netlink_handle
read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
if (read_len < 0)
- goto out_fail;
+ return -1;
if (nladdr.nl_pid != 0)
continue;
if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
- {
- if (this_buf_size >= SIZE_MAX / 2)
- goto out_fail;
-
- 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;
-
- if (__libc_use_alloca (2 * this_buf_size))
- buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
- else
- {
- this_buf_size *= 2;
-
- char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
- if (new_buf == NULL)
- goto out_fail;
- buf = new_buf;
-
- use_malloc = true;
- }
- buf_size = this_buf_size;
-
- iov.iov_base = buf;
- iov.iov_len = this_buf_size;
-
- /* Increase sequence number, so that we can distinguish
- between old and new request messages. */
- h->seq++;
-
- if (__netlink_sendreq (h, type) < 0)
- goto out_fail;
-
- continue;
- }
+ return -1;
size_t count = 0;
size_t remaining_len = read_len;
@@ -237,39 +176,9 @@ __netlink_request (struct netlink_handle
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;
+ return -1;
}
}
@@ -281,7 +190,7 @@ __netlink_request (struct netlink_handle
nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
+ read_len);
if (nlm_next == NULL)
- goto out_fail;
+ return -1;
nlm_next->next = NULL;
nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
nlm_next->size = read_len;
@@ -293,14 +202,7 @@ __netlink_request (struct netlink_handle
h->end_ptr = nlm_next;
}
- if (use_malloc)
- free (buf);
return 0;
-
-out_fail:
- if (use_malloc)
- free (buf);
- return -1;
}
Jakub
next reply other threads:[~2007-03-14 18:16 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-14 18:16 Jakub Jelinek [this message]
2007-03-15 0:45 ` Ulrich Drepper
2007-03-15 8:37 ` Jakub Jelinek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070314182000.GK1826@sunsite.mff.cuni.cz \
--to=jakub@redhat.com \
--cc=drepper@redhat.com \
--cc=libc-hacker@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).