1
0
Fork 0

tuned-adm: switch completely to DBus

This commit is contained in:
Jan Vcelak 2012-11-05 17:00:47 +01:00
parent 14e183f93d
commit 718a611a7f
5 changed files with 155 additions and 119 deletions

View file

@ -3,8 +3,7 @@
# tuned-adm: A command line utility for switching between user
# definable tuning profiles.
#
# Copyright (C) 2012 Red Hat, Inc.
# Authors: Jan Kaluza
# Copyright (C) 2008-2012 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@ -21,127 +20,57 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
import os
import argparse
import sys
import locale
import signal
import traceback
import tuned.admin
PIDFILE = "/run/tuned/tuned.pid"
def usage():
print """
Usage: tuned-adm <command>
commands:
help show this help message and exit
list list all available and active profiles
active show current active profile
off switch off all tunning
profile <profile-name> switch to given profile
"""
def listdir_joined(path):
return [os.path.join(path, entry) for entry in os.listdir(path)]
class Tuned_adm:
def error(self, msg, exit_code = 1):
print >>sys.stderr, msg
sys.exit(exit_code)
def check_permissions(self):
if not os.geteuid() == 0:
self.error("Only root can run this script.", 2)
def run(self, args):
if args[0] == "list":
self.show_profiles()
elif args[0] == "active":
self.show_active_profile()
#self.service_status("tuned")
#self.service_status("ktune")
elif args[0] == "off":
self.check_permissions()
self.off()
elif args[0] == "profile":
if len(args) >= 2:
self.check_permissions()
self.set_active_profile(args[1:])
else:
self.error("Invalid profile specification. Use 'tuned-adm list' to get all available profiles.")
else:
self.error("Nonexistent argument '%s'." % args[0])
def off(self):
pid = 0
try:
with open(PIDFILE) as f:
pid = int(f.read())
except (OSError,IOError) as e:
pass
if pid:
os.kill(pid, signal.SIGTERM)
def show_active_profile(self):
try:
with open("/etc/tuned/active_profile") as f:
print "Current active profile:", f.read().replace("\n", " ")
except:
pass
def get_profiles(self):
profiles = []
try:
profiles += listdir_joined("/usr/lib/tuned")
except:
pass
try:
profiles += listdir_joined("/etc/tuned")
except:
pass
return sorted(map(lambda p: os.path.basename(p), \
filter(lambda p: os.path.exists(os.path.join(p, "tuned.conf")), profiles)))
def show_profiles(self):
print "Available profiles:"
for p in self.get_profiles():
print "- " + p
self.show_active_profile()
def set_active_profile(self, profiles):
pid = 0
try:
with open(PIDFILE) as f:
pid = int(f.read())
except (OSError,IOError) as e:
self.error("Cannot read %s: %s" % (PIDFILE, str(e)))
for profile in profiles:
if not profile in self.get_profiles():
self.error("Profile %s doesn't exist." % profile)
if pid:
try:
with open("/etc/tuned/active_profile", "w") as f:
f.write('\n'.join(profiles))
except (OSError,IOError) as e:
log.error("Cannot write profile into /etc/tuned/active_profile: %s" % (e))
os.kill(pid, signal.SIGHUP)
DBUS_BUS = "com.redhat.tuned"
DBUS_OBJECT = "/Tuned"
DBUS_INTERFACE = "com.redhat.tuned.control"
if __name__ == "__main__":
args = sys.argv[1:]
parser = argparse.ArgumentParser(description="Manage tuned daemon.")
parser.add_argument("--debug", action="store_true", help=argparse.SUPPRESS)
subparsers = parser.add_subparsers()
if len(args) < 1:
print >>sys.stderr, "Missing arguments."
usage()
parser_list = subparsers.add_parser("list", help="list available profiles")
parser_list.set_defaults(action="list")
parser_active = subparsers.add_parser("active", help="show active profile")
parser_active.set_defaults(action="active")
parser_off = subparsers.add_parser("off", help="switch off all tunings")
parser_off.set_defaults(action="off")
parser_profile = subparsers.add_parser("profile", help="switch to a given profile")
parser_profile.set_defaults(action="profile")
parser_profile.add_argument("profiles", metavar="profile", type=str, nargs="+", help="profile name")
args = parser.parse_args(sys.argv[1:])
options = vars(args)
debug = options.pop("debug")
action_name = options.pop("action")
result = False
try:
controller = tuned.admin.DBusController(DBUS_BUS, DBUS_OBJECT, DBUS_INTERFACE)
admin = tuned.admin.Admin(controller)
action = getattr(admin, action_name)
result = action(**options)
except tuned.admin.TunedAdminException as e:
if not debug:
print >>sys.stderr, e
else:
traceback.print_exc()
sys.exit(2)
except:
traceback.print_exc()
sys.exit(3)
if result == False:
sys.exit(1)
if args[0] in [ "help", "--help", "-h" ]:
usage()
else:
sys.exit(0)
tuned_adm = Tuned_adm()
tuned_adm.run(args)

3
tuned/admin/__init__.py Normal file
View file

@ -0,0 +1,3 @@
from admin import *
from exceptions import *
from dbus_controller import *

43
tuned/admin/admin.py Normal file
View file

@ -0,0 +1,43 @@
import sys
class Admin(object):
def __init__(self, controller):
self._controller = controller
def _error(self, message):
print >>sys.stderr, message
def list(self):
profiles = self._controller.profiles()
print "Available profiles:"
for profile in profiles:
print "- %s" % profile
self.active()
def active(self):
profile = self._controller.active_profile()
if profile is not None:
print "Current active profile: %s" % profile
return True
else:
print "No current active profile."
return False
def profile(self, profiles):
profile_name = " ".join(profiles)
if not self._controller.switch_profile(profile_name):
self._error("Cannot switch the profile.")
return False
if not self._controller.is_running():
if not self._controller.start():
self._error("Cannot enable the tuning.")
return False
return True
def off(self):
result = self._controller.off()
if not result:
self._error("Cannot disable active profile.")
return result

View file

@ -0,0 +1,57 @@
import dbus
import dbus.exceptions
from exceptions import TunedAdminException
__all__ = ["DBusController"]
class DBusController(object):
def __init__(self, bus_name, interface_name, object_name):
self._bus_name = bus_name
self._interface_name = interface_name
self._object_name = object_name
self._proxy = None
def _init_proxy(self):
if self._proxy is None:
bus = dbus.SystemBus()
self._proxy = bus.get_object(self._bus_name, self._interface_name, self._object_name)
def _call(self, method_name, *args, **kwargs):
try:
self._init_proxy()
except dbus.exceptions.DBusException:
raise TunedAdminException("Cannot talk to Tuned daemon via DBus.")
try:
method = self._proxy.get_dbus_method(method_name)
return method(*args, **kwargs)
except dbus.exceptions.DBusException as dbus_exception:
raise TunedAdminException("DBus call to Tuned daemon failed (%s)." % str(dbus_exception))
def is_running(self):
return self._call("is_running")
def start(self):
return self._call("start")
def stop(self):
return self._call("stop")
def profiles(self):
return self._call("profiles")
def active_profile(self):
profile_name = self._call("active_profile")
if profile_name != "":
return profile_name
else:
return None
def switch_profile(self, new_profile):
if new_profile != "":
return self._call("switch_profile", new_profile)
else:
return False
def off(self):
return self._call("disable")

View file

@ -0,0 +1,4 @@
import tuned.exceptions
class TunedAdminException(tuned.exceptions.TunedException):
pass