From dc8d0cc17207f657dc12ef72252cd02f00d09e12 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 2 Dec 2021 11:53:04 -0800 Subject: [PATCH] libct/intelrdt: wrap Root in sync.Once In case resctrl filesystem can not be found in /proc/self/mountinfo (which is pretty common on non-server or non-x86 hardware), subsequent calls to Root() will result in parsing it again and again. Use sync.Once to avoid it. Make unit tests call it so that Root() won't actually parse mountinfo in tests. Signed-off-by: Kir Kolyshkin (cherry picked from commit 02e961bcf9423dbaa8134eac0b77e16f0550e40e) Signed-off-by: Kir Kolyshkin --- libcontainer/intelrdt/intelrdt.go | 41 +++++++++++++----------------- libcontainer/intelrdt/util_test.go | 5 ++++ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/libcontainer/intelrdt/intelrdt.go b/libcontainer/intelrdt/intelrdt.go index 8b6bf3ef0..07e4e1fd9 100644 --- a/libcontainer/intelrdt/intelrdt.go +++ b/libcontainer/intelrdt/intelrdt.go @@ -276,35 +276,30 @@ func findIntelRdtMountpointDir(f io.Reader) (string, error) { // For Root() use only. var ( - intelRdtRoot string - rootMu sync.Mutex + intelRdtRoot string + intelRdtRootErr error + rootOnce sync.Once ) // Root returns the Intel RDT "resource control" filesystem mount point. func Root() (string, error) { - rootMu.Lock() - defer rootMu.Unlock() + rootOnce.Do(func() { + f, err := os.Open("/proc/self/mountinfo") + if err != nil { + intelRdtRootErr = err + return + } + root, err := findIntelRdtMountpointDir(f) + f.Close() + if err != nil { + intelRdtRootErr = err + return + } - if intelRdtRoot != "" { - return intelRdtRoot, nil - } + intelRdtRoot = root + }) - f, err := os.Open("/proc/self/mountinfo") - if err != nil { - return "", err - } - root, err := findIntelRdtMountpointDir(f) - f.Close() - if err != nil { - return "", err - } - - if _, err := os.Stat(root); err != nil { - return "", err - } - - intelRdtRoot = root - return intelRdtRoot, nil + return intelRdtRoot, intelRdtRootErr } type cpuInfoFlags struct { diff --git a/libcontainer/intelrdt/util_test.go b/libcontainer/intelrdt/util_test.go index f1b4244e2..b29d685e9 100644 --- a/libcontainer/intelrdt/util_test.go +++ b/libcontainer/intelrdt/util_test.go @@ -26,7 +26,12 @@ func NewIntelRdtTestUtil(t *testing.T) *intelRdtTestUtil { config := &configs.Config{ IntelRdt: &configs.IntelRdt{}, } + + // Assign fake intelRtdRoot value, returned by Root(). intelRdtRoot = t.TempDir() + // Make sure Root() won't even try to parse mountinfo. + rootOnce.Do(func() {}) + testIntelRdtPath := filepath.Join(intelRdtRoot, "resctrl") // Ensure the full mock Intel RDT "resource control" filesystem path exists