/* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_sysctl( void ) { int i, n; size_t siz; int ncpu_mib[] = { CTL_HW, HW_NCPU }; #if !(defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) ) ) int model_mib[] = { CTL_HW, HW_MODEL }; #endif char descr[ SNMP_MAXBUF ]; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); siz = sizeof(n); sysctl(ncpu_mib, 2, &n, &siz, NULL, 0); if ( n <= 0 ) n = 1; /* Single CPU system */ siz = sizeof(descr); #if defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) ) sysctlbyname("machdep.cpu_brand", descr, &siz, NULL, 0); #else sysctl(model_mib, 2, descr, &siz, NULL, 0); #endif for ( i = 0; i < n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->status = 2; /* running */ sprintf( cpu->name, "cpu%d", i ); sprintf( cpu->descr, "%s", descr ); } cpu_num = n; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { struct vmmeter vmm; size_t len; struct kinfo_cputime cp_time; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); kinfo_get_sched_cputime(&cp_time); len = sizeof(vmm); sysctlbyname("vm.vmmeter", &vmm, &len, NULL, 0); cpu->user_ticks = cp_time.cp_user; cpu->nice_ticks = cp_time.cp_nice; cpu->sys2_ticks = cp_time.cp_sys + cp_time.cp_intr; cpu->idle_ticks = cp_time.cp_idle; cpu->kern_ticks = cp_time.cp_sys; cpu->intrpt_ticks = cp_time.cp_intr; cpu->swapIn = vmm.v_swappgsin + vmm.v_vnodepgsin; cpu->swapOut = vmm.v_swappgsout + vmm.v_vnodepgsout; cpu->nInterrupts = vmm.v_intr; cpu->nCtxSwitches = vmm.v_swtch; /* Copy "overall" figures to cpu0 entry */ _cpu_copy_stats( cpu ); return 0; }
void _cpu_copy_stats( netsnmp_cpu_info *cpu ) { netsnmp_cpu_info *cpu2; /* * Copy "overall" statistics to the 'cpu0' entry * on single CPU systems where this isn't done automatically */ cpu2 = netsnmp_cpu_get_byIdx( 0, 1 ); if (!cpu || !cpu2) return; cpu2->user_ticks = cpu->user_ticks; cpu2->nice_ticks = cpu->nice_ticks; cpu2->sys_ticks = cpu->sys_ticks; cpu2->sys2_ticks = cpu->sys2_ticks; cpu2->idle_ticks = cpu->idle_ticks; cpu2->wait_ticks = cpu->wait_ticks; cpu2->kern_ticks = cpu->kern_ticks; cpu2->intrpt_ticks = cpu->intrpt_ticks; cpu2->sirq_ticks = cpu->sirq_ticks; cpu2->nInterrupts = cpu->nInterrupts; cpu2->nCtxSwitches = cpu->nCtxSwitches; cpu2->swapIn = cpu->swapIn; cpu2->swapOut = cpu->swapOut; cpu2->pageIn = cpu->pageIn; cpu2->pageOut = cpu->pageOut; }
/* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_kstat( void ) { int i = 0, n = 0, clock, state_begin; char ctype[15], ftype[15], state[10]; kstat_t *ksp; kstat_named_t *ks_data; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); if (kstat_fd == NULL) kstat_fd = kstat_open(); kstat_chain_update( kstat_fd ); DEBUGMSGTL(("cpu", "cpu_kstat init\n ")); for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (ksp->ks_flags & KSTAT_FLAG_INVALID) continue; if ((strcmp(ksp->ks_module, "cpu_info") == 0) && (strcmp(ksp->ks_class, "misc" ) == 0)) { kstat_read(kstat_fd, ksp, NULL ); n++; clock = 999999; memset(ctype, 0, sizeof(ctype)); memset(ftype, 0, sizeof(ftype)); memset(state, 0, sizeof(state)); for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) { if ( strcmp( ks_data->name, "state" ) == 0 ) { strlcpy(state, ks_data->value.c, sizeof(state)); } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) { state_begin = ks_data->value.i32; } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) { strlcpy(ctype, ks_data->value.c, sizeof(ctype)); } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) { strlcpy(ftype, ks_data->value.c, sizeof(ftype)); } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) { clock = ks_data->value.i32; } } i = ksp->ks_instance; cpu = netsnmp_cpu_get_byIdx( i, 1 ); sprintf( cpu->name, "cpu%d", i ); sprintf( cpu->descr, "CPU %d Sun %d MHz %s with %s FPU %s", i, clock, ctype, ftype, state ); cpu->status = _cpu_status(state); /* XXX - or in 'n_c_a_load' ? */ } } cpu_num = i; }
/* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_perfstat( void ) { int i; perfstat_id_t name; perfstat_cpu_t *cs2; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); cpu_num = perfstat_cpu( NULL, NULL, sizeof(perfstat_cpu_t), 0 ); cs2 = (perfstat_cpu_t*)malloc( cpu_num*sizeof(perfstat_cpu_t)); strcpy( name.name, ""); if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), cpu_num) > 0) { for ( i = 0; i < cpu_num; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); sprintf( cpu->name, cs2[i].name); } } free(cs2); }
/* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_kinfo( void ) { netsnmp_cpu_info *cpu; int i; size_t len; char descr[ SNMP_MAXBUF ]; cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); kinfo_get_cpus(&cpu_num); len = sizeof(descr); sysctlbyname("hw.model", descr, &len, NULL, 0); for ( i = 0; i < cpu_num; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->status = 2; /* running */ sprintf(cpu->name, "cpu%d", i); sprintf(cpu->descr, "%s", descr); } }
/* * Initialise the list of CPUs on the system * (including descriptions) * * XXX - Assumes x86-style /proc/cpuinfo format * See CPUinfo database at * http://www.rush3d.com/gcc/ * for info on alternative styles */ void init_cpu_linux( void ) { FILE *fp; char buf[1024], *cp; int i, n = 0; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); fp = fopen( CPU_FILE, "r" ); if (!fp) { snmp_log(LOG_ERR, "Can't open procinfo file %s\n", CPU_FILE); return; } while ( fgets( buf, sizeof(buf), fp)) { if ( sscanf( buf, "processor : %d", &i ) == 1) { n++; cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->status = 2; /* running */ sprintf( cpu->name, "cpu%d", i ); #if defined(__s390__) || defined(__s390x__) strcat( cpu->descr, "An S/390 CPU" ); #endif } #ifdef DESCR_FIELD if (!strncmp( buf, DESCR_FIELD, strlen(DESCR_FIELD))) { cp = strchr( buf, ':' ); strcpy( cpu->descr, cp+2 ); cp = strchr( cpu->descr, '\n' ); *cp = 0; } #endif #ifdef DESCR2_FIELD if (!strncmp( buf, DESCR2_FIELD, strlen(DESCR2_FIELD))) { cp = strchr( buf, ':' ); strcat( cpu->descr, cp ); cp = strchr( cpu->descr, '\n' ); *cp = 0; } #endif } fclose(fp); cpu_num = n; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { long cpu_stats[CPUSTATES]; struct vmmeter mem_stats; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); auto_nlist( CPU_SYMBOL, (char *) cpu_stats, sizeof(cpu_stats)); auto_nlist( MEM_SYMBOL, (char *)&mem_stats, sizeof(mem_stats)); cpu->user_ticks = (unsigned long long)cpu_stats[CP_USER]; cpu->nice_ticks = (unsigned long long)cpu_stats[CP_NICE]; cpu->sys2_ticks = (unsigned long long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR]; cpu->idle_ticks = (unsigned long long)cpu_stats[CP_IDLE]; cpu->kern_ticks = (unsigned long long)cpu_stats[CP_SYS]; cpu->intrpt_ticks = (unsigned long long)cpu_stats[CP_INTR]; /* wait_ticks, sirq_ticks unused */ /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ #if defined(openbsd2) || defined(darwin) cpu->swapIn = (unsigned long long)mem_stats.v_swpin; cpu->swapOut = (unsigned long long)mem_stats.v_swpout; #else cpu->swapIn = (unsigned long long)mem_stats.v_swappgsin+mem_stats.v_vnodepgsin; cpu->swapOut = (unsigned long long)mem_stats.v_swappgsout+mem_stats.v_vnodepgsout; #endif cpu->nInterrupts = (unsigned long long)mem_stats.v_intr; cpu->nCtxSwitches = (unsigned long long)mem_stats.v_swtch; #ifdef PER_CPU_INFO for ( i = 0; i < n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 0 ); /* XXX - per-CPU statistics */ } #else /* Copy "overall" figures to cpu0 entry */ _cpu_copy_stats( cpu ); #endif return 0; }
/* * Initialise the list of CPUs on the system * (including descriptions) */ void init_cpu_nlist( void ) { int n; size_t i; int ncpu_mib[] = { CTL_HW, HW_NCPU }; int model_mib[] = { CTL_HW, HW_MODEL }; char descr[ SNMP_MAXBUF ]; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 ); strcpy(cpu->name, "Overall CPU statistics"); i = sizeof(n); sysctl(ncpu_mib, 2, &n, &i, NULL, 0); i = sizeof(descr); sysctl(model_mib, 2, descr, &i, NULL, 0); if ( n <= 0 ) n = 1; /* Single CPU system */ for ( i=0; i<n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->status = 2; /* running */ sprintf(cpu->name, "cpu%d", i); sprintf(cpu->descr, "%s", descr); } cpu_num = n; }
u_char * var_hrproc(struct variable * vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { int proc_idx; unsigned long long value; netsnmp_cpu_info *cpu; proc_idx = header_hrproc(vp, name, length, exact, var_len, write_method); if (proc_idx == MATCH_FAILED) return NULL; switch (vp->magic) { case HRPROC_ID: *var_len = nullOidLen; return (u_char *) nullOid; case HRPROC_LOAD: cpu = netsnmp_cpu_get_byIdx( proc_idx & HRDEV_TYPE_MASK, 0 ); if ( !cpu || !cpu->history || !cpu->history[0].total_hist || ( cpu->history[0].total_hist == cpu->total_ticks )) return NULL; value = (cpu->idle_ticks - cpu->history[0].idle_hist)*100; value /= (cpu->total_ticks - cpu->history[0].total_hist); long_return = 100 - value; if (long_return < 0) long_return = 0; return (u_char *) & long_return; default: DEBUGMSGTL(("host/hr_proc", "unknown sub-id %d in var_hrproc\n", vp->magic)); } return NULL; }
const char * describe_proc(int idx) { netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( idx & HRDEV_TYPE_MASK, 0 ); return (cpu ? cpu->descr : NULL ); }
static unsigned vmstat (int iindex) { double duse, dsys, didl, ddiv, divo2; double druse, drnic, drsys, dridl; unsigned int hertz; double ddiv2; netsnmp_cpu_info *cpu; netsnmp_cpu_load (); cpu = netsnmp_cpu_get_byIdx (-1, 0); duse = cpu->user_ticks + cpu->nice_ticks; dsys = cpu->sys_ticks; didl = cpu->idle_ticks; ddiv = duse + dsys + didl; hertz = sysconf (_SC_CLK_TCK); /* get ticks/s from system */ divo2 = ddiv / 2; druse = cpu->user_ticks; drnic = cpu->nice_ticks; drsys = cpu->sys_ticks; dridl = cpu->idle_ticks; ddiv2 = ddiv + cpu->wait_ticks + cpu->intrpt_ticks + cpu->sirq_ticks; if (cpu->history) { duse -= (cpu->history[0].user_hist + cpu->history[0].nice_hist); dsys -= cpu->history[0].sys_hist; didl -= cpu->history[0].idle_hist; ddiv2 -= cpu->history[0].total_hist; } if (!ddiv) ddiv = 1; /* Protect against division-by-0 */ switch (iindex) { case swapin: return (cpu->swapIn * 4 * hertz + divo2) / ddiv; case swapout: return (cpu->swapOut * 4 * hertz + divo2) / ddiv; case iosent: return (cpu->pageIn * hertz + divo2) / ddiv; case ioreceive: return (cpu->pageOut * hertz + divo2) / ddiv; case sysinterrupts: return (cpu->nInterrupts * hertz + divo2) / ddiv; case syscontext: return (cpu->nCtxSwitches * hertz + divo2) / ddiv; case cpuuser: return (ddiv2 ? 100 * duse / ddiv2 : 0); case cpusystem: return (ddiv2 ? 100 * dsys / ddiv2 : 0); case cpuidle: return (ddiv2 ? 100 * didl / ddiv2 : 0); case cpurawuser: return druse; case cpurawnice: return drnic; case cpurawsystem: return drsys; case cpurawidle: return dridl; case rawinterrupts: return cpu->nInterrupts; case rawcontext: return cpu->nCtxSwitches; case cpurawwait: return cpu->wait_ticks; case cpurawinter: return cpu->intrpt_ticks; case cpurawsoft: return cpu->sirq_ticks; case rawiosent: return cpu->pageOut * 2; case rawioreceive: return cpu->pageIn * 2; case rawswapin: return cpu->swapIn; case rawswapout: return cpu->swapOut; default: return -1; } }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { #ifdef NETSNMP_KERN_MCPU int i; #endif /* * Strictly speaking, BSDi ought to use * "struct cpustats cpu_stats" * but this array was used in the previous code, and * is correct for the {Open,Net}BSD versions too. * Don't fight it, Dave - go with the flow.... */ NETSNMP_CPU_STATS cpu_stats[CPUSTATES]; #if !defined(__FreeBSD__) || defined(__FreeBSD_kernel__) && !defined(__NetBSD__) int cpu_mib[] = { CTL_KERN, NETSNMP_KERN_CPU }; #endif size_t cpu_size = sizeof(cpu_stats); #ifdef NETSNMP_KERN_MCPU NETSNMP_KERN_MCPU_TYPE *mcpu_stats; int mcpu_mib[] = { CTL_KERN, NETSNMP_KERN_MCPU }; size_t mcpu_size; #endif NETSNMP_VM_STATS_TYPE mem_stats; int mem_mib[] = { CTL_VM, NETSNMP_VM_STATS }; size_t mem_size = sizeof(NETSNMP_VM_STATS_TYPE); netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); #if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)) sysctlbyname("kern.cp_time", cpu_stats, &cpu_size, NULL, 0); #else sysctl(cpu_mib, 2, cpu_stats, &cpu_size, NULL, 0); #endif cpu->user_ticks = (unsigned long long)cpu_stats[CP_USER]; cpu->nice_ticks = (unsigned long long)cpu_stats[CP_NICE]; cpu->sys2_ticks = (unsigned long long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR]; cpu->kern_ticks = (unsigned long long)cpu_stats[CP_SYS]; cpu->idle_ticks = (unsigned long long)cpu_stats[CP_IDLE]; cpu->intrpt_ticks = (unsigned long long)cpu_stats[CP_INTR]; /* wait_ticks, sirq_ticks unused */ /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ sysctl(mem_mib, 2, &mem_stats, &mem_size, NULL, 0); cpu->nInterrupts = (unsigned long long)mem_stats.NS_VM_INTR; cpu->nCtxSwitches = (unsigned long long)mem_stats.NS_VM_SWTCH; cpu->swapIn = (unsigned long long)mem_stats.NS_VM_SWAPIN; cpu->swapOut = (unsigned long long)mem_stats.NS_VM_SWAPOUT; #ifdef NS_VM_PAGEIN cpu->pageIn = (unsigned long long)mem_stats.NS_VM_PAGEIN; #endif #ifdef NS_VM_PAGEOUT cpu->pageOut = (unsigned long long)mem_stats.NS_VM_PAGEOUT; #endif #ifdef NETSNMP_KERN_MCPU mcpu_size = cpu_num*sizeof(NETSNMP_KERN_MCPU_TYPE); mcpu_stats = malloc(mcpu_size); sysctl(mcpu_mib, 2, mcpu_stats, &mcpu_size, NULL, 0); for ( i = 0; i < cpu_num; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 0 ); /* XXX - per-CPU statistics - mcpu_mib[i].??? */ } free(mcpu_stats); #else /* Copy "overall" figures to cpu0 entry */ _cpu_copy_stats( cpu ); #endif return 0; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { static char *buff = NULL; static int bsize = 0; static int first = 1; static int num_cpuline_elem = 0; int bytes_read, statfd, i; char *b1, *b2; unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, ciowll = 0, cirqll = 0, csoftll = 0, cstealll = 0, cguestll = 0, cguest_nicell = 0; netsnmp_cpu_info* cpu; if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(STAT_FILE); return -1; } if (bsize == 0) { bsize = getpagesize()-1; buff = (char*)malloc(bsize+1); if (buff == NULL) { return -1; } } while ((bytes_read = read(statfd, buff, bsize)) == bsize) { bsize += BUFSIZ; buff = (char*)realloc(buff, bsize+1); DEBUGMSGTL(("cpu", "/proc/stat buffer increased to %d\n", bsize)); close(statfd); statfd = open(STAT_FILE, O_RDONLY, 0); if (statfd == -1) { snmp_log_perror(STAT_FILE); return -1; } } close(statfd); if ( bytes_read < 0 ) { snmp_log_perror(STAT_FILE "read error"); return -1; } buff[bytes_read] = '\0'; /* * CPU statistics (overall and per-CPU) */ b1 = buff; while ((b2 = strstr( b1, "cpu" ))) { if (b2[3] == ' ') { cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (!cpu) { snmp_log_perror("No (overall) CPU info entry"); return -1; } b1 = b2+4; /* Skip "cpu " */ } else { sscanf( b2, "cpu%d", &i ); /* Create on the fly to support non-x86 systems - see init */ cpu = netsnmp_cpu_get_byIdx( i, 1 ); if (!cpu) { snmp_log_perror("Missing CPU info entry"); break; } b1 = b2; /* Skip "cpuN " */ while(*b1 != ' ') b1++; b1++; } num_cpuline_elem = sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll, &cstealll, &cguestll, &cguest_nicell); DEBUGMSGTL(("cpu", "/proc/stat cpu line number of elements: %i\n", num_cpuline_elem)); /* kernel 2.6.33 and above */ if (num_cpuline_elem == 10) { cpu->guestnice_ticks = cguest_nicell; } /* kernel 2.6.24 and above */ if (num_cpuline_elem >= 9) { cpu->guest_ticks = cguestll; } /* kernel 2.6.11 and above */ if (num_cpuline_elem >= 8) { cpu->steal_ticks = cstealll; } /* kernel 2.6 */ if (num_cpuline_elem >= 5) { cpu->wait_ticks = ciowll; cpu->intrpt_ticks = cirqll; cpu->sirq_ticks = csoftll; } /* rest */ cpu->user_ticks = cusell; cpu->nice_ticks = cicell; cpu->sys_ticks = csysll; cpu->idle_ticks = cidell; } if ( b1 == buff ) { if (first) snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE); } /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu = netsnmp_cpu_get_byIdx( -1, 0 ); _cpu_load_swap_etc( buff, cpu ); /* * XXX - TODO: extract per-CPU statistics * (Into separate netsnmp_cpu_info data structures) */ first = 0; return 0; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { int i,n; perfstat_id_t name; perfstat_cpu_total_t cs; perfstat_cpu_t *cs2; perfstat_memory_total_t ms; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (perfstat_cpu_total((perfstat_id_t *)NULL, &cs, sizeof(perfstat_cpu_total_t), 1) > 0) { /* Returns 'u_longlong_t' statistics */ cpu->user_ticks = (unsigned long long)cs.user / cs.ncpus; cpu->sys_ticks = ((unsigned long long)cs.sys + (unsigned long long)cs.wait) / cs.ncpus; cpu->kern_ticks = (unsigned long long)cs.sys / cs.ncpus; cpu->wait_ticks = (unsigned long long)cs.wait / cs.ncpus; cpu->idle_ticks = (unsigned long long)cs.idle / cs.ncpus; /* intrpt_ticks, sirq_ticks, nice_ticks unused */ /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu->pageIn = (unsigned long long)cs.sysread; cpu->pageOut = (unsigned long long)cs.syswrite; cpu->nInterrupts = (unsigned long long)cs.devintrs + cs.softintrs; cpu->nCtxSwitches = (unsigned long long)cs.pswitch; } if (perfstat_memory_total((perfstat_id_t *)NULL, &ms, sizeof(perfstat_memory_total_t), 1) > 0) { cpu->swapIn = (unsigned long long)ms.pgspins; cpu->swapOut = (unsigned long long)ms.pgspouts; } /* * Per-CPU statistics */ n = cs.ncpus; /* XXX - Compare against cpu_num */ cs2 = (perfstat_cpu_t*)malloc( n*sizeof(perfstat_cpu_t)); strcpy( name.name, ""); if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), n) > 0) { for ( i = 0; i < n; i++ ) { cpu = netsnmp_cpu_get_byIdx( i, 1 ); cpu->user_ticks = (unsigned long long)cs2[i].user; cpu->sys_ticks = (unsigned long long)cs2[i].sys + (unsigned long long)cs2[i].wait; cpu->kern_ticks = (unsigned long long)cs2[i].sys; cpu->wait_ticks = (unsigned long long)cs2[i].wait; cpu->idle_ticks = (unsigned long long)cs2[i].idle; cpu->pageIn = (unsigned long long)cs2[i].sysread; cpu->pageOut = (unsigned long long)cs2[i].syswrite; cpu->nCtxSwitches = (unsigned long long)cs2[i].pswitch; /* Interrupt stats only apply overall, not per-CPU */ } } else { _cpu_copy_stats( cpu ); } free(cs2); return 0; }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { int i=1; kstat_t *ksp; cpu_stat_t cs; netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 0 ); netsnmp_cpu_info *cpu2; /* Clear overall stats, ready for summing individual CPUs */ cpu->user_ticks = 0; cpu->idle_ticks = 0; cpu->kern_ticks = 0; cpu->wait_ticks = 0; cpu->sys2_ticks = 0; cpu->swapIn = 0; cpu->swapOut = 0; cpu->nInterrupts = 0; cpu->nCtxSwitches = 0; kstat_chain_update( kstat_fd ); DEBUGMSGTL(("cpu", "cpu_kstat load\n ")); for (ksp = kstat_fd->kc_chain; ksp != NULL; ksp = ksp->ks_next) { if (ksp->ks_flags & KSTAT_FLAG_INVALID) continue; if (strcmp(ksp->ks_module, "cpu_stat") == 0) { i = ksp->ks_instance; cpu2 = netsnmp_cpu_get_byIdx( i, 0 ); if ( !cpu2 ) break; /* or continue ? */ /* Skip new CPUs */ if ((ksp->ks_type != KSTAT_TYPE_RAW) || (ksp->ks_data_size != sizeof(cs))|| (kstat_read(kstat_fd, ksp, &cs) == -1)) { DEBUGMSGTL(("cpu", "cpu_kstat load failed (%d)\n ", i)); break; /* or continue ? */ } cpu2->user_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_USER]; cpu2->idle_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_IDLE]; cpu2->kern_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_KERNEL]; cpu2->wait_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_WAIT]; /* or cs.cpu_sysinfo.wait[W_IO]+cs.cpu_sysinfo.wait[W_PIO] */ cpu2->sys2_ticks = (unsigned long long)cpu2->kern_ticks+cpu2->wait_ticks; /* nice_ticks, intrpt_ticks, sirq_ticks unused */ /* sum these for the overall stats */ cpu->user_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_USER]; cpu->idle_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_IDLE]; cpu->kern_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_KERNEL]; cpu->wait_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_WAIT]; /* or cs.cpu_sysinfo.wait[W_IO]+cs.cpu_sysinfo.wait[W_PIO] */ cpu->sys2_ticks += (unsigned long long)cpu2->kern_ticks+cpu2->wait_ticks; /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu->swapIn += (unsigned long long)cs.cpu_vminfo.swapin; cpu->swapOut += (unsigned long long)cs.cpu_vminfo.swapout; cpu->pageIn += (unsigned long long)cs.cpu_sysinfo.bread; cpu->pageOut += (unsigned long long)cs.cpu_sysinfo.bwrite; cpu->nInterrupts += (unsigned long long)cs.cpu_sysinfo.intr; cpu->nCtxSwitches += (unsigned long long)cs.cpu_sysinfo.pswitch; } } return 0; }
int vmstat_handler (netsnmp_mib_handler * handler, netsnmp_handler_registration * reginfo, netsnmp_agent_request_info * reqinfo, netsnmp_request_info * requests) { oid obj; unsigned long long value = 0; char cp[300]; netsnmp_cpu_info *info = netsnmp_cpu_get_byIdx (-1, 0); switch (reqinfo->mode) { case MODE_GET: obj = requests->requestvb->name[requests->requestvb->name_length - 2]; switch (obj) { case MIBINDEX: /* dummy value */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, 1); break; case ERRORNAME: /* dummy name */ sprintf (cp, "systemStats"); snmp_set_var_typed_value (requests->requestvb, ASN_OCTET_STR, cp, strlen (cp)); break; /* case IOSENT: long_ret = vmstat(iosent); return ((u_char *) (&long_ret)); case IORECEIVE: long_ret = vmstat(ioreceive); return ((u_char *) (&long_ret)); case IORAWSENT: long_ret = vmstat(rawiosent); return ((u_char *) (&long_ret)); case IORAWRECEIVE: long_ret = vmstat(rawioreceive); return ((u_char *) (&long_ret)); */ /* * Raw CPU statistics * Taken directly from the (overall) cpu_info structure. * * XXX - Need some form of flag to skip objects that * aren't supported on a given architecture. */ case CPURAWUSER: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->user_ticks & 0xffffffff); break; case CPURAWNICE: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->nice_ticks & 0xffffffff); break; case CPURAWSYSTEM: /* * Some architecture have traditionally reported a * combination of CPU statistics for this object. * The CPU HAL module uses 'sys2_ticks' for this, * so use this value in preference to 'sys_ticks' * if it has a non-zero value. */ snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, (info->sys2_ticks ? info->sys2_ticks : info->sys_ticks) & 0xffffffff); break; case CPURAWIDLE: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->idle_ticks & 0xffffffff); break; case CPURAWWAIT: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->wait_ticks & 0xffffffff); break; case CPURAWKERNEL: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->kern_ticks & 0xffffffff); break; case CPURAWINTR: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->intrpt_ticks & 0xffffffff); break; case CPURAWSOFTIRQ: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->sirq_ticks & 0xffffffff); break; case CPURAWSTEAL: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->steal_ticks & 0xffffffff); break; case CPURAWGUEST: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->guest_ticks & 0xffffffff); break; case CPURAWGUESTNICE: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->guestnice_ticks & 0xffffffff); break; /* * 'Cooked' CPU statistics * Percentage usage of the specified statistic calculated * over the period (1 min) that history is being kept for. * * This is actually a change of behaviour for some architectures, * but: * a) It ensures consistency across all systems * a) It matches the definition of the MIB objects * * Note that this value will only be reported once the agent * has a full minute's history collected. */ case CPUUSER: if (info->history && info->history[0].total_hist) { value = (info->user_ticks - info->history[0].user_hist) * 100; if (info->total_ticks - info->history[0].total_hist) value /= (info->total_ticks - info->history[0].total_hist); else value = 0; /* or skip this entry */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; case CPUSYSTEM: if (info->history && info->history[0].total_hist) { /* or sys2_ticks ??? */ value = (info->sys_ticks - info->history[0].sys_hist) * 100; if (info->total_ticks - info->history[0].total_hist) value /= (info->total_ticks - info->history[0].total_hist); else value = 0; /* or skip this entry */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; case CPUIDLE: if (info->history && info->history[0].total_hist) { value = (info->idle_ticks - info->history[0].idle_hist) * 100; if (info->total_ticks - info->history[0].total_hist) value /= (info->total_ticks - info->history[0].total_hist); else value = 0; /* or skip this entry */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; /* * Similarly for the Interrupt and Context switch statistics * (raw and per-second, calculated over the last minute) */ case SYSRAWINTERRUPTS: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->nInterrupts & 0xffffffff); break; case SYSRAWCONTEXT: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->nCtxSwitches & 0xffffffff); break; case SYSINTERRUPTS: if (info->history && info->history[0].total_hist) { value = (info->nInterrupts - info->history[0].intr_hist) / 60; snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; case SYSCONTEXT: if (info->history && info->history[0].total_hist) { value = (info->nCtxSwitches - info->history[0].ctx_hist) / 60; snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; /* * Similarly for the Swap statistics... */ case RAWSWAPIN: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->swapIn & 0xffffffff); break; case RAWSWAPOUT: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->swapOut & 0xffffffff); break; case SWAPIN: if (info->history && info->history[0].total_hist) { value = (info->swapIn - info->history[0].swpi_hist) / 60; /* ??? value *= PAGE_SIZE; */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; case SWAPOUT: if (info->history && info->history[0].total_hist) { value = (info->swapOut - info->history[0].swpo_hist) / 60; /* ??? value *= PAGE_SIZE; */ snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; /* * ... and the I/O statistics. */ case IORAWSENT: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->pageOut & 0xffffffff); break; case IORAWRECEIVE: snmp_set_var_typed_integer (requests->requestvb, ASN_COUNTER, info->pageIn & 0xffffffff); break; case IOSENT: if (info->history && info->history[0].total_hist) { value = (info->pageOut - info->history[0].pageo_hist) / 60; snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; case IORECEIVE: if (info->history && info->history[0].total_hist) { value = (info->pageIn - info->history[0].pagei_hist) / 60; snmp_set_var_typed_integer (requests->requestvb, ASN_INTEGER, value & 0x7fffffff); } break; default: /* XXX - The systemStats group is "holely", so walking it would trigger this message repeatedly. We really need a form of the table column registration mechanism, that would work with scalar groups. snmp_log(LOG_ERR, "unknown object (%d) in vmstat_handler\n", (int)obj); */ break; } break; default: snmp_log (LOG_ERR, "unknown mode (%d) in vmstat_handler\n", reqinfo->mode); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; }
int proc_status(int idx) { netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( idx & HRDEV_TYPE_MASK, 0 ); return (cpu ? cpu->status : 0 ); }
/* * Load the latest CPU usage statistics */ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) { static char *buff = NULL; static int bsize = 0; static int first = 1; static int has_cpu_26 = 1; int statfd, i; char *b1, *b2; unsigned long long cusell = 0, cicell = 0, csysll = 0, cidell = 0, ciowll = 0, cirqll = 0, csoftll = 0; netsnmp_cpu_info* cpu; if ((statfd = open(STAT_FILE, O_RDONLY, 0)) == -1) { snmp_log_perror(STAT_FILE); return -1; } if (bsize == 0) { bsize = 256; buff = malloc(bsize); } while (read(statfd, buff, bsize) == bsize) { bsize += 256; buff = realloc(buff, bsize); DEBUGMSGTL(("cpu", "/proc/stat buffer increased to %d\n", bsize)); close(statfd); statfd = open(STAT_FILE, O_RDONLY, 0); } close(statfd); /* * CPU statistics (overall and per-CPU) */ b1 = buff; while ((b2 = strstr( b1, "cpu" ))) { if (b2[3] == ' ') { cpu = netsnmp_cpu_get_byIdx( -1, 0 ); if (!cpu) { snmp_log_perror("No (overall) CPU info entry"); return -1; } b1 = b2+4; /* Skip "cpu " */ } else { sscanf( b2, "cpu%d", &i ); /* Create on the fly to support non-x86 systems - see init */ cpu = netsnmp_cpu_get_byIdx( i, 1 ); if (!cpu) { snmp_log_perror("Missing CPU info entry"); break; } b1 = b2+5; /* Skip "cpuN " */ } if (!has_cpu_26 || sscanf(b1, "%llu %llu %llu %llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell, &ciowll, &cirqll, &csoftll) != 7) { has_cpu_26 = 0; sscanf(b1, "%llu %llu %llu %llu", &cusell, &cicell, &csysll, &cidell); } else { cpu->wait_ticks = (unsigned long)ciowll; cpu->intrpt_ticks = (unsigned long)cirqll; cpu->sirq_ticks = (unsigned long)csoftll; } cpu->user_ticks = (unsigned long)cusell; cpu->nice_ticks = (unsigned long)cicell; cpu->sys_ticks = (unsigned long)csysll; cpu->idle_ticks = (unsigned long)cidell; } if ( b1 == buff ) { if (first) snmp_log(LOG_ERR, "No cpu line in %s\n", STAT_FILE); } /* * Interrupt/Context Switch statistics * XXX - Do these really belong here ? */ cpu = netsnmp_cpu_get_byIdx( -1, 0 ); _cpu_load_swap_etc( buff, cpu ); /* * XXX - TODO: extract per-CPU statistics * (Into separate netsnmp_cpu_info data structures) */ first = 0; return 0; }