tuned-adm: switch completely to DBus
This commit is contained in:
parent
14e183f93d
commit
718a611a7f
5 changed files with 155 additions and 119 deletions
167
tuned-adm.py
167
tuned-adm.py
|
|
@ -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
3
tuned/admin/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from admin import *
|
||||
from exceptions import *
|
||||
from dbus_controller import *
|
||||
43
tuned/admin/admin.py
Normal file
43
tuned/admin/admin.py
Normal 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
|
||||
57
tuned/admin/dbus_controller.py
Normal file
57
tuned/admin/dbus_controller.py
Normal 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")
|
||||
4
tuned/admin/exceptions.py
Normal file
4
tuned/admin/exceptions.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import tuned.exceptions
|
||||
|
||||
class TunedAdminException(tuned.exceptions.TunedException):
|
||||
pass
|
||||
Loading…
Reference in a new issue