From d4c9e293f052609a7bdb45013ad59f5e4ef2776c Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 1 Feb 2022 13:07:58 -0500 Subject: [PATCH] import python-linux-procfs-0.7.0-1.el9 --- .gitignore | 2 +- .python-linux-procfs.metadata | 2 +- ...-linux-procfs-Fix-UnicodeDecodeError.patch | 68 --- ...cfs-Fix-traceback-with-non-utf8-char.patch | 33 -- ...cfs-Propagate-error-to-user-if-a-pid.patch | 68 --- ...ython-linux-procfs-Various-clean-ups.patch | 502 ------------------ ...cfs-pflags-Handle-pids-that-complete.patch | 50 -- SPECS/python-linux-procfs.spec | 13 +- 8 files changed, 8 insertions(+), 730 deletions(-) delete mode 100644 SOURCES/python-linux-procfs-Fix-UnicodeDecodeError.patch delete mode 100644 SOURCES/python-linux-procfs-Fix-traceback-with-non-utf8-char.patch delete mode 100644 SOURCES/python-linux-procfs-Propagate-error-to-user-if-a-pid.patch delete mode 100644 SOURCES/python-linux-procfs-Various-clean-ups.patch delete mode 100644 SOURCES/python-linux-procfs-pflags-Handle-pids-that-complete.patch diff --git a/.gitignore b/.gitignore index 75af5c0..2e51ded 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/python-linux-procfs-0.6.3.tar.xz +SOURCES/python-linux-procfs-0.7.0.tar.xz diff --git a/.python-linux-procfs.metadata b/.python-linux-procfs.metadata index 5089672..89ef68a 100644 --- a/.python-linux-procfs.metadata +++ b/.python-linux-procfs.metadata @@ -1 +1 @@ -99ff8644d17abacf9b63d81693b6330b429f0d32 SOURCES/python-linux-procfs-0.6.3.tar.xz +63a85059394ac0d1b8f93fbb251be6408bf5d2f7 SOURCES/python-linux-procfs-0.7.0.tar.xz diff --git a/SOURCES/python-linux-procfs-Fix-UnicodeDecodeError.patch b/SOURCES/python-linux-procfs-Fix-UnicodeDecodeError.patch deleted file mode 100644 index 45735b0..0000000 --- a/SOURCES/python-linux-procfs-Fix-UnicodeDecodeError.patch +++ /dev/null @@ -1,68 +0,0 @@ -From a752e7995bfdabb08b5bb6bcd437b9a5d2e53a7a Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Thu, 9 Dec 2021 10:11:07 -0500 -Subject: [PATCH 2/2] python-linux-procfs: Fix UnicodeDecodeError - -Commit 7570fc0d6082 meant to solve the UnicodeDecodeError - -Instead it actually increased the problem by reading lines as bytes -and decoding them. - -The original problem is hard to trigger and doesn't trigger consistently -with reproducers. In addition there seems to be a difference in how this -is handled between python-3.6 to python-3.9 - -For now, we should return the code to reading as utf-8 (the default) -since that handles more cases than the current code. - -We can catch the UnicodeDecodeError and ignore it for now. It is not -ideal because we are not handling some pids that trigger the error. - -This patch also includes a fix for a FileNotFoundError which can occur if -a pid exits and disappears before we try to read it in the /proc file -system. - -Signed-off-by: John Kacur ---- - procfs/procfs.py | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/procfs/procfs.py b/procfs/procfs.py -index a78bac5376e3..de55dfc1aef4 100755 ---- a/procfs/procfs.py -+++ b/procfs/procfs.py -@@ -44,7 +44,11 @@ def process_cmdline(pid_info): - if pid_info["cmdline"]: - return reduce(lambda a, b: a + " %s" % b, pid_info["cmdline"]).strip() - -- return pid_info["stat"]["comm"] -+ try: -+ """ If a pid disappears before we query it, return None """ -+ return pid_info["stat"]["comm"] -+ except: -+ return None - - - class pidstat: -@@ -374,9 +378,15 @@ class process: - return hasattr(self, attr) - - def load_cmdline(self): -- with open("/proc/%d/cmdline" % self.pid, mode='rb') as f: -- cmdline = f.readline().decode(encoding='unicode_escape') -- self.cmdline = cmdline.strip().split('\0')[:-1] -+ try: -+ with open("/proc/%d/cmdline" % self.pid) as f: -+ self.cmdline = f.readline().strip().split('\0')[:-1] -+ except FileNotFoundError: -+ """ This can happen when a pid disappears """ -+ self.cmdline = None -+ except UnicodeDecodeError: -+ """ TODO - this shouldn't happen, needs to be investigated """ -+ self.cmdline = None - - def load_threads(self): - self.threads = pidstats("/proc/%d/task/" % self.pid) --- -2.31.1 - diff --git a/SOURCES/python-linux-procfs-Fix-traceback-with-non-utf8-char.patch b/SOURCES/python-linux-procfs-Fix-traceback-with-non-utf8-char.patch deleted file mode 100644 index ec5399e..0000000 --- a/SOURCES/python-linux-procfs-Fix-traceback-with-non-utf8-char.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7570fc0d6082cb476c32233c2904214dd57737a8 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Fri, 19 Nov 2021 16:03:22 -0500 -Subject: [PATCH] python-linux-procfs: Fix traceback with non-utf8 chars in the - /proc/PID/cmdline - -Fix traceback if there are non-utf8 characters in the /proc/PID/cmdline - -Signed-off-by: John Kacur ---- - procfs/procfs.py | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/procfs/procfs.py b/procfs/procfs.py -index 3b7474cccb01..408b2bcd0a31 100755 ---- a/procfs/procfs.py -+++ b/procfs/procfs.py -@@ -357,9 +357,9 @@ class process: - return hasattr(self, attr) - - def load_cmdline(self): -- f = open("/proc/%d/cmdline" % self.pid) -- self.cmdline = f.readline().strip().split('\0')[:-1] -- f.close() -+ with open("/proc/%d/cmdline" % self.pid, mode='rb') as f: -+ cmdline = f.readline().decode(encoding='unicode_escape') -+ self.cmdline = cmdline.strip().split('\0')[:-1] - - def load_threads(self): - self.threads = pidstats("/proc/%d/task/" % self.pid) --- -2.31.1 - diff --git a/SOURCES/python-linux-procfs-Propagate-error-to-user-if-a-pid.patch b/SOURCES/python-linux-procfs-Propagate-error-to-user-if-a-pid.patch deleted file mode 100644 index bbd5ced..0000000 --- a/SOURCES/python-linux-procfs-Propagate-error-to-user-if-a-pid.patch +++ /dev/null @@ -1,68 +0,0 @@ -From b7ea06b21456d465f2d9d11358fb803eb277357f Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 23 Nov 2021 09:58:58 -0500 -Subject: [PATCH 1/3] python-linux-procfs: Propagate error to user if a pid is - completed - -If a pid is completed and disappears a FileNotFoundError will occur -because /proc/pid/stat will disappear too. - -It is not possible to check for the file first because it could still -disappear between the time of the check and the time of use. - -Propagate this error to the user. -The user should handle this with a try, except clause and ignore it if -an exception occurs. - -Signed-off-by: John Kacur ---- - procfs/procfs.py | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/procfs/procfs.py b/procfs/procfs.py -index 408b2bcd0a31..a0e9977214fe 100755 ---- a/procfs/procfs.py -+++ b/procfs/procfs.py -@@ -130,7 +130,12 @@ class pidstat: - - def __init__(self, pid, basedir="/proc"): - self.pid = pid -- self.load(basedir) -+ try: -+ self.load(basedir) -+ except FileNotFoundError: -+ # The file representing the pid has disappeared -+ # propagate the error to the user to handle -+ raise - - def __getitem__(self, fieldname): - return self.fields[fieldname] -@@ -151,7 +156,11 @@ class pidstat: - return fieldname in self.fields - - def load(self, basedir="/proc"): -- f = open("%s/%d/stat" % (basedir, self.pid)) -+ try: -+ f = open("%s/%d/stat" % (basedir, self.pid)) -+ except FileNotFoundError: -+ # The pid has disappeared, propagate the error -+ raise - fields = f.readline().strip().split(') ') - f.close() - fields = fields[0].split(' (') + fields[1].split() -@@ -338,7 +347,11 @@ class process: - else: - sclass = pidstatus - -- setattr(self, attr, sclass(self.pid, self.basedir)) -+ try: -+ setattr(self, attr, sclass(self.pid, self.basedir)) -+ except FileNotFoundError: -+ # The pid has disappeared, progate the error -+ raise - elif attr == "cmdline": - self.load_cmdline() - elif attr == "threads": --- -2.31.1 - diff --git a/SOURCES/python-linux-procfs-Various-clean-ups.patch b/SOURCES/python-linux-procfs-Various-clean-ups.patch deleted file mode 100644 index 5e0a690..0000000 --- a/SOURCES/python-linux-procfs-Various-clean-ups.patch +++ /dev/null @@ -1,502 +0,0 @@ -From ce8cacdd515bf7270daef62648d5f994f111cded Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Thu, 2 Dec 2021 16:52:10 -0500 -Subject: [PATCH 1/2] python-linux-procfs: Various clean-ups - -- Replace f=open with 'with' (context managers), except in try-except blocks -- Reformat lines that are too long, especially in comments -- Use min() instead of if construct -- Use bool instead of complicated and True or False constructs -- Reorder imports - -Signed-off-by: John Kacur ---- - procfs/procfs.py | 292 +++++++++++++++++++++++------------------------ - 1 file changed, 142 insertions(+), 150 deletions(-) - -diff --git a/procfs/procfs.py b/procfs/procfs.py -index a0e9977214fe..a78bac5376e3 100755 ---- a/procfs/procfs.py -+++ b/procfs/procfs.py -@@ -19,10 +19,10 @@ - # - - import os --import time --from functools import reduce - import platform - import re -+import time -+from functools import reduce - from six.moves import range - from procfs.utilist import bitmasklist - -@@ -37,8 +37,9 @@ def is_s390(): - - def process_cmdline(pid_info): - """ -- Returns the process command line, if available in the given `process' class, if -- not available, falls back to using the comm (short process name) in its pidstat key. -+ Returns the process command line, if available in the given `process' class, -+ if not available, falls back to using the comm (short process name) in its -+ pidstat key. - """ - if pid_info["cmdline"]: - return reduce(lambda a, b: a + " %s" % b, pid_info["cmdline"]).strip() -@@ -47,10 +48,12 @@ def process_cmdline(pid_info): - - - class pidstat: -- """Provides a dictionary to access the fields in the per process /proc/PID/stat -- files. -+ """ -+ Provides a dictionary to access the fields in the -+ per process /proc/PID/stat files. - -- One can obtain the available fields asking for the keys of the dictionary, e.g.: -+ One can obtain the available fields by asking for the keys of the -+ dictionary, e.g.: - - >>> p = procfs.pidstat(1) - >>> print p.keys() -@@ -182,8 +185,7 @@ class pidstat: - Returns true if this process has a fixed smp affinity mask, - not allowing it to be moved to a different set of CPUs. - """ -- return self.fields["flags"] & self.PF_THREAD_BOUND and \ -- True or False -+ return bool(self.fields["flags"] & self.PF_THREAD_BOUND) - - def process_flags(self): - """ -@@ -193,33 +195,34 @@ class pidstat: - - As of v4.2-rc7 these include (from include/linux/sched.h comments): - -- PF_EXITING Getting shut down -- PF_EXITPIDONE Pi exit done on shut down -+ PF_EXITING Getting shut down -+ PF_EXITPIDONE Pi exit done on shut down - PF_VCPU I'm a virtual CPU -- PF_WQ_WORKER I'm a workqueue worker -- PF_FORKNOEXEC Forked but didn't exec -- PF_MCE_PROCESS Process policy on mce errors -- PF_SUPERPRIV Used super-user privileges -+ PF_WQ_WORKER I'm a workqueue worker -+ PF_FORKNOEXEC Forked but didn't exec -+ PF_MCE_PROCESS Process policy on mce errors -+ PF_SUPERPRIV Used super-user privileges - PF_DUMPCORE Dumped core - PF_SIGNALED Killed by a signal - PF_MEMALLOC Allocating memory -- PF_NPROC_EXCEEDED Set_user noticed that RLIMIT_NPROC was exceeded -- PF_USED_MATH If unset the fpu must be initialized before use -- PF_USED_ASYNC Used async_schedule*(), used by module init -+ PF_NPROC_EXCEEDED Set_user noticed that RLIMIT_NPROC was exceeded -+ PF_USED_MATH If unset the fpu must be initialized before use -+ PF_USED_ASYNC Used async_schedule*(), used by module init - PF_NOFREEZE This thread should not be frozen -- PF_FROZEN Frozen for system suspend -- PF_FSTRANS Inside a filesystem transaction -- PF_KSWAPD I am kswapd -+ PF_FROZEN Frozen for system suspend -+ PF_FSTRANS Inside a filesystem transaction -+ PF_KSWAPD I am kswapd - PF_MEMALLOC_NOIO Allocating memory without IO involved - PF_LESS_THROTTLE Throttle me less: I clean memory -- PF_KTHREAD I am a kernel thread -+ PF_KTHREAD I am a kernel thread - PF_RANDOMIZE Randomize virtual address space - PF_SWAPWRITE Allowed to write to swap - PF_NO_SETAFFINITY Userland is not allowed to meddle with cpus_allowed - PF_MCE_EARLY Early kill for mce process policy -- PF_MUTEX_TESTER Thread belongs to the rt mutex tester -- PF_FREEZER_SKIP Freezer should not count it as freezable -- PF_SUSPEND_TASK This thread called freeze_processes and should not be frozen -+ PF_MUTEX_TESTER Thread belongs to the rt mutex tester -+ PF_FREEZER_SKIP Freezer should not count it as freezable -+ PF_SUSPEND_TASK This thread called freeze_processes and -+ should not be frozen - - """ - sflags = [] -@@ -236,8 +239,8 @@ class pidstat: - def cannot_set_affinity(self, pid): - PF_NO_SETAFFINITY = 0x04000000 - try: -- return int(self.processes[pid]["stat"]["flags"]) & \ -- PF_NO_SETAFFINITY and True or False -+ return bool(int(self.processes[pid]["stat"]["flags"]) & -+ PF_NO_SETAFFINITY) - except: - return True - -@@ -245,19 +248,21 @@ def cannot_set_affinity(self, pid): - def cannot_set_thread_affinity(self, pid, tid): - PF_NO_SETAFFINITY = 0x04000000 - try: -- return int(self.processes[pid].threads[tid]["stat"]["flags"]) & \ -- PF_NO_SETAFFINITY and True or False -+ return bool(int(self.processes[pid].threads[tid]["stat"]["flags"]) & -+ PF_NO_SETAFFINITY) - except: - return True - - - class pidstatus: - """ -- Provides a dictionary to access the fields in the per process /proc/PID/status -- files. This provides additional information about processes and threads to what -- can be obtained with the procfs.pidstat() class. -+ Provides a dictionary to access the fields -+ in the per process /proc/PID/status files. -+ This provides additional information about processes and threads to -+ what can be obtained with the procfs.pidstat() class. - -- One can obtain the available fields asking for the keys of the dictionary, e.g.: -+ One can obtain the available fields by asking for the keys of the -+ dictionary, e.g.: - - >>> import procfs - >>> p = procfs.pidstatus(1) -@@ -312,19 +317,18 @@ class pidstatus: - return fieldname in self.fields - - def load(self, basedir="/proc"): -- f = open("%s/%d/status" % (basedir, self.pid)) - self.fields = {} -- for line in f.readlines(): -- fields = line.split(":") -- if len(fields) != 2: -- continue -- name = fields[0] -- value = fields[1].strip() -- try: -- self.fields[name] = int(value) -- except: -- self.fields[name] = value -- f.close() -+ with open("%s/%d/status" % (basedir, self.pid)) as f: -+ for line in f.readlines(): -+ fields = line.split(":") -+ if len(fields) != 2: -+ continue -+ name = fields[0] -+ value = fields[1].strip() -+ try: -+ self.fields[name] = int(value) -+ except: -+ self.fields[name] = value - - - class process: -@@ -380,14 +384,13 @@ class process: - del self.threads[self.pid] - - def load_cgroups(self): -- f = open("/proc/%d/cgroup" % self.pid) - self.cgroups = "" -- for line in reversed(f.readlines()): -- if len(self.cgroups) != 0: -- self.cgroups = self.cgroups + "," + line[:-1] -- else: -- self.cgroups = line[:-1] -- f.close() -+ with open("/proc/%d/cgroup" % self.pid) as f: -+ for line in reversed(f.readlines()): -+ if len(self.cgroups) != 0: -+ self.cgroups = self.cgroups + "," + line[:-1] -+ else: -+ self.cgroups = line[:-1] - - def load_environ(self): - """ -@@ -416,12 +419,11 @@ class process: - >>> - """ - self.environ = {} -- f = open("/proc/%d/environ" % self.pid) -- for x in f.readline().split('\0'): -- if len(x) > 0: -- y = x.split('=') -- self.environ[y[0]] = y[1] -- f.close() -+ with open("/proc/%d/environ" % self.pid) as f: -+ for x in f.readline().split('\0'): -+ if len(x) > 0: -+ y = x.split('=') -+ self.environ[y[0]] = y[1] - - - class pidstats: -@@ -465,18 +467,18 @@ class pidstats: - - def reload(self): - """ -- This operation will throw away the current dictionary contents, if any, and -- read all the pid files from /proc/, instantiating a 'process' instance for -- each of them. -+ This operation will throw away the current dictionary contents, -+ if any, and read all the pid files from /proc/, instantiating a -+ 'process' instance for each of them. - -- This is a high overhead operation, and should be avoided if the perf python -- binding can be used to detect when new threads appear and existing ones -- terminate. -+ This is a high overhead operation, and should be avoided if the -+ perf python binding can be used to detect when new threads appear -+ and existing ones terminate. - - In RHEL it is found in the python-perf rpm package. - -- More information about the perf facilities can be found in the 'perf_event_open' -- man page. -+ More information about the perf facilities can be found in the -+ 'perf_event_open' man page. - """ - del self.processes - self.processes = {} -@@ -643,24 +645,21 @@ class interrupts: - def reload(self): - del self.interrupts - self.interrupts = {} -- f = open("/proc/interrupts") -- -- for line in f.readlines(): -- line = line.strip() -- fields = line.split() -- if fields[0][:3] == "CPU": -- self.nr_cpus = len(fields) -- continue -- irq = fields[0].strip(":") -- self.interrupts[irq] = {} -- self.interrupts[irq] = self.parse_entry(fields[1:], line) -- try: -- nirq = int(irq) -- except: -- continue -- self.interrupts[irq]["affinity"] = self.parse_affinity(nirq) -- -- f.close() -+ with open("/proc/interrupts") as f: -+ for line in f.readlines(): -+ line = line.strip() -+ fields = line.split() -+ if fields[0][:3] == "CPU": -+ self.nr_cpus = len(fields) -+ continue -+ irq = fields[0].strip(":") -+ self.interrupts[irq] = {} -+ self.interrupts[irq] = self.parse_entry(fields[1:], line) -+ try: -+ nirq = int(irq) -+ except: -+ continue -+ self.interrupts[irq]["affinity"] = self.parse_affinity(nirq) - - def parse_entry(self, fields, line): - dict = {} -@@ -681,9 +680,8 @@ class interrupts: - - def parse_affinity(self, irq): - try: -- f = open("/proc/irq/%s/smp_affinity" % irq) -- line = f.readline() -- f.close() -+ with open("/proc/irq/%s/smp_affinity" % irq) as f: -+ line = f.readline() - return bitmasklist(line, self.nr_cpus) - except IOError: - return [0, ] -@@ -741,11 +739,11 @@ class cmdline: - """ - Parses the kernel command line (/proc/cmdline), turning it into a dictionary." - -- Useful to figure out if some kernel boolean knob has been turned on, as well -- as to find the value associated to other kernel knobs. -+ Useful to figure out if some kernel boolean knob has been turned on, -+ as well as to find the value associated to other kernel knobs. - -- It can also be used to find out about parameters passed to the init process, -- such as 'BOOT_IMAGE', etc. -+ It can also be used to find out about parameters passed to the -+ init process, such as 'BOOT_IMAGE', etc. - - E.g.: - >>> import procfs -@@ -762,15 +760,13 @@ class cmdline: - self.parse() - - def parse(self): -- f = open("/proc/cmdline") -- for option in f.readline().strip().split(): -- fields = option.split("=") -- if len(fields) == 1: -- self.options[fields[0]] = True -- else: -- self.options[fields[0]] = fields[1] -- -- f.close() -+ with open("/proc/cmdline") as f: -+ for option in f.readline().strip().split(): -+ fields = option.split("=") -+ if len(fields) == 1: -+ self.options[fields[0]] = True -+ else: -+ self.options[fields[0]] = fields[1] - - def __getitem__(self, key): - return self.options[key] -@@ -790,9 +786,9 @@ class cpuinfo: - Dictionary with information about CPUs in the system. - - Please refer to 'man procfs(5)' for further information about the -- '/proc/cpuinfo' file, that is the source of the information provided by this -- class. The 'man lscpu(1)' also has information about a program that uses -- the '/proc/cpuinfo' file. -+ '/proc/cpuinfo' file, that is the source of the information provided -+ by this class. The 'man lscpu(1)' also has information about a program that -+ uses the '/proc/cpuinfo' file. - - Using this class one can obtain the number of CPUs in a system: - -@@ -801,14 +797,14 @@ class cpuinfo: - 4 - - It is also possible to figure out aspects of the CPU topology, such as -- how many CPU physical sockets exists, i.e. groups of CPUs sharing components -- such as CPU memory caches: -+ how many CPU physical sockets exists, i.e. groups of CPUs sharing -+ components such as CPU memory caches: - - >>> print len(cpus.sockets) - 1 - -- Additionally dictionary with information common to all CPUs in the system is -- available: -+ Additionally dictionary with information common to all CPUs in the system -+ is available: - - >>> print cpus["model name"] - Intel(R) Core(TM) i7-3667U CPU @ 2.00GHz -@@ -836,28 +832,26 @@ class cpuinfo: - return self.tags - - def parse(self, filename): -- f = open(filename) -- for line in f.readlines(): -- line = line.strip() -- if not line: -- continue -- fields = line.split(":") -- tagname = fields[0].strip().lower() -- if tagname == "processor": -- self.nr_cpus += 1 -- continue -- if is_s390() and tagname == "cpu number": -- self.nr_cpus += 1 -- continue -- if tagname == "core id": -- continue -- self.tags[tagname] = fields[1].strip() -- if tagname == "physical id": -- socket_id = self.tags[tagname] -- if socket_id not in self.sockets: -- self.sockets.append(socket_id) -- -- f.close() -+ with open(filename) as f: -+ for line in f.readlines(): -+ line = line.strip() -+ if not line: -+ continue -+ fields = line.split(":") -+ tagname = fields[0].strip().lower() -+ if tagname == "processor": -+ self.nr_cpus += 1 -+ continue -+ if is_s390() and tagname == "cpu number": -+ self.nr_cpus += 1 -+ continue -+ if tagname == "core id": -+ continue -+ self.tags[tagname] = fields[1].strip() -+ if tagname == "physical id": -+ socket_id = self.tags[tagname] -+ if socket_id not in self.sockets: -+ self.sockets.append(socket_id) - self.nr_sockets = self.sockets and len(self.sockets) or \ - (self.nr_cpus / - ("siblings" in self.tags and int(self.tags["siblings"]) or 1)) -@@ -870,7 +864,8 @@ class smaps_lib: - Representation of an mmap in place for a process. Can be used to figure - out which processes have an library mapped, etc. - -- The 'perm' member can be used to figure out executable mmaps, i.e. libraries. -+ The 'perm' member can be used to figure out executable mmaps, -+ i.e. libraries. - - The 'vm_start' and 'vm_end' in turn can be used when trying to resolve - processor instruction pointer addresses to a symbol name in a library. -@@ -967,13 +962,12 @@ class smaps: - return self.entries[index] - - def reload(self): -- f = open("/proc/%d/smaps" % self.pid) - line = None -- while True: -- line = self.parse_entry(f, line) -- if not line: -- break -- f.close() -+ with("/proc/%d/smaps" % self.pid) as f: -+ while True: -+ line = self.parse_entry(f, line) -+ if not line: -+ break - self.nr_entries = len(self.entries) - - def find_by_name_fragment(self, fragment): -@@ -1055,18 +1049,17 @@ class cpusstats: - def reload(self): - last_entries = self.entries - self.entries = {} -- f = open(self.filename) -- for line in f.readlines(): -- fields = line.strip().split() -- if fields[0][:3].lower() != "cpu": -- continue -- c = cpustat(fields) -- if c.name == "cpu": -- idx = 0 -- else: -- idx = int(c.name[3:]) + 1 -- self.entries[idx] = c -- f.close() -+ with open(self.filename) as f: -+ for line in f.readlines(): -+ fields = line.strip().split() -+ if fields[0][:3].lower() != "cpu": -+ continue -+ c = cpustat(fields) -+ if c.name == "cpu": -+ idx = 0 -+ else: -+ idx = int(c.name[3:]) + 1 -+ self.entries[idx] = c - last_time = self.time - self.time = time.time() - if last_entries: -@@ -1082,8 +1075,7 @@ class cpusstats: - (curr.nice - prev.nice) + \ - (curr.system - prev.system) - curr.usage = (delta / interval_hz) * 100 -- if curr.usage > 100: -- curr.usage = 100 -+ curr.usage = min(curr.usage, 100) - - - if __name__ == '__main__': --- -2.31.1 - diff --git a/SOURCES/python-linux-procfs-pflags-Handle-pids-that-complete.patch b/SOURCES/python-linux-procfs-pflags-Handle-pids-that-complete.patch deleted file mode 100644 index c27fa20..0000000 --- a/SOURCES/python-linux-procfs-pflags-Handle-pids-that-complete.patch +++ /dev/null @@ -1,50 +0,0 @@ -From eb984b30e325bbf27844bf9c1f90767504468db5 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 23 Nov 2021 13:01:05 -0500 -Subject: [PATCH 2/3] python-linux-procfs: pflags: Handle pids that completed - -Sometimes pids disappear when they are completed. - -Programs such as pflags that use procfs must account for that. -The solution is to simply recognize this situation, and to continue. - -Signed-off-by: John Kacur ---- - pflags | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/pflags b/pflags -index 3407b6f51c96..46d396c87c2b 100755 ---- a/pflags -+++ b/pflags -@@ -50,14 +50,25 @@ def main(argv): - pids = list(ps.processes.keys()) - - pids.sort() -- len_comms = [len(ps[pid]["stat"]["comm"]) for pid in pids if pid in ps] -+ len_comms = [] -+ for pid in pids: -+ if pid in ps: -+ try: -+ len(ps[pid]["stat"]["comm"]) -+ except (TypeError, FileNotFoundError): -+ continue -+ len_comms.append(len(ps[pid]["stat"]["comm"])) -+ - max_comm_len = max(len_comms, default=0) - del len_comms - - for pid in pids: - if pid not in ps: - continue -- flags = ps[pid].stat.process_flags() -+ try: -+ flags = ps[pid].stat.process_flags() -+ except AttributeError: -+ continue - # Remove flags that were superseeded - if "PF_THREAD_BOUND" in flags and "PF_NO_SETAFFINITY" in flags: - flags.remove("PF_THREAD_BOUND") --- -2.31.1 - diff --git a/SPECS/python-linux-procfs.spec b/SPECS/python-linux-procfs.spec index ae50c4b..e976738 100644 --- a/SPECS/python-linux-procfs.spec +++ b/SPECS/python-linux-procfs.spec @@ -1,6 +1,6 @@ Name: python-linux-procfs -Version: 0.6.3 -Release: 5%{?dist} +Version: 0.7.0 +Release: 1%{?dist} License: GPLv2 Summary: Linux /proc abstraction classes URL: https://git.kernel.org/pub/scm/libs/python/%{name}/%{name}.git @@ -13,11 +13,6 @@ BuildRequires: python3-setuptools Abstractions to extract information from the Linux kernel /proc files. # PATCHES -Patch1: python-linux-procfs-Fix-traceback-with-non-utf8-char.patch -Patch2: python-linux-procfs-Propagate-error-to-user-if-a-pid.patch -Patch3: python-linux-procfs-pflags-Handle-pids-that-complete.patch -Patch4: python-linux-procfs-Various-clean-ups.patch -Patch5: python-linux-procfs-Fix-UnicodeDecodeError.patch %description %_description @@ -48,6 +43,10 @@ rm -rf %{buildroot} %license COPYING %changelog +* Tue Jan 11 2022 John Kacur - 0.7.0-1 +- Rebase to upstream version python-linux-procfs-0.7.0 +Resolves: rhbz#2031156 + * Mon Dec 13 2021 John Kacur - 0.6.3-5 - various clean-ups including using 'with' context managers in try-except - Fix to ignore UnicodeDecodeError when it occurs