Get the Docker Engine to build clean on Solaris
Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
This commit is contained in:
parent
d97f6ab5f1
commit
a531a67461
23 changed files with 495 additions and 27 deletions
|
@ -1,4 +1,4 @@
|
||||||
// +build linux freebsd
|
// +build linux freebsd solaris
|
||||||
|
|
||||||
package directory
|
package directory
|
||||||
|
|
||||||
|
|
7
fileutils/fileutils_solaris.go
Normal file
7
fileutils/fileutils_solaris.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
package fileutils
|
||||||
|
|
||||||
|
// GetTotalUsedFds Returns the number of used File Descriptors.
|
||||||
|
// On Solaris these limits are per process and not systemwide
|
||||||
|
func GetTotalUsedFds() int {
|
||||||
|
return -1
|
||||||
|
}
|
31
listeners/listeners_solaris.go
Normal file
31
listeners/listeners_solaris.go
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
package listeners
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/docker/go-connections/sockets"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Init creates new listeners for the server.
|
||||||
|
func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) (ls []net.Listener, err error) {
|
||||||
|
switch proto {
|
||||||
|
case "tcp":
|
||||||
|
l, err := sockets.NewTCPSocket(addr, tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ls = append(ls, l)
|
||||||
|
case "unix":
|
||||||
|
l, err := sockets.NewUnixSocket(addr, socketGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err)
|
||||||
|
}
|
||||||
|
ls = append(ls, l)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid protocol format: %q", proto)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !windows
|
// +build !windows,!solaris
|
||||||
|
|
||||||
package listeners
|
package listeners
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!freebsd freebsd,!cgo
|
// +build !linux,!freebsd freebsd,!cgo solaris,!cgo
|
||||||
|
|
||||||
package mount
|
package mount
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ func GetMounts() ([]*Info, error) {
|
||||||
return parseMountTable()
|
return parseMountTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mounted looks at /proc/self/mountinfo to determine of the specified
|
// Mounted determines if a specified mountpoint has been mounted.
|
||||||
// mountpoint has been mounted
|
// On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab.
|
||||||
func Mounted(mountpoint string) (bool, error) {
|
func Mounted(mountpoint string) (bool, error) {
|
||||||
entries, err := parseMountTable()
|
entries, err := parseMountTable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
33
mount/mounter_solaris.go
Normal file
33
mount/mounter_solaris.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package mount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <stdio.h>
|
||||||
|
// #include <sys/mount.h>
|
||||||
|
// int Mount(const char *spec, const char *dir, int mflag,
|
||||||
|
// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
|
||||||
|
// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen);
|
||||||
|
// }
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func mount(device, target, mType string, flag uintptr, data string) error {
|
||||||
|
spec := C.CString(device)
|
||||||
|
dir := C.CString(target)
|
||||||
|
fstype := C.CString(mType)
|
||||||
|
_, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0)
|
||||||
|
C.free(unsafe.Pointer(spec))
|
||||||
|
C.free(unsafe.Pointer(dir))
|
||||||
|
C.free(unsafe.Pointer(fstype))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmount(target string, flag int) error {
|
||||||
|
err := unix.Unmount(target, flag)
|
||||||
|
return err
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!freebsd freebsd,!cgo
|
// +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
|
||||||
|
|
||||||
package mount
|
package mount
|
||||||
|
|
||||||
|
|
37
mount/mountinfo_solaris.go
Normal file
37
mount/mountinfo_solaris.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package mount
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/mnttab.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseMountTable() ([]*Info, error) {
|
||||||
|
mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
|
||||||
|
if mnttab == nil {
|
||||||
|
return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
|
||||||
|
}
|
||||||
|
|
||||||
|
var out []*Info
|
||||||
|
var mp C.struct_mnttab
|
||||||
|
|
||||||
|
ret := C.getmntent(mnttab, &mp)
|
||||||
|
for ret == 0 {
|
||||||
|
var mountinfo Info
|
||||||
|
mountinfo.Mountpoint = C.GoString(mp.mnt_mountp)
|
||||||
|
mountinfo.Source = C.GoString(mp.mnt_special)
|
||||||
|
mountinfo.Fstype = C.GoString(mp.mnt_fstype)
|
||||||
|
mountinfo.Opts = C.GoString(mp.mnt_mntopts)
|
||||||
|
out = append(out, &mountinfo)
|
||||||
|
ret = C.getmntent(mnttab, &mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
C.fclose(mnttab)
|
||||||
|
return out, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !windows,!linux,!freebsd freebsd,!cgo
|
// +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
|
||||||
|
|
||||||
package mount
|
package mount
|
||||||
|
|
||||||
|
|
14
parsers/kernel/uname_solaris.go
Normal file
14
parsers/kernel/uname_solaris.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func uname() (*unix.Utsname, error) {
|
||||||
|
uts := &unix.Utsname{}
|
||||||
|
|
||||||
|
if err := unix.Uname(uts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return uts, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux
|
// +build !linux,!solaris
|
||||||
|
|
||||||
package kernel
|
package kernel
|
||||||
|
|
||||||
|
|
37
parsers/operatingsystem/operatingsystem_solaris.go
Normal file
37
parsers/operatingsystem/operatingsystem_solaris.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package operatingsystem
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <zone.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
var etcOsRelease = "/etc/release"
|
||||||
|
|
||||||
|
// GetOperatingSystem gets the name of the current operating system.
|
||||||
|
func GetOperatingSystem() (string, error) {
|
||||||
|
b, err := ioutil.ReadFile(etcOsRelease)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if i := bytes.Index(b, []byte("\n")); i >= 0 {
|
||||||
|
b = bytes.Trim(b[:i], " ")
|
||||||
|
return string(b), nil
|
||||||
|
}
|
||||||
|
return "", errors.New("release not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsContainerized returns true if we are running inside a container.
|
||||||
|
func IsContainerized() (bool, error) {
|
||||||
|
if C.getzoneid() != 0 {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
package platform
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
// runtimeArchitecture gets the name of the current architecture (x86, x86_64, …)
|
|
||||||
func runtimeArchitecture() (string, error) {
|
|
||||||
cmd := exec.Command("uname", "-m")
|
|
||||||
machine, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(machine), nil
|
|
||||||
}
|
|
18
platform/architecture_unix.go
Normal file
18
platform/architecture_unix.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// +build freebsd solaris
|
||||||
|
|
||||||
|
package platform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// runtimeArchitecture get the name of the current architecture (i86pc, sun4v)
|
||||||
|
func runtimeArchitecture() (string, error) {
|
||||||
|
cmd := exec.Command("/usr/bin/uname", "-m")
|
||||||
|
machine, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(machine)), nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build freebsd
|
// +build freebsd solaris
|
||||||
|
|
||||||
package reexec
|
package reexec
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!windows,!freebsd
|
// +build !linux,!windows,!freebsd,!solaris
|
||||||
|
|
||||||
package reexec
|
package reexec
|
||||||
|
|
||||||
|
|
42
signal/signal_solaris.go
Normal file
42
signal/signal_solaris.go
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package signal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SignalMap is a map of Solaris signals.
|
||||||
|
// SIGINFO and SIGTHR not defined for Solaris
|
||||||
|
var SignalMap = map[string]syscall.Signal{
|
||||||
|
"ABRT": syscall.SIGABRT,
|
||||||
|
"ALRM": syscall.SIGALRM,
|
||||||
|
"BUF": syscall.SIGBUS,
|
||||||
|
"CHLD": syscall.SIGCHLD,
|
||||||
|
"CONT": syscall.SIGCONT,
|
||||||
|
"EMT": syscall.SIGEMT,
|
||||||
|
"FPE": syscall.SIGFPE,
|
||||||
|
"HUP": syscall.SIGHUP,
|
||||||
|
"ILL": syscall.SIGILL,
|
||||||
|
"INT": syscall.SIGINT,
|
||||||
|
"IO": syscall.SIGIO,
|
||||||
|
"IOT": syscall.SIGIOT,
|
||||||
|
"KILL": syscall.SIGKILL,
|
||||||
|
"LWP": syscall.SIGLWP,
|
||||||
|
"PIPE": syscall.SIGPIPE,
|
||||||
|
"PROF": syscall.SIGPROF,
|
||||||
|
"QUIT": syscall.SIGQUIT,
|
||||||
|
"SEGV": syscall.SIGSEGV,
|
||||||
|
"STOP": syscall.SIGSTOP,
|
||||||
|
"SYS": syscall.SIGSYS,
|
||||||
|
"TERM": syscall.SIGTERM,
|
||||||
|
"TRAP": syscall.SIGTRAP,
|
||||||
|
"TSTP": syscall.SIGTSTP,
|
||||||
|
"TTIN": syscall.SIGTTIN,
|
||||||
|
"TTOU": syscall.SIGTTOU,
|
||||||
|
"URG": syscall.SIGURG,
|
||||||
|
"USR1": syscall.SIGUSR1,
|
||||||
|
"USR2": syscall.SIGUSR2,
|
||||||
|
"VTALRM": syscall.SIGVTALRM,
|
||||||
|
"WINCH": syscall.SIGWINCH,
|
||||||
|
"XCPU": syscall.SIGXCPU,
|
||||||
|
"XFSZ": syscall.SIGXFSZ,
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!darwin,!freebsd,!windows
|
// +build !linux,!darwin,!freebsd,!windows,!solaris
|
||||||
|
|
||||||
package signal
|
package signal
|
||||||
|
|
||||||
|
|
119
sysinfo/sysinfo_solaris.go
Normal file
119
sysinfo/sysinfo_solaris.go
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package sysinfo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo LDFLAGS: -llgrp
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/lgrp_user.h>
|
||||||
|
int getLgrpCount() {
|
||||||
|
lgrp_cookie_t lgrpcookie = LGRP_COOKIE_NONE;
|
||||||
|
uint_t nlgrps;
|
||||||
|
|
||||||
|
if ((lgrpcookie = lgrp_init(LGRP_VIEW_OS)) == LGRP_COOKIE_NONE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
nlgrps = lgrp_nlgrps(lgrpcookie);
|
||||||
|
return nlgrps;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// IsCPUSharesAvailable returns whether CPUShares setting is supported.
|
||||||
|
// We need FSS to be set as default scheduling class to support CPU Shares
|
||||||
|
func IsCPUSharesAvailable() bool {
|
||||||
|
cmd := exec.Command("/usr/sbin/dispadmin", "-d")
|
||||||
|
outBuf := new(bytes.Buffer)
|
||||||
|
errBuf := new(bytes.Buffer)
|
||||||
|
cmd.Stderr = errBuf
|
||||||
|
cmd.Stdout = outBuf
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (strings.Contains(outBuf.String(), "FSS"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new SysInfo, using the filesystem to detect which features
|
||||||
|
// the kernel supports.
|
||||||
|
//NOTE Solaris: If we change the below capabilities be sure
|
||||||
|
// to update verifyPlatformContainerSettings() in daemon_solaris.go
|
||||||
|
func New(quiet bool) *SysInfo {
|
||||||
|
sysInfo := &SysInfo{}
|
||||||
|
sysInfo.cgroupMemInfo = setCgroupMem(quiet)
|
||||||
|
sysInfo.cgroupCPUInfo = setCgroupCPU(quiet)
|
||||||
|
sysInfo.cgroupBlkioInfo = setCgroupBlkioInfo(quiet)
|
||||||
|
sysInfo.cgroupCpusetInfo = setCgroupCPUsetInfo(quiet)
|
||||||
|
|
||||||
|
sysInfo.IPv4ForwardingDisabled = false
|
||||||
|
|
||||||
|
sysInfo.AppArmor = false
|
||||||
|
|
||||||
|
return sysInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// setCgroupMem reads the memory information for Solaris.
|
||||||
|
func setCgroupMem(quiet bool) cgroupMemInfo {
|
||||||
|
|
||||||
|
return cgroupMemInfo{
|
||||||
|
MemoryLimit: true,
|
||||||
|
SwapLimit: true,
|
||||||
|
MemoryReservation: false,
|
||||||
|
OomKillDisable: false,
|
||||||
|
MemorySwappiness: false,
|
||||||
|
KernelMemory: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setCgroupCPU reads the cpu information for Solaris.
|
||||||
|
func setCgroupCPU(quiet bool) cgroupCPUInfo {
|
||||||
|
|
||||||
|
return cgroupCPUInfo{
|
||||||
|
CPUShares: true,
|
||||||
|
CPUCfsPeriod: false,
|
||||||
|
CPUCfsQuota: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// blkio switches are not supported in Solaris.
|
||||||
|
func setCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
|
||||||
|
|
||||||
|
return cgroupBlkioInfo{
|
||||||
|
BlkioWeight: false,
|
||||||
|
BlkioWeightDevice: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setCgroupCPUsetInfo reads the cpuset information for Solaris.
|
||||||
|
func setCgroupCPUsetInfo(quiet bool) cgroupCpusetInfo {
|
||||||
|
|
||||||
|
return cgroupCpusetInfo{
|
||||||
|
Cpuset: true,
|
||||||
|
Cpus: getCPUCount(),
|
||||||
|
Mems: getLgrpCount(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCPUCount() string {
|
||||||
|
ncpus := C.sysconf(C._SC_NPROCESSORS_ONLN)
|
||||||
|
if ncpus <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.FormatInt(int64(ncpus), 16)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLgrpCount() string {
|
||||||
|
nlgrps := C.getLgrpCount()
|
||||||
|
if nlgrps <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strconv.FormatInt(int64(nlgrps), 16)
|
||||||
|
}
|
128
system/meminfo_solaris.go
Normal file
128
system/meminfo_solaris.go
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// #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("Error getting system memory info %v\n", 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
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// +build !linux,!windows
|
// +build !linux,!windows,!solaris
|
||||||
|
|
||||||
package system
|
package system
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,20 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
rdev: uint64(s.Rdev),
|
rdev: uint64(s.Rdev),
|
||||||
mtim: s.Mtim}, nil
|
mtim: s.Mtim}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromStatT loads a system.StatT from a syscal.Stat_t.
|
||||||
|
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return fromStatT(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat takes a path to a file and returns
|
||||||
|
// a system.StatT type pertaining to that file.
|
||||||
|
//
|
||||||
|
// Throws an error if the file does not exist
|
||||||
|
func Stat(path string) (*StatT, error) {
|
||||||
|
s := &syscall.Stat_t{}
|
||||||
|
if err := syscall.Stat(path, s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fromStatT(s)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue