!101 [sync] PR-100: runc:support set cpuset.perfer

From: @openeuler-sync-bot 
Reviewed-by: @Vanient, @duguhaotian 
Signed-off-by: @duguhaotian
This commit is contained in:
openeuler-ci-bot 2022-12-15 09:18:06 +00:00 committed by Gitee
commit 1cb1970936
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 618 additions and 19 deletions

View File

@ -1 +1 @@
cb26a1d64df3e8697823357efc86c33f567714d7
f1708be8345798020decae623fc866212541f986

View File

@ -1,19 +1,17 @@
From 107de8857b41b5ac3c2d1230383e3855fac872de Mon Sep 17 00:00:00 2001
From: xiadanni <xiadanni1@huawei.com>
Date: Tue, 7 Dec 2021 20:40:52 +0800
From 40dd39dea67339fdcb88e64e52d054648fcbd362 Mon Sep 17 00:00:00 2001
From: zhongjiawei <zhongjiawei1@huawei.com>
Date: Tue, 5 Jul 2022 17:28:48 +0800
Subject: [PATCH] runc: fix cgroup info print error
reason: still using syslog hook to print logrus in create-init,
as logPipe will be closed before printCgroupInfo() called, cgroup info
could not be printed by logPipe.
Signed-off-by: xiadanni <xiadanni1@huawei.com>
---
main_unix.go | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
main_unix.go | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/main_unix.go b/main_unix.go
index 45e6df61..0355b276 100644
index 45e6df61..04799491 100644
--- a/main_unix.go
+++ b/main_unix.go
@@ -19,13 +19,14 @@ func init() {
@ -37,14 +35,6 @@ index 45e6df61..0355b276 100644
}
}
@@ -33,6 +34,7 @@ var initCommand = cli.Command{
Name: "init",
Usage: `initialize the namespaces and launch the process (do not call it outside of runc)`,
Action: func(context *cli.Context) error {
+ logrus.Info("child process init-command start")
factory, _ := libcontainer.New("")
if err := factory.StartInitialization(); err != nil {
fmt.Fprintf(os.Stderr, "libcontainer: container start initialization failed: %s", err)
--
2.27.0
2.30.0

View File

@ -0,0 +1,157 @@
From 01519a2176a214dd6da1c217b4c1c8f11007fc61 Mon Sep 17 00:00:00 2001
From: Vanient <xiadanni1@huawei.com>
Date: Sat, 7 May 2022 09:39:57 +0800
Subject: [PATCH] runc: support set cpuset.prefer_cpus using --cpuset-cpus
we need to set cpuset.prefer_cpus for performance. Using "+" as
separator, the cpuset value after separator is the prefer_cpus value.
Signed-off-by: Vanient <xiadanni1@huawei.com>
---
libcontainer/cgroups/fs/cpuset.go | 116 ++++++++++++++++++++++++++++--
1 file changed, 112 insertions(+), 4 deletions(-)
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
index 76cb719b..28ffbdb6 100644
--- a/libcontainer/cgroups/fs/cpuset.go
+++ b/libcontainer/cgroups/fs/cpuset.go
@@ -8,6 +8,8 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "strconv"
+ "strings"
"github.com/Sirupsen/logrus"
"github.com/opencontainers/runc/libcontainer/cgroups"
@@ -30,17 +32,123 @@ func (s *CpusetGroup) Apply(d *cgroupData) error {
return s.ApplyDir(dir, d.config, d.pid)
}
-func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
- var ret error
- if cgroup.Resources.CpusetCpus != "" {
- if err := writeFile(path, "cpuset.cpus", cgroup.Resources.CpusetCpus); err != nil {
+func parseCpus(cpus string) (map[int]bool, error) {
+ persedCpus := make(map[int]bool)
+ for _, cpu := range strings.Split(cpus, ",") {
+ if cpuInt, err := strconv.Atoi(cpu); err == nil {
+ persedCpus[cpuInt] = true
+ continue
+ }
+
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpu)
+ ranges := strings.Split(cpu, "-")
+ if len(ranges) != 2 {
+ return nil, invalidFormatError
+ }
+ lower, err1 := strconv.Atoi(ranges[0])
+ upper, err2 := strconv.Atoi(ranges[1])
+ if err1 != nil || err2 != nil {
+ return nil, invalidFormatError
+ }
+ if lower > upper {
+ return nil, invalidFormatError
+ }
+ const max = 8192
+ if upper > max {
+ return nil, fmt.Errorf("value of out range, maximum is %d", max)
+ }
+ for i := lower; i <= upper; i++ {
+ persedCpus[i] = true
+ }
+ }
+
+ return persedCpus, nil
+}
+
+func checkInCpuset(cpuset, prefer map[int]bool) bool {
+ for k := range prefer {
+ if _, ok := cpuset[k]; !ok {
+ return false
+ }
+ }
+ return true
+}
+
+func parseCpuset(cpuset string) (string, string, error) {
+ var cpusetStr, preferCpusStr string
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpuset)
+
+ splits := strings.Split(cpuset, "+")
+ if len(splits) == 1 {
+ cpusetStr = cpuset
+ } else if len(splits) == 2 {
+ if !strings.HasSuffix(splits[0], ",") {
+ return "", "", invalidFormatError
+ }
+ cpusetStr = strings.TrimSuffix(splits[0], ",")
+ preferCpusStr = splits[1]
+
+ cpusetMap, err := parseCpus(cpusetStr)
+ if err != nil {
+ return "", "", err
+ }
+ preferCpusMap, err := parseCpus(preferCpusStr)
+ if err != nil {
+ return "", "", err
+ }
+ if !checkInCpuset(cpusetMap, preferCpusMap) {
+ return "", "", fmt.Errorf("invalid preferred_cpus: %s not in cpuset: %s", preferCpusStr, cpusetStr)
+ }
+ } else {
+ return "", "", invalidFormatError
+ }
+
+ return cpusetStr, preferCpusStr, nil
+}
+
+func (s *CpusetGroup) setCpuset(path, cpuset string) error {
+ if _, err := os.Stat(filepath.Join(path, "cpuset.preferred_cpus")); err != nil {
+ var ret error
+ if err := writeFile(path, "cpuset.cpus", cpuset); err != nil {
ret = fmt.Errorf("failed to set cpuset.cpus, %v", err)
if _, err := os.Stat(path); err != nil {
ret = fmt.Errorf("%v, failed to stat %v, %v", ret, path, err)
}
return ret
}
+ return nil
+ }
+
+ cpusetStr, preferCpusStr, err := parseCpuset(cpuset)
+ if err != nil {
+ return err
+ }
+
+ if _, err := os.Stat(path); err != nil {
+ return fmt.Errorf("failed to stat %v, %v", path, err)
+ }
+ if err := writeFile(path, "cpuset.preferred_cpus", ""); err != nil {
+ return fmt.Errorf("failed to set cpuset.preferred_cpus to nil, %v", err)
}
+ if err := writeFile(path, "cpuset.cpus", cpusetStr); err != nil {
+ return fmt.Errorf("failed to set cpuset.cpus, %v", err)
+ }
+ if preferCpusStr != "" {
+ if err := writeFile(path, "cpuset.preferred_cpus", preferCpusStr); err != nil {
+ return fmt.Errorf("failed to set cpuset.preferred_cpus, %v", err)
+ }
+ }
+
+ return nil
+}
+
+// Set sets container cpuset cgroup
+func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
+ var ret error
+ if cgroup.Resources.CpusetCpus != "" {
+ return s.setCpuset(path, cgroup.Resources.CpusetCpus)
+ }
+
if cgroup.Resources.CpusetMems != "" {
if err := writeFile(path, "cpuset.mems", cgroup.Resources.CpusetMems); err != nil {
ret = fmt.Errorf("failed to set cpuset.cpus, %v", err)
--
2.27.0

View File

@ -0,0 +1,329 @@
From 360973d5fc25923681b911027ee711dfa77525cf Mon Sep 17 00:00:00 2001
From: Vanient <xiadanni1@huawei.com>
Date: Mon, 9 May 2022 20:32:24 +0800
Subject: [PATCH] [Huawei]runc:add DT for cpuset.preferred_cpus setting
Signed-off-by: Vanient <xiadanni1@huawei.com>
---
libcontainer/cgroups/fs/cpuset.go | 8 +-
libcontainer/cgroups/fs/cpuset_test.go | 217 +++++++++++++++++++++++++
tests/test_docker_cpuset_preferred.sh | 41 +++++
3 files changed, 265 insertions(+), 1 deletion(-)
create mode 100755 tests/test_docker_cpuset_preferred.sh
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
index 28ffbdb6..ebf75ec3 100644
--- a/libcontainer/cgroups/fs/cpuset.go
+++ b/libcontainer/cgroups/fs/cpuset.go
@@ -35,12 +35,15 @@ func (s *CpusetGroup) Apply(d *cgroupData) error {
func parseCpus(cpus string) (map[int]bool, error) {
persedCpus := make(map[int]bool)
for _, cpu := range strings.Split(cpus, ",") {
+ invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpu)
if cpuInt, err := strconv.Atoi(cpu); err == nil {
+ if cpuInt < 0 {
+ return nil, invalidFormatError
+ }
persedCpus[cpuInt] = true
continue
}
- invalidFormatError := fmt.Errorf("invalid cpuset format: %s", cpu)
ranges := strings.Split(cpu, "-")
if len(ranges) != 2 {
return nil, invalidFormatError
@@ -50,6 +53,9 @@ func parseCpus(cpus string) (map[int]bool, error) {
if err1 != nil || err2 != nil {
return nil, invalidFormatError
}
+ if lower < 0 || upper < 0 {
+ return nil, invalidFormatError
+ }
if lower > upper {
return nil, invalidFormatError
}
diff --git a/libcontainer/cgroups/fs/cpuset_test.go b/libcontainer/cgroups/fs/cpuset_test.go
index 0f929151..1fd2141c 100644
--- a/libcontainer/cgroups/fs/cpuset_test.go
+++ b/libcontainer/cgroups/fs/cpuset_test.go
@@ -3,6 +3,9 @@
package fs
import (
+ "os"
+ "path/filepath"
+ "strings"
"testing"
)
@@ -35,6 +38,220 @@ func TestCpusetSetCpus(t *testing.T) {
}
}
+type cpusetTestCase struct {
+ name string
+ dir string
+ cpuset string
+ wantPrefer string
+ wantCpuset string
+ errorStr string
+ wantErr bool
+}
+
+func getCpusetTestcaes() []cpusetTestCase {
+ testDir := "/sys/fs/cgroup/cpuset/runc-test"
+ errStr1 := "failed to set"
+ errStr2 := "invalid cpuset format"
+ errStr3 := "invalid preferred_cpus"
+ return []cpusetTestCase{
+ {
+ name: "Test1",
+ cpuset: "0,1,2,+1,2",
+ dir: testDir,
+ wantPrefer: "1-2",
+ wantCpuset: "0-2",
+ wantErr: false,
+ },
+ {
+ name: "Test2",
+ cpuset: "0-3,+1,2",
+ dir: testDir,
+ wantPrefer: "1-2",
+ wantCpuset: "0-3",
+ wantErr: false,
+ },
+ {
+ name: "Test3",
+ cpuset: "0,1,2,+1,2",
+ dir: "/aaa/bbb/invalid",
+ wantErr: true,
+ errorStr: errStr1,
+ },
+ {
+ name: "Test4",
+ cpuset: "0,1,2,+1,2",
+ dir: "",
+ wantErr: true,
+ errorStr: errStr1,
+ },
+ {
+ name: "Test5",
+ cpuset: "0,1,2,+1,2",
+ dir: "/" + strings.Repeat("a", 4097),
+ wantErr: true,
+ errorStr: errStr1,
+ },
+ {
+ name: "Test6",
+ cpuset: "0,1,2,a,+1",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test7",
+ cpuset: "0,1,2,+1,+2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test8",
+ cpuset: "0,1,1.2,+1,2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test9",
+ cpuset: "0,-1,2,+1,2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test10",
+ cpuset: "012+1,2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test11",
+ cpuset: "0,1,2,+3-1",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test12",
+ cpuset: "0,1,2,+4",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr3,
+ },
+ {
+ name: "Test13",
+ cpuset: "1-3+1-2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test14",
+ cpuset: "1-3,+1,2",
+ dir: testDir,
+ wantPrefer: "1-2",
+ wantCpuset: "1-3",
+ wantErr: false,
+ },
+ {
+ name: "Test15",
+ cpuset: "1-3,+1-2",
+ dir: testDir,
+ wantPrefer: "1-2",
+ wantCpuset: "1-3",
+ wantErr: false,
+ },
+ {
+ name: "Test16",
+ cpuset: "1-3,+1,4",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr3,
+ },
+ {
+ name: "Test17",
+ cpuset: "1-3,+1-2-3",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test18",
+ cpuset: "1-3,+a-2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test19",
+ cpuset: "1-3,+3-2",
+ dir: testDir,
+ wantErr: true,
+ errorStr: errStr2,
+ },
+ {
+ name: "Test20",
+ cpuset: "1-3,+2-10000",
+ dir: testDir,
+ wantErr: true,
+ errorStr: "value of out range",
+ },
+ }
+}
+
+func TestCpusetSetCpusetCpus(t *testing.T) {
+ cgroupRoot := "/sys/fs/cgroup"
+ testDir := filepath.Join(cgroupRoot, "cpuset", "runc-test")
+ err := os.MkdirAll(testDir, 0600)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer func() {
+ err := os.RemoveAll(testDir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ }()
+
+ cpuset := &CpusetGroup{}
+ tests := getCpusetTestcaes()
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ err := cpuset.setCpuset(tt.dir, tt.cpuset)
+ if (err != nil) != tt.wantErr {
+ t.Fatal(err)
+ }
+
+ if err != nil {
+ if !strings.Contains(err.Error(), tt.errorStr) {
+ t.Fatalf("Get the wrong error, want %v, get %v", tt.errorStr, err.Error())
+ }
+ return
+ }
+
+ value, err := getCgroupParamString(tt.dir, "cpuset.cpus")
+ if err != nil {
+ t.Fatalf("Failed to parse cpuset.cpus - %s", err)
+ }
+
+ if value != tt.wantCpuset {
+ t.Fatal("Got the wrong value, set cpuset.cpus failed.")
+ }
+
+ value, err = getCgroupParamString(tt.dir, "cpuset.preferred_cpus")
+ if err != nil {
+ t.Fatalf("Failed to parse cpuset.cpus - %s", err)
+ }
+
+ if value != tt.wantPrefer {
+ t.Fatal("Got the wrong value, set cpuset.cpus failed.")
+ }
+ })
+ }
+}
+
func TestCpusetSetMems(t *testing.T) {
helper := NewCgroupTestUtil("cpuset", t)
defer helper.cleanup()
diff --git a/tests/test_docker_cpuset_preferred.sh b/tests/test_docker_cpuset_preferred.sh
new file mode 100755
index 00000000..c80db24e
--- /dev/null
+++ b/tests/test_docker_cpuset_preferred.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+# Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
+# rubik licensed under the Mulan PSL v2.
+# You can use this software according to the terms and conditions of the Mulan PSL v2.
+# You may obtain a copy of Mulan PSL v2 at:
+# http://license.coscl.org.cn/MulanPSL2
+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
+# PURPOSE.
+# See the Mulan PSL v2 for more details.
+# Create: 2022-05-09
+# Description:set preferred cpuset
+
+which docker > /dev/null
+if [ $? -ne 0 ]; then
+ echo "environment not supported, skip test"
+ exit 0
+fi
+
+image="rnd-dockerhub.huawei.com/official/euleros:latest"
+containerID=$(docker run -itd --cpuset-cpus 0,1,+1 $image sh)
+if [ $? -ne 0 ]; then
+ echo "FAILED: start container failed"
+ exit 1
+fi
+
+cpuset=$(cat /sys/fs/cgroup/cpuset/docker/"$containerID"/cpuset.cpus)
+preferred_cpuset=$(cat /sys/fs/cgroup/cpuset/docker/"$containerID"/cpuset.preferred_cpus)
+if [ "$cpuset" != "0-1" ]; then
+ echo "FAILED: get wrong cpuset value"
+ exit 1
+fi
+if [ "$preferred_cpuset" != "1" ]; then
+ echo "FAILED: get wrong preferred_cpuset value"
+ exit 1
+fi
+
+docker rm -f "$containerID" > /dev/null
+echo "PASS"
+exit 0
--
2.27.0

View File

@ -0,0 +1,28 @@
From b4840e2463cea04325ad978359e496949eb9f7ca Mon Sep 17 00:00:00 2001
From: chenjiankun <chenjiankun1@huawei.com>
Date: Wed, 23 Nov 2022 10:20:04 +0800
Subject: [PATCH] runc: fix can't set cpuset-cpus and cpuset-mems at the same
time
---
libcontainer/cgroups/fs/cpuset.go | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libcontainer/cgroups/fs/cpuset.go b/libcontainer/cgroups/fs/cpuset.go
index ebf75ec3..ce1389d8 100644
--- a/libcontainer/cgroups/fs/cpuset.go
+++ b/libcontainer/cgroups/fs/cpuset.go
@@ -152,7 +152,9 @@ func (s *CpusetGroup) setCpuset(path, cpuset string) error {
func (s *CpusetGroup) Set(path string, cgroup *configs.Cgroup) error {
var ret error
if cgroup.Resources.CpusetCpus != "" {
- return s.setCpuset(path, cgroup.Resources.CpusetCpus)
+ if err := s.setCpuset(path, cgroup.Resources.CpusetCpus); err != nil {
+ return err
+ }
}
if cgroup.Resources.CpusetMems != "" {
--
2.23.0

View File

@ -0,0 +1,57 @@
From 6ea4aed9b0e96e037cd0e4c6accc1197a63e1ac0 Mon Sep 17 00:00:00 2001
From: zhongjiawei <zhongjiawei1@huawei.com>
Date: Tue, 23 Aug 2022 10:32:23 +0800
Subject: [PATCH] runc: write state.json atomically
We want to make sure that the state file is syned and cannot be
read partially or truncated.
Conflict:NA
Reference:https://github.com/opencontainers/runc/pull/2467/commits/a4a306d2a2850e26052c86c329dc2d1a0521f723
---
libcontainer/container_linux.go | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
index 7be84a63..e9031267 100644
--- a/libcontainer/container_linux.go
+++ b/libcontainer/container_linux.go
@@ -1384,14 +1384,30 @@ func (c *linuxContainer) updateState(process parentProcess) (*State, error) {
}
return state, nil
}
+func (c *linuxContainer) saveState(s *State) (retErr error) {
+ tmpFile, err := ioutil.TempFile(c.root, "state-")
+ if err != nil {
+ return err
+ }
-func (c *linuxContainer) saveState(s *State) error {
- f, err := os.Create(filepath.Join(c.root, stateFilename))
+ defer func() {
+ if retErr != nil {
+ tmpFile.Close()
+ os.Remove(tmpFile.Name())
+ }
+ }()
+
+ err = utils.WriteJSON(tmpFile, s)
if err != nil {
return err
}
- defer f.Close()
- return utils.WriteJSON(f, s)
+ err = tmpFile.Close()
+ if err != nil {
+ return err
+ }
+
+ stateFilePath := filepath.Join(c.root, stateFilename)
+ return os.Rename(tmpFile.Name(), stateFilePath)
}
func (c *linuxContainer) deleteState() error {
--
2.30.0

View File

@ -0,0 +1,27 @@
From c0ff47aba74ea06836ee53f7077c7930e378820c Mon Sep 17 00:00:00 2001
From: zhongjiawei <zhongjiawei1@huawei.com>
Date: Thu, 15 Dec 2022 15:30:23 +0800
Subject: [PATCH] runc:Make sure signalAllProcesses is invoked in the function
of destroy when container shares pid namespace
---
libcontainer/state_linux.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcontainer/state_linux.go b/libcontainer/state_linux.go
index b570a24..c77d4f2 100644
--- a/libcontainer/state_linux.go
+++ b/libcontainer/state_linux.go
@@ -38,7 +38,8 @@ type containerState interface {
}
func destroy(c *linuxContainer) error {
- if !c.config.Namespaces.Contains(configs.NEWPID) {
+ if !c.config.Namespaces.Contains(configs.NEWPID) ||
+ c.config.Namespaces.PathOf(configs.NEWPID) != "" {
if err := signalAllProcesses(c.cgroupManager, syscall.SIGKILL); err != nil {
logrus.Warn(err)
}
--
2.30.0

View File

@ -4,7 +4,7 @@
Name: docker-runc
Version: 1.0.0.rc3
Release: 306
Release: 307
Summary: runc is a CLI tool for spawning and running containers according to the OCI specification.
License: ASL 2.0
@ -53,6 +53,12 @@ install -p -m 755 runc $RPM_BUILD_ROOT/%{_bindir}/runc
%{_bindir}/runc
%changelog
* Thu Dec 15 2022 zhongjiawei<zhongjiawei1@huawei.com> - 1.0.0.rc3-307
- Type:bugfix
- CVE:NA
- SUG:NA
- DESC:support set cpuset.perfer
* Mon Nov 21 2022 Ge Wang <wangge20@h-partners.com> - 1.0.0.rc3-306
- Type:bugfix
- CVE:NA

View File

@ -133,4 +133,9 @@ patch/0131-runc-change-Umask-to-0022.patch
patch/0132-runc-fix-systemd-cgroup-after-memory-type-changed.patch
patch/0133-runc-add-CGO-sercuity-build-options.patch
patch/0134-runc-add-errnoRet-in-Syscall-struct.patch
patch/0135-runc-support-set-cpuset.prefer_cpus-using-cpuset-cpu.patch
patch/0136-runc-add-DT-for-cpuset.preferred_cpus-setting.patch
patch/0137-runc-fix-can-t-set-cpuset-cpus-and-cpuset-mems-at-th.patch
patch/0138-runc-write-state.json-atomically.patch
patch/0139-runc-Make-sure-signalAllProcesses-is-invoked-in-the-.patch
#end