diff --git a/exec/executor_common_linux.go b/exec/executor_common_linux.go index df2edaf..a988215 100644 --- a/exec/executor_common_linux.go +++ b/exec/executor_common_linux.go @@ -33,6 +33,7 @@ import ( "github.com/chaosblade-io/chaosblade-spec-go/spec" "github.com/chaosblade-io/chaosblade-spec-go/util" "github.com/containerd/cgroups" + cgroupsv2 "github.com/containerd/cgroups/v2" ) // CommonExecutor is an executor implementation which used copy chaosblade tool to the target container and executed @@ -155,23 +156,54 @@ func execForHangAction(uid string, ctx context.Context, expModel *spec.ExpModel, log.Debugf(ctx, "cgroup root path %s", cgroupRoot) - control, err := cgroups.Load(osexec.Hierarchy(cgroupRoot), osexec.PidPath(int(pid))) - if err != nil { - sprintf := fmt.Sprintf("cgroups load failed, %s", err.Error()) - return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) - } - - if err := command.Start(); err != nil { - sprintf := fmt.Sprintf("command start failed, %s", err.Error()) - return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + isCgroupV2 := false + if _, err := os.Stat(fmt.Sprintf("%s/cgroup.controllers", cgroupRoot)); err == nil { + isCgroupV2 = true } - - // add target cgroups - if err = control.Add(cgroups.Process{Pid: command.Process.Pid}); err != nil { - if err := command.Process.Kill(); err != nil { - sprintf := fmt.Sprintf("create experiment failed, %v", err) + if isCgroupV2 { + g, err := cgroupsv2.PidGroupPath(int(pid)) + if err != nil { + sprintf := fmt.Sprintf("loading cgroup2 for %d, err ", pid, err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + cg, err := cgroupsv2.LoadManager("/sys/fs/cgroup/", g) + if err != nil { + if err != cgroupsv2.ErrCgroupDeleted { + sprintf := fmt.Sprintf("cgroups V2 load failed, %s", err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + if cg, err = cgroupsv2.NewManager("/sys/fs/cgroup", cgroupRoot, nil); err != nil { + sprintf := fmt.Sprintf("cgroups V2 new manager failed, %s", err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + } + if err := command.Start(); err != nil { + sprintf := fmt.Sprintf("command start failed, %s", err.Error()) return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) } + if err := cg.AddProc(uint64(command.Process.Pid)); err != nil { + if err := command.Process.Kill(); err != nil { + sprintf := fmt.Sprintf("add process to cgroups V2 failed, %s", err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + } + } else { + control, err := cgroups.Load(osexec.Hierarchy(cgroupRoot), osexec.PidPath(int(pid))) + if err != nil { + sprintf := fmt.Sprintf("cgroups V1 load failed, %s", err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + if err := command.Start(); err != nil { + sprintf := fmt.Sprintf("command start failed, %s", err.Error()) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + // add target cgroups + if err = control.Add(cgroups.Process{Pid: command.Process.Pid}); err != nil { + if err := command.Process.Kill(); err != nil { + sprintf := fmt.Sprintf("create experiment failed, %v", err) + return spec.ReturnFail(spec.OsCmdExecFailed, sprintf) + } + } } signal := make(chan bool, 1) @@ -190,7 +222,6 @@ func execForHangAction(uid string, ctx context.Context, expModel *spec.ExpModel, } } - log.Infof(ctx, "wait nsexec process pasue, current comm: %s, pid: %d", comm, command.Process.Pid) if comm == "pause\n" { signal <- true diff --git a/go.mod b/go.mod index 8247e47..bb0544f 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/Microsoft/hcsshim v0.8.21 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect + github.com/cilium/ebpf v0.6.2 // indirect github.com/containerd/continuity v0.1.0 // indirect github.com/containerd/fifo v1.0.0 // indirect github.com/containerd/ttrpc v1.0.2 // indirect diff --git a/go.sum b/go.sum index d847bb6..4362fe1 100644 --- a/go.sum +++ b/go.sum @@ -107,6 +107,7 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2 h1:iHsfF/t4aW4heW2YKfeHrVPGdtYTL4C4KocpM8KTSnI= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -267,6 +268,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= diff --git a/version/version.go b/version/version.go index f99c02a..851bf4d 100644 --- a/version/version.go +++ b/version/version.go @@ -17,4 +17,4 @@ package version // Default version is latest, you can specify the value at compile time, see Makefile in chaosblade project for the details -var BladeVersion = "1.7.1" +var BladeVersion = "1.7.4"