-
Notifications
You must be signed in to change notification settings - Fork 398
Detect container ID via cgroup inode when pa… #1367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fb2b79c
650e1d6
09ffd67
4cd3c0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,8 +10,10 @@ import ( | |
| "errors" | ||
| "fmt" | ||
| "io" | ||
| "io/fs" | ||
| "os" | ||
| "path" | ||
| "path/filepath" | ||
| "regexp" | ||
| "strconv" | ||
| "strings" | ||
|
|
@@ -181,6 +183,62 @@ func extractContainerID(pid libpf.PID) (libpf.String, error) { | |
| return parseContainerID(cgroupFile), nil | ||
| } | ||
|
|
||
| // CgroupRootInode returns the inode of /proc/<pid>/root/sys/fs/cgroup, which identifies | ||
| // the cgroup namespace root visible to the given process, unaffected by namespace masking. | ||
| func CgroupRootInode(pid libpf.PID) (uint64, error) { | ||
| var st unix.Stat_t | ||
| if err := unix.Stat(fmt.Sprintf("/proc/%d/root/sys/fs/cgroup", pid), &st); err != nil { | ||
| return 0, err | ||
| } | ||
| return st.Ino, nil | ||
| } | ||
|
|
||
| // DetectSelfContainerIDViaInode detects the current process's container ID by matching | ||
| // cgroup directory inodes. When the process runs in a private cgroup namespace (cgroup v2), | ||
| // /proc/self/cgroup returns a path relative to the namespace root (e.g. "0::/"), making it | ||
| // impossible to extract the container ID via the standard path. However, stat("/sys/fs/cgroup") | ||
| // returns the inode of the process's actual cgroup directory on the host, unaffected by | ||
| // namespace masking. This function walks the host's cgroup tree (via | ||
| // /proc/1/root/sys/fs/cgroup) to find the directory whose inode matches, then extracts | ||
| // the container ID from its path. | ||
| func DetectSelfContainerIDViaInode() (libpf.String, uint64, error) { | ||
| const hostCgroupRoot = "/proc/1/root/sys/fs/cgroup" | ||
|
|
||
| var selfStat unix.Stat_t | ||
| if err := unix.Stat("/sys/fs/cgroup", &selfStat); err != nil { | ||
| return libpf.NullString, 0, fmt.Errorf("failed to stat /sys/fs/cgroup: %w", err) | ||
| } | ||
| selfIno := selfStat.Ino | ||
|
|
||
| var matched libpf.String | ||
| err := filepath.WalkDir(hostCgroupRoot, func(path string, d fs.DirEntry, err error) error { | ||
| if err != nil { | ||
| if d == nil { | ||
| return err // root is inaccessible | ||
| } | ||
| return nil // skip inaccessible subdirectories | ||
| } | ||
| if !d.IsDir() { | ||
| return nil | ||
| } | ||
| var st unix.Stat_t | ||
| if err := unix.Stat(path, &st); err != nil { | ||
| return nil | ||
| } | ||
| if st.Ino == selfIno { | ||
| if parts := expContainerID.FindStringSubmatch(path); len(parts) == 2 { | ||
| matched = libpf.Intern(parts[1]) | ||
| } | ||
| return filepath.SkipAll | ||
| } | ||
| return nil | ||
| }) | ||
| if err != nil { | ||
| return libpf.NullString, 0, fmt.Errorf("failed to walk host cgroup tree: %w", err) | ||
| } | ||
|
Comment on lines
+236
to
+238
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will this logic ever be triggered?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can now be triggered in the case added by 4cd3c0c. |
||
| return matched, selfIno, nil | ||
| } | ||
|
|
||
| func trimMappingPath(path string) string { | ||
| // Trim the deleted indication from the path. | ||
| // See path_with_deleted in linux/fs/d_path.c | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -113,6 +113,16 @@ type ProcessManager struct { | |||||||||||||||
|
|
||||||||||||||||
| // includeEnvVars holds a list of env vars that should be captured from processes | ||||||||||||||||
| includeEnvVars libpf.Set[string] | ||||||||||||||||
|
|
||||||||||||||||
| // selfCgroupIno is the inode of the profiler's cgroup directory | ||||||||||||||||
| // (stat("/sys/fs/cgroup")). Used to identify processes whose cgroup root | ||||||||||||||||
| // matches the profiler's, which need the selfContainerID fallback. | ||||||||||||||||
| selfCgroupIno uint64 | ||||||||||||||||
|
|
||||||||||||||||
| // selfContainerID is the profiler's own container ID, detected once at startup. | ||||||||||||||||
| // Used as a fallback when /proc/<pid>/cgroup yields no container ID for processes | ||||||||||||||||
| // that share the profiler's cgroup directory (e.g., private cgroup namespace). | ||||||||||||||||
| selfContainerID libpf.String | ||||||||||||||||
|
Comment on lines
+120
to
+125
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit (no need to be applied): These seem to be constant across the whole execution, one option would be replacing it with a closure that captures the values.
Suggested change
|
||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| // Mapping represents an executable memory mapping of a process. | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if
/proc/1/root/sys/fs/cgroupcan't be walked? Seems like we'll returnniland swallow an error that we should probably be logging?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, thanks for flagging this. Fixed in 4cd3c0c