From 905cb9a78f13d321860ee921990d60447c148605 Mon Sep 17 00:00:00 2001
From: zhong-jiawei-1 <zhongjiawei1@huawei.com>
Date: Tue, 25 Oct 2022 11:18:42 +0800
Subject: [PATCH] runc:add DT for cpuset.preferred_cpus setting

---
 .../libcontainer/cgroups/fs/cpuset_test.go    | 217 ++++++++++++++++++
 .../tests/test_docker_cpuset_preferred.sh     |  41 ++++
 2 files changed, 258 insertions(+)
 create mode 100755 runc-1.1.3/tests/test_docker_cpuset_preferred.sh

diff --git a/runc-1.1.3/libcontainer/cgroups/fs/cpuset_test.go b/runc-1.1.3/libcontainer/cgroups/fs/cpuset_test.go
index 8933b3c..0c72c7d 100644
--- a/runc-1.1.3/libcontainer/cgroups/fs/cpuset_test.go
+++ b/runc-1.1.3/libcontainer/cgroups/fs/cpuset_test.go
@@ -1,6 +1,9 @@
 package fs
 
 import (
+	"os"
+	"path/filepath"
+	"strings"
 	"reflect"
 	"testing"
 
@@ -66,6 +69,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) {
 	path := tempDir(t, "cpuset")
 
diff --git a/runc-1.1.3/tests/test_docker_cpuset_preferred.sh b/runc-1.1.3/tests/test_docker_cpuset_preferred.sh
new file mode 100755
index 0000000..c80db24
--- /dev/null
+++ b/runc-1.1.3/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.30.0

