Skip to content

Commit 34a62d8

Browse files
kbfuispeakc0de
andauthored
fix the cgroup 2 problem (#677)
Co-authored-by: Shubham Chaudhary <[email protected]>
1 parent 8246ff8 commit 34a62d8

File tree

1 file changed

+37
-15
lines changed

1 file changed

+37
-15
lines changed

chaoslib/litmus/stress-chaos/helper/stress-helper.go

+37-15
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,9 @@ func prepareStressChaos(experimentsDetails *experimentTypes.ExperimentDetails, c
110110
return stacktrace.Propagate(err, "could not parse targets")
111111
}
112112

113-
var targets []targetDetails
113+
var (
114+
targets []targetDetails
115+
)
114116

115117
for _, t := range targetList.Target {
116118
td := targetDetails{
@@ -131,7 +133,7 @@ func prepareStressChaos(experimentsDetails *experimentTypes.ExperimentDetails, c
131133
return stacktrace.Propagate(err, "could not get container pid")
132134
}
133135

134-
td.CGroupManager, err = getCGroupManager(td)
136+
td.CGroupManager, err, td.GroupPath = getCGroupManager(td)
135137
if err != nil {
136138
return stacktrace.Propagate(err, "could not get cgroup manager")
137139
}
@@ -499,50 +501,69 @@ func abortWatcher(targets []targetDetails, resultName, chaosNS string) {
499501
}
500502

501503
// getCGroupManager will return the cgroup for the given pid of the process
502-
func getCGroupManager(t targetDetails) (interface{}, error) {
504+
func getCGroupManager(t targetDetails) (interface{}, error, string) {
503505
if cgroups.Mode() == cgroups.Unified {
504-
groupPath, err := cgroupsv2.PidGroupPath(t.Pid)
506+
groupPath := ""
507+
output, err := exec.Command("bash", "-c", fmt.Sprintf("nsenter -t 1 -C -m -- cat /proc/%v/cgroup", t.Pids[index])).CombinedOutput()
505508
if err != nil {
506-
return nil, cerrors.Error{ErrorCode: cerrors.ErrorTypeHelper, Source: t.Source, Target: fmt.Sprintf("{podName: %s, namespace: %s, container: %s}", t.Name, t.Namespace, t.TargetContainer), Reason: fmt.Sprintf("fail to get pid group path: %s", err.Error())}
509+
return nil, errors.Errorf("Error in getting groupPath,%s", string(output)), ""
510+
}
511+
parts := strings.SplitN(string(output), ":", 3)
512+
if len(parts) < 3 {
513+
return "", fmt.Errorf("invalid cgroup entry: %s", string(output)), ""
514+
}
515+
if parts[0] == "0" && parts[1] == "" {
516+
groupPath = parts[2]
507517
}
508518

509-
cgroup2, err := cgroupsv2.LoadManager("/sys/fs/cgroup", groupPath)
519+
log.Infof("group path: %s", groupPath)
520+
521+
cgroup2, err := cgroupsv2.LoadManager("/sys/fs/cgroup", string(groupPath))
510522
if err != nil {
511-
return nil, cerrors.Error{ErrorCode: cerrors.ErrorTypeHelper, Source: t.Source, Target: fmt.Sprintf("{podName: %s, namespace: %s, container: %s}", t.Name, t.Namespace, t.TargetContainer), Reason: fmt.Sprintf("fail to load the cgroup: %s", err.Error())}
523+
return nil, errors.Errorf("Error loading cgroup v2 manager, %v", err), ""
512524
}
513-
return cgroup2, nil
525+
return cgroup2, nil, groupPath
514526
}
515527
path := pidPath(t)
516528
cgroup, err := findValidCgroup(path, t)
517529
if err != nil {
518-
return nil, stacktrace.Propagate(err, "could not find valid cgroup")
530+
return nil, stacktrace.Propagate(err, "could not find valid cgroup"), ""
519531
}
520532
cgroup1, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(cgroup))
521533
if err != nil {
522-
return nil, cerrors.Error{ErrorCode: cerrors.ErrorTypeHelper, Source: t.Source, Target: fmt.Sprintf("{podName: %s, namespace: %s, container: %s}", t.Name, t.Namespace, t.TargetContainer), Reason: fmt.Sprintf("fail to load the cgroup: %s", err.Error())}
534+
return nil, cerrors.Error{ErrorCode: cerrors.ErrorTypeHelper, Source: t.Source, Target: fmt.Sprintf("{podName: %s, namespace: %s, container: %s}", t.Name, t.Namespace, t.TargetContainer), Reason: fmt.Sprintf("fail to load the cgroup: %s", err.Error())}, ""
523535
}
524536

525-
return cgroup1, nil
537+
return cgroup1, nil, ""
526538
}
527539

528540
// addProcessToCgroup will add the process to cgroup
529541
// By default it will add to v1 cgroup
530-
func addProcessToCgroup(pid int, control interface{}) error {
542+
func addProcessToCgroup(pid int, control interface{}, groupPath string) error {
531543
if cgroups.Mode() == cgroups.Unified {
532-
var cgroup1 = control.(*cgroupsv2.Manager)
533-
return cgroup1.AddProc(uint64(pid))
544+
args := []string{"-t", "1", "-C", "--", "sudo", "sh", "-c", fmt.Sprintf("echo %d >> /sys/fs/cgroup%s/cgroup.procs", pid, strings.ReplaceAll(groupPath, "\n", ""))}
545+
output, err := exec.Command("nsenter", args...).CombinedOutput()
546+
if err != nil {
547+
return cerrors.Error{
548+
ErrorCode: cerrors.ErrorTypeChaosInject,
549+
Reason: fmt.Sprintf("failed to add process to cgroup %s: %v", string(output), err),
550+
}
551+
}
552+
return nil
534553
}
535554
var cgroup1 = control.(cgroups.Cgroup)
536555
return cgroup1.Add(cgroups.Process{Pid: pid})
537556
}
538557

558+
539559
func injectChaos(t targetDetails, stressors, stressType string) (*exec.Cmd, error) {
540560
stressCommand := fmt.Sprintf("pause nsutil -t %v -p -- %v", strconv.Itoa(t.Pid), stressors)
541561
// for io stress,we need to enter into mount ns of the target container
542562
// enabling it by passing -m flag
543563
if stressType == "pod-io-stress" {
544564
stressCommand = fmt.Sprintf("pause nsutil -t %v -p -m -- %v", strconv.Itoa(t.Pid), stressors)
545565
}
566+
546567
log.Infof("[Info]: starting process: %v", stressCommand)
547568

548569
// launch the stress-ng process on the target container in paused mode
@@ -556,7 +577,7 @@ func injectChaos(t targetDetails, stressors, stressType string) (*exec.Cmd, erro
556577
}
557578

558579
// add the stress process to the cgroup of target container
559-
if err = addProcessToCgroup(cmd.Process.Pid, t.CGroupManager); err != nil {
580+
if err = addProcessToCgroup(cmd.Process.Pid, t.CGroupManager, t.GroupPath); err != nil {
560581
if killErr := cmd.Process.Kill(); killErr != nil {
561582
return nil, cerrors.Error{ErrorCode: cerrors.ErrorTypeChaosInject, Source: t.Source, Target: fmt.Sprintf("{podName: %s, namespace: %s, container: %s}", t.Name, t.Namespace, t.TargetContainer), Reason: fmt.Sprintf("fail to add the stress process to cgroup %s and kill stress process: %s", err.Error(), killErr.Error())}
562583
}
@@ -584,4 +605,5 @@ type targetDetails struct {
584605
CGroupManager interface{}
585606
Cmd *exec.Cmd
586607
Source string
608+
GroupPath string
587609
}

0 commit comments

Comments
 (0)