Commit 2f49364c authored by Rocky Automation's avatar Rocky Automation 📺
Browse files

import rteval-3.0-13.el8

parents
SOURCES/rteval-3.0.tar.xz
ee9134bcf8791823770f3ed764e52d003bd7a597 SOURCES/rteval-3.0.tar.xz
From 3a432a4217e1d91bb1dbc2e0503942997c40f370 Mon Sep 17 00:00:00 2001
From: Scott Wood <swood@redhat.com>
Date: Mon, 6 Apr 2020 17:14:03 -0500
Subject: [PATCH 01/17] Makefile: Remove non-distutil install leftovers
setup.py installs into /usr/local by default, but the makefile
is still creating directories in /usr that it doesn't install
anything into. Worse, the uninstall target removes things
from /usr rather than what was installed by "make install".
Signed-off-by: Scott Wood <swood@redhat.com>
Signed-off-by: John Kacur <jkacur@redhat.com>
---
Makefile | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/Makefile b/Makefile
index f784ba778bc3..f91e6e06a9a4 100644
--- a/Makefile
+++ b/Makefile
@@ -15,9 +15,6 @@ XMLRPCDIR := server
DESTDIR :=
PREFIX := /usr
DATADIR := $(DESTDIR)/$(PREFIX)/share
-CONFDIR := $(DESTDIR)/etc
-MANDIR := $(DESTDIR)/$(PREFIX)/share/man
-PYLIB := $(DESTDIR)$(shell $(PYTHON) -c 'import distutils.sysconfig; print distutils.sysconfig.get_python_lib()')
LOADDIR := loadsource
KLOAD := $(LOADDIR)/linux-5.1.tar.xz
@@ -60,17 +57,6 @@ install_loads: $(LOADS)
installdirs:
[ -d $(DATADIR)/rteval ] || mkdir -p $(DATADIR)/rteval
- [ -d $(CONFDIR) ] || mkdir -p $(CONFDIR)
- [ -d $(MANDIR)/man8 ] || mkdir -p $(MANDIR)/man8
- [ -d $(PYLIB) ] || mkdir -p $(PYLIB)
- [ -d $(DESTDIR)/usr/bin ] || mkdir -p $(DESTDIR)/usr/bin
-
-uninstall:
- rm -f /usr/bin/rteval
- rm -f $(CONFDIR)/rteval.conf
- rm -f $(MANDIR)/man8/rteval.8.gz
- rm -rf $(PYLIB)/rteval
- rm -rf $(DATADIR)/rteval
tarfile: rteval-$(VERSION).tar.bz2
--
2.21.3
From 91f72680851a7ab863d3733bc90e915404e68bc8 Mon Sep 17 00:00:00 2001
From: Scott Wood <swood@redhat.com>
Date: Mon, 6 Apr 2020 17:14:04 -0500
Subject: [PATCH 02/17] Makefile: Use parentheses around print args
Otherwise, this fails on python3.
Signed-off-by: Scott Wood <swood@redhat.com>
Signed-off-by: John Kacur <jkacur@redhat.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index f91e6e06a9a4..479bda8d8674 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ else
PYTHON = python2
endif
PACKAGE := rteval
-VERSION := $(shell $(PYTHON) -c "from rteval import RTEVAL_VERSION; print RTEVAL_VERSION")
+VERSION := $(shell $(PYTHON) -c "from rteval import RTEVAL_VERSION; print(RTEVAL_VERSION)")
D := 10
# XML-RPC related files
--
2.21.3
From 7aba0df2cc6072da955ee0ad8bf907dc10cec468 Mon Sep 17 00:00:00 2001
From: Scott Wood <swood@redhat.com>
Date: Mon, 6 Apr 2020 17:14:05 -0500
Subject: [PATCH 03/17] modules: Don't abort if a workload isn't running
Each module is responsible for respawning the load when it finishes. The
only thing that the additional check at the rtevalModulePrototype level
accomplishes is introducing a race condition that will kill rteval if a
load ends after _WorkloadTask() checks, but before the check in the
caller.
Signed-off-by: Scott Wood <swood@redhat.com>
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/modules/__init__.py | 3 ---
1 file changed, 3 deletions(-)
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
index 0feb8a916179..5ae7cd488406 100644
--- a/rteval/modules/__init__.py
+++ b/rteval/modules/__init__.py
@@ -189,9 +189,6 @@ class rtevalModulePrototype(threading.Thread):
if self.shouldStop():
break
- if not self.WorkloadAlive():
- self._log(Log.DEBUG, "%s workload stopped running." % self._module_type)
- break
time.sleep(self.__sleeptime)
self.__timestamps["runloop_stop"] = datetime.now()
--
2.21.3
From d136b8b29b0ec90f07d89dfd834e02f8f8e525b6 Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Mon, 15 Jun 2020 18:06:45 -0400
Subject: [PATCH 17/17] rteval: Add the stressng load module
Add the stressng load module to run stress-ng as a load to rteval
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval-cmd | 3 +-
rteval.conf | 1 +
rteval/modules/loads/stressng.py | 135 +++++++++++++++++++++++++++++++
rteval/rteval.conf | 3 +-
4 files changed, 140 insertions(+), 2 deletions(-)
create mode 100644 rteval/modules/loads/stressng.py
diff --git a/rteval-cmd b/rteval-cmd
index 7d0d00516bd3..bc6948699788 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -221,7 +221,8 @@ if __name__ == '__main__':
if not config.HasSection('loads'):
config.AppendConfig('loads', {
'kcompile' : 'module',
- 'hackbench' : 'module'})
+ 'hackbench' : 'module',
+ 'stressng' : 'module'})
if not config.HasSection('measurement'):
config.AppendConfig('measurement', {
diff --git a/rteval.conf b/rteval.conf
index 6b22b29943ee..4c32fcf4d842 100644
--- a/rteval.conf
+++ b/rteval.conf
@@ -11,3 +11,4 @@ cyclictest: module
[loads]
kcompile: module
hackbench: module
+stressng: module
diff --git a/rteval/modules/loads/stressng.py b/rteval/modules/loads/stressng.py
new file mode 100644
index 000000000000..e5edb51c4c44
--- /dev/null
+++ b/rteval/modules/loads/stressng.py
@@ -0,0 +1,135 @@
+""" Module containing class Stressng to manage stress-ng as an rteval load """
+import os
+import os.path
+import time
+import subprocess
+import signal
+from rteval.modules.loads import CommandLineLoad
+from rteval.Log import Log
+from rteval.misc import expand_cpulist
+from rteval.systopology import SysTopology
+
+class Stressng(CommandLineLoad):
+ " This class creates a load module that runs stress-ng "
+ def __init__(self, config, logger):
+ CommandLineLoad.__init__(self, "stressng", config, logger)
+ self.logger = logger
+ self.started = False
+ self.process = None
+ self.cfg = config
+ self.__in = None
+ self.__out = None
+ self.__err = None
+ self.__nullfp = None
+ self.cmd = None
+ " Only run this module if the user specifies an option "
+ if self.cfg.option is not None:
+ self._donotrun = False
+ else:
+ self._donotrun = True
+
+ def _WorkloadSetup(self):
+ " Since there is nothing to build, we don't need to do anything here "
+ return
+
+ def _WorkloadBuild(self):
+ " Nothing to build, so we are ready "
+ self._setReady()
+
+ def _WorkloadPrepare(self):
+ " Set-up logging "
+ self.__nullfp = os.open("/dev/null", os.O_RDWR)
+ self.__in = self.__nullfp
+ if self._logging:
+ self.__out = self.open_logfile("stressng.stdout")
+ self.__err = self.open_logfile("stressng.stderr")
+ else:
+ self.__out = self.__err = self.__nullfp
+
+ # stress-ng is only run if the user specifies an option
+ self.cmd = ['stress-ng']
+ self.cmd.append('--%s' % str(self.cfg.option))
+ if self.cfg.arg is not None:
+ self.cmd.append(self.cfg.arg)
+ if self.cfg.timeout is not None:
+ self.cmd.append('--timeout %s' % str(self.cfg.timeout))
+
+ systop = SysTopology()
+ # get the number of nodes
+ nodes = systop.getnodes()
+
+ # get the cpus for each node
+ cpus = {}
+ for n in nodes:
+ cpus[n] = systop.getcpus(int(n))
+ # if a cpulist was specified, only allow cpus in that list on the node
+ if self.cpulist:
+ cpus[n] = [c for c in cpus[n] if str(c) in expand_cpulist(self.cpulist)]
+
+ # remove nodes with no cpus available for running
+ for node, cpu in list(cpus.items()):
+ if not cpu:
+ nodes.remove(node)
+ self._log(Log.DEBUG, "node %s has no available cpus, removing" % node)
+ if self.cpulist:
+ for node in nodes:
+ cpulist = ",".join([str(n) for n in cpus[node]])
+ self.cmd.append('--taskset %s' % cpulist)
+
+ def _WorkloadTask(self):
+ """ Kick of the workload here """
+ if self.started:
+ # Only start the task once
+ return
+
+ self._log(Log.DEBUG, "starting with %s" % " ".join(self.cmd))
+ try:
+ self.process = subprocess.Popen(self.cmd,
+ stdout=self.__out,
+ stderr=self.__err,
+ stdin=self.__in)
+ self.started = True
+ self._log(Log.DEBUG, "running")
+ except OSError:
+ self._log(Log.DEBUG, "Failed to run")
+ self.started = False
+ return
+
+ def WorkloadAlive(self):
+ " Return true if stress-ng workload is alive "
+ if self.started:
+ return self.process.poll() is None
+ return False
+
+ def _WorkloadCleanup(self):
+ " Makesure to kill stress-ng before rteval ends "
+ if not self.started:
+ return
+ # poll() returns None if the process is still running
+ while self.process.poll() is None:
+ self._log(Log.DEBUG, "Sending SIGINT")
+ self.process.send_signal(signal.SIGINT)
+ time.sleep(2)
+ return
+
+
+def create(config, logger):
+ """ Create an instance of the Stressng class in stressng module """
+ return Stressng(config, logger)
+
+def ModuleParameters():
+ """ Commandline options for Stress-ng """
+ return {
+ "option": {
+ "descr": "stressor specific option",
+ "metavar": "OPTION"
+ },
+ "arg": {
+ "descr": "stressor specific arg",
+ "metavar" : "ARG"
+ },
+ "timeout": {
+ "descr": "timeout after T seconds",
+ "metavar" : "T"
+ },
+ }
diff --git a/rteval/rteval.conf b/rteval/rteval.conf
index 0d1afb30b754..db0b8ef005b6 100644
--- a/rteval/rteval.conf
+++ b/rteval/rteval.conf
@@ -15,9 +15,10 @@ priority: 95
kcompile: module
hackbench: module
dbench: external
+stressng: module
[kcompile]
-source: linux-2.6.39.tar.bz2
+source: linux-5.1.xz
jobspercore: 2
[hackbench]
--
2.21.3
From f65d46723cd0e2d3a9b1f788b0ffa51e7fd04f8b Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Thu, 23 May 2019 17:54:20 +0200
Subject: [PATCH 1/2] rteval: Check whether a cpu is online before adding it to
the list
Check whether a cpu is online before adding it to the list
If sys online files exist, use them to determine if a cpu is online
This is done in two places, misc.py, and also in systopology which is
getting the cpus from the numa node in /sys/devices, including offline
cpus
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/misc.py | 19 ++++++++++++++++++-
rteval/systopology.py | 29 ++++++++++++++++++++++++-----
2 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/rteval/misc.py b/rteval/misc.py
index 7c9991483728..a43a8964e061 100644
--- a/rteval/misc.py
+++ b/rteval/misc.py
@@ -36,7 +36,24 @@ def expand_cpulist(cpulist):
return [ str(i) for i in list(set(result)) ]
def online_cpus():
- return [ str(c.replace('/sys/devices/system/cpu/cpu', '')) for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*') ]
+ online_cpus = []
+ # Check for the online file with cpu1 since cpu0 can't always be offlined
+ if os.path.exists('/sys/devices/system/cpu/cpu1/online'):
+ for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*'):
+ num = str(c.replace('/sys/devices/system/cpu/cpu',''))
+ # On some machine you can't turn off cpu0
+ if not os.path.exists(c + '/online') and num == "0":
+ online_cpus.append(num)
+ else:
+ with open(c + '/online') as f:
+ is_online = f.read().rstrip('\n')
+ if is_online == "1":
+ online_cpus.append(num)
+ else: # use the old heuristic
+ for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*'):
+ num = str(c.replace('/sys/devices/system/cpu/cpu',''))
+ online_cpus.append(num)
+ return online_cpus
def invert_cpulist(cpulist):
return [ c for c in online_cpus() if c not in cpulist]
diff --git a/rteval/systopology.py b/rteval/systopology.py
index 97a6037e83aa..07674658df8e 100644
--- a/rteval/systopology.py
+++ b/rteval/systopology.py
@@ -45,6 +45,7 @@ class CpuList(object):
self.cpulist = cpulist
elif type(cpulist) is str:
self.cpulist = self.__expand_cpulist(cpulist)
+ self.cpulist = self.online_cpulist(self.cpulist)
self.cpulist.sort()
def __str__(self):
@@ -56,6 +57,10 @@ class CpuList(object):
def __len__(self):
return len(self.cpulist)
+ def online_file_exists(self):
+ if os.path.exists('/sys/devices/system/cpu/cpu1/online'):
+ return True
+ return False
# return the index of the last element of a sequence
# that steps by one
@@ -68,7 +73,6 @@ class CpuList(object):
return idx
return lim - 1
-
#
# collapse a list of cpu numbers into a string range
# of cpus (e.g. 0-5, 7, 9)
@@ -110,15 +114,30 @@ class CpuList(object):
return self.cpulist
# check whether cpu n is online
- def isonline(self, n):
+ def is_online(self, n):
if n not in self.cpulist:
raise RuntimeError("invalid cpu number %d" % n)
if n == 0:
return True
path = os.path.join(CpuList.cpupath,'cpu%d' % n)
- if os.path.exists(path):
- return sysread(path, "online") == 1
- return False
+ # Some hardware doesn't allow cpu0 to be turned off
+ if not os.path.exists(path + '/online') and n == 0:
+ return True
+ else:
+ return sysread(path, "online") == "1"
+
+ # Given a cpulist, return a cpulist of online cpus
+ def online_cpulist(self, cpulist):
+ # This only works if the sys online files exist
+ if not self.online_file_exists():
+ return cpulist
+ newlist = []
+ for cpu in cpulist:
+ if not self.online_file_exists() and cpu == '0':
+ newlist.append(cpu)
+ elif self.is_online(int(cpu)):
+ newlist.append(cpu)
+ return newlist
#
# class to abstract access to NUMA nodes in /sys filesystem
--
2.20.1
From 24efd8cf2fbde73636c4c8434447b0e04dc7a89a Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Tue, 19 Nov 2019 12:12:33 +0100
Subject: [PATCH] rteval: Don't assume cpu0 cannot be offlined, test it
Don't just assume that cpu0 cannot be offlined.
If the file /sys/devices/system/cpu/cpu0/online exists, then test the
value just like for every other cpu
However, if the file doesn't exist, that means that it cannot be
offlined.
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/systopology.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/rteval/systopology.py b/rteval/systopology.py
index 9556e51d96a2..7c3878e51be4 100644
--- a/rteval/systopology.py
+++ b/rteval/systopology.py
@@ -117,8 +117,6 @@ class CpuList(object):
def is_online(self, n):
if n not in self.cpulist:
raise RuntimeError("invalid cpu number %d" % n)
- if n == 0:
- return True
path = os.path.join(CpuList.cpupath,'cpu%d' % n)
# Some hardware doesn't allow cpu0 to be turned off
if not os.path.exists(path + '/online') and n == 0:
--
2.20.1
From 08c37d8d5b5476a9ecf128eebe9aed1c033b1b08 Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Thu, 27 Aug 2020 15:41:07 -0400
Subject: [PATCH] rteval: Parse cpuinfo correctly when model name has a colon
The function cpuinfo() splits fields in /proc/cpuinfo with a colon ':'
This can cause a
ValueError: too many values to unpack (expected 2)
This is easily fixed by setting the maximum number of splits to 1
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/misc.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/rteval/misc.py b/rteval/misc.py
index a43a8964e061..6184c9286f11 100644
--- a/rteval/misc.py
+++ b/rteval/misc.py
@@ -69,8 +69,10 @@ def cpuinfo():
info = {}
for l in open('/proc/cpuinfo'):
l = l.strip()
- if not l: continue
- key,val = [ i.strip() for i in l.split(':')]
+ if not l:
+ continue
+ # Split a maximum of one time. In case a model name has ':' in it
+ key, val = [i.strip() for i in l.split(':', 1)]
if key == 'processor':
core = val
info[core] = {}
--
2.26.2
From 0b45cccbe759c9f32bdf9903ed5a5f2a687692ee Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Wed, 24 Jun 2020 09:06:01 -0400
Subject: [PATCH] rteval: Rename self.cmd to self.args for inheritance in
stressng
Load modules inherits from CommandLineLoad
CommandLineLoad has a method MakeReport which relies on the variable
"args". Class Stressng needs to use this variable name instead of it's
own for this mechanism to work.
This commit changes the name in Stressng, but perhaps a better fix in
the future would be to use accessor methods, instead of relying on a
variable name
This commit also sets jobs to 1, which is required in MakeReport. The
actual number of jobs is handled by the external stress-ng program,
depending upon the arg that Class Stressng invokes it with.
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/modules/loads/stressng.py | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/rteval/modules/loads/stressng.py b/rteval/modules/loads/stressng.py
index e5edb51c4c44..926de38e3116 100644
--- a/rteval/modules/loads/stressng.py
+++ b/rteval/modules/loads/stressng.py
@@ -21,7 +21,7 @@ class Stressng(CommandLineLoad):
self.__out = None
self.__err = None
self.__nullfp = None
- self.cmd = None
+ self.args = None
" Only run this module if the user specifies an option "
if self.cfg.option is not None:
self._donotrun = False
@@ -47,12 +47,12 @@ class Stressng(CommandLineLoad):
self.__out = self.__err = self.__nullfp
# stress-ng is only run if the user specifies an option
- self.cmd = ['stress-ng']
- self.cmd.append('--%s' % str(self.cfg.option))
+ self.args = ['stress-ng']
+ self.args.append('--%s' % str(self.cfg.option))
if self.cfg.arg is not None:
- self.cmd.append(self.cfg.arg)
+ self.args.append(self.cfg.arg)
if self.cfg.timeout is not None:
- self.cmd.append('--timeout %s' % str(self.cfg.timeout))
+ self.args.append('--timeout %s' % str(self.cfg.timeout))
systop = SysTopology()
# get the number of nodes
@@ -74,7 +74,7 @@ class Stressng(CommandLineLoad):
if self.cpulist:
for node in nodes:
cpulist = ",".join([str(n) for n in cpus[node]])
- self.cmd.append('--taskset %s' % cpulist)
+ self.args.append('--taskset %s' % cpulist)
def _WorkloadTask(self):
""" Kick of the workload here """
@@ -82,13 +82,14 @@ class Stressng(CommandLineLoad):
# Only start the task once
return
- self._log(Log.DEBUG, "starting with %s" % " ".join(self.cmd))
+ self._log(Log.DEBUG, "starting with %s" % " ".join(self.args))
try:
- self.process = subprocess.Popen(self.cmd,
+ self.process = subprocess.Popen(self.args,
stdout=self.__out,
stderr=self.__err,
stdin=self.__in)
self.started = True
+ self.jobs = 1
self._log(Log.DEBUG, "running")
except OSError:
self._log(Log.DEBUG, "Failed to run")
--
2.21.3
From c6aac7eac1625c537f2517af3d3baf0ad5b8a2c4 Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Wed, 6 May 2020 03:56:10 -0400
Subject: [PATCH 12/17] rteval: Some style changes to
rteval/modules/measurement/__init__.py
rteval: Some style changes to rteval/modules/measurement/__init__.py
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/modules/measurement/__init__.py | 12 ++++++------