Add /proc/sys/kernel/sem.

PiperOrigin-RevId: 345178956
This commit is contained in:
Jing Chen 2020-12-02 00:11:17 -08:00 committed by gVisor bot
parent 41675ebc63
commit b26dd6d9b7
5 changed files with 46 additions and 10 deletions

View File

@ -32,6 +32,17 @@ const (
SEM_STAT_ANY = 20
)
// Information about system-wide sempahore limits and parameters.
//
// Source: include/uapi/linux/sem.h
const (
SEMMNI = 32000
SEMMSL = 32000
SEMMNS = SEMMNI * SEMMSL
SEMOPM = 500
SEMVMX = 32767
)
const SEM_UNDO = 0x1000
// Sembuf is equivalent to struct sembuf.

View File

@ -84,6 +84,7 @@ func (p *proc) newKernelDir(ctx context.Context, msrc *fs.MountSource) *fs.Inode
children := map[string]*fs.Inode{
"hostname": newProcInode(ctx, &h, msrc, fs.SpecialFile, nil),
"sem": newStaticProcInode(ctx, msrc, []byte(fmt.Sprintf("%d\t%d\t%d\t%d\n", linux.SEMMSL, linux.SEMMNS, linux.SEMOPM, linux.SEMMNI))),
"shmall": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMALL, 10))),
"shmmax": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMAX, 10))),
"shmmni": newStaticProcInode(ctx, msrc, []byte(strconv.FormatUint(linux.SHMMNI, 10))),

View File

@ -44,6 +44,7 @@ func (fs *filesystem) newSysDir(ctx context.Context, root *auth.Credentials, k *
return fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"kernel": fs.newStaticDir(ctx, root, map[string]kernfs.Inode{
"hostname": fs.newInode(ctx, root, 0444, &hostnameData{}),
"sem": fs.newInode(ctx, root, 0444, newStaticFile(fmt.Sprintf("%d\t%d\t%d\t%d\n", linux.SEMMSL, linux.SEMMNS, linux.SEMOPM, linux.SEMMNI))),
"shmall": fs.newInode(ctx, root, 0444, shmData(linux.SHMALL)),
"shmmax": fs.newInode(ctx, root, 0444, shmData(linux.SHMMAX)),
"shmmni": fs.newInode(ctx, root, 0444, shmData(linux.SHMMNI)),

View File

@ -29,17 +29,17 @@ import (
)
const (
valueMax = 32767 // SEMVMX
// Maximum semaphore value.
valueMax = linux.SEMVMX
// semaphoresMax is "maximum number of semaphores per semaphore ID" (SEMMSL).
semaphoresMax = 32000
// Maximum number of semaphore sets.
setsMax = linux.SEMMNI
// setMax is "system-wide limit on the number of semaphore sets" (SEMMNI).
setsMax = 32000
// Maximum number of semaphroes in a semaphore set.
semsMax = linux.SEMMSL
// semaphoresTotalMax is "system-wide limit on the number of semaphores"
// (SEMMNS = SEMMNI*SEMMSL).
semaphoresTotalMax = 1024000000
// Maximum number of semaphores in all semaphroe sets.
semsTotalMax = linux.SEMMNS
)
// Registry maintains a set of semaphores that can be found by key or ID.
@ -122,7 +122,7 @@ func NewRegistry(userNS *auth.UserNamespace) *Registry {
// be found. If exclusive is true, it fails if a set with the same key already
// exists.
func (r *Registry) FindOrCreate(ctx context.Context, key, nsems int32, mode linux.FileMode, private, create, exclusive bool) (*Set, error) {
if nsems < 0 || nsems > semaphoresMax {
if nsems < 0 || nsems > semsMax {
return nil, syserror.EINVAL
}
@ -166,7 +166,7 @@ func (r *Registry) FindOrCreate(ctx context.Context, key, nsems int32, mode linu
if len(r.semaphores) >= setsMax {
return nil, syserror.EINVAL
}
if r.totalSems() > int(semaphoresTotalMax-nsems) {
if r.totalSems() > int(semsTotalMax-nsems) {
return nil, syserror.EINVAL
}

View File

@ -17,6 +17,7 @@
#include <fcntl.h>
#include <limits.h>
#include <linux/magic.h>
#include <linux/sem.h>
#include <sched.h>
#include <signal.h>
#include <stddef.h>
@ -2409,6 +2410,28 @@ TEST(ProcFilesystems, PresenceOfShmMaxMniAll) {
ASSERT_LE(shmall, ULONG_MAX - (1UL << 24));
}
TEST(ProcFilesystems, PresenceOfSem) {
uint32_t semmsl = 0;
uint32_t semmns = 0;
uint32_t semopm = 0;
uint32_t semmni = 0;
std::string proc_file;
proc_file = ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/sys/kernel/sem"));
ASSERT_FALSE(proc_file.empty());
std::vector<absl::string_view> sem_limits =
absl::StrSplit(proc_file, absl::ByAnyChar("\t"), absl::SkipWhitespace());
ASSERT_EQ(sem_limits.size(), 4);
ASSERT_TRUE(absl::SimpleAtoi(sem_limits[0], &semmsl));
ASSERT_TRUE(absl::SimpleAtoi(sem_limits[1], &semmns));
ASSERT_TRUE(absl::SimpleAtoi(sem_limits[2], &semopm));
ASSERT_TRUE(absl::SimpleAtoi(sem_limits[3], &semmni));
ASSERT_EQ(semmsl, SEMMSL);
ASSERT_EQ(semmns, SEMMNS);
ASSERT_EQ(semopm, SEMOPM);
ASSERT_EQ(semmni, SEMMNI);
}
// Check that /proc/mounts is a symlink to self/mounts.
TEST(ProcMounts, IsSymlink) {
auto link = ASSERT_NO_ERRNO_AND_VALUE(ReadLink("/proc/mounts"));