1
0
Fork 0

implemented recommend profile functionality

resolves: rhbz#848935
This commit is contained in:
Jaroslav Škarvada 2012-11-29 10:25:05 +01:00
parent ed287a393d
commit 3d95e77f78
11 changed files with 86 additions and 5 deletions

View file

@ -13,7 +13,8 @@ archive: clean
cp AUTHORS COPYING INSTALL README $(VERSIONED_NAME)
cp tuned.py tuned.spec tuned.service tuned.tmpfiles Makefile tuned-adm.py tuned.bash dbus.conf $(VERSIONED_NAME)
cp tuned.py tuned.spec tuned.service tuned.tmpfiles Makefile tuned-adm.py \
tuned.bash dbus.conf recommend.conf $(VERSIONED_NAME)
cp -a doc experiments man profiles systemtap tuned $(VERSIONED_NAME)
tar cjf $(VERSIONED_NAME).tar.bz2 $(VERSIONED_NAME)
@ -47,11 +48,13 @@ install:
# configuration files
mkdir -p $(DESTDIR)/etc/tuned
echo -n balanced > $(DESTDIR)/etc/tuned/active_profile
# None profile in the moment, autodetection will be used
echo -n > $(DESTDIR)/etc/tuned/active_profile
# profiles
# profiles & system config
mkdir -p $(DESTDIR)$(TUNED_PROFILESDIR)
cp -a profiles/* $(DESTDIR)$(TUNED_PROFILESDIR)/
install -m 0644 recommend.conf $(DESTDIR)$(TUNED_PROFILESDIR)/recommend.conf
# Install bash completion
mkdir -p $(DESTDIR)/etc/bash_completion.d

View file

@ -47,6 +47,10 @@ Show current active profile.
.B profile <profile>
Switches to the given profilename. If none is given or no valid one is given the command gracefully exits without performing any operation.
.TP
.B recommend
Recommend profile suitable for your system. Currently only static detection is implemented - it decides according to data in /etc/system-release-cpe and virt-what output. The rules for autodetection are defined in recommend.conf in profile directory. They can be overriden by user by putting the recommend.conf into /etc/tuned. The default rules recommends profiles targeted to the best performance or balanced profile if unsure.
.TP
.B off
Switch off tuned.

17
recommend.conf Normal file
View file

@ -0,0 +1,17 @@
# Tuned rules for recommend_profile.
#
# The 'virt' RE matches virt-what output.
# The 'system' RE matches /etc/system-release-cpe.
# Both 'virt' and 'system' needs to match for profile to match.
# If 'virt' or 'system' is not specified, it matches for every string.
# If 'virt' or 'system' is empty, i.e. 'virt=', it matches only empty string (alias for '^$').
# If several profiles matched, the first match is taken.
[throughput-performance]
virt=
system=.*computenode.*
[virtual-guest]
virt=.+
[balanced]

View file

@ -46,6 +46,9 @@ if __name__ == "__main__":
parser_profile.set_defaults(action="profile")
parser_profile.add_argument("profiles", metavar="profile", type=str, nargs="+", help="profile name")
parser_off = subparsers.add_parser("recommend", help="recommend profile")
parser_off.set_defaults(action="recommend_profile")
args = parser.parse_args(sys.argv[1:])
options = vars(args)

View file

@ -70,10 +70,17 @@ if [ $1 -eq 1 ]; then
/usr/bin/systemctl daemon-reload &>/dev/null || :
fi
# try to autodetect the best profile for the system in case there is none preset
if [ ! -f /etc/tuned/active_profile -o -z "`cat /etc/tuned/active_profile 2>/dev/null`" ]
then
PROFILE=`/usr/sbin/tuned-adm recommend 2>/dev/null`
[ "$PROFILE" ] || PROFILE=balanced
/usr/sbin/tuned-adm profile "$PROFILE" 2>/dev/null || echo -n "$PROFILE" > /etc/tuned/active_profile
fi
# convert active_profile from full path to name (if needed)
sed -i 's|.*/\([^/]\+\)/[^\.]\+\.conf|\1|' /etc/tuned/active_profile
%preun
# package removal, not upgrade
if [ $1 -eq 0 ]; then

View file

@ -36,6 +36,9 @@ class Admin(object):
return True
def recommend_profile(self):
print self._controller.recommend_profile()
def off(self):
result = self._controller.off()
if not result:

View file

@ -1,5 +1,6 @@
import dbus
import dbus.exceptions
import tuned.utils.commands
from exceptions import TunedAdminException
__all__ = ["DBusController"]
@ -53,5 +54,12 @@ class DBusController(object):
else:
return False
def recommend_profile(self):
try:
profile = self._call("recommend_profile")
except TunedAdminException:
profile = tuned.utils.commands.recommend_profile()
return profile
def off(self):
return self._call("disable")

4
tuned/consts.py Normal file
View file

@ -0,0 +1,4 @@
LOAD_DIRECTORIES = ["/usr/lib/tuned", "/etc/tuned"]
AUTODETECT_FILE = "autodetect.conf"
DEFAULT_PROFILE = "balanced"
SYSTEM_RELEASE_FILE = "/etc/system-release-cpe"

View file

@ -7,6 +7,7 @@ import signal
import os
import sys
import select
import tuned.consts as consts
PID_FILE = "/run/tuned/tuned.pid"
DAEMONIZE_PARENT_TIMEOUT = 5
@ -28,7 +29,7 @@ class Application(object):
profile_factory = profiles.Factory()
profile_merger = profiles.Merger()
profile_locator = profiles.Locator(["/usr/lib/tuned", "/etc/tuned"])
profile_locator = profiles.Locator(consts.LOAD_DIRECTORIES)
profile_loader = profiles.Loader(profile_locator, profile_factory, profile_merger)
self._daemon = daemon.Daemon(unit_manager, profile_loader, profile_name)

View file

@ -2,6 +2,7 @@ from tuned import exports
import tuned.logs
import tuned.exceptions
import threading
import tuned.utils.commands
__all__ = ["Controller"]
@ -97,3 +98,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
@exports.export("", "as")
def profiles(self):
return self._daemon.profile_loader.profile_locator.get_known_names()
@exports.export("", "s")
def recommend_profile(self):
return tuned.utils.commands.recommend_profile()

View file

@ -1,6 +1,9 @@
import tuned.logs
import copy
import os
import tuned.consts as consts
import ConfigParser
import re
from subprocess import *
__all__ = ["write_to_file", "read_file", "execute"]
@ -40,3 +43,26 @@ def execute(args):
log.error("Executing %s error: %s" % (args[0], e))
return out
def recommend_profile():
profile = consts.DEFAULT_PROFILE
for f in consts.LOAD_DIRECTORIES:
parser = ConfigParser.SafeConfigParser(allow_no_value = False)
try:
parser.read(os.path.join(f, consts.AUTODETECT_FILE))
except:
continue
for section in reversed(parser.sections()):
match1 = match2 = True
for option, value in parser.items(section):
value = str(value)
if value == "":
value = r"^$"
if option == "virt":
if not re.match(value, execute("virt-what"), re.S):
match1 = False
elif option == "system":
if not re.match(value, read_file(consts.SYSTEM_RELEASE_FILE), re.S):
match2 = False
if match1 and match2:
profile = section
return profile