diff --git a/container/common/helpers.go b/container/common/helpers.go index 3b3d27f300..318333e69a 100644 --- a/container/common/helpers.go +++ b/container/common/helpers.go @@ -301,7 +301,19 @@ func readUInt64(dirpath string, file string) uint64 { } // Lists all directories under "path" and outputs the results as children of "parent". -func ListDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}) error { +func ListDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}, rawPrefixWhiteList []string) error { + if len(rawPrefixWhiteList) > 0 && parent != "/" { + inWhiteList := false + for _, prefix := range rawPrefixWhiteList { + if strings.HasPrefix(parent, prefix) || strings.HasPrefix(prefix, parent) { + inWhiteList = true + break + } + } + if !inWhiteList { + return nil + } + } dirents, err := os.ReadDir(dirpath) if err != nil { // Ignore if this hierarchy does not exist. @@ -322,7 +334,7 @@ func ListDirectories(dirpath string, parent string, recursive bool, output map[s // List subcontainers if asked to. if recursive { - if err := ListDirectories(path.Join(dirpath, dirname), name, true, output); err != nil { + if err := ListDirectories(path.Join(dirpath, dirname), name, true, output, rawPrefixWhiteList); err != nil { return err } } @@ -349,10 +361,10 @@ func CgroupExists(cgroupPaths map[string]string) bool { return false } -func ListContainers(name string, cgroupPaths map[string]string, listType container.ListType) ([]info.ContainerReference, error) { +func ListContainers(name string, cgroupPaths map[string]string, listType container.ListType, rawPrefixWhiteList []string) ([]info.ContainerReference, error) { containers := make(map[string]struct{}) for _, cgroupPath := range cgroupPaths { - err := ListDirectories(cgroupPath, name, listType == container.ListRecursive, containers) + err := ListDirectories(cgroupPath, name, listType == container.ListRecursive, containers, rawPrefixWhiteList) if err != nil { return nil, err } diff --git a/container/common/helpers_test.go b/container/common/helpers_test.go index db9e13829f..93827f774e 100644 --- a/container/common/helpers_test.go +++ b/container/common/helpers_test.go @@ -35,7 +35,7 @@ import ( func BenchmarkListDirectories(b *testing.B) { for i := 0; i < b.N; i++ { output := make(map[string]struct{}) - if err := ListDirectories("/sys/fs/cgroup", "", true, output); err != nil { + if err := ListDirectories("/sys/fs/cgroup", "", true, output, []string{}); err != nil { b.Fatal(err) } } diff --git a/container/raw/factory.go b/container/raw/factory.go index 0ab60829a8..fd496ccb37 100644 --- a/container/raw/factory.go +++ b/container/raw/factory.go @@ -65,7 +65,7 @@ func (f *rawFactory) NewContainerHandler(name string, metadataEnvAllowList []str if !inHostNamespace { rootFs = "/rootfs" } - return newRawContainerHandler(name, f.cgroupSubsystems, f.machineInfoFactory, f.fsInfo, f.watcher, rootFs, f.includedMetrics) + return newRawContainerHandler(name, f.cgroupSubsystems, f.machineInfoFactory, f.fsInfo, f.watcher, rootFs, f.includedMetrics, f.rawPrefixWhiteList) } // The raw factory can handle any container. If --docker_only is set to true, non-docker containers are ignored except for "/" and those whitelisted by raw_cgroup_prefix_whitelist flag. diff --git a/container/raw/handler.go b/container/raw/handler.go index a53c018806..fba22dc7c8 100644 --- a/container/raw/handler.go +++ b/container/raw/handler.go @@ -45,13 +45,16 @@ type rawContainerHandler struct { includedMetrics container.MetricSet libcontainerHandler *libcontainer.Handler + + // List of raw container cgroup path prefix whitelist. + rawPrefixWhiteList []string } func isRootCgroup(name string) bool { return name == "/" } -func newRawContainerHandler(name string, cgroupSubsystems map[string]string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet) (container.ContainerHandler, error) { +func newRawContainerHandler(name string, cgroupSubsystems map[string]string, machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, watcher *common.InotifyWatcher, rootFs string, includedMetrics container.MetricSet, rawPrefixWhiteList []string) (container.ContainerHandler, error) { cHints, err := common.GetContainerHintsFromFile(*common.ArgContainerHints) if err != nil { return nil, err @@ -90,6 +93,7 @@ func newRawContainerHandler(name string, cgroupSubsystems map[string]string, mac externalMounts: externalMounts, includedMetrics: includedMetrics, libcontainerHandler: handler, + rawPrefixWhiteList: rawPrefixWhiteList, }, nil } @@ -268,7 +272,7 @@ func (h *rawContainerHandler) GetContainerIPAddress() string { } func (h *rawContainerHandler) ListContainers(listType container.ListType) ([]info.ContainerReference, error) { - return common.ListContainers(h.name, h.cgroupPaths, listType) + return common.ListContainers(h.name, h.cgroupPaths, listType, h.rawPrefixWhiteList) } func (h *rawContainerHandler) ListProcesses(listType container.ListType) ([]int, error) { diff --git a/container/raw/watcher.go b/container/raw/watcher.go index dec1aeaea4..63f97cd40f 100644 --- a/container/raw/watcher.go +++ b/container/raw/watcher.go @@ -43,6 +43,9 @@ type rawContainerWatcher struct { // Signal for watcher thread to stop. stopWatcher chan error + + // List of raw container cgroup path prefix whitelist. + rawPrefixWhiteList []string } func NewRawContainerWatcher(includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) { @@ -123,6 +126,18 @@ func (w *rawContainerWatcher) watchDirectory(events chan watcher.ContainerEvent, if strings.HasSuffix(containerName, ".mount") { return false, nil } + if len(w.rawPrefixWhiteList) > 0 && containerName != "/" { + inWhiteList := false + for _, prefix := range w.rawPrefixWhiteList { + if strings.HasPrefix(containerName, prefix) || strings.HasPrefix(prefix, containerName) { + inWhiteList = true + break + } + } + if !inWhiteList { + return false, nil + } + } alreadyWatching, err := w.watcher.AddWatch(containerName, dir) if err != nil { return alreadyWatching, err