This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
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
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |