diff --git a/.gitignore b/.gitignore index ce47971..f0db1ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/rteval-3.5.tar.xz +SOURCES/rteval-3.7.tar.xz diff --git a/.rteval.metadata b/.rteval.metadata index 476b584..4772766 100644 --- a/.rteval.metadata +++ b/.rteval.metadata @@ -1 +1 @@ -3aee70e8cca181b05b522acab8a44d45fb876e28 SOURCES/rteval-3.5.tar.xz +fe85dce7852985e9ca916877b278feed31508f8f SOURCES/rteval-3.7.tar.xz diff --git a/SOURCES/Added-code-to-check-if-the-proc-net-if_inet6-file-ex.patch b/SOURCES/Added-code-to-check-if-the-proc-net-if_inet6-file-ex.patch deleted file mode 100644 index ca1c33e..0000000 --- a/SOURCES/Added-code-to-check-if-the-proc-net-if_inet6-file-ex.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0ba98b12775b5394aab2205df29d93439d625cc3 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:35 -0400 -Subject: [PATCH] Added code to check if the proc/net/if_inet6 file exists - while loading IPv6 addresses in the IPv6Addresses class - -Added code to check if the proc/net/if_inet6 file exists while loading IPv6 addresses in the IPv6Addresses class. If it doesn't, then the system has IPv6 disabled, and that chunk of code is passed. - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/newnet.py | 28 ++++++++++++++++------------ - 1 file changed, 16 insertions(+), 12 deletions(-) - -diff --git a/rteval/sysinfo/newnet.py b/rteval/sysinfo/newnet.py -index 63417d9e59f1..2911400ceb6c 100644 ---- a/rteval/sysinfo/newnet.py -+++ b/rteval/sysinfo/newnet.py -@@ -72,19 +72,23 @@ class IPv6Addresses(): - and a list of ipv6addresses - ''' - MYP = '/proc/net/if_inet6' -- with open(MYP, 'r') as f: -- mystr = f.readline().strip() -- while len(mystr) > 0: -- ipv6addr , _, _, _, _, intf = mystr.split() -- ipv6addr = compress_iv6(ipv6addr) -- if intf == 'lo': -- mystr = f.readline().strip() -- continue -- if intf not in self.data: -- self.data[intf] = [ipv6addr] -- else: -- self.data[intf].append(ipv6addr) -+ try: -+ with open(MYP, 'r') as f: - mystr = f.readline().strip() -+ while len(mystr) > 0: -+ ipv6addr , _, _, _, _, intf = mystr.split() -+ ipv6addr = compress_iv6(ipv6addr) -+ if intf == 'lo': -+ mystr = f.readline().strip() -+ continue -+ if intf not in self.data: -+ self.data[intf] = [ipv6addr] -+ else: -+ self.data[intf].append(ipv6addr) -+ mystr = f.readline().strip() -+ # if IPv6 is disabled, the if_net6 files does not exist, so we can pass -+ except FileNotFoundError: -+ pass - - class IPv4Addresses(): - ''' Obtains a list of IPv4 addresses from the proc file system ''' --- -2.31.1 - diff --git a/SOURCES/Fix-DMI-WARNING-when-not-running-as-root.patch b/SOURCES/Fix-DMI-WARNING-when-not-running-as-root.patch deleted file mode 100644 index e901b20..0000000 --- a/SOURCES/Fix-DMI-WARNING-when-not-running-as-root.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 149c119df7c7a8ddfd1abc7a127d536cc0674230 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 23 Aug 2022 14:57:37 -0400 -Subject: [PATCH 1/3] rteval: Fix "DMI WARNING" when not running as root - -In some cases it is not necessary to run as root, for example when -running -Z (--summarize) to summarize an existing report. - -In such cases we do not want to see the message: -** DMI WARNING ** Failed to open memory buffer (/dev/mem): Permission denied - -The fix here is to surpresses that message. - -In addition: -- the unused "config" option to DMIinfo.__init__ is removed -- A few strings are converted to f-strings -- "with" is used to open the xsltfile - -Signed-off-by: John Kacur ---- - rteval/sysinfo/__init__.py | 6 ++--- - rteval/sysinfo/dmi.py | 45 +++++++++++++++++++------------------- - 2 files changed, 26 insertions(+), 25 deletions(-) - -diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py -index 0436ebb350d9..a4359382f006 100644 ---- a/rteval/sysinfo/__init__.py -+++ b/rteval/sysinfo/__init__.py -@@ -42,7 +42,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, - self.__logger = logger - KernelInfo.__init__(self, logger=logger) - SystemServices.__init__(self, logger=logger) -- dmi.DMIinfo.__init__(self, config, logger=logger) -+ dmi.DMIinfo.__init__(self, logger=logger) - CPUtopology.__init__(self) - OSInfo.__init__(self, logger=logger) - cmdlineInfo.__init__(self, logger=logger) -@@ -80,8 +80,8 @@ if __name__ == "__main__": - cfg.installdir = "." - si = SystemInfo(cfg, logger=l) - -- print("\tRunning on %s" % si.get_base_os()) -- print("\tNUMA nodes: %d" % si.mem_get_numa_nodes()) -+ print(f"\tRunning on {si.get_base_os()}") -+ print(f"\tNUMA nodes: {si.mem_get_numa_nodes()}") - print("\tMemory available: %03.2f %s\n" % si.mem_get_size()) - - print("\tServices: ") -diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py -index 80cf3c723b36..5965c128c093 100644 ---- a/rteval/sysinfo/dmi.py -+++ b/rteval/sysinfo/dmi.py -@@ -1,6 +1,4 @@ - # --# dmi.py - class to wrap DMI Table information --# - # Copyright 2009 - 2013 Clark Williams - # Copyright 2009 - 2013 David Sommerseth - # -@@ -24,6 +22,7 @@ - # including keys needed to generate an equivalently functional executable - # are deemed to be part of the source code. - # -+""" dmi.py class to wrap DMI Table Information """ - - import sys - import os -@@ -52,16 +51,18 @@ def ProcessWarnings(): - if warnings is None: - return - -+ ignore1 = '/dev/mem: Permission denied' -+ ignore2 = 'No SMBIOS nor DMI entry point found, sorry.' -+ ignore3 = 'Failed to open memory buffer (/dev/mem): Permission denied' -+ ignore = (ignore1, ignore2, ignore3) - for warnline in warnings.split('\n'): - # Ignore these warnings, as they are "valid" if not running as root -- if warnline == '/dev/mem: Permission denied': -- continue -- if warnline == 'No SMBIOS nor DMI entry point found, sorry.': -+ if warnline in ignore: - continue - - # All other warnings will be printed - if len(warnline) > 0: -- print("** DMI WARNING ** %s" % warnline) -+ print(f"** DMI WARNING ** {warnline}") - - dmidecode.clear_warnings() - -@@ -69,8 +70,7 @@ def ProcessWarnings(): - class DMIinfo: - '''class used to obtain DMI info via python-dmidecode''' - -- # TODO: Remove unnecessary config -- def __init__(self, config, logger): -+ def __init__(self, logger): - self.__version = '0.5' - - if not dmidecode_loaded: -@@ -83,22 +83,24 @@ class DMIinfo: - - self.__xsltparser = self.__load_xslt('rteval_dmi.xsl') - -- def __load_xslt(self, fname): -- xsltfile = None -+ @staticmethod -+ def __load_xslt(fname): -+ xsltf = None - if os.path.exists(fname): -- xsltfile = open(fname, "r") -- elif rtevalConfig.default_config_search([fname], os.path.isfile): -- xsltfile = open(rtevalConfig.default_config_search([fname], os.path.isfile), "r") -- -- if xsltfile: -- xsltdoc = lxml.etree.parse(xsltfile) -- ret = lxml.etree.XSLT(xsltdoc) -- xsltfile.close() -+ xsltf = fname -+ else: -+ xsltf = rtevalConfig.default_config_search([fname], os.path.isfile) -+ -+ if xsltf: -+ with open(xsltf, "r") as xsltfile: -+ xsltdoc = lxml.etree.parse(xsltfile) -+ ret = lxml.etree.XSLT(xsltdoc) - return ret - - raise RuntimeError(f'Could not locate XSLT template for DMI data ({fname})') - - def MakeReport(self): -+ """ Add DMI information to final report """ - rep_n = libxml2.newNode("DMIinfo") - rep_n.newProp("version", self.__version) - if self.__fake: -@@ -113,7 +115,7 @@ class DMIinfo: - return rep_n - - def unit_test(rootdir): -- """ unit_test for dmi.py, looks a little crufty! """ -+ """ unit_test for dmi.py """ - - class UnittestConfigDummy: - def __init__(self, rootdir): -@@ -132,15 +134,14 @@ def unit_test(rootdir): - - log = Log() - log.SetLogVerbosity(Log.DEBUG|Log.INFO) -- cfg = UnittestConfigDummy(rootdir) -- d = DMIinfo(cfg, log) -+ d = DMIinfo(log) - dx = d.MakeReport() - x = libxml2.newDoc("1.0") - x.setRootElement(dx) - x.saveFormatFileEnc("-", "UTF-8", 1) - return 0 - except Exception as e: -- print("** EXCEPTION: %s" % str(e)) -+ print(f"** EXCEPTION: {str(e)}") - return 1 - - if __name__ == '__main__': --- -2.37.3 - diff --git a/SOURCES/rteval-Add-relative-cpulists-for-measurements.patch b/SOURCES/rteval-Add-relative-cpulists-for-measurements.patch new file mode 100644 index 0000000..933255f --- /dev/null +++ b/SOURCES/rteval-Add-relative-cpulists-for-measurements.patch @@ -0,0 +1,278 @@ +From 64ce7848dfabd2056d35c8a60f3354db45e36286 Mon Sep 17 00:00:00 2001 +From: Tomas Glozar +Date: Thu, 18 Jan 2024 10:18:10 +0100 +Subject: [PATCH 2/4] rteval: Add relative cpulists for measurements + +Instead of specifying an absolute list of CPUs to run measurements on +in --measurement-cpulist, implement an option to specify a relative list +with respect to the current cpuset of rteval. + +The relative cpulist can include CPUs both for addition and for removal, +e.g. +0,1,-7,8. + +Also move the logic for processing cpulists specified by the user as +a string into cpulists usable by rteval to a single function. + +Signed-off-by: Tomas Glozar +Signed-off-by: John Kacur +--- + rteval-cmd | 26 +++++++----- + rteval/cpulist_utils.py | 33 ++++++++++++++++ + rteval/modules/measurement/__init__.py | 9 +---- + rteval/modules/measurement/cyclictest.py | 50 +++--------------------- + rteval/systopology.py | 33 ++++++++++++++++ + 5 files changed, 90 insertions(+), 61 deletions(-) + +diff --git a/rteval-cmd b/rteval-cmd +index d224728..a5e8746 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -30,7 +30,7 @@ from rteval import RtEval, rtevalConfig + from rteval.modules.loads import LoadModules + from rteval.modules.measurement import MeasurementModules + from rteval.version import RTEVAL_VERSION +-from rteval.systopology import SysTopology ++from rteval.systopology import SysTopology, parse_cpulist_from_config + from rteval.modules.loads.kcompile import ModuleParameters + import rteval.cpulist_utils as cpulist_utils + +@@ -339,26 +339,32 @@ if __name__ == '__main__': + + ldcfg = config.GetSection('loads') + msrcfg = config.GetSection('measurement') +- if ldcfg.cpulist and msrcfg.cpulist: ++ msrcfg_cpulist_present = msrcfg.cpulist != "" ++ # Parse measurement cpulist using parse_cpulist_from_config to account for run-on-isolcpus ++ # and relative cpusets ++ cpulist = parse_cpulist_from_config(msrcfg.cpulist, msrcfg.run_on_isolcpus) ++ if msrcfg_cpulist_present and not cpulist_utils.is_relative(msrcfg.cpulist) and msrcfg.run_on_isolcpus: ++ logger.log(Log.WARN, "ignoring --measurement-run-on-isolcpus, since cpulist is specified") ++ msrcfg.cpulist = collapse_cpulist(cpulist) ++ if ldcfg.cpulist: + ldcfg.cpulist = remove_offline(ldcfg.cpulist) +- msrcfg.cpulist = remove_offline(msrcfg.cpulist) + # if we only specified one set of cpus (loads or measurement) + # default the other to the inverse of the specified list +- if not ldcfg.cpulist and msrcfg.cpulist: ++ if not ldcfg.cpulist and msrcfg_cpulist_present: + tmplist = expand_cpulist(msrcfg.cpulist) + tmplist = SysTopology().invert_cpulist(tmplist) +- ldcfg.cpulist = compress_cpulist(tmplist) +- msrcfg.cpulist = remove_offline(msrcfg.cpulist) +- if not msrcfg.cpulist and ldcfg.cpulist: ++ tmplist = cpulist_utils.online_cpulist(tmplist) ++ ldcfg.cpulist = collapse_cpulist(tmplist) ++ if not msrcfg_cpulist_present and ldcfg.cpulist: + tmplist = expand_cpulist(ldcfg.cpulist) + tmplist = SysTopology().invert_cpulist(tmplist) +- msrcfg.cpulist = compress_cpulist(tmplist) +- ldcfg.cpulist = remove_offline(ldcfg.cpulist) ++ tmplist = cpulist_utils.online_cpulist(tmplist) ++ msrcfg.cpulist = collapse_cpulist(tmplist) + + if ldcfg.cpulist: + logger.log(Log.DEBUG, f"loads cpulist: {ldcfg.cpulist}") + # if --onlyload is specified msrcfg.cpulist is unused +- if msrcfg.cpulist and not rtevcfg.onlyload: ++ if msrcfg_cpulist_present and not rtevcfg.onlyload: + logger.log(Log.DEBUG, f"measurement cpulist: {msrcfg.cpulist}") + logger.log(Log.DEBUG, f"workdir: {rtevcfg.workdir}") + +diff --git a/rteval/cpulist_utils.py b/rteval/cpulist_utils.py +index 402d579..7abc45a 100644 +--- a/rteval/cpulist_utils.py ++++ b/rteval/cpulist_utils.py +@@ -126,3 +126,36 @@ def nonisolated_cpulist(cpulist): + isolated_cpulist = sysread(cpupath, "isolated") + isolated_cpulist = expand_cpulist(isolated_cpulist) + return list(set(cpulist).difference(set(isolated_cpulist))) ++ ++ ++def is_relative(cpulist): ++ return cpulist.startswith("+") or cpulist.startswith("-") ++ ++ ++def expand_relative_cpulist(cpulist): ++ """ ++ Expand a relative cpulist into a tuple of lists. ++ :param cpulist: Relative cpulist of form +1,2,3,-4,5,6 ++ :return: Tuple of two lists, one for added CPUs, one for removed CPUs ++ """ ++ added_cpus = [] ++ removed_cpus = [] ++ ++ if not cpulist: ++ return added_cpus, removed_cpus ++ ++ cpus = None ++ ++ for part in cpulist.split(','): ++ if part.startswith('+') or part.startswith('-'): ++ cpus = added_cpus if part[0] == '+' else removed_cpus ++ part = part[1:] ++ if '-' in part: ++ a, b = part.split('-') ++ a, b = int(a), int(b) ++ cpus.extend(list(range(a, b + 1))) ++ else: ++ a = int(part) ++ cpus.append(a) ++ ++ return list(set(added_cpus)), list(set(removed_cpus)) +diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py +index 66dc9c5..11bd7b0 100644 +--- a/rteval/modules/measurement/__init__.py ++++ b/rteval/modules/measurement/__init__.py +@@ -5,7 +5,7 @@ + + import libxml2 + from rteval.modules import RtEvalModules, ModuleContainer +-from rteval.systopology import SysTopology as SysTop ++from rteval.systopology import parse_cpulist_from_config + import rteval.cpulist_utils as cpulist_utils + + class MeasurementProfile(RtEvalModules): +@@ -183,12 +183,7 @@ measurement profiles, based on their characteristics""" + rep_n = libxml2.newNode("Measurements") + cpulist = self.__cfg.GetSection("measurement").cpulist + run_on_isolcpus = self.__cfg.GetSection("measurement").run_on_isolcpus +- if cpulist: +- # Convert str to list and remove offline cpus +- cpulist = cpulist_utils.expand_cpulist(cpulist) +- cpulist = cpulist_utils.online_cpulist(cpulist) +- else: +- cpulist = SysTop().online_cpus() if run_on_isolcpus else SysTop().default_cpus() ++ cpulist = parse_cpulist_from_config(cpulist, run_on_isolcpus) + rep_n.newProp("measurecpus", cpulist_utils.collapse_cpulist(cpulist)) + + for mp in self.__measureprofiles: +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index fdca257..7224225 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -16,8 +16,7 @@ import math + import libxml2 + from rteval.Log import Log + from rteval.modules import rtevalModulePrototype +-from rteval.systopology import cpuinfo +-from rteval.systopology import SysTopology ++from rteval.systopology import cpuinfo, parse_cpulist_from_config + import rteval.cpulist_utils as cpulist_utils + + expand_cpulist = cpulist_utils.expand_cpulist +@@ -193,39 +192,9 @@ class Cyclictest(rtevalModulePrototype): + self.__priority = int(self.__cfg.setdefault('priority', 95)) + self.__buckets = int(self.__cfg.setdefault('buckets', 2000)) + self.__numcores = 0 +- self.__cpus = [] + self.__cyclicdata = {} +- self.__sparse = False +- self.__run_on_isolcpus = bool(self.__cfg.setdefault('run-on-isolcpus', False)) +- +- if self.__cfg.cpulist: +- self.__cpulist = self.__cfg.cpulist +- self.__cpus = expand_cpulist(self.__cpulist) +- # Only include online cpus +- self.__cpus = cpulist_utils.online_cpulist(self.__cpus) +- # Reset cpulist from the newly calculated self.__cpus +- self.__cpulist = cpulist_utils.collapse_cpulist(self.__cpus) +- self.__cpus = [str(c) for c in self.__cpus] +- self.__sparse = True +- if self.__run_on_isolcpus: +- self._log(Log.WARN, "ignoring --measurement-run-on-isolcpus, since cpulist is specified") +- else: +- self.__cpus = SysTopology().online_cpus_str() +- # Get the cpuset from the environment +- cpuset = os.sched_getaffinity(0) +- # Convert the elements to strings +- cpuset = [str(c) for c in cpuset] +- # Get isolated CPU list +- isolcpus = [str(c) for c in SysTopology().isolated_cpus()] +- # Only include cpus that are in the cpuset and isolated CPUs if run_on_isolcpus is enabled +- self.__cpus = [c for c in self.__cpus if c in cpuset or self.__run_on_isolcpus and c in isolcpus] +- if self.__run_on_isolcpus: +- self.__sparse = True +- self.__cpulist = cpulist_utils.collapse_cpulist([int(c) for c in self.__cpus]) +- +- # Sort the list of cpus to align with the order reported by cyclictest +- self.__cpus.sort(key=int) +- ++ self.__cpulist = self.__cfg.cpulist ++ self.__cpus = [str(c) for c in expand_cpulist(self.__cpulist)] + self.__numcores = len(self.__cpus) + + info = cpuinfo() +@@ -242,10 +211,7 @@ class Cyclictest(rtevalModulePrototype): + logfnc=self._log) + self.__cyclicdata['system'].description = (f"({self.__numcores} cores) ") + info['0']['model name'] + +- if self.__sparse: +- self._log(Log.DEBUG, f"system using {self.__numcores} cpu cores") +- else: +- self._log(Log.DEBUG, f"system has {self.__numcores} cpu cores") ++ self._log(Log.DEBUG, f"system using {self.__numcores} cpu cores") + self.__started = False + self.__cyclicoutput = None + self.__breaktraceval = None +@@ -280,12 +246,8 @@ class Cyclictest(rtevalModulePrototype): + f'-h {self.__buckets}', + f"-p{int(self.__priority)}", + ] +- if self.__sparse: +- self.__cmd.append(f'-t{self.__numcores}') +- self.__cmd.append(f'-a{self.__cpulist}') +- else: +- self.__cmd.append('-t') +- self.__cmd.append('-a') ++ self.__cmd.append(f'-t{self.__numcores}') ++ self.__cmd.append(f'-a{self.__cpulist}') + + if 'threads' in self.__cfg and self.__cfg.threads: + self.__cmd.append(f"-t{int(self.__cfg.threads)}") +diff --git a/rteval/systopology.py b/rteval/systopology.py +index 9e45762..6bcfc77 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -241,6 +241,39 @@ class SysTopology: + """ return a list of online cpus in cpulist """ + return [c for c in self.online_cpus() if c in cpulist] + ++ ++def parse_cpulist_from_config(cpulist, run_on_isolcpus=False): ++ """ ++ Generates a cpulist based on --*-cpulist argument given by user ++ :param cpulist: Value of --*-cpulist argument ++ :param run_on_isolcpus: Value of --*-run-on-isolcpus argument ++ :return: Sorted list of CPUs as integers ++ """ ++ if cpulist and not cpulist_utils.is_relative(cpulist): ++ result = cpulist_utils.expand_cpulist(cpulist) ++ # Only include online cpus ++ result = cpulist_utils.online_cpulist(result) ++ else: ++ result = SysTopology().online_cpus() ++ # Get the cpuset from the environment ++ cpuset = os.sched_getaffinity(0) ++ # Get isolated CPU list ++ isolcpus = SysTopology().isolated_cpus() ++ if cpulist and cpulist_utils.is_relative(cpulist): ++ # Include cpus that are not removed in relative cpuset and are either in cpuset from affinity, ++ # isolcpus (with run_on_isolcpus enabled, or added by relative cpuset ++ added_cpus, removed_cpus = cpulist_utils.expand_relative_cpulist(cpulist) ++ result = [c for c in result ++ if (c in cpuset or ++ c in added_cpus or ++ run_on_isolcpus and c in isolcpus) and ++ c not in removed_cpus] ++ else: ++ # Only include cpus that are in the cpuset and isolated CPUs if run_on_isolcpus is enabled ++ result = [c for c in result if c in cpuset or run_on_isolcpus and c in isolcpus] ++ return result ++ ++ + if __name__ == "__main__": + + def unit_test(): +-- +2.43.0 + diff --git a/SOURCES/rteval-Catch-failures-in-python-dmidecode.patch b/SOURCES/rteval-Catch-failures-in-python-dmidecode.patch deleted file mode 100644 index ce35982..0000000 --- a/SOURCES/rteval-Catch-failures-in-python-dmidecode.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 606bb31cbf967e5e48c10c7e8ea8bab0685eb410 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Thu, 2 Feb 2023 00:47:31 -0500 -Subject: [PATCH] rteval: Catch failures in python-dmidecode - -python-dmidecode can generate incorrect xml, -namely Attribute unit redefined - -Although useful, the dmidecode is not critical to rteval reporting. - -Therefore catch this, and first see if we can at least query the bios. -If that works report the bios instead off all, and if that -doesn't work, just continue without the dmidecode report. - -Signed-off-by: John Kacur ---- - rteval/sysinfo/dmi.py | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py -index 83f347623b58..89a7faae06b1 100644 ---- a/rteval/sysinfo/dmi.py -+++ b/rteval/sysinfo/dmi.py -@@ -79,6 +79,7 @@ class DMIinfo: - - def __init__(self, logger=None): - self.__version = '0.6' -+ self._log = logger - - if not dmidecode_avail: - logger.log(Log.DEBUG, "DMI info unavailable, ignoring DMI tables") -@@ -115,7 +116,18 @@ class DMIinfo: - rep_n.newProp("not_available", "1") - else: - self.__dmixml.SetResultType(dmidecode.DMIXML_DOC) -- dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all')) -+ try: -+ dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all')) -+ except Exception as ex1: -+ self._log.log(Log.DEBUG, f'** EXCEPTION {str(ex1)}, will query BIOS only') -+ try: -+ # If we can't query 'all', at least query 'bios' -+ dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('bios')) -+ except Exception as ex2: -+ rep_n.addContent("No DMI tables available") -+ rep_n.newProp("not_available", "1") -+ self._log.log(Log.DEBUG, f'** EXCEPTION {str(ex2)}, dmi info will not be reported') -+ return rep_n - resdoc = self.__xsltparser(dmiqry) - dmi_n = xmlout.convert_lxml_to_libxml2_nodes(resdoc.getroot()) - rep_n.addChild(dmi_n) --- -2.39.0 - diff --git a/SOURCES/rteval-Change-the-default-kernel-to-compile-to-linux.patch b/SOURCES/rteval-Change-the-default-kernel-for-kcompile.patch similarity index 56% rename from SOURCES/rteval-Change-the-default-kernel-to-compile-to-linux.patch rename to SOURCES/rteval-Change-the-default-kernel-for-kcompile.patch index b9a6308..8af26cf 100644 --- a/SOURCES/rteval-Change-the-default-kernel-to-compile-to-linux.patch +++ b/SOURCES/rteval-Change-the-default-kernel-for-kcompile.patch @@ -1,11 +1,9 @@ -From 0f39c69610985b07ce2aa41142d2f0481da8e3a4 Mon Sep 17 00:00:00 2001 +From c0ee73f00f6868e0ead5ace958a88a6a23db6ad3 Mon Sep 17 00:00:00 2001 From: John Kacur -Date: Fri, 3 Feb 2023 16:13:09 -0500 -Subject: [PATCH 8/8] rteval: Change the default kernel to compile to - linux-6.1.8 +Date: Thu, 9 Nov 2023 15:43:53 -0500 +Subject: [PATCH] rteval: Change the default kernel for kcompile to linux-6.6.1 -rteval compiles the linux kernel as a load -Change the default kernel that rteval compiles to linux-6.1.8 +Change the default kernel for kcompile to linux-6.6.1 Signed-off-by: John Kacur --- @@ -15,53 +13,53 @@ Signed-off-by: John Kacur 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile -index ffea8a05f460..81ca8242bbbe 100644 +index b73e8c13f3e5..14f74e087eff 100644 --- a/Makefile +++ b/Makefile -@@ -17,7 +17,7 @@ PREFIX := /usr +@@ -18,7 +18,7 @@ PREFIX := /usr DATADIR := $(DESTDIR)/$(PREFIX)/share LOADDIR := loadsource --KLOAD := $(LOADDIR)/linux-5.18.1.tar.xz -+KLOAD := $(LOADDIR)/linux-6.1.8.tar.xz +-KLOAD := $(LOADDIR)/linux-6.1.8.tar.xz ++KLOAD := $(LOADDIR)/linux-6.6.1.tar.xz BLOAD := $(LOADDIR)/dbench-4.0.tar.gz LOADS := $(KLOAD) $(BLOAD) diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py -index 6faa686f81d0..35ee5cbbb52d 100644 +index 8be79ce630d5..0d025771e90e 100644 --- a/rteval/modules/loads/kcompile.py +++ b/rteval/modules/loads/kcompile.py -@@ -38,7 +38,7 @@ from rteval.systopology import CpuList, SysTopology - expand_cpulist = CpuList.expand_cpulist +@@ -20,7 +20,7 @@ expand_cpulist = CpuList.expand_cpulist compress_cpulist = CpuList.compress_cpulist + nonisolated_cpulist = CpuList.nonisolated_cpulist --DEFAULT_KERNEL_PREFIX = "linux-5.18" -+DEFAULT_KERNEL_PREFIX = "linux-6.1" +-DEFAULT_KERNEL_PREFIX = "linux-6.1" ++DEFAULT_KERNEL_PREFIX = "linux-6.6" class KBuildJob: '''Class to manage a build job bound to a particular node''' -@@ -349,7 +349,7 @@ class Kcompile(CommandLineLoad): +@@ -334,7 +334,7 @@ class Kcompile(CommandLineLoad): def ModuleParameters(): return {"source": {"descr": "Source tar ball", -- "default": "linux-5.18.1.tar.xz", -+ "default": "linux-6.1.8.tar.xz", +- "default": "linux-6.1.8.tar.xz", ++ "default": "linux-6.6.1.tar.xz", "metavar": "TARBALL"}, "jobspercore": {"descr": "Number of working threads per core", "default": 2, diff --git a/rteval/rteval.conf b/rteval/rteval.conf -index 1a8d0afd2642..79e28032dc6b 100644 +index 79e28032dc6b..a4aad33e264f 100644 --- a/rteval/rteval.conf +++ b/rteval/rteval.conf @@ -18,7 +18,7 @@ dbench: external stressng: module [kcompile] --source: linux-5.18.1.xz -+source: linux-6.1.8.xz +-source: linux-6.1.8.xz ++source: linux-6.6.1.xz jobspercore: 2 [hackbench] -- -2.39.0 +2.41.0 diff --git a/SOURCES/rteval-Convert-CpuList-class-to-a-module.patch b/SOURCES/rteval-Convert-CpuList-class-to-a-module.patch new file mode 100644 index 0000000..b5bbcfb --- /dev/null +++ b/SOURCES/rteval-Convert-CpuList-class-to-a-module.patch @@ -0,0 +1,616 @@ +From a788ea3ec976e51309f0bfae1a41cce704a77f2d Mon Sep 17 00:00:00 2001 +From: Tomas Glozar +Date: Thu, 18 Jan 2024 10:18:09 +0100 +Subject: [PATCH 1/4] rteval: Convert CpuList class to a module + +Move out code from CpuList class in rteval.systopology into a separate +module named rteval.cpulist_utils and avoid wrapping CPU lists in +a CpuList object. + +Almost all uses of CpuList in the code either use the static methods of +the class or its constructor to filter online CPUs by running +CpuList(...).cpulist. The only exception to this are NumaNode and +SimNumaNode classes in systopology; these store a CpuList object, +however their .getcpulist() method extracts the list out. Thus, +the class is completely unnecessary. + +Note: A better name for the module would be cpulist, consistent with the +original name of the class, but this name is already used for variables +throughout the code, hence cpulist_utils is used instead. + +Signed-off-by: Tomas Glozar +Signed-off-by: John Kacur +--- + rteval-cmd | 10 +- + rteval/cpulist_utils.py | 128 ++++++++++++++++++ + rteval/modules/loads/__init__.py | 8 +- + rteval/modules/loads/hackbench.py | 9 +- + rteval/modules/loads/kcompile.py | 11 +- + rteval/modules/loads/stressng.py | 8 +- + rteval/modules/measurement/__init__.py | 8 +- + rteval/modules/measurement/cyclictest.py | 11 +- + rteval/systopology.py | 165 ++--------------------- + 9 files changed, 177 insertions(+), 181 deletions(-) + create mode 100644 rteval/cpulist_utils.py + +diff --git a/rteval-cmd b/rteval-cmd +index 7c41429..d224728 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -30,11 +30,13 @@ from rteval import RtEval, rtevalConfig + from rteval.modules.loads import LoadModules + from rteval.modules.measurement import MeasurementModules + from rteval.version import RTEVAL_VERSION +-from rteval.systopology import CpuList, SysTopology ++from rteval.systopology import SysTopology + from rteval.modules.loads.kcompile import ModuleParameters ++import rteval.cpulist_utils as cpulist_utils + +-compress_cpulist = CpuList.compress_cpulist +-expand_cpulist = CpuList.expand_cpulist ++compress_cpulist = cpulist_utils.compress_cpulist ++expand_cpulist = cpulist_utils.expand_cpulist ++collapse_cpulist = cpulist_utils.collapse_cpulist + + def summarize(repfile, xslt): + """ Summarize an already existing XML report """ +@@ -211,7 +213,7 @@ def remove_offline(cpulist): + """ return cpulist in collapsed compressed form with only online cpus """ + tmplist = expand_cpulist(cpulist) + tmplist = SysTopology().online_cpulist(tmplist) +- return CpuList.collapse_cpulist(tmplist) ++ return collapse_cpulist(tmplist) + + + if __name__ == '__main__': +diff --git a/rteval/cpulist_utils.py b/rteval/cpulist_utils.py +new file mode 100644 +index 0000000..402d579 +--- /dev/null ++++ b/rteval/cpulist_utils.py +@@ -0,0 +1,128 @@ ++# -*- coding: utf-8 -*- ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Copyright 2016 - Clark Williams ++# Copyright 2021 - John Kacur ++# Copyright 2023 - Tomas Glozar ++# ++"""Module providing utility functions for working with CPU lists""" ++ ++import os ++ ++ ++cpupath = "/sys/devices/system/cpu" ++ ++ ++def sysread(path, obj): ++ """ Helper function for reading system files """ ++ with open(os.path.join(path, obj), "r") as fp: ++ return fp.readline().strip() ++ ++ ++def _online_file_exists(): ++ """ Check whether machine / kernel is configured with online file """ ++ # Note: some machines do not have cpu0/online so we check cpu1/online. ++ # In the case of machines with a single CPU, there is no cpu1, but ++ # that is not a problem, since a single CPU cannot be offline ++ return os.path.exists(os.path.join(cpupath, "cpu1/online")) ++ ++ ++def _isolated_file_exists(): ++ """ Check whether machine / kernel is configured with isolated file """ ++ return os.path.exists(os.path.join(cpupath, "isolated")) ++ ++ ++def collapse_cpulist(cpulist): ++ """ ++ Collapse a list of cpu numbers into a string range ++ of cpus (e.g. 0-5, 7, 9) ++ """ ++ cur_range = [None, None] ++ result = [] ++ for cpu in cpulist + [None]: ++ if cur_range[0] is None: ++ cur_range[0] = cur_range[1] = cpu ++ continue ++ if cpu is not None and cpu == cur_range[1] + 1: ++ # Extend currently processed range ++ cur_range[1] += 1 ++ else: ++ # Range processing finished, add range to string ++ result.append(f"{cur_range[0]}-{cur_range[1]}" ++ if cur_range[0] != cur_range[1] ++ else str(cur_range[0])) ++ # Reset ++ cur_range[0] = cur_range[1] = cpu ++ return ",".join(result) ++ ++ ++def compress_cpulist(cpulist): ++ """ return a string representation of cpulist """ ++ if not cpulist: ++ return "" ++ if isinstance(cpulist[0], int): ++ return ",".join(str(e) for e in cpulist) ++ return ",".join(cpulist) ++ ++ ++def expand_cpulist(cpulist): ++ """ expand a range string into an array of cpu numbers ++ don't error check against online cpus ++ """ ++ result = [] ++ ++ if not cpulist: ++ return result ++ ++ for part in cpulist.split(','): ++ if '-' in part: ++ a, b = part.split('-') ++ a, b = int(a), int(b) ++ result.extend(list(range(a, b + 1))) ++ else: ++ a = int(part) ++ result.append(a) ++ return [int(i) for i in list(set(result))] ++ ++ ++def is_online(n): ++ """ check whether cpu n is online """ ++ path = os.path.join(cpupath, f'cpu{n}') ++ ++ # Some hardware doesn't allow cpu0 to be turned off ++ if not os.path.exists(path + '/online') and n == 0: ++ return True ++ ++ return sysread(path, "online") == "1" ++ ++ ++def online_cpulist(cpulist): ++ """ Given a cpulist, return a cpulist of online cpus """ ++ # This only works if the sys online files exist ++ if not _online_file_exists(): ++ return cpulist ++ newlist = [] ++ for cpu in cpulist: ++ if not _online_file_exists() and cpu == '0': ++ newlist.append(cpu) ++ elif is_online(int(cpu)): ++ newlist.append(cpu) ++ return newlist ++ ++ ++def isolated_cpulist(cpulist): ++ """Given a cpulist, return a cpulist of isolated CPUs""" ++ if not _isolated_file_exists(): ++ return cpulist ++ isolated_cpulist = sysread(cpupath, "isolated") ++ isolated_cpulist = expand_cpulist(isolated_cpulist) ++ return list(set(isolated_cpulist) & set(cpulist)) ++ ++ ++def nonisolated_cpulist(cpulist): ++ """Given a cpulist, return a cpulist of non-isolated CPUs""" ++ if not _isolated_file_exists(): ++ return cpulist ++ isolated_cpulist = sysread(cpupath, "isolated") ++ isolated_cpulist = expand_cpulist(isolated_cpulist) ++ return list(set(cpulist).difference(set(isolated_cpulist))) +diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py +index 13fba1e..0845742 100644 +--- a/rteval/modules/loads/__init__.py ++++ b/rteval/modules/loads/__init__.py +@@ -11,7 +11,8 @@ import libxml2 + from rteval.Log import Log + from rteval.rtevalConfig import rtevalCfgSection + from rteval.modules import RtEvalModules, rtevalModulePrototype +-from rteval.systopology import CpuList, SysTopology as SysTop ++from rteval.systopology import SysTopology as SysTop ++import rteval.cpulist_utils as cpulist_utils + + class LoadThread(rtevalModulePrototype): + def __init__(self, name, config, logger=None): +@@ -117,10 +118,11 @@ class LoadModules(RtEvalModules): + cpulist = self._cfg.GetSection(self._module_config).cpulist + if cpulist: + # Convert str to list and remove offline cpus +- cpulist = CpuList(cpulist).cpulist ++ cpulist = cpulist_utils.expand_cpulist(cpulist) ++ cpulist = cpulist_utils.online_cpulist(cpulist) + else: + cpulist = SysTop().default_cpus() +- rep_n.newProp("loadcpus", CpuList.collapse_cpulist(cpulist)) ++ rep_n.newProp("loadcpus", cpulist_utils.collapse_cpulist(cpulist)) + + return rep_n + +diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py +index cfc7063..a70fdb3 100644 +--- a/rteval/modules/loads/hackbench.py ++++ b/rteval/modules/loads/hackbench.py +@@ -16,10 +16,11 @@ import errno + from signal import SIGKILL + from rteval.modules.loads import CommandLineLoad + from rteval.Log import Log +-from rteval.systopology import CpuList, SysTopology ++from rteval.systopology import SysTopology ++import rteval.cpulist_utils as cpulist_utils + +-expand_cpulist = CpuList.expand_cpulist +-isolated_cpulist = CpuList.isolated_cpulist ++expand_cpulist = cpulist_utils.expand_cpulist ++isolated_cpulist = cpulist_utils.isolated_cpulist + + class Hackbench(CommandLineLoad): + def __init__(self, config, logger): +@@ -61,7 +62,7 @@ class Hackbench(CommandLineLoad): + self.cpus[n] = [c for c in self.cpus[n] if c in expand_cpulist(self.cpulist)] + # if a cpulist was not specified, exclude isolated cpus + else: +- self.cpus[n] = CpuList.nonisolated_cpulist(self.cpus[n]) ++ self.cpus[n] = cpulist_utils.nonisolated_cpulist(self.cpus[n]) + + # track largest number of cpus used on a node + node_biggest = len(self.cpus[n]) +diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py +index 0d02577..b606f7a 100644 +--- a/rteval/modules/loads/kcompile.py ++++ b/rteval/modules/loads/kcompile.py +@@ -14,11 +14,12 @@ import subprocess + from rteval.modules import rtevalRuntimeError + from rteval.modules.loads import CommandLineLoad + from rteval.Log import Log +-from rteval.systopology import CpuList, SysTopology ++from rteval.systopology import SysTopology ++import rteval.cpulist_utils as cpulist_utils + +-expand_cpulist = CpuList.expand_cpulist +-compress_cpulist = CpuList.compress_cpulist +-nonisolated_cpulist = CpuList.nonisolated_cpulist ++expand_cpulist = cpulist_utils.expand_cpulist ++compress_cpulist = cpulist_utils.compress_cpulist ++nonisolated_cpulist = cpulist_utils.nonisolated_cpulist + + DEFAULT_KERNEL_PREFIX = "linux-6.6" + +@@ -38,7 +39,7 @@ class KBuildJob: + os.mkdir(self.objdir) + + # Exclude isolated CPUs if cpulist not set +- cpus_available = len(nonisolated_cpulist(self.node.cpus.cpulist)) ++ cpus_available = len(nonisolated_cpulist(self.node.cpus)) + + if os.path.exists('/usr/bin/numactl') and not cpulist: + # Use numactl +diff --git a/rteval/modules/loads/stressng.py b/rteval/modules/loads/stressng.py +index 7c9e63f..cbcf6b7 100644 +--- a/rteval/modules/loads/stressng.py ++++ b/rteval/modules/loads/stressng.py +@@ -7,10 +7,10 @@ import subprocess + import signal + from rteval.modules.loads import CommandLineLoad + from rteval.Log import Log +-from rteval.systopology import CpuList, SysTopology ++from rteval.systopology import SysTopology ++import rteval.cpulist_utils as cpulist_utils + +-expand_cpulist = CpuList.expand_cpulist +-nonisolated_cpulist = CpuList.nonisolated_cpulist ++expand_cpulist = cpulist_utils.expand_cpulist + + class Stressng(CommandLineLoad): + " This class creates a load module that runs stress-ng " +@@ -73,7 +73,7 @@ class Stressng(CommandLineLoad): + cpus[n] = [c for c in cpus[n] if c in expand_cpulist(self.cpulist)] + # if a cpulist was not specified, exclude isolated cpus + else: +- cpus[n] = CpuList.nonisolated_cpulist(cpus[n]) ++ cpus[n] = cpulist_utils.nonisolated_cpulist(cpus[n]) + + + # remove nodes with no cpus available for running +diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py +index 41b8022..66dc9c5 100644 +--- a/rteval/modules/measurement/__init__.py ++++ b/rteval/modules/measurement/__init__.py +@@ -5,7 +5,8 @@ + + import libxml2 + from rteval.modules import RtEvalModules, ModuleContainer +-from rteval.systopology import CpuList, SysTopology as SysTop ++from rteval.systopology import SysTopology as SysTop ++import rteval.cpulist_utils as cpulist_utils + + class MeasurementProfile(RtEvalModules): + """Keeps and controls all the measurement modules with the same measurement profile""" +@@ -184,10 +185,11 @@ measurement profiles, based on their characteristics""" + run_on_isolcpus = self.__cfg.GetSection("measurement").run_on_isolcpus + if cpulist: + # Convert str to list and remove offline cpus +- cpulist = CpuList(cpulist).cpulist ++ cpulist = cpulist_utils.expand_cpulist(cpulist) ++ cpulist = cpulist_utils.online_cpulist(cpulist) + else: + cpulist = SysTop().online_cpus() if run_on_isolcpus else SysTop().default_cpus() +- rep_n.newProp("measurecpus", CpuList.collapse_cpulist(cpulist)) ++ rep_n.newProp("measurecpus", cpulist_utils.collapse_cpulist(cpulist)) + + for mp in self.__measureprofiles: + mprep_n = mp.MakeReport() +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index 1b14e7e..fdca257 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -17,9 +17,10 @@ import libxml2 + from rteval.Log import Log + from rteval.modules import rtevalModulePrototype + from rteval.systopology import cpuinfo +-from rteval.systopology import CpuList, SysTopology ++from rteval.systopology import SysTopology ++import rteval.cpulist_utils as cpulist_utils + +-expand_cpulist = CpuList.expand_cpulist ++expand_cpulist = cpulist_utils.expand_cpulist + + class RunData: + '''class to keep instance data from a cyclictest run''' +@@ -201,9 +202,9 @@ class Cyclictest(rtevalModulePrototype): + self.__cpulist = self.__cfg.cpulist + self.__cpus = expand_cpulist(self.__cpulist) + # Only include online cpus +- self.__cpus = CpuList(self.__cpus).cpulist ++ self.__cpus = cpulist_utils.online_cpulist(self.__cpus) + # Reset cpulist from the newly calculated self.__cpus +- self.__cpulist = CpuList.collapse_cpulist(self.__cpus) ++ self.__cpulist = cpulist_utils.collapse_cpulist(self.__cpus) + self.__cpus = [str(c) for c in self.__cpus] + self.__sparse = True + if self.__run_on_isolcpus: +@@ -220,7 +221,7 @@ class Cyclictest(rtevalModulePrototype): + self.__cpus = [c for c in self.__cpus if c in cpuset or self.__run_on_isolcpus and c in isolcpus] + if self.__run_on_isolcpus: + self.__sparse = True +- self.__cpulist = CpuList.collapse_cpulist([int(c) for c in self.__cpus]) ++ self.__cpulist = cpulist_utils.collapse_cpulist([int(c) for c in self.__cpus]) + + # Sort the list of cpus to align with the order reported by cyclictest + self.__cpus.sort(key=int) +diff --git a/rteval/systopology.py b/rteval/systopology.py +index bed5192..9e45762 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -9,12 +9,8 @@ + import os + import os.path + import glob +- +- +-def sysread(path, obj): +- """ Helper function for reading system files """ +- with open(os.path.join(path, obj), "r") as fp: +- return fp.readline().strip() ++import rteval.cpulist_utils as cpulist_utils ++from rteval.cpulist_utils import sysread + + def cpuinfo(): + ''' return a dictionary of cpu keys with various cpu information ''' +@@ -56,145 +52,6 @@ def cpuinfo(): + return info + + +-# +-# class to provide access to a list of cpus +-# +- +-class CpuList: +- "Object that represents a group of system cpus" +- +- cpupath = '/sys/devices/system/cpu' +- +- def __init__(self, cpulist): +- if isinstance(cpulist, list): +- self.cpulist = cpulist +- elif isinstance(cpulist, str): +- self.cpulist = self.expand_cpulist(cpulist) +- self.cpulist = self.online_cpulist(self.cpulist) +- self.cpulist.sort() +- +- def __str__(self): +- return self.collapse_cpulist(self.cpulist) +- +- def __contains__(self, cpu): +- return cpu in self.cpulist +- +- def __len__(self): +- return len(self.cpulist) +- +- def getcpulist(self): +- """ return the list of cpus tracked """ +- return self.cpulist +- +- @staticmethod +- def online_file_exists(): +- """ Check whether machine / kernel is configured with online file """ +- # Note: some machines do not have cpu0/online so we check cpu1/online. +- # In the case of machines with a single CPU, there is no cpu1, but +- # that is not a problem, since a single CPU cannot be offline +- return os.path.exists(os.path.join(CpuList.cpupath, "cpu1/online")) +- +- @staticmethod +- def isolated_file_exists(): +- """ Check whether machine / kernel is configured with isolated file """ +- return os.path.exists(os.path.join(CpuList.cpupath, "isolated")) +- +- @staticmethod +- def collapse_cpulist(cpulist): +- """ +- Collapse a list of cpu numbers into a string range +- of cpus (e.g. 0-5, 7, 9) +- """ +- cur_range = [None, None] +- result = [] +- for cpu in cpulist + [None]: +- if cur_range[0] is None: +- cur_range[0] = cur_range[1] = cpu +- continue +- if cpu is not None and cpu == cur_range[1] + 1: +- # Extend currently processed range +- cur_range[1] += 1 +- else: +- # Range processing finished, add range to string +- result.append(f"{cur_range[0]}-{cur_range[1]}" +- if cur_range[0] != cur_range[1] +- else str(cur_range[0])) +- # Reset +- cur_range[0] = cur_range[1] = cpu +- return ",".join(result) +- +- @staticmethod +- def compress_cpulist(cpulist): +- """ return a string representation of cpulist """ +- if not cpulist: +- return "" +- if isinstance(cpulist[0], int): +- return ",".join(str(e) for e in cpulist) +- return ",".join(cpulist) +- +- @staticmethod +- def expand_cpulist(cpulist): +- """ expand a range string into an array of cpu numbers +- don't error check against online cpus +- """ +- result = [] +- +- if not cpulist: +- return result +- +- for part in cpulist.split(','): +- if '-' in part: +- a, b = part.split('-') +- a, b = int(a), int(b) +- result.extend(list(range(a, b + 1))) +- else: +- a = int(part) +- result.append(a) +- return [int(i) for i in list(set(result))] +- +- @staticmethod +- def is_online(n): +- """ check whether cpu n is online """ +- path = os.path.join(CpuList.cpupath, f'cpu{n}') +- +- # Some hardware doesn't allow cpu0 to be turned off +- if not os.path.exists(path + '/online') and n == 0: +- return True +- +- return sysread(path, "online") == "1" +- +- @staticmethod +- def online_cpulist(cpulist): +- """ Given a cpulist, return a cpulist of online cpus """ +- # This only works if the sys online files exist +- if not CpuList.online_file_exists(): +- return cpulist +- newlist = [] +- for cpu in cpulist: +- if not CpuList.online_file_exists() and cpu == '0': +- newlist.append(cpu) +- elif CpuList.is_online(int(cpu)): +- newlist.append(cpu) +- return newlist +- +- @staticmethod +- def isolated_cpulist(cpulist): +- """Given a cpulist, return a cpulist of isolated CPUs""" +- if not CpuList.isolated_file_exists(): +- return cpulist +- isolated_cpulist = sysread(CpuList.cpupath, "isolated") +- isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist) +- return list(set(isolated_cpulist) & set(cpulist)) +- +- @staticmethod +- def nonisolated_cpulist(cpulist): +- """Given a cpulist, return a cpulist of non-isolated CPUs""" +- if not CpuList.isolated_file_exists(): +- return cpulist +- isolated_cpulist = sysread(CpuList.cpupath, "isolated") +- isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist) +- return list(set(cpulist).difference(set(isolated_cpulist))) +- + # + # class to abstract access to NUMA nodes in /sys filesystem + # +@@ -208,7 +65,8 @@ class NumaNode: + """ + self.path = path + self.nodeid = int(os.path.basename(path)[4:].strip()) +- self.cpus = CpuList(sysread(self.path, "cpulist")) ++ self.cpus = cpulist_utils.expand_cpulist(sysread(self.path, "cpulist")) ++ self.cpus = cpulist_utils.online_cpulist(self.cpus) + self.getmeminfo() + + def __contains__(self, cpu): +@@ -240,11 +98,11 @@ class NumaNode: + + def getcpustr(self): + """ return list of cpus for this node as a string """ +- return str(self.cpus) ++ return cpulist_utils.collapse_cpulist(self.cpus) + + def getcpulist(self): + """ return list of cpus for this node """ +- return self.cpus.getcpulist() ++ return self.cpus + + class SimNumaNode(NumaNode): + """class representing a simulated NUMA node. +@@ -257,7 +115,8 @@ class SimNumaNode(NumaNode): + + def __init__(self): + self.nodeid = 0 +- self.cpus = CpuList(sysread(SimNumaNode.cpupath, "possible")) ++ self.cpus = cpulist_utils.expand_cpulist(sysread(SimNumaNode.cpupath, "possible")) ++ self.cpus = cpulist_utils.online_cpulist(self.cpus) + self.getmeminfo() + + def getmeminfo(self): +@@ -339,7 +198,7 @@ class SysTopology: + """ return a list of integers of all online cpus """ + cpulist = [] + for n in self.nodes: +- cpulist += self.getcpus(n) ++ cpulist += cpulist_utils.online_cpulist(self.getcpus(n)) + cpulist.sort() + return cpulist + +@@ -347,7 +206,7 @@ class SysTopology: + """ return a list of integers of all isolated cpus """ + cpulist = [] + for n in self.nodes: +- cpulist += CpuList.isolated_cpulist(self.getcpus(n)) ++ cpulist += cpulist_utils.isolated_cpulist(self.getcpus(n)) + cpulist.sort() + return cpulist + +@@ -355,7 +214,7 @@ class SysTopology: + """ return a list of integers of all default schedulable cpus, i.e. online non-isolated cpus """ + cpulist = [] + for n in self.nodes: +- cpulist += CpuList.nonisolated_cpulist(self.getcpus(n)) ++ cpulist += cpulist_utils.nonisolated_cpulist(self.getcpus(n)) + cpulist.sort() + return cpulist + +@@ -403,7 +262,7 @@ if __name__ == "__main__": + + onlcpus = s.online_cpus() + print(f'onlcpus = {onlcpus}') +- onlcpus = CpuList.collapse_cpulist(onlcpus) ++ onlcpus = cpulist_utils.collapse_cpulist(onlcpus) + print(f'onlcpus = {onlcpus}') + + onlcpus_str = s.online_cpus_str() +-- +2.43.0 + diff --git a/SOURCES/rteval-Disable-use-of-python-dmidecode.patch b/SOURCES/rteval-Disable-use-of-python-dmidecode.patch new file mode 100644 index 0000000..ceed1b5 --- /dev/null +++ b/SOURCES/rteval-Disable-use-of-python-dmidecode.patch @@ -0,0 +1,87 @@ +From d142f0d23d8df1cede3573c3d6cfbf16535b3475 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Wed, 20 Dec 2023 17:55:21 -0500 +Subject: [PATCH 2/2] rteval: Disable use of python-dmidecode + +python-dmidecode is not being maintained upstream. +For now just disable it's use in rteval since it is useful but not +essential information for running rteval + +In the future look at generating this info directly using dmidecode. + +Signed-off-by: John Kacur +--- + README | 6 ------ + doc/installing.txt | 9 --------- + rteval/sysinfo/dmi.py | 4 ++-- + 3 files changed, 2 insertions(+), 17 deletions(-) + +diff --git a/README b/README +index a5cf98344a46..b352d7f66ad2 100644 +--- a/README ++++ b/README +@@ -19,15 +19,9 @@ Rteval requires the following packages to run: + Python >= 3.0 + http://www.python.org/download/ + +-python-ethtool +- git://git.kernel.org/pub/scm/linux/kernel/git/acme/python-ethtool.git +- + python-lxml + http://lxml.de/ + +-python-dmidecode +- http://www.ohloh.net/p/python-dmidecode +- + libxml2-python + http://xmlsoft.org/ + +diff --git a/doc/installing.txt b/doc/installing.txt +index ff2d43cb9481..227249bbc9ed 100644 +--- a/doc/installing.txt ++++ b/doc/installing.txt +@@ -1,18 +1,10 @@ + The rteval utility requires some external software libraries to run + properly. These are: + +-python-ethtool +- A python library to query network interfaces +- git://git.kernel.org/pub/scm/linux/kernel/git/acme/python-ethtool.git +- + python-lxml + A python library to parse XML files and XSLT stylesheets + http://lxml.de/ + +-python-dmidecode +- A python library used to access DMI table information +- http://www.autonomy.net.au/display/pydmi/Home +- + libxml2-python + A python library to parse XML files + http://xmlsoft.org/ +@@ -22,7 +14,6 @@ rt-tests + git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git + + +-$ sudo yum install python-{dmidecode,ethtool) + $ git clone \ + git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git + $ cd rt-tests && sudo make prefix=/usr install +diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py +index e8285d263fe6..c01a0eef1435 100644 +--- a/rteval/sysinfo/dmi.py ++++ b/rteval/sysinfo/dmi.py +@@ -15,8 +15,8 @@ from rteval import xmlout + from rteval import rtevalConfig + + try: +- import dmidecode +- dmidecode_avail = True ++ # import dmidecode ++ dmidecode_avail = False + except ModuleNotFoundError: + dmidecode_avail = False + +-- +2.42.0 + diff --git a/SOURCES/rteval-Don-t-attempt-to-get-DMIinfo-if-there-are-dmi.patch b/SOURCES/rteval-Don-t-attempt-to-get-DMIinfo-if-there-are-dmi.patch deleted file mode 100644 index aaf95f8..0000000 --- a/SOURCES/rteval-Don-t-attempt-to-get-DMIinfo-if-there-are-dmi.patch +++ /dev/null @@ -1,169 +0,0 @@ -From bce23ecc5d8bb6cab86843f7a42164ee44ef091f Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Thu, 27 Oct 2022 11:14:27 -0400 -Subject: [PATCH 3/3] rteval: Don't attempt to get DMIinfo if there are dmi - warnings - -If the python module dmidecode is available, but produces warnings, -you can get a traceback. This happens on some arm boxes, -as shown in the traceback below. - -Fix this by treating any warnings that are not listed in the -ignorable warnings as if dmi info is not available. - -Also add logging to dmi.ProcessWarnings() - -./rteval-cmd -d10s -** DMI WARNING ** /sys/firmware/efi/systab: SMBIOS entry point missing -got system topology: 1 node system (4 cores per node) -rteval run on 5.19.16-200.fc36.aarch64 started at Fri Oct 21 16:11:51 2022 -started 3 loads on 4 cores -started measurement threads on 4 cores -Run duration: 10.0 seconds -stopping run at Fri Oct 21 16:13:26 2022 -Traceback (most recent call last): - File "/root/src/rteval/./rteval-cmd", line 402, in - ec = rteval.Measure() - File "/root/src/rteval/rteval/__init__.py", line 286, in Measure - self._report(measure_start, self.__rtevcfg.xslt_report) - File "/root/src/rteval/rteval/rtevalReport.py", line 76, in _report - self.__xmlreport.AppendXMLnodes(self._sysinfo.MakeReport()) - File "/root/src/rteval/rteval/sysinfo/__init__.py", line 69, in MakeReport - report_n.addChild(dmi.DMIinfo.MakeReport(self)) - File "/root/src/rteval/rteval/sysinfo/dmi.py", line 111, in MakeReport - dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all')) - File "/usr/lib64/python3.10/site-packages/dmidecode.py", line 64, in QuerySection - ret = libxml2.xmlDoc( _obj = xmlapi(query_type='s', -RuntimeError: [src/dmidecodemodule.c:331] Error decoding DMI data - -** COLLECTED WARNINGS ** -/sys/firmware/efi/systab: SMBIOS entry point missing -** END OF WARNINGS ** - -Signed-off-by: John Kacur ---- - rteval-cmd | 4 ++-- - rteval/sysinfo/__init__.py | 2 +- - rteval/sysinfo/dmi.py | 34 +++++++++++++++++++++------------- - 3 files changed, 24 insertions(+), 16 deletions(-) - -diff --git a/rteval-cmd b/rteval-cmd -index 6a928362828f..1e6a7fc86baa 100755 ---- a/rteval-cmd -+++ b/rteval-cmd -@@ -210,8 +210,6 @@ def remove_offline(cpulist): - if __name__ == '__main__': - from rteval.sysinfo import dmi - -- dmi.ProcessWarnings() -- - # set LD_BIND_NOW to resolve shared library symbols - # note: any string will do, nothing significant about 'rteval' - -@@ -261,6 +259,8 @@ if __name__ == '__main__': - | (rtevcfg.debugging and Log.DEBUG) - logger.SetLogVerbosity(loglev) - -+ dmi.ProcessWarnings(logger=logger) -+ - # Load modules - loadmods = LoadModules(config, logger=logger) - measuremods = MeasurementModules(config, logger=logger) -diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py -index bb1d00810856..5767e5b7f6fe 100644 ---- a/rteval/sysinfo/__init__.py -+++ b/rteval/sysinfo/__init__.py -@@ -49,7 +49,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, - NetworkInfo.__init__(self, logger=logger) - - # Parse initial DMI decoding errors -- dmi.ProcessWarnings() -+ dmi.ProcessWarnings(logger=logger) - - # Parse CPU info - CPUtopology._parse(self) -diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py -index 5965c128c093..83f347623b58 100644 ---- a/rteval/sysinfo/dmi.py -+++ b/rteval/sysinfo/dmi.py -@@ -1,6 +1,7 @@ - # - # Copyright 2009 - 2013 Clark Williams - # Copyright 2009 - 2013 David Sommerseth -+# Copyright 2022 John Kacur - # - # 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 -@@ -34,14 +35,19 @@ from rteval import rtevalConfig - - try: - import dmidecode -- dmidecode_loaded = True -+ dmidecode_avail = True - except ModuleNotFoundError: -- dmidecode_loaded = False -+ dmidecode_avail = False - --def ProcessWarnings(): -+def set_dmidecode_avail(val): -+ """ Used to set global variable dmidecode_avail from a function """ -+ global dmidecode_avail -+ dmidecode_avail = val -+ -+def ProcessWarnings(logger=None): - """ Process Warnings from dmidecode """ - -- if not dmidecode_loaded: -+ if not dmidecode_avail: - return - - if not hasattr(dmidecode, 'get_warnings'): -@@ -62,7 +68,8 @@ def ProcessWarnings(): - - # All other warnings will be printed - if len(warnline) > 0: -- print(f"** DMI WARNING ** {warnline}") -+ logger.log(Log.DEBUG, f"** DMI WARNING ** {warnline}") -+ set_dmidecode_avail(False) - - dmidecode.clear_warnings() - -@@ -70,11 +77,11 @@ def ProcessWarnings(): - class DMIinfo: - '''class used to obtain DMI info via python-dmidecode''' - -- def __init__(self, logger): -- self.__version = '0.5' -+ def __init__(self, logger=None): -+ self.__version = '0.6' - -- if not dmidecode_loaded: -- logger.log(Log.DEBUG|Log.WARN, "No dmidecode module found, ignoring DMI tables") -+ if not dmidecode_avail: -+ logger.log(Log.DEBUG, "DMI info unavailable, ignoring DMI tables") - self.__fake = True - return - -@@ -127,14 +134,15 @@ def unit_test(rootdir): - self.__dict__[k] = self.config[k] - - try: -- ProcessWarnings() -+ log = Log() -+ log.SetLogVerbosity(Log.DEBUG|Log.INFO) -+ -+ ProcessWarnings(logger=log) - if os.getuid() != 0: - print("** ERROR ** Must be root to run this unit_test()") - return 1 - -- log = Log() -- log.SetLogVerbosity(Log.DEBUG|Log.INFO) -- d = DMIinfo(log) -+ d = DMIinfo(logger=log) - dx = d.MakeReport() - x = libxml2.newDoc("1.0") - x.setRootElement(dx) --- -2.37.3 - diff --git a/SOURCES/rteval-Log.py-Convert-to-f-strings.patch b/SOURCES/rteval-Log.py-Convert-to-f-strings.patch deleted file mode 100644 index 3b12c82..0000000 --- a/SOURCES/rteval-Log.py-Convert-to-f-strings.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 78bd089e89e15b09db8e1d2bdcc0d9620d4da03c Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 6 Dec 2022 14:44:44 -0500 -Subject: rteval: Log.py: Convert to f-strings - -Convert Log.py to f-strings - -Signed-off-by: John Kacur ---- - rteval/Log.py | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/rteval/Log.py b/rteval/Log.py -index 63ca3b8681f8..8d08ab3e210a 100644 ---- a/rteval/Log.py -+++ b/rteval/Log.py -@@ -60,10 +60,7 @@ class Log: - - def log(self, logtype, msg): - if (logtype & self.__logverb) or logtype == self.ALWAYS: -- self.__logfile.write("%s%s\n" % -- (self.__logtype_str(logtype), -- msg) -- ) -+ self.__logfile.write(f"{self.__logtype_str(logtype)}{msg}\n") - - - -@@ -80,8 +77,8 @@ def unit_test(rootdir): - def run_log_test(l): - for lt in range(min(logtypes), max(logtypes)*2): - test = ", ".join([logtypes_s[logtypes.index(i)] for i in [p for p in takewhile(lambda x: x <= lt, (2**i for i in count())) if p & lt]]) -- print("Testing verbosity flags set to: (%i) %s" % (lt, test)) -- msg = "Log entry when verbosity is set to %i [%s]" % (lt, test) -+ print(f"Testing verbosity flags set to: ({lt}) {test}") -+ msg = f"Log entry when verbosity is set to {lt} [{test}]" - l.SetLogVerbosity(lt) - test_log(l, msg) - print("-"*20) --- -2.40.1 - diff --git a/SOURCES/rteval-Makefile-More-rpm-cleanups.patch b/SOURCES/rteval-Makefile-More-rpm-cleanups.patch new file mode 100644 index 0000000..abca54c --- /dev/null +++ b/SOURCES/rteval-Makefile-More-rpm-cleanups.patch @@ -0,0 +1,64 @@ +From 2d2e85c459d240926c99b1961bbef090aa80a1fc Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Wed, 20 Dec 2023 17:22:22 -0500 +Subject: [PATCH 1/2] rteval: Makefile: More rpm cleanups + +Afer having removed the upstream specfile, there were still a few +references to rpms in the Makefile. These are not necessary because any +work with rpms can be done with modern rpm tools and are typically done +by distributions + +Also test whether directory 'run' exists since it may have been removed +by make realclean, and create it if it does not + +Signed-off-by: John Kacur +--- + Makefile | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/Makefile b/Makefile +index ee4cca555b95..b8bed643f760 100644 +--- a/Makefile ++++ b/Makefile +@@ -31,6 +31,7 @@ load: + $(PYTHON) rteval-cmd --onlyload -D -L -v --workdir=./run --loaddir=$(HERE)/loadsource -f $(HERE)/rteval/rteval.conf -i $(HERE)/rteval + + sysreport: ++ [ -d $(HERE)/run ] || mkdir run + $(PYTHON) rteval-cmd -D -v --workdir=$(HERE)/run --loaddir=$(HERE)/loadsource --duration=$(D) -i $(HERE)/rteval --sysreport + + clean: +@@ -39,7 +40,7 @@ clean: + + realclean: clean + [ -f $(XMLRPCDIR)/Makefile ] && make -C $(XMLRPCDIR) maintainer-clean || echo -n +- rm -rf run rpm ++ rm -rf run + + install: install_loads install_rteval + +@@ -73,13 +74,6 @@ rteval-xmlrpc-$(XMLRPCVER).tar.gz : + make distcheck + cp $(XMLRPCDIR)/rteval-xmlrpc-$(XMLRPCVER).tar.gz $(HERE)/ + +-rpm_prep: +- rm -rf rpm +- mkdir -p rpm/{BUILD,RPMS,SRPMS,SOURCES,SPECS} +- +-rpms rpm: rpm_prep rtevalrpm loadrpm +- +- + help: + @echo "" + @echo "rteval Makefile targets:" +@@ -88,6 +82,7 @@ help: + @echo " tarfile: create the source tarball" + @echo " install: install rteval locally" + @echo " clean: cleanup generated files" ++ @echo " realclean: Same as clean plus directory run" + @echo " sysreport: do a short testrun and generate sysreport data" + @echo " tags: generate a ctags file" + @echo " cleantags: remove the ctags file" +-- +2.42.0 + diff --git a/SOURCES/rteval-Minor-improvements-to-CpuList-class.patch b/SOURCES/rteval-Minor-improvements-to-CpuList-class.patch new file mode 100644 index 0000000..44430e0 --- /dev/null +++ b/SOURCES/rteval-Minor-improvements-to-CpuList-class.patch @@ -0,0 +1,85 @@ +From 768daa63ec8e2299da53afe081e7304b37fc91cf Mon Sep 17 00:00:00 2001 +From: Tomas Glozar +Date: Wed, 29 Nov 2023 10:34:55 +0100 +Subject: [PATCH 2/9] rteval: Minor improvements to CpuList class + +- Remove unnecessary if-else from online_file_exists +- Use cpupath in online_file_exists +- In is_online, remove check for n in cpuset and make it static +- Mark also the remaining methods static since they do not rely on +any fields of the class + +Signed-off-by: Tomas Glozar +- Removed incorrect line from commit message +Signed-off-by: John Kacur +--- + rteval/systopology.py | 29 +++++++++++++++-------------- + 1 file changed, 15 insertions(+), 14 deletions(-) + +diff --git a/rteval/systopology.py b/rteval/systopology.py +index ea8e242..60ac8e8 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -82,12 +82,17 @@ class CpuList: + def __len__(self): + return len(self.cpulist) + ++ def getcpulist(self): ++ """ return the list of cpus tracked """ ++ return self.cpulist ++ + @staticmethod + def online_file_exists(): + """ Check whether machine / kernel is configured with online file """ +- if os.path.exists('/sys/devices/system/cpu/cpu1/online'): +- return True +- return False ++ # Note: some machines do not have cpu0/online so we check cpu1/online. ++ # In the case of machines with a single CPU, there is no cpu1, but ++ # that is not a problem, since a single CPU cannot be offline ++ return os.path.exists(os.path.join(CpuList.cpupath, "cpu1/online")) + + @staticmethod + def isolated_file_exists(): +@@ -147,14 +152,9 @@ class CpuList: + result.append(a) + return [int(i) for i in list(set(result))] + +- def getcpulist(self): +- """ return the list of cpus tracked """ +- return self.cpulist +- +- def is_online(self, n): ++ @staticmethod ++ def is_online(n): + """ check whether cpu n is online """ +- if n not in self.cpulist: +- raise RuntimeError(f"invalid cpu number {n}") + path = os.path.join(CpuList.cpupath, f'cpu{n}') + + # Some hardware doesn't allow cpu0 to be turned off +@@ -163,16 +163,17 @@ class CpuList: + + return sysread(path, "online") == "1" + +- def online_cpulist(self, cpulist): ++ @staticmethod ++ def online_cpulist(cpulist): + """ Given a cpulist, return a cpulist of online cpus """ + # This only works if the sys online files exist +- if not self.online_file_exists(): ++ if not CpuList.online_file_exists(): + return cpulist + newlist = [] + for cpu in cpulist: +- if not self.online_file_exists() and cpu == '0': ++ if not CpuList.online_file_exists() and cpu == '0': + newlist.append(cpu) +- elif self.is_online(int(cpu)): ++ elif CpuList.is_online(int(cpu)): + newlist.append(cpu) + return newlist + +-- +2.43.0 + diff --git a/SOURCES/rteval-Refactor-collapse_cpulist-in-systopology.patch b/SOURCES/rteval-Refactor-collapse_cpulist-in-systopology.patch new file mode 100644 index 0000000..cb43c85 --- /dev/null +++ b/SOURCES/rteval-Refactor-collapse_cpulist-in-systopology.patch @@ -0,0 +1,225 @@ +From 4b4f50900e38a931ed9585c6cf200b74c0120a20 Mon Sep 17 00:00:00 2001 +From: Tomas Glozar +Date: Wed, 29 Nov 2023 10:34:54 +0100 +Subject: [PATCH 1/9] rteval: Refactor collapse_cpulist in systopology + +Instead of having duplicate code in two functions, one top-level and +one member function of CpuList, have only one static function in +CpuList. + +Additionally re-write the implementation to use a more straight forward +one-pass algorithm. + +Signed-off-by: Tomas Glozar +Signed-off-by: John Kacur +--- + rteval-cmd | 4 +- + rteval/modules/loads/__init__.py | 4 +- + rteval/modules/measurement/__init__.py | 4 +- + rteval/modules/measurement/cyclictest.py | 6 +-- + rteval/systopology.py | 68 ++++++++---------------- + 5 files changed, 30 insertions(+), 56 deletions(-) + +diff --git a/rteval-cmd b/rteval-cmd +index 6f613a3..7c41429 100755 +--- a/rteval-cmd ++++ b/rteval-cmd +@@ -30,7 +30,7 @@ from rteval import RtEval, rtevalConfig + from rteval.modules.loads import LoadModules + from rteval.modules.measurement import MeasurementModules + from rteval.version import RTEVAL_VERSION +-from rteval.systopology import CpuList, SysTopology, collapse_cpulist ++from rteval.systopology import CpuList, SysTopology + from rteval.modules.loads.kcompile import ModuleParameters + + compress_cpulist = CpuList.compress_cpulist +@@ -211,7 +211,7 @@ def remove_offline(cpulist): + """ return cpulist in collapsed compressed form with only online cpus """ + tmplist = expand_cpulist(cpulist) + tmplist = SysTopology().online_cpulist(tmplist) +- return collapse_cpulist(tmplist) ++ return CpuList.collapse_cpulist(tmplist) + + + if __name__ == '__main__': +diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py +index aca0c9f..13fba1e 100644 +--- a/rteval/modules/loads/__init__.py ++++ b/rteval/modules/loads/__init__.py +@@ -11,7 +11,7 @@ import libxml2 + from rteval.Log import Log + from rteval.rtevalConfig import rtevalCfgSection + from rteval.modules import RtEvalModules, rtevalModulePrototype +-from rteval.systopology import collapse_cpulist, CpuList, SysTopology as SysTop ++from rteval.systopology import CpuList, SysTopology as SysTop + + class LoadThread(rtevalModulePrototype): + def __init__(self, name, config, logger=None): +@@ -120,7 +120,7 @@ class LoadModules(RtEvalModules): + cpulist = CpuList(cpulist).cpulist + else: + cpulist = SysTop().default_cpus() +- rep_n.newProp("loadcpus", collapse_cpulist(cpulist)) ++ rep_n.newProp("loadcpus", CpuList.collapse_cpulist(cpulist)) + + return rep_n + +diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py +index 2a0556b..41b8022 100644 +--- a/rteval/modules/measurement/__init__.py ++++ b/rteval/modules/measurement/__init__.py +@@ -5,7 +5,7 @@ + + import libxml2 + from rteval.modules import RtEvalModules, ModuleContainer +-from rteval.systopology import collapse_cpulist, CpuList, SysTopology as SysTop ++from rteval.systopology import CpuList, SysTopology as SysTop + + class MeasurementProfile(RtEvalModules): + """Keeps and controls all the measurement modules with the same measurement profile""" +@@ -187,7 +187,7 @@ measurement profiles, based on their characteristics""" + cpulist = CpuList(cpulist).cpulist + else: + cpulist = SysTop().online_cpus() if run_on_isolcpus else SysTop().default_cpus() +- rep_n.newProp("measurecpus", collapse_cpulist(cpulist)) ++ rep_n.newProp("measurecpus", CpuList.collapse_cpulist(cpulist)) + + for mp in self.__measureprofiles: + mprep_n = mp.MakeReport() +diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py +index 0af1d31..1b14e7e 100644 +--- a/rteval/modules/measurement/cyclictest.py ++++ b/rteval/modules/measurement/cyclictest.py +@@ -17,7 +17,7 @@ import libxml2 + from rteval.Log import Log + from rteval.modules import rtevalModulePrototype + from rteval.systopology import cpuinfo +-from rteval.systopology import CpuList, SysTopology, collapse_cpulist ++from rteval.systopology import CpuList, SysTopology + + expand_cpulist = CpuList.expand_cpulist + +@@ -203,7 +203,7 @@ class Cyclictest(rtevalModulePrototype): + # Only include online cpus + self.__cpus = CpuList(self.__cpus).cpulist + # Reset cpulist from the newly calculated self.__cpus +- self.__cpulist = collapse_cpulist(self.__cpus) ++ self.__cpulist = CpuList.collapse_cpulist(self.__cpus) + self.__cpus = [str(c) for c in self.__cpus] + self.__sparse = True + if self.__run_on_isolcpus: +@@ -220,7 +220,7 @@ class Cyclictest(rtevalModulePrototype): + self.__cpus = [c for c in self.__cpus if c in cpuset or self.__run_on_isolcpus and c in isolcpus] + if self.__run_on_isolcpus: + self.__sparse = True +- self.__cpulist = collapse_cpulist(self.__cpus) ++ self.__cpulist = CpuList.collapse_cpulist([int(c) for c in self.__cpus]) + + # Sort the list of cpus to align with the order reported by cyclictest + self.__cpus.sort(key=int) +diff --git a/rteval/systopology.py b/rteval/systopology.py +index 62ad355..ea8e242 100644 +--- a/rteval/systopology.py ++++ b/rteval/systopology.py +@@ -10,25 +10,6 @@ import os + import os.path + import glob + +-# Utility version of collapse_cpulist that doesn't require a CpuList object +-def collapse_cpulist(cpulist): +- """ Collapse a list of cpu numbers into a string range +- of cpus (e.g. 0-5, 7, 9) """ +- if len(cpulist) == 0: +- return "" +- idx = CpuList.longest_sequence(cpulist) +- if idx == 0: +- seq = str(cpulist[0]) +- else: +- if idx == 1: +- seq = f"{cpulist[0]},{cpulist[idx]}" +- else: +- seq = f"{cpulist[0]}-{cpulist[idx]}" +- +- rest = collapse_cpulist(cpulist[idx+1:]) +- if rest == "": +- return seq +- return ",".join((seq, rest)) + + def sysread(path, obj): + """ Helper function for reading system files """ +@@ -93,7 +74,7 @@ class CpuList: + self.cpulist.sort() + + def __str__(self): +- return self.__collapse_cpulist(self.cpulist) ++ return self.collapse_cpulist(self.cpulist) + + def __contains__(self, cpu): + return cpu in self.cpulist +@@ -114,35 +95,28 @@ class CpuList: + return os.path.exists(os.path.join(CpuList.cpupath, "isolated")) + + @staticmethod +- def longest_sequence(cpulist): +- """ return index of last element of a sequence that steps by one """ +- lim = len(cpulist) +- for idx, _ in enumerate(cpulist): +- if idx+1 == lim: +- break +- if int(cpulist[idx+1]) != (int(cpulist[idx])+1): +- return idx +- return lim - 1 +- +- def __collapse_cpulist(self, cpulist): +- """ Collapse a list of cpu numbers into a string range ++ def collapse_cpulist(cpulist): ++ """ ++ Collapse a list of cpu numbers into a string range + of cpus (e.g. 0-5, 7, 9) + """ +- if len(cpulist) == 0: +- return "" +- idx = self.longest_sequence(cpulist) +- if idx == 0: +- seq = str(cpulist[0]) +- else: +- if idx == 1: +- seq = f"{cpulist[0]},{cpulist[idx]}" ++ cur_range = [None, None] ++ result = [] ++ for cpu in cpulist + [None]: ++ if cur_range[0] is None: ++ cur_range[0] = cur_range[1] = cpu ++ continue ++ if cpu is not None and cpu == cur_range[1] + 1: ++ # Extend currently processed range ++ cur_range[1] += 1 + else: +- seq = f"{cpulist[0]}-{cpulist[idx]}" +- +- rest = self.__collapse_cpulist(cpulist[idx+1:]) +- if rest == "": +- return seq +- return ",".join((seq, rest)) ++ # Range processing finished, add range to string ++ result.append(f"{cur_range[0]}-{cur_range[1]}" ++ if cur_range[0] != cur_range[1] ++ else str(cur_range[0])) ++ # Reset ++ cur_range[0] = cur_range[1] = cpu ++ return ",".join(result) + + @staticmethod + def compress_cpulist(cpulist): +@@ -428,7 +402,7 @@ if __name__ == "__main__": + + onlcpus = s.online_cpus() + print(f'onlcpus = {onlcpus}') +- onlcpus = collapse_cpulist(onlcpus) ++ onlcpus = CpuList.collapse_cpulist(onlcpus) + print(f'onlcpus = {onlcpus}') + + onlcpus_str = s.online_cpus_str() +-- +2.43.0 + diff --git a/SOURCES/rteval-Remove-upstream-spec-file.patch b/SOURCES/rteval-Remove-upstream-spec-file.patch new file mode 100644 index 0000000..d35f4cc --- /dev/null +++ b/SOURCES/rteval-Remove-upstream-spec-file.patch @@ -0,0 +1,566 @@ +From de8e25ff3a30dbdbba6fb1b68ea0921dff55cd91 Mon Sep 17 00:00:00 2001 +From: John Kacur +Date: Mon, 13 Nov 2023 14:32:19 -0500 +Subject: [PATCH] rteval: Remove upstream spec file + +Specfiles should be maintained by distributions and not in the upstream +code. In practice they are not maintained upstream except for version +numbers, so just remove the specfile. + +This also moves a lot of functionality around rpms in the Makefile, but +this functionality exists in tools such as rpmbuild and friends anyway. + +Signed-off-by: John Kacur +--- + Makefile | 37 ---- + rteval.spec | 484 ---------------------------------------------------- + 2 files changed, 521 deletions(-) + delete mode 100644 rteval.spec + +diff --git a/Makefile b/Makefile +index 14f74e087eff..ee4cca555b95 100644 +--- a/Makefile ++++ b/Makefile +@@ -79,49 +79,12 @@ rpm_prep: + + rpms rpm: rpm_prep rtevalrpm loadrpm + +-rtevalrpm: rteval-$(VERSION).tar.bz2 +- cp $^ rpm/SOURCES +- cp rteval.spec rpm/SPECS +- rpmbuild -ba --define "_topdir $(HERE)/rpm" rpm/SPECS/rteval.spec +- +-rtevalsrpm: rteval-$(VERSION).tar.bz2 +- cp $^ rpm/SOURCES +- cp rteval.spec rpm/SPECS +- rpmbuild -bs --define "_topdir $(HERE)/rpm" rpm/SPECS/rteval.spec +- +- +-xmlrpcrpm: rteval-xmlrpc-$(XMLRPCVER).tar.gz +- cp rteval-xmlrpc-$(XMLRPCVER).tar.gz rpm/SOURCES/ +- cp server/rteval-parser.spec rpm/SPECS/ +- rpmbuild -ba --define "_topdir $(HERE)/rpm" rpm/SPECS/rteval-parser.spec +- +-xmlsrpm: rteval-xmlrpc-$(XMLRPCVER).tar.gz +- cp rteval-xmlrpc-$(XMLRPCVER).tar.gz rpm/SOURCES/ +- cp server/rteval-parser.spec rpm/SPECS/ +- rpmbuild -bs --define "_topdir $(HERE)/rpm" rpm/SPECS/rteval-parser.spec +- +-loadrpm: +- rm -rf rpm-loads +- mkdir -p rpm-loads/{BUILD,RPMS,SRPMS,SOURCES,SPECS} +- cp rteval-loads.spec rpm-loads/SPECS +- cp $(LOADS) rpm-loads/SOURCES +- rpmbuild -ba --define "_topdir $(HERE)/rpm-loads" rpm-loads/SPECS/rteval-loads.spec +- +-rpmlint: rpms +- @echo "===============" +- @echo "running rpmlint" +- rpmlint -v $(shell find ./rpm -type f -name "*.rpm") \ +- $(shell find ./rpm-loads -type f -name "*.rpm") \ +- $(shell find ./rpm/SPECS -type f -name "rteval*.spec") \ +- $(shell find ./rpm-loads/SPECS -type f -name "rteval*.spec" ) + + help: + @echo "" + @echo "rteval Makefile targets:" + @echo "" + @echo " runit: do a short testrun locally [default]" +- @echo " rpm: run rpmbuild for all rpms" +- @echo " rpmlint: run rpmlint against all rpms/srpms/specfiles" + @echo " tarfile: create the source tarball" + @echo " install: install rteval locally" + @echo " clean: cleanup generated files" +diff --git a/rteval.spec b/rteval.spec +deleted file mode 100644 +index b5842f0d8206..000000000000 +--- a/rteval.spec ++++ /dev/null +@@ -1,484 +0,0 @@ +-%{!?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: rteval +-Version: 3.7 +-Release: 1%{?dist} +-Summary: Utility to evaluate system suitability for RT Linux +- +-Group: Development/Tools +-License: GPLv2 +-URL: http://git.kernel.org/?p=linux/kernel/git/clrkwllms/rteval.git +-Source0: rteval-%{version}.tar.bz2 +-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +- +-BuildRequires: python3-devel +-Requires: platform-python +-Requires: python3-ethtool python3-lxml +-Requires: python3-dmidecode >= 3.10 +-Requires: rt-tests >= 0.97 +-Requires: rteval-loads >= 1.4 +-Requires: rteval-common => %{version}-%{release} +-Requires: sysstat +-Requires: bzip2 +-Requires: kernel-headers +-Requires: sos +-BuildArch: noarch +-Obsoletes: rteval <= 1.7 +-Requires: numactl +- +-%description +-The rteval script is a utility for measuring various aspects of +-realtime behavior on a system under load. The script unpacks the +-kernel source, and then goes into a loop, running hackbench and +-compiling a kernel tree. During that loop the cyclictest program +-is run to measure event response time. After the run time completes, +-a statistical analysis of the event response times is done and printed +-to the screen. +- +- +-%package common +-Summary: Common rteval files +-BuildArch: noarch +- +-%description common +-Common files used by rteval, rteval-xmlrpc and rteval-parser +- +-%prep +-%setup -q +- +-# version sanity check (make sure specfile and rteval.py match) +-cp rteval/version.py rtevalversion.py +-srcver=$(%{__python} -c "from rtevalversion import RTEVAL_VERSION; print RTEVAL_VERSION") +-rm -rf rtevalversion.py +-if [ $srcver != %{version} ]; then +- printf "\n***\n*** rteval spec file version do not match the rteval/rteval.py version\n***\n\n" +- exit -1 +-fi +- +-%build +-%{__python} setup.py build +- +-%install +-%{__python} setup.py install --root=$RPM_BUILD_ROOT +- +-%clean +-rm -rf $RPM_BUILD_ROOT +- +-%files common +-%doc COPYING +-%dir %{_datadir}/%{name} +-%{python_sitelib}/rteval/rtevalclient.py* +-%{python_sitelib}/rteval/rtevalConfig.py* +-%{python_sitelib}/rteval/rtevalXMLRPC.py* +-%{python_sitelib}/rteval/version.py* +-%{python_sitelib}/rteval/Log.py* +-%{python_sitelib}/rteval/misc.py* +-%{python_sitelib}/rteval/systopology.py* +- +-%files +-%defattr(-,root,root,-) +-%if "%{python_ver}" >= "2.5" +-%{python_sitelib}/*.egg-info +-%endif +- +-%doc COPYING README doc/rteval.txt +-%{_mandir}/man8/rteval.8.gz +-%config(noreplace) %{_sysconfdir}/rteval.conf +-%{_datadir}/%{name}/rteval_*.xsl +-%{python_sitelib}/rteval/__init__.py* +-%{python_sitelib}/rteval/rtevalMailer.py* +-%{python_sitelib}/rteval/rtevalReport.py* +-%{python_sitelib}/rteval/xmlout.py* +-%{python_sitelib}/rteval/modules +-%{python_sitelib}/rteval/sysinfo +-/usr/bin/rteval +- +-%changelog +-* Thu Mar 16 2017 Clark Williams - 2.14-1 +-- removed leftover import of systopology from sysinfo +- +-* Wed Mar 15 2017 Clark Williams - 2.13-2 +-- Updated specfile to correct version and bz [1382155] +- +-* Tue Sep 20 2016 Clark Williams - 2.12-1 +-- handle empty environment variables SUDO_USER and USER [1312057] +- +-* Tue Aug 30 2016 Clark Williams - 2.11-1 +-- make sure we return non-zero for early exit from tests +- +-* Wed Aug 3 2016 Clark Williams - 2.10-1 +-- bumped version for RHEL 7.3 release +- +-* Mon May 9 2016 Clark Williams - 2.9.1 +-- default cpulist for modules if only one specified [1333831] +- +-* Tue Apr 26 2016 Clark Williams - 2.8.1 +-- add the --version option to print the rteval version +-- made the --cyclictest-breaktrace option work properly [1209986] +- +-* Fri Apr 1 2016 Clark Williams - 2.7.1 +-- treat SIGINT and SIGTERM as valid end-of-run events [1278757] +-- added cpulist options to man page +- +-* Thu Feb 11 2016 Clark Williams - 2.6.1 +-- update to make --loads-cpulist and --measurement-cpulist work [1306437] +- +-* Thu Dec 10 2015 Clark Williams - 2.5-1 +-- stop using old numactl --cpubind argument +- +-* Wed Dec 9 2015 Clark Williams - 2.4.2 +-- added Require of package numactl +- +-* Tue Nov 17 2015 Clark Williams - 2.4.1 +-- rework hackbench load to not generate cross-node traffic [1282826] +- +-* Wed Aug 12 2015 Clark Williams - 2.3-1 +-- comment out HWLatDetect module from default config [1245699] +- +-* Wed Jun 10 2015 Clark Williams - 2.2-1 +-- add --loads-cpulist and --measurement-cpulist to allow cpu placement [1230401] +- +-* Thu Apr 23 2015 Luis Claudio R. Goncalves - 2.1-8 +-- load default configs when no config file is specified (Jiri kastner) [1212452] +- +-* Wed Jan 14 2015 Clark Williams - 2.1-7 +-- added requires of bzip2 to specfile [1151567] +- +-* Thu Jan 8 2015 Clark Williams - 2.1-6 +-- cleaned up product documentation [1173315] +- +-* Mon Nov 10 2014 Luis Claudio R. Goncalves - 2.1-5 +-- rebuild for RHEL-7.1 (1151567) +- +-* Thu Mar 27 2014 Clark Williams - 2.1-4 +-- cherry-picked old commit to deal with installdir problem +- +-* Wed Mar 26 2014 Clark Williams - 2.1-3 +-- added sysstat requires to specfile +- +-* Tue Mar 12 2013 David Sommerseth - 2.1-2 +-- Migrated from libxslt-python to python-lxml +- +-* Fri Jan 18 2013 David Sommerseth - 2.1-1 +-- Made some log lines clearer +-- cyclictest: Added --cyclictest-breaktrace feature +-- cyclictest: Removed --cyclictest-distance option +-- cyclictest: Use a tempfile buffer for cyclictest's stdout data +-- cyclictest: Report if breaktrace was triggered +-- cyclictest: Make the unit test work again +-- cyclictest: Only log and show statistic data when samples are collected +-- Copyright updates +- +-* Thu Jan 17 2013 David Sommerseth - 2.0.1-1 +-- Fix up type casting in the core module code +-- hwlatdetect: Add some more useful debug info +-- Reworked the run logic for modules - allow them to flag they won't run +-- Fixed a few log messages in load modules +-- Add a 30 seconds sleep before unleashing the measurement threads +- +-* Thu Jan 10 2013 David Sommerseth - 2.0-3 +-- Separate out RTEVAL_VERSION into rteval.version, to avoid +- massive BuildRequirements +- +-* Fri Dec 21 2012 David Sommerseth - 2.0-2 +-- Split out common files into rteval-common +- +-* Fri Dec 21 2012 David Sommerseth - 2.0-1 +-- Updated to rteval v2.0 and reworked spec file to use setup.py directly +- +-* Tue Oct 23 2012 Clark Williams - 1.36-1 +-- deal with system not having dmidecode python module +-- make sure to cast priority parameter to int +-- from Raphaël Beamonte : +- - Rewrite of the get_kthreads method to make it cross-distribution +- - Adds getcmdpath method to use which to locate the used commands +- - Rewrite of the get_services method to make it cross-distribution +- +-* Mon Apr 2 2012 Clark Williams - 1.35-1 +-- fix thinko where SIGINT and SIGTERM handlers were commented out +- +-* Thu Jan 12 2012 Clark Williams - 1.34-1 +-- fix missing config merge in rteval.py to pass parameters +- down to cyclictest +-- modify hackbench to use helper function to start process +- +-* Sat May 14 2011 Clark Williams - 1.33-1 +-- modify hackbench cutoff to be 0.75GB/core +- +-* Mon Aug 23 2010 Clark Williams - 1.32-1 +-- update docs +-- refactor some RTEval methods to utility functions +-- modify hackbench.py not to run under low memory conditions +-- clean up XML generation to deal with new hackbench code +-- clean up XSL code to deal with new XML 'run' attribute +-- from David Sommerseth : +- - improve CPU socket counting logic +- - delay log directory creation until actually needed +-- from Gowrishankar : +- - check if the core id really exists (multithreading fix) +- +-* Mon Jul 26 2010 Clark Williams - 1.31-1 +-- from David Sommerseth : +- - Updated hackbench implementation to avoid overusing resources +- - Don't show NUMA node information if it's missing in the summary.xml +- - Show CPU cores properly +- +-* Wed Jul 21 2010 Clark Williams - 1.30-1 +-- added code to hackbench to try to detect and ease memory pressure +- +-* Fri Jul 16 2010 Clark Williams - 1.29-1 +-- fixed incorrect type value in kcompile.py +- +-* Fri Jul 16 2010 Clark Williams - 1.28-1 +-- added logic to loads to adjust number of jobs based on ratio +- of memory per core +- +-* Wed Jul 14 2010 Clark Williams - 1.27-1 +-- modified hackbench to go back to using threads rather than +- processes for units of work +-- added memory size, number of numa nodes and run duration to the +- parameter dictionary passed to all loads and cyclictest +- +-* Tue Jul 13 2010 Clark Williams - 1.26-1 +-- modified hackbench parameters to reduce memory consumption +- +-* Mon Jul 12 2010 Clark Williams - 1.25-1 +-- fixed cyclictest bug that caused everything to be uniprocessor +-- updated source copyrights to 2010 +- +-* Fri Jul 9 2010 Clark Williams - 1.24-1 +-- modified hackbench arguments and added new parameters for +- hackbench in rteval.conf +- +-* Thu Jul 8 2010 Clark Williams - 1.23-1 +-- version bump to deal with out-of-sync cvs issue +- +-* Thu Jul 8 2010 Clark Williams - 1.22-1 +-- merged David Sommerseth changes to use +- hackbench from rt-tests packages rather than carry local copy +-- converted all loads and cyclictest to pass __init__ parameters +- in a dictionary rather than as discrete parameters +-- added logging for load output +- +-* Tue Apr 13 2010 Clark Williams - 1.21-1 +-- from Luis Claudio Goncalves : +- - remove unecessary wait() call in cyclictest.py +- - close /dev/null after using it +- - call subprocess.wait() when needed +- - remove delayloop code in hackbench.py +-- from David Sommerseth : +- - add SIGINT handler +- - handle non-root user case +- - process DMI warnings before command line arguments +- - added --annotate feature to rteval +- - updates to xmlrpc code +- +-* Tue Apr 6 2010 Clark Williams - 1.20-1 +-- code fixes from Luis Claudio Goncalves +-- from David Sommerseth : +- - xmlrpc server updates +- - cputopology.py for recording topology in xml +- - added NUMA node recording for run data +- - rpmlint fixes +-- added start of rteval whitepaper in docs dir +- +-* Tue Mar 16 2010 Clark Williams - 1.19-1 +-- add ability for --summarize to read tarfiles +-- from David Sommerseth +- - gather info about loaded kernel modules for XML file +- - added child tracking to hackbench to prevent zombies +- +-* Tue Feb 16 2010 Clark Williams - 1.18-1 +-- fix usage of python 2.6 features on RHEL5 (python 2.4) +- +-* Tue Feb 16 2010 Clark Williams - 1.17-1 +-- added logic to filter non-printables from service status output +- so that we have legal XML output +-- added logic to hackbench.py to cleanup properly at the end +- of the test +- +-* Thu Feb 11 2010 Clark Williams - 1.16-1 +-- fix errors in show_remaining_time() introduced because +- time values are floats rather than ints +- +-* Thu Feb 11 2010 Clark Williams - 1.15-1 +-- added logic to use --numa and --smp options of new cyclictest +-- added countdown report for time remaining in a run +- +-* Tue Feb 9 2010 Clark Williams - 1.14-1 +-- David Sommerseth : +- merged XMLReport() changes for hwcert suite +- +-* Tue Dec 22 2009 Clark Williams - 1.13-1 +-- added cyclictest default initializers +-- added sanity checks to statistics reduction code +-- updated release checklist to include origin push +-- updated Makefile clean and help targets +-- davids updates (mainly for v7 integration): +- - Add explicit sys.path directory to the python sitelib+ +- '/rteval' +- - Send program arguments via RtEval() constructor +- - Added more DMI data into the summary.xml report +- - Fixed issue with not including all devices in the +- OnBoardDeviceInfo tag +- +-* Thu Dec 3 2009 David Sommerseth - 1.12-2 +-- fixed Makefile and specfile to include and install the +- rteval/rteval_histogram_raw.py source file for gaining +- raw access to histogram data +-- Removed xmlrpc package during merge against master_ipv4 branch +- +-* Wed Nov 25 2009 Clark Williams - 1.12-1 +-- fix incorrect reporting of measurement thread priorities +- +-* Mon Nov 16 2009 Clark Williams - 1.11-5 +-- ensure that no double-slashes ("//") appear in the symlink +- path for /usr/bin/rteval (problem with rpmdiff) +- +-* Tue Nov 10 2009 Clark Williams - 1.11-4 +-- changed symlink back to install and tracked by %%files +- +-* Mon Nov 9 2009 Clark Williams - 1.11-3 +-- changed symlink generation from %%post to %%posttrans +- +-* Mon Nov 9 2009 Clark Williams - 1.11-2 +-- fixed incorrect dependency for libxslt +- +-* Fri Nov 6 2009 Clark Williams - 1.11-1 +-- added base OS info to XML file and XSL report +-- created new package rteval-loads for the load source code +- +-* Wed Nov 4 2009 Clark Williams - 1.10-1 +-- added config file section for cyclictest and two settable +- parameters, buckets and interval +- +-* Thu Oct 29 2009 Clark Williams - 1.9-1 +-- merged davids updates: +- -H option (raw histogram data) +- cleaned up xsl files +- fixed cpu sorting +- +-* Mon Oct 26 2009 David Sommerseth - 1.8-3 +-- Fixed rpmlint complaints +- +-* Mon Oct 26 2009 David Sommerseth - 1.8-2 +-- Added xmlrpc package, containing the XML-RPC mod_python modules +- +-* Tue Oct 20 2009 Clark Williams - 1.8-1 +-- split kcompile and hackbench into sub-packages +-- reworked Makefile (and specfile) install/uninstall logic +-- fixed sysreport incorrect plugin option +-- catch failure when running on root-squashed NFS +- +-* Tue Oct 13 2009 Clark Williams - 1.7-1 +-- added kthread status to xml file +-- merged davids changes for option processing and additions +- to xml summary +- +-* Tue Oct 13 2009 Clark Williams - 1.6-1 +-- changed stat calculation to loop less +-- added methods to grab service and kthread status +- +-* Mon Oct 12 2009 Clark Williams - 1.5-1 +-- changed cyclictest to use less memory when doing statisics +- calculations +-- updated debug output to use module name prefixes +-- changed option processing to only process config file once +- +-* Fri Oct 9 2009 Clark Williams - 1.4-1 +-- changed cyclictest to use histogram rather than sample array +-- calcuated statistics directly from histogram +-- changed sample interval to 100us +-- added -a (affinity) argument to force cpu affinity for +- measurement threads +- +-* Thu Sep 24 2009 David Sommerseth - 1.3-3 +-- Cleaned up the spec file and made rpmlint happy +- +-* Wed Sep 23 2009 David Sommerseth - 1.3-2 +-- Removed version number from /usr/share/rteval path +- +-* Tue Sep 22 2009 Clark Williams - 1.3-1 +-- changes from davids: +- * changed report code to sort by processor id +- * added report submission retry logic +- * added emailer class +- +-* Fri Sep 18 2009 Clark Williams - 1.2-1 +-- added config file handling for modifying load behavior and +- setting defaults +-- added units in report per IBM request +- +-* Wed Aug 26 2009 Clark Williams - 1.1-2 +-- missed a version change in rteval/rteval.py +- +-* Wed Aug 26 2009 Clark Williams - 1.1-1 +-- modified cyclictest.py to start cyclictest threads with a +- 'distance' of zero, meaning they all have the same measurement +- interval +- +-* Tue Aug 25 2009 Clark Williams - 1.0-1 +-- merged davids XMLRPC fixes +-- fixed --workdir option +-- verion bump to 1.0 +- +-* Thu Aug 13 2009 Clark Williams - 0.9-2 +-- fixed problem with incorrect version in rteval.py +- +-* Tue Aug 4 2009 Clark Williams - 0.9-1 +-- merged dsommers XMLRPC and database changes +-- Specify minimum python-dmidecode version, which got native XML support +-- Added rteval_dmi.xsl +-- Fixed permission issues in /usr/share/rteval-x.xx +- +-* Wed Jul 22 2009 Clark Williams - 0.8-1 +-- added code to capture clocksource info +-- added code to copy dmesg info to report directory +-- added code to display clocksource info in report +-- added --summarize option to display summary of existing report +-- added helpfile target to Makefile +- +-* Thu Mar 26 2009 Clark Williams - 0.7-1 +-- added require for python-schedutils to specfile +-- added default for cyclictest output file +-- added help parameter to option parser data +-- renamed xml output file to summary.xml +-- added routine to create tarfile of result files +- +-* Wed Mar 18 2009 Clark Williams - 0.6-6 +-- added code to handle binary data coming from DMI tables +- +-* Wed Mar 18 2009 Clark Williams - 0.6-5 +-- fixed logic for locating XSL template (williams) +-- fixed another stupid typo in specfile (williams) +- +-* Wed Mar 18 2009 Clark Williams - 0.6-4 +-- fixed specfile to install rteval_text.xsl in /usr/share directory +- +-* Wed Mar 18 2009 Clark Williams - 0.6-3 +-- added Requires for libxslt-python (williams) +-- fixed race condition in xmlout constructor/destructor (williams) +- +-* Wed Mar 18 2009 Clark Williams - 0.6-2 +-- added Requires for libxslt (williams) +-- fixed stupid typo in rteval/rteval.py (williams) +- +-* Wed Mar 18 2009 Clark Williams - 0.6-1 +-- added xml output logic (williams, dsommers) +-- added xlst template for report generator (dsommers) +-- added dmi/smbios output to report (williams) +-- added __del__ method to hackbench to cleanup after run (williams) +-- modified to always keep run data (williams) +- +-* Fri Feb 20 2009 Clark Williams - 0.5-1 +-- fixed tab/space mix problem +-- added report path line to report +- +-* Fri Feb 20 2009 Clark Williams - 0.4-1 +-- reworked report output +-- handle keyboard interrupt better +-- removed duration mismatch between rteval and cyclictest +- +-* Mon Feb 2 2009 Clark Williams - 0.3-1 +-- initial checkin +-- +2.41.0 + diff --git a/SOURCES/rteval-Replace-python-ethtool-with-inline-code.patch b/SOURCES/rteval-Replace-python-ethtool-with-inline-code.patch deleted file mode 100644 index 59b4592..0000000 --- a/SOURCES/rteval-Replace-python-ethtool-with-inline-code.patch +++ /dev/null @@ -1,399 +0,0 @@ -From d0552193364d160252d117c5bf2e298a31550e3c Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Mon, 10 Oct 2022 09:49:47 -0400 -Subject: [PATCH] rteval: Replace python-ethtool with inline code - -This patch adds the file newnet.py to replace the use of python-ethtool -The information it generates will appear in the summary.xml -You can also test the functionality by running -python rteval/sysinfo/newnet.py - -Signed-off-by: John Kacur -- V2 Add SPDX license identifier -Signed-off-by: John Kacur ---- - rteval/sysinfo/__init__.py | 3 +- - rteval/sysinfo/network.py | 117 ------------------- - rteval/sysinfo/newnet.py | 225 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 227 insertions(+), 118 deletions(-) - delete mode 100644 rteval/sysinfo/network.py - create mode 100644 rteval/sysinfo/newnet.py - -diff --git a/rteval/sysinfo/__init__.py b/rteval/sysinfo/__init__.py -index a4359382f006..bb1d00810856 100644 ---- a/rteval/sysinfo/__init__.py -+++ b/rteval/sysinfo/__init__.py -@@ -32,7 +32,7 @@ from rteval.sysinfo.services import SystemServices - from rteval.sysinfo.cputopology import CPUtopology - from rteval.sysinfo.memory import MemoryInfo - from rteval.sysinfo.osinfo import OSInfo --from rteval.sysinfo.network import NetworkInfo -+from rteval.sysinfo.newnet import NetworkInfo - from rteval.sysinfo.cmdline import cmdlineInfo - from rteval.sysinfo import dmi - -@@ -46,6 +46,7 @@ class SystemInfo(KernelInfo, SystemServices, dmi.DMIinfo, CPUtopology, - CPUtopology.__init__(self) - OSInfo.__init__(self, logger=logger) - cmdlineInfo.__init__(self, logger=logger) -+ NetworkInfo.__init__(self, logger=logger) - - # Parse initial DMI decoding errors - dmi.ProcessWarnings() -diff --git a/rteval/sysinfo/network.py b/rteval/sysinfo/network.py -deleted file mode 100644 -index ce9989a1240b..000000000000 ---- a/rteval/sysinfo/network.py -+++ /dev/null -@@ -1,117 +0,0 @@ --# -*- coding: utf-8 -*- --# --# Copyright 2009 - 2013 David Sommerseth --# --# 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 --# the Free Software Foundation; either version 2 of the License, or --# (at your option) any later version. --# --# This program 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. --# --# You should have received a copy of the GNU General Public License along --# with this program; if not, write to the Free Software Foundation, Inc., --# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --# --# For the avoidance of doubt the "preferred form" of this code is one which --# is in an open unpatent encumbered format. Where cryptographic key signing --# forms part of the process of creating an executable the information --# including keys needed to generate an equivalently functional executable --# are deemed to be part of the source code. --# -- --import ethtool, libxml2 -- --class NetworkInfo(object): -- def __init__(self): -- pass -- -- def net_GetDefaultGW(self): -- # Get the interface name for the IPv4 default gw -- route = open('/proc/net/route') -- defgw4 = None -- if route: -- rl = route.readline() -- while rl != '' : -- rl = route.readline() -- splt = rl.split("\t") -- # Only catch default route -- if len(splt) > 2 and splt[2] != '00000000' and splt[1] == '00000000': -- defgw4 = splt[0] -- break -- route.close() -- return (defgw4, None) # IPv6 gw not yet implemented -- -- def MakeReport(self): -- ncfg_n = libxml2.newNode("NetworkConfig") -- (defgw4, defgw6) = self.net_GetDefaultGW() -- -- # Make an interface tag for each device found -- if hasattr(ethtool, 'get_interfaces_info'): -- # Using the newer python-ethtool API (version >= 0.4) -- for dev in ethtool.get_interfaces_info(ethtool.get_devices()): -- if dev.device == 'lo': -- continue -- -- intf_n = libxml2.newNode('interface') -- intf_n.newProp('device', dev.device) -- intf_n.newProp('hwaddr', dev.mac_address) -- ncfg_n.addChild(intf_n) -- -- # Protcol configurations -- if dev.ipv4_address: -- ipv4_n = libxml2.newNode('IPv4') -- ipv4_n.newProp('ipaddr', dev.ipv4_address) -- ipv4_n.newProp('netmask', str(dev.ipv4_netmask)) -- ipv4_n.newProp('broadcast', dev.ipv4_broadcast) -- ipv4_n.newProp('defaultgw', (defgw4 == dev.device) and '1' or '0') -- intf_n.addChild(ipv4_n) -- -- for ip6 in dev.get_ipv6_addresses(): -- ipv6_n = libxml2.newNode('IPv6') -- ipv6_n.newProp('ipaddr', ip6.address) -- ipv6_n.newProp('netmask', str(ip6.netmask)) -- ipv6_n.newProp('scope', ip6.scope) -- intf_n.addChild(ipv6_n) -- -- else: # Fall back to older python-ethtool API (version < 0.4) -- ifdevs = ethtool.get_active_devices() -- ifdevs.remove('lo') -- ifdevs.sort() -- -- for dev in ifdevs: -- intf_n = libxml2.newNode('interface') -- intf_n.newProp('device', dev.device) -- intf_n.newProp('hwaddr', dev.mac_address) -- ncfg_n.addChild(intf_n) -- -- ipv4_n = libxml2.newNode('IPv4') -- ipv4_n.newProp('ipaddr', ethtool.get_ipaddr(dev)) -- ipv4_n.newProp('netmask', str(ethtool.get_netmask(dev))) -- ipv4_n.newProp('defaultgw', (defgw4 == dev) and '1' or '0') -- intf_n.addChild(ipv4_n) -- -- return ncfg_n -- -- --def unit_test(rootdir): -- import sys -- try: -- net = NetworkInfo() -- doc = libxml2.newDoc('1.0') -- cfg = net.MakeReport() -- doc.setRootElement(cfg) -- doc.saveFormatFileEnc('-', 'UTF-8', 1) -- -- except Exception as e: -- import traceback -- traceback.print_exc(file=sys.stdout) -- print("** EXCEPTION %s", str(e)) -- return 1 -- --if __name__ == '__main__': -- unit_test(None) -- -diff --git a/rteval/sysinfo/newnet.py b/rteval/sysinfo/newnet.py -new file mode 100644 -index 000000000000..63417d9e59f1 ---- /dev/null -+++ b/rteval/sysinfo/newnet.py -@@ -0,0 +1,225 @@ -+''' Module to obtain network information for the rteval report ''' -+# -+# Copyright 2022 John Kacur 0: -+ (iface, dest, gateway, _, _, _, _, _, _, _, _) = line.split() -+ if iface == 'Iface': -+ line = f.readline().strip() -+ continue -+ if dest == '00000000' and gateway != '00000000': -+ addr = int(gateway, base=16) -+ defaultgw = str(ipaddress.IPv4Address(socket.ntohl(addr))) -+ return defaultgw -+ line = f.readline().strip() -+ return defaultgw -+ -+class IPv6Addresses(): -+ ''' Obtains a list of IPv6 addresses from the proc file system ''' -+ -+ def __init__(self): -+ self.data = {} -+ IPv6Addresses.load(self) -+ -+ def __contains__(self, dev): -+ return dev in self.data -+ -+ def __getitem__(self, dev): -+ return self.data.get(dev, None) -+ -+ def __iter__(self): -+ return iter(self.data) -+ -+ def load(self): -+ ''' -+ Called by init to load the self.data dictionary with device keys -+ and a list of ipv6addresses -+ ''' -+ MYP = '/proc/net/if_inet6' -+ with open(MYP, 'r') as f: -+ mystr = f.readline().strip() -+ while len(mystr) > 0: -+ ipv6addr , _, _, _, _, intf = mystr.split() -+ ipv6addr = compress_iv6(ipv6addr) -+ if intf == 'lo': -+ mystr = f.readline().strip() -+ continue -+ if intf not in self.data: -+ self.data[intf] = [ipv6addr] -+ else: -+ self.data[intf].append(ipv6addr) -+ mystr = f.readline().strip() -+ -+class IPv4Addresses(): -+ ''' Obtains a list of IPv4 addresses from the proc file system ''' -+ -+ def __init__(self): -+ self.data = {} -+ IPv4Addresses.load(self) -+ -+ def __contains__(self, dev): -+ return dev in self.data -+ -+ def __getitem__(self, dev): -+ return self.data[dev] -+ -+ def __iter__(self): -+ return iter(self.data) -+ -+ def load(self): -+ ''' -+ Called by init to load the self.data dictionary with -+ device keys, and value consisting of a list of -+ ipv4address, netmask and broadcast address -+ ''' -+ MYP = '/proc/net/route' -+ with open(MYP, 'r') as f: -+ mystr = f.readline().strip() -+ while len(mystr) > 0: -+ intf, dest, _, _, _, _, _, mask, _, _, _ = mystr.split() -+ # Skip over the head of the table an the gateway line -+ if intf == "Iface" or dest == '00000000': -+ mystr = f.readline().strip() -+ continue -+ d1 = int(dest, base=16) -+ m1 = int(mask, base=16) -+ addr = str(ipaddress.IPv4Address(socket.ntohl(d1))) -+ netmask = str(ipaddress.IPv4Address(socket.ntohl(m1))) -+ addr_with_mask = ipaddress.ip_network(addr + '/' + netmask) -+ broadcast = str(addr_with_mask.broadcast_address) -+ if intf not in self.data: -+ self.data[intf] = [(addr, netmask, broadcast)] -+ else: -+ self.data[intf].append((addr, netmask, broadcast)) -+ mystr = f.readline().strip() -+ -+ -+class MacAddresses(): -+ ''' Obtains a list of hardware addresses of network devices ''' -+ -+ def __init__(self): -+ self.mac_address = {} -+ self.path = None -+ MacAddresses.load(self) -+ -+ def load(self): -+ ''' -+ called by init to load self.mac_address as a dictionary of -+ device keys, and mac or hardware addresses as values -+ ''' -+ nics = get_active_devices() -+ for nic in nics: -+ self.path = f'/sys/class/net/{nic}' -+ hwaddr = MacAddresses.set_val(self, 'address') -+ self.mac_address[nic] = hwaddr -+ -+ def set_val(self, val): -+ ''' Return the result of reading self.path/val ''' -+ val_path = f'{self.path}/{val}' -+ if os.path.exists(val_path): -+ with open(val_path, 'r') as f: -+ return f.readline().strip() -+ return None -+ -+ def __contains__(self, dev): -+ return dev in self.mac_address -+ -+ def __getitem__(self, dev): -+ return self.mac_address[dev] -+ -+ def __iter__(self): -+ return iter(self.mac_address) -+ -+class NetworkInfo(): -+ ''' Creates an xml report of the network for rteval ''' -+ -+ def __init__(self, logger): -+ self.defgw4 = get_defaultgw() -+ self.__logger = logger -+ -+ def MakeReport(self): -+ ''' Make an xml report for rteval ''' -+ ncfg_n = libxml2.newNode("NetworkConfig") -+ defgw4 = self.defgw4 -+ -+ mads = MacAddresses() -+ for device in mads: -+ if device == 'lo': -+ continue -+ intf_n = libxml2.newNode('interface') -+ intf_n.newProp('device', device) -+ intf_n.newProp('hwaddr', mads[device]) -+ ncfg_n.addChild(intf_n) -+ -+ ipv4ads = IPv4Addresses() -+ ipv6ads = IPv6Addresses() -+ for dev in ipv4ads: -+ if dev != device: -+ continue -+ for lelem in ipv4ads[dev]: -+ ipv4_n = libxml2.newNode('IPv4') -+ (ipaddr, netmask, broadcast) = lelem -+ ipv4_n.newProp('ipaddr', ipaddr) -+ ipv4_n.newProp('netmask', netmask) -+ ipv4_n.newProp('broadcast', broadcast) -+ ipv4_n.newProp('defaultgw', (defgw4 == ipaddr) and '1' or '0') -+ intf_n.addChild(ipv4_n) -+ if ipv6ads[dev]: -+ for lelem in ipv6ads[dev]: -+ ipv6_n = libxml2.newNode('IPv6') -+ ipaddr = lelem -+ ipv6_n.newProp('ipaddr', ipaddr) -+ intf_n.addChild(ipv6_n) -+ return ncfg_n -+ -+if __name__ == "__main__": -+ -+ try: -+ log = Log() -+ log.SetLogVerbosity(Log.DEBUG|Log.INFO) -+ net = NetworkInfo(logger=log) -+ doc = libxml2.newDoc('1.0') -+ cfg = net.MakeReport() -+ doc.setRootElement(cfg) -+ doc.saveFormatFileEnc('-', 'UTF-8', 1) -+ -+ except Exception as e: -+ import traceback -+ traceback.print_exc(file=sys.stdout) -+ print(f"** EXCEPTION {str(e)}") --- -2.37.3 - diff --git a/SOURCES/rteval-Use-f-strings-in-cputopology.patch b/SOURCES/rteval-Use-f-strings-in-cputopology.patch deleted file mode 100644 index 64c7999..0000000 --- a/SOURCES/rteval-Use-f-strings-in-cputopology.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c8f7457cfb23b595bdd3f500dc1c9790c7302dd3 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:29 -0400 -Subject: rteval: Use f-strings in cputopology - -Use f-strings in cputopology - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/cputopology.py | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/rteval/sysinfo/cputopology.py b/rteval/sysinfo/cputopology.py -index ced7e1f295b7..2bb632312320 100644 ---- a/rteval/sysinfo/cputopology.py -+++ b/rteval/sysinfo/cputopology.py -@@ -124,9 +124,7 @@ def unit_test(rootdir): - x.saveFormatFileEnc('-', 'UTF-8', 1) - - print(" ---- getCPUcores() / getCPUscokets() ---- ") -- print("CPU cores: %i (online: %i) - CPU sockets: %i" % (cputop.cpu_getCores(False), -- cputop.cpu_getCores(True), -- cputop.cpu_getSockets())) -+ print(f"CPU cores: {cputop.cpu_getCores(False)} (online: {cputop.cpu_getCores(True)}) - CPU sockets: {cputop.cpu_getSockets()}") - return 0 - except Exception as e: - # import traceback --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-kernel.py.patch b/SOURCES/rteval-Use-f-strings-in-kernel.py.patch deleted file mode 100644 index 928c0c3..0000000 --- a/SOURCES/rteval-Use-f-strings-in-kernel.py.patch +++ /dev/null @@ -1,31 +0,0 @@ -From a4acd156917024303f326dd5e66a7c9e2d12fda3 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:30 -0400 -Subject: rteval: Use f-strings in kernel.py - -Use f-strings in kernel.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/kernel.py | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/rteval/sysinfo/kernel.py b/rteval/sysinfo/kernel.py -index f2e9d72ac2ef..ba5cadda40c5 100644 ---- a/rteval/sysinfo/kernel.py -+++ b/rteval/sysinfo/kernel.py -@@ -47,8 +47,8 @@ class KernelInfo: - policies = {'DLN': 'deadline', 'FF':'fifo', 'RR':'rrobin', 'TS':'other', '?':'unknown'} - ret_kthreads = {} - self.__log(Log.DEBUG, "getting kthread status") -- cmd = '%s -eocommand,pid,policy,rtprio,comm' % getcmdpath('ps') -- self.__log(Log.DEBUG, "cmd: %s" % cmd) -+ cmd = f"{getcmdpath('ps')} -eocommand,pid,policy,rtprio,comm" -+ self.__log(Log.DEBUG, f"cmd: {cmd}") - c = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) - for p in c.stdout: - v = p.strip().split() --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-memory.py.patch b/SOURCES/rteval-Use-f-strings-in-memory.py.patch deleted file mode 100644 index 98aca44..0000000 --- a/SOURCES/rteval-Use-f-strings-in-memory.py.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 6e063353072b73e43a732bb5dfa265767ac0dbd7 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:31 -0400 -Subject: rteval: Use f-strings in memory.py - -Use f-strings in memory.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/memory.py | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/rteval/sysinfo/memory.py b/rteval/sysinfo/memory.py -index 7c5fd6f315cf..cc2fa2cfa4be 100644 ---- a/rteval/sysinfo/memory.py -+++ b/rteval/sysinfo/memory.py -@@ -49,7 +49,7 @@ class MemoryInfo: - if l.startswith('MemTotal:'): - parts = l.split() - if parts[2].lower() != 'kb': -- raise RuntimeError("Units changed from kB! (%s)" % parts[2]) -+ raise RuntimeError(f"Units changed from kB! ({parts[2]})") - rawsize = int(parts[1]) - f.close() - break -@@ -76,7 +76,7 @@ class MemoryInfo: - - memsize = self.mem_get_size() - mem_n = libxml2.newNode("memory_size") -- mem_n.addContent("%.3f" % memsize[0]) -+ mem_n.addContent(f"{memsize[0]:.3f}") - mem_n.newProp("unit", memsize[1]) - rep_n.addChild(mem_n) - -@@ -88,8 +88,8 @@ def unit_test(rootdir): - import sys - try: - mi = MemoryInfo() -- print("Numa nodes: %i" % mi.mem_get_numa_nodes()) -- print("Memory: %i %s" % mi.mem_get_size()) -+ print(f"Numa nodes: {mi.mem_get_numa_nodes()}") -+ print(f"Memory: {int(mi.mem_get_size()[0])} {mi.mem_get_size()[1]}") - except Exception as e: - import traceback - traceback.print_exc(file=sys.stdout) --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-osinfo.patch b/SOURCES/rteval-Use-f-strings-in-osinfo.patch deleted file mode 100644 index 3897897..0000000 --- a/SOURCES/rteval-Use-f-strings-in-osinfo.patch +++ /dev/null @@ -1,61 +0,0 @@ -From f821e5f2daf595838395d80ba89ee5699076daf1 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:32 -0400 -Subject: rteval: Use f-strings in osinfo - -Use f-strings in osinfo.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/osinfo.py | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/rteval/sysinfo/osinfo.py b/rteval/sysinfo/osinfo.py -index ead5e3939cfa..83dc78b96fdd 100644 ---- a/rteval/sysinfo/osinfo.py -+++ b/rteval/sysinfo/osinfo.py -@@ -55,9 +55,9 @@ class OSInfo: - shutil.copyfile(dpath, os.path.join(repdir, "dmesg")) - return - if os.path.exists('/usr/bin/dmesg'): -- subprocess.call('/usr/bin/dmesg > %s' % os.path.join(repdir, "dmesg"), shell=True) -+ subprocess.call(f'/usr/bin/dmesg > {os.path.join(repdir, "dmesg")}', shell=True) - return -- print("dmesg file not found at %s and no dmesg exe found!" % dpath) -+ print(f"dmesg file not found at {dpath} and no dmesg exe found!") - - - -@@ -69,16 +69,16 @@ class OSInfo: - else: - raise RuntimeError("Can't find sosreport/sysreport") - -- self.__logger.log(Log.DEBUG, "report tool: %s" % exe) -+ self.__logger.log(Log.DEBUG, f"report tool: {exe}") - options = ['-k', 'rpm.rpmva=off', - '--name=rteval', - '--batch'] - - self.__logger.log(Log.INFO, "Generating SOS report") -- self.__logger.log(Log.INFO, "using command %s" % " ".join([exe]+options)) -+ self.__logger.log(Log.INFO, f"using command {' '.join([exe]+options)}") - subprocess.call([exe] + options) - for s in glob('/tmp/s?sreport-rteval-*'): -- self.__logger.log(Log.DEBUG, "moving %s to %s" % (s, repdir)) -+ self.__logger.log(Log.DEBUG, f"moving {s} to {repdir}") - shutil.move(s, repdir) - - -@@ -118,7 +118,7 @@ def unit_test(rootdir): - log = Log() - log.SetLogVerbosity(Log.DEBUG|Log.INFO) - osi = OSInfo(logger=log) -- print("Base OS: %s" % osi.get_base_os()) -+ print(f"Base OS: {osi.get_base_os()}") - - print("Testing OSInfo::copy_dmesg('/tmp'): ", end=' ') - osi.copy_dmesg('/tmp') --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-rtevalConfig.patch b/SOURCES/rteval-Use-f-strings-in-rtevalConfig.patch deleted file mode 100644 index 8c02fb1..0000000 --- a/SOURCES/rteval-Use-f-strings-in-rtevalConfig.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 2de834b44c2a731bc25449d84456396c0d519198 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:28 -0400 -Subject: rteval: Use f-strings in rtevalConfig - -Use f-strings in rtevalConfig.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/rtevalConfig.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rteval/rtevalConfig.py b/rteval/rtevalConfig.py -index de88924642ca..41f1a567720f 100644 ---- a/rteval/rtevalConfig.py -+++ b/rteval/rtevalConfig.py -@@ -115,7 +115,7 @@ class rtevalCfgSection: - "Simple method for dumping config when object is used as a string" - if not self.__cfgdata: - return "# empty" -- return "\n".join(["%s: %s" % (k, v) for k, v in list(self.__cfgdata.items())]) + "\n" -+ return "\n".join([f"{k}: {v}" for k, v in list(self.__cfgdata.items())]) + "\n" - - - def __setattr__(self, key, val): --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-rtevalclient.py.patch b/SOURCES/rteval-Use-f-strings-in-rtevalclient.py.patch deleted file mode 100644 index 43a0989..0000000 --- a/SOURCES/rteval-Use-f-strings-in-rtevalclient.py.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5e4fed8a745f70f9be1199f047069e144e9b8fd5 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:27 -0400 -Subject: rteval: Use f-strings in rtevalclient.py - -Use f-strings in rtevalclient.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/rtevalclient.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rteval/rtevalclient.py b/rteval/rtevalclient.py -index 26c953005326..7ff7d2700cfc 100644 ---- a/rteval/rtevalclient.py -+++ b/rteval/rtevalclient.py -@@ -61,7 +61,7 @@ class rtevalclient: - cmpr = compr.compress(fbuf.getvalue()) - data = base64.b64encode(cmpr + compr.flush()) - ret = self.srv.SendReport(self.hostname, data) -- print("rtevalclient::SendReport() - Sent %i bytes (XML document length: %i bytes, compression ratio: %.02f%%)" % (len(data), doclen, (1-(float(len(data)) / float(doclen)))*100 )) -+ print(f"rtevalclient::SendReport() - Sent {len(data)} bytes (XML document length: {doclen} bytes, compression ratio: {(1-(float(len(data)) / float(doclen)))*100}:.2f)") - return ret - - def SendDataAsFile(self, fname, data, decompr = False): --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-services.py.patch b/SOURCES/rteval-Use-f-strings-in-services.py.patch deleted file mode 100644 index 9950cb9..0000000 --- a/SOURCES/rteval-Use-f-strings-in-services.py.patch +++ /dev/null @@ -1,61 +0,0 @@ -From d83a8eb7f0b830408659483922eca25b51bd7b5e Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:33 -0400 -Subject: rteval: Use f-strings in services.py - -Use f-strings in services.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/services.py | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/rteval/sysinfo/services.py b/rteval/sysinfo/services.py -index c85980e19165..a87b4abeea76 100644 ---- a/rteval/sysinfo/services.py -+++ b/rteval/sysinfo/services.py -@@ -55,17 +55,17 @@ class SystemServices: - break - if not servicesdir: - raise RuntimeError("No services dir (init.d) found on your system") -- self.__log(Log.DEBUG, "Services located in %s, going through each service file to check status" % servicesdir) -+ self.__log(Log.DEBUG, f"Services located in {servicesdir}, going through each service file to check status") - ret_services = {} - for service in glob.glob(os.path.join(servicesdir, '*')): - servicename = os.path.basename(service) - if not [1 for p in reject if fnmatch.fnmatch(servicename, p)] \ - and os.access(service, os.X_OK): -- cmd = '%s -qs "\(^\|\W\)status)" %s' % (getcmdpath('grep'), service) -+ cmd = f'{getcmdpath("grep")} -qs "\(^\|\W\)status)" {service}' - c = subprocess.Popen(cmd, shell=True, encoding='utf-8') - c.wait() - if c.returncode == 0: -- cmd = ['env', '-i', 'LANG="%s"' % os.environ['LANG'], 'PATH="%s"' % os.environ['PATH'], 'TERM="%s"' % os.environ['TERM'], service, 'status'] -+ cmd = ['env', '-i', f'LANG="{os.environ["LANG"]}"', f'PATH="{os.environ["PATH"]}"', f'TERM="{os.environ["TERM"]}"', service, 'status'] - c = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') - c.wait() - if c.returncode == 0 and (c.stdout.read() or c.stderr.read()): -@@ -79,8 +79,8 @@ class SystemServices: - - def __get_services_systemd(self): - ret_services = {} -- cmd = '%s list-unit-files -t service --no-legend' % getcmdpath('systemctl') -- self.__log(Log.DEBUG, "cmd: %s" % cmd) -+ cmd = f'{getcmdpath("systemctl")} list-unit-files -t service --no-legend' -+ self.__log(Log.DEBUG, f"cmd: {cmd}") - c = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') - for p in c.stdout: - # p are lines like b'servicename.service status' -@@ -133,7 +133,7 @@ def unit_test(rootdir): - - return 0 - except Exception as err: -- print("** EXCEPTION: %s" % str(err)) -+ print(f"** EXCEPTION: {str(err)}") - return 1 - - --- -2.40.1 - diff --git a/SOURCES/rteval-Use-f-strings-in-tools.py.patch b/SOURCES/rteval-Use-f-strings-in-tools.py.patch deleted file mode 100644 index d521adf..0000000 --- a/SOURCES/rteval-Use-f-strings-in-tools.py.patch +++ /dev/null @@ -1,27 +0,0 @@ -From adc41fa998fc15dff2c5edf3f57e6cd0970e17e5 Mon Sep 17 00:00:00 2001 -From: Anubhav Shelat -Date: Thu, 1 Jun 2023 16:27:34 -0400 -Subject: rteval: Use f-strings in tools.py - -Use f-strings in tools.py - -Signed-off-by: Anubhav Shelat -Signed-off-by: John Kacur ---- - rteval/sysinfo/tools.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rteval/sysinfo/tools.py b/rteval/sysinfo/tools.py -index 3993da413d8a..aa00b3d3eafc 100644 ---- a/rteval/sysinfo/tools.py -+++ b/rteval/sysinfo/tools.py -@@ -40,5 +40,5 @@ def getcmdpath(which): - pathSave[which] = cmdfile - break - if not pathSave[which]: -- raise RuntimeError("Command '%s' is unknown on this system" % which) -+ raise RuntimeError(f"Command '{which}' is unknown on this system") - return pathSave[which] --- -2.40.1 - diff --git a/SOURCES/rteval-rteval-__init__.py-Convert-regular-strings-to.patch b/SOURCES/rteval-rteval-__init__.py-Convert-regular-strings-to.patch deleted file mode 100644 index 9a37a61..0000000 --- a/SOURCES/rteval-rteval-__init__.py-Convert-regular-strings-to.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 0f44bad0f6d95448425903c4ec3a3fa8093ae6e7 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Wed, 9 Nov 2022 12:28:38 -0500 -Subject: rteval: rteval/__init__.py: Convert regular strings to f-strings - -Convert regular strings to f-strings in __init__.py - -Signed-off-by: John Kacur ---- - rteval/__init__.py | 32 +++++++++++++++----------------- - 1 file changed, 15 insertions(+), 17 deletions(-) - -diff --git a/rteval/__init__.py b/rteval/__init__.py -index 22af8e85d5aa..d8127425febe 100644 ---- a/rteval/__init__.py -+++ b/rteval/__init__.py -@@ -59,7 +59,7 @@ def sig_handler(signum, frame): - stopsig_received = True - print("*** stop signal received - stopping rteval run ***") - else: -- raise RuntimeError("SIGNAL received! (%d)" % signum) -+ raise RuntimeError(f"SIGNAL received! ({signum})") - - class RtEval(rtevalReport): - def __init__(self, config, loadmods, measuremods, logger): -@@ -96,10 +96,10 @@ class RtEval(rtevalReport): - self.__mailer = None - - if not os.path.exists(self.__rtevcfg.xslt_report): -- raise RuntimeError("can't find XSL template (%s)!" % self.__rtevcfg.xslt_report) -+ raise RuntimeError(f"can't find XSL template ({self.__rtevcfg.xslt_report})!") - - # Add rteval directory into module search path -- sys.path.insert(0, '%s/rteval' % sysconfig.get_python_lib()) -+ sys.path.insert(0, f'{sysconfig.get_python_lib()}/rteval') - - # Initialise the report module - rtevalReport.__init__(self, self.__version, -@@ -110,8 +110,7 @@ class RtEval(rtevalReport): - self.__xmlrpc = rtevalXMLRPC(self.__rtevcfg.xmlrpc, self.__logger, self.__mailer) - if not self.__xmlrpc.Ping(): - if not self.__rtevcfg.xmlrpc_noabort: -- print("ERROR: Could not reach XML-RPC server '%s'. Aborting." % \ -- self.__rtevcfg.xmlrpc) -+ print(f"ERROR: Could not reach XML-RPC server '{self.__rtevcfg.xmlrpc}'. Aborting.") - sys.exit(2) - else: - print("WARNING: Could not ping the XML-RPC server. Will continue anyway.") -@@ -174,8 +173,7 @@ class RtEval(rtevalReport): - - measure_start = None - (with_loads, run_parallel) = measure_profile.GetProfile() -- self.__logger.log(Log.INFO, "Using measurement profile [loads: %s parallel: %s]" % ( -- with_loads, run_parallel)) -+ self.__logger.log(Log.INFO, f"Using measurement profile [loads: {with_loads} parallel: {run_parallel}]") - try: - nthreads = 0 - -@@ -183,23 +181,23 @@ class RtEval(rtevalReport): - if with_loads: - self._loadmods.Start() - -- print("rteval run on %s started at %s" % (os.uname()[2], time.asctime())) -+ print(f"rteval run on {os.uname()[2]} started at {time.asctime()}") - onlinecpus = self._sysinfo.cpu_getCores(True) - cpulist = self._loadmods._cfg.GetSection("loads").cpulist - if cpulist: -- print("started %d loads on cores %s" % (self._loadmods.ModulesLoaded(), cpulist), end=' ') -+ print(f"started {self._loadmods.ModulesLoaded()} loads on cores {cpulist}", end=' ') - else: -- print("started %d loads on %d cores" % (self._loadmods.ModulesLoaded(), onlinecpus), end=' ') -+ print(f"started {self._loadmods.ModulesLoaded()} loads on {onlinecpus} cores", end=' ') - if self._sysinfo.mem_get_numa_nodes() > 1: -- print(" with %d numa nodes" % self._sysinfo.mem_get_numa_nodes()) -+ print(f" with {self._sysinfo.mem_get_numa_nodes()} numa nodes") - else: - print("") - cpulist = self._measuremods._MeasurementModules__cfg.GetSection("measurement").cpulist - if cpulist: -- print("started measurement threads on cores %s" % cpulist) -+ print(f"started measurement threads on cores {cpulist}") - else: -- print("started measurement threads on %d cores" % onlinecpus) -- print("Run duration: %s seconds" % str(self.__rtevcfg.duration)) -+ print(f"started measurement threads on {onlinecpus} cores") -+ print(f"Run duration: {str(self.__rtevcfg.duration)} seconds") - - # start the cyclictest thread - measure_profile.Start() -@@ -219,7 +217,7 @@ class RtEval(rtevalReport): - # wait for time to expire or thread to die - signal.signal(signal.SIGINT, sig_handler) - signal.signal(signal.SIGTERM, sig_handler) -- self.__logger.log(Log.INFO, "waiting for duration (%s)" % str(self.__rtevcfg.duration)) -+ self.__logger.log(Log.INFO, f"waiting for duration ({str(self.__rtevcfg.duration)})") - stoptime = (time.time() + float(self.__rtevcfg.duration)) - currtime = time.time() - rpttime = currtime + report_interval -@@ -246,7 +244,7 @@ class RtEval(rtevalReport): - left_to_run = stoptime - currtime - self.__show_remaining_time(left_to_run) - rpttime = currtime + report_interval -- print("load average: %.2f" % self._loadmods.GetLoadAvg()) -+ print(f"load average: {self._loadmods.GetLoadAvg():.2f}") - currtime = time.time() - - self.__logger.log(Log.DEBUG, "out of measurement loop") -@@ -265,7 +263,7 @@ class RtEval(rtevalReport): - if with_loads: - self._loadmods.Stop() - -- print("stopping run at %s" % time.asctime()) -+ print(f"stopping run at {time.asctime()}") - - # wait for measurement modules to finish calculating stats - measure_profile.WaitForCompletion() --- -2.40.1 - diff --git a/SOURCES/rteval-rtevalConfig.py-Convert-regular-strings-to-f-.patch b/SOURCES/rteval-rtevalConfig.py-Convert-regular-strings-to-f-.patch deleted file mode 100644 index e30b73c..0000000 --- a/SOURCES/rteval-rtevalConfig.py-Convert-regular-strings-to-f-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0945147e2c459dfff400fe8bfdebd11e6464eab4 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Wed, 9 Nov 2022 14:14:50 -0500 -Subject: rteval: rtevalConfig.py: Convert regular strings to f-strings - -Convert regular strings to f-strings in rtevalConfig.py - -Signed-off-by: John Kacur ---- - rteval/rtevalConfig.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/rteval/rtevalConfig.py b/rteval/rtevalConfig.py -index decd36ed18ab..de88924642ca 100644 ---- a/rteval/rtevalConfig.py -+++ b/rteval/rtevalConfig.py -@@ -196,7 +196,7 @@ class rtevalConfig: - - # get our system topology info - self.__systopology = SysTopology() -- print(("got system topology: %s" % self.__systopology)) -+ print(f"got system topology: {self.__systopology}") - - # Import the default config first - for sect, vals in list(default_config.items()): -@@ -225,7 +225,7 @@ class rtevalConfig: - "Simple method for dumping config when object is used as a string" - ret = "" - for sect in list(self.__config_data.keys()): -- ret += "[%s]\n%s\n" % (sect, str(self.__config_data[sect])) -+ ret += f"[{sect}]\n{str(self.__config_data[sect])}\n" - return ret - - -@@ -240,7 +240,7 @@ class rtevalConfig: - for f in ('rteval.conf', '/etc/rteval.conf'): - p = os.path.abspath(f) - if os.path.exists(p): -- self.__info("found config file %s" % p) -+ self.__info(f"found config file {p}") - return p - raise RuntimeError("Unable to find configfile") - -@@ -258,7 +258,7 @@ class rtevalConfig: - # Don't try to reread this file if it's already been parsed - return - -- self.__info("reading config file %s" % cfgfile) -+ self.__info(f"reading config file {cfgfile}") - ini = configparser.ConfigParser() - ini.optionxform = str - ini.read(cfgfile) -@@ -321,7 +321,7 @@ class rtevalConfig: - # Return a new object with config settings of a given section - return self.__config_data[section] - except KeyError: -- raise KeyError("The section '%s' does not exist in the config file" % section) -+ raise KeyError(f"The section '{section}' does not exist in the config file") - - - def unit_test(rootdir): --- -2.40.1 - diff --git a/SOURCES/rteval-rtevalReport.py-Convert-regular-strings-to-f-.patch b/SOURCES/rteval-rtevalReport.py-Convert-regular-strings-to-f-.patch deleted file mode 100644 index aa29ba0..0000000 --- a/SOURCES/rteval-rtevalReport.py-Convert-regular-strings-to-f-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 96ce02046afedfac27c69c30d6ee6b9511238131 Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Wed, 9 Nov 2022 12:47:09 -0500 -Subject: rteval: rtevalReport.py: Convert regular strings to f-strings - -Convert regular strings to f-strings in rtevalReport.py - -Signed-off-by: John Kacur ---- - rteval/rtevalReport.py | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/rteval/rtevalReport.py b/rteval/rtevalReport.py -index fdfaed560cfa..af3e6c9a703b 100644 ---- a/rteval/rtevalReport.py -+++ b/rteval/rtevalReport.py -@@ -100,11 +100,11 @@ class rtevalReport: - - def _show_report(self, xmlfile, xsltfile): - '''summarize a previously generated xml file''' -- print("Loading %s for summarizing" % xmlfile) -+ print(f"Loading {xmlfile} for summarizing") - - xsltfullpath = os.path.join(self.__installdir, xsltfile) - if not os.path.exists(xsltfullpath): -- raise RuntimeError("can't find XSL template (%s)!" % xsltfullpath) -+ raise RuntimeError(f"can't find XSL template ({xsltfullpath})!") - - xmlreport = xmlout.XMLOut('rteval', self.__version) - xmlreport.LoadReport(xmlfile) -@@ -131,7 +131,7 @@ class rtevalReport: - - def _tar_results(self): - if not os.path.isdir(self.__reportdir): -- raise RuntimeError("no such directory: %s" % self.__reportdir) -+ raise RuntimeError(f"no such directory: {self.__reportdir}") - - dirname = os.path.dirname(self.__reportdir) - rptdir = os.path.basename(self.__reportdir) --- -2.40.1 - diff --git a/SOURCES/rteval-rtevalXMLRPC.py-Convert-regular-strings-to-f-.patch b/SOURCES/rteval-rtevalXMLRPC.py-Convert-regular-strings-to-f-.patch deleted file mode 100644 index e466996..0000000 --- a/SOURCES/rteval-rtevalXMLRPC.py-Convert-regular-strings-to-f-.patch +++ /dev/null @@ -1,114 +0,0 @@ -From eceb9de2d2a0bcf3394ca257d42f91bdcac71caf Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Wed, 9 Nov 2022 13:42:59 -0500 -Subject: rteval: rtevalXMLRPC.py: Convert regular strings to f-strings - -Convert regular strings to f-strings in rtevalXMLRPC.py - -Signed-off-by: John Kacur ---- - rteval/rtevalXMLRPC.py | 34 ++++++++++++++-------------------- - 1 file changed, 14 insertions(+), 20 deletions(-) - -diff --git a/rteval/rtevalXMLRPC.py b/rteval/rtevalXMLRPC.py -index f24e21a8ed2f..6dce12ad78bb 100644 ---- a/rteval/rtevalXMLRPC.py -+++ b/rteval/rtevalXMLRPC.py -@@ -33,7 +33,7 @@ from .Log import Log - class rtevalXMLRPC: - def __init__(self, host, logger, mailer=None): - self.__host = host -- self.__url = "http://%s/rteval/API1/" % self.__host -+ self.__url = f"http://{self.__host}/rteval/API1/" - self.__logger = logger - self.__mailer = mailer - self.__client = rtevalclient.rtevalclient(self.__url) -@@ -41,7 +41,7 @@ class rtevalXMLRPC: - - def Ping(self): - res = None -- self.__logger.log(Log.DEBUG, "Checking if XML-RPC server '%s' is reachable" % self.__host) -+ self.__logger.log(Log.DEBUG, f"Checking if XML-RPC server '{self.__host}' is reachable") - attempt = 0 - ping_success = False - warning_sent = False -@@ -52,10 +52,10 @@ class rtevalXMLRPC: - ping_success = True - except xmlrpc.client.ProtocolError: - # Server do not support Hello(), but is reachable -- self.__logger.log(Log.INFO, "Got XML-RPC connection with %s but it did not support Hello()" % self.__host) -+ self.__logger.log(Log.INFO, f"Got XML-RPC connection with {self.__host} but it did not support Hello()") - res = None - except socket.error as err: -- self.__logger.log(Log.INFO, "Could not establish XML-RPC contact with %s\n%s" % (self.__host, str(err))) -+ self.__logger.log(Log.INFO, f"Could not establish XML-RPC contact with {self.__host}\n{str(err)}") - - # Do attempts handling - attempt += 1 -@@ -63,17 +63,16 @@ class rtevalXMLRPC: - break # To avoid sleeping before we abort - - if (self.__mailer is not None) and (not warning_sent): -- self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to ping XML-RPC server", "Server %s did not respond." % self.__host) -+ self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to ping XML-RPC server", f"Server {self.__host} did not respond.") - warning_sent = True - -- print("Failed pinging XML-RPC server. Doing another attempt(%i) " % attempt) -+ print(f"Failed pinging XML-RPC server. Doing another attempt({attempt}) ") - time.sleep(attempt) #*15) # Incremental sleep - sleep attempts*15 seconds - ping_success = False - - if res: -- self.__logger.log(Log.INFO, "Verified XML-RPC connection with %s (XML-RPC API version: %i)" % (res["server"], res["APIversion"])) -- self.__logger.log(Log.DEBUG, "Recieved greeting: %s" % res["greeting"]) -- -+ self.__logger.log(Log.INFO, f'Verified XML-RPC connection with {res["server"]} (XML-RPC API version: {res["APIversion"]})') -+ self.__logger.log(Log.DEBUG, f"Recieved greeting: {res['greeting']}") - return ping_success - - -@@ -85,9 +84,9 @@ class rtevalXMLRPC: - warning_sent = False - while attempt < 6: - try: -- print("Submitting report to %s" % self.__url) -+ print(f"Submitting report to {self.__url}") - rterid = self.__client.SendReport(xmlreport) -- print("Report registered with submission id %i" % rterid) -+ print(f"Report registered with submission id {rterid}") - attempt = 10 - exitcode = 0 # Success - except socket.error: -@@ -96,12 +95,10 @@ class rtevalXMLRPC: - break # To avoid sleeping before we abort - - if (self.__mailer is not None) and (not warning_sent): -- self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to submit report to XML-RPC server", -- "Server %s did not respond. Not giving up yet." -- % self.__host) -+ self.__mailer.SendMessage("[RTEVAL:WARNING] Failed to submit report to XML-RPC server", f"Server {self.__host} did not respond. Not giving up yet.") - warning_sent = True - -- print("Failed sending report. Doing another attempt(%i) " % attempt) -+ print(f"Failed sending report. Making another attempt({attempt}) ") - time.sleep(attempt) #*5*60) # Incremental sleep - sleep attempts*5 minutes - - except Exception as err: -@@ -111,12 +108,9 @@ class rtevalXMLRPC: - if self.__mailer is not None: - # Send final result messages - if exitcode == 2: -- self.__mailer.SendMessage("[RTEVAL:FAILURE] Failed to submit report to XML-RPC server", -- "Server %s did not respond at all after %i attempts." -- % (self.__host, attempt - 1)) -+ self.__mailer.SendMessage("[RTEVAL:FAILURE] Failed to submit report to XML-RPC server", f"Server {self.__host} did not respond at all after {attempt - 1} attempts.") - elif (exitcode == 0) and warning_sent: - self.__mailer.SendMessage("[RTEVAL:SUCCESS] XML-RPC server available again", -- "Succeeded to submit the report to %s" -- % self.__host) -+ f"Succeeded to submit the report to {self.__host}") - - return exitcode --- -2.40.1 - diff --git a/SOURCES/rteval-xmlout.py-Convert-to-f-strings-where-possible.patch b/SOURCES/rteval-xmlout.py-Convert-to-f-strings-where-possible.patch deleted file mode 100644 index cb69092..0000000 --- a/SOURCES/rteval-xmlout.py-Convert-to-f-strings-where-possible.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ecd21eff1601e0ef666b80e0709eacbd4754250c Mon Sep 17 00:00:00 2001 -From: John Kacur -Date: Tue, 6 Dec 2022 14:35:49 -0500 -Subject: rteval: xmlout.py: Convert to f-strings where possible - -Convert xmlout.py to f-strings where possible - -Signed-off-by: John Kacur ---- - rteval/xmlout.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/rteval/xmlout.py b/rteval/xmlout.py -index a955fb11c77a..b549cc87a2cc 100644 ---- a/rteval/xmlout.py -+++ b/rteval/xmlout.py -@@ -67,7 +67,7 @@ class XMLOut: - - def __del__(self): - if self.level > 0: -- raise RuntimeError("XMLOut: open blocks at __del__ (last opened '%s')" % self.currtag.name) -+ raise RuntimeError(f"XMLOut: open blocks at __del__ (last opened '{self.currtag.name}')") - if self.xmldoc is not None: - self.xmldoc.freeDoc() - -@@ -131,7 +131,7 @@ class XMLOut: - self.__parseToXML(n, v) - node.addChild(n) - else: -- raise TypeError("unhandled type (%s) for value '%s'" % (type(data), str(data))) -+ raise TypeError(f"unhandled type ({str(type(data))}) for value '{str(data)}'") - - def close(self): - if self.status == 0: -@@ -139,7 +139,7 @@ class XMLOut: - if self.status == 3: - raise RuntimeError("XMLOut: XML document already closed") - if self.level > 0: -- raise RuntimeError("XMLOut: open blocks at close() (last opened '%s')" % self.currtag.name) -+ raise RuntimeError(f"XMLOut: open blocks at close() (last opened '{self.currtag.name}')") - - if self.status == 1: # Only set the root node in the doc on created reports (NewReport called) - self.xmldoc.setRootElement(self.xmlroot) -@@ -172,7 +172,7 @@ class XMLOut: - root = self.xmldoc.children - if root.name != self.roottag: - self.status = 3 -- raise RuntimeError("XMLOut: Loaded report is not a valid %s XML file" % self.roottag) -+ raise RuntimeError(f"XMLOut: Loaded report is not a valid {self.roottag} XML file") - - if validate_version is True: - ver = root.hasProp('version') -@@ -183,7 +183,7 @@ class XMLOut: - - if ver.getContent() != self.version: - self.status = 3 -- raise RuntimeError("XMLOut: Loaded report is not of version %s" % self.version) -+ raise RuntimeError(f"XMLOut: Loaded report is not of version {self.version}") - - self.status = 2 # Confirm that we have loaded a report from file - --- -2.40.1 - diff --git a/SPECS/rteval.spec b/SPECS/rteval.spec index 7f679df..a8bcfbd 100644 --- a/SPECS/rteval.spec +++ b/SPECS/rteval.spec @@ -1,6 +1,6 @@ Name: rteval -Version: 3.5 -Release: 9%{?dist} +Version: 3.7 +Release: 7%{?dist} Summary: Utility to evaluate system suitability for RT Linux Group: Development/Tools @@ -12,7 +12,6 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: python3-devel Requires: python3-lxml Requires: python3-libxml2 -Requires: python3-dmidecode >= 3.10 Requires: python3-requests Requires: realtime-tests >= 2.5-1 Requires: rteval-loads >= 1.6-2 @@ -31,27 +30,14 @@ Requires: dwarves BuildArch: noarch #Patches -Patch1: rteval-Replace-python-ethtool-with-inline-code.patch -Patch2: Fix-DMI-WARNING-when-not-running-as-root.patch -Patch3: rteval-Don-t-attempt-to-get-DMIinfo-if-there-are-dmi.patch -Patch4: rteval-Catch-failures-in-python-dmidecode.patch -Patch5: rteval-Change-the-default-kernel-to-compile-to-linux.patch -Patch6: Added-code-to-check-if-the-proc-net-if_inet6-file-ex.patch -Patch7: rteval-rteval-__init__.py-Convert-regular-strings-to.patch -Patch8: rteval-rtevalReport.py-Convert-regular-strings-to-f-.patch -Patch9: rteval-rtevalXMLRPC.py-Convert-regular-strings-to-f-.patch -Patch10: rteval-rtevalConfig.py-Convert-regular-strings-to-f-.patch -Patch11: rteval-xmlout.py-Convert-to-f-strings-where-possible.patch -Patch12: rteval-Log.py-Convert-to-f-strings.patch -Patch13: rteval-Use-f-strings-in-rtevalclient.py.patch -Patch14: rteval-Use-f-strings-in-rtevalConfig.patch -Patch15: rteval-Use-f-strings-in-kernel.py.patch -Patch16: rteval-Use-f-strings-in-memory.py.patch -Patch17: rteval-Use-f-strings-in-osinfo.patch -Patch18: rteval-Use-f-strings-in-services.py.patch -Patch19: rteval-Use-f-strings-in-tools.py.patch -Patch20: rteval-Use-f-strings-in-cputopology.patch - +Patch1: rteval-Change-the-default-kernel-for-kcompile.patch +Patch2: rteval-Remove-upstream-spec-file.patch +Patch3: rteval-Makefile-More-rpm-cleanups.patch +Patch4: rteval-Disable-use-of-python-dmidecode.patch +Patch5: rteval-Refactor-collapse_cpulist-in-systopology.patch +Patch6: rteval-Minor-improvements-to-CpuList-class.patch +Patch7: rteval-Convert-CpuList-class-to-a-module.patch +Patch8: rteval-Add-relative-cpulists-for-measurements.patch %description The rteval script is a utility for measuring various aspects of @@ -72,18 +58,6 @@ to the screen. %patch6 -p1 %patch7 -p1 %patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -%patch20 -p1 %build %{__python3} setup.py build @@ -105,6 +79,44 @@ to the screen. %{_bindir}/rteval %changelog +* Wed Jan 31 2024 Tomas Glozar - 3.7-7 +- Added patchset for relative cpuset functionality from upstream +Resolves: RHEL-9912 + +* Thu Dec 21 2023 John Kacur - 3.7-6 +- Disable the use of python-dmidecode +Resolves: RHEL-8857 + +* Wed Nov 15 2023 John Kacur - 3.7-5 +- Add a capabilities rule to the rpminspect.yaml file +Resolves: RHEL-16400 + +* Tue Nov 14 2023 John Kacur - 3.7-4 +- Add an rpminspect.yaml file to turn off permissions checks + for python egg-info files +Resolves: RHEL-16400 + +* Mon Nov 13 2023 John Kacur - 3.7-3 +- Remove upstream specfile +Resolves: RHEL-7615 + +* Thu Nov 09 2023 John Kacur - 3.7-2 +- Update rteval to use linux-6.6.1 as the default kernel for kcompile +Resolves: RHEL-14483 + +* Tue Oct 24 2023 John Kacur - 3.7-1 +- Rebase to rteval-3.7 upstream +jiraProject == RHEL-7863 + +* Wed Oct 04 2023 Tomas Glozar - 3.5-11 +- Added patch set that enables rteval to do load calculations and reporting +correctly on systems with isolated CPUs +jiraProject== RHEL-8681 + +* Wed Oct 04 2023 John Kacur - 3.5.10 +- Added patches to use argparse instead of deprecated optparse +jiraProject == RHEL-9026 + * Fri Aug 11 2023 John Kacur - 3.5-9 - Added patches to use f-strings where possible, no functional change jiraProject== RHEL-798