Merge pull request #58687 from PengTaoWW/fixTCResourceLeaks

Automatic merge from submit-queue (batch tested with PRs 58317, 58687, 57872, 59063, 59328). 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>.

Fix TC resource Leak

ref: https://github.com/kubernetes/kubernetes/issues/56840 fix



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

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note

```
pull/6/head
Kubernetes Submit Queue 2018-02-05 18:43:33 -08:00 committed by GitHub
commit f68fc04b66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 22 deletions

View File

@ -128,15 +128,15 @@ func asciiCIDR(cidr string) (string, error) {
return fmt.Sprintf("%s/%d", ip.String(), size), nil
}
func (t *tcShaper) findCIDRClass(cidr string) (class, handle string, found bool, err error) {
func (t *tcShaper) findCIDRClass(cidr string) (classAndHandleList [][]string, found bool, err error) {
data, err := t.e.Command("tc", "filter", "show", "dev", t.iface).CombinedOutput()
if err != nil {
return "", "", false, err
return classAndHandleList, false, err
}
hex, err := hexCIDR(cidr)
if err != nil {
return "", "", false, err
return classAndHandleList, false, err
}
spec := fmt.Sprintf("match %s", hex)
@ -156,12 +156,17 @@ func (t *tcShaper) findCIDRClass(cidr string) (class, handle string, found bool,
// expected tc line:
// filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1
if len(parts) != 19 {
return "", "", false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(parts), parts)
}
return parts[18], parts[9], true, nil
return classAndHandleList, false, fmt.Errorf("unexpected output from tc: %s %d (%v)", filter, len(parts), parts)
} else {
resultTmp := []string{parts[18], parts[9]}
classAndHandleList = append(classAndHandleList, resultTmp)
}
}
return "", "", false, nil
}
if len(classAndHandleList) > 0 {
return classAndHandleList, true, nil
}
return classAndHandleList, false, nil
}
func makeKBitString(rsrc *resource.Quantity) string {
@ -237,7 +242,7 @@ func (t *tcShaper) interfaceExists() (bool, string, error) {
}
func (t *tcShaper) ReconcileCIDR(cidr string, upload, download *resource.Quantity) error {
_, _, found, err := t.findCIDRClass(cidr)
_, found, err := t.findCIDRClass(cidr)
if err != nil {
return err
}
@ -272,22 +277,31 @@ func (t *tcShaper) initializeInterface() error {
}
func (t *tcShaper) Reset(cidr string) error {
class, handle, found, err := t.findCIDRClass(cidr)
classAndHandle, found, err := t.findCIDRClass(cidr)
if err != nil {
return err
}
if !found {
return fmt.Errorf("Failed to find cidr: %s on interface: %s", cidr, t.iface)
}
for i := 0; i < len(classAndHandle); i++ {
if err := t.execAndLog("tc", "filter", "del",
"dev", t.iface,
"parent", "1:",
"proto", "ip",
"prio", "1",
"handle", handle, "u32"); err != nil {
"handle", classAndHandle[i][1], "u32"); err != nil {
return err
}
return t.execAndLog("tc", "class", "del", "dev", t.iface, "parent", "1:", "classid", class)
if err := t.execAndLog("tc", "class", "del",
"dev", t.iface,
"parent", "1:",
"classid", classAndHandle[i][0]); err != nil {
return err
}
}
return nil
}
func (t *tcShaper) deleteInterface(class string) error {

View File

@ -259,7 +259,7 @@ func TestFindCIDRClass(t *testing.T) {
},
}
shaper := &tcShaper{e: &fexec}
class, handle, found, err := shaper.findCIDRClass(test.cidr)
classAndHandle, found, err := shaper.findCIDRClass(test.cidr)
if test.expectErr {
if err == nil {
t.Errorf("unexpected non-error")
@ -270,14 +270,14 @@ func TestFindCIDRClass(t *testing.T) {
}
if test.expectNotFound {
if found {
t.Errorf("unexpectedly found an interface: %s %s", class, handle)
t.Errorf("unexpectedly found an interface: %s", classAndHandle)
}
} else {
if class != test.expectedClass {
t.Errorf("expected: %s, found %s", test.expectedClass, class)
if classAndHandle[0][0] != test.expectedClass {
t.Errorf("expected class: %s, found %s", test.expectedClass, classAndHandle)
}
if handle != test.expectedHandle {
t.Errorf("expected: %s, found %s", test.expectedHandle, handle)
if classAndHandle[0][1] != test.expectedHandle {
t.Errorf("expected handle: %s, found %s", test.expectedHandle, classAndHandle)
}
}
}