From owner-svn-src-head@FreeBSD.ORG Wed Apr 10 20:29:24 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 40C08105; Wed, 10 Apr 2013 20:29:24 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 338B48B0; Wed, 10 Apr 2013 20:29:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3AKTOJU064670; Wed, 10 Apr 2013 20:29:24 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3AKTNF8064667; Wed, 10 Apr 2013 20:29:23 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201304102029.r3AKTNF8064667@svn.freebsd.org> From: Gleb Smirnoff Date: Wed, 10 Apr 2013 20:29:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r249345 - head/usr.bin/netstat X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Apr 2013 20:29:24 -0000 Author: glebius Date: Wed Apr 10 20:29:23 2013 New Revision: 249345 URL: http://svnweb.freebsd.org/changeset/base/249345 Log: Use kvm_counter_u64_fetch() to fix obtaining ipstat and tcpstat from kernel core files. Sponsored by: Nginx, Inc. Modified: head/usr.bin/netstat/inet.c head/usr.bin/netstat/main.c head/usr.bin/netstat/netstat.h Modified: head/usr.bin/netstat/inet.c ============================================================================== --- head/usr.bin/netstat/inet.c Wed Apr 10 20:26:53 2013 (r249344) +++ head/usr.bin/netstat/inet.c Wed Apr 10 20:29:23 2013 (r249345) @@ -603,8 +603,13 @@ tcp_stats(u_long off, const char *name, warn("sysctl: net.inet.tcp.stats"); return; } - } else - kread(off, &tcpstat, len); + } else { + u_long tcpstat_p[sizeof(struct tcpstat)/sizeof(uint64_t)]; + + kread(off, &tcpstat_p, sizeof(tcpstat_p)); + kread_counters(tcpstat_p, (uint64_t *)&tcpstat, + sizeof(struct tcpstat)/sizeof(uint64_t)); + } printf ("%s:\n", name); @@ -858,8 +863,13 @@ ip_stats(u_long off, const char *name, i warn("sysctl: net.inet.ip.stats"); return; } - } else - kread(off, &ipstat, len); + } else { + u_long ipstat_p[sizeof(struct ipstat)/sizeof(uint64_t)]; + + kread(off, &ipstat_p, sizeof(ipstat_p)); + kread_counters(ipstat_p, (uint64_t *)&ipstat, + sizeof(struct ipstat)/sizeof(uint64_t)); + } printf("%s:\n", name); Modified: head/usr.bin/netstat/main.c ============================================================================== --- head/usr.bin/netstat/main.c Wed Apr 10 20:26:53 2013 (r249344) +++ head/usr.bin/netstat/main.c Wed Apr 10 20:29:23 2013 (r249345) @@ -147,11 +147,11 @@ static struct nlist nl[] = { #define N_IPCOMPSTAT 37 { .n_name = "_ipcompstat" }, #define N_TCPSTAT 38 - { .n_name = "_tcpstat" }, + { .n_name = "_tcpstatp" }, #define N_UDPSTAT 39 { .n_name = "_udpstat" }, #define N_IPSTAT 40 - { .n_name = "_ipstat" }, + { .n_name = "_ipstatp" }, #define N_ICMPSTAT 41 { .n_name = "_icmpstat" }, #define N_IGMPSTAT 42 @@ -696,37 +696,50 @@ printproto(struct protox *tp, const char (*pr)(off, name, af, tp->pr_protocol); } +static int +kvmd_init(void) +{ + char errbuf[_POSIX2_LINE_MAX]; + + if (kvmd != NULL) + return (0); + + kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); + setgid(getgid()); + + if (kvmd == NULL) { + warnx("kvm not available: %s", errbuf); + return (-1); + } + + if (kvm_nlist(kvmd, nl) < 0) { + if (nlistf) + errx(1, "%s: kvm_nlist: %s", nlistf, + kvm_geterr(kvmd)); + else + errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); + } + + if (nl[0].n_type == 0) { + if (nlistf) + errx(1, "%s: no namelist", nlistf); + else + errx(1, "no namelist"); + } + + return (0); +} + /* * Read kernel memory, return 0 on success. */ int kread(u_long addr, void *buf, size_t size) { - char errbuf[_POSIX2_LINE_MAX]; - if (kvmd == NULL) { - kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); - setgid(getgid()); - if (kvmd != NULL) { - if (kvm_nlist(kvmd, nl) < 0) { - if (nlistf) - errx(1, "%s: kvm_nlist: %s", nlistf, - kvm_geterr(kvmd)); - else - errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); - } + if (kvmd_init() < 0) + return (-1); - if (nl[0].n_type == 0) { - if (nlistf) - errx(1, "%s: no namelist", nlistf); - else - errx(1, "no namelist"); - } - } else { - warnx("kvm not available: %s", errbuf); - return(-1); - } - } if (!buf) return (0); if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) { @@ -736,6 +749,22 @@ kread(u_long addr, void *buf, size_t siz return (0); } +/* + * Read an array of N counters in kernel memory into array of N uint64_t's. + */ +int +kread_counters(u_long *addr, uint64_t *rval, size_t count) +{ + + if (kvmd_init() < 0) + return (-1); + + for (u_int i = 0; i < count; i++, addr++, rval++) + *rval = kvm_counter_u64_fetch(kvmd, *addr); + + return (0); +} + const char * plural(uintmax_t n) { Modified: head/usr.bin/netstat/netstat.h ============================================================================== --- head/usr.bin/netstat/netstat.h Wed Apr 10 20:26:53 2013 (r249344) +++ head/usr.bin/netstat/netstat.h Wed Apr 10 20:29:23 2013 (r249345) @@ -60,6 +60,7 @@ extern int af; /* address family */ extern int live; /* true if we are examining a live system */ int kread(u_long addr, void *buf, size_t size); +int kread_counters(u_long *addr, uint64_t *rval, size_t count); const char *plural(uintmax_t); const char *plurales(uintmax_t); const char *pluralies(uintmax_t);