|
|
|
@ -101,7 +101,7 @@ func (p *Process) TgidWithContext(ctx context.Context) (int32, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) ExeWithContext(ctx context.Context) (string, error) {
|
|
|
|
|
return p.fillFromExeWithContext()
|
|
|
|
|
return p.fillFromExeWithContext(ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) CmdlineWithContext(ctx context.Context) (string, error) {
|
|
|
|
@ -121,7 +121,7 @@ func (p *Process) createTimeWithContext(ctx context.Context) (int64, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) CwdWithContext(ctx context.Context) (string, error) {
|
|
|
|
|
return p.fillFromCwdWithContext()
|
|
|
|
|
return p.fillFromCwdWithContext(ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
|
|
|
|
@ -135,7 +135,7 @@ func (p *Process) StatusWithContext(ctx context.Context) ([]string, error) {
|
|
|
|
|
func (p *Process) ForegroundWithContext(ctx context.Context) (bool, error) {
|
|
|
|
|
// see https://github.com/shirou/gopsutil/issues/596#issuecomment-432707831 for implementation details
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
statPath := common.HostProc(strconv.Itoa(int(pid)), "stat")
|
|
|
|
|
statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "stat")
|
|
|
|
|
contents, err := ioutil.ReadFile(statPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return false, err
|
|
|
|
@ -203,7 +203,7 @@ func (p *Process) RlimitWithContext(ctx context.Context) ([]RlimitStat, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) ([]RlimitStat, error) {
|
|
|
|
|
rlimits, err := p.fillFromLimitsWithContext()
|
|
|
|
|
rlimits, err := p.fillFromLimitsWithContext(ctx)
|
|
|
|
|
if !gatherUsed || err != nil {
|
|
|
|
|
return rlimits, err
|
|
|
|
|
}
|
|
|
|
@ -258,7 +258,7 @@ func (p *Process) RlimitUsageWithContext(ctx context.Context, gatherUsed bool) (
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) IOCountersWithContext(ctx context.Context) (*IOCountersStat, error) {
|
|
|
|
|
return p.fillFromIOWithContext()
|
|
|
|
|
return p.fillFromIOWithContext(ctx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) NumCtxSwitchesWithContext(ctx context.Context) (*NumCtxSwitchesStat, error) {
|
|
|
|
@ -284,7 +284,7 @@ func (p *Process) NumThreadsWithContext(ctx context.Context) (int32, error) {
|
|
|
|
|
|
|
|
|
|
func (p *Process) ThreadsWithContext(ctx context.Context) (map[int32]*cpu.TimesStat, error) {
|
|
|
|
|
ret := make(map[int32]*cpu.TimesStat)
|
|
|
|
|
taskPath := common.HostProc(strconv.Itoa(int(p.Pid)), "task")
|
|
|
|
|
taskPath := common.HostProcWithContext(ctx, strconv.Itoa(int(p.Pid)), "task")
|
|
|
|
|
|
|
|
|
|
tids, err := readPidsFromDir(taskPath)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -315,7 +315,7 @@ func (p *Process) CPUAffinityWithContext(ctx context.Context) ([]int32, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, error) {
|
|
|
|
|
meminfo, _, err := p.fillFromStatmWithContext()
|
|
|
|
|
meminfo, _, err := p.fillFromStatmWithContext(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -323,7 +323,7 @@ func (p *Process) MemoryInfoWithContext(ctx context.Context) (*MemoryInfoStat, e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) MemoryInfoExWithContext(ctx context.Context) (*MemoryInfoExStat, error) {
|
|
|
|
|
_, memInfoEx, err := p.fillFromStatmWithContext()
|
|
|
|
|
_, memInfoEx, err := p.fillFromStatmWithContext(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -381,12 +381,12 @@ func (p *Process) ConnectionsMaxWithContext(ctx context.Context, max int) ([]net
|
|
|
|
|
func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]MemoryMapsStat, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
var ret []MemoryMapsStat
|
|
|
|
|
smapsPath := common.HostProc(strconv.Itoa(int(pid)), "smaps")
|
|
|
|
|
smapsPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "smaps")
|
|
|
|
|
if grouped {
|
|
|
|
|
ret = make([]MemoryMapsStat, 1)
|
|
|
|
|
// If smaps_rollup exists (require kernel >= 4.15), then we will use it
|
|
|
|
|
// for pre-summed memory information for a process.
|
|
|
|
|
smapsRollupPath := common.HostProc(strconv.Itoa(int(pid)), "smaps_rollup")
|
|
|
|
|
smapsRollupPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "smaps_rollup")
|
|
|
|
|
if _, err := os.Stat(smapsRollupPath); !os.IsNotExist(err) {
|
|
|
|
|
smapsPath = smapsRollupPath
|
|
|
|
|
}
|
|
|
|
@ -482,7 +482,7 @@ func (p *Process) MemoryMapsWithContext(ctx context.Context, grouped bool) (*[]M
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Process) EnvironWithContext(ctx context.Context) ([]string, error) {
|
|
|
|
|
environPath := common.HostProc(strconv.Itoa(int(p.Pid)), "environ")
|
|
|
|
|
environPath := common.HostProcWithContext(ctx, strconv.Itoa(int(p.Pid)), "environ")
|
|
|
|
|
|
|
|
|
|
environContent, err := ioutil.ReadFile(environPath)
|
|
|
|
|
if err != nil {
|
|
|
|
@ -508,9 +508,9 @@ func limitToUint(val string) (uint64, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get num_fds from /proc/(pid)/limits
|
|
|
|
|
func (p *Process) fillFromLimitsWithContext() ([]RlimitStat, error) {
|
|
|
|
|
func (p *Process) fillFromLimitsWithContext(ctx context.Context) ([]RlimitStat, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
limitsFile := common.HostProc(strconv.Itoa(int(pid)), "limits")
|
|
|
|
|
limitsFile := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "limits")
|
|
|
|
|
d, err := os.Open(limitsFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
@ -603,7 +603,7 @@ func (p *Process) fillFromLimitsWithContext() ([]RlimitStat, error) {
|
|
|
|
|
// Get list of /proc/(pid)/fd files
|
|
|
|
|
func (p *Process) fillFromfdListWithContext(ctx context.Context) (string, []string, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
statPath := common.HostProc(strconv.Itoa(int(pid)), "fd")
|
|
|
|
|
statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "fd")
|
|
|
|
|
d, err := os.Open(statPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return statPath, []string{}, err
|
|
|
|
@ -643,9 +643,9 @@ func (p *Process) fillFromfdWithContext(ctx context.Context) (int32, []*OpenFile
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get cwd from /proc/(pid)/cwd
|
|
|
|
|
func (p *Process) fillFromCwdWithContext() (string, error) {
|
|
|
|
|
func (p *Process) fillFromCwdWithContext(ctx context.Context) (string, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
cwdPath := common.HostProc(strconv.Itoa(int(pid)), "cwd")
|
|
|
|
|
cwdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cwd")
|
|
|
|
|
cwd, err := os.Readlink(cwdPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
@ -654,9 +654,9 @@ func (p *Process) fillFromCwdWithContext() (string, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get exe from /proc/(pid)/exe
|
|
|
|
|
func (p *Process) fillFromExeWithContext() (string, error) {
|
|
|
|
|
func (p *Process) fillFromExeWithContext(ctx context.Context) (string, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
exePath := common.HostProc(strconv.Itoa(int(pid)), "exe")
|
|
|
|
|
exePath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "exe")
|
|
|
|
|
exe, err := os.Readlink(exePath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
@ -667,7 +667,7 @@ func (p *Process) fillFromExeWithContext() (string, error) {
|
|
|
|
|
// Get cmdline from /proc/(pid)/cmdline
|
|
|
|
|
func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
|
|
|
|
|
cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline")
|
|
|
|
|
cmdline, err := ioutil.ReadFile(cmdPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
@ -681,7 +681,7 @@ func (p *Process) fillFromCmdlineWithContext(ctx context.Context) (string, error
|
|
|
|
|
|
|
|
|
|
func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
cmdPath := common.HostProc(strconv.Itoa(int(pid)), "cmdline")
|
|
|
|
|
cmdPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "cmdline")
|
|
|
|
|
cmdline, err := ioutil.ReadFile(cmdPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
@ -702,9 +702,9 @@ func (p *Process) fillSliceFromCmdlineWithContext(ctx context.Context) ([]string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get IO status from /proc/(pid)/io
|
|
|
|
|
func (p *Process) fillFromIOWithContext() (*IOCountersStat, error) {
|
|
|
|
|
func (p *Process) fillFromIOWithContext(ctx context.Context) (*IOCountersStat, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
ioPath := common.HostProc(strconv.Itoa(int(pid)), "io")
|
|
|
|
|
ioPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "io")
|
|
|
|
|
ioline, err := ioutil.ReadFile(ioPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
@ -738,9 +738,9 @@ func (p *Process) fillFromIOWithContext() (*IOCountersStat, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get memory info from /proc/(pid)/statm
|
|
|
|
|
func (p *Process) fillFromStatmWithContext() (*MemoryInfoStat, *MemoryInfoExStat, error) {
|
|
|
|
|
func (p *Process) fillFromStatmWithContext(ctx context.Context) (*MemoryInfoStat, *MemoryInfoExStat, error) {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
memPath := common.HostProc(strconv.Itoa(int(pid)), "statm")
|
|
|
|
|
memPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "statm")
|
|
|
|
|
contents, err := ioutil.ReadFile(memPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, nil, err
|
|
|
|
@ -791,7 +791,7 @@ func (p *Process) fillFromStatmWithContext() (*MemoryInfoStat, *MemoryInfoExStat
|
|
|
|
|
|
|
|
|
|
// Get name from /proc/(pid)/comm or /proc/(pid)/status
|
|
|
|
|
func (p *Process) fillNameWithContext(ctx context.Context) error {
|
|
|
|
|
err := p.fillFromCommWithContext()
|
|
|
|
|
err := p.fillFromCommWithContext(ctx)
|
|
|
|
|
if err == nil && p.name != "" && len(p.name) < 15 {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
@ -799,9 +799,9 @@ func (p *Process) fillNameWithContext(ctx context.Context) error {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get name from /proc/(pid)/comm
|
|
|
|
|
func (p *Process) fillFromCommWithContext() error {
|
|
|
|
|
func (p *Process) fillFromCommWithContext(ctx context.Context) error {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
statPath := common.HostProc(strconv.Itoa(int(pid)), "comm")
|
|
|
|
|
statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "comm")
|
|
|
|
|
contents, err := ioutil.ReadFile(statPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -818,7 +818,7 @@ func (p *Process) fillFromStatus() error {
|
|
|
|
|
|
|
|
|
|
func (p *Process) fillFromStatusWithContext(ctx context.Context) error {
|
|
|
|
|
pid := p.Pid
|
|
|
|
|
statPath := common.HostProc(strconv.Itoa(int(pid)), "status")
|
|
|
|
|
statPath := common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "status")
|
|
|
|
|
contents, err := ioutil.ReadFile(statPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -1023,9 +1023,9 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
|
|
|
|
|
var statPath string
|
|
|
|
|
|
|
|
|
|
if tid == -1 {
|
|
|
|
|
statPath = common.HostProc(strconv.Itoa(int(pid)), "stat")
|
|
|
|
|
statPath = common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "stat")
|
|
|
|
|
} else {
|
|
|
|
|
statPath = common.HostProc(strconv.Itoa(int(pid)), "task", strconv.Itoa(int(tid)), "stat")
|
|
|
|
|
statPath = common.HostProcWithContext(ctx, strconv.Itoa(int(pid)), "task", strconv.Itoa(int(tid)), "stat")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
contents, err := ioutil.ReadFile(statPath)
|
|
|
|
@ -1129,7 +1129,7 @@ func (p *Process) fillFromStatWithContext(ctx context.Context) (uint64, int32, *
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func pidsWithContext(ctx context.Context) ([]int32, error) {
|
|
|
|
|
return readPidsFromDir(common.HostProc())
|
|
|
|
|
return readPidsFromDir(common.HostProcWithContext(ctx))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
|
|
|
|
|