123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- // Copyright (c) 2016 Jasper Lievisse Adriaanse <j@jasper.la>.
- // +build openbsd
- package gosigar
- /*
- #include <sys/param.h>
- #include <sys/types.h>
- #include <sys/sysctl.h>
- #include <sys/mount.h>
- #include <sys/sched.h>
- #include <sys/swap.h>
- #include <stdlib.h>
- #include <unistd.h>
- */
- import "C"
- //import "github.com/davecgh/go-spew/spew"
- import (
- "runtime"
- "syscall"
- "time"
- "unsafe"
- )
- type Uvmexp struct {
- pagesize uint32
- pagemask uint32
- pageshift uint32
- npages uint32
- free uint32
- active uint32
- inactive uint32
- paging uint32
- wired uint32
- zeropages uint32
- reserve_pagedaemon uint32
- reserve_kernel uint32
- anonpages uint32
- vnodepages uint32
- vtextpages uint32
- freemin uint32
- freetarg uint32
- inactarg uint32
- wiredmax uint32
- anonmin uint32
- vtextmin uint32
- vnodemin uint32
- anonminpct uint32
- vtextmi uint32
- npct uint32
- vnodeminpct uint32
- nswapdev uint32
- swpages uint32
- swpginuse uint32
- swpgonly uint32
- nswget uint32
- nanon uint32
- nanonneeded uint32
- nfreeanon uint32
- faults uint32
- traps uint32
- intrs uint32
- swtch uint32
- softs uint32
- syscalls uint32
- pageins uint32
- obsolete_swapins uint32
- obsolete_swapouts uint32
- pgswapin uint32
- pgswapout uint32
- forks uint32
- forks_ppwait uint32
- forks_sharevm uint32
- pga_zerohit uint32
- pga_zeromiss uint32
- zeroaborts uint32
- fltnoram uint32
- fltnoanon uint32
- fltpgwait uint32
- fltpgrele uint32
- fltrelck uint32
- fltrelckok uint32
- fltanget uint32
- fltanretry uint32
- fltamcopy uint32
- fltnamap uint32
- fltnomap uint32
- fltlget uint32
- fltget uint32
- flt_anon uint32
- flt_acow uint32
- flt_obj uint32
- flt_prcopy uint32
- flt_przero uint32
- pdwoke uint32
- pdrevs uint32
- pdswout uint32
- pdfreed uint32
- pdscans uint32
- pdanscan uint32
- pdobscan uint32
- pdreact uint32
- pdbusy uint32
- pdpageouts uint32
- pdpending uint32
- pddeact uint32
- pdreanon uint32
- pdrevnode uint32
- pdrevtext uint32
- fpswtch uint32
- kmapent uint32
- }
- type Bcachestats struct {
- numbufs uint64
- numbufpages uint64
- numdirtypages uint64
- numcleanpages uint64
- pendingwrites uint64
- pendingreads uint64
- numwrites uint64
- numreads uint64
- cachehits uint64
- busymapped uint64
- dmapages uint64
- highpages uint64
- delwribufs uint64
- kvaslots uint64
- kvaslots_avail uint64
- }
- type Swapent struct {
- se_dev C.dev_t
- se_flags int32
- se_nblks int32
- se_inuse int32
- se_priority int32
- sw_path []byte
- }
- func (self *FileSystemList) Get() error {
- num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT)
- if err != nil {
- return err
- }
- buf := make([]syscall.Statfs_t, num)
- _, err = syscall.Getfsstat(buf, C.MNT_NOWAIT)
- if err != nil {
- return err
- }
- fslist := make([]FileSystem, 0, num)
- for i := 0; i < num; i++ {
- fs := FileSystem{}
- fs.DirName = bytePtrToString(&buf[i].F_mntonname[0])
- fs.DevName = bytePtrToString(&buf[i].F_mntfromname[0])
- fs.SysTypeName = bytePtrToString(&buf[i].F_fstypename[0])
- fslist = append(fslist, fs)
- }
- self.List = fslist
- return err
- }
- func (self *FileSystemUsage) Get(path string) error {
- stat := syscall.Statfs_t{}
- err := syscall.Statfs(path, &stat)
- if err != nil {
- return err
- }
- self.Total = uint64(stat.F_blocks) * uint64(stat.F_bsize)
- self.Free = uint64(stat.F_bfree) * uint64(stat.F_bsize)
- self.Avail = uint64(stat.F_bavail) * uint64(stat.F_bsize)
- self.Used = self.Total - self.Free
- self.Files = stat.F_files
- self.FreeFiles = stat.F_ffree
- return nil
- }
- func (self *FDUsage) Get() error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func (self *LoadAverage) Get() error {
- avg := []C.double{0, 0, 0}
- C.getloadavg(&avg[0], C.int(len(avg)))
- self.One = float64(avg[0])
- self.Five = float64(avg[1])
- self.Fifteen = float64(avg[2])
- return nil
- }
- func (self *Uptime) Get() error {
- tv := syscall.Timeval{}
- mib := [2]int32{C.CTL_KERN, C.KERN_BOOTTIME}
- n := uintptr(0)
- // First we determine how much memory we'll need to pass later on (via `n`)
- _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- // Now perform the actual sysctl(3) call, storing the result in tv
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&tv)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
- return nil
- }
- func (self *Mem) Get() error {
- n := uintptr(0)
- var uvmexp Uvmexp
- mib := [2]int32{C.CTL_VM, C.VM_UVMEXP}
- n = uintptr(0)
- // First we determine how much memory we'll need to pass later on (via `n`)
- _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- var bcachestats Bcachestats
- mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT}
- n = uintptr(0)
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- self.Total = uint64(uvmexp.npages) << uvmexp.pageshift
- self.Used = uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift
- self.Free = uint64(uvmexp.free) << uvmexp.pageshift
- self.ActualFree = self.Free + (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
- self.ActualUsed = self.Used - (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
- return nil
- }
- func (self *Swap) Get() error {
- nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0)
- // If there are no swap devices, nothing to do here.
- if nswap == 0 {
- return nil
- }
- swdev := make([]Swapent, nswap)
- rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap)
- if rnswap == 0 {
- return nil
- }
- for i := 0; i < int(nswap); i++ {
- if swdev[i].se_flags&C.SWF_ENABLE == 2 {
- self.Used = self.Used + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE))
- self.Total = self.Total + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE))
- }
- }
- self.Free = self.Total - self.Used
- return nil
- }
- func (self *HugeTLBPages) Get() error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func (self *Cpu) Get() error {
- load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
- mib := [2]int32{C.CTL_KERN, C.KERN_CPTIME}
- n := uintptr(0)
- // First we determine how much memory we'll need to pass later on (via `n`)
- _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&load)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- self.User = uint64(load[0])
- self.Nice = uint64(load[1])
- self.Sys = uint64(load[2])
- self.Irq = uint64(load[3])
- self.Idle = uint64(load[4])
- return nil
- }
- func (self *CpuList) Get() error {
- mib := [2]int32{C.CTL_HW, C.HW_NCPU}
- var ncpu int
- n := uintptr(0)
- // First we determine how much memory we'll need to pass later on (via `n`)
- _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- // Now perform the actual sysctl(3) call, storing the result in ncpu
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
- self.List = make([]Cpu, ncpu)
- for curcpu := range self.List {
- sysctlCptime(ncpu, curcpu, &load)
- fillCpu(&self.List[curcpu], load)
- }
- return nil
- }
- func (self *ProcList) Get() error {
- return nil
- }
- func (self *ProcArgs) Get(pid int) error {
- return nil
- }
- func (self *ProcEnv) Get(pid int) error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func (self *ProcState) Get(pid int) error {
- return nil
- }
- func (self *ProcMem) Get(pid int) error {
- return nil
- }
- func (self *ProcTime) Get(pid int) error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func (self *ProcExe) Get(pid int) error {
- return nil
- }
- func (self *ProcFDUsage) Get(pid int) error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func (self *Rusage) Get(pid int) error {
- return ErrNotImplemented{runtime.GOOS}
- }
- func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) {
- cpu.User = uint64(load[0])
- cpu.Nice = uint64(load[1])
- cpu.Sys = uint64(load[2])
- cpu.Irq = uint64(load[3])
- cpu.Idle = uint64(load[4])
- }
- func sysctlCptime(ncpu int, curcpu int, load *[C.CPUSTATES]C.long) error {
- var mib []int32
- // Use the correct mib based on the number of CPUs and fill out the
- // current CPU number in case of SMP. (0 indexed cf. self.List)
- if ncpu == 0 {
- mib = []int32{C.CTL_KERN, C.KERN_CPTIME}
- } else {
- mib = []int32{C.CTL_KERN, C.KERN_CPTIME2, int32(curcpu)}
- }
- len := len(mib)
- n := uintptr(0)
- // First we determine how much memory we'll need to pass later on (via `n`)
- _, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), 0, uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- _, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), uintptr(unsafe.Pointer(load)), uintptr(unsafe.Pointer(&n)), 0, 0)
- if errno != 0 || n == 0 {
- return nil
- }
- return nil
- }
|