blob: 03dfb7e43c6c266a556cbfcfc42967e6d5e65e56 [file] [log] [blame]
#!/usr/bin/python
#
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
__author__ = 'kdlucas@chromium.org (Kelly Lucas)'
import logging
import os
from autotest_lib.client.bin import utils, test
from autotest_lib.client.common_lib import error
class platform_OSLimits(test.test):
"""
Verify os limitations are set to correct levels.
"""
version = 1
def get_limit(self, key, path):
"""
Find and return values held in path.
Args:
key: dictionary key of os limit.
path: pathname of file with current value.
Returns:
value found in path. If it's a number we'll convert to integer.
"""
value = None
# Most files have only one value, but if there are multiple values we
# will handle it differently. Determine this from the key.
multivals = ['max_open', 'max_procs']
limits = {'max_open': 'Max open files',
'max_procs': 'Max processes',
}
if key in multivals:
output = utils.read_file(path)
lines = output.splitlines()
for line in lines:
if limits[key] in line:
fields = line.split(limits[key])
vals = fields[1].split()
value = (vals[0])
else:
value = (utils.read_one_line(path))
if value == 'unlimited':
return value
else:
return int(value)
def run_once(self):
errors = set()
# Max procs, max threads, and file max are dependent upon total memory.
# The kernel uses a formula similar to:
# MemTotal-kb / 128 = max procs
# MemTotal-kb / 64 = max threads
# MemTotal-kb / 10 = file_max
# But note that MemTotal changes at the end of initialization.
# The values used below for these settings should give sufficient head
# room for usage and kernel allocation.
ref_min = {'file_max': 50000,
'kptr_restrict': 1,
'max_open': 1024,
'max_procs': 3000,
'max_threads': 7000,
'ngroups_max': 65536,
'nr_open': 1048576,
'pid_max': 32768,
'randomize_va_space': 2,
'mmap_min_addr': 65536,
}
ref_equal = {'leases': 1,
'panic': -1,
'sysrq': 1,
'suid-dump': 2,
'tcp_syncookies': 1,
}
refpath = {'file_max': '/proc/sys/fs/file-max',
'leases': '/proc/sys/fs/leases-enable',
'max_open': '/proc/self/limits',
'max_procs': '/proc/self/limits',
'max_threads': '/proc/sys/kernel/threads-max',
'mmap_min_addr': '/proc/sys/vm/mmap_min_addr',
'kptr_restrict': '/proc/sys/kernel/kptr_restrict',
'ngroups_max': '/proc/sys/kernel/ngroups_max',
'nr_open': '/proc/sys/fs/nr_open',
'panic': '/proc/sys/kernel/panic',
'pid_max': '/proc/sys/kernel/pid_max',
'randomize_va_space': '/proc/sys/kernel/randomize_va_space',
'suid-dump': '/proc/sys/fs/suid_dumpable',
'sysrq': '/proc/sys/kernel/sysrq',
'tcp_syncookies': '/proc/sys/net/ipv4/tcp_syncookies',
}
# Adjust arch-specific values.
if utils.get_arch().startswith('arm'):
ref_min['mmap_min_addr'] = 32768;
# FIXME(kees): armel builds need COMPAT_BRK removed.
ref_min['randomize_va_space'] = 1;
# Create osvalue dictionary with the same keys as refpath.
osvalue = {}
for key in refpath:
osvalue[key] = None
for key in ref_min:
osvalue[key] = self.get_limit(key, refpath[key])
if osvalue[key] < ref_min[key]:
logging.warn('%s is %d' % (refpath[key], osvalue[key]))
logging.warn('%s should be at least %d' % (refpath[key],
ref_min[key]))
errors.add(key)
for key in ref_equal:
osvalue[key] = self.get_limit(key, refpath[key])
if osvalue[key] != ref_equal[key]:
logging.warn('%s is set to %d' % (refpath[key], osvalue[key]))
logging.warn('Expected %d' % ref_equal[key])
errors.add(key)
# Look for anything from refpath that wasn't checked yet:
for key in osvalue:
if osvalue[key] == None:
logging.warn('%s was never checked')
errors.add(key)
# If self.error is not zero, there were errors.
if len(errors) > 0:
raise error.TestFail('Found incorrect values: %s' %
', '.join(errors))