1
0
Fork 0

Merge pull request #74 from olysonek/fixes

Various fixes
This commit is contained in:
Jaroslav Škarvada 2017-10-10 10:09:22 +02:00 committed by GitHub
commit 66bef6e45a
6 changed files with 60 additions and 39 deletions

View file

@ -222,7 +222,7 @@ class Admin(object):
return self._action_dbus_list()
profile_name = " ".join(profiles)
if profile_name == "":
return False
return self._controller.exit(False)
self._daemon_action_finished.clear()
(ret, msg) = self._controller.switch_profile(profile_name)
if self._async or not ret:

View file

@ -186,9 +186,7 @@ class Application(object):
# override global config if ran from command line with daemon option (-d)
if daemon:
self.config.set(consts.CFG_DAEMON, True)
if self.config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON):
exports.start()
else:
if not self.config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON):
log.warn("Using one shot no deamon mode, most of the functionality will be not available, it can be changed in global config")
result = self._controller.run()
if self.config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON):

View file

@ -28,9 +28,12 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
Controller main loop. The call is blocking.
"""
log.info("starting controller")
self.start()
res = self.start()
daemon = self._global_config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON)
if not res and daemon:
exports.start()
if self._global_config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON):
if daemon:
self._terminate.clear()
# we have to pass some timeout, otherwise signals will not work
while not self._cmd.wait(self._terminate, 3600):

View file

@ -6,13 +6,14 @@ from tuned.exceptions import TunedException
from tuned.profiles.exceptions import InvalidProfileException
import tuned.consts as consts
from tuned.utils.commands import commands
from tuned import exports
import re
log = tuned.logs.get()
class Daemon(object):
def __init__(self, unit_manager, profile_loader, profile_name=None, config=None, application=None):
def __init__(self, unit_manager, profile_loader, profile_names=None, config=None, application=None):
log.debug("initializing daemon")
self._daemon = consts.CFG_DEF_DAEMON
self._sleep_interval = int(consts.CFG_DEF_SLEEP_INTERVAL)
@ -43,7 +44,7 @@ class Daemon(object):
self._init_threads()
self._cmd = commands()
try:
self._init_profile(profile_name)
self._init_profile(profile_names)
except TunedException as e:
log.error("Cannot set initial profile. No tunings will be enabled: %s" % e)
@ -57,40 +58,44 @@ class Daemon(object):
self._not_used.set()
self._profile_applied = threading.Event()
def _init_profile(self, profile_name):
def _init_profile(self, profile_names):
manual = True
if profile_name is None:
(profile_name, manual) = self._get_startup_profile()
if profile_name is None:
if profile_names is None:
(profile_names, manual) = self._get_startup_profile()
if profile_names is None:
log.info("No profile is preset, running in manual mode. No profile will be enabled.")
# Passed through '-p' cmdline option
elif profile_name == "":
elif profile_names == "":
log.info("No profile will be enabled.")
self._profile = None
self._manual = None
self.set_profile(profile_name, manual)
self.set_profile(profile_names, manual)
def set_profile(self, profile_name, manual, save_instantly=False):
def set_profile(self, profile_names, manual, save_instantly=False):
if self.is_running():
raise TunedException(self._notify_profile_changed(profile_name, False, "Cannot set profile while the daemon is running."))
raise TunedException(self._notify_profile_changed(profile_names, False, "Cannot set profile while the daemon is running."))
if profile_name == "" or profile_name is None:
if profile_names == "" or profile_names is None:
self._profile = None
self._manual = manual
elif profile_name not in self.profile_loader.profile_locator.get_known_names():
raise TunedException(self._notify_profile_changed(profile_name, False, "Requested profile '%s' doesn't exist." % profile_name))
else:
profile_list = profile_names.split()
for profile in profile_list:
if profile not in self.profile_loader.profile_locator.get_known_names():
raise TunedException(self._notify_profile_changed(\
profile_names, False,\
"Requested profile '%s' doesn't exist." % profile))
try:
self._profile = self._profile_loader.load(profile_name)
self._profile = self._profile_loader.load(profile_names)
self._manual = manual
except InvalidProfileException as e:
raise TunedException(self._notify_profile_changed(profile_name, False, "Cannot load profile '%s': %s" % (profile_name, e)))
raise TunedException(self._notify_profile_changed(profile_names, False, "Cannot load profile(s) '%s': %s" % (profile_names, e)))
if save_instantly:
if profile_name is None:
profile_name = ""
self._save_active_profile(profile_name, manual)
if profile_names is None:
profile_names = ""
self._save_active_profile(profile_names, manual)
@property
def profile(self):
@ -106,17 +111,19 @@ class Daemon(object):
# send notification when profile is changed (everything is setup) or if error occured
# result: True - OK, False - error occured
def _notify_profile_changed(self, profile_name, result, errstr):
def _notify_profile_changed(self, profile_names, result, errstr):
if self._application is not None and self._application._dbus_exporter is not None:
self._application._dbus_exporter.send_signal(consts.DBUS_SIGNAL_PROFILE_CHANGED, profile_name, result, errstr)
self._application._dbus_exporter.send_signal(consts.DBUS_SIGNAL_PROFILE_CHANGED, profile_names, result, errstr)
return errstr
def _system_shutting_down(self):
def _full_rollback_required(self):
retcode, out = self._cmd.execute(["systemctl", "is-system-running"], no_errors = [0])
if retcode < 0:
return False
if out[:8] == "stopping":
return True
return False
retcode, out = self._cmd.execute(["systemctl", "list-jobs"], no_errors = [0])
return re.search(r"\b(shutdown|reboot|halt|poweroff)\.target.*start", out) is not None
return re.search(r"\b(shutdown|reboot|halt|poweroff)\.target.*start", out) is None
def _thread_code(self):
if self._profile is None:
@ -127,6 +134,8 @@ class Daemon(object):
self._unit_manager.start_tuning()
self._profile_applied.set()
log.info("static tuning from profile '%s' applied" % self._profile.name)
if self._daemon:
exports.start()
self._notify_profile_changed(self._profile.name, True, "OK")
if self._daemon:
@ -163,18 +172,18 @@ class Daemon(object):
# stopped by user and in such case do full cleanup, without systemd never
# do full cleanup
full_rollback = False
if self._system_shutting_down():
log.info("terminating Tuned due to system shutdown / reboot")
else:
if self._full_rollback_required():
log.info("terminating Tuned, rolling back all changes")
full_rollback = True
else:
log.info("terminating Tuned due to system shutdown / reboot")
if self._daemon:
self._unit_manager.stop_tuning(full_rollback)
self._unit_manager.destroy_all()
def _save_active_profile(self, profile_name, manual):
def _save_active_profile(self, profile_names, manual):
try:
self._cmd.save_active_profile(profile_name, manual)
self._cmd.save_active_profile(profile_names, manual)
except TunedException as e:
log.error(str(e))

View file

@ -56,6 +56,9 @@ class DBusExporter(interfaces.ExporterInterface):
def object_name(self):
return self._object_name
def running(self):
return self._thread is not None
def export(self, method, in_signature, out_signature):
if not inspect.ismethod(method):
raise Exception("Only bound methods can be exported.")
@ -129,6 +132,8 @@ class DBusExporter(interfaces.ExporterInterface):
self._dbus_object_cls = cls
def start(self):
if self.running():
return
if self._dbus_object_cls is None:
self._construct_dbus_object_class()

View file

@ -38,11 +38,16 @@ class NetTuningPlugin(base.Plugin):
def _instance_init(self, instance):
instance._has_static_tuning = True
instance._has_dynamic_tuning = True
instance._load_monitor = self._monitors_repository.create("net", instance.devices)
instance._idle = {}
instance._stats = {}
if self._option_bool(instance.options["dynamic"]):
instance._has_dynamic_tuning = True
instance._load_monitor = self._monitors_repository.create("net", instance.devices)
instance._idle = {}
instance._stats = {}
else:
instance._has_dynamic_tuning = False
instance._load_monitor = None
instance._idle = None
instance._stats = None
def _instance_cleanup(self, instance):
if instance._load_monitor is not None:
@ -120,6 +125,7 @@ class NetTuningPlugin(base.Plugin):
@classmethod
def _get_config_options(cls):
return {
"dynamic": True,
"wake_on_lan": None,
"nf_conntrack_hashsize": None,
"features": None,