void get_iface_stats_kstat (char verbose) { kstat_ctl_t *kc; kstat_t *ksp; kstat_io_t kio; kstat_named_t *i_bytes=NULL,*o_bytes=NULL,*i_packets=NULL,*o_packets=NULL,*i_errors=NULL,*o_errors=NULL; char *name; int hidden_if=0,current_if_num=0,my_errno=0; t_iface_speed_stats tmp_if_stats; t_iface_speed_stats stats; /* local struct, used to calc total values */ memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */ kc = kstat_open(); if (kc==NULL) deinit(1, "kstat failed: %s\n",strerror(my_errno)); name=(char *)malloc(KSTAT_STRLEN); if (!name) { kstat_close(kc); deinit(1,"mem alloc failed: %s\n",strerror(errno)); } /* loop for interfaces */ for (ksp = kc->kc_chain;ksp != NULL;ksp = ksp->ks_next) { if ((strcmp(ksp->ks_class, "net") != 0 && input_method==KSTAT_IN) || (strcmp(ksp->ks_class, "disk") != 0 && input_method==KSTATDISK_IN && ksp->ks_type != KSTAT_TYPE_IO)) continue; /* skip all other stats */ strncpy(name,ksp->ks_name,KSTAT_STRLEN); name[KSTAT_STRLEN-1]='\0'; if (KSTAT_IN==input_method) { kstat_read(kc, ksp, NULL); i_bytes=(kstat_named_t *)kstat_data_lookup(ksp, "rbytes"); o_bytes=(kstat_named_t *)kstat_data_lookup(ksp, "obytes"); i_packets=(kstat_named_t *)kstat_data_lookup(ksp, "ipackets"); o_packets=(kstat_named_t *)kstat_data_lookup(ksp, "opackets"); i_errors=(kstat_named_t *)kstat_data_lookup(ksp, "ierrors"); o_errors=(kstat_named_t *)kstat_data_lookup(ksp, "oerrors"); if (!i_bytes || !o_bytes || !i_packets || !o_packets || !i_errors || !o_errors) continue; /* use ui32 values, the 64 bit values return strange (very big) differences */ tmp_if_stats.bytes.in=i_bytes->value.ui32; tmp_if_stats.bytes.out=o_bytes->value.ui32; tmp_if_stats.packets.in=i_packets->value.ui32; tmp_if_stats.packets.out=o_packets->value.ui32; tmp_if_stats.errors.in=i_errors->value.ui32; tmp_if_stats.errors.out=o_errors->value.ui32; } else if (KSTATDISK_IN==input_method) { kstat_read(kc, ksp, &kio); tmp_if_stats.bytes.in=kio.nread; tmp_if_stats.bytes.out=kio.nwritten; tmp_if_stats.packets.in=kio.reads; tmp_if_stats.packets.out=kio.writes; tmp_if_stats.errors.in=tmp_if_stats.errors.out=0; } else { free(name); kstat_close(kc); deinit(1,"im confused about kstat input methods!\n"); } /* init new interfaces and add fetched data to old or new one */ hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, (tmp_if_stats.bytes.in != 0 || tmp_if_stats.bytes.out != 0)); current_if_num++; } /* add to total stats and output current stats if verbose */ finish_iface_stats (verbose, stats, hidden_if,current_if_num); /* clean buffers */ free(name); kstat_close(kc); return; }
nvlist_t * drive_get_stats(descriptor_t *dp, int stat_type, int *errp) { disk_t *diskp; nvlist_t *stats; diskp = dp->p.disk; if (nvlist_alloc(&stats, NVATTRS, 0) != 0) { *errp = ENOMEM; return (NULL); } if (stat_type == DM_DRV_STAT_PERFORMANCE || stat_type == DM_DRV_STAT_DIAGNOSTIC) { alias_t *ap; kstat_ctl_t *kc; ap = diskp->aliases; if (ap == NULL || ap->kstat_name == NULL) { nvlist_free(stats); *errp = EACCES; return (NULL); } if ((kc = kstat_open()) == NULL) { nvlist_free(stats); *errp = EACCES; return (NULL); } while (ap != NULL) { int status; if (ap->kstat_name == NULL) { continue; } if (stat_type == DM_DRV_STAT_PERFORMANCE) { status = get_io_kstats(kc, ap->kstat_name, stats); } else { status = get_err_kstats(kc, ap->kstat_name, stats); } if (status != 0) { nvlist_free(stats); (void) kstat_close(kc); *errp = ENOMEM; return (NULL); } ap = ap->next; } (void) kstat_close(kc); *errp = 0; return (stats); } if (stat_type == DM_DRV_STAT_TEMPERATURE) { int fd; if ((fd = drive_open_disk(diskp, NULL, 0)) >= 0) { struct dk_temperature temp; if (ioctl(fd, DKIOCGTEMPERATURE, &temp) >= 0) { if (nvlist_add_uint32(stats, DM_TEMPERATURE, temp.dkt_cur_temp) != 0) { *errp = ENOMEM; nvlist_free(stats); return (NULL); } } else { *errp = errno; nvlist_free(stats); return (NULL); } (void) close(fd); } else { *errp = errno; nvlist_free(stats); return (NULL); } *errp = 0; return (stats); } nvlist_free(stats); *errp = EINVAL; return (NULL); }
/* * Return a list of tuples for network I/O statistics. */ static PyObject * psutil_net_io_counters(PyObject *self, PyObject *args) { kstat_ctl_t *kc = NULL; kstat_t *ksp; kstat_named_t *rbytes, *wbytes, *rpkts, *wpkts, *ierrs, *oerrs; PyObject *py_retdict = PyDict_New(); PyObject *py_ifc_info = NULL; if (py_retdict == NULL) return NULL; kc = kstat_open(); if (kc == NULL) goto error; ksp = kc->kc_chain; while (ksp != NULL) { if (ksp->ks_type != KSTAT_TYPE_NAMED) goto next; if (strcmp(ksp->ks_class, "net") != 0) goto next; /* // XXX "lo" (localhost) interface makes kstat_data_lookup() fail // (maybe because "ifconfig -a" says it's a virtual interface?). if ((strcmp(ksp->ks_module, "link") != 0) && (strcmp(ksp->ks_module, "lo") != 0)) { goto skip; */ if ((strcmp(ksp->ks_module, "link") != 0)) { goto next; } if (kstat_read(kc, ksp, NULL) == -1) { errno = 0; continue; } rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes"); wbytes = (kstat_named_t *)kstat_data_lookup(ksp, "obytes"); rpkts = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets"); wpkts = (kstat_named_t *)kstat_data_lookup(ksp, "opackets"); ierrs = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors"); oerrs = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors"); if ((rbytes == NULL) || (wbytes == NULL) || (rpkts == NULL) || (wpkts == NULL) || (ierrs == NULL) || (oerrs == NULL)) { PyErr_SetString(PyExc_RuntimeError, "kstat_data_lookup() failed"); goto error; } #if defined(_INT64_TYPE) py_ifc_info = Py_BuildValue("(KKKKkkii)", rbytes->value.ui64, wbytes->value.ui64, rpkts->value.ui64, wpkts->value.ui64, ierrs->value.ui32, oerrs->value.ui32, #else py_ifc_info = Py_BuildValue("(kkkkkkii)", rbytes->value.ui32, wbytes->value.ui32, rpkts->value.ui32, wpkts->value.ui32, ierrs->value.ui32, oerrs->value.ui32, #endif 0, // dropin not supported 0 // dropout not supported ); if (!py_ifc_info) goto error; if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info)) goto error; Py_DECREF(py_ifc_info); goto next; next: ksp = ksp->ks_next; } kstat_close(kc); return py_retdict; error: Py_XDECREF(py_ifc_info); Py_DECREF(py_retdict); if (kc != NULL) kstat_close(kc); return NULL; }
int updateNetDev( void ) { #ifdef HAVE_KSTAT kstat_ctl_t *kctl; kstat_t *ksp; kstat_named_t *kdata; int i; /* * get a kstat handle and update the user's kstat chain */ if( (kctl = kstat_open()) == NULL ) return( 0 ); while( kstat_chain_update( kctl ) != 0 ) ; for( i = 0; i < NetDevCount; i++ ) { char *name; char *ptr; /* * chop off the trailing interface no */ name = strdup( IfInfo[i].Name ); ptr = name + strlen( name ) - 1; while( (ptr > name) && isdigit( (int) *ptr ) ) { *ptr = '\0'; ptr--; } /* * traverse the kstat chain * to find the appropriate statistics */ if( (ksp = kstat_lookup( kctl, name, 0, IfInfo[i].Name )) == NULL ) { free( name ); return( 0 ); } if( kstat_read( kctl, ksp, NULL ) == -1 ) { free( name ); return( 0 ); } free( name ); /* * lookup & store the data */ kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ipackets" ); if( kdata != NULL ) { IfInfo[i].OLDipackets = IfInfo[i].ipackets; IfInfo[i].ipackets = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "opackets" ); if( kdata != NULL ) { IfInfo[i].OLDopackets = IfInfo[i].opackets; IfInfo[i].opackets = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "ierrors" ); if( kdata != NULL ) { IfInfo[i].OLDierrors = IfInfo[i].ierrors; IfInfo[i].ierrors = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "oerrors" ); if( kdata != NULL ) { IfInfo[i].OLDoerrors = IfInfo[i].oerrors; IfInfo[i].oerrors = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "collisions" ); if( kdata != NULL ) { IfInfo[i].OLDcollisions = IfInfo[i].collisions; IfInfo[i].collisions = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multixmt" ); if( kdata != NULL ) { IfInfo[i].OLDmultixmt = IfInfo[i].multixmt; IfInfo[i].multixmt = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "multircv" ); if( kdata != NULL ) { IfInfo[i].OLDmultircv = IfInfo[i].multircv; IfInfo[i].multircv = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstxmt" ); if( kdata != NULL ) { IfInfo[i].OLDbrdcstxmt = IfInfo[i].brdcstxmt; IfInfo[i].brdcstxmt = kdata->value.ul; } kdata = (kstat_named_t *) kstat_data_lookup( ksp, "brdcstrcv" ); if( kdata != NULL ) { IfInfo[i].OLDbrdcstrcv = IfInfo[i].brdcstrcv; IfInfo[i].brdcstrcv = kdata->value.ul; } } kstat_close( kctl ); #endif /* ! HAVE_KSTAT */ return( 0 ); }
static int get_swap_io(zbx_uint64_t *swapin, zbx_uint64_t *pgswapin, zbx_uint64_t *swapout, zbx_uint64_t *pgswapout, char **error) { kstat_ctl_t *kc; kstat_t *k; cpu_stat_t *cpu; int cpu_count = 0; if (NULL == (kc = kstat_open())) { *error = zbx_dsprintf(NULL, "Cannot open kernel statistics facility: %s", zbx_strerror(errno)); return SYSINFO_RET_FAIL; } for (k = kc->kc_chain; NULL != k; k = k->ks_next) { if (0 == strncmp(k->ks_name, "cpu_stat", 8)) { if (-1 == kstat_read(kc, k, NULL)) { *error = zbx_dsprintf(NULL, "Cannot read from kernel statistics facility: %s", zbx_strerror(errno)); goto clean; } cpu = (cpu_stat_t *)k->ks_data; if (NULL != swapin) { /* uint_t swapin; */ /* swapins */ *swapin += cpu->cpu_vminfo.swapin; } if (NULL != pgswapin) { /* uint_t pgswapin; */ /* pages swapped in */ *pgswapin += cpu->cpu_vminfo.pgswapin; } if (NULL != swapout) { /* uint_t swapout; */ /* swapout */ *swapout += cpu->cpu_vminfo.swapout; } if (NULL != pgswapout) { /* uint_t pgswapout; */ /* pages swapped out */ *pgswapout += cpu->cpu_vminfo.pgswapout; } cpu_count++; } } if (0 == cpu_count) { kstat_close(kc); *error = zbx_strdup(NULL, "Cannot find swap information."); return SYSINFO_RET_FAIL; } clean: kstat_close(kc); return SYSINFO_RET_OK; }
sg_page_stats *sg_get_page_stats(){ #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; cpu_stat_t cs; #endif #if defined(LINUX) || defined(CYGWIN) FILE *f; char *line_ptr; #endif #if defined(FREEBSD) || defined(DFBSD) size_t size; #endif #if defined(NETBSD) || defined(OPENBSD) struct uvmexp *uvm; #endif #ifdef AIX perfstat_memory_total_t mem; #endif #ifdef HPUX struct pst_vminfo vminfo; #endif page_stats.systime = time(NULL); page_stats.pages_pagein=0; page_stats.pages_pageout=0; #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { sg_set_error(SG_ERROR_KSTAT_OPEN, NULL); return NULL; } for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) { if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue; if (kstat_read(kc, ksp, &cs) == -1) { continue; } page_stats.pages_pagein+=(long long)cs.cpu_vminfo.pgpgin; page_stats.pages_pageout+=(long long)cs.cpu_vminfo.pgpgout; } kstat_close(kc); #endif #if defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/vmstat", "r")) != NULL) { while ((line_ptr = sg_f_read_line(f, "")) != NULL) { long long value; if (sscanf(line_ptr, "%*s %lld", &value) != 1) { continue; } if (strncmp(line_ptr, "pgpgin ", 7) == 0) { page_stats.pages_pagein = value; } else if (strncmp(line_ptr, "pgpgout ", 8) == 0) { page_stats.pages_pageout = value; } } fclose(f); } else if ((f = fopen("/proc/stat", "r")) != NULL) { if ((line_ptr = sg_f_read_line(f, "page")) == NULL) { sg_set_error(SG_ERROR_PARSE, "page"); fclose(f); return NULL; } if (sscanf(line_ptr, "page %lld %lld", &page_stats.pages_pagein, &page_stats.pages_pageout) != 2) { sg_set_error(SG_ERROR_PARSE, "page"); fclose(f); return NULL; } fclose(f); } else { sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/stat"); return NULL; } #endif #if defined(FREEBSD) || defined(DFBSD) size = sizeof page_stats.pages_pagein; if (sysctlbyname("vm.stats.vm.v_swappgsin", &page_stats.pages_pagein, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsin"); return NULL; } size = sizeof page_stats.pages_pageout; if (sysctlbyname("vm.stats.vm.v_swappgsout", &page_stats.pages_pageout, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsout"); return NULL; } #endif #if defined(NETBSD) || defined(OPENBSD) if ((uvm = sg_get_uvmexp()) == NULL) { return NULL; } page_stats.pages_pagein = uvm->pgswapin; page_stats.pages_pageout = uvm->pgswapout; #endif #ifdef AIX /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); return NULL; } page_stats.pages_pagein = mem.pgins; page_stats.pages_pageout = mem.pgouts; #endif #ifdef HPUX if( pstat_getvminfo( &vminfo, sizeof(vminfo), 1, 0 ) == -1 ) { sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "pstat_getswap"); return NULL; }; page_stats.pages_pagein = vminfo.psv_spgin; page_stats.pages_pageout = vminfo.psv_spgout; #endif #ifdef WIN32 sg_set_error(SG_ERROR_UNSUPPORTED, "Win32"); return NULL; #endif return &page_stats; }
sg_mem_stats *sg_get_mem_stats(){ static sg_mem_stats mem_stat; #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; long totalmem; int pagesize; #endif #if defined(LINUX) || defined(CYGWIN) char *line_ptr; unsigned long long value; FILE *f; #endif #if defined(FREEBSD) || defined(DFBSD) int mib[2]; u_long physmem; size_t size; u_int free_count; u_int cache_count; u_int inactive_count; int pagesize; #endif #if defined(NETBSD) || defined(OPENBSD) struct uvmexp *uvm; #endif #ifdef SOLARIS if((pagesize=sysconf(_SC_PAGESIZE)) == -1){ sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PAGESIZE"); return NULL; } if((totalmem=sysconf(_SC_PHYS_PAGES)) == -1){ sg_set_error_with_errno(SG_ERROR_SYSCONF, "_SC_PHYS_PAGES"); return NULL; } if ((kc = kstat_open()) == NULL) { sg_set_error(SG_ERROR_KSTAT_OPEN, NULL); return NULL; } if((ksp=kstat_lookup(kc, "unix", 0, "system_pages")) == NULL){ sg_set_error(SG_ERROR_KSTAT_LOOKUP, "unix,0,system_pages"); return NULL; } if (kstat_read(kc, ksp, 0) == -1) { sg_set_error(SG_ERROR_KSTAT_READ, NULL); return NULL; } if((kn=kstat_data_lookup(ksp, "freemem")) == NULL){ sg_set_error(SG_ERROR_KSTAT_DATA_LOOKUP, "freemem"); return NULL; } kstat_close(kc); mem_stat.total = (long long)totalmem * (long long)pagesize; mem_stat.free = ((long long)kn->value.ul) * (long long)pagesize; mem_stat.used = mem_stat.total - mem_stat.free; #endif #if defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/meminfo", "r")) == NULL) { sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/meminfo"); return NULL; } while ((line_ptr = sg_f_read_line(f, "")) != NULL) { if (sscanf(line_ptr, "%*s %llu kB", &value) != 1) { continue; } value *= 1024; if (strncmp(line_ptr, "MemTotal:", 9) == 0) { mem_stat.total = value; } else if (strncmp(line_ptr, "MemFree:", 8) == 0) { mem_stat.free = value; } else if (strncmp(line_ptr, "Cached:", 7) == 0) { mem_stat.cache = value; } } fclose(f); mem_stat.used = mem_stat.total - mem_stat.free; #endif #if defined(FREEBSD) || defined(DFBSD) /* Returns bytes */ mib[0] = CTL_HW; mib[1] = HW_PHYSMEM; size = sizeof physmem; if (sysctl(mib, 2, &physmem, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_PHYSMEM"); return NULL; } mem_stat.total = physmem; /*returns pages*/ size = sizeof free_count; if (sysctlbyname("vm.stats.vm.v_free_count", &free_count, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_free_count"); return NULL; } size = sizeof inactive_count; if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count , &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_inactive_count"); return NULL; } size = sizeof cache_count; if (sysctlbyname("vm.stats.vm.v_cache_count", &cache_count, &size, NULL, 0) < 0){ sg_set_error_with_errno(SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_cache_count"); return NULL; } /* Because all the vm.stats returns pages, I need to get the page size. * After that I then need to multiple the anything that used vm.stats to * get the system statistics by pagesize */ pagesize = getpagesize(); mem_stat.cache=cache_count*pagesize; /* Of couse nothing is ever that simple :) And I have inactive pages to * deal with too. So I'm going to add them to free memory :) */ mem_stat.free=(free_count*pagesize)+(inactive_count*pagesize); mem_stat.used=physmem-mem_stat.free; #endif #if defined(NETBSD) || defined(OPENBSD) if ((uvm = sg_get_uvmexp()) == NULL) { return NULL; } mem_stat.total = uvm->pagesize * uvm->npages; #ifdef NETBSD mem_stat.cache = uvm->pagesize * (uvm->filepages + uvm->execpages); #else /* Can't find cache memory on OpenBSD */ mem_stat.cache = 0; #endif mem_stat.free = uvm->pagesize * (uvm->free + uvm->inactive); mem_stat.used = mem_stat.total - mem_stat.free; #endif return &mem_stat; }
void CPU_Load_Monitor::access_kstats (unsigned long *which_idle) { this->kstats_ = kstat_open (); if (this->kstats_ == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("opening kstats file failed\n"))); return; } this->kstat_id_ = this->kstats_->kc_chain_id; while (true) { this->kernel_ = 0UL; this->wait_ = 0UL; this->user_ = 0UL; (*which_idle) = 0UL; /// Unlike Linux's "/proc/stat", there is no entry for total CPU /// stats, so we have to sum them manually. for (this->kstat_ = this->kstats_->kc_chain; this->kstat_ != 0; this->kstat_ = this->kstat_->ks_next) { int result = ACE_OS::strncmp (this->kstat_->ks_name, "cpu_stat", ACE_OS::strlen ("cpu_stat")); if (result == 0) { /// Because the kstat chain can change dynamically, /// watch the chain ID and restart the walk if the ID /// differs from what we saw during the walk. The restart /// is done by breaking from the cycle with kstat_ not 0. kid_t kstat_id = kstat_read (this->kstats_, this->kstat_, 0); if (kstat_id != this->kstat_id_) { break; } cpu_stat_t &kstat_cpu = *((cpu_stat_t *) this->kstat_->ks_data); this->kernel_ += kstat_cpu.cpu_sysinfo.cpu[CPU_KERNEL]; this->wait_ += kstat_cpu.cpu_sysinfo.cpu[CPU_WAIT]; this->user_ += kstat_cpu.cpu_sysinfo.cpu[CPU_USER]; (*which_idle) += kstat_cpu.cpu_sysinfo.cpu[CPU_IDLE]; } } if (this->kstat_ != 0) { /// The ID changed underneath us, so get the new one and /// start again. this->kstat_id_ = kstat_chain_update (this->kstats_); if (! this->kstat_id_ > 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("kstat chain update ") ACE_TEXT ("returned null id\n"))); return; } } else { /// Clean run, exit the WHILE loop. break; } } int status = kstat_close (this->kstats_); if (status != 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("closing kstats file failed\n"))); } }
/* * Returns uptime in centiseconds(!). */ long get_uptime(void) { #if !defined(solaris2) && !defined(linux) && !defined(cygwin) && !defined(aix4) && !defined(aix5) && !defined(aix6) && !defined(aix7) struct timeval now; long boottime_csecs, nowtime_csecs; boottime_csecs = get_boottime(); if (boottime_csecs == 0) return 0; gettimeofday(&now, (struct timezone *) 0); nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000); return (nowtime_csecs - boottime_csecs); #endif #if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) struct nlist nl; int kmem; time_t lbolt; nl.n_name = "lbolt"; if(knlist(&nl, 1, sizeof(struct nlist)) != 0) return(0); if(nl.n_type == 0 || nl.n_value == 0) return(0); if((kmem = open("/dev/mem", 0)) < 0) return 0; lseek(kmem, (long) nl.n_value, L_SET); read(kmem, &lbolt, sizeof(lbolt)); close(kmem); return(lbolt); #endif #ifdef solaris2 kstat_ctl_t *ksc = kstat_open(); kstat_t *ks; kid_t kid; kstat_named_t *named; u_long lbolt = 0; if (ksc) { ks = kstat_lookup(ksc, "unix", -1, "system_misc"); if (ks) { kid = kstat_read(ksc, ks, NULL); if (kid != -1) { named = kstat_data_lookup(ks, "lbolt"); if (named) { #ifdef KSTAT_DATA_UINT32 lbolt = named->value.ui32; #else lbolt = named->value.ul; #endif } } } kstat_close(ksc); } return lbolt; #endif /* solaris2 */ #ifdef linux FILE *in = fopen("/proc/uptime", "r"); long uptim = 0, a, b; if (in) { if (2 == fscanf(in, "%ld.%ld", &a, &b)) uptim = a * 100 + b; fclose(in); } return uptim; #endif /* linux */ #ifdef cygwin return (0); /* not implemented */ #endif }
/* * Main Program */ int main(int argc, char *argv[]) { /* * Variable Declaration */ kstat_ctl_t *kc; /* Kstat controller */ double rbps; /* read bytes per sec */ double wbps; /* write bytes per sec */ double rkps; /* read Kb per sec */ double wkps; /* write Kb per sec */ double rpps; /* read packets per sec */ double wpps; /* write packets per sec */ double ravs; /* read average packet size */ double wavs; /* write average packet size */ double sats; /* saturation value per sec */ double tdiff; /* time difference between samples */ double util; /* utilisation */ struct tm *times; /* time struct */ char timestr[16]; /* time string */ time_t boot_time; /* boot time */ int num; /* NIC counter */ int interval; /* interval, secs */ int loop_max; /* max output lines */ int loop; /* current loop number */ int line; /* output line counter */ int option; /* command line switch */ hrtime_t period_n; /* period of each iteration in nanoseconds */ hrtime_t start_n; /* start point of an iteration, nsec */ hrtime_t end_n; /* end time of work in an iteration, nsec */ hrtime_t pause_n; /* time until start of next iteration, nsec */ struct timespec pause_tv; /* time until start of next iteration */ /* defaults */ interval = INTERVAL; loop_max = LOOP_MAX; line = PAGESIZE; loop = 0; g_style = 0; g_skipzero = 0; g_someints = 0; g_forever = 0; for (num = 0; num <= g_interfacemax; num++) { g_idold[num].rbytes = 0; g_idold[num].wbytes = 0; g_idold[num].rpackets = 0; g_idold[num].wpackets = 0; g_idold[num].sat = 0; } /* * Process arguments */ while ((option = getopt(argc, argv, "hi:sz")) != -1) { switch (option) { case 'h': usage(); break; case 'i': g_someints = 1; (void) bufsplit(",", 0, (char **)0); (void) bufsplit(optarg, NIC_COUNT_MAX, g_tracked); break; case 's': g_style = 1; break; case 'z': g_skipzero = 1; break; default: usage(); } } argv += optind; if ((argc - optind) >= 1) { interval = atoi(*argv); if (interval == 0) usage(); argv++; if ((argc - optind) >= 2) loop_max = atoi(*argv); else g_forever = 1; } /* Open Kstat */ if ((kc = kstat_open()) == NULL) die("ERROR3: Can't open /dev/kstat.\n", 3); /* Fetch boot time */ boot_time = fetch_boot_time(kc); for (num = 0; num <= g_interfacemax; num++) g_idold[num].time = boot_time; /* Calculate the period of each iteration */ period_n = (hrtime_t) interval * NANOSEC; /* Get time when we started */ start_n = gethrtime(); /* * Main Loop */ for (;;) { /* Print header line */ if (line >= PAGESIZE) { line = 0; print_header(); } /* * Fetch Data */ populate_g_idnew(kc); /* Check we matched some NICs */ if (g_interfacemax == -1) die("ERROR4: No such interface found.", 4); /* * Calculate and Print Data */ for (num = 0; num <= g_interfacemax; num++) { /* Calculate time difference */ tdiff = g_idnew[num].time - g_idold[num].time; if (tdiff == 0) tdiff = 1; /* Calculate per second values */ rbps = (g_idnew[num].rbytes - g_idold[num].rbytes) / tdiff; wbps = (g_idnew[num].wbytes - g_idold[num].wbytes) / tdiff; rpps = (g_idnew[num].rpackets - g_idold[num].rpackets) / tdiff; wpps = (g_idnew[num].wpackets - g_idold[num].wpackets) / tdiff; sats = (g_idnew[num].sat - g_idold[num].sat) / tdiff; rkps = rbps / 1024; wkps = wbps / 1024; if (rpps > 0) ravs = rbps / rpps; else ravs = 0; if (wpps > 0) wavs = wbps / wpps; else wavs = 0; /* Calculate utilisation */ if (g_idnew[num].speed > 0) { /* * the following has a mysterious "800", it is * 100 for the % conversion, and 8 for * bytes2bits. */ util = (rbps + wbps) * 800 / g_idnew[num].speed; if (util > 100) util = 100; } else util = 0; /* always print header if there are multiple NICs */ if (g_interfacemax > 0) line += PAGESIZE; else line++; /* Skip zero lines */ if (g_skipzero && (util == 0)) continue; /* Fetch time */ times = localtime(&g_idnew[num].time); (void) strftime(timestr, sizeof (timestr), "%H:%M:%S", times); /* Print output line */ (void) printf("%s %11s %36s ", timestr, g_idnew[num].name, g_idnew[num].zone); if (g_style) (void) printf("%14.3f %14.3f\n", rkps, wkps); else (void) printf( "%7.2f %7.2f %7.2f %7.2f " "%7.2f %7.2f %7.2f %7.2f\n", rkps, wkps, rpps, wpps, ravs, wavs, util, sats); g_idold[num] = g_idnew[num]; } /* end point */ if (!g_forever) if (++loop == loop_max) break; /* flush output */ if (fflush(stdout) != 0) die("ERROR5: fflush(stdout) failed\n", 5); /* have a kip */ end_n = gethrtime(); pause_n = start_n + period_n - end_n; if (pause_n > 0) { pause_tv.tv_sec = pause_n / NANOSEC; pause_tv.tv_nsec = pause_n % NANOSEC; (void) nanosleep(&pause_tv, (struct timespec *) NULL); } start_n += period_n; } /* * Close Kstat */ (void) kstat_close(kc); return (0); }
int readDiskCounters(HSP *sp, SFLHost_dsk_counters *dsk) { int gotData = NO; kstat_ctl_t *kc; kstat_t *ksp; kstat_io_t kio; FILE *mounts; struct mnttab mp; char *mount, *device, *type; struct statvfs buf; u_long blocksize; fsblkcnt_t free, size; uint64_t total_size, total_free; uint64_t bytes_size, bytes_free; uint32_t pc, tmppc; uint32_t reads, writes; uint64_t bytes_read, bytes_written; kc = kstat_open(); if (NULL == kc) { myLog(LOG_ERR, "readDiskCounters kstat_open() failed"); } mounts = fopen("/etc/mnttab", "r"); if (mounts) { total_size = 0; total_free = 0; pc = 0; //void *treeRoot = NULL; while (0 == getmntent(mounts, &mp)) { mount = mp.mnt_mountp; device = mp.mnt_special; type = mp.mnt_fstype; // See Ganglia libmetrics/metrics.c::valid_mount_type() if (!strncmp(type, "ufs", 3) && !strncmp(type, "vxfs", 4)) continue; // don't count it again if it was seen before //if (NULL != tfind(device, &treeRoot, (my_comparison_fn_t)strcmp)) // continue; //else // // not found, so remember it // tsearch(my_strdup(device), &treeRoot, (my_comparison_fn_t)strcmp); gotData = YES; statvfs(mount, &buf); size = buf.f_blocks; free = buf.f_bavail; blocksize = buf.f_frsize; bytes_size = (uint64_t)size * (uint64_t)blocksize; bytes_free = (uint64_t)free * (uint64_t)blocksize; total_size += bytes_size; total_free += bytes_free; if (size > 0) { tmppc = (uint32_t)((((uint64_t)size - (uint64_t)free) * 10000) / ((double)size)); if (tmppc > pc) pc = tmppc; } } //tdestroy(treeRoot, my_free); // disk_total dsk->disk_total += total_size; // disk_free dsk->disk_free += total_free; // part_max_used dsk->part_max_used = pc; reads = 0; writes = 0; bytes_read = 0; bytes_written = 0; if (NULL != kc) { for (ksp = kc->kc_chain; NULL != ksp; ksp = ksp->ks_next) { if (KSTAT_TYPE_IO == ksp->ks_type && !(strncmp(ksp->ks_class, "disk", 4))) { gotData = YES; kstat_read(kc, ksp, &kio); reads += kio.reads; writes += kio.writes; bytes_read += kio.nread; bytes_written += kio.nwritten; } } // reads dsk->reads = reads; // read_time // TODO: rtime of kstat disk class is "run time", not "read time". Determine where // to get read time from. SFL_UNDEF_COUNTER(dsk->read_time); // writes dsk->writes = writes; // write_time // TODO: wtime of kstat disk class is "wait time", not "write time". Determine where // to get write time from. SFL_UNDEF_COUNTER(dsk->write_time); } // accumulate the 64-bit counters uint64_t total_sectors_read = (uint64_t) bytes_read / ((float)ASSUMED_DISK_SECTOR_BYTES); uint64_t total_sectors_written = (uint64_t)(bytes_written / ((float)ASSUMED_DISK_SECTOR_BYTES)); sp->diskIO.bytes_read += bytes_read; sp->diskIO.last_sectors_read = (total_sectors_read - sp->diskIO.last_sectors_read); sp->diskIO.bytes_written += bytes_written; sp->diskIO.last_sectors_written = (total_sectors_written - sp->diskIO.last_sectors_written); // bytes_read dsk->bytes_read = sp->diskIO.bytes_read; // bytes_written dsk->bytes_written = sp->diskIO.bytes_written; fclose(mounts); } kstat_close(kc); return gotData; }
static int hwloc_look_kstat(struct hwloc_topology *topology) { /* FIXME this assumes that all sockets are identical */ char *CPUType = hwloc_solaris_get_chip_type(); char *CPUModel = hwloc_solaris_get_chip_model(); kstat_ctl_t *kc = kstat_open(); kstat_t *ksp; kstat_named_t *stat; unsigned look_cores = 1, look_chips = 1; unsigned Pproc_max = 0; unsigned Pproc_alloc = 256; struct hwloc_solaris_Pproc { unsigned Lsock, Psock, Lcore, Lproc; } * Pproc = malloc(Pproc_alloc * sizeof(*Pproc)); unsigned Lproc_num = 0; unsigned Lproc_alloc = 256; struct hwloc_solaris_Lproc { unsigned Pproc; } * Lproc = malloc(Lproc_alloc * sizeof(*Lproc)); unsigned Lcore_num = 0; unsigned Lcore_alloc = 256; struct hwloc_solaris_Lcore { unsigned Pcore, Psock; } * Lcore = malloc(Lcore_alloc * sizeof(*Lcore)); unsigned Lsock_num = 0; unsigned Lsock_alloc = 256; struct hwloc_solaris_Lsock { unsigned Psock; } * Lsock = malloc(Lsock_alloc * sizeof(*Lsock)); unsigned sockid, coreid, cpuid; unsigned i; for (i = 0; i < Pproc_alloc; i++) { Pproc[i].Lproc = -1; Pproc[i].Lsock = -1; Pproc[i].Psock = -1; Pproc[i].Lcore = -1; } if (!kc) { hwloc_debug("kstat_open failed: %s\n", strerror(errno)); free(Pproc); free(Lproc); free(Lcore); free(Lsock); return 0; } for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { if (strncmp("cpu_info", ksp->ks_module, 8)) continue; cpuid = ksp->ks_instance; if (kstat_read(kc, ksp, NULL) == -1) { fprintf(stderr, "kstat_read failed for CPU%u: %s\n", cpuid, strerror(errno)); continue; } hwloc_debug("cpu%u\n", cpuid); if (cpuid >= Pproc_alloc) { Pproc_alloc *= 2; Pproc = realloc(Pproc, Pproc_alloc * sizeof(*Pproc)); for(i = Pproc_alloc/2; i < Pproc_alloc; i++) { Pproc[i].Lproc = -1; Pproc[i].Lsock = -1; Pproc[i].Psock = -1; Pproc[i].Lcore = -1; } } Pproc[cpuid].Lproc = Lproc_num; if (Lproc_num >= Lproc_alloc) { Lproc_alloc *= 2; Lproc = realloc(Lproc, Lproc_alloc * sizeof(*Lproc)); } Lproc[Lproc_num].Pproc = cpuid; Lproc_num++; if (cpuid >= Pproc_max) Pproc_max = cpuid + 1; stat = (kstat_named_t *) kstat_data_lookup(ksp, "state"); if (!stat) hwloc_debug("could not read state for CPU%u: %s\n", cpuid, strerror(errno)); else if (stat->data_type != KSTAT_DATA_CHAR) hwloc_debug("unknown kstat type %d for cpu state\n", stat->data_type); else { hwloc_debug("cpu%u's state is %s\n", cpuid, stat->value.c); if (strcmp(stat->value.c, "on-line")) /* not online */ hwloc_bitmap_clr(topology->levels[0][0]->online_cpuset, cpuid); } if (look_chips) do { /* Get Chip ID */ stat = (kstat_named_t *) kstat_data_lookup(ksp, "chip_id"); if (!stat) { if (Lsock_num) fprintf(stderr, "could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); else hwloc_debug("could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); look_chips = 0; continue; } switch (stat->data_type) { case KSTAT_DATA_INT32: sockid = stat->value.i32; break; case KSTAT_DATA_UINT32: sockid = stat->value.ui32; break; #ifdef _INT64_TYPE case KSTAT_DATA_UINT64: sockid = stat->value.ui64; break; case KSTAT_DATA_INT64: sockid = stat->value.i64; break; #endif default: fprintf(stderr, "chip_id type %d unknown\n", stat->data_type); look_chips = 0; continue; } Pproc[cpuid].Psock = sockid; for (i = 0; i < Lsock_num; i++) if (sockid == Lsock[i].Psock) break; Pproc[cpuid].Lsock = i; hwloc_debug("%u on socket %u (%u)\n", cpuid, i, sockid); if (i == Lsock_num) { if (Lsock_num == Lsock_alloc) { Lsock_alloc *= 2; Lsock = realloc(Lsock, Lsock_alloc * sizeof(*Lsock)); } Lsock[Lsock_num++].Psock = sockid; } } while(0); if (look_cores) do { /* Get Core ID */ stat = (kstat_named_t *) kstat_data_lookup(ksp, "core_id"); if (!stat) { if (Lcore_num) fprintf(stderr, "could not read core id for CPU%u: %s\n", cpuid, strerror(errno)); else hwloc_debug("could not read core id for CPU%u: %s\n", cpuid, strerror(errno)); look_cores = 0; continue; } switch (stat->data_type) { case KSTAT_DATA_INT32: coreid = stat->value.i32; break; case KSTAT_DATA_UINT32: coreid = stat->value.ui32; break; #ifdef _INT64_TYPE case KSTAT_DATA_UINT64: coreid = stat->value.ui64; break; case KSTAT_DATA_INT64: coreid = stat->value.i64; break; #endif default: fprintf(stderr, "core_id type %d unknown\n", stat->data_type); look_cores = 0; continue; } for (i = 0; i < Lcore_num; i++) if (coreid == Lcore[i].Pcore && Pproc[cpuid].Psock == Lcore[i].Psock) break; Pproc[cpuid].Lcore = i; hwloc_debug("%u on core %u (%u)\n", cpuid, i, coreid); if (i == Lcore_num) { if (Lcore_num == Lcore_alloc) { Lcore_alloc *= 2; Lcore = realloc(Lcore, Lcore_alloc * sizeof(*Lcore)); } Lcore[Lcore_num].Psock = Pproc[cpuid].Psock; Lcore[Lcore_num++].Pcore = coreid; } } while(0); /* Note: there is also clog_id for the Thread ID (not unique) and * pkg_core_id for the core ID (not unique). They are not useful to us * however. */ } if (look_chips) { struct hwloc_obj *obj; unsigned j,k; hwloc_debug("%d Sockets\n", Lsock_num); for (j = 0; j < Lsock_num; j++) { obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, Lsock[j].Psock); if (CPUType) hwloc_obj_add_info(obj, "CPUType", CPUType); if (CPUModel) hwloc_obj_add_info(obj, "CPUModel", CPUModel); obj->cpuset = hwloc_bitmap_alloc(); for(k=0; k<Pproc_max; k++) if (Pproc[k].Lsock == j) hwloc_bitmap_set(obj->cpuset, k); hwloc_debug_1arg_bitmap("Socket %d has cpuset %s\n", j, obj->cpuset); hwloc_insert_object_by_cpuset(topology, obj); } hwloc_debug("%s", "\n"); } if (look_cores) { struct hwloc_obj *obj; unsigned j,k; hwloc_debug("%d Cores\n", Lcore_num); for (j = 0; j < Lcore_num; j++) { obj = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, Lcore[j].Pcore); obj->cpuset = hwloc_bitmap_alloc(); for(k=0; k<Pproc_max; k++) if (Pproc[k].Lcore == j) hwloc_bitmap_set(obj->cpuset, k); hwloc_debug_1arg_bitmap("Core %d has cpuset %s\n", j, obj->cpuset); hwloc_insert_object_by_cpuset(topology, obj); } hwloc_debug("%s", "\n"); } if (Lproc_num) { struct hwloc_obj *obj; unsigned j,k; hwloc_debug("%d PUs\n", Lproc_num); for (j = 0; j < Lproc_num; j++) { obj = hwloc_alloc_setup_object(HWLOC_OBJ_PU, Lproc[j].Pproc); obj->cpuset = hwloc_bitmap_alloc(); for(k=0; k<Pproc_max; k++) if (Pproc[k].Lproc == j) hwloc_bitmap_set(obj->cpuset, k); hwloc_debug_1arg_bitmap("PU %d has cpuset %s\n", j, obj->cpuset); hwloc_insert_object_by_cpuset(topology, obj); } hwloc_debug("%s", "\n"); } kstat_close(kc); free(Pproc); free(Lproc); free(Lcore); free(Lsock); return Lproc_num > 0; }
/* record the startup time, for returning uptime */ static void set_startup_time(int sysuptime) { startup_time = time(NULL); if(sysuptime) { /* use system uptime instead of daemon uptime */ #if defined(__linux__) char buff[64]; int uptime = 0, fd; fd = open("/proc/uptime", O_RDONLY); if(fd < 0) { syslog(LOG_ERR, "open(\"/proc/uptime\" : %m"); } else { memset(buff, 0, sizeof(buff)); if(read(fd, buff, sizeof(buff) - 1) < 0) { syslog(LOG_ERR, "read(\"/proc/uptime\" : %m"); } else { uptime = atoi(buff); syslog(LOG_INFO, "system uptime is %d seconds", uptime); } close(fd); startup_time -= uptime; } #elif defined(SOLARIS_KSTATS) kstat_ctl_t *kc; kc = kstat_open(); if(kc != NULL) { kstat_t *ksp; ksp = kstat_lookup(kc, "unix", 0, "system_misc"); if(ksp && (kstat_read(kc, ksp, NULL) != -1)) { void *ptr = kstat_data_lookup(ksp, "boot_time"); if(ptr) memcpy(&startup_time, ptr, sizeof(startup_time)); else syslog(LOG_ERR, "cannot find boot_time kstat"); } else syslog(LOG_ERR, "cannot open kstats for unix/0/system_misc: %m"); kstat_close(kc); } #else struct timeval boottime; size_t size = sizeof(boottime); int name[2] = { CTL_KERN, KERN_BOOTTIME }; if(sysctl(name, 2, &boottime, &size, NULL, 0) < 0) { syslog(LOG_ERR, "sysctl(\"kern.boottime\") failed"); } else { startup_time = boottime.tv_sec; } #endif } }
/* * Return stats about a particular network * interface. References: * https://github.com/dpaleino/wicd/blob/master/wicd/backends/be-ioctl.py * http://www.i-scream.org/libstatgrab/ */ static PyObject* psutil_net_if_stats(PyObject* self, PyObject* args) { kstat_ctl_t *kc = NULL; kstat_t *ksp; kstat_named_t *knp; int ret; int sock = -1; int duplex; int speed; PyObject *py_retdict = PyDict_New(); PyObject *py_ifc_info = NULL; PyObject *py_is_up = NULL; if (py_retdict == NULL) return NULL; kc = kstat_open(); if (kc == NULL) goto error; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { if (strcmp(ksp->ks_class, "net") == 0) { struct lifreq ifr; kstat_read(kc, ksp, NULL); if (ksp->ks_type != KSTAT_TYPE_NAMED) continue; if (strcmp(ksp->ks_class, "net") != 0) continue; strncpy(ifr.lifr_name, ksp->ks_name, sizeof(ifr.lifr_name)); ret = ioctl(sock, SIOCGLIFFLAGS, &ifr); if (ret == -1) continue; // not a network interface // is up? if ((ifr.lifr_flags & IFF_UP) != 0) { if ((knp = kstat_data_lookup(ksp, "link_up")) != NULL) { if (knp->value.ui32 != 0u) py_is_up = Py_True; else py_is_up = Py_False; } else { py_is_up = Py_True; } } else { py_is_up = Py_False; } Py_INCREF(py_is_up); // duplex duplex = 0; // unknown if ((knp = kstat_data_lookup(ksp, "link_duplex")) != NULL) { if (knp->value.ui32 == 1) duplex = 1; // half else if (knp->value.ui32 == 2) duplex = 2; // full } // speed if ((knp = kstat_data_lookup(ksp, "ifspeed")) != NULL) // expressed in bits per sec, we want mega bits per sec speed = (int)knp->value.ui64 / 1000000; else speed = 0; // mtu ret = ioctl(sock, SIOCGLIFMTU, &ifr); if (ret == -1) goto error; py_ifc_info = Py_BuildValue("(Oiii)", py_is_up, duplex, speed, ifr.lifr_mtu); if (!py_ifc_info) goto error; if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info)) goto error; Py_DECREF(py_ifc_info); } } close(sock); kstat_close(kc); return py_retdict; error: Py_XDECREF(py_is_up); Py_XDECREF(py_ifc_info); Py_DECREF(py_retdict); if (sock != -1) close(sock); if (kc != NULL) kstat_close(kc); PyErr_SetFromErrno(PyExc_OSError); return NULL; }
static sg_error sg_get_page_stats_int(sg_page_stats *page_stats_buf){ #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; cpu_stat_t cs; #elif defined(LINUX) || defined(CYGWIN) FILE *f; #define LINE_BUF_SIZE 256 char line_buf[LINE_BUF_SIZE]; #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) # if defined(HAVE_HOST_STATISTICS64) struct vm_statistics64 vm_stats; # else struct vm_statistics vm_stats; # endif mach_msg_type_number_t count; kern_return_t rc; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) int mib[2]; struct uvmexp_sysctl uvm; size_t size = sizeof(uvm); #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(FREEBSD) || defined(DFBSD) size_t size; #elif defined(NETBSD) || defined(OPENBSD) int mib[2]; struct uvmexp uvm; size_t size = sizeof(uvm); #elif defined(AIX) perfstat_memory_total_t mem; #elif defined(HPUX) struct pst_vminfo vminfo; #endif page_stats_buf->systime = time(NULL); page_stats_buf->pages_pagein=0; page_stats_buf->pages_pageout=0; #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { RETURN_WITH_SET_ERROR("page", SG_ERROR_KSTAT_OPEN, NULL); } for (ksp = kc->kc_chain; ksp!=NULL; ksp = ksp->ks_next) { if ((strcmp(ksp->ks_module, "cpu_stat")) != 0) continue; if (kstat_read(kc, ksp, &cs) == -1) continue; page_stats_buf->pages_pagein += (long long)cs.cpu_vminfo.pgpgin; page_stats_buf->pages_pageout += (long long)cs.cpu_vminfo.pgpgout; } kstat_close(kc); #elif defined(LINUX) || defined(CYGWIN) if ((f = fopen("/proc/vmstat", "r")) != NULL) { unsigned matches = 0; while( (matches < 2) && (fgets(line_buf, sizeof(line_buf), f) != NULL) ) { unsigned long long value; if (sscanf(line_buf, "%*s %llu", &value) != 1) continue; if (strncmp(line_buf, "pgpgin ", 7) == 0) { page_stats_buf->pages_pagein = value; ++matches; } else if (strncmp(line_buf, "pgpgout ", 8) == 0) { page_stats_buf->pages_pageout = value; ++matches; } } fclose(f); if( matches < 2 ) { RETURN_WITH_SET_ERROR( "page", SG_ERROR_PARSE, "/proc/vmstat" ); } } else if ((f = fopen("/proc/stat", "r")) != NULL) { if (sg_f_read_line(f, line_buf, sizeof(line_buf), "page") == NULL) { fclose(f); RETURN_FROM_PREVIOUS_ERROR( "page", sg_get_error() ); } fclose(f); if( sscanf( line_buf, "page %llu %llu", &page_stats_buf->pages_pagein, &page_stats_buf->pages_pageout ) != 2 ) { RETURN_WITH_SET_ERROR("page", SG_ERROR_PARSE, "page"); } } else { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_OPEN, "/proc/stat"); } #elif defined(HAVE_HOST_STATISTICS) || defined(HAVE_HOST_STATISTICS64) self_host_port = mach_host_self(); # if defined(HAVE_HOST_STATISTICS64) count = HOST_VM_INFO64_COUNT; rc = host_statistics64(self_host_port, HOST_VM_INFO64, (host_info64_t)(&vm_stats), &count); # else count = HOST_VM_INFO_COUNT; rc = host_statistics(self_host_port, HOST_VM_INFO, (host_info_t)(&vm_stats), &count); # endif if( rc != KERN_SUCCESS ) { RETURN_WITH_SET_ERROR_WITH_ERRNO_CODE( "mem", SG_ERROR_MACHCALL, rc, "host_statistics" ); } page_stats_buf->pages_pagein = vm_stats.pageins; page_stats_buf->pages_pageout = vm_stats.pageouts; #elif defined(HAVE_STRUCT_UVMEXP_SYSCTL) && defined(VM_UVMEXP2) mib[0] = CTL_VM; mib[1] = VM_UVMEXP2; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP2"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(HAVE_STRUCT_UVMEXP) && defined(VM_UVMEXP) mib[0] = CTL_VM; mib[1] = VM_UVMEXP; if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("mem", SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP"); } page_stats_buf->pages_pagein = uvm.pgswapin; page_stats_buf->pages_pageout = uvm.pgswapout; #elif defined(FREEBSD) || defined(DFBSD) size = sizeof(page_stats_buf->pages_pagein); if (sysctlbyname("vm.stats.vm.v_swappgsin", &page_stats_buf->pages_pagein, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsin"); } size = sizeof(page_stats_buf->pages_pageout); if (sysctlbyname("vm.stats.vm.v_swappgsout", &page_stats_buf->pages_pageout, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "vm.stats.vm.v_swappgsout"); } #elif defined(AIX) /* return code is number of structures returned */ if(perfstat_memory_total(NULL, &mem, sizeof(perfstat_memory_total_t), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "perfstat_memory_total"); } page_stats_buf->pages_pagein = mem.pgins; page_stats_buf->pages_pageout = mem.pgouts; #elif defined(HPUX) if( pstat_getvminfo( &vminfo, sizeof(vminfo), 1, 0 ) == -1 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("page", SG_ERROR_SYSCTLBYNAME, "pstat_getswap"); } page_stats_buf->pages_pagein = vminfo.psv_spgin; page_stats_buf->pages_pageout = vminfo.psv_spgout; #else RETURN_WITH_SET_ERROR("page", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif return SG_ERROR_NONE; }
/* * Return a list of tuples for network I/O statistics. */ static PyObject * psutil_net_io_counters(PyObject *self, PyObject *args) { kstat_ctl_t *kc = NULL; kstat_t *ksp; kstat_named_t *rbytes, *wbytes, *rpkts, *wpkts, *ierrs, *oerrs; int ret; int sock = -1; struct lifreq ifr; PyObject *py_retdict = PyDict_New(); PyObject *py_ifc_info = NULL; if (py_retdict == NULL) return NULL; kc = kstat_open(); if (kc == NULL) goto error; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } ksp = kc->kc_chain; while (ksp != NULL) { if (ksp->ks_type != KSTAT_TYPE_NAMED) goto next; if (strcmp(ksp->ks_class, "net") != 0) goto next; // skip 'lo' (localhost) because it doesn't have the statistics we need // and it makes kstat_data_lookup() fail if (strcmp(ksp->ks_module, "lo") == 0) goto next; // check if this is a network interface by sending a ioctl strncpy(ifr.lifr_name, ksp->ks_name, sizeof(ifr.lifr_name)); ret = ioctl(sock, SIOCGLIFFLAGS, &ifr); if (ret == -1) goto next; if (kstat_read(kc, ksp, NULL) == -1) { errno = 0; goto next; } rbytes = (kstat_named_t *)kstat_data_lookup(ksp, "rbytes"); wbytes = (kstat_named_t *)kstat_data_lookup(ksp, "obytes"); rpkts = (kstat_named_t *)kstat_data_lookup(ksp, "ipackets"); wpkts = (kstat_named_t *)kstat_data_lookup(ksp, "opackets"); ierrs = (kstat_named_t *)kstat_data_lookup(ksp, "ierrors"); oerrs = (kstat_named_t *)kstat_data_lookup(ksp, "oerrors"); if ((rbytes == NULL) || (wbytes == NULL) || (rpkts == NULL) || (wpkts == NULL) || (ierrs == NULL) || (oerrs == NULL)) { PyErr_SetString(PyExc_RuntimeError, "kstat_data_lookup() failed"); goto error; } if (rbytes->data_type == KSTAT_DATA_UINT64) { py_ifc_info = Py_BuildValue("(KKKKIIii)", wbytes->value.ui64, rbytes->value.ui64, wpkts->value.ui64, rpkts->value.ui64, ierrs->value.ui32, oerrs->value.ui32, 0, // dropin not supported 0 // dropout not supported ); } else { py_ifc_info = Py_BuildValue("(IIIIIIii)", wbytes->value.ui32, rbytes->value.ui32, wpkts->value.ui32, rpkts->value.ui32, ierrs->value.ui32, oerrs->value.ui32, 0, // dropin not supported 0 // dropout not supported ); } if (!py_ifc_info) goto error; if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info)) goto error; Py_DECREF(py_ifc_info); goto next; next: ksp = ksp->ks_next; } kstat_close(kc); close(sock); return py_retdict; error: Py_XDECREF(py_ifc_info); Py_DECREF(py_retdict); if (kc != NULL) kstat_close(kc); if (sock != -1) { close(sock); } return NULL; }
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { int lookup_instance; kstat_ctl_t* kc; kstat_t* ksp; kstat_named_t* knp; uv_cpu_info_t* cpu_info; if ((kc = kstat_open()) == NULL) { return uv__new_sys_error(errno); } /* Get count of cpus */ lookup_instance = 0; while ((ksp = kstat_lookup(kc, (char*)"cpu_info", lookup_instance, NULL))) { lookup_instance++; } *cpu_infos = (uv_cpu_info_t*)malloc(lookup_instance * sizeof(uv_cpu_info_t)); if (!(*cpu_infos)) { return uv__new_artificial_error(UV_ENOMEM); } *count = lookup_instance; cpu_info = *cpu_infos; lookup_instance = 0; while ((ksp = kstat_lookup(kc, (char*)"cpu_info", lookup_instance, NULL))) { if (kstat_read(kc, ksp, NULL) == -1) { cpu_info->speed = 0; cpu_info->model = NULL; } else { knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"clock_MHz"); assert(knp->data_type == KSTAT_DATA_INT32 || knp->data_type == KSTAT_DATA_INT64); cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32 : knp->value.i64; knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"brand"); assert(knp->data_type == KSTAT_DATA_STRING); cpu_info->model = strdup(KSTAT_NAMED_STR_PTR(knp)); } lookup_instance++; cpu_info++; } cpu_info = *cpu_infos; lookup_instance = 0; while ( (ksp = kstat_lookup(kc, (char*)"cpu", lookup_instance, (char*)"sys"))) { if (kstat_read(kc, ksp, NULL) == -1) { cpu_info->cpu_times.user = 0; cpu_info->cpu_times.nice = 0; cpu_info->cpu_times.sys = 0; cpu_info->cpu_times.idle = 0; cpu_info->cpu_times.irq = 0; } else { knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"cpu_ticks_user"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.user = knp->value.ui64; knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"cpu_ticks_kernel"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.sys = knp->value.ui64; knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"cpu_ticks_idle"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.idle = knp->value.ui64; knp = (kstat_named_t*)kstat_data_lookup(ksp, (char*)"intr"); assert(knp->data_type == KSTAT_DATA_UINT64); cpu_info->cpu_times.irq = knp->value.ui64; cpu_info->cpu_times.nice = 0; } lookup_instance++; cpu_info++; } kstat_close(kc); return uv_ok_; }
PGM_GNUC_INTERNAL bool pgm_time_init ( pgm_error_t** error ) { char *pgm_timer; size_t envlen; errno_t err; if (pgm_atomic_exchange_and_add32 (&time_ref_count, 1) > 0) return TRUE; /* user preferred time stamp function */ err = pgm_dupenv_s (&pgm_timer, &envlen, "PGM_TIMER"); if (0 != err || 0 == envlen) { pgm_timer = pgm_strdup ( /* default time stamp function */ #if defined(_WIN32) "MMTIME" #else "GETTIMEOFDAY" #endif ); } pgm_time_since_epoch = pgm_time_conv; switch (pgm_timer[0]) { #ifdef HAVE_FTIME case 'F': pgm_minor (_("Using ftime() timer.")); pgm_time_update_now = pgm_ftime_update; break; #endif #ifdef HAVE_CLOCK_GETTIME case 'C': pgm_minor (_("Using clock_gettime() timer.")); pgm_time_update_now = pgm_clock_update; break; #endif #ifdef HAVE_DEV_RTC case 'R': pgm_minor (_("Using /dev/rtc timer.")); pgm_time_update_now = pgm_rtc_update; pgm_time_since_epoch = pgm_time_conv_from_reset; break; #endif #ifdef HAVE_RDTSC case 'T': pgm_minor (_("Using TSC timer.")); pgm_time_update_now = pgm_tsc_update; pgm_time_since_epoch = pgm_time_conv_from_reset; break; #endif #ifdef HAVE_DEV_HPET case 'H': pgm_minor (_("Using HPET timer.")); pgm_time_update_now = pgm_hpet_update; pgm_time_since_epoch = pgm_time_conv_from_reset; break; #endif #ifdef HAVE_GETTIMEOFDAY case 'G': pgm_minor (_("Using gettimeofday() timer.")); pgm_time_update_now = pgm_gettimeofday_update; break; #endif #ifdef _WIN32 case 'M': pgm_minor (_("Using multi-media timer.")); pgm_time_update_now = pgm_mmtime_update; pgm_time_since_epoch = pgm_time_conv_from_reset; break; case 'Q': pgm_minor (_("Using QueryPerformanceCounter() timer.")); pgm_time_update_now = pgm_queryperformancecounter_update; pgm_time_since_epoch = pgm_time_conv_from_reset; break; #endif default: pgm_set_error (error, PGM_ERROR_DOMAIN_TIME, PGM_ERROR_FAILED, _("Unsupported time stamp function: PGM_TIMER=%s"), pgm_timer); pgm_free (pgm_timer); goto err_cleanup; } /* clean environment copy */ pgm_free (pgm_timer); #ifdef HAVE_DEV_RTC if (pgm_time_update_now == pgm_rtc_update) { pgm_error_t* sub_error = NULL; if (!pgm_rtc_init (&sub_error)) { pgm_propagate_error (error, sub_error); goto err_cleanup; } } #endif #ifdef _WIN32 if (pgm_time_update_now == pgm_queryperformancecounter_update) { /* MSDN statement: The frequency cannot change while the system is running. * http://msdn.microsoft.com/en-us/library/ms644905(v=vs.85).aspx */ LARGE_INTEGER frequency; if (QueryPerformanceFrequency (&frequency)) { tsc_khz = (uint_fast32_t)(frequency.QuadPart / 1000LL); pgm_minor (_("High-resolution performance counter frequency %lld Hz"), frequency.QuadPart); } else { const DWORD save_errno = GetLastError(); char winstr[1024]; pgm_set_error (error, PGM_ERROR_DOMAIN_TIME, PGM_ERROR_FAILED, _("No supported high-resolution performance counter: %s"), pgm_win_strerror (winstr, sizeof (winstr), save_errno)); goto err_cleanup; } set_tsc_mul (tsc_khz); } #endif /* _WIN32 */ #ifdef HAVE_RDTSC if (pgm_time_update_now == pgm_tsc_update) { char *rdtsc_frequency; #ifdef HAVE_PROC_CPUINFO /* attempt to parse clock ticks from kernel */ FILE *fp = fopen ("/proc/cpuinfo", "r"); if (fp) { char buffer[1024]; while (!feof(fp) && fgets (buffer, sizeof(buffer), fp)) { if (strstr (buffer, "cpu MHz")) { const char *p = strchr (buffer, ':'); if (p) tsc_khz = atoi (p + 1) * 1000; break; } } fclose (fp); } #elif defined(_WIN32) /* core frequency HKLM/Hardware/Description/System/CentralProcessor/0/~Mhz */ HKEY hKey; if (ERROR_SUCCESS == RegOpenKeyExA (HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey)) { DWORD dwData = 0; DWORD dwDataSize = sizeof (dwData); if (ERROR_SUCCESS == RegQueryValueExA (hKey, "~MHz", NULL, NULL, (LPBYTE)&dwData, &dwDataSize)) { tsc_khz = dwData * 1000; pgm_minor (_("Registry reports central processor frequency %u MHz"), (unsigned)dwData); /* dump processor name for comparison aid of obtained frequency */ char szProcessorBrandString[48]; dwDataSize = sizeof (szProcessorBrandString); if (ERROR_SUCCESS == RegQueryValueExA (hKey, "ProcessorNameString", NULL, NULL, (LPBYTE)szProcessorBrandString, &dwDataSize)) { pgm_minor (_("Processor Brand String \"%s\""), szProcessorBrandString); } } else { const DWORD save_errno = GetLastError(); char winstr[1024]; pgm_warn (_("Registry query on HKLM\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\~MHz failed: %s"), pgm_win_strerror (winstr, sizeof (winstr), save_errno)); } RegCloseKey (hKey); } #elif defined(__APPLE__) /* nb: RDTSC is non-functional on Darwin */ uint64_t cpufrequency; size_t len; len = sizeof (cpufrequency); if (0 == sysctlbyname ("hw.cpufrequency", &cpufrequency, &len, NULL, 0)) { tsc_khz = (uint_fast32_t)(cpufrequency / 1000); } #elif defined(__FreeBSD__) /* frequency in Mhz */ unsigned long clockrate; size_t len; len = sizeof (clockrate); if (0 == sysctlbyname ("hw.clockrate", &clockrate, &len, NULL, 0)) { tsc_khz = (uint_fast32_t)(clockrate * 1000); } #elif defined(__NetBSD__) uint64_t clockrate; size_t len; len = sizeof (clockrate); if (0 == sysctlbyname ("machdep.tsc_freq", &clockrate, &len, NULL, 0)) { tsc_khz = (uint_fast32_t)(clockrate / 1000); } #elif defined(KSTAT_DATA_INT32) /* ref: http://developers.sun.com/solaris/articles/kstatc.html */ kstat_ctl_t* kc; kstat_t* ksp; kstat_named_t* kdata; if (NULL != (kc = kstat_open()) && NULL != (ksp = kstat_lookup (kc, "cpu_info", -1, NULL)) && KSTAT_TYPE_NAMED == ksp->ks_type && -1 != kstat_read (kc, ksp, NULL) && NULL != (kdata = kstat_data_lookup (ksp, "clock_MHz")) && KSTAT_DATA_INT32 == kdata->data_type) { tsc_khz = (uint_fast32_t)(kdata->value.i32 * 1000); kstat_close (kc); } #endif /* !_WIN32 */ /* e.g. export RDTSC_FREQUENCY=3200.000000 * * Value can be used to override kernel tick rate as well as internal calibration */ err = pgm_dupenv_s (&rdtsc_frequency, &envlen, "RDTSC_FREQUENCY"); if (0 == err && envlen > 0) { tsc_khz = atoi (rdtsc_frequency) * 1000; pgm_free (rdtsc_frequency); } #ifndef _WIN32 /* calibrate */ if (0 >= tsc_khz) { pgm_error_t* sub_error = NULL; if (!pgm_tsc_init (&sub_error)) { pgm_propagate_error (error, sub_error); goto err_cleanup; } } #endif pgm_minor (_("TSC frequency set at %u KHz"), (unsigned)(tsc_khz)); set_tsc_mul (tsc_khz); } #endif /* HAVE_RDTSC */ #ifdef HAVE_DEV_HPET if (pgm_time_update_now == pgm_hpet_update) { pgm_error_t* sub_error = NULL; if (!pgm_hpet_init (&sub_error)) { pgm_propagate_error (error, sub_error); goto err_cleanup; } } #endif pgm_time_update_now(); /* calculate relative time offset */ #if defined(HAVE_DEV_RTC) || defined(HAVE_RDTSC) || defined(HAVE_DEV_HPET) || defined(_WIN32) if ( 0 # ifdef HAVE_DEV_RTC || pgm_time_update_now == pgm_rtc_update # endif # ifdef HAVE_RDTSC || pgm_time_update_now == pgm_tsc_update # endif # ifdef HAVE_DEV_HPET || pgm_time_update_now == pgm_hpet_update # endif # ifdef _WIN32 || pgm_time_update_now == pgm_mmtime_update || pgm_time_update_now == pgm_queryperformancecounter_update # endif ) { # if defined( HAVE_GETTIMEOFDAY ) rel_offset = pgm_gettimeofday_update() - pgm_time_update_now(); # elif defined( HAVE_FTIME ) rel_offset = pgm_ftime_update() - pgm_time_update_now(); # else # error "gettimeofday() or ftime() required to calculate counter offset" # endif } #else rel_offset = 0; #endif /* update Windows timer resolution to 1ms */ #ifdef _WIN32 TIMECAPS tc; if (TIMERR_NOERROR == timeGetDevCaps (&tc, sizeof (TIMECAPS))) { wTimerRes = min (max (tc.wPeriodMin, 1 /* ms */), tc.wPeriodMax); timeBeginPeriod (wTimerRes); pgm_debug ("Set timer resolution to %ums.", wTimerRes); } else { pgm_warn (_("Unable to determine timer device resolution.")); } #endif return TRUE; err_cleanup: pgm_atomic_dec32 (&time_ref_count); return FALSE; }
int SYSTEM_BOOTTIME(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; #ifdef HAVE_ZONE_H if (GLOBAL_ZONEID == getzoneid()) { #endif kstat_ctl_t *kc; kstat_t *kp; kstat_named_t *kn; if (NULL == (kc = kstat_open())) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open kernel statistics facility: %s", zbx_strerror(errno))); return ret; } if (NULL == (kp = kstat_lookup(kc, "unix", 0, "system_misc"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up in kernel statistics facility: %s", zbx_strerror(errno))); goto clean; } if (-1 == kstat_read(kc, kp, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot read from kernel statistics facility: %s", zbx_strerror(errno))); goto clean; } if (NULL == (kn = (kstat_named_t *)kstat_data_lookup(kp, "boot_time"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up data in kernel statistics facility:" " %s", zbx_strerror(errno))); goto clean; } SET_UI64_RESULT(result, get_kstat_numeric_value(kn)); ret = SYSINFO_RET_OK; clean: kstat_close(kc); #ifdef HAVE_ZONE_H } else { struct utmpx utmpx_local, *utmpx; utmpx_local.ut_type = BOOT_TIME; setutxent(); if (NULL != (utmpx = getutxid(&utmpx_local))) { SET_UI64_RESULT(result, utmpx->ut_xtime); ret = SYSINFO_RET_OK; } else SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system boot time.")); endutxent(); } #endif return ret; }
int getloadavg (double loadavg[], int nelem) { int elem = 0; /* Return value. */ # ifdef NO_GET_LOAD_AVG # define LDAV_DONE errno = ENOSYS; elem = -1; # endif # if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) /* Solaris <= 2.6 */ /* Use libkstat because we don't have to be root. */ # define LDAV_DONE kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; int saved_errno; kc = kstat_open (); if (kc == 0) return -1; ksp = kstat_lookup (kc, "unix", 0, "system_misc"); if (ksp == 0) return -1; if (kstat_read (kc, ksp, 0) == -1) return -1; kn = kstat_data_lookup (ksp, "avenrun_1min"); if (kn == 0) { /* Return -1 if no load average information is available. */ nelem = 0; elem = -1; } if (nelem >= 1) loadavg[elem++] = (double) kn->value.ul / FSCALE; if (nelem >= 2) { kn = kstat_data_lookup (ksp, "avenrun_5min"); if (kn != 0) { loadavg[elem++] = (double) kn->value.ul / FSCALE; if (nelem >= 3) { kn = kstat_data_lookup (ksp, "avenrun_15min"); if (kn != 0) loadavg[elem++] = (double) kn->value.ul / FSCALE; } } } saved_errno = errno; kstat_close (kc); errno = saved_errno; # endif /* HAVE_LIBKSTAT */ # if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) /* HP-UX */ /* Use pstat_getdynamic() because we don't have to be root. */ # define LDAV_DONE # undef LOAD_AVE_TYPE struct pst_dynamic dyn_info; if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) return -1; if (nelem > 0) loadavg[elem++] = dyn_info.psd_avg_1_min; if (nelem > 1) loadavg[elem++] = dyn_info.psd_avg_5_min; if (nelem > 2) loadavg[elem++] = dyn_info.psd_avg_15_min; # endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ # if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT /* AIX */ # define LDAV_DONE # undef LOAD_AVE_TYPE /* Use perfstat_cpu_total because we don't have to be root. */ { perfstat_cpu_total_t cpu_stats; int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1); if (result == -1) return result; loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS); loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS); loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS); elem = 3; } # endif # if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__)) /* Linux without glibc, Cygwin */ # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef LINUX_LDAV_FILE # define LINUX_LDAV_FILE "/proc/loadavg" # endif char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; char const *ptr = ldavgbuf; int fd, count, saved_errno; fd = open (LINUX_LDAV_FILE, O_RDONLY); if (fd == -1) return -1; count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); saved_errno = errno; (void) close (fd); errno = saved_errno; if (count <= 0) return -1; ldavgbuf[count] = '\0'; for (elem = 0; elem < nelem; elem++) { double numerator = 0; double denominator = 1; while (*ptr == ' ') ptr++; /* Finish if this number is missing, and report an error if all were missing. */ if (! ('0' <= *ptr && *ptr <= '9')) { if (elem == 0) { errno = ENOTSUP; return -1; } break; } while ('0' <= *ptr && *ptr <= '9') numerator = 10 * numerator + (*ptr++ - '0'); if (*ptr == '.') for (ptr++; '0' <= *ptr && *ptr <= '9'; ptr++) numerator = 10 * numerator + (*ptr - '0'), denominator *= 10; loadavg[elem++] = numerator / denominator; } return elem; # endif /* __linux__ || __CYGWIN__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ # define LDAV_DONE # undef LOAD_AVE_TYPE # ifndef NETBSD_LDAV_FILE # define NETBSD_LDAV_FILE "/kern/loadavg" # endif unsigned long int load_ave[3], scale; int count; FILE *fp; fp = fopen (NETBSD_LDAV_FILE, "r"); if (fp == NULL) return -1; count = fscanf (fp, "%lu %lu %lu %lu\n", &load_ave[0], &load_ave[1], &load_ave[2], &scale); (void) fclose (fp); if (count != 4) { errno = ENOTSUP; return -1; } for (elem = 0; elem < nelem; elem++) loadavg[elem] = (double) load_ave[elem] / (double) scale; return elem; # endif /* __NetBSD__ */ # if !defined (LDAV_DONE) && defined (NeXT) /* NeXTStep */ # define LDAV_DONE /* The NeXT code was adapted from iscreen 3.2. */ host_t host; struct processor_set_basic_info info; unsigned int info_count; /* We only know how to get the 1-minute average for this system, so even if the caller asks for more than 1, we only return 1. */ if (!getloadavg_initialized) { if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) getloadavg_initialized = true; } if (getloadavg_initialized) { info_count = PROCESSOR_SET_BASIC_INFO_COUNT; if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, (processor_set_info_t) &info, &info_count) != KERN_SUCCESS) getloadavg_initialized = false; else { if (nelem > 0) loadavg[elem++] = (double) info.load_average / LOAD_SCALE; } } if (!getloadavg_initialized) { errno = ENOTSUP; return -1; } # endif /* NeXT */ # if !defined (LDAV_DONE) && defined (UMAX) # define LDAV_DONE /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not have a /dev/kmem. Information about the workings of the running kernel can be gathered with inq_stats system calls. We only know how to get the 1-minute average for this system. */ struct proc_summary proc_sum_data; struct stat_descr proc_info; double load; register unsigned int i, j; if (cpus == 0) { register unsigned int c, i; struct cpu_config conf; struct stat_descr desc; desc.sd_next = 0; desc.sd_subsys = SUBSYS_CPU; desc.sd_type = CPUTYPE_CONFIG; desc.sd_addr = (char *) &conf; desc.sd_size = sizeof conf; if (inq_stats (1, &desc)) return -1; c = 0; for (i = 0; i < conf.config_maxclass; ++i) { struct class_stats stats; memset (&stats, 0, sizeof stats); desc.sd_type = CPUTYPE_CLASS; desc.sd_objid = i; desc.sd_addr = (char *) &stats; desc.sd_size = sizeof stats; if (inq_stats (1, &desc)) return -1; c += stats.class_numcpus; } cpus = c; samples = cpus < 2 ? 3 : (2 * cpus / 3); } proc_info.sd_next = 0; proc_info.sd_subsys = SUBSYS_PROC; proc_info.sd_type = PROCTYPE_SUMMARY; proc_info.sd_addr = (char *) &proc_sum_data; proc_info.sd_size = sizeof (struct proc_summary); proc_info.sd_sizeused = 0; if (inq_stats (1, &proc_info) != 0) return -1; load = proc_sum_data.ps_nrunnable; j = 0; for (i = samples - 1; i > 0; --i) { load += proc_sum_data.ps_nrun[j]; if (j++ == PS_NRUNSIZE) j = 0; } if (nelem > 0) loadavg[elem++] = load / samples / cpus; # endif /* UMAX */ # if !defined (LDAV_DONE) && defined (DGUX) # define LDAV_DONE /* This call can return -1 for an error, but with good args it's not supposed to fail. The first argument is for no apparent reason of type 'long int *'. */ dg_sys_info ((long int *) &load_info, DG_SYS_INFO_LOAD_INFO_TYPE, DG_SYS_INFO_LOAD_VERSION_0); if (nelem > 0) loadavg[elem++] = load_info.one_minute; if (nelem > 1) loadavg[elem++] = load_info.five_minute; if (nelem > 2) loadavg[elem++] = load_info.fifteen_minute; # endif /* DGUX */ # if !defined (LDAV_DONE) && defined (apollo) # define LDAV_DONE /* Apollo code from [email protected] (Ray Lischner). This system call is not documented. The load average is obtained as three long integers, for the load average over the past minute, five minutes, and fifteen minutes. Each value is a scaled integer, with 16 bits of integer part and 16 bits of fraction part. I'm not sure which operating system first supported this system call, but I know that SR10.2 supports it. */ extern void proc1_$get_loadav (); unsigned long load_ave[3]; proc1_$get_loadav (load_ave); if (nelem > 0) loadavg[elem++] = load_ave[0] / 65536.0; if (nelem > 1) loadavg[elem++] = load_ave[1] / 65536.0; if (nelem > 2) loadavg[elem++] = load_ave[2] / 65536.0; # endif /* apollo */ # if !defined (LDAV_DONE) && defined (OSF_MIPS) # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); loadavg[elem++] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[0] : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); # endif /* OSF_MIPS */ # if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) /* DJGPP */ # define LDAV_DONE /* A faithful emulation is going to have to be saved for a rainy day. */ for ( ; elem < nelem; elem++) { loadavg[elem] = 0.0; } # endif /* __MSDOS__ || WINDOWS32 */ # if !defined (LDAV_DONE) && defined (OSF_ALPHA) /* OSF/1 */ # define LDAV_DONE struct tbl_loadavg load_ave; table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); for (elem = 0; elem < nelem; elem++) loadavg[elem] = (load_ave.tl_lscale == 0 ? load_ave.tl_avenrun.d[elem] : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); # endif /* OSF_ALPHA */ # if ! defined LDAV_DONE && defined __VMS /* VMS */ /* VMS specific code -- read from the Load Ave driver. */ LOAD_AVE_TYPE load_ave[3]; static bool getloadavg_initialized; # ifdef eunice struct { int dsc$w_length; char *dsc$a_pointer; } descriptor; # endif /* Ensure that there is a channel open to the load ave device. */ if (!getloadavg_initialized) { /* Attempt to open the channel. */ # ifdef eunice descriptor.dsc$w_length = 18; descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; # else $DESCRIPTOR (descriptor, "LAV0:"); # endif if (sys$assign (&descriptor, &channel, 0, 0) & 1) getloadavg_initialized = true; } /* Read the load average vector. */ if (getloadavg_initialized && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, load_ave, 12, 0, 0, 0, 0) & 1)) { sys$dassgn (channel); getloadavg_initialized = false; } if (!getloadavg_initialized) { errno = ENOTSUP; return -1; } # endif /* ! defined LDAV_DONE && defined __VMS */ # if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS /* IRIX, other old systems */ /* UNIX-specific code -- read the average from /dev/kmem. */ # define LDAV_PRIVILEGED /* This code requires special installation. */ LOAD_AVE_TYPE load_ave[3]; /* Get the address of LDAV_SYMBOL. */ if (offset == 0) { # ifndef sgi # if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER strcpy (name_list[0].n_name, LDAV_SYMBOL); strcpy (name_list[1].n_name, ""); # else /* NLIST_STRUCT */ # ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME name_list[0].n_un.n_name = LDAV_SYMBOL; name_list[1].n_un.n_name = 0; # else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ name_list[0].n_name = LDAV_SYMBOL; name_list[1].n_name = 0; # endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ # endif /* NLIST_STRUCT */ # ifndef SUNOS_5 if ( # if !(defined (_AIX) && !defined (ps2)) nlist (KERNEL_FILE, name_list) # else /* _AIX */ knlist (name_list, 1, sizeof (name_list[0])) # endif >= 0) /* Omit "&& name_list[0].n_type != 0 " -- it breaks on Sun386i. */ { # ifdef FIXUP_KERNEL_SYMBOL_ADDR FIXUP_KERNEL_SYMBOL_ADDR (name_list); # endif offset = name_list[0].n_value; } # endif /* !SUNOS_5 */ # else /* sgi */ ptrdiff_t ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); if (ldav_off != -1) offset = (long int) ldav_off & 0x7fffffff; # endif /* sgi */ } /* Make sure we have /dev/kmem open. */ if (!getloadavg_initialized) { # ifndef SUNOS_5 /* Set the channel to close on exec, so it does not litter any child's descriptor table. */ # ifndef O_CLOEXEC # define O_CLOEXEC 0 # endif int fd = open ("/dev/kmem", O_RDONLY | O_CLOEXEC); if (0 <= fd) { # if F_DUPFD_CLOEXEC if (fd <= STDERR_FILENO) { int fd1 = fcntl (fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1); close (fd); fd = fd1; } # endif if (0 <= fd) { channel = fd; getloadavg_initialized = true; } } # else /* SUNOS_5 */ /* We pass 0 for the kernel, corefile, and swapfile names to use the currently running kernel. */ kd = kvm_open (0, 0, 0, O_RDONLY, 0); if (kd != 0) { /* nlist the currently running kernel. */ kvm_nlist (kd, name_list); offset = name_list[0].n_value; getloadavg_initialized = true; } # endif /* SUNOS_5 */ } /* If we can, get the load average values. */ if (offset && getloadavg_initialized) { /* Try to read the load. */ # ifndef SUNOS_5 if (lseek (channel, offset, 0) == -1L || read (channel, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { close (channel); getloadavg_initialized = false; } # else /* SUNOS_5 */ if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) != sizeof (load_ave)) { kvm_close (kd); getloadavg_initialized = false; } # endif /* SUNOS_5 */ } if (offset == 0 || !getloadavg_initialized) { errno = ENOTSUP; return -1; } # endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */ # if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ if (nelem > 0) loadavg[elem++] = LDAV_CVT (load_ave[0]); if (nelem > 1) loadavg[elem++] = LDAV_CVT (load_ave[1]); if (nelem > 2) loadavg[elem++] = LDAV_CVT (load_ave[2]); # define LDAV_DONE # endif /* !LDAV_DONE && LOAD_AVE_TYPE */ # if !defined LDAV_DONE errno = ENOSYS; elem = -1; # endif return elem; }
int SYSTEM_UPTIME(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { #ifdef HAVE_SYSINFO_UPTIME struct sysinfo info; if (0 == sysinfo(&info)) { SET_UI64_RESULT(result, info.uptime); return SYSINFO_RET_OK; } else return SYSINFO_RET_FAIL; #else #ifdef HAVE_FUNCTION_SYSCTL_KERN_BOOTTIME struct timeval uptime; int mib[2], len, now; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; len = sizeof(uptime); if (0 != sysctl(mib, 2, &uptime, (size_t *)&len, NULL, 0)) return SYSINFO_RET_FAIL; now = time(NULL); SET_UI64_RESULT(result, now-uptime.tv_sec); return SYSINFO_RET_OK; #else /* Solaris */ #ifdef HAVE_KSTAT_H kstat_ctl_t *kc; kstat_t *kp; kstat_named_t *kn; long hz; long secs; /* open kstat */ kc = kstat_open(); if (0 == kc) return SYSINFO_RET_FAIL; /* read uptime counter */ kp = kstat_lookup(kc, "unix", 0, "system_misc"); if (0 == kp) { kstat_close(kc); return SYSINFO_RET_FAIL; } if (-1 == kstat_read(kc, kp, 0)) { kstat_close(kc); return SYSINFO_RET_FAIL; } hz = sysconf(_SC_CLK_TCK); /* make sure we do not divide by 0 */ assert(hz); kn = (kstat_named_t*)kstat_data_lookup(kp, "clk_intr"); secs = get_kstat_numeric_value(kn) / hz; /* close kstat */ kstat_close(kc); SET_UI64_RESULT(result, secs); return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif #endif #endif }
/* * Return information about system virtual memory. */ static PyObject * psutil_swap_mem(PyObject *self, PyObject *args) { // XXX (arghhh!) // total/free swap mem: commented out as for some reason I can't // manage to get the same results shown by "swap -l", despite the // code below is exactly the same as: // http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/ // cmd/swap/swap.c // We're going to parse "swap -l" output from Python (sigh!) /* struct swaptable *st; struct swapent *swapent; int i; struct stat64 statbuf; char *path; char fullpath[MAXPATHLEN+1]; int num; if ((num = swapctl(SC_GETNSWP, NULL)) == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if (num == 0) { PyErr_SetString(PyExc_RuntimeError, "no swap devices configured"); return NULL; } if ((st = malloc(num * sizeof(swapent_t) + sizeof (int))) == NULL) { PyErr_SetString(PyExc_RuntimeError, "malloc failed"); return NULL; } if ((path = malloc(num * MAXPATHLEN)) == NULL) { PyErr_SetString(PyExc_RuntimeError, "malloc failed"); return NULL; } swapent = st->swt_ent; for (i = 0; i < num; i++, swapent++) { swapent->ste_path = path; path += MAXPATHLEN; } st->swt_n = num; if ((num = swapctl(SC_LIST, st)) == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } swapent = st->swt_ent; long t = 0, f = 0; for (i = 0; i < num; i++, swapent++) { int diskblks_per_page =(int)(sysconf(_SC_PAGESIZE) >> DEV_BSHIFT); t += (long)swapent->ste_pages; f += (long)swapent->ste_free; } free(st); return Py_BuildValue("(kk)", t, f); */ kstat_ctl_t *kc; kstat_t *k; cpu_stat_t *cpu; int cpu_count = 0; int flag = 0; uint_t sin = 0; uint_t sout = 0; kc = kstat_open(); if (kc == NULL) { return PyErr_SetFromErrno(PyExc_OSError);; } k = kc->kc_chain; while (k != NULL) { if ((strncmp(k->ks_name, "cpu_stat", 8) == 0) && \ (kstat_read(kc, k, NULL) != -1) ) { flag = 1; cpu = (cpu_stat_t *) k->ks_data; sin += cpu->cpu_vminfo.pgswapin; // num pages swapped in sout += cpu->cpu_vminfo.pgswapout; // num pages swapped out } cpu_count += 1; k = k->ks_next; } kstat_close(kc); if (!flag) { PyErr_SetString(PyExc_RuntimeError, "no swap device was found"); return NULL; } return Py_BuildValue("(II)", sin, sout); }
/** * This routine returns kbyte of real memory in use. * @return: TRUE if successful, FALSE if failed (or not available) */ int used_system_memory_sysdep(SystemInfo_T *si) { int i, n, num; kstat_ctl_t *kctl; kstat_named_t *knamed; kstat_t *kstat; swaptbl_t *s; char *strtab; unsigned long long total = 0ULL; unsigned long long used = 0ULL; /* Memory */ kctl = kstat_open(); kstat = kstat_lookup(kctl, "unix", 0, "system_pages"); if (kstat_read(kctl, kstat, 0) == -1) { LogError("system statistic error -- memory usage gathering failed\n"); kstat_close(kctl); return FALSE; } knamed = kstat_data_lookup(kstat, "freemem"); if (knamed) si->total_mem_kbyte = systeminfo.mem_kbyte_max-pagetok(knamed->value.ul); kstat_close(kctl); /* Swap */ again: if ((num = swapctl(SC_GETNSWP, 0)) == -1) { LogError("system statistic error -- swap usage gathering failed: %s\n", STRERROR); return FALSE; } if (num == 0) { DEBUG("system statistic -- no swap configured\n"); si->swap_kbyte_max = 0; return TRUE; } s = (swaptbl_t *)xmalloc(num * sizeof(swapent_t) + sizeof(struct swaptable)); strtab = (char *)xmalloc((num + 1) * MAXSTRSIZE); for (i = 0; i < (num + 1); i++) s->swt_ent[i].ste_path = strtab + (i * MAXSTRSIZE); s->swt_n = num + 1; if ((n = swapctl(SC_LIST, s)) < 0) { LogError("system statistic error -- swap usage gathering failed: %s\n", STRERROR); si->swap_kbyte_max = 0; FREE(s); FREE(strtab); return FALSE; } if (n > num) { DEBUG("system statistic -- new swap added: deferring swap usage statistics to next cycle\n"); FREE(s); FREE(strtab); goto again; } for (i = 0; i < n; i++) { if (!(s->swt_ent[i].ste_flags & ST_INDEL) && !(s->swt_ent[i].ste_flags & ST_DOINGDEL)) { total += s->swt_ent[i].ste_pages; used += s->swt_ent[i].ste_pages - s->swt_ent[i].ste_free; } } FREE(s); FREE(strtab); si->swap_kbyte_max = (unsigned long)(double)(total * page_size) / 1024.; si->total_swap_kbyte = (unsigned long)(double)(used * page_size) / 1024.; return TRUE; }
/* * Returns uptime in centiseconds(!). */ long get_uptime (void) { #if defined(bsdlike) && !defined(solaris2) && !defined(linux) struct timeval boottime, now, diff; #ifndef CAN_USE_SYSCTL int kmem; static struct nlist nl[] = { #if !defined(hpux) { (char*)"_boottime" }, #else { "boottime" }, #endif { (char*)"" } }; if ((kmem = open("/dev/kmem", 0)) < 0) return 0; nlist(KERNEL_LOC, nl); if (nl[0].n_type == 0){ close(kmem); return 0; } lseek(kmem, (long)nl[0].n_value, L_SET); read(kmem, &boottime, sizeof(boottime)); close(kmem); #else /* CAN_USE_SYSCTL */ int mib[2]; size_t len; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; len = sizeof(boottime); sysctl(mib, 2, &boottime, &len, NULL, NULL); #endif /* CAN_USE_SYSCTL */ gettimeofday(&now,(struct timezone *)0); now.tv_sec--; now.tv_usec += 1000000L; diff.tv_sec = now.tv_sec - boottime.tv_sec; diff.tv_usec = now.tv_usec - boottime.tv_usec; if (diff.tv_usec > 1000000L){ diff.tv_usec -= 1000000L; diff.tv_sec++; } return ((diff.tv_sec * 100) + (diff.tv_usec / 10000)); #endif /* bsdlike */ #ifdef solaris2 kstat_ctl_t *ksc = kstat_open(); kstat_t *ks; kid_t kid; kstat_named_t *named; u_long lbolt; if (ksc == NULL) return 0; ks = kstat_lookup (ksc, "unix", -1, "system_misc"); if (ks == NULL) return 0; kid = kstat_read (ksc, ks, NULL); if (kid == -1) return 0; named = kstat_data_lookup(ks, "lbolt"); if (named == NULL) return 0; lbolt = named->value.ul; kstat_close(ksc); return lbolt; #endif /* solaris2 */ #ifdef linux FILE *in = fopen ("/proc/uptime", "r"); long uptim = 0, a, b; if (in) { if (2 == fscanf (in, "%ld.%ld", &a, &b)) uptim = a * 100 + b; fclose (in); } return uptim; #endif /* linux */ return (0); /* not implemented */ }
/** * This routine returns system/user CPU time in use. * @return: TRUE if successful, FALSE if failed (or not available) */ int used_system_cpu_sysdep(SystemInfo_T *si) { int i, ncpu = 0, ncpus; long cpu_user = 0, cpu_syst = 0, cpu_wait = 0; long total = 0; kstat_ctl_t *kctl; kstat_named_t *knamed; kstat_t *kstat; kstat_t **cpu_ks; cpu_stat_t *cpu_stat; si->total_cpu_user_percent = 0; si->total_cpu_syst_percent = 0; si->total_cpu_wait_percent = 0; kctl = kstat_open(); kstat = kstat_lookup(kctl, "unix", 0, "system_misc"); if (kstat_read(kctl, kstat, 0) == -1) goto error; if (NULL == (knamed = kstat_data_lookup(kstat, "ncpus"))) goto error; ncpus = knamed->value.ui32; cpu_ks = (kstat_t **)xmalloc(ncpus * sizeof(kstat_t *)); cpu_stat = (cpu_stat_t *)xmalloc(ncpus * sizeof(cpu_stat_t)); for (kstat = kctl->kc_chain; kstat; kstat = kstat->ks_next) { if (strncmp(kstat->ks_name, "cpu_stat", 8) == 0) { if (-1 == kstat_read(kctl, kstat, NULL)) goto error2; cpu_ks[ncpu] = kstat; if (++ncpu > ncpus) goto error2; } } for (i = 0; i < ncpu; i++) { if (-1 == kstat_read(kctl, cpu_ks[i], &cpu_stat[i])) goto error2; cpu_user += cpu_stat[i].cpu_sysinfo.cpu[CPU_USER]; cpu_syst += cpu_stat[i].cpu_sysinfo.cpu[CPU_KERNEL]; cpu_wait += cpu_stat[i].cpu_sysinfo.cpu[CPU_WAIT]; total += (cpu_stat[i].cpu_sysinfo.cpu[0]+ cpu_stat[i].cpu_sysinfo.cpu[1]+ cpu_stat[i].cpu_sysinfo.cpu[2]+ cpu_stat[i].cpu_sysinfo.cpu[3]); } if (old_total == 0.0 ) { si->total_cpu_user_percent = -10; si->total_cpu_syst_percent = -10; si->total_cpu_wait_percent = -10; } else { si->total_cpu_user_percent = (int)((1000 * (cpu_user - old_cpu_user)) / (total - old_total)); si->total_cpu_syst_percent = (int)((1000 * (cpu_syst - old_cpu_syst)) / (total - old_total)); si->total_cpu_wait_percent = (int)((1000 * (cpu_wait - old_cpu_wait)) / (total - old_total)); } old_cpu_user = cpu_user; old_cpu_syst = cpu_syst; old_cpu_wait = cpu_wait; old_total = total; FREE(cpu_ks); FREE(cpu_stat); kstat_close(kctl); return TRUE; error2: old_total=0; FREE(cpu_ks); FREE(cpu_stat); error: kstat_close(kctl); return FALSE; }
CollectorSolaris::~CollectorSolaris() { if (mKC) kstat_close(mKC); }
static sg_error sg_get_host_info_int(sg_host_info *host_info_buf) { #ifdef WIN32 unsigned long nameln; char *name; long long result; OSVERSIONINFOEX osinfo; SYSTEM_INFO sysinfo; char *tmp_name; char tmp[10]; #else struct utsname os; # if defined(HPUX) struct pst_static pstat_static; struct pst_dynamic pstat_dynamic; time_t currtime; long boottime; # elif defined(SOLARIS) time_t boottime, curtime; kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kn; char *isainfo = NULL; long isabufsz, rc; # elif defined(LINUX) || defined(CYGWIN) FILE *f; # elif defined(ALLBSD) int mib[2]; struct timeval boottime; time_t curtime; size_t size; int ncpus; # if defined(HW_MACHINE_ARCH) || defined(HW_MACHINE) char arch_name[16]; # endif # elif defined(AIX) static perfstat_cpu_total_t cpu_total; sg_error rc; # if defined(HAVE_GETUTXENT) struct utmpx *ut; # else struct utmp *ut; # endif # endif #endif host_info_buf->ncpus = 0; host_info_buf->maxcpus = 0; host_info_buf->bitwidth = 0; host_info_buf->host_state = sg_unknown_configuration; host_info_buf->uptime = 0; host_info_buf->systime = 0; #ifdef WIN32 /* these settings are static after boot, so why get them * constantly? * * Because we want to know some changes anyway - at least * when the hostname (DNS?) changes */ /* get system name */ nameln = MAX_COMPUTERNAME_LENGTH + 1; name = sg_malloc(nameln); if(name == NULL) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } /* * XXX probably GetComputerNameEx() is a better entry point ... */ if( GetComputerName(name, &nameln) == 0 ) { free(name); RETURN_WITH_SET_ERROR("os", SG_ERROR_HOST, "GetComputerName"); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->hostname, name)) { free(name); RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } free(name); /* get OS name, version and build */ ZeroMemory(&osinfo, sizeof(OSVERSIONINFOEX)); osinfo.dwOSVersionInfoSize = sizeof(osinfo); if(!GetVersionEx(&osinfo)) { RETURN_WITH_SET_ERROR("os", SG_ERROR_HOST, "GetVersionEx"); } GetSystemInfo(&sysinfo); /* Release - single number */ if(snprintf(tmp, sizeof(tmp), "%ld", osinfo.dwBuildNumber) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SPRINTF, NULL); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_release, tmp)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } /* Version */ /* usually a single digit . single digit, eg 5.0 */ if(snprintf(tmp, sizeof(tmp), "%ld.%ld", osinfo.dwMajorVersion, osinfo.dwMinorVersion) == -1) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_version, tmp)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } /* OS name */ tmp_name = get_os_name(osinfo, sysinfo); if(tmp_name == NULL) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_name, tmp_name)) { free(tmp_name); RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } free(tmp_name); /* Platform */ switch(sysinfo.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_INTEL: if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, "Intel")) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } break; case PROCESSOR_ARCHITECTURE_IA64: if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, "IA64")) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } break; case PROCESSOR_ARCHITECTURE_AMD64: if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, "AMD64")) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } break; default: if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, "Unknown")){ RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } break; } if(read_counter_large(SG_WIN32_UPTIME, &result)) { RETURN_WITH_SET_ERROR("os", SG_ERROR_PDHREAD, PDH_UPTIME); } host_info_buf->uptime = (time_t) result; #else if((uname(&os)) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_UNAME, NULL); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_name, os.sysname)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_release, os.release)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->os_version, os.version)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, os.machine)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->hostname, os.nodename)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } /* get uptime */ #ifdef HPUX if (pstat_getstatic(&pstat_static, sizeof(pstat_static), 1, 0) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_PSTAT, "pstat_static"); } if (pstat_getdynamic(&pstat_dynamic, sizeof(pstat_dynamic), 1, 0) == -1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_PSTAT, "pstat_dynamic"); } currtime = time(NULL); boottime = pstat_static.boot_time; host_info_buf->uptime = currtime - boottime; host_info_buf->ncpus = pstat_dynamic.psd_proc_cnt; host_info_buf->maxcpus = pstat_dynamic.psd_max_proc_cnt; host_info_buf->bitwidth = sysconf(_SC_KERNEL_BITS); /* * TODO: getting virtualization state * 1) on boostrapping this component, try loading /opt/hpvm/lib/libhpvm.so (or so) * 2) get function addresses for * a) HPVM_boolean hpvm_api_server_check() * b) HPVM_boolean hpvm_api_virtmach_check() * * Seems to be hardware virtualization ... * See: http://docstore.mik.ua/manuals/hp-ux/en/T2767-90141/index.html (hpvmpubapi(3)) * http://jreypo.wordpress.com/tag/hpvm/ * http://jreypo.wordpress.com/category/hp-ux/page/3/ * http://h20338.www2.hp.com/enterprise/us/en/os/hpux11i-partitioning-integrity-vm.html */ #elif defined(SOLARIS) if ((kc = kstat_open()) == NULL) { RETURN_WITH_SET_ERROR("os", SG_ERROR_KSTAT_OPEN, NULL); } if((ksp=kstat_lookup(kc, "unix", -1, "system_misc"))==NULL){ kstat_close(kc); RETURN_WITH_SET_ERROR("os", SG_ERROR_KSTAT_LOOKUP, "unix,-1,system_misc"); } if (kstat_read(kc, ksp, 0) == -1) { kstat_close(kc); RETURN_WITH_SET_ERROR("os", SG_ERROR_KSTAT_READ, NULL); } if((kn=kstat_data_lookup(ksp, "boot_time")) == NULL){ kstat_close(kc); RETURN_WITH_SET_ERROR("os", SG_ERROR_KSTAT_DATA_LOOKUP, "boot_time"); } /* XXX verify on Solaris 10 if it's still ui32 */ boottime = (kn->value.ui32); kstat_close(kc); time(&curtime); host_info_buf->uptime = curtime - boottime; host_info_buf->ncpus = sysconf(_SC_NPROCESSORS_ONLN); host_info_buf->maxcpus = sysconf(_SC_NPROCESSORS_CONF); isainfo = sg_malloc( isabufsz = (32 * sizeof(*isainfo)) ); if( NULL == isainfo ) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } # define MKSTR(x) #x # if defined(SI_ARCHITECTURE_K) # define SYSINFO_CMD SI_ARCHITECTURE_K # elif defined(SI_ISALIST) # define SYSINFO_CMD SI_ISALIST # else # define SYSINFO_CMD SI_ARCHITECTURE # endif sysinfo_again: if( -1 == ( rc = sysinfo( SYSINFO_CMD, isainfo, isabufsz ) ) ) { free(isainfo); RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSINFO, MKSTR(SYSINFO_CMD) ); } else if( rc > isabufsz ) { char *tmp = sg_realloc(isainfo, rc); if( NULL == tmp ) { free(isainfo); RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } isabufsz = rc; isainfo = tmp; goto sysinfo_again; } host_info_buf->bitwidth = get_bitwidth_by_arch_name(isainfo); free(isainfo); host_info_buf->host_state = sg_unknown_configuration; #elif defined(LINUX) || defined(CYGWIN) if ((f=fopen("/proc/uptime", "r")) == NULL) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_OPEN, "/proc/uptime"); } #define TIME_T_SCANF_FMT (sizeof(int[(((time_t)-1)/2)%4+1]) == sizeof(int[1]) ? "%ld %*d" : "%lu %*d" ) if((fscanf(f,TIME_T_SCANF_FMT,&host_info_buf->uptime)) != 1){ fclose(f); RETURN_WITH_SET_ERROR("os", SG_ERROR_PARSE, NULL); } fclose(f); # if defined(LINUX) host_info_buf->ncpus = sysconf(_SC_NPROCESSORS_ONLN); host_info_buf->maxcpus = sysconf(_SC_NPROCESSORS_CONF); if( access( "/proc/sys/kernel/vsyscall64", F_OK ) == 0 || access( "/proc/sys/abi/vsyscall32", F_OK ) == 0 ) { host_info_buf->bitwidth = 64; } else { host_info_buf->bitwidth = sysconf(_SC_LONG_BIT); // well, maybe 64-bit disabled 128-bit system o.O } host_info_buf->host_state = sg_unknown_configuration; # endif #elif defined(ALLBSD) mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; size = sizeof(boottime); if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "CTL_KERN.KERN_BOOTTIME"); } time(&curtime); host_info_buf->uptime= curtime - boottime.tv_sec; # if defined(HW_NCPU) mib[0] = CTL_HW; mib[1] = HW_NCPU; size = sizeof(int); if( sysctl( mib, 2, &ncpus, &size, NULL, 0 ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "CTL_HW.HW_NCPU" ); } # endif # if defined(HW_MACHINE_ARCH) mib[0] = CTL_HW; mib[1] = HW_MACHINE_ARCH; size = sizeof(arch_name); if( sysctl( mib, 2, arch_name, &size, NULL, 0 ) == 0 ) { host_info_buf->bitwidth = get_bitwidth_by_arch_name(arch_name); } else { # endif # if defined(HW_MACHINE) mib[0] = CTL_HW; mib[1] = HW_MACHINE; size = sizeof(arch_name); if( sysctl( mib, 2, arch_name, &size, NULL, 0 ) == 0 ) { host_info_buf->bitwidth = get_bitwidth_by_arch_name(arch_name); } else { SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "CTL_HW.HW_MACHINE" ); } # elif defined(HW_MACHINE_ARCH) SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "CTL_HW.HW_MACHINE_ARCH" ); # endif # if defined(HW_MACHINE_ARCH) } # endif host_info_buf->host_state = sg_unknown_configuration; /* details must be analysed "manually", no syscall */ host_info_buf->maxcpus = (unsigned)ncpus; # if defined(HW_NCPUONLINE) /* use knowledge about number of cpu's online, when available instead of assuming all of them */ mib[0] = CTL_HW; mib[1] = HW_NCPUONLINE; size = sizeof(int); if( sysctl( mib, 2, &ncpus, &size, NULL, 0 ) < 0 ) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "CTL_HW.HW_NCPUONLINE" ); } # endif host_info_buf->ncpus = (unsigned)ncpus; #elif defined(AIX) if(perfstat_cpu_total(NULL, &cpu_total, sizeof(cpu_total), 1) != 1) { RETURN_WITH_SET_ERROR_WITH_ERRNO("os", SG_ERROR_SYSCTL, "perfstat_cpu_total"); } if(SG_ERROR_NONE != sg_update_string(&host_info_buf->platform, cpu_total.description)) { RETURN_FROM_PREVIOUS_ERROR( "os", sg_get_error() ); } host_info_buf->ncpus = cpu_total.ncpus; host_info_buf->maxcpus = cpu_total.ncpus_cfg; host_info_buf->bitwidth = sysconf(_SC_AIX_KERNEL_BITMODE); if( sysconf(_SC_LPAR_ENABLED) > 0 ) { host_info_buf->host_state = sg_hardware_virtualized; } else { host_info_buf->host_state = sg_physical_host; } #ifdef ENABLE_THREADS if( SG_ERROR_NONE != ( rc = sg_lock_mutex("utmp") ) ) { RETURN_FROM_PREVIOUS_ERROR( "os", rc ); } #endif # if defined(HAVE_GETUTXENT) # define UTENTFN getutxent # define UTENTTM ut->ut_tv.tv_sec setutxent(); # else # define UTENTFN getutent # define UTENTTM ut->ut_time setutent(); # endif while( NULL != ( ut = UTENTFN() ) ) { if( ut->ut_type == BOOT_TIME ) { host_info_buf->uptime = time(NULL) - UTENTTM; break; } } # if defined(HAVE_GETUTXENT) endutxent(); # else endutent(); # endif #ifdef ENABLE_THREADS if( SG_ERROR_NONE != ( rc = sg_unlock_mutex("utmp") ) ) { RETURN_FROM_PREVIOUS_ERROR( "os", rc ); } #endif #else RETURN_WITH_SET_ERROR("os", SG_ERROR_UNSUPPORTED, OS_TYPE); #endif #endif /* WIN32 */ host_info_buf->systime = time(NULL); return SG_ERROR_NONE; }
/** * Run once function that initializes the kstats we need here. * * @returns IPRT status code. * @param pvUser Unused. */ static DECLCALLBACK(int) rtMpSolarisOnce(void *pvUser) { int rc = VINF_SUCCESS; NOREF(pvUser); /* * Open kstat and find the cpu_info entries for each of the CPUs. */ g_pKsCtl = kstat_open(); if (g_pKsCtl) { g_capCpuInfo = RTMpGetCount(); g_papCpuInfo = (kstat_t **)RTMemAllocZ(g_capCpuInfo * sizeof(kstat_t *)); if (g_papCpuInfo) { g_cu64CoreIds = g_capCpuInfo; g_pu64CoreIds = (uint64_t *)RTMemAllocZ(g_cu64CoreIds * sizeof(uint64_t)); if (g_pu64CoreIds) { rc = RTCritSectInit(&g_MpSolarisCritSect); if (RT_SUCCESS(rc)) { RTCPUID i = 0; for (kstat_t *pKsp = g_pKsCtl->kc_chain; pKsp != NULL; pKsp = pKsp->ks_next) { if (!RTStrCmp(pKsp->ks_module, "cpu_info")) { AssertBreak(i < g_capCpuInfo); g_papCpuInfo[i++] = pKsp; /** @todo ks_instance == cpu_id (/usr/src/uts/common/os/cpu.c)? Check this and fix it ASAP. */ } } rc = rtMpSolarisGetCoreIds(); if (RT_SUCCESS(rc)) return VINF_SUCCESS; else Log(("rtMpSolarisGetCoreIds failed. rc=%Rrc\n", rc)); } RTMemFree(g_pu64CoreIds); g_pu64CoreIds = NULL; } else rc = VERR_NO_MEMORY; /* bail out, we failed. */ RTMemFree(g_papCpuInfo); g_papCpuInfo = NULL; } else rc = VERR_NO_MEMORY; kstat_close(g_pKsCtl); g_pKsCtl = NULL; } else { rc = RTErrConvertFromErrno(errno); if (RT_SUCCESS(rc)) rc = VERR_INTERNAL_ERROR; Log(("kstat_open() -> %d (%Rrc)\n", errno, rc)); } return rc; }
static void kstat_do_read(void) { kstat_ctl_t * kc; kstat_t * kst; kstat_named_t * kn, *kn2; intf_t * i; if (!(kc = kstat_open())) quit("kstat_open() failed"); if ((kst = kstat_lookup(kc, NULL, -1, NULL))) { for (; kst; kst = kst->ks_next) { if (strcmp(kst->ks_class, "net")) continue; if (kstat_read(kc, kst, NULL) < 0) continue; if (!strcmp(kst->ks_name, "zero_copy")) continue; i = lookup_intf(get_local_node(), kst->ks_name, 0, 0); if (NULL == i) continue; #define KSTAT_GET(S) (kstat_named_t *) kstat_data_lookup(kst, #S) if ((kn = KSTAT_GET(rbytes64))) { i->i_rx_bytes.r_total = kn->value.ui64; i->i_rx_bytes.r_is64bit = 1; } else if ((kn = KSTAT_GET(rbytes))) i->i_rx_bytes.r_total = kn->value.ui32; if ((kn = KSTAT_GET(ipackets64))) { i->i_rx_packets.r_total = kn->value.ui64; i->i_rx_packets.r_is64bit = 1; } else if ((kn = KSTAT_GET(ipackets))) i->i_rx_packets.r_total = kn->value.ui32; if ((kn = KSTAT_GET(obytes64))) i->i_tx_bytes.r_total = kn->value.ui64; else if ((kn = KSTAT_GET(obytes))) i->i_tx_bytes.r_total = kn->value.ui32; if ((kn = KSTAT_GET(opackets64))) i->i_tx_packets.r_total = kn->value.ui64; else if ((kn = KSTAT_GET(opackets))) i->i_tx_packets.r_total = kn->value.ui32; if ((kn = KSTAT_GET(ierror)) && (kn2 = KSTAT_GET(oerrors))) update_attr(i, ERRORS, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); if ((kn = KSTAT_GET(multircv64)) && (kn2 = KSTAT_GET(multixmt64))) update_attr(i, MULTICAST, kn->value.ui64, kn2->value.ui64, RX_PROVIDED | TX_PROVIDED); else if ((kn = KSTAT_GET(multircv)) && (kn2 = KSTAT_GET(multixmt))) update_attr(i, MULTICAST, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); if ((kn = KSTAT_GET(brdcstrcv)) && (kn2 = KSTAT_GET(brdcstxmt))) update_attr(i, BROADCAST, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); #undef KSTAT_GET notify_update(i); increase_lifetime(i, 1); } } kstat_close(kc); }