File: meminfo_solaris.go

package info (click to toggle)
golang-github-containers-storage 1.43.0%2Bds1-8
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,820 kB
  • sloc: sh: 581; ansic: 388; makefile: 164; awk: 12
file content (130 lines) | stat: -rw-r--r-- 3,251 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//go:build solaris && cgo
// +build solaris,cgo

package system

import (
	"fmt"
	"unsafe"
)

// #cgo CFLAGS: -std=c99
// #cgo LDFLAGS: -lkstat
// #include <unistd.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <kstat.h>
// #include <sys/swap.h>
// #include <sys/param.h>
// struct swaptable *allocSwaptable(int num) {
//	struct swaptable *st;
//	struct swapent *swapent;
// 	st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
//	swapent = st->swt_ent;
//	for (int i = 0; i < num; i++,swapent++) {
//		swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
//	}
//	st->swt_n = num;
//	return st;
//}
// void freeSwaptable (struct swaptable *st) {
//	struct swapent *swapent = st->swt_ent;
//	for (int i = 0; i < st->swt_n; i++,swapent++) {
//		free(swapent->ste_path);
//	}
//	free(st);
// }
// swapent_t getSwapEnt(swapent_t *ent, int i) {
//	return ent[i];
// }
// int64_t getPpKernel() {
//	int64_t pp_kernel = 0;
//	kstat_ctl_t *ksc;
//	kstat_t *ks;
//	kstat_named_t *knp;
//	kid_t kid;
//
//	if ((ksc = kstat_open()) == NULL) {
//		return -1;
//	}
//	if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
//		return -1;
//	}
//	if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
//	    ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
//		return -1;
//	}
//	switch (knp->data_type) {
//	case KSTAT_DATA_UINT64:
//		pp_kernel = knp->value.ui64;
//		break;
//	case KSTAT_DATA_UINT32:
//		pp_kernel = knp->value.ui32;
//		break;
//	}
//	pp_kernel *= sysconf(_SC_PAGESIZE);
//	return (pp_kernel > 0 ? pp_kernel : -1);
// }
import "C"

// Get the system memory info using sysconf same as prtconf
func getTotalMem() int64 {
	pagesize := C.sysconf(C._SC_PAGESIZE)
	npages := C.sysconf(C._SC_PHYS_PAGES)
	return int64(pagesize * npages)
}

func getFreeMem() int64 {
	pagesize := C.sysconf(C._SC_PAGESIZE)
	npages := C.sysconf(C._SC_AVPHYS_PAGES)
	return int64(pagesize * npages)
}

// ReadMemInfo retrieves memory statistics of the host system and returns a
//  MemInfo type.
func ReadMemInfo() (*MemInfo, error) {

	ppKernel := C.getPpKernel()
	MemTotal := getTotalMem()
	MemFree := getFreeMem()
	SwapTotal, SwapFree, err := getSysSwap()

	if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
		SwapFree < 0 {
		return nil, fmt.Errorf("getting system memory info %w", err)
	}

	meminfo := &MemInfo{}
	// Total memory is total physical memory less than memory locked by kernel
	meminfo.MemTotal = MemTotal - int64(ppKernel)
	meminfo.MemFree = MemFree
	meminfo.SwapTotal = SwapTotal
	meminfo.SwapFree = SwapFree

	return meminfo, nil
}

func getSysSwap() (int64, int64, error) {
	var tSwap int64
	var fSwap int64
	var diskblksPerPage int64
	num, err := C.swapctl(C.SC_GETNSWP, nil)
	if err != nil {
		return -1, -1, err
	}
	st := C.allocSwaptable(num)
	_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
	if err != nil {
		C.freeSwaptable(st)
		return -1, -1, err
	}

	diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
	for i := 0; i < int(num); i++ {
		swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
		tSwap += int64(swapent.ste_pages) * diskblksPerPage
		fSwap += int64(swapent.ste_free) * diskblksPerPage
	}
	C.freeSwaptable(st)
	return tSwap, fSwap, nil
}