func prepareMonitoringGroup()

in resctrl/utils.go [102:175]


func prepareMonitoringGroup(containerName string, getContainerPids func() ([]string, error), inHostNamespace bool) (string, error) {
	if containerName == rootContainer {
		return rootResctrl, nil
	}

	pids, err := getContainerPids()
	if err != nil {
		return "", err
	}

	if len(pids) == 0 {
		return "", fmt.Errorf("couldn't obtain %q container pids: there is no pids in cgroup", containerName)
	}

	// Firstly, find the control group to which the container belongs.
	// Consider the root group.
	controlGroupPath, err := findGroup(rootResctrl, pids, true, false)
	if err != nil {
		return "", fmt.Errorf("%q %q: %q", noControlGroupFoundError, containerName, err)
	}
	if controlGroupPath == "" {
		return "", fmt.Errorf("%q %q", noControlGroupFoundError, containerName)
	}

	// Check if there is any monitoring group.
	monGroupPath, err := findGroup(filepath.Join(controlGroupPath, monGroupsDirName), pids, false, true)
	if err != nil {
		return "", fmt.Errorf("couldn't find monitoring group matching %q container: %v", containerName, err)
	}

	// Prepare new one if not exists.
	if monGroupPath == "" {
		// Remove leading prefix.
		// e.g. /my/container -> my/container
		if len(containerName) >= minContainerNameLen && containerName[0] == containerPrefix {
			containerName = containerName[1:]
		}

		// Add own prefix and use `-` instead `/`.
		// e.g. my/container -> cadvisor-my-container
		properContainerName := fmt.Sprintf("%s-%s", monGroupPrefix, strings.Replace(containerName, "/", "-", -1))
		monGroupPath = filepath.Join(controlGroupPath, monitoringGroupDir, properContainerName)

		err = os.MkdirAll(monGroupPath, os.ModePerm)
		if err != nil {
			return "", fmt.Errorf("couldn't create monitoring group directory for %q container: %w", containerName, err)
		}

		if !inHostNamespace {
			processPath = "/rootfs/proc"
		}

		for _, pid := range pids {
			processThreads, err := getAllProcessThreads(filepath.Join(processPath, pid, processTask))
			if err != nil {
				return "", err
			}
			for _, thread := range processThreads {
				err = intelrdt.WriteIntelRdtTasks(monGroupPath, thread)
				if err != nil {
					secondError := os.Remove(monGroupPath)
					if secondError != nil {
						return "", fmt.Errorf(
							"coudn't assign pids to %q container monitoring group: %w \n couldn't clear %q monitoring group: %v",
							containerName, err, containerName, secondError)
					}
					return "", fmt.Errorf("coudn't assign pids to %q container monitoring group: %w", containerName, err)
				}
			}
		}
	}

	return monGroupPath, nil
}