Cgroup: reduce redundant parsing of mountinfo
Avoid parsing the whole lines of mountinfo after all mountpoints of the target subsytems are found, or when the target subsystem is not enabled. Signed-off-by: Tatsushi Inagaki <e29253@jp.ibm.com>
This commit is contained in:
parent
1d2bea3d46
commit
2a1a6cdf44
|
@ -23,6 +23,9 @@ func FindCgroupMountpoint(subsystem string) (string, error) {
|
||||||
// We are not using mount.GetMounts() because it's super-inefficient,
|
// We are not using mount.GetMounts() because it's super-inefficient,
|
||||||
// parsing it directly sped up x10 times because of not using Sscanf.
|
// parsing it directly sped up x10 times because of not using Sscanf.
|
||||||
// It was one of two major performance drawbacks in container start.
|
// It was one of two major performance drawbacks in container start.
|
||||||
|
if !isSubsystemAvailable(subsystem) {
|
||||||
|
return "", NewNotFoundError(subsystem)
|
||||||
|
}
|
||||||
f, err := os.Open("/proc/self/mountinfo")
|
f, err := os.Open("/proc/self/mountinfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -47,6 +50,9 @@ func FindCgroupMountpoint(subsystem string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
|
func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
|
||||||
|
if !isSubsystemAvailable(subsystem) {
|
||||||
|
return "", "", NewNotFoundError(subsystem)
|
||||||
|
}
|
||||||
f, err := os.Open("/proc/self/mountinfo")
|
f, err := os.Open("/proc/self/mountinfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
@ -70,6 +76,15 @@ func FindCgroupMountpointAndRoot(subsystem string) (string, string, error) {
|
||||||
return "", "", NewNotFoundError(subsystem)
|
return "", "", NewNotFoundError(subsystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isSubsystemAvailable(subsystem string) bool {
|
||||||
|
cgroups, err := ParseCgroupFile("/proc/self/cgroup")
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, avail := cgroups[subsystem]
|
||||||
|
return avail
|
||||||
|
}
|
||||||
|
|
||||||
func FindCgroupMountpointDir() (string, error) {
|
func FindCgroupMountpointDir() (string, error) {
|
||||||
f, err := os.Open("/proc/self/mountinfo")
|
f, err := os.Open("/proc/self/mountinfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -124,7 +139,8 @@ func (m Mount) GetThisCgroupDir(cgroups map[string]string) (string, error) {
|
||||||
func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
|
func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
|
||||||
res := make([]Mount, 0, len(ss))
|
res := make([]Mount, 0, len(ss))
|
||||||
scanner := bufio.NewScanner(mi)
|
scanner := bufio.NewScanner(mi)
|
||||||
for scanner.Scan() {
|
numFound := 0
|
||||||
|
for scanner.Scan() && numFound < len(ss) {
|
||||||
txt := scanner.Text()
|
txt := scanner.Text()
|
||||||
sepIdx := strings.Index(txt, " - ")
|
sepIdx := strings.Index(txt, " - ")
|
||||||
if sepIdx == -1 {
|
if sepIdx == -1 {
|
||||||
|
@ -139,12 +155,15 @@ func getCgroupMountsHelper(ss map[string]bool, mi io.Reader) ([]Mount, error) {
|
||||||
Root: fields[3],
|
Root: fields[3],
|
||||||
}
|
}
|
||||||
for _, opt := range strings.Split(fields[len(fields)-1], ",") {
|
for _, opt := range strings.Split(fields[len(fields)-1], ",") {
|
||||||
|
if !ss[opt] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if strings.HasPrefix(opt, cgroupNamePrefix) {
|
if strings.HasPrefix(opt, cgroupNamePrefix) {
|
||||||
m.Subsystems = append(m.Subsystems, opt[len(cgroupNamePrefix):])
|
m.Subsystems = append(m.Subsystems, opt[len(cgroupNamePrefix):])
|
||||||
}
|
} else {
|
||||||
if ss[opt] {
|
|
||||||
m.Subsystems = append(m.Subsystems, opt)
|
m.Subsystems = append(m.Subsystems, opt)
|
||||||
}
|
}
|
||||||
|
numFound++
|
||||||
}
|
}
|
||||||
res = append(res, m)
|
res = append(res, m)
|
||||||
}
|
}
|
||||||
|
@ -161,13 +180,13 @@ func GetCgroupMounts() ([]Mount, error) {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
all, err := GetAllSubsystems()
|
all, err := ParseCgroupFile("/proc/self/cgroup")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
allMap := make(map[string]bool)
|
allMap := make(map[string]bool)
|
||||||
for _, s := range all {
|
for s := range all {
|
||||||
allMap[s] = true
|
allMap[s] = true
|
||||||
}
|
}
|
||||||
return getCgroupMountsHelper(allMap, f)
|
return getCgroupMountsHelper(allMap, f)
|
||||||
|
|
Loading…
Reference in New Issue