From eccaf795b95cb8b24e61d7c277b375156efeb540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Mon, 8 Jun 2020 17:27:59 +0200 Subject: [PATCH 1/2] tuned-adm: Fix profile_info crash when no profile is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If Tuned is running without any profile applied (e.g. after running 'tuned-adm off'), then 'tuned-adm profile_info' crashes with the following error: 2020-06-08 17:24:11,998 ERROR dbus.connection: Unable to set arguments (None,) according to signature 's': : Expected a string or unicode object ERROR:dbus.connection:Unable to set arguments (None,) according to signature 's': : Expected a string or unicode object dbus[25054]: arguments to dbus_message_get_destination() were incorrect, assertion "message != NULL" failed in file ../../dbus/dbus-message.c line 3678. This is normally a bug in some application using the D-Bus library. D-Bus not built with -rdynamic so unable to print a backtrace Aborted (core dumped) To fix it, detect that no profile is applied and print the same message as in _action_profile_info in this case. Signed-off-by: Ondřej Lysoněk --- tuned/admin/admin.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tuned/admin/admin.py b/tuned/admin/admin.py index c56633b..680d267 100644 --- a/tuned/admin/admin.py +++ b/tuned/admin/admin.py @@ -149,7 +149,12 @@ class Admin(object): def _action_dbus_profile_info(self, profile = ""): if profile == "": profile = self._dbus_get_active_profile() - return self._controller.exit(self._print_profile_info(profile, self._controller.profile_info(profile))) + if profile: + res = self._print_profile_info(profile, self._controller.profile_info(profile)) + else: + print("No current active profile.") + res = False + return self._controller.exit(res) def _action_profile_info(self, profile = ""): if profile == "": From 902292088338bce8d7f5f742ab01b7920405bf00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= Date: Mon, 8 Jun 2020 16:51:20 +0200 Subject: [PATCH 2/2] Make tuned-adm indicate which profile is post-loaded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the post-loaded profile is shown only among regular active profiles. For example: Current active profile: balanced post This is not entirely user-friendly, because the user may not know why the post-loaded profile is there, given that they did not specify it in a 'tuned-adm profile' command and given that it's not present in /etc/tuned/active_profile. To give the user a hint about this and also to make it easy to see exactly which profile is post-loaded, we make 'tuned-adm active' show the following: Current active profile: balanced post Current post-loaded profile: post Signed-off-by: Ondřej Lysoněk --- com.redhat.tuned.policy | 10 ++++++++++ tuned/admin/admin.py | 36 ++++++++++++++++++++++++++++++++-- tuned/admin/dbus_controller.py | 3 +++ tuned/daemon/controller.py | 6 ++++++ tuned/daemon/daemon.py | 6 ++++++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/com.redhat.tuned.policy b/com.redhat.tuned.policy index ee54d03..0d0934f 100644 --- a/com.redhat.tuned.policy +++ b/com.redhat.tuned.policy @@ -27,6 +27,16 @@ + + Show active post-loaded profile + Authentication is required to show active post-loaded profile + + yes + yes + yes + + + Disable Tuned Authentication is required to disable Tuned diff --git a/tuned/admin/admin.py b/tuned/admin/admin.py index 680d267..b47e6b4 100644 --- a/tuned/admin/admin.py +++ b/tuned/admin/admin.py @@ -131,6 +131,16 @@ class Admin(object): manual = profile is not None return consts.ACTIVE_PROFILE_MANUAL if manual else consts.ACTIVE_PROFILE_AUTO + def _dbus_get_post_loaded_profile(self): + profile_name = self._controller.post_loaded_profile() + if profile_name == "": + profile_name = None + return profile_name + + def _get_post_loaded_profile(self): + profile_name = self._cmd.get_post_loaded_profile() + return profile_name + def _print_profile_info(self, profile, profile_info): if profile_info[0] == True: print("Profile name:") @@ -176,20 +186,42 @@ class Admin(object): print("Current active profile: %s" % profile_name) return True + def _print_post_loaded_profile(self, profile_name): + if profile_name: + print("Current post-loaded profile: %s" % profile_name) + def _action_dbus_active(self): - return self._controller.exit(self._print_profile_name(self._dbus_get_active_profile())) + active_profile = self._dbus_get_active_profile() + res = self._print_profile_name(active_profile) + if res: + post_loaded_profile = self._dbus_get_post_loaded_profile() + self._print_post_loaded_profile(post_loaded_profile) + return self._controller.exit(res) def _action_active(self): try: profile_name = self._get_active_profile() + post_loaded_profile = self._get_post_loaded_profile() + # The result of the DBus call active_profile includes + # the post-loaded profile, so add it here as well + if post_loaded_profile: + if profile_name: + profile_name += " " + else: + profile_name = "" + profile_name += post_loaded_profile except TunedException as e: self._error(str(e)) return False if profile_name is not None and not self._tuned_is_running(): print("It seems that tuned daemon is not running, preset profile is not activated.") print("Preset profile: %s" % profile_name) + if post_loaded_profile: + print("Preset post-loaded profile: %s" % post_loaded_profile) return True - return self._print_profile_name(profile_name) + res = self._print_profile_name(profile_name) + self._print_post_loaded_profile(post_loaded_profile) + return res def _print_profile_mode(self, mode): print("Profile selection mode: " + mode) diff --git a/tuned/admin/dbus_controller.py b/tuned/admin/dbus_controller.py index a03d35e..5141375 100644 --- a/tuned/admin/dbus_controller.py +++ b/tuned/admin/dbus_controller.py @@ -117,6 +117,9 @@ class DBusController(object): def profile_mode(self): return self._call("profile_mode") + def post_loaded_profile(self): + return self._call("post_loaded_profile") + def switch_profile(self, new_profile): if new_profile == "": return (False, "No profile specified") diff --git a/tuned/daemon/controller.py b/tuned/daemon/controller.py index 88e4438..60cba34 100644 --- a/tuned/daemon/controller.py +++ b/tuned/daemon/controller.py @@ -210,6 +210,12 @@ class Controller(tuned.exports.interfaces.ExportableInterface): mode = consts.ACTIVE_PROFILE_MANUAL if manual else consts.ACTIVE_PROFILE_AUTO return mode, "" + @exports.export("", "s") + def post_loaded_profile(self, caller = None): + if caller == "": + return "" + return self._daemon.post_loaded_profile or "" + @exports.export("", "b") def disable(self, caller = None): if caller == "": diff --git a/tuned/daemon/daemon.py b/tuned/daemon/daemon.py index d0149d9..e2c5c32 100644 --- a/tuned/daemon/daemon.py +++ b/tuned/daemon/daemon.py @@ -161,6 +161,12 @@ class Daemon(object): def manual(self): return self._manual + @property + def post_loaded_profile(self): + # Return the profile name only if the profile is active. If + # the profile is not active, then the value is meaningless. + return self._post_loaded_profile if self._profile else None + @property def profile_loader(self): return self._profile_loader