From abb40865310b7e29d6c3182b8850a8a28a588d10 Mon Sep 17 00:00:00 2001 From: WAKAYAMA shirou Date: Sat, 15 Aug 2015 01:20:56 +0900 Subject: [PATCH] host[freebsd]: change to use utmpx for 9.0 or later. --- docker/docker_notlinux.go | 1 - host/host_freebsd.go | 60 ++++++++++++++++++++++++++++++++------ host/host_freebsd_amd64.go | 19 ++++++++++-- host/types_freebsd.go | 5 +++- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/docker/docker_notlinux.go b/docker/docker_notlinux.go index ff2f5e035..fb59e21cc 100644 --- a/docker/docker_notlinux.go +++ b/docker/docker_notlinux.go @@ -5,7 +5,6 @@ package docker import ( "encoding/json" - "github.com/shirou/gopsutil/common" "github.com/shirou/gopsutil/cpu" ) diff --git a/host/host_freebsd.go b/host/host_freebsd.go index 5b955b42b..edbd5dd69 100644 --- a/host/host_freebsd.go +++ b/host/host_freebsd.go @@ -77,9 +77,13 @@ func BootTime() (int64, error) { } func Users() ([]UserStat, error) { - utmpfile := "/var/run/utmp" - var ret []UserStat + utmpfile := "/var/run/utx.active" + if !common.PathExists(utmpfile) { + utmpfile = "/var/run/utmp" // before 9.0 + return getUsersFromUtmp(utmpfile) + } + var ret []UserStat file, err := os.Open(utmpfile) if err != nil { return ret, err @@ -90,24 +94,25 @@ func Users() ([]UserStat, error) { return ret, err } - u := Utmp{} - entrySize := int(unsafe.Sizeof(u)) + u := Utmpx{} + entrySize := int(unsafe.Sizeof(u)) - 3 + entrySize = 197 // TODO: why should 197 count := len(buf) / entrySize for i := 0; i < count; i++ { b := buf[i*entrySize : i*entrySize+entrySize] - - var u Utmp + var u Utmpx br := bytes.NewReader(b) err := binary.Read(br, binary.LittleEndian, &u) - if err != nil || u.Time == 0 { + if err != nil || u.Type != 4 { continue } + sec := (binary.LittleEndian.Uint32(u.Tv.Sec[:])) / 2 // TODO: user := UserStat{ - User: common.IntToString(u.Name[:]), + User: common.IntToString(u.User[:]), Terminal: common.IntToString(u.Line[:]), Host: common.IntToString(u.Host[:]), - Started: int(u.Time), + Started: int(sec), } ret = append(ret, user) @@ -141,3 +146,40 @@ func GetVirtualization() (string, string, error) { return system, role, nil } + +// before 9.0 +func getUsersFromUtmp(utmpfile string) ([]UserStat, error) { + var ret []UserStat + file, err := os.Open(utmpfile) + if err != nil { + return ret, err + } + buf, err := ioutil.ReadAll(file) + if err != nil { + return ret, err + } + + u := Utmp{} + entrySize := int(unsafe.Sizeof(u)) + count := len(buf) / entrySize + + for i := 0; i < count; i++ { + b := buf[i*entrySize : i*entrySize+entrySize] + var u Utmp + br := bytes.NewReader(b) + err := binary.Read(br, binary.LittleEndian, &u) + if err != nil || u.Time == 0 { + continue + } + user := UserStat{ + User: common.IntToString(u.Name[:]), + Terminal: common.IntToString(u.Line[:]), + Host: common.IntToString(u.Host[:]), + Started: int(u.Time), + } + + ret = append(ret, user) + } + + return ret, nil +} diff --git a/host/host_freebsd_amd64.go b/host/host_freebsd_amd64.go index 7706cbdea..46be58688 100644 --- a/host/host_freebsd_amd64.go +++ b/host/host_freebsd_amd64.go @@ -1,7 +1,5 @@ -// +build freebsd -// +build amd64 // Created by cgo -godefs - DO NOT EDIT -// cgo -godefs host/types_freebsd.go +// cgo -godefs types_freebsd.go package host @@ -26,3 +24,18 @@ type Utmp struct { Host [16]int8 Time int32 } +type Utmpx struct { + Type int16 + Tv Timeval + Id [8]int8 + Pid int32 + User [32]int8 + Line [16]int8 + Host [125]int8 + // Host [128]int8 + // X__ut_spare [64]int8 +} +type Timeval struct { + Sec [4]byte + Usec [3]byte +} diff --git a/host/types_freebsd.go b/host/types_freebsd.go index dd768f4b8..113b22eea 100644 --- a/host/types_freebsd.go +++ b/host/types_freebsd.go @@ -9,7 +9,8 @@ package host /* #define KERNEL #include -#include +#include +#include enum { sizeofPtr = sizeof(void*), @@ -38,3 +39,5 @@ type ( ) type Utmp C.struct_utmp +type Utmpx C.struct_utmpx +type Timeval C.struct_timeval