(layout cgroupLayout, identifiers []string)
| 655 | } |
| 656 | |
| 657 | func findMemoryUsagePathByIdentifier(layout cgroupLayout, identifiers []string) (string, error) { |
| 658 | const maxWalkDepth = 8 // bound the search to avoid slow walks over large cgroup trees |
| 659 | |
| 660 | type match struct { |
| 661 | path string |
| 662 | idLen int |
| 663 | depth int |
| 664 | } |
| 665 | |
| 666 | mountDepth := strings.Count(filepath.Clean(layout.mountPoint), string(os.PathSeparator)) |
| 667 | best := match{} |
| 668 | |
| 669 | err := filepath.WalkDir(layout.mountPoint, func(path string, d os.DirEntry, walkErr error) error { |
| 670 | if walkErr != nil { |
| 671 | return walkErr |
| 672 | } |
| 673 | currentDepth := strings.Count(path, string(os.PathSeparator)) - mountDepth |
| 674 | if d.IsDir() && currentDepth > maxWalkDepth { |
| 675 | return filepath.SkipDir |
| 676 | } |
| 677 | if d.IsDir() || d.Name() != layout.usageFile { |
| 678 | return nil |
| 679 | } |
| 680 | dir := filepath.Dir(path) |
| 681 | if dir == layout.mountPoint { |
| 682 | return nil |
| 683 | } |
| 684 | dirLower := strings.ToLower(dir) |
| 685 | for _, identifier := range identifiers { |
| 686 | if !strings.Contains(dirLower, identifier) { |
| 687 | continue |
| 688 | } |
| 689 | depth := strings.Count(dirLower, string(os.PathSeparator)) |
| 690 | if len(identifier) > best.idLen || (len(identifier) == best.idLen && depth > best.depth) { |
| 691 | best = match{ |
| 692 | path: path, |
| 693 | idLen: len(identifier), |
| 694 | depth: depth, |
| 695 | } |
| 696 | } |
| 697 | break |
| 698 | } |
| 699 | return nil |
| 700 | }) |
| 701 | if err != nil { |
| 702 | return "", err |
| 703 | } |
| 704 | if best.path == "" { |
| 705 | return "", fmt.Errorf("failed to find container-specific %s under %s", layout.usageFile, layout.mountPoint) |
| 706 | } |
| 707 | return best.path, nil |
| 708 | } |
| 709 | |
| 710 | // getRootNSPID returns this process's PID in the root (initial) PID namespace |
| 711 | // by reading the NSpid field from /proc/self/status. NSpid lists namespaces |
no test coverage detected