Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions tuned-main.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ update_interval = 10
# one hardcoded profile (by default "balanced").
recommend_command = 1

# Whether to reapply sysctl from /run/sysctl.d/, /etc/sysctl.d/ and
# /etc/sysctl.conf. If enabled, these sysctls will be re-appliead
# after TuneD sysctls are applied, i.e. TuneD sysctls will not
# override user-provided system sysctls.
reapply_sysctl = 1
# Avoid modifying sysctls that are configured in /run/sysctl.d/,
# /etc/sysctl.d/ and /etc/sysctl.conf. If enabled, TuneD doesn't
# assumes systemd-sysctl.service(8) or an equivalent service manages
# these sysctls and will refrain from ever touching them.
protect_sysctl = 1

# Default priority assigned to instances
default_instance_priority = 0
Expand All @@ -40,6 +40,17 @@ log_file_count = 2
# Log file max size
log_file_max_size = 1MB

# Whether to reapply sysctl from /run/sysctl.d/, /etc/sysctl.d/ and
# /etc/sysctl.conf. If enabled, these sysctls will be re-appliead
# after TuneD sysctls are applied, i.e. TuneD sysctls will not
# override user-provided system sysctls. Note that this may cause
# the sysctls to be reset at runtime, yielding potentially unexpected
# results. It is a better idea to rely on systemd-sysctl.service(8)
# or an equivalent service alone to configure the defaults at a well
# defined occassion on early boot and use the protect_sysctl setting
# to preserve the defaults if needed.
# reapply_sysctl = 0

# Preset system uname string for architecture specific tuning.
# It can be used to force tuning for specific architecture.
# If commented, "uname" will be called to fill its content.
Expand Down
6 changes: 5 additions & 1 deletion tuned/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
CFG_SLEEP_INTERVAL = "sleep_interval"
CFG_UPDATE_INTERVAL = "update_interval"
CFG_RECOMMEND_COMMAND = "recommend_command"
CFG_PROTECT_SYSCTL = "protect_sysctl"
CFG_REAPPLY_SYSCTL = "reapply_sysctl"
CFG_DEFAULT_INSTANCE_PRIORITY = "default_instance_priority"
CFG_UDEV_BUFFER_SIZE = "udev_buffer_size"
Expand Down Expand Up @@ -124,8 +125,11 @@
# recommend command availability
CFG_DEF_RECOMMEND_COMMAND = True
CFG_FUNC_RECOMMEND_COMMAND = "getboolean"
# protect system sysctl
CFG_DEF_PROTECT_SYSCTL = True
CFG_FUNC_PROTECT_SYSCTL = "getboolean"
# reapply system sysctl
CFG_DEF_REAPPLY_SYSCTL = True
CFG_DEF_REAPPLY_SYSCTL = False
CFG_FUNC_REAPPLY_SYSCTL = "getboolean"
# default instance priority
CFG_DEF_DEFAULT_INSTANCE_PRIORITY = 0
Expand Down
43 changes: 28 additions & 15 deletions tuned/plugins/plugin_sysctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ def _instance_cleanup(self, instance):
self._storage.unset(storage_key)

def _instance_apply_static(self, instance):
system_sysctl = _read_system_sysctl()
protect_sysctl = self._global_cfg.get_bool(consts.CFG_PROTECT_SYSCTL, consts.CFG_DEF_PROTECT_SYSCTL)

for option, value in list(instance._sysctl.items()):
if protect_sysctl and option in system_sysctl:
log.info("sysctl '%s' will not be set to '%s', is set to '%s' in sysctl.conf(5)/sysctl.d(5)"
% (option, value, system_sysctl[option]))
continue
original_value = _read_sysctl(option)
if original_value is None:
log.error("sysctl option %s will not be set, failed to read the original value."
Expand All @@ -84,7 +91,12 @@ def _instance_apply_static(self, instance):

if self._global_cfg.get_bool(consts.CFG_REAPPLY_SYSCTL, consts.CFG_DEF_REAPPLY_SYSCTL):
log.info("reapplying system sysctl")
_apply_system_sysctl(instance._sysctl)
for option, value in list(system_sysctl.items()):
if option in instance._sysctl and instance._sysctl[option] != value:
log.info("Overriding sysctl parameter '%s' from '%s' to '%s'"
% (option, instance._sysctl[option], value))
_write_sysctl(option, value, ignore_missing = True)


def _instance_verify_static(self, instance, ignore_missing, devices):
ret = True
Expand All @@ -103,7 +115,8 @@ def _instance_unapply_static(self, instance, full_rollback = False):
_write_sysctl(option, value)


def _apply_system_sysctl(instance_sysctl):
def _read_system_sysctl():
sysctls = {}
files = {}
for d in SYSCTL_CONFIG_DIRS:
try:
Expand All @@ -119,23 +132,28 @@ def _apply_system_sysctl(instance_sysctl):
for fname in sorted(files.keys()):
d = files[fname]
path = "%s/%s" % (d, fname)
_apply_sysctl_config_file(path, instance_sysctl)
_apply_sysctl_config_file("/etc/sysctl.conf", instance_sysctl)
sysctls.update(_read_sysctl_config_file(path))
sysctls.update(_read_sysctl_config_file("/etc/sysctl.conf"))
return sysctls

def _apply_sysctl_config_file(path, instance_sysctl):
log.debug("Applying sysctl settings from file %s" % path)
def _read_sysctl_config_file(path):
log.debug("Reading sysctl settings from file %s" % path)
sysctls = {}
try:
with open(path, "r") as f:
for lineno, line in enumerate(f, 1):
_apply_sysctl_config_line(path, lineno, line, instance_sysctl)
log.debug("Finished applying sysctl settings from file %s"
sysctl_line = _read_sysctl_config_line(path, lineno, line)
if sysctl_line is not None:
sysctls[sysctl_line[0]] = sysctl_line[1]
log.debug("Finished reading sysctl settings from file %s"
% path)
except (OSError, IOError) as e:
if e.errno != errno.ENOENT:
log.error("Error reading sysctl settings from file %s: %s"
% (path, str(e)))
return sysctls

def _apply_sysctl_config_line(path, lineno, line, instance_sysctl):
def _read_sysctl_config_line(path, lineno, line):
line = line.strip()
if len(line) == 0 or line[0] == "#" or line[0] == ";":
return
Expand All @@ -150,12 +168,7 @@ def _apply_sysctl_config_line(path, lineno, line, instance_sysctl):
log.error("Syntax error in file %s, line %d"
% (path, lineno))
return
value = value.strip()
if option in instance_sysctl and instance_sysctl[option] != value:
log.info("Overriding sysctl parameter '%s' from '%s' to '%s'"
% (option, instance_sysctl[option], value))

_write_sysctl(option, value, ignore_missing = True)
return (option, value.strip())

def _get_sysctl_path(option):
return "/proc/sys/%s" % option.replace(".", "/")
Expand Down