mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add support for prlimit(RLIMIT_NOFILE) to trace procfs.
Updates #4805 PiperOrigin-RevId: 451029238
This commit is contained in:
@@ -51,9 +51,9 @@ const Infinity = ^uint64(0)
|
||||
// +stateify savable
|
||||
type Limit struct {
|
||||
// Cur specifies the current limit.
|
||||
Cur uint64
|
||||
Cur uint64 `json:"cur,omitempty"`
|
||||
// Max specifies the maximum settable limit.
|
||||
Max uint64
|
||||
Max uint64 `json:"max,omitempty"`
|
||||
}
|
||||
|
||||
// LimitSet represents the Limits that correspond to each LimitType.
|
||||
|
||||
@@ -11,6 +11,7 @@ go_library(
|
||||
"//pkg/log",
|
||||
"//pkg/sentry/fsimpl/proc",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/limits",
|
||||
"//pkg/sentry/mm",
|
||||
"//pkg/sentry/vfs",
|
||||
],
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/proc"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/limits"
|
||||
"gvisor.dev/gvisor/pkg/sentry/mm"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
)
|
||||
@@ -57,6 +58,9 @@ type ProcessProcfsDump struct {
|
||||
StartTime int64 `json:"clone_ts,omitempty"`
|
||||
// Root is /proc/[pid]/root.
|
||||
Root string `json:"root,omitempty"`
|
||||
// Limits constains resource limits for this process. Currently only
|
||||
// RLIMIT_NOFILE is supported.
|
||||
Limits map[string]limits.Limit `json:"limits,omitempty"`
|
||||
}
|
||||
|
||||
// getMM returns t's MemoryManager. On success, the MemoryManager's users count
|
||||
@@ -170,6 +174,13 @@ func getRoot(t *kernel.Task, pid kernel.ThreadID) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func getFDLimit(ctx context.Context, pid kernel.ThreadID) (limits.Limit, error) {
|
||||
if limitSet := limits.FromContext(ctx); limitSet != nil {
|
||||
return limitSet.Get(limits.NumberOfFiles), nil
|
||||
}
|
||||
return limits.Limit{}, fmt.Errorf("could not find limit set for pid %s", pid)
|
||||
}
|
||||
|
||||
// Dump returns a procfs dump for process pid. t must be a task in process pid.
|
||||
func Dump(t *kernel.Task, pid kernel.ThreadID) (ProcessProcfsDump, error) {
|
||||
ctx := t.AsyncContext()
|
||||
@@ -180,6 +191,11 @@ func Dump(t *kernel.Task, pid kernel.ThreadID) (ProcessProcfsDump, error) {
|
||||
}
|
||||
defer mm.DecUsers(ctx)
|
||||
|
||||
fdLimit, err := getFDLimit(ctx, pid)
|
||||
if err != nil {
|
||||
return ProcessProcfsDump{}, err
|
||||
}
|
||||
|
||||
return ProcessProcfsDump{
|
||||
PID: int32(pid),
|
||||
Exe: getExecutablePath(ctx, pid, mm),
|
||||
@@ -189,5 +205,8 @@ func Dump(t *kernel.Task, pid kernel.ThreadID) (ProcessProcfsDump, error) {
|
||||
FDs: getFDs(ctx, t, pid),
|
||||
StartTime: t.StartTime().Nanoseconds(),
|
||||
Root: getRoot(t, pid),
|
||||
Limits: map[string]limits.Limit{
|
||||
"RLIMIT_NOFILE": fdLimit,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ go_test(
|
||||
"//pkg/sentry/control",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/limits",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/sentry/seccheck",
|
||||
"//pkg/sentry/seccheck/checkers/remote/test",
|
||||
|
||||
@@ -21,7 +21,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"gvisor.dev/gvisor/pkg/sentry/limits"
|
||||
"gvisor.dev/gvisor/pkg/sentry/seccheck"
|
||||
"gvisor.dev/gvisor/pkg/sentry/seccheck/checkers/remote/test"
|
||||
pb "gvisor.dev/gvisor/pkg/sentry/seccheck/points/points_go_proto"
|
||||
@@ -295,6 +297,13 @@ func TestProcfsDump(t *testing.T) {
|
||||
testEnv := "GVISOR_IS_GREAT=true"
|
||||
spec.Process.Env = append(spec.Process.Env, testEnv)
|
||||
spec.Process.Cwd = "/"
|
||||
fdLimit := limits.Limit{
|
||||
Cur: 10_000,
|
||||
Max: 100_000,
|
||||
}
|
||||
spec.Process.Rlimits = []specs.POSIXRlimit{
|
||||
{Type: "RLIMIT_NOFILE", Hard: fdLimit.Max, Soft: fdLimit.Cur},
|
||||
}
|
||||
_, bundleDir, cleanup, err := testutil.SetupContainer(spec, conf)
|
||||
if err != nil {
|
||||
t.Fatalf("error setting up container: %v", err)
|
||||
@@ -383,4 +392,8 @@ func TestProcfsDump(t *testing.T) {
|
||||
if want := "/"; procfsDump[0].Root != "/" {
|
||||
t.Errorf("expected root to be %q, but got %q", want, procfsDump[0].Root)
|
||||
}
|
||||
|
||||
if got := procfsDump[0].Limits["RLIMIT_NOFILE"]; got != fdLimit {
|
||||
t.Errorf("expected FD limit to be %+v, but got %+v", fdLimit, got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user