github.com/cdoern/storage@v1.12.13/pkg/system/meminfo_solaris.go (about) 1 // +build solaris,cgo 2 3 package system 4 5 import ( 6 "fmt" 7 "unsafe" 8 ) 9 10 // #cgo CFLAGS: -std=c99 11 // #cgo LDFLAGS: -lkstat 12 // #include <unistd.h> 13 // #include <stdlib.h> 14 // #include <stdio.h> 15 // #include <kstat.h> 16 // #include <sys/swap.h> 17 // #include <sys/param.h> 18 // struct swaptable *allocSwaptable(int num) { 19 // struct swaptable *st; 20 // struct swapent *swapent; 21 // st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int)); 22 // swapent = st->swt_ent; 23 // for (int i = 0; i < num; i++,swapent++) { 24 // swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char)); 25 // } 26 // st->swt_n = num; 27 // return st; 28 //} 29 // void freeSwaptable (struct swaptable *st) { 30 // struct swapent *swapent = st->swt_ent; 31 // for (int i = 0; i < st->swt_n; i++,swapent++) { 32 // free(swapent->ste_path); 33 // } 34 // free(st); 35 // } 36 // swapent_t getSwapEnt(swapent_t *ent, int i) { 37 // return ent[i]; 38 // } 39 // int64_t getPpKernel() { 40 // int64_t pp_kernel = 0; 41 // kstat_ctl_t *ksc; 42 // kstat_t *ks; 43 // kstat_named_t *knp; 44 // kid_t kid; 45 // 46 // if ((ksc = kstat_open()) == NULL) { 47 // return -1; 48 // } 49 // if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) { 50 // return -1; 51 // } 52 // if (((kid = kstat_read(ksc, ks, NULL)) == -1) || 53 // ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) { 54 // return -1; 55 // } 56 // switch (knp->data_type) { 57 // case KSTAT_DATA_UINT64: 58 // pp_kernel = knp->value.ui64; 59 // break; 60 // case KSTAT_DATA_UINT32: 61 // pp_kernel = knp->value.ui32; 62 // break; 63 // } 64 // pp_kernel *= sysconf(_SC_PAGESIZE); 65 // return (pp_kernel > 0 ? pp_kernel : -1); 66 // } 67 import "C" 68 69 // Get the system memory info using sysconf same as prtconf 70 func getTotalMem() int64 { 71 pagesize := C.sysconf(C._SC_PAGESIZE) 72 npages := C.sysconf(C._SC_PHYS_PAGES) 73 return int64(pagesize * npages) 74 } 75 76 func getFreeMem() int64 { 77 pagesize := C.sysconf(C._SC_PAGESIZE) 78 npages := C.sysconf(C._SC_AVPHYS_PAGES) 79 return int64(pagesize * npages) 80 } 81 82 // ReadMemInfo retrieves memory statistics of the host system and returns a 83 // MemInfo type. 84 func ReadMemInfo() (*MemInfo, error) { 85 86 ppKernel := C.getPpKernel() 87 MemTotal := getTotalMem() 88 MemFree := getFreeMem() 89 SwapTotal, SwapFree, err := getSysSwap() 90 91 if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 || 92 SwapFree < 0 { 93 return nil, fmt.Errorf("error getting system memory info %v\n", err) 94 } 95 96 meminfo := &MemInfo{} 97 // Total memory is total physical memory less than memory locked by kernel 98 meminfo.MemTotal = MemTotal - int64(ppKernel) 99 meminfo.MemFree = MemFree 100 meminfo.SwapTotal = SwapTotal 101 meminfo.SwapFree = SwapFree 102 103 return meminfo, nil 104 } 105 106 func getSysSwap() (int64, int64, error) { 107 var tSwap int64 108 var fSwap int64 109 var diskblksPerPage int64 110 num, err := C.swapctl(C.SC_GETNSWP, nil) 111 if err != nil { 112 return -1, -1, err 113 } 114 st := C.allocSwaptable(num) 115 _, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st)) 116 if err != nil { 117 C.freeSwaptable(st) 118 return -1, -1, err 119 } 120 121 diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT) 122 for i := 0; i < int(num); i++ { 123 swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i)) 124 tSwap += int64(swapent.ste_pages) * diskblksPerPage 125 fSwap += int64(swapent.ste_free) * diskblksPerPage 126 } 127 C.freeSwaptable(st) 128 return tSwap, fSwap, nil 129 }