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