Re: netstat: sysctl: net.route.0.0.dump.0: Cannot allocate memor
----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)--
Content-Type: Multipart/Mixed;
boundary="--Next_Part(Fri_Feb_21_18_20_37_2014_329)--"
Content-Transfer-Encoding: 7bit
----Next_Part(Fri_Feb_21_18_20_37_2014_329)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Ian FREISLICH <ianf@clue.co.za> wrote
in <E1WGltZ-0000kf-1A@clue.co.za>:
ia> Hiroki Sato wrote:
ia> > ia> While recieving my routing table I used to be able to check how far
ia> > ia> it got by counting the output netstat -rn. It takes about 2 seconds
ia> > ia> to recieve the routes from my route-server, but over a minute to
ia> > ia> update the kernel routing table.
ia> > ia>
ia> > ia> I'm now getting this error until zebra completes route insertion.
ia> > ia>
ia> > ia> [firewall1.jnb1] ~ $ netstat -rn |wc -l
ia> > ia> netstat: sysctl: net.route.0.0.dump.0: Cannot allocate memory
ia> > ia> 1
ia> > ia> [firewall1.jnb1] ~ $ netstat -rn |wc -l
ia> > ia> 480446
ia> >
ia> > Perhaps does the attached patch fix this?
ia>
ia> Sadly, not.
Hm, how about the attached one?
I think the cause is just a race when length of the sysctl's output
is changed in kernel after the buffer allocation in userspace, not
memory shortage. Size of the routing table can quickly change.
-- Hiroki
----Next_Part(Fri_Feb_21_18_20_37_2014_329)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="netstat-1.diff"
Index: usr.bin/netstat/route.c
===================================================================
--- usr.bin/netstat/route.c (revision 262283)
+++ usr.bin/netstat/route.c (working copy)
@@ -69,6 +69,7 @@
#include <sysexits.h>
#include <unistd.h>
#include <err.h>
+#include <errno.h>
#include "netstat.h"
#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d)))
@@ -560,7 +561,7 @@
char *buf, *next, *lim;
struct rt_msghdr *rtm;
struct sockaddr *sa;
- int fam = 0, ifindex = 0, size;
+ int fam = 0, ifindex = 0, size, count = 0;
struct ifaddrs *ifap, *ifa;
struct sockaddr_dl *sdl;
@@ -600,6 +601,7 @@
freeifaddrs(ifap);
+retry:
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
@@ -607,19 +609,24 @@
mib[4] = NET_RT_DUMP;
mib[5] = 0;
mib[6] = fibnum;
- if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0) {
+ if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
err(1, "sysctl: net.route.0.%d.dump.%d estimate", af, fibnum);
+ if ((buf = malloc(needed)) == NULL)
+ errx(2, "malloc(%zd)", needed);
+ if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) {
+ if (errno == ENOMEM && count++ < 20) {
+ warnx("Routing table grew, retrying");
+ sleep(1);
+ free(buf);
+ goto retry;
+ } else
+ err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
}
-
- if ((buf = malloc(needed)) == 0) {
- errx(2, "malloc(%lu)", (unsigned long)needed);
- }
- if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
- err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
- }
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
+ if (rtm->rtm_version != RTM_VERSION)
+ continue;
/*
* Peek inside header to determine AF
*/
----Next_Part(Fri_Feb_21_18_20_37_2014_329)----
----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)--
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iEYEABECAAYFAlMHGmUACgkQTyzT2CeTzy1+ZQCcDA3RXqqLhsnrSAfBkB0joLyy
r70AnAjWvIMo0M9RJkKR9sprugWyW44j
=UO1z
-----END PGP SIGNATURE-----
----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)----
討論串 (同標題文章)
完整討論串 (本文為第 4 之 7 篇):