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>
This commit is contained in:
Sebastiaan van Stijn 2022-10-01 22:32:09 +02:00
parent 630fc3839e
commit 55d18b7db9
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
5 changed files with 22 additions and 24 deletions

View file

@ -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

View file

@ -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.")
}
}

View file

@ -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...)
}

View file

@ -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))
}
}

View file

@ -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