These changes don't completely fix the gui for Gtk-3.0 but they get us a lot closer, patches that improve this are very welcome, so get hacking!
I also fixed up the spacing and formatting to match python standards as of python3
John Kacur (33): tuna_gui.py: Reformat the file, style fix-ups tuna_gui.glade: Initial changes to upgrade glade file for gtk3 tuna_gui.py: gtk2 to gtk3 changes tuna: gui changes for gtk2 to gtk3 tuna: More changes to header files in tuna/gui for gtk3 tuna: add to gitignore and create gitattributes tuna: modernize the spacing in irqview tuna: Remove old glade imports from tuna_gui.py tuna_gui.py: Fix inconsistent spacing from in tuna_gui.py tuna: cpuview.py - Modernize the spacing tuna: cpuview.py: A few more style improvements irqview: fix bad spacing tuna: procview.py: Update the spacing and style tuna: commonview.py: Update the spacing and style tuna: procview.py: Update spacing and style tuna: util.py: Update the spacing and fix some style problems tuna-cmd: Update the spacing and style for tuna-cmd tuna: tuna-cmd:py: Convert type comparison to isinstance tuna: config.py: Update spacing to 4 spaces tuna/gui/__init__.py: Fix some whitespace problems tuna: commonview.py: Fix comparisons with None tuna: cpuview.py: box.pack_start needs extra parameter tuna: tuna-cmd.py Fix style problems recommened by PEP8 tuna: Fix spacing of oscilloscope.py tuna: config.py: Port file to Gtk-3.0 tuna:irqview.py: Port to Gtk-3.0 tuna: procview.py: Port to Gtk-3.0 tuna: profileview.py: Port to Gtk-3.0 tuna: util.py: Fix some style problems tuna: oscilloscope.py: Changes to port to Gtk-3.0 tuna: sysfs.py: Update spacing / tabs to modern python style tuna: tuna.py: Update spacing / tabs to modern python style tuna: tuna_gui.py: Chanages to port to Gtk-3.0
.gitattributes | 2 + .gitignore | 2 + oscilloscope-cmd.py | 141 ++-- tuna-cmd.py | 1267 ++++++++++++++++++------------------ tuna/config.py | 760 +++++++++++----------- tuna/gui/__init__.py | 6 +- tuna/gui/commonview.py | 521 +++++++-------- tuna/gui/cpuview.py | 694 ++++++++++---------- tuna/gui/irqview.py | 640 ++++++++++--------- tuna/gui/procview.py | 1347 +++++++++++++++++++-------------------- tuna/gui/profileview.py | 668 ++++++++++--------- tuna/gui/util.py | 226 +++---- tuna/oscilloscope.py | 861 ++++++++++++------------- tuna/sysfs.py | 199 +++--- tuna/tuna.py | 1207 ++++++++++++++++++----------------- tuna/tuna_gui.glade | 1037 ++++++++++++++++-------------- tuna/tuna_gui.py | 294 +++++---- 17 files changed, 5030 insertions(+), 4842 deletions(-) create mode 100644 .gitattributes mode change 100755 => 100644 tuna/gui/util.py
This change reformats the file to modern python formating. It also corrects a number of style changes.
This is in prepartion for changes to update the gui code, which will occur in subsequent patches.
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.py | 286 +++++++++++++++++++++++++---------------------- 1 file changed, 154 insertions(+), 132 deletions(-)
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 490dc5946cbc..25e3a2c1741a 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -1,10 +1,15 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import pygtk -pygtk.require("2.0") +import os +import procfs +import sys
-import gtk, gobject, os, procfs, sys +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +import gobject import gtk.glade from gtk import ListStore from .gui.cpuview import cpuview @@ -14,136 +19,153 @@ from .gui.commonview import commonview from .gui.profileview import profileview from .config import Config
-tuna_glade_dirs = [ ".", "tuna", "/usr/share/tuna" ] +tuna_glade_dirs = [".", "tuna", "/usr/share/tuna"] tuna_glade = None
class main_gui:
- def __init__(self, show_kthreads = True, show_uthreads = True, cpus_filtered = []): - global tuna_glade - - (app, localedir) = ('tuna', '/usr/share/locale') - gtk.glade.bindtextdomain(app, localedir) - gtk.glade.textdomain(app) - - if self.check_root(): - sys.exit(1) - for dir in tuna_glade_dirs: - tuna_glade = "%s/tuna_gui.glade" % dir - if os.access(tuna_glade, os.F_OK): - break - self.wtree = gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") - self.ps = procfs.pidstats() - self.irqs = procfs.interrupts() - self.window = self.wtree.get_widget("mainbig_window") - - self.procview = procview(self.wtree.get_widget("processlist"), - self.ps, show_kthreads, show_uthreads, - cpus_filtered, tuna_glade) - self.irqview = irqview(self.wtree.get_widget("irqlist"), - self.irqs, self.ps, cpus_filtered, - tuna_glade) - self.cpuview = cpuview(self.wtree.get_widget("vpaned1"), - self.wtree.get_widget("hpaned2"), - self.wtree.get_widget("cpuview"), - self.procview, self.irqview, cpus_filtered) - - self.config = Config() - self.check_env() - self.commonview = commonview() - self.commonview.contentTable = self.wtree.get_widget("commonTbl") - self.commonview.configFileCombo = self.wtree.get_widget("profileSelector") - - self.profileview = profileview() - self.profileview.config = self.config - self.commonview.config = self.config - self.profileview.commonview = self.commonview - self.commonview.profileview = self.profileview - - self.profileview.setWtree(self.wtree) - self.profileview.init_default_file() - - event_handlers = { "on_mainbig_window_delete_event" : self.on_mainbig_window_delete_event, - "on_processlist_button_press_event" : self.procview.on_processlist_button_press_event, - "on_irqlist_button_press_event" : self.irqview.on_irqlist_button_press_event, - "on_loadProfileButton_clicked" : self.profileview.on_loadProfileButton_clicked, - "on_SaveButton_clicked" : self.profileview.on_SaveButton_clicked, - "on_UpdateButton_clicked" : self.profileview.on_UpdateButton_clicked, - "on_applyChanges_clicked" : self.commonview.on_applyChanges_clicked, - "on_undoChanges_clicked" : self.commonview.on_undoChanges_clicked, - "on_saveSnapshot_clicked" : self.commonview.on_saveSnapshot_clicked, - "on_saveTunedChanges_clicked" : self.commonview.on_saveTunedChanges_clicked, - "on_profileSelector_changed" : self.commonview.on_profileSelector_changed, - "on_profileTree_button_press_event" : self.profileview.on_profileTree_button_press_event - } - - self.wtree.signal_autoconnect(event_handlers) - - self.ps.reload_threads() - self.show() - self.timer = gobject.timeout_add(2500, self.refresh) - try: - self.icon = gtk.status_icon_new_from_stock(gtk.STOCK_PREFERENCES) - self.icon.connect("activate", self.on_status_icon_activate) - self.icon.connect("popup-menu", self.on_status_icon_popup_menu) - except AttributeError: - # Old pygtk2 - pass - pixbuf = self.window.render_icon(gtk.STOCK_PREFERENCES, - gtk.ICON_SIZE_SMALL_TOOLBAR) - self.window.set_icon(pixbuf) - - def on_status_icon_activate(self, status_icon): - if self.window.is_active(): - self.window.hide() - else: - self.window.present() - - def on_status_icon_popup_menu(self, icon, event_button, event_time): - menu = gtk.Menu() - - quit = gtk.MenuItem("_Quit") - menu.add(quit) - quit.connect_object('activate', self.on_mainbig_window_delete_event, icon) - quit.show() - - menu.popup(None, None, None, event_button, event_time) - - def on_mainbig_window_delete_event(self, obj, event = None): - gtk.main_quit() - - def show(self): - self.cpuview.refresh() - self.irqview.show() - self.procview.show() - - def refresh(self): - if not self.procview.evlist: # Poll, as we don't have perf - self.ps.reload() - self.ps.reload_threads() - self.procview.show() - self.irqview.refresh() - return True - - def check_root(self): - if os.getuid() == 0: - return False - self.binpath = sys.executable.strip(os.path.basename(sys.executable)) - os.execv(self.binpath + 'pkexec', [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) - return True - - def check_env(self): - if not os.path.exists(self.config.config["root"]): - try: - os.stat(self.config.config["root"]) - except (IOError,OSError): - os.mkdir(self.config.config["root"]) - if not os.path.exists("/root/.local/share/"): - try: - os.stat("/root/.local/share/") - except (IOError,OSError): - os.mkdir("/root/.local/") - os.mkdir("/root/.local/share/") - - def run(self): - gtk.main() + def __init__(self, show_kthreads=True, show_uthreads=True, cpus_filtered=[]): + global tuna_glade + + (app, localedir) = ('tuna', '/usr/share/locale') + gtk.glade.bindtextdomain(app, localedir) + gtk.glade.textdomain(app) + + if self.check_root(): + sys.exit(1) + for dir in tuna_glade_dirs: + tuna_glade = "%s/tuna_gui.glade" % dir + if os.access(tuna_glade, os.F_OK): + break + self.wtree = gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") + self.ps = procfs.pidstats() + self.irqs = procfs.interrupts() + self.window = self.wtree.get_widget("mainbig_window") + + self.procview = procview( + self.wtree.get_widget("processlist"), + self.ps, show_kthreads, show_uthreads, + cpus_filtered, tuna_glade) + self.irqview = irqview( + self.wtree.get_widget("irqlist"), + self.irqs, self.ps, cpus_filtered, + tuna_glade) + self.cpuview = cpuview( + self.wtree.get_widget("vpaned1"), + self.wtree.get_widget("hpaned2"), + self.wtree.get_widget("cpuview"), + self.procview, self.irqview, cpus_filtered) + + self.config = Config() + self.check_env() + self.commonview = commonview() + self.commonview.contentTable = self.wtree.get_widget("commonTbl") + self.commonview.configFileCombo = self.wtree.get_widget("profileSelector") + + self.profileview = profileview() + self.profileview.config = self.config + self.commonview.config = self.config + self.profileview.commonview = self.commonview + self.commonview.profileview = self.profileview + + self.profileview.setWtree(self.wtree) + self.profileview.init_default_file() + + event_handlers = { + "on_mainbig_window_delete_event" + : self.on_mainbig_window_delete_event, + "on_processlist_button_press_event" + : self.procview.on_processlist_button_press_event, + "on_irqlist_button_press_event" + : self.irqview.on_irqlist_button_press_event, + "on_loadProfileButton_clicked" + : self.profileview.on_loadProfileButton_clicked, + "on_SaveButton_clicked" + : self.profileview.on_SaveButton_clicked, + "on_UpdateButton_clicked" + : self.profileview.on_UpdateButton_clicked, + "on_applyChanges_clicked" + : self.commonview.on_applyChanges_clicked, + "on_undoChanges_clicked" + : self.commonview.on_undoChanges_clicked, + "on_saveSnapshot_clicked" + : self.commonview.on_saveSnapshot_clicked, + "on_saveTunedChanges_clicked" + : self.commonview.on_saveTunedChanges_clicked, + "on_profileSelector_changed" + : self.commonview.on_profileSelector_changed, + "on_profileTree_button_press_event" + : self.profileview.on_profileTree_button_press_event + } + + self.wtree.signal_autoconnect(event_handlers) + + self.ps.reload_threads() + self.show() + self.timer = gobject.timeout_add(2500, self.refresh) + try: + self.icon = gtk.status_icon_new_from_stock(gtk.STOCK_PREFERENCES) + self.icon.connect("activate", self.on_status_icon_activate) + self.icon.connect("popup-menu", self.on_status_icon_popup_menu) + except AttributeError: + # Old pygtk2 + pass + pixbuf = self.window.render_icon(gtk.STOCK_PREFERENCES, + gtk.ICON_SIZE_SMALL_TOOLBAR) + self.window.set_icon(pixbuf) + + def on_status_icon_activate(self, status_icon): + if self.window.is_active(): + self.window.hide() + else: + self.window.present() + + def on_status_icon_popup_menu(self, icon, event_button, event_time): + menu = gtk.Menu() + + quit = gtk.MenuItem("_Quit") + menu.add(quit) + quit.connect_object('activate', self.on_mainbig_window_delete_event, icon) + quit.show() + + menu.popup(None, None, None, event_button, event_time) + + def on_mainbig_window_delete_event(self, obj, event=None): + gtk.main_quit() + + def show(self): + self.cpuview.refresh() + self.irqview.show() + self.procview.show() + + def refresh(self): + if not self.procview.evlist: # Poll, as we don't have perf + self.ps.reload() + self.ps.reload_threads() + self.procview.show() + self.irqview.refresh() + return True + + def check_root(self): + if os.getuid() == 0: + return False + self.binpath = sys.executable.strip(os.path.basename(sys.executable)) + os.execv(self.binpath + 'pkexec', + [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) + return True + + def check_env(self): + if not os.path.exists(self.config.config["root"]): + try: + os.stat(self.config.config["root"]) + except (IOError, OSError): + os.mkdir(self.config.config["root"]) + if not os.path.exists("/root/.local/share/"): + try: + os.stat("/root/.local/share/") + except (IOError, OSError): + os.mkdir("/root/.local/") + os.mkdir("/root/.local/share/") + + def run(self): + gtk.main()
Changes via pygi-convert.sh script for gtk3
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 25e3a2c1741a..008f55b5df35 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -9,8 +9,8 @@ import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk
-import gobject -import gtk.glade +from gi.repository import GObject +import Gtk.glade from gtk import ListStore from .gui.cpuview import cpuview from .gui.irqview import irqview @@ -28,8 +28,8 @@ class main_gui: global tuna_glade
(app, localedir) = ('tuna', '/usr/share/locale') - gtk.glade.bindtextdomain(app, localedir) - gtk.glade.textdomain(app) + Gtk.glade.bindtextdomain(app, localedir) + Gtk.glade.textdomain(app)
if self.check_root(): sys.exit(1) @@ -37,7 +37,7 @@ class main_gui: tuna_glade = "%s/tuna_gui.glade" % dir if os.access(tuna_glade, os.F_OK): break - self.wtree = gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") + self.wtree = Gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") self.ps = procfs.pidstats() self.irqs = procfs.interrupts() self.window = self.wtree.get_widget("mainbig_window") @@ -102,16 +102,16 @@ class main_gui:
self.ps.reload_threads() self.show() - self.timer = gobject.timeout_add(2500, self.refresh) + self.timer = GObject.timeout_add(2500, self.refresh) try: - self.icon = gtk.status_icon_new_from_stock(gtk.STOCK_PREFERENCES) + self.icon = Gtk.status_icon_new_from_stock(Gtk.STOCK_PREFERENCES) self.icon.connect("activate", self.on_status_icon_activate) self.icon.connect("popup-menu", self.on_status_icon_popup_menu) except AttributeError: # Old pygtk2 pass - pixbuf = self.window.render_icon(gtk.STOCK_PREFERENCES, - gtk.ICON_SIZE_SMALL_TOOLBAR) + pixbuf = self.window.render_icon(Gtk.STOCK_PREFERENCES, + Gtk.IconSize.SMALL_TOOLBAR) self.window.set_icon(pixbuf)
def on_status_icon_activate(self, status_icon): @@ -121,9 +121,9 @@ class main_gui: self.window.present()
def on_status_icon_popup_menu(self, icon, event_button, event_time): - menu = gtk.Menu() + menu = Gtk.Menu()
- quit = gtk.MenuItem("_Quit") + quit = Gtk.MenuItem("_Quit") menu.add(quit) quit.connect_object('activate', self.on_mainbig_window_delete_event, icon) quit.show() @@ -131,7 +131,7 @@ class main_gui: menu.popup(None, None, None, event_button, event_time)
def on_mainbig_window_delete_event(self, obj, event=None): - gtk.main_quit() + Gtk.main_quit()
def show(self): self.cpuview.refresh() @@ -168,4 +168,4 @@ class main_gui: os.mkdir("/root/.local/share/")
def run(self): - gtk.main() + Gtk.main()
More changes to header files in tuna/gui for gtk3
Multiple imports on one line cause problems for conversion scripts
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/config.py | 25 +++++++++++++++---------- tuna/gui/cpuview.py | 11 ++++++++--- tuna/gui/irqview.py | 10 ++++++++-- tuna/gui/procview.py | 7 ++++++- tuna/gui/util.py | 6 +++++- 5 files changed, 42 insertions(+), 17 deletions(-)
diff --git a/tuna/config.py b/tuna/config.py index 019317fe3d32..e7d755c7296d 100644 --- a/tuna/config.py +++ b/tuna/config.py @@ -1,6 +1,11 @@ -import io, os, re, fnmatch -import sys, gtk -import codecs, configparser +import io +import os +import re +import fnmatch +import sys +from gi.repository import Gtk +import codecs +import configparser from time import localtime, strftime from subprocess import Popen, PIPE, STDOUT, call TUNED_CONF="""[sysctl]\n""" @@ -69,8 +74,8 @@ class Config: f.close() return 0 except (configparser.Error, IOError): - dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,\ - gtk.BUTTONS_OK, "%s\n%s" % \ + dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,\ + Gtk.ButtonsType.OK, "%s\n%s" % \ (_("Corruputed config file: "), _(self.config['root']+profileName))) ret = dialog.run() dialog.destroy() @@ -113,14 +118,14 @@ class Config: f.write(self.aliasToOriginal(data[index][ind]["label"])+"="+data[index][ind]["value"]+"\n") f.close() if profile[0] != "tuna": - dialog = gtk.MessageDialog(None,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, "%s%s\n%s" % \ + dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "%s%s\n%s" % \ (_("Current active profile is: "), _(profile[0]), _("Set new created profile as current in tuned daemon?"))) ret = dialog.run() dialog.destroy() - if ret == gtk.RESPONSE_YES: + if ret == Gtk.ResponseType.YES: self.setCurrentActiveProfile() if self.currentActiveProfile()[0] != "tuna": raise RuntimeError ("%s %s\n%s" % \ @@ -129,8 +134,8 @@ class Config: _("Setting of new tuned profile failed! Check if tuned is installed and active"))) return False else: - dialog = gtk.MessageDialog(None,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Tuna profile is now active in tuned daemon.")) + dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Tuna profile is now active in tuned daemon.")) ret = dialog.run() dialog.destroy() return True diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py index 78775c0882da..a2bd1d950e8d 100755 --- a/tuna/gui/cpuview.py +++ b/tuna/gui/cpuview.py @@ -1,11 +1,16 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import gi from functools import reduce -gi.require_version("Gtk", "3.0")
-import gtk, gobject, math, os, procfs, schedutils +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk +from gi.repository import GObject +import math +import os +import procfs +import schedutils from tuna import sysfs, tuna, gui
def set_affinity_warning(tid, affinity): diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py index 147809064ca5..be43bbb89d2d 100755 --- a/tuna/gui/irqview.py +++ b/tuna/gui/irqview.py @@ -1,12 +1,18 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import gi from functools import reduce + +import gi gi.require_version("Gtk", "3.0")
from tuna import tuna, gui -import ethtool, gobject, gtk, os, procfs, schedutils +import ethtool +from gi.repository import GObject +from gi.repository import Gtk +import os +import procfs +import schedutils
class irq_druid:
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 790bc31208ff..62ba9cf27949 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -2,7 +2,12 @@ import gi gi.require_version("Gtk", "3.0")
from tuna import tuna, gui -import gobject, gtk, procfs, re, schedutils +from gi.repository import GObject +from gi.repository import Gtk +import procfs +import re +import schedutils + try: import perf except: diff --git a/tuna/gui/util.py b/tuna/gui/util.py index 79c49a221363..b2d012662483 100755 --- a/tuna/gui/util.py +++ b/tuna/gui/util.py @@ -1,7 +1,11 @@ import gi gi.require_version("Gtk", "3.0")
-import gobject, gtk, pango, procfs, schedutils +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import Pango +import procfs +import schedutils from tuna import tuna
class list_store_column:
Make programming tuna a bit more enjoyable, don't show swap files and create gitattributes to specify files not to include in archives
Signed-off-by: John Kacur jkacur@redhat.com --- .gitattributes | 2 ++ .gitignore | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 .gitattributes
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000000..596615322fb3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.gitattributes export-ignore +.gitignore export-ignore diff --git a/.gitignore b/.gitignore index 0d20b6487c61..021454b526ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *.pyc +*~ +*.swp
Modernize the spacing and style in irqview
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/irqview.py | 630 ++++++++++++++++++++++---------------------- 1 file changed, 314 insertions(+), 316 deletions(-)
diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py index be43bbb89d2d..db113086de4a 100755 --- a/tuna/gui/irqview.py +++ b/tuna/gui/irqview.py @@ -1,331 +1,329 @@ # -*- python -*- # -*- coding: utf-8 -*- - +import os from functools import reduce +import ethtool +import schedutils
import gi gi.require_version("Gtk", "3.0") - -from tuna import tuna, gui -import ethtool from gi.repository import GObject from gi.repository import Gtk -import os + import procfs -import schedutils +from tuna import tuna, gui
class irq_druid:
- def __init__(self, irqs, ps, irq, gladefile): - self.irqs = irqs - self.ps = ps - self.irq = irq - self.window = Gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") - self.dialog = self.window.get_widget("set_irq_attributes") - pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, - Gtk.IconSize.SMALL_TOOLBAR) - self.dialog.set_icon(pixbuf) - event_handlers = { "on_irq_affinity_text_changed" : self.on_irq_affinity_text_changed, - "on_sched_policy_combo_changed": self.on_sched_policy_combo_changed } - self.window.signal_autoconnect(event_handlers) - - self.sched_pri = self.window.get_widget("irq_pri_spinbutton") - self.sched_policy = self.window.get_widget("irq_policy_combobox") - self.affinity = self.window.get_widget("irq_affinity_text") - text = self.window.get_widget("irq_text") - - users = tuna.get_irq_users(irqs, irq) - self.affinity_text = tuna.get_irq_affinity_text(irqs, irq) - - irq_re = tuna.threaded_irq_re(irq) - pids = self.ps.find_by_regex(irq_re) - if pids: - pid = pids[0] - prio = int(ps[pid]["stat"]["rt_priority"]) - self.create_policy_model(self.sched_policy) - self.sched_policy.set_active(schedutils.get_scheduler(pid)) - self.sched_pri.set_value(prio) - text.set_markup("IRQ <b>%u</b> (PID <b>%u</b>), pri <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ - ( irq, pid, prio, self.affinity_text, - ",".join(users))) - else: - self.sched_pri.set_sensitive(False) - self.sched_policy.set_sensitive(False) - text.set_markup("IRQ <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ - ( irq, self.affinity_text, - ",".join(users))) - - self.affinity.set_text(self.affinity_text) - - def create_policy_model(self, policy): - ( COL_TEXT, COL_SCHED ) = list(range(2)) - list_store = Gtk.ListStore(GObject.TYPE_STRING, - GObject.TYPE_UINT) - renderer = Gtk.CellRendererText() - policy.pack_start(renderer, True) - policy.add_attribute(renderer, "text", COL_TEXT) - for pol in range(4): - row = list_store.append() - list_store.set(row, COL_TEXT, schedutils.schedstr(pol), - COL_SCHED, pol) - policy.set_model(list_store) - - def on_sched_policy_combo_changed(self, button): - new_policy = self.sched_policy.get_active() - if new_policy in ( schedutils.SCHED_FIFO, schedutils.SCHED_RR ): - can_change_pri = True - else: - can_change_pri = False - self.sched_pri.set_sensitive(can_change_pri) - - def on_irq_affinity_text_changed(self, button): - gui.on_affinity_text_changed(self) - - def run(self): - changed = False - if self.dialog.run() == Gtk.ResponseType.OK: - new_policy = self.sched_policy.get_active() - new_prio = int(self.sched_pri.get_value()) - new_affinity = self.affinity.get_text() - irq_re = tuna.threaded_irq_re(self.irq) - pids = self.ps.find_by_regex(irq_re) - if pids: - if gui.thread_set_attributes(self.ps[pids[0]], - new_policy, - new_prio, - new_affinity, - self.irqs.nr_cpus): - changed = True - - try: - new_affinity = [ int(a) for a in new_affinity.split(",") ] - except: - try: - new_affinity = tuna.cpustring_to_list(new_affinity) - except: - new_affinity = procfs.bitmasklist(new_affinity, - self.irqs.nr_cpus) - - new_affinity.sort() - - curr_affinity = self.irqs[self.irq]["affinity"] - if curr_affinity != new_affinity: - tuna.set_irq_affinity(self.irq, - procfs.hexbitmask(new_affinity, - self.irqs.nr_cpus)) - changed = True - - self.dialog.destroy() - return changed + def __init__(self, irqs, ps, irq, gladefile): + self.irqs = irqs + self.ps = ps + self.irq = irq + self.window = Gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") + self.dialog = self.window.get_widget("set_irq_attributes") + pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, + Gtk.IconSize.SMALL_TOOLBAR) + self.dialog.set_icon(pixbuf) + event_handlers = { + "on_irq_affinity_text_changed" : self.on_irq_affinity_text_changed, + "on_sched_policy_combo_changed": self.on_sched_policy_combo_changed} + self.window.signal_autoconnect(event_handlers) + + self.sched_pri = self.window.get_widget("irq_pri_spinbutton") + self.sched_policy = self.window.get_widget("irq_policy_combobox") + self.affinity = self.window.get_widget("irq_affinity_text") + text = self.window.get_widget("irq_text") + + users = tuna.get_irq_users(irqs, irq) + self.affinity_text = tuna.get_irq_affinity_text(irqs, irq) + + irq_re = tuna.threaded_irq_re(irq) + pids = self.ps.find_by_regex(irq_re) + if pids: + pid = pids[0] + prio = int(ps[pid]["stat"]["rt_priority"]) + self.create_policy_model(self.sched_policy) + self.sched_policy.set_active(schedutils.get_scheduler(pid)) + self.sched_pri.set_value(prio) + text.set_markup( + "IRQ <b>%u</b> (PID <b>%u</b>), pri <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ + (irq, pid, prio, self.affinity_text, ",".join(users))) + else: + self.sched_pri.set_sensitive(False) + self.sched_policy.set_sensitive(False) + text.set_markup( + "IRQ <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ + (irq, self.affinity_text, ",".join(users))) + self.affinity.set_text(self.affinity_text) + + def create_policy_model(self, policy): + (COL_TEXT, COL_SCHED) = list(range(2)) + list_store = Gtk.ListStore(GObject.TYPE_STRING, + GObject.TYPE_UINT) + renderer = Gtk.CellRendererText() + policy.pack_start(renderer, True) + policy.add_attribute(renderer, "text", COL_TEXT) + for pol in range(4): + row = list_store.append() + list_store.set(row, COL_TEXT, schedutils.schedstr(pol), + COL_SCHED, pol) + policy.set_model(list_store) + + def on_sched_policy_combo_changed(self, button): + new_policy = self.sched_policy.get_active() + if new_policy in (schedutils.SCHED_FIFO, schedutils.SCHED_RR): + can_change_pri = True + else: + can_change_pri = False + self.sched_pri.set_sensitive(can_change_pri) + + def on_irq_affinity_text_changed(self, button): + gui.on_affinity_text_changed(self) + + def run(self): + changed = False + if self.dialog.run() == Gtk.ResponseType.OK: + new_policy = self.sched_policy.get_active() + new_prio = int(self.sched_pri.get_value()) + new_affinity = self.affinity.get_text() + irq_re = tuna.threaded_irq_re(self.irq) + pids = self.ps.find_by_regex(irq_re) + if pids: + if gui.thread_set_attributes(self.ps[pids[0]], + new_policy, + new_prio, + new_affinity, + self.irqs.nr_cpus): + changed = True + try: + new_affinity = [int(a) for a in new_affinity.split(",")] + except: + try: + new_affinity = tuna.cpustring_to_list(new_affinity) + except: + new_affinity = procfs.bitmasklist(new_affinity, + self.irqs.nr_cpus) + + new_affinity.sort() + + curr_affinity = self.irqs[self.irq]["affinity"] + if curr_affinity != new_affinity: + tuna.set_irq_affinity( + self.irq, procfs.hexbitmask(new_affinity, + self.irqs.nr_cpus)) + changed = True + + self.dialog.destroy() + return changed
class irqview:
- nr_columns = 7 - ( COL_NUM, COL_PID, COL_POL, COL_PRI, - COL_AFF, COL_EVENTS, COL_USERS ) = list(range(nr_columns)) - columns = (gui.list_store_column(_("IRQ")), - gui.list_store_column(_("PID"), GObject.TYPE_INT), - gui.list_store_column(_("Policy"), GObject.TYPE_STRING), - gui.list_store_column(_("Priority"), GObject.TYPE_INT), - gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), - gui.list_store_column(_("Events")), - gui.list_store_column(_("Users"), GObject.TYPE_STRING)) - - def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile): - - self.is_root = os.getuid() == 0 - self.irqs = irqs - self.ps = ps - self.treeview = treeview - self.gladefile = gladefile - self.has_threaded_irqs = tuna.has_threaded_irqs(ps) - if not self.has_threaded_irqs: - self.nr_columns = 4 - ( self.COL_NUM, - self.COL_AFF, - self.COL_EVENTS, - self.COL_USERS ) = list(range(self.nr_columns)) - self.columns = (gui.list_store_column(_("IRQ")), - gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), - gui.list_store_column(_("Events")), - gui.list_store_column(_("Users"), GObject.TYPE_STRING)) - - self.list_store = Gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns)) - - # Allow selecting multiple rows - selection = treeview.get_selection() - selection.set_mode(Gtk.SelectionMode.MULTIPLE) - - # Allow enable drag and drop of rows - self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, - gui.DND_TARGETS, - Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) - self.treeview.connect("drag_data_get", self.on_drag_data_get_data) - self.renderer = Gtk.CellRendererText() - - for col in range(self.nr_columns): - column = Gtk.TreeViewColumn(self.columns[col].name, - self.renderer, text = col) - column.set_sort_column_id(col) - column.add_attribute(self.renderer, "weight", - col + self.nr_columns) - self.treeview.append_column(column) - - self.cpus_filtered = cpus_filtered - self.refreshing = True - - self.treeview.set_model(self.list_store) - - def foreach_selected_cb(self, model, path, iter, irq_list): - irq = model.get_value(iter, self.COL_NUM) - irq_list.append(str(irq)) - - def on_drag_data_get_data(self, treeview, context, - selection, target_id, etime): - treeselection = treeview.get_selection() - irq_list = [] - treeselection.selected_foreach(self.foreach_selected_cb, irq_list) - selection.set(selection.target, 8, "irq:" + ",".join(irq_list)) - - def set_irq_columns(self, iter, irq, irq_info, nics): - new_value = [ None ] * self.nr_columns - users = tuna.get_irq_users(self.irqs, irq, nics) - if self.has_threaded_irqs: - irq_re = tuna.threaded_irq_re(irq) - pids = self.ps.find_by_regex(irq_re) - if pids: - pid = pids[0] - prio = int(self.ps[pid]["stat"]["rt_priority"]) - sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] - else: - sched = "" - pid = -1 - prio = -1 - new_value[self.COL_PID] = pid - new_value[self.COL_POL] = sched - new_value[self.COL_PRI] = prio - - new_value[self.COL_NUM] = irq - new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) - new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) - new_value[self.COL_USERS] = ",".join(users) - - gui.set_store_columns(self.list_store, iter, new_value) - - def show(self): - new_irqs = [] - for sirq in list(self.irqs.keys()): - try: - new_irqs.append(int(sirq)) - except: - continue - - nics = ethtool.get_active_devices() - - row = self.list_store.get_iter_first() - while row: - irq = self.list_store.get_value(row, self.COL_NUM) - # IRQ was unregistered? I.e. driver unloaded? - if irq not in self.irqs: - if self.list_store.remove(row): - # removed and row now its the next one - continue - # Was the last one - break - elif tuna.irq_filtered(irq, self.irqs, - self.cpus_filtered, - self.is_root): - new_irqs.remove(irq) - if self.list_store.remove(row): - # removed and row now its the next one - continue - # Was the last one - break - else: - try: - new_irqs.remove(irq) - irq_info = self.irqs[irq] - self.set_irq_columns(row, irq, irq_info, nics) - except: - if self.list_store.remove(row): - # removed and row now its the next one - continue - # Was the last one - break - - row = self.list_store.iter_next(row) - - new_irqs.sort() - for irq in new_irqs: - if tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, - self.is_root): - continue - row = self.list_store.append() - irq_info = self.irqs[irq] - try: - self.set_irq_columns(row, irq, irq_info, nics) - except: - self.list_store.remove(row) - - self.treeview.show_all() - - def refresh(self): - if not self.refreshing: - return - self.irqs.reload() - self.show() - - def refresh_toggle(self, unused): - self.refreshing = not self.refreshing - - def edit_attributes(self, a): - ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) - if not ret: - return - path, col, xpos, ypos = ret - if not path: - return - row = self.list_store.get_iter(path) - irq = self.list_store.get_value(row, self.COL_NUM) - if irq not in self.irqs: - return - - dialog = irq_druid(self.irqs, self.ps, irq, self.gladefile) - if dialog.run(): - self.refresh() - - def on_irqlist_button_press_event(self, treeview, event): - if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: - return - - self.last_x = int(event.x) - self.last_y = int(event.y) - - menu = Gtk.Menu() - - setattr = Gtk.MenuItem(_("_Set IRQ attributes")) - if self.refreshing: - refresh = Gtk.MenuItem(_("Sto_p refreshing the IRQ list")) - else: - refresh = Gtk.MenuItem(_("_Refresh the IRQ list")) - - menu.add(setattr) - menu.add(refresh) - - setattr.connect_object('activate', self.edit_attributes, event) - refresh.connect_object('activate', self.refresh_toggle, event) - - setattr.show() - refresh.show() - - menu.popup(None, None, None, event.button, event.time) - - def toggle_mask_cpu(self, cpu, enabled): - if not enabled: - if cpu not in self.cpus_filtered: - self.cpus_filtered.append(cpu) - self.show() - else: - if cpu in self.cpus_filtered: - self.cpus_filtered.remove(cpu) - self.show() + nr_columns = 7 + (COL_NUM, COL_PID, COL_POL, COL_PRI, + COL_AFF, COL_EVENTS, COL_USERS) = list(range(nr_columns)) + columns = (gui.list_store_column(_("IRQ")), + gui.list_store_column(_("PID"), GObject.TYPE_INT), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), + gui.list_store_column(_("Priority"), GObject.TYPE_INT), + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), + gui.list_store_column(_("Events")), + gui.list_store_column(_("Users"), GObject.TYPE_STRING)) + + def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile): + + self.is_root = os.getuid() == 0 + self.irqs = irqs + self.ps = ps + self.treeview = treeview + self.gladefile = gladefile + self.has_threaded_irqs = tuna.has_threaded_irqs(ps) + if not self.has_threaded_irqs: + self.nr_columns = 4 + (self.COL_NUM, + self.COL_AFF, + self.COL_EVENTS, + self.COL_USERS) = list(range(self.nr_columns)) + self.columns = (gui.list_store_column(_("IRQ")), + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), + gui.list_store_column(_("Events")), + gui.list_store_column(_("Users"), GObject.TYPE_STRING)) + + self.list_store = Gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns)) + + # Allow selecting multiple rows + selection = treeview.get_selection() + selection.set_mode(Gtk.SelectionMode.MULTIPLE) + + # Allow enable drag and drop of rows + self.treeview.enable_model_drag_source( + Gdk.ModifierType.BUTTON1_MASK, + gui.DND_TARGETS, + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + self.treeview.connect("drag_data_get", self.on_drag_data_get_data) + self.renderer = Gtk.CellRendererText() + + for col in range(self.nr_columns): + column = Gtk.TreeViewColumn(self.columns[col].name, + self.renderer, text=col) + column.set_sort_column_id(col) + column.add_attribute(self.renderer, "weight", + col + self.nr_columns) + self.treeview.append_column(column) + + self.cpus_filtered = cpus_filtered + self.refreshing = True + + self.treeview.set_model(self.list_store) + + def foreach_selected_cb(self, model, path, iter, irq_list): + irq = model.get_value(iter, self.COL_NUM) + irq_list.append(str(irq)) + + def on_drag_data_get_data(self, treeview, context, + selection, target_id, etime): + treeselection = treeview.get_selection() + irq_list = [] + treeselection.selected_foreach(self.foreach_selected_cb, irq_list) + selection.set(selection.target, 8, "irq:" + ",".join(irq_list)) + + def set_irq_columns(self, iter, irq, irq_info, nics): + new_value = [None] * self.nr_columns + users = tuna.get_irq_users(self.irqs, irq, nics) + if self.has_threaded_irqs: + irq_re = tuna.threaded_irq_re(irq) + pids = self.ps.find_by_regex(irq_re) + if pids: + pid = pids[0] + prio = int(self.ps[pid]["stat"]["rt_priority"]) + sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] + else: + sched = "" + pid = -1 + prio = -1 + new_value[self.COL_PID] = pid + new_value[self.COL_POL] = sched + new_value[self.COL_PRI] = prio + + new_value[self.COL_NUM] = irq + new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) + new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) + new_value[self.COL_USERS] = ",".join(users) + + gui.set_store_columns(self.list_store, iter, new_value) + + def show(self): + new_irqs = [] + for sirq in list(self.irqs.keys()): + try: + new_irqs.append(int(sirq)) + except: + continue + + nics = ethtool.get_active_devices() + + row = self.list_store.get_iter_first() + while row: + irq = self.list_store.get_value(row, self.COL_NUM) + # IRQ was unregistered? I.e. driver unloaded? + if irq not in self.irqs: + if self.list_store.remove(row): + # removed and row now its the next one + continue + # Was the last one + break + elif tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, + self.is_root): + new_irqs.remove(irq) + if self.list_store.remove(row): + # removed and row now its the next one + continue + # Was the last one + break + else: + try: + new_irqs.remove(irq) + irq_info = self.irqs[irq] + self.set_irq_columns(row, irq, irq_info, nics) + except: + if self.list_store.remove(row): + # removed and row now its the next one + continue + # Was the last one + break + + row = self.list_store.iter_next(row) + + new_irqs.sort() + for irq in new_irqs: + if tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, + self.is_root): + continue + row = self.list_store.append() + irq_info = self.irqs[irq] + try: + self.set_irq_columns(row, irq, irq_info, nics) + except: + self.list_store.remove(row) + + self.treeview.show_all() + + def refresh(self): + if not self.refreshing: + return + self.irqs.reload() + self.show() + + def refresh_toggle(self, unused): + self.refreshing = not self.refreshing + + def edit_attributes(self, a): + ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) + if not ret: + return + path, col, xpos, ypos = ret + if not path: + return + row = self.list_store.get_iter(path) + irq = self.list_store.get_value(row, self.COL_NUM) + if irq not in self.irqs: + return + + dialog = irq_druid(self.irqs, self.ps, irq, self.gladefile) + if dialog.run(): + self.refresh() + + def on_irqlist_button_press_event(self, treeview, event): + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: + return + + self.last_x = int(event.x) + self.last_y = int(event.y) + + menu = Gtk.Menu() + + setattr = Gtk.MenuItem(_("_Set IRQ attributes")) + if self.refreshing: + refresh = Gtk.MenuItem(_("Sto_p refreshing the IRQ list")) + else: + refresh = Gtk.MenuItem(_("_Refresh the IRQ list")) + + menu.add(setattr) + menu.add(refresh) + + setattr.connect_object('activate', self.edit_attributes, event) + refresh.connect_object('activate', self.refresh_toggle, event) + + setattr.show() + refresh.show() + + menu.popup(None, None, None, event.button, event.time) + + def toggle_mask_cpu(self, cpu, enabled): + if not enabled: + if cpu not in self.cpus_filtered: + self.cpus_filtered.append(cpu) + self.show() + else: + if cpu in self.cpus_filtered: + self.cpus_filtered.remove(cpu) + self.show()
Remove old glade imports from tuna_gui.py
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.py | 2 -- 1 file changed, 2 deletions(-)
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index c57533153ca4..eaa557349b7e 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -9,8 +9,6 @@ gi.require_version("Gtk", "3.0") from gi.repository import Gtk
from gi.repository import GObject -import Gtk.glade -from Gtk import ListStore from .gui.cpuview import cpuview from .gui.irqview import irqview from .gui.procview import procview
Fixing some spacing that wasn't consistent from the changes to modernize the spacing in tuna_gui.py
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.py | 108 +++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 54 deletions(-)
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index eaa557349b7e..f9d44c085d9f 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -113,58 +113,58 @@ class main_gui: Gtk.IconSize.SMALL_TOOLBAR) self.window.set_icon(pixbuf)
- def on_status_icon_activate(self, status_icon): - if self.window.is_active(): - self.window.hide() - else: - self.window.present() - - def on_status_icon_popup_menu(self, icon, event_button, event_time): - menu = Gtk.Menu() - - quit = Gtk.MenuItem("_Quit") - menu.add(quit) - quit.connect_object('activate', self.on_mainbig_window_delete_event, icon) - quit.show() - - menu.popup(None, None, None, event_button, event_time) - - def on_mainbig_window_delete_event(self, obj, event=None): - Gtk.main_quit() - - def show(self): - self.cpuview.refresh() - self.irqview.show() + def on_status_icon_activate(self, status_icon): + if self.window.is_active(): + self.window.hide() + else: + self.window.present() + + def on_status_icon_popup_menu(self, icon, event_button, event_time): + menu = Gtk.Menu() + + quit = Gtk.MenuItem("_Quit") + menu.add(quit) + quit.connect_object('activate', self.on_mainbig_window_delete_event, icon) + quit.show() + + menu.popup(None, None, None, event_button, event_time) + + def on_mainbig_window_delete_event(self, obj, event=None): + Gtk.main_quit() + + def show(self): + self.cpuview.refresh() + self.irqview.show() + self.procview.show() + + def refresh(self): + if not self.procview.evlist: # Poll, as we don't have perf + self.ps.reload() + self.ps.reload_threads() self.procview.show() - - def refresh(self): - if not self.procview.evlist: # Poll, as we don't have perf - self.ps.reload() - self.ps.reload_threads() - self.procview.show() - self.irqview.refresh() - return True - - def check_root(self): - if os.getuid() == 0: - return False - self.binpath = sys.executable.strip(os.path.basename(sys.executable)) - os.execv(self.binpath + 'pkexec', - [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) - return True - - def check_env(self): - if not os.path.exists(self.config.config["root"]): - try: - os.stat(self.config.config["root"]) - except (IOError, OSError): - os.mkdir(self.config.config["root"]) - if not os.path.exists("/root/.local/share/"): - try: - os.stat("/root/.local/share/") - except (IOError, OSError): - os.mkdir("/root/.local/") - os.mkdir("/root/.local/share/") - - def run(self): - Gtk.main() + self.irqview.refresh() + return True + + def check_root(self): + if os.getuid() == 0: + return False + self.binpath = sys.executable.strip(os.path.basename(sys.executable)) + os.execv(self.binpath + 'pkexec', + [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) + return True + + def check_env(self): + if not os.path.exists(self.config.config["root"]): + try: + os.stat(self.config.config["root"]) + except (IOError, OSError): + os.mkdir(self.config.config["root"]) + if not os.path.exists("/root/.local/share/"): + try: + os.stat("/root/.local/share/") + except (IOError, OSError): + os.mkdir("/root/.local/") + os.mkdir("/root/.local/share/") + + def run(self): + Gtk.main()
Modernize the spacing in cpuview.py, no tabs, 4 space indents
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/cpuview.py | 667 ++++++++++++++++++++++---------------------- 1 file changed, 333 insertions(+), 334 deletions(-)
diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py index a2bd1d950e8d..58034b8d099f 100755 --- a/tuna/gui/cpuview.py +++ b/tuna/gui/cpuview.py @@ -14,354 +14,353 @@ import schedutils from tuna import sysfs, tuna, gui
def set_affinity_warning(tid, affinity): - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, - Gtk.ButtonsType.OK, - _("Couldn't change the affinity of %(tid)d to %(affinity)s!") % \ + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, + Gtk.ButtonsType.OK, + _("Couldn't change the affinity of %(tid)d to %(affinity)s!") % \ {"tid": tid, "affinity": affinity}) - dialog.run() - dialog.destroy() + dialog.run() + dialog.destroy()
def drop_handler_move_threads_to_cpu(new_affinity, data): - pid_list = [ int(pid) for pid in data.split(",") ] + pid_list = [ int(pid) for pid in data.split(",") ]
- return tuna.move_threads_to_cpu(new_affinity, pid_list, - set_affinity_warning) + return tuna.move_threads_to_cpu(new_affinity, + pid_list, set_affinity_warning)
def drop_handler_move_irqs_to_cpu(cpus, data): - irq_list = [ int(irq) for irq in data.split(",") ] - new_affinity = [ reduce(lambda a, b: a | b, + irq_list = [ int(irq) for irq in data.split(",") ] + new_affinity = [ reduce(lambda a, b: a | b, [1 << cpu for cpu in cpus]), ]
- for irq in irq_list: - tuna.set_irq_affinity(irq, new_affinity) + for irq in irq_list: + tuna.set_irq_affinity(irq, new_affinity)
- # FIXME: check if we really changed the affinity, but - # its only an optimization to avoid a needless refresh - # in the irqview, now we always refresh. - return True + # FIXME: check if we really changed the affinity, but + # its only an optimization to avoid a needless refresh + # in the irqview, now we always refresh. + return True
class cpu_socket_frame(Gtk.Frame):
- ( COL_FILTER, COL_CPU, COL_USAGE ) = list(range(3)) - - def __init__(self, socket, cpus, creator): - - if creator.nr_sockets > 1: - GObject.GObject.__init__(self, _("Socket %s") % socket) - else: - GObject.GObject.__init__(self) - - self.socket = socket - self.cpus = cpus - self.nr_cpus = len(cpus) - self.creator = creator - - self.list_store = Gtk.ListStore(GObject.TYPE_BOOLEAN, - GObject.TYPE_UINT, - GObject.TYPE_UINT) - - self.treeview = Gtk.TreeView(self.list_store) - - # Filter column - renderer = Gtk.CellRendererToggle() - renderer.connect('toggled', self.filter_toggled, self.list_store) - column = Gtk.TreeViewColumn(_('Filter'), renderer, active = self.COL_FILTER) - self.treeview.append_column(column) - - # CPU# column - column = Gtk.TreeViewColumn(_('CPU'), Gtk.CellRendererText(), - text = self.COL_CPU) - self.treeview.append_column(column) - - # CPU usage column - try: - column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererProgress(), - text = self.COL_USAGE, value = self.COL_USAGE) - except: - # CellRendererProgress needs pygtk2 >= 2.6 - column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererText(), + ( COL_FILTER, COL_CPU, COL_USAGE ) = list(range(3)) + + def __init__(self, socket, cpus, creator): + + if creator.nr_sockets > 1: + GObject.GObject.__init__(self, _("Socket %s") % socket) + else: + GObject.GObject.__init__(self) + + self.socket = socket + self.cpus = cpus + self.nr_cpus = len(cpus) + self.creator = creator + + self.list_store = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_UINT, + GObject.TYPE_UINT) + + self.treeview = Gtk.TreeView(self.list_store) + + # Filter column + renderer = Gtk.CellRendererToggle() + renderer.connect('toggled', self.filter_toggled, self.list_store) + column = Gtk.TreeViewColumn(_('Filter'), renderer, + active = self.COL_FILTER) + self.treeview.append_column(column) + + # CPU# column + column = Gtk.TreeViewColumn(_('CPU'), Gtk.CellRendererText(), + text = self.COL_CPU) + self.treeview.append_column(column) + + # CPU usage column + try: + column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererProgress(), + text = self.COL_USAGE, + value = self.COL_USAGE) + except: + # CellRendererProgress needs pygtk2 >= 2.6 + column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererText(), text = self.COL_USAGE) - self.treeview.append_column(column) - - self.add(self.treeview) - - self.treeview.enable_model_drag_dest(gui.DND_TARGETS, - Gdk.DragAction.DEFAULT) - self.treeview.connect("drag_data_received", - self.on_drag_data_received_data) - self.treeview.connect("button_press_event", - self.on_cpu_socket_frame_button_press_event) - - self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.creator.procview), - "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview), } - - self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, - Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) - self.connect("drag_data_received", - self.on_frame_drag_data_received_data) - - def on_frame_drag_data_received_data(self, w, context, x, y, - selection, info, etime): - # Move to all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] - # pid list, a irq list, etc - source, data = selection.data.split(":") - - if source in self.drop_handlers: - if self.drop_handlers[source][0](cpus, data): - self.drop_handlers[source][1].refresh() - else: - print("cpu_socket_frame: unhandled drag source '%s'" % source) - - def on_drag_data_received_data(self, treeview, context, x, y, - selection, info, etime): - drop_info = treeview.get_dest_row_at_pos(x, y) - - # pid list, a irq list, etc - source, data = selection.data.split(":") - - if drop_info: - model = treeview.get_model() - path, position = drop_info - iter = model.get_iter(path) - cpus = [ model.get_value(iter, self.COL_CPU), ] - else: - # Move to all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] - - if source in self.drop_handlers: - if self.drop_handlers[source][0](cpus, data): - self.drop_handlers[source][1].refresh() - else: - print("cpu_socket_frame: unhandled drag source '%s'" % source) - - def refresh(self): - self.list_store.clear() - for i in range(self.nr_cpus): - cpu = self.cpus[i] - cpunr = int(cpu.name[3:]) - usage = self.creator.cpustats[cpunr + 1].usage - - iter = self.list_store.append() - self.list_store.set(iter, - self.COL_FILTER, cpunr not in self.creator.cpus_filtered, - self.COL_CPU, cpunr, - self.COL_USAGE, int(usage)) - self.treeview.show_all() - - def isolate_cpu(self, a): - ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) - if not ret: - return - path, col, xpos, ypos = ret - if not path: - return - row = self.list_store.get_iter(path) - cpu = self.list_store.get_value(row, self.COL_CPU) - - self.creator.isolate_cpus([cpu,]) - - def include_cpu(self, a): - ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) - if not ret: - return - path, col, xpos, ypos = ret - if not path: - return - row = self.list_store.get_iter(path) - cpu = self.list_store.get_value(row, self.COL_CPU) - - self.creator.include_cpus([cpu,]) - - def restore_cpu(self, a): - - self.creator.restore_cpu() - - def isolate_cpu_socket(self, a): - - # Isolate all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] - self.creator.isolate_cpus(cpus) - - def include_cpu_socket(self, a): - - # Include all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] - self.creator.include_cpus(cpus) - - def on_cpu_socket_frame_button_press_event(self, treeview, event): - if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: - return - - self.last_x = int(event.x) - self.last_y = int(event.y) - - menu = Gtk.Menu() - - include = Gtk.MenuItem(_("I_nclude CPU")) - isolate = Gtk.MenuItem(_("_Isolate CPU")) - if self.creator.nr_sockets > 1: - include_socket = Gtk.MenuItem(_("I_nclude CPU Socket")) - isolate_socket = Gtk.MenuItem(_("_Isolate CPU Socket")) - restore = Gtk.MenuItem(_("_Restore CPU")) - - menu.add(include) - menu.add(isolate) - if self.creator.nr_sockets > 1: - menu.add(include_socket) - menu.add(isolate_socket) - menu.add(restore) - - include.connect_object('activate', self.include_cpu, event) - isolate.connect_object('activate', self.isolate_cpu, event) - if self.creator.nr_sockets > 1: - include_socket.connect_object('activate', self.include_cpu_socket, event) - isolate_socket.connect_object('activate', self.isolate_cpu_socket, event) - if not (self.creator.previous_pid_affinities or \ - self.creator.previous_irq_affinities): - restore.set_sensitive(False) - restore.connect_object('activate', self.restore_cpu, event) - - include.show() - isolate.show() - if self.creator.nr_sockets > 1: - include_socket.show() - isolate_socket.show() - restore.show() - - menu.popup(None, None, None, event.button, event.time) - - def filter_toggled(self, cell, path, model): - # get toggled iter - iter = model.get_iter((int(path),)) - enabled = model.get_value(iter, self.COL_FILTER) - cpu = model.get_value(iter, self.COL_CPU) - - enabled = not enabled - self.creator.toggle_mask_cpu(cpu, enabled) - - # set new value - model.set(iter, self.COL_FILTER, enabled) + self.treeview.append_column(column) + self.add(self.treeview) + self.treeview.enable_model_drag_dest(gui.DND_TARGETS, + Gdk.DragAction.DEFAULT) + self.treeview.connect("drag_data_received", + self.on_drag_data_received_data) + self.treeview.connect("button_press_event", + self.on_cpu_socket_frame_button_press_event) + self.drop_handlers = { + "pid": (drop_handler_move_threads_to_cpu, + self.creator.procview), + "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview),} + + self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + self.connect("drag_data_received", + self.on_frame_drag_data_received_data) + + def on_frame_drag_data_received_data(self, w, context, x, y, + selection, info, etime): + # Move to all CPUs in this socket + cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + # pid list, a irq list, etc + source, data = selection.data.split(":") + + if source in self.drop_handlers: + if self.drop_handlers[source][0](cpus, data): + self.drop_handlers[source][1].refresh() + else: + print("cpu_socket_frame: unhandled drag source '%s'" % source) + + def on_drag_data_received_data(self, treeview, context, x, y,selection, + info, etime): + drop_info = treeview.get_dest_row_at_pos(x, y) + + # pid list, a irq list, etc + source, data = selection.data.split(":") + + if drop_info: + model = treeview.get_model() + path, position = drop_info + iter = model.get_iter(path) + cpus = [ model.get_value(iter, self.COL_CPU), ] + else: + # Move to all CPUs in this socket + cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + + if source in self.drop_handlers: + if self.drop_handlers[source][0](cpus, data): + self.drop_handlers[source][1].refresh() + else: + print("cpu_socket_frame: unhandled drag source '%s'" % source) + + def refresh(self): + self.list_store.clear() + for i in range(self.nr_cpus): + cpu = self.cpus[i] + cpunr = int(cpu.name[3:]) + usage = self.creator.cpustats[cpunr + 1].usage + + iter = self.list_store.append() + self.list_store.set( + iter, self.COL_FILTER, cpunr not in self.creator.cpus_filtered, + self.COL_CPU, cpunr, self.COL_USAGE, int(usage)) + self.treeview.show_all() + + def isolate_cpu(self, a): + ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) + if not ret: + return + path, col, xpos, ypos = ret + if not path: + return + row = self.list_store.get_iter(path) + cpu = self.list_store.get_value(row, self.COL_CPU) + + self.creator.isolate_cpus([cpu,]) + + def include_cpu(self, a): + ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) + if not ret: + return + path, col, xpos, ypos = ret + if not path: + return + row = self.list_store.get_iter(path) + cpu = self.list_store.get_value(row, self.COL_CPU) + + self.creator.include_cpus([cpu,]) + + def restore_cpu(self, a): + self.creator.restore_cpu() + + def isolate_cpu_socket(self, a): + + # Isolate all CPUs in this socket + cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + self.creator.isolate_cpus(cpus) + + def include_cpu_socket(self, a): + + # Include all CPUs in this socket + cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + self.creator.include_cpus(cpus) + + def on_cpu_socket_frame_button_press_event(self, treeview, event): + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: + return + + self.last_x = int(event.x) + self.last_y = int(event.y) + + menu = Gtk.Menu() + + include = Gtk.MenuItem(_("I_nclude CPU")) + isolate = Gtk.MenuItem(_("_Isolate CPU")) + if self.creator.nr_sockets > 1: + include_socket = Gtk.MenuItem(_("I_nclude CPU Socket")) + isolate_socket = Gtk.MenuItem(_("_Isolate CPU Socket")) + restore = Gtk.MenuItem(_("_Restore CPU")) + + menu.add(include) + menu.add(isolate) + if self.creator.nr_sockets > 1: + menu.add(include_socket) + menu.add(isolate_socket) + menu.add(restore) + + include.connect_object('activate', self.include_cpu, event) + isolate.connect_object('activate', self.isolate_cpu, event) + if self.creator.nr_sockets > 1: + include_socket.connect_object('activate', self.include_cpu_socket, + event) + isolate_socket.connect_object('activate', self.isolate_cpu_socket, + event) + if not (self.creator.previous_pid_affinities or \ + self.creator.previous_irq_affinities): + restore.set_sensitive(False) + restore.connect_object('activate', self.restore_cpu, event) + + include.show() + isolate.show() + if self.creator.nr_sockets > 1: + include_socket.show() + isolate_socket.show() + restore.show() + + menu.popup(None, None, None, event.button, event.time) + + def filter_toggled(self, cell, path, model): + # get toggled iter + iter = model.get_iter((int(path),)) + enabled = model.get_value(iter, self.COL_FILTER) + cpu = model.get_value(iter, self.COL_CPU) + + enabled = not enabled + self.creator.toggle_mask_cpu(cpu, enabled) + + # set new value + model.set(iter, self.COL_FILTER, enabled)
class cpuview:
- def __init__(self, vpaned, hpaned, window, procview, irqview, cpus_filtered): - self.cpus = sysfs.cpus() - self.cpustats = procfs.cpusstats() - self.socket_frames = {} - - self.procview = procview - self.irqview = irqview - - vbox = window.get_child().get_child() - socket_ids = [] - for id in list(self.cpus.sockets.keys()): - try: - socket_ids.append(int(id)) - except TypeError: # Skip over offline cpus - type None - continue - socket_ids.sort() - - self.nr_sockets = len(socket_ids) - if self.nr_sockets > 1: - columns = math.ceil(math.sqrt(self.nr_sockets)) - rows = math.ceil(self.nr_sockets / columns) - box = Gtk.HBox() - vbox.pack_start(box, True, True) - else: - box = vbox - - column = 1 - for socket_id in socket_ids: - frame = cpu_socket_frame(socket_id, - self.cpus.sockets[str(socket_id)], - self) - box.pack_start(frame, False, False) - self.socket_frames[socket_id] = frame - if self.nr_sockets > 1: - if column == columns: - box = Gtk.HBox() - vbox.pack_start(box, True, True) - column = 1 - else: - column += 1 - - window.show_all() - - self.cpus_filtered = cpus_filtered - self.refresh() - - self.previous_pid_affinities = None - self.previous_irq_affinities = None - - req = frame.size_request() - # FIXME: what is the slack we have - # to add to every row and column? - width = req[0] + 16 - height = req[1] + 20 - if self.nr_sockets > 1: - width *= columns - height *= rows - vpaned.set_position(int(height)) - hpaned.set_position(int(width)) - - self.timer = GObject.timeout_add(3000, self.refresh) - - def isolate_cpus(self, cpus): - self.previous_pid_affinities, \ - self.previous_irq_affinities = tuna.isolate_cpus(cpus, self.cpus.nr_cpus) - - if self.previous_pid_affinities: - self.procview.refresh() - - if self.previous_irq_affinities: - self.irqview.refresh() - - def include_cpus(self, cpus): - self.previous_pid_affinities, \ - self.previous_irq_affinities = tuna.include_cpus(cpus, self.cpus.nr_cpus) - - if self.previous_pid_affinities: - self.procview.refresh() - - if self.previous_irq_affinities: - self.irqview.refresh() - - def restore_cpu(self): - if not (self.previous_pid_affinities or \ - self.previous_irq_affinities): - return - affinities = self.previous_pid_affinities - for pid in list(affinities.keys()): - try: - schedutils.set_affinity(pid, affinities[pid]) - except: - pass - - affinities = self.previous_irq_affinities - for irq in list(affinities.keys()): - tuna.set_irq_affinity(int(irq), - procfs.hexbitmask(affinities[irq], - self.cpus.nr_cpus)) - - self.previous_pid_affinities = None - self.previous_irq_affinities = None - - def toggle_mask_cpu(self, cpu, enabled): - if enabled: - if cpu in self.cpus_filtered: - self.cpus_filtered.remove(cpu) + def __init__(self, vpaned, hpaned, window, procview, irqview, cpus_filtered): + self.cpus = sysfs.cpus() + self.cpustats = procfs.cpusstats() + self.socket_frames = {} + + self.procview = procview + self.irqview = irqview + + vbox = window.get_child().get_child() + socket_ids = [] + for id in list(self.cpus.sockets.keys()): + try: + socket_ids.append(int(id)) + except TypeError: # Skip over offline cpus - type None + continue + socket_ids.sort() + + self.nr_sockets = len(socket_ids) + if self.nr_sockets > 1: + columns = math.ceil(math.sqrt(self.nr_sockets)) + rows = math.ceil(self.nr_sockets / columns) + box = Gtk.HBox() + vbox.pack_start(box, True, True) + else: + box = vbox + + column = 1 + for socket_id in socket_ids: + frame = cpu_socket_frame(socket_id, + self.cpus.sockets[str(socket_id)], self) + box.pack_start(frame, False, False) + self.socket_frames[socket_id] = frame + if self.nr_sockets > 1: + if column == columns: + box = Gtk.HBox() + vbox.pack_start(box, True, True) + column = 1 else: - if cpu not in self.cpus_filtered: - self.cpus_filtered.append(cpu) - - self.procview.toggle_mask_cpu(cpu, enabled) - self.irqview.toggle_mask_cpu(cpu, enabled) - - def refresh(self): - self.cpustats.reload() - for frame in list(self.socket_frames.keys()): - self.socket_frames[frame].refresh() - return True + column += 1 + + window.show_all() + + self.cpus_filtered = cpus_filtered + self.refresh() + + self.previous_pid_affinities = None + self.previous_irq_affinities = None + + req = frame.size_request() + # FIXME: what is the slack we have + # to add to every row and column? + width = req[0] + 16 + height = req[1] + 20 + if self.nr_sockets > 1: + width *= columns + height *= rows + vpaned.set_position(int(height)) + hpaned.set_position(int(width)) + + self.timer = GObject.timeout_add(3000, self.refresh) + + def isolate_cpus(self, cpus): + self.previous_pid_affinities, \ + self.previous_irq_affinities = tuna.isolate_cpus(cpus, self.cpus.nr_cpus) + + if self.previous_pid_affinities: + self.procview.refresh() + + if self.previous_irq_affinities: + self.irqview.refresh() + + def include_cpus(self, cpus): + self.previous_pid_affinities, \ + self.previous_irq_affinities = tuna.include_cpus(cpus, self.cpus.nr_cpus) + + if self.previous_pid_affinities: + self.procview.refresh() + + if self.previous_irq_affinities: + self.irqview.refresh() + + def restore_cpu(self): + if not (self.previous_pid_affinities or \ + self.previous_irq_affinities): + return + affinities = self.previous_pid_affinities + for pid in list(affinities.keys()): + try: + schedutils.set_affinity(pid, affinities[pid]) + except: + pass + + affinities = self.previous_irq_affinities + for irq in list(affinities.keys()): + tuna.set_irq_affinity(int(irq), + procfs.hexbitmask(affinities[irq], + self.cpus.nr_cpus)) + + self.previous_pid_affinities = None + self.previous_irq_affinities = None + + def toggle_mask_cpu(self, cpu, enabled): + if enabled: + if cpu in self.cpus_filtered: + self.cpus_filtered.remove(cpu) + else: + if cpu not in self.cpus_filtered: + self.cpus_filtered.append(cpu) + + self.procview.toggle_mask_cpu(cpu, enabled) + self.irqview.toggle_mask_cpu(cpu, enabled) + + def refresh(self): + self.cpustats.reload() + for frame in list(self.socket_frames.keys()): + self.socket_frames[frame].refresh() + return True
A few more style fixups suggested by pylint-3
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/cpuview.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py index 58034b8d099f..bcb846773471 100755 --- a/tuna/gui/cpuview.py +++ b/tuna/gui/cpuview.py @@ -24,15 +24,14 @@ def set_affinity_warning(tid, affinity): dialog.destroy()
def drop_handler_move_threads_to_cpu(new_affinity, data): - pid_list = [ int(pid) for pid in data.split(",") ] + pid_list = [int(pid) for pid in data.split(",")]
return tuna.move_threads_to_cpu(new_affinity, pid_list, set_affinity_warning)
def drop_handler_move_irqs_to_cpu(cpus, data): - irq_list = [ int(irq) for irq in data.split(",") ] - new_affinity = [ reduce(lambda a, b: a | b, - [1 << cpu for cpu in cpus]), ] + irq_list = [int(irq) for irq in data.split(",")] + new_affinity = [reduce(lambda a, b: a | b, [1 << cpu for cpu in cpus]),]
for irq in irq_list: tuna.set_irq_affinity(irq, new_affinity) @@ -44,7 +43,7 @@ def drop_handler_move_irqs_to_cpu(cpus, data):
class cpu_socket_frame(Gtk.Frame):
- ( COL_FILTER, COL_CPU, COL_USAGE ) = list(range(3)) + (COL_FILTER, COL_CPU, COL_USAGE) = list(range(3))
def __init__(self, socket, cpus, creator):
@@ -67,23 +66,23 @@ class cpu_socket_frame(Gtk.Frame): renderer = Gtk.CellRendererToggle() renderer.connect('toggled', self.filter_toggled, self.list_store) column = Gtk.TreeViewColumn(_('Filter'), renderer, - active = self.COL_FILTER) + active=self.COL_FILTER) self.treeview.append_column(column)
# CPU# column column = Gtk.TreeViewColumn(_('CPU'), Gtk.CellRendererText(), - text = self.COL_CPU) + text=self.COL_CPU) self.treeview.append_column(column)
# CPU usage column try: column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererProgress(), - text = self.COL_USAGE, - value = self.COL_USAGE) + text=self.COL_USAGE, + value=self.COL_USAGE) except: # CellRendererProgress needs pygtk2 >= 2.6 column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererText(), - text = self.COL_USAGE) + text=self.COL_USAGE) self.treeview.append_column(column) self.add(self.treeview) self.treeview.enable_model_drag_dest(gui.DND_TARGETS, @@ -94,7 +93,7 @@ class cpu_socket_frame(Gtk.Frame): self.on_cpu_socket_frame_button_press_event) self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, - self.creator.procview), + self.creator.procview), "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview),}
self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, @@ -105,7 +104,7 @@ class cpu_socket_frame(Gtk.Frame): def on_frame_drag_data_received_data(self, w, context, x, y, selection, info, etime): # Move to all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + cpus = [int(cpu.name[3:]) for cpu in self.cpus] # pid list, a irq list, etc source, data = selection.data.split(":")
@@ -115,7 +114,7 @@ class cpu_socket_frame(Gtk.Frame): else: print("cpu_socket_frame: unhandled drag source '%s'" % source)
- def on_drag_data_received_data(self, treeview, context, x, y,selection, + def on_drag_data_received_data(self, treeview, context, x, y, selection, info, etime): drop_info = treeview.get_dest_row_at_pos(x, y)
@@ -126,10 +125,10 @@ class cpu_socket_frame(Gtk.Frame): model = treeview.get_model() path, position = drop_info iter = model.get_iter(path) - cpus = [ model.get_value(iter, self.COL_CPU), ] + cpus = [model.get_value(iter, self.COL_CPU),] else: # Move to all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + cpus = [int(cpu.name[3:]) for cpu in self.cpus]
if source in self.drop_handlers: if self.drop_handlers[source][0](cpus, data): @@ -180,13 +179,13 @@ class cpu_socket_frame(Gtk.Frame): def isolate_cpu_socket(self, a):
# Isolate all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + cpus = [int(cpu.name[3:]) for cpu in self.cpus] self.creator.isolate_cpus(cpus)
def include_cpu_socket(self, a):
# Include all CPUs in this socket - cpus = [ int(cpu.name[3:]) for cpu in self.cpus ] + cpus = [int(cpu.name[3:]) for cpu in self.cpus] self.creator.include_cpus(cpus)
def on_cpu_socket_frame_button_press_event(self, treeview, event):
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/irqview.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py index db113086de4a..e3a0c640bb2c 100755 --- a/tuna/gui/irqview.py +++ b/tuna/gui/irqview.py @@ -204,12 +204,12 @@ class irqview: new_value[self.COL_POL] = sched new_value[self.COL_PRI] = prio
- new_value[self.COL_NUM] = irq - new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) - new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) - new_value[self.COL_USERS] = ",".join(users) + new_value[self.COL_NUM] = irq + new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) + new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) + new_value[self.COL_USERS] = ",".join(users)
- gui.set_store_columns(self.list_store, iter, new_value) + gui.set_store_columns(self.list_store, iter, new_value)
def show(self): new_irqs = []
Update the spacing and style of commonview.py
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/commonview.py | 517 +++++++++++++++++++++-------------------- 1 file changed, 262 insertions(+), 255 deletions(-)
diff --git a/tuna/gui/commonview.py b/tuna/gui/commonview.py index 1a43f41ed438..861a55b1b48b 100644 --- a/tuna/gui/commonview.py +++ b/tuna/gui/commonview.py @@ -3,270 +3,277 @@ from gi.repository import Gtk from tuna import tuna, gui
class commonview: - def updateCommonView(self): - try: - self.contentTable - self.config - except: - pass - self.cleanUp() - self.setup() + def updateCommonView(self): + try: + self.contentTable + self.config + except: + pass + self.cleanUp() + self.setup()
- def cleanUp(self): - for value in self.contentTable.get_children(): - if value.get_name() == "controls": - self.ctrl = value - if value.get_name() == "profileSelectorBox": - self.selector = value - self.contentTable.remove(value) + def cleanUp(self): + for value in self.contentTable.get_children(): + if value.get_name() == "controls": + self.ctrl = value + if value.get_name() == "profileSelectorBox": + self.selector = value + self.contentTable.remove(value)
- def setup(self): - try: - self.contentTable.set_homogeneous(False) - catListlenght = len(self.config.categories) - if catListlenght <= 0: - return False - row = ((catListlenght+(catListlenght%2))/2)-catListlenght%2 - frames = {} - frameContent = {} - catCntr = 0 - contentCntr = 0 - self.contentTable.resize(row+3,2) - self.contentTable.attach(self.ctrl,0,2,1,2,Gtk.AttachOptions.FILL,Gtk.AttachOptions.FILL) - self.contentTable.attach(self.selector,0,2,0,1,Gtk.AttachOptions.FILL,Gtk.AttachOptions.FILL) - cur = self.profileview.configFileCombo.get_model() - for val in cur: - if val[0] == self.config.cacheFileName: - try: - self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) - except TypeError as e: - pass - self.configFileCombo.set_active(val.path[0]) - try: - self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) - except TypeError as e: - pass - while catCntr < catListlenght: - frames[catCntr] = Gtk.Frame() - tLabel = Gtk.Label(label='<b>'+self.config.categories[catCntr]+'</b>') - tLabel.set_use_markup(True) - frames[catCntr].set_label_widget(tLabel) - frameContent[catCntr] = {} - frameContent[catCntr]['labels'] = {} - frameContent[catCntr]['texts'] = {} - frameContent[catCntr]['tooltips'] = {} - currentCol = catCntr%2 - currentRow = (catCntr/2)+2 - if len(self.config.ctlParams[catCntr]) > 0: - frameContent[catCntr]['table'] = Gtk.Table(len(self.config.ctlParams[catCntr]),2,False) - else: - frameContent[catCntr]['table'] = Gtk.Table(1,2,False) - contentCntr = 0 - for val in sorted(self.config.ctlParams[catCntr], key=str.lower): - if self.config.getSystemValue(val) != self.config.ctlParams[catCntr][val]: - star = "*" - else: - star = "" - frameContent[catCntr]['labels'][contentCntr] = Gtk.Label(label=self.config.originalToAlias(val)+star) - frameContent[catCntr]['labels'][contentCntr].set_alignment(0,0.5) - frameContent[catCntr]['tooltips'][contentCntr] = tuna.proc_sys_help(val) - if len(frameContent[catCntr]['tooltips'][contentCntr]): - frameContent[catCntr]['labels'][contentCntr].set_tooltip_text(frameContent[catCntr]['tooltips'][contentCntr]) - if val in self.config.ctlGuiParams[catCntr]: - # scale control - frameContent[catCntr]['texts'][contentCntr] = Gtk.HScale() - frameContent[catCntr]['texts'][contentCntr].set_range(self.config.ctlGuiParams[catCntr][val][0], self.config.ctlGuiParams[catCntr][val][1]) - frameContent[catCntr]['texts'][contentCntr].set_update_policy(Gtk.UPDATE_CONTINUOUS) - frameContent[catCntr]['texts'][contentCntr].set_value(int(self.config.ctlParams[catCntr][val])) - frameContent[catCntr]['texts'][contentCntr].set_digits(0) - else: - # input field - frameContent[catCntr]['texts'][contentCntr] = Gtk.Entry(256) - frameContent[catCntr]['texts'][contentCntr].set_alignment(0) - frameContent[catCntr]['texts'][contentCntr].set_text(self.config.ctlParams[catCntr][val]) - frameContent[catCntr]['texts'][contentCntr].connect("button-release-event", self.checkStar, catCntr, contentCntr, val, frameContent[catCntr]['labels'][contentCntr]) - frameContent[catCntr]['texts'][contentCntr].connect("focus-out-event", self.checkStar, catCntr,contentCntr,val, frameContent[catCntr]['labels'][contentCntr]) - frameContent[catCntr]['table'].attach(frameContent[catCntr]['labels'][contentCntr],0,1,contentCntr,contentCntr+1,Gtk.AttachOptions.FILL,xpadding=5) - frameContent[catCntr]['table'].attach(frameContent[catCntr]['texts'][contentCntr],1,2,contentCntr,contentCntr+1,xpadding=10) - contentCntr = contentCntr+1 - frames[catCntr].add(frameContent[catCntr]['table']) - self.contentTable.attach(frames[catCntr],currentCol,currentCol+1,currentRow,currentRow+1,Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,Gtk.AttachOptions.FILL,1,1) - catCntr = catCntr+1 - self.ctrl.set_padding(5,5,0,5) - self.contentTable.set_border_width(5) - self.contentTable.show_all() - except AttributeError as e: - return False + def setup(self): + try: + self.contentTable.set_homogeneous(False) + catListlenght = len(self.config.categories) + if catListlenght <= 0: + return False + row = ((catListlenght+(catListlenght%2))/2)-catListlenght%2 + frames = {} + frameContent = {} + catCntr = 0 + contentCntr = 0 + self.contentTable.resize(row+3, 2) + self.contentTable.attach(self.ctrl, 0, 2, 1, 2, + Gtk.AttachOptions.FILL, + Gtk.AttachOptions.FILL) + self.contentTable.attach(self.selector, 0, 2, 0, 1, + Gtk.AttachOptions.FILL, + Gtk.AttachOptions.FILL) + cur = self.profileview.configFileCombo.get_model() + for val in cur: + if val[0] == self.config.cacheFileName: + try: + self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) + except TypeError as e: + pass + self.configFileCombo.set_active(val.path[0]) + try: + self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) + except TypeError as e: + pass + while catCntr < catListlenght: + frames[catCntr] = Gtk.Frame() + tLabel = Gtk.Label(label='<b>'+self.config.categories[catCntr]+'</b>') + tLabel.set_use_markup(True) + frames[catCntr].set_label_widget(tLabel) + frameContent[catCntr] = {} + frameContent[catCntr]['labels'] = {} + frameContent[catCntr]['texts'] = {} + frameContent[catCntr]['tooltips'] = {} + currentCol = catCntr%2 + currentRow = (catCntr/2)+2 + if len(self.config.ctlParams[catCntr]) > 0: + frameContent[catCntr]['table'] = Gtk.Table(len(self.config.ctlParams[catCntr]), 2, False) + else: + frameContent[catCntr]['table'] = Gtk.Table(1, 2, False) + contentCntr = 0 + for val in sorted(self.config.ctlParams[catCntr], key=str.lower): + if self.config.getSystemValue(val) != self.config.ctlParams[catCntr][val]: + star = "*" + else: + star = "" + frameContent[catCntr]['labels'][contentCntr] = Gtk.Label(label=self.config.originalToAlias(val)+star) + frameContent[catCntr]['labels'][contentCntr].set_alignment(0, 0.5) + frameContent[catCntr]['tooltips'][contentCntr] = tuna.proc_sys_help(val) + if len(frameContent[catCntr]['tooltips'][contentCntr]): + frameContent[catCntr]['labels'][contentCntr].set_tooltip_text(frameContent[catCntr]['tooltips'][contentCntr]) + if val in self.config.ctlGuiParams[catCntr]: + # scale control + frameContent[catCntr]['texts'][contentCntr] = Gtk.HScale() + frameContent[catCntr]['texts'][contentCntr].set_range(self.config.ctlGuiParams[catCntr][val][0], self.config.ctlGuiParams[catCntr][val][1]) + frameContent[catCntr]['texts'][contentCntr].set_update_policy(Gtk.UPDATE_CONTINUOUS) + frameContent[catCntr]['texts'][contentCntr].set_value(int(self.config.ctlParams[catCntr][val])) + frameContent[catCntr]['texts'][contentCntr].set_digits(0) + else: + # input field + frameContent[catCntr]['texts'][contentCntr] = Gtk.Entry(256) + frameContent[catCntr]['texts'][contentCntr].set_alignment(0) + frameContent[catCntr]['texts'][contentCntr].set_text(self.config.ctlParams[catCntr][val]) + frameContent[catCntr]['texts'][contentCntr].connect("button-release-event", self.checkStar, catCntr, contentCntr, val, frameContent[catCntr]['labels'][contentCntr]) + frameContent[catCntr]['texts'][contentCntr].connect("focus-out-event", self.checkStar, catCntr, contentCntr, val, frameContent[catCntr]['labels'][contentCntr]) + frameContent[catCntr]['table'].attach(frameContent[catCntr]['labels'][contentCntr], 0, 1, contentCntr, contentCntr+1, Gtk.AttachOptions.FILL, xpadding=5) + frameContent[catCntr]['table'].attach(frameContent[catCntr]['texts'][contentCntr], 1, 2, contentCntr, contentCntr+1, xpadding=10) + contentCntr = contentCntr+1 + frames[catCntr].add(frameContent[catCntr]['table']) + self.contentTable.attach(frames[catCntr], currentCol, currentCol+1, currentRow, currentRow+1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 1, 1) + catCntr = catCntr+1 + self.ctrl.set_padding(5, 5, 0, 5) + self.contentTable.set_border_width(5) + self.contentTable.show_all() + except AttributeError as e: + return False
- def guiSnapshot(self): - self.ret = {} - self.property_cntr = 0 - for value in self.contentTable.get_children(): - if value.get_name() == "controls" or value.get_name() == "profileSelectorBox": - continue - self.ret[value.get_label()] = {} - for content in value: - if content.get_name() != "GtkTable": - continue - self.property_cntr = 0 - for content_last in content.get_children(): - if not content.child_get_property(content_last,"top-attach") in self.ret[value.get_label()]: - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")] = {} - if content_last.get_name() == "GtkLabel": - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['label'] = content_last.get_label() - else: - if content_last.get_name() == "GtkEntry": - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['value'] = content_last.get_text() - else: - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['value'] = str(int(content_last.get_value())) - return self.ret + def guiSnapshot(self): + self.ret = {} + self.property_cntr = 0 + for value in self.contentTable.get_children(): + if value.get_name() == "controls" or value.get_name() == "profileSelectorBox": + continue + self.ret[value.get_label()] = {} + for content in value: + if content.get_name() != "GtkTable": + continue + self.property_cntr = 0 + for content_last in content.get_children(): + if not content.child_get_property(content_last, "top-attach") in self.ret[value.get_label()]: + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")] = {} + if content_last.get_name() == "GtkLabel": + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['label'] = content_last.get_label() + else: + if content_last.get_name() == "GtkEntry": + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['value'] = content_last.get_text() + else: + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['value'] = str(int(content_last.get_value())) + return self.ret
- def systemSnapshot(self): - self.ret = {} - self.property_cntr = 0 - for value in self.contentTable.get_children(): - if value.get_name() == "controls" or value.get_name() == "profileSelectorBox": - continue - self.ret[value.get_label()] = {} - for content in value: - if content.get_name() != "GtkTable": - continue - self.property_cntr = 0 - for content_last in content.get_children(): - if not content.child_get_property(content_last,"top-attach") in self.ret[value.get_label()]: - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")] = {} - if content_last.get_name() == "GtkLabel": - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['label'] = content_last.get_label() - self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['value'] = self.config.getSystemValue(self.ret[value.get_label()][content.child_get_property(content_last,"top-attach")]['label']) - return self.ret + def systemSnapshot(self): + self.ret = {} + self.property_cntr = 0 + for value in self.contentTable.get_children(): + if value.get_name() == "controls" or value.get_name() == "profileSelectorBox": + continue + self.ret[value.get_label()] = {} + for content in value: + if content.get_name() != "GtkTable": + continue + self.property_cntr = 0 + for content_last in content.get_children(): + if not content.child_get_property(content_last, "top-attach") in self.ret[value.get_label()]: + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")] = {} + if content_last.get_name() == "GtkLabel": + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['label'] = content_last.get_label() + self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['value'] = self.config.getSystemValue(self.ret[value.get_label()][content.child_get_property(content_last, "top-attach")]['label']) + return self.ret
- def on_applyChanges_clicked(self,widget): - self.config.backup = self.systemSnapshot() - self.config.applyChanges(self.guiSnapshot()) - self.updateCommonView() + def on_applyChanges_clicked(self, widget): + self.config.backup = self.systemSnapshot() + self.config.applyChanges(self.guiSnapshot()) + self.updateCommonView()
- def on_undoChanges_clicked(self,widget): - try: - self.config.backup - self.config.applyChanges(self.config.backup) - self.updateCommonView() - except: - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, - _("Backup not found, this button is useable after click on apply")) - ret = dialog.run() - dialog.destroy() + def on_undoChanges_clicked(self, widget): + try: + self.config.backup + self.config.applyChanges(self.config.backup) + self.updateCommonView() + except: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, \ + _("Backup not found, this button is useable after click on apply")) + ret = dialog.run() + dialog.destroy()
- def on_saveSnapshot_clicked(self,widget): - ret = self.guiSnapshot() - self.config.saveSnapshot(self.ret) - old_name = self.get_current_combo_selection() - if self.profileview.setProfileFileList(): - self.profileview.set_current_tree_selection(old_name[1]) - self.set_current_combo_selection(old_name[1]) + def on_saveSnapshot_clicked(self, widget): + ret = self.guiSnapshot() + self.config.saveSnapshot(self.ret) + old_name = self.get_current_combo_selection() + if self.profileview.setProfileFileList(): + self.profileview.set_current_tree_selection(old_name[1]) + self.set_current_combo_selection(old_name[1])
- def on_saveTunedChanges_clicked(self,widget): - if not self.config.checkTunedDaemon(): - dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("Tuned daemon undetected!\nFor this function you must have installed Tuned daemon.")) - ret = dialog.run() - dialog.destroy() - return False - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, - _("This function can create new profile for tuned daemon and apply config permanently after reboot.\nProfile will be permanently saved and rewrite all old profiles created by tuna!\nUsing this only if you know that config cant corrupt your system!\nRealy can do it?")) - ret = dialog.run() - dialog.destroy() - if ret == Gtk.ResponseType.NO: - return False - try: - ret = self.guiSnapshot() - self.config.saveTuned(ret) - except RuntimeError as e: - dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,str(e)) - ret = dialog.run() - dialog.destroy() - self.profileview.setProfileFileList() + def on_saveTunedChanges_clicked(self, widget): + if not self.config.checkTunedDaemon(): + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, \ + _("Tuned daemon undetected!\nFor this function you must have installed Tuned daemon.")) + ret = dialog.run() + dialog.destroy() + return False + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, \ + _("This function can create new profile for tuned daemon and apply config permanently after reboot.\nProfile will be permanently saved and rewrite all old profiles created by tuna!\nUsing this only if you know that config cant corrupt your system!\nRealy can do it?")) + ret = dialog.run() + dialog.destroy() + if ret == Gtk.ResponseType.NO: + return False + try: + ret = self.guiSnapshot() + self.config.saveTuned(ret) + except RuntimeError as e: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, str(e)) + ret = dialog.run() + dialog.destroy() + self.profileview.setProfileFileList()
- def on_profileSelector_changed(self, widget): - ret = self.get_current_combo_selection() - if ret[0] < 0: - return False - self.restoreConfig = False - err = self.config.checkConfigFile(self.config.config['root']+ret[1]) - if err != '': - self.restoreConfig = True - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, - _("Config file contain errors: \n%s\nRun autocorrect?") % _(err)) - dlgret = dialog.run() - dialog.destroy() - if dlgret == Gtk.ResponseType.YES: - self.config.fixConfigFile(self.config.config['root'] + ret[1]) - err = self.config.checkConfigFile(self.config.config['root'] + ret[1]) - if err != '': - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, - _("Config file contain errors: \n%s\nAutocorrect failed!") % _(err)) - dialog.run() - dialog.destroy() - self.restoreConfig = True - else: - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.INFO, Gtk.ButtonsType.OK, - _("Autocorrect OK")) - dialog.run() - dialog.destroy() - self.restoreConfig = False - if self.restoreConfig: - old = self.config.cacheFileName.rfind("/") - old = self.config.cacheFileName[old+1:len(self.config.cacheFileName)] - cur = self.configFileCombo.get_model() - for val in cur: - if val[0] == old: - self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) - self.configFileCombo.set_active(val.path[0]) - self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) - return False - cur = self.profileview.configFileTree.get_model() - for val in cur: - if val[0] == ret[1]: - self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) - self.profileview.configFileTree.set_cursor(val.path[0]) - self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) - self.config.loadTuna(ret[1]) - self.config.updateDefault(ret[1]) - self.updateCommonView() - return True + def on_profileSelector_changed(self, widget): + ret = self.get_current_combo_selection() + if ret[0] < 0: + return False + self.restoreConfig = False + err = self.config.checkConfigFile(self.config.config['root']+ret[1]) + if err != '': + self.restoreConfig = True + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, \ + _("Config file contain errors: \n%s\nRun autocorrect?") % _(err)) + dlgret = dialog.run() + dialog.destroy() + if dlgret == Gtk.ResponseType.YES: + self.config.fixConfigFile(self.config.config['root'] + ret[1]) + err = self.config.checkConfigFile(self.config.config['root'] + ret[1]) + if err != '': + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, \ + _("Config file contain errors: \n%s\nAutocorrect failed!") % _(err)) + dialog.run() + dialog.destroy() + self.restoreConfig = True + else: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, \ + _("Autocorrect OK")) + dialog.run() + dialog.destroy() + self.restoreConfig = False + if self.restoreConfig: + old = self.config.cacheFileName.rfind("/") + old = self.config.cacheFileName[old+1:len(self.config.cacheFileName)] + cur = self.configFileCombo.get_model() + for val in cur: + if val[0] == old: + self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) + self.configFileCombo.set_active(val.path[0]) + self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) + return False + cur = self.profileview.configFileTree.get_model() + for val in cur: + if val[0] == ret[1]: + self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) + self.profileview.configFileTree.set_cursor(val.path[0]) + self.configFileCombo.handler_unblock_by_func(self.on_profileSelector_changed) + self.config.loadTuna(ret[1]) + self.config.updateDefault(ret[1]) + self.updateCommonView() + return True
- def get_current_combo_selection(self): - combo_iter = self.configFileCombo.get_active_iter() - combo_row = self.configFileCombo.get_active() - if combo_iter != None: - model = self.configFileCombo.get_model() - return (combo_row,model[combo_iter][0]) - else: - return (-1,"ERROR") + def get_current_combo_selection(self): + combo_iter = self.configFileCombo.get_active_iter() + combo_row = self.configFileCombo.get_active() + if combo_iter != None: + model = self.configFileCombo.get_model() + return (combo_row, model[combo_iter][0]) + else: + return (-1, "ERROR")
- def set_current_combo_selection(self, string): - cur = self.configFileCombo.get_model() - for val in cur: - if val[0] == string: - self.configFileCombo.set_active(val.path[0]) + def set_current_combo_selection(self, string): + cur = self.configFileCombo.get_model() + for val in cur: + if val[0] == string: + self.configFileCombo.set_active(val.path[0])
- def checkStar(self, widget, event, catCntr,contentCntr,val,label): - lbl = label.get_label().replace("*",""); - if widget.get_name() == "GtkEntry": - value = widget.get_text() - else: - value = str(int(widget.get_value())) - if value != self.config.getSystemValue(lbl): - label.set_label(lbl+"*") - else: - label.set_label(lbl) + def checkStar(self, widget, event, catCntr, contentCntr, val, label): + lbl = label.get_label().replace("*", "") + if widget.get_name() == "GtkEntry": + value = widget.get_text() + else: + value = str(int(widget.get_value())) + if value != self.config.getSystemValue(lbl): + label.set_label(lbl+"*") + else: + label.set_label(lbl)
Update the spacing and stlyle in procview.py
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/procview.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index fa70ab400a43..d5d95ed3e486 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -184,11 +184,10 @@ class process_druid: if self.set_attributes_for_threads(self.pid, new_policy, new_prio, new_affinity): changed = True - else: - changed = self.set_attributes_for_regex(self.regex_edit.get_text(), - new_policy, - new_prio, - new_affinity) + else: + changed = self.set_attributes_for_regex( + self.regex_edit.get_text(), new_policy, new_prio, + new_affinity)
self.dialog.destroy() return changed @@ -276,8 +275,8 @@ class procview:
# Allow enable drag and drop of rows self.treeview.enable_model_drag_source( - Gdk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, - Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + Gtk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, + Gtk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) @@ -655,8 +654,8 @@ class procview: menu.add(uthreads) menu.add(help)
- save_kthreads_tunings.connect_object('activate', - self.save_kthreads_tunings, event) + save_kthreads_tunings.connect_object( + 'activate', self.save_kthreads_tunings, event) setattr.connect_object('activate', self.edit_attributes, event) refresh.connect_object('activate', self.refresh_toggle, event) kthreads.connect_object('activate', self.kthreads_view_toggled, event)
Update the spacing to use spaces instead of tags and to 4 space indents. Fix some of the problems from pylint
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/util.py | 208 +++++++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 104 deletions(-) mode change 100755 => 100644 tuna/gui/util.py
diff --git a/tuna/gui/util.py b/tuna/gui/util.py old mode 100755 new mode 100644 index b2d012662483..ed55eb8149e4 --- a/tuna/gui/util.py +++ b/tuna/gui/util.py @@ -9,118 +9,118 @@ import schedutils from tuna import tuna
class list_store_column: - def __init__(self, name, type = GObject.TYPE_UINT): - self.name = name - self.type = type + def __init__(self, name, type=GObject.TYPE_UINT): + self.name = name + self.type = type
def generate_list_store_columns_with_attr(columns): - for column in columns: - yield column.type - for column in columns: - yield GObject.TYPE_UINT + for column in columns: + yield column.type + for column in columns: + yield GObject.TYPE_UINT
def set_store_columns(store, row, new_value): - nr_columns = len(new_value) - for col in range(nr_columns): - col_weight = col + nr_columns - cur_value = store.get_value(row, col) - if cur_value == new_value[col]: - new_weight = Pango.Weight.NORMAL - else: - new_weight = Pango.Weight.BOLD + nr_columns = len(new_value) + for col in range(nr_columns): + col_weight = col + nr_columns + cur_value = store.get_value(row, col) + if cur_value == new_value[col]: + new_weight = Pango.Weight.NORMAL + else: + new_weight = Pango.Weight.BOLD
- store.set(row, col, new_value[col], col_weight, new_weight) + store.set(row, col, new_value[col], col_weight, new_weight)
def on_affinity_text_changed(self): - new_affinity_text = self.affinity.get_text().strip() - if self.affinity_text != new_affinity_text: - try: - for cpu in new_affinity_text.strip(",").split(","): - new_affinity_cpu_entry = int(cpu, 16) - except: - try: - new_affinity = tuna.cpustring_to_list(new_affinity_text) - except: - if len(new_affinity_text) > 0 and new_affinity_text[-1] != '-' and new_affinity_text[0:2] not in ('0x', '0X'): - # print "not a hex number" - self.affinity.set_text(self.affinity_text) - return - self.affinity_text = new_affinity_text + new_affinity_text = self.affinity.get_text().strip() + if self.affinity_text != new_affinity_text: + try: + for cpu in new_affinity_text.strip(",").split(","): + new_affinity_cpu_entry = int(cpu, 16) + except: + try: + new_affinity = tuna.cpustring_to_list(new_affinity_text) + except: + if len(new_affinity_text) > 0 and new_affinity_text[-1] != '-' and new_affinity_text[0:2] not in ('0x', '0X'): + # print "not a hex number" + self.affinity.set_text(self.affinity_text) + return + self.affinity_text = new_affinity_text
def invalid_affinity(): - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, - Gtk.ButtonsType.OK, - _("Invalid affinity, specify a list of CPUs!")) - dialog.run() - dialog.destroy() - return False + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, \ + Gtk.ButtonsType.OK, \ + _("Invalid affinity, specify a list of CPUs!")) + dialog.run() + dialog.destroy() + return False
def thread_set_attributes(pid_info, new_policy, new_prio, new_affinity, nr_cpus): - pid = pid_info.pid - changed = False - curr_policy = schedutils.get_scheduler(pid) - curr_prio = int(pid_info["stat"]["rt_priority"]) - if new_policy == schedutils.SCHED_OTHER: - new_prio = 0 - if curr_policy != new_policy or curr_prio != new_prio: - try: - schedutils.set_scheduler(pid, new_policy, new_prio) - except: - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, - Gtk.ButtonsType.OK, - _("Invalid parameters!")) - dialog.run() - dialog.destroy() - return False - - curr_policy = schedutils.get_scheduler(pid) - if curr_policy != new_policy: - print(_("couldn't change pid %(pid)d from %(cpol)s(%(cpri)d) to %(npol)s(%(npri)d)!") % \ - { 'pid': pid, 'cpol': schedutils.schedstr(curr_policy), - 'cpri': curr_prio, - 'npol': schedutils.schedstr(new_policy), - 'npri': new_prio}) - else: - changed = True - - try: - curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError - if e.args[0] == 3: - return False - raise e - - try: - new_affinity = [ int(a) for a in new_affinity.split(",") ] - except: - try: - new_affinity = tuna.cpustring_to_list(new_affinity) - except: - new_affinity = procfs.bitmasklist(new_affinity, nr_cpus) - - new_affinity.sort() - - if curr_affinity != new_affinity: - try: - schedutils.set_affinity(pid, new_affinity) - except: - return invalid_affinity() - - try: - curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError - if e.args[0] == 3: - return False - raise e - - if curr_affinity != new_affinity: - print(_("couldn't change pid %(pid)d from %(caff)s to %(naff)s!") % \ - { 'pid':pid, 'caff':curr_affinity, 'naff':new_affinity }) - else: - changed = True - - return changed + pid = pid_info.pid + changed = False + curr_policy = schedutils.get_scheduler(pid) + curr_prio = int(pid_info["stat"]["rt_priority"]) + if new_policy == schedutils.SCHED_OTHER: + new_prio = 0 + if curr_policy != new_policy or curr_prio != new_prio: + try: + schedutils.set_scheduler(pid, new_policy, new_prio) + except: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, \ + Gtk.ButtonsType.OK, \ + _("Invalid parameters!")) + dialog.run() + dialog.destroy() + return False + + curr_policy = schedutils.get_scheduler(pid) + if curr_policy != new_policy: + print(_("couldn't change pid %(pid)d from %(cpol)s(%(cpri)d) to %(npol)s(%(npri)d)!") % \ + {'pid': pid, 'cpol': schedutils.schedstr(curr_policy), + 'cpri': curr_prio, + 'npol': schedutils.schedstr(new_policy), + 'npri': new_prio}) + else: + changed = True + + try: + curr_affinity = schedutils.get_affinity(pid) + except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError + if e.args[0] == 3: + return False + raise e + + try: + new_affinity = [int(a) for a in new_affinity.split(",")] + except: + try: + new_affinity = tuna.cpustring_to_list(new_affinity) + except: + new_affinity = procfs.bitmasklist(new_affinity, nr_cpus) + + new_affinity.sort() + + if curr_affinity != new_affinity: + try: + schedutils.set_affinity(pid, new_affinity) + except: + return invalid_affinity() + + try: + curr_affinity = schedutils.get_affinity(pid) + except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError + if e.args[0] == 3: + return False + raise e + + if curr_affinity != new_affinity: + print(_("couldn't change pid %(pid)d from %(caff)s to %(naff)s!") % \ + {'pid':pid, 'caff':curr_affinity, 'naff':new_affinity}) + else: + changed = True + + return changed
- Put imports on separate lines. - change exit to sys.exit - change type() comparison to isinstance - remove test for set, since it has long been a standard import - Fix a few lines that are to large with continuations, etc
Signed-off-by: John Kacur jkacur@redhat.com --- tuna-cmd.py | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/tuna-cmd.py b/tuna-cmd.py index ebadbe1e240a..99fe355baa77 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -14,12 +14,21 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details.
-import getopt, ethtool, fnmatch, errno, os, procfs, re, schedutils, sys -from tuna import tuna, sysfs - +""" tuna - Application Tuning GUI """ + +import os +import sys +import errno +import re +import getopt +import fnmatch import gettext import locale from functools import reduce +import ethtool +import schedutils +import procfs +from tuna import tuna, sysfs
try: import inet_diag @@ -27,12 +36,6 @@ try: except: have_inet_diag = False
-try: - set -except NameError: - # In python < 2.4, "set" is not the first class citizen. - from sets import Set as set - # FIXME: ETOOMANYGLOBALS, we need a class!
nr_cpus = None @@ -129,10 +132,9 @@ def ps_show_header(has_ctxt_switch_info, cgroups=False): print("%7s %6s %5s %7s %s" % \ (" ", " ", " ", _("thread"), has_ctxt_switch_info and "ctxt_switches" or "")) - print("%7s %6s %5s %7s%s %15s" % \ - ("pid", "SCHED_", "rtpri", "affinity", - has_ctxt_switch_info and " %9s %12s" % ("voluntary", "nonvoluntary") or "", - "cmd"), end=' ') + print("%7s %6s %5s %7s%s %15s" % ("pid", "SCHED_", "rtpri", "affinity", \ + has_ctxt_switch_info and " %9s %12s" % ("voluntary", "nonvoluntary") \ + or "", "cmd"), end=' ') if cgroups: print(" %7s" % ("cgroup")) else: @@ -448,7 +450,7 @@ def list_config(): print(_("Preloaded config files:")) for value in config.populate(): print(value) - exit(1) + sys.exit(1)
def main(): global ps @@ -492,7 +494,7 @@ def main(): if o in ("-h", "--help"): usage() return - elif o in ("-a", "--config_file_apply"): + if o in ("-a", "--config_file_apply"): apply_config(a) elif o in ("-l", "--config_file_list"): list_config() @@ -508,7 +510,8 @@ def main(): try: cpu_list = tuna.nohz_full_list() except: - print("tuna: --nohz_full " + _(" needs nohz_full=cpulist on the kernel command line")) + print("tuna: --nohz_full " + \ + _(" needs nohz_full=cpulist on the kernel command line")) sys.exit(2) elif o in ("-C", "--affect_children"): affect_children = True @@ -529,7 +532,7 @@ def main(): # threads was found, which would result in an empty # thread list, i.e. we would print all the threads # in the system when we should print nothing. - if not op_list and type(a) == type(''): + if not op_list and isinstance(a, type('')): thread_list_str = do_list_op(op, thread_list_str, a.split(",")) if not op: @@ -557,7 +560,8 @@ def main(): else: try: tuna.threads_set_priority(thread_list, a, affect_children) - except (SystemError, OSError) as err: # old python-schedutils incorrectly raised SystemError + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: print("tuna: %s" % err) sys.exit(2) elif o in ("-P", "--show_threads"): @@ -619,7 +623,7 @@ def main(): list(map(irq_mapper, list(set(a.split(",")))))) irq_list = do_list_op(op, irq_list, op_list) # See comment above about thread_list_str - if not op_list and type(a) == type(''): + if not op_list and isinstance(a, type('')): irq_list_str = do_list_op(op, irq_list_str, a.split(",")) if not op: thread_list = [] @@ -669,7 +673,7 @@ def main(): # threads was found, which would result in an empty # thread list, i.e. we would print all the threads # in the system when we should print nothing. - if not op_list and type(a) == type(''): + if not op_list and isinstance(a, type('')): thread_list_str = do_list_op(op, thread_list_str, a.split(",")) if not op: irq_list = None
- Update spacing to 4 spaces instead of an 8 space tab - Fix various minor problems pointed out by pylint
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/config.py | 728 +++++++++++++++++++++++++------------------------ 1 file changed, 365 insertions(+), 363 deletions(-)
diff --git a/tuna/config.py b/tuna/config.py index e7d755c7296d..6c7e759f5937 100644 --- a/tuna/config.py +++ b/tuna/config.py @@ -3,400 +3,402 @@ import os import re import fnmatch import sys -from gi.repository import Gtk import codecs import configparser from time import localtime, strftime from subprocess import Popen, PIPE, STDOUT, call -TUNED_CONF="""[sysctl]\n""" +from gi.repository import Gtk +TUNED_CONF = """[sysctl]\n"""
class Config: - #init config, load /etc/tuna.conf (if not exist, create it) - def __init__(self): - self.aliasList = [] - self.aliasReverse = [] - self.configFile = "/etc/tuna.conf" + #init config, load /etc/tuna.conf (if not exist, create it) + def __init__(self): + self.aliasList = [] + self.aliasReverse = [] + self.configFile = "/etc/tuna.conf" + + try: + self.configParser = configparser.RawConfigParser() + self.configParser.read(self.configFile) + cfg = self.configParser.items('global') + except configparser.Error: + f = open(self.configFile, 'w') + f.write("[global]\n") + f.write("root=/etc/tuna/\n") + f.write("lastFile=\n") + f.close() + self.configParser.read(self.configFile) + cfg = self.configParser.items('global') + self.config = {}
- try: - self.configParser = configparser.RawConfigParser() - self.configParser.read(self.configFile) - cfg = self.configParser.items('global') - except configparser.Error: - f = open(self.configFile,'w') - f.write("[global]\n") - f.write("root=/etc/tuna/\n") - f.write("lastFile=\n") - f.close() - self.configParser.read(self.configFile) - cfg = self.configParser.items('global') - self.config = {} + for option, value in cfg: + self.config[option] = value + self.cacheFileName = ''
- for option, value in cfg: - self.config[option] = value - self.cacheFileName = '' + def FileNameToConfigPath(self, filename): + return filename.replace(".", "\.").replace("/", ".")
- def FileNameToConfigPath(self, filename): - return filename.replace(".", "\.").replace("/", ".") + def ConfigPathToFileName(self, configpath): + return configpath.replace(".", "/").replace("\/", ".")
- def ConfigPathToFileName(self, configpath): - return configpath.replace(".", "/").replace("\/", ".") + def updateDefault(self, filename): + if filename.replace("", "temp-direct-load.conf") != filename: + self.temp = configparser.RawConfigParser() + self.temp.read(self.configFile) + self.temp.set('global', 'lastFile', filename) + with open(self.configFile, 'wb') as cfgfile: + self.temp.write(cfgfile) + self.config['lastfile'] = filename
- def updateDefault(self, filename): - if filename.replace("", "temp-direct-load.conf") != filename: - self.temp = configparser.RawConfigParser() - self.temp.read(self.configFile) - self.temp.set('global', 'lastFile', filename) - with open(self.configFile, 'wb') as cfgfile: - self.temp.write(cfgfile) - self.config['lastfile'] = filename + def load(self, profileName): + tmp = configparser.RawConfigParser() + tmp.read(self.config['root'] + profileName) + try: + check = tmp.items('categories') + except configparser.NoSectionError: + if self.tuned2Tuna(profileName) < 0: + return -1 + return self.loadTuna(profileName)
- def load(self, profileName): - tmp = configparser.RawConfigParser() - tmp.read(self.config['root'] + profileName) - try: - check = tmp.items('categories') - except configparser.NoSectionError: - if(self.tuned2Tuna(profileName) < 0): - return -1 - return self.loadTuna(profileName) + def tuned2Tuna(self, profileName): + try: + tmp = configparser.RawConfigParser() + tmp.read(self.config['root']+profileName) + content = tmp.items('sysctl') + f = open(self.config['root']+profileName, 'w') + f.write("[categories]\n") + f.write("sysctl=Tuned import\n") + f.write("[sysctl]\n") + for option, value in content: + f.write(option + "=" + value + "\n") + f.close() + return 0 + except (configparser.Error, IOError): + dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,\ + Gtk.ButtonsType.OK, "%s\n%s" % \ + (_("Corruputed config file: "), _(self.config['root']+profileName))) + ret = dialog.run() + dialog.destroy() + return -1
- def tuned2Tuna(self,profileName): - try: - tmp = configparser.RawConfigParser() - tmp.read(self.config['root']+profileName) - content = tmp.items('sysctl') - f = open(self.config['root']+profileName,'w') - f.write("[categories]\n") - f.write("sysctl=Tuned import\n") - f.write("[sysctl]\n") - for option,value in content: - f.write(option + "=" + value + "\n") - f.close() - return 0 - except (configparser.Error, IOError): - dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,\ - Gtk.ButtonsType.OK, "%s\n%s" % \ - (_("Corruputed config file: "), _(self.config['root']+profileName))) - ret = dialog.run() - dialog.destroy() - return -1 + def checkTunedDaemon(self): + for path in os.environ["PATH"].split(os.pathsep): + path = path.strip('"') + tFile = os.path.join(path, "tuned") + if os.path.isfile(tFile) and os.access(tFile, os.X_OK): + return True + return False
- def checkTunedDaemon(self): - for path in os.environ["PATH"].split(os.pathsep): - path = path.strip('"') - tFile = os.path.join(path, "tuned") - if os.path.isfile(tFile) and os.access(tFile, os.X_OK): - return True - return False + def currentActiveProfile(self): + proc = Popen(["tuned-adm", "active"], stdout=PIPE, stderr=PIPE) + ret = proc.communicate() + profile = ret[0] + if profile and profile.find("Current active profile: ") == 0: + return (profile[len("Current active profile: "):profile.find("\n")], ret[1]) + return ("unknown", ret[1])
- def currentActiveProfile(self): - proc = Popen(["tuned-adm", "active"], stdout=PIPE, stderr=PIPE) - ret = proc.communicate() - profile = ret[0] - if profile and profile.find("Current active profile: ") == 0: - return (profile[len("Current active profile: "):profile.find("\n")],ret[1]) - return ("unknown",ret[1]) + def setCurrentActiveProfile(self): + call("tuned-adm profile tuna", shell=True)
- def setCurrentActiveProfile(self): - call("tuned-adm profile tuna", shell=True) + def saveTuned(self, data): + ldir = "/etc/tuned/tuna" + profile = self.currentActiveProfile() + if profile[1]: + raise RuntimeError(_("Can't activate tuna profile in tuned daemon\n%s" % profile[1])) + # return False - unreachable code here! + if not os.path.exists(ldir): + try: + os.stat(ldir) + except (IOError, OSError): + os.mkdir(ldir) + f = codecs.open(os.path.join(ldir, "tuned.conf"), "w", "utf-8") + f.write(TUNED_CONF) + for index in data: + for ind in data[index]: + f.write(self.aliasToOriginal(data[index][ind]["label"])+"="+data[index][ind]["value"]+"\n") + f.close() + if profile[0] != "tuna": + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "%s%s\n%s" % \ + (_("Current active profile is: "), + _(profile[0]), + _("Set new created profile as current in tuned daemon?"))) + ret = dialog.run() + dialog.destroy() + if ret == Gtk.ResponseType.YES: + self.setCurrentActiveProfile() + if self.currentActiveProfile()[0] != "tuna": + raise RuntimeError("%s %s\n%s" % \ + (_("Current active profile is: "), \ + _(profile), \ + _("Setting of new tuned profile failed! Check if tuned is installed and active"))) + dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL \ + | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, \ + _("Tuna profile is now active in tuned daemon.")) + ret = dialog.run() + dialog.destroy() + return True
- def saveTuned(self, data): - ldir = "/etc/tuned/tuna" - profile = self.currentActiveProfile() - if profile[1]: - raise RuntimeError (_("Can't activate tuna profile in tuned daemon\n%s" % profile[1])) - return False - if not os.path.exists(ldir): - try: - os.stat(ldir) - except (IOError,OSError): - os.mkdir(ldir) - f = codecs.open(os.path.join(ldir, "tuned.conf"), "w", "utf-8") - f.write(TUNED_CONF) - for index in data: - for ind in data[index]: - f.write(self.aliasToOriginal(data[index][ind]["label"])+"="+data[index][ind]["value"]+"\n") - f.close() - if profile[0] != "tuna": - dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "%s%s\n%s" % \ - (_("Current active profile is: "), - _(profile[0]), - _("Set new created profile as current in tuned daemon?"))) - ret = dialog.run() - dialog.destroy() - if ret == Gtk.ResponseType.YES: - self.setCurrentActiveProfile() - if self.currentActiveProfile()[0] != "tuna": - raise RuntimeError ("%s %s\n%s" % \ - (_("Current active profile is: "), - _(profile), - _("Setting of new tuned profile failed! Check if tuned is installed and active"))) - return False - else: - dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Tuna profile is now active in tuned daemon.")) - ret = dialog.run() - dialog.destroy() - return True
+ def loadTuna(self, profileName): + err = self.checkConfigFile(self.config['root'] + profileName) + if err != '': + raise RuntimeError(_("Config file contain errors: ") + _(err)) + try: + self.configParser = configparser.RawConfigParser() + self.configParser.read(self.config['root'] + profileName) + tempCategories = self.configParser.items('categories') + self.catIndex = 0 + self.categoriesOrigin = {} + self.categories = {} + self.ctlParams = {} + self.ctlGuiParams = {} + self.aliasList = [] + self.aliasReverse = [] + for option, value in tempCategories: + if value != "": + oldTempCfg = self.configParser.items(option) + self.ctlParams[self.catIndex] = {} + self.ctlGuiParams[self.catIndex] = {} + tempCfg = [] + for index in range(len(oldTempCfg)): + if self.isFnString(oldTempCfg[index][0]): + expanded = self.getFilesByFN("/proc/sys", \ + self.ConfigPathToFileName(oldTempCfg[index][0])) + for index2 in range(len(expanded)): + expandedData = (self.FileNameToConfigPath(expanded[index2]), oldTempCfg[index][1]) + tempCfg.append(expandedData) + else: + tempCfg.append(oldTempCfg[index]) + for opt, val in tempCfg: + if val.find(',') != -1 and val.find(',', val.find(',')) != -1 and len(val.split(",")) > 2: + self.ctlGuiParams[self.catIndex][opt] = val.split(",") + val = self.ctlGuiParams[self.catIndex][opt][2] + sys = self.getSystemValue(opt) + if val == "" or val == sys: + self.ctlParams[self.catIndex][opt] = sys + else: + self.ctlParams[self.catIndex][opt] = val + if opt in self.ctlGuiParams[self.catIndex]: + if self.ctlGuiParams[self.catIndex][opt][0] == '': + self.ctlGuiParams[self.catIndex][opt][0] = int(int(self.ctlParams[self.catIndex][opt])/10) + else: + self.ctlGuiParams[self.catIndex][opt][0] = int(self.ctlGuiParams[self.catIndex][opt][0]) + if self.ctlGuiParams[self.catIndex][opt][1] == '': + self.ctlGuiParams[self.catIndex][opt][1] = int(int(self.ctlParams[self.catIndex][opt])*10) + else: + self.ctlGuiParams[self.catIndex][opt][1] = int(self.ctlGuiParams[self.catIndex][opt][1]) + self.categories[self.catIndex] = value + self.categoriesOrigin[self.catIndex] = option + self.catIndex = self.catIndex + 1 + except (configparser.Error, IOError): + print(_("Config file is corrupted")) + return -1 + try: + self.aliasList = self.configParser.items('guiAlias') + except configparser.Error: + self.aliasList = [] + self.aliasReverse = [] + return 0
- def loadTuna(self, profileName): - err = self.checkConfigFile(self.config['root'] + profileName) - if err != '': - raise RuntimeError(_("Config file contain errors: ") + _(err)) - return -1 - try: - self.configParser = configparser.RawConfigParser() - self.configParser.read(self.config['root'] + profileName) - tempCategories = self.configParser.items('categories') - self.catIndex = 0 - self.categoriesOrigin = {} - self.categories = {} - self.ctlParams = {} - self.ctlGuiParams = {} - self.aliasList = [] - self.aliasReverse = [] - for option, value in tempCategories: - if value != "": - oldTempCfg = self.configParser.items(option) - self.ctlParams[self.catIndex] = {} - self.ctlGuiParams[self.catIndex] = {} - tempCfg = [] - for index in range(len(oldTempCfg)): - if self.isFnString(oldTempCfg[index][0]): - expanded = self.getFilesByFN("/proc/sys", self.ConfigPathToFileName(oldTempCfg[index][0])) - for index2 in range(len(expanded)): - expandedData = (self.FileNameToConfigPath(expanded[index2]), oldTempCfg[index][1]) - tempCfg.append(expandedData) - else: - tempCfg.append(oldTempCfg[index]) - for opt, val in tempCfg: - if val.find(',') != -1 and val.find(',',val.find(',')) != -1 and len(val.split(",")) > 2: - self.ctlGuiParams[self.catIndex][opt] = val.split(",") - val = self.ctlGuiParams[self.catIndex][opt][2] - sys = self.getSystemValue(opt) - if val == "" or val == sys: - self.ctlParams[self.catIndex][opt] = sys - else: - self.ctlParams[self.catIndex][opt] = val - if opt in self.ctlGuiParams[self.catIndex]: - if self.ctlGuiParams[self.catIndex][opt][0] == '': - self.ctlGuiParams[self.catIndex][opt][0] = int(int(self.ctlParams[self.catIndex][opt])/10) - else: - self.ctlGuiParams[self.catIndex][opt][0] = int(self.ctlGuiParams[self.catIndex][opt][0]) - if self.ctlGuiParams[self.catIndex][opt][1] == '': - self.ctlGuiParams[self.catIndex][opt][1] = int(int(self.ctlParams[self.catIndex][opt])*10) - else: - self.ctlGuiParams[self.catIndex][opt][1] = int(self.ctlGuiParams[self.catIndex][opt][1]) - self.categories[self.catIndex] = value - self.categoriesOrigin[self.catIndex] = option - self.catIndex = self.catIndex + 1 - except (configparser.Error, IOError): - print(_("Config file is corrupted")) - return -1 - try: - self.aliasList = self.configParser.items('guiAlias') - except configparser.Error: - self.aliasList = [] - self.aliasReverse = [] - return 0 + def updateDescription(self, filename): + try: + self.temp = configparser.RawConfigParser() + self.temp.read(self.config['root'] + filename) + self.description = self.temp.items('fileDescription') + self.description = dict(self.description)['text'] + except configparser.Error as e: + self.description = _("Description for this profile not found") + if e != configparser.NoSectionError: + print(e) + return self.description
- def updateDescription(self, filename): - try: - self.temp = configparser.RawConfigParser() - self.temp.read(self.config['root'] + filename) - self.description = self.temp.items('fileDescription') - self.description = dict(self.description)['text'] - except configparser.Error as e: - self.description = _("Description for this profile not found") - if e != configparser.NoSectionError: - print(e) - return self.description + def fileToCache(self, profileName): + try: + f = open(self.config['root'] + profileName, 'r') + except IOError: + pass + if f is None: + raise RuntimeError(_("Cant open this config file: %s" % (self.config['root'] + profileName))) + self.cacheFileName = profileName + self.cache = f.read() + f.close() + self.updateDescription(profileName)
- def fileToCache(self, profileName): - try: - f = open(self.config['root'] + profileName, 'r') - except IOError: - pass - if f is None: - raise RuntimeError(_("Cant open this config file: %s" % (self.config['root'] + profileName))) - return False - self.cacheFileName = profileName - self.cache = f.read() - f.close() - self.updateDescription(profileName) + def cacheToFile(self, profileName): + try: + f = open(self.config['root'] + profileName, 'w') + f.write(self.cache) + f.close() + except IOError: + print(_("Cant write to config file: %s" % (self.config['root'] + profileName)))
- def cacheToFile(self, profileName): - try: - f = open(self.config['root'] + profileName, 'w') - f.write(self.cache) - f.close() - except IOError: - print(_("Cant write to config file: %s" % (self.config['root'] + profileName))) + def loadDirect(self, data): + try: + f = open(self.config['root']+"temp-direct-load.conf", 'w') + except IOError: + raise RuntimeError(_("Cant open this config file: %stemp-direct-load.conf" % (self.config['root']))) + f.write(data) + f.close() + ret = self.load("temp-direct-load.conf") + os.unlink(self.config['root']+"temp-direct-load.conf") + return ret
- def loadDirect(self, data): - try: - f = open(self.config['root']+"temp-direct-load.conf", 'w') - except IOError: - raise RuntimeError(_("Cant open this config file: %stemp-direct-load.conf" % (self.config['root']))) - f.write(data) - f.close() - ret = self.load("temp-direct-load.conf") - os.unlink(self.config['root']+"temp-direct-load.conf") - return ret + def populate(self): + return [files for files in os.listdir(self.config['root']) if files != "temp-direct-load.conf"]
- def populate(self): - return [files for files in os.listdir(self.config['root']) if files!="temp-direct-load.conf"] - - def getSystemValue(self, filename): - filename = self.aliasToOriginal(filename) - try: - buffer = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'r').read() - except IOError: - print(_("Invalid item! file: /proc/sys/%s" %(self.ConfigPathToFileName(filename)))) - return "" - return buffer.strip() + def getSystemValue(self, filename): + filename = self.aliasToOriginal(filename) + try: + buffer = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'r').read() + except IOError: + print(_("Invalid item! file: /proc/sys/%s" %(self.ConfigPathToFileName(filename)))) + return "" + return buffer.strip()
- def setSystemValue(self, filename, value): - filename = self.aliasToOriginal(filename) - old = self.getSystemValue(filename) - if value == "" or old == value: - return 0 - try: - fp = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'w') - fp.write(value) - except IOError: - print("%s%s %s %s" % (_("Cant write to file! path: /proc/sys/"), self.ConfigPathToFileName(filename), _("value:"), value)) - return -1 - return 0 + def setSystemValue(self, filename, value): + filename = self.aliasToOriginal(filename) + old = self.getSystemValue(filename) + if value == "" or old == value: + return 0 + try: + fp = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'w') + fp.write(value) + except IOError: + print("%s%s %s %s" % (_("Cant write to file! path: /proc/sys/"), \ + self.ConfigPathToFileName(filename), _("value:"), value)) + return -1 + return 0
- def applyChanges(self, data): - for cat in data: - for itemId in data[cat]: - self.setSystemValue(data[cat][itemId]['label'], data[cat][itemId]['value']) - self.reloadSystemValues(data) + def applyChanges(self, data): + for cat in data: + for itemId in data[cat]: + self.setSystemValue(data[cat][itemId]['label'], data[cat][itemId]['value']) + self.reloadSystemValues(data)
- def reloadSystemValues(self, data): - for cat in self.ctlParams: - for param in self.ctlParams[cat]: - sys = self.getSystemValue(param) - self.ctlParams[cat][param] = sys + def reloadSystemValues(self, data): + for cat in self.ctlParams: + for param in self.ctlParams[cat]: + sys = self.getSystemValue(param) + self.ctlParams[cat][param] = sys
- def aliasToOriginal(self, string): - string = string.replace("*","") - if string in dict(self.aliasReverse): - return dict(self.aliasReverse)[string] - return string + def aliasToOriginal(self, string): + string = string.replace("*", "") + if string in dict(self.aliasReverse): + return dict(self.aliasReverse)[string] + return string
- def originalToAlias(self, string): - tmpString = string - for src,dst in self.aliasList: - tmpString = tmpString.replace(src,dst) - if string != tmpString: - self.aliasReverse[len(self.aliasReverse):] = [(tmpString,string)] - return tmpString - return string + def originalToAlias(self, string): + tmpString = string + for src, dst in self.aliasList: + tmpString = tmpString.replace(src, dst) + if string != tmpString: + self.aliasReverse[len(self.aliasReverse):] = [(tmpString, string)] + return tmpString + return string
- def saveSnapshot(self,data): - tempconfig = configparser.RawConfigParser() - tempconfig.readfp(io.BytesIO(self.cache)) - snapcat = tempconfig.items('categories') - out = {} - cats = {} - for opt,val in snapcat: - for index in range(len(data[val])): - data[val][index]['label'] = self.aliasToOriginal(data[val][index]['label']) - out[data[val][index]['label']] = data[val][index]['value'] - for opt,val in snapcat: - snapcontPacked = tempconfig.items(opt) - snapcont = [] - for index in range(len(snapcontPacked)): - if self.isFnString(snapcontPacked[index][0]): - expanded = self.getFilesByFN("/proc/sys",self.ConfigPathToFileName(snapcontPacked[index][0])) - for index2 in range(len(expanded)): - expandedData = (self.FileNameToConfigPath(expanded[index2]),snapcontPacked[index][1]) - snapcont.append(expandedData) - else: - snapcont.append(snapcontPacked[index]) - for iopt,ival in snapcont: - if ival == '': - tempconfig.set(opt, iopt, out[iopt]) - elif ival == ',,': - tempconfig.set(opt, iopt, ',,' + out[iopt]) - else: - reival = ival - pos = [reival.start() for reival in re.finditer(',', reival)] - if len(pos) == 2: - ival = ival[0:pos[1]+1] - tempconfig.set(opt, iopt, ival + out[iopt]) - else: - tempconfig.set(opt, iopt, out[iopt]) - if 'lastfile' in self.config: - self.name = self.config['lastfile'].replace('.conf', '') - else: - self.name = 'snapshot' - snapFileName = self.config['root'] + self.name + strftime("-%Y-%m-%d-%H:%M:%S", localtime()) + '.conf' - try: - with open(snapFileName , 'w') as configfile: - tempconfig.write(configfile) - except IOError: - print(_("Cant save snapshot")) - return snapFileName + def saveSnapshot(self, data): + tempconfig = configparser.RawConfigParser() + tempconfig.readfp(io.BytesIO(self.cache)) + snapcat = tempconfig.items('categories') + out = {} + for opt, val in snapcat: + for index in range(len(data[val])): + data[val][index]['label'] = self.aliasToOriginal(data[val][index]['label']) + out[data[val][index]['label']] = data[val][index]['value'] + for opt, val in snapcat: + snapcontPacked = tempconfig.items(opt) + snapcont = [] + for index in range(len(snapcontPacked)): + if self.isFnString(snapcontPacked[index][0]): + expanded = self.getFilesByFN("/proc/sys", \ + self.ConfigPathToFileName(snapcontPacked[index][0])) + for index2 in range(len(expanded)): + expandedData = (self.FileNameToConfigPath(expanded[index2]), snapcontPacked[index][1]) + snapcont.append(expandedData) + else: + snapcont.append(snapcontPacked[index]) + for iopt, ival in snapcont: + if ival == '': + tempconfig.set(opt, iopt, out[iopt]) + elif ival == ',,': + tempconfig.set(opt, iopt, ',,' + out[iopt]) + else: + reival = ival + pos = [reival.start() for reival in re.finditer(',', reival)] + if len(pos) == 2: + ival = ival[0:pos[1]+1] + tempconfig.set(opt, iopt, ival + out[iopt]) + else: + tempconfig.set(opt, iopt, out[iopt]) + if 'lastfile' in self.config: + self.name = self.config['lastfile'].replace('.conf', '') + else: + self.name = 'snapshot' + snapFileName = self.config['root'] + self.name \ + + strftime("-%Y-%m-%d-%H:%M:%S", localtime()) + '.conf' + try: + with open(snapFileName, 'w') as configfile: + tempconfig.write(configfile) + except IOError: + print(_("Cant save snapshot")) + return snapFileName
- def checkConfigFile(self, filename): - self.empty = True - try: - msgStack = '' - if not os.path.exists(filename): - msgStack = "%s%s %s %s" % (msgStack, _("Error: File"), filename, _("not found\n")) - return msgStack - self.checkParser = configparser.RawConfigParser() - self.checkParser.read(filename) - for option,value in self.checkParser.items('categories'): - if not self.checkParser.items(option): - msgStack = "%s%s %s\n" % (msgStack, _("Error: Enabled section is empty:"), option) - return msgStack - current = self.checkParser.items(option) - for opt,val in current: - if not os.path.exists("/proc/sys/" + self.ConfigPathToFileName(opt)) and len(self.getFilesByFN("/proc/sys/", self.ConfigPathToFileName(opt))) == 0: - msgStack = "%s%s%s\n" % (msgStack, _("Warning: File not found: /proc/sys/"), opt) - self.empty = False - if self.empty: - msgStack = "%s%s" % (msgStack, _("Empty config File")) - return msgStack - except (configparser.Error, IOError) as e: - return "Error {0}".format(str(e)) + def checkConfigFile(self, filename): + self.empty = True + try: + msgStack = '' + if not os.path.exists(filename): + msgStack = "%s%s %s %s" % (msgStack, _("Error: File"), filename, _("not found\n")) + return msgStack + self.checkParser = configparser.RawConfigParser() + self.checkParser.read(filename) + for option, value in self.checkParser.items('categories'): + if not self.checkParser.items(option): + msgStack = "%s%s %s\n" % (msgStack, _("Error: Enabled section is empty:"), option) + return msgStack + current = self.checkParser.items(option) + for opt, val in current: + if not os.path.exists("/proc/sys/" + self.ConfigPathToFileName(opt)) and len(self.getFilesByFN("/proc/sys/", self.ConfigPathToFileName(opt))) == 0: + msgStack = "%s%s%s\n" % (msgStack, _("Warning: File not found: /proc/sys/"), opt) + self.empty = False + if self.empty: + msgStack = "%s%s" % (msgStack, _("Empty config File")) + return msgStack + except (configparser.Error, IOError) as e: + return "Error {0}".format(str(e))
- def fixConfigFile(self, filename): - try: - self.checkParser = configparser.RawConfigParser() - self.checkParser.read(filename) - for option,value in self.checkParser.items('categories'): - if not self.checkParser.items(option): - self.checkParser.remove_option('categories', option) - self.checkParser.set('categories', '#' + option, value) - current = self.checkParser.items(option) - for opt,val in current: - if not os.path.exists("/proc/sys/" + self.ConfigPathToFileName(opt)) and len(self.getFilesByFN("/proc/sys/", self.ConfigPathToFileName(opt))) == 0: - self.checkParser.remove_option(option, opt) - self.checkParser.set(option, '#' + opt, val) - except (configparser.Error, IOError) as e: - return "Error {0}".format(str(e)) - with open(filename, 'w') as configfile: - self.checkParser.write(configfile) + def fixConfigFile(self, filename): + try: + self.checkParser = configparser.RawConfigParser() + self.checkParser.read(filename) + for option, value in self.checkParser.items('categories'): + if not self.checkParser.items(option): + self.checkParser.remove_option('categories', option) + self.checkParser.set('categories', '#' + option, value) + current = self.checkParser.items(option) + for opt, val in current: + if not os.path.exists("/proc/sys/" + self.ConfigPathToFileName(opt)) and len(self.getFilesByFN("/proc/sys/", self.ConfigPathToFileName(opt))) == 0: + self.checkParser.remove_option(option, opt) + self.checkParser.set(option, '#' + opt, val) + except (configparser.Error, IOError) as e: + return "Error {0}".format(str(e)) + with open(filename, 'w') as configfile: + self.checkParser.write(configfile)
- def isFnString(self, string): - regMatch = ['[', '*', '?'] - for char in regMatch: - if char in string: - return True - return False + def isFnString(self, string): + regMatch = ['[', '*', '?'] + for char in regMatch: + if char in string: + return True + return False
- def getFilesByFN(self, troot, fn): - mylist = {} - for root, dirs, files in os.walk(troot, topdown=True): - for cfile in files: - if fnmatch.fnmatch(root + "/" + cfile, "*" + fn): - mylist[len(mylist)] = root.replace(troot,"")[1:] + "/" + cfile - return mylist + def getFilesByFN(self, troot, fn): + mylist = {} + for root, dirs, files in os.walk(troot, topdown=True): + for cfile in files: + if fnmatch.fnmatch(root + "/" + cfile, "*" + fn): + mylist[len(mylist)] = root.replace(troot, "")[1:] + "/" + cfile + return mylist
Fix some minor white space problems
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tuna/gui/__init__.py b/tuna/gui/__init__.py index ba4057261e02..ad1191c13d8d 100755 --- a/tuna/gui/__init__.py +++ b/tuna/gui/__init__.py @@ -9,8 +9,8 @@ __license__ = "GPLv2 License" DND_TARGET_STRING = 0 DND_TARGET_ROOTWIN = 1
-DND_TARGETS = [ ('STRING', 0, DND_TARGET_STRING), - ('text/plain', 0, DND_TARGET_STRING), - ('application/x-rootwin-drop', 0, DND_TARGET_ROOTWIN) ] +DND_TARGETS = [('STRING', 0, DND_TARGET_STRING), + ('text/plain', 0, DND_TARGET_STRING), + ('application/x-rootwin-drop', 0, DND_TARGET_ROOTWIN)]
from .util import *
- Fix comparisons with None, != None should be is not None for example - Remove unnecessary imports - Remove unused variable in except statement
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/commonview.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/tuna/gui/commonview.py b/tuna/gui/commonview.py index 861a55b1b48b..59ca24405b1d 100644 --- a/tuna/gui/commonview.py +++ b/tuna/gui/commonview.py @@ -1,6 +1,5 @@ -import gi from gi.repository import Gtk -from tuna import tuna, gui +from tuna import tuna
class commonview: def updateCommonView(self): @@ -43,7 +42,7 @@ class commonview: if val[0] == self.config.cacheFileName: try: self.configFileCombo.handler_block_by_func(self.on_profileSelector_changed) - except TypeError as e: + except TypeError: pass self.configFileCombo.set_active(val.path[0]) try: @@ -255,11 +254,10 @@ class commonview: def get_current_combo_selection(self): combo_iter = self.configFileCombo.get_active_iter() combo_row = self.configFileCombo.get_active() - if combo_iter != None: + if combo_iter is not None: model = self.configFileCombo.get_model() return (combo_row, model[combo_iter][0]) - else: - return (-1, "ERROR") + return (-1, "ERROR")
def set_current_combo_selection(self, string): cur = self.configFileCombo.get_model()
- Fix some white space issues. - fix box.pack_start to add a paramter - comment out some lines in around the fame.size_request to get things working. May require some more exact fixes later.
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/cpuview.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py index bcb846773471..4915ce4e5f1d 100755 --- a/tuna/gui/cpuview.py +++ b/tuna/gui/cpuview.py @@ -3,21 +3,21 @@
from functools import reduce
+import math import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk +from gi.repository import Gdk from gi.repository import GObject -import math -import os -import procfs import schedutils +import procfs from tuna import sysfs, tuna, gui
def set_affinity_warning(tid, affinity): - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, - Gtk.ButtonsType.OK, + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, \ + Gtk.ButtonsType.OK, \ _("Couldn't change the affinity of %(tid)d to %(affinity)s!") % \ {"tid": tid, "affinity": affinity}) dialog.run() @@ -82,7 +82,7 @@ class cpu_socket_frame(Gtk.Frame): except: # CellRendererProgress needs pygtk2 >= 2.6 column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererText(), - text=self.COL_USAGE) + text=self.COL_USAGE) self.treeview.append_column(column) self.add(self.treeview) self.treeview.enable_model_drag_dest(gui.DND_TARGETS, @@ -96,8 +96,8 @@ class cpu_socket_frame(Gtk.Frame): self.creator.procview), "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview),}
- self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, - Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + #self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, + # Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.connect("drag_data_received", self.on_frame_drag_data_received_data)
@@ -276,7 +276,7 @@ class cpuview: for socket_id in socket_ids: frame = cpu_socket_frame(socket_id, self.cpus.sockets[str(socket_id)], self) - box.pack_start(frame, False, False) + box.pack_start(frame, False, False, 0) self.socket_frames[socket_id] = frame if self.nr_sockets > 1: if column == columns: @@ -294,11 +294,14 @@ class cpuview: self.previous_pid_affinities = None self.previous_irq_affinities = None
- req = frame.size_request() + #req = frame.size_request() + req = frame.get_preferred_size() # FIXME: what is the slack we have # to add to every row and column? - width = req[0] + 16 - height = req[1] + 20 + #width = req[0] + 16 + width = 16 + #height = req[1] + 20 + height = 20 if self.nr_sockets > 1: width *= columns height *= rows @@ -341,7 +344,7 @@ class cpuview: affinities = self.previous_irq_affinities for irq in list(affinities.keys()): tuna.set_irq_affinity(int(irq), - procfs.hexbitmask(affinities[irq], + procfs.hexbitmask(affinities[irq], \ self.cpus.nr_cpus))
self.previous_pid_affinities = None
Fix style problems recommened by PEP8
Signed-off-by: John Kacur jkacur@redhat.com --- tuna-cmd.py | 205 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 122 insertions(+), 83 deletions(-)
diff --git a/tuna-cmd.py b/tuna-cmd.py index 99fe355baa77..0388ecb87290 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -43,51 +43,63 @@ ps = None irqs = None version = "0.14.1"
+ def usage(): print(_('Usage: tuna [OPTIONS]')) fmt = '\t%-40s %s' print(fmt % ('-h, --help', _('Give this help list'))) - print(fmt % ('-a, --config_file_apply=profilename', _('Apply changes described in profile'))) - print(fmt % ('-l, --config_file_list', _('List preloaded profiles'))) + print(fmt % ('-a, --config_file_apply=profilename', + _('Apply changes described in profile'))) + print(fmt % ('-l, --config_file_list', + _('List preloaded profiles'))) print(fmt % ('-g, --gui', _('Start the GUI'))) - print(fmt % ('-G, --cgroup', _('Display the processes with the type of cgroups they are in'))) - print(fmt % ('-c, --cpus=' + _('CPU-LIST'), _('%(cpulist)s affected by commands') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-C, --affect_children', _('Operation will affect children threads'))) - print(fmt % ('-f, --filter', _('Display filter the selected entities'))) - print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-I, --include', _('Allow all threads to run on %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-K, --no_kthreads', _('Operations will not affect kernel threads'))) - print(fmt % ('-m, --move', _('Move selected entities to %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-N, --nohz_full', _('CPUs in nohz_full= kernel command line will be affected by operations'))) + print(fmt % ('-G, --cgroup', + _('Display the processes with the type of cgroups they are in'))) + print(fmt % ('-c, --cpus=' + _('CPU-LIST'), _('%(cpulist)s affected by commands') % + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-C, --affect_children', + _('Operation will affect children threads'))) + print(fmt % ('-f, --filter', + _('Display filter the selected entities'))) + print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-I, --include', _('Allow all threads to run on %(cpulist)s') % + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-K, --no_kthreads', + _('Operations will not affect kernel threads'))) + print(fmt % ('-m, --move', _('Move selected entities to %(cpulist)s') % + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-N, --nohz_full', + _('CPUs in nohz_full= kernel command line will be affected by operations'))) if have_inet_diag: - print(fmt % ('-n, --show_sockets', _('Show network sockets in use by threads'))) + print(fmt % ('-n, --show_sockets', + _('Show network sockets in use by threads'))) print(fmt % ('-p, --priority=[' + - _('POLICY') + ':]' + - _('RTPRIO'), _('Set thread scheduler tunables: %(policy)s and %(rtprio)s') % \ - {"policy": _('POLICY'), "rtprio": _('RTPRIO')})) + _('POLICY') + ':]' + + _('RTPRIO'), _('Set thread scheduler tunables: %(policy)s and %(rtprio)s') % + {"policy": _('POLICY'), "rtprio": _('RTPRIO')})) print(fmt % ('-P, --show_threads', _('Show thread list'))) print(fmt % ('-Q, --show_irqs', _('Show IRQ list'))) print(fmt % ('-q, --irqs=' + _('IRQ-LIST'), _('%(irqlist)s affected by commands') % - {"irqlist": _('IRQ-LIST')})) - print(fmt % ('-r, --run=' + _('COMMAND'), _('fork a new process and run the %(command)s') % \ - {"command": _('COMMAND')})) - print(fmt % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % \ - {"filename": _('FILENAME')})) + {"irqlist": _('IRQ-LIST')})) + print(fmt % ('-r, --run=' + _('COMMAND'), _('fork a new process and run the %(command)s') % + {"command": _('COMMAND')})) + print(fmt % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % + {"filename": _('FILENAME')})) print(fmt % ('-S, --sockets=' + - _('CPU-SOCKET-LIST'), _('%(cpusocketlist)s affected by commands') % \ - {"cpusocketlist": _('CPU-SOCKET-LIST')})) + _('CPU-SOCKET-LIST'), _('%(cpusocketlist)s affected by commands') % + {"cpusocketlist": _('CPU-SOCKET-LIST')})) print(fmt % ('-t, --threads=' + - _('THREAD-LIST'), _('%(threadlist)s affected by commands') % \ - {"threadlist": _('THREAD-LIST')})) - print(fmt % ('-U, --no_uthreads', _('Operations will not affect user threads'))) + _('THREAD-LIST'), _('%(threadlist)s affected by commands') % + {"threadlist": _('THREAD-LIST')})) + print(fmt % ('-U, --no_uthreads', + _('Operations will not affect user threads'))) print(fmt % ('-v, --version', _('Show version'))) - print(fmt % ('-W, --what_is', _('Provides help about selected entities'))) - print(fmt % ('-x, --spread', _('Spread selected entities over %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) + print(fmt % ('-W, --what_is', + _('Provides help about selected entities'))) + print(fmt % ('-x, --spread', _('Spread selected entities over %(cpulist)s') % + {"cpulist": _('CPU-LIST')})) +
def get_nr_cpus(): global nr_cpus @@ -96,8 +108,10 @@ def get_nr_cpus(): nr_cpus = procfs.cpuinfo().nr_cpus return nr_cpus
+ nics = None
+ def get_nics(): global nics if nics: @@ -105,6 +119,7 @@ def get_nics(): nics = ethtool.get_active_devices() return nics
+ def thread_help(tid): global ps if not ps: @@ -119,6 +134,7 @@ def thread_help(tid): help, title = tuna.kthread_help_plain_text(tid, cmdline) print("%s\n\n%s" % (title, _(help)))
+ def save(cpu_list, thread_list, filename): kthreads = tuna.get_kthread_sched_tunings() for name in list(kthreads.keys()): @@ -128,31 +144,34 @@ def save(cpu_list, thread_list, filename): del kthreads[name] tuna.generate_rtgroups(filename, kthreads, get_nr_cpus())
+ def ps_show_header(has_ctxt_switch_info, cgroups=False): - print("%7s %6s %5s %7s %s" % \ - (" ", " ", " ", _("thread"), - has_ctxt_switch_info and "ctxt_switches" or "")) - print("%7s %6s %5s %7s%s %15s" % ("pid", "SCHED_", "rtpri", "affinity", \ - has_ctxt_switch_info and " %9s %12s" % ("voluntary", "nonvoluntary") \ - or "", "cmd"), end=' ') + print("%7s %6s %5s %7s %s" % + (" ", " ", " ", _("thread"), + has_ctxt_switch_info and "ctxt_switches" or "")) + print("%7s %6s %5s %7s%s %15s" % ("pid", "SCHED_", "rtpri", "affinity", + has_ctxt_switch_info and " %9s %12s" % ( + "voluntary", "nonvoluntary") + or "", "cmd"), end=' ') if cgroups: print(" %7s" % ("cgroup")) else: print("")
+ def ps_show_sockets(pid, ps, inodes, inode_re, indent=0): header_printed = False dirname = "/proc/%s/fd" % pid try: filenames = os.listdir(dirname) - except: # Process died + except: # Process died return sindent = " " * indent for filename in filenames: pathname = os.path.join(dirname, filename) try: linkto = os.readlink(pathname) - except: # Process died + except: # Process died continue inode_match = inode_re.match(linkto) if not inode_match: @@ -161,16 +180,17 @@ def ps_show_sockets(pid, ps, inodes, inode_re, indent=0): if inode not in inodes: continue if not header_printed: - print("%s%-10s %-6s %-6s %15s:%-5s %15s:%-5s" % \ - (sindent, "State", "Recv-Q", "Send-Q", - "Local Address", "Port", - "Peer Address", "Port")) + print("%s%-10s %-6s %-6s %15s:%-5s %15s:%-5s" % + (sindent, "State", "Recv-Q", "Send-Q", + "Local Address", "Port", + "Peer Address", "Port")) header_printed = True s = inodes[inode] - print("%s%-10s %-6d %-6d %15s:%-5d %15s:%-5d" % \ - (sindent, s.state(), - s.receive_queue(), s.write_queue(), - s.saddr(), s.sport(), s.daddr(), s.dport())) + print("%s%-10s %-6d %-6d %15s:%-5d %15s:%-5d" % + (sindent, s.state(), + s.receive_queue(), s.write_queue(), + s.saddr(), s.sport(), s.daddr(), s.dport())) +
def format_affinity(affinity): if len(affinity) <= 4: @@ -178,12 +198,13 @@ def format_affinity(affinity):
return ",".join(str(hex(a)) for a in procfs.hexbitmask(affinity, get_nr_cpus()))
+ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups): global irqs try: affinity = format_affinity(schedutils.get_affinity(pid)) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError if e.args[0] == errno.ESRCH: return raise e @@ -201,7 +222,8 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, users = irqs[tuna.irq_thread_number(cmd)]["users"] for u in users: if u in get_nics(): - users[users.index(u)] = "%s(%s)" % (u, ethtool.get_module(u)) + users[users.index(u)] = "%s(%s)" % ( + u, ethtool.get_module(u)) users = ",".join(users) else: u = cmd[cmd.find('-') + 1:] @@ -212,8 +234,10 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes,
ctxt_switch_info = "" if has_ctxt_switch_info: - voluntary_ctxt_switches = int(ps[pid]["status"]["voluntary_ctxt_switches"]) - nonvoluntary_ctxt_switches = int(ps[pid]["status"]["nonvoluntary_ctxt_switches"]) + voluntary_ctxt_switches = int( + ps[pid]["status"]["voluntary_ctxt_switches"]) + nonvoluntary_ctxt_switches = int( + ps[pid]["status"]["nonvoluntary_ctxt_switches"]) ctxt_switch_info = " %9d %12s" % (voluntary_ctxt_switches, nonvoluntary_ctxt_switches)
@@ -236,9 +260,9 @@ def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, sock_inodes, sock_inode_re, cgroups)
-def ps_show(ps, affect_children, thread_list, cpu_list, \ - irq_list_numbers, show_uthreads, show_kthreads, \ - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups): +def ps_show(ps, affect_children, thread_list, cpu_list, + irq_list_numbers, show_uthreads, show_kthreads, + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups):
ps_list = [] for pid in list(ps.keys()): @@ -265,7 +289,7 @@ def ps_show(ps, affect_children, thread_list, cpu_list, \ continue try: affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError if e.args[0] == errno.ESRCH: continue raise e @@ -279,6 +303,7 @@ def ps_show(ps, affect_children, thread_list, cpu_list, \ ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups)
+ def load_socktype(socktype, inodes): idiag = inet_diag.create(socktype=socktype) while True: @@ -288,12 +313,14 @@ def load_socktype(socktype, inodes): break inodes[s.inode()] = s
+ def load_sockets(): inodes = {} for socktype in (inet_diag.TCPDIAG_GETSOCK, inet_diag.DCCPDIAG_GETSOCK): load_socktype(socktype, inodes) return inodes
+ def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, affect_children, show_sockets, cgroups): ps = procfs.pidstats() @@ -310,13 +337,14 @@ def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, try: if sys.stdout.isatty(): ps_show_header(has_ctxt_switch_info, cgroups) - ps_show(ps, affect_children, thread_list, \ - cpu_list, irq_list, show_uthreads, show_kthreads, \ - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups) + ps_show(ps, affect_children, thread_list, + cpu_list, irq_list, show_uthreads, show_kthreads, + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups) except IOError: # 'tuna -P | head' for instance pass
+ def find_drivers_by_users(users): nics = get_nics() drivers = [] @@ -333,6 +361,7 @@ def find_drivers_by_users(users):
return drivers
+ def show_irqs(irq_list, cpu_list): global irqs if not irqs: @@ -365,6 +394,7 @@ def show_irqs(irq_list, cpu_list): else: print()
+ def do_list_op(op, current_list, op_list): if not current_list: current_list = [] @@ -374,10 +404,11 @@ def do_list_op(op, current_list, op_list): return list(set(current_list) - set(op_list)) return list(set(op_list))
+ def thread_mapper(s): global ps try: - return [int(s),] + return [int(s), ] except: pass
@@ -388,10 +419,11 @@ def thread_mapper(s): except: return ps.find_by_name(s)
+ def irq_mapper(s): global irqs try: - return [int(s),] + return [int(s), ] except: pass if not irqs: @@ -407,6 +439,7 @@ def irq_mapper(s):
return irq_list
+ def pick_op(argument): if argument == "": return (None, argument) @@ -414,6 +447,7 @@ def pick_op(argument): return (argument[0], argument[1:]) return (None, argument)
+ def i18n_init(): (app, localedir) = ('tuna', '/usr/share/locale') locale.setlocale(locale.LC_ALL, '') @@ -421,6 +455,7 @@ def i18n_init(): gettext.textdomain(app) gettext.install(app, localedir)
+ def apply_config(filename): from tuna.config import Config config = Config() @@ -444,6 +479,7 @@ def apply_config(filename): ctrl = ctrl + 1 config.applyChanges(values)
+ def list_config(): from tuna.config import Config config = Config() @@ -452,19 +488,20 @@ def list_config(): print(value) sys.exit(1)
+ def main(): global ps
i18n_init() try: short = "a:c:CfgGhiIKlmNp:PQq:r:s:S:t:UvWx" - long = ["cpus=", "affect_children", "filter", "gui", "help", \ - "isolate", "include", "no_kthreads", "move", "nohz_full", \ - "show_sockets", "priority=", "show_threads", \ - "show_irqs", "irqs=", \ - "save=", "sockets=", "threads=", "no_uthreads", \ - "version", "what_is", "spread", "cgroup", "config_file_apply=", \ - "config_file_list=", "run="] + long = ["cpus=", "affect_children", "filter", "gui", "help", + "isolate", "include", "no_kthreads", "move", "nohz_full", + "show_sockets", "priority=", "show_threads", + "show_irqs", "irqs=", + "save=", "sockets=", "threads=", "no_uthreads", + "version", "what_is", "spread", "cgroup", "config_file_apply=", + "config_file_list=", "run="] if have_inet_diag: short += "n" int.append("show_sockets") @@ -510,8 +547,8 @@ def main(): try: cpu_list = tuna.nohz_full_list() except: - print("tuna: --nohz_full " + \ - _(" needs nohz_full=cpulist on the kernel command line")) + print("tuna: --nohz_full " + + _(" needs nohz_full=cpulist on the kernel command line")) sys.exit(2) elif o in ("-C", "--affect_children"): affect_children = True @@ -524,8 +561,8 @@ def main(): thread_list_str = '' else: (op, a) = pick_op(a) - op_list = reduce(lambda i, j: i + j, \ - list(map(thread_mapper, a.split(",")))) + op_list = reduce(lambda i, j: i + j, + list(map(thread_mapper, a.split(",")))) op_list = list(set(op_list)) thread_list = do_list_op(op, thread_list, op_list) # Check if a process name was especified and no @@ -570,8 +607,8 @@ def main(): if not thread_list and not irq_list: if thread_list_str or irq_list_str: continue - do_ps(thread_list, cpu_list, irq_list, uthreads, \ - kthreads, affect_children, show_sockets, cgroups) + do_ps(thread_list, cpu_list, irq_list, uthreads, + kthreads, affect_children, show_sockets, cgroups) elif o in ("-Q", "--show_irqs"): # If the user specified IRQ names that weren't # resolved to IRQs, don't show all IRQs. @@ -608,19 +645,20 @@ def main(): op_list = [] for socket in sockets: if socket not in cpu_info.sockets: - print("tuna: %s" % \ - (_("invalid socket %(socket)s sockets available: %(available)s") % \ - {"socket": socket, - "available": ",".join(list(cpu_info.sockets.keys()))})) + print("tuna: %s" % + (_("invalid socket %(socket)s sockets available: %(available)s") % + {"socket": socket, + "available": ",".join(list(cpu_info.sockets.keys()))})) sys.exit(2) - op_list += [int(cpu.name[3:]) for cpu in cpu_info.sockets[socket]] + op_list += [int(cpu.name[3:]) + for cpu in cpu_info.sockets[socket]] cpu_list = do_list_op(op, cpu_list, op_list) elif o in ("-K", "--no_kthreads"): kthreads = False elif o in ("-q", "--irqs"): (op, a) = pick_op(a) - op_list = reduce(lambda i, j: i + j, \ - list(map(irq_mapper, list(set(a.split(",")))))) + op_list = reduce(lambda i, j: i + j, + list(map(irq_mapper, list(set(a.split(",")))))) irq_list = do_list_op(op, irq_list, op_list) # See comment above about thread_list_str if not op_list and isinstance(a, type('')): @@ -664,8 +702,8 @@ def main(): # the command first, and then get the list of pids, tuna.run_command(a, policy, rtprio, cpu_list)
- op_list = reduce(lambda i, j: i + j, \ - list(map(thread_mapper, a.split(",")))) + op_list = reduce(lambda i, j: i + j, + list(map(thread_mapper, a.split(",")))) op_list = list(set(op_list)) thread_list = do_list_op(op, thread_list, op_list)
@@ -705,5 +743,6 @@ def main(): except KeyboardInterrupt: pass
+ if __name__ == '__main__': main()
Fix spacing and other style problems in oscilloscope.py
Signed-off-by: John Kacur jkacur@redhat.com --- oscilloscope-cmd.py | 141 +++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 67 deletions(-)
diff --git a/oscilloscope-cmd.py b/oscilloscope-cmd.py index 753b879cbe57..3672b794b30c 100755 --- a/oscilloscope-cmd.py +++ b/oscilloscope-cmd.py @@ -20,81 +20,88 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA
-import getopt, sys, gtk +import getopt +import sys +import gi +from gi.repository import Gtk +gi.require_version("Gtk", "3.0") from tuna import oscilloscope
+ def usage(): - print('''Usage: oscilloscope [OPTIONS] - -h, --help Give this help list - -d, --delimiter=CHARACTER CHARACTER used as a delimiter [Default: :] - -f, --field=FIELD FIELD to plot [Default: 2] - -g, --geometry=GEOMETRY X geometry specification (see "X" man page) - -m, --max_value=MAX_VALUE MAX_VALUE for the scale - -M, --sample_multiplier=VALUE VALUE to multiply each sample - -n, --noscale Do not scale when a sample is > MAX_SCALE - -s, --nr_samples_on_screen=NR Show NR samples on screen - -S, --snapshot_samples=NR Take NR samples, a snapshot and exit - -u, --unit=TYPE Unit TYPE [Default: us] + print('''Usage: oscilloscope [OPTIONS] + -h, --help Give this help list + -d, --delimiter=CHARACTER CHARACTER used as a delimiter [Default: :] + -f, --field=FIELD FIELD to plot [Default: 2] + -g, --geometry=GEOMETRY X geometry specification (see "X" man page) + -m, --max_value=MAX_VALUE MAX_VALUE for the scale + -M, --sample_multiplier=VALUE VALUE to multiply each sample + -n, --noscale Do not scale when a sample is > MAX_SCALE + -s, --nr_samples_on_screen=NR Show NR samples on screen + -S, --snapshot_samples=NR Take NR samples, a snapshot and exit + -u, --unit=TYPE Unit TYPE [Default: us] ''')
+ def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], - "d:f:g:hM:m:ns:S:u:", - ("geometry=", - "help", "max_value=", - "sample_multiplier=", - "noscale", - "nr_samples_on_screen=", - "snapshot_samples=", - "unit=")) - except getopt.GetoptError as err: - usage() - print(str(err)) - sys.exit(2) + try: + opts, args = getopt.getopt(sys.argv[1:], + "d:f:g:hM:m:ns:S:u:", + ("geometry=", + "help", "max_value=", + "sample_multiplier=", + "noscale", + "nr_samples_on_screen=", + "snapshot_samples=", + "unit=")) + except getopt.GetoptError as err: + usage() + print(str(err)) + sys.exit(2) + + max_value = 250 + sample_multiplier = 1 + snapshot_samples = 0 + delimiter = ':' + field = 2 + ylabel = "Latency" + unitlabel = "us" + geometry = None + scale = True + nr_samples_on_screen = 250
- max_value = 250 - sample_multiplier = 1 - snapshot_samples = 0 - delimiter = ':' - field = 2 - ylabel = "Latency" - unitlabel = "us" - geometry = None - scale = True - nr_samples_on_screen = 250 + for o, a in opts: + if o in ("-d", "--delimiter"): + delimiter = a + elif o in ("-f", "--field"): + field = int(a) + elif o in ("-g", "--geometry"): + geometry = a + elif o in ("-h", "--help"): + usage() + return + elif o in ("-m", "--max_value"): + max_value = int(a) + elif o in ("-M", "--sample_multiplier"): + sample_multiplier = float(a) + elif o in ("-n", "--noscale"): + scale = False + elif o in ("-s", "--nr_samples_on_screen"): + nr_samples_on_screen = int(a) + elif o in ("-S", "--snapshot_samples"): + snapshot_samples = int(a) + elif o in ("-u", "--unit"): + unitlabel = a
- for o, a in opts: - if o in ("-d", "--delimiter"): - delimiter = a - elif o in ("-f", "--field"): - field = int(a) - elif o in ("-g", "--geometry"): - geometry = a - elif o in ("-h", "--help"): - usage() - return - elif o in ("-m", "--max_value"): - max_value = int(a) - elif o in ("-M", "--sample_multiplier"): - sample_multiplier = float(a) - elif o in ("-n", "--noscale"): - scale = False - elif o in ("-s", "--nr_samples_on_screen"): - nr_samples_on_screen = int(a) - elif o in ("-S", "--snapshot_samples"): - snapshot_samples = int(a) - elif o in ("-u", "--unit"): - unitlabel = a + o = oscilloscope.cyclictestoscope(max_value, snapshot_samples, + nr_samples_on_screen=nr_samples_on_screen, + delimiter=delimiter, field=field, + ylabel="%s (%s)" % (ylabel, unitlabel), + geometry=geometry, scale=scale, + sample_multiplier=sample_multiplier) + o.run() + Gtk.main()
- o = oscilloscope.cyclictestoscope(max_value, snapshot_samples, - nr_samples_on_screen = nr_samples_on_screen, - delimiter = delimiter, field = field, - ylabel = "%s (%s)" % (ylabel, unitlabel), - geometry = geometry, scale = scale, - sample_multiplier = sample_multiplier) - o.run() - gtk.main()
if __name__ == '__main__': - main() + main()
Port file to Gtk-3.0 Fix many style problems in config.py
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/config.py | 119 +++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 48 deletions(-)
diff --git a/tuna/config.py b/tuna/config.py index 6c7e759f5937..03dc4790e55d 100644 --- a/tuna/config.py +++ b/tuna/config.py @@ -10,8 +10,9 @@ from subprocess import Popen, PIPE, STDOUT, call from gi.repository import Gtk TUNED_CONF = """[sysctl]\n"""
+ class Config: - #init config, load /etc/tuna.conf (if not exist, create it) + # init config, load /etc/tuna.conf (if not exist, create it) def __init__(self): self.aliasList = [] self.aliasReverse = [] @@ -74,9 +75,9 @@ class Config: f.close() return 0 except (configparser.Error, IOError): - dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR,\ - Gtk.ButtonsType.OK, "%s\n%s" % \ - (_("Corruputed config file: "), _(self.config['root']+profileName))) + dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, "%s\n%s" % + (_("Corruputed config file: "), _(self.config['root']+profileName))) ret = dialog.run() dialog.destroy() return -1 @@ -104,7 +105,8 @@ class Config: ldir = "/etc/tuned/tuna" profile = self.currentActiveProfile() if profile[1]: - raise RuntimeError(_("Can't activate tuna profile in tuned daemon\n%s" % profile[1])) + raise RuntimeError( + _("Can't activate tuna profile in tuned daemon\n%s" % profile[1])) # return False - unreachable code here! if not os.path.exists(ldir): try: @@ -115,34 +117,35 @@ class Config: f.write(TUNED_CONF) for index in data: for ind in data[index]: - f.write(self.aliasToOriginal(data[index][ind]["label"])+"="+data[index][ind]["value"]+"\n") + f.write(self.aliasToOriginal( + data[index][ind]["label"])+"="+data[index][ind]["value"]+"\n") f.close() if profile[0] != "tuna": - dialog = Gtk.MessageDialog(None, \ - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "%s%s\n%s" % \ - (_("Current active profile is: "), - _(profile[0]), - _("Set new created profile as current in tuned daemon?"))) + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "%s%s\n%s" % + (_("Current active profile is: "), + _(profile[0]), + _("Set new created profile as current in tuned daemon?"))) ret = dialog.run() dialog.destroy() if ret == Gtk.ResponseType.YES: self.setCurrentActiveProfile() if self.currentActiveProfile()[0] != "tuna": - raise RuntimeError("%s %s\n%s" % \ - (_("Current active profile is: "), \ - _(profile), \ - _("Setting of new tuned profile failed! Check if tuned is installed and active"))) - dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL \ - | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ - Gtk.MessageType.INFO, Gtk.ButtonsType.OK, \ - _("Tuna profile is now active in tuned daemon.")) + raise RuntimeError("%s %s\n%s" % + (_("Current active profile is: "), + _(profile), + _("Setting of new tuned profile failed! Check if tuned is installed and active"))) + dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL + | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, + _("Tuna profile is now active in tuned daemon.")) ret = dialog.run() dialog.destroy() return True
- def loadTuna(self, profileName): + print(f'profileName = {profileName}') # REMOVE err = self.checkConfigFile(self.config['root'] + profileName) if err != '': raise RuntimeError(_("Config file contain errors: ") + _(err)) @@ -165,16 +168,18 @@ class Config: tempCfg = [] for index in range(len(oldTempCfg)): if self.isFnString(oldTempCfg[index][0]): - expanded = self.getFilesByFN("/proc/sys", \ - self.ConfigPathToFileName(oldTempCfg[index][0])) + expanded = self.getFilesByFN("/proc/sys", + self.ConfigPathToFileName(oldTempCfg[index][0])) for index2 in range(len(expanded)): - expandedData = (self.FileNameToConfigPath(expanded[index2]), oldTempCfg[index][1]) + expandedData = (self.FileNameToConfigPath( + expanded[index2]), oldTempCfg[index][1]) tempCfg.append(expandedData) else: tempCfg.append(oldTempCfg[index]) for opt, val in tempCfg: if val.find(',') != -1 and val.find(',', val.find(',')) != -1 and len(val.split(",")) > 2: - self.ctlGuiParams[self.catIndex][opt] = val.split(",") + self.ctlGuiParams[self.catIndex][opt] = val.split( + ",") val = self.ctlGuiParams[self.catIndex][opt][2] sys = self.getSystemValue(opt) if val == "" or val == sys: @@ -183,13 +188,17 @@ class Config: self.ctlParams[self.catIndex][opt] = val if opt in self.ctlGuiParams[self.catIndex]: if self.ctlGuiParams[self.catIndex][opt][0] == '': - self.ctlGuiParams[self.catIndex][opt][0] = int(int(self.ctlParams[self.catIndex][opt])/10) + self.ctlGuiParams[self.catIndex][opt][0] = int( + int(self.ctlParams[self.catIndex][opt])/10) else: - self.ctlGuiParams[self.catIndex][opt][0] = int(self.ctlGuiParams[self.catIndex][opt][0]) + self.ctlGuiParams[self.catIndex][opt][0] = int( + self.ctlGuiParams[self.catIndex][opt][0]) if self.ctlGuiParams[self.catIndex][opt][1] == '': - self.ctlGuiParams[self.catIndex][opt][1] = int(int(self.ctlParams[self.catIndex][opt])*10) + self.ctlGuiParams[self.catIndex][opt][1] = int( + int(self.ctlParams[self.catIndex][opt])*10) else: - self.ctlGuiParams[self.catIndex][opt][1] = int(self.ctlGuiParams[self.catIndex][opt][1]) + self.ctlGuiParams[self.catIndex][opt][1] = int( + self.ctlGuiParams[self.catIndex][opt][1]) self.categories[self.catIndex] = value self.categoriesOrigin[self.catIndex] = option self.catIndex = self.catIndex + 1 @@ -221,7 +230,8 @@ class Config: except IOError: pass if f is None: - raise RuntimeError(_("Cant open this config file: %s" % (self.config['root'] + profileName))) + raise RuntimeError(_("Cant open this config file: %s" % + (self.config['root'] + profileName))) self.cacheFileName = profileName self.cache = f.read() f.close() @@ -233,13 +243,15 @@ class Config: f.write(self.cache) f.close() except IOError: - print(_("Cant write to config file: %s" % (self.config['root'] + profileName))) + print(_("Cant write to config file: %s" % + (self.config['root'] + profileName)))
def loadDirect(self, data): try: f = open(self.config['root']+"temp-direct-load.conf", 'w') except IOError: - raise RuntimeError(_("Cant open this config file: %stemp-direct-load.conf" % (self.config['root']))) + raise RuntimeError( + _("Cant open this config file: %stemp-direct-load.conf" % (self.config['root']))) f.write(data) f.close() ret = self.load("temp-direct-load.conf") @@ -252,9 +264,11 @@ class Config: def getSystemValue(self, filename): filename = self.aliasToOriginal(filename) try: - buffer = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'r').read() + buffer = open( + "/proc/sys/" + self.ConfigPathToFileName(filename), 'r').read() except IOError: - print(_("Invalid item! file: /proc/sys/%s" %(self.ConfigPathToFileName(filename)))) + print(_("Invalid item! file: /proc/sys/%s" % + (self.ConfigPathToFileName(filename)))) return "" return buffer.strip()
@@ -267,15 +281,16 @@ class Config: fp = open("/proc/sys/" + self.ConfigPathToFileName(filename), 'w') fp.write(value) except IOError: - print("%s%s %s %s" % (_("Cant write to file! path: /proc/sys/"), \ - self.ConfigPathToFileName(filename), _("value:"), value)) + print("%s%s %s %s" % (_("Cant write to file! path: /proc/sys/"), + self.ConfigPathToFileName(filename), _("value:"), value)) return -1 return 0
def applyChanges(self, data): for cat in data: for itemId in data[cat]: - self.setSystemValue(data[cat][itemId]['label'], data[cat][itemId]['value']) + self.setSystemValue( + data[cat][itemId]['label'], data[cat][itemId]['value']) self.reloadSystemValues(data)
def reloadSystemValues(self, data): @@ -295,7 +310,8 @@ class Config: for src, dst in self.aliasList: tmpString = tmpString.replace(src, dst) if string != tmpString: - self.aliasReverse[len(self.aliasReverse):] = [(tmpString, string)] + self.aliasReverse[len(self.aliasReverse):] = [ + (tmpString, string)] return tmpString return string
@@ -306,17 +322,19 @@ class Config: out = {} for opt, val in snapcat: for index in range(len(data[val])): - data[val][index]['label'] = self.aliasToOriginal(data[val][index]['label']) + data[val][index]['label'] = self.aliasToOriginal( + data[val][index]['label']) out[data[val][index]['label']] = data[val][index]['value'] for opt, val in snapcat: snapcontPacked = tempconfig.items(opt) snapcont = [] for index in range(len(snapcontPacked)): if self.isFnString(snapcontPacked[index][0]): - expanded = self.getFilesByFN("/proc/sys", \ - self.ConfigPathToFileName(snapcontPacked[index][0])) + expanded = self.getFilesByFN("/proc/sys", + self.ConfigPathToFileName(snapcontPacked[index][0])) for index2 in range(len(expanded)): - expandedData = (self.FileNameToConfigPath(expanded[index2]), snapcontPacked[index][1]) + expandedData = (self.FileNameToConfigPath( + expanded[index2]), snapcontPacked[index][1]) snapcont.append(expandedData) else: snapcont.append(snapcontPacked[index]) @@ -327,7 +345,8 @@ class Config: tempconfig.set(opt, iopt, ',,' + out[iopt]) else: reival = ival - pos = [reival.start() for reival in re.finditer(',', reival)] + pos = [reival.start() + for reival in re.finditer(',', reival)] if len(pos) == 2: ival = ival[0:pos[1]+1] tempconfig.set(opt, iopt, ival + out[iopt]) @@ -338,7 +357,7 @@ class Config: else: self.name = 'snapshot' snapFileName = self.config['root'] + self.name \ - + strftime("-%Y-%m-%d-%H:%M:%S", localtime()) + '.conf' + + strftime("-%Y-%m-%d-%H:%M:%S", localtime()) + '.conf' try: with open(snapFileName, 'w') as configfile: tempconfig.write(configfile) @@ -351,18 +370,21 @@ class Config: try: msgStack = '' if not os.path.exists(filename): - msgStack = "%s%s %s %s" % (msgStack, _("Error: File"), filename, _("not found\n")) + msgStack = "%s%s %s %s" % (msgStack, _( + "Error: File"), filename, _("not found\n")) return msgStack self.checkParser = configparser.RawConfigParser() self.checkParser.read(filename) for option, value in self.checkParser.items('categories'): if not self.checkParser.items(option): - msgStack = "%s%s %s\n" % (msgStack, _("Error: Enabled section is empty:"), option) + msgStack = "%s%s %s\n" % (msgStack, _( + "Error: Enabled section is empty:"), option) return msgStack current = self.checkParser.items(option) for opt, val in current: if not os.path.exists("/proc/sys/" + self.ConfigPathToFileName(opt)) and len(self.getFilesByFN("/proc/sys/", self.ConfigPathToFileName(opt))) == 0: - msgStack = "%s%s%s\n" % (msgStack, _("Warning: File not found: /proc/sys/"), opt) + msgStack = "%s%s%s\n" % (msgStack, _( + "Warning: File not found: /proc/sys/"), opt) self.empty = False if self.empty: msgStack = "%s%s" % (msgStack, _("Empty config File")) @@ -400,5 +422,6 @@ class Config: for root, dirs, files in os.walk(troot, topdown=True): for cfile in files: if fnmatch.fnmatch(root + "/" + cfile, "*" + fn): - mylist[len(mylist)] = root.replace(troot, "")[1:] + "/" + cfile + mylist[len(mylist)] = root.replace( + troot, "")[1:] + "/" + cfile return mylist
Port to Gtk-3.0
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/irqview.py | 70 ++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 32 deletions(-)
diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py index e3a0c640bb2c..012bd9f5ec4f 100755 --- a/tuna/gui/irqview.py +++ b/tuna/gui/irqview.py @@ -1,5 +1,10 @@ # -*- python -*- # -*- coding: utf-8 -*- +from tuna import tuna, gui +import procfs +from gi.repository import Gdk +from gi.repository import Gtk +from gi.repository import GObject import os from functools import reduce import ethtool @@ -7,11 +12,7 @@ import schedutils
import gi gi.require_version("Gtk", "3.0") -from gi.repository import GObject -from gi.repository import Gtk
-import procfs -from tuna import tuna, gui
class irq_druid:
@@ -19,20 +20,22 @@ class irq_druid: self.irqs = irqs self.ps = ps self.irq = irq - self.window = Gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") - self.dialog = self.window.get_widget("set_irq_attributes") + self.window = Gtk.Builder(gladefile) + #self.window = Gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") + self.dialog = self.window.get_object("set_irq_attributes") pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.SMALL_TOOLBAR) self.dialog.set_icon(pixbuf) event_handlers = { - "on_irq_affinity_text_changed" : self.on_irq_affinity_text_changed, + "on_irq_affinity_text_changed": self.on_irq_affinity_text_changed, "on_sched_policy_combo_changed": self.on_sched_policy_combo_changed} - self.window.signal_autoconnect(event_handlers) + # self.window.signal_autoconnect(event_handlers) + self.window.connect_signals(event_handlers)
- self.sched_pri = self.window.get_widget("irq_pri_spinbutton") - self.sched_policy = self.window.get_widget("irq_policy_combobox") - self.affinity = self.window.get_widget("irq_affinity_text") - text = self.window.get_widget("irq_text") + self.sched_pri = self.window.get_object("irq_pri_spinbutton") + self.sched_policy = self.window.get_object("irq_policy_combobox") + self.affinity = self.window.get_object("irq_affinity_text") + text = self.window.get_object("irq_text")
users = tuna.get_irq_users(irqs, irq) self.affinity_text = tuna.get_irq_affinity_text(irqs, irq) @@ -46,13 +49,13 @@ class irq_druid: self.sched_policy.set_active(schedutils.get_scheduler(pid)) self.sched_pri.set_value(prio) text.set_markup( - "IRQ <b>%u</b> (PID <b>%u</b>), pri <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ + "IRQ <b>%u</b> (PID <b>%u</b>), pri <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % (irq, pid, prio, self.affinity_text, ",".join(users))) else: self.sched_pri.set_sensitive(False) self.sched_policy.set_sensitive(False) text.set_markup( - "IRQ <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % \ + "IRQ <b>%u</b>, aff <b>%s</b>, <tt><b>%s</b></tt>" % (irq, self.affinity_text, ",".join(users))) self.affinity.set_text(self.affinity_text)
@@ -116,6 +119,7 @@ class irq_druid: self.dialog.destroy() return changed
+ class irqview:
nr_columns = 7 @@ -144,11 +148,13 @@ class irqview: self.COL_EVENTS, self.COL_USERS) = list(range(self.nr_columns)) self.columns = (gui.list_store_column(_("IRQ")), - gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), - gui.list_store_column(_("Events")), - gui.list_store_column(_("Users"), GObject.TYPE_STRING)) + gui.list_store_column( + _("Affinity"), GObject.TYPE_STRING), + gui.list_store_column(_("Events")), + gui.list_store_column(_("Users"), GObject.TYPE_STRING))
- self.list_store = Gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns)) + self.list_store = Gtk.ListStore( + *gui.generate_list_store_columns_with_attr(self.columns))
# Allow selecting multiple rows selection = treeview.get_selection() @@ -206,7 +212,8 @@ class irqview:
new_value[self.COL_NUM] = irq new_value[self.COL_AFF] = tuna.get_irq_affinity_text(self.irqs, irq) - new_value[self.COL_EVENTS] = reduce(lambda a, b: a + b, irq_info["cpu"]) + new_value[self.COL_EVENTS] = reduce( + lambda a, b: a + b, irq_info["cpu"]) new_value[self.COL_USERS] = ",".join(users)
gui.set_store_columns(self.list_store, iter, new_value) @@ -231,25 +238,24 @@ class irqview: continue # Was the last one break - elif tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, - self.is_root): + if tuna.irq_filtered(irq, self.irqs, self.cpus_filtered, + self.is_root): new_irqs.remove(irq) if self.list_store.remove(row): # removed and row now its the next one continue # Was the last one break - else: - try: - new_irqs.remove(irq) - irq_info = self.irqs[irq] - self.set_irq_columns(row, irq, irq_info, nics) - except: - if self.list_store.remove(row): - # removed and row now its the next one - continue - # Was the last one - break + try: + new_irqs.remove(irq) + irq_info = self.irqs[irq] + self.set_irq_columns(row, irq, irq_info, nics) + except: + if self.list_store.remove(row): + # removed and row now its the next one + continue + # Was the last one + break
row = self.list_store.iter_next(row)
Port to Gtk-3.0
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/procview.py | 86 ++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 42 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index d5d95ed3e486..435ce111439a 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -1,12 +1,14 @@ +import re +import schedutils + import gi gi.require_version("Gtk", "3.0") - -from tuna import tuna, gui from gi.repository import GObject from gi.repository import Gtk +from gi.repository import Gdk + +from tuna import tuna, gui import procfs -import re -import schedutils
try: import perf @@ -26,8 +28,10 @@ class process_druid: self.pid = pid self.pid_info = pid_info self.nr_cpus = nr_cpus - self.window = Gtk.glade.XML(gladefile, "set_process_attributes", "tuna") - self.dialog = self.window.get_widget("set_process_attributes") + self.window = Gtk.Builder() + self.window.add_from_file(gladefile) +# self.window = Gtk.glade.XML(gladefile, "set_process_attributes", "tuna") + self.dialog = self.window.get_object("set_process_attributes") pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.SMALL_TOOLBAR) self.dialog.set_icon(pixbuf) @@ -38,14 +42,15 @@ class process_druid: "on_command_regex_clicked" : self.on_command_regex_clicked, "on_all_these_threads_clicked" : self.on_all_these_threads_clicked, "on_just_this_thread_clicked" : self.on_just_this_thread_clicked} - self.window.signal_autoconnect(event_handlers) - self.sched_pri = self.window.get_widget("sched_pri_spin") - self.sched_policy = self.window.get_widget("sched_policy_combo") - self.regex_edit = self.window.get_widget("cmdline_regex") - self.affinity = self.window.get_widget("affinity_text") - self.just_this_thread = self.window.get_widget("just_this_thread") - self.all_these_threads = self.window.get_widget("all_these_threads") - processes = self.window.get_widget("matching_process_list") + #self.window.signal_autoconnect(event_handlers) + self.window.connect_signals(event_handlers) + self.sched_pri = self.window.get_object("sched_pri_spin") + self.sched_policy = self.window.get_object("sched_policy_combo") + self.regex_edit = self.window.get_object("cmdline_regex") + self.affinity = self.window.get_object("affinity_text") + self.just_this_thread = self.window.get_object("just_this_thread") + self.all_these_threads = self.window.get_object("all_these_threads") + processes = self.window.get_object("matching_process_list")
self.sched_pri.set_value(int(pid_info["stat"]["rt_priority"])) cmdline_regex = procfs.process_cmdline(pid_info) @@ -275,8 +280,8 @@ class procview:
# Allow enable drag and drop of rows self.treeview.enable_model_drag_source( - Gtk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, - Gtk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + Gdk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) @@ -435,36 +440,34 @@ class procview: continue # removed and its the last one break - else: + try: + new_tids.remove(tid) + except: + # FIXME: understand in what situation this + # can happen, seems harmless from visual + # inspection. + pass + if tuna.thread_filtered(tid, self.cpus_filtered, + self.show_kthreads, self.show_uthreads): + if self.tree_store.remove(row): + # removed and now row is the next one + continue + # removed and its the last one + break try: - new_tids.remove(tid) - except: - # FIXME: understand in what situation this - # can happen, seems harmless from visual - # inspection. - pass - if tuna.thread_filtered(tid, self.cpus_filtered, - self.show_kthreads, self.show_uthreads): + self.set_thread_columns(row, tid, threads[tid]) + if "threads" in threads[tid]: + children = threads[tid]["threads"] + else: + children = {} + child_row = self.tree_store.iter_children(row) + self.update_rows(children, child_row, row) + except: # thread doesn't exists anymore if self.tree_store.remove(row): # removed and now row is the next one continue # removed and its the last one break - else: - try: - self.set_thread_columns(row, tid, threads[tid]) - if "threads" in threads[tid]: - children = threads[tid]["threads"] - else: - children = {} - child_row = self.tree_store.iter_children(row) - self.update_rows(children, child_row, row) - except: # thread doesn't exists anymore - if self.tree_store.remove(row): - # removed and now row is the next one - continue - # removed and its the last one - break
previous_row = row row = self.tree_store.iter_next(row) @@ -488,8 +491,7 @@ class procview:
if "threads" in threads[tid]: children = threads[tid]["threads"] - children_list = list(children.keys()) - children_list.sort() + children_list = sorted(children.keys()) for child in children_list: child_row = self.tree_store.append(row) try:
Port to Gtk-3.0
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/profileview.py | 664 ++++++++++++++++++++-------------------- 1 file changed, 328 insertions(+), 336 deletions(-)
diff --git a/tuna/gui/profileview.py b/tuna/gui/profileview.py index 96ae1ea1bab4..4f68bf41c322 100644 --- a/tuna/gui/profileview.py +++ b/tuna/gui/profileview.py @@ -1,367 +1,359 @@ +import os +import shutil import gi from gi.repository import Gtk - from tuna import tuna, gui
-import os, shutil - class profileview: - def on_loadProfileButton_clicked(self, button): - self.dialog = Gtk.FileChooserDialog("Open...", None, - Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, - Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) - self.dialog.set_default_response(Gtk.ResponseType.OK) - filter = Gtk.FileFilter() - filter.set_name("All files") - filter.add_pattern("*") - self.dialog.add_filter(filter) - self.dialog.set_current_folder(self.config.config["root"]) - self.response = self.dialog.run() - if self.response == Gtk.ResponseType.OK: - self.addFile(self.dialog.get_filename()) - self.setProfileFileList() - self.dialog.destroy() + def on_loadProfileButton_clicked(self, button): + self.dialog = Gtk.FileChooserDialog("Open...", None, \ + Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, \ + Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + self.dialog.set_default_response(Gtk.ResponseType.OK) + filter = Gtk.FileFilter() + filter.set_name("All files") + filter.add_pattern("*") + self.dialog.add_filter(filter) + self.dialog.set_current_folder(self.config.config["root"]) + self.response = self.dialog.run() + if self.response == Gtk.ResponseType.OK: + self.addFile(self.dialog.get_filename()) + self.setProfileFileList() + self.dialog.destroy()
- def setWtree(self, wtree): - self.configFileTree = wtree.get_widget("profileTree") - self.profileContent = wtree.get_widget("profileContent") - self.configFileCombo = wtree.get_widget("profileSelector") - self.profileDescription = wtree.get_widget("profileDescriptionText") - self.frame = wtree.get_widget("TunableFramesw") + def setWtree(self, wtree): + self.configFileTree = wtree.get_object("profileTree") + self.profileContent = wtree.get_object("profileContent") + self.configFileCombo = wtree.get_object("profileSelector") + self.profileDescription = wtree.get_object("profileDescriptionText") + self.frame = wtree.get_object("TunableFramesw")
- def setProfileFileList(self): - self.clearConfig() - for val in self.config.populate(): - self.addConfig(val) - return True + def setProfileFileList(self): + self.clearConfig() + for val in self.config.populate(): + self.addConfig(val) + return True
- def addFile(self,value): - try: - if os.path.isfile(value): - tmp = value.rfind("/") - shutil.copy(value, self.config.config['root']+value[tmp:len(value)]) - self.setProfileFileList() - self.config.load(value[tmp:len(value)]) - except Exception as e: - self.show_mbox_warning(str(e)) + def addFile(self, value): + try: + if os.path.isfile(value): + tmp = value.rfind("/") + shutil.copy(value, self.config.config['root']+value[tmp:len(value)]) + self.setProfileFileList() + self.config.load(value[tmp:len(value)]) + except Exception as e: + self.show_mbox_warning(str(e))
- def updateProfileContent(self): - try: - self.config.cache - except: - self.config.cache = "" - self.profileContentBuffer = self.profileContent.get_buffer() - self.profileContentBuffer.set_text(self.config.cache) + def updateProfileContent(self): + try: + self.config.cache + except: + self.config.cache = "" + self.profileContentBuffer = self.profileContent.get_buffer() + self.profileContentBuffer.set_text(self.config.cache)
- def clearConfig(self): - try: - self.config_store.clear() - self.combo_store.clear() - except: - pass + def clearConfig(self): + try: + self.config_store.clear() + self.combo_store.clear() + except: + pass
- def addConfig(self,config): - if not self.configFileTree or not self.configFileCombo: - return False - try: - self.configs - self.configFileCombo - except AttributeError: - self.config_store = Gtk.ListStore(str) - self.configs = self.configFileTree - self.configFileTree.append_column(Gtk.TreeViewColumn('Profile Name', Gtk.CellRendererText(), text=0)) - self.configHandler = self.configs.connect('cursor_changed', self.changeProfile) - self.configs.set_model(self.config_store) - self.combo_store = Gtk.ListStore(str) - self.configFileCombo.set_model(self.combo_store) - cell = Gtk.CellRendererText() - self.configFileCombo.pack_start(cell, True) - self.configFileCombo.add_attribute(cell, "text", 0) - self.config_store.append([config]) - self.configs.show() - self.combo_store.append([config]) - self.configFileCombo.show() + def addConfig(self, config): + if not self.configFileTree or not self.configFileCombo: + return False + try: + self.configs + self.configFileCombo + except AttributeError: + self.config_store = Gtk.ListStore(str) + self.configs = self.configFileTree + self.configFileTree.append_column(Gtk.TreeViewColumn('Profile Name', Gtk.CellRendererText(), text=0)) + self.configHandler = self.configs.connect('cursor_changed', self.changeProfile) + self.configs.set_model(self.config_store) + self.combo_store = Gtk.ListStore(str) + self.configFileCombo.set_model(self.combo_store) + cell = Gtk.CellRendererText() + self.configFileCombo.pack_start(cell, True) + self.configFileCombo.add_attribute(cell, "text", 0) + self.config_store.append([config]) + self.configs.show() + self.combo_store.append([config]) + self.configFileCombo.show()
- def changeProfile(self,config): - try: - f = open(self.config.config['root']+self.config.cacheFileName, 'r') - temp = f.read() - f.close() - self.profileContentBuffer = self.profileContent.get_buffer() - buff = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(),self.profileContentBuffer.get_end_iter()) - if temp != buff: - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, - Gtk.ButtonsType.YES_NO, - "%s\n\n%s\n%s" % \ - (_("Config file was changed!"), - _("All changes will be lost"), - _("Realy continue?"),)) - ret = dialog.run() - dialog.destroy() - if ret == Gtk.ResponseType.NO: - old = self.config.cacheFileName.rfind("/") - old = self.config.cacheFileName[old+1:len(self.config.cacheFileName)] - self.set_current_tree_selection(old) - return False - except IOError as e: - pass - currentFile = self.get_current_tree_selection() - self.config.fileToCache(currentFile) - self.updateProfileContent() - self.profileDescription.set_text(self.config.description) + def changeProfile(self, config): + try: + f = open(self.config.config['root']+self.config.cacheFileName, 'r') + temp = f.read() + f.close() + self.profileContentBuffer = self.profileContent.get_buffer() + buff = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(), self.profileContentBuffer.get_end_iter()) + if temp != buff: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL \ + | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, \ + "%s\n\n%s\n%s" % \ + (_("Config file was changed!"), + _("All changes will be lost"), + _("Realy continue?"),)) + ret = dialog.run() + dialog.destroy() + if ret == Gtk.ResponseType.NO: + old = self.config.cacheFileName.rfind("/") + old = self.config.cacheFileName[old+1:len(self.config.cacheFileName)] + self.set_current_tree_selection(old) + return False + except IOError as e: + pass + currentFile = self.get_current_tree_selection() + self.config.fileToCache(currentFile) + self.updateProfileContent() + self.profileDescription.set_text(self.config.description)
- def on_SaveButton_clicked(self, widget): - try: - self.profileContentBuffer = self.profileContent.get_buffer() - self.config.cache = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(),self.profileContentBuffer.get_end_iter()) - self.config.cacheToFile(self.config.cacheFileName) - except IOError as e: - self.show_mbox_warning(_("Cannot write to config file: %s") % (self.config.cacheFileName)) + def on_SaveButton_clicked(self, widget): + try: + self.profileContentBuffer = self.profileContent.get_buffer() + self.config.cache = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(), self.profileContentBuffer.get_end_iter()) + self.config.cacheToFile(self.config.cacheFileName) + except IOError as e: + self.show_mbox_warning(_("Cannot write to config file: %s") % (self.config.cacheFileName))
- def on_UpdateButton_clicked(self, widget): - self.profileContentBuffer = self.profileContent.get_buffer() - self.temp = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(),self.profileContentBuffer.get_end_iter()) - try: - if not self.config.loadDirect(self.temp): - self.commonview.updateCommonView() - self.config.updateDefault(self.config.cacheFileName) - self.frame.show() - else: - self.frame.hide() - except RuntimeError as e: - self.show_mbox_warning(str(e)) - self.frame.hide() + def on_UpdateButton_clicked(self, widget): + self.profileContentBuffer = self.profileContent.get_buffer() + self.temp = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(), self.profileContentBuffer.get_end_iter()) + try: + if not self.config.loadDirect(self.temp): + self.commonview.updateCommonView() + self.config.updateDefault(self.config.cacheFileName) + self.frame.show() + else: + self.frame.hide() + except RuntimeError as e: + self.show_mbox_warning(str(e)) + self.frame.hide()
- def init_default_file(self): - self.setProfileFileList() - try: - if 'lastfile' in self.config.config and \ - not self.config.load(self.config.config['lastfile']): - cur = self.configFileTree.get_model() - for val in cur: - if val[0] == self.config.config['lastfile']: - self.configFileTree.set_cursor(val.path[0]) - self.commonview.updateCommonView() - self.frame.show() - else: - self.frame.hide() - except RuntimeError as e: - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, - _("%s\nRun autocorect?") % _(str(e))) - dlgret = dialog.run() - dialog.destroy() - if dlgret == Gtk.ResponseType.YES: - if 'lastfile' in self.config.config: - self.config.fixConfigFile(self.config.config['root'] + self.config.config['lastfile']) - err = self.config.checkConfigFile(self.config.config['root'] + self.config.config['lastfile']) - if err != '': - self.show_mbox_warning(_("Default %s" % str(err))) - self.frame.hide() - else: - self.init_default_file() - else: - self.frame.hide() - else: - self.frame.hide() + def init_default_file(self): + self.setProfileFileList() + try: + if 'lastfile' in self.config.config and \ + not self.config.load(self.config.config['lastfile']): + cur = self.configFileTree.get_model() + for val in cur: + if val[0] == self.config.config['lastfile']: + self.configFileTree.set_cursor(val.path[0]) + self.commonview.updateCommonView() + self.frame.show() + else: + self.frame.hide() + except RuntimeError as e: + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, \ + _("%s\nRun autocorect?") % _(str(e))) + dlgret = dialog.run() + dialog.destroy() + if dlgret == Gtk.ResponseType.YES: + if 'lastfile' in self.config.config: + self.config.fixConfigFile(self.config.config['root'] + self.config.config['lastfile']) + err = self.config.checkConfigFile(self.config.config['root'] + self.config.config['lastfile']) + if err != '': + self.show_mbox_warning(_("Default %s" % str(err))) + self.frame.hide() + else: + self.init_default_file() + else: + self.frame.hide() + else: + self.frame.hide()
- def on_profileTree_button_press_event(self, treeview, event): - if event.button == 3: - x = int(event.x) - y = int(event.y) - time = event.time - pthinfo = treeview.get_path_at_pos(x, y) - if pthinfo is not None: - path, col, cellx, celly = pthinfo - treeview.grab_focus() - treeview.set_cursor( path, col, 0) - context = Gtk.Menu() + def on_profileTree_button_press_event(self, treeview, event): + if event.button == 3: + x = int(event.x) + y = int(event.y) + time = event.time + pthinfo = treeview.get_path_at_pos(x, y) + if pthinfo is not None: + path, col, cellx, celly = pthinfo + treeview.grab_focus() + treeview.set_cursor(path, col, 0) + context = Gtk.Menu()
- item = Gtk.ImageMenuItem(_("New profile")) - item.connect("activate", self.on_menu_new) - img = Gtk.Image.new_from_stock(Gtk.STOCK_NEW, Gtk.IconSize.MENU) - img.show() - item.set_image(img) - context.append(item) + item = Gtk.ImageMenuItem(_("New profile")) + item.connect("activate", self.on_menu_new) + img = Gtk.Image.new_from_stock(Gtk.STOCK_NEW, Gtk.IconSize.MENU) + img.show() + item.set_image(img) + context.append(item)
- item = Gtk.ImageMenuItem(_("Rename")) - item.connect("activate", self.on_menu_rename) - img = Gtk.Image.new_from_stock(Gtk.STOCK_FILE, Gtk.IconSize.MENU) - img.show() - item.set_image(img) - context.append(item) + item = Gtk.ImageMenuItem(_("Rename")) + item.connect("activate", self.on_menu_rename) + img = Gtk.Image.new_from_stock(Gtk.STOCK_FILE, Gtk.IconSize.MENU) + img.show() + item.set_image(img) + context.append(item)
- item = Gtk.ImageMenuItem(_("Copy")) - item.connect("activate", self.on_menu_copy) - img = Gtk.Image.new_from_stock(Gtk.STOCK_COPY, Gtk.IconSize.MENU) - img.show() - item.set_image(img) - context.append(item) + item = Gtk.ImageMenuItem(_("Copy")) + item.connect("activate", self.on_menu_copy) + img = Gtk.Image.new_from_stock(Gtk.STOCK_COPY, Gtk.IconSize.MENU) + img.show() + item.set_image(img) + context.append(item)
- item = Gtk.ImageMenuItem(_("Delete")) - item.connect("activate", self.on_menu_delete) - img = Gtk.Image.new_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.MENU) - img.show() - item.set_image(img) - context.append(item) + item = Gtk.ImageMenuItem(_("Delete")) + item.connect("activate", self.on_menu_delete) + img = Gtk.Image.new_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.MENU) + img.show() + item.set_image(img) + context.append(item)
- item = Gtk.ImageMenuItem(_("Check")) - item.connect("activate", self.on_menu_check) - img = Gtk.Image.new_from_stock(Gtk.STOCK_SPELL_CHECK, Gtk.IconSize.MENU) - img.show() - item.set_image(img) - context.append(item) + item = Gtk.ImageMenuItem(_("Check")) + item.connect("activate", self.on_menu_check) + img = Gtk.Image.new_from_stock(Gtk.STOCK_SPELL_CHECK, Gtk.IconSize.MENU) + img.show() + item.set_image(img) + context.append(item)
- context.show_all() - context.popup(None, None, None, event.button, time) - return True + context.show_all() + context.popup(None, None, None, event.button, time) + return True
- def get_current_tree_selection(self): - selection = self.configFileTree.get_selection() - tree_model, tree_iter = selection.get_selected() - return tree_model.get_value(tree_iter, 0) + def get_current_tree_selection(self): + selection = self.configFileTree.get_selection() + tree_model, tree_iter = selection.get_selected() + return tree_model.get_value(tree_iter, 0)
- def set_current_tree_selection(self, string): - cur = self.configFileTree.get_model() - for val in cur: - if val[0] == string: - self.configFileTree.set_cursor(val.path[0]) - return True - return False + def set_current_tree_selection(self, string): + cur = self.configFileTree.get_model() + for val in cur: + if val[0] == string: + self.configFileTree.set_cursor(val.path[0]) + return True + return False
- def on_menu_new(self, widget): - filename = self.get_text_dialog(_("Please enter new filename"),"empty.conf") - if(filename == None or filename == "" or os.path.exists(self.config.config['root']+filename)): - self.show_mbox_warning(_("Bad or empty filename %s" % _(filename))) - return False - else: - try: - f = open(self.config.config['root'] + filename, 'w') - f.write("#List of enabled categories\n") - f.write("[categories]\n") - f.write("#format:\n") - f.write("# category_identifier=Category Name\n") - f.write("\n") - f.write("#[category_identifier]\n") - f.write("#value.name=default\n") - f.write("#value.name=slider_min,slider_max,default\n") - f.write("\n") - f.write("#[guiAlias]\n") - f.write("#value.name=Alias\n") - f.write("\n") - f.write("#[fileDescription]\n") - f.write("#text=Description of this profile\n") - f.write("\n") - f.close() - if self.setProfileFileList(): - self.set_current_tree_selection(filename) - self.frame.hide() - except IOError as io: - self.show_mbox_warning(str(io)) - return True + def on_menu_new(self, widget): + filename = self.get_text_dialog(_("Please enter new filename"), \ + "empty.conf") + if(filename is None or filename == "" or os.path.exists(self.config.config['root']+filename)): + self.show_mbox_warning(_("Bad or empty filename %s" % _(filename))) + return False + try: + f = open(self.config.config['root'] + filename, 'w') + f.write("#List of enabled categories\n") + f.write("[categories]\n") + f.write("#format:\n") + f.write("# category_identifier=Category Name\n") + f.write("\n") + f.write("#[category_identifier]\n") + f.write("#value.name=default\n") + f.write("#value.name=slider_min,slider_max,default\n") + f.write("\n") + f.write("#[guiAlias]\n") + f.write("#value.name=Alias\n") + f.write("\n") + f.write("#[fileDescription]\n") + f.write("#text=Description of this profile\n") + f.write("\n") + f.close() + if self.setProfileFileList(): + self.set_current_tree_selection(filename) + self.frame.hide() + except IOError as io: + self.show_mbox_warning(str(io)) + return True
- def on_menu_check(self, widget): - filename = self.get_current_tree_selection() - err = self.config.checkConfigFile(self.config.config['root']+filename) - if err != '': - self.show_mbox_warning("%s\n%s" % (_("Config file contain errors:"), _(err))) - return False - else: - dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,\ - Gtk.ButtonsType.OK, "%s\n" % (_("Config file looks OK"))) - ret = dialog.run() - dialog.destroy() - self.set_current_tree_selection(filename) - return True + def on_menu_check(self, widget): + filename = self.get_current_tree_selection() + err = self.config.checkConfigFile(self.config.config['root']+filename) + if err != '': + self.show_mbox_warning("%s\n%s" % (_("Config file contain errors:"), _(err))) + return False + dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO, \ + Gtk.ButtonsType.OK, "%s\n" % (_("Config file looks OK"))) + ret = dialog.run() + dialog.destroy() + self.set_current_tree_selection(filename) + return True
- def on_menu_rename(self, widget): - old_filename = self.get_current_tree_selection() - new_filename = self.get_text_dialog(_("Please enter new name for %s" % (old_filename)), old_filename) - if(new_filename == None or new_filename == ""): - self.show_mbox_warning(_("Bad or empty filename %s" % _(new_filename))) - return False - else: - try: - os.rename(self.config.config['root'] + old_filename, self.config.config['root'] + new_filename) - if self.setProfileFileList(): - self.set_current_tree_selection(new_filename) - if self.config.checkConfigFile(self.config.config['root'] + new_filename) == '': - self.commonview.updateCommonView() - else: - self.frame.hide() - except OSError as io: - self.show_mbox_warning(str(io)) - return True + def on_menu_rename(self, widget): + old_filename = self.get_current_tree_selection() + new_filename = self.get_text_dialog(_("Please enter new name for %s" % (old_filename)), old_filename) + if(new_filename is None or new_filename == ""): + self.show_mbox_warning(_("Bad or empty filename %s" % _(new_filename))) + return False + try: + os.rename(self.config.config['root'] + old_filename, self.config.config['root'] + new_filename) + if self.setProfileFileList(): + self.set_current_tree_selection(new_filename) + if self.config.checkConfigFile(self.config.config['root'] + new_filename) == '': + self.commonview.updateCommonView() + else: + self.frame.hide() + except OSError as io: + self.show_mbox_warning(str(io)) + return True
- def on_menu_copy(self, widget): - old_filename = self.get_current_tree_selection() - new_filename = self.get_text_dialog(_("Please enter name for new file"), old_filename) - if(new_filename == None or new_filename == ""): - self.show_mbox_warning(_("Bad or empty filename %s" % _(new_filename))) - return False - else: - try: - shutil.copy2(self.config.config['root']+old_filename, self.config.config['root']+new_filename) - except (shutil.Error, IOError) as e: - self.show_mbox_warning(str(e)) - if self.setProfileFileList(): - self.set_current_tree_selection(new_filename) - if self.config.checkConfigFile(self.config.config['root'] + new_filename) == '': - self.commonview.updateCommonView() - else: - self.frame.hide() - return True + def on_menu_copy(self, widget): + old_filename = self.get_current_tree_selection() + new_filename = self.get_text_dialog(_("Please enter name for new file"), old_filename) + if(new_filename is None or new_filename == ""): + self.show_mbox_warning(_("Bad or empty filename %s" % _(new_filename))) + return False + try: + shutil.copy2(self.config.config['root']+old_filename, self.config.config['root']+new_filename) + except (shutil.Error, IOError) as e: + self.show_mbox_warning(str(e)) + if self.setProfileFileList(): + self.set_current_tree_selection(new_filename) + if self.config.checkConfigFile(self.config.config['root'] + new_filename) == '': + self.commonview.updateCommonView() + else: + self.frame.hide() + return True
- def on_menu_delete(self, widget): - filename = self.get_current_tree_selection() - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, - _("Profile %s will be deleted!\nReally?" % (filename))) - ret = dialog.run() - dialog.destroy() - if ret == Gtk.ResponseType.YES: - try: - os.unlink(self.config.config['root'] + filename) - except OSError as oe: - self.show_mbox_warning(str(oe)) - return False - if self.setProfileFileList(): - self.configFileTree.set_cursor(0) - currentFile = self.get_current_tree_selection() - if self.config.checkConfigFile(self.config.config['root'] + currentFile) == '': - self.commonview.updateCommonView() - return True - else: - self.frame.hide() - return False + def on_menu_delete(self, widget): + filename = self.get_current_tree_selection() + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, \ + _("Profile %s will be deleted!\nReally?" % (filename))) + ret = dialog.run() + dialog.destroy() + if ret == Gtk.ResponseType.YES: + try: + os.unlink(self.config.config['root'] + filename) + except OSError as oe: + self.show_mbox_warning(str(oe)) + return False + if self.setProfileFileList(): + self.configFileTree.set_cursor(0) + currentFile = self.get_current_tree_selection() + if self.config.checkConfigFile(self.config.config['root'] + currentFile) == '': + self.commonview.updateCommonView() + return True + self.frame.hide() + return False
- def get_text_dialog(self, message, default=''): - d = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.QUESTION, - Gtk.ButtonsType.OK_CANCEL, - message) - entry = Gtk.Entry() - entry.set_text(default) - entry.show() - d.vbox.pack_end(entry, True, True, 0) - entry.connect('activate', lambda _: d.response(Gtk.ResponseType.OK)) - d.set_default_response(Gtk.ResponseType.OK) - r = d.run() - text = entry.get_text().decode('utf8') - d.destroy() - if r == Gtk.ResponseType.OK: - return text - else: - return None + def get_text_dialog(self, message, default=''): + d = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.QUESTION, Gtk.ButtonsType.OK_CANCEL, message) + entry = Gtk.Entry() + entry.set_text(default) + entry.show() + d.vbox.pack_end(entry, True, True, 0) + entry.connect('activate', lambda _: d.response(Gtk.ResponseType.OK)) + d.set_default_response(Gtk.ResponseType.OK) + r = d.run() + text = entry.get_text().decode('utf8') + d.destroy() + if r == Gtk.ResponseType.OK: + return text + return None
- def show_mbox_warning(self, message): - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _((str(message)))) - ret = dialog.run() - dialog.destroy() + def show_mbox_warning(self, message): + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _((str(message)))) + ret = dialog.run() + dialog.destroy()
Fix some style problems, make the code more readable.
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/util.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/tuna/gui/util.py b/tuna/gui/util.py index ed55eb8149e4..3b5ff426213b 100644 --- a/tuna/gui/util.py +++ b/tuna/gui/util.py @@ -4,8 +4,8 @@ gi.require_version("Gtk", "3.0") from gi.repository import GObject from gi.repository import Gtk from gi.repository import Pango -import procfs import schedutils +import procfs from tuna import tuna
class list_store_column: @@ -41,7 +41,9 @@ def on_affinity_text_changed(self): try: new_affinity = tuna.cpustring_to_list(new_affinity_text) except: - if len(new_affinity_text) > 0 and new_affinity_text[-1] != '-' and new_affinity_text[0:2] not in ('0x', '0X'): + if len(new_affinity_text) > 0 \ + and new_affinity_text[-1] != '-' \ + and new_affinity_text[0:2] not in ('0x', '0X'): # print "not a hex number" self.affinity.set_text(self.affinity_text) return @@ -89,10 +91,12 @@ def thread_set_attributes(pid_info, new_policy, new_prio, new_affinity, nr_cpus)
try: curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError - if e.args[0] == 3: + # (3, 'No such process') old python-schedutils + # incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == 3: return False - raise e + raise err
try: new_affinity = [int(a) for a in new_affinity.split(",")] @@ -112,10 +116,12 @@ def thread_set_attributes(pid_info, new_policy, new_prio, new_affinity, nr_cpus)
try: curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # (3, 'No such process') old python-schedutils incorrectly raised SystemError - if e.args[0] == 3: + # (3, 'No such process') old python-schedutils + # incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == 3: return False - raise e + raise err
if curr_affinity != new_affinity: print(_("couldn't change pid %(pid)d from %(caff)s to %(naff)s!") % \
Change to port to Gtk-3.0
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/oscilloscope.py | 861 ++++++++++++++++++++++--------------------- 1 file changed, 435 insertions(+), 426 deletions(-)
diff --git a/tuna/oscilloscope.py b/tuna/oscilloscope.py index b26f90311283..a2ab2f5d2643 100755 --- a/tuna/oscilloscope.py +++ b/tuna/oscilloscope.py @@ -1,7 +1,7 @@ # Oscilloscope # # Copyright 2008-2009 Red Hat, Inc. -# +# # Arnaldo Carvalho de Melo acme@redhat.com # # Please check the tuna repository at: @@ -23,434 +23,443 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA
-import gobject, gtk, os, sys -from matplotlib.backends.backend_gtkagg import \ - FigureCanvasGTKAgg as figure_canvas -import matplotlib.figure, matplotlib.ticker, numpy - -class histogram_frame(gtk.Frame): - def __init__(self, title = "Statistics", width = 780, height = 100, - max_value = 500, nr_entries = 10, - facecolor = "white"): - gtk.Frame.__init__(self, title) - - self.fraction = int(max_value / nr_entries) - if self.fraction == 0: - self.fraction = max_value - nr_entries = 1 - self.max_value = max_value - self.nr_entries = nr_entries - self.nr_samples = 0 - - table = gtk.Table(3, self.nr_entries + 1, False) - table.set_border_width(5) - table.set_row_spacings(5) - table.set_col_spacings(10) - self.add(table) - self.buckets = [ 0, ] * (nr_entries + 1) - self.buckets_bar = [ None, ] * (nr_entries + 1) - self.buckets_counter = [ None, ] * (nr_entries + 1) - - prefix = "<=" - for bucket in range(self.nr_entries + 1): - bucket_range = (bucket + 1) * self.fraction - if bucket_range > self.max_value: - prefix = ">" - bucket_range = self.max_value - - label = gtk.Label("%s %d" % (prefix, bucket_range)) - label.set_alignment(0, 1) - table.attach(label, 0, 1, bucket, bucket + 1, 0, 0, 0, 0) - - self.buckets_bar[bucket] = gtk.ProgressBar() - table.attach(self.buckets_bar[bucket], 1, 2, bucket, bucket + 1, 0, 0, 0, 0) - - self.buckets_counter[bucket] = gtk.Label("0") - label.set_alignment(0, 1) - table.attach(self.buckets_counter[bucket], 2, 3, bucket, bucket + 1, 0, 0, 0, 0) - - self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(facecolor)) - - def add_sample(self, sample): - if sample > self.max_value: - bucket = self.nr_entries - else: - bucket = int(sample / self.fraction) - self.nr_samples += 1 - self.buckets[bucket] += 1 - - def refresh(self): - for bucket in range(self.nr_entries + 1): - self.buckets_counter[bucket].set_text(str(self.buckets[bucket])) - fraction = float(self.buckets[bucket]) / self.nr_samples - self.buckets_bar[bucket].set_fraction(fraction) - - def reset(self): - self.buckets = [ 0, ] * (self.nr_entries + 1) - self.nr_samples = 0 - -class oscilloscope_frame(gtk.Frame): - - def __init__(self, title = "Osciloscope", width = 780, height = 360, - nr_samples_on_screen = 250, graph_type = '-', - max_value = 500, plot_color = "lightgreen", - bg_color = "darkgreen", facecolor = "white", - ylabel = "Latency", picker = None): - - gtk.Frame.__init__(self, title) - - self.font = { 'fontname' : 'Liberation Sans', - 'color' : 'b', - 'fontweight' : 'bold', - 'fontsize' : 10 } - - self.max_value = max_value - self.nr_samples_on_screen = nr_samples_on_screen - self.ind = numpy.arange(nr_samples_on_screen) - self.samples = [ 0.0 ] * nr_samples_on_screen - - figure = matplotlib.figure.Figure(figsize = (10, 4), dpi = 100, - facecolor = facecolor) - ax = figure.add_subplot(111) - self.ax = ax - ax.set_axis_bgcolor(bg_color) - - self.on_screen_samples = ax.plot(self.ind, self.samples, graph_type, - color = plot_color, - picker = picker) - - ax.set_ylim(0, max_value) - ax.set_ylabel(ylabel, self.font) - ax.set_xlabel("%d samples" % nr_samples_on_screen, self.font) - ax.set_xticklabels([]) - ax.grid(True) - - for label in ax.get_yticklabels(): - label.set(fontsize = 8) - - self.canvas = figure_canvas(figure) # a gtk.DrawingArea - self.canvas.set_size_request(width, height) - - self.add(self.canvas) - self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(facecolor)) - self.nr_samples = 0 - - def add_sample(self, sample): - del self.samples[0] - self.samples.append(sample) - self.on_screen_samples[0].set_data(self.ind, self.samples) - self.nr_samples += 1 - if self.nr_samples <= self.nr_samples_on_screen: - self.ax.set_xlabel("%d samples" % self.nr_samples, self.font) - - def reset(self): - self.samples = [ 0.0 ] * self.nr_samples_on_screen - self.nr_samples = 0 - self.on_screen_samples[0].set_data(self.ind, self.samples) - - def refresh(self): - self.canvas.draw() - return - -def add_table_row(table, row, label_text, label_value = "0"): - label = gtk.Label(label_text) - label.set_use_underline(True) - label.set_alignment(0, 1) - table.attach(label, 0, 1, row, row + 1, 0, 0, 0, 0) - - label = gtk.Label(label_value) - table.attach(label, 1, 2, row, row + 1, 0, 0, 0, 0) - return label - -class system_info_frame(gtk.Frame): - def __init__(self, title = "System", facecolor = "white"): - gtk.Frame.__init__(self, title) - - self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(facecolor)) - - table = gtk.Table(3, 2, False) - table.set_border_width(5) - table.set_row_spacings(5) - table.set_col_spacings(10) - self.add(table) - - u = os.uname() - add_table_row(table, 0, "Kernel Release", u[2]) - add_table_row(table, 1, "Architecture", u[4]) - add_table_row(table, 2, "Machine", u[1]) - -class oscilloscope(gtk.Window): - - def __init__(self, get_sample = None, width = 800, height = 500, - nr_samples_on_screen = 250, - graph_type = '-', title = "Osciloscope", - max_value = 500, plot_color = "lightgreen", - bg_color = "darkgreen", facecolor = "white", - ylabel = "Latency", - picker = None, - snapshot_samples = 0, - geometry = None, scale = True): - - gtk.Window.__init__(self) - if geometry: - self.parse_geometry(geometry) - width, height = self.get_size() - else: - self.set_default_size(width, height) - - self.get_sample = get_sample - self.max_value = max_value - self.snapshot_samples = snapshot_samples - self.scale = scale - - self.set_title(title) - - vbox = gtk.VBox() - vbox.set_border_width(8) - self.add(vbox) - - stats_frame = gtk.Frame("Statistics") - stats_frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(facecolor)) - - table = gtk.Table(3, 2, False) - table.set_border_width(5) - table.set_row_spacings(5) - table.set_col_spacings(10) - stats_frame.add(table) - - self.min_label = add_table_row(table, 0, "Min") - self.avg_label = add_table_row(table, 1, "Avg") - self.max_label = add_table_row(table, 2, "Max") - - help_frame = gtk.Frame("Help") - help_frame.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(facecolor)) - - table = gtk.Table(4, 2, False) - table.set_border_width(5) - table.set_row_spacings(5) - table.set_col_spacings(10) - help_frame.add(table) - - add_table_row(table, 0, "Space", "Pause") - add_table_row(table, 1, "S", "Snapshot") - add_table_row(table, 2, "R", "Reset") - add_table_row(table, 3, "Q", "Quit") - - self.scope = oscilloscope_frame("Scope", - int(width * 0.94), - int(height * 0.64), - nr_samples_on_screen, - max_value = max_value, - graph_type = graph_type, - picker = picker, - ylabel = ylabel) - - self.hist = histogram_frame("Histogram", 0, 0, nr_entries = 5, - max_value = max_value) - - info_frame = system_info_frame() - - vbox_help_info = gtk.VBox() - vbox_help_info.pack_start(info_frame, False, False) - vbox_help_info.pack_end(help_frame, False, False) - hbox = gtk.HBox() - hbox.pack_start(vbox_help_info, False, False) - hbox.pack_start(stats_frame, False, False) - hbox.pack_end(self.hist, True, True) - - vbox.pack_start(self.scope, True, True) - vbox.pack_end(hbox, True, False) - - self.show_all() - - self.getting_samples = False - self.refreshing_screen = False - self.max = self.min = None - self.avg = 0 - - def add_sample(self, sample): - if not self.max or self.max < sample: - self.max = sample - - if not self.min or self.min > sample: - self.min = sample - - self.avg = (self.avg + sample) / 2 - self.scope.add_sample(sample) - self.hist.add_sample(sample) - - def refresh(self): - if self.scale and self.max > self.scope.max_value: - self.scope.max_value *= 2 - self.scope.ax.set_ylim(0, self.scope.max_value) - self.scope.refresh() - self.hist.refresh() - while gtk.events_pending(): - gtk.main_iteration() - - def get_samples(self, fd, condition): - try: - sample = self.get_sample() - prev_min, prev_avg, prev_max = self.min, self.avg, self.max - - self.add_sample(sample) - - if self.refreshing_screen: - if self.min != prev_min: - self.min_label.set_text("%-6.3f" % self.min) - if self.avg != prev_avg: - self.avg_label.set_text("%-6.3f" % self.avg) - if self.max != prev_max: - self.max_label.set_text("%-6.3f" % self.max) +import os +import sys +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +#from matplotlib.backends.backend_gtkagg import \ +# FigureCanvasGTKAgg as figure_canvas +from matplotlib.backends.backend_agg import \ + FigureCanvasAgg as figure_canvas +import matplotlib.figure +import matplotlib.ticker +import numpy + +class histogram_frame(Gtk.Frame): + def __init__(self, title="Statistics", width=780, height=100, + max_value=500, nr_entries=10, facecolor="white"): + + Gtk.Frame.__init__(self, title) + + self.fraction = int(max_value / nr_entries) + if self.fraction == 0: + self.fraction = max_value + nr_entries = 1 + self.max_value = max_value + self.nr_entries = nr_entries + self.nr_samples = 0 + + table = Gtk.Table(3, self.nr_entries + 1, False) + table.set_border_width(5) + table.set_row_spacings(5) + table.set_col_spacings(10) + self.add(table) + self.buckets = [0, ] * (nr_entries + 1) + self.buckets_bar = [None, ] * (nr_entries + 1) + self.buckets_counter = [None, ] * (nr_entries + 1) + + prefix = "<=" + for bucket in range(self.nr_entries + 1): + bucket_range = (bucket + 1) * self.fraction + if bucket_range > self.max_value: + prefix = ">" + bucket_range = self.max_value + + label = Gtk.Label("%s %d" % (prefix, bucket_range)) + label.set_alignment(0, 1) + table.attach(label, 0, 1, bucket, bucket + 1, 0, 0, 0, 0) + + self.buckets_bar[bucket] = Gtk.ProgressBar() + table.attach(self.buckets_bar[bucket], 1, 2, bucket, bucket + 1, 0, 0, 0, 0) + + self.buckets_counter[bucket] = Gtk.Label(label="0") + label.set_alignment(0, 1) + table.attach(self.buckets_counter[bucket], 2, 3, bucket, bucket + 1, 0, 0, 0, 0) + + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(facecolor)) + + def add_sample(self, sample): + if sample > self.max_value: + bucket = self.nr_entries + else: + bucket = int(sample / self.fraction) + self.nr_samples += 1 + self.buckets[bucket] += 1 + + def refresh(self): + for bucket in range(self.nr_entries + 1): + self.buckets_counter[bucket].set_text(str(self.buckets[bucket])) + fraction = float(self.buckets[bucket]) / self.nr_samples + self.buckets_bar[bucket].set_fraction(fraction) + + def reset(self): + self.buckets = [0, ] * (self.nr_entries + 1) + self.nr_samples = 0 + +class oscilloscope_frame(Gtk.Frame): + + def __init__(self, title="Osciloscope", width=780, height=360, + nr_samples_on_screen=250, graph_type='-', + max_value=500, plot_color="lightgeen", + bg_color="darkgreen", facecolor="white", + ylabel="Latency", picker=None): + + Gtk.Frame.__init__(self, title) + + self.font = {'fontname' : 'Liberation Sans', + 'color' : 'b', + 'fontweight' : 'bold', + 'fontsize' : 10} + + self.max_value = max_value + self.nr_samples_on_screen = nr_samples_on_screen + self.ind = numpy.arange(nr_samples_on_screen) + self.samples = [0.0] * nr_samples_on_screen + + figure = matplotlib.figure.Figure(figsize=(10, 4), dpi=100, + facecolor=facecolor) + ax = figure.add_subplot(111) + self.ax = ax + ax.set_axis_bgcolor(bg_color) + + self.on_screen_samples = ax.plot(self.ind, self.samples, graph_type, + color=plot_color, picker=picker) + + ax.set_ylim(0, max_value) + ax.set_ylabel(ylabel, self.font) + ax.set_xlabel("%d samples" % nr_samples_on_screen, self.font) + ax.set_xticklabels([]) + ax.grid(True) + + for label in ax.get_yticklabels(): + label.set(fontsize=8) + + self.canvas = figure_canvas(figure) # a Gtk.DrawingArea + self.canvas.set_size_request(width, height) + + self.add(self.canvas) + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(facecolor)) + self.nr_samples = 0 + + def add_sample(self, sample): + del self.samples[0] + self.samples.append(sample) + self.on_screen_samples[0].set_data(self.ind, self.samples) + self.nr_samples += 1 + if self.nr_samples <= self.nr_samples_on_screen: + self.ax.set_xlabel("%d samples" % self.nr_samples, self.font) + + def reset(self): + self.samples = [0.0] * self.nr_samples_on_screen + self.nr_samples = 0 + self.on_screen_samples[0].set_data(self.ind, self.samples) + + def refresh(self): + self.canvas.draw() + return + +def add_table_row(table, row, label_text, label_value="0"): + label = Gtk.Label(label=label_text) + label.set_use_underline(True) + label.set_alignment(0, 1) + table.attach(label, 0, 1, row, row + 1, 0, 0, 0, 0) + + label = Gtk.Label(label=label_value) + table.attach(label, 1, 2, row, row + 1, 0, 0, 0, 0) + return label + +class system_info_frame(Gtk.Frame): + def __init__(self, title="System", facecolor="white"): + Gtk.Frame.__init__(self, title) + + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(facecolor)) + + table = Gtk.Table(3, 2, False) + table.set_border_width(5) + table.set_row_spacings(5) + table.set_col_spacings(10) + self.add(table) + + u = os.uname() + add_table_row(table, 0, "Kernel Release", u[2]) + add_table_row(table, 1, "Architecture", u[4]) + add_table_row(table, 2, "Machine", u[1]) + +class oscilloscope(Gtk.Window): + + def __init__(self, get_sample=None, width=800, height=500, + nr_samples_on_screen=250, + graph_type='-', title="Osciloscope", + max_value=500, plot_color="lightgreen", + bg_color="darkgreen", facecolor="white", + ylabel="Latency", + picker=None, + snapshot_samples=0, + geometry=None, scale=True): + + Gtk.Window.__init__(self) + if geometry: + self.parse_geometry(geometry) + width, height = self.get_size() + else: + self.set_default_size(width, height) + + self.get_sample = get_sample + self.max_value = max_value + self.snapshot_samples = snapshot_samples + self.scale = scale + + self.set_title(title) + + vbox = Gtk.VBox() + vbox.set_border_width(8) + self.add(vbox) + + stats_frame = Gtk.Frame("Statistics") + stats_frame.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(facecolor)) + + table = Gtk.Table(3, 2, False) + table.set_border_width(5) + table.set_row_spacings(5) + table.set_col_spacings(10) + stats_frame.add(table) + + self.min_label = add_table_row(table, 0, "Min") + self.avg_label = add_table_row(table, 1, "Avg") + self.max_label = add_table_row(table, 2, "Max") + + help_frame = Gtk.Frame("Help") + help_frame.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(facecolor)) + + table = Gtk.Table(4, 2, False) + table.set_border_width(5) + table.set_row_spacings(5) + table.set_col_spacings(10) + help_frame.add(table) + + add_table_row(table, 0, "Space", "Pause") + add_table_row(table, 1, "S", "Snapshot") + add_table_row(table, 2, "R", "Reset") + add_table_row(table, 3, "Q", "Quit") + + self.scope = oscilloscope_frame("Scope", + int(width * 0.94), + int(height * 0.64), + nr_samples_on_screen, + max_value=max_value, + graph_type=graph_type, + picker=picker, + ylabel=ylabel) + + self.hist = histogram_frame("Histogram", 0, 0, nr_entries=5, + max_value=max_value) + + info_frame = system_info_frame() + + vbox_help_info = Gtk.VBox() + vbox_help_info.pack_start(info_frame, False, False) + vbox_help_info.pack_end(help_frame, False, False) + hbox = Gtk.HBox() + hbox.pack_start(vbox_help_info, False, False) + hbox.pack_start(stats_frame, False, False) + hbox.pack_end(self.hist, True, True) + + vbox.pack_start(self.scope, True, True) + vbox.pack_end(hbox, True, False) + + self.show_all() + + self.getting_samples = False + self.refreshing_screen = False + self.max = self.min = None + self.avg = 0 + + def add_sample(self, sample): + if not self.max or self.max < sample: + self.max = sample + + if not self.min or self.min > sample: + self.min = sample + + self.avg = (self.avg + sample) / 2 + self.scope.add_sample(sample) + self.hist.add_sample(sample) + + def refresh(self): + if self.scale and self.max > self.scope.max_value: + self.scope.max_value *= 2 + self.scope.ax.set_ylim(0, self.scope.max_value) + self.scope.refresh() + self.hist.refresh() + while Gtk.events_pending(): + Gtk.main_iteration() + + def get_samples(self, fd, condition): + try: + sample = self.get_sample() + prev_min, prev_avg, prev_max = self.min, self.avg, self.max + + self.add_sample(sample) + + if self.refreshing_screen: + if self.min != prev_min: + self.min_label.set_text("%-6.3f" % self.min) + if self.avg != prev_avg: + self.avg_label.set_text("%-6.3f" % self.avg) + if self.max != prev_max: + self.max_label.set_text("%-6.3f" % self.max) + + self.refresh() + + if self.snapshot_samples == self.scope.nr_samples: + self.snapshot() + Gtk.main_quit() + except: + print("invalid sample, check the input format") + pass + return self.getting_samples + + def run(self, fd): + self.connect("key_press_event", self.key_press_event) + self.getting_samples = True + self.refreshing_screen = True + GObject.io_add_watch(fd, GObject.IO_IN | GObject.IO_PRI, + self.get_samples) + + def freeze_screen(self, state=False): + self.refreshing_screen = state + + def stop(self): + self.getting_samples = False + self.refreshing_screen = False + + def snapshot(self): + self.scope.canvas.print_figure("scope_snapshot.svg") + + def reset(self): + self.scope.max_value = self.max_value + self.scope.ax.set_ylim(0, self.scope.max_value) + self.scope.reset() + self.hist.reset() + self.min = self.max_value + self.max = 0 + self.avg = 0 + + def key_press_event(self, widget, event): + if event.keyval == ord(' '): + self.freeze_screen(not self.refreshing_screen) + elif event.keyval in (ord('s'), ord('S')): + self.snapshot() + elif event.keyval in (ord('r'), ord('R')): + self.reset() + elif event.keyval in (ord('q'), ord('Q')): + Gtk.main_quit() + +class ftrace_window(Gtk.Window): + + (COL_FUNCTION, ) = list(range(1)) + + def __init__(self, trace, parent=None): + Gtk.Window.__init__(self) + try: + self.set_screen(parent.get_screen()) + except AttributeError: + self.connect('destroy', lambda *w: Gtk.main_quit()) + + self.set_border_width(8) + self.set_default_size(350, 500) + self.set_title("ftrace") + + vbox = Gtk.VBox(False, 8) + self.add(vbox) + + sw = Gtk.ScrolledWindow() + sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + vbox.pack_start(sw, True, True) + + store = Gtk.ListStore(GObject.TYPE_STRING) + + for entry in trace: + if entry[0] in ["#", "\n"] or entry[:4] == "vim:": + continue + iter = store.append() + store.set(iter, self.COL_FUNCTION, entry.strip()) + + treeview = Gtk.TreeView(store) + treeview.set_rules_hint(True) + + column = Gtk.TreeViewColumn("Function", Gtk.CellRendererText(), + text=self.COL_FUNCTION) + treeview.append_column(column) + + sw.add(treeview) + self.show_all()
- self.refresh() - - if self.snapshot_samples == self.scope.nr_samples: - self.snapshot() - gtk.main_quit() - except: - print("invalid sample, check the input format") - pass - return self.getting_samples - - def run(self, fd): - self.connect("key_press_event", self.key_press_event) - self.getting_samples = True - self.refreshing_screen = True - gobject.io_add_watch(fd, gobject.IO_IN | gobject.IO_PRI, - self.get_samples) - - def freeze_screen(self, state = False): - self.refreshing_screen = state - - def stop(self): - self.getting_samples = False - self.refreshing_screen = False - - def snapshot(self): - self.scope.canvas.print_figure("scope_snapshot.svg") - - def reset(self): - self.scope.max_value = self.max_value - self.scope.ax.set_ylim(0, self.scope.max_value) - self.scope.reset() - self.hist.reset() - self.min = self.max_value - self.max = 0 - self.avg = 0 - - def key_press_event(self, widget, event): - if event.keyval == ord(' '): - self.freeze_screen(not self.refreshing_screen) - elif event.keyval in (ord('s'), ord('S')): - self.snapshot() - elif event.keyval in (ord('r'), ord('R')): - self.reset() - elif event.keyval in (ord('q'), ord('Q')): - gtk.main_quit() - -class ftrace_window(gtk.Window): - - (COL_FUNCTION, ) = list(range(1)) - - def __init__(self, trace, parent = None): - gtk.Window.__init__(self) +class cyclictestoscope(oscilloscope): + def __init__(self, max_value, snapshot_samples=0, nr_samples_on_screen=500, + delimiter=':', field=2, ylabel="Latency", + geometry=None, scale=True, sample_multiplier=1): + oscilloscope.__init__(self, self.get_sample, + title="CyclictestoSCOPE", + nr_samples_on_screen=nr_samples_on_screen, + width=900, max_value=max_value, + picker=self.scope_picker, + snapshot_samples=snapshot_samples, + ylabel=ylabel, geometry=geometry, + scale=scale) + + self.connect("destroy", self.quit) + self.delimiter = delimiter + self.sample_multiplier = sample_multiplier + self.field = field + self.latency_tracer = os.access("/sys/kernel/debug/tracing/trace", os.R_OK) + if self.latency_tracer: + self.traces = [None,] * nr_samples_on_screen + + def scope_picker(self, line, mouseevent): + if (not self.latency_tracer) or mouseevent.xdata is None: + return False, dict() + + x = int(mouseevent.xdata) + if self.traces[x]: + fw = ftrace_window(self.traces[x], self) + return False, dict() + + def get_sample(self): + fields = sys.stdin.readline().split(self.delimiter) + try: + sample = float(fields[self.field]) * self.sample_multiplier + except: + print("fields=%s, self.field=%s,self.delimiter=%s" % (fields, self.field, self.delimiter)) + return None + + if self.latency_tracer: + del self.traces[0] + if sample > self.avg: + print(sample) try: - self.set_screen(parent.get_screen()) - except AttributeError: - self.connect('destroy', lambda *w: gtk.main_quit()) - - self.set_border_width(8) - self.set_default_size(350, 500) - self.set_title("ftrace") - - vbox = gtk.VBox(False, 8) - self.add(vbox) - - sw = gtk.ScrolledWindow() - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) - sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) - vbox.pack_start(sw, True, True) - - store = gtk.ListStore(gobject.TYPE_STRING) - - for entry in trace: - if entry[0] in [ "#", "\n" ] or entry[:4] == "vim:": - continue - iter = store.append() - store.set(iter, self.COL_FUNCTION, entry.strip()) + f = open("/sys/kernel/debug/tracing/trace") + trace = f.readlines() + f.close() + f = open("/sys/kernel/debug/tracing/tracing_max_latency", "w") + f.write("0\n") + f.close() + except: + trace = None + else: + print("-") + trace = None
- treeview = gtk.TreeView(store) - treeview.set_rules_hint(True) + self.traces.append(trace)
- column = gtk.TreeViewColumn("Function", gtk.CellRendererText(), - text = self.COL_FUNCTION) - treeview.append_column(column) + return sample
- sw.add(treeview) - self.show_all() + def run(self): + oscilloscope.run(self, sys.stdin.fileno())
-class cyclictestoscope(oscilloscope): - def __init__(self, max_value, snapshot_samples = 0, nr_samples_on_screen = 500, - delimiter = ':', field = 2, ylabel = "Latency", - geometry = None, scale = True, sample_multiplier = 1): - oscilloscope.__init__(self, self.get_sample, - title = "CyclictestoSCOPE", - nr_samples_on_screen = nr_samples_on_screen, - width = 900, max_value = max_value, - picker = self.scope_picker, - snapshot_samples = snapshot_samples, - ylabel = ylabel, geometry = geometry, - scale = scale) - - self.connect("destroy", self.quit) - self.delimiter = delimiter - self.sample_multiplier = sample_multiplier - self.field = field - self.latency_tracer = os.access("/sys/kernel/debug/tracing/trace", os.R_OK) - if self.latency_tracer: - self.traces = [ None, ] * nr_samples_on_screen - - def scope_picker(self, line, mouseevent): - if (not self.latency_tracer) or mouseevent.xdata is None: - return False, dict() - - x = int(mouseevent.xdata) - if self.traces[x]: - fw = ftrace_window(self.traces[x], self) - return False, dict() - - def get_sample(self): - fields = sys.stdin.readline().split(self.delimiter) - try: - sample = float(fields[self.field]) * self.sample_multiplier - except: - print("fields=%s, self.field=%s,self.delimiter=%s" % (fields, self.field, self.delimiter)) - return None - - if self.latency_tracer: - del self.traces[0] - if sample > self.avg: - print(sample) - try: - f = open("/sys/kernel/debug/tracing/trace") - trace = f.readlines() - f.close() - f = open("/sys/kernel/debug/tracing/tracing_max_latency", "w") - f.write("0\n") - f.close() - except: - trace = None - else: - print("-") - trace = None - - self.traces.append(trace) - - return sample - - def run(self): - oscilloscope.run(self, sys.stdin.fileno()) - - def quit(self, x): - gtk.main_quit() + def quit(self, x): + Gtk.main_quit()
Update spacing / tabs to modern python style
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/sysfs.py | 199 +++++++++++++++++++++++++------------------------- 1 file changed, 99 insertions(+), 100 deletions(-)
diff --git a/tuna/sysfs.py b/tuna/sysfs.py index 8b8a988659ce..6b3e1df97919 100755 --- a/tuna/sysfs.py +++ b/tuna/sysfs.py @@ -4,107 +4,106 @@ import os
class cpu: - def __init__(self, basedir, name): - self.name = name - self.dir = "%s/%s" % (basedir, name) - self.reload() - - def __lt__(self, other): - self.name < other.name - - def readfile(self, name): - try: - f = open("%s/%s" % (self.dir, name)) - value = f.readline().strip() - f.close() - except: - raise - return value - - def reload_online(self): - self.online = True - try: - self.online = self.readfile("online") == "1" - except: - # boot CPU, usually cpu0, can't be brought offline, so - # lacks the file and non root users can't read. In both - # cases assume CPU is online. - pass - - def reload(self): - self.reload_online() - if self.online: - try: - self.physical_package_id = self.readfile("topology/physical_package_id") - except: - self.physical_package_id = "0" - else: - self.physical_package_id = None - - def set_online(self, online = True): - try: - f = open("%s/online" % self.dir, "w") - f.write("%d\n" % (online and 1 or 0)) - f.close() - except: - pass - - self.reload_online() - return online == self.online + def __init__(self, basedir, name): + self.name = name + self.dir = "%s/%s" % (basedir, name) + self.reload() + + def __lt__(self, other): + self.name < other.name + + def readfile(self, name): + try: + f = open("%s/%s" % (self.dir, name)) + value = f.readline().strip() + f.close() + except: + raise + return value + + def reload_online(self): + self.online = True + try: + self.online = self.readfile("online") == "1" + except: + # boot CPU, usually cpu0, can't be brought offline, so + # lacks the file and non root users can't read. In both + # cases assume CPU is online. + pass + + def reload(self): + self.reload_online() + if self.online: + try: + self.physical_package_id = self.readfile("topology/physical_package_id") + except: + self.physical_package_id = "0" + else: + self.physical_package_id = None + + def set_online(self, online=True): + try: + f = open("%s/online" % self.dir, "w") + f.write("%d\n" % (online and 1 or 0)) + f.close() + except: + pass + + self.reload_online() + return online == self.online
class cpus: - def __init__(self, basedir = "/sys/devices/system/cpu"): - self.basedir = basedir - self.cpus = {} - self.sockets = {} - self.reload() - self.nr_cpus = len(self.cpus) - - def __getitem__(self, key): - return self.cpus[key] - - def keys(self): - return list(self.cpus.keys()) - - def has_key(self, key): - return key in self.cpus - - def reload(self): - sockets_to_sort = [] - for name in os.listdir(self.basedir): - if name[:3] != "cpu" or not name[3].isdigit(): - continue - - if name in self.cpus: - self.cpus[name].reload(self.basedir) - else: - c = cpu(self.basedir, name) - self.cpus[name] = c - try: - socket = c.physical_package_id - except: - socket = "0" - if socket in self.sockets: - self.sockets[socket].insert(0, c) - else: - self.sockets[socket] = [ c, ] - - sockets_to_sort.append(socket) - - for socket in sockets_to_sort: - self.sockets[socket].sort() + def __init__(self, basedir="/sys/devices/system/cpu"): + self.basedir = basedir + self.cpus = {} + self.sockets = {} + self.reload() + self.nr_cpus = len(self.cpus) + + def __getitem__(self, key): + return self.cpus[key] + + def keys(self): + return list(self.cpus.keys()) + + def has_key(self, key): + return key in self.cpus + + def reload(self): + sockets_to_sort = [] + for name in os.listdir(self.basedir): + if name[:3] != "cpu" or not name[3].isdigit(): + continue + + if name in self.cpus: + self.cpus[name].reload(self.basedir) + else: + c = cpu(self.basedir, name) + self.cpus[name] = c + try: + socket = c.physical_package_id + except: + socket = "0" + if socket in self.sockets: + self.sockets[socket].insert(0, c) + else: + self.sockets[socket] = [c, ] + + sockets_to_sort.append(socket) + + for socket in sockets_to_sort: + self.sockets[socket].sort()
if __name__ == '__main__': - import sys - - cpus = cpus() - - for socket in list(cpus.sockets.keys()): - print("Socket %s" % socket) - for c in cpus.sockets[socket]: - print(" %s" % c.name) - print(" online: %s" % c.online) - c.set_online(False) - print(" online: %s" % c.online) - c.set_online() - print(" online: %s" % c.online) + + cpus = cpus() + + for socket in list(cpus.sockets.keys()): + print("Socket %s" % socket) + for c in cpus.sockets[socket]: + print(" %s" % c.name) + print(" online: %s" % c.online) + c.set_online(False) + print(" online: %s" % c.online) + c.set_online() + print(" online: %s" % c.online)
Change to port to Gtk-3.0
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index f9d44c085d9f..2360f5356754 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -3,12 +3,14 @@
import sys import os +import locale
import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk - +from gi.repository import Gdk from gi.repository import GObject +import procfs from .gui.cpuview import cpuview from .gui.irqview import irqview from .gui.procview import procview @@ -16,8 +18,6 @@ from .gui.commonview import commonview from .gui.profileview import profileview from .config import Config
-import procfs - tuna_glade_dirs = [".", "tuna", "/usr/share/tuna"] tuna_glade = None
@@ -27,8 +27,8 @@ class main_gui: global tuna_glade
(app, localedir) = ('tuna', '/usr/share/locale') - Gtk.glade.bindtextdomain(app, localedir) - Gtk.glade.textdomain(app) + locale.bindtextdomain(app, localedir) + locale.textdomain(app)
if self.check_root(): sys.exit(1) @@ -36,30 +36,32 @@ class main_gui: tuna_glade = "%s/tuna_gui.glade" % dir if os.access(tuna_glade, os.F_OK): break - self.wtree = Gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") + self.wtree = Gtk.Builder() + self.wtree.add_from_file(tuna_glade) + #self.wtree = Gtk.glade.XML(tuna_glade, "mainbig_window", "tuna") self.ps = procfs.pidstats() self.irqs = procfs.interrupts() - self.window = self.wtree.get_widget("mainbig_window") + self.window = self.wtree.get_object("mainbig_window")
self.procview = procview( - self.wtree.get_widget("processlist"), + self.wtree.get_object("processlist"), self.ps, show_kthreads, show_uthreads, cpus_filtered, tuna_glade) self.irqview = irqview( - self.wtree.get_widget("irqlist"), + self.wtree.get_object("irqlist"), self.irqs, self.ps, cpus_filtered, tuna_glade) self.cpuview = cpuview( - self.wtree.get_widget("vpaned1"), - self.wtree.get_widget("hpaned2"), - self.wtree.get_widget("cpuview"), + self.wtree.get_object("vpaned1"), + self.wtree.get_object("hpaned2"), + self.wtree.get_object("cpuview"), self.procview, self.irqview, cpus_filtered)
self.config = Config() self.check_env() self.commonview = commonview() - self.commonview.contentTable = self.wtree.get_widget("commonTbl") - self.commonview.configFileCombo = self.wtree.get_widget("profileSelector") + self.commonview.contentTable = self.wtree.get_object("commonTbl") + self.commonview.configFileCombo = self.wtree.get_object("profileSelector")
self.profileview = profileview() self.profileview.config = self.config @@ -97,7 +99,8 @@ class main_gui: : self.profileview.on_profileTree_button_press_event }
- self.wtree.signal_autoconnect(event_handlers) + #self.wtree.signal_autoconnect(event_handlers) + self.wtree.connect_signals(event_handlers)
self.ps.reload_threads() self.show() @@ -150,7 +153,7 @@ class main_gui: return False self.binpath = sys.executable.strip(os.path.basename(sys.executable)) os.execv(self.binpath + 'pkexec', - [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) + [sys.executable] + [self.binpath + 'tuna'] + sys.argv[1:]) return True
def check_env(self):
Initial changes for the glade file for gtk3
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna_gui.glade | 1037 ++++++++++++++++++++++--------------------- 1 file changed, 543 insertions(+), 494 deletions(-)
diff --git a/tuna/tuna_gui.glade b/tuna/tuna_gui.glade index b188c1d5bb99..2b572cac2548 100644 --- a/tuna/tuna_gui.glade +++ b/tuna/tuna_gui.glade @@ -1,57 +1,59 @@ -<?xml version="1.0"?> -<glade-interface> - <!-- interface-requires gtk+ 2.6 --> - <!-- interface-naming-policy toplevel-contextual --> - <widget class="GtkWindow" id="mainbig_window"> +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.36.0 --> +<interface> + <requires lib="gtk+" version="3.22"/> + <object class="GtkWindow" id="mainbig_window"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">1</property> <property name="title" translatable="yes">Tuna</property> <property name="default_width">800</property> <property name="default_height">600</property> - <signal name="destroy_event" handler="on_mainbig_window_destroy_event"/> - <signal name="delete_event" handler="on_mainbig_window_delete_event"/> + <signal name="delete-event" handler="on_mainbig_window_delete_event" swapped="no"/> + <signal name="destroy-event" handler="on_mainbig_window_destroy_event" swapped="no"/> <child> - <widget class="GtkTable" id="table2"> + <object class="GtkTable" id="table2"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkNotebook" id="notebook2"> + <object class="GtkNotebook" id="notebook2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="tab_hborder">1</property> <child> - <widget class="GtkFrame" id="monitor_frame"> + <object class="GtkFrame" id="monitor_frame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <child> - <widget class="GtkViewport" id="viewport1"> + <object class="GtkViewport" id="viewport1"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkVPaned" id="vpaned1"> + <object class="GtkVPaned" id="vpaned1"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="border_width">3</property> <child> - <widget class="GtkHPaned" id="hpaned2"> + <object class="GtkHPaned" id="hpaned2"> <property name="height_request">160</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="border_width">3</property> <property name="position">200</property> <child> - <widget class="GtkScrolledWindow" id="cpuview"> + <object class="GtkScrolledWindow" id="cpuview"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> <child> - <widget class="GtkViewport" id="viewport2"> + <object class="GtkViewport" id="viewport2"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkVBox" id="cpuview_box"> + <object class="GtkVBox" id="cpuview_box"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="border_width">2</property> - <signal name="button_press_event" handler="on_cpuview_button_press_event"/> + <signal name="button-press-event" handler="on_cpuview_button_press_event" swapped="no"/> <child> <placeholder/> </child> @@ -61,172 +63,179 @@ <child> <placeholder/> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> <property name="resize">False</property> <property name="shrink">True</property> </packing> </child> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <object class="GtkScrolledWindow" id="scrolledwindow2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> <child> - <widget class="GtkTreeView" id="irqlist"> + <object class="GtkTreeView" id="irqlist"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="border_width">2</property> <property name="rules_hint">True</property> - <signal name="button_press_event" handler="on_irqlist_button_press_event"/> - </widget> + <signal name="button-press-event" handler="on_irqlist_button_press_event" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + </object> </child> - </widget> + </object> <packing> <property name="resize">True</property> <property name="shrink">True</property> </packing> </child> - </widget> + </object> <packing> <property name="resize">False</property> <property name="shrink">True</property> </packing> </child> <child> - <widget class="GtkScrolledWindow" id="bottomscrolledwindow"> + <object class="GtkScrolledWindow" id="bottomscrolledwindow"> <property name="visible">True</property> <property name="can_focus">True</property> <child> - <widget class="GtkTreeView" id="processlist"> + <object class="GtkTreeView" id="processlist"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="border_width">2</property> <property name="rules_hint">True</property> - <signal name="button_press_event" handler="on_processlist_button_press_event"/> - </widget> + <signal name="button-press-event" handler="on_processlist_button_press_event" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + </object> </child> - </widget> + </object> <packing> <property name="resize">True</property> <property name="shrink">True</property> </packing> </child> - </widget> + </object> </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="monitor_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Kernel Monitoring</property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> + </object> </child> - </widget> + </object> </child> <child> - <widget class="GtkLabel" id="monitor_tab_label"> + <object class="GtkLabel" id="monitor_tab_label"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Monitoring</property> - </widget> + </object> <packing> + <property name="position">1</property> <property name="tab_fill">False</property> - <property name="type">tab</property> </packing> </child> <child> - <widget class="GtkScrolledWindow" id="TunableFramesw"> + <object class="GtkScrolledWindow" id="TunableFramesw"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> <child> - <widget class="GtkViewport" id="TunableFrame"> + <object class="GtkViewport" id="TunableFrame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="resize_mode">queue</property> <child> - <widget class="GtkTable" id="commonTbl"> + <object class="GtkTable" id="commonTbl"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">2</property> <property name="homogeneous">True</property> <child> - <widget class="GtkAlignment" id="profileSelectorBox"> + <object class="GtkAlignment" id="profileSelectorBox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="yalign">0</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="selectorHbox"> + <object class="GtkHBox" id="selectorHbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkLabel" id="currentProfileLabel"> + <object class="GtkLabel" id="currentProfileLabel"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Current active tuna profile: </property> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkComboBox" id="profileSelector"> + <object class="GtkComboBox" id="profileSelector"> <property name="visible">True</property> - <signal name="changed" handler="on_profileSelector_changed"/> - </widget> + <property name="can_focus">False</property> + <signal name="changed" handler="on_profileSelector_changed" swapped="no"/> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> <packing> - <property name="x_options"></property> - <property name="y_options"></property> + <property name="x_options"/> + <property name="y_options"/> </packing> </child> <child> - <widget class="GtkAlignment" id="controls"> + <object class="GtkAlignment" id="controls"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xalign">0</property> <property name="yalign">0</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="controls-sub"> + <object class="GtkHBox" id="controls-sub"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkButton" id="saveChanges"> + <object class="GtkButton" id="saveChanges"> <property name="width_request">150</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="has_tooltip">True</property> - <property name="tooltip" translatable="yes">Save current values to file as default values</property> - <signal name="clicked" handler="on_saveSnapshot_clicked"/> + <signal name="clicked" handler="on_saveSnapshot_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment14"> + <object class="GtkAlignment" id="alignment14"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox10"> + <object class="GtkHBox" id="hbox10"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image3"> + <object class="GtkImage" id="image3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-save</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -234,50 +243,54 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label18"> + <object class="GtkLabel" id="label18"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Save Snapshot</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkButton" id="saveTunedChanges"> + <object class="GtkButton" id="saveTunedChanges"> <property name="width_request">220</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="has_tooltip">True</property> - <property name="tooltip" translatable="yes">Create and activate new profile in tuned daemon. This daemon can apply this settings after boot.</property> - <signal name="clicked" handler="on_saveTunedChanges_clicked"/> + <signal name="clicked" handler="on_saveTunedChanges_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment1"> + <object class="GtkAlignment" id="alignment1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox9"> + <object class="GtkHBox" id="hbox9"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image5"> + <object class="GtkImage" id="image5"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-save</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -285,50 +298,54 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label13"> + <object class="GtkLabel" id="label13"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Save & Apply permanently</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> <child> - <widget class="GtkButton" id="undoChanges"> + <object class="GtkButton" id="undoChanges"> <property name="width_request">150</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="has_tooltip">True</property> - <property name="tooltip" translatable="yes">Undo the last change applied</property> - <signal name="clicked" handler="on_undoChanges_clicked"/> + <signal name="clicked" handler="on_undoChanges_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment2"> + <object class="GtkAlignment" id="alignment2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox12"> + <object class="GtkHBox" id="hbox12"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image6"> + <object class="GtkImage" id="image6"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-undo</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -336,50 +353,54 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label14"> + <object class="GtkLabel" id="label14"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Restore changes</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">2</property> </packing> </child> <child> - <widget class="GtkButton" id="applyChanges"> + <object class="GtkButton" id="applyChanges"> <property name="width_request">220</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="has_tooltip">True</property> - <property name="tooltip" translatable="yes">Apply current values on this system. Values marked with star will be changed. All other system values is same as here</property> - <signal name="clicked" handler="on_applyChanges_clicked"/> + <signal name="clicked" handler="on_applyChanges_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment15"> + <object class="GtkAlignment" id="alignment15"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox11"> + <object class="GtkHBox" id="hbox11"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image4"> + <object class="GtkImage" id="image4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-apply</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -387,23 +408,25 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label19"> + <object class="GtkLabel" id="label19"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Apply changes</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">3</property> </packing> @@ -411,70 +434,76 @@ <child> <placeholder/> </child> - </widget> + </object> </child> - </widget> + </object> <packing> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="x_options"></property> - <property name="y_options"></property> + <property name="x_options"/> + <property name="y_options"/> <property name="x_padding">20</property> <property name="y_padding">20</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> <property name="position">1</property> </packing> </child> <child> - <widget class="GtkLabel" id="common_tab_l"> + <object class="GtkLabel" id="common_tab_l"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Profile management</property> - </widget> + </object> <packing> <property name="position">1</property> <property name="tab_fill">False</property> - <property name="type">tab</property> </packing> </child> <child> - <widget class="GtkFrame" id="profile_frame"> + <object class="GtkFrame" id="profile_frame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <child> - <widget class="GtkAlignment" id="alignment3"> + <object class="GtkAlignment" id="alignment3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> - <widget class="GtkHBox" id="hbox4"> + <object class="GtkHBox" id="hbox4"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkFrame" id="frame4"> + <object class="GtkFrame" id="frame4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <widget class="GtkAlignment" id="alignment6"> + <object class="GtkAlignment" id="alignment6"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">12</property> <child> - <widget class="GtkVBox" id="vbox6"> + <object class="GtkVBox" id="vbox6"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkButton" id="loadProfileButton"> + <object class="GtkButton" id="loadProfileButton"> <property name="label" translatable="yes">Load Profile from External Location</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> - <signal name="clicked" handler="on_loadProfileButton_clicked" after="yes"/> - </widget> + <signal name="clicked" handler="on_loadProfileButton_clicked" after="yes" swapped="no"/> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -482,149 +511,141 @@ </packing> </child> <child> - <widget class="GtkFrame" id="loadedProfileFrame"> + <object class="GtkFrame" id="loadedProfileFrame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <widget class="GtkAlignment" id="profileAlignment"> + <object class="GtkAlignment" id="profileAlignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow6"> + <object class="GtkScrolledWindow" id="scrolledwindow6"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="shadow_type">in</property> <child> - <widget class="GtkTreeView" id="profileTree"> + <object class="GtkTreeView" id="profileTree"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="tooltip" translatable="yes">Right mouse click on profile for more options</property> - <signal name="button_press_event" handler="on_profileTree_button_press_event"/> - </widget> + <signal name="button-press-event" handler="on_profileTree_button_press_event" swapped="no"/> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + </object> </child> - </widget> + </object> </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="profileConfigsLabel"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Preloaded Configurations</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> - <widget class="GtkFrame" id="profileDescriptionFrame"> + <object class="GtkFrame" id="profileDescriptionFrame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <widget class="GtkLabel" id="profileDescriptionText"> + <object class="GtkLabel" id="profileDescriptionText"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="wrap">True</property> <property name="xalign">0</property> <property name="yalign">0</property> - <property name="wrap">True</property> - </widget> - </child> - <child> - <widget class="GtkLabel" id="profileDescriptionLabel"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Profile description</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - <child> - <widget class="GtkLabel" id="Profiles"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Loaded Profiles</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkFrame" id="tunableFrame"> + <object class="GtkFrame" id="tunableFrame"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <widget class="GtkAlignment" id="tunableAlignment"> + <object class="GtkAlignment" id="tunableAlignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="left_padding">4</property> <child> - <widget class="GtkVBox" id="vbox7"> + <object class="GtkVBox" id="vbox7"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkAlignment" id="tune_alignment"> + <object class="GtkAlignment" id="tune_alignment"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> <child> - <widget class="GtkTextView" id="profileContent"> + <object class="GtkTextView" id="profileContent"> <property name="visible">True</property> <property name="can_focus">True</property> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkHBox" id="hbox5"> + <object class="GtkHBox" id="hbox5"> <property name="height_request">46</property> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkButton" id="SaveButton"> + <object class="GtkButton" id="SaveButton"> <property name="height_request">34</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> - <signal name="clicked" handler="on_SaveButton_clicked"/> + <signal name="clicked" handler="on_SaveButton_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment9"> + <object class="GtkAlignment" id="alignment9"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox7"> + <object class="GtkHBox" id="hbox7"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image2"> + <object class="GtkImage" id="image2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-save</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -632,48 +653,53 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label12"> + <object class="GtkLabel" id="label12"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Save Configuration to File</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkButton" id="updateButton"> + <object class="GtkButton" id="updateButton"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> - <signal name="clicked" handler="on_UpdateButton_clicked"/> + <signal name="clicked" handler="on_UpdateButton_clicked" swapped="no"/> <child> - <widget class="GtkAlignment" id="alignment8"> + <object class="GtkAlignment" id="alignment8"> <property name="height_request">34</property> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xscale">0</property> <property name="yscale">0</property> <child> - <widget class="GtkHBox" id="hbox6"> + <object class="GtkHBox" id="hbox6"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkImage" id="image1"> + <object class="GtkImage" id="image1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="stock">gtk-apply</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -681,80 +707,65 @@ </packing> </child> <child> - <widget class="GtkLabel" id="label11"> + <object class="GtkLabel" id="label11"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Update Management Tab</property> <property name="use_underline">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label10"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Tunable Profile Settings</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> + </object> </child> - <child> - <widget class="GtkLabel" id="tuning_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Tuning Profiles</property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> + </object> <packing> <property name="position">2</property> </packing> </child> <child> - <widget class="GtkLabel" id="profile_tab_l"> + <object class="GtkLabel" id="profile_tab_l"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Profile editing</property> - </widget> + </object> <packing> <property name="position">2</property> <property name="tab_fill">False</property> - <property name="type">tab</property> </packing> </child> <child> @@ -762,170 +773,299 @@ </child> <child> <placeholder/> + </child> + </object> + </child> + </object> + </child> + <child type="titlebar"> + <placeholder/> + </child> + </object> + <object class="GtkFileChooserDialog" id="profileChooser"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">5</property> + <property name="role">GtkFileChooserDialog</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button3"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> <packing> - <property name="type">tab</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> - </widget> + <child> + <object class="GtkButton" id="button4"> + <property name="label">gtk-open</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> </child> - </widget> + </object> + </child> + <action-widgets> + <action-widget response="-6">button3</action-widget> + <action-widget response="-5">button4</action-widget> + </action-widgets> + <child type="titlebar"> + <placeholder/> </child> - </widget> - <widget class="GtkDialog" id="set_irq_attributes"> + </object> + <object class="GtkDialog" id="set_irq_attributes"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="title" translatable="yes">Set IRQ Attributes</property> <property name="type_hint">dialog</property> - <property name="has_separator">False</property> <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox2"> + <object class="GtkBox" id="dialog-vbox2"> <property name="visible">True</property> + <property name="can_focus">False</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="cancelbutton2"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="okbutton2"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> <child> - <widget class="GtkFrame" id="frame2"> + <object class="GtkFrame" id="frame2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0.05000000074505806</property> <child> - <widget class="GtkVBox" id="vbox4"> + <object class="GtkVBox" id="vbox4"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkLabel" id="irq_text"> + <object class="GtkLabel" id="irq_text"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="ypad">12</property> <property name="use_markup">True</property> <property name="single_line_mode">True</property> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkTable" id="table1"> + <object class="GtkTable" id="table1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="n_rows">2</property> <property name="n_columns">3</property> <property name="column_spacing">10</property> <property name="homogeneous">True</property> <child> - <widget class="GtkEntry" id="irq_affinity_text"> + <object class="GtkEntry" id="irq_affinity_text"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="on_irq_affinity_text_changed"/> - </widget> + <property name="invisible_char">●</property> + <signal name="changed" handler="on_irq_affinity_text_changed" swapped="no"/> + </object> <packing> <property name="left_attach">2</property> <property name="right_attach">3</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="y_options"></property> + <property name="y_options"/> </packing> </child> <child> - <widget class="GtkSpinButton" id="irq_pri_spinbutton"> + <object class="GtkSpinButton" id="irq_pri_spinbutton"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="adjustment">0 0 100 1 10 0</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - </widget> + </object> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="y_options"></property> + <property name="y_options"/> </packing> </child> <child> - <widget class="GtkComboBox" id="irq_policy_combobox"> + <object class="GtkComboBox" id="irq_policy_combobox"> <property name="visible">True</property> - <signal name="changed" handler="on_irq_policy_combobox_changed"/> - </widget> + <property name="can_focus">False</property> + <signal name="changed" handler="on_irq_policy_combobox_changed" swapped="no"/> + </object> <packing> <property name="top_attach">1</property> <property name="bottom_attach">2</property> - <property name="x_options"></property> + <property name="x_options"/> </packing> </child> <child> - <widget class="GtkLabel" id="label9"> + <object class="GtkLabel" id="label9"> <property name="visible">True</property> - <property name="xalign">0</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">A_ffinity</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">irq_affinity_text</property> - </widget> + <property name="xalign">0</property> + </object> <packing> <property name="left_attach">2</property> <property name="right_attach">3</property> - <property name="x_options"></property> - <property name="y_options"></property> + <property name="x_options"/> + <property name="y_options"/> </packing> </child> <child> - <widget class="GtkLabel" id="label8"> + <object class="GtkLabel" id="label8"> <property name="visible">True</property> - <property name="xalign">0</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">_Scheduler priority</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">irq_pri_spinbutton</property> - </widget> + <property name="xalign">0</property> + </object> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="x_options"></property> - <property name="y_options"></property> + <property name="x_options"/> + <property name="y_options"/> </packing> </child> <child> - <widget class="GtkLabel" id="label7"> + <object class="GtkLabel" id="label7"> <property name="visible">True</property> - <property name="xalign">0</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">_Policy</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">irq_policy_combobox</property> - </widget> + <property name="xalign">0</property> + </object> <packing> - <property name="x_options"></property> - <property name="y_options"></property> + <property name="x_options"/> + <property name="y_options"/> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - <child> - <widget class="GtkLabel" id="label6"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Set attributes for this IRQ:</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> + </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> + </object> + </child> + <action-widgets> + <action-widget response="-6">cancelbutton2</action-widget> + <action-widget response="-5">okbutton2</action-widget> + </action-widgets> + <child type="titlebar"> + <placeholder/> + </child> + </object> + <object class="GtkDialog" id="set_process_attributes"> + <property name="width_request">600</property> + <property name="height_request">500</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="title" translatable="yes">Set Process Attributes</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area2"> + <object class="GtkButtonBox" id="dialog-action_area1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="layout_style">end</property> <child> - <widget class="GtkButton" id="cancelbutton2"> + <object class="GtkButton" id="cancelbutton1"> <property name="label">gtk-cancel</property> - <property name="response_id">-6</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="can_default">True</property> <property name="receives_default">False</property> <property name="use_stock">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -933,68 +1073,59 @@ </packing> </child> <child> - <widget class="GtkButton" id="okbutton2"> + <object class="GtkButton" id="okbutton1"> <property name="label">gtk-ok</property> - <property name="response_id">-5</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="can_default">True</property> <property name="receives_default">False</property> <property name="use_stock">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> + <property name="fill">False</property> <property name="pack_type">end</property> <property name="position">0</property> </packing> </child> - </widget> - </child> - </widget> - <widget class="GtkDialog" id="set_process_attributes"> - <property name="width_request">600</property> - <property name="height_request">500</property> - <property name="visible">True</property> - <property name="title" translatable="yes">Set Process Attributes</property> - <property name="type_hint">dialog</property> - <property name="has_separator">False</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> <child> - <widget class="GtkVBox" id="vbox1"> + <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">1</property> <child> - <widget class="GtkHBox" id="hbox1"> + <object class="GtkHBox" id="hbox1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkFrame" id="frame1"> + <object class="GtkFrame" id="frame1"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label_xalign">0</property> <child> - <widget class="GtkVBox" id="vbox2"> + <object class="GtkVBox" id="vbox2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">5</property> <property name="spacing">3</property> <child> - <widget class="GtkRadioButton" id="just_this_thread"> + <object class="GtkRadioButton" id="just_this_thread"> <property name="label" translatable="yes">_Just the selected thread</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="use_underline">True</property> <property name="draw_indicator">True</property> - <signal name="clicked" handler="on_just_this_thread_clicked"/> - </widget> + <signal name="clicked" handler="on_just_this_thread_clicked" swapped="no"/> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1002,7 +1133,7 @@ </packing> </child> <child> - <widget class="GtkRadioButton" id="all_these_threads"> + <object class="GtkRadioButton" id="all_these_threads"> <property name="label" translatable="yes">_All threads of the selected process</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -1010,8 +1141,8 @@ <property name="use_underline">True</property> <property name="draw_indicator">True</property> <property name="group">just_this_thread</property> - <signal name="clicked" handler="on_all_these_threads_clicked"/> - </widget> + <signal name="clicked" handler="on_all_these_threads_clicked" swapped="no"/> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1019,7 +1150,7 @@ </packing> </child> <child> - <widget class="GtkRadioButton" id="command_regex"> + <object class="GtkRadioButton" id="command_regex"> <property name="label" translatable="yes">A_ll command lines matching the regex below:</property> <property name="visible">True</property> <property name="can_focus">True</property> @@ -1027,46 +1158,40 @@ <property name="use_underline">True</property> <property name="draw_indicator">True</property> <property name="group">just_this_thread</property> - <signal name="clicked" handler="on_command_regex_clicked"/> - </widget> + <signal name="clicked" handler="on_command_regex_clicked" swapped="no"/> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">2</property> </packing> </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Set for these processes</b></property> - <property name="use_markup">True</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <widget class="GtkVBox" id="vbox3"> + <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="border_width">5</property> <property name="spacing">5</property> <child> - <widget class="GtkHBox" id="hbox2"> + <object class="GtkHBox" id="hbox2"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkLabel" id="label4"> + <object class="GtkLabel" id="label4"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">_Policy: </property> <property name="use_underline">True</property> - <property name="mnemonic_widget">sched_policy_combo</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1074,15 +1199,18 @@ </packing> </child> <child> - <widget class="GtkComboBox" id="sched_policy_combo"> + <object class="GtkComboBox" id="sched_policy_combo"> <property name="visible">True</property> - <signal name="changed" handler="on_sched_policy_combo_changed"/> - </widget> + <property name="can_focus">False</property> + <signal name="changed" handler="on_sched_policy_combo_changed" swapped="no"/> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1090,17 +1218,18 @@ </packing> </child> <child> - <widget class="GtkHBox" id="sched_pri_hbox"> + <object class="GtkHBox" id="sched_pri_hbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">2</property> <child> - <widget class="GtkLabel" id="label2"> + <object class="GtkLabel" id="label2"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">_Scheduler priority:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">sched_pri_spin</property> <property name="single_line_mode">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1108,18 +1237,19 @@ </packing> </child> <child> - <widget class="GtkSpinButton" id="sched_pri_spin"> + <object class="GtkSpinButton" id="sched_pri_spin"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="adjustment">0 0 100 1 10 0</property> <property name="climb_rate">1</property> <property name="numeric">True</property> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1127,15 +1257,16 @@ </packing> </child> <child> - <widget class="GtkHBox" id="hbox3"> + <object class="GtkHBox" id="hbox3"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkLabel" id="label5"> + <object class="GtkLabel" id="label5"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">A_ffinity:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">affinity_text</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1143,31 +1274,33 @@ </packing> </child> <child> - <widget class="GtkEntry" id="affinity_text"> + <object class="GtkEntry" id="affinity_text"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="on_affinity_text_changed"/> - </widget> + <property name="invisible_char">●</property> + <signal name="changed" handler="on_affinity_text_changed" swapped="no"/> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">2</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1175,18 +1308,19 @@ </packing> </child> <child> - <widget class="GtkHBox" id="regex_hbox"> + <object class="GtkHBox" id="regex_hbox"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="spacing">3</property> <child> - <widget class="GtkLabel" id="label3"> + <object class="GtkLabel" id="label3"> <property name="visible">True</property> + <property name="can_focus">False</property> <property name="xpad">3</property> <property name="label" translatable="yes">Command line rege_x:</property> <property name="use_underline">True</property> - <property name="mnemonic_widget">cmdline_regex</property> <property name="single_line_mode">True</property> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1194,17 +1328,19 @@ </packing> </child> <child> - <widget class="GtkEntry" id="cmdline_regex"> + <object class="GtkEntry" id="cmdline_regex"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="invisible_char">●</property> - <signal name="changed" handler="on_cmdline_regex_changed"/> - </widget> + <property name="invisible_char">●</property> + <signal name="changed" handler="on_cmdline_regex_changed" swapped="no"/> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> - </widget> + </object> <packing> <property name="expand">False</property> <property name="fill">False</property> @@ -1212,127 +1348,40 @@ </packing> </child> <child> - <widget class="GtkScrolledWindow" id="scrolledwindow3"> + <object class="GtkScrolledWindow" id="scrolledwindow3"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="hscrollbar_policy">automatic</property> - <property name="vscrollbar_policy">automatic</property> <child> - <widget class="GtkTreeView" id="matching_process_list"> + <object class="GtkTreeView" id="matching_process_list"> <property name="visible">True</property> <property name="can_focus">True</property> - </widget> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + </object> </child> - </widget> + </object> <packing> + <property name="expand">True</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> - </widget> - <packing> - <property name="position">1</property> - </packing> - </child> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <widget class="GtkButton" id="cancelbutton1"> - <property name="label">gtk-cancel</property> - <property name="response_id">-6</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="okbutton1"> - <property name="label">gtk-ok</property> - <property name="response_id">-5</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> + </object> <packing> <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> - </widget> + </object> </child> - </widget> - <widget class="GtkFileChooserDialog" id="profileChooser"> - <property name="visible">True</property> - <property name="border_width">5</property> - <property name="role">GtkFileChooserDialog</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox4"> - <property name="visible">True</property> - <property name="spacing">2</property> - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area4"> - <property name="visible">True</property> - <property name="layout_style">end</property> - <child> - <widget class="GtkButton" id="button3"> - <property name="label">gtk-cancel</property> - <property name="response_id">-6</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button4"> - <property name="label">gtk-open</property> - <property name="response_id">-5</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </widget> - <packing> - <property name="expand">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - </widget> + <action-widgets> + <action-widget response="-6">cancelbutton1</action-widget> + <action-widget response="-5">okbutton1</action-widget> + </action-widgets> + <child type="titlebar"> + <placeholder/> </child> - </widget> -</glade-interface> + </object> +</interface>
Changes via pygi-convert.sh for gtk2 to gtk3 to the tuna/gui/ directory
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/commonview.py | 70 ++++++++++---------- tuna/gui/cpuview.py | 62 +++++++++--------- tuna/gui/irqview.py | 54 +++++++-------- tuna/gui/procview.py | 142 ++++++++++++++++++++-------------------- tuna/gui/profileview.py | 100 ++++++++++++++-------------- tuna/gui/util.py | 28 ++++---- tuna/tuna_gui.py | 7 +- 7 files changed, 232 insertions(+), 231 deletions(-)
diff --git a/tuna/gui/commonview.py b/tuna/gui/commonview.py index a8b475b63538..1a43f41ed438 100644 --- a/tuna/gui/commonview.py +++ b/tuna/gui/commonview.py @@ -1,5 +1,5 @@ -import pygtk -import gtk +import gi +from gi.repository import Gtk from tuna import tuna, gui
class commonview: @@ -32,8 +32,8 @@ class commonview: catCntr = 0 contentCntr = 0 self.contentTable.resize(row+3,2) - self.contentTable.attach(self.ctrl,0,2,1,2,gtk.FILL,gtk.FILL) - self.contentTable.attach(self.selector,0,2,0,1,gtk.FILL,gtk.FILL) + self.contentTable.attach(self.ctrl,0,2,1,2,Gtk.AttachOptions.FILL,Gtk.AttachOptions.FILL) + self.contentTable.attach(self.selector,0,2,0,1,Gtk.AttachOptions.FILL,Gtk.AttachOptions.FILL) cur = self.profileview.configFileCombo.get_model() for val in cur: if val[0] == self.config.cacheFileName: @@ -47,8 +47,8 @@ class commonview: except TypeError as e: pass while catCntr < catListlenght: - frames[catCntr] = gtk.Frame() - tLabel = gtk.Label('<b>'+self.config.categories[catCntr]+'</b>') + frames[catCntr] = Gtk.Frame() + tLabel = Gtk.Label(label='<b>'+self.config.categories[catCntr]+'</b>') tLabel.set_use_markup(True) frames[catCntr].set_label_widget(tLabel) frameContent[catCntr] = {} @@ -58,39 +58,39 @@ class commonview: currentCol = catCntr%2 currentRow = (catCntr/2)+2 if len(self.config.ctlParams[catCntr]) > 0: - frameContent[catCntr]['table'] = gtk.Table(len(self.config.ctlParams[catCntr]),2,False) + frameContent[catCntr]['table'] = Gtk.Table(len(self.config.ctlParams[catCntr]),2,False) else: - frameContent[catCntr]['table'] = gtk.Table(1,2,False) + frameContent[catCntr]['table'] = Gtk.Table(1,2,False) contentCntr = 0 for val in sorted(self.config.ctlParams[catCntr], key=str.lower): if self.config.getSystemValue(val) != self.config.ctlParams[catCntr][val]: star = "*" else: star = "" - frameContent[catCntr]['labels'][contentCntr] = gtk.Label(self.config.originalToAlias(val)+star) + frameContent[catCntr]['labels'][contentCntr] = Gtk.Label(label=self.config.originalToAlias(val)+star) frameContent[catCntr]['labels'][contentCntr].set_alignment(0,0.5) frameContent[catCntr]['tooltips'][contentCntr] = tuna.proc_sys_help(val) if len(frameContent[catCntr]['tooltips'][contentCntr]): frameContent[catCntr]['labels'][contentCntr].set_tooltip_text(frameContent[catCntr]['tooltips'][contentCntr]) if val in self.config.ctlGuiParams[catCntr]: # scale control - frameContent[catCntr]['texts'][contentCntr] = gtk.HScale() + frameContent[catCntr]['texts'][contentCntr] = Gtk.HScale() frameContent[catCntr]['texts'][contentCntr].set_range(self.config.ctlGuiParams[catCntr][val][0], self.config.ctlGuiParams[catCntr][val][1]) - frameContent[catCntr]['texts'][contentCntr].set_update_policy(gtk.UPDATE_CONTINUOUS) + frameContent[catCntr]['texts'][contentCntr].set_update_policy(Gtk.UPDATE_CONTINUOUS) frameContent[catCntr]['texts'][contentCntr].set_value(int(self.config.ctlParams[catCntr][val])) frameContent[catCntr]['texts'][contentCntr].set_digits(0) else: # input field - frameContent[catCntr]['texts'][contentCntr] = gtk.Entry(256) + frameContent[catCntr]['texts'][contentCntr] = Gtk.Entry(256) frameContent[catCntr]['texts'][contentCntr].set_alignment(0) frameContent[catCntr]['texts'][contentCntr].set_text(self.config.ctlParams[catCntr][val]) frameContent[catCntr]['texts'][contentCntr].connect("button-release-event", self.checkStar, catCntr, contentCntr, val, frameContent[catCntr]['labels'][contentCntr]) frameContent[catCntr]['texts'][contentCntr].connect("focus-out-event", self.checkStar, catCntr,contentCntr,val, frameContent[catCntr]['labels'][contentCntr]) - frameContent[catCntr]['table'].attach(frameContent[catCntr]['labels'][contentCntr],0,1,contentCntr,contentCntr+1,gtk.FILL,xpadding=5) + frameContent[catCntr]['table'].attach(frameContent[catCntr]['labels'][contentCntr],0,1,contentCntr,contentCntr+1,Gtk.AttachOptions.FILL,xpadding=5) frameContent[catCntr]['table'].attach(frameContent[catCntr]['texts'][contentCntr],1,2,contentCntr,contentCntr+1,xpadding=10) contentCntr = contentCntr+1 frames[catCntr].add(frameContent[catCntr]['table']) - self.contentTable.attach(frames[catCntr],currentCol,currentCol+1,currentRow,currentRow+1,gtk.FILL | gtk.EXPAND,gtk.FILL,1,1) + self.contentTable.attach(frames[catCntr],currentCol,currentCol+1,currentRow,currentRow+1,Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,Gtk.AttachOptions.FILL,1,1) catCntr = catCntr+1 self.ctrl.set_padding(5,5,0,5) self.contentTable.set_border_width(5) @@ -151,9 +151,9 @@ class commonview: self.config.applyChanges(self.config.backup) self.updateCommonView() except: - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("Backup not found, this button is useable after click on apply")) ret = dialog.run() dialog.destroy() @@ -168,25 +168,25 @@ class commonview:
def on_saveTunedChanges_clicked(self,widget): if not self.config.checkTunedDaemon(): - dialog = gtk.MessageDialog(None,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _("Tuned daemon undetected!\nFor this function you must have installed Tuned daemon.")) + dialog = Gtk.MessageDialog(None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _("Tuned daemon undetected!\nFor this function you must have installed Tuned daemon.")) ret = dialog.run() dialog.destroy() return False - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("This function can create new profile for tuned daemon and apply config permanently after reboot.\nProfile will be permanently saved and rewrite all old profiles created by tuna!\nUsing this only if you know that config cant corrupt your system!\nRealy can do it?")) ret = dialog.run() dialog.destroy() - if ret == gtk.RESPONSE_NO: + if ret == Gtk.ResponseType.NO: return False try: ret = self.guiSnapshot() self.config.saveTuned(ret) except RuntimeError as e: - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,str(e)) + dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,str(e)) ret = dialog.run() dialog.destroy() self.profileview.setProfileFileList() @@ -199,27 +199,27 @@ class commonview: err = self.config.checkConfigFile(self.config.config['root']+ret[1]) if err != '': self.restoreConfig = True - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("Config file contain errors: \n%s\nRun autocorrect?") % _(err)) dlgret = dialog.run() dialog.destroy() - if dlgret == gtk.RESPONSE_YES: + if dlgret == Gtk.ResponseType.YES: self.config.fixConfigFile(self.config.config['root'] + ret[1]) err = self.config.checkConfigFile(self.config.config['root'] + ret[1]) if err != '': - dialog = gtk.MessageDialog(None, - gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _("Config file contain errors: \n%s\nAutocorrect failed!") % _(err)) dialog.run() dialog.destroy() self.restoreConfig = True else: - dialog = gtk.MessageDialog(None, - gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_INFO, gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _("Autocorrect OK")) dialog.run() dialog.destroy() diff --git a/tuna/gui/cpuview.py b/tuna/gui/cpuview.py index 7a048fb1c356..78775c0882da 100755 --- a/tuna/gui/cpuview.py +++ b/tuna/gui/cpuview.py @@ -1,18 +1,18 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import pygtk +import gi from functools import reduce -pygtk.require("2.0") +gi.require_version("Gtk", "3.0")
import gtk, gobject, math, os, procfs, schedutils from tuna import sysfs, tuna, gui
def set_affinity_warning(tid, affinity): - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, - gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, + Gtk.ButtonsType.OK, _("Couldn't change the affinity of %(tid)d to %(affinity)s!") % \ {"tid": tid, "affinity": affinity}) dialog.run() @@ -37,53 +37,53 @@ def drop_handler_move_irqs_to_cpu(cpus, data): # in the irqview, now we always refresh. return True
-class cpu_socket_frame(gtk.Frame): +class cpu_socket_frame(Gtk.Frame):
( COL_FILTER, COL_CPU, COL_USAGE ) = list(range(3))
def __init__(self, socket, cpus, creator):
if creator.nr_sockets > 1: - gtk.Frame.__init__(self, _("Socket %s") % socket) + GObject.GObject.__init__(self, _("Socket %s") % socket) else: - gtk.Frame.__init__(self) + GObject.GObject.__init__(self)
self.socket = socket self.cpus = cpus self.nr_cpus = len(cpus) self.creator = creator
- self.list_store = gtk.ListStore(gobject.TYPE_BOOLEAN, - gobject.TYPE_UINT, - gobject.TYPE_UINT) + self.list_store = Gtk.ListStore(GObject.TYPE_BOOLEAN, + GObject.TYPE_UINT, + GObject.TYPE_UINT)
- self.treeview = gtk.TreeView(self.list_store) + self.treeview = Gtk.TreeView(self.list_store)
# Filter column - renderer = gtk.CellRendererToggle() + renderer = Gtk.CellRendererToggle() renderer.connect('toggled', self.filter_toggled, self.list_store) - column = gtk.TreeViewColumn(_('Filter'), renderer, active = self.COL_FILTER) + column = Gtk.TreeViewColumn(_('Filter'), renderer, active = self.COL_FILTER) self.treeview.append_column(column)
# CPU# column - column = gtk.TreeViewColumn(_('CPU'), gtk.CellRendererText(), + column = Gtk.TreeViewColumn(_('CPU'), Gtk.CellRendererText(), text = self.COL_CPU) self.treeview.append_column(column)
# CPU usage column try: - column = gtk.TreeViewColumn(_('Usage'), gtk.CellRendererProgress(), + column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererProgress(), text = self.COL_USAGE, value = self.COL_USAGE) except: # CellRendererProgress needs pygtk2 >= 2.6 - column = gtk.TreeViewColumn(_('Usage'), gtk.CellRendererText(), + column = Gtk.TreeViewColumn(_('Usage'), Gtk.CellRendererText(), text = self.COL_USAGE) self.treeview.append_column(column)
self.add(self.treeview)
self.treeview.enable_model_drag_dest(gui.DND_TARGETS, - gtk.gdk.ACTION_DEFAULT) + Gdk.DragAction.DEFAULT) self.treeview.connect("drag_data_received", self.on_drag_data_received_data) self.treeview.connect("button_press_event", @@ -92,8 +92,8 @@ class cpu_socket_frame(gtk.Frame): self.drop_handlers = { "pid": (drop_handler_move_threads_to_cpu, self.creator.procview), "irq": (drop_handler_move_irqs_to_cpu, self.creator.irqview), }
- self.drag_dest_set(gtk.DEST_DEFAULT_ALL, gui.DND_TARGETS, - gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) + self.drag_dest_set(Gtk.DestDefaults.ALL, gui.DND_TARGETS, + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.connect("drag_data_received", self.on_frame_drag_data_received_data)
@@ -187,20 +187,20 @@ class cpu_socket_frame(gtk.Frame): self.creator.include_cpus(cpus)
def on_cpu_socket_frame_button_press_event(self, treeview, event): - if event.type != gtk.gdk.BUTTON_PRESS or event.button != 3: + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: return
self.last_x = int(event.x) self.last_y = int(event.y)
- menu = gtk.Menu() + menu = Gtk.Menu()
- include = gtk.MenuItem(_("I_nclude CPU")) - isolate = gtk.MenuItem(_("_Isolate CPU")) + include = Gtk.MenuItem(_("I_nclude CPU")) + isolate = Gtk.MenuItem(_("_Isolate CPU")) if self.creator.nr_sockets > 1: - include_socket = gtk.MenuItem(_("I_nclude CPU Socket")) - isolate_socket = gtk.MenuItem(_("_Isolate CPU Socket")) - restore = gtk.MenuItem(_("_Restore CPU")) + include_socket = Gtk.MenuItem(_("I_nclude CPU Socket")) + isolate_socket = Gtk.MenuItem(_("_Isolate CPU Socket")) + restore = Gtk.MenuItem(_("_Restore CPU"))
menu.add(include) menu.add(isolate) @@ -263,7 +263,7 @@ class cpuview: if self.nr_sockets > 1: columns = math.ceil(math.sqrt(self.nr_sockets)) rows = math.ceil(self.nr_sockets / columns) - box = gtk.HBox() + box = Gtk.HBox() vbox.pack_start(box, True, True) else: box = vbox @@ -277,7 +277,7 @@ class cpuview: self.socket_frames[socket_id] = frame if self.nr_sockets > 1: if column == columns: - box = gtk.HBox() + box = Gtk.HBox() vbox.pack_start(box, True, True) column = 1 else: @@ -302,7 +302,7 @@ class cpuview: vpaned.set_position(int(height)) hpaned.set_position(int(width))
- self.timer = gobject.timeout_add(3000, self.refresh) + self.timer = GObject.timeout_add(3000, self.refresh)
def isolate_cpus(self, cpus): self.previous_pid_affinities, \ diff --git a/tuna/gui/irqview.py b/tuna/gui/irqview.py index df19f6ee0b66..147809064ca5 100755 --- a/tuna/gui/irqview.py +++ b/tuna/gui/irqview.py @@ -1,9 +1,9 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import pygtk +import gi from functools import reduce -pygtk.require("2.0") +gi.require_version("Gtk", "3.0")
from tuna import tuna, gui import ethtool, gobject, gtk, os, procfs, schedutils @@ -14,10 +14,10 @@ class irq_druid: self.irqs = irqs self.ps = ps self.irq = irq - self.window = gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") + self.window = Gtk.glade.XML(gladefile, "set_irq_attributes", "tuna") self.dialog = self.window.get_widget("set_irq_attributes") - pixbuf = self.dialog.render_icon(gtk.STOCK_PREFERENCES, - gtk.ICON_SIZE_SMALL_TOOLBAR) + pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, + Gtk.IconSize.SMALL_TOOLBAR) self.dialog.set_icon(pixbuf) event_handlers = { "on_irq_affinity_text_changed" : self.on_irq_affinity_text_changed, "on_sched_policy_combo_changed": self.on_sched_policy_combo_changed } @@ -53,9 +53,9 @@ class irq_druid:
def create_policy_model(self, policy): ( COL_TEXT, COL_SCHED ) = list(range(2)) - list_store = gtk.ListStore(gobject.TYPE_STRING, - gobject.TYPE_UINT) - renderer = gtk.CellRendererText() + list_store = Gtk.ListStore(GObject.TYPE_STRING, + GObject.TYPE_UINT) + renderer = Gtk.CellRendererText() policy.pack_start(renderer, True) policy.add_attribute(renderer, "text", COL_TEXT) for pol in range(4): @@ -77,7 +77,7 @@ class irq_druid:
def run(self): changed = False - if self.dialog.run() == gtk.RESPONSE_OK: + if self.dialog.run() == Gtk.ResponseType.OK: new_policy = self.sched_policy.get_active() new_prio = int(self.sched_pri.get_value()) new_affinity = self.affinity.get_text() @@ -118,12 +118,12 @@ class irqview: ( COL_NUM, COL_PID, COL_POL, COL_PRI, COL_AFF, COL_EVENTS, COL_USERS ) = list(range(nr_columns)) columns = (gui.list_store_column(_("IRQ")), - gui.list_store_column(_("PID"), gobject.TYPE_INT), - gui.list_store_column(_("Policy"), gobject.TYPE_STRING), - gui.list_store_column(_("Priority"), gobject.TYPE_INT), - gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), + gui.list_store_column(_("PID"), GObject.TYPE_INT), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), + gui.list_store_column(_("Priority"), GObject.TYPE_INT), + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), gui.list_store_column(_("Events")), - gui.list_store_column(_("Users"), gobject.TYPE_STRING)) + gui.list_store_column(_("Users"), GObject.TYPE_STRING))
def __init__(self, treeview, irqs, ps, cpus_filtered, gladefile):
@@ -140,25 +140,25 @@ class irqview: self.COL_EVENTS, self.COL_USERS ) = list(range(self.nr_columns)) self.columns = (gui.list_store_column(_("IRQ")), - gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), gui.list_store_column(_("Events")), - gui.list_store_column(_("Users"), gobject.TYPE_STRING)) + gui.list_store_column(_("Users"), GObject.TYPE_STRING))
- self.list_store = gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns)) + self.list_store = Gtk.ListStore(*gui.generate_list_store_columns_with_attr(self.columns))
# Allow selecting multiple rows selection = treeview.get_selection() - selection.set_mode(gtk.SELECTION_MULTIPLE) + selection.set_mode(Gtk.SelectionMode.MULTIPLE)
# Allow enable drag and drop of rows - self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, + self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, - gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) - self.renderer = gtk.CellRendererText() + self.renderer = Gtk.CellRendererText()
for col in range(self.nr_columns): - column = gtk.TreeViewColumn(self.columns[col].name, + column = Gtk.TreeViewColumn(self.columns[col].name, self.renderer, text = col) column.set_sort_column_id(col) column.add_attribute(self.renderer, "weight", @@ -289,19 +289,19 @@ class irqview: self.refresh()
def on_irqlist_button_press_event(self, treeview, event): - if event.type != gtk.gdk.BUTTON_PRESS or event.button != 3: + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: return
self.last_x = int(event.x) self.last_y = int(event.y)
- menu = gtk.Menu() + menu = Gtk.Menu()
- setattr = gtk.MenuItem(_("_Set IRQ attributes")) + setattr = Gtk.MenuItem(_("_Set IRQ attributes")) if self.refreshing: - refresh = gtk.MenuItem(_("Sto_p refreshing the IRQ list")) + refresh = Gtk.MenuItem(_("Sto_p refreshing the IRQ list")) else: - refresh = gtk.MenuItem(_("_Refresh the IRQ list")) + refresh = Gtk.MenuItem(_("_Refresh the IRQ list"))
menu.add(setattr) menu.add(refresh) diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 9b2a21a8bb58..790bc31208ff 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -1,5 +1,5 @@ -import pygtk -pygtk.require("2.0") +import gi +gi.require_version("Gtk", "3.0")
from tuna import tuna, gui import gobject, gtk, procfs, re, schedutils @@ -21,10 +21,10 @@ class process_druid: self.pid = pid self.pid_info = pid_info self.nr_cpus = nr_cpus - self.window = gtk.glade.XML(gladefile, "set_process_attributes", "tuna") + self.window = Gtk.glade.XML(gladefile, "set_process_attributes", "tuna") self.dialog = self.window.get_widget("set_process_attributes") - pixbuf = self.dialog.render_icon(gtk.STOCK_PREFERENCES, - gtk.ICON_SIZE_SMALL_TOOLBAR) + pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, + Gtk.IconSize.SMALL_TOOLBAR) self.dialog.set_icon(pixbuf) event_handlers = { "on_cmdline_regex_changed" : self.on_cmdline_regex_changed, "on_affinity_text_changed" : self.on_affinity_text_changed, @@ -69,12 +69,12 @@ class process_druid: def create_matching_process_model(self, processes): labels = [ "PID", "Name" ]
- self.process_list_store = gtk.ListStore(gobject.TYPE_UINT, - gobject.TYPE_STRING) - renderer = gtk.CellRendererText() + self.process_list_store = Gtk.ListStore(GObject.TYPE_UINT, + GObject.TYPE_STRING) + renderer = Gtk.CellRendererText()
for col in range(len(labels)): - column = gtk.TreeViewColumn(labels[col], renderer, text = col) + column = Gtk.TreeViewColumn(labels[col], renderer, text = col) column.set_sort_column_id(col) processes.append_column(column)
@@ -82,9 +82,9 @@ class process_druid:
def create_policy_model(self, policy): ( COL_TEXT, COL_SCHED ) = list(range(2)) - list_store = gtk.ListStore(gobject.TYPE_STRING, - gobject.TYPE_UINT) - renderer = gtk.CellRendererText() + list_store = Gtk.ListStore(GObject.TYPE_STRING, + GObject.TYPE_UINT) + renderer = Gtk.CellRendererText() policy.pack_start(renderer, True) policy.add_attribute(renderer, "text", COL_TEXT) for pol in range(4): @@ -166,7 +166,7 @@ class process_druid:
def run(self): changed = False - if self.dialog.run() == gtk.RESPONSE_OK: + if self.dialog.run() == Gtk.ResponseType.OK: new_policy = int(self.sched_policy.get_active()) new_prio = int(self.sched_pri.get_value()) new_affinity = self.affinity.get_text() @@ -201,13 +201,13 @@ class procview: nr_columns = 8 ( COL_PID, COL_POL, COL_PRI, COL_AFF, COL_VOLCTXT, COL_NONVOLCTXT, COL_CGROUP, COL_CMDLINE ) = list(range(nr_columns)) columns = (gui.list_store_column(_("PID")), - gui.list_store_column(_("Policy"), gobject.TYPE_STRING), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), gui.list_store_column(_("Priority")), - gui.list_store_column(_("Affinity"), gobject.TYPE_STRING), - gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), - gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), + gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
def __init__(self, treeview, ps, show_kthreads, show_uthreads, @@ -234,45 +234,45 @@ class procview: pass
self.columns = (gui.list_store_column(_("PID")), - gui.list_store_column(_("Policy"), gobject.TYPE_STRING), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), gui.list_store_column(_("Priority")), - gui.list_store_column(_("Affinity"), gobject.TYPE_STRING)) + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING))
if self.nr_columns==5: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) + self.columns = self.columns + (gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
elif self.nr_columns==6: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CGROUP, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), - gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) + self.columns = self.columns + (gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
elif self.nr_columns==7: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.NONVOLCTXT, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) + self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
elif self.nr_columns==8: ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, self.COL_NONVOLCTXT, self.COL_CGROUP, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), gobject.TYPE_UINT), - gui.list_store_column(_("CGroup"), gobject.TYPE_STRING), - gui.list_store_column(_("Command Line"), gobject.TYPE_STRING)) + self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING))
- self.tree_store = gtk.TreeStore(*gui.generate_list_store_columns_with_attr(self.columns)) + self.tree_store = Gtk.TreeStore(*gui.generate_list_store_columns_with_attr(self.columns)) self.treeview.set_model(self.tree_store)
# Allow selecting multiple rows selection = treeview.get_selection() - selection.set_mode(gtk.SELECTION_MULTIPLE) + selection.set_mode(Gtk.SelectionMode.MULTIPLE)
# Allow enable drag and drop of rows - self.treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, + self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, - gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE) + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) self.treeview.connect("drag_data_get", self.on_drag_data_get_data) try: self.treeview.connect("query-tooltip", self.on_query_tooltip) @@ -280,15 +280,15 @@ class procview: # old versions of pygtk2+ doesn't have this signal pass
- self.renderer = gtk.CellRendererText() + self.renderer = Gtk.CellRendererText() for col in range(self.nr_columns): - column = gtk.TreeViewColumn(self.columns[col].name, + column = Gtk.TreeViewColumn(self.columns[col].name, self.renderer, text = col) column.add_attribute(self.renderer, "weight", col + self.nr_columns) column.set_sort_column_id(col) if(col == self.COL_CGROUP): - column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_fixed_width(130) try: self.treeview.set_tooltip_column(col) @@ -348,7 +348,7 @@ class procview: self.evlist.mmap() self.pollfd = self.evlist.get_pollfd() for f in self.pollfd: - gobject.io_add_watch(f, gtk.gdk.INPUT_READ, self.perf_process_events) + GObject.io_add_watch(f, Gdk.INPUT_READ, self.perf_process_events) self.perf_counter = {}
def on_query_tooltip(self, treeview, x, y, keyboard_mode, tooltip): @@ -551,10 +551,10 @@ class procview: cmdline = self.tree_store.get_value(row, self.COL_CMDLINE) help, title = tuna.kthread_help_plain_text(pid, cmdline)
- dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_INFO, - gtk.BUTTONS_OK, _(help)) + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, + Gtk.ButtonsType.OK, _(help)) dialog.set_title(title) ret = dialog.run() dialog.destroy() @@ -563,26 +563,26 @@ class procview: self.refreshing = not self.refreshing
def save_kthreads_tunings(self, a): - dialog = gtk.FileChooserDialog(_("Save As"), + dialog = Gtk.FileChooserDialog(_("Save As"), None, - gtk.FILE_CHOOSER_ACTION_SAVE, - (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OK, gtk.RESPONSE_OK)) - dialog.set_default_response(gtk.RESPONSE_OK) + Gtk.FileChooserAction.SAVE, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OK, Gtk.ResponseType.OK)) + dialog.set_default_response(Gtk.ResponseType.OK)
try: dialog.set_do_overwrite_confirmation(True) except: pass
- filter = gtk.FileFilter() + filter = Gtk.FileFilter() filter.set_name("rtctl config files") filter.add_pattern("*.rtctl") filter.add_pattern("*.tuna") filter.add_pattern("*rtgroup*") dialog.add_filter(filter)
- filter = gtk.FileFilter() + filter = Gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) @@ -592,7 +592,7 @@ class procview: filename = dialog.get_filename() dialog.destroy()
- if response != gtk.RESPONSE_OK: + if response != Gtk.ResponseType.OK: return
self.refresh() @@ -600,10 +600,10 @@ class procview: tuna.generate_rtgroups(filename, kthreads, self.nr_cpus)
if filename != "/etc/rtgroups": - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_INFO, - gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, + Gtk.ButtonsType.YES_NO, "Kernel thread tunings saved!\n\n" "Now you can use it with rtctl:\n\n" "rtctl --file %s reset\n\n" @@ -613,46 +613,46 @@ class procview: "Do you want to do that now?" % (filename, filename)) response = dialog.run() dialog.destroy() - if response == gtk.RESPONSE_YES: + if response == Gtk.ResponseType.YES: filename = "/etc/rtgroups" tuna.generate_rtgroups(filename, kthreads, self.nr_cpus)
- dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_INFO, - gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.INFO, + Gtk.ButtonsType.OK, _("Kernel thread tunings saved to %s!") % filename) dialog.run() dialog.destroy()
def on_processlist_button_press_event(self, treeview, event): - if event.type != gtk.gdk.BUTTON_PRESS or event.button != 3: + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: return
self.last_x = int(event.x) self.last_y = int(event.y)
- menu = gtk.Menu() + menu = Gtk.Menu()
- setattr = gtk.MenuItem(_("_Set process attributes")) + setattr = Gtk.MenuItem(_("_Set process attributes")) if self.refreshing: - refresh = gtk.MenuItem(_("Sto_p refreshing the process list")) + refresh = Gtk.MenuItem(_("Sto_p refreshing the process list")) else: - refresh = gtk.MenuItem(_("_Refresh the process list")) + refresh = Gtk.MenuItem(_("_Refresh the process list"))
if self.show_kthreads: - kthreads = gtk.MenuItem(_("_Hide kernel threads")) + kthreads = Gtk.MenuItem(_("_Hide kernel threads")) else: - kthreads = gtk.MenuItem(_("_Show kernel threads")) + kthreads = Gtk.MenuItem(_("_Show kernel threads"))
if self.show_uthreads: - uthreads = gtk.MenuItem(_("_Hide user threads")) + uthreads = Gtk.MenuItem(_("_Hide user threads")) else: - uthreads = gtk.MenuItem(_("_Show user threads")) + uthreads = Gtk.MenuItem(_("_Show user threads"))
- help = gtk.MenuItem(_("_What is this?")) + help = Gtk.MenuItem(_("_What is this?"))
- save_kthreads_tunings = gtk.MenuItem(_("_Save kthreads tunings")) + save_kthreads_tunings = Gtk.MenuItem(_("_Save kthreads tunings"))
menu.add(save_kthreads_tunings) menu.add(setattr) diff --git a/tuna/gui/profileview.py b/tuna/gui/profileview.py index fe670bfca3c7..96ae1ea1bab4 100644 --- a/tuna/gui/profileview.py +++ b/tuna/gui/profileview.py @@ -1,5 +1,5 @@ -import pygtk -import gtk +import gi +from gi.repository import Gtk
from tuna import tuna, gui
@@ -7,17 +7,17 @@ import os, shutil
class profileview: def on_loadProfileButton_clicked(self, button): - self.dialog = gtk.FileChooserDialog("Open...", None, - gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, - gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) - self.dialog.set_default_response(gtk.RESPONSE_OK) - filter = gtk.FileFilter() + self.dialog = Gtk.FileChooserDialog("Open...", None, + Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + self.dialog.set_default_response(Gtk.ResponseType.OK) + filter = Gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") self.dialog.add_filter(filter) self.dialog.set_current_folder(self.config.config["root"]) self.response = self.dialog.run() - if self.response == gtk.RESPONSE_OK: + if self.response == Gtk.ResponseType.OK: self.addFile(self.dialog.get_filename()) self.setProfileFileList() self.dialog.destroy() @@ -67,14 +67,14 @@ class profileview: self.configs self.configFileCombo except AttributeError: - self.config_store = gtk.ListStore(str) + self.config_store = Gtk.ListStore(str) self.configs = self.configFileTree - self.configFileTree.append_column(gtk.TreeViewColumn('Profile Name', gtk.CellRendererText(), text=0)) + self.configFileTree.append_column(Gtk.TreeViewColumn('Profile Name', Gtk.CellRendererText(), text=0)) self.configHandler = self.configs.connect('cursor_changed', self.changeProfile) self.configs.set_model(self.config_store) - self.combo_store = gtk.ListStore(str) + self.combo_store = Gtk.ListStore(str) self.configFileCombo.set_model(self.combo_store) - cell = gtk.CellRendererText() + cell = Gtk.CellRendererText() self.configFileCombo.pack_start(cell, True) self.configFileCombo.add_attribute(cell, "text", 0) self.config_store.append([config]) @@ -90,17 +90,17 @@ class profileview: self.profileContentBuffer = self.profileContent.get_buffer() buff = self.profileContentBuffer.get_text(self.profileContentBuffer.get_start_iter(),self.profileContentBuffer.get_end_iter()) if temp != buff: - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, - gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, + Gtk.ButtonsType.YES_NO, "%s\n\n%s\n%s" % \ (_("Config file was changed!"), _("All changes will be lost"), _("Realy continue?"),)) ret = dialog.run() dialog.destroy() - if ret == gtk.RESPONSE_NO: + if ret == Gtk.ResponseType.NO: old = self.config.cacheFileName.rfind("/") old = self.config.cacheFileName[old+1:len(self.config.cacheFileName)] self.set_current_tree_selection(old) @@ -148,13 +148,13 @@ class profileview: else: self.frame.hide() except RuntimeError as e: - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("%s\nRun autocorect?") % _(str(e))) dlgret = dialog.run() dialog.destroy() - if dlgret == gtk.RESPONSE_YES: + if dlgret == Gtk.ResponseType.YES: if 'lastfile' in self.config.config: self.config.fixConfigFile(self.config.config['root'] + self.config.config['lastfile']) err = self.config.checkConfigFile(self.config.config['root'] + self.config.config['lastfile']) @@ -178,39 +178,39 @@ class profileview: path, col, cellx, celly = pthinfo treeview.grab_focus() treeview.set_cursor( path, col, 0) - context = gtk.Menu() + context = Gtk.Menu()
- item = gtk.ImageMenuItem(_("New profile")) + item = Gtk.ImageMenuItem(_("New profile")) item.connect("activate", self.on_menu_new) - img = gtk.image_new_from_stock(gtk.STOCK_NEW, gtk.ICON_SIZE_MENU) + img = Gtk.Image.new_from_stock(Gtk.STOCK_NEW, Gtk.IconSize.MENU) img.show() item.set_image(img) context.append(item)
- item = gtk.ImageMenuItem(_("Rename")) + item = Gtk.ImageMenuItem(_("Rename")) item.connect("activate", self.on_menu_rename) - img = gtk.image_new_from_stock(gtk.STOCK_FILE, gtk.ICON_SIZE_MENU) + img = Gtk.Image.new_from_stock(Gtk.STOCK_FILE, Gtk.IconSize.MENU) img.show() item.set_image(img) context.append(item)
- item = gtk.ImageMenuItem(_("Copy")) + item = Gtk.ImageMenuItem(_("Copy")) item.connect("activate", self.on_menu_copy) - img = gtk.image_new_from_stock(gtk.STOCK_COPY, gtk.ICON_SIZE_MENU) + img = Gtk.Image.new_from_stock(Gtk.STOCK_COPY, Gtk.IconSize.MENU) img.show() item.set_image(img) context.append(item)
- item = gtk.ImageMenuItem(_("Delete")) + item = Gtk.ImageMenuItem(_("Delete")) item.connect("activate", self.on_menu_delete) - img = gtk.image_new_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_MENU) + img = Gtk.Image.new_from_stock(Gtk.STOCK_DELETE, Gtk.IconSize.MENU) img.show() item.set_image(img) context.append(item)
- item = gtk.ImageMenuItem(_("Check")) + item = Gtk.ImageMenuItem(_("Check")) item.connect("activate", self.on_menu_check) - img = gtk.image_new_from_stock(gtk.STOCK_SPELL_CHECK, gtk.ICON_SIZE_MENU) + img = Gtk.Image.new_from_stock(Gtk.STOCK_SPELL_CHECK, Gtk.IconSize.MENU) img.show() item.set_image(img) context.append(item) @@ -270,8 +270,8 @@ class profileview: self.show_mbox_warning("%s\n%s" % (_("Config file contain errors:"), _(err))) return False else: - dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO,\ - gtk.BUTTONS_OK, "%s\n" % (_("Config file looks OK"))) + dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,\ + Gtk.ButtonsType.OK, "%s\n" % (_("Config file looks OK"))) ret = dialog.run() dialog.destroy() self.set_current_tree_selection(filename) @@ -317,13 +317,13 @@ class profileview:
def on_menu_delete(self, widget): filename = self.get_current_tree_selection() - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, _("Profile %s will be deleted!\nReally?" % (filename))) ret = dialog.run() dialog.destroy() - if ret == gtk.RESPONSE_YES: + if ret == Gtk.ResponseType.YES: try: os.unlink(self.config.config['root'] + filename) except OSError as oe: @@ -340,28 +340,28 @@ class profileview: return False
def get_text_dialog(self, message, default=''): - d = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_QUESTION, - gtk.BUTTONS_OK_CANCEL, + d = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.OK_CANCEL, message) - entry = gtk.Entry() + entry = Gtk.Entry() entry.set_text(default) entry.show() - d.vbox.pack_end(entry) - entry.connect('activate', lambda _: d.response(gtk.RESPONSE_OK)) - d.set_default_response(gtk.RESPONSE_OK) + d.vbox.pack_end(entry, True, True, 0) + entry.connect('activate', lambda _: d.response(Gtk.ResponseType.OK)) + d.set_default_response(Gtk.ResponseType.OK) r = d.run() text = entry.get_text().decode('utf8') d.destroy() - if r == gtk.RESPONSE_OK: + if r == Gtk.ResponseType.OK: return text else: return None
def show_mbox_warning(self, message): - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _((str(message)))) + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _((str(message)))) ret = dialog.run() dialog.destroy() diff --git a/tuna/gui/util.py b/tuna/gui/util.py index 9e30ed92bd4c..79c49a221363 100755 --- a/tuna/gui/util.py +++ b/tuna/gui/util.py @@ -1,11 +1,11 @@ -import pygtk -pygtk.require("2.0") +import gi +gi.require_version("Gtk", "3.0")
import gobject, gtk, pango, procfs, schedutils from tuna import tuna
class list_store_column: - def __init__(self, name, type = gobject.TYPE_UINT): + def __init__(self, name, type = GObject.TYPE_UINT): self.name = name self.type = type
@@ -13,7 +13,7 @@ def generate_list_store_columns_with_attr(columns): for column in columns: yield column.type for column in columns: - yield gobject.TYPE_UINT + yield GObject.TYPE_UINT
def set_store_columns(store, row, new_value): nr_columns = len(new_value) @@ -21,9 +21,9 @@ def set_store_columns(store, row, new_value): col_weight = col + nr_columns cur_value = store.get_value(row, col) if cur_value == new_value[col]: - new_weight = pango.WEIGHT_NORMAL + new_weight = Pango.Weight.NORMAL else: - new_weight = pango.WEIGHT_BOLD + new_weight = Pango.Weight.BOLD
store.set(row, col, new_value[col], col_weight, new_weight)
@@ -44,10 +44,10 @@ def on_affinity_text_changed(self): self.affinity_text = new_affinity_text
def invalid_affinity(): - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, - gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, + Gtk.ButtonsType.OK, _("Invalid affinity, specify a list of CPUs!")) dialog.run() dialog.destroy() @@ -64,10 +64,10 @@ def thread_set_attributes(pid_info, new_policy, new_prio, new_affinity, nr_cpus) try: schedutils.set_scheduler(pid, new_policy, new_prio) except: - dialog = gtk.MessageDialog(None, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - gtk.MESSAGE_WARNING, - gtk.BUTTONS_OK, + dialog = Gtk.MessageDialog(None, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + Gtk.MessageType.WARNING, + Gtk.ButtonsType.OK, _("Invalid parameters!")) dialog.run() dialog.destroy() diff --git a/tuna/tuna_gui.py b/tuna/tuna_gui.py index 008f55b5df35..c57533153ca4 100755 --- a/tuna/tuna_gui.py +++ b/tuna/tuna_gui.py @@ -1,9 +1,8 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import os -import procfs import sys +import os
import gi gi.require_version("Gtk", "3.0") @@ -11,7 +10,7 @@ from gi.repository import Gtk
from gi.repository import GObject import Gtk.glade -from gtk import ListStore +from Gtk import ListStore from .gui.cpuview import cpuview from .gui.irqview import irqview from .gui.procview import procview @@ -19,6 +18,8 @@ from .gui.commonview import commonview from .gui.profileview import profileview from .config import Config
+import procfs + tuna_glade_dirs = [".", "tuna", "/usr/share/tuna"] tuna_glade = None
Update the spacing and style.
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/gui/procview.py | 1333 +++++++++++++++++++++--------------------- 1 file changed, 661 insertions(+), 672 deletions(-)
diff --git a/tuna/gui/procview.py b/tuna/gui/procview.py index 62ba9cf27949..fa70ab400a43 100755 --- a/tuna/gui/procview.py +++ b/tuna/gui/procview.py @@ -9,686 +9,675 @@ import re import schedutils
try: - import perf + import perf except: - pass + pass
def N_(s): - """gettext_noop""" - return s + """gettext_noop""" + return s
class process_druid:
- ( PROCESS_COL_PID, PROCESS_COL_NAME ) = list(range(2)) - - def __init__(self, ps, pid, pid_info, nr_cpus, gladefile): - self.ps = ps - self.pid = pid - self.pid_info = pid_info - self.nr_cpus = nr_cpus - self.window = Gtk.glade.XML(gladefile, "set_process_attributes", "tuna") - self.dialog = self.window.get_widget("set_process_attributes") - pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, - Gtk.IconSize.SMALL_TOOLBAR) - self.dialog.set_icon(pixbuf) - event_handlers = { "on_cmdline_regex_changed" : self.on_cmdline_regex_changed, - "on_affinity_text_changed" : self.on_affinity_text_changed, - "on_sched_policy_combo_changed" : self.on_sched_policy_combo_changed, - "on_command_regex_clicked" : self.on_command_regex_clicked, - "on_all_these_threads_clicked" : self.on_all_these_threads_clicked, - "on_just_this_thread_clicked" : self.on_just_this_thread_clicked } - self.window.signal_autoconnect(event_handlers) - - self.sched_pri = self.window.get_widget("sched_pri_spin") - self.sched_policy = self.window.get_widget("sched_policy_combo") - self.regex_edit = self.window.get_widget("cmdline_regex") - self.affinity = self.window.get_widget("affinity_text") - self.just_this_thread = self.window.get_widget("just_this_thread") - self.all_these_threads = self.window.get_widget("all_these_threads") - processes = self.window.get_widget("matching_process_list") - - self.sched_pri.set_value(int(pid_info["stat"]["rt_priority"])) - cmdline_regex = procfs.process_cmdline(pid_info) - self.affinity_text = tuna.list_to_cpustring(schedutils.get_affinity(pid)) - self.affinity.set_text(self.affinity_text) - self.create_matching_process_model(processes) - self.create_policy_model(self.sched_policy) - self.sched_policy.set_active(schedutils.get_scheduler(pid)) - self.regex_edit.set_text(cmdline_regex) - self.just_this_thread.set_active(True) - self.regex_edit.set_sensitive(False) - if pid not in ps or "threads" not in ps[pid]: - self.all_these_threads.hide() - self.on_just_this_thread_clicked(None) - - def refresh_match_pids(self, cmdline_regex): - self.process_list_store.clear() - for match_pid in self.ps.find_by_cmdline_regex(cmdline_regex): - info = self.process_list_store.append() - pid_info = self.ps[match_pid] - cmdline = procfs.process_cmdline(pid_info) - self.process_list_store.set(info, self.PROCESS_COL_PID, match_pid, - self.PROCESS_COL_NAME, - cmdline) - - def create_matching_process_model(self, processes): - labels = [ "PID", "Name" ] - - self.process_list_store = Gtk.ListStore(GObject.TYPE_UINT, - GObject.TYPE_STRING) - renderer = Gtk.CellRendererText() - - for col in range(len(labels)): - column = Gtk.TreeViewColumn(labels[col], renderer, text = col) - column.set_sort_column_id(col) - processes.append_column(column) - - processes.set_model(self.process_list_store) - - def create_policy_model(self, policy): - ( COL_TEXT, COL_SCHED ) = list(range(2)) - list_store = Gtk.ListStore(GObject.TYPE_STRING, - GObject.TYPE_UINT) - renderer = Gtk.CellRendererText() - policy.pack_start(renderer, True) - policy.add_attribute(renderer, "text", COL_TEXT) - for pol in range(4): - row = list_store.append() - list_store.set(row, COL_TEXT, schedutils.schedstr(pol), - COL_SCHED, pol) - policy.set_model(list_store) - - def on_cmdline_regex_changed(self, entry): - process_regex_text = entry.get_text() - try: - cmdline_regex = re.compile(process_regex_text) - except: - self.process_list_store.clear() - return - self.refresh_match_pids(cmdline_regex) - - def on_just_this_thread_clicked(self, button): - self.regex_edit.set_sensitive(False) - self.process_list_store.clear() - info = self.process_list_store.append() - cmdline = procfs.process_cmdline(self.pid_info) - self.process_list_store.set(info, - self.PROCESS_COL_PID, self.pid, - self.PROCESS_COL_NAME, cmdline) - - def on_command_regex_clicked(self, button): - self.regex_edit.set_sensitive(True) - self.on_cmdline_regex_changed(self.regex_edit) - - def on_all_these_threads_clicked(self, button): - self.regex_edit.set_sensitive(False) - self.process_list_store.clear() - info = self.process_list_store.append() - cmdline = procfs.process_cmdline(self.ps[self.pid]) - self.process_list_store.set(info, - self.PROCESS_COL_PID, self.pid, - self.PROCESS_COL_NAME, cmdline) - for tid in list(self.ps[self.pid]["threads"].keys()): - child = self.process_list_store.append() - self.process_list_store.set(child, - self.PROCESS_COL_PID, tid, - self.PROCESS_COL_NAME, cmdline) - - - def on_sched_policy_combo_changed(self, button): - new_policy = self.sched_policy.get_active() - if new_policy in ( schedutils.SCHED_FIFO, schedutils.SCHED_RR ): - can_change_pri = True - else: - can_change_pri = False - self.sched_pri.set_sensitive(can_change_pri) - - def on_affinity_text_changed(self, button): - gui.on_affinity_text_changed(self) - - def set_attributes_for_regex(self, regex, new_policy, new_prio, new_affinity): - changed = False - cmdline_regex = re.compile(regex) - for match_pid in self.ps.find_by_cmdline_regex(cmdline_regex): - if gui.thread_set_attributes(self.ps[match_pid], - new_policy, new_prio, - new_affinity, - self.nr_cpus): - changed = True - - return changed - - def set_attributes_for_threads(self, pid, new_policy, new_prio, new_affinity): - changed = False - threads = self.ps[pid]["threads"] - for tid in list(threads.keys()): - if gui.thread_set_attributes(threads[tid], new_policy, - new_prio, new_affinity, - self.nr_cpus): - changed = True - - return changed - - def run(self): - changed = False - if self.dialog.run() == Gtk.ResponseType.OK: - new_policy = int(self.sched_policy.get_active()) - new_prio = int(self.sched_pri.get_value()) - new_affinity = self.affinity.get_text() - if self.just_this_thread.get_active(): - changed = gui.thread_set_attributes(self.pid_info, - new_policy, - new_prio, - new_affinity, - self.nr_cpus) - elif self.all_these_threads.get_active(): - if gui.thread_set_attributes(self.pid_info, - new_policy, new_prio, - new_affinity, - self.nr_cpus): - changed = True - if self.set_attributes_for_threads(self.pid, - new_policy, - new_prio, - new_affinity): - changed = True - else: - changed = self.set_attributes_for_regex(self.regex_edit.get_text(), - new_policy, - new_prio, - new_affinity) - - self.dialog.destroy() - return changed + (PROCESS_COL_PID, PROCESS_COL_NAME) = list(range(2)) + + def __init__(self, ps, pid, pid_info, nr_cpus, gladefile): + self.ps = ps + self.pid = pid + self.pid_info = pid_info + self.nr_cpus = nr_cpus + self.window = Gtk.glade.XML(gladefile, "set_process_attributes", "tuna") + self.dialog = self.window.get_widget("set_process_attributes") + pixbuf = self.dialog.render_icon(Gtk.STOCK_PREFERENCES, + Gtk.IconSize.SMALL_TOOLBAR) + self.dialog.set_icon(pixbuf) + event_handlers = { + "on_cmdline_regex_changed" : self.on_cmdline_regex_changed, + "on_affinity_text_changed" : self.on_affinity_text_changed, + "on_sched_policy_combo_changed" : self.on_sched_policy_combo_changed, + "on_command_regex_clicked" : self.on_command_regex_clicked, + "on_all_these_threads_clicked" : self.on_all_these_threads_clicked, + "on_just_this_thread_clicked" : self.on_just_this_thread_clicked} + self.window.signal_autoconnect(event_handlers) + self.sched_pri = self.window.get_widget("sched_pri_spin") + self.sched_policy = self.window.get_widget("sched_policy_combo") + self.regex_edit = self.window.get_widget("cmdline_regex") + self.affinity = self.window.get_widget("affinity_text") + self.just_this_thread = self.window.get_widget("just_this_thread") + self.all_these_threads = self.window.get_widget("all_these_threads") + processes = self.window.get_widget("matching_process_list") + + self.sched_pri.set_value(int(pid_info["stat"]["rt_priority"])) + cmdline_regex = procfs.process_cmdline(pid_info) + self.affinity_text = tuna.list_to_cpustring(schedutils.get_affinity(pid)) + self.affinity.set_text(self.affinity_text) + self.create_matching_process_model(processes) + self.create_policy_model(self.sched_policy) + self.sched_policy.set_active(schedutils.get_scheduler(pid)) + self.regex_edit.set_text(cmdline_regex) + self.just_this_thread.set_active(True) + self.regex_edit.set_sensitive(False) + if pid not in ps or "threads" not in ps[pid]: + self.all_these_threads.hide() + self.on_just_this_thread_clicked(None) + + def refresh_match_pids(self, cmdline_regex): + self.process_list_store.clear() + for match_pid in self.ps.find_by_cmdline_regex(cmdline_regex): + info = self.process_list_store.append() + pid_info = self.ps[match_pid] + cmdline = procfs.process_cmdline(pid_info) + self.process_list_store.set(info, self.PROCESS_COL_PID, match_pid, + self.PROCESS_COL_NAME, cmdline) + + def create_matching_process_model(self, processes): + labels = ["PID", "Name"] + + self.process_list_store = Gtk.ListStore(GObject.TYPE_UINT, + GObject.TYPE_STRING) + renderer = Gtk.CellRendererText() + + for col in range(len(labels)): + column = Gtk.TreeViewColumn(labels[col], renderer, text=col) + column.set_sort_column_id(col) + processes.append_column(column) + + processes.set_model(self.process_list_store) + + def create_policy_model(self, policy): + (COL_TEXT, COL_SCHED) = list(range(2)) + list_store = Gtk.ListStore(GObject.TYPE_STRING, + GObject.TYPE_UINT) + renderer = Gtk.CellRendererText() + policy.pack_start(renderer, True) + policy.add_attribute(renderer, "text", COL_TEXT) + for pol in range(4): + row = list_store.append() + list_store.set(row, COL_TEXT, schedutils.schedstr(pol), + COL_SCHED, pol) + policy.set_model(list_store) + + def on_cmdline_regex_changed(self, entry): + process_regex_text = entry.get_text() + try: + cmdline_regex = re.compile(process_regex_text) + except: + self.process_list_store.clear() + return + self.refresh_match_pids(cmdline_regex) + + def on_just_this_thread_clicked(self, button): + self.regex_edit.set_sensitive(False) + self.process_list_store.clear() + info = self.process_list_store.append() + cmdline = procfs.process_cmdline(self.pid_info) + self.process_list_store.set(info, + self.PROCESS_COL_PID, self.pid, + self.PROCESS_COL_NAME, cmdline) + + def on_command_regex_clicked(self, button): + self.regex_edit.set_sensitive(True) + self.on_cmdline_regex_changed(self.regex_edit) + + def on_all_these_threads_clicked(self, button): + self.regex_edit.set_sensitive(False) + self.process_list_store.clear() + info = self.process_list_store.append() + cmdline = procfs.process_cmdline(self.ps[self.pid]) + self.process_list_store.set(info, + self.PROCESS_COL_PID, self.pid, + self.PROCESS_COL_NAME, cmdline) + for tid in list(self.ps[self.pid]["threads"].keys()): + child = self.process_list_store.append() + self.process_list_store.set(child, + self.PROCESS_COL_PID, tid, + self.PROCESS_COL_NAME, cmdline) + + + def on_sched_policy_combo_changed(self, button): + new_policy = self.sched_policy.get_active() + if new_policy in (schedutils.SCHED_FIFO, schedutils.SCHED_RR): + can_change_pri = True + else: + can_change_pri = False + self.sched_pri.set_sensitive(can_change_pri) + + def on_affinity_text_changed(self, button): + gui.on_affinity_text_changed(self) + + def set_attributes_for_regex(self, regex, new_policy, new_prio, new_affinity): + changed = False + cmdline_regex = re.compile(regex) + for match_pid in self.ps.find_by_cmdline_regex(cmdline_regex): + if gui.thread_set_attributes(self.ps[match_pid], + new_policy, new_prio, + new_affinity, self.nr_cpus): + changed = True + + return changed + + def set_attributes_for_threads(self, pid, new_policy, new_prio, new_affinity): + changed = False + threads = self.ps[pid]["threads"] + for tid in list(threads.keys()): + if gui.thread_set_attributes(threads[tid], new_policy, + new_prio, new_affinity, self.nr_cpus): + changed = True + + return changed + + def run(self): + changed = False + if self.dialog.run() == Gtk.ResponseType.OK: + new_policy = int(self.sched_policy.get_active()) + new_prio = int(self.sched_pri.get_value()) + new_affinity = self.affinity.get_text() + if self.just_this_thread.get_active(): + changed = gui.thread_set_attributes(self.pid_info, new_policy, + new_prio, new_affinity, + self.nr_cpus) + elif self.all_these_threads.get_active(): + if gui.thread_set_attributes(self.pid_info, new_policy, + new_prio, new_affinity, + self.nr_cpus): + changed = True + if self.set_attributes_for_threads(self.pid, new_policy, + new_prio, new_affinity): + changed = True + else: + changed = self.set_attributes_for_regex(self.regex_edit.get_text(), + new_policy, + new_prio, + new_affinity) + + self.dialog.destroy() + return changed
class procview:
- nr_columns = 8 - ( COL_PID, COL_POL, COL_PRI, COL_AFF, COL_VOLCTXT, COL_NONVOLCTXT, COL_CGROUP, COL_CMDLINE ) = list(range(nr_columns)) - columns = (gui.list_store_column(_("PID")), - gui.list_store_column(_("Policy"), GObject.TYPE_STRING), - gui.list_store_column(_("Priority")), - gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), - gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), - gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) - - def __init__(self, treeview, ps, - show_kthreads, show_uthreads, - cpus_filtered, gladefile): - self.ps = ps - self.treeview = treeview - self.nr_cpus = procfs.cpuinfo().nr_cpus - self.gladefile = gladefile - - self.evlist = None - try: - self.perf_init() - except: # No perf, poll /proc baby, poll - pass - - if "voluntary_ctxt_switches" not in ps[1]["status"]: - self.nr_columns = 5 - else: - self.nr_columns = 7 - try: - if ps[1]["cgroups"]: - self.nr_columns = self.nr_columns + 1 - except: - pass - - self.columns = (gui.list_store_column(_("PID")), - gui.list_store_column(_("Policy"), GObject.TYPE_STRING), - gui.list_store_column(_("Priority")), - gui.list_store_column(_("Affinity"), GObject.TYPE_STRING)) - - if self.nr_columns==5: - ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) - - elif self.nr_columns==6: - ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_CGROUP, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), - gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) - - elif self.nr_columns==7: - ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, - self.NONVOLCTXT, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) - - elif self.nr_columns==8: - ( self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, self.COL_VOLCTXT, - self.COL_NONVOLCTXT, self.COL_CGROUP, self.COL_CMDLINE ) = list(range(self.nr_columns)) - self.columns = self.columns + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), - gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), - gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) - - self.tree_store = Gtk.TreeStore(*gui.generate_list_store_columns_with_attr(self.columns)) - self.treeview.set_model(self.tree_store) - - # Allow selecting multiple rows - selection = treeview.get_selection() - selection.set_mode(Gtk.SelectionMode.MULTIPLE) - - # Allow enable drag and drop of rows - self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, - gui.DND_TARGETS, - Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) - self.treeview.connect("drag_data_get", self.on_drag_data_get_data) - try: - self.treeview.connect("query-tooltip", self.on_query_tooltip) - except: - # old versions of pygtk2+ doesn't have this signal - pass - - self.renderer = Gtk.CellRendererText() - for col in range(self.nr_columns): - column = Gtk.TreeViewColumn(self.columns[col].name, - self.renderer, text = col) - column.add_attribute(self.renderer, "weight", - col + self.nr_columns) - column.set_sort_column_id(col) - if(col == self.COL_CGROUP): - column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) - column.set_fixed_width(130) - try: - self.treeview.set_tooltip_column(col) - except: - # old versions of pygtk2+ doesn't have this signal - pass - column.set_resizable(True) - self.treeview.append_column(column) - - self.show_kthreads = show_kthreads - self.show_uthreads = show_uthreads - self.cpus_filtered = cpus_filtered - self.refreshing = True - - def perf_process_events(self, source, condition): - had_events = True - while had_events: - had_events = False - for cpu in self.cpu_map: - event = self.evlist.read_on_cpu(cpu) - if event: - had_events = True - if event.type == perf.RECORD_FORK: - if event.pid == event.tid: - try: - self.ps.processes[event.pid] = procfs.process(event.pid) - except: # short lived thread - pass - else: - try: - self.ps.processes[event.pid].threads.processes[event.tid] = procfs.process(event.tid) - except AttributeError: - self.ps.processes[event.pid].threads = procfs.pidstats("/proc/%d/task/" % event.pid) - elif event.type == perf.RECORD_EXIT: - del self.ps[int(event.tid)] - elif event.type == perf.RECORD_SAMPLE: - tid = event.sample_tid - if tid in self.perf_counter: - self.perf_counter[tid] += event.sample_period - else: - self.perf_counter[tid] = event.sample_period - - self.show() - return True - - def perf_init(self): - self.cpu_map = perf.cpu_map() - self.thread_map = perf.thread_map() - self.evsel_cycles = perf.evsel(task = 1, comm = 1, - wakeup_events = 1, - watermark = 1, - sample_type = perf.SAMPLE_CPU | - perf.SAMPLE_TID) - self.evsel_cycles.open(cpus = self.cpu_map, threads = self.thread_map); - self.evlist = perf.evlist(self.cpu_map, self.thread_map) - self.evlist.add(self.evsel_cycles) - self.evlist.mmap() - self.pollfd = self.evlist.get_pollfd() - for f in self.pollfd: - GObject.io_add_watch(f, Gdk.INPUT_READ, self.perf_process_events) - self.perf_counter = {} - - def on_query_tooltip(self, treeview, x, y, keyboard_mode, tooltip): - x, y = treeview.convert_widget_to_bin_window_coords(x, y) - ret = treeview.get_path_at_pos(x, y) - tooltip.set_text(None) - if not ret: - return True - path, col, xpos, ypos = ret - if not path: - return True - col_id = col.get_sort_column_id() - if col_id != self.COL_CMDLINE: - return True - row = self.tree_store.get_iter(path) - if not row: - return True - pid = int(self.tree_store.get_value(row, self.COL_PID)) - if not tuna.iskthread(pid): - return True - cmdline = self.tree_store.get_value(row, self.COL_CMDLINE).split(' ')[0] - help = tuna.kthread_help(cmdline) - tooltip.set_markup("<b>%s %d(%s)</b>\n%s" % \ + nr_columns = 8 + (COL_PID, COL_POL, COL_PRI, COL_AFF, COL_VOLCTXT, COL_NONVOLCTXT, + COL_CGROUP, COL_CMDLINE) = list(range(nr_columns)) + columns = (gui.list_store_column(_("PID")), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), + gui.list_store_column(_("Priority")), + gui.list_store_column(_("Affinity"), GObject.TYPE_STRING), + gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) + + def __init__(self, treeview, ps, show_kthreads, show_uthreads, + cpus_filtered, gladefile): + self.ps = ps + self.treeview = treeview + self.nr_cpus = procfs.cpuinfo().nr_cpus + self.gladefile = gladefile + + self.evlist = None + try: + self.perf_init() + except: # No perf, poll /proc baby, poll + pass + + if "voluntary_ctxt_switches" not in ps[1]["status"]: + self.nr_columns = 5 + else: + self.nr_columns = 7 + try: + if ps[1]["cgroups"]: + self.nr_columns = self.nr_columns + 1 + except: + pass + + self.columns = (gui.list_store_column(_("PID")), + gui.list_store_column(_("Policy"), GObject.TYPE_STRING), + gui.list_store_column(_("Priority")), + gui.list_store_column(_("Affinity"), + GObject.TYPE_STRING)) + + if self.nr_columns == 5: + (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, + self.COL_CMDLINE) = list(range(self.nr_columns)) + self.columns = self.columns \ + + (gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) + + elif self.nr_columns == 6: + (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, + self.COL_CGROUP, self.COL_CMDLINE) = list(range(self.nr_columns)) + self.columns = self.columns \ + + (gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) + elif self.nr_columns == 7: + (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, \ + self.COL_VOLCTXT, self.NONVOLCTXT, self.COL_CMDLINE) \ + = list(range(self.nr_columns)) + self.columns = self.columns \ + + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) + + elif self.nr_columns == 8: + (self.COL_PID, self.COL_POL, self.COL_PRI, self.COL_AFF, \ + self.COL_VOLCTXT, self.COL_NONVOLCTXT, self.COL_CGROUP, \ + self.COL_CMDLINE) = list(range(self.nr_columns)) + self.columns = self.columns \ + + (gui.list_store_column(_("VolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("NonVolCtxtSwitch"), GObject.TYPE_UINT), + gui.list_store_column(_("CGroup"), GObject.TYPE_STRING), + gui.list_store_column(_("Command Line"), GObject.TYPE_STRING)) + + self.tree_store = Gtk.TreeStore(*gui.generate_list_store_columns_with_attr(self.columns)) + self.treeview.set_model(self.tree_store) + + # Allow selecting multiple rows + selection = treeview.get_selection() + selection.set_mode(Gtk.SelectionMode.MULTIPLE) + + # Allow enable drag and drop of rows + self.treeview.enable_model_drag_source( + Gdk.ModifierType.BUTTON1_MASK, gui.DND_TARGETS, + Gdk.DragAction.DEFAULT | Gdk.DragAction.MOVE) + self.treeview.connect("drag_data_get", self.on_drag_data_get_data) + try: + self.treeview.connect("query-tooltip", self.on_query_tooltip) + except: + # old versions of pygtk2+ doesn't have this signal + pass + + self.renderer = Gtk.CellRendererText() + for col in range(self.nr_columns): + column = Gtk.TreeViewColumn(self.columns[col].name, + self.renderer, text=col) + column.add_attribute(self.renderer, "weight", + col + self.nr_columns) + column.set_sort_column_id(col) + if col == self.COL_CGROUP: + column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + column.set_fixed_width(130) + try: + self.treeview.set_tooltip_column(col) + except: + # old versions of pygtk2+ doesn't have this signal + pass + column.set_resizable(True) + self.treeview.append_column(column) + + self.show_kthreads = show_kthreads + self.show_uthreads = show_uthreads + self.cpus_filtered = cpus_filtered + self.refreshing = True + + def perf_process_events(self, source, condition): + had_events = True + while had_events: + had_events = False + for cpu in self.cpu_map: + event = self.evlist.read_on_cpu(cpu) + if event: + had_events = True + if event.type == perf.RECORD_FORK: + if event.pid == event.tid: + try: + self.ps.processes[event.pid] = procfs.process(event.pid) + except: # short lived thread + pass + else: + try: + self.ps.processes[event.pid].threads.processes[event.tid] = procfs.process(event.tid) + except AttributeError: + self.ps.processes[event.pid].threads = procfs.pidstats("/proc/%d/task/" % event.pid) + elif event.type == perf.RECORD_EXIT: + del self.ps[int(event.tid)] + elif event.type == perf.RECORD_SAMPLE: + tid = event.sample_tid + if tid in self.perf_counter: + self.perf_counter[tid] += event.sample_period + else: + self.perf_counter[tid] = event.sample_period + + self.show() + return True + + def perf_init(self): + self.cpu_map = perf.cpu_map() + self.thread_map = perf.thread_map() + self.evsel_cycles = perf.evsel(task=1, comm=1, wakeup_events=1, \ + watermark=1, sample_type=perf.SAMPLE_CPU | perf.SAMPLE_TID) + self.evsel_cycles.open(cpus=self.cpu_map, threads=self.thread_map) + self.evlist = perf.evlist(self.cpu_map, self.thread_map) + self.evlist.add(self.evsel_cycles) + self.evlist.mmap() + self.pollfd = self.evlist.get_pollfd() + for f in self.pollfd: + GObject.io_add_watch(f, Gdk.INPUT_READ, self.perf_process_events) + self.perf_counter = {} + + def on_query_tooltip(self, treeview, x, y, keyboard_mode, tooltip): + x, y = treeview.convert_widget_to_bin_window_coords(x, y) + ret = treeview.get_path_at_pos(x, y) + tooltip.set_text(None) + if not ret: + return True + path, col, xpos, ypos = ret + if not path: + return True + col_id = col.get_sort_column_id() + if col_id != self.COL_CMDLINE: + return True + row = self.tree_store.get_iter(path) + if not row: + return True + pid = int(self.tree_store.get_value(row, self.COL_PID)) + if not tuna.iskthread(pid): + return True + cmdline = self.tree_store.get_value(row, self.COL_CMDLINE).split(' ')[0] + help = tuna.kthread_help(cmdline) + tooltip.set_markup("<b>%s %d(%s)</b>\n%s" % \ (_("Kernel Thread"), pid, cmdline, _(help))) - return True - - def foreach_selected_cb(self, model, path, iter, pid_list): - pid = model.get_value(iter, self.COL_PID) - pid_list.append(str(pid)) - - def on_drag_data_get_data(self, treeview, context, - selection, target_id, etime): - treeselection = treeview.get_selection() - pid_list = [] - treeselection.selected_foreach(self.foreach_selected_cb, pid_list) - selection.set(selection.target, 8, "pid:" + ",".join(pid_list)) - - def set_thread_columns(self, iter, tid, thread_info): - new_value = [ None ] * self.nr_columns - - new_value[self.COL_PRI] = int(thread_info["stat"]["rt_priority"]) - new_value[self.COL_POL] = schedutils.schedstr(schedutils.get_scheduler(tid))[6:] - thread_affinity_list = schedutils.get_affinity(tid) - - new_value[self.COL_PID] = tid - new_value[self.COL_AFF] = tuna.list_to_cpustring(thread_affinity_list) - try: - new_value[self.COL_VOLCTXT] = int(thread_info["status"]["voluntary_ctxt_switches"]) - new_value[self.COL_NONVOLCTXT] = int(thread_info["status"]["nonvoluntary_ctxt_switches"]) - new_value[self.COL_CGROUP] = thread_info["cgroups"] - except: - pass - - new_value[self.COL_CMDLINE] = procfs.process_cmdline(thread_info) - - gui.set_store_columns(self.tree_store, iter, new_value) - - def show(self, force_refresh = False): - # Start with the first row, if there is one, on the - # process list. If the first time update_rows will just - # have everything in new_tids and append_new_tids will - # create the rows. - if not self.refreshing and not force_refresh: - return - row = self.tree_store.get_iter_first() - self.update_rows(self.ps, row, None) - self.treeview.show_all() - - def update_rows(self, threads, row, parent_row): - new_tids = list(threads.keys()) - previous_row = None - while row: - tid = self.tree_store.get_value(row, self.COL_PID) - if previous_row: - previous_tid = self.tree_store.get_value(previous_row, self.COL_PID) - if previous_tid == tid: - # print "WARNING: tree_store dup %d, fixing..." % tid - self.tree_store.remove(previous_row) - if tid not in threads: - if self.tree_store.remove(row): - # removed and now row is the next one - continue - # removed and its the last one - break - else: - try: - new_tids.remove(tid) - except: - # FIXME: understand in what situation this - # can happen, seems harmless from visual - # inspection. - pass - if tuna.thread_filtered(tid, self.cpus_filtered, - self.show_kthreads, - self.show_uthreads): - if self.tree_store.remove(row): - # removed and now row is the next one - continue - # removed and its the last one - break - else: - try: - self.set_thread_columns(row, tid, threads[tid]) - - if "threads" in threads[tid]: - children = threads[tid]["threads"] - else: - children = {} - - child_row = self.tree_store.iter_children(row) - self.update_rows(children, child_row, row) - except: # thread doesn't exists anymore - if self.tree_store.remove(row): - # removed and now row is the next one - continue - # removed and its the last one - break - - previous_row = row - row = self.tree_store.iter_next(row) - - new_tids.sort() - self.append_new_tids(parent_row, threads, new_tids) - - def append_new_tids(self, parent_row, threads, tid_list): - for tid in tid_list: - if tuna.thread_filtered(tid, self.cpus_filtered, - self.show_kthreads, - self.show_uthreads): - continue - - row = self.tree_store.append(parent_row) - - try: - self.set_thread_columns(row, tid, threads[tid]) - except: # Thread doesn't exists anymore - self.tree_store.remove(row) - continue - - if "threads" in threads[tid]: - children = threads[tid]["threads"] - children_list = list(children.keys()) - children_list.sort() - for child in children_list: - child_row = self.tree_store.append(row) - try: - self.set_thread_columns(child_row, - child, - children[child]) - except: # Thread doesn't exists anymore - self.tree_store.remove(child_row) - - def refresh(self): - self.ps.reload() - self.ps.reload_threads() - - self.show(True) - - def edit_attributes(self, a): - ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) - if not ret: - return - path, col, xpos, ypos = ret - if not path: - return - row = self.tree_store.get_iter(path) - pid = self.tree_store.get_value(row, self.COL_PID) - if pid in self.ps: - pid_info = self.ps[pid] - else: - parent = self.tree_store.iter_parent(row) - ppid = self.tree_store.get_value(parent, self.COL_PID) - pid_info = self.ps[ppid].threads[pid] - - dialog = process_druid(self.ps, pid, pid_info, self.nr_cpus, - self.gladefile) - if dialog.run(): - self.refresh() - - def kthreads_view_toggled(self, a): - self.show_kthreads = not self.show_kthreads - self.show(True) - - def uthreads_view_toggled(self, a): - self.show_uthreads = not self.show_uthreads - self.show(True) - - def help_dialog(self, a): - ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) - if not ret: - return - path, col, xpos, ypos = ret - if not path: - return - row = self.tree_store.get_iter(path) - pid = self.tree_store.get_value(row, self.COL_PID) - if pid not in self.ps: - return - - cmdline = self.tree_store.get_value(row, self.COL_CMDLINE) - help, title = tuna.kthread_help_plain_text(pid, cmdline) - - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.INFO, - Gtk.ButtonsType.OK, _(help)) - dialog.set_title(title) - ret = dialog.run() - dialog.destroy() - - def refresh_toggle(self, a): - self.refreshing = not self.refreshing - - def save_kthreads_tunings(self, a): - dialog = Gtk.FileChooserDialog(_("Save As"), - None, - Gtk.FileChooserAction.SAVE, - (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, - Gtk.STOCK_OK, Gtk.ResponseType.OK)) - dialog.set_default_response(Gtk.ResponseType.OK) - - try: - dialog.set_do_overwrite_confirmation(True) - except: - pass - - filter = Gtk.FileFilter() - filter.set_name("rtctl config files") - filter.add_pattern("*.rtctl") - filter.add_pattern("*.tuna") - filter.add_pattern("*rtgroup*") - dialog.add_filter(filter) - - filter = Gtk.FileFilter() - filter.set_name("All files") - filter.add_pattern("*") - dialog.add_filter(filter) - - response = dialog.run() - - filename = dialog.get_filename() - dialog.destroy() - - if response != Gtk.ResponseType.OK: - return - - self.refresh() - kthreads = tuna.get_kthread_sched_tunings(self.ps) - tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) - - if filename != "/etc/rtgroups": - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.INFO, - Gtk.ButtonsType.YES_NO, - "Kernel thread tunings saved!\n\n" - "Now you can use it with rtctl:\n\n" - "rtctl --file %s reset\n\n" - "If you want the changes to be in " - "effect every time you boot the system " - "please move %s to /etc/rtgroups\n\n" - "Do you want to do that now?" % (filename, filename)) - response = dialog.run() - dialog.destroy() - if response == Gtk.ResponseType.YES: - filename = "/etc/rtgroups" - tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) - - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - Gtk.MessageType.INFO, - Gtk.ButtonsType.OK, - _("Kernel thread tunings saved to %s!") % filename) - dialog.run() - dialog.destroy() - - def on_processlist_button_press_event(self, treeview, event): - if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: - return - - self.last_x = int(event.x) - self.last_y = int(event.y) - - menu = Gtk.Menu() - - setattr = Gtk.MenuItem(_("_Set process attributes")) - if self.refreshing: - refresh = Gtk.MenuItem(_("Sto_p refreshing the process list")) - else: - refresh = Gtk.MenuItem(_("_Refresh the process list")) - - if self.show_kthreads: - kthreads = Gtk.MenuItem(_("_Hide kernel threads")) - else: - kthreads = Gtk.MenuItem(_("_Show kernel threads")) - - if self.show_uthreads: - uthreads = Gtk.MenuItem(_("_Hide user threads")) - else: - uthreads = Gtk.MenuItem(_("_Show user threads")) - - help = Gtk.MenuItem(_("_What is this?")) - - save_kthreads_tunings = Gtk.MenuItem(_("_Save kthreads tunings")) - - menu.add(save_kthreads_tunings) - menu.add(setattr) - menu.add(refresh) - menu.add(kthreads) - menu.add(uthreads) - menu.add(help) - - save_kthreads_tunings.connect_object('activate', + return True + + def foreach_selected_cb(self, model, path, iter, pid_list): + pid = model.get_value(iter, self.COL_PID) + pid_list.append(str(pid)) + + def on_drag_data_get_data(self, treeview, context, selection, + target_id, etime): + treeselection = treeview.get_selection() + pid_list = [] + treeselection.selected_foreach(self.foreach_selected_cb, pid_list) + selection.set(selection.target, 8, "pid:" + ",".join(pid_list)) + + def set_thread_columns(self, iter, tid, thread_info): + new_value = [None] * self.nr_columns + + new_value[self.COL_PRI] = int(thread_info["stat"]["rt_priority"]) + new_value[self.COL_POL] = schedutils.schedstr(schedutils.get_scheduler(tid))[6:] + thread_affinity_list = schedutils.get_affinity(tid) + + new_value[self.COL_PID] = tid + new_value[self.COL_AFF] = tuna.list_to_cpustring(thread_affinity_list) + try: + new_value[self.COL_VOLCTXT] = int(thread_info["status"]["voluntary_ctxt_switches"]) + new_value[self.COL_NONVOLCTXT] \ + = int(thread_info["status"]["nonvoluntary_ctxt_switches"]) + new_value[self.COL_CGROUP] = thread_info["cgroups"] + except: + pass + + new_value[self.COL_CMDLINE] = procfs.process_cmdline(thread_info) + + gui.set_store_columns(self.tree_store, iter, new_value) + + def show(self, force_refresh=False): + # Start with the first row, if there is one, on the + # process list. If the first time update_rows will just + # have everything in new_tids and append_new_tids will + # create the rows. + if not self.refreshing and not force_refresh: + return + row = self.tree_store.get_iter_first() + self.update_rows(self.ps, row, None) + self.treeview.show_all() + + def update_rows(self, threads, row, parent_row): + new_tids = list(threads.keys()) + previous_row = None + while row: + tid = self.tree_store.get_value(row, self.COL_PID) + if previous_row: + previous_tid = self.tree_store.get_value(previous_row, self.COL_PID) + if previous_tid == tid: + # print "WARNING: tree_store dup %d, fixing..." % tid + self.tree_store.remove(previous_row) + if tid not in threads: + if self.tree_store.remove(row): + # removed and now row is the next one + continue + # removed and its the last one + break + else: + try: + new_tids.remove(tid) + except: + # FIXME: understand in what situation this + # can happen, seems harmless from visual + # inspection. + pass + if tuna.thread_filtered(tid, self.cpus_filtered, + self.show_kthreads, self.show_uthreads): + if self.tree_store.remove(row): + # removed and now row is the next one + continue + # removed and its the last one + break + else: + try: + self.set_thread_columns(row, tid, threads[tid]) + if "threads" in threads[tid]: + children = threads[tid]["threads"] + else: + children = {} + child_row = self.tree_store.iter_children(row) + self.update_rows(children, child_row, row) + except: # thread doesn't exists anymore + if self.tree_store.remove(row): + # removed and now row is the next one + continue + # removed and its the last one + break + + previous_row = row + row = self.tree_store.iter_next(row) + + new_tids.sort() + self.append_new_tids(parent_row, threads, new_tids) + + def append_new_tids(self, parent_row, threads, tid_list): + for tid in tid_list: + if tuna.thread_filtered(tid, self.cpus_filtered, self.show_kthreads, + self.show_uthreads): + continue + + row = self.tree_store.append(parent_row) + + try: + self.set_thread_columns(row, tid, threads[tid]) + except: # Thread doesn't exists anymore + self.tree_store.remove(row) + continue + + if "threads" in threads[tid]: + children = threads[tid]["threads"] + children_list = list(children.keys()) + children_list.sort() + for child in children_list: + child_row = self.tree_store.append(row) + try: + self.set_thread_columns(child_row, child, + children[child]) + except: # Thread doesn't exists anymore + self.tree_store.remove(child_row) + + def refresh(self): + self.ps.reload() + self.ps.reload_threads() + + self.show(True) + + def edit_attributes(self, a): + ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) + if not ret: + return + path, col, xpos, ypos = ret + if not path: + return + row = self.tree_store.get_iter(path) + pid = self.tree_store.get_value(row, self.COL_PID) + if pid in self.ps: + pid_info = self.ps[pid] + else: + parent = self.tree_store.iter_parent(row) + ppid = self.tree_store.get_value(parent, self.COL_PID) + pid_info = self.ps[ppid].threads[pid] + + dialog = process_druid(self.ps, pid, pid_info, self.nr_cpus, + self.gladefile) + if dialog.run(): + self.refresh() + + def kthreads_view_toggled(self, a): + self.show_kthreads = not self.show_kthreads + self.show(True) + + def uthreads_view_toggled(self, a): + self.show_uthreads = not self.show_uthreads + self.show(True) + + def help_dialog(self, a): + ret = self.treeview.get_path_at_pos(self.last_x, self.last_y) + if not ret: + return + path, col, xpos, ypos = ret + if not path: + return + row = self.tree_store.get_iter(path) + pid = self.tree_store.get_value(row, self.COL_PID) + if pid not in self.ps: + return + + cmdline = self.tree_store.get_value(row, self.COL_CMDLINE) + help, title = tuna.kthread_help_plain_text(pid, cmdline) + + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, _(help)) + dialog.set_title(title) + ret = dialog.run() + dialog.destroy() + + def refresh_toggle(self, a): + self.refreshing = not self.refreshing + + def save_kthreads_tunings(self, a): + dialog = Gtk.FileChooserDialog(_("Save As"), None, \ + Gtk.FileChooserAction.SAVE, \ + (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, \ + Gtk.STOCK_OK, Gtk.ResponseType.OK)) + dialog.set_default_response(Gtk.ResponseType.OK) + + try: + dialog.set_do_overwrite_confirmation(True) + except: + pass + + filter = Gtk.FileFilter() + filter.set_name("rtctl config files") + filter.add_pattern("*.rtctl") + filter.add_pattern("*.tuna") + filter.add_pattern("*rtgroup*") + dialog.add_filter(filter) + + filter = Gtk.FileFilter() + filter.set_name("All files") + filter.add_pattern("*") + dialog.add_filter(filter) + + response = dialog.run() + + filename = dialog.get_filename() + dialog.destroy() + + if response != Gtk.ResponseType.OK: + return + + self.refresh() + kthreads = tuna.get_kthread_sched_tunings(self.ps) + tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) + + if filename != "/etc/rtgroups": + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.INFO, Gtk.ButtonsType.YES_NO, \ + "Kernel thread tunings saved!\n\n" \ + "Now you can use it with rtctl:\n\n" \ + "rtctl --file %s reset\n\n" \ + "If you want the changes to be in " \ + "effect every time you boot the system " \ + "please move %s to /etc/rtgroups\n\n" \ + "Do you want to do that now?" % (filename, filename)) + response = dialog.run() + dialog.destroy() + if response == Gtk.ResponseType.YES: + filename = "/etc/rtgroups" + tuna.generate_rtgroups(filename, kthreads, self.nr_cpus) + + dialog = Gtk.MessageDialog(None, \ + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, \ + Gtk.MessageType.INFO, Gtk.ButtonsType.OK, \ + _("Kernel thread tunings saved to %s!") % filename) + dialog.run() + dialog.destroy() + + def on_processlist_button_press_event(self, treeview, event): + if event.type != Gdk.EventType.BUTTON_PRESS or event.button != 3: + return + + self.last_x = int(event.x) + self.last_y = int(event.y) + + menu = Gtk.Menu() + + setattr = Gtk.MenuItem(_("_Set process attributes")) + if self.refreshing: + refresh = Gtk.MenuItem(_("Sto_p refreshing the process list")) + else: + refresh = Gtk.MenuItem(_("_Refresh the process list")) + + if self.show_kthreads: + kthreads = Gtk.MenuItem(_("_Hide kernel threads")) + else: + kthreads = Gtk.MenuItem(_("_Show kernel threads")) + + if self.show_uthreads: + uthreads = Gtk.MenuItem(_("_Hide user threads")) + else: + uthreads = Gtk.MenuItem(_("_Show user threads")) + + help = Gtk.MenuItem(_("_What is this?")) + + save_kthreads_tunings = Gtk.MenuItem(_("_Save kthreads tunings")) + + menu.add(save_kthreads_tunings) + menu.add(setattr) + menu.add(refresh) + menu.add(kthreads) + menu.add(uthreads) + menu.add(help) + + save_kthreads_tunings.connect_object('activate', self.save_kthreads_tunings, event) - setattr.connect_object('activate', self.edit_attributes, event) - refresh.connect_object('activate', self.refresh_toggle, event) - kthreads.connect_object('activate', self.kthreads_view_toggled, event) - uthreads.connect_object('activate', self.uthreads_view_toggled, event) - help.connect_object('activate', self.help_dialog, event) - - save_kthreads_tunings.show() - setattr.show() - refresh.show() - kthreads.show() - uthreads.show() - help.show() - - menu.popup(None, None, None, event.button, event.time) - - def toggle_mask_cpu(self, cpu, enabled): - if not enabled: - if cpu not in self.cpus_filtered: - self.cpus_filtered.append(cpu) - self.show(True) - else: - if cpu in self.cpus_filtered: - self.cpus_filtered.remove(cpu) - self.show(True) + setattr.connect_object('activate', self.edit_attributes, event) + refresh.connect_object('activate', self.refresh_toggle, event) + kthreads.connect_object('activate', self.kthreads_view_toggled, event) + uthreads.connect_object('activate', self.uthreads_view_toggled, event) + help.connect_object('activate', self.help_dialog, event) + + save_kthreads_tunings.show() + setattr.show() + refresh.show() + kthreads.show() + uthreads.show() + help.show() + + menu.popup(None, None, None, event.button, event.time) + + def toggle_mask_cpu(self, cpu, enabled): + if not enabled: + if cpu not in self.cpus_filtered: + self.cpus_filtered.append(cpu) + self.show(True) + else: + if cpu in self.cpus_filtered: + self.cpus_filtered.remove(cpu) + self.show(True)
Update the spacing and style for tuna-cmd
Signed-off-by: John Kacur jkacur@redhat.com --- tuna-cmd.py | 1222 +++++++++++++++++++++++++-------------------------- 1 file changed, 608 insertions(+), 614 deletions(-)
diff --git a/tuna-cmd.py b/tuna-cmd.py index f49674787662..ebadbe1e240a 100755 --- a/tuna-cmd.py +++ b/tuna-cmd.py @@ -22,16 +22,16 @@ import locale from functools import reduce
try: - import inet_diag - have_inet_diag = True + import inet_diag + have_inet_diag = True except: - have_inet_diag = False + have_inet_diag = False
try: - set + set except NameError: - # In python < 2.4, "set" is not the first class citizen. - from sets import Set as set + # In python < 2.4, "set" is not the first class citizen. + from sets import Set as set
# FIXME: ETOOMANYGLOBALS, we need a class!
@@ -41,671 +41,665 @@ irqs = None version = "0.14.1"
def usage(): - print(_('Usage: tuna [OPTIONS]')) - fmt = '\t%-40s %s' - print(fmt % ('-h, --help', _('Give this help list'))) - print(fmt % ('-a, --config_file_apply=profilename', _('Apply changes described in profile'))) - print(fmt % ('-l, --config_file_list', _('List preloaded profiles'))) - print(fmt % ('-g, --gui', _('Start the GUI'))) - print(fmt % ('-G, --cgroup', _('Display the processes with the type of cgroups they are in'))) - print(fmt % ('-c, --cpus=' + _('CPU-LIST'), _('%(cpulist)s affected by commands') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-C, --affect_children', _('Operation will affect children threads'))) - print(fmt % ('-f, --filter', _('Display filter the selected entities'))) - print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-I, --include', _('Allow all threads to run on %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-K, --no_kthreads', _('Operations will not affect kernel threads'))) - print(fmt % ('-m, --move', _('Move selected entities to %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) - print(fmt % ('-N, --nohz_full', _('CPUs in nohz_full= kernel command line will be affected by operations'))) - if have_inet_diag: - print(fmt % ('-n, --show_sockets', _('Show network sockets in use by threads'))) - print(fmt % ('-p, --priority=[' + - _('POLICY') + ':]' + - _('RTPRIO'), _('Set thread scheduler tunables: %(policy)s and %(rtprio)s') % \ - {"policy": _('POLICY'), "rtprio": _('RTPRIO')})) - print(fmt % ('-P, --show_threads', _('Show thread list'))) - print(fmt % ('-Q, --show_irqs', _('Show IRQ list'))) - print(fmt % ('-q, --irqs=' + _('IRQ-LIST'), _('%(irqlist)s affected by commands') % - {"irqlist": _('IRQ-LIST')})) - print(fmt % ('-r, --run=' + _('COMMAND'), _('fork a new process and run the %(command)s') % \ - {"command": _('COMMAND')})) - print(fmt % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % \ - {"filename": _('FILENAME')})) - print(fmt % ('-S, --sockets=' + - _('CPU-SOCKET-LIST'), _('%(cpusocketlist)s affected by commands') % \ - {"cpusocketlist": _('CPU-SOCKET-LIST')})) - print(fmt % ('-t, --threads=' + - _('THREAD-LIST'), _('%(threadlist)s affected by commands') % \ - {"threadlist": _('THREAD-LIST')})) - print(fmt % ('-U, --no_uthreads', _('Operations will not affect user threads'))) - print(fmt % ('-v, --version', _('Show version'))) - print(fmt % ('-W, --what_is', _('Provides help about selected entities'))) - print(fmt % ('-x, --spread', _('Spread selected entities over %(cpulist)s') % \ - {"cpulist": _('CPU-LIST')})) + print(_('Usage: tuna [OPTIONS]')) + fmt = '\t%-40s %s' + print(fmt % ('-h, --help', _('Give this help list'))) + print(fmt % ('-a, --config_file_apply=profilename', _('Apply changes described in profile'))) + print(fmt % ('-l, --config_file_list', _('List preloaded profiles'))) + print(fmt % ('-g, --gui', _('Start the GUI'))) + print(fmt % ('-G, --cgroup', _('Display the processes with the type of cgroups they are in'))) + print(fmt % ('-c, --cpus=' + _('CPU-LIST'), _('%(cpulist)s affected by commands') % \ + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-C, --affect_children', _('Operation will affect children threads'))) + print(fmt % ('-f, --filter', _('Display filter the selected entities'))) + print(fmt % ('-i, --isolate', _('Move all threads away from %(cpulist)s') % \ + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-I, --include', _('Allow all threads to run on %(cpulist)s') % \ + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-K, --no_kthreads', _('Operations will not affect kernel threads'))) + print(fmt % ('-m, --move', _('Move selected entities to %(cpulist)s') % \ + {"cpulist": _('CPU-LIST')})) + print(fmt % ('-N, --nohz_full', _('CPUs in nohz_full= kernel command line will be affected by operations'))) + if have_inet_diag: + print(fmt % ('-n, --show_sockets', _('Show network sockets in use by threads'))) + print(fmt % ('-p, --priority=[' + + _('POLICY') + ':]' + + _('RTPRIO'), _('Set thread scheduler tunables: %(policy)s and %(rtprio)s') % \ + {"policy": _('POLICY'), "rtprio": _('RTPRIO')})) + print(fmt % ('-P, --show_threads', _('Show thread list'))) + print(fmt % ('-Q, --show_irqs', _('Show IRQ list'))) + print(fmt % ('-q, --irqs=' + _('IRQ-LIST'), _('%(irqlist)s affected by commands') % + {"irqlist": _('IRQ-LIST')})) + print(fmt % ('-r, --run=' + _('COMMAND'), _('fork a new process and run the %(command)s') % \ + {"command": _('COMMAND')})) + print(fmt % ('-s, --save=' + _('FILENAME'), _('Save kthreads sched tunables to %(filename)s') % \ + {"filename": _('FILENAME')})) + print(fmt % ('-S, --sockets=' + + _('CPU-SOCKET-LIST'), _('%(cpusocketlist)s affected by commands') % \ + {"cpusocketlist": _('CPU-SOCKET-LIST')})) + print(fmt % ('-t, --threads=' + + _('THREAD-LIST'), _('%(threadlist)s affected by commands') % \ + {"threadlist": _('THREAD-LIST')})) + print(fmt % ('-U, --no_uthreads', _('Operations will not affect user threads'))) + print(fmt % ('-v, --version', _('Show version'))) + print(fmt % ('-W, --what_is', _('Provides help about selected entities'))) + print(fmt % ('-x, --spread', _('Spread selected entities over %(cpulist)s') % \ + {"cpulist": _('CPU-LIST')}))
def get_nr_cpus(): - global nr_cpus - if nr_cpus: - return nr_cpus - nr_cpus = procfs.cpuinfo().nr_cpus + global nr_cpus + if nr_cpus: return nr_cpus + nr_cpus = procfs.cpuinfo().nr_cpus + return nr_cpus
nics = None
def get_nics(): - global nics - if nics: - return nics - nics = ethtool.get_active_devices() + global nics + if nics: return nics + nics = ethtool.get_active_devices() + return nics
def thread_help(tid): - global ps - if not ps: - ps = procfs.pidstats() + global ps + if not ps: + ps = procfs.pidstats()
- if tid not in ps: - print("tuna: " + _("thread %d doesn't exists!") % tid) - return + if tid not in ps: + print("tuna: " + _("thread %d doesn't exists!") % tid) + return
- pinfo = ps[tid] - cmdline = procfs.process_cmdline(pinfo) - help, title = tuna.kthread_help_plain_text(tid, cmdline) - print("%s\n\n%s" % (title, _(help))) + pinfo = ps[tid] + cmdline = procfs.process_cmdline(pinfo) + help, title = tuna.kthread_help_plain_text(tid, cmdline) + print("%s\n\n%s" % (title, _(help)))
def save(cpu_list, thread_list, filename): - kthreads = tuna.get_kthread_sched_tunings() - for name in list(kthreads.keys()): - kt = kthreads[name] - if (cpu_list and not set(kt.affinity).intersection(set(cpu_list))) or \ - (thread_list and kt.pid not in thread_list) : - del kthreads[name] - tuna.generate_rtgroups(filename, kthreads, get_nr_cpus()) - -def ps_show_header(has_ctxt_switch_info,cgroups = False): - print("%7s %6s %5s %7s %s" % \ - (" ", " ", " ", _("thread"), - has_ctxt_switch_info and "ctxt_switches" or "")) - print("%7s %6s %5s %7s%s %15s" % \ - ("pid", "SCHED_", "rtpri", "affinity", - has_ctxt_switch_info and " %9s %12s" % ("voluntary", "nonvoluntary") or "", - "cmd"), end=' ') - if cgroups: - print(" %7s" % ("cgroup")) - else: - print("") + kthreads = tuna.get_kthread_sched_tunings() + for name in list(kthreads.keys()): + kt = kthreads[name] + if (cpu_list and not set(kt.affinity).intersection(set(cpu_list))) or \ + (thread_list and kt.pid not in thread_list): + del kthreads[name] + tuna.generate_rtgroups(filename, kthreads, get_nr_cpus()) + +def ps_show_header(has_ctxt_switch_info, cgroups=False): + print("%7s %6s %5s %7s %s" % \ + (" ", " ", " ", _("thread"), + has_ctxt_switch_info and "ctxt_switches" or "")) + print("%7s %6s %5s %7s%s %15s" % \ + ("pid", "SCHED_", "rtpri", "affinity", + has_ctxt_switch_info and " %9s %12s" % ("voluntary", "nonvoluntary") or "", + "cmd"), end=' ') + if cgroups: + print(" %7s" % ("cgroup")) + else: + print("")
-def ps_show_sockets(pid, ps, inodes, inode_re, indent = 0): - header_printed = False - dirname = "/proc/%s/fd" % pid +def ps_show_sockets(pid, ps, inodes, inode_re, indent=0): + header_printed = False + dirname = "/proc/%s/fd" % pid + try: + filenames = os.listdir(dirname) + except: # Process died + return + sindent = " " * indent + for filename in filenames: + pathname = os.path.join(dirname, filename) try: - filenames = os.listdir(dirname) + linkto = os.readlink(pathname) except: # Process died - return - sindent = " " * indent - for filename in filenames: - pathname = os.path.join(dirname, filename) - try: - linkto = os.readlink(pathname) - except: # Process died - continue - inode_match = inode_re.match(linkto) - if not inode_match: - continue - inode = int(inode_match.group(1)) - if inode not in inodes: - continue - if not header_printed: - print("%s%-10s %-6s %-6s %15s:%-5s %15s:%-5s" % \ - (sindent, "State", "Recv-Q", "Send-Q", - "Local Address", "Port", - "Peer Address", "Port")) - header_printed = True - s = inodes[inode] - print("%s%-10s %-6d %-6d %15s:%-5d %15s:%-5d" % \ - (sindent, s.state(), - s.receive_queue(), s.write_queue(), - s.saddr(), s.sport(), s.daddr(), s.dport())) + continue + inode_match = inode_re.match(linkto) + if not inode_match: + continue + inode = int(inode_match.group(1)) + if inode not in inodes: + continue + if not header_printed: + print("%s%-10s %-6s %-6s %15s:%-5s %15s:%-5s" % \ + (sindent, "State", "Recv-Q", "Send-Q", + "Local Address", "Port", + "Peer Address", "Port")) + header_printed = True + s = inodes[inode] + print("%s%-10s %-6d %-6d %15s:%-5d %15s:%-5d" % \ + (sindent, s.state(), + s.receive_queue(), s.write_queue(), + s.saddr(), s.sport(), s.daddr(), s.dport()))
def format_affinity(affinity): - if len(affinity) <= 4: - return ",".join(str(a) for a in affinity) - - return ",".join(str(hex(a)) for a in procfs.hexbitmask(affinity, get_nr_cpus())) - -def ps_show_thread(pid, affect_children, ps, - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups): - global irqs + if len(affinity) <= 4: + return ",".join(str(a) for a in affinity) + + return ",".join(str(hex(a)) for a in procfs.hexbitmask(affinity, get_nr_cpus())) + +def ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, sock_inodes, + sock_inode_re, cgroups): + global irqs + try: + affinity = format_affinity(schedutils.get_affinity(pid)) + except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError + if e.args[0] == errno.ESRCH: + return + raise e + + sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] + rtprio = int(ps[pid]["stat"]["rt_priority"]) + cgout = ps[pid]["cgroups"] + cmd = ps[pid]["stat"]["comm"] + users = "" + if tuna.is_irq_thread(cmd): try: - affinity = format_affinity(schedutils.get_affinity(pid)) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - return - raise e - - sched = schedutils.schedstr(schedutils.get_scheduler(pid))[6:] - rtprio = int(ps[pid]["stat"]["rt_priority"]) - cgout = ps[pid]["cgroups"] - cmd = ps[pid]["stat"]["comm"] - users = "" - if tuna.is_irq_thread(cmd): + if not irqs: + irqs = procfs.interrupts() + if cmd[:4] == "IRQ-": + users = irqs[tuna.irq_thread_number(cmd)]["users"] + for u in users: + if u in get_nics(): + users[users.index(u)] = "%s(%s)" % (u, ethtool.get_module(u)) + users = ",".join(users) + else: + u = cmd[cmd.find('-') + 1:] + if u in get_nics(): + users = ethtool.get_module(u) + except: + users = "Not found in /proc/interrupts!" + + ctxt_switch_info = "" + if has_ctxt_switch_info: + voluntary_ctxt_switches = int(ps[pid]["status"]["voluntary_ctxt_switches"]) + nonvoluntary_ctxt_switches = int(ps[pid]["status"]["nonvoluntary_ctxt_switches"]) + ctxt_switch_info = " %9d %12s" % (voluntary_ctxt_switches, + nonvoluntary_ctxt_switches) + + if affect_children: + print(" %-5d " % pid, end=' ') + else: + print(" %-5d" % pid, end=' ') + print("%6s %5d %8s%s %15s %s" % (sched, rtprio, affinity, + ctxt_switch_info, cmd, users), end=' ') + if cgroups: + print(" %9s" % cgout, end=' ') + print("") + if sock_inodes: + ps_show_sockets(pid, ps, sock_inodes, sock_inode_re, + affect_children and 3 or 4) + if affect_children and "threads" in ps[pid]: + for tid in list(ps[pid]["threads"].keys()): + ps_show_thread(tid, False, ps[pid]["threads"], + has_ctxt_switch_info, + sock_inodes, sock_inode_re, cgroups) + + +def ps_show(ps, affect_children, thread_list, cpu_list, \ + irq_list_numbers, show_uthreads, show_kthreads, \ + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups): + + ps_list = [] + for pid in list(ps.keys()): + iskth = tuna.iskthread(pid) + if not show_uthreads and not iskth: + continue + if not show_kthreads and iskth: + continue + in_irq_list = False + if irq_list_numbers: + if tuna.is_hardirq_handler(ps, pid): try: - if not irqs: - irqs = procfs.interrupts() - if cmd[:4] == "IRQ-": - users = irqs[tuna.irq_thread_number(cmd)]["users"] - for u in users: - if u in get_nics(): - users[users.index(u)] = "%s(%s)" % (u, ethtool.get_module(u)) - users = ",".join(users) - else: - u = cmd[cmd.find('-') + 1:] - if u in get_nics(): - users = ethtool.get_module(u) + irq = int(ps[pid]["stat"]["comm"][4:]) + if irq not in irq_list_numbers: + if not thread_list: + continue + else: + in_irq_list = True except: - users = "Not found in /proc/interrupts!" - - ctxt_switch_info = "" - if has_ctxt_switch_info: - voluntary_ctxt_switches = int(ps[pid]["status"]["voluntary_ctxt_switches"]) - nonvoluntary_ctxt_switches = int(ps[pid]["status"]["nonvoluntary_ctxt_switches"]) - ctxt_switch_info = " %9d %12s" % (voluntary_ctxt_switches, - nonvoluntary_ctxt_switches) - - if affect_children: - print(" %-5d " % pid, end=' ') - else: - print(" %-5d" % pid, end=' ') - print("%6s %5d %8s%s %15s %s" % (sched, rtprio, affinity, - ctxt_switch_info, cmd, users), end=' ') - if cgroups: - print(" %9s" % cgout, end=' ') - print("") - if sock_inodes: - ps_show_sockets(pid, ps, sock_inodes, sock_inode_re, - affect_children and 3 or 4) - if affect_children and "threads" in ps[pid]: - for tid in list(ps[pid]["threads"].keys()): - ps_show_thread(tid, False, ps[pid]["threads"], - has_ctxt_switch_info, - sock_inodes, sock_inode_re, cgroups) - - -def ps_show(ps, affect_children, thread_list, cpu_list, - irq_list_numbers, show_uthreads, show_kthreads, - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups): - - ps_list = [] - for pid in list(ps.keys()): - iskth = tuna.iskthread(pid) - if not show_uthreads and not iskth: - continue - if not show_kthreads and iskth: - continue - in_irq_list = False - if irq_list_numbers: - if tuna.is_hardirq_handler(ps, pid): - try: - irq = int(ps[pid]["stat"]["comm"][4:]) - if irq not in irq_list_numbers: - if not thread_list: - continue - else: - in_irq_list = True - except: - pass - elif not thread_list: - continue - if not in_irq_list and thread_list and pid not in thread_list: - continue - try: - affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if cpu_list and not set(cpu_list).intersection(set(affinity)): - continue - ps_list.append(pid) - - ps_list.sort() - - for pid in ps_list: - ps_show_thread(pid, affect_children, ps, - has_ctxt_switch_info, sock_inodes, - sock_inode_re, cgroups) + pass + elif not thread_list: + continue + if not in_irq_list and thread_list and pid not in thread_list: + continue + try: + affinity = schedutils.get_affinity(pid) + except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError + if e.args[0] == errno.ESRCH: + continue + raise e + if cpu_list and not set(cpu_list).intersection(set(affinity)): + continue + ps_list.append(pid) + + ps_list.sort() + + for pid in ps_list: + ps_show_thread(pid, affect_children, ps, has_ctxt_switch_info, + sock_inodes, sock_inode_re, cgroups)
def load_socktype(socktype, inodes): - idiag = inet_diag.create(socktype = socktype) - while True: - try: - s = idiag.get() - except: - break - inodes[s.inode()] = s + idiag = inet_diag.create(socktype=socktype) + while True: + try: + s = idiag.get() + except: + break + inodes[s.inode()] = s
def load_sockets(): - inodes = {} - for socktype in (inet_diag.TCPDIAG_GETSOCK, - inet_diag.DCCPDIAG_GETSOCK): - load_socktype(socktype, inodes) - return inodes - -def do_ps(thread_list, cpu_list, irq_list, show_uthreads, - show_kthreads, affect_children, show_sockets, cgroups): - ps = procfs.pidstats() - if affect_children: - ps.reload_threads() - - sock_inodes = None - sock_inode_re = None - if show_sockets: - sock_inodes = load_sockets() - sock_inode_re = re.compile(r"socket:[(\d+)]") - - has_ctxt_switch_info = "voluntary_ctxt_switches" in ps[1]["status"] - try: - if sys.stdout.isatty(): - ps_show_header(has_ctxt_switch_info, cgroups) - ps_show(ps, affect_children, thread_list, - cpu_list, irq_list, show_uthreads, show_kthreads, - has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups) - except IOError: - # 'tuna -P | head' for instance - pass + inodes = {} + for socktype in (inet_diag.TCPDIAG_GETSOCK, inet_diag.DCCPDIAG_GETSOCK): + load_socktype(socktype, inodes) + return inodes + +def do_ps(thread_list, cpu_list, irq_list, show_uthreads, show_kthreads, + affect_children, show_sockets, cgroups): + ps = procfs.pidstats() + if affect_children: + ps.reload_threads() + + sock_inodes = None + sock_inode_re = None + if show_sockets: + sock_inodes = load_sockets() + sock_inode_re = re.compile(r"socket:[(\d+)]") + + has_ctxt_switch_info = "voluntary_ctxt_switches" in ps[1]["status"] + try: + if sys.stdout.isatty(): + ps_show_header(has_ctxt_switch_info, cgroups) + ps_show(ps, affect_children, thread_list, \ + cpu_list, irq_list, show_uthreads, show_kthreads, \ + has_ctxt_switch_info, sock_inodes, sock_inode_re, cgroups) + except IOError: + # 'tuna -P | head' for instance + pass
def find_drivers_by_users(users): - nics = get_nics() - drivers = [] - for u in users: - try: - idx = u.index('-') - u = u[:idx] - except: - pass - if u in nics: - driver = ethtool.get_module(u) - if driver not in drivers: - drivers.append(driver) - - return drivers + nics = get_nics() + drivers = [] + for u in users: + try: + idx = u.index('-') + u = u[:idx] + except: + pass + if u in nics: + driver = ethtool.get_module(u) + if driver not in drivers: + drivers.append(driver)
-def show_irqs(irq_list, cpu_list): - global irqs - if not irqs: - irqs = procfs.interrupts() + return drivers
- if sys.stdout.isatty(): - print("%4s %-16s %8s" % ("#", _("users"), _("affinity"),)) - sorted_irqs = [] - for k in list(irqs.keys()): - try: - irqn = int(k) - affinity = irqs[irqn]["affinity"] - except: - continue - if irq_list and irqn not in irq_list: - continue - - if cpu_list and not set(cpu_list).intersection(set(affinity)): - continue - sorted_irqs.append(irqn) - - sorted_irqs.sort() - for irq in sorted_irqs: - affinity = format_affinity(irqs[irq]["affinity"]) - users = irqs[irq]["users"] - print("%4d %-16s %8s" % (irq, ",".join(users), affinity), end=' ') - drivers = find_drivers_by_users(users) - if drivers: - print(" %s" % ",".join(drivers)) - else: - print() +def show_irqs(irq_list, cpu_list): + global irqs + if not irqs: + irqs = procfs.interrupts() + + if sys.stdout.isatty(): + print("%4s %-16s %8s" % ("#", _("users"), _("affinity"),)) + sorted_irqs = [] + for k in list(irqs.keys()): + try: + irqn = int(k) + affinity = irqs[irqn]["affinity"] + except: + continue + if irq_list and irqn not in irq_list: + continue + + if cpu_list and not set(cpu_list).intersection(set(affinity)): + continue + sorted_irqs.append(irqn) + + sorted_irqs.sort() + for irq in sorted_irqs: + affinity = format_affinity(irqs[irq]["affinity"]) + users = irqs[irq]["users"] + print("%4d %-16s %8s" % (irq, ",".join(users), affinity), end=' ') + drivers = find_drivers_by_users(users) + if drivers: + print(" %s" % ",".join(drivers)) + else: + print()
def do_list_op(op, current_list, op_list): - if not current_list: - current_list = [] - if op == '+': - return list(set(current_list + op_list)) - if op == '-': - return list(set(current_list) - set(op_list)) - return list(set(op_list)) + if not current_list: + current_list = [] + if op == '+': + return list(set(current_list + op_list)) + if op == '-': + return list(set(current_list) - set(op_list)) + return list(set(op_list))
def thread_mapper(s): - global ps - try: - return [ int(s), ] - except: - pass + global ps + try: + return [int(s),] + except: + pass
- ps = procfs.pidstats() + ps = procfs.pidstats()
- try: - return ps.find_by_regex(re.compile(fnmatch.translate(s))) - except: - return ps.find_by_name(s) + try: + return ps.find_by_regex(re.compile(fnmatch.translate(s))) + except: + return ps.find_by_name(s)
def irq_mapper(s): - global irqs + global irqs + try: + return [int(s),] + except: + pass + if not irqs: + irqs = procfs.interrupts() + + irq_list_str = irqs.find_by_user_regex(re.compile(fnmatch.translate(s))) + irq_list = [] + for i in irq_list_str: try: - return [ int(s), ] + irq_list.append(int(i)) except: - pass - if not irqs: - irqs = procfs.interrupts() + pass
- irq_list_str = irqs.find_by_user_regex(re.compile(fnmatch.translate(s))) - irq_list = [] - for i in irq_list_str: - try: - irq_list.append(int(i)) - except: - pass - - return irq_list + return irq_list
def pick_op(argument): - if argument == "": - return (None, argument) - if argument[0] in ('+', '-'): - return (argument[0], argument[1:]) + if argument == "": return (None, argument) + if argument[0] in ('+', '-'): + return (argument[0], argument[1:]) + return (None, argument)
def i18n_init(): - (app, localedir) = ('tuna', '/usr/share/locale') - locale.setlocale(locale.LC_ALL, '') - gettext.bindtextdomain(app, localedir) - gettext.textdomain(app) - gettext.install(app, localedir) + (app, localedir) = ('tuna', '/usr/share/locale') + locale.setlocale(locale.LC_ALL, '') + gettext.bindtextdomain(app, localedir) + gettext.textdomain(app) + gettext.install(app, localedir)
def apply_config(filename): - from tuna.config import Config - config = Config() - if os.path.exists(filename): - config.config['root'] = os.getcwd() + "/" - filename = os.path.basename(filename) - else: - if not os.path.exists(config.config['root']+filename): - print(filename + _(" not found!")) - exit(-1) - if config.loadTuna(filename): - exit(1) - ctrl = 0 - values = {} - values['toapply'] = {} - for index in range(len(config.ctlParams)): - for opt in config.ctlParams[index]: - values['toapply'][ctrl] = {} - values['toapply'][ctrl]['label'] = opt - values['toapply'][ctrl]['value'] = config.ctlParams[index][opt] - ctrl = ctrl + 1 - config.applyChanges(values) + from tuna.config import Config + config = Config() + if os.path.exists(filename): + config.config['root'] = os.getcwd() + "/" + filename = os.path.basename(filename) + else: + if not os.path.exists(config.config['root']+filename): + print(filename + _(" not found!")) + exit(-1) + if config.loadTuna(filename): + exit(1) + ctrl = 0 + values = {} + values['toapply'] = {} + for index in range(len(config.ctlParams)): + for opt in config.ctlParams[index]: + values['toapply'][ctrl] = {} + values['toapply'][ctrl]['label'] = opt + values['toapply'][ctrl]['value'] = config.ctlParams[index][opt] + ctrl = ctrl + 1 + config.applyChanges(values)
def list_config(): - from tuna.config import Config - config = Config() - print(_("Preloaded config files:")) - for value in config.populate(): - print(value) - exit(1) + from tuna.config import Config + config = Config() + print(_("Preloaded config files:")) + for value in config.populate(): + print(value) + exit(1)
def main(): - global ps - - i18n_init() - try: - short = "a:c:CfgGhiIKlmNp:PQq:r:s:S:t:UvWx" - long = ["cpus=", "affect_children", "filter", "gui", "help", - "isolate", "include", "no_kthreads", "move", "nohz_full", - "show_sockets", "priority=", "show_threads", - "show_irqs", "irqs=", - "save=", "sockets=", "threads=", "no_uthreads", - "version", "what_is", "spread","cgroup","config_file_apply=","config_file_list=", - "run=" ] - if have_inet_diag: - short += "n" - int.append("show_sockets") - opts, args = getopt.getopt(sys.argv[1:], short, long) - except getopt.GetoptError as err: + global ps + + i18n_init() + try: + short = "a:c:CfgGhiIKlmNp:PQq:r:s:S:t:UvWx" + long = ["cpus=", "affect_children", "filter", "gui", "help", \ + "isolate", "include", "no_kthreads", "move", "nohz_full", \ + "show_sockets", "priority=", "show_threads", \ + "show_irqs", "irqs=", \ + "save=", "sockets=", "threads=", "no_uthreads", \ + "version", "what_is", "spread", "cgroup", "config_file_apply=", \ + "config_file_list=", "run="] + if have_inet_diag: + short += "n" + int.append("show_sockets") + opts, args = getopt.getopt(sys.argv[1:], short, long) + except getopt.GetoptError as err: + usage() + print(str(err)) + sys.exit(2) + + run_gui = not opts + kthreads = True + uthreads = True + cgroups = False + cpu_list = None + irq_list = None + irq_list_str = None + rtprio = None + policy = None + thread_list = [] + thread_list_str = None + filter = False + affect_children = False + show_sockets = False + p_waiting_action = False + + for o, a in opts: + if o in ("-h", "--help"): + usage() + return + elif o in ("-a", "--config_file_apply"): + apply_config(a) + elif o in ("-l", "--config_file_list"): + list_config() + elif o in ("-c", "--cpus"): + (op, a) = pick_op(a) + try: + op_list = tuna.cpustring_to_list(a) + except ValueError: usage() - print(str(err)) + return + cpu_list = do_list_op(op, cpu_list, op_list) + elif o in ("-N", "--nohz_full"): + try: + cpu_list = tuna.nohz_full_list() + except: + print("tuna: --nohz_full " + _(" needs nohz_full=cpulist on the kernel command line")) sys.exit(2) - - run_gui = not opts - kthreads = True - uthreads = True - cgroups = False - cpu_list = None - irq_list = None - irq_list_str = None - rtprio = None - policy = None - thread_list = [] - thread_list_str = None - filter = False - affect_children = False - show_sockets = False - p_waiting_action = False - - for o, a in opts: - if o in ("-h", "--help"): - usage() - return - elif o in ("-a", "--config_file_apply"): - apply_config(a) - elif o in ("-l", "--config_file_list"): - list_config() - elif o in ("-c", "--cpus"): - (op, a) = pick_op(a) - try: - op_list = tuna.cpustring_to_list(a) - except ValueError: - usage() - return - cpu_list = do_list_op(op, cpu_list, op_list) - elif o in ("-N", "--nohz_full"): - try: - cpu_list = tuna.nohz_full_list() - except: - print("tuna: --nohz_full " + _(" needs nohz_full=cpulist on the kernel command line")) - sys.exit(2) - elif o in ("-C", "--affect_children"): - affect_children = True - elif o in ("-G", "--cgroup"): - cgroups = True - elif o in ("-t", "--threads"): - # The -t - will reset thread list - if a == '-': - thread_list = [] - thread_list_str = '' - else: - (op, a) = pick_op(a) - op_list = reduce(lambda i, j: i + j, - list(map(thread_mapper, a.split(",")))) - op_list = list(set(op_list)) - thread_list = do_list_op(op, thread_list, op_list) - # Check if a process name was especified and no - # threads was found, which would result in an empty - # thread list, i.e. we would print all the threads - # in the system when we should print nothing. - if not op_list and type(a) == type(''): - thread_list_str = do_list_op(op, thread_list_str, - a.split(",")) - if not op: - irq_list = None - elif o in ("-f", "--filter"): - filter = True - elif o in ("-g", "--gui"): - run_gui = True - elif o in ("-i", "--isolate"): - if not cpu_list: - print("tuna: --isolate " + _("requires a cpu list!")) - sys.exit(2) - tuna.isolate_cpus(cpu_list, get_nr_cpus()) - elif o in ("-I", "--include"): - if not cpu_list: - print("tuna: --include " + _("requires a cpu list!")) - sys.exit(2) - tuna.include_cpus(cpu_list, get_nr_cpus()) - elif o in ("-p", "--priority"): - # Save policy and rtprio for future Actions (e.g. --run). - (policy, rtprio) = tuna.get_policy_and_rtprio(a) - if not thread_list: - # For backward compatibility - p_waiting_action = True - else: - try: - tuna.threads_set_priority(thread_list, a, affect_children) - except (SystemError, OSError) as err: # old python-schedutils incorrectly raised SystemError - print("tuna: %s" % err) - sys.exit(2) - elif o in ("-P", "--show_threads"): - # If the user specified process names that weren't - # resolved to pids, don't show all threads. - if not thread_list and not irq_list: - if thread_list_str or irq_list_str: - continue - do_ps(thread_list, cpu_list, irq_list, uthreads, - kthreads, affect_children, show_sockets, cgroups) - elif o in ("-Q", "--show_irqs"): - # If the user specified IRQ names that weren't - # resolved to IRQs, don't show all IRQs. - if not irq_list and irq_list_str: - continue - show_irqs(irq_list, cpu_list) - elif o in ("-n", "--show_sockets"): - show_sockets = True - elif o in ("-m", "--move", "-x", "--spread"): - if not cpu_list: - print("tuna: --move " + _("requires a cpu list!")) - sys.exit(2) - if not (thread_list or irq_list): - print("tuna: --move " + _("requires a list of threads/irqs!")) - sys.exit(2) - - spread = o in ("-x", "--spread") - - if thread_list: - tuna.move_threads_to_cpu(cpu_list, thread_list, - spread = spread) - - if irq_list: - tuna.move_irqs_to_cpu(cpu_list, irq_list, - spread = spread) - elif o in ("-s", "--save"): - save(cpu_list, thread_list, a) - elif o in ("-S", "--sockets"): - (op, a) = pick_op(a) - sockets = [socket for socket in a.split(",")] - - if not cpu_list: - cpu_list = [] - - cpu_info = sysfs.cpus() - op_list = [] - for socket in sockets: - if socket not in cpu_info.sockets: - print("tuna: %s" % \ - (_("invalid socket %(socket)s sockets available: %(available)s") % \ - {"socket": socket, - "available": ",".join(list(cpu_info.sockets.keys()))})) - sys.exit(2) - op_list += [ int(cpu.name[3:]) for cpu in cpu_info.sockets[socket] ] - cpu_list = do_list_op(op, cpu_list, op_list) - elif o in ("-K", "--no_kthreads"): - kthreads = False - elif o in ("-q", "--irqs"): - (op, a) = pick_op(a) - op_list = reduce(lambda i, j: i + j, - list(map(irq_mapper, list(set(a.split(",")))))) - irq_list = do_list_op(op, irq_list, op_list) - # See comment above about thread_list_str - if not op_list and type(a) == type(''): - irq_list_str = do_list_op(op, irq_list_str, - a.split(",")) - if not op: - thread_list = [] - if not ps: - ps = procfs.pidstats() - if tuna.has_threaded_irqs(ps): - for irq in irq_list: - irq_re = tuna.threaded_irq_re(irq) - irq_threads = ps.find_by_regex(irq_re) - if irq_threads: - # Change the affinity of the thread too - # as we can't rely on changing the irq - # affinity changing the affinity of the - # thread or vice versa. We need to change - # both. - thread_list += irq_threads - - elif o in ("-U", "--no_uthreads"): - uthreads = False - elif o in ("-v", "--version"): - print(version) - elif o in ("-W", "--what_is"): - if not thread_list: - print("tuna: --what_is " + _("requires a thread list!")) - sys.exit(2) - for tid in thread_list: - thread_help(tid) - elif o in ("-r", "--run"): - # If -p is set, it will be consumed. So, no backward compatible - # error handling action must be taken. - p_waiting_action = False - - # pick_op() before run the command: to remove the prefix - # + or - from command line. - (op, a) = pick_op(a) - - # In order to include the new process, it must run - # the command first, and then get the list of pids, - tuna.run_command(a, policy, rtprio, cpu_list) - - op_list = reduce(lambda i, j: i + j, - list(map(thread_mapper, a.split(",")))) - op_list = list(set(op_list)) - thread_list = do_list_op(op, thread_list, op_list) - - # Check if a process name was especified and no - # threads was found, which would result in an empty - # thread list, i.e. we would print all the threads - # in the system when we should print nothing. - if not op_list and type(a) == type(''): - thread_list_str = do_list_op(op, thread_list_str, - a.split(",")) - if not op: - irq_list = None - - # For backward compatibility: when -p used to be only an Action, it - # used to exit(2) if no action was taken (i.e. if no threads_list - # was set). - if p_waiting_action: - print(("tuna: -p ") + _("requires a thread list!")) + elif o in ("-C", "--affect_children"): + affect_children = True + elif o in ("-G", "--cgroup"): + cgroups = True + elif o in ("-t", "--threads"): + # The -t - will reset thread list + if a == '-': + thread_list = [] + thread_list_str = '' + else: + (op, a) = pick_op(a) + op_list = reduce(lambda i, j: i + j, \ + list(map(thread_mapper, a.split(",")))) + op_list = list(set(op_list)) + thread_list = do_list_op(op, thread_list, op_list) + # Check if a process name was especified and no + # threads was found, which would result in an empty + # thread list, i.e. we would print all the threads + # in the system when we should print nothing. + if not op_list and type(a) == type(''): + thread_list_str = do_list_op(op, thread_list_str, + a.split(",")) + if not op: + irq_list = None + elif o in ("-f", "--filter"): + filter = True + elif o in ("-g", "--gui"): + run_gui = True + elif o in ("-i", "--isolate"): + if not cpu_list: + print("tuna: --isolate " + _("requires a cpu list!")) sys.exit(2) - - if run_gui: + tuna.isolate_cpus(cpu_list, get_nr_cpus()) + elif o in ("-I", "--include"): + if not cpu_list: + print("tuna: --include " + _("requires a cpu list!")) + sys.exit(2) + tuna.include_cpus(cpu_list, get_nr_cpus()) + elif o in ("-p", "--priority"): + # Save policy and rtprio for future Actions (e.g. --run). + (policy, rtprio) = tuna.get_policy_and_rtprio(a) + if not thread_list: + # For backward compatibility + p_waiting_action = True + else: try: - from tuna import tuna_gui - except ImportError: - # gui packages not installed - print(_('tuna: packages needed for the GUI missing.')) - print(_(' Make sure xauth, pygtk2-libglade are installed.')) - usage() - return - except RuntimeError: - print("tuna: machine needs to be authorized via xhost or ssh -X?") - return + tuna.threads_set_priority(thread_list, a, affect_children) + except (SystemError, OSError) as err: # old python-schedutils incorrectly raised SystemError + print("tuna: %s" % err) + sys.exit(2) + elif o in ("-P", "--show_threads"): + # If the user specified process names that weren't + # resolved to pids, don't show all threads. + if not thread_list and not irq_list: + if thread_list_str or irq_list_str: + continue + do_ps(thread_list, cpu_list, irq_list, uthreads, \ + kthreads, affect_children, show_sockets, cgroups) + elif o in ("-Q", "--show_irqs"): + # If the user specified IRQ names that weren't + # resolved to IRQs, don't show all IRQs. + if not irq_list and irq_list_str: + continue + show_irqs(irq_list, cpu_list) + elif o in ("-n", "--show_sockets"): + show_sockets = True + elif o in ("-m", "--move", "-x", "--spread"): + if not cpu_list: + print("tuna: --move " + _("requires a cpu list!")) + sys.exit(2) + if not (thread_list or irq_list): + print("tuna: --move " + _("requires a list of threads/irqs!")) + sys.exit(2)
- try: - cpus_filtered = filter and cpu_list or [] - app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered) - app.run() - except KeyboardInterrupt: - pass + spread = o in ("-x", "--spread") + + if thread_list: + tuna.move_threads_to_cpu(cpu_list, thread_list, spread=spread) + + if irq_list: + tuna.move_irqs_to_cpu(cpu_list, irq_list, spread=spread) + elif o in ("-s", "--save"): + save(cpu_list, thread_list, a) + elif o in ("-S", "--sockets"): + (op, a) = pick_op(a) + sockets = [socket for socket in a.split(",")] + + if not cpu_list: + cpu_list = [] + + cpu_info = sysfs.cpus() + op_list = [] + for socket in sockets: + if socket not in cpu_info.sockets: + print("tuna: %s" % \ + (_("invalid socket %(socket)s sockets available: %(available)s") % \ + {"socket": socket, + "available": ",".join(list(cpu_info.sockets.keys()))})) + sys.exit(2) + op_list += [int(cpu.name[3:]) for cpu in cpu_info.sockets[socket]] + cpu_list = do_list_op(op, cpu_list, op_list) + elif o in ("-K", "--no_kthreads"): + kthreads = False + elif o in ("-q", "--irqs"): + (op, a) = pick_op(a) + op_list = reduce(lambda i, j: i + j, \ + list(map(irq_mapper, list(set(a.split(",")))))) + irq_list = do_list_op(op, irq_list, op_list) + # See comment above about thread_list_str + if not op_list and type(a) == type(''): + irq_list_str = do_list_op(op, irq_list_str, a.split(",")) + if not op: + thread_list = [] + if not ps: + ps = procfs.pidstats() + if tuna.has_threaded_irqs(ps): + for irq in irq_list: + irq_re = tuna.threaded_irq_re(irq) + irq_threads = ps.find_by_regex(irq_re) + if irq_threads: + # Change the affinity of the thread too + # as we can't rely on changing the irq + # affinity changing the affinity of the + # thread or vice versa. We need to change + # both. + thread_list += irq_threads + + elif o in ("-U", "--no_uthreads"): + uthreads = False + elif o in ("-v", "--version"): + print(version) + elif o in ("-W", "--what_is"): + if not thread_list: + print("tuna: --what_is " + _("requires a thread list!")) + sys.exit(2) + for tid in thread_list: + thread_help(tid) + elif o in ("-r", "--run"): + # If -p is set, it will be consumed. So, no backward compatible + # error handling action must be taken. + p_waiting_action = False + + # pick_op() before run the command: to remove the prefix + # + or - from command line. + (op, a) = pick_op(a) + + # In order to include the new process, it must run + # the command first, and then get the list of pids, + tuna.run_command(a, policy, rtprio, cpu_list) + + op_list = reduce(lambda i, j: i + j, \ + list(map(thread_mapper, a.split(",")))) + op_list = list(set(op_list)) + thread_list = do_list_op(op, thread_list, op_list) + + # Check if a process name was especified and no + # threads was found, which would result in an empty + # thread list, i.e. we would print all the threads + # in the system when we should print nothing. + if not op_list and type(a) == type(''): + thread_list_str = do_list_op(op, thread_list_str, a.split(",")) + if not op: + irq_list = None + + # For backward compatibility: when -p used to be only an Action, it + # used to exit(2) if no action was taken (i.e. if no threads_list + # was set). + if p_waiting_action: + print(("tuna: -p ") + _("requires a thread list!")) + sys.exit(2) + + if run_gui: + try: + from tuna import tuna_gui + except ImportError: + # gui packages not installed + print(_('tuna: packages needed for the GUI missing.')) + print(_(' Make sure xauth, pygtk2-libglade are installed.')) + usage() + return + except RuntimeError: + print("tuna: machine needs to be authorized via xhost or ssh -X?") + return + + try: + cpus_filtered = filter and cpu_list or [] + app = tuna_gui.main_gui(kthreads, uthreads, cpus_filtered) + app.run() + except KeyboardInterrupt: + pass
if __name__ == '__main__': main()
Update spacing / tabs to modern python recommendations
Signed-off-by: John Kacur jkacur@redhat.com --- tuna/tuna.py | 1207 +++++++++++++++++++++++++------------------------- 1 file changed, 609 insertions(+), 598 deletions(-)
diff --git a/tuna/tuna.py b/tuna/tuna.py index ed44a29424d6..30e87529f656 100755 --- a/tuna/tuna.py +++ b/tuna/tuna.py @@ -1,655 +1,667 @@ # -*- python -*- # -*- coding: utf-8 -*-
-import copy, ethtool, errno, os, procfs, re, schedutils, sys, shlex -from . import help +import copy +import errno +import os +import re +import sys +import shlex import fnmatch import platform +import schedutils +import ethtool +import procfs from procfs import utilist +from . import help
try: - set -except NameError: - from sets import Set as set - -try: - fntable + fntable except NameError: - fntable = [] + fntable = []
def kthread_help(key): - if '/' in key: - key = key[:key.rfind('/')+1] - return help.KTHREAD_HELP.get(key, " ") + if '/' in key: + key = key[:key.rfind('/')+1] + return help.KTHREAD_HELP.get(key, " ")
def proc_sys_help(key): - if not len(fntable): - regMatch = ['[', '*', '?'] - for value in help.PROC_SYS_HELP: - for char in regMatch: - if char in value: - fntable.append(value) - temp = help.PROC_SYS_HELP.get(key, "") - if len(temp): - return key + ":\n" + temp - else: - for value in fntable: - if fnmatch.fnmatch(key, value): - return key + ":\n" + help.PROC_SYS_HELP.get(value, "") - return key + if not fntable: + reg_match = ['[', '*', '?'] + for value in help.PROC_SYS_HELP: + for char in reg_match: + if char in value: + fntable.append(value) + temp = help.PROC_SYS_HELP.get(key, "") + if temp: + return key + ":\n" + temp + for value in fntable: + if fnmatch.fnmatch(key, value): + return key + ":\n" + help.PROC_SYS_HELP.get(value, "") + return key
def kthread_help_plain_text(pid, cmdline): - cmdline = cmdline.split(' ')[0] - params = {'pid':pid, 'cmdline':cmdline} + cmdline = cmdline.split(' ')[0] + params = {'pid':pid, 'cmdline':cmdline}
- if iskthread(pid): - title = _("Kernel Thread %(pid)d (%(cmdline)s):") % params - help = kthread_help(cmdline) - else: - title = _("User Thread %(pid)d (%(cmdline)s):") % params - help = title + if iskthread(pid): + title = _("Kernel Thread %(pid)d (%(cmdline)s):") % params + help = kthread_help(cmdline) + else: + title = _("User Thread %(pid)d (%(cmdline)s):") % params + help = title
- return help, title + return help, title
def iskthread(pid): - # FIXME: we should leave to the callers to handle all the exceptions, - # in this function, so that they know that the thread vanished and - # can act accordingly, removing entries from tree views, etc - try: - f = open("/proc/%d/smaps" % pid) - except IOError: - # Thread has vanished - return True + # FIXME: we should leave to the callers to handle all the exceptions, + # in this function, so that they know that the thread vanished and + # can act accordingly, removing entries from tree views, etc + try: + f = open("/proc/%d/smaps" % pid) + except IOError: + # Thread has vanished + return True
- line = f.readline() - f.close() - if line: - return False - # Zombies also doesn't have smaps entries, so check the - # state: - try: - p = procfs.pidstat(pid) - except: - return True - - if p["state"] == 'Z': - return False + line = f.readline() + f.close() + if line: + return False + # Zombies also doesn't have smaps entries, so check the + # state: + try: + p = procfs.pidstat(pid) + except: return True - + + if p["state"] == 'Z': + return False + return True + def irq_thread_number(cmd): - if cmd[:4] == "irq/": - return cmd[4:cmd.find('-')] - elif cmd[:4] == "IRQ-": - return cmd[4:] - else: - raise LookupError + if cmd[:4] == "irq/": + return cmd[4:cmd.find('-')] + if cmd[:4] == "IRQ-": + return cmd[4:] + raise LookupError
def is_irq_thread(cmd): - return cmd[:4] in ("IRQ-", "irq/") + return cmd[:4] in ("IRQ-", "irq/")
def threaded_irq_re(irq): - return re.compile("(irq/%s-.+|IRQ-%s)" % (irq, irq)) + return re.compile("(irq/%s-.+|IRQ-%s)" % (irq, irq))
# FIXME: Move to python-linux-procfs def has_threaded_irqs(ps): - irq_re = re.compile("(irq/[0-9]+-.+|IRQ-[0-9]+)") - return len(ps.find_by_regex(irq_re)) > 0 + irq_re = re.compile("(irq/[0-9]+-.+|IRQ-[0-9]+)") + return len(ps.find_by_regex(irq_re)) > 0
def set_irq_affinity_filename(filename, bitmasklist): - pathname="/proc/irq/%s" % filename - f = open(pathname, "w") - text = ",".join(["%x" % a for a in bitmasklist]) - f.write("%s\n" % text) - try: - f.close() - except IOError: - # This happens with IRQ 0, for instance - return False - return True + pathname = "/proc/irq/%s" % filename + f = open(pathname, "w") + text = ",".join(["%x" % a for a in bitmasklist]) + f.write("%s\n" % text) + try: + f.close() + except IOError: + # This happens with IRQ 0, for instance + return False + return True
def set_irq_affinity(irq, bitmasklist): - return set_irq_affinity_filename("%d/smp_affinity" % irq, bitmasklist) + return set_irq_affinity_filename("%d/smp_affinity" % irq, bitmasklist)
def cpustring_to_list(cpustr): - """Convert a string of numbers to an integer list. - - Given a string of comma-separated numbers and number ranges, - return a simple sorted list of the integers it represents. - - This function will throw exceptions for badly-formatted strings. - - Returns a list of integers.""" - - fields = cpustr.strip().split(",") - cpu_list = [] - for field in fields: - ends = [ int(a, 0) for a in field.split("-") ] - if len(ends) > 2: - raise SyntaxError("Syntax error") - if len(ends) == 2: - cpu_list += list(range(ends[0], ends[1] + 1)) - else: - cpu_list += [ends[0]] - return list(set(cpu_list)) + """Convert a string of numbers to an integer list. + + Given a string of comma-separated numbers and number ranges, + return a simple sorted list of the integers it represents. + + This function will throw exceptions for badly-formatted strings. + + Returns a list of integers.""" + + fields = cpustr.strip().split(",") + cpu_list = [] + for field in fields: + ends = [int(a, 0) for a in field.split("-")] + if len(ends) > 2: + raise SyntaxError("Syntax error") + if len(ends) == 2: + cpu_list += list(range(ends[0], ends[1] + 1)) + else: + cpu_list += [ends[0]] + return list(set(cpu_list))
def list_to_cpustring(l): - """Convert a list of integers into a range string. - - Consecutive values will be collapsed into ranges. - - This should not throw any exceptions as long as the list is all - positive integers. - - Returns a string.""" - - l = list(set(l)) - strings = [] - inrange = False - prev = -2 - while len(l): - i = l.pop(0) - if i - 1 == prev: - while len(l): - j = l.pop(0) - if j - 1 != i: - l.insert(0, j) - break; - i = j - t = strings.pop() - if int(t) + 1 == i: - strings.append("%s,%u" % (t, i)) - else: - strings.append("%s-%u" % (t, i)) - else: - strings.append("%u" % i) - prev = i - return ",".join(strings) + """Convert a list of integers into a range string. + + Consecutive values will be collapsed into ranges. + + This should not throw any exceptions as long as the list is all + positive integers. + + Returns a string.""" + + l = list(set(l)) + strings = [] + prev = -2 + while l: + i = l.pop(0) + if i - 1 == prev: + while l: + j = l.pop(0) + if j - 1 != i: + l.insert(0, j) + break + i = j + t = strings.pop() + if int(t) + 1 == i: + strings.append("%s,%u" % (t, i)) + else: + strings.append("%s-%u" % (t, i)) + else: + strings.append("%u" % i) + prev = i + return ",".join(strings)
# FIXME: move to python-linux-procfs def is_hardirq_handler(self, pid): - PF_HARDIRQ = 0x08000000 - try: - return int(self.processes[pid]["stat"]["flags"]) & \ - PF_HARDIRQ and True or False - except: - return False - -def move_threads_to_cpu(cpus, pid_list, set_affinity_warning = None, - spread = False): - changed = False - - ps = procfs.pidstats() - cpu_idx = 0 - nr_cpus = len(cpus) - new_affinity = cpus - last_cpu = max(cpus) + 1 - for pid in pid_list: - if spread: - new_affinity = [cpus[cpu_idx]] - cpu_idx += 1 - if cpu_idx == nr_cpus: - cpu_idx = 0 + PF_HARDIRQ = 0x08000000 + try: + return int(self.processes[pid]["stat"]["flags"]) & \ + PF_HARDIRQ and True or False + except: + return False
+def move_threads_to_cpu(cpus, pid_list, set_affinity_warning=None, spread=False): + changed = False + + ps = procfs.pidstats() + cpu_idx = 0 + nr_cpus = len(cpus) + new_affinity = cpus + last_cpu = max(cpus) + 1 + for pid in pid_list: + if spread: + new_affinity = [cpus[cpu_idx]] + cpu_idx += 1 + if cpu_idx == nr_cpus: + cpu_idx = 0 + + try: + try: + curr_affinity = schedutils.get_affinity(pid) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + curr_affinity = None + raise err + if set(curr_affinity) != set(new_affinity): try: + schedutils.set_affinity(pid, new_affinity) + curr_affinity = schedutils.get_affinity(pid) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + curr_affinity = None + raise err + if set(curr_affinity) == set(new_affinity): + changed = True + if is_hardirq_handler(ps, pid): try: - curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - curr_affinity = None - raise e - if set(curr_affinity) != set(new_affinity): - try: - schedutils.set_affinity(pid, new_affinity) - curr_affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - curr_affinity == None - raise e - if set(curr_affinity) == set(new_affinity): - changed = True - if is_hardirq_handler(ps, pid): - try: - irq = int(ps[pid]["stat"]["comm"][4:]) - bitmasklist = procfs.hexbitmask(new_affinity, last_cpu) - set_irq_affinity(irq, bitmasklist) - except: - pass - elif set_affinity_warning: - set_affinity_warning(pid, new_affinity) - else: - print("move_threads_to_cpu: %s " % \ - (_("could not change %(pid)d affinity to %(new_affinity)s") % \ - {'pid':pid, 'new_affinity':new_affinity})) - - # See if this is the thread group leader - if pid not in ps: - continue - - threads = procfs.pidstats("/proc/%d/task" % pid) - for tid in list(threads.keys()): - try: - curr_affinity = schedutils.get_affinity(tid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if set(curr_affinity) != set(new_affinity): - try: - schedutils.set_affinity(tid, new_affinity) - curr_affinity = schedutils.get_affinity(tid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if set(curr_affinity) == set(new_affinity): - changed = True - elif set_affinity_warning: - set_affinity_warning(tid, new_affinity) - else: - print("move_threads_to_cpu: %s " % \ - (_("could not change %(pid)d affinity to %(new_affinity)s") % \ - {'pid':pid, 'new_affinity':new_affinity})) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - # process died - continue - elif e.args[0] == errno.EINVAL: # unmovable thread) - print("thread %(pid)d cannot be moved as requested" %{'pid':pid}, file=sys.stderr) - continue - raise e - return changed - -def move_irqs_to_cpu(cpus, irq_list, spread = False): - changed = 0 - unprocessed = [] - - cpu_idx = 0 - nr_cpus = len(cpus) - new_affinity = cpus - last_cpu = max(cpus) + 1 - irqs = None - ps = procfs.pidstats() - for i in irq_list: - try: - irq = int(i) - except: - if not irqs: - irqs = procfs.interrupts() - irq = irqs.find_by_user(i) - if not irq: - unprocessed.append(i) - continue - try: - irq = int(irq) + irq = int(ps[pid]["stat"]["comm"][4:]) + bitmasklist = procfs.hexbitmask(new_affinity, last_cpu) + set_irq_affinity(irq, bitmasklist) except: - unprocessed.append(i) - continue - - if spread: - new_affinity = [cpus[cpu_idx]] - cpu_idx += 1 - if cpu_idx == nr_cpus: - cpu_idx = 0 - - bitmasklist = procfs.hexbitmask(new_affinity, last_cpu) - set_irq_affinity(irq, bitmasklist) - changed += 1 - pid = ps.find_by_name("IRQ-%d" % irq) - if pid: - pid = int(pid[0]) - try: - schedutils.set_affinity(pid, new_affinity) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - unprocessed.append(i) - changed -= 1 - continue - raise e + pass + elif set_affinity_warning: + set_affinity_warning(pid, new_affinity) + else: + print("move_threads_to_cpu: %s " % \ + (_("could not change %(pid)d affinity to %(new_affinity)s") % \ + {'pid':pid, 'new_affinity':new_affinity})) + + # See if this is the thread group leader + if pid not in ps: + continue
- return (changed, unprocessed) + threads = procfs.pidstats("/proc/%d/task" % pid) + for tid in list(threads.keys()): + try: + curr_affinity = schedutils.get_affinity(tid) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + if set(curr_affinity) != set(new_affinity): + try: + schedutils.set_affinity(tid, new_affinity) + curr_affinity = schedutils.get_affinity(tid) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + if set(curr_affinity) == set(new_affinity): + changed = True + elif set_affinity_warning: + set_affinity_warning(tid, new_affinity) + else: + print("move_threads_to_cpu: %s " % \ + (_("could not change %(pid)d affinity to %(new_affinity)s") % \ + {'pid':pid, 'new_affinity':new_affinity})) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + # process died + continue + if err.args[0] == errno.EINVAL: # unmovable thread) + print("thread %(pid)d cannot be moved as requested" %{'pid':pid}, file=sys.stderr) + continue + raise err + return changed + +def move_irqs_to_cpu(cpus, irq_list, spread=False): + changed = 0 + unprocessed = [] + + cpu_idx = 0 + nr_cpus = len(cpus) + new_affinity = cpus + last_cpu = max(cpus) + 1 + irqs = None + ps = procfs.pidstats() + for i in irq_list: + try: + irq = int(i) + except: + if not irqs: + irqs = procfs.interrupts() + irq = irqs.find_by_user(i) + if not irq: + unprocessed.append(i) + continue + try: + irq = int(irq) + except: + unprocessed.append(i) + continue + + if spread: + new_affinity = [cpus[cpu_idx]] + cpu_idx += 1 + if cpu_idx == nr_cpus: + cpu_idx = 0 + + bitmasklist = procfs.hexbitmask(new_affinity, last_cpu) + set_irq_affinity(irq, bitmasklist) + changed += 1 + pid = ps.find_by_name("IRQ-%d" % irq) + if pid: + pid = int(pid[0]) + try: + schedutils.set_affinity(pid, new_affinity) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + unprocessed.append(i) + changed -= 1 + continue + raise err + + return (changed, unprocessed)
def affinity_remove_cpus(affinity, cpus, nr_cpus): - # If the cpu being isolated was the only one in the current affinity + # If the cpu being isolated was the only one in the current affinity + affinity = list(set(affinity) - set(cpus)) + if not affinity: + affinity = list(range(nr_cpus)) affinity = list(set(affinity) - set(cpus)) - if not affinity: - affinity = list(range(nr_cpus)) - affinity = list(set(affinity) - set(cpus)) - return affinity + return affinity
# True if machine is s390 or s390x def is_s390(): machine = platform.machine() if re.search('s390', machine): return True - else: - return False + return False
# Shound be moved to python_linux_procfs.interrupts, shared with interrupts.parse_affinity, etc. def parse_irq_affinity_filename(filename, nr_cpus): - try: - f = open("/proc/irq/%s" % filename) - except IOError as err: - if is_s390(): - print("This operation is not supported on s390", file=sys.stderr) - print("tuna: %s" % err, file=sys.stderr) - sys.exit(2) + try: + f = open("/proc/irq/%s" % filename) + except IOError as err: + if is_s390(): + print("This operation is not supported on s390", file=sys.stderr) + print("tuna: %s" % err, file=sys.stderr) + sys.exit(2)
- line = f.readline() - f.close() - return utilist.bitmasklist(line, nr_cpus) + line = f.readline() + f.close() + return utilist.bitmasklist(line, nr_cpus)
def isolate_cpus(cpus, nr_cpus): - fname = sys._getframe( ).f_code.co_name # Function name - ps = procfs.pidstats() - ps.reload_threads() - previous_pid_affinities = {} - for pid in list(ps.keys()): - if procfs.cannot_set_affinity(ps, pid): - continue + fname = sys._getframe().f_code.co_name # Function name + ps = procfs.pidstats() + ps.reload_threads() + previous_pid_affinities = {} + for pid in list(ps.keys()): + if procfs.cannot_set_affinity(ps, pid): + continue + try: + affinity = schedutils.get_affinity(pid) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + if err.args[0] == errno.EINVAL: + print("Function:", fname, ",", err.strerror, file=sys.stderr) + sys.exit(2) + raise err + if set(affinity).intersection(set(cpus)): + previous_pid_affinities[pid] = copy.copy(affinity) + affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) + try: + schedutils.set_affinity(pid, affinity) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + if err.args[0] == errno.EINVAL: + print("Function:", fname, ",", err.strerror, file=sys.stderr) + sys.exit(2) + raise err + + if "threads" not in ps[pid]: + continue + threads = ps[pid]["threads"] + for tid in list(threads.keys()): + if procfs.cannot_set_thread_affinity(ps, pid, tid): + continue + try: + affinity = schedutils.get_affinity(tid) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + if err.args[0] == errno.EINVAL: + print("Function:", fname, ",", err.strerror, file=sys.stderr) + sys.exit(2) + raise err + if set(affinity).intersection(set(cpus)): + previous_pid_affinities[tid] = copy.copy(affinity) + affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) try: - affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - elif e.args[0] == errno.EINVAL: - print("Function:", fname, ",", e.strerror, file=sys.stderr) - sys.exit(2) - raise e - if set(affinity).intersection(set(cpus)): - previous_pid_affinities[pid] = copy.copy(affinity) - affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) - try: - schedutils.set_affinity(pid, affinity) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - elif e.args[0] == errno.EINVAL: - print("Function:", fname, ",", e.strerror, file=sys.stderr) - sys.exit(2) - raise e - - if "threads" not in ps[pid]: - continue - threads = ps[pid]["threads"] - for tid in list(threads.keys()): - if procfs.cannot_set_thread_affinity(ps, pid, tid): - continue - try: - affinity = schedutils.get_affinity(tid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - elif e.args[0] == errno.EINVAL: - print("Function:", fname, ",", e.strerror, file=sys.stderr) - sys.exit(2) - raise e - if set(affinity).intersection(set(cpus)): - previous_pid_affinities[tid] = copy.copy(affinity) - affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) - try: - schedutils.set_affinity(tid, affinity) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - elif e.args[0] == errno.EINVAL: - print("Function:", fname, ",", e.strerror, file=sys.stderr) - sys.exit(2) - raise e - - del ps - - # Now isolate it from IRQs too - irqs = procfs.interrupts() - previous_irq_affinities = {} - for irq in list(irqs.keys()): - # LOC, NMI, TLB, etc - if "affinity" not in irqs[irq]: + schedutils.set_affinity(tid, affinity) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: continue - affinity = irqs[irq]["affinity"] - if set(affinity).intersection(set(cpus)): - previous_irq_affinities[irq] = copy.copy(affinity) - affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) - set_irq_affinity(int(irq), - procfs.hexbitmask(affinity, - nr_cpus)) + if err.args[0] == errno.EINVAL: + print("Function:", fname, ",", err.strerror, file=sys.stderr) + sys.exit(2) + raise err
- affinity = parse_irq_affinity_filename("default_smp_affinity", nr_cpus) - affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) - set_irq_affinity_filename("default_smp_affinity", procfs.hexbitmask(affinity, nr_cpus)) + del ps
- return (previous_pid_affinities, previous_irq_affinities) + # Now isolate it from IRQs too + irqs = procfs.interrupts() + previous_irq_affinities = {} + for irq in list(irqs.keys()): + # LOC, NMI, TLB, etc + if "affinity" not in irqs[irq]: + continue + affinity = irqs[irq]["affinity"] + if set(affinity).intersection(set(cpus)): + previous_irq_affinities[irq] = copy.copy(affinity) + affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) + set_irq_affinity(int(irq), procfs.hexbitmask(affinity, nr_cpus)) + + affinity = parse_irq_affinity_filename("default_smp_affinity", nr_cpus) + affinity = affinity_remove_cpus(affinity, cpus, nr_cpus) + set_irq_affinity_filename("default_smp_affinity", procfs.hexbitmask(affinity, nr_cpus)) + + return (previous_pid_affinities, previous_irq_affinities)
def include_cpus(cpus, nr_cpus): - ps = procfs.pidstats() - ps.reload_threads() - previous_pid_affinities = {} - for pid in list(ps.keys()): - if procfs.cannot_set_affinity(ps, pid): - continue + ps = procfs.pidstats() + ps.reload_threads() + previous_pid_affinities = {} + for pid in list(ps.keys()): + if procfs.cannot_set_affinity(ps, pid): + continue + try: + affinity = schedutils.get_affinity(pid) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + if set(affinity).intersection(set(cpus)) != set(cpus): + previous_pid_affinities[pid] = copy.copy(affinity) + affinity = list(set(affinity + cpus)) + try: + schedutils.set_affinity(pid, affinity) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + + if "threads" not in ps[pid]: + continue + threads = ps[pid]["threads"] + for tid in list(threads.keys()): + if procfs.cannot_set_thread_affinity(ps, pid, tid): + continue + try: + affinity = schedutils.get_affinity(tid) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + if set(affinity).intersection(set(cpus)) != set(cpus): + previous_pid_affinities[tid] = copy.copy(affinity) + affinity = list(set(affinity + cpus)) try: - affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if set(affinity).intersection(set(cpus)) != set(cpus): - previous_pid_affinities[pid] = copy.copy(affinity) - affinity = list(set(affinity + cpus)) - try: - schedutils.set_affinity(pid, affinity) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - - if "threads" not in ps[pid]: - continue - threads = ps[pid]["threads"] - for tid in list(threads.keys()): - if procfs.cannot_set_thread_affinity(ps, pid, tid): - continue - try: - affinity = schedutils.get_affinity(tid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if set(affinity).intersection(set(cpus)) != set(cpus): - previous_pid_affinities[tid] = copy.copy(affinity) - affinity = list(set(affinity + cpus)) - try: - schedutils.set_affinity(tid, affinity) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - - del ps - - # Now include it in IRQs too - irqs = procfs.interrupts() - previous_irq_affinities = {} - for irq in list(irqs.keys()): - # LOC, NMI, TLB, etc - if "affinity" not in irqs[irq]: + schedutils.set_affinity(tid, affinity) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: continue - affinity = irqs[irq]["affinity"] - if set(affinity).intersection(set(cpus)) != set(cpus): - previous_irq_affinities[irq] = copy.copy(affinity) - affinity = list(set(affinity + cpus)) - set_irq_affinity(int(irq), - procfs.hexbitmask(affinity, nr_cpus)) - - affinity = parse_irq_affinity_filename("default_smp_affinity", nr_cpus) - affinity = list(set(affinity + cpus)) - set_irq_affinity_filename("default_smp_affinity", procfs.hexbitmask(affinity, nr_cpus)) - - return (previous_pid_affinities, previous_irq_affinities) - -def get_irq_users(irqs, irq, nics = None): - if not nics: - nics = ethtool.get_active_devices() - users = irqs[irq]["users"] - for u in users: - if u in nics: - try: - users[users.index(u)] = "%s(%s)" % (u, ethtool.get_module(u)) - except IOError: - # Old kernel, doesn't implement ETHTOOL_GDRVINFO - pass - return users + raise err + + del ps + + # Now include it in IRQs too + irqs = procfs.interrupts() + previous_irq_affinities = {} + for irq in list(irqs.keys()): + # LOC, NMI, TLB, etc + if "affinity" not in irqs[irq]: + continue + affinity = irqs[irq]["affinity"] + if set(affinity).intersection(set(cpus)) != set(cpus): + previous_irq_affinities[irq] = copy.copy(affinity) + affinity = list(set(affinity + cpus)) + set_irq_affinity(int(irq), procfs.hexbitmask(affinity, nr_cpus)) + + affinity = parse_irq_affinity_filename("default_smp_affinity", nr_cpus) + affinity = list(set(affinity + cpus)) + set_irq_affinity_filename("default_smp_affinity", procfs.hexbitmask(affinity, nr_cpus)) + + return (previous_pid_affinities, previous_irq_affinities) + +def get_irq_users(irqs, irq, nics=None): + if not nics: + nics = ethtool.get_active_devices() + users = irqs[irq]["users"] + for u in users: + if u in nics: + try: + users[users.index(u)] = "%s(%s)" % (u, ethtool.get_module(u)) + except IOError: + # Old kernel, doesn't implement ETHTOOL_GDRVINFO + pass + return users
def get_irq_affinity_text(irqs, irq): - affinity_list = irqs[irq]["affinity"] - try: - return list_to_cpustring(affinity_list) - except: - # needs root prio to read /proc/irq/<NUM>/smp_affinity - return "" + affinity_list = irqs[irq]["affinity"] + try: + return list_to_cpustring(affinity_list) + except: + # needs root prio to read /proc/irq/<NUM>/smp_affinity + return ""
def get_policy_and_rtprio(parm): - parms = parm.split(":") - rtprio = 0 - policy = None - if parms[0].upper() in ["OTHER", "BATCH", "IDLE", "FIFO", "RR"]: - policy = schedutils.schedfromstr("SCHED_%s" % parms[0].upper()) - if len(parms) > 1: - rtprio = int(parms[1]) - elif parms[0].upper() in ["FIFO", "RR"]: - rtprio = 1 - elif parms[0].isdigit(): - rtprio = int(parms[0]) - else: - raise ValueError - return (policy, rtprio) + parms = parm.split(":") + rtprio = 0 + policy = None + if parms[0].upper() in ["OTHER", "BATCH", "IDLE", "FIFO", "RR"]: + policy = schedutils.schedfromstr("SCHED_%s" % parms[0].upper()) + if len(parms) > 1: + rtprio = int(parms[1]) + elif parms[0].upper() in ["FIFO", "RR"]: + rtprio = 1 + elif parms[0].isdigit(): + rtprio = int(parms[0]) + else: + raise ValueError + return (policy, rtprio)
def thread_filtered(tid, cpus_filtered, show_kthreads, show_uthreads): - if cpus_filtered: - try: - affinity = schedutils.get_affinity(tid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - return False - raise e + if cpus_filtered: + try: + affinity = schedutils.get_affinity(tid) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + return False + raise err
- if set(cpus_filtered + affinity) == set(cpus_filtered): - return True + if set(cpus_filtered + affinity) == set(cpus_filtered): + return True
- if not (show_kthreads and show_uthreads): - kthread = iskthread(tid) - if ((not show_kthreads) and kthread) or \ - ((not show_uthreads) and not kthread): - return True + if not (show_kthreads and show_uthreads): + kthread = iskthread(tid) + if ((not show_kthreads) and kthread) or \ + ((not show_uthreads) and not kthread): + return True
- return False + return False
def irq_filtered(irq, irqs, cpus_filtered, is_root): - if cpus_filtered and is_root: - affinity = irqs[irq]["affinity"] - if set(cpus_filtered + affinity) == set(cpus_filtered): - return True + if cpus_filtered and is_root: + affinity = irqs[irq]["affinity"] + if set(cpus_filtered + affinity) == set(cpus_filtered): + return True
- return False + return False
def thread_set_priority(tid, policy, rtprio): - if not policy and policy != 0: - policy = schedutils.get_scheduler(tid) - schedutils.set_scheduler(tid, policy, rtprio) - -def threads_set_priority(tids, parm, affect_children = False): + if not policy and policy != 0: + policy = schedutils.get_scheduler(tid) + schedutils.set_scheduler(tid, policy, rtprio) + +def threads_set_priority(tids, parm, affect_children=False): + try: + (policy, rtprio) = get_policy_and_rtprio(parm) + except ValueError: + print("tuna: " + _(""%s" is unsupported priority value!") % parms[0]) + return + + for tid in tids: try: - (policy, rtprio) = get_policy_and_rtprio(parm) - except ValueError: - print("tuna: " + _(""%s" is unsupported priority value!") % parms[0]) - return - - for tid in tids: - try: - thread_set_priority(tid, policy, rtprio) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - if affect_children: - for child in [int (a) for a in os.listdir("/proc/%d/task" % tid)]: - if child != tid: - try: - thread_set_priority(child, policy, rtprio) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e + thread_set_priority(tid, policy, rtprio) + # old python-schedutils incorrectly raised SystemError + except (SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + if affect_children: + for child in [int(a) for a in os.listdir("/proc/%d/task" % tid)]: + if child != tid: + try: + thread_set_priority(child, policy, rtprio) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err
class sched_tunings: - def __init__(self, name, pid, policy, rtprio, affinity, percpu): - self.name = name - self.pid = pid - self.policy = policy - self.rtprio = int(rtprio) - self.affinity = affinity - self.percpu = percpu - -def get_kthread_sched_tunings(proc = None): - if not proc: - proc = procfs.pidstats() - - kthreads = {} - for pid in list(proc.keys()): - name = proc[pid]["stat"]["comm"] - # Trying to set the priority of the migration threads will - # fail, at least on 3.6.0-rc1 and doesn't make sense anyway - # and this function is only used to save those priorities - # to reset them using tools like rtctl, skip those to - # avoid sched_setscheduler/chrt to fail - if iskthread(pid) and not name.startswith("migration/"): - rtprio = int(proc[pid]["stat"]["rt_priority"]) - try: - policy = schedutils.get_scheduler(pid) - affinity = schedutils.get_affinity(pid) - except (SystemError, OSError) as e: # old python-schedutils incorrectly raised SystemError - if e.args[0] == errno.ESRCH: - continue - raise e - percpu = iskthread(pid) and \ - proc.is_bound_to_cpu(pid) - kthreads[name] = sched_tunings(name, pid, policy, - rtprio, affinity, - percpu) - - return kthreads + def __init__(self, name, pid, policy, rtprio, affinity, percpu): + self.name = name + self.pid = pid + self.policy = policy + self.rtprio = int(rtprio) + self.affinity = affinity + self.percpu = percpu + +def get_kthread_sched_tunings(proc=None): + if not proc: + proc = procfs.pidstats() + + kthreads = {} + for pid in list(proc.keys()): + name = proc[pid]["stat"]["comm"] + # Trying to set the priority of the migration threads will + # fail, at least on 3.6.0-rc1 and doesn't make sense anyway + # and this function is only used to save those priorities + # to reset them using tools like rtctl, skip those to + # avoid sched_setscheduler/chrt to fail + if iskthread(pid) and not name.startswith("migration/"): + rtprio = int(proc[pid]["stat"]["rt_priority"]) + try: + policy = schedutils.get_scheduler(pid) + affinity = schedutils.get_affinity(pid) + # old python-schedutils incorrectly raised SystemError + except(SystemError, OSError) as err: + if err.args[0] == errno.ESRCH: + continue + raise err + percpu = iskthread(pid) and \ + proc.is_bound_to_cpu(pid) + kthreads[name] = sched_tunings(name, pid, policy, rtprio, + affinity, percpu) + + return kthreads
def run_command(cmd, policy, rtprio, cpu_list): - newpid = os.fork() - if newpid == 0: - cmd_list = shlex.split(cmd) - pid = os.getpid() - if rtprio: - try: - thread_set_priority(pid, policy, rtprio) - except (SystemError, OSError) as err: - print("tuna: %s" % err) - sys.exit(2) - if cpu_list: - try: - schedutils.set_affinity(pid, cpu_list) - except (SystemError, OSError) as err: - print("tuna: %s" % err) - sys.exit(2) + newpid = os.fork() + if newpid == 0: + cmd_list = shlex.split(cmd) + pid = os.getpid() + if rtprio: + try: + thread_set_priority(pid, policy, rtprio) + except (SystemError, OSError) as err: + print("tuna: %s" % err) + sys.exit(2) + if cpu_list: + try: + schedutils.set_affinity(pid, cpu_list) + except (SystemError, OSError) as err: + print("tuna: %s" % err) + sys.exit(2)
- try: - os.execvp(cmd_list[0], cmd_list) - except (SystemError, OSError) as err: - print("tuna: %s" % err) - sys.exit(2) - else: - os.waitpid(newpid, 0); + try: + os.execvp(cmd_list[0], cmd_list) + except (SystemError, OSError) as err: + print("tuna: %s" % err) + sys.exit(2) + else: + os.waitpid(newpid, 0)
def generate_rtgroups(filename, kthreads, nr_cpus): - f = open(filename, "w") - f.write('''# Generated by tuna + f = open(filename, "w") + f.write('''# Generated by tuna # # Use it with rtctl: # @@ -673,44 +685,43 @@ def generate_rtgroups(filename, kthreads, nr_cpus): # The regex is matched against process names as printed by "ps -eo cmd".
''' % filename) - f.write("kthreads:*:1:*:[.*]$\n\n") + f.write("kthreads:*:1:*:[.*]$\n\n")
- per_cpu_kthreads = [] - names = list(kthreads.keys()) - names.sort() - for name in names: - kt = kthreads[name] - try: - idx = name.index("/") - common = name[:idx] - if common in per_cpu_kthreads: - continue - per_cpu_kthreads.append(common) - name = common - if common[:5] == "sirq-": - common = "(sirq|softirq)" + common[4:] - elif common[:8] == "softirq-": - common = "(sirq|softirq)" + common[7:] - name = "s" + name[4:] - regex = common + "/.*" - except: - idx = 0 - regex = name - pass - if kt.percpu or idx != 0 or name == "posix_cpu_timer": - # Don't mess with workqueues, etc - # posix_cpu_timer is too long and doesn't - # have PF_THREAD_BOUND in its per process - # flags... - mask = "*" - else: - mask = ",".join([hex(a) for a in \ - procfs.hexbitmask(kt.affinity, nr_cpus)]) - f.write("%s:%c:%d:%s:[%s]$\n" % (name, - schedutils.schedstr(kt.policy)[6].lower(), - kt.rtprio, mask, regex)) - f.close() + per_cpu_kthreads = [] + names = list(kthreads.keys()) + names.sort() + for name in names: + kt = kthreads[name] + try: + idx = name.index("/") + common = name[:idx] + if common in per_cpu_kthreads: + continue + per_cpu_kthreads.append(common) + name = common + if common[:5] == "sirq-": + common = "(sirq|softirq)" + common[4:] + elif common[:8] == "softirq-": + common = "(sirq|softirq)" + common[7:] + name = "s" + name[4:] + regex = common + "/.*" + except: + idx = 0 + regex = name + if kt.percpu or idx != 0 or name == "posix_cpu_timer": + # Don't mess with workqueues, etc + # posix_cpu_timer is too long and doesn't + # have PF_THREAD_BOUND in its per process + # flags... + mask = "*" + else: + mask = ",".join([hex(a) for a in \ + procfs.hexbitmask(kt.affinity, nr_cpus)]) + f.write("%s:%c:%d:%s:[%s]$\n" % (name, \ + schedutils.schedstr(kt.policy)[6].lower(), \ + kt.rtprio, mask, regex)) + f.close()
def nohz_full_list(): - return [ int(cpu) for cpu in procfs.cmdline().options["nohz_full"].split(",") ] + return [int(cpu) for cpu in procfs.cmdline().options["nohz_full"].split(",")]
hi john, can you look at https://github.com/cz172638/tuna/tree/osc-py3-gi results from tuna's master looks weird. regards j.
On Tue, Dec 22, 2020 at 10:16 PM John Kacur jkacur@redhat.com wrote:
These changes don't completely fix the gui for Gtk-3.0 but they get us a lot closer, patches that improve this are very welcome, so get hacking!
I also fixed up the spacing and formatting to match python standards as of python3
John Kacur (33): tuna_gui.py: Reformat the file, style fix-ups tuna_gui.glade: Initial changes to upgrade glade file for gtk3 tuna_gui.py: gtk2 to gtk3 changes tuna: gui changes for gtk2 to gtk3 tuna: More changes to header files in tuna/gui for gtk3 tuna: add to gitignore and create gitattributes tuna: modernize the spacing in irqview tuna: Remove old glade imports from tuna_gui.py tuna_gui.py: Fix inconsistent spacing from in tuna_gui.py tuna: cpuview.py - Modernize the spacing tuna: cpuview.py: A few more style improvements irqview: fix bad spacing tuna: procview.py: Update the spacing and style tuna: commonview.py: Update the spacing and style tuna: procview.py: Update spacing and style tuna: util.py: Update the spacing and fix some style problems tuna-cmd: Update the spacing and style for tuna-cmd tuna: tuna-cmd:py: Convert type comparison to isinstance tuna: config.py: Update spacing to 4 spaces tuna/gui/__init__.py: Fix some whitespace problems tuna: commonview.py: Fix comparisons with None tuna: cpuview.py: box.pack_start needs extra parameter tuna: tuna-cmd.py Fix style problems recommened by PEP8 tuna: Fix spacing of oscilloscope.py tuna: config.py: Port file to Gtk-3.0 tuna:irqview.py: Port to Gtk-3.0 tuna: procview.py: Port to Gtk-3.0 tuna: profileview.py: Port to Gtk-3.0 tuna: util.py: Fix some style problems tuna: oscilloscope.py: Changes to port to Gtk-3.0 tuna: sysfs.py: Update spacing / tabs to modern python style tuna: tuna.py: Update spacing / tabs to modern python style tuna: tuna_gui.py: Chanages to port to Gtk-3.0
.gitattributes | 2 + .gitignore | 2 + oscilloscope-cmd.py | 141 ++-- tuna-cmd.py | 1267 ++++++++++++++++++------------------ tuna/config.py | 760 +++++++++++----------- tuna/gui/__init__.py | 6 +- tuna/gui/commonview.py | 521 +++++++-------- tuna/gui/cpuview.py | 694 ++++++++++---------- tuna/gui/irqview.py | 640 ++++++++++--------- tuna/gui/procview.py | 1347 +++++++++++++++++++-------------------- tuna/gui/profileview.py | 668 ++++++++++--------- tuna/gui/util.py | 226 +++---- tuna/oscilloscope.py | 861 ++++++++++++------------- tuna/sysfs.py | 199 +++--- tuna/tuna.py | 1207 ++++++++++++++++++----------------- tuna/tuna_gui.glade | 1037 ++++++++++++++++-------------- tuna/tuna_gui.py | 294 +++++---- 17 files changed, 5030 insertions(+), 4842 deletions(-) create mode 100644 .gitattributes mode change 100755 => 100644 tuna/gui/util.py
-- 2.26.2 _______________________________________________ tuna-devel mailing list -- tuna-devel@lists.fedorahosted.org To unsubscribe send an email to tuna-devel-leave@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/tuna-devel@lists.fedorahosted.o...
tuna-devel@lists.fedorahosted.org