Bump runc to v1.1.9

Signed-off-by: Davanum Srinivas <davanum@gmail.com>
This commit is contained in:
Davanum Srinivas
2023-08-30 08:21:59 -04:00
parent 3cf3702d1e
commit a926f594da
16 changed files with 186 additions and 242 deletions

View File

@@ -1,11 +1,9 @@
package intelrdt
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strconv"
@@ -13,6 +11,8 @@ import (
"sync"
"github.com/moby/sys/mountinfo"
"golang.org/x/sys/unix"
"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
"github.com/opencontainers/runc/libcontainer/configs"
)
@@ -145,34 +145,31 @@ import (
* }
*/
type Manager interface {
// Applies Intel RDT configuration to the process with the specified pid
Apply(pid int) error
// Returns statistics for Intel RDT
GetStats() (*Stats, error)
// Destroys the Intel RDT container-specific 'container_id' group
Destroy() error
// Returns Intel RDT path to save in a state file and to be able to
// restore the object later
GetPath() string
// Set Intel RDT "resource control" filesystem as configured.
Set(container *configs.Config) error
}
// This implements interface Manager
type intelRdtManager struct {
type Manager struct {
mu sync.Mutex
config *configs.Config
id string
path string
}
func NewManager(config *configs.Config, id string, path string) Manager {
return &intelRdtManager{
// NewManager returns a new instance of Manager, or nil if the Intel RDT
// functionality is not specified in the config, available from hardware or
// enabled in the kernel.
func NewManager(config *configs.Config, id string, path string) *Manager {
if config.IntelRdt == nil {
return nil
}
if _, err := Root(); err != nil {
// Intel RDT is not available.
return nil
}
return newManager(config, id, path)
}
// newManager is the same as NewManager, except it does not check if the feature
// is actually available. Used by unit tests that mock intelrdt paths.
func newManager(config *configs.Config, id string, path string) *Manager {
return &Manager{
config: config,
id: id,
path: path,
@@ -188,71 +185,52 @@ var (
catEnabled bool
// The flag to indicate if Intel RDT/MBA is enabled
mbaEnabled bool
// The flag to indicate if Intel RDT/MBA Software Controller is enabled
mbaScEnabled bool
// For Intel RDT initialization
initOnce sync.Once
errNotFound = errors.New("Intel RDT resctrl mount point not found")
errNotFound = errors.New("Intel RDT not available")
)
// Check if Intel RDT sub-features are enabled in featuresInit()
func featuresInit() {
initOnce.Do(func() {
// 1. Check if hardware and kernel support Intel RDT sub-features
flagsSet, err := parseCpuInfoFile("/proc/cpuinfo")
if err != nil {
return
}
// 2. Check if Intel RDT "resource control" filesystem is available.
// 1. Check if Intel RDT "resource control" filesystem is available.
// The user guarantees to mount the filesystem.
root, err := Root()
if err != nil {
return
}
// 3. Double check if Intel RDT sub-features are available in
// "resource control" filesystem. Intel RDT sub-features can be
// 2. Check if Intel RDT sub-features are available in "resource
// control" filesystem. Intel RDT sub-features can be
// selectively disabled or enabled by kernel command line
// (e.g., rdt=!l3cat,mba) in 4.14 and newer kernel
if flagsSet.CAT {
if _, err := os.Stat(filepath.Join(root, "info", "L3")); err == nil {
catEnabled = true
}
if _, err := os.Stat(filepath.Join(root, "info", "L3")); err == nil {
catEnabled = true
}
if mbaScEnabled {
// We confirm MBA Software Controller is enabled in step 2,
// MBA should be enabled because MBA Software Controller
// depends on MBA
if _, err := os.Stat(filepath.Join(root, "info", "MB")); err == nil {
mbaEnabled = true
} else if flagsSet.MBA {
if _, err := os.Stat(filepath.Join(root, "info", "MB")); err == nil {
mbaEnabled = true
}
}
if flagsSet.MBMTotal || flagsSet.MBMLocal || flagsSet.CMT {
if _, err := os.Stat(filepath.Join(root, "info", "L3_MON")); err != nil {
return
}
enabledMonFeatures, err = getMonFeatures(root)
if err != nil {
return
}
if enabledMonFeatures.mbmTotalBytes || enabledMonFeatures.mbmLocalBytes {
mbmEnabled = true
}
if enabledMonFeatures.llcOccupancy {
cmtEnabled = true
}
if _, err := os.Stat(filepath.Join(root, "info", "L3_MON")); err != nil {
return
}
enabledMonFeatures, err = getMonFeatures(root)
if err != nil {
return
}
if enabledMonFeatures.mbmTotalBytes || enabledMonFeatures.mbmLocalBytes {
mbmEnabled = true
}
if enabledMonFeatures.llcOccupancy {
cmtEnabled = true
}
})
}
// Return the mount point path of Intel RDT "resource control" filesysem
func findIntelRdtMountpointDir(f io.Reader) (string, error) {
mi, err := mountinfo.GetMountsFromReader(f, func(m *mountinfo.Info) (bool, bool) {
// findIntelRdtMountpointDir returns the mount point of the Intel RDT "resource control" filesystem.
func findIntelRdtMountpointDir() (string, error) {
mi, err := mountinfo.GetMounts(func(m *mountinfo.Info) (bool, bool) {
// similar to mountinfo.FSTypeFilter but stops after the first match
if m.FSType == "resctrl" {
return false, true // don't skip, stop
@@ -266,97 +244,45 @@ func findIntelRdtMountpointDir(f io.Reader) (string, error) {
return "", errNotFound
}
// Check if MBA Software Controller is enabled through mount option "-o mba_MBps"
if strings.Contains(","+mi[0].VFSOptions+",", ",mba_MBps,") {
mbaScEnabled = true
}
return mi[0].Mountpoint, nil
}
// For Root() use only.
var (
intelRdtRoot string
rootMu sync.Mutex
intelRdtRoot string
intelRdtRootErr error
rootOnce sync.Once
)
// The kernel creates this (empty) directory if resctrl is supported by the
// hardware and kernel. The user is responsible for mounting the resctrl
// filesystem, and they could mount it somewhere else if they wanted to.
const defaultResctrlMountpoint = "/sys/fs/resctrl"
// Root returns the Intel RDT "resource control" filesystem mount point.
func Root() (string, error) {
rootMu.Lock()
defer rootMu.Unlock()
if intelRdtRoot != "" {
return intelRdtRoot, nil
}
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
}
type cpuInfoFlags struct {
CAT bool // Cache Allocation Technology
MBA bool // Memory Bandwidth Allocation
// Memory Bandwidth Monitoring related.
MBMTotal bool
MBMLocal bool
CMT bool // Cache Monitoring Technology
}
func parseCpuInfoFile(path string) (cpuInfoFlags, error) {
infoFlags := cpuInfoFlags{}
f, err := os.Open(path)
if err != nil {
return infoFlags, err
}
defer f.Close()
s := bufio.NewScanner(f)
for s.Scan() {
line := s.Text()
// Search "cat_l3" and "mba" flags in first "flags" line
if strings.HasPrefix(line, "flags") {
flags := strings.Split(line, " ")
// "cat_l3" flag for CAT and "mba" flag for MBA
for _, flag := range flags {
switch flag {
case "cat_l3":
infoFlags.CAT = true
case "mba":
infoFlags.MBA = true
case "cqm_mbm_total":
infoFlags.MBMTotal = true
case "cqm_mbm_local":
infoFlags.MBMLocal = true
case "cqm_occup_llc":
infoFlags.CMT = true
}
rootOnce.Do(func() {
// Does this system support resctrl?
var statfs unix.Statfs_t
if err := unix.Statfs(defaultResctrlMountpoint, &statfs); err != nil {
if errors.Is(err, unix.ENOENT) {
err = errNotFound
}
return infoFlags, nil
intelRdtRootErr = err
return
}
}
if err := s.Err(); err != nil {
return infoFlags, err
}
return infoFlags, nil
// Has the resctrl fs been mounted to the default mount point?
if statfs.Type == unix.RDTGROUP_SUPER_MAGIC {
intelRdtRoot = defaultResctrlMountpoint
return
}
// The resctrl fs could have been mounted somewhere nonstandard.
intelRdtRoot, intelRdtRootErr = findIntelRdtMountpointDir()
})
return intelRdtRoot, intelRdtRootErr
}
// Gets a single uint64 value from the specified file.
@@ -502,14 +428,8 @@ func IsMBAEnabled() bool {
return mbaEnabled
}
// Check if Intel RDT/MBA Software Controller is enabled
func IsMBAScEnabled() bool {
featuresInit()
return mbaScEnabled
}
// Get the path of the clos group in "resource control" filesystem that the container belongs to
func (m *intelRdtManager) getIntelRdtPath() (string, error) {
func (m *Manager) getIntelRdtPath() (string, error) {
rootPath, err := Root()
if err != nil {
return "", err
@@ -524,7 +444,7 @@ func (m *intelRdtManager) getIntelRdtPath() (string, error) {
}
// Applies Intel RDT configuration to the process with the specified pid
func (m *intelRdtManager) Apply(pid int) (err error) {
func (m *Manager) Apply(pid int) (err error) {
// If intelRdt is not specified in config, we do nothing
if m.config.IntelRdt == nil {
return nil
@@ -559,11 +479,11 @@ func (m *intelRdtManager) Apply(pid int) (err error) {
}
// Destroys the Intel RDT container-specific 'container_id' group
func (m *intelRdtManager) Destroy() error {
func (m *Manager) Destroy() error {
// Don't remove resctrl group if closid has been explicitly specified. The
// group is likely externally managed, i.e. by some other entity than us.
// There are probably other containers/tasks sharing the same group.
if m.config.IntelRdt == nil || m.config.IntelRdt.ClosID == "" {
if m.config.IntelRdt != nil && m.config.IntelRdt.ClosID == "" {
m.mu.Lock()
defer m.mu.Unlock()
if err := os.RemoveAll(m.GetPath()); err != nil {
@@ -576,7 +496,7 @@ func (m *intelRdtManager) Destroy() error {
// Returns Intel RDT path to save in a state file and to be able to
// restore the object later
func (m *intelRdtManager) GetPath() string {
func (m *Manager) GetPath() string {
if m.path == "" {
m.path, _ = m.getIntelRdtPath()
}
@@ -584,7 +504,7 @@ func (m *intelRdtManager) GetPath() string {
}
// Returns statistics for Intel RDT
func (m *intelRdtManager) GetStats() (*Stats, error) {
func (m *Manager) GetStats() (*Stats, error) {
// If intelRdt is not specified in config
if m.config.IntelRdt == nil {
return nil, nil
@@ -670,7 +590,7 @@ func (m *intelRdtManager) GetStats() (*Stats, error) {
}
// Set Intel RDT "resource control" filesystem as configured.
func (m *intelRdtManager) Set(container *configs.Config) error {
func (m *Manager) Set(container *configs.Config) error {
// About L3 cache schema:
// It has allocation bitmasks/values for L3 cache on each socket,
// which contains L3 cache id and capacity bitmask (CBM).