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 ab344b4c..daf3524f 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 2bff3403..e8e0e8df 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 8f3a632c..57beffae 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 dc89c796..be98dd79 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 1e8072b1..353991e8 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 fdc88ddd..947ac972 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 03b3407f..49f52c9c 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 bb83bfc9..f3c7ad6a 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 3e85cc06..dde5c390 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 fd08e859..85bda0e2 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 4e829e05..c65151a9 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 398f7854..ba73a7eb 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 0736bc41..08512733 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 1d941a08..ebebc2f0 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 f811f8b1..84b970ac 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 71c2257f..df72e654 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 750a5926..9e393bcf 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 a15af5ad..17be10f1 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 + 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 + } + } } - - 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 - } - - 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