浏览代码

libnetwork/resolvconf: use []byte for hash instead of string

After my last change, I noticed that the hash is used as a []byte in most
cases (other than tests). This patch updates the type to use a []byte, which
(although unlikely very important) also improves performance:

Compared to the previous version:

    benchstat new.txt new2.txt
    name         old time/op    new time/op    delta
    HashData-10     128ns ± 1%     116ns ± 1%   -9.77%  (p=0.000 n=20+20)

    name         old alloc/op   new alloc/op   delta
    HashData-10      208B ± 0%       88B ± 0%  -57.69%  (p=0.000 n=20+20)

    name         old allocs/op  new allocs/op  delta
    HashData-10      3.00 ± 0%      2.00 ± 0%  -33.33%  (p=0.000 n=20+20)

And compared to the original version:

    benchstat old.txt new2.txt
    name         old time/op    new time/op    delta
    HashData-10     201ns ± 1%     116ns ± 1%  -42.39%  (p=0.000 n=18+20)

    name         old alloc/op   new alloc/op   delta
    HashData-10      416B ± 0%       88B ± 0%  -78.85%  (p=0.000 n=20+20)

    name         old allocs/op  new allocs/op  delta
    HashData-10      6.00 ± 0%      2.00 ± 0%  -66.67%  (p=0.000 n=20+20)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 2 年之前
父节点
当前提交
55d18b7db9

+ 1 - 1
libnetwork/resolvconf/resolvconf.go

@@ -88,7 +88,7 @@ var (
 // File contains the resolv.conf content and its hash
 type File struct {
 	Content []byte
-	Hash    string
+	Hash    []byte
 }
 
 // Get returns the contents of /etc/resolv.conf and its hash

+ 1 - 2
libnetwork/resolvconf/resolvconf_linux_test.go

@@ -18,8 +18,7 @@ func TestGet(t *testing.T) {
 	if string(resolvConfUtils.Content) != string(resolvConfSystem) {
 		t.Fatalf("/etc/resolv.conf and GetResolvConf have different content.")
 	}
-	hashSystem := hashData(resolvConfSystem)
-	if resolvConfUtils.Hash != hashSystem {
+	if !bytes.Equal(resolvConfUtils.Hash, hashData(resolvConfSystem)) {
 		t.Fatalf("/etc/resolv.conf and GetResolvConf have different hashes.")
 	}
 }

+ 4 - 2
libnetwork/resolvconf/utils.go

@@ -6,7 +6,9 @@ import (
 )
 
 // hashData returns the sha256 sum of data.
-func hashData(data []byte) string {
+func hashData(data []byte) []byte {
 	f := sha256.Sum256(data)
-	return "sha256:" + hex.EncodeToString(f[:])
+	out := make([]byte, 2*sha256.Size)
+	hex.Encode(out, f[:])
+	return append([]byte("sha256:"), out...)
 }

+ 6 - 3
libnetwork/resolvconf/utils_test.go

@@ -1,11 +1,14 @@
 package resolvconf
 
-import "testing"
+import (
+	"bytes"
+	"testing"
+)
 
 func TestHashData(t *testing.T) {
 	const expected = "sha256:4d11186aed035cc624d553e10db358492c84a7cd6b9670d92123c144930450aa"
-	if actual := hashData([]byte("hash-me")); actual != expected {
-		t.Fatalf("Expecting %s, got %s", expected, actual)
+	if actual := hashData([]byte("hash-me")); !bytes.Equal(actual, []byte(expected)) {
+		t.Fatalf("Expecting %s, got %s", expected, string(actual))
 	}
 }
 

+ 10 - 16
libnetwork/sandbox_dns_unix.go

@@ -4,6 +4,7 @@
 package libnetwork
 
 import (
+	"bytes"
 	"fmt"
 	"net"
 	"os"
@@ -279,7 +280,8 @@ func (sb *Sandbox) setupDNS() error {
 	}
 
 	// Write hash
-	if err := os.WriteFile(sb.config.resolvConfHashFile, []byte(newRC.Hash), filePerm); err != nil {
+	err = os.WriteFile(sb.config.resolvConfHashFile, newRC.Hash, filePerm)
+	if err != nil {
 		return types.InternalErrorf("failed to write resolv.conf hash file when setting up dns for sandbox %s: %v", sb.ID(), err)
 	}
 
@@ -287,11 +289,6 @@ func (sb *Sandbox) setupDNS() error {
 }
 
 func (sb *Sandbox) updateDNS(ipv6Enabled bool) error {
-	var (
-		currHash string
-		hashFile = sb.config.resolvConfHashFile
-	)
-
 	// This is for the host mode networking
 	if sb.config.useDefaultSandBox {
 		return nil
@@ -301,23 +298,20 @@ func (sb *Sandbox) updateDNS(ipv6Enabled bool) error {
 		return nil
 	}
 
+	var currHash []byte
 	currRC, err := resolvconf.GetSpecific(sb.config.resolvConfPath)
 	if err != nil {
 		if !os.IsNotExist(err) {
 			return err
 		}
 	} else {
-		h, err := os.ReadFile(hashFile)
-		if err != nil {
-			if !os.IsNotExist(err) {
-				return err
-			}
-		} else {
-			currHash = string(h)
+		currHash, err = os.ReadFile(sb.config.resolvConfHashFile)
+		if err != nil && !os.IsNotExist(err) {
+			return err
 		}
 	}
 
-	if currHash != "" && currHash != currRC.Hash {
+	if len(currHash) > 0 && !bytes.Equal(currHash, currRC.Hash) {
 		// Seems the user has changed the container resolv.conf since the last time
 		// we checked so return without doing anything.
 		// logrus.Infof("Skipping update of resolv.conf file with ipv6Enabled: %t because file was touched by user", ipv6Enabled)
@@ -344,14 +338,14 @@ func (sb *Sandbox) updateDNS(ipv6Enabled bool) error {
 		tmpHashFile.Close()
 		return err
 	}
-	_, err = tmpHashFile.Write([]byte(newRC.Hash))
+	_, err = tmpHashFile.Write(newRC.Hash)
 	if err1 := tmpHashFile.Close(); err == nil {
 		err = err1
 	}
 	if err != nil {
 		return err
 	}
-	return os.Rename(tmpHashFile.Name(), hashFile)
+	return os.Rename(tmpHashFile.Name(), sb.config.resolvConfHashFile)
 }
 
 // Embedded DNS server has to be enabled for this sandbox. Rebuild the container's