Add support for /proc/[pid]/limits

This commit is contained in:
Josh Seba
2022-12-12 14:06:51 -08:00
parent 368e854146
commit b4a05ce65b
4 changed files with 136 additions and 0 deletions
+1
View File
@@ -64,6 +64,7 @@ func (fs *filesystem) newTaskInode(ctx context.Context, task *kernel.Task, pidns
"fdinfo": fs.newFDInfoDirInode(ctx, task),
"gid_map": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0644, &idMapData{task: task, gids: true}),
"io": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0400, newIO(task, isThreadGroup)),
"limits": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &limitsData{task: task}),
"maps": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mapsData{task: task}),
"mem": fs.newMemInode(ctx, task, fs.NextIno(), 0400),
"mountinfo": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mountInfoData{fs: fs, task: task}),
+37
View File
@@ -529,6 +529,43 @@ func (fd *memFD) SetStat(context.Context, vfs.SetStatOptions) error {
// Release implements vfs.FileDescriptionImpl.Release.
func (fd *memFD) Release(context.Context) {}
// limitsData implements vfs.DynamicBytesSource for /proc/[pid]/limits.
//
// +stateify savable
type limitsData struct {
kernfs.DynamicBytesFile
task *kernel.Task
}
func (d *limitsData) Generate(ctx context.Context, buf *bytes.Buffer) error {
// formatting matches the kernel output from linux/fs/proc/base.c:proc_pid_limits()
fmt.Fprintf(buf, "Limit Soft Limit Hard Limit Units \n")
for _, lt := range limits.AllLimitTypes {
fmt.Fprintf(buf, "%-25s ", lt.Name())
l := d.task.Limits().Get(lt)
if l.Cur == limits.Infinity {
fmt.Fprintf(buf, "%-20s ", "unlimited")
} else {
fmt.Fprintf(buf, "%-20d ", l.Cur)
}
if l.Max == limits.Infinity {
fmt.Fprintf(buf, "%-20s ", "unlimited")
} else {
fmt.Fprintf(buf, "%-20d ", l.Max)
}
if u := lt.Unit(); u != "" {
fmt.Fprintf(buf, "%-10s", u)
}
buf.WriteByte('\n')
}
return nil
}
// mapsData implements vfs.DynamicBytesSource for /proc/[pid]/maps.
//
// +stateify savable
+1
View File
@@ -78,6 +78,7 @@ var (
"fdinfo": linux.DT_DIR,
"gid_map": linux.DT_REG,
"io": linux.DT_REG,
"limits": linux.DT_REG,
"maps": linux.DT_REG,
"mem": linux.DT_REG,
"mountinfo": linux.DT_REG,
+97
View File
@@ -43,6 +43,103 @@ const (
Rttime
)
var AllLimitTypes = []LimitType{
CPU,
FileSize,
Data,
Stack,
Core,
Rss,
ProcessCount,
NumberOfFiles,
MemoryLocked,
AS,
Locks,
SignalsPending,
MessageQueueBytes,
Nice,
RealTimePriority,
Rttime,
}
// Name returns the kernel name of the limit
func (lt LimitType) Name() string {
switch lt {
case CPU:
return "Max cpu time"
case FileSize:
return "Max file size"
case Data:
return "Max data size"
case Stack:
return "Max stack size"
case Core:
return "Max core file size"
case Rss:
return "Max resident set"
case ProcessCount:
return "Max processes"
case NumberOfFiles:
return "Max open files"
case MemoryLocked:
return "Max locked memory"
case AS:
return "Max address space"
case Locks:
return "Max file locks"
case SignalsPending:
return "Max pending signals"
case MessageQueueBytes:
return "Max msgqueue size"
case Nice:
return "Max nice priority"
case RealTimePriority:
return "Max realtime priority"
case Rttime:
return "Max realtime timeout"
}
return "unknown"
}
// Unit returns the unit string for a limit
func (lt LimitType) Unit() string {
switch lt {
case CPU:
return "seconds"
case FileSize:
return "bytes"
case Data:
return "bytes"
case Stack:
return "bytes"
case Core:
return "bytes"
case Rss:
return "bytes"
case ProcessCount:
return "processes"
case NumberOfFiles:
return "files"
case MemoryLocked:
return "bytes"
case AS:
return "bytes"
case Locks:
return "locks"
case SignalsPending:
return "signals"
case MessageQueueBytes:
return "bytes"
case Nice:
return ""
case RealTimePriority:
return ""
case Rttime:
return "us"
}
return ""
}
// Infinity is a constant representing a resource with no limit.
const Infinity = ^uint64(0)