diff --git a/SOURCES/interrupts-Do-not-refrain-from-parsing-the-irq-affin.patch b/SOURCES/interrupts-Do-not-refrain-from-parsing-the-irq-affin.patch new file mode 100644 index 0000000..e7ef7ae --- /dev/null +++ b/SOURCES/interrupts-Do-not-refrain-from-parsing-the-irq-affin.patch @@ -0,0 +1,60 @@ +From 9361b771ad0b8fe1206469b89fc2eef9d13fe8b2 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Wed, 10 Jun 2015 19:44:20 -0300 +Subject: [PATCH 3/7] interrupts: Do not refrain from parsing the irq + affinities for !root + +I.e. let the OS be the one to decide if access to this file is allowed +or not, and non root users can see this, at least around 4.1-rc times: + +Running: procfs/procfs.py: + + 31: {'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI-edge', 'cpu': [178564, 0, 285828, 0], 'users': ['xhci_hcd']} + 30: {'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI-edge', 'cpu': [342630, 0, 197229, 0], 'users': ['0000:00:1f.2']} + 35: {'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI-edge', 'cpu': [858, 0, 565, 0], 'users': ['snd_hda_intel']} + 34: {'affinity': [0, 1, 2, 3], 'type': 'PCI-MSI-edge', 'cpu': [306, 0, 44, 0], 'users': ['thunderbolt']} + +And now 'tuna -Q' works for non root users: + + [acme@zoo python-linux-procfs]$ ../tuna/tuna-cmd.py -Q + # users affinity + 0 timer 0,1,2,3 + 8 rtc0 0,1,2,3 + 9 acpi 0,1,2,3 + 17 17-fasteoi brcmsmac 0,1,2,3 + 22 22-fasteoi ehci_hcd:usb4 0,1,2,3 + 23 23-fasteoi ehci_hcd:usb3 0,1,2,3 + 26 pciehp 0,1,2,3 + 27 pciehp 0,1,2,3 + 28 pciehp 0,1,2,3 + 29 pciehp 0,1,2,3 + 30 0000:00:1f.2 0,1,2,3 + 31 xhci_hcd 0,1,2,3 + 32 i915 0,1,2,3 + 33 mei_me 0,1,2,3 + 34 thunderbolt 0,1,2,3 + 35 snd_hda_intel 0,1,2,3 + [acme@zoo python-linux-procfs]$ + +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + procfs/procfs.py | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index 4ff7e9804bc9..2d0e2b043797 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -405,8 +405,6 @@ class interrupts: + return dict + + def parse_affinity(self, irq): +- if os.getuid() != 0: +- return + try: + f = file("/proc/irq/%s/smp_affinity" % irq) + line = f.readline() +-- +1.8.3.1 + diff --git a/SOURCES/pflags-Add-command-line-utility-to-print-processor-f.patch b/SOURCES/pflags-Add-command-line-utility-to-print-processor-f.patch new file mode 100644 index 0000000..41214a5 --- /dev/null +++ b/SOURCES/pflags-Add-command-line-utility-to-print-processor-f.patch @@ -0,0 +1,103 @@ +From 8dc7ac166c30435d87a76bb5067724497a7ba592 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Thu, 11 Jun 2015 16:45:33 -0300 +Subject: [PATCH 6/7] pflags: Add command line utility to print processor flags + +E.g.: + + $ ./pflags-cmd.py ssh*,bash,6941 + 1278 sshd RANDOMIZE|SUPERPRIV|USED_ASYNC|USED_MATH + 2692 bash RANDOMIZE|USED_ASYNC|USED_MATH + 2919 bash RANDOMIZE|SUPERPRIV|USED_ASYNC|USED_MATH + 3116 bash RANDOMIZE|USED_ASYNC|USED_MATH + 3149 bash RANDOMIZE|USED_ASYNC|USED_MATH + 3384 bash RANDOMIZE|USED_ASYNC|USED_MATH + 3579 bash RANDOMIZE|USED_ASYNC|USED_MATH + 3834 ssh RANDOMIZE|USED_ASYNC|USED_MATH + 4372 bash RANDOMIZE|USED_ASYNC|USED_MATH + 5024 bash RANDOMIZE|USED_ASYNC|USED_MATH + 6339 bash RANDOMIZE|USED_ASYNC|USED_MATH + 6941 vim FREEZER_SKIP|RANDOMIZE|USED_ASYNC|USED_MATH + $ + +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + pflags-cmd.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + create mode 100755 pflags-cmd.py + +diff --git a/pflags-cmd.py b/pflags-cmd.py +new file mode 100755 +index 000000000000..9228c688e7a2 +--- /dev/null ++++ b/pflags-cmd.py +@@ -0,0 +1,65 @@ ++#! /usr/bin/python ++# -*- python -*- ++# -*- coding: utf-8 -*- ++# print process flags ++# Copyright (C) 2015 Red Hat Inc. ++# Arnaldo Carvalho de Melo ++# ++# This application is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; version 2. ++# ++# This application is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++import procfs, re, fnmatch, sys ++ ++ps = None ++ ++def thread_mapper(s): ++ global ps ++ ++ try: ++ return [ int(s), ] ++ except: ++ pass ++ try: ++ return ps.find_by_regex(re.compile(fnmatch.translate(s))) ++ except: ++ return ps.find_by_name(s) ++ ++def main(argv): ++ ++ global ps ++ ps = procfs.pidstats() ++ ++ if (len(argv) > 1): ++ pids = reduce(lambda i, j: i + j, map(thread_mapper, argv[1].split(","))) ++ else: ++ pids = ps.processes.keys() ++ ++ pids.sort() ++ len_comms = map(lambda pid: len(ps[pid]["stat"]["comm"]), pids) ++ max_comm_len = max(len_comms) ++ del(len_comms) ++ ++ for pid in pids: ++ flags = ps[pid].stat.process_flags() ++ # Remove flags that were superseeded ++ if "PF_THREAD_BOUND" in flags and "PF_NO_SETAFFINITY" in flags: ++ flags.remove("PF_THREAD_BOUND") ++ if "PF_FLUSHER" in flags and "PF_NPROC_EXCEEDED" in flags: ++ flags.remove("PF_FLUSHER") ++ if "PF_SWAPOFF" in flags and "PF_MEMALLOC_NOIO" in flags: ++ flags.remove("PF_SWAPOFF") ++ if "PF_FREEZER_NOSIG" in flags and "PF_SUSPEND_TASK" in flags: ++ flags.remove("PF_FREEZER_NOSIG") ++ comm = ps[pid].stat["comm"] ++ flags.sort() ++ sflags = reduce(lambda i, j: "%s|%s" % (i, j), map(lambda a: a[3:],flags)) ++ print "%6d %*s %s" %(pid, max_comm_len, comm, sflags) ++ ++if __name__ == '__main__': ++ main(sys.argv) +-- +1.8.3.1 + diff --git a/SOURCES/pidstat-Add-PF_NO_SETAFFINITY-const.patch b/SOURCES/pidstat-Add-PF_NO_SETAFFINITY-const.patch new file mode 100644 index 0000000..834a26d --- /dev/null +++ b/SOURCES/pidstat-Add-PF_NO_SETAFFINITY-const.patch @@ -0,0 +1,59 @@ +From 905f778dc295ad5d934fed6fd5f2742c2123dbcd Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Wed, 10 Jun 2015 19:38:18 -0300 +Subject: [PATCH 2/7] pidstat: Add PF_NO_SETAFFINITY const + +For the stat flag that means that userland is not allowed to meddle with +cpus_allowed, i.e. with the thread's smp affinity, via +sched_setaffinity. + +This indeed has the same value as PF_THREAD_BOUND, see the kernel +sources for an explanation, but basically was in this cset: + +commit 14a40ffccd6163bbcd1d6f32b28a88ffe6149fc6 +Author: Tejun Heo +Date: Tue Mar 19 13:45:20 2013 -0700 + + sched: replace PF_THREAD_BOUND with PF_NO_SETAFFINITY + + PF_THREAD_BOUND was originally used to mark kernel threads which + were bound to a specific CPU using kthread_bind() and a task with + the flag set allows cpus_allowed modifications only to itself. + Workqueue is currently abusing it to prevent userland from meddling + with cpus_allowed of workqueue workers. + + --------------------------------------------------------------- + +So add the new const but keep the old one, we may have some tool out +there using it. + +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + procfs/procfs.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index 0dbf7f5b7da5..4ff7e9804bc9 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -2,7 +2,7 @@ + # -*- python -*- + # -*- coding: utf-8 -*- + # +-# Copyright (C) 2007 Red Hat, Inc. ++# Copyright (C) 2007-2015 Red Hat, Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -54,6 +54,7 @@ class pidstat: + PF_SPREAD_PAGE = 0x01000000 + PF_SPREAD_SLAB = 0x02000000 + PF_THREAD_BOUND = 0x04000000 ++ PF_NO_SETAFFINITY = 0x04000000 # /* Userland is not allowed to meddle with cpus_allowed */ + PF_MEMPOLICY = 0x10000000 + PF_MUTEX_TESTER = 0x20000000 + PF_FREEZER_SKIP = 0x40000000 +-- +1.8.3.1 + diff --git a/SOURCES/pidstat-Add-missing-PF_-flags.patch b/SOURCES/pidstat-Add-missing-PF_-flags.patch new file mode 100644 index 0000000..cd33a09 --- /dev/null +++ b/SOURCES/pidstat-Add-missing-PF_-flags.patch @@ -0,0 +1,63 @@ +From b23bec399251f669d860f5c04c32f4c77325dcfb Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Thu, 11 Jun 2015 16:44:52 -0300 +Subject: [PATCH 5/7] pidstat: Add missing PF_ flags + +Adding the ones found in the v4.1-rc kernel. + +Signed-off-by: Arnaldo Carvalho de Melo +--- + procfs/procfs.py | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index f1604ba6ed01..6b4fd84f3171 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -30,22 +30,30 @@ def process_cmdline(pid_info): + + class pidstat: + ++ # Entries with the same value, the one with a comment after it is the ++ # more recent, having replaced the other name in v4.1-rc kernel times. ++ + PF_ALIGNWARN = 0x00000001 + PF_STARTING = 0x00000002 + PF_EXITING = 0x00000004 + PF_EXITPIDONE = 0x00000008 + PF_VCPU = 0x00000010 ++ PF_WQ_WORKER = 0x00000020 # /* I'm a workqueue worker */ + PF_FORKNOEXEC = 0x00000040 ++ PF_MCE_PROCESS = 0x00000080 # /* process policy on mce errors */ + PF_SUPERPRIV = 0x00000100 + PF_DUMPCORE = 0x00000200 + PF_SIGNALED = 0x00000400 + PF_MEMALLOC = 0x00000800 ++ PF_NPROC_EXCEEDED= 0x00001000 # /* set_user noticed that RLIMIT_NPROC was exceeded */ + PF_FLUSHER = 0x00001000 + PF_USED_MATH = 0x00002000 ++ PF_USED_ASYNC = 0x00004000 # /* used async_schedule*(), used by module init */ + PF_NOFREEZE = 0x00008000 + PF_FROZEN = 0x00010000 + PF_FSTRANS = 0x00020000 + PF_KSWAPD = 0x00040000 ++ PF_MEMALLOC_NOIO = 0x00080000 # /* Allocating memory without IO involved */ + PF_SWAPOFF = 0x00080000 + PF_LESS_THROTTLE = 0x00100000 + PF_KTHREAD = 0x00200000 +@@ -55,10 +63,12 @@ class pidstat: + PF_SPREAD_SLAB = 0x02000000 + PF_THREAD_BOUND = 0x04000000 + PF_NO_SETAFFINITY = 0x04000000 # /* Userland is not allowed to meddle with cpus_allowed */ ++ PF_MCE_EARLY = 0x08000000 # /* Early kill for mce process policy */ + PF_MEMPOLICY = 0x10000000 + PF_MUTEX_TESTER = 0x20000000 + PF_FREEZER_SKIP = 0x40000000 + PF_FREEZER_NOSIG = 0x80000000 ++ PF_SUSPEND_TASK = 0x80000000 # /* this thread called freeze_processes and should not be frozen */ + + proc_stat_fields = [ "pid", "comm", "state", "ppid", "pgrp", "session", + "tty_nr", "tpgid", "flags", "minflt", "cminflt", +-- +1.8.3.1 + diff --git a/SOURCES/pidstat-Fix-process_flags-method.patch b/SOURCES/pidstat-Fix-process_flags-method.patch new file mode 100644 index 0000000..695257b --- /dev/null +++ b/SOURCES/pidstat-Fix-process_flags-method.patch @@ -0,0 +1,30 @@ +From ade62416612d7f9de610602a4ccc5210e09b34b9 Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Thu, 11 Jun 2015 16:20:03 -0300 +Subject: [PATCH 4/7] pidstat: Fix process_flags() method + +It was referencing self.flags, that doesn't exists, fix it by making it +access self.fields["flags"] instead. + +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + procfs/procfs.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index 2d0e2b043797..f1604ba6ed01 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -115,7 +115,7 @@ class pidstat: + if attr[:3] != "PF_": + continue + value = getattr(self, attr) +- if value & self.flags: ++ if value & self.fields["flags"]: + sflags.append(attr) + + return sflags +-- +1.8.3.1 + diff --git a/SOURCES/pidstat-Support-COMM-names-with-spaces.patch b/SOURCES/pidstat-Support-COMM-names-with-spaces.patch new file mode 100644 index 0000000..dd030ae --- /dev/null +++ b/SOURCES/pidstat-Support-COMM-names-with-spaces.patch @@ -0,0 +1,35 @@ +From d2b197d585de99fec07ce78d4233eff4f32c350e Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Mon, 15 Jun 2015 12:44:29 -0300 +Subject: [PATCH 7/7] pidstat: Support COMM names with spaces + +The load method was just splitting the fields using space as the +separator, but since some COMM names started having spaces... We +better use the () as the COMM "quotes", using spaces as the +separator for the remaining fields. + +Reported-by: Luiz Capitulino +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + procfs/procfs.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index 6b4fd84f3171..0ed55af1c219 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -100,8 +100,9 @@ class pidstat: + + def load(self, basedir = "/proc"): + f = open("%s/%d/stat" % (basedir, self.pid)) +- fields = f.readline().strip().split() ++ fields = f.readline().strip().split(') ') + f.close() ++ fields = fields[0].split(' (') + fields[1].split() + self.fields = {} + nr_fields = min(len(fields), len(self.proc_stat_fields)) + for i in range(nr_fields): +-- +1.8.3.1 + diff --git a/SOURCES/procfs-Add-a-__contains__-method-to-dict-classes.patch b/SOURCES/procfs-Add-a-__contains__-method-to-dict-classes.patch new file mode 100644 index 0000000..cd5b471 --- /dev/null +++ b/SOURCES/procfs-Add-a-__contains__-method-to-dict-classes.patch @@ -0,0 +1,69 @@ +From 0f2e3966ccb296e350e7895fc95beb20d6d5be7e Mon Sep 17 00:00:00 2001 +From: Guy Streeter +Date: Thu, 28 May 2015 12:22:45 -0500 +Subject: [PATCH 1/7] procfs: Add a __contains__ method to dict classes + +Signed-off-by: Guy Streeter +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: John Kacur +--- + procfs/procfs.py | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/procfs/procfs.py b/procfs/procfs.py +index ecd7b202f223..0dbf7f5b7da5 100755 +--- a/procfs/procfs.py ++++ b/procfs/procfs.py +@@ -84,6 +84,9 @@ class pidstat: + def has_key(self, fieldname): + return self.fields.has_key(fieldname) + ++ def __contains__(self, fieldname): ++ return fieldname in self.fields ++ + def load(self, basedir = "/proc"): + f = open("%s/%d/stat" % (basedir, self.pid)) + fields = f.readline().strip().split() +@@ -131,6 +134,9 @@ class pidstatus: + def has_key(self, fieldname): + return self.fields.has_key(fieldname) + ++ def __contains__(self, fieldname): ++ return fieldname in self.fields ++ + def load(self, basedir = "/proc"): + f = open("%s/%d/status" % (basedir, self.pid)) + self.fields = {} +@@ -175,6 +181,9 @@ class process: + def has_key(self, attr): + return hasattr(self, attr) + ++ def __contains__(self, attr): ++ return hasattr(self, attr) ++ + def load_cmdline(self): + f = file("/proc/%d/cmdline" % self.pid) + self.cmdline = f.readline().strip().split('\0')[:-1] +@@ -227,6 +236,9 @@ class pidstats: + def has_key(self, key): + return self.processes.has_key(key) + ++ def __contains__(self, key): ++ return key in self.processes ++ + def reload(self): + del self.processes + self.processes = {} +@@ -350,6 +362,9 @@ class interrupts: + def has_key(self, key): + return self.interrupts.has_key(str(key)) + ++ def __contains__(self, key): ++ return str(key) in self.interrupts ++ + def reload(self): + del self.interrupts + self.interrupts = {} +-- +1.8.3.1 + diff --git a/SPECS/python-linux-procfs.spec b/SPECS/python-linux-procfs.spec index 828e56f..f174d99 100644 --- a/SPECS/python-linux-procfs.spec +++ b/SPECS/python-linux-procfs.spec @@ -1,16 +1,22 @@ %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %{!?python_ver: %define python_ver %(%{__python} -c "import sys ; print sys.version[:3]")} - - Name: python-linux-procfs Version: 0.4.6 -Release: 2%{?dist} +Release: 3%{?dist} License: GPLv2 Summary: Linux /proc abstraction classes Group: System Environment/Libraries Source: http://userweb.kernel.org/~acme/python-linux-procfs/%{name}-%{version}.tar.bz2 -# Patch0: 0001-pidstats-Added-support-for-parsing-cgroups-as-a-per-.patch + +Patch1: procfs-Add-a-__contains__-method-to-dict-classes.patch +Patch2: pidstat-Add-PF_NO_SETAFFINITY-const.patch +Patch3: interrupts-Do-not-refrain-from-parsing-the-irq-affin.patch +Patch4: pidstat-Fix-process_flags-method.patch +Patch5: pidstat-Add-missing-PF_-flags.patch +Patch6: pflags-Add-command-line-utility-to-print-processor-f.patch +Patch7: pidstat-Support-COMM-names-with-spaces.patch + URL: http://userweb.kernel.org/~acme/python-linux-procfs BuildArch: noarch BuildRequires: python-devel @@ -21,7 +27,13 @@ Abstractions to extract information from the Linux kernel /proc files. %prep %setup -q -# %patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build %{__python} setup.py build @@ -29,12 +41,15 @@ Abstractions to extract information from the Linux kernel /proc files. %install rm -rf %{buildroot} %{__python} setup.py install --skip-build --root %{buildroot} +mkdir -p %{buildroot}%{_bindir} +cp pflags-cmd.py %{buildroot}%{_bindir}/pflags %clean rm -rf %{buildroot} %files %defattr(0755,root,root,0755) +%{_bindir}/pflags %{python_sitelib}/procfs/ %defattr(0644,root,root,0755) %if "%{python_ver}" >= "2.5" @@ -43,10 +58,20 @@ rm -rf %{buildroot} %doc COPYING %changelog +* Thu Jun 25 2015 John Kacur - 0.4.6-3 +- procfs-Add-a-__contains__-method-to-dict-classes.patch +- pidstat-Add-PF_NO_SETAFFINITY-const.patch +- interrupts-Do-not-refrain-from-parsing-the-irq-affin.patch +- pidstat-Fix-process_flags-method.patch +- pidstat-Add-missing-PF_-flags.patch +- pflags-Add-command-line-utility-to-print-processor-f.patch +- pidstat-Support-COMM-names-with-spaces.patch +Resolves: rhbz#1232394 + * Fri Dec 27 2013 Daniel Mach - 0.4.6-2 - Mass rebuild 2013-12-27 -* Wed Jun 14 2013 Jiri Kastner - 0.4.6-1 +* Fri Jun 14 2013 Jiri Kastner - 0.4.6-1 - updated to 0.4.6 * Thu Jun 6 2013 Jiri Kastner - 0.4.5-1 @@ -73,7 +98,7 @@ rm -rf %{buildroot} * Thu Feb 26 2009 Fedora Release Engineering - 0.4.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild -* Mon Feb 10 2009 Arnaldo Carvalho de Melo - 0.4.4-1 +* Tue Feb 10 2009 Arnaldo Carvalho de Melo - 0.4.4-1 - Even more fixes due to the fedora review process * Mon Feb 9 2009 Arnaldo Carvalho de Melo - 0.4.3-1