Merge pull request #55841 from ConnorDoyle/cpuman-file-state-for-none-policy

Automatic merge from submit-queue (batch tested with PRs 55841, 55948, 55945). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

CPU Manager: file state for all policies

**What this PR does / why we need it**:

Before this change, the new file-backed state was only enabled for the static CPU manager policy. This patch enables persistent state for all policies.

This PR fixes #55736 and the potential CPU resource leak described in that issue.

**Release note**:

```release-note
NONE
```

/kind bug
/sig node
/assign @balajismaniam
This commit is contained in:
Kubernetes Submit Queue 2017-11-18 14:10:12 -08:00 committed by GitHub
commit 869b5ab191
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 6 deletions

View File

@ -106,13 +106,11 @@ func NewManager(
stateFileDirecory string, stateFileDirecory string,
) (Manager, error) { ) (Manager, error) {
var policy Policy var policy Policy
var stateHandle state.State
switch policyName(cpuPolicyName) { switch policyName(cpuPolicyName) {
case PolicyNone: case PolicyNone:
policy = NewNonePolicy() policy = NewNonePolicy()
stateHandle = state.NewMemoryState()
case PolicyStatic: case PolicyStatic:
topo, err := topology.Discover(machineInfo) topo, err := topology.Discover(machineInfo)
@ -141,18 +139,20 @@ func NewManager(
reservedCPUsFloat := float64(reservedCPUs.MilliValue()) / 1000 reservedCPUsFloat := float64(reservedCPUs.MilliValue()) / 1000
numReservedCPUs := int(math.Ceil(reservedCPUsFloat)) numReservedCPUs := int(math.Ceil(reservedCPUsFloat))
policy = NewStaticPolicy(topo, numReservedCPUs) policy = NewStaticPolicy(topo, numReservedCPUs)
stateHandle = state.NewFileState(path.Join(stateFileDirecory, CPUManagerStateFileName), policy.Name())
default: default:
glog.Errorf("[cpumanager] Unknown policy \"%s\", falling back to default policy \"%s\"", cpuPolicyName, PolicyNone) glog.Errorf("[cpumanager] Unknown policy \"%s\", falling back to default policy \"%s\"", cpuPolicyName, PolicyNone)
policy = NewNonePolicy() policy = NewNonePolicy()
stateHandle = state.NewMemoryState()
} }
stateImpl := state.NewFileState(
path.Join(stateFileDirecory, CPUManagerStateFileName),
policy.Name())
manager := &manager{ manager := &manager{
policy: policy, policy: policy,
reconcilePeriod: reconcilePeriod, reconcilePeriod: reconcilePeriod,
state: stateHandle, state: stateImpl,
machineInfo: machineInfo, machineInfo: machineInfo,
nodeAllocatableReservation: nodeAllocatableReservation, nodeAllocatableReservation: nodeAllocatableReservation,
} }

View File

@ -75,12 +75,14 @@ func TestFileStateTryRestore(t *testing.T) {
testCases := []struct { testCases := []struct {
description string description string
stateFileContent string stateFileContent string
policyName string
expErr string expErr string
expectedState *stateMemory expectedState *stateMemory
}{ }{
{ {
"Invalid JSON - empty file", "Invalid JSON - empty file",
"\n", "\n",
"none",
"state file: could not unmarshal, corrupted state file", "state file: could not unmarshal, corrupted state file",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -90,6 +92,7 @@ func TestFileStateTryRestore(t *testing.T) {
{ {
"Invalid JSON - invalid content", "Invalid JSON - invalid content",
"{", "{",
"none",
"state file: could not unmarshal, corrupted state file", "state file: could not unmarshal, corrupted state file",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -99,6 +102,7 @@ func TestFileStateTryRestore(t *testing.T) {
{ {
"Try restore defaultCPUSet only", "Try restore defaultCPUSet only",
`{"policyName": "none", "defaultCpuSet": "4-6"}`, `{"policyName": "none", "defaultCpuSet": "4-6"}`,
"none",
"", "",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -108,6 +112,7 @@ func TestFileStateTryRestore(t *testing.T) {
{ {
"Try restore defaultCPUSet only - invalid name", "Try restore defaultCPUSet only - invalid name",
`{"policyName": "none", "defaultCpuSet" "4-6"}`, `{"policyName": "none", "defaultCpuSet" "4-6"}`,
"none",
"", "",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -123,6 +128,7 @@ func TestFileStateTryRestore(t *testing.T) {
"container2": "1-3" "container2": "1-3"
} }
}`, }`,
"none",
"", "",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{ assignments: ContainerCPUAssignments{
@ -132,9 +138,24 @@ func TestFileStateTryRestore(t *testing.T) {
defaultCPUSet: cpuset.NewCPUSet(), defaultCPUSet: cpuset.NewCPUSet(),
}, },
}, },
{
"Try restore invalid policy name",
`{
"policyName": "A",
"defaultCpuSet": "0-7",
"entries": {}
}`,
"B",
"policy configured \"B\" != policy from state file \"A\"",
&stateMemory{
assignments: ContainerCPUAssignments{},
defaultCPUSet: cpuset.NewCPUSet(),
},
},
{ {
"Try restore invalid assignments", "Try restore invalid assignments",
`{"entries": }`, `{"entries": }`,
"none",
"state file: could not unmarshal, corrupted state file", "state file: could not unmarshal, corrupted state file",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -151,6 +172,7 @@ func TestFileStateTryRestore(t *testing.T) {
"container2": "1-3" "container2": "1-3"
} }
}`, }`,
"none",
"", "",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{ assignments: ContainerCPUAssignments{
@ -166,6 +188,7 @@ func TestFileStateTryRestore(t *testing.T) {
"policyName": "none", "policyName": "none",
"defaultCpuSet": "2-sd" "defaultCpuSet": "2-sd"
}`, }`,
"none",
"state file: could not parse state file", "state file: could not parse state file",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -182,6 +205,7 @@ func TestFileStateTryRestore(t *testing.T) {
"container2": "1-3" "container2": "1-3"
} }
}`, }`,
"none",
"state file: could not parse state file", "state file: could not parse state file",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -191,6 +215,7 @@ func TestFileStateTryRestore(t *testing.T) {
{ {
"TryRestoreState creates empty state file", "TryRestoreState creates empty state file",
"", "",
"none",
"", "",
&stateMemory{ &stateMemory{
assignments: ContainerCPUAssignments{}, assignments: ContainerCPUAssignments{},
@ -214,7 +239,7 @@ func TestFileStateTryRestore(t *testing.T) {
defer os.Remove(sfilePath.Name()) defer os.Remove(sfilePath.Name())
logData, fileState := stderrCapture(t, func() State { logData, fileState := stderrCapture(t, func() State {
return NewFileState(sfilePath.Name(), "none") return NewFileState(sfilePath.Name(), tc.policyName)
}) })
if tc.expErr != "" { if tc.expErr != "" {