github.com/brahmaroutu/docker@v1.2.1-0.20160809185609-eb28dde01f16/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  }