Skip to content

Commit 76779af

Browse files
authored
Merge pull request #1051 from Lomanic/issue1049
[process][posix] Fix #1049 check if procfs is mounted before checking if pid exists there
2 parents f69e79f + 0881c11 commit 76779af

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

process/process_posix.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ func getTerminalMap() (map[uint64]string, error) {
7171
return ret, nil
7272
}
7373

74+
// isMount is a port of python's os.path.ismount()
75+
// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216
76+
// https://docs.python.org/3/library/os.path.html#os.path.ismount
77+
func isMount(path string) bool {
78+
var stat1 unix.Stat_t
79+
if err := unix.Lstat(path, &stat1); err != nil {
80+
return false
81+
}
82+
if stat1.Mode == unix.DT_LNK {
83+
return false
84+
}
85+
parent := filepath.Join(path, "..")
86+
var stat2 unix.Stat_t
87+
if err := unix.Lstat(parent, &stat2); err != nil {
88+
return false
89+
}
90+
return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino
91+
}
92+
7493
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
7594
if pid <= 0 {
7695
return false, fmt.Errorf("invalid pid %v", pid)
@@ -79,20 +98,15 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
7998
if err != nil {
8099
return false, err
81100
}
82-
83-
if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
84-
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
85-
// This covers the case when running inside container with a different process namespace (by default)
86-
101+
if isMount(common.HostProc()) { // if /<HOST_PROC>/proc exists and is mounted, check if /<HOST_PROC>/proc/<PID> folder exists
87102
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
88103
if os.IsNotExist(err) {
89104
return false, nil
90105
}
91106
return err == nil, err
92107
}
93108

94-
//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
95-
//Make sense only if we run in the same process namespace
109+
// procfs does not exist or is not mounted, check PID existence by signalling the pid
96110
err = proc.Signal(syscall.Signal(0))
97111
if err == nil {
98112
return true, nil

v3/process/process_posix.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ func getTerminalMap() (map[uint64]string, error) {
7171
return ret, nil
7272
}
7373

74+
// isMount is a port of python's os.path.ismount()
75+
// https://github.com/python/cpython/blob/08ff4369afca84587b1c82034af4e9f64caddbf2/Lib/posixpath.py#L186-L216
76+
// https://docs.python.org/3/library/os.path.html#os.path.ismount
77+
func isMount(path string) bool {
78+
var stat1 unix.Stat_t
79+
if err := unix.Lstat(path, &stat1); err != nil {
80+
return false
81+
}
82+
if stat1.Mode == unix.DT_LNK {
83+
return false
84+
}
85+
parent := filepath.Join(path, "..")
86+
var stat2 unix.Stat_t
87+
if err := unix.Lstat(parent, &stat2); err != nil {
88+
return false
89+
}
90+
return stat1.Dev != stat2.Dev || stat1.Ino == stat2.Ino
91+
}
92+
7493
func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
7594
if pid <= 0 {
7695
return false, fmt.Errorf("invalid pid %v", pid)
@@ -80,19 +99,15 @@ func PidExistsWithContext(ctx context.Context, pid int32) (bool, error) {
8099
return false, err
81100
}
82101

83-
if _, err := os.Stat(common.HostProc()); err == nil { //Means that proc filesystem exist
84-
// Checking PID existence based on existence of /<HOST_PROC>/proc/<PID> folder
85-
// This covers the case when running inside container with a different process namespace (by default)
86-
102+
if isMount(common.HostProc()) { // if /<HOST_PROC>/proc exists and is mounted, check if /<HOST_PROC>/proc/<PID> folder exists
87103
_, err := os.Stat(common.HostProc(strconv.Itoa(int(pid))))
88104
if os.IsNotExist(err) {
89105
return false, nil
90106
}
91107
return err == nil, err
92108
}
93109

94-
//'/proc' filesystem is not exist, checking of PID existence is done via signalling the process
95-
//Make sense only if we run in the same process namespace
110+
// procfs does not exist or is not mounted, check PID existence by signalling the pid
96111
err = proc.Signal(syscall.Signal(0))
97112
if err == nil {
98113
return true, nil
@@ -158,4 +173,3 @@ func (p *Process) UsernameWithContext(ctx context.Context) (string, error) {
158173
}
159174
return "", nil
160175
}
161-

0 commit comments

Comments
 (0)