mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 18:37:45 +08:00
system diagnostics command
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
This commit is contained in:
parent
b910d8ad0b
commit
11104d401e
15
Godeps/Godeps.json
generated
15
Godeps/Godeps.json
generated
@ -286,6 +286,21 @@
|
||||
"ImportPath": "github.com/satori/go.uuid",
|
||||
"Rev": "7c7f2020c4c9491594b85767967f4619c2fa75f9"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/common",
|
||||
"Comment": "1.0.0-167-g6a274c3",
|
||||
"Rev": "6a274c3628382ab316340478300f5282b89f7778"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/disk",
|
||||
"Comment": "1.0.0-167-g6a274c3",
|
||||
"Rev": "6a274c3628382ab316340478300f5282b89f7778"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/mem",
|
||||
"Comment": "1.0.0-167-g6a274c3",
|
||||
"Rev": "6a274c3628382ab316340478300f5282b89f7778"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/steakknife/hamming",
|
||||
"Comment": "0.0.10",
|
||||
|
||||
209
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common.go
generated
vendored
Normal file
209
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common.go
generated
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
//
|
||||
// gopsutil is a port of psutil(http://pythonhosted.org/psutil/).
|
||||
// This covers these architectures.
|
||||
// - linux (amd64, arm)
|
||||
// - freebsd (amd64)
|
||||
// - windows (amd64)
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Invoker interface {
|
||||
Command(string, ...string) ([]byte, error)
|
||||
}
|
||||
|
||||
type Invoke struct{}
|
||||
|
||||
func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
|
||||
return exec.Command(name, arg...).Output()
|
||||
}
|
||||
|
||||
type FakeInvoke struct {
|
||||
CommandExpectedDir string // CommandExpectedDir specifies dir which includes expected outputs.
|
||||
Suffix string // Suffix species expected file name suffix such as "fail"
|
||||
Error error // If Error specfied, return the error.
|
||||
}
|
||||
|
||||
// Command in FakeInvoke returns from expected file if exists.
|
||||
func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
|
||||
if i.Error != nil {
|
||||
return []byte{}, i.Error
|
||||
}
|
||||
|
||||
arch := runtime.GOOS
|
||||
|
||||
fname := strings.Join(append([]string{name}, arg...), "")
|
||||
fname = url.QueryEscape(fname)
|
||||
var dir string
|
||||
if i.CommandExpectedDir == "" {
|
||||
dir = "expected"
|
||||
} else {
|
||||
dir = i.CommandExpectedDir
|
||||
}
|
||||
fpath := path.Join(dir, arch, fname)
|
||||
if i.Suffix != "" {
|
||||
fpath += "_" + i.Suffix
|
||||
}
|
||||
if PathExists(fpath) {
|
||||
return ioutil.ReadFile(fpath)
|
||||
} else {
|
||||
return exec.Command(name, arg...).Output()
|
||||
}
|
||||
}
|
||||
|
||||
var NotImplementedError = errors.New("not implemented yet")
|
||||
|
||||
// ReadLines reads contents from a file and splits them by new lines.
|
||||
// A convenience wrapper to ReadLinesOffsetN(filename, 0, -1).
|
||||
func ReadLines(filename string) ([]string, error) {
|
||||
return ReadLinesOffsetN(filename, 0, -1)
|
||||
}
|
||||
|
||||
// ReadLines reads contents from file and splits them by new line.
|
||||
// The offset tells at which line number to start.
|
||||
// The count determines the number of lines to read (starting from offset):
|
||||
// n >= 0: at most n lines
|
||||
// n < 0: whole file
|
||||
func ReadLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return []string{""}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var ret []string
|
||||
|
||||
r := bufio.NewReader(f)
|
||||
for i := 0; i < n+int(offset) || n < 0; i++ {
|
||||
line, err := r.ReadString('\n')
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if i < int(offset) {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, strings.Trim(line, "\n"))
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func IntToString(orig []int8) string {
|
||||
ret := make([]byte, len(orig))
|
||||
size := -1
|
||||
for i, o := range orig {
|
||||
if o == 0 {
|
||||
size = i
|
||||
break
|
||||
}
|
||||
ret[i] = byte(o)
|
||||
}
|
||||
if size == -1 {
|
||||
size = len(orig)
|
||||
}
|
||||
|
||||
return string(ret[0:size])
|
||||
}
|
||||
|
||||
func ByteToString(orig []byte) string {
|
||||
n := -1
|
||||
l := -1
|
||||
for i, b := range orig {
|
||||
// skip left side null
|
||||
if l == -1 && b == 0 {
|
||||
continue
|
||||
}
|
||||
if l == -1 {
|
||||
l = i
|
||||
}
|
||||
|
||||
if b == 0 {
|
||||
break
|
||||
}
|
||||
n = i + 1
|
||||
}
|
||||
if n == -1 {
|
||||
return string(orig)
|
||||
}
|
||||
return string(orig[l:n])
|
||||
}
|
||||
|
||||
// Parse to int32 without error
|
||||
func mustParseInt32(val string) int32 {
|
||||
vv, _ := strconv.ParseInt(val, 10, 32)
|
||||
return int32(vv)
|
||||
}
|
||||
|
||||
// Parse to uint64 without error
|
||||
func mustParseUint64(val string) uint64 {
|
||||
vv, _ := strconv.ParseInt(val, 10, 64)
|
||||
return uint64(vv)
|
||||
}
|
||||
|
||||
// Parse to Float64 without error
|
||||
func mustParseFloat64(val string) float64 {
|
||||
vv, _ := strconv.ParseFloat(val, 64)
|
||||
return vv
|
||||
}
|
||||
|
||||
// StringsHas checks the target string slice containes src or not
|
||||
func StringsHas(target []string, src string) bool {
|
||||
for _, t := range target {
|
||||
if strings.TrimSpace(t) == src {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// StringsContains checks the src in any string of the target string slice
|
||||
func StringsContains(target []string, src string) bool {
|
||||
for _, t := range target {
|
||||
if strings.Contains(t, src) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// get struct attributes.
|
||||
// This method is used only for debugging platform dependent code.
|
||||
func attributes(m interface{}) map[string]reflect.Type {
|
||||
typ := reflect.TypeOf(m)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
|
||||
attrs := make(map[string]reflect.Type)
|
||||
if typ.Kind() != reflect.Struct {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
p := typ.Field(i)
|
||||
if !p.Anonymous {
|
||||
attrs[p.Name] = p.Type
|
||||
}
|
||||
}
|
||||
|
||||
return attrs
|
||||
}
|
||||
|
||||
func PathExists(filename string) bool {
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
60
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_darwin.go
generated
vendored
Normal file
60
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_darwin.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// +build darwin
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
out, err := exec.Command("/usr/sbin/sysctl", "-n", mib).Output()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
v := strings.Replace(string(out), "{ ", "", 1)
|
||||
v = strings.Replace(string(v), " }", "", 1)
|
||||
values := strings.Fields(string(v))
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
||||
miblen := uint64(len(mib))
|
||||
|
||||
// get required buffer size
|
||||
length := uint64(0)
|
||||
_, _, err := syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(unsafe.Pointer(&mib[0])),
|
||||
uintptr(miblen),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&length)),
|
||||
0,
|
||||
0)
|
||||
if err != 0 {
|
||||
var b []byte
|
||||
return b, length, err
|
||||
}
|
||||
if length == 0 {
|
||||
var b []byte
|
||||
return b, length, err
|
||||
}
|
||||
// get proc info itself
|
||||
buf := make([]byte, length)
|
||||
_, _, err = syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(unsafe.Pointer(&mib[0])),
|
||||
uintptr(miblen),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(&length)),
|
||||
0,
|
||||
0)
|
||||
if err != 0 {
|
||||
return buf, length, err
|
||||
}
|
||||
|
||||
return buf, length, nil
|
||||
}
|
||||
60
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_freebsd.go
generated
vendored
Normal file
60
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// +build freebsd
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func DoSysctrl(mib string) ([]string, error) {
|
||||
out, err := exec.Command("/sbin/sysctl", "-n", mib).Output()
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
v := strings.Replace(string(out), "{ ", "", 1)
|
||||
v = strings.Replace(string(v), " }", "", 1)
|
||||
values := strings.Fields(string(v))
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func CallSyscall(mib []int32) ([]byte, uint64, error) {
|
||||
miblen := uint64(len(mib))
|
||||
|
||||
// get required buffer size
|
||||
length := uint64(0)
|
||||
_, _, err := syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(unsafe.Pointer(&mib[0])),
|
||||
uintptr(miblen),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&length)),
|
||||
0,
|
||||
0)
|
||||
if err != 0 {
|
||||
var b []byte
|
||||
return b, length, err
|
||||
}
|
||||
if length == 0 {
|
||||
var b []byte
|
||||
return b, length, err
|
||||
}
|
||||
// get proc info itself
|
||||
buf := make([]byte, length)
|
||||
_, _, err = syscall.Syscall6(
|
||||
syscall.SYS___SYSCTL,
|
||||
uintptr(unsafe.Pointer(&mib[0])),
|
||||
uintptr(miblen),
|
||||
uintptr(unsafe.Pointer(&buf[0])),
|
||||
uintptr(unsafe.Pointer(&length)),
|
||||
0,
|
||||
0)
|
||||
if err != 0 {
|
||||
return buf, length, err
|
||||
}
|
||||
|
||||
return buf, length, nil
|
||||
}
|
||||
3
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_linux.go
generated
vendored
Normal file
3
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_linux.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// +build linux
|
||||
|
||||
package common
|
||||
90
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_test.go
generated
vendored
Normal file
90
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_test.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReadlines(t *testing.T) {
|
||||
ret, err := ReadLines("common_test.go")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !strings.Contains(ret[0], "package common") {
|
||||
t.Error("could not read correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadLinesOffsetN(t *testing.T) {
|
||||
ret, err := ReadLinesOffsetN("common_test.go", 2, 1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(ret[0])
|
||||
if !strings.Contains(ret[0], `import (`) {
|
||||
t.Error("could not read correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntToString(t *testing.T) {
|
||||
src := []int8{65, 66, 67}
|
||||
dst := IntToString(src)
|
||||
if dst != "ABC" {
|
||||
t.Error("could not convert")
|
||||
}
|
||||
}
|
||||
func TestByteToString(t *testing.T) {
|
||||
src := []byte{65, 66, 67}
|
||||
dst := ByteToString(src)
|
||||
if dst != "ABC" {
|
||||
t.Error("could not convert")
|
||||
}
|
||||
|
||||
src = []byte{0, 65, 66, 67}
|
||||
dst = ByteToString(src)
|
||||
if dst != "ABC" {
|
||||
t.Error("could not convert")
|
||||
}
|
||||
}
|
||||
|
||||
func TestmustParseInt32(t *testing.T) {
|
||||
ret := mustParseInt32("11111")
|
||||
if ret != int32(11111) {
|
||||
t.Error("could not parse")
|
||||
}
|
||||
}
|
||||
func TestmustParseUint64(t *testing.T) {
|
||||
ret := mustParseUint64("11111")
|
||||
if ret != uint64(11111) {
|
||||
t.Error("could not parse")
|
||||
}
|
||||
}
|
||||
func TestmustParseFloat64(t *testing.T) {
|
||||
ret := mustParseFloat64("11111.11")
|
||||
if ret != float64(11111.11) {
|
||||
t.Error("could not parse")
|
||||
}
|
||||
ret = mustParseFloat64("11111")
|
||||
if ret != float64(11111) {
|
||||
t.Error("could not parse")
|
||||
}
|
||||
}
|
||||
func TestStringsContains(t *testing.T) {
|
||||
target, err := ReadLines("common_test.go")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !StringsContains(target, "func TestStringsContains(t *testing.T) {") {
|
||||
t.Error("cloud not test correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathExists(t *testing.T) {
|
||||
if !PathExists("common_test.go") {
|
||||
t.Error("exists but return not exists")
|
||||
}
|
||||
if PathExists("should_not_exists.go") {
|
||||
t.Error("not exists but return exists")
|
||||
}
|
||||
}
|
||||
40
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_unix.go
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_unix.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
// +build linux freebsd darwin
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CallLsof(invoke Invoker, pid int32, args ...string) ([]string, error) {
|
||||
var cmd []string
|
||||
if pid == 0 { // will get from all processes.
|
||||
cmd = []string{"-a", "-n", "-P"}
|
||||
} else {
|
||||
cmd = []string{"-a", "-n", "-P", "-p", strconv.Itoa(int(pid))}
|
||||
}
|
||||
cmd = append(cmd, args...)
|
||||
lsof, err := exec.LookPath("lsof")
|
||||
if err != nil {
|
||||
return []string{}, err
|
||||
}
|
||||
out, err := invoke.Command(lsof, cmd...)
|
||||
if err != nil {
|
||||
// if no pid found, lsof returnes code 1.
|
||||
if err.Error() == "exit status 1" && len(out) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
|
||||
var ret []string
|
||||
for _, l := range lines[1:] {
|
||||
if len(l) == 0 {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, l)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
110
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_windows.go
generated
vendored
Normal file
110
Godeps/_workspace/src/github.com/shirou/gopsutil/common/common_windows.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
// +build windows
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// for double values
|
||||
type PDH_FMT_COUNTERVALUE_DOUBLE struct {
|
||||
CStatus uint32
|
||||
DoubleValue float64
|
||||
}
|
||||
|
||||
// for 64 bit integer values
|
||||
type PDH_FMT_COUNTERVALUE_LARGE struct {
|
||||
CStatus uint32
|
||||
LargeValue int64
|
||||
}
|
||||
|
||||
// for long values
|
||||
type PDH_FMT_COUNTERVALUE_LONG struct {
|
||||
CStatus uint32
|
||||
LongValue int32
|
||||
padding [4]byte
|
||||
}
|
||||
|
||||
// windows system const
|
||||
const (
|
||||
ERROR_SUCCESS = 0
|
||||
ERROR_FILE_NOT_FOUND = 2
|
||||
DRIVE_REMOVABLE = 2
|
||||
DRIVE_FIXED = 3
|
||||
HKEY_LOCAL_MACHINE = 0x80000002
|
||||
RRF_RT_REG_SZ = 0x00000002
|
||||
RRF_RT_REG_DWORD = 0x00000010
|
||||
PDH_FMT_LONG = 0x00000100
|
||||
PDH_FMT_DOUBLE = 0x00000200
|
||||
PDH_FMT_LARGE = 0x00000400
|
||||
PDH_INVALID_DATA = 0xc0000bc6
|
||||
PDH_INVALID_HANDLE = 0xC0000bbc
|
||||
PDH_NO_DATA = 0x800007d5
|
||||
)
|
||||
|
||||
var (
|
||||
Modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
ModNt = syscall.NewLazyDLL("ntdll.dll")
|
||||
ModPdh = syscall.NewLazyDLL("pdh.dll")
|
||||
|
||||
ProcGetSystemTimes = Modkernel32.NewProc("GetSystemTimes")
|
||||
ProcNtQuerySystemInformation = ModNt.NewProc("NtQuerySystemInformation")
|
||||
PdhOpenQuery = ModPdh.NewProc("PdhOpenQuery")
|
||||
PdhAddCounter = ModPdh.NewProc("PdhAddCounterW")
|
||||
PdhCollectQueryData = ModPdh.NewProc("PdhCollectQueryData")
|
||||
PdhGetFormattedCounterValue = ModPdh.NewProc("PdhGetFormattedCounterValue")
|
||||
PdhCloseQuery = ModPdh.NewProc("PdhCloseQuery")
|
||||
)
|
||||
|
||||
type FILETIME struct {
|
||||
DwLowDateTime uint32
|
||||
DwHighDateTime uint32
|
||||
}
|
||||
|
||||
// borrowed from net/interface_windows.go
|
||||
func BytePtrToString(p *uint8) string {
|
||||
a := (*[10000]uint8)(unsafe.Pointer(p))
|
||||
i := 0
|
||||
for a[i] != 0 {
|
||||
i++
|
||||
}
|
||||
return string(a[:i])
|
||||
}
|
||||
|
||||
// CounterInfo
|
||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||
type CounterInfo struct {
|
||||
PostName string
|
||||
CounterName string
|
||||
Counter syscall.Handle
|
||||
}
|
||||
|
||||
// CreateQuery XXX
|
||||
// copied from https://github.com/mackerelio/mackerel-agent/
|
||||
func CreateQuery() (syscall.Handle, error) {
|
||||
var query syscall.Handle
|
||||
r, _, err := PdhOpenQuery.Call(0, 0, uintptr(unsafe.Pointer(&query)))
|
||||
if r != 0 {
|
||||
return 0, err
|
||||
}
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// CreateCounter XXX
|
||||
func CreateCounter(query syscall.Handle, pname, cname string) (*CounterInfo, error) {
|
||||
var counter syscall.Handle
|
||||
r, _, err := PdhAddCounter.Call(
|
||||
uintptr(query),
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cname))),
|
||||
0,
|
||||
uintptr(unsafe.Pointer(&counter)))
|
||||
if r != 0 {
|
||||
return nil, err
|
||||
}
|
||||
return &CounterInfo{
|
||||
PostName: pname,
|
||||
CounterName: cname,
|
||||
Counter: counter,
|
||||
}, nil
|
||||
}
|
||||
634
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/binary.go
generated
vendored
Normal file
634
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/binary.go
generated
vendored
Normal file
@ -0,0 +1,634 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package binary implements simple translation between numbers and byte
|
||||
// sequences and encoding and decoding of varints.
|
||||
//
|
||||
// Numbers are translated by reading and writing fixed-size values.
|
||||
// A fixed-size value is either a fixed-size arithmetic
|
||||
// type (int8, uint8, int16, float32, complex64, ...)
|
||||
// or an array or struct containing only fixed-size values.
|
||||
//
|
||||
// The varint functions encode and decode single integer values using
|
||||
// a variable-length encoding; smaller values require fewer bytes.
|
||||
// For a specification, see
|
||||
// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
|
||||
//
|
||||
// This package favors simplicity over efficiency. Clients that require
|
||||
// high-performance serialization, especially for large data structures,
|
||||
// should look at more advanced solutions such as the encoding/gob
|
||||
// package or protocol buffers.
|
||||
package disk
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// A ByteOrder specifies how to convert byte sequences into
|
||||
// 16-, 32-, or 64-bit unsigned integers.
|
||||
type ByteOrder interface {
|
||||
Uint16([]byte) uint16
|
||||
Uint32([]byte) uint32
|
||||
Uint64([]byte) uint64
|
||||
PutUint16([]byte, uint16)
|
||||
PutUint32([]byte, uint32)
|
||||
PutUint64([]byte, uint64)
|
||||
String() string
|
||||
}
|
||||
|
||||
// LittleEndian is the little-endian implementation of ByteOrder.
|
||||
var LittleEndian littleEndian
|
||||
|
||||
// BigEndian is the big-endian implementation of ByteOrder.
|
||||
var BigEndian bigEndian
|
||||
|
||||
type littleEndian struct{}
|
||||
|
||||
func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
|
||||
|
||||
func (littleEndian) PutUint16(b []byte, v uint16) {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
}
|
||||
|
||||
func (littleEndian) Uint32(b []byte) uint32 {
|
||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||
}
|
||||
|
||||
func (littleEndian) PutUint32(b []byte, v uint32) {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v >> 16)
|
||||
b[3] = byte(v >> 24)
|
||||
}
|
||||
|
||||
func (littleEndian) Uint64(b []byte) uint64 {
|
||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||
}
|
||||
|
||||
func (littleEndian) PutUint64(b []byte, v uint64) {
|
||||
b[0] = byte(v)
|
||||
b[1] = byte(v >> 8)
|
||||
b[2] = byte(v >> 16)
|
||||
b[3] = byte(v >> 24)
|
||||
b[4] = byte(v >> 32)
|
||||
b[5] = byte(v >> 40)
|
||||
b[6] = byte(v >> 48)
|
||||
b[7] = byte(v >> 56)
|
||||
}
|
||||
|
||||
func (littleEndian) String() string { return "LittleEndian" }
|
||||
|
||||
func (littleEndian) GoString() string { return "binary.LittleEndian" }
|
||||
|
||||
type bigEndian struct{}
|
||||
|
||||
func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
|
||||
|
||||
func (bigEndian) PutUint16(b []byte, v uint16) {
|
||||
b[0] = byte(v >> 8)
|
||||
b[1] = byte(v)
|
||||
}
|
||||
|
||||
func (bigEndian) Uint32(b []byte) uint32 {
|
||||
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||
}
|
||||
|
||||
func (bigEndian) PutUint32(b []byte, v uint32) {
|
||||
b[0] = byte(v >> 24)
|
||||
b[1] = byte(v >> 16)
|
||||
b[2] = byte(v >> 8)
|
||||
b[3] = byte(v)
|
||||
}
|
||||
|
||||
func (bigEndian) Uint64(b []byte) uint64 {
|
||||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||
}
|
||||
|
||||
func (bigEndian) PutUint64(b []byte, v uint64) {
|
||||
b[0] = byte(v >> 56)
|
||||
b[1] = byte(v >> 48)
|
||||
b[2] = byte(v >> 40)
|
||||
b[3] = byte(v >> 32)
|
||||
b[4] = byte(v >> 24)
|
||||
b[5] = byte(v >> 16)
|
||||
b[6] = byte(v >> 8)
|
||||
b[7] = byte(v)
|
||||
}
|
||||
|
||||
func (bigEndian) String() string { return "BigEndian" }
|
||||
|
||||
func (bigEndian) GoString() string { return "binary.BigEndian" }
|
||||
|
||||
// Read reads structured binary data from r into data.
|
||||
// Data must be a pointer to a fixed-size value or a slice
|
||||
// of fixed-size values.
|
||||
// Bytes read from r are decoded using the specified byte order
|
||||
// and written to successive fields of the data.
|
||||
// When reading into structs, the field data for fields with
|
||||
// blank (_) field names is skipped; i.e., blank field names
|
||||
// may be used for padding.
|
||||
// When reading into a struct, all non-blank fields must be exported.
|
||||
func Read(r io.Reader, order ByteOrder, data interface{}) error {
|
||||
// Fast path for basic types and slices.
|
||||
if n := intDataSize(data); n != 0 {
|
||||
var b [8]byte
|
||||
var bs []byte
|
||||
if n > len(b) {
|
||||
bs = make([]byte, n)
|
||||
} else {
|
||||
bs = b[:n]
|
||||
}
|
||||
if _, err := io.ReadFull(r, bs); err != nil {
|
||||
return err
|
||||
}
|
||||
switch data := data.(type) {
|
||||
case *int8:
|
||||
*data = int8(b[0])
|
||||
case *uint8:
|
||||
*data = b[0]
|
||||
case *int16:
|
||||
*data = int16(order.Uint16(bs))
|
||||
case *uint16:
|
||||
*data = order.Uint16(bs)
|
||||
case *int32:
|
||||
*data = int32(order.Uint32(bs))
|
||||
case *uint32:
|
||||
*data = order.Uint32(bs)
|
||||
case *int64:
|
||||
*data = int64(order.Uint64(bs))
|
||||
case *uint64:
|
||||
*data = order.Uint64(bs)
|
||||
case []int8:
|
||||
for i, x := range bs { // Easier to loop over the input for 8-bit values.
|
||||
data[i] = int8(x)
|
||||
}
|
||||
case []uint8:
|
||||
copy(data, bs)
|
||||
case []int16:
|
||||
for i := range data {
|
||||
data[i] = int16(order.Uint16(bs[2*i:]))
|
||||
}
|
||||
case []uint16:
|
||||
for i := range data {
|
||||
data[i] = order.Uint16(bs[2*i:])
|
||||
}
|
||||
case []int32:
|
||||
for i := range data {
|
||||
data[i] = int32(order.Uint32(bs[4*i:]))
|
||||
}
|
||||
case []uint32:
|
||||
for i := range data {
|
||||
data[i] = order.Uint32(bs[4*i:])
|
||||
}
|
||||
case []int64:
|
||||
for i := range data {
|
||||
data[i] = int64(order.Uint64(bs[8*i:]))
|
||||
}
|
||||
case []uint64:
|
||||
for i := range data {
|
||||
data[i] = order.Uint64(bs[8*i:])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fallback to reflect-based decoding.
|
||||
v := reflect.ValueOf(data)
|
||||
size := -1
|
||||
switch v.Kind() {
|
||||
case reflect.Ptr:
|
||||
v = v.Elem()
|
||||
size = dataSize(v)
|
||||
case reflect.Slice:
|
||||
size = dataSize(v)
|
||||
}
|
||||
if size < 0 {
|
||||
return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
|
||||
}
|
||||
d := &decoder{order: order, buf: make([]byte, size)}
|
||||
if _, err := io.ReadFull(r, d.buf); err != nil {
|
||||
return err
|
||||
}
|
||||
d.value(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes the binary representation of data into w.
|
||||
// Data must be a fixed-size value or a slice of fixed-size
|
||||
// values, or a pointer to such data.
|
||||
// Bytes written to w are encoded using the specified byte order
|
||||
// and read from successive fields of the data.
|
||||
// When writing structs, zero values are written for fields
|
||||
// with blank (_) field names.
|
||||
func Write(w io.Writer, order ByteOrder, data interface{}) error {
|
||||
// Fast path for basic types and slices.
|
||||
if n := intDataSize(data); n != 0 {
|
||||
var b [8]byte
|
||||
var bs []byte
|
||||
if n > len(b) {
|
||||
bs = make([]byte, n)
|
||||
} else {
|
||||
bs = b[:n]
|
||||
}
|
||||
switch v := data.(type) {
|
||||
case *int8:
|
||||
bs = b[:1]
|
||||
b[0] = byte(*v)
|
||||
case int8:
|
||||
bs = b[:1]
|
||||
b[0] = byte(v)
|
||||
case []int8:
|
||||
for i, x := range v {
|
||||
bs[i] = byte(x)
|
||||
}
|
||||
case *uint8:
|
||||
bs = b[:1]
|
||||
b[0] = *v
|
||||
case uint8:
|
||||
bs = b[:1]
|
||||
b[0] = byte(v)
|
||||
case []uint8:
|
||||
bs = v
|
||||
case *int16:
|
||||
bs = b[:2]
|
||||
order.PutUint16(bs, uint16(*v))
|
||||
case int16:
|
||||
bs = b[:2]
|
||||
order.PutUint16(bs, uint16(v))
|
||||
case []int16:
|
||||
for i, x := range v {
|
||||
order.PutUint16(bs[2*i:], uint16(x))
|
||||
}
|
||||
case *uint16:
|
||||
bs = b[:2]
|
||||
order.PutUint16(bs, *v)
|
||||
case uint16:
|
||||
bs = b[:2]
|
||||
order.PutUint16(bs, v)
|
||||
case []uint16:
|
||||
for i, x := range v {
|
||||
order.PutUint16(bs[2*i:], x)
|
||||
}
|
||||
case *int32:
|
||||
bs = b[:4]
|
||||
order.PutUint32(bs, uint32(*v))
|
||||
case int32:
|
||||
bs = b[:4]
|
||||
order.PutUint32(bs, uint32(v))
|
||||
case []int32:
|
||||
for i, x := range v {
|
||||
order.PutUint32(bs[4*i:], uint32(x))
|
||||
}
|
||||
case *uint32:
|
||||
bs = b[:4]
|
||||
order.PutUint32(bs, *v)
|
||||
case uint32:
|
||||
bs = b[:4]
|
||||
order.PutUint32(bs, v)
|
||||
case []uint32:
|
||||
for i, x := range v {
|
||||
order.PutUint32(bs[4*i:], x)
|
||||
}
|
||||
case *int64:
|
||||
bs = b[:8]
|
||||
order.PutUint64(bs, uint64(*v))
|
||||
case int64:
|
||||
bs = b[:8]
|
||||
order.PutUint64(bs, uint64(v))
|
||||
case []int64:
|
||||
for i, x := range v {
|
||||
order.PutUint64(bs[8*i:], uint64(x))
|
||||
}
|
||||
case *uint64:
|
||||
bs = b[:8]
|
||||
order.PutUint64(bs, *v)
|
||||
case uint64:
|
||||
bs = b[:8]
|
||||
order.PutUint64(bs, v)
|
||||
case []uint64:
|
||||
for i, x := range v {
|
||||
order.PutUint64(bs[8*i:], x)
|
||||
}
|
||||
}
|
||||
_, err := w.Write(bs)
|
||||
return err
|
||||
}
|
||||
|
||||
// Fallback to reflect-based encoding.
|
||||
v := reflect.Indirect(reflect.ValueOf(data))
|
||||
size := dataSize(v)
|
||||
if size < 0 {
|
||||
return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
|
||||
}
|
||||
buf := make([]byte, size)
|
||||
e := &encoder{order: order, buf: buf}
|
||||
e.value(v)
|
||||
_, err := w.Write(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
// Size returns how many bytes Write would generate to encode the value v, which
|
||||
// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
|
||||
// If v is neither of these, Size returns -1.
|
||||
func Size(v interface{}) int {
|
||||
return dataSize(reflect.Indirect(reflect.ValueOf(v)))
|
||||
}
|
||||
|
||||
// dataSize returns the number of bytes the actual data represented by v occupies in memory.
|
||||
// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
|
||||
// it returns the length of the slice times the element size and does not count the memory
|
||||
// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
|
||||
func dataSize(v reflect.Value) int {
|
||||
if v.Kind() == reflect.Slice {
|
||||
if s := sizeof(v.Type().Elem()); s >= 0 {
|
||||
return s * v.Len()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
return sizeof(v.Type())
|
||||
}
|
||||
|
||||
// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
|
||||
func sizeof(t reflect.Type) int {
|
||||
switch t.Kind() {
|
||||
case reflect.Array:
|
||||
if s := sizeof(t.Elem()); s >= 0 {
|
||||
return s * t.Len()
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
sum := 0
|
||||
for i, n := 0, t.NumField(); i < n; i++ {
|
||||
s := sizeof(t.Field(i).Type)
|
||||
if s < 0 {
|
||||
return -1
|
||||
}
|
||||
sum += s
|
||||
}
|
||||
return sum
|
||||
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.Ptr:
|
||||
return int(t.Size())
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
type coder struct {
|
||||
order ByteOrder
|
||||
buf []byte
|
||||
}
|
||||
|
||||
type decoder coder
|
||||
type encoder coder
|
||||
|
||||
func (d *decoder) uint8() uint8 {
|
||||
x := d.buf[0]
|
||||
d.buf = d.buf[1:]
|
||||
return x
|
||||
}
|
||||
|
||||
func (e *encoder) uint8(x uint8) {
|
||||
e.buf[0] = x
|
||||
e.buf = e.buf[1:]
|
||||
}
|
||||
|
||||
func (d *decoder) uint16() uint16 {
|
||||
x := d.order.Uint16(d.buf[0:2])
|
||||
d.buf = d.buf[2:]
|
||||
return x
|
||||
}
|
||||
|
||||
func (e *encoder) uint16(x uint16) {
|
||||
e.order.PutUint16(e.buf[0:2], x)
|
||||
e.buf = e.buf[2:]
|
||||
}
|
||||
|
||||
func (d *decoder) uint32() uint32 {
|
||||
x := d.order.Uint32(d.buf[0:4])
|
||||
d.buf = d.buf[4:]
|
||||
return x
|
||||
}
|
||||
|
||||
func (e *encoder) uint32(x uint32) {
|
||||
e.order.PutUint32(e.buf[0:4], x)
|
||||
e.buf = e.buf[4:]
|
||||
}
|
||||
|
||||
func (d *decoder) uint64() uint64 {
|
||||
x := d.order.Uint64(d.buf[0:8])
|
||||
d.buf = d.buf[8:]
|
||||
return x
|
||||
}
|
||||
|
||||
func (e *encoder) uint64(x uint64) {
|
||||
e.order.PutUint64(e.buf[0:8], x)
|
||||
e.buf = e.buf[8:]
|
||||
}
|
||||
|
||||
func (d *decoder) int8() int8 { return int8(d.uint8()) }
|
||||
|
||||
func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
|
||||
|
||||
func (d *decoder) int16() int16 { return int16(d.uint16()) }
|
||||
|
||||
func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
|
||||
|
||||
func (d *decoder) int32() int32 { return int32(d.uint32()) }
|
||||
|
||||
func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
|
||||
|
||||
func (d *decoder) int64() int64 { return int64(d.uint64()) }
|
||||
|
||||
func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
|
||||
|
||||
func (d *decoder) value(v reflect.Value) {
|
||||
switch v.Kind() {
|
||||
case reflect.Array:
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
d.value(v.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
t := v.Type()
|
||||
l := v.NumField()
|
||||
for i := 0; i < l; i++ {
|
||||
// Note: Calling v.CanSet() below is an optimization.
|
||||
// It would be sufficient to check the field name,
|
||||
// but creating the StructField info for each field is
|
||||
// costly (run "go test -bench=ReadStruct" and compare
|
||||
// results when making changes to this code).
|
||||
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||
d.value(v)
|
||||
} else {
|
||||
d.skip(v)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
d.value(v.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Int8:
|
||||
v.SetInt(int64(d.int8()))
|
||||
case reflect.Int16:
|
||||
v.SetInt(int64(d.int16()))
|
||||
case reflect.Int32:
|
||||
v.SetInt(int64(d.int32()))
|
||||
case reflect.Int64:
|
||||
v.SetInt(d.int64())
|
||||
|
||||
case reflect.Uint8:
|
||||
v.SetUint(uint64(d.uint8()))
|
||||
case reflect.Uint16:
|
||||
v.SetUint(uint64(d.uint16()))
|
||||
case reflect.Uint32:
|
||||
v.SetUint(uint64(d.uint32()))
|
||||
case reflect.Uint64:
|
||||
v.SetUint(d.uint64())
|
||||
|
||||
case reflect.Float32:
|
||||
v.SetFloat(float64(math.Float32frombits(d.uint32())))
|
||||
case reflect.Float64:
|
||||
v.SetFloat(math.Float64frombits(d.uint64()))
|
||||
|
||||
case reflect.Complex64:
|
||||
v.SetComplex(complex(
|
||||
float64(math.Float32frombits(d.uint32())),
|
||||
float64(math.Float32frombits(d.uint32())),
|
||||
))
|
||||
case reflect.Complex128:
|
||||
v.SetComplex(complex(
|
||||
math.Float64frombits(d.uint64()),
|
||||
math.Float64frombits(d.uint64()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
func (e *encoder) value(v reflect.Value) {
|
||||
switch v.Kind() {
|
||||
case reflect.Array:
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
e.value(v.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Struct:
|
||||
t := v.Type()
|
||||
l := v.NumField()
|
||||
for i := 0; i < l; i++ {
|
||||
// see comment for corresponding code in decoder.value()
|
||||
if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
|
||||
e.value(v)
|
||||
} else {
|
||||
e.skip(v)
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
l := v.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
e.value(v.Index(i))
|
||||
}
|
||||
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Int8:
|
||||
e.int8(int8(v.Int()))
|
||||
case reflect.Int16:
|
||||
e.int16(int16(v.Int()))
|
||||
case reflect.Int32:
|
||||
e.int32(int32(v.Int()))
|
||||
case reflect.Int64:
|
||||
e.int64(v.Int())
|
||||
}
|
||||
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Uint8:
|
||||
e.uint8(uint8(v.Uint()))
|
||||
case reflect.Uint16:
|
||||
e.uint16(uint16(v.Uint()))
|
||||
case reflect.Uint32:
|
||||
e.uint32(uint32(v.Uint()))
|
||||
case reflect.Uint64:
|
||||
e.uint64(v.Uint())
|
||||
}
|
||||
|
||||
case reflect.Float32, reflect.Float64:
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Float32:
|
||||
e.uint32(math.Float32bits(float32(v.Float())))
|
||||
case reflect.Float64:
|
||||
e.uint64(math.Float64bits(v.Float()))
|
||||
}
|
||||
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Complex64:
|
||||
x := v.Complex()
|
||||
e.uint32(math.Float32bits(float32(real(x))))
|
||||
e.uint32(math.Float32bits(float32(imag(x))))
|
||||
case reflect.Complex128:
|
||||
x := v.Complex()
|
||||
e.uint64(math.Float64bits(real(x)))
|
||||
e.uint64(math.Float64bits(imag(x)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *decoder) skip(v reflect.Value) {
|
||||
d.buf = d.buf[dataSize(v):]
|
||||
}
|
||||
|
||||
func (e *encoder) skip(v reflect.Value) {
|
||||
n := dataSize(v)
|
||||
for i := range e.buf[0:n] {
|
||||
e.buf[i] = 0
|
||||
}
|
||||
e.buf = e.buf[n:]
|
||||
}
|
||||
|
||||
// intDataSize returns the size of the data required to represent the data when encoded.
|
||||
// It returns zero if the type cannot be implemented by the fast path in Read or Write.
|
||||
func intDataSize(data interface{}) int {
|
||||
switch data := data.(type) {
|
||||
case int8, *int8, *uint8:
|
||||
return 1
|
||||
case []int8:
|
||||
return len(data)
|
||||
case []uint8:
|
||||
return len(data)
|
||||
case int16, *int16, *uint16:
|
||||
return 2
|
||||
case []int16:
|
||||
return 2 * len(data)
|
||||
case []uint16:
|
||||
return 2 * len(data)
|
||||
case int32, *int32, *uint32:
|
||||
return 4
|
||||
case []int32:
|
||||
return 4 * len(data)
|
||||
case []uint32:
|
||||
return 4 * len(data)
|
||||
case int64, *int64, *uint64:
|
||||
return 8
|
||||
case []int64:
|
||||
return 8 * len(data)
|
||||
case []uint64:
|
||||
return 8 * len(data)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
52
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk.go
generated
vendored
Normal file
52
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type DiskUsageStat struct {
|
||||
Path string `json:"path"`
|
||||
Fstype string `json:"fstype"`
|
||||
Total uint64 `json:"total"`
|
||||
Free uint64 `json:"free"`
|
||||
Used uint64 `json:"used"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
InodesTotal uint64 `json:"inodes_total"`
|
||||
InodesUsed uint64 `json:"inodes_used"`
|
||||
InodesFree uint64 `json:"inodes_free"`
|
||||
InodesUsedPercent float64 `json:"inodes_used_percent"`
|
||||
}
|
||||
|
||||
type DiskPartitionStat struct {
|
||||
Device string `json:"device"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
Fstype string `json:"fstype"`
|
||||
Opts string `json:"opts"`
|
||||
}
|
||||
|
||||
type DiskIOCountersStat struct {
|
||||
ReadCount uint64 `json:"read_count"`
|
||||
WriteCount uint64 `json:"write_count"`
|
||||
ReadBytes uint64 `json:"read_bytes"`
|
||||
WriteBytes uint64 `json:"write_bytes"`
|
||||
ReadTime uint64 `json:"read_time"`
|
||||
WriteTime uint64 `json:"write_time"`
|
||||
Name string `json:"name"`
|
||||
IoTime uint64 `json:"io_time"`
|
||||
SerialNumber string `json:"serial_number"`
|
||||
}
|
||||
|
||||
func (d DiskUsageStat) String() string {
|
||||
s, _ := json.Marshal(d)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (d DiskPartitionStat) String() string {
|
||||
s, _ := json.Marshal(d)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (d DiskIOCountersStat) String() string {
|
||||
s, _ := json.Marshal(d)
|
||||
return string(s)
|
||||
}
|
||||
104
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go
generated
vendored
Normal file
104
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
// +build darwin
|
||||
|
||||
package disk
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
|
||||
var ret []DiskPartitionStat
|
||||
|
||||
count, err := Getfsstat(nil, MntWait)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
fs := make([]Statfs_t, count)
|
||||
_, err = Getfsstat(fs, MntWait)
|
||||
for _, stat := range fs {
|
||||
opts := "rw"
|
||||
if stat.Flags&MntReadOnly != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if stat.Flags&MntSynchronous != 0 {
|
||||
opts += ",sync"
|
||||
}
|
||||
if stat.Flags&MntNoExec != 0 {
|
||||
opts += ",noexec"
|
||||
}
|
||||
if stat.Flags&MntNoSuid != 0 {
|
||||
opts += ",nosuid"
|
||||
}
|
||||
if stat.Flags&MntUnion != 0 {
|
||||
opts += ",union"
|
||||
}
|
||||
if stat.Flags&MntAsync != 0 {
|
||||
opts += ",async"
|
||||
}
|
||||
if stat.Flags&MntSuidDir != 0 {
|
||||
opts += ",suiddir"
|
||||
}
|
||||
if stat.Flags&MntSoftDep != 0 {
|
||||
opts += ",softdep"
|
||||
}
|
||||
if stat.Flags&MntNoSymFollow != 0 {
|
||||
opts += ",nosymfollow"
|
||||
}
|
||||
if stat.Flags&MntGEOMJournal != 0 {
|
||||
opts += ",gjounalc"
|
||||
}
|
||||
if stat.Flags&MntMultilabel != 0 {
|
||||
opts += ",multilabel"
|
||||
}
|
||||
if stat.Flags&MntACLs != 0 {
|
||||
opts += ",acls"
|
||||
}
|
||||
if stat.Flags&MntNoATime != 0 {
|
||||
opts += ",noattime"
|
||||
}
|
||||
if stat.Flags&MntClusterRead != 0 {
|
||||
opts += ",nocluster"
|
||||
}
|
||||
if stat.Flags&MntClusterWrite != 0 {
|
||||
opts += ",noclusterw"
|
||||
}
|
||||
if stat.Flags&MntNFS4ACLs != 0 {
|
||||
opts += ",nfs4acls"
|
||||
}
|
||||
d := DiskPartitionStat{
|
||||
Device: common.IntToString(stat.Mntfromname[:]),
|
||||
Mountpoint: common.IntToString(stat.Mntonname[:]),
|
||||
Fstype: common.IntToString(stat.Fstypename[:]),
|
||||
Opts: opts,
|
||||
}
|
||||
ret = append(ret, d)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
|
||||
return nil, common.NotImplementedError
|
||||
}
|
||||
|
||||
func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
var bufsize uintptr
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getFsType(stat syscall.Statfs_t) string {
|
||||
return common.IntToString(stat.Fstypename[:])
|
||||
}
|
||||
58
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin_amd64.go
generated
vendored
Normal file
58
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_darwin_amd64.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
// +build darwin
|
||||
// +build amd64
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
MntWait = 1
|
||||
MfsNameLen = 15 /* length of fs type name, not inc. nul */
|
||||
MNameLen = 90 /* length of buffer for returned name */
|
||||
|
||||
MFSTYPENAMELEN = 16 /* length of fs type name including null */
|
||||
MAXPATHLEN = 1024
|
||||
MNAMELEN = MAXPATHLEN
|
||||
|
||||
SYS_GETFSSTAT64 = 347
|
||||
)
|
||||
|
||||
type Fsid struct{ val [2]int32 } /* file system id type */
|
||||
type uid_t int32
|
||||
|
||||
// sys/mount.h
|
||||
const (
|
||||
MntReadOnly = 0x00000001 /* read only filesystem */
|
||||
MntSynchronous = 0x00000002 /* filesystem written synchronously */
|
||||
MntNoExec = 0x00000004 /* can't exec from filesystem */
|
||||
MntNoSuid = 0x00000008 /* don't honor setuid bits on fs */
|
||||
MntUnion = 0x00000020 /* union with underlying filesystem */
|
||||
MntAsync = 0x00000040 /* filesystem written asynchronously */
|
||||
MntSuidDir = 0x00100000 /* special handling of SUID on dirs */
|
||||
MntSoftDep = 0x00200000 /* soft updates being done */
|
||||
MntNoSymFollow = 0x00400000 /* do not follow symlinks */
|
||||
MntGEOMJournal = 0x02000000 /* GEOM journal support enabled */
|
||||
MntMultilabel = 0x04000000 /* MAC support for individual objects */
|
||||
MntACLs = 0x08000000 /* ACL support enabled */
|
||||
MntNoATime = 0x10000000 /* disable update of file access time */
|
||||
MntClusterRead = 0x40000000 /* disable cluster read */
|
||||
MntClusterWrite = 0x80000000 /* disable cluster write */
|
||||
MntNFS4ACLs = 0x00000010
|
||||
)
|
||||
|
||||
type Statfs_t struct {
|
||||
Bsize uint32
|
||||
Iosize int32
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail uint64
|
||||
Files uint64
|
||||
Ffree uint64
|
||||
Fsid Fsid
|
||||
Owner uint32
|
||||
Type uint32
|
||||
Flags uint32
|
||||
Fssubtype uint32
|
||||
Fstypename [16]int8
|
||||
Mntonname [1024]int8
|
||||
Mntfromname [1024]int8
|
||||
Reserved [8]uint32
|
||||
}
|
||||
179
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go
generated
vendored
Normal file
179
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
// +build freebsd
|
||||
|
||||
package disk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
const (
|
||||
CTLKern = 1
|
||||
// KernDevstat = 773 // for freebsd 8.4
|
||||
// KernDevstatAll = 772 // for freebsd 8.4
|
||||
KernDevstat = 974
|
||||
KernDevstatAll = 975
|
||||
)
|
||||
|
||||
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
|
||||
var ret []DiskPartitionStat
|
||||
|
||||
// get length
|
||||
count, err := syscall.Getfsstat(nil, MNT_WAIT)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
fs := make([]Statfs, count)
|
||||
_, err = Getfsstat(fs, MNT_WAIT)
|
||||
|
||||
for _, stat := range fs {
|
||||
opts := "rw"
|
||||
if stat.Flags&MNT_RDONLY != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if stat.Flags&MNT_SYNCHRONOUS != 0 {
|
||||
opts += ",sync"
|
||||
}
|
||||
if stat.Flags&MNT_NOEXEC != 0 {
|
||||
opts += ",noexec"
|
||||
}
|
||||
if stat.Flags&MNT_NOSUID != 0 {
|
||||
opts += ",nosuid"
|
||||
}
|
||||
if stat.Flags&MNT_UNION != 0 {
|
||||
opts += ",union"
|
||||
}
|
||||
if stat.Flags&MNT_ASYNC != 0 {
|
||||
opts += ",async"
|
||||
}
|
||||
if stat.Flags&MNT_SUIDDIR != 0 {
|
||||
opts += ",suiddir"
|
||||
}
|
||||
if stat.Flags&MNT_SOFTDEP != 0 {
|
||||
opts += ",softdep"
|
||||
}
|
||||
if stat.Flags&MNT_NOSYMFOLLOW != 0 {
|
||||
opts += ",nosymfollow"
|
||||
}
|
||||
if stat.Flags&MNT_GJOURNAL != 0 {
|
||||
opts += ",gjounalc"
|
||||
}
|
||||
if stat.Flags&MNT_MULTILABEL != 0 {
|
||||
opts += ",multilabel"
|
||||
}
|
||||
if stat.Flags&MNT_ACLS != 0 {
|
||||
opts += ",acls"
|
||||
}
|
||||
if stat.Flags&MNT_NOATIME != 0 {
|
||||
opts += ",noattime"
|
||||
}
|
||||
if stat.Flags&MNT_NOCLUSTERR != 0 {
|
||||
opts += ",nocluster"
|
||||
}
|
||||
if stat.Flags&MNT_NOCLUSTERW != 0 {
|
||||
opts += ",noclusterw"
|
||||
}
|
||||
if stat.Flags&MNT_NFS4ACLS != 0 {
|
||||
opts += ",nfs4acls"
|
||||
}
|
||||
|
||||
d := DiskPartitionStat{
|
||||
Device: common.IntToString(stat.Mntfromname[:]),
|
||||
Mountpoint: common.IntToString(stat.Mntonname[:]),
|
||||
Fstype: common.IntToString(stat.Fstypename[:]),
|
||||
Opts: opts,
|
||||
}
|
||||
ret = append(ret, d)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
|
||||
// statinfo->devinfo->devstat
|
||||
// /usr/include/devinfo.h
|
||||
|
||||
// sysctl.sysctl ('kern.devstat.all', 0)
|
||||
ret := make(map[string]DiskIOCountersStat)
|
||||
mib := []int32{CTLKern, KernDevstat, KernDevstatAll}
|
||||
|
||||
buf, length, err := common.CallSyscall(mib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds := Devstat{}
|
||||
devstatLen := int(unsafe.Sizeof(ds))
|
||||
count := int(length / uint64(devstatLen))
|
||||
|
||||
buf = buf[8:] // devstat.all has version in the head.
|
||||
// parse buf to Devstat
|
||||
for i := 0; i < count; i++ {
|
||||
b := buf[i*devstatLen : i*devstatLen+devstatLen]
|
||||
d, err := parseDevstat(b)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
un := strconv.Itoa(int(d.Unit_number))
|
||||
name := common.IntToString(d.Device_name[:]) + un
|
||||
|
||||
ds := DiskIOCountersStat{
|
||||
ReadCount: d.Operations[DEVSTAT_READ],
|
||||
WriteCount: d.Operations[DEVSTAT_WRITE],
|
||||
ReadBytes: d.Bytes[DEVSTAT_READ],
|
||||
WriteBytes: d.Bytes[DEVSTAT_WRITE],
|
||||
ReadTime: d.Duration[DEVSTAT_READ].Compute(),
|
||||
WriteTime: d.Duration[DEVSTAT_WRITE].Compute(),
|
||||
Name: name,
|
||||
}
|
||||
ret[name] = ds
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (b Bintime) Compute() uint64 {
|
||||
BINTIME_SCALE := 5.42101086242752217003726400434970855712890625e-20
|
||||
return uint64(b.Sec) + b.Frac*uint64(BINTIME_SCALE)
|
||||
}
|
||||
|
||||
// BT2LD(time) ((long double)(time).sec + (time).frac * BINTIME_SCALE)
|
||||
|
||||
// Getfsstat is borrowed from pkg/syscall/syscall_freebsd.go
|
||||
// change Statfs_t to Statfs in order to get more information
|
||||
func Getfsstat(buf []Statfs, flags int) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
var bufsize uintptr
|
||||
if len(buf) > 0 {
|
||||
_p0 = unsafe.Pointer(&buf[0])
|
||||
bufsize = unsafe.Sizeof(Statfs{}) * uintptr(len(buf))
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall(syscall.SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseDevstat(buf []byte) (Devstat, error) {
|
||||
var ds Devstat
|
||||
br := bytes.NewReader(buf)
|
||||
// err := binary.Read(br, binary.LittleEndian, &ds)
|
||||
err := Read(br, binary.LittleEndian, &ds)
|
||||
if err != nil {
|
||||
return ds, err
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
func getFsType(stat syscall.Statfs_t) string {
|
||||
return common.IntToString(stat.Fstypename[:])
|
||||
}
|
||||
111
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_amd64.go
generated
vendored
Normal file
111
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_freebsd_amd64.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
// Created by cgo -godefs - DO NOT EDIT
|
||||
// cgo -godefs types_freebsd.go
|
||||
|
||||
package disk
|
||||
|
||||
const (
|
||||
sizeofPtr = 0x8
|
||||
sizeofShort = 0x2
|
||||
sizeofInt = 0x4
|
||||
sizeofLong = 0x8
|
||||
sizeofLongLong = 0x8
|
||||
sizeofLongDouble = 0x8
|
||||
|
||||
DEVSTAT_NO_DATA = 0x00
|
||||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
MNT_RDONLY = 0x00000001
|
||||
MNT_SYNCHRONOUS = 0x00000002
|
||||
MNT_NOEXEC = 0x00000004
|
||||
MNT_NOSUID = 0x00000008
|
||||
MNT_UNION = 0x00000020
|
||||
MNT_ASYNC = 0x00000040
|
||||
MNT_SUIDDIR = 0x00100000
|
||||
MNT_SOFTDEP = 0x00200000
|
||||
MNT_NOSYMFOLLOW = 0x00400000
|
||||
MNT_GJOURNAL = 0x02000000
|
||||
MNT_MULTILABEL = 0x04000000
|
||||
MNT_ACLS = 0x08000000
|
||||
MNT_NOATIME = 0x10000000
|
||||
MNT_NOCLUSTERR = 0x40000000
|
||||
MNT_NOCLUSTERW = 0x80000000
|
||||
MNT_NFS4ACLS = 0x00000010
|
||||
|
||||
MNT_WAIT = 1
|
||||
MNT_NOWAIT = 2
|
||||
MNT_LAZY = 3
|
||||
MNT_SUSPEND = 4
|
||||
)
|
||||
|
||||
type (
|
||||
_C_short int16
|
||||
_C_int int32
|
||||
_C_long int64
|
||||
_C_long_long int64
|
||||
_C_long_double int64
|
||||
)
|
||||
|
||||
type Statfs struct {
|
||||
Version uint32
|
||||
Type uint32
|
||||
Flags uint64
|
||||
Bsize uint64
|
||||
Iosize uint64
|
||||
Blocks uint64
|
||||
Bfree uint64
|
||||
Bavail int64
|
||||
Files uint64
|
||||
Ffree int64
|
||||
Syncwrites uint64
|
||||
Asyncwrites uint64
|
||||
Syncreads uint64
|
||||
Asyncreads uint64
|
||||
Spare [10]uint64
|
||||
Namemax uint32
|
||||
Owner uint32
|
||||
Fsid Fsid
|
||||
Charspare [80]int8
|
||||
Fstypename [16]int8
|
||||
Mntfromname [88]int8
|
||||
Mntonname [88]int8
|
||||
}
|
||||
type Fsid struct {
|
||||
Val [2]int32
|
||||
}
|
||||
|
||||
type Devstat struct {
|
||||
Sequence0 uint32
|
||||
Allocated int32
|
||||
Start_count uint32
|
||||
End_count uint32
|
||||
Busy_from Bintime
|
||||
Dev_links _Ctype_struct___0
|
||||
Device_number uint32
|
||||
Device_name [16]int8
|
||||
Unit_number int32
|
||||
Bytes [4]uint64
|
||||
Operations [4]uint64
|
||||
Duration [4]Bintime
|
||||
Busy_time Bintime
|
||||
Creation_time Bintime
|
||||
Block_size uint32
|
||||
Pad_cgo_0 [4]byte
|
||||
Tag_types [3]uint64
|
||||
Flags uint32
|
||||
Device_type uint32
|
||||
Priority uint32
|
||||
Pad_cgo_1 [4]byte
|
||||
Id *byte
|
||||
Sequence1 uint32
|
||||
Pad_cgo_2 [4]byte
|
||||
}
|
||||
type Bintime struct {
|
||||
Sec int64
|
||||
Frac uint64
|
||||
}
|
||||
|
||||
type _Ctype_struct___0 struct {
|
||||
Empty uint64
|
||||
}
|
||||
327
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go
generated
vendored
Normal file
327
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_linux.go
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
// +build linux
|
||||
|
||||
package disk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
const (
|
||||
SectorSize = 512
|
||||
)
|
||||
const (
|
||||
// man statfs
|
||||
ADFS_SUPER_MAGIC = 0xadf5
|
||||
AFFS_SUPER_MAGIC = 0xADFF
|
||||
BDEVFS_MAGIC = 0x62646576
|
||||
BEFS_SUPER_MAGIC = 0x42465331
|
||||
BFS_MAGIC = 0x1BADFACE
|
||||
BINFMTFS_MAGIC = 0x42494e4d
|
||||
BTRFS_SUPER_MAGIC = 0x9123683E
|
||||
CGROUP_SUPER_MAGIC = 0x27e0eb
|
||||
CIFS_MAGIC_NUMBER = 0xFF534D42
|
||||
CODA_SUPER_MAGIC = 0x73757245
|
||||
COH_SUPER_MAGIC = 0x012FF7B7
|
||||
CRAMFS_MAGIC = 0x28cd3d45
|
||||
DEBUGFS_MAGIC = 0x64626720
|
||||
DEVFS_SUPER_MAGIC = 0x1373
|
||||
DEVPTS_SUPER_MAGIC = 0x1cd1
|
||||
EFIVARFS_MAGIC = 0xde5e81e4
|
||||
EFS_SUPER_MAGIC = 0x00414A53
|
||||
EXT_SUPER_MAGIC = 0x137D
|
||||
EXT2_OLD_SUPER_MAGIC = 0xEF51
|
||||
EXT2_SUPER_MAGIC = 0xEF53
|
||||
EXT3_SUPER_MAGIC = 0xEF53
|
||||
EXT4_SUPER_MAGIC = 0xEF53
|
||||
FUSE_SUPER_MAGIC = 0x65735546
|
||||
FUTEXFS_SUPER_MAGIC = 0xBAD1DEA
|
||||
HFS_SUPER_MAGIC = 0x4244
|
||||
HOSTFS_SUPER_MAGIC = 0x00c0ffee
|
||||
HPFS_SUPER_MAGIC = 0xF995E849
|
||||
HUGETLBFS_MAGIC = 0x958458f6
|
||||
ISOFS_SUPER_MAGIC = 0x9660
|
||||
JFFS2_SUPER_MAGIC = 0x72b6
|
||||
JFS_SUPER_MAGIC = 0x3153464a
|
||||
MINIX_SUPER_MAGIC = 0x137F /* orig. minix */
|
||||
MINIX_SUPER_MAGIC2 = 0x138F /* 30 char minix */
|
||||
MINIX2_SUPER_MAGIC = 0x2468 /* minix V2 */
|
||||
MINIX2_SUPER_MAGIC2 = 0x2478 /* minix V2, 30 char names */
|
||||
MINIX3_SUPER_MAGIC = 0x4d5a /* minix V3 fs, 60 char names */
|
||||
MQUEUE_MAGIC = 0x19800202
|
||||
MSDOS_SUPER_MAGIC = 0x4d44
|
||||
NCP_SUPER_MAGIC = 0x564c
|
||||
NFS_SUPER_MAGIC = 0x6969
|
||||
NILFS_SUPER_MAGIC = 0x3434
|
||||
NTFS_SB_MAGIC = 0x5346544e
|
||||
OCFS2_SUPER_MAGIC = 0x7461636f
|
||||
OPENPROM_SUPER_MAGIC = 0x9fa1
|
||||
PIPEFS_MAGIC = 0x50495045
|
||||
PROC_SUPER_MAGIC = 0x9fa0
|
||||
PSTOREFS_MAGIC = 0x6165676C
|
||||
QNX4_SUPER_MAGIC = 0x002f
|
||||
QNX6_SUPER_MAGIC = 0x68191122
|
||||
RAMFS_MAGIC = 0x858458f6
|
||||
REISERFS_SUPER_MAGIC = 0x52654973
|
||||
ROMFS_MAGIC = 0x7275
|
||||
SELINUX_MAGIC = 0xf97cff8c
|
||||
SMACK_MAGIC = 0x43415d53
|
||||
SMB_SUPER_MAGIC = 0x517B
|
||||
SOCKFS_MAGIC = 0x534F434B
|
||||
SQUASHFS_MAGIC = 0x73717368
|
||||
SYSFS_MAGIC = 0x62656572
|
||||
SYSV2_SUPER_MAGIC = 0x012FF7B6
|
||||
SYSV4_SUPER_MAGIC = 0x012FF7B5
|
||||
TMPFS_MAGIC = 0x01021994
|
||||
UDF_SUPER_MAGIC = 0x15013346
|
||||
UFS_MAGIC = 0x00011954
|
||||
USBDEVICE_SUPER_MAGIC = 0x9fa2
|
||||
V9FS_MAGIC = 0x01021997
|
||||
VXFS_SUPER_MAGIC = 0xa501FCF5
|
||||
XENFS_SUPER_MAGIC = 0xabba1974
|
||||
XENIX_SUPER_MAGIC = 0x012FF7B4
|
||||
XFS_SUPER_MAGIC = 0x58465342
|
||||
_XIAFS_SUPER_MAGIC = 0x012FD16D
|
||||
|
||||
AFS_SUPER_MAGIC = 0x5346414F
|
||||
AUFS_SUPER_MAGIC = 0x61756673
|
||||
ANON_INODE_FS_SUPER_MAGIC = 0x09041934
|
||||
CEPH_SUPER_MAGIC = 0x00C36400
|
||||
ECRYPTFS_SUPER_MAGIC = 0xF15F
|
||||
FAT_SUPER_MAGIC = 0x4006
|
||||
FHGFS_SUPER_MAGIC = 0x19830326
|
||||
FUSEBLK_SUPER_MAGIC = 0x65735546
|
||||
FUSECTL_SUPER_MAGIC = 0x65735543
|
||||
GFS_SUPER_MAGIC = 0x1161970
|
||||
GPFS_SUPER_MAGIC = 0x47504653
|
||||
MTD_INODE_FS_SUPER_MAGIC = 0x11307854
|
||||
INOTIFYFS_SUPER_MAGIC = 0x2BAD1DEA
|
||||
ISOFS_R_WIN_SUPER_MAGIC = 0x4004
|
||||
ISOFS_WIN_SUPER_MAGIC = 0x4000
|
||||
JFFS_SUPER_MAGIC = 0x07C0
|
||||
KAFS_SUPER_MAGIC = 0x6B414653
|
||||
LUSTRE_SUPER_MAGIC = 0x0BD00BD0
|
||||
NFSD_SUPER_MAGIC = 0x6E667364
|
||||
PANFS_SUPER_MAGIC = 0xAAD7AAEA
|
||||
RPC_PIPEFS_SUPER_MAGIC = 0x67596969
|
||||
SECURITYFS_SUPER_MAGIC = 0x73636673
|
||||
UFS_BYTESWAPPED_SUPER_MAGIC = 0x54190100
|
||||
VMHGFS_SUPER_MAGIC = 0xBACBACBC
|
||||
VZFS_SUPER_MAGIC = 0x565A4653
|
||||
ZFS_SUPER_MAGIC = 0x2FC12FC1
|
||||
)
|
||||
|
||||
// coreutils/src/stat.c
|
||||
var fsTypeMap = map[int64]string{
|
||||
ADFS_SUPER_MAGIC: "adfs", /* 0xADF5 local */
|
||||
AFFS_SUPER_MAGIC: "affs", /* 0xADFF local */
|
||||
AFS_SUPER_MAGIC: "afs", /* 0x5346414F remote */
|
||||
ANON_INODE_FS_SUPER_MAGIC: "anon-inode FS", /* 0x09041934 local */
|
||||
AUFS_SUPER_MAGIC: "aufs", /* 0x61756673 remote */
|
||||
// AUTOFS_SUPER_MAGIC: "autofs", /* 0x0187 local */
|
||||
BEFS_SUPER_MAGIC: "befs", /* 0x42465331 local */
|
||||
BDEVFS_MAGIC: "bdevfs", /* 0x62646576 local */
|
||||
BFS_MAGIC: "bfs", /* 0x1BADFACE local */
|
||||
BINFMTFS_MAGIC: "binfmt_misc", /* 0x42494E4D local */
|
||||
BTRFS_SUPER_MAGIC: "btrfs", /* 0x9123683E local */
|
||||
CEPH_SUPER_MAGIC: "ceph", /* 0x00C36400 remote */
|
||||
CGROUP_SUPER_MAGIC: "cgroupfs", /* 0x0027E0EB local */
|
||||
CIFS_MAGIC_NUMBER: "cifs", /* 0xFF534D42 remote */
|
||||
CODA_SUPER_MAGIC: "coda", /* 0x73757245 remote */
|
||||
COH_SUPER_MAGIC: "coh", /* 0x012FF7B7 local */
|
||||
CRAMFS_MAGIC: "cramfs", /* 0x28CD3D45 local */
|
||||
DEBUGFS_MAGIC: "debugfs", /* 0x64626720 local */
|
||||
DEVFS_SUPER_MAGIC: "devfs", /* 0x1373 local */
|
||||
DEVPTS_SUPER_MAGIC: "devpts", /* 0x1CD1 local */
|
||||
ECRYPTFS_SUPER_MAGIC: "ecryptfs", /* 0xF15F local */
|
||||
EFS_SUPER_MAGIC: "efs", /* 0x00414A53 local */
|
||||
EXT_SUPER_MAGIC: "ext", /* 0x137D local */
|
||||
EXT2_SUPER_MAGIC: "ext2/ext3", /* 0xEF53 local */
|
||||
EXT2_OLD_SUPER_MAGIC: "ext2", /* 0xEF51 local */
|
||||
FAT_SUPER_MAGIC: "fat", /* 0x4006 local */
|
||||
FHGFS_SUPER_MAGIC: "fhgfs", /* 0x19830326 remote */
|
||||
FUSEBLK_SUPER_MAGIC: "fuseblk", /* 0x65735546 remote */
|
||||
FUSECTL_SUPER_MAGIC: "fusectl", /* 0x65735543 remote */
|
||||
FUTEXFS_SUPER_MAGIC: "futexfs", /* 0x0BAD1DEA local */
|
||||
GFS_SUPER_MAGIC: "gfs/gfs2", /* 0x1161970 remote */
|
||||
GPFS_SUPER_MAGIC: "gpfs", /* 0x47504653 remote */
|
||||
HFS_SUPER_MAGIC: "hfs", /* 0x4244 local */
|
||||
HPFS_SUPER_MAGIC: "hpfs", /* 0xF995E849 local */
|
||||
HUGETLBFS_MAGIC: "hugetlbfs", /* 0x958458F6 local */
|
||||
MTD_INODE_FS_SUPER_MAGIC: "inodefs", /* 0x11307854 local */
|
||||
INOTIFYFS_SUPER_MAGIC: "inotifyfs", /* 0x2BAD1DEA local */
|
||||
ISOFS_SUPER_MAGIC: "isofs", /* 0x9660 local */
|
||||
ISOFS_R_WIN_SUPER_MAGIC: "isofs", /* 0x4004 local */
|
||||
ISOFS_WIN_SUPER_MAGIC: "isofs", /* 0x4000 local */
|
||||
JFFS_SUPER_MAGIC: "jffs", /* 0x07C0 local */
|
||||
JFFS2_SUPER_MAGIC: "jffs2", /* 0x72B6 local */
|
||||
JFS_SUPER_MAGIC: "jfs", /* 0x3153464A local */
|
||||
KAFS_SUPER_MAGIC: "k-afs", /* 0x6B414653 remote */
|
||||
LUSTRE_SUPER_MAGIC: "lustre", /* 0x0BD00BD0 remote */
|
||||
MINIX_SUPER_MAGIC: "minix", /* 0x137F local */
|
||||
MINIX_SUPER_MAGIC2: "minix (30 char.)", /* 0x138F local */
|
||||
MINIX2_SUPER_MAGIC: "minix v2", /* 0x2468 local */
|
||||
MINIX2_SUPER_MAGIC2: "minix v2 (30 char.)", /* 0x2478 local */
|
||||
MINIX3_SUPER_MAGIC: "minix3", /* 0x4D5A local */
|
||||
MQUEUE_MAGIC: "mqueue", /* 0x19800202 local */
|
||||
MSDOS_SUPER_MAGIC: "msdos", /* 0x4D44 local */
|
||||
NCP_SUPER_MAGIC: "novell", /* 0x564C remote */
|
||||
NFS_SUPER_MAGIC: "nfs", /* 0x6969 remote */
|
||||
NFSD_SUPER_MAGIC: "nfsd", /* 0x6E667364 remote */
|
||||
NILFS_SUPER_MAGIC: "nilfs", /* 0x3434 local */
|
||||
NTFS_SB_MAGIC: "ntfs", /* 0x5346544E local */
|
||||
OPENPROM_SUPER_MAGIC: "openprom", /* 0x9FA1 local */
|
||||
OCFS2_SUPER_MAGIC: "ocfs2", /* 0x7461636f remote */
|
||||
PANFS_SUPER_MAGIC: "panfs", /* 0xAAD7AAEA remote */
|
||||
PIPEFS_MAGIC: "pipefs", /* 0x50495045 remote */
|
||||
PROC_SUPER_MAGIC: "proc", /* 0x9FA0 local */
|
||||
PSTOREFS_MAGIC: "pstorefs", /* 0x6165676C local */
|
||||
QNX4_SUPER_MAGIC: "qnx4", /* 0x002F local */
|
||||
QNX6_SUPER_MAGIC: "qnx6", /* 0x68191122 local */
|
||||
RAMFS_MAGIC: "ramfs", /* 0x858458F6 local */
|
||||
REISERFS_SUPER_MAGIC: "reiserfs", /* 0x52654973 local */
|
||||
ROMFS_MAGIC: "romfs", /* 0x7275 local */
|
||||
RPC_PIPEFS_SUPER_MAGIC: "rpc_pipefs", /* 0x67596969 local */
|
||||
SECURITYFS_SUPER_MAGIC: "securityfs", /* 0x73636673 local */
|
||||
SELINUX_MAGIC: "selinux", /* 0xF97CFF8C local */
|
||||
SMB_SUPER_MAGIC: "smb", /* 0x517B remote */
|
||||
SOCKFS_MAGIC: "sockfs", /* 0x534F434B local */
|
||||
SQUASHFS_MAGIC: "squashfs", /* 0x73717368 local */
|
||||
SYSFS_MAGIC: "sysfs", /* 0x62656572 local */
|
||||
SYSV2_SUPER_MAGIC: "sysv2", /* 0x012FF7B6 local */
|
||||
SYSV4_SUPER_MAGIC: "sysv4", /* 0x012FF7B5 local */
|
||||
TMPFS_MAGIC: "tmpfs", /* 0x01021994 local */
|
||||
UDF_SUPER_MAGIC: "udf", /* 0x15013346 local */
|
||||
UFS_MAGIC: "ufs", /* 0x00011954 local */
|
||||
UFS_BYTESWAPPED_SUPER_MAGIC: "ufs", /* 0x54190100 local */
|
||||
USBDEVICE_SUPER_MAGIC: "usbdevfs", /* 0x9FA2 local */
|
||||
V9FS_MAGIC: "v9fs", /* 0x01021997 local */
|
||||
VMHGFS_SUPER_MAGIC: "vmhgfs", /* 0xBACBACBC remote */
|
||||
VXFS_SUPER_MAGIC: "vxfs", /* 0xA501FCF5 local */
|
||||
VZFS_SUPER_MAGIC: "vzfs", /* 0x565A4653 local */
|
||||
XENFS_SUPER_MAGIC: "xenfs", /* 0xABBA1974 local */
|
||||
XENIX_SUPER_MAGIC: "xenix", /* 0x012FF7B4 local */
|
||||
XFS_SUPER_MAGIC: "xfs", /* 0x58465342 local */
|
||||
_XIAFS_SUPER_MAGIC: "xia", /* 0x012FD16D local */
|
||||
ZFS_SUPER_MAGIC: "zfs", /* 0x2FC12FC1 local */
|
||||
}
|
||||
|
||||
// Get disk partitions.
|
||||
// should use setmntent(3) but this implement use /etc/mtab file
|
||||
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
|
||||
|
||||
filename := "/etc/mtab"
|
||||
lines, err := common.ReadLines(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]DiskPartitionStat, 0, len(lines))
|
||||
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
d := DiskPartitionStat{
|
||||
Device: fields[0],
|
||||
Mountpoint: fields[1],
|
||||
Fstype: fields[2],
|
||||
Opts: fields[3],
|
||||
}
|
||||
ret = append(ret, d)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
|
||||
filename := "/proc/diskstats"
|
||||
lines, err := common.ReadLines(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make(map[string]DiskIOCountersStat, 0)
|
||||
empty := DiskIOCountersStat{}
|
||||
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
name := fields[2]
|
||||
reads, err := strconv.ParseUint((fields[3]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
rbytes, err := strconv.ParseUint((fields[5]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
rtime, err := strconv.ParseUint((fields[6]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
writes, err := strconv.ParseUint((fields[7]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
wbytes, err := strconv.ParseUint((fields[9]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
wtime, err := strconv.ParseUint((fields[10]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
iotime, err := strconv.ParseUint((fields[12]), 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
d := DiskIOCountersStat{
|
||||
ReadBytes: rbytes * SectorSize,
|
||||
WriteBytes: wbytes * SectorSize,
|
||||
ReadCount: reads,
|
||||
WriteCount: writes,
|
||||
ReadTime: rtime,
|
||||
WriteTime: wtime,
|
||||
IoTime: iotime,
|
||||
}
|
||||
if d == empty {
|
||||
continue
|
||||
}
|
||||
d.Name = name
|
||||
|
||||
d.SerialNumber = GetDiskSerialNumber(name)
|
||||
ret[name] = d
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func GetDiskSerialNumber(name string) string {
|
||||
n := fmt.Sprintf("--name=%s", name)
|
||||
out, err := exec.Command("/sbin/udevadm", "info", "--query=property", n).Output()
|
||||
|
||||
// does not return error, just an empty string
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
for _, line := range lines {
|
||||
values := strings.Split(line, "=")
|
||||
if len(values) < 2 || values[0] != "ID_SERIAL" {
|
||||
// only get ID_SERIAL, not ID_SERIAL_SHORT
|
||||
continue
|
||||
}
|
||||
return values[1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getFsType(stat syscall.Statfs_t) string {
|
||||
t := int64(stat.Type)
|
||||
ret, ok := fsTypeMap[t]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return ret
|
||||
}
|
||||
97
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_test.go
generated
vendored
Normal file
97
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_test.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
package disk
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDisk_usage(t *testing.T) {
|
||||
path := "/"
|
||||
if runtime.GOOS == "windows" {
|
||||
path = "C:"
|
||||
}
|
||||
v, err := DiskUsage(path)
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
if v.Path != path {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisk_partitions(t *testing.T) {
|
||||
ret, err := DiskPartitions(false)
|
||||
if err != nil || len(ret) == 0 {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
empty := DiskPartitionStat{}
|
||||
for _, disk := range ret {
|
||||
if disk == empty {
|
||||
t.Errorf("Could not get device info %v", disk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisk_io_counters(t *testing.T) {
|
||||
ret, err := DiskIOCounters()
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
if len(ret) == 0 {
|
||||
t.Errorf("ret is empty, %v", ret)
|
||||
}
|
||||
empty := DiskIOCountersStat{}
|
||||
for part, io := range ret {
|
||||
if io == empty {
|
||||
t.Errorf("io_counter error %v, %v", part, io)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiskUsageStat_String(t *testing.T) {
|
||||
v := DiskUsageStat{
|
||||
Path: "/",
|
||||
Total: 1000,
|
||||
Free: 2000,
|
||||
Used: 3000,
|
||||
UsedPercent: 50.1,
|
||||
InodesTotal: 4000,
|
||||
InodesUsed: 5000,
|
||||
InodesFree: 6000,
|
||||
InodesUsedPercent: 49.1,
|
||||
Fstype: "ext4",
|
||||
}
|
||||
e := `{"path":"/","fstype":"ext4","total":1000,"free":2000,"used":3000,"used_percent":50.1,"inodes_total":4000,"inodes_used":5000,"inodes_free":6000,"inodes_used_percent":49.1}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("DiskUsageStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiskPartitionStat_String(t *testing.T) {
|
||||
v := DiskPartitionStat{
|
||||
Device: "sd01",
|
||||
Mountpoint: "/",
|
||||
Fstype: "ext4",
|
||||
Opts: "ro",
|
||||
}
|
||||
e := `{"device":"sd01","mountpoint":"/","fstype":"ext4","opts":"ro"}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("DiskUsageStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiskIOCountersStat_String(t *testing.T) {
|
||||
v := DiskIOCountersStat{
|
||||
Name: "sd01",
|
||||
ReadCount: 100,
|
||||
WriteCount: 200,
|
||||
ReadBytes: 300,
|
||||
WriteBytes: 400,
|
||||
SerialNumber: "SERIAL",
|
||||
}
|
||||
e := `{"read_count":100,"write_count":200,"read_bytes":300,"write_bytes":400,"read_time":0,"write_time":0,"name":"sd01","io_time":0,"serial_number":"SERIAL"}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("DiskUsageStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
30
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go
generated
vendored
Normal file
30
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_unix.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// +build freebsd linux darwin
|
||||
|
||||
package disk
|
||||
|
||||
import "syscall"
|
||||
|
||||
func DiskUsage(path string) (*DiskUsageStat, error) {
|
||||
stat := syscall.Statfs_t{}
|
||||
err := syscall.Statfs(path, &stat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bsize := stat.Bsize
|
||||
|
||||
ret := &DiskUsageStat{
|
||||
Path: path,
|
||||
Fstype: getFsType(stat),
|
||||
Total: (uint64(stat.Blocks) * uint64(bsize)),
|
||||
Free: (uint64(stat.Bfree) * uint64(bsize)),
|
||||
InodesTotal: (uint64(stat.Files)),
|
||||
InodesFree: (uint64(stat.Ffree)),
|
||||
}
|
||||
|
||||
ret.InodesUsed = (ret.InodesTotal - ret.InodesFree)
|
||||
ret.InodesUsedPercent = (float64(ret.InodesUsed) / float64(ret.InodesTotal)) * 100.0
|
||||
ret.Used = (uint64(stat.Blocks) - uint64(stat.Bfree)) * uint64(bsize)
|
||||
ret.UsedPercent = (float64(ret.Used) / float64(ret.Total)) * 100.0
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
155
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go
generated
vendored
Normal file
155
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/disk_windows.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
// +build windows
|
||||
|
||||
package disk
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/StackExchange/wmi"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
var (
|
||||
procGetDiskFreeSpaceExW = common.Modkernel32.NewProc("GetDiskFreeSpaceExW")
|
||||
procGetLogicalDriveStringsW = common.Modkernel32.NewProc("GetLogicalDriveStringsW")
|
||||
procGetDriveType = common.Modkernel32.NewProc("GetDriveTypeW")
|
||||
provGetVolumeInformation = common.Modkernel32.NewProc("GetVolumeInformationW")
|
||||
)
|
||||
|
||||
var (
|
||||
FileFileCompression = int64(16) // 0x00000010
|
||||
FileReadOnlyVolume = int64(524288) // 0x00080000
|
||||
)
|
||||
|
||||
type Win32_PerfFormattedData struct {
|
||||
Name string
|
||||
AvgDiskBytesPerRead uint64
|
||||
AvgDiskBytesPerWrite uint64
|
||||
AvgDiskReadQueueLength uint64
|
||||
AvgDiskWriteQueueLength uint64
|
||||
AvgDisksecPerRead uint64
|
||||
AvgDisksecPerWrite uint64
|
||||
}
|
||||
|
||||
const WaitMSec = 500
|
||||
|
||||
func DiskUsage(path string) (*DiskUsageStat, error) {
|
||||
ret := &DiskUsageStat{}
|
||||
|
||||
lpFreeBytesAvailable := int64(0)
|
||||
lpTotalNumberOfBytes := int64(0)
|
||||
lpTotalNumberOfFreeBytes := int64(0)
|
||||
diskret, _, err := procGetDiskFreeSpaceExW.Call(
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
|
||||
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
|
||||
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
|
||||
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
|
||||
if diskret == 0 {
|
||||
return nil, err
|
||||
}
|
||||
ret = &DiskUsageStat{
|
||||
Path: path,
|
||||
Total: uint64(lpTotalNumberOfBytes),
|
||||
Free: uint64(lpTotalNumberOfFreeBytes),
|
||||
Used: uint64(lpTotalNumberOfBytes) - uint64(lpTotalNumberOfFreeBytes),
|
||||
UsedPercent: (float64(lpTotalNumberOfBytes) - float64(lpTotalNumberOfFreeBytes)) / float64(lpTotalNumberOfBytes) * 100,
|
||||
// InodesTotal: 0,
|
||||
// InodesFree: 0,
|
||||
// InodesUsed: 0,
|
||||
// InodesUsedPercent: 0,
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DiskPartitions(all bool) ([]DiskPartitionStat, error) {
|
||||
var ret []DiskPartitionStat
|
||||
lpBuffer := make([]byte, 254)
|
||||
diskret, _, err := procGetLogicalDriveStringsW.Call(
|
||||
uintptr(len(lpBuffer)),
|
||||
uintptr(unsafe.Pointer(&lpBuffer[0])))
|
||||
if diskret == 0 {
|
||||
return ret, err
|
||||
}
|
||||
for _, v := range lpBuffer {
|
||||
if v >= 65 && v <= 90 {
|
||||
path := string(v) + ":"
|
||||
if path == "A:" || path == "B:" { // skip floppy drives
|
||||
continue
|
||||
}
|
||||
typepath, _ := syscall.UTF16PtrFromString(path)
|
||||
typeret, _, _ := procGetDriveType.Call(uintptr(unsafe.Pointer(typepath)))
|
||||
if typeret == 0 {
|
||||
return ret, syscall.GetLastError()
|
||||
}
|
||||
// 2: DRIVE_REMOVABLE 3: DRIVE_FIXED 5: DRIVE_CDROM
|
||||
|
||||
if typeret == 2 || typeret == 3 || typeret == 5 {
|
||||
lpVolumeNameBuffer := make([]byte, 256)
|
||||
lpVolumeSerialNumber := int64(0)
|
||||
lpMaximumComponentLength := int64(0)
|
||||
lpFileSystemFlags := int64(0)
|
||||
lpFileSystemNameBuffer := make([]byte, 256)
|
||||
volpath, _ := syscall.UTF16PtrFromString(string(v) + ":/")
|
||||
driveret, _, err := provGetVolumeInformation.Call(
|
||||
uintptr(unsafe.Pointer(volpath)),
|
||||
uintptr(unsafe.Pointer(&lpVolumeNameBuffer[0])),
|
||||
uintptr(len(lpVolumeNameBuffer)),
|
||||
uintptr(unsafe.Pointer(&lpVolumeSerialNumber)),
|
||||
uintptr(unsafe.Pointer(&lpMaximumComponentLength)),
|
||||
uintptr(unsafe.Pointer(&lpFileSystemFlags)),
|
||||
uintptr(unsafe.Pointer(&lpFileSystemNameBuffer[0])),
|
||||
uintptr(len(lpFileSystemNameBuffer)))
|
||||
if driveret == 0 {
|
||||
if typeret == 5 {
|
||||
continue //device is not ready will happen if there is no disk in the drive
|
||||
}
|
||||
return ret, err
|
||||
}
|
||||
opts := "rw"
|
||||
if lpFileSystemFlags&FileReadOnlyVolume != 0 {
|
||||
opts = "ro"
|
||||
}
|
||||
if lpFileSystemFlags&FileFileCompression != 0 {
|
||||
opts += ".compress"
|
||||
}
|
||||
|
||||
d := DiskPartitionStat{
|
||||
Mountpoint: path,
|
||||
Device: path,
|
||||
Fstype: string(bytes.Replace(lpFileSystemNameBuffer, []byte("\x00"), []byte(""), -1)),
|
||||
Opts: opts,
|
||||
}
|
||||
ret = append(ret, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func DiskIOCounters() (map[string]DiskIOCountersStat, error) {
|
||||
ret := make(map[string]DiskIOCountersStat, 0)
|
||||
var dst []Win32_PerfFormattedData
|
||||
|
||||
err := wmi.Query("SELECT * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk ", &dst)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
for _, d := range dst {
|
||||
if len(d.Name) > 3 { // not get _Total or Harddrive
|
||||
continue
|
||||
}
|
||||
ret[d.Name] = DiskIOCountersStat{
|
||||
Name: d.Name,
|
||||
ReadCount: uint64(d.AvgDiskReadQueueLength),
|
||||
WriteCount: d.AvgDiskWriteQueueLength,
|
||||
ReadBytes: uint64(d.AvgDiskBytesPerRead),
|
||||
WriteBytes: uint64(d.AvgDiskBytesPerWrite),
|
||||
ReadTime: d.AvgDisksecPerRead,
|
||||
WriteTime: d.AvgDisksecPerWrite,
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
85
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/types_freebsd.go
generated
vendored
Normal file
85
Godeps/_workspace/src/github.com/shirou/gopsutil/disk/types_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
// +build ignore
|
||||
// Hand writing: _Ctype_struct___0
|
||||
|
||||
/*
|
||||
Input to cgo -godefs.
|
||||
|
||||
*/
|
||||
|
||||
package disk
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <devstat.h>
|
||||
|
||||
enum {
|
||||
sizeofPtr = sizeof(void*),
|
||||
};
|
||||
|
||||
// because statinfo has long double snap_time, redefine with changing long long
|
||||
struct statinfo2 {
|
||||
long cp_time[CPUSTATES];
|
||||
long tk_nin;
|
||||
long tk_nout;
|
||||
struct devinfo *dinfo;
|
||||
long long snap_time;
|
||||
};
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// Machine characteristics; for internal use.
|
||||
|
||||
const (
|
||||
sizeofPtr = C.sizeofPtr
|
||||
sizeofShort = C.sizeof_short
|
||||
sizeofInt = C.sizeof_int
|
||||
sizeofLong = C.sizeof_long
|
||||
sizeofLongLong = C.sizeof_longlong
|
||||
sizeofLongDouble = C.sizeof_longlong
|
||||
|
||||
DEVSTAT_NO_DATA = 0x00
|
||||
DEVSTAT_READ = 0x01
|
||||
DEVSTAT_WRITE = 0x02
|
||||
DEVSTAT_FREE = 0x03
|
||||
|
||||
// from sys/mount.h
|
||||
MNT_RDONLY = 0x00000001 /* read only filesystem */
|
||||
MNT_SYNCHRONOUS = 0x00000002 /* filesystem written synchronously */
|
||||
MNT_NOEXEC = 0x00000004 /* can't exec from filesystem */
|
||||
MNT_NOSUID = 0x00000008 /* don't honor setuid bits on fs */
|
||||
MNT_UNION = 0x00000020 /* union with underlying filesystem */
|
||||
MNT_ASYNC = 0x00000040 /* filesystem written asynchronously */
|
||||
MNT_SUIDDIR = 0x00100000 /* special handling of SUID on dirs */
|
||||
MNT_SOFTDEP = 0x00200000 /* soft updates being done */
|
||||
MNT_NOSYMFOLLOW = 0x00400000 /* do not follow symlinks */
|
||||
MNT_GJOURNAL = 0x02000000 /* GEOM journal support enabled */
|
||||
MNT_MULTILABEL = 0x04000000 /* MAC support for individual objects */
|
||||
MNT_ACLS = 0x08000000 /* ACL support enabled */
|
||||
MNT_NOATIME = 0x10000000 /* disable update of file access time */
|
||||
MNT_NOCLUSTERR = 0x40000000 /* disable cluster read */
|
||||
MNT_NOCLUSTERW = 0x80000000 /* disable cluster write */
|
||||
MNT_NFS4ACLS = 0x00000010
|
||||
|
||||
MNT_WAIT = 1 /* synchronously wait for I/O to complete */
|
||||
MNT_NOWAIT = 2 /* start all I/O, but do not wait for it */
|
||||
MNT_LAZY = 3 /* push data not written by filesystem syncer */
|
||||
MNT_SUSPEND = 4 /* Suspend file system after sync */
|
||||
|
||||
)
|
||||
|
||||
// Basic types
|
||||
|
||||
type (
|
||||
_C_short C.short
|
||||
_C_int C.int
|
||||
_C_long C.long
|
||||
_C_long_long C.longlong
|
||||
_C_long_double C.longlong
|
||||
)
|
||||
|
||||
type Statfs C.struct_statfs
|
||||
type Fsid C.struct_fsid
|
||||
|
||||
type Devstat C.struct_devstat
|
||||
type Bintime C.struct_bintime
|
||||
38
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem.go
generated
vendored
Normal file
38
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
package mem
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type VirtualMemoryStat struct {
|
||||
Total uint64 `json:"total"`
|
||||
Available uint64 `json:"available"`
|
||||
Used uint64 `json:"used"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
Free uint64 `json:"free"`
|
||||
Active uint64 `json:"active"`
|
||||
Inactive uint64 `json:"inactive"`
|
||||
Buffers uint64 `json:"buffers"`
|
||||
Cached uint64 `json:"cached"`
|
||||
Wired uint64 `json:"wired"`
|
||||
Shared uint64 `json:"shared"`
|
||||
}
|
||||
|
||||
type SwapMemoryStat struct {
|
||||
Total uint64 `json:"total"`
|
||||
Used uint64 `json:"used"`
|
||||
Free uint64 `json:"free"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
Sin uint64 `json:"sin"`
|
||||
Sout uint64 `json:"sout"`
|
||||
}
|
||||
|
||||
func (m VirtualMemoryStat) String() string {
|
||||
s, _ := json.Marshal(m)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (m SwapMemoryStat) String() string {
|
||||
s, _ := json.Marshal(m)
|
||||
return string(s)
|
||||
}
|
||||
153
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go
generated
vendored
Normal file
153
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin.go
generated
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// +build darwin
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func getPageSize() (uint64, error) {
|
||||
out, err := exec.Command("pagesize").Output()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
o := strings.TrimSpace(string(out))
|
||||
p, err := strconv.ParseUint(o, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Runs vm_stat and returns Free and inactive pages
|
||||
func getVmStat(pagesize uint64, vms *VirtualMemoryStat) error {
|
||||
out, err := exec.Command("vm_stat").Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return parseVmStat(string(out), pagesize, vms)
|
||||
}
|
||||
|
||||
func parseVmStat(out string, pagesize uint64, vms *VirtualMemoryStat) error {
|
||||
var err error
|
||||
|
||||
lines := strings.Split(out, "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Split(line, ":")
|
||||
if len(fields) < 2 {
|
||||
continue
|
||||
}
|
||||
key := strings.TrimSpace(fields[0])
|
||||
value := strings.Trim(fields[1], " .")
|
||||
switch key {
|
||||
case "Pages free":
|
||||
free, e := strconv.ParseUint(value, 10, 64)
|
||||
if e != nil {
|
||||
err = e
|
||||
}
|
||||
vms.Free = free * pagesize
|
||||
case "Pages inactive":
|
||||
inactive, e := strconv.ParseUint(value, 10, 64)
|
||||
if e != nil {
|
||||
err = e
|
||||
}
|
||||
vms.Cached += inactive * pagesize
|
||||
vms.Inactive = inactive * pagesize
|
||||
case "Pages active":
|
||||
active, e := strconv.ParseUint(value, 10, 64)
|
||||
if e != nil {
|
||||
err = e
|
||||
}
|
||||
vms.Active = active * pagesize
|
||||
case "Pages wired down":
|
||||
wired, e := strconv.ParseUint(value, 10, 64)
|
||||
if e != nil {
|
||||
err = e
|
||||
}
|
||||
vms.Wired = wired * pagesize
|
||||
case "Pages purgeable":
|
||||
purgeable, e := strconv.ParseUint(value, 10, 64)
|
||||
if e != nil {
|
||||
err = e
|
||||
}
|
||||
vms.Cached += purgeable * pagesize
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// VirtualMemory returns VirtualmemoryStat.
|
||||
func VirtualMemory() (*VirtualMemoryStat, error) {
|
||||
ret := &VirtualMemoryStat{}
|
||||
|
||||
p, err := getPageSize()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t, err := common.DoSysctrl("hw.memsize")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
total, err := strconv.ParseUint(t[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = getVmStat(p, ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret.Available = ret.Free + ret.Cached
|
||||
ret.Total = total
|
||||
|
||||
ret.Used = ret.Total - ret.Free
|
||||
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// SwapMemory returns swapinfo.
|
||||
func SwapMemory() (*SwapMemoryStat, error) {
|
||||
var ret *SwapMemoryStat
|
||||
|
||||
swapUsage, err := common.DoSysctrl("vm.swapusage")
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
total := strings.Replace(swapUsage[2], "M", "", 1)
|
||||
used := strings.Replace(swapUsage[5], "M", "", 1)
|
||||
free := strings.Replace(swapUsage[8], "M", "", 1)
|
||||
|
||||
total_v, err := strconv.ParseFloat(total, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
used_v, err := strconv.ParseFloat(used, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
free_v, err := strconv.ParseFloat(free, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := float64(0)
|
||||
if total_v != 0 {
|
||||
u = ((total_v - free_v) / total_v) * 100.0
|
||||
}
|
||||
|
||||
// vm.swapusage shows "M", multiply 1000
|
||||
ret = &SwapMemoryStat{
|
||||
Total: uint64(total_v * 1000),
|
||||
Used: uint64(used_v * 1000),
|
||||
Free: uint64(free_v * 1000),
|
||||
UsedPercent: u,
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
67
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin_test.go
generated
vendored
Normal file
67
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_darwin_test.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
// +build darwin
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
var vm_stat_out = `
|
||||
Mach Virtual Memory Statistics: (page size of 4096 bytes)
|
||||
Pages free: 105885.
|
||||
Pages active: 725641.
|
||||
Pages inactive: 449242.
|
||||
Pages speculative: 6155.
|
||||
Pages throttled: 0.
|
||||
Pages wired down: 560835.
|
||||
Pages purgeable: 128967.
|
||||
"Translation faults": 622528839.
|
||||
Pages copy-on-write: 17697839.
|
||||
Pages zero filled: 311034413.
|
||||
Pages reactivated: 4705104.
|
||||
Pages purged: 5605610.
|
||||
File-backed pages: 349192.
|
||||
Anonymous pages: 831846.
|
||||
Pages stored in compressor: 876507.
|
||||
Pages occupied by compressor: 249167.
|
||||
Decompressions: 4555025.
|
||||
Compressions: 7524729.
|
||||
Pageins: 40532443.
|
||||
Pageouts: 126496.
|
||||
Swapins: 2988073.
|
||||
Swapouts: 3283599.
|
||||
`
|
||||
|
||||
func TestParseVmStat(t *testing.T) {
|
||||
ret := &VirtualMemoryStat{}
|
||||
err := parseVmStat(vm_stat_out, 4096, ret)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %s\n", err.Error())
|
||||
}
|
||||
|
||||
if ret.Free != uint64(105885*4096) {
|
||||
t.Errorf("Free pages, actual: %d, expected: %d", ret.Free,
|
||||
105885*4096)
|
||||
}
|
||||
|
||||
if ret.Inactive != uint64(449242*4096) {
|
||||
t.Errorf("Inactive pages, actual: %d, expected: %d", ret.Inactive,
|
||||
449242*4096)
|
||||
}
|
||||
|
||||
if ret.Active != uint64(725641*4096) {
|
||||
t.Errorf("Active pages, actual: %d, expected: %d", ret.Active,
|
||||
725641*4096)
|
||||
}
|
||||
|
||||
if ret.Wired != uint64(560835*4096) {
|
||||
t.Errorf("Wired pages, actual: %d, expected: %d", ret.Wired,
|
||||
560835*4096)
|
||||
}
|
||||
|
||||
if ret.Cached != uint64(128967*4096+449242.*4096) {
|
||||
t.Errorf("Cached pages, actual: %d, expected: %d", ret.Cached,
|
||||
128967*4096+449242.*4096)
|
||||
}
|
||||
}
|
||||
129
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go
generated
vendored
Normal file
129
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
// +build freebsd
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func VirtualMemory() (*VirtualMemoryStat, error) {
|
||||
pageSize, err := common.DoSysctrl("vm.stats.vm.v_page_size")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p, err := strconv.ParseUint(pageSize[0], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageCount, err := common.DoSysctrl("vm.stats.vm.v_page_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
free, err := common.DoSysctrl("vm.stats.vm.v_free_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
active, err := common.DoSysctrl("vm.stats.vm.v_active_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inactive, err := common.DoSysctrl("vm.stats.vm.v_inactive_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cache, err := common.DoSysctrl("vm.stats.vm.v_cache_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buffer, err := common.DoSysctrl("vfs.bufspace")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wired, err := common.DoSysctrl("vm.stats.vm.v_wire_count")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parsed := make([]uint64, 0, 7)
|
||||
vv := []string{
|
||||
pageCount[0],
|
||||
free[0],
|
||||
active[0],
|
||||
inactive[0],
|
||||
cache[0],
|
||||
buffer[0],
|
||||
wired[0],
|
||||
}
|
||||
for _, target := range vv {
|
||||
t, err := strconv.ParseUint(target, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parsed = append(parsed, t)
|
||||
}
|
||||
|
||||
ret := &VirtualMemoryStat{
|
||||
Total: parsed[0] * p,
|
||||
Free: parsed[1] * p,
|
||||
Active: parsed[2] * p,
|
||||
Inactive: parsed[3] * p,
|
||||
Cached: parsed[4] * p,
|
||||
Buffers: parsed[5],
|
||||
Wired: parsed[6] * p,
|
||||
}
|
||||
|
||||
ret.Available = ret.Inactive + ret.Cached + ret.Free
|
||||
ret.Used = ret.Active + ret.Wired + ret.Cached
|
||||
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Return swapinfo
|
||||
// FreeBSD can have multiple swap devices. but use only first device
|
||||
func SwapMemory() (*SwapMemoryStat, error) {
|
||||
out, err := exec.Command("swapinfo").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ret *SwapMemoryStat
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
values := strings.Fields(line)
|
||||
// skip title line
|
||||
if len(values) == 0 || values[0] == "Device" {
|
||||
continue
|
||||
}
|
||||
|
||||
u := strings.Replace(values[4], "%", "", 1)
|
||||
total_v, err := strconv.ParseUint(values[1], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
used_v, err := strconv.ParseUint(values[2], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
free_v, err := strconv.ParseUint(values[3], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
up_v, err := strconv.ParseFloat(u, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret = &SwapMemoryStat{
|
||||
Total: total_v,
|
||||
Used: used_v,
|
||||
Free: free_v,
|
||||
UsedPercent: up_v,
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
99
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go
generated
vendored
Normal file
99
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_linux.go
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
// +build linux
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
func VirtualMemory() (*VirtualMemoryStat, error) {
|
||||
filename := "/proc/meminfo"
|
||||
lines, _ := common.ReadLines(filename)
|
||||
// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
|
||||
memavail := false
|
||||
|
||||
ret := &VirtualMemoryStat{}
|
||||
for _, line := range lines {
|
||||
fields := strings.Split(line, ":")
|
||||
if len(fields) != 2 {
|
||||
continue
|
||||
}
|
||||
key := strings.TrimSpace(fields[0])
|
||||
value := strings.TrimSpace(fields[1])
|
||||
value = strings.Replace(value, " kB", "", -1)
|
||||
|
||||
t, err := strconv.ParseUint(value, 10, 64)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
switch key {
|
||||
case "MemTotal":
|
||||
ret.Total = t * 1024
|
||||
case "MemFree":
|
||||
ret.Free = t * 1024
|
||||
case "MemAvailable":
|
||||
memavail = true
|
||||
ret.Available = t * 1024
|
||||
case "Buffers":
|
||||
ret.Buffers = t * 1024
|
||||
case "Cached":
|
||||
ret.Cached = t * 1024
|
||||
case "Active":
|
||||
ret.Active = t * 1024
|
||||
case "Inactive":
|
||||
ret.Inactive = t * 1024
|
||||
}
|
||||
}
|
||||
if !memavail {
|
||||
ret.Available = ret.Free + ret.Buffers + ret.Cached
|
||||
}
|
||||
ret.Used = ret.Total - ret.Free
|
||||
ret.UsedPercent = float64(ret.Total-ret.Available) / float64(ret.Total) * 100.0
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func SwapMemory() (*SwapMemoryStat, error) {
|
||||
sysinfo := &syscall.Sysinfo_t{}
|
||||
|
||||
if err := syscall.Sysinfo(sysinfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SwapMemoryStat{
|
||||
Total: uint64(sysinfo.Totalswap),
|
||||
Free: uint64(sysinfo.Freeswap),
|
||||
}
|
||||
ret.Used = ret.Total - ret.Free
|
||||
//check Infinity
|
||||
if ret.Total != 0 {
|
||||
ret.UsedPercent = float64(ret.Total-ret.Free) / float64(ret.Total) * 100.0
|
||||
} else {
|
||||
ret.UsedPercent = 0
|
||||
}
|
||||
lines, _ := common.ReadLines("/proc/vmstat")
|
||||
for _, l := range lines {
|
||||
fields := strings.Fields(l)
|
||||
if len(fields) < 2 {
|
||||
continue
|
||||
}
|
||||
switch fields[0] {
|
||||
case "pswpin":
|
||||
value, err := strconv.ParseUint(fields[1], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret.Sin = value * 4 * 1024
|
||||
case "pswpout":
|
||||
value, err := strconv.ParseUint(fields[1], 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret.Sout = value * 4 * 1024
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
55
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_test.go
generated
vendored
Normal file
55
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_test.go
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
package mem
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVirtual_memory(t *testing.T) {
|
||||
v, err := VirtualMemory()
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
empty := &VirtualMemoryStat{}
|
||||
if v == empty {
|
||||
t.Errorf("error %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwap_memory(t *testing.T) {
|
||||
v, err := SwapMemory()
|
||||
if err != nil {
|
||||
t.Errorf("error %v", err)
|
||||
}
|
||||
empty := &SwapMemoryStat{}
|
||||
if v == empty {
|
||||
t.Errorf("error %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVirtualMemoryStat_String(t *testing.T) {
|
||||
v := VirtualMemoryStat{
|
||||
Total: 10,
|
||||
Available: 20,
|
||||
Used: 30,
|
||||
UsedPercent: 30.1,
|
||||
Free: 40,
|
||||
}
|
||||
e := `{"total":10,"available":20,"used":30,"used_percent":30.1,"free":40,"active":0,"inactive":0,"buffers":0,"cached":0,"wired":0,"shared":0}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("VirtualMemoryStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSwapMemoryStat_String(t *testing.T) {
|
||||
v := SwapMemoryStat{
|
||||
Total: 10,
|
||||
Used: 30,
|
||||
Free: 40,
|
||||
UsedPercent: 30.1,
|
||||
}
|
||||
e := `{"total":10,"used":30,"free":40,"used_percent":30.1,"sin":0,"sout":0}`
|
||||
if e != fmt.Sprintf("%v", v) {
|
||||
t.Errorf("SwapMemoryStat string is invalid: %v", v)
|
||||
}
|
||||
}
|
||||
50
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go
generated
vendored
Normal file
50
Godeps/_workspace/src/github.com/shirou/gopsutil/mem/mem_windows.go
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
// +build windows
|
||||
|
||||
package mem
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
common "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/common"
|
||||
)
|
||||
|
||||
var (
|
||||
procGlobalMemoryStatusEx = common.Modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||
)
|
||||
|
||||
type MEMORYSTATUSEX struct {
|
||||
cbSize uint32
|
||||
dwMemoryLoad uint32
|
||||
ullTotalPhys uint64 // in bytes
|
||||
ullAvailPhys uint64
|
||||
ullTotalPageFile uint64
|
||||
ullAvailPageFile uint64
|
||||
ullTotalVirtual uint64
|
||||
ullAvailVirtual uint64
|
||||
ullAvailExtendedVirtual uint64
|
||||
}
|
||||
|
||||
func VirtualMemory() (*VirtualMemoryStat, error) {
|
||||
var memInfo MEMORYSTATUSEX
|
||||
memInfo.cbSize = uint32(unsafe.Sizeof(memInfo))
|
||||
mem, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&memInfo)))
|
||||
if mem == 0 {
|
||||
return nil, syscall.GetLastError()
|
||||
}
|
||||
|
||||
ret := &VirtualMemoryStat{
|
||||
Total: memInfo.ullTotalPhys,
|
||||
Available: memInfo.ullAvailPhys,
|
||||
UsedPercent: float64(memInfo.dwMemoryLoad),
|
||||
}
|
||||
|
||||
ret.Used = ret.Total - ret.Available
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func SwapMemory() (*SwapMemoryStat, error) {
|
||||
ret := &SwapMemoryStat{}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
@ -103,7 +103,6 @@ var cmdDetailsMap = map[*cmds.Command]cmdDetails{
|
||||
daemonCmd: {doesNotUseConfigAsInput: true, cannotRunOnDaemon: true},
|
||||
commandsClientCmd: {doesNotUseRepo: true},
|
||||
commands.CommandsDaemonCmd: {doesNotUseRepo: true},
|
||||
commands.DiagCmd: {cannotRunOnClient: true},
|
||||
commands.VersionCmd: {doesNotUseConfigAsInput: true, doesNotUseRepo: true}, // must be permitted to run before init
|
||||
commands.UpdateCmd: {preemptsAutoUpdate: true, cannotRunOnDaemon: true},
|
||||
commands.UpdateCheckCmd: {preemptsAutoUpdate: true},
|
||||
|
||||
@ -46,6 +46,7 @@ var DiagCmd = &cmds.Command{
|
||||
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"net": diagNetCmd,
|
||||
"sys": sysDiagCmd,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
138
core/commands/sysdiag.go
Normal file
138
core/commands/sysdiag.go
Normal file
@ -0,0 +1,138 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
|
||||
manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
||||
psud "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/disk"
|
||||
psum "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
var sysDiagCmd = &cmds.Command{
|
||||
Helptext: cmds.HelpText{
|
||||
Tagline: "prints out system diagnostic information.",
|
||||
ShortDescription: `
|
||||
Prints out information about your computer to aid in easier debugging.
|
||||
`,
|
||||
},
|
||||
Run: func(req cmds.Request, res cmds.Response) {
|
||||
info := make(map[string]interface{})
|
||||
err := runtimeInfo(info)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
err = envVarInfo(info)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
err = diskSpaceInfo(info)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
err = memInfo(info)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
err = netInfo(info)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
|
||||
res.SetOutput(info)
|
||||
},
|
||||
}
|
||||
|
||||
func runtimeInfo(out map[string]interface{}) error {
|
||||
rt := make(map[string]interface{})
|
||||
rt["os"] = runtime.GOOS
|
||||
rt["arch"] = runtime.GOARCH
|
||||
rt["compiler"] = runtime.Compiler
|
||||
rt["version"] = runtime.Version()
|
||||
rt["numcpu"] = runtime.NumCPU()
|
||||
rt["gomaxprocs"] = runtime.GOMAXPROCS(0)
|
||||
rt["numgoroutines"] = runtime.NumGoroutine()
|
||||
|
||||
out["runtime"] = rt
|
||||
return nil
|
||||
}
|
||||
|
||||
func envVarInfo(out map[string]interface{}) error {
|
||||
ev := make(map[string]interface{})
|
||||
ev["GOPATH"] = os.Getenv("GOPATH")
|
||||
ev["IPFS_PATH"] = os.Getenv("IPFS_PATH")
|
||||
|
||||
out["environment"] = ev
|
||||
return nil
|
||||
}
|
||||
|
||||
func ipfsPath() string {
|
||||
p := os.Getenv("IPFS_PATH")
|
||||
if p == "" {
|
||||
p = path.Join(os.Getenv("HOME"), ".ipfs")
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func diskSpaceInfo(out map[string]interface{}) error {
|
||||
di := make(map[string]interface{})
|
||||
dinfo, err := psud.DiskUsage(ipfsPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
di["fstype"] = dinfo.Fstype
|
||||
di["total_space"] = dinfo.Total
|
||||
di["used_space"] = dinfo.Used
|
||||
di["free_space"] = dinfo.Free
|
||||
|
||||
out["diskinfo"] = di
|
||||
return nil
|
||||
}
|
||||
|
||||
func memInfo(out map[string]interface{}) error {
|
||||
m := make(map[string]interface{})
|
||||
swap, err := psum.SwapMemory()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
virt, err := psum.VirtualMemory()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m["swap"] = swap
|
||||
m["virt"] = virt
|
||||
out["memory"] = m
|
||||
return nil
|
||||
}
|
||||
|
||||
func netInfo(out map[string]interface{}) error {
|
||||
n := make(map[string]interface{})
|
||||
addrs, err := manet.InterfaceMultiaddrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var straddrs []string
|
||||
for _, a := range addrs {
|
||||
straddrs = append(straddrs, a.String())
|
||||
}
|
||||
|
||||
n["interface_addresses"] = straddrs
|
||||
out["net"] = n
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user