Merge pull request #3727 from stgraber/fixes
Some checks are pending
Build / Build (${{ matrix.architecture }}) (amd64) (push) Waiting to run
Build / Build (${{ matrix.architecture }}) (arm64) (push) Waiting to run
Tests / Code (oldstable) (push) Waiting to run
Tests / Code (stable) (push) Waiting to run
Tests / Code (tip) (push) Waiting to run
Tests / System (btrfs, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (btrfs, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (ceph, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (ceph, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, oldstable, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, stable, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_container) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_core) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_network) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, cluster) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_container) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_core) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_network) (push) Waiting to run
Tests / System (dir, tip, ubuntu-24.04-arm, standalone_storage) (push) Waiting to run
Tests / System (linstor, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (linstor, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (lvm, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (lvm, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (random, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (random, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / System (zfs, stable, ubuntu-24.04, cluster) (push) Waiting to run
Tests / System (zfs, stable, ubuntu-24.04, standalone_storage) (push) Waiting to run
Tests / Client (oldstable, macos-latest) (push) Waiting to run
Tests / Client (oldstable, ubuntu-latest) (push) Waiting to run
Tests / Client (oldstable, windows-latest) (push) Waiting to run
Tests / Client (stable, macos-latest) (push) Waiting to run
Tests / Client (stable, ubuntu-latest) (push) Waiting to run
Tests / Client (stable, windows-latest) (push) Waiting to run
Tests / Documentation (push) Waiting to run

Split memory and swap cgroup2 checks and tweak validation
This commit is contained in:
Stéphane Graber 2026-07-27 16:25:15 -04:00 committed by GitHub
commit 6ef74a5920
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 26 deletions

View File

@ -153,7 +153,7 @@ func (cg *CGroup) GetProcessesUsage() (int64, error) {
// SetMemorySwapLimit sets the hard limit for swap.
func (cg *CGroup) SetMemorySwapLimit(limit int64) error {
if !cgControllers["memory"] {
if !cgControllers["memory.swap"] {
return ErrControllerMissing
}
@ -314,7 +314,7 @@ func (cg *CGroup) SetMemorySwappiness(limit int64) error {
// GetMemorySwapLimit returns the hard limit on swap usage.
func (cg *CGroup) GetMemorySwapLimit() (int64, error) {
if !cgControllers["memory"] {
if !cgControllers["memory.swap"] {
return -1, ErrControllerMissing
}
@ -337,7 +337,7 @@ func (cg *CGroup) GetMemorySwapLimit() (int64, error) {
// GetMemorySwapUsage return current usage of swap.
func (cg *CGroup) GetMemorySwapUsage() (int64, error) {
if !cgControllers["memory"] {
if !cgControllers["memory.swap"] {
return -1, ErrControllerMissing
}

View File

@ -11,6 +11,7 @@ import (
"github.com/lxc/incus/v7/internal/server/db/cluster"
"github.com/lxc/incus/v7/internal/server/db/warningtype"
"github.com/lxc/incus/v7/shared/logger"
"github.com/lxc/incus/v7/shared/util"
)
var cgControllers = map[string]bool{}
@ -37,6 +38,9 @@ const (
// Memory resource control.
Memory
// MemorySwap resource control.
MemorySwap
// Pids resource control.
Pids
)
@ -54,6 +58,8 @@ func Supports(resource Resource) bool {
return cgControllers["io"]
case Memory:
return cgControllers["memory"]
case MemorySwap:
return cgControllers["memory.swap"]
case Pids:
return cgControllers["pids"]
}
@ -98,6 +104,11 @@ func Warnings() []cluster.Warning {
TypeCode: warningtype.MissingCGroupMemoryController,
LastMessage: "memory limits will be ignored",
})
} else if !Supports(MemorySwap) {
warnings = append(warnings, cluster.Warning{
TypeCode: warningtype.MissingCGroupMemorySwapAccounting,
LastMessage: "swap limits will be ignored",
})
}
if !Supports(Pids) {
@ -156,5 +167,15 @@ func Init() {
}
_ = controllers.Close()
// Check for swap accounting support (can be disabled through kernel arguments).
if cgControllers["memory"] {
for _, path := range []string{filepath.Join(cgPath, fields[2]), filepath.Join(cgPath, "init.scope")} {
if util.PathExists(filepath.Join(path, "memory.swap.current")) {
cgControllers["memory.swap"] = true
break
}
}
}
}
}

View File

@ -1192,7 +1192,10 @@ func (d *lxc) initLXC(config bool) (*liblxc.Container, error) {
if util.IsTrueOrEmpty(memorySwap) || util.IsFalse(memorySwap) {
err = cg.SetMemorySwapLimit(0)
if err != nil {
return nil, err
// Ignore missing swap accounting unless explicitly configured.
if memorySwap != "" || !errors.Is(err, cgroup.ErrControllerMissing) {
return nil, err
}
}
} else {
// Additional memory as swap.
@ -5332,7 +5335,7 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
// Store the old values for revert
oldMemswLimit := int64(-1)
if cgroup.Supports(cgroup.Memory) {
if cgroup.Supports(cgroup.MemorySwap) {
oldMemswLimit, err = cg.GetMemorySwapLimit()
if err != nil {
oldMemswLimit = -1
@ -5363,7 +5366,7 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
}
// Reset everything
if cgroup.Supports(cgroup.Memory) {
if cgroup.Supports(cgroup.MemorySwap) {
err = cg.SetMemorySwapLimit(-1)
if err != nil {
revertMemory()
@ -5398,26 +5401,27 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
return err
}
if cgroup.Supports(cgroup.Memory) {
if util.IsTrueOrEmpty(memorySwap) || util.IsFalse(memorySwap) {
err = cg.SetMemorySwapLimit(0)
if err != nil {
revertMemory()
return err
}
} else {
// Additional memory as swap.
swapInt, err := units.ParseByteSizeString(memorySwap)
if err != nil {
if util.IsTrueOrEmpty(memorySwap) || util.IsFalse(memorySwap) {
err = cg.SetMemorySwapLimit(0)
if err != nil {
// Ignore missing swap accounting unless explicitly configured.
if memorySwap != "" || !errors.Is(err, cgroup.ErrControllerMissing) {
revertMemory()
return err
}
}
} else {
// Additional memory as swap.
swapInt, err := units.ParseByteSizeString(memorySwap)
if err != nil {
revertMemory()
return err
}
err = cg.SetMemorySwapLimit(swapInt)
if err != nil {
revertMemory()
return err
}
err = cg.SetMemorySwapLimit(swapInt)
if err != nil {
revertMemory()
return err
}
}
}
@ -5441,8 +5445,11 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
// Maximum priority (10) should be default swappiness (60).
err = cg.SetMemorySwappiness(int64(70 - priority))
if err != nil && !errors.Is(err, cgroup.ErrControllerMissing) {
return err
if err != nil {
// Ignore missing swappiness support unless explicitly configured.
if memorySwapPriority != "" || !errors.Is(err, cgroup.ErrControllerMissing) {
return err
}
}
}
}
@ -9370,7 +9377,7 @@ func (d *lxc) Metrics(hostInterfaces []net.Interface) (*metrics.MetricSet, error
out.AddSamples(metrics.MemoryOOMKillsTotal, metrics.Sample{Value: float64(oomKills)})
// Handle swap.
if cgroup.Supports(cgroup.Memory) {
if cgroup.Supports(cgroup.MemorySwap) {
swapUsage, err := cg.GetMemorySwapUsage()
if err != nil {
d.logger.Warn("Failed to get swap usage", logger.Ctx{"err": err})

View File

@ -1797,7 +1797,7 @@ func (srv *Server) HandleSysinfoSyscall(c Instance, siov *Iovec) int {
instMetrics.Freeram = instMetrics.Totalram - uint64(memoryUsage) - instMetrics.Bufferram
// Get instance swap info.
if cgroup.Supports(cgroup.Memory) {
if cgroup.Supports(cgroup.MemorySwap) {
swapLimit, err := cg.GetMemorySwapLimit()
if err != nil {
l.Warn("Failed getting swap limit", logger.Ctx{"err": err})