From cae8efcffa765c9534442328d385bdd883faf5df Mon Sep 17 00:00:00 2001 From: shirou Date: Sat, 27 Apr 2019 13:45:12 +0900 Subject: [PATCH 1/3] [cpu]: remove unused field Stolen see #676 --- cpu/cpu.go | 6 ++---- cpu/cpu_test.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cpu/cpu.go b/cpu/cpu.go index ab344b4..daf3524 100644 --- a/cpu/cpu.go +++ b/cpu/cpu.go @@ -27,7 +27,6 @@ type TimesStat struct { Steal float64 `json:"steal"` Guest float64 `json:"guest"` GuestNice float64 `json:"guestNice"` - Stolen float64 `json:"stolen"` } type InfoStat struct { @@ -80,7 +79,6 @@ func (c TimesStat) String() string { `"steal":` + strconv.FormatFloat(c.Steal, 'f', 1, 64), `"guest":` + strconv.FormatFloat(c.Guest, 'f', 1, 64), `"guestNice":` + strconv.FormatFloat(c.GuestNice, 'f', 1, 64), - `"stolen":` + strconv.FormatFloat(c.Stolen, 'f', 1, 64), } return `{` + strings.Join(v, ",") + `}` @@ -89,7 +87,7 @@ func (c TimesStat) String() string { // Total returns the total number of seconds in a CPUTimesStat func (c TimesStat) Total() float64 { total := c.User + c.System + c.Nice + c.Iowait + c.Irq + c.Softirq + c.Steal + - c.Guest + c.GuestNice + c.Idle + c.Stolen + c.Guest + c.GuestNice + c.Idle return total } @@ -100,7 +98,7 @@ func (c InfoStat) String() string { func getAllBusy(t TimesStat) (float64, float64) { busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + - t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen + t.Softirq + t.Steal + t.Guest + t.GuestNice return busy + t.Idle, busy } diff --git a/cpu/cpu_test.go b/cpu/cpu_test.go index 2bff340..e8e0e8d 100644 --- a/cpu/cpu_test.go +++ b/cpu/cpu_test.go @@ -71,7 +71,7 @@ func TestCPUTimeStat_String(t *testing.T) { System: 200.1, Idle: 300.1, } - e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0,"stolen":0.0}` + e := `{"cpu":"cpu0","user":100.1,"system":200.1,"idle":300.1,"nice":0.0,"iowait":0.0,"irq":0.0,"softirq":0.0,"steal":0.0,"guest":0.0,"guestNice":0.0}` if e != fmt.Sprintf("%v", v) { t.Errorf("CPUTimesStat string is invalid: %v", v) } From 86c7289cccb77e0af53de140dffe722f0549e8ef Mon Sep 17 00:00:00 2001 From: Segflow Date: Sun, 5 May 2019 20:45:07 +0100 Subject: [PATCH 2/3] Fix: use filename in exec.LookPath instead of full path exec.LookPath searches for the file in the $PATH, which mean giving it an absolute path is against it's own purposes. --- cpu/cpu_freebsd.go | 2 +- cpu/cpu_linux.go | 2 +- cpu/cpu_openbsd.go | 2 +- cpu/cpu_solaris.go | 6 +++--- host/host_linux.go | 2 +- host/host_solaris.go | 10 +++++----- internal/common/common_darwin.go | 2 +- internal/common/common_freebsd.go | 2 +- internal/common/common_linux.go | 2 +- internal/common/common_openbsd.go | 2 +- mem/mem_solaris.go | 6 +++--- net/net_darwin.go | 4 ++-- net/net_freebsd.go | 2 +- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cpu/cpu_freebsd.go b/cpu/cpu_freebsd.go index 8f3a632..57beffa 100644 --- a/cpu/cpu_freebsd.go +++ b/cpu/cpu_freebsd.go @@ -26,7 +26,7 @@ var cpuTimesSize int var emptyTimes cpuTimes func init() { - getconf, err := exec.LookPath("/usr/bin/getconf") + getconf, err := exec.LookPath("getconf") if err != nil { return } diff --git a/cpu/cpu_linux.go b/cpu/cpu_linux.go index dc89c79..be98dd7 100644 --- a/cpu/cpu_linux.go +++ b/cpu/cpu_linux.go @@ -16,7 +16,7 @@ import ( var CPUTick = float64(100) func init() { - getconf, err := exec.LookPath("/usr/bin/getconf") + getconf, err := exec.LookPath("getconf") if err != nil { return } diff --git a/cpu/cpu_openbsd.go b/cpu/cpu_openbsd.go index 1e8072b..353991e 100644 --- a/cpu/cpu_openbsd.go +++ b/cpu/cpu_openbsd.go @@ -37,7 +37,7 @@ var ClocksPerSec = float64(128) func init() { func() { - getconf, err := exec.LookPath("/usr/bin/getconf") + getconf, err := exec.LookPath("getconf") if err != nil { return } diff --git a/cpu/cpu_solaris.go b/cpu/cpu_solaris.go index fdc88dd..947ac97 100644 --- a/cpu/cpu_solaris.go +++ b/cpu/cpu_solaris.go @@ -17,7 +17,7 @@ import ( var ClocksPerSec = float64(128) func init() { - getconf, err := exec.LookPath("/usr/bin/getconf") + getconf, err := exec.LookPath("getconf") if err != nil { return } @@ -44,7 +44,7 @@ func Info() ([]InfoStat, error) { } func InfoWithContext(ctx context.Context) ([]InfoStat, error) { - psrInfo, err := exec.LookPath("/usr/sbin/psrinfo") + psrInfo, err := exec.LookPath("psrinfo") if err != nil { return nil, fmt.Errorf("cannot find psrinfo: %s", err) } @@ -53,7 +53,7 @@ func InfoWithContext(ctx context.Context) ([]InfoStat, error) { return nil, fmt.Errorf("cannot execute psrinfo: %s", err) } - isaInfo, err := exec.LookPath("/usr/bin/isainfo") + isaInfo, err := exec.LookPath("isainfo") if err != nil { return nil, fmt.Errorf("cannot find isainfo: %s", err) } diff --git a/host/host_linux.go b/host/host_linux.go index 03b3407..49f52c9 100644 --- a/host/host_linux.go +++ b/host/host_linux.go @@ -279,7 +279,7 @@ func getLSB() (*LSB, error) { } } } else if common.PathExists("/usr/bin/lsb_release") { - lsb_release, err := exec.LookPath("/usr/bin/lsb_release") + lsb_release, err := exec.LookPath("lsb_release") if err != nil { return ret, err } diff --git a/host/host_solaris.go b/host/host_solaris.go index bb83bfc..f3c7ad6 100644 --- a/host/host_solaris.go +++ b/host/host_solaris.go @@ -33,7 +33,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { result.Hostname = hostname // Parse versions from output of `uname(1)` - uname, err := exec.LookPath("/usr/bin/uname") + uname, err := exec.LookPath("uname") if err != nil { return nil, err } @@ -85,7 +85,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { switch result.Platform { case "SmartOS": // If everything works, use the current zone ID as the HostID if present. - zonename, err := exec.LookPath("/usr/bin/zonename") + zonename, err := exec.LookPath("zonename") if err == nil { out, err := invoke.CommandWithContext(ctx, zonename) if err == nil { @@ -112,7 +112,7 @@ func InfoWithContext(ctx context.Context) (*InfoStat, error) { // this point there are no hardware facilities available. This behavior // matches that of other supported OSes. if result.HostID == "" { - hostID, err := exec.LookPath("/usr/bin/hostid") + hostID, err := exec.LookPath("hostid") if err == nil { out, err := invoke.CommandWithContext(ctx, hostID) if err == nil { @@ -151,7 +151,7 @@ func BootTime() (uint64, error) { } func BootTimeWithContext(ctx context.Context) (uint64, error) { - kstat, err := exec.LookPath("/usr/bin/kstat") + kstat, err := exec.LookPath("kstat") if err != nil { return 0, err } @@ -215,7 +215,7 @@ func KernelVersion() (string, error) { func KernelVersionWithContext(ctx context.Context) (string, error) { // Parse versions from output of `uname(1)` - uname, err := exec.LookPath("/usr/bin/uname") + uname, err := exec.LookPath("uname") if err != nil { return "", err } diff --git a/internal/common/common_darwin.go b/internal/common/common_darwin.go index 3e85cc0..dde5c39 100644 --- a/internal/common/common_darwin.go +++ b/internal/common/common_darwin.go @@ -13,7 +13,7 @@ import ( ) func DoSysctrlWithContext(ctx context.Context, mib string) ([]string, error) { - sysctl, err := exec.LookPath("/usr/sbin/sysctl") + sysctl, err := exec.LookPath("sysctl") if err != nil { return []string{}, err } diff --git a/internal/common/common_freebsd.go b/internal/common/common_freebsd.go index fd08e85..85bda0e 100644 --- a/internal/common/common_freebsd.go +++ b/internal/common/common_freebsd.go @@ -28,7 +28,7 @@ func SysctlUint(mib string) (uint64, error) { } func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("/sbin/sysctl") + sysctl, err := exec.LookPath("sysctl") if err != nil { return []string{}, err } diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index 4e829e0..c65151a 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -9,7 +9,7 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("/sbin/sysctl") + sysctl, err := exec.LookPath("sysctl") if err != nil { return []string{}, err } diff --git a/internal/common/common_openbsd.go b/internal/common/common_openbsd.go index 398f785..ba73a7e 100644 --- a/internal/common/common_openbsd.go +++ b/internal/common/common_openbsd.go @@ -12,7 +12,7 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - sysctl, err := exec.LookPath("/sbin/sysctl") + sysctl, err := exec.LookPath("sysctl") if err != nil { return []string{}, err } diff --git a/mem/mem_solaris.go b/mem/mem_solaris.go index 0736bc4..0851273 100644 --- a/mem/mem_solaris.go +++ b/mem/mem_solaris.go @@ -52,7 +52,7 @@ func SwapMemoryWithContext(ctx context.Context) (*SwapMemoryStat, error) { } func zoneName() (string, error) { - zonename, err := exec.LookPath("/usr/bin/zonename") + zonename, err := exec.LookPath("zonename") if err != nil { return "", err } @@ -69,7 +69,7 @@ func zoneName() (string, error) { var globalZoneMemoryCapacityMatch = regexp.MustCompile(`memory size: ([\d]+) Megabytes`) func globalZoneMemoryCapacity() (uint64, error) { - prtconf, err := exec.LookPath("/usr/sbin/prtconf") + prtconf, err := exec.LookPath("prtconf") if err != nil { return 0, err } @@ -96,7 +96,7 @@ func globalZoneMemoryCapacity() (uint64, error) { var kstatMatch = regexp.MustCompile(`([^\s]+)[\s]+([^\s]*)`) func nonGlobalZoneMemoryCapacity() (uint64, error) { - kstat, err := exec.LookPath("/usr/bin/kstat") + kstat, err := exec.LookPath("kstat") if err != nil { return 0, err } diff --git a/net/net_darwin.go b/net/net_darwin.go index 1d941a0..ebebc2f 100644 --- a/net/net_darwin.go +++ b/net/net_darwin.go @@ -174,7 +174,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, retIndex int ) - netstat, err := exec.LookPath("/usr/sbin/netstat") + netstat, err := exec.LookPath("netstat") if err != nil { return nil, err } @@ -204,7 +204,7 @@ func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, } } else { // duplicated interface, list all interfaces - ifconfig, err := exec.LookPath("/sbin/ifconfig") + ifconfig, err := exec.LookPath("ifconfig") if err != nil { return nil, err } diff --git a/net/net_freebsd.go b/net/net_freebsd.go index f811f8b..84b970a 100644 --- a/net/net_freebsd.go +++ b/net/net_freebsd.go @@ -17,7 +17,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { } func IOCountersWithContext(ctx context.Context, pernic bool) ([]IOCountersStat, error) { - netstat, err := exec.LookPath("/usr/bin/netstat") + netstat, err := exec.LookPath("netstat") if err != nil { return nil, err } From 0e0dd767df7e630443977625d8c74fdc791e96b5 Mon Sep 17 00:00:00 2001 From: Lomanic Date: Wed, 8 May 2019 17:56:14 +0200 Subject: [PATCH 3/3] [process][darwin] Fix #670 remove call to common.Pipeline (prone to race condition) Also properly parse lsof to get second txt record instead of hoping the 5th line is the right one (wrong data returned for pid 57) --- internal/common/common.go | 43 ------------------------------------------ internal/common/common_unix.go | 2 +- process/process_darwin.go | 33 ++++++++++++-------------------- 3 files changed, 13 insertions(+), 65 deletions(-) diff --git a/internal/common/common.go b/internal/common/common.go index 71c2257..df72e65 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -332,49 +332,6 @@ func HostRun(combineWith ...string) string { return GetEnv("HOST_RUN", "/run", combineWith...) } -// https://gist.github.com/kylelemons/1525278 -func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) { - // Require at least one command - if len(cmds) < 1 { - return nil, nil, nil - } - - // Collect the output from the command(s) - var output bytes.Buffer - var stderr bytes.Buffer - - last := len(cmds) - 1 - for i, cmd := range cmds[:last] { - var err error - // Connect each command's stdin to the previous command's stdout - if cmds[i+1].Stdin, err = cmd.StdoutPipe(); err != nil { - return nil, nil, err - } - // Connect each command's stderr to a buffer - cmd.Stderr = &stderr - } - - // Connect the output and error for the last command - cmds[last].Stdout, cmds[last].Stderr = &output, &stderr - - // Start each command - for _, cmd := range cmds { - if err := cmd.Start(); err != nil { - return output.Bytes(), stderr.Bytes(), err - } - } - - // Wait for each command to complete - for _, cmd := range cmds { - if err := cmd.Wait(); err != nil { - return output.Bytes(), stderr.Bytes(), err - } - } - - // Return the pipeline output and the collected standard error - return output.Bytes(), stderr.Bytes(), nil -} - // getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running // sysctl commands (see DoSysctrl). func getSysctrlEnv(env []string) []string { diff --git a/internal/common/common_unix.go b/internal/common/common_unix.go index 750a592..9e393bc 100644 --- a/internal/common/common_unix.go +++ b/internal/common/common_unix.go @@ -23,7 +23,7 @@ func CallLsofWithContext(ctx context.Context, invoke Invoker, pid int32, args .. } out, err := invoke.CommandWithContext(ctx, lsof, cmd...) if err != nil { - // if no pid found, lsof returnes code 1. + // if no pid found, lsof returns code 1. if err.Error() == "exit status 1" && len(out) == 0 { return []string{}, nil } diff --git a/process/process_darwin.go b/process/process_darwin.go index a15af5a..17be10f 100644 --- a/process/process_darwin.go +++ b/process/process_darwin.go @@ -108,30 +108,21 @@ func (p *Process) ExeWithContext(ctx context.Context) (string, error) { if err != nil { return "", err } - - awk_bin, err := exec.LookPath("awk") + out, err := invoke.CommandWithContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn") if err != nil { - return "", err + return "", fmt.Errorf("bad call to lsof: %s", err) } - - sed_bin, err := exec.LookPath("sed") - if err != nil { - return "", err - } - - lsof := exec.CommandContext(ctx, lsof_bin, "-p", strconv.Itoa(int(p.Pid)), "-Fpfn") - awk := exec.CommandContext(ctx, awk_bin, "NR==5{print}") - sed := exec.CommandContext(ctx, sed_bin, "s/n\\//\\//") - - output, _, err := common.Pipeline(lsof, awk, sed) - - if err != nil { - return "", err + txtFound := 0 + lines := strings.Split(string(out), "\n") + for i := 1; i < len(lines); i += 2 { + if lines[i] == "ftxt" { + txtFound++ + if txtFound == 2 { + return lines[i-1][1:], nil + } + } } - - ret := strings.TrimSpace(string(output)) - - return ret, nil + return "", fmt.Errorf("missing txt data returned by lsof") } // Cmdline returns the command line arguments of the process as a string with