Merge pull request #2921 from kolyshkin/faster-openfile

This commit is contained in:
Akihiro Suda
2021-04-30 17:06:37 +09:00
committed by GitHub
3 changed files with 70 additions and 9 deletions
+40
View File
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
)
@@ -104,3 +105,42 @@ func TestTryDefaultCgroupRoot(t *testing.T) {
t.Errorf("tryDefaultCgroupRoot: want %q, got %q", exp, res)
}
}
func BenchmarkGetStats(b *testing.B) {
if cgroups.IsCgroup2UnifiedMode() {
b.Skip("cgroup v2 is not supported")
}
// Unset TestMode as we work with real cgroupfs here,
// and we want OpenFile to perform the fstype check.
fscommon.TestMode = false
defer func() {
fscommon.TestMode = true
}()
cg := &configs.Cgroup{
Path: "/some/kind/of/a/path/here",
Resources: &configs.Resources{},
}
m := NewManager(cg, nil, false)
err := m.Apply(-1)
if err != nil {
b.Fatal(err)
}
defer func() {
_ = m.Destroy()
}()
var st *cgroups.Stats
b.ResetTimer()
for i := 0; i < b.N; i++ {
st, err = m.GetStats()
if err != nil {
b.Fatal(err)
}
}
if st.CpuStats.CpuUsage.TotalUsage != 0 {
b.Fatalf("stats: %+v", st)
}
}
+26 -9
View File
@@ -5,7 +5,6 @@ import (
"strings"
"sync"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -17,7 +16,7 @@ const (
)
var (
// Set to true by fs unit tests
// TestMode is set to true by unit tests that need "fake" cgroupfs.
TestMode bool
cgroupFd int = -1
@@ -71,12 +70,12 @@ func OpenFile(dir, file string, flags int) (*os.File, error) {
flags |= os.O_TRUNC | os.O_CREATE
mode = 0o600
}
if prepareOpenat2() != nil {
return openFallback(dir, file, flags, mode)
}
reldir := strings.TrimPrefix(dir, cgroupfsPrefix)
if len(reldir) == len(dir) { // non-standard path, old system?
return openWithSecureJoin(dir, file, flags, mode)
}
if prepareOpenat2() != nil {
return openWithSecureJoin(dir, file, flags, mode)
return openFallback(dir, file, flags, mode)
}
relname := reldir + "/" + file
@@ -93,11 +92,29 @@ func OpenFile(dir, file string, flags int) (*os.File, error) {
return os.NewFile(uintptr(fd), cgroupfsPrefix+relname), nil
}
func openWithSecureJoin(dir, file string, flags int, mode os.FileMode) (*os.File, error) {
path, err := securejoin.SecureJoin(dir, file)
var errNotCgroupfs = errors.New("not a cgroup file")
// openFallback is used when openat2(2) is not available. It checks the opened
// file is on cgroupfs, returning an error otherwise.
func openFallback(dir, file string, flags int, mode os.FileMode) (*os.File, error) {
path := dir + "/" + file
fd, err := os.OpenFile(path, flags, mode)
if err != nil {
return nil, err
}
if TestMode {
return fd, nil
}
// Check this is a cgroupfs file.
var st unix.Statfs_t
if err := unix.Fstatfs(int(fd.Fd()), &st); err != nil {
_ = fd.Close()
return nil, &os.PathError{Op: "statfs", Path: path, Err: err}
}
if st.Type != unix.CGROUP_SUPER_MAGIC && st.Type != unix.CGROUP2_SUPER_MAGIC {
_ = fd.Close()
return nil, &os.PathError{Op: "open", Path: path, Err: errNotCgroupfs}
}
return os.OpenFile(path, flags, mode)
return fd, nil
}
@@ -17,6 +17,10 @@ const (
floatString = "2048"
)
func init() {
TestMode = true
}
func TestGetCgroupParamsInt(t *testing.T) {
// Setup tempdir.
tempDir, err := ioutil.TempDir("", "cgroup_utils_test")