Example #1
0
func NewSchedulerLoadReader() (SchedulerLoadReader, error) {
	schedDebug, err := fs.Open("/proc/sched_debug")
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(schedDebug)
	stateMachine := newSchedDebugReader()
	for scanner.Scan() {
		line := scanner.Text()
		err = stateMachine.ProcessLine(line)
		if err != nil {
			return nil, err
		}
	}
	if err = scanner.Err(); err != nil {
		return nil, err
	}
	return stateMachine.Load()
}
Example #2
0
// Given a container name, returns the parent and name of the container to be fed to libcontainer.
func SplitName(containerName string) (string, string, error) {
	parent, id := path.Split(containerName)
	cgroupSelf, err := fs.Open("/proc/1/cgroup")
	if err != nil {
		return "", "", err
	}
	scanner := bufio.NewScanner(cgroupSelf)

	// Find how nested we are. Libcontainer takes container names relative to the current process.
	subsys := []string{"memory", "cpu"}
	nestedLevels := 0
	for scanner.Scan() {
		line := scanner.Text()
		elems := strings.Split(line, ":")
		if len(elems) < 3 {
			continue
		}
		for _, s := range subsys {
			if elems[1] == s {
				if elems[2] == "/" {
					// We're running at root, no nesting.
					nestedLevels = 0
				} else {
					// Count how deeply nested we are.
					nestedLevels = strings.Count(elems[2], "/")
				}
				break
			}
		}
	}
	if nestedLevels > 0 {
		// we are running inside a docker container
		upperLevel := strings.Repeat("../", nestedLevels)
		parent = filepath.Join(upperLevel, parent)
	}

	// Strip the last "/"
	if parent[len(parent)-1] == '/' {
		parent = parent[:len(parent)-1]
	}

	return parent, id, nil
}
Example #3
0
// Add() read the schedstat of pid, and add stat to the fields
// in self parameters. This function is useful if one wants to read stats of
// a group of processes.
func (self *ProcessSchedStat) Add(pid int) error {
	if self == nil {
		return fmt.Errorf("nil stat")
	}

	path := fmt.Sprintf("/proc/%d/schedstat", pid)
	f, err := fs.Open(path)
	if err != nil {
		return err
	}
	defer f.Close()
	v, err := readUint64List(f)
	if err != nil {
		return err
	}
	if len(v) < 3 {
		return fmt.Errorf("only %v fields read from %v: %v", len(v), path, v)
	}
	self.Running += v[0]
	self.RunWait += v[1]
	self.NumTimeSlices += v[2]
	self.NumProcesses++
	return nil
}