$NetBSD: patch-aa,v 1.19 2007/12/17 22:08:12 veego Exp $ --- bsd/kernel.cc.orig 2006-02-18 08:36:06.000000000 +0100 +++ bsd/kernel.cc 2007-12-17 21:23:26.000000000 +0100 @@ -115,8 +115,16 @@ // in __NetBSD_Version__ for us if needed. #if defined(XOSVIEW_NETBSD) && defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 106010000) #define NETBSD_1_6A +#ifdef HW_DISKSTATS +static int dmib[3] = {CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl)}; +#endif +#ifdef HW_IOSTATS +static int dmib[3] = {CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl)}; +#include +#endif #endif +#include "netmeter.h" /* For netIface_ */ #include "general.h" #include "kernel.h" /* To grab CVSID stuff. */ @@ -303,9 +311,11 @@ void OpenKDIfNeeded() { + static int initialized = 0; char unusederrorstring[_POSIX2_LINE_MAX]; - if (kd) return; // kd is non-NULL, so it has been initialized. BCG + if (initialized) return; + initialized = 1; /* Open it read-only, for a little added safety. */ /* If the first character of kernelFileName is not '\0', then use @@ -313,8 +323,10 @@ specifying NULL. */ if ((kd = kvm_openfiles ((kernelFileName[0]) ? kernelFileName : NULL, NULL, NULL, O_RDONLY, unusederrorstring)) - == NULL) - err (-1, "OpenKDIfNeeded():kvm-open()"); + == NULL) { + warn ("OpenKDIfNeeded():kvm-open()"); + return; + } // Parenthetical note: FreeBSD kvm_openfiles() uses getbootfile() to get // the correct kernel file if the 1st arg is NULL. As far as I can see, // one should always use NULL in FreeBSD, but I suppose control is never a @@ -400,6 +412,8 @@ static int mib[] = { CTL_KERN, KERN_CPUSTATS }; #endif #if defined(XOSVIEW_NETBSD) && (__NetBSD_Version__ >= 104260000) + uint64_t cp_time[CPUSTATES]; + size_t size = sizeof(cp_time[0]) * CPUSTATES; static int mib[] = { CTL_KERN, KERN_CP_TIME }; #endif @@ -407,14 +421,11 @@ if (CPUSTATES != 5) errx (-1, "Error: xosview for *BSD expects 5 cpu states!\n"); #if defined(__NetBSD_Version__) && __NetBSD_Version__ > 104260000 /* > 1.4Z */ - struct schedstate_percpu ssp; - size_t size = sizeof(ssp.spc_cp_time); - if (sysctl(mib, 2, ssp.spc_cp_time, &size, NULL, 0) < 0) { - fprintf(stderr, "can't get schedstate_percpu: %s\n", strerror(errno)); - memset(&ssp, 0, sizeof(ssp)); + if (sysctl(mib, 2, cp_time, &size, NULL, 0) < 0) { + fprintf(stderr, "xosview: sysctl kern.cp_time failed: %s\n", strerror(errno)); + bzero(&cp_time, size); } - for (size = 0; size < CPUSTATES; size++) - timeArray[size] = (long) ssp.spc_cp_time[size]; + bcopy (cp_time, timeArray, size); #else #ifdef XOSVIEW_BSDI if (sysctl(mib, 2, &cpu, &size, NULL, 0) < 0) { @@ -441,7 +452,7 @@ } void -BSDGetNetInOut (long long * inbytes, long long * outbytes) { +NetMeter::BSDGetNetInOut (long long * inbytes, long long * outbytes) { struct ifnet * ifnetp; @@ -466,7 +477,8 @@ while (ifnetp) { // Now, dereference the pointer to get the ifnet struct. safe_kvm_read ((u_long) ifnetp, &ifnet, sizeof(ifnet)); -#ifdef NET_DEBUG +#ifdef XOSVIEW_NETBSD + if (netIface_ != "False" ) { char ifname[256]; #ifdef NETBSD_OLD_IFACE // In pre-1.2A, getting the interface name was more complicated. @@ -476,15 +488,21 @@ safe_kvm_read ((u_long) (((char*)ifnetp) + (&ifnet.if_xname[0] - (char*)&ifnet)), ifname, 256); snprintf (ifname, 256, "%s", ifname); #endif +#ifdef NET_DEBUG printf ("Interface name is %s\n", ifname); printf ("Ibytes: %8llu Obytes %8llu\n", (unsigned long long) ifnet.if_ibytes, (unsigned long long) ifnet.if_obytes); printf ("Ipackets: %8llu\n", (unsigned long long) ifnet.if_ipackets); -#endif +#endif /* NET_DEBUG */ + if (ifname != netIface_) + goto skipif; + } +#endif /* XOSVIEW_NETBSD */ *inbytes += ifnet.if_ibytes; *outbytes += ifnet.if_obytes; + skipif: // Linked-list step taken from if.c in netstat source, line 120. #ifdef XOSVIEW_FREEBSD #if (__FreeBSD_version >= 300000) @@ -773,13 +791,12 @@ #ifdef NETBSD_1_6A // Do a sysctl with a NULL data pointer to get the size that would // have been returned, and use that to figure out # drives. - int mib[3] = {CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl)}; size_t size; - if (sysctl(mib, 3, NULL, &size, NULL, 0) < 0) { + if (sysctl(dmib, 3, NULL, &size, NULL, 0) < 0) { warnx("!!! The DiskMeter sysctl failed. Disabling DiskMeter."); return 0; } - NetBSD_N_Drives = size / sizeof(struct disk_sysctl); + NetBSD_N_Drives = size / dmib[2]; return 1; #endif return ValidSymbol(DISKLIST_SYM_INDEX); @@ -816,19 +833,29 @@ #else #if defined(NETBSD_1_6A) // Use the new sysctl to do this for us. - int mib[3] = {CTL_HW, HW_DISKSTATS, sizeof(struct disk_sysctl)}; - size_t sysctl_sz = NetBSD_N_Drives * sizeof(struct disk_sysctl); + size_t sysctl_sz = NetBSD_N_Drives * dmib[2]; +#ifdef HW_DISKSTATS struct disk_sysctl drive_stats[NetBSD_N_Drives]; +#endif +#ifdef HW_IOSTATS + struct io_sysctl drive_stats[NetBSD_N_Drives]; +#endif // Do the sysctl. - if (sysctl(mib, 3, drive_stats, &sysctl_sz, NULL, 0) < 0) { + if (sysctl(dmib, 3, drive_stats, &sysctl_sz, NULL, 0) < 0) { err(1, "sysctl hw.diskstats failed"); } // Now accumulate the total. unsigned long long xferred = 0; for (unsigned int i = 0; i < NetBSD_N_Drives; i++) { +#ifdef HW_DISKSTATS xferred += drive_stats[i].dk_rbytes + drive_stats[i].dk_wbytes; +#endif +#ifdef HW_IOSTATS + if (drive_stats[i].type == IOSTAT_DISK) + xferred += drive_stats[i].rbytes + drive_stats[i].wbytes; +#endif } *bytesXferred = xferred; #else @@ -1016,7 +1043,7 @@ while (evptr && i < NUM_INTR) { - safe_kvm_read((unsigned int)evptr, &evcnt, sizeof(evcnt)); + safe_kvm_read((u_long)evptr, &evcnt, sizeof(evcnt)); evptr = evcnt.ev_list.tqe_next; @@ -1024,7 +1051,7 @@ if (evcnt.ev_type != EVCNT_TYPE_INTR) continue; - safe_kvm_read((unsigned int)evcnt.ev_name, evname, evcnt.ev_namelen); + safe_kvm_read((u_long)evcnt.ev_name, evname, evcnt.ev_namelen); // If it's a soft interrupt (has a name that starts with "soft"), skip it. if (!strncmp(evname, "soft", 4)) continue;