From 2c0f291b3c0a42715deebe19a1ca301bcd9fb9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Dejean?= Date: Mon, 28 Feb 2005 08:15:59 +0000 Subject: [PATCH] Fix a bug in netlist where glibtop_netlist.number was never initialized to * Makefile.am: * cpu.c: (glibtop_get_cpu_p): * netlist.c: (glibtop_get_netlist_s): * netload.c: (glibtop_get_netload_p): * procmem.c: (glibtop_get_proc_mem_p): Fix a bug in netlist where glibtop_netlist.number was never initialized to 0 (this resulted in a NULL pointer dereference in the network load feature of the multiload applet) * Add support for getting interface flags and packet counts even on interfaces without IP addresses (needed for the network load feature of the multiload applet) * Restore per-process limits in the !FreeBSD or __FreeBSD_version < 500013 case * Add CPU interrupt time as IOWAIT to get support for the cpu load feature of the multiload applet. Patch from marcus@freebsd.org (Joe Marcus Clarke). Closes #168704. --- sysdeps/freebsd/ChangeLog | 24 ++++++ sysdeps/freebsd/Makefile.am | 2 +- sysdeps/freebsd/cpu.c | 5 +- sysdeps/freebsd/netlist.c | 4 + sysdeps/freebsd/netload.c | 156 ++++++++++++++++++------------------ sysdeps/freebsd/procmem.c | 17 ++-- 6 files changed, 120 insertions(+), 88 deletions(-) diff --git a/sysdeps/freebsd/ChangeLog b/sysdeps/freebsd/ChangeLog index c4830110..e6a1e2cc 100644 --- a/sysdeps/freebsd/ChangeLog +++ b/sysdeps/freebsd/ChangeLog @@ -1,3 +1,27 @@ +2005-02-28 Benoît Dejean + + * Makefile.am: + * cpu.c: (glibtop_get_cpu_p): + * netlist.c: (glibtop_get_netlist_s): + * netload.c: (glibtop_get_netload_p): + * procmem.c: (glibtop_get_proc_mem_p): + + Fix a bug in netlist where glibtop_netlist.number was never initialized to 0 + (this resulted in a NULL pointer dereference in the network load feature + of the multiload applet) + + * Add support for getting interface flags and packet counts even on interfaces + without IP addresses (needed for the network load feature of the multiload applet) + + * Restore per-process limits in the !FreeBSD or __FreeBSD_version < 500013 + case + + * Add CPU interrupt time as IOWAIT to get support for the cpu load feature of + the multiload applet. + + Patch from marcus@freebsd.org (Joe Marcus Clarke). + Closes #168704. + 2005-02-23 Benoît Dejean * Makefile.am: diff --git a/sysdeps/freebsd/Makefile.am b/sysdeps/freebsd/Makefile.am index 2adb51a5..7a3ae6c2 100644 --- a/sysdeps/freebsd/Makefile.am +++ b/sysdeps/freebsd/Makefile.am @@ -12,7 +12,7 @@ libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \ sem_limits.c proclist.c procstate.c procuid.c \ proctime.c procmem.c procsignal.c prockernel.c \ procsegment.c procargs.c procmap.c netlist.c \ - netload.c ppp.c procopenfiles.c + netload.c ppp.c procopenfiles.c fsusage.c libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO) diff --git a/sysdeps/freebsd/cpu.c b/sysdeps/freebsd/cpu.c index 50678366..377e0339 100644 --- a/sysdeps/freebsd/cpu.c +++ b/sysdeps/freebsd/cpu.c @@ -34,7 +34,8 @@ static const unsigned long _glibtop_sysdeps_cpu = (1L << GLIBTOP_CPU_TOTAL) + (1L << GLIBTOP_CPU_USER) + (1L << GLIBTOP_CPU_NICE) + (1L << GLIBTOP_CPU_SYS) + -(1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY); +(1L << GLIBTOP_CPU_IDLE) + (1L << GLIBTOP_CPU_FREQUENCY) + +(1L << GLIBTOP_CPU_IOWAIT); #ifndef KERN_CP_TIME /* nlist structure for kernel access */ @@ -122,6 +123,8 @@ glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf) buf->sys = cpts [CP_SYS]; /* set idle time */ buf->idle = cpts [CP_IDLE]; + /* set iowait (really just interrupt) time */ + buf->iowait = cpts [CP_INTR]; /* set frequency */ /* diff --git a/sysdeps/freebsd/netlist.c b/sysdeps/freebsd/netlist.c index 8c595385..a2ef08b3 100644 --- a/sysdeps/freebsd/netlist.c +++ b/sysdeps/freebsd/netlist.c @@ -43,6 +43,10 @@ glibtop_get_netlist_s (glibtop *server, glibtop_netlist *buf) struct if_nameindex *ifstart, *ifs; GPtrArray *devices; + glibtop_init_s (&server, GLIBTOP_SYSDEPS_NETLIST, 0); + + memset (buf, 0, sizeof (glibtop_netlist)); + ifs = ifstart = if_nameindex(); devices = g_ptr_array_new(); diff --git a/sysdeps/freebsd/netload.c b/sysdeps/freebsd/netload.c index dd52f7c8..79a1ce0e 100644 --- a/sysdeps/freebsd/netload.c +++ b/sysdeps/freebsd/netload.c @@ -40,11 +40,6 @@ static const unsigned long _glibtop_sysdeps_netload = (1L << GLIBTOP_NETLOAD_IF_FLAGS) + -(1L << GLIBTOP_NETLOAD_MTU) + -#if !defined(__bsdi__) -(1L << GLIBTOP_NETLOAD_SUBNET) + -#endif -(1L << GLIBTOP_NETLOAD_ADDRESS) + (1L << GLIBTOP_NETLOAD_PACKETS_IN) + (1L << GLIBTOP_NETLOAD_PACKETS_OUT) + (1L << GLIBTOP_NETLOAD_PACKETS_TOTAL) + @@ -56,6 +51,13 @@ static const unsigned long _glibtop_sysdeps_netload = (1L << GLIBTOP_NETLOAD_ERRORS_TOTAL) + (1L << GLIBTOP_NETLOAD_COLLISIONS); +static const unsigned _glibtop_sysdeps_netload_data = +(1L << GLIBTOP_NETLOAD_ADDRESS) + +#if !defined(__bsdi__) +(1L << GLIBTOP_NETLOAD_SUBNET) + +#endif +(1L << GLIBTOP_NETLOAD_MTU); + /* nlist structure for kernel access */ static struct nlist nlst [] = { { "_ifnet" }, @@ -81,9 +83,9 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, { struct ifnet ifnet; u_long ifnetaddr, ifnetfound, ifaddraddr; - struct sockaddr *sa; + struct sockaddr *sa = NULL; char tname [16]; - char temp [16]; + char name [32]; union { struct ifaddr ifa; @@ -114,12 +116,21 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, if (kvm_read (server->machine.kd, (u_long) ifnet.if_name, tname, 16) != 16) glibtop_error_io_r (server, "kvm_read (if_name)"); - snprintf(temp, (15 - strlen(tname)), "%d", ifnet.if_unit); - strcat(tname, temp); - tname [15] = 0; + tname[15] = '\0'; + snprintf (name, 32, "%s%d", tname, ifnet.if_unit); #else - g_strlcpy (tname, ifnet.if_xname, sizeof tname); + g_strlcpy (name, ifnet.if_xname, sizeof(name)); #endif +#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) + ifnetaddr = (u_long) ifnet.if_link.tqe_next; +#elif defined(__FreeBSD__) || defined(__bsdi__) + ifnetaddr = (u_long) ifnet.if_next; +#else + ifnetaddr = (u_long) ifnet.if_list.tqe_next; +#endif + + if (strcmp (name, interface) != 0) + continue; #if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) ifaddraddr = (u_long) ifnet.if_addrhead.tqh_first; @@ -129,6 +140,55 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, ifaddraddr = (u_long) ifnet.if_addrlist.tqh_first; #endif } + if (ifnet.if_flags & IFF_UP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP); + if (ifnet.if_flags & IFF_BROADCAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST); + if (ifnet.if_flags & IFF_DEBUG) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG); + if (ifnet.if_flags & IFF_LOOPBACK) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK); + if (ifnet.if_flags & IFF_POINTOPOINT) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT); + if (ifnet.if_flags & IFF_RUNNING) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING); + if (ifnet.if_flags & IFF_NOARP) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP); + if (ifnet.if_flags & IFF_PROMISC) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC); + if (ifnet.if_flags & IFF_ALLMULTI) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI); + if (ifnet.if_flags & IFF_OACTIVE) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE); + if (ifnet.if_flags & IFF_SIMPLEX) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX); + if (ifnet.if_flags & IFF_LINK0) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0); + if (ifnet.if_flags & IFF_LINK1) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1); + if (ifnet.if_flags & IFF_LINK2) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2); +#ifdef __FreeBSD__ + if (ifnet.if_flags & IFF_ALTPHYS) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS); +#endif + if (ifnet.if_flags & IFF_MULTICAST) + buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST); + + buf->packets_in = ifnet.if_ipackets; + buf->packets_out = ifnet.if_opackets; + buf->packets_total = buf->packets_in + buf->packets_out; + + buf->bytes_in = ifnet.if_ibytes; + buf->bytes_out = ifnet.if_obytes; + buf->bytes_total = buf->bytes_in + buf->bytes_out; + + buf->errors_in = ifnet.if_ierrors; + buf->errors_out = ifnet.if_oerrors; + buf->errors_total = buf->errors_in + buf->errors_out; + + buf->collisions = ifnet.if_collisions; + buf->flags = _glibtop_sysdeps_netload; if (ifaddraddr) { if ((kvm_read (server->machine.kd, ifaddraddr, &ifaddr, @@ -137,86 +197,22 @@ glibtop_get_netload_p (glibtop *server, glibtop_netload *buf, #define CP(x) ((char *)(x)) cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + - CP(&ifaddr); sa = (struct sockaddr *)cp; + CP(&ifaddr); + sa = (struct sockaddr *)cp; - if (!strcmp (interface, tname) && (sa->sa_family == AF_INET)) { + if (sa->sa_family == AF_INET) { sin = (struct sockaddr_in *)sa; - - if (ifnet.if_flags & IFF_UP) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_UP); - if (ifnet.if_flags & IFF_BROADCAST) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_BROADCAST); - if (ifnet.if_flags & IFF_DEBUG) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_DEBUG); - if (ifnet.if_flags & IFF_LOOPBACK) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LOOPBACK); - if (ifnet.if_flags & IFF_POINTOPOINT) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_POINTOPOINT); - if (ifnet.if_flags & IFF_RUNNING) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_RUNNING); - if (ifnet.if_flags & IFF_NOARP) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_NOARP); - if (ifnet.if_flags & IFF_PROMISC) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_PROMISC); - if (ifnet.if_flags & IFF_ALLMULTI) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALLMULTI); - if (ifnet.if_flags & IFF_OACTIVE) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_OACTIVE); - if (ifnet.if_flags & IFF_SIMPLEX) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_SIMPLEX); - if (ifnet.if_flags & IFF_LINK0) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK0); - if (ifnet.if_flags & IFF_LINK1) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK1); - if (ifnet.if_flags & IFF_LINK2) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_LINK2); -#ifdef __FreeBSD__ - if (ifnet.if_flags & IFF_ALTPHYS) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_ALTPHYS); -#endif - if (ifnet.if_flags & IFF_MULTICAST) - buf->if_flags |= (1L << GLIBTOP_IF_FLAGS_MULTICAST); - #if !defined(__bsdi__) /* Commenting out to "fix" #13345. */ buf->subnet = htonl (ifaddr.in.ia_subnet); #endif buf->address = sin->sin_addr.s_addr; - buf->mtu = ifnet.if_mtu; - buf->packets_in = ifnet.if_ipackets; - buf->packets_out = ifnet.if_opackets; - buf->packets_total = buf->packets_in + buf->packets_out; + buf->flags |= _glibtop_sysdeps_netload_data; - buf->bytes_in = ifnet.if_ibytes; - buf->bytes_out = ifnet.if_obytes; - buf->bytes_total = buf->bytes_in + buf->bytes_out; - - buf->errors_in = ifnet.if_ierrors; - buf->errors_out = ifnet.if_oerrors; - buf->errors_total = buf->errors_in + buf->errors_out; - - buf->collisions = ifnet.if_collisions; - buf->flags = _glibtop_sysdeps_netload; - return; } - -#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) - ifaddraddr = (u_long)ifaddr.ifa.ifa_link.tqe_next; -#elif defined(__FreeBSD__) || defined(__bsdi__) - ifaddraddr = (u_long)ifaddr.ifa.ifa_next; -#else - ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next; -#endif } - -#if defined(__FreeBSD__) && (__FreeBSD_version >= 300000) - ifnetaddr = (u_long) ifnet.if_link.tqe_next; -#elif defined(__FreeBSD__) || defined(__bsdi__) - ifnetaddr = (u_long) ifnet.if_next; -#else - ifnetaddr = (u_long) ifnet.if_list.tqe_next; -#endif + return; } } diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c index 0bba91a2..5673c544 100644 --- a/sysdeps/freebsd/procmem.c +++ b/sysdeps/freebsd/procmem.c @@ -31,7 +31,7 @@ #include #include #include -#ifdef __NetBSD__ && (__NetBSD_Version__ >= 105020000) +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) #include #else #include @@ -47,7 +47,7 @@ #include #endif #include -#ifdef __NetBSD__ && (__NetBSD_Version__ >= 105020000) +#if defined(__NetBSD__) && (__NetBSD_Version__ >= 105020000) #include #else #include @@ -125,7 +125,9 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, #else struct vm_object object; #endif - struct rlimit rlimit; +#if !defined(__FreeBSD__) || (__FreeBSD_version < 500013) + struct plimit plimit; +#endif int count; glibtop_init_p (server, (1L << GLIBTOP_SYSDEPS_PROC_MEM), 0); @@ -160,12 +162,15 @@ glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, #define PROC_VMSPACE kp_proc.p_vmspace - if (getrlimit (RLIMIT_RSS, &rlimit) < 0) { - glibtop_warn_io_r (server, "getrlimit"); + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].PROC_VMSPACE, + (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) { + glibtop_warn_io_r (server, "kvm_read (plimit)"); return; } - buf->rss_rlim = (u_int64_t) (rlimit.rlim_cur); + buf->rss_rlim = (guint64) + (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur); vms = &pinfo [0].kp_eproc.e_vm;