int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) { struct pst_swapinfo swapinfo; struct pst_vminfo vminfo; int i=0; swap->total = swap->free = 0; while (pstat_getswap(&swapinfo, sizeof(swapinfo), 1, i++) > 0) { swapinfo.pss_nfpgs *= 4; /* nfpgs is in 512 byte blocks */ if (swapinfo.pss_nblksenabled == 0) { swapinfo.pss_nblksenabled = swapinfo.pss_nfpgs; } swap->total += swapinfo.pss_nblksenabled; swap->free += swapinfo.pss_nfpgs; } swap->used = swap->total - swap->free; pstat_getvminfo(&vminfo, sizeof(vminfo), 1, 0); swap->page_in = vminfo.psv_spgin; swap->page_out = vminfo.psv_spgout; return SIGAR_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; }
static int getentropy_fallback(void *buf, size_t len) { uint8_t results[SHA512_DIGEST_LENGTH]; int save_errno = errno, e, pgs = sysconf(_SC_PAGESIZE), faster = 0, repeat; static int cnt; struct timespec ts; struct timeval tv; struct pst_vminfo pvi; struct pst_vm_status pvs; struct pst_dynamic pdy; struct rusage ru; sigset_t sigset; struct stat st; SHA512_CTX ctx; static pid_t lastpid; pid_t pid; size_t i, ii, m; char *p; pid = getpid(); if (lastpid == pid) { faster = 1; repeat = 2; } else { faster = 0; lastpid = pid; repeat = REPEAT; } for (i = 0; i < len; ) { int j; SHA512_Init(&ctx); for (j = 0; j < repeat; j++) { HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } HX(pstat_getvminfo(&pvi, sizeof(pvi), 1, 0) != 1, pvi); HX(pstat_getprocvm(&pvs, sizeof(pvs), 0, 0) != 1, pvs); for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) HX(clock_gettime(cl[ii], &ts) == -1, ts); HX((pid = getpid()) == -1, pid); HX((pid = getsid(pid)) == -1, pid); HX((pid = getppid()) == -1, pid); HX((pid = getpgid(0)) == -1, pid); HX((e = getpriority(0, 0)) == -1, e); if(pstat_getdynamic(&pdy, sizeof(pdy), 1, 0) != 1) { HD(errno); } else { HD(pdy.psd_avg_1_min); HD(pdy.psd_avg_5_min); HD(pdy.psd_avg_15_min); } if (!faster) { ts.tv_sec = 0; ts.tv_nsec = 1; (void) nanosleep(&ts, NULL); } HX(sigpending(&sigset) == -1, sigset); HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1, sigset); HF(getentropy); /* an addr in this library */ HF(printf); /* an addr in libc */ p = (char *)&p; HD(p); /* an addr on stack */ p = (char *)&errno; HD(p); /* the addr of errno */ if (i == 0) { struct sockaddr_storage ss; struct statvfs stvfs; struct termios tios; socklen_t ssl; off_t off; /* * Prime-sized mappings encourage fragmentation; * thus exposing some address entropy. */ struct mm { size_t npg; void *p; } mm[] = { { 17, MAP_FAILED }, { 3, MAP_FAILED }, { 11, MAP_FAILED }, { 2, MAP_FAILED }, { 5, MAP_FAILED }, { 3, MAP_FAILED }, { 7, MAP_FAILED }, { 1, MAP_FAILED }, { 57, MAP_FAILED }, { 3, MAP_FAILED }, { 131, MAP_FAILED }, { 1, MAP_FAILED }, }; for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { HX(mm[m].p = mmap(NULL, mm[m].npg * pgs, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, (off_t)0), mm[m].p); if (mm[m].p != MAP_FAILED) { size_t mo; /* Touch some memory... */ p = mm[m].p; mo = cnt % (mm[m].npg * pgs - 1); p[mo] = 1; cnt += (int)((long)(mm[m].p) / pgs); } /* Check cnts and times... */ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++) { HX((e = clock_gettime(cl[ii], &ts)) == -1, ts); if (e != -1) cnt += (int)ts.tv_nsec; } HX((e = getrusage(RUSAGE_SELF, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) { if (mm[m].p != MAP_FAILED) munmap(mm[m].p, mm[m].npg * pgs); mm[m].p = MAP_FAILED; } HX(stat(".", &st) == -1, st); HX(statvfs(".", &stvfs) == -1, stvfs); HX(stat("/", &st) == -1, st); HX(statvfs("/", &stvfs) == -1, stvfs); HX((e = fstat(0, &st)) == -1, st); if (e == -1) { if (S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { HX(fstatvfs(0, &stvfs) == -1, stvfs); HX((off = lseek(0, (off_t)0, SEEK_CUR)) < 0, off); } if (S_ISCHR(st.st_mode)) { HX(tcgetattr(0, &tios) == -1, tios); } else if (S_ISSOCK(st.st_mode)) { memset(&ss, 0, sizeof ss); ssl = sizeof(ss); HX(getpeername(0, (void *)&ss, &ssl) == -1, ss); } } HX((e = getrusage(RUSAGE_CHILDREN, &ru)) == -1, ru); if (e != -1) { cnt += (int)ru.ru_utime.tv_sec; cnt += (int)ru.ru_utime.tv_usec; } } else { /* Subsequent hashes absorb previous result */ HD(results); } HX((e = gettimeofday(&tv, NULL)) == -1, tv); if (e != -1) { cnt += (int)tv.tv_sec; cnt += (int)tv.tv_usec; } HD(cnt); } SHA512_Final(results, &ctx); memcpy((char *)buf + i, results, min(sizeof(results), len - i)); i += min(sizeof(results), len - i); } explicit_bzero(&ctx, sizeof ctx); explicit_bzero(results, sizeof results); if (gotdata(buf, len) == 0) { errno = save_errno; return 0; /* satisfied */ } errno = EIO; return -1; }
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; }