Skip to content

Commit

Permalink
readCon speedup
Browse files Browse the repository at this point in the history
When looking at runc strace output, I noticed that selinux attr files
are read byte by byte:

	read(8, "u", 1) = 1
	read(8, "n", 1) = 1
	....

Apparently, this happens because fmt.Fscanf("%s") works that way.

Let's read the whole file via ioutil.ReadAll instead.

The added benchmark shows a drastic improvement:

name            old time/op    new time/op    delta
CurrentLabel-4    26.4µs ± 1%     4.3µs ± 1%   -83.73%  (p=0.004 n=6+5)

name            old alloc/op   new alloc/op   delta
CurrentLabel-4      352B ± 0%      776B ± 0%  +120.45%  (p=0.002 n=6+6)

name            old allocs/op  new allocs/op  delta
CurrentLabel-4      9.00 ± 0%      7.00 ± 0%   -22.22%  (p=0.002 n=6+6)

Note that increased allocation size is caused by the fact that ReadAll
preallocates a 512 bytes buffer, which is very reasonable.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
kolyshkin committed Sep 8, 2021
1 parent 2cb8e92 commit 52abbe8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
15 changes: 7 additions & 8 deletions go-selinux/selinux_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,15 @@ func readCon(fpath string) (string, error) {
if err := isProcHandle(in); err != nil {
return "", err
}
return readConFd(in)
}

var retval string
if _, err := fmt.Fscanf(in, "%s", &retval); err != nil {
func readConFd(in *os.File) (string, error) {
data, err := ioutil.ReadAll(in)
if err != nil {
return "", err
}
return strings.Trim(retval, "\x00"), nil
return string(bytes.TrimSuffix(data, []byte{0})), nil
}

// classIndex returns the int index for an object class in the loaded policy,
Expand Down Expand Up @@ -664,11 +667,7 @@ func readWriteCon(fpath string, val string) (string, error) {
return "", err
}

var retval string
if _, err := fmt.Fscanf(f, "%s", &retval); err != nil {
return "", err
}
return strings.Trim(retval, "\x00"), nil
return readConFd(f)
}

// setExecLabel sets the SELinux label that the kernel will use for any programs
Expand Down
14 changes: 14 additions & 0 deletions go-selinux/selinux_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,17 @@ func BenchmarkChcon(b *testing.B) {
}
}
}

func BenchmarkCurrentLabel(b *testing.B) {
var (
l string
err error
)
for n := 0; n < b.N; n++ {
l, err = CurrentLabel()
if err != nil {
b.Fatal(err)
}
}
b.Log(l)
}

0 comments on commit 52abbe8

Please sign in to comment.