1
0
mirror of https://github.com/containers/podman.git synced 2026-02-05 15:45:08 +01:00
Files
podman/pkg/util/rlimit.go
2025-11-20 22:59:50 -08:00

76 lines
1.9 KiB
Go

//go:build !remote
package util
import (
"fmt"
"strings"
"github.com/containers/podman/v6/pkg/rootless"
"github.com/docker/go-units"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
// FormatRlimits formats the rlimits to the runtime spec format
func FormatRlimits(rlimits []specs.POSIXRlimit) []specs.POSIXRlimit {
formatted := make([]specs.POSIXRlimit, len(rlimits))
for i, rlimit := range rlimits {
typ := strings.ToUpper(rlimit.Type)
if !strings.HasPrefix(typ, "RLIMIT_") {
typ = "RLIMIT_" + typ
}
rlimit.Type = typ
formatted[i] = ClampRlimitToHost(rlimit)
}
return formatted
}
// ClampRlimitToHost translates Hard or soft limits of -1 to the current
// processes Max limit
func ClampRlimitToHost(u specs.POSIXRlimit) specs.POSIXRlimit {
if !rootless.IsRootless() || (int64(u.Hard) != -1 && int64(u.Soft) != -1) {
return u
}
rlimitName := strings.TrimPrefix(strings.ToLower(u.Type), "rlimit_")
ul, err := units.ParseUlimit(fmt.Sprintf("%s=%d:%d", rlimitName, int64(u.Soft), int64(u.Hard)))
if err != nil {
logrus.Warnf("Failed to check %s ulimit %q", u.Type, err)
return u
}
rl, err := ul.GetRlimit()
if err != nil {
logrus.Warnf("Failed to check %s ulimit %q", u.Type, err)
return u
}
var rlimit unix.Rlimit
if err := unix.Getrlimit(rl.Type, &rlimit); err != nil {
logrus.Warnf("Failed to return %s ulimit %q", u.Type, err)
return u
}
maxLimit := rlimitMaxToUint64(rlimit.Max)
if int64(u.Hard) == -1 {
u.Hard = maxLimit
}
if int64(u.Soft) == -1 {
u.Soft = maxLimit
}
return u
}
// rlimitMaxToUint64 converts unix.Rlimit.Max to uint64.
// On Linux, Max is uint64; on Darwin/BSD, Max is int64.
func rlimitMaxToUint64(max any) uint64 {
switch v := max.(type) {
case uint64:
return v
case int64:
return uint64(v)
default:
panic(fmt.Sprintf("unexpected type for rlimit.Max: %T (expected uint64 or int64)", v))
}
}