diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..05be9b3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/tuned-2.10.0.tar.gz
diff --git a/.tuned.metadata b/.tuned.metadata
new file mode 100644
index 0000000..8c2c6b0
--- /dev/null
+++ b/.tuned.metadata
@@ -0,0 +1 @@
+24ecb366bf503d8f6a79ced3f8faf239c81ad8cf SOURCES/tuned-2.10.0.tar.gz
diff --git a/SOURCES/0001-Make-python-dmidecode-a-weak-dependency.patch b/SOURCES/0001-Make-python-dmidecode-a-weak-dependency.patch
new file mode 100644
index 0000000..6351d3b
--- /dev/null
+++ b/SOURCES/0001-Make-python-dmidecode-a-weak-dependency.patch
@@ -0,0 +1,76 @@
+From df1ce7287ad373694193d79a7843e4e054d40848 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Wed, 10 Oct 2018 14:26:51 +0200
+Subject: [PATCH] Make python-dmidecode a weak dependency
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's only available on x86_64.
+
+Resolves: rhbz#1565598
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned.spec              |  4 ++--
+ tuned/utils/commands.py | 19 +++++++++++++------
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/tuned.spec b/tuned.spec
+index 3bf0db2..9cd74e1 100644
+--- a/tuned.spec
++++ b/tuned.spec
+@@ -57,10 +57,10 @@ Requires: %{_py}-schedutils, %{_py}-linux-procfs, %{_py}-perf
+ # requires for packages with inconsistent python2/3 names
+ %if %{with python3}
+ Requires: python3-dbus, python3-gobject-base
+-Requires: python3-dmidecode
++Recommends: python3-dmidecode
+ %else
+ Requires: dbus-python, pygobject3-base
+-Requires: python-dmidecode
++Recommends: python-dmidecode
+ %endif
+ Requires: virt-what, ethtool, gawk, hdparm
+ Requires: util-linux, dbus, polkit
+diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
+index 9634709..5692450 100644
+--- a/tuned/utils/commands.py
++++ b/tuned/utils/commands.py
+@@ -9,7 +9,11 @@ import re
+ import procfs
+ from subprocess import *
+ from tuned.exceptions import TunedException
+-import dmidecode
++try:
++	import dmidecode
++	have_dmidecode = True
++except:
++	have_dmidecode = False
+ try:
+ 	import syspurpose.files
+ 	have_syspurpose = True
+@@ -420,12 +424,15 @@ class commands:
+ 						if len(ps.find_by_regex(re.compile(value))) == 0:
+ 							match = False
+ 					elif option == "chassis_type":
+-						for chassis in dmidecode.chassis().values():
+-							chassis_type = chassis["data"]["Type"].decode("ascii")
+-							if re.match(value, chassis_type, re.IGNORECASE):
+-								break
++						if have_dmidecode:
++							for chassis in dmidecode.chassis().values():
++								chassis_type = chassis["data"]["Type"].decode("ascii")
++								if re.match(value, chassis_type, re.IGNORECASE):
++									break
++							else:
++								match = False
+ 						else:
+-							match = False
++							log.debug("Ignoring 'chassis_type' in '%s', dmidecode is not available." % fname)
+ 					elif option == "syspurpose_role":
+ 						if have_syspurpose:
+ 							s = syspurpose.files.SyspurposeStore(
+-- 
+2.17.1
+
diff --git a/SOURCES/0001-Support-chassis-type-matching-in-recommend.conf.patch b/SOURCES/0001-Support-chassis-type-matching-in-recommend.conf.patch
new file mode 100644
index 0000000..49b92d8
--- /dev/null
+++ b/SOURCES/0001-Support-chassis-type-matching-in-recommend.conf.patch
@@ -0,0 +1,75 @@
+From 469a86250168ab51287b2e2c3d88efc1c8edec7e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Tue, 7 Aug 2018 17:07:49 +0200
+Subject: [PATCH 1/2] Support chassis type matching in recommend.conf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resolves: rhbz#1565598
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ Makefile                | 4 +++-
+ tuned.spec              | 2 ++
+ tuned/utils/commands.py | 8 ++++++++
+ 3 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index f302db1..816fcb1 100644
+--- a/Makefile
++++ b/Makefile
+@@ -212,6 +212,8 @@ test:
+ 	$(PYTHON) -m unittest discover tests
+ 
+ lint:
+-	$(PYLINT) -E -f parseable tuned *.py
++	# --ignore commands.py is a workaround for
++	# https://bugzilla.redhat.com/show_bug.cgi?id=1613466
++	$(PYLINT) --ignore commands.py -E -f parseable tuned *.py
+ 
+ .PHONY: clean archive srpm tag test lint
+diff --git a/tuned.spec b/tuned.spec
+index ed4c4f0..2b4f039 100644
+--- a/tuned.spec
++++ b/tuned.spec
+@@ -57,8 +57,10 @@ Requires: %{_py}-schedutils, %{_py}-linux-procfs, %{_py}-perf
+ # requires for packages with inconsistent python2/3 names
+ %if %{with python3}
+ Requires: python3-dbus, python3-gobject-base
++Requires: python3-dmidecode
+ %else
+ Requires: dbus-python, pygobject3-base
++Requires: python-dmidecode
+ %endif
+ Requires: virt-what, ethtool, gawk, hdparm
+ Requires: util-linux, dbus, polkit
+diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
+index 41d6d99..8bb31a3 100644
+--- a/tuned/utils/commands.py
++++ b/tuned/utils/commands.py
+@@ -9,6 +9,7 @@ import re
+ import procfs
+ from subprocess import *
+ from tuned.exceptions import TunedException
++import dmidecode
+ 
+ log = tuned.logs.get()
+ 
+@@ -413,6 +414,13 @@ class commands:
+ 						ps.reload_threads()
+ 						if len(ps.find_by_regex(re.compile(value))) == 0:
+ 							match = False
++					elif option == "chassis_type":
++						for chassis in dmidecode.chassis().values():
++							chassis_type = chassis["data"]["Type"].decode("ascii")
++							if re.match(value, chassis_type, re.IGNORECASE):
++								break
++						else:
++							match = False
+ 				if match:
+ 					# remove the ",.*" suffix
+ 					r = re.compile(r",[^,]*$")
+-- 
+2.17.1
+
diff --git a/SOURCES/0001-plugin_disk-Fix-checking-the-removable-attribute-on-.patch b/SOURCES/0001-plugin_disk-Fix-checking-the-removable-attribute-on-.patch
new file mode 100644
index 0000000..49ce5ab
--- /dev/null
+++ b/SOURCES/0001-plugin_disk-Fix-checking-the-removable-attribute-on-.patch
@@ -0,0 +1,35 @@
+From 2cc3d747986837d7e7957f5a4baede2dd691348a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Thu, 24 Jan 2019 16:28:24 +0100
+Subject: [PATCH] plugin_disk: Fix checking the 'removable' attribute on
+ python3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The 'removable' attribute is a bytestring, so it will never be equal to
+"0" in python3. Check equality with b"0" instead.
+
+The patch was originally written by Tomáš Korbař.
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned/plugins/plugin_disk.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tuned/plugins/plugin_disk.py b/tuned/plugins/plugin_disk.py
+index 1de1257..65504d8 100644
+--- a/tuned/plugins/plugin_disk.py
++++ b/tuned/plugins/plugin_disk.py
+@@ -39,7 +39,7 @@ class DiskPlugin(hotplug.Plugin):
+ 	@classmethod
+ 	def _device_is_supported(cls, device):
+ 		return  device.device_type == "disk" and \
+-			device.attributes.get("removable", None) == "0" and \
++			device.attributes.get("removable", None) == b"0" and \
+ 			(device.parent is None or \
+ 					device.parent.subsystem in ["scsi", "virtio", "xen"])
+ 
+-- 
+2.20.1
+
diff --git a/SOURCES/0001-scheduler-Keep-polling-file-objects-alive-long-enoug.patch b/SOURCES/0001-scheduler-Keep-polling-file-objects-alive-long-enoug.patch
new file mode 100644
index 0000000..9b4d661
--- /dev/null
+++ b/SOURCES/0001-scheduler-Keep-polling-file-objects-alive-long-enoug.patch
@@ -0,0 +1,39 @@
+From a54b35c3b0c3b228eb924ed4ebfb964eead86cca Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Fri, 14 Dec 2018 13:13:58 +0100
+Subject: [PATCH] scheduler: Keep polling file objects alive long enough
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Make sure the file objects returned by evlist.get_pollfd()
+don't go out of scope and get destroyed too soon. This is
+a workaround for python3-perf rhbz#1659445.
+
+Resolves: rhbz#1659140
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned/plugins/plugin_scheduler.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tuned/plugins/plugin_scheduler.py b/tuned/plugins/plugin_scheduler.py
+index 93b6d91..22e49d3 100644
+--- a/tuned/plugins/plugin_scheduler.py
++++ b/tuned/plugins/plugin_scheduler.py
+@@ -448,7 +448,11 @@ class SchedulerPlugin(base.Plugin):
+ 	def _thread_code(self, instance):
+ 		r = self._cmd.re_lookup_compile(instance._sched_lookup)
+ 		poll = select.poll()
+-		for fd in instance._evlist.get_pollfd():
++		# Store the file objects in a local variable so that they don't
++		# go out of scope too soon. This is a workaround for
++		# python3-perf bug rhbz#1659445.
++		fds = instance._evlist.get_pollfd()
++		for fd in fds:
+ 			poll.register(fd)
+ 		while not instance._terminate.is_set():
+ 			# timeout to poll in milliseconds
+-- 
+2.17.2
+
diff --git a/SOURCES/0001-tuned-adm-Fix-a-traceback-when-run-without-action-sp.patch b/SOURCES/0001-tuned-adm-Fix-a-traceback-when-run-without-action-sp.patch
new file mode 100644
index 0000000..208e24f
--- /dev/null
+++ b/SOURCES/0001-tuned-adm-Fix-a-traceback-when-run-without-action-sp.patch
@@ -0,0 +1,38 @@
+From 6678c472abbd5f645dbb99ab2946c0e35ded7499 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Tue, 10 Jul 2018 00:24:00 +0200
+Subject: [PATCH] tuned-adm: Fix a traceback when run without action specified
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Running tuned-adm without an action specified using Python 3 results
+in a traceback. This is because in this case parse_args does not
+exit with a usage message in Python 3 and the 'action' option
+is then undefined.
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned-adm.py | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tuned-adm.py b/tuned-adm.py
+index 1b9623d..1df8cc3 100755
+--- a/tuned-adm.py
++++ b/tuned-adm.py
+@@ -100,7 +100,11 @@ if __name__ == "__main__":
+ 	debug = options.pop("debug")
+ 	asynco = options.pop("async")
+ 	timeout = options.pop("timeout")
+-	action_name = options.pop("action")
++	try:
++		action_name = options.pop("action")
++	except KeyError:
++		parser.print_usage(file = sys.stderr)
++		sys.exit(1)
+ 	log_level = options.pop("loglevel")
+ 	result = False
+ 
+-- 
+2.14.4
+
diff --git a/SOURCES/0001-tuned-gui-Sort-plugins-based-on-their-name.patch b/SOURCES/0001-tuned-gui-Sort-plugins-based-on-their-name.patch
new file mode 100644
index 0000000..c2d146d
--- /dev/null
+++ b/SOURCES/0001-tuned-gui-Sort-plugins-based-on-their-name.patch
@@ -0,0 +1,35 @@
+From d46834808c3226b3a6e48649df65befc399c21cd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Wed, 11 Jul 2018 00:41:45 +0200
+Subject: [PATCH] tuned-gui: Sort plugins based on their name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously the sorting was done by comparing the objects themselves,
+which is not what we want and it doesn't work in Python 3 - TypeError
+is raised, e.g:
+TypeError: '<' not supported between instances of 'BootloaderPlugin' and 'MountsPlugin'
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned-gui.py | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tuned-gui.py b/tuned-gui.py
+index 8f72fd5..e486687 100755
+--- a/tuned-gui.py
++++ b/tuned-gui.py
+@@ -278,7 +278,8 @@ class Base(object):
+ 		self.treestore_profiles = Gtk.ListStore(GObject.TYPE_STRING,
+ 				GObject.TYPE_STRING)
+ 		self.treestore_plugins = Gtk.ListStore(GObject.TYPE_STRING)
+-		for plugin in sorted(self.plugin_loader.plugins):
++		for plugin in sorted(self.plugin_loader.plugins,
++				key = lambda plugin: plugin.name):
+ 			self.treestore_plugins.append([plugin.name])
+ 		self.combobox_plugins = \
+ 			self.builder.get_object('comboboxPlugins')
+-- 
+2.14.4
+
diff --git a/SOURCES/0002-Support-syspurpose-role-matching-in-recommend.conf.patch b/SOURCES/0002-Support-syspurpose-role-matching-in-recommend.conf.patch
new file mode 100644
index 0000000..317aca4
--- /dev/null
+++ b/SOURCES/0002-Support-syspurpose-role-matching-in-recommend.conf.patch
@@ -0,0 +1,73 @@
+From 9efd6d77283324ed8b8802431522a7a4eabd9aa0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Fri, 10 Aug 2018 16:17:47 +0200
+Subject: [PATCH 2/2] Support syspurpose role matching in recommend.conf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resolves: rhbz#1565598
+
+Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
+---
+ tuned.spec              |  3 +++
+ tuned/utils/commands.py | 22 ++++++++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/tuned.spec b/tuned.spec
+index 2b4f039..3bf0db2 100644
+--- a/tuned.spec
++++ b/tuned.spec
+@@ -67,6 +67,9 @@ Requires: util-linux, dbus, polkit
+ %if 0%{?fedora} > 22 || 0%{?rhel} > 7
+ Recommends: kernel-tools
+ %endif
++%if 0%{?rhel} > 7
++Requires: python3-syspurpose
++%endif
+ 
+ %description
+ The tuned package contains a daemon that tunes system settings dynamically.
+diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
+index 8bb31a3..9a81baf 100644
+--- a/tuned/utils/commands.py
++++ b/tuned/utils/commands.py
+@@ -10,6 +10,11 @@ import procfs
+ from subprocess import *
+ from tuned.exceptions import TunedException
+ import dmidecode
++try:
++	import syspurpose.files
++	have_syspurpose = True
++except:
++	have_syspurpose = False
+ 
+ log = tuned.logs.get()
+ 
+@@ -421,6 +426,23 @@ class commands:
+ 								break
+ 						else:
+ 							match = False
++					elif option == "syspurpose_role":
++						if have_syspurpose:
++							s = syspurpose.files.SyspurposeStore(
++									syspurpose.files.USER_SYSPURPOSE,
++									raise_on_error = True)
++							role = ""
++							try:
++								s.read_file()
++								role = s.contents["role"]
++							except (IOError, OSError, KeyError) as e:
++								if hasattr(e, "errno") and e.errno != errno.ENOENT:
++									log.error("Failed to load the syspurpose file: %s" % e)
++							if re.match(value, role, re.IGNORECASE) is None:
++								match = False
++						else:
++							log.error("Failed to process 'syspurpose_role' in '%s', the syspurpose module is not available" % fname)
++
+ 				if match:
+ 					# remove the ",.*" suffix
+ 					r = re.compile(r",[^,]*$")
+-- 
+2.17.1
+
diff --git a/SOURCES/recommend.conf b/SOURCES/recommend.conf
new file mode 100644
index 0000000..9c0b046
--- /dev/null
+++ b/SOURCES/recommend.conf
@@ -0,0 +1,61 @@
+# Tuned rules for recommend_profile.
+#
+# Syntax:
+# [PROFILE1]
+# KEYWORD11=RE11
+# KEYWORD21=RE12
+#
+# [PROFILE2]
+# KEYWORD21=RE21
+# KEYWORD22=RE22
+
+# KEYWORD can be:
+# virt            - for RE to match output of virt-what
+# system          - for RE to match content of /etc/system-release-cpe
+# process         - for RE to match running processes. It can have arbitrary
+#                   suffix, all process* lines have to match for the PROFILE
+#                   to match (i.e. the AND operator)
+# /FILE           - for RE to match content of the FILE, e.g.:
+#                   '/etc/passwd=.+'. If file doesn't exist, its RE will not
+#                   match.
+# chassis_type    - for RE to match the chassis type as reported by dmidecode
+# syspurpose_role - for RE to match the system role as reported by syspurpose
+
+# All REs for all KEYWORDs have to match for PROFILE to match (i.e. the AND operator).
+# If 'virt' or 'system' is not specified, it matches for every string.
+# If 'virt' or 'system' is empty, i.e. 'virt=', it matches only empty string (alias for '^$').
+# If several profiles matched, the first match is taken.
+#
+# Limitation:
+# Each profile can be specified only once, because there cannot be
+# multiple sections in the configuration file with the same name
+# (ConfigObj limitation).
+# If there is a need to specify the profile multiple times, unique
+# suffix like ',ANYSTRING' can be used. Everything after the last ','
+# is stripped by the parser, e.g.:
+#
+# [balanced,1]
+# /FILE1=RE1
+#
+# [balanced,2]
+# /FILE2=RE2
+#
+# This will set 'balanced' profile in case there is FILE1 matching RE1 or
+# FILE2 matching RE2 or both.
+
+[atomic-host]
+virt=
+syspurpose_role=.*atomic.*
+
+[atomic-guest]
+virt=.+
+syspurpose_role=.*atomic.*
+
+[virtual-guest]
+virt=.+
+
+[balanced]
+syspurpose_role=.*(desktop|workstation).*
+chassis_type=.*(Notebook|Laptop|Portable).*
+
+[throughput-performance]
diff --git a/SOURCES/tuned-2.10.0-add-support-for-bls.patch b/SOURCES/tuned-2.10.0-add-support-for-bls.patch
new file mode 100644
index 0000000..ec8311b
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-add-support-for-bls.patch
@@ -0,0 +1,275 @@
+From 731070a68e54e01015b520e2c19141a912923218 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
+Date: Sun, 9 Dec 2018 20:16:50 +0100
+Subject: [PATCH] Added support for Boot loader specification (BLS)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resolves: rhbz#1576435
+
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ 91-tuned.install                   | 31 ++++++++++++++++++++++
+ Makefile                           |  6 ++++-
+ tuned.spec                         | 19 ++++++++++++++
+ tuned/consts.py                    |  3 +++
+ tuned/plugins/plugin_bootloader.py | 41 +++++++++++++++++++++++++++---
+ tuned/utils/commands.py            | 15 ++++++-----
+ 6 files changed, 104 insertions(+), 11 deletions(-)
+ create mode 100644 91-tuned.install
+
+diff --git a/91-tuned.install b/91-tuned.install
+new file mode 100644
+index 0000000..18d00d9
+--- /dev/null
++++ b/91-tuned.install
+@@ -0,0 +1,31 @@
++#!/bin/bash
++
++COMMAND="$1"
++KERNEL_VERSION="$2"
++BOOT_DIR_ABS="$3"
++KERNEL_IMAGE="$4"
++
++if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
++  exit 0
++fi
++
++MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
++
++# with grub2 always /boot
++BOOT_ROOT="/boot"
++LOADER_ENTRIES="$BOOT_ROOT/loader/entries"
++
++[ -d "$LOADER_ENTRIES" ] || exit 0
++
++[ "$COMMAND" = "add" ] || exit 0
++
++pushd "$LOADER_ENTRIES"
++for f in `basename "$MACHINE_ID"`-*.conf; do
++  if [ -f "$f" -a "${f: -12}" != "-rescue.conf" ]; then
++    grep -q '^\s*options\s\+.*\$tuned_params' "$f" || sed -i '/^\s*options\s\+/ s/\(.*\)/\1 \$tuned_params/' "$f"
++    grep -q '^\s*initrd\s\+.*\$tuned_initrd' "$f" || sed -i '/^\s*initrd\s\+/ s/\(.*\)/\1 \$tuned_initrd/' "$f"
++  fi
++done
++popd
++
++exit 0
+diff --git a/Makefile b/Makefile
+index 816fcb1..f61cd01 100644
+--- a/Makefile
++++ b/Makefile
+@@ -40,6 +40,7 @@ PYTHON_SITELIB = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_pytho
+ ifeq ($(PYTHON_SITELIB),)
+ $(error Failed to determine python library directory)
+ endif
++KERNELINSTALLHOOKDIR = /usr/lib/kernel/install.d
+ TUNED_PROFILESDIR = /usr/lib/tuned
+ TUNED_RECOMMEND_DIR = $(TUNED_PROFILESDIR)/recommend.d
+ TUNED_USER_RECOMMEND_DIR = $(SYSCONFDIR)/tuned/recommend.d
+@@ -59,7 +60,7 @@ release-cp: release-dir
+ 
+ 	cp -a tuned.py tuned.spec tuned.service tuned.tmpfiles Makefile tuned-adm.py \
+ 		tuned-adm.bash dbus.conf recommend.conf tuned-main.conf 00_tuned \
+-		bootcmdline modules.conf com.redhat.tuned.policy \
++		91-tuned.install bootcmdline modules.conf com.redhat.tuned.policy \
+ 		com.redhat.tuned.gui.policy tuned-gui.py tuned-gui.glade \
+ 		tuned-gui.desktop $(VERSIONED_NAME)
+ 	cp -a doc experiments libexec man profiles systemtap tuned contrib icons \
+@@ -180,6 +181,9 @@ install: install-dirs
+ 	# grub template
+ 	install -Dpm 0755 00_tuned $(DESTDIR)$(SYSCONFDIR)/grub.d/00_tuned
+ 
++	# kernel install hook
++	install -Dpm 0755 91-tuned.install $(DESTDIR)$(KERNELINSTALLHOOKDIR)/91-tuned.install
++
+ 	# polkit configuration
+ 	install -Dpm 0644 com.redhat.tuned.policy $(DESTDIR)$(DATADIR)/polkit-1/actions/com.redhat.tuned.policy
+ 	install -Dpm 0644 com.redhat.tuned.gui.policy $(DESTDIR)$(DATADIR)/polkit-1/actions/com.redhat.tuned.gui.policy
+diff --git a/tuned.spec b/tuned.spec
+index 1ecf320..b7ee60d 100644
+--- a/tuned.spec
++++ b/tuned.spec
+@@ -278,6 +278,24 @@ if [ "$1" == 0 ]; then
+   if [ -r "%{_sysconfdir}/default/grub" ]; then
+     sed -i '/GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:+$GRUB_CMDLINE_LINUX_DEFAULT }\\$tuned_params"/d' %{_sysconfdir}/default/grub
+   fi
++
++# cleanup for Boot loader specification (BLS)
++
++# clear grubenv variables
++  grub2-editenv - unset tuned_params tuned_initrd &>/dev/null || :
++# unpatch BLS entries
++  MACHINE_ID=`cat /etc/machine-id 2>/dev/null`
++  if [ "$MACHINE_ID" ]
++  then
++    for f in /boot/loader/entries/$MACHINE_ID-*.conf
++    do
++      if [ -f "$f" -a "${f: -12}" != "-rescue.conf" ]
++      then
++        sed -i '/^\s*options\s\+.*\$tuned_params/ s/\s\+\$tuned_params\b//g' "$f" &>/dev/null || :
++        sed -i '/^\s*initrd\s\+.*\$tuned_initrd/ s/\s\+\$tuned_initrd\b//g' "$f" &>/dev/null || :
++      fi
++    done
++  fi
+ fi
+ 
+ 
+@@ -374,6 +392,7 @@ fi
+ %{_datadir}/tuned/grub2
+ %{_datadir}/polkit-1/actions/com.redhat.tuned.policy
+ %ghost %{_sysconfdir}/modprobe.d/kvm.rt.tuned.conf
++%{_prefix}/lib/kernel/install.d/91-tuned.install
+ 
+ %files gtk
+ %defattr(-,root,root,-)
+diff --git a/tuned/consts.py b/tuned/consts.py
+index ab87c70..de94059 100644
+--- a/tuned/consts.py
++++ b/tuned/consts.py
+@@ -37,6 +37,9 @@ BOOT_CMDLINE_TUNED_VAR = "TUNED_BOOT_CMDLINE"
+ BOOT_CMDLINE_INITRD_ADD_VAR = "TUNED_BOOT_INITRD_ADD"
+ BOOT_CMDLINE_FILE = "/etc/tuned/bootcmdline"
+ PETITBOOT_DETECT_DIR = "/sys/firmware/opal"
++MACHINE_ID_FILE = "/etc/machine-id"
++KERNEL_UPDATE_HOOK_FILE = "/usr/lib/kernel/install.d/91-tuned.install"
++BLS_ENTRIES_PATH = "/boot/loader/entries"
+ 
+ # modules plugin configuration
+ MODULES_FILE = "/etc/modprobe.d/tuned.conf"
+diff --git a/tuned/plugins/plugin_bootloader.py b/tuned/plugins/plugin_bootloader.py
+index d88b62c..400b07e 100644
+--- a/tuned/plugins/plugin_bootloader.py
++++ b/tuned/plugins/plugin_bootloader.py
+@@ -94,7 +94,7 @@ class BootloaderPlugin(base.Plugin):
+ 
+ 	def _remove_grub2_tuning(self):
+ 		if not self._grub2_cfg_file_names:
+-			log.error("cannot find grub.cfg to patch, you need to regenerate it by hand using grub2-mkconfig")
++			log.info("cannot find grub.cfg to patch")
+ 			return
+ 		self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR : "", consts.BOOT_CMDLINE_INITRD_ADD_VAR : ""})
+ 		for f in self._grub2_cfg_file_names:
+@@ -107,6 +107,7 @@ class BootloaderPlugin(base.Plugin):
+ 		if full_rollback:
+ 			log.info("removing grub2 tuning previously added by Tuned")
+ 			self._remove_grub2_tuning()
++			self._update_grubenv({"tuned_params" : "", "tuned_initrd" : ""})
+ 
+ 	def _grub2_cfg_unpatch(self, grub2_cfg):
+ 		log.debug("unpatching grub.cfg")
+@@ -138,7 +139,7 @@ class BootloaderPlugin(base.Plugin):
+ 	def _grub2_default_env_patch(self):
+ 		grub2_default_env = self._cmd.read_file(consts.GRUB2_DEFAULT_ENV_FILE)
+ 		if len(grub2_default_env) <= 0:
+-			log.error("error reading '%s'" % consts.GRUB2_DEFAULT_ENV_FILE)
++			log.info("cannot read '%s'" % consts.GRUB2_DEFAULT_ENV_FILE)
+ 			return False
+ 
+ 		d = {"GRUB_CMDLINE_LINUX_DEFAULT" : consts.GRUB2_TUNED_VAR, "GRUB_INITRD_OVERLAY" : consts.GRUB2_TUNED_INITRD_VAR}
+@@ -157,12 +158,12 @@ class BootloaderPlugin(base.Plugin):
+ 	def _grub2_cfg_patch(self, d):
+ 		log.debug("patching grub.cfg")
+ 		if not self._grub2_cfg_file_names:
+-			log.error("cannot find grub.cfg to patch, you need to regenerate it by hand by grub2-mkconfig")
++			log.info("cannot find grub.cfg to patch")
+ 			return False
+ 		for f in self._grub2_cfg_file_names:
+ 			grub2_cfg = self._cmd.read_file(f)
+ 			if len(grub2_cfg) <= 0:
+-				log.error("error patching %s, you need to regenerate it by hand by grub2-mkconfig" % f)
++				log.info("cannot patch %s" % f)
+ 				return False
+ 			log.debug("adding boot command line parameters to '%s'" % f)
+ 			grub2_cfg_new = grub2_cfg
+@@ -187,6 +188,37 @@ class BootloaderPlugin(base.Plugin):
+ 		self._grub2_cfg_patch({consts.GRUB2_TUNED_VAR : self._cmdline_val, consts.GRUB2_TUNED_INITRD_VAR : self._initrd_val})
+ 		self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR : self._cmdline_val, consts.BOOT_CMDLINE_INITRD_ADD_VAR : self._initrd_val})
+ 
++	def _has_bls(self):
++		return os.path.exists(consts.BLS_ENTRIES_PATH)
++
++	def _update_grubenv(self, d):
++		log.debug("updating grubenv, setting %s" % str(d));
++		l = ["%s=%s" % (str(option), str(value)) for option, value in d.items()]
++		(rc, out) = self._cmd.execute(["grub2-editenv", "-", "set"] + l)
++		if rc != 0:
++			log.warn("cannot update grubenv: '%s'" % out)
++			return False;
++		return True
++
++	def _bls_entries_patch_initial(self):
++		machine_id = self._cmd.get_machine_id()
++		if machine_id == "":
++			return False
++		log.debug("running kernel update hook '%s' to patch BLS entries" % consts.KERNEL_UPDATE_HOOK_FILE)
++		(rc, out) = self._cmd.execute([consts.KERNEL_UPDATE_HOOK_FILE, "add"], env = {"KERNEL_INSTALL_MACHINE_ID" : machine_id})
++		if rc != 0:
++			log.warn("cannot patch BLS entries: '%s'" % out)
++			return False
++		return True
++
++	def _bls_update(self):
++		log.debug("updating BLS")
++		if self._has_bls() and \
++			self._update_grubenv({"tuned_params" : self._cmdline_val, "tuned_initrd" : self._initrd_val}) and \
++			self._bls_entries_patch_initial():
++				return True
++		return False
++
+ 	def _init_initrd_dst_img(self, name):
+ 		if self._initrd_dst_img_val is None:
+ 			self._initrd_dst_img_val = os.path.join(consts.BOOT_DIR, os.path.basename(name))
+@@ -307,4 +339,5 @@ class BootloaderPlugin(base.Plugin):
+ 	def _instance_post_static(self, instance, enabling):
+ 		if enabling and self.update_grub2_cfg:
+ 			self._grub2_update()
++			self._bls_update()
+ 			self.update_grub2_cfg = False
+diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
+index 5692450..68d2ea5 100644
+--- a/tuned/utils/commands.py
++++ b/tuned/utils/commands.py
+@@ -25,7 +25,6 @@ log = tuned.logs.get()
+ class commands:
+ 
+ 	def __init__(self, logging = True):
+-		self._environment = None
+ 		self._logging = logging
+ 
+ 	def _error(self, msg):
+@@ -208,21 +207,25 @@ class commands:
+ 
+ 		return self.write_to_file(f, data)
+ 
++	# returns machine ID or empty string "" in case of error
++	def get_machine_id(self, no_error = True):
++		return self.read_file(consts.MACHINE_ID_FILE, no_error).strip()
++
+ 	# "no_errors" can be list of return codes not treated as errors, if 0 is in no_errors, it means any error
+ 	# returns (retcode, out), where retcode is exit code of the executed process or -errno if
+ 	# OSError or IOError exception happened
+-	def execute(self, args, shell = False, cwd = None, no_errors = [], return_err = False):
++	def execute(self, args, shell = False, cwd = None, env = {}, no_errors = [], return_err = False):
+ 		retcode = 0
+-		if self._environment is None:
+-			self._environment = os.environ.copy()
+-			self._environment["LC_ALL"] = "C"
++		_environment = os.environ.copy()
++		_environment["LC_ALL"] = "C"
++		_environment.update(env)
+ 
+ 		self._debug("Executing %s." % str(args))
+ 		out = ""
+ 		err_msg = None
+ 		try:
+ 			proc = Popen(args, stdout = PIPE, stderr = PIPE, \
+-					env = self._environment, \
++					env = _environment, \
+ 					shell = shell, cwd = cwd, \
+ 					close_fds = True, \
+ 					universal_newlines = True)
+-- 
+2.17.2
+
diff --git a/SOURCES/tuned-2.10.0-disable-ksm-once.patch b/SOURCES/tuned-2.10.0-disable-ksm-once.patch
new file mode 100644
index 0000000..a35883d
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-disable-ksm-once.patch
@@ -0,0 +1,84 @@
+diff --git a/profiles/cpu-partitioning/script.sh b/profiles/cpu-partitioning/script.sh
+index 0e94d3a..efe9bcb 100755
+--- a/profiles/cpu-partitioning/script.sh
++++ b/profiles/cpu-partitioning/script.sh
+@@ -54,8 +54,8 @@ stop() {
+     then
+         sed -i '/^IRQBALANCE_BANNED_CPUS=/d' /etc/sysconfig/irqbalance
+         teardown_kvm_mod_low_latency
++        enable_ksm
+     fi
+-    enable_ksm
+     enable_balance_domains
+     return "$?"
+ }
+diff --git a/profiles/functions b/profiles/functions
+index 1ed0120..aab608a 100644
+--- a/profiles/functions
++++ b/profiles/functions
+@@ -531,35 +531,30 @@ setup_kvm_mod_low_latency()
+ 
+ KSM_SERVICES="ksm ksmtuned"
+ KSM_RUN_PATH=/sys/kernel/mm/ksm/run
++KSM_MASK_FILE="${STORAGE_PERSISTENT}/ksm-masked"
+ 
+ disable_ksm()
+ {
+-	for s in $KSM_SERVICES; do
+-		if systemctl is-enabled -q $s; then
+-			systemctl -q disable $s
++	if [ ! -f $KSM_MASK_FILE ]; then
++		# Always create $KSM_MASK_FILE, since we don't want to
++		# run any systemctl commands during boot
++		if ! touch $KSM_MASK_FILE; then
++			die "failed to create $KSM_MASK_FILE"
+ 		fi
+-
+-		if systemctl is-active -q $s; then
+-			systemctl -q stop $s
+-		fi
+-	done
+-
+-	if [ -f $KSM_RUN_PATH ]; then
++		systemctl --now --quiet mask $KSM_SERVICES
+ 		# Unmerge all shared pages
+-		echo 2 > $KSM_RUN_PATH
++		test -f $KSM_RUN_PATH && echo 2 > $KSM_RUN_PATH
+ 	fi
+ }
+ 
++# Should only be called when full_rollback == true
+ enable_ksm()
+ {
+-	for s in $KSM_SERVICES; do
+-		systemctl -q preset $s
+-
+-		# Only start the service if it's enabled by defaut
+-		if systemctl is-enabled -q $s; then
+-			systemctl start $s
++	if [ -f $KSM_MASK_FILE ]; then
++		if systemctl --quiet unmask $KSM_SERVICES; then
++			rm -f $KSM_MASK_FILE
+ 		fi
+-	done
++	fi
+ }
+ 
+ die() {
+diff --git a/profiles/realtime-virtual-host/script.sh b/profiles/realtime-virtual-host/script.sh
+index a9366cb..469ee2a 100755
+--- a/profiles/realtime-virtual-host/script.sh
++++ b/profiles/realtime-virtual-host/script.sh
+@@ -93,8 +93,10 @@ start() {
+ }
+ 
+ stop() {
+-    [ "$1" = "full_rollback" ] && teardown_kvm_mod_low_latency
+-    enable_ksm
++    if [ "$1" = "full_rollback" ]; then
++        teardown_kvm_mod_low_latency
++        enable_ksm
++    fi
+     systemctl stop rt-entsk
+     return "$?"
+ }
diff --git a/SOURCES/tuned-2.10.0-makefile-full-python-path.patch b/SOURCES/tuned-2.10.0-makefile-full-python-path.patch
new file mode 100644
index 0000000..39b3f4b
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-makefile-full-python-path.patch
@@ -0,0 +1,18 @@
+--- a/Makefile
++++ b/Makefile
+@@ -30,12 +30,12 @@ VERSIONED_NAME = $(NAME)-$(VERSION)$(GIT_PSUFFIX)
+ SYSCONFDIR = /etc
+ DATADIR = /usr/share
+ DOCDIR = $(DATADIR)/doc/$(NAME)
+-PYTHON = python3
++PYTHON = /usr/bin/python3
+ PYLINT = pylint-3
+ ifeq ($(PYTHON),python2)
+ PYLINT = pylint-2
+ endif
+-SHEBANG_REWRITE_REGEX= '1s/^(\#!\/usr\/bin\/)\<python\>/\1$(PYTHON)/'
++SHEBANG_REWRITE_REGEX= '1s|^\#!/usr/bin/\<python\>|\#!$(PYTHON)|'
+ PYTHON_SITELIB = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_python_lib; print(get_python_lib());')
+ ifeq ($(PYTHON_SITELIB),)
+ $(error Failed to determine python library directory)
+
diff --git a/SOURCES/tuned-2.10.0-mssql-tuning.patch b/SOURCES/tuned-2.10.0-mssql-tuning.patch
new file mode 100644
index 0000000..df200c3
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-mssql-tuning.patch
@@ -0,0 +1,108 @@
+From 26db89de18efad1b453618ea8156422d26e0c85f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
+Date: Tue, 8 Jan 2019 15:00:33 +0100
+Subject: [PATCH] mssql: updated tuning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Added vm plugin option 'transparent_hugepage.defrag'.
+
+Resolves: rhbz#1660178
+
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ profiles/mssql/tuned.conf  |  9 ++++++++-
+ tuned/plugins/plugin_vm.py | 32 +++++++++++++++++++++++++++-----
+ 2 files changed, 35 insertions(+), 6 deletions(-)
+
+diff --git a/profiles/mssql/tuned.conf b/profiles/mssql/tuned.conf
+index 2491717..35e208a 100644
+--- a/profiles/mssql/tuned.conf
++++ b/profiles/mssql/tuned.conf
+@@ -6,5 +6,12 @@
+ summary=Optimize for MS SQL Server
+ include=throughput-performance
+ 
++[vm]
++transparent_hugepage.defrag=always
++
+ [sysctl]
+-vm.max_map_count=262144
++vm.max_map_count=800000
++kernel.numa_balancing=0
++kernel.sched_latency_ns=60000000
++kernel.sched_min_granularity_ns=15000000
++kernel.sched_wakeup_granularity_ns=2000000
+diff --git a/tuned/plugins/plugin_vm.py b/tuned/plugins/plugin_vm.py
+index be570e2..9021ac3 100644
+--- a/tuned/plugins/plugin_vm.py
++++ b/tuned/plugins/plugin_vm.py
+@@ -20,6 +20,7 @@ class VMPlugin(base.Plugin):
+ 		return {
+ 			"transparent_hugepages" : None,
+ 			"transparent_hugepage" : None,
++			"transparent_hugepage.defrag" : None,
+ 		}
+ 
+ 	def _instance_init(self, instance):
+@@ -30,10 +31,11 @@ class VMPlugin(base.Plugin):
+ 		pass
+ 
+ 	@classmethod
+-	def _thp_file(self):
+-		path = "/sys/kernel/mm/transparent_hugepage/enabled"
++	def _thp_path(self):
++		path = "/sys/kernel/mm/transparent_hugepage"
+ 		if not os.path.exists(path):
+-			path =  "/sys/kernel/mm/redhat_transparent_hugepage/enabled"
++			# RHEL-6 support
++			path =  "/sys/kernel/mm/redhat_transparent_hugepage"
+ 		return path
+ 
+ 	@command_set("transparent_hugepages")
+@@ -49,7 +51,7 @@ class VMPlugin(base.Plugin):
+ 				log.info("transparent_hugepage is already set in kernel boot cmdline, ingoring value from profile")
+ 			return None
+ 
+-		sys_file = self._thp_file()
++		sys_file = os.path.join(self._thp_path(), "enabled")
+ 		if os.path.exists(sys_file):
+ 			if not sim:
+ 				cmd.write_to_file(sys_file, value)
+@@ -66,7 +68,7 @@ class VMPlugin(base.Plugin):
+ 
+ 	@command_get("transparent_hugepages")
+ 	def _get_transparent_hugepages(self):
+-		sys_file = self._thp_file()
++		sys_file = os.path.join(self._thp_path(), "enabled")
+ 		if os.path.exists(sys_file):
+ 			return cmd.get_active_option(cmd.read_file(sys_file))
+ 		else:
+@@ -76,3 +78,23 @@ class VMPlugin(base.Plugin):
+ 	@command_get("transparent_hugepage")
+ 	def _get_transparent_hugepage(self):
+ 		return self._get_transparent_hugepages()
++
++	@command_set("transparent_hugepage.defrag")
++	def _set_transparent_hugepage_defrag(self, value, sim):
++		sys_file = os.path.join(self._thp_path(), "defrag")
++		if os.path.exists(sys_file):
++			if not sim:
++				cmd.write_to_file(sys_file, value)
++			return value
++		else:
++			if not sim:
++				log.warn("Option 'transparent_hugepage.defrag' is not supported on current hardware.")
++			return None
++
++	@command_get("transparent_hugepage.defrag")
++	def _get_transparent_hugepage_defrag(self):
++		sys_file = os.path.join(self._thp_path(), "defrag")
++		if os.path.exists(sys_file):
++			return cmd.get_active_option(cmd.read_file(sys_file))
++		else:
++			return None
+-- 
+2.20.1
+
diff --git a/SOURCES/tuned-2.10.0-python-3.7-fix.patch b/SOURCES/tuned-2.10.0-python-3.7-fix.patch
new file mode 100644
index 0000000..9c90c67
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-python-3.7-fix.patch
@@ -0,0 +1,60 @@
+From f19b7c5713acb76a200811f6531acf2791505cac Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
+Date: Wed, 4 Jul 2018 23:27:38 +0200
+Subject: [PATCH] Fixed compatibility with python-3.7
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In python-3.7 async is a keyword, so it cannot be redefined.
+
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ tuned-adm.py         | 4 ++--
+ tuned/admin/admin.py | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tuned-adm.py b/tuned-adm.py
+index ea85c54..1b9623d 100755
+--- a/tuned-adm.py
++++ b/tuned-adm.py
+@@ -98,7 +98,7 @@ if __name__ == "__main__":
+ 
+ 	options = vars(args)
+ 	debug = options.pop("debug")
+-	async = options.pop("async")
++	asynco = options.pop("async")
+ 	timeout = options.pop("timeout")
+ 	action_name = options.pop("action")
+ 	log_level = options.pop("loglevel")
+@@ -107,7 +107,7 @@ if __name__ == "__main__":
+ 	dbus = config.get_bool(consts.CFG_DAEMON, consts.CFG_DEF_DAEMON)
+ 
+ 	try:
+-		admin = tuned.admin.Admin(dbus, debug, async, timeout, log_level)
++		admin = tuned.admin.Admin(dbus, debug, asynco, timeout, log_level)
+ 
+ 		result = admin.action(action_name, **options)
+ 	except:
+diff --git a/tuned/admin/admin.py b/tuned/admin/admin.py
+index 728af32..3f84413 100644
+--- a/tuned/admin/admin.py
++++ b/tuned/admin/admin.py
+@@ -14,12 +14,12 @@ import threading
+ import logging
+ 
+ class Admin(object):
+-	def __init__(self, dbus = True, debug = False, async = False,
++	def __init__(self, dbus = True, debug = False, asynco = False,
+ 			timeout = consts.ADMIN_TIMEOUT,
+ 			log_level = logging.ERROR):
+ 		self._dbus = dbus
+ 		self._debug = debug
+-		self._async = async
++		self._async = asynco
+ 		self._timeout = timeout
+ 		self._cmd = commands(debug)
+ 		self._profiles_locator = profiles_locator(consts.LOAD_DIRECTORIES)
+-- 
+2.14.4
+
diff --git a/SOURCES/tuned-2.10.0-realtime-virtual-enable-rt-entsk.patch b/SOURCES/tuned-2.10.0-realtime-virtual-enable-rt-entsk.patch
new file mode 100644
index 0000000..e464f0f
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-realtime-virtual-enable-rt-entsk.patch
@@ -0,0 +1,94 @@
+From 837c6bd12a5eedc3fbf46291bf1040e724786efd Mon Sep 17 00:00:00 2001
+From: Marcelo Tosatti <mtosatti@redhat.com>
+Date: Fri, 31 Aug 2018 13:27:12 +0200
+Subject: [PATCH] start/stop rt-entsk daemon on initialization/shutdown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The rt-entsk application, part of newer rt-setup packages,
+worksaround a latency issue with static key
+IPI's. What it does it:
+
+/*
+ * Open a socket, and enable timestamping on it.
+ *
+ * This is to avoid Chrony from changing timestamping
+ * user count from 0->1 and vice-versa, causing
+ * static key enable/disable IPIs.
+ *
+ */
+
+Start/stop the systemctl service from the realtime-virtual-host
+and realtime-virtual-guest profiles.
+
+Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ profiles/realtime-virtual-guest/script.sh  | 19 +++++++++++++++++++
+ profiles/realtime-virtual-guest/tuned.conf |  3 +++
+ profiles/realtime-virtual-host/script.sh   |  2 ++
+ 3 files changed, 24 insertions(+)
+ create mode 100755 profiles/realtime-virtual-guest/script.sh
+
+diff --git a/profiles/realtime-virtual-guest/script.sh b/profiles/realtime-virtual-guest/script.sh
+new file mode 100755
+index 0000000..33cb730
+--- /dev/null
++++ b/profiles/realtime-virtual-guest/script.sh
+@@ -0,0 +1,19 @@
++#!/bin/sh
++
++. /usr/lib/tuned/functions
++
++start() {
++    systemctl start rt-entsk
++    return "$?"
++}
++
++stop() {
++    systemctl stop rt-entsk
++    return "$?"
++}
++
++verify() {
++    return "$?"
++}
++
++process $@
+diff --git a/profiles/realtime-virtual-guest/tuned.conf b/profiles/realtime-virtual-guest/tuned.conf
+index fb2bc42..8e1f67e 100644
+--- a/profiles/realtime-virtual-guest/tuned.conf
++++ b/profiles/realtime-virtual-guest/tuned.conf
+@@ -36,5 +36,8 @@ group.ktimersoftd=0:f:3:*:ktimersoftd.*
+ 
+ ps_blacklist=ksoftirqd.*;rcuc.*;rcub.*;ktimersoftd.*
+ 
++[script]
++script=${i:PROFILE_DIR}/script.sh
++
+ [bootloader]
+ cmdline_rvg=+nohz=on nohz_full=${isolated_cores} rcu_nocbs=${isolated_cores}
+diff --git a/profiles/realtime-virtual-host/script.sh b/profiles/realtime-virtual-host/script.sh
+index 515d254..a9366cb 100755
+--- a/profiles/realtime-virtual-host/script.sh
++++ b/profiles/realtime-virtual-host/script.sh
+@@ -87,6 +87,7 @@ start() {
+     if [ -f $CACHE_VALUE_FILE ]; then
+         echo `cat $CACHE_VALUE_FILE` > $KVM_LAPIC_FILE
+     fi
++    systemctl start rt-entsk
+ 
+     return 0
+ }
+@@ -94,6 +95,7 @@ start() {
+ stop() {
+     [ "$1" = "full_rollback" ] && teardown_kvm_mod_low_latency
+     enable_ksm
++    systemctl stop rt-entsk
+     return "$?"
+ }
+ 
+-- 
+2.14.4
+
diff --git a/SOURCES/tuned-2.10.0-s390x-bls-workaround.patch b/SOURCES/tuned-2.10.0-s390x-bls-workaround.patch
new file mode 100644
index 0000000..e780e94
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-s390x-bls-workaround.patch
@@ -0,0 +1,108 @@
+From 41b38ab6e7a411e609776eec544451f3de76e523 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
+Date: Mon, 10 Dec 2018 17:49:54 +0100
+Subject: [PATCH] Added workaround for zipl (s390x) not supporting multiple
+ initrds
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This workaround can be removed once implemented upstream, ticket:
+https://github.com/ibm-s390-tools/s390-tools/issues/49
+
+RHEL bugzilla:
+rhbz#1576435
+
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ 91-tuned.install => 92-tuned.install | 15 ++++++++++++---
+ Makefile                             |  4 ++--
+ tuned.spec                           |  2 +-
+ tuned/consts.py                      |  2 +-
+ 4 files changed, 16 insertions(+), 7 deletions(-)
+ rename 91-tuned.install => 92-tuned.install (58%)
+
+diff --git a/91-tuned.install b/92-tuned.install
+similarity index 58%
+rename from 91-tuned.install
+rename to 92-tuned.install
+index 18d00d9..00eefc7 100644
+--- a/91-tuned.install
++++ b/92-tuned.install
+@@ -19,13 +19,22 @@ LOADER_ENTRIES="$BOOT_ROOT/loader/entries"
+ 
+ [ "$COMMAND" = "add" ] || exit 0
+ 
+-pushd "$LOADER_ENTRIES"
++# Workaround for rhbz#1657858
++ARCH=`uname -m`
++[ "${ARCH:0:4}" = "s390" ]
++HANDLE_INITRD="$?"
++
++pushd "$LOADER_ENTRIES" &> /dev/null
+ for f in `basename "$MACHINE_ID"`-*.conf; do
+   if [ -f "$f" -a "${f: -12}" != "-rescue.conf" ]; then
+     grep -q '^\s*options\s\+.*\$tuned_params' "$f" || sed -i '/^\s*options\s\+/ s/\(.*\)/\1 \$tuned_params/' "$f"
+-    grep -q '^\s*initrd\s\+.*\$tuned_initrd' "$f" || sed -i '/^\s*initrd\s\+/ s/\(.*\)/\1 \$tuned_initrd/' "$f"
++    if [ "$HANDLE_INITRD" = "1" ]; then
++      grep -q '^\s*initrd\s\+.*\$tuned_initrd' "$f" || sed -i '/^\s*initrd\s\+/ s/\(.*\)/\1 \$tuned_initrd/' "$f"
++    else
++      sed -i '/^\s*initrd\s\+.*\$tuned_initrd/ s/\s\+\$tuned_initrd\b//g' "$f"
++    fi
+   fi
+ done
+-popd
++popd &> /dev/null
+ 
+ exit 0
+diff --git a/Makefile b/Makefile
+index f61cd01..36e22ff 100644
+--- a/Makefile
++++ b/Makefile
+@@ -60,7 +60,7 @@ release-cp: release-dir
+ 
+ 	cp -a tuned.py tuned.spec tuned.service tuned.tmpfiles Makefile tuned-adm.py \
+ 		tuned-adm.bash dbus.conf recommend.conf tuned-main.conf 00_tuned \
+-		91-tuned.install bootcmdline modules.conf com.redhat.tuned.policy \
++		92-tuned.install bootcmdline modules.conf com.redhat.tuned.policy \
+ 		com.redhat.tuned.gui.policy tuned-gui.py tuned-gui.glade \
+ 		tuned-gui.desktop $(VERSIONED_NAME)
+ 	cp -a doc experiments libexec man profiles systemtap tuned contrib icons \
+@@ -182,7 +182,7 @@ install: install-dirs
+ 	install -Dpm 0755 00_tuned $(DESTDIR)$(SYSCONFDIR)/grub.d/00_tuned
+ 
+ 	# kernel install hook
+-	install -Dpm 0755 91-tuned.install $(DESTDIR)$(KERNELINSTALLHOOKDIR)/91-tuned.install
++	install -Dpm 0755 92-tuned.install $(DESTDIR)$(KERNELINSTALLHOOKDIR)/92-tuned.install
+ 
+ 	# polkit configuration
+ 	install -Dpm 0644 com.redhat.tuned.policy $(DESTDIR)$(DATADIR)/polkit-1/actions/com.redhat.tuned.policy
+diff --git a/tuned.spec b/tuned.spec
+index 300c8aa..6ac575e 100644
+--- a/tuned.spec
++++ b/tuned.spec
+@@ -392,7 +392,7 @@ fi
+ %{_datadir}/tuned/grub2
+ %{_datadir}/polkit-1/actions/com.redhat.tuned.policy
+ %ghost %{_sysconfdir}/modprobe.d/kvm.rt.tuned.conf
+-%{_prefix}/lib/kernel/install.d/91-tuned.install
++%{_prefix}/lib/kernel/install.d/92-tuned.install
+ 
+ %files gtk
+ %defattr(-,root,root,-)
+diff --git a/tuned/consts.py b/tuned/consts.py
+index de94059..39f9209 100644
+--- a/tuned/consts.py
++++ b/tuned/consts.py
+@@ -38,7 +38,7 @@ BOOT_CMDLINE_INITRD_ADD_VAR = "TUNED_BOOT_INITRD_ADD"
+ BOOT_CMDLINE_FILE = "/etc/tuned/bootcmdline"
+ PETITBOOT_DETECT_DIR = "/sys/firmware/opal"
+ MACHINE_ID_FILE = "/etc/machine-id"
+-KERNEL_UPDATE_HOOK_FILE = "/usr/lib/kernel/install.d/91-tuned.install"
++KERNEL_UPDATE_HOOK_FILE = "/usr/lib/kernel/install.d/92-tuned.install"
+ BLS_ENTRIES_PATH = "/boot/loader/entries"
+ 
+ # modules plugin configuration
+-- 
+2.17.2
+
diff --git a/SOURCES/tuned-2.10.0-update-kvm-modprobe-file.patch b/SOURCES/tuned-2.10.0-update-kvm-modprobe-file.patch
new file mode 100644
index 0000000..d4d4886
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-update-kvm-modprobe-file.patch
@@ -0,0 +1,73 @@
+From c4a0aef63df41a79e96c1276ac732ecde8d58d86 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
+Date: Thu, 22 Nov 2018 17:38:12 +0100
+Subject: [PATCH] functions: reworked setup_kvm_mod_low_latency to count with
+ kernel changes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It updates the KVM modprobe file if its content differs from what's
+supported on the current system. It may look a bit over-engineered, but
+it's done this way to lower the possibility of race condition.
+
+Resolves: rhbz#1649408
+
+Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
+---
+ profiles/functions | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+diff --git a/profiles/functions b/profiles/functions
+index 919409c..aab608a 100644
+--- a/profiles/functions
++++ b/profiles/functions
+@@ -503,26 +503,29 @@ eee_set_normal_fsb() {
+ 
+ kvm_modprobe_file=/etc/modprobe.d/kvm.rt.tuned.conf
+ 
+-setup_kvm_mod_low_latency()
++teardown_kvm_mod_low_latency()
+ {
+-	if [ -f $kvm_modprobe_file ]; then
+-		return
+-	fi
+-
+-	modinfo -p kvm | grep -q kvmclock_periodic_sync
+-	if [ "$?" -eq 0 ]; then
+-		echo "options kvm kvmclock_periodic_sync=0" > $kvm_modprobe_file
+-	fi
+-
+-	modinfo -p kvm_intel | grep -q ple_gap
+-	if [ "$?" -eq 0 ]; then
+-		echo "options kvm_intel ple_gap=0" >> $kvm_modprobe_file
+-	fi
++	rm -f $kvm_modprobe_file
+ }
+ 
+-teardown_kvm_mod_low_latency()
++setup_kvm_mod_low_latency()
+ {
+-	rm -f $kvm_modprobe_file
++	local HAS_KPS=""
++	local HAS_PLE_GAP=""
++	local WANTS_KPS=""
++	local WANTS_PLE_GAP=""
++
++	modinfo -p kvm | grep -q kvmclock_periodic_sync && HAS_KPS=1
++	modinfo -p kvm_intel | grep -q ple_gap && HAS_PLE_GAP=1
++	grep -qs kvmclock_periodic_sync "$kvm_modprobe_file" && WANTS_KPS=1
++	grep -qs ple_gap "$kvm_modprobe_file" && WANTS_PLE_GAP=1
++
++	if [ "$HAS_KPS" != "$WANTS_KPS" -o "$HAS_PLE_GAP" != "$WANTS_PLE_GAP" ]; then
++		teardown_kvm_mod_low_latency
++		[ "$HAS_KPS" ] && echo "options kvm kvmclock_periodic_sync=0" > $kvm_modprobe_file
++		[ "$HAS_PLE_GAP" ] && echo "options kvm_intel ple_gap=0" >> $kvm_modprobe_file
++	fi
++	return 0
+ }
+ 
+ #
+-- 
+2.14.5
+
diff --git a/SOURCES/tuned-2.10.0-use-online-cpus.patch b/SOURCES/tuned-2.10.0-use-online-cpus.patch
new file mode 100644
index 0000000..8cc34fd
--- /dev/null
+++ b/SOURCES/tuned-2.10.0-use-online-cpus.patch
@@ -0,0 +1,104 @@
+diff --git a/profiles/cpu-partitioning/tuned.conf b/profiles/cpu-partitioning/tuned.conf
+index 3c52215..1821b74 100644
+--- a/profiles/cpu-partitioning/tuned.conf
++++ b/profiles/cpu-partitioning/tuned.conf
+@@ -19,13 +19,13 @@ tmpdir=${f:strip:${f:exec:/usr/bin/mktemp:-d}}
+ isolated_cores_expanded=${f:cpulist_unpack:${isolated_cores}}
+ isolated_cpumask=${f:cpulist2hex:${isolated_cores_expanded}}
+ not_isolated_cores_expanded=${f:cpulist_invert:${isolated_cores_expanded}}
+-isolated_cores_present_expanded=${f:cpulist_present:${isolated_cores}}
+-not_isolated_cores_present_expanded=${f:cpulist_present:${not_isolated_cores_expanded}}
++isolated_cores_online_expanded=${f:cpulist_online:${isolated_cores}}
++not_isolated_cores_online_expanded=${f:cpulist_online:${not_isolated_cores_expanded}}
+ not_isolated_cpumask=${f:cpulist2hex:${not_isolated_cores_expanded}}
+ no_balance_cores_expanded=${f:cpulist_unpack:${no_balance_cores}}
+ 
+-# Fail if isolated_cores contains CPUs which are not present
+-assert2=${f:assertion:isolated_cores contains present CPU(s):${isolated_cores_expanded}:${isolated_cores_present_expanded}}
++# Fail if isolated_cores contains CPUs which are not online
++assert2=${f:assertion:isolated_cores contains online CPU(s):${isolated_cores_expanded}:${isolated_cores_online_expanded}}
+ 
+ [sysctl]
+ kernel.hung_task_timeout_secs = 600
+diff --git a/profiles/realtime-virtual-guest/tuned.conf b/profiles/realtime-virtual-guest/tuned.conf
+index b90e76f..fb2bc42 100644
+--- a/profiles/realtime-virtual-guest/tuned.conf
++++ b/profiles/realtime-virtual-guest/tuned.conf
+@@ -15,10 +15,10 @@ isolated_cores_assert_check = \\${isolated_cores}
+ assert1=${f:assertion_non_equal:isolated_cores are set:${isolated_cores}:${isolated_cores_assert_check}}
+ 
+ isolated_cores_expanded=${f:cpulist_unpack:${isolated_cores}}
+-isolated_cores_present_expanded=${f:cpulist_present:${isolated_cores}}
++isolated_cores_online_expanded=${f:cpulist_online:${isolated_cores}}
+ 
+-# Fail if isolated_cores contains CPUs which are not present
+-assert2=${f:assertion:isolated_cores contains present CPU(s):${isolated_cores_expanded}:${isolated_cores_present_expanded}}
++# Fail if isolated_cores contains CPUs which are not online
++assert2=${f:assertion:isolated_cores contains online CPU(s):${isolated_cores_expanded}:${isolated_cores_online_expanded}}
+ 
+ [scheduler]
+ # group.group_name=rule_priority:scheduler_policy:scheduler_priority:core_affinity_in_hex:process_name_regex
+diff --git a/profiles/realtime-virtual-host/tuned.conf b/profiles/realtime-virtual-host/tuned.conf
+index 0346fff..5e0ff1f 100644
+--- a/profiles/realtime-virtual-host/tuned.conf
++++ b/profiles/realtime-virtual-host/tuned.conf
+@@ -20,10 +20,10 @@ isolated_cores_assert_check = \\${isolated_cores}
+ assert1=${f:assertion_non_equal:isolated_cores are set:${isolated_cores}:${isolated_cores_assert_check}}
+ 
+ isolated_cores_expanded=${f:cpulist_unpack:${isolated_cores}}
+-isolated_cores_present_expanded=${f:cpulist_present:${isolated_cores}}
++isolated_cores_online_expanded=${f:cpulist_online:${isolated_cores}}
+ 
+-# Fail if isolated_cores contains CPUs which are not present
+-assert2=${f:assertion:isolated_cores contains present CPU(s):${isolated_cores_expanded}:${isolated_cores_present_expanded}}
++# Fail if isolated_cores contains CPUs which are not online
++assert2=${f:assertion:isolated_cores contains online CPU(s):${isolated_cores_expanded}:${isolated_cores_online_expanded}}
+ 
+ [scheduler]
+ # group.group_name=rule_priority:scheduler_policy:scheduler_priority:core_affinity_in_hex:process_name_regex
+diff --git a/profiles/realtime/tuned.conf b/profiles/realtime/tuned.conf
+index b2273cf..c595e67 100644
+--- a/profiles/realtime/tuned.conf
++++ b/profiles/realtime/tuned.conf
+@@ -18,10 +18,10 @@ assert1=${f:assertion_non_equal:isolated_cores are set:${isolated_cores}:${isola
+ # Non-isolated cores cpumask including offline cores
+ not_isolated_cpumask = ${f:cpulist2hex_invert:${isolated_cores}}
+ isolated_cores_expanded=${f:cpulist_unpack:${isolated_cores}}
+-isolated_cores_present_expanded=${f:cpulist_present:${isolated_cores}}
++isolated_cores_online_expanded=${f:cpulist_online:${isolated_cores}}
+ 
+-# Fail if isolated_cores contains CPUs which are not present
+-assert2=${f:assertion:isolated_cores contains present CPU(s):${isolated_cores_expanded}:${isolated_cores_present_expanded}}
++# Fail if isolated_cores contains CPUs which are not online
++assert2=${f:assertion:isolated_cores contains online CPU(s):${isolated_cores_expanded}:${isolated_cores_online_expanded}}
+ 
+ [sysctl]
+ kernel.hung_task_timeout_secs = 600
+diff --git a/tuned/profiles/functions/function_cpulist_invert.py b/tuned/profiles/functions/function_cpulist_invert.py
+index 375eb67..2aff3c9 100644
+--- a/tuned/profiles/functions/function_cpulist_invert.py
++++ b/tuned/profiles/functions/function_cpulist_invert.py
+@@ -8,7 +8,7 @@ log = tuned.logs.get()
+ class cpulist_invert(base.Function):
+ 	"""
+ 	Inverts list of CPUs (makes its complement). For the complement it
+-	gets number of present CPUs from the /sys/devices/system/cpu/present,
++	gets number of present CPUs from the /sys/devices/system/cpu/online,
+ 	e.g. system with 4 CPUs (0-3), the inversion of list "0,2,3" will be
+ 	"1"
+ 	"""
+diff --git a/tuned/utils/commands.py b/tuned/utils/commands.py
+index 8b7df57..41d6d99 100644
+--- a/tuned/utils/commands.py
++++ b/tuned/utils/commands.py
+@@ -363,8 +363,8 @@ class commands:
+ 	# Inverts CPU list (i.e. makes its complement)
+ 	def cpulist_invert(self, l):
+ 		cpus = self.cpulist_unpack(l)
+-		present = self.cpulist_unpack(self.read_file("/sys/devices/system/cpu/present"))
+-		return list(set(present) - set(cpus))
++		online = self.cpulist_unpack(self.read_file("/sys/devices/system/cpu/online"))
++		return list(set(online) - set(cpus))
+ 
+ 	# Converts CPU list to hexadecimal CPU mask
+ 	def cpulist2hex(self, l):
diff --git a/SPECS/tuned.spec b/SPECS/tuned.spec
new file mode 100644
index 0000000..063fbb3
--- /dev/null
+++ b/SPECS/tuned.spec
@@ -0,0 +1,1066 @@
+%if 0%{?fedora}
+%if 0%{?fedora} > 27
+%bcond_without python3
+%else
+%bcond_with python3
+%endif
+%else
+%if 0%{?rhel} && 0%{?rhel} < 8
+%bcond_with python3
+%else
+%bcond_without python3
+%endif
+%endif
+
+%if %{with python3}
+%global _py python3
+%else
+%{!?python2_sitelib:%global python2_sitelib %{python_sitelib}}
+%if 0%{?rhel} && 0%{?rhel} < 8
+%global _py python
+%else
+%global _py python2
+%endif
+%endif
+
+#%%global prerelease rc
+#%%global prereleasenum 2
+
+%global prerel1 %{?prerelease:.%{prerelease}%{prereleasenum}}
+%global prerel2 %{?prerelease:-%{prerelease}.%{prereleasenum}}
+
+Summary: A dynamic adaptive system tuning daemon
+Name: tuned
+Version: 2.10.0
+Release: 15%{?prerel1}%{?dist}
+License: GPLv2+
+Source0: https://github.com/redhat-performance/%{name}/archive/v%{version}%{?prerel2}.tar.gz#/%{name}-%{version}%{?prerel2}.tar.gz
+# RHEL-8 specific recommend.conf:
+Source1: recommend.conf
+URL: http://www.tuned-project.org/
+BuildArch: noarch
+BuildRequires: systemd, desktop-file-utils
+Requires(post): systemd, virt-what
+Requires(preun): systemd
+Requires(postun): systemd
+BuildRequires: %{_py}, %{_py}-devel
+Requires: %{_py}-decorator, %{_py}-pyudev, %{_py}-configobj
+Requires: %{_py}-schedutils, %{_py}-linux-procfs, %{_py}-perf
+# requires for packages with inconsistent python2/3 names
+%if %{with python3}
+Requires: python3-dbus, python3-gobject-base
+Recommends: python3-dmidecode
+%else
+Requires: dbus-python, pygobject3-base
+%endif
+Requires: virt-what, ethtool, gawk, hdparm
+Requires: util-linux, dbus, polkit
+%if 0%{?fedora} > 22 || 0%{?rhel} > 7
+Recommends: kernel-tools
+%endif
+%if 0%{?rhel} > 7
+Requires: python3-syspurpose
+%endif
+
+# Upstream patch:
+Patch0: tuned-2.10.0-python-3.7-fix.patch
+# Upstream patch:
+Patch1: 0001-tuned-adm-Fix-a-traceback-when-run-without-action-sp.patch
+# Upstream patch:
+Patch2: tuned-2.10.0-makefile-full-python-path.patch
+# Upstream patch:
+Patch3: 0001-tuned-gui-Sort-plugins-based-on-their-name.patch
+Patch4: tuned-2.10.0-use-online-cpus.patch
+# Upstream patch:
+Patch5: 0001-Support-chassis-type-matching-in-recommend.conf.patch
+# Upstream patch:
+Patch6: 0002-Support-syspurpose-role-matching-in-recommend.conf.patch
+# Upstream patch:
+Patch7: 0001-Make-python-dmidecode-a-weak-dependency.patch
+Patch8: tuned-2.10.0-realtime-virtual-enable-rt-entsk.patch
+Patch9: tuned-2.10.0-disable-ksm-once.patch
+Patch10: tuned-2.10.0-update-kvm-modprobe-file.patch
+# Upstream patch:
+Patch11: tuned-2.10.0-add-support-for-bls.patch
+Patch12: tuned-2.10.0-s390x-bls-workaround.patch
+# https://github.com/redhat-performance/tuned/pull/144
+Patch13: 0001-scheduler-Keep-polling-file-objects-alive-long-enoug.patch
+# Upstream patch
+Patch14: tuned-2.10.0-mssql-tuning.patch
+# Upstream patch (2cc3d747986837d7e7957f5a4baede2dd691348a)
+Patch15: 0001-plugin_disk-Fix-checking-the-removable-attribute-on-.patch
+
+%description
+The tuned package contains a daemon that tunes system settings dynamically.
+It does so by monitoring the usage of several system components periodically.
+Based on that information components will then be put into lower or higher
+power saving modes to adapt to the current usage. Currently only ethernet
+network and ATA harddisk devices are implemented.
+
+%if 0%{?rhel} <= 7 && 0%{!?fedora:1}
+# RHEL <= 7
+%global docdir %{_docdir}/%{name}-%{version}
+%else
+# RHEL > 7 || fedora
+%global docdir %{_docdir}/%{name}
+%endif
+
+%package gtk
+Summary: GTK GUI for tuned
+Requires: %{name} = %{version}-%{release}
+Requires: powertop, polkit
+# requires for packages with inconsistent python2/3 names
+%if %{with python3}
+Requires: python3-gobject-base
+%else
+Requires: pygobject3-base
+%endif
+
+%description gtk
+GTK GUI that can control tuned and provides simple profile editor.
+
+%package utils
+Requires: %{name} = %{version}-%{release}
+Requires: powertop
+Summary: Various tuned utilities
+
+%description utils
+This package contains utilities that can help you to fine tune and
+debug your system and manage tuned profiles.
+
+%package utils-systemtap
+Summary: Disk and net statistic monitoring systemtap scripts
+Requires: %{name} = %{version}-%{release}
+Requires: systemtap
+
+%description utils-systemtap
+This package contains several systemtap scripts to allow detailed
+manual monitoring of the system. Instead of the typical IO/sec it collects
+minimal, maximal and average time between operations to be able to
+identify applications that behave power inefficient (many small operations
+instead of fewer large ones).
+
+%package profiles-sap
+Summary: Additional tuned profile(s) targeted to SAP NetWeaver loads
+Requires: %{name} = %{version}
+
+%description profiles-sap
+Additional tuned profile(s) targeted to SAP NetWeaver loads.
+
+%package profiles-mssql
+Summary: Additional tuned profile(s) for MS SQL Server
+Requires: %{name} = %{version}
+
+%description profiles-mssql
+Additional tuned profile(s) for MS SQL Server.
+
+%package profiles-oracle
+Summary: Additional tuned profile(s) targeted to Oracle loads
+Requires: %{name} = %{version}
+
+%description profiles-oracle
+Additional tuned profile(s) targeted to Oracle loads.
+
+%package profiles-sap-hana
+Summary: Additional tuned profile(s) targeted to SAP HANA loads
+Requires: %{name} = %{version}
+
+%description profiles-sap-hana
+Additional tuned profile(s) targeted to SAP HANA loads.
+
+%package profiles-atomic
+Summary: Additional tuned profile(s) targeted to Atomic
+Requires: %{name} = %{version}
+
+%description profiles-atomic
+Additional tuned profile(s) targeted to Atomic host and guest.
+
+%package profiles-realtime
+Summary: Additional tuned profile(s) targeted to realtime
+Requires: %{name} = %{version}
+Requires: tuna
+
+%description profiles-realtime
+Additional tuned profile(s) targeted to realtime.
+
+%package profiles-nfv-guest
+Summary: Additional tuned profile(s) targeted to Network Function Virtualization (NFV) guest
+Requires: %{name} = %{version}
+Requires: %{name}-profiles-realtime = %{version}
+Requires: tuna
+
+%description profiles-nfv-guest
+Additional tuned profile(s) targeted to Network Function Virtualization (NFV) guest.
+
+%package profiles-nfv-host
+Summary: Additional tuned profile(s) targeted to Network Function Virtualization (NFV) host
+Requires: %{name} = %{version}
+Requires: %{name}-profiles-realtime = %{version}
+Requires: tuna
+%if 0%{?rhel} == 7
+Requires: qemu-kvm-tools-rhev
+%else
+Recommends: tuned-profiles-nfv-host-bin
+%endif
+
+%description profiles-nfv-host
+Additional tuned profile(s) targeted to Network Function Virtualization (NFV) host.
+
+# this is kept for backward compatibility, it should be dropped for RHEL-8
+%package profiles-nfv
+Summary: Additional tuned profile(s) targeted to Network Function Virtualization (NFV)
+Requires: %{name} = %{version}
+Requires: %{name}-profiles-nfv-guest = %{version}
+Requires: %{name}-profiles-nfv-host = %{version}
+
+%description profiles-nfv
+Additional tuned profile(s) targeted to Network Function Virtualization (NFV).
+
+%package profiles-cpu-partitioning
+Summary: Additional tuned profile(s) optimized for CPU partitioning
+Requires: %{name} = %{version}
+
+%description profiles-cpu-partitioning
+Additional tuned profile(s) optimized for CPU partitioning.
+
+%package profiles-compat
+Summary: Additional tuned profiles mainly for backward compatibility with tuned 1.0
+Requires: %{name} = %{version}
+
+%description profiles-compat
+Additional tuned profiles mainly for backward compatibility with tuned 1.0.
+It can be also used to fine tune your system for specific scenarios.
+
+%prep
+%setup -q -n %{name}-%{version}%{?prerel2}
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+
+# workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1626473 (maybe not needed)
+chmod 0755 profiles/realtime-virtual-guest/script.sh
+
+# Replace the upstream recommend.conf with a RHEL-8-specific one
+rm -f recommend.conf
+cp -p %{SOURCE1} recommend.conf
+
+%build
+
+%install
+make install DESTDIR=%{buildroot} DOCDIR=%{docdir} \
+%if %{with python3}
+	PYTHON=%{__python3}
+%else
+	PYTHON=%{__python2}
+%endif
+%if 0%{?rhel}
+sed -i 's/\(dynamic_tuning[ \t]*=[ \t]*\).*/\10/' %{buildroot}%{_sysconfdir}/tuned/tuned-main.conf
+%endif
+
+# conditional support for grub2, grub2 is not available on all architectures
+# and tuned is noarch package, thus the following hack is needed
+mkdir -p %{buildroot}%{_datadir}/tuned/grub2
+mv %{buildroot}%{_sysconfdir}/grub.d/00_tuned %{buildroot}%{_datadir}/tuned/grub2/00_tuned
+rmdir %{buildroot}%{_sysconfdir}/grub.d
+
+# ghost for persistent storage
+mkdir -p %{buildroot}%{_var}/lib/tuned
+
+# ghost for NFV
+mkdir -p %{buildroot}%{_sysconfdir}/modprobe.d
+touch %{buildroot}%{_sysconfdir}/modprobe.d/kvm.rt.tuned.conf
+
+# validate desktop file
+desktop-file-validate %{buildroot}%{_datadir}/applications/tuned-gui.desktop
+
+%post
+%systemd_post tuned.service
+
+# convert active_profile from full path to name (if needed)
+sed -i 's|.*/\([^/]\+\)/[^\.]\+\.conf|\1|' /etc/tuned/active_profile
+
+# convert GRUB_CMDLINE_LINUX to GRUB_CMDLINE_LINUX_DEFAULT
+if [ -r "%{_sysconfdir}/default/grub" ]; then
+  sed -i 's/GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX \\$tuned_params"/GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \\$tuned_params"/' \
+    %{_sysconfdir}/default/grub
+fi
+
+
+%preun
+%systemd_preun tuned.service
+if [ "$1" == 0 ]; then
+# clear persistent storage
+  rm -f %{_var}/lib/tuned/*
+# clear temporal storage
+  rm -f /run/tuned/*
+fi
+
+
+%postun
+%systemd_postun_with_restart tuned.service
+
+# conditional support for grub2, grub2 is not available on all architectures
+# and tuned is noarch package, thus the following hack is needed
+if [ "$1" == 0 ]; then
+  rm -f %{_sysconfdir}/grub.d/00_tuned || :
+# unpatch /etc/default/grub
+  if [ -r "%{_sysconfdir}/default/grub" ]; then
+    sed -i '/GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT:+$GRUB_CMDLINE_LINUX_DEFAULT }\\$tuned_params"/d' %{_sysconfdir}/default/grub
+  fi
+
+# cleanup for Boot loader specification (BLS)
+
+# clear grubenv variables
+  grub2-editenv - unset tuned_params tuned_initrd &>/dev/null || :
+# unpatch BLS entries
+  MACHINE_ID=`cat /etc/machine-id 2>/dev/null`
+  if [ "$MACHINE_ID" ]
+  then
+    for f in /boot/loader/entries/$MACHINE_ID-*.conf
+    do
+      if [ -f "$f" -a "${f: -12}" != "-rescue.conf" ]
+      then
+        sed -i '/^\s*options\s\+.*\$tuned_params/ s/\s\+\$tuned_params\b//g' "$f" &>/dev/null || :
+        sed -i '/^\s*initrd\s\+.*\$tuned_initrd/ s/\s\+\$tuned_initrd\b//g' "$f" &>/dev/null || :
+      fi
+    done
+  fi
+fi
+
+
+%triggerun -- tuned < 2.0-0
+# remove ktune from old tuned, now part of tuned
+/usr/sbin/service ktune stop &>/dev/null || :
+/usr/sbin/chkconfig --del ktune &>/dev/null || :
+
+
+%posttrans
+# conditional support for grub2, grub2 is not available on all architectures
+# and tuned is noarch package, thus the following hack is needed
+if [ -d %{_sysconfdir}/grub.d ]; then
+  cp -a %{_datadir}/tuned/grub2/00_tuned %{_sysconfdir}/grub.d/00_tuned
+  selinuxenabled &>/dev/null && \
+    restorecon %{_sysconfdir}/grub.d/00_tuned &>/dev/null || :
+fi
+
+
+%files
+%exclude %{docdir}/README.utils
+%exclude %{docdir}/README.scomes
+%exclude %{docdir}/README.NFV
+%doc %{docdir}
+%{_datadir}/bash-completion/completions/tuned-adm
+%if %{with python3}
+%exclude %{python3_sitelib}/tuned/gtk
+%{python3_sitelib}/tuned
+%else
+%exclude %{python2_sitelib}/tuned/gtk
+%{python2_sitelib}/tuned
+%endif
+%{_sbindir}/tuned
+%{_sbindir}/tuned-adm
+%exclude %{_sysconfdir}/tuned/realtime-variables.conf
+%exclude %{_sysconfdir}/tuned/realtime-virtual-guest-variables.conf
+%exclude %{_sysconfdir}/tuned/realtime-virtual-host-variables.conf
+%exclude %{_sysconfdir}/tuned/cpu-partitioning-variables.conf
+%exclude %{_sysconfdir}/tuned/sap-hana-vmware-variables.conf
+%exclude %{_prefix}/lib/tuned/default
+%exclude %{_prefix}/lib/tuned/desktop-powersave
+%exclude %{_prefix}/lib/tuned/laptop-ac-powersave
+%exclude %{_prefix}/lib/tuned/server-powersave
+%exclude %{_prefix}/lib/tuned/laptop-battery-powersave
+%exclude %{_prefix}/lib/tuned/enterprise-storage
+%exclude %{_prefix}/lib/tuned/spindown-disk
+%exclude %{_prefix}/lib/tuned/sap-netweaver
+%exclude %{_prefix}/lib/tuned/sap-hana
+%exclude %{_prefix}/lib/tuned/sap-hana-vmware
+%exclude %{_prefix}/lib/tuned/mssql
+%exclude %{_prefix}/lib/tuned/oracle
+%exclude %{_prefix}/lib/tuned/atomic-host
+%exclude %{_prefix}/lib/tuned/atomic-guest
+%exclude %{_prefix}/lib/tuned/realtime
+%exclude %{_prefix}/lib/tuned/realtime-virtual-guest
+%exclude %{_prefix}/lib/tuned/realtime-virtual-host
+%exclude %{_prefix}/lib/tuned/cpu-partitioning
+%{_prefix}/lib/tuned
+%dir %{_sysconfdir}/tuned
+%dir %{_sysconfdir}/tuned/recommend.d
+%dir %{_libexecdir}/tuned
+%{_libexecdir}/tuned/defirqaffinity*
+%config(noreplace) %verify(not size mtime md5) %{_sysconfdir}/tuned/active_profile
+%config(noreplace) %verify(not size mtime md5) %{_sysconfdir}/tuned/profile_mode
+%config(noreplace) %{_sysconfdir}/tuned/tuned-main.conf
+%config(noreplace) %verify(not size mtime md5) %{_sysconfdir}/tuned/bootcmdline
+%{_sysconfdir}/dbus-1/system.d/com.redhat.tuned.conf
+%verify(not size mtime md5) %{_sysconfdir}/modprobe.d/tuned.conf
+%{_tmpfilesdir}/tuned.conf
+%{_unitdir}/tuned.service
+%dir %{_localstatedir}/log/tuned
+%dir /run/tuned
+%dir %{_var}/lib/tuned
+%{_mandir}/man5/tuned*
+%{_mandir}/man7/tuned-profiles.7*
+%{_mandir}/man8/tuned*
+%dir %{_datadir}/tuned
+%{_datadir}/tuned/grub2
+%{_datadir}/polkit-1/actions/com.redhat.tuned.policy
+%ghost %{_sysconfdir}/modprobe.d/kvm.rt.tuned.conf
+%{_prefix}/lib/kernel/install.d/92-tuned.install
+
+%files gtk
+%{_sbindir}/tuned-gui
+%if %{with python3}
+%{python3_sitelib}/tuned/gtk
+%else
+%{python2_sitelib}/tuned/gtk
+%endif
+%{_datadir}/tuned/ui
+%{_datadir}/polkit-1/actions/com.redhat.tuned.gui.policy
+%{_datadir}/icons/hicolor/scalable/apps/tuned.svg
+%{_datadir}/applications/tuned-gui.desktop
+
+%files utils
+%doc COPYING
+%{_bindir}/powertop2tuned
+%{_libexecdir}/tuned/pmqos-static*
+
+%files utils-systemtap
+%doc doc/README.utils
+%doc doc/README.scomes
+%doc COPYING
+%{_sbindir}/varnetload
+%{_sbindir}/netdevstat
+%{_sbindir}/diskdevstat
+%{_sbindir}/scomes
+%{_mandir}/man8/varnetload.*
+%{_mandir}/man8/netdevstat.*
+%{_mandir}/man8/diskdevstat.*
+%{_mandir}/man8/scomes.*
+
+%files profiles-sap
+%{_prefix}/lib/tuned/sap-netweaver
+%{_mandir}/man7/tuned-profiles-sap.7*
+
+%files profiles-sap-hana
+%config(noreplace) %{_sysconfdir}/tuned/sap-hana-vmware-variables.conf
+%{_prefix}/lib/tuned/sap-hana
+%{_prefix}/lib/tuned/sap-hana-vmware
+%{_mandir}/man7/tuned-profiles-sap-hana.7*
+
+%files profiles-mssql
+%{_prefix}/lib/tuned/mssql
+%{_mandir}/man7/tuned-profiles-mssql.7*
+
+%files profiles-oracle
+%{_prefix}/lib/tuned/oracle
+%{_mandir}/man7/tuned-profiles-oracle.7*
+
+%files profiles-atomic
+%{_prefix}/lib/tuned/atomic-host
+%{_prefix}/lib/tuned/atomic-guest
+%{_mandir}/man7/tuned-profiles-atomic.7*
+
+%files profiles-realtime
+%config(noreplace) %{_sysconfdir}/tuned/realtime-variables.conf
+%{_prefix}/lib/tuned/realtime
+%{_mandir}/man7/tuned-profiles-realtime.7*
+
+%files profiles-nfv-guest
+%config(noreplace) %{_sysconfdir}/tuned/realtime-virtual-guest-variables.conf
+%{_prefix}/lib/tuned/realtime-virtual-guest
+%{_mandir}/man7/tuned-profiles-nfv-guest.7*
+
+%files profiles-nfv-host
+%config(noreplace) %{_sysconfdir}/tuned/realtime-virtual-host-variables.conf
+%{_prefix}/lib/tuned/realtime-virtual-host
+%{_mandir}/man7/tuned-profiles-nfv-host.7*
+
+%files profiles-nfv
+%doc %{docdir}/README.NFV
+
+%files profiles-cpu-partitioning
+%config(noreplace) %{_sysconfdir}/tuned/cpu-partitioning-variables.conf
+%{_prefix}/lib/tuned/cpu-partitioning
+%{_mandir}/man7/tuned-profiles-cpu-partitioning.7*
+
+%files profiles-compat
+%{_prefix}/lib/tuned/default
+%{_prefix}/lib/tuned/desktop-powersave
+%{_prefix}/lib/tuned/laptop-ac-powersave
+%{_prefix}/lib/tuned/server-powersave
+%{_prefix}/lib/tuned/laptop-battery-powersave
+%{_prefix}/lib/tuned/enterprise-storage
+%{_prefix}/lib/tuned/spindown-disk
+%{_mandir}/man7/tuned-profiles-compat.7*
+
+%changelog
+* Fri Feb 22 2019 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-15
+- Fixed disk plugin to correctly match devices with python3
+  Resolves: rhbz#1676513
+
+* Tue Jan  8 2019 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-14
+- Updated mssql tuning
+  Resolves: rhbz#1660178
+
+* Fri Dec 14 2018 Ondřej Lysoněk <olysonek@redhat.com> - 2.10.0-13
+- Fix excessive CPU usage in the scheduler plugin
+- Resolves: rhbz#1659140
+
+* Mon Dec 10 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-12
+- Added workaround for s390x zipl not supporting multiple initrds
+  Related: rhbz#1576435
+
+* Sun Dec  9 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-11
+- Added support for BLS
+  Resolves: rhbz#1576435
+
+* Thu Dec  6 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-10
+- Reworked setup_kvm_mod_low_latency to count with kernel changes
+  Resolves: rhbz#1653819
+
+* Tue Nov 27 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-9
+- realtime-virtual-guest/host: start/stop rt-entsk daemon on
+  initialization/shutdown
+  resolves: rhbz#1619822
+
+* Tue Nov 27 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-8
+- Disable ksm once, re-enable it on full rollback
+  Resolves: rhbz#1652076
+
+* Wed Oct 10 2018 Ondřej Lysoněk <olysonek@redhat.com> - 2.10.0-7
+- Make python3-dmidecode a weak dependency as it's x86_64 only
+- Resolves: rhbz#1565598
+
+* Tue Oct 09 2018 Ondřej Lysoněk <olysonek@redhat.com> - 2.10.0-6
+- Fix rules for profile recommendation
+- Resolves: rhbz#1565598
+
+* Wed Aug  8 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-5
+- use online CPUs for cpusets calculations instead of present CPUs
+  resolves: rhbz#1613832
+
+* Wed Jul 11 2018 Ondřej Lysoněk <olysonek@redhat.com> - 2.10.0-4
+- Fix a traceback in tuned-gui
+
+* Tue Jul 10 2018 Ondřej Lysoněk <olysonek@redhat.com> - 2.10.0-3
+- tuned-adm: Fix a traceback when run without action specified
+
+* Mon Jul  9 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-2
+- used python intepreter path from the rpm macro
+
+* Wed Jul  4 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-1
+- new release
+  - rebased tuned to latest upstream
+    related: rhbz#1546598
+  - IRQ affinity handled by scheduler plugin
+    resolves: rhbz#1590937
+
+* Mon Jun 25 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.10.0-0.1.rc1
+- new release
+  - rebased tuned to latest upstream
+    resolves: rhbz#1546598
+  - script: show stderr output in the log
+  - realtime-virtual-host: script.sh: add error checking
+  - man: improved tuned-profiles-cpu-partitioning.7
+  - bootloader: check if grub2_cfg_file_name is None in _remove_grub2_tuning()
+  - plugin_scheduler: whitelist/blacklist processed also for thread names
+  - bootloader: patch all GRUB2 config files
+  - profiles: added mssql profile
+  - tuned-adm: print log excerpt when changing profile
+  - cpu-partitioning: use no_balance_cores instead of no_rebalance_cores
+  - sysctl: support assignment modifiers as other plugins do
+  - oracle: fixed ip_local_port_range parity warning
+    resolves: rhbz#1527219
+  - Fix verifying cpumask on systems with more than 32 cores
+    resolves: rhbz#1528368
+  - oracle: updated the profile to be in sync with KCS 39188
+    resolves: rhbz#1447323
+
+* Fri Jun  8 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.9.0-10.20180430git5d0a9d91
+- Fixed python3-gobject-base requirement
+
+* Thu May 17 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.9.0-9.20180430git5d0a9d91
+- Bumped release to fix conflict caused by automerge
+
+* Mon Apr 30 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.9.0-1.20180430git5d0a9d91
+- New version
+- Dropped plugin-disk-traceback-fix patch (upstreamed)
+
+* Fri Mar 23 2018 Jaroslav Škarvada <jskarvad@redhat.com> - 2.8.0-6
+- Dropped qemu-kvm-tools-rhev requirement, now satisfied by
+  tuned-profiles-nfv-host-bin
+  Related: rhbz#1504681
+
+* Mon Aug 21 2017 Jaroslav Škarvada <jskarvad@redhat.com> - 2.8.0-5
+- kernel-tools made weak dependency
+
+* Thu Jul 27 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.8.0-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Mon Jul 24 2017 Jaroslav Škarvada <jskarvad@redhat.com> - 2.8.0-3
+- fixed traceback in disk plugin if dynamic tuning is enabled
+
+* Fri Apr 28 2017 Jaroslav Škarvada <jskarvad@redhat.com> - 2.8.0-2
+- qemu-kvm-tools-rhev made weak dependency
+
+* Fri Apr  7 2017 Jaroslav Škarvada <jskarvad@redhat.com> - 2.8.0-1
+- new release
+  - rebase tuned to latest upstream
+    resolves: rhbz#1388454
+  - cpu-partitioning: enabled timer migration
+    resolves: rhbz#1408308
+  - cpu-partitioning: disabled kvmclock sync and ple
+    resolves: rhbz#1395855
+  - spec: muted error if there is no selinux support
+    resolves: rhbz#1404214
+  - units: implemented instance priority
+    resolves: rhbz#1246172
+  - bootloader: added support for initrd overlays
+    resolves: rhbz#1414098
+  - cpu-partitioning: set CPUAffinity early in initrd image
+    resolves: rhbz#1394965
+  - cpu-partitioning: set workqueue affinity early
+    resolves: rhbz#1395899
+  - scsi_host: fixed probing of ALPM, missing ALPM logged as info
+    resolves: rhbz#1416712
+  - added new profile cpu-partitioning
+    resolves: rhbz#1359956
+  - bootloader: improved inheritance
+    resolves: rhbz#1274464
+  - units: mplemented udev-based regexp device matching
+    resolves: rhbz#1251240
+  - units: introduced pre_script, post_script
+    resolves: rhbz#1246176
+  - realtime-virtual-host: accommodate new ktimersoftd thread
+    resolves: rhbz#1332563
+  - defirqaffinity: fixed traceback due to syntax error
+    resolves: rhbz#1369791
+  - variables: support inheritance of variables
+    resolves: rhbz#1433496
+  - scheduler: added support for cores isolation
+    resolves: rhbz#1403309
+  - tuned-profiles-nfv splitted to host/guest and dropped unneeded dependency
+    resolves: rhbz#1413111
+  - desktop: fixed typo in profile summary
+    resolves: rhbz#1421238
+  - with systemd don't do full rollback on shutdown / reboot
+    resolves: rhbz#1421286
+  - builtin functions: added virt_check function and support to include
+    resolves: rhbz#1426654
+  - cpulist_present: explicitly sorted present CPUs
+    resolves: rhbz#1432240
+  - plugin_scheduler: fixed initialization
+    resolves: rhbz#1433496
+  - log errors when applying a profile fails
+    resolves: rhbz#1434360
+  - systemd: added support for older systemd CPUAffinity syntax
+    resolves: rhbz#1441791
+  - scheduler: added workarounds for low level exceptions from
+    python-linux-procfs
+    resolves: rhbz#1441792
+  - bootloader: workaround for adding tuned_initrd to new kernels on restart
+    resolves: rhbz#1441797
+
+* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Mon Oct 17 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.7.1-3
+- Fixed traceback when non-existent profile is queried through
+  tuned-adm profile_info
+  Resolves: rhbz#1385145
+
+* Wed Sep 21 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.7.1-2
+- Fixed pkexec
+  Resolves: rhbz#1377896
+
+* Tue Aug  2 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.7.1-1
+- New release
+  Resolves: rhbz#1362481
+- Dropped tuned-gui-traceback-fix and tuned-adm-list-no-dbus-traceback-fix
+  patches (both upstreamed)
+
+* Thu Jul 21 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.7.0-2
+- Fixed tuned-gui traceback (by tuned-gui-traceback-fix patch)
+  Resolves: rhbz#1358846
+- Fixed 'tuned-adm list' traceback if daemon is not running
+  (by tuned-adm-list-no-dbus-traceback-fix patch)
+
+* Tue Jul 19 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.7.0-1
+- new-release
+  - gui: fixed save profile
+    resolves: rhbz#1242491
+  - tuned-adm: added --ignore-missing parameter
+    resolves: rhbz#1243807
+  - plugin_vm: added transparent_hugepage alias
+    resolves: rhbz#1249610
+  - plugins: added modules plugin
+    resolves: rhbz#1249618
+  - plugin_cpu: do not show error if cpupower or x86_energy_perf_policy are
+    missing
+    resolves: rhbz#1254417
+  - tuned-adm: fixed restart attempt if tuned is not running
+    resolves: rhbz#1258755
+  - nfv: avoided race condition by using synchronous mode
+    resolves: rhbz#1259039
+  - realtime: added check for isolcpus sanity
+    resolves: rhbz#1264128
+  - pm_qos: fixed exception if PM_QoS is not available
+    resolves: rhbz#1296137
+  - plugin_sysctl: reapply system sysctl after Tuned sysctl are applied
+    resolves: rhbz#1302953
+  - atomic: increase number of inotify watches
+    resolves: rhbz#1322001
+  - realtime-virtual-host/guest: added rcu_nocbs kernel boot parameter
+    resolves: rhbz#1334479
+  - realtime: fixed kernel.sched_rt_runtime_us to be -1
+    resolves: rhbz#1346715
+  - tuned-adm: fixed detection of no_daemon mode
+    resolves: rhbz#1351536
+  - plugin_base: correctly strip assignment modifiers even if not used
+    resolves: rhbz#1353142
+  - plugin_disk: try to workaround embedded '/' in device names
+    related: rhbz#1353142
+  - sap-hana: explicitly setting kernel.numa_balancing = 0 for better performance
+    resolves: rhbz#1355768
+  - switched to polkit authorization
+    resolves: rhbz#1095142
+  - plugins: added scsi_host plugin
+    resolves: rhbz#1246992
+  - spec: fixed conditional support for grub2 to work with selinux
+    resolves: rhbz#1351937
+  - gui: added tuned icon and desktop file
+    resolves: rhbz#1356369
+
+* Tue Jul 19 2016 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.6.0-3
+- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages
+
+* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.6.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Tue Jan  5 2016 Jaroslav Škarvada <jskarvad@redhat.com> - 2.6.0-1
+- new-release
+  - plugin_cpu: do not show error if cpupower or x86_energy_perf_policy are missing
+  - plugin_sysctl: fixed quoting of sysctl values
+    resolves: rhbz#1254538
+  - tuned-adm: added log file location hint to verify command output
+  - libexec: fixed listdir and isdir in defirqaffinity.py
+    resolves: rhbz#1252160
+  - plugin_cpu: save and restore only intel pstate attributes that were changed
+    resolves: rhbz#1252156
+  - functions: fixed sysfs save to work with options
+    resolves: rhbz#1251507
+  - plugins: added scsi_host plugin
+  - tuned-adm: fixed restart attempt if tuned is not running
+  - spec: fixed post scriptlet to work without grub
+    resolves: rhbz#1265654
+  - tuned-profiles-nfv: fix find-lapictscdeadline-optimal.sh for CPUS where ns > 6500
+    resolves: rhbz#1267284
+  - functions: fixed restore_logs_syncing to preserve SELinux context on rsyslog.conf
+    resolves: rhbz#1268901
+  - realtime: set unboud workqueues cpumask
+    resolves: rhbz#1259043
+  - spec: correctly remove tuned footprint from /etc/default/grub
+    resolves: rhbz#1268845
+  - gui: fixed creation of new profile
+    resolves: rhbz#1274609
+  - profiles: removed nohz_full from the realtime profile
+    resolves: rhbz#1274486
+  - profiles: Added nohz_full and nohz=on to realtime guest/host profiles
+    resolves: rhbz#1274445
+  - profiles: fixed lapic_timer_adv_ns cache
+    resolves: rhbz#1259452
+  - plugin_sysctl: pass verification even if the option doesn't exist
+    related: rhbz#1252153
+  - added support for 'summary' and 'description' of profiles,
+    extended D-Bus API for Cockpit
+    related: rhbz#1228356
+
+* Wed Aug 12 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.5.1-2
+- packaging fixes for rpm-4.12.90
+- dropped qemu-kvm-tools-rhev requirement (not in Fedora)
+
+* Tue Aug  4 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.5.1-1
+- new-release
+  related: rhbz#1155052
+  - plugin_scheduler: work with nohz_full
+    resolves: rhbz#1247184
+  - fixed realtime-virtual-guest/host profiles packaged twice
+    resolves: rhbz#1249028
+  - fixed requirements of realtime and nfv profiles
+  - fixed tuned-gui not starting
+  - various other minor fixes
+
+* Sun Jul  5 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.5.0-1
+- new-release
+  resolves: rhbz#1155052
+  - add support for ethtool -C to tuned network plugin
+    resolves: rhbz#1152539
+  - add support for ethtool -K to tuned network plugin
+    resolves: rhbz#1152541
+  - add support for calculation of values for the kernel command line
+    resolves: rhbz#1191595
+  - no error output if there is no hdparm installed
+    resolves: rhbz#1191775
+  - do not run hdparm on hotplug events if there is no hdparm tuning
+    resolves: rhbz#1193682
+  - add oracle tuned profile
+    resolves: rhbz#1196298
+  - fix bash completions for tuned-adm
+    resolves: rhbz#1207668
+  - add glob support to tuned sysfs plugin
+    resolves: rhbz#1212831
+  - add tuned-adm verify subcommand
+    resolves: rhbz#1212836
+  - do not install tuned kernel command line to rescue kernels
+    resolves: rhbz#1223864
+  - add variables support
+    resolves: rhbz#1225124
+  - add built-in support for unit conversion into tuned
+    resolves: rhbz#1225135
+  - fix vm.max_map_count setting in sap-netweaver profile
+    resolves: rhbz#1228562
+  - add tuned profile for RHEL-RT
+    resolves: rhbz#1228801
+  - plugin_scheduler: added support for runtime tuning of processes
+    resolves: rhbz#1148546
+  - add support for changing elevators on xvd* devices (Amazon EC2)
+    resolves: rhbz#1170152
+  - add workaround to be run after systemd-sysctl
+    resolves: rhbz#1189263
+  - do not change settings of transparent hugepages if set in kernel cmdline
+    resolves: rhbz#1189868
+  - add tuned profiles for RHEL-NFV
+    resolves: rhbz#1228803
+  - plugin_bootloader: apply $tuned_params to existing kernels
+    resolves: rhbz#1233004
+
+* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.4.1-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Thu Apr 30 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.1-5
+- fixed configobj class imports
+  resolves: rhbz#1217327
+
+* Thu Apr  2 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.1-4
+- fixed bash completion
+  resolves: rhbz#1207668
+
+* Fri Jan  9 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.1-3
+- fixed KeyError exception in powertop2tuned
+
+* Mon Jan  5 2015 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.1-2
+- remove 00_tuned grub2 template upon tuned uninstall
+  resolves: rhbz#1178310
+
+* Thu Oct 16 2014 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.1-1
+- new-release
+  - fixed return code of tuned grub template
+    resolves: rhbz#1151768
+  - plugin_bootloader: fix for multiple parameters on command line
+    related: rhbz#1148711
+  - tuned-adm: fixed traceback on "tuned-adm list"
+    resolves: rhbz#1149162
+  - plugin_bootloader is automatically disabled if grub2 is not found
+    resolves: rhbz#1150047
+  - plugin_disk: set_spindown and set_APM made independent
+    resolves: rhbz#976725
+
+* Wed Oct  1 2014 Jaroslav Škarvada <jskarvad@redhat.com> - 2.4.0-1
+- new-release
+  resolves: rhbz#1093883
+  - fixed traceback if profile cannot be loaded
+    related: rhbz#953128
+  - powertop2tuned: fixed traceback if rewriting file instead of dir
+    resolves: rhbz#963441
+  - throughput-performance: altered dirty ratios for better performance
+    resolves: rhbz#1043533
+  - latency-performance: leaving THP on its default
+    resolves: rhbz#1064510
+  - used throughput-performance profile on server by default
+    resolves: rhbz#1063481
+  - network-latency: added new profile
+    resolves: rhbz#1052418
+  - network-throughput: added new profile
+    resolves: rhbz#1052421
+  - recommend.conf: fixed config file
+    resolves: rhbz#1069123
+  - systemd: added cpupower.service conflict
+    resolves: rhbz#1073392
+  - balanced: used medium_power ALPM policy
+  - added support for >, < assignment modifiers in tuned.conf
+  - handled root block devices
+  - balanced: used conservative CPU governor
+    resolves: rhbz#1124125
+  - plugins: added selinux plugin
+  - plugin_net: added nf_conntrack_hashsize parameter
+  - profiles: added atomic-host profile
+    resolves: rhbz#1091977
+  - profiles: added atomic-guest profile
+    resolves: rhbz#1091979
+  - moved profile autodetection from post install script to tuned daemon
+    resolves: rhbz#1144067
+  - profiles: included sap-hana and sap-hana-vmware profiles
+  - man: structured profiles manual pages according to sub-packages
+  - added missing hdparm dependency
+    resolves: rhbz#1144858
+  - improved error handling of switch_profile
+    resolves: rhbz#1068699
+  - tuned-adm: active: detect whether tuned deamon is running
+    related: rhbz#1068699
+  - removed active_profile from RPM verification
+    resolves: rhbz#1104126
+  - plugin_disk: readahead value can be now specified in sectors
+    resolves: rhbz#1127127
+  - plugins: added bootloader plugin
+    resolves: rhbz#1044111
+  - plugin_disk: added error counter to hdparm calls
+  - plugins: added scheduler plugin
+    resolves: rhbz#1100826
+  - added tuned-gui
+
+* Thu Mar  6 2014 Jaroslav Škarvada <jskarvad@redhat.com> - 2.3.0-3
+- added kernel-tools requirement
+  resolves: rhbz#1072981
+
+* Fri Nov  8 2013 Jaroslav Škarvada <jskarvad@redhat.com> - 2.3.0-2
+- fixed race condition in the start/stop code
+  resolves: rhbz#1028119
+- improved tuned responsiveness
+  resolves: rhbz#1028122
+
+* Wed Nov  6 2013 Jaroslav Škarvada <jskarvad@redhat.com> - 2.3.0-1
+- new-release
+  resolves: rhbz#1020743
+  - audio plugin: fixed audio settings in standard profiles
+    resolves: rhbz#1019805
+  - video plugin: fixed tunings
+  - daemon: fixed crash if preset profile is not available
+    resolves: rhbz#953128
+  - man: various updates and corrections
+  - functions: fixed usb and bluetooth handling
+  - tuned: switched to lightweighted pygobject3-base
+  - daemon: added global config for dynamic_tuning
+    resolves: rhbz#1006427
+  - utils: added pmqos-static script for debug purposes
+    resolves: rhbz#1015676
+  - throughput-performance: various fixes
+    resolves: rhbz#987570
+  - tuned: added global option update_interval
+  - plugin_cpu: added support for x86_energy_perf_policy
+    resolves: rhbz#1015675
+  - dbus: fixed KeyboardInterrupt handling
+  - plugin_cpu: added support for intel_pstate
+    resolves: rhbz#996722
+  - profiles: various fixes
+    resolves: rhbz#922068
+  - profiles: added desktop profile
+    resolves: rhbz#996723
+  - tuned-adm: implemented non DBus fallback control
+  - profiles: added sap profile
+  - tuned: lowered CPU usage due to python bug
+    resolves: rhbz#917587
+
+* Tue Mar 19 2013 Jaroslav Škarvada <jskarvad@redhat.com> - 2.2.2-1
+- new-release:
+  - cpu plugin: fixed cpupower workaround
+  - cpu plugin: fixed crash if cpupower is installed
+
+* Fri Mar  1 2013 Jaroslav Škarvada <jskarvad@redhat.com> - 2.2.1-1
+- new release:
+  - audio plugin: fixed error handling in _get_timeout
+  - removed cpupower dependency, added sysfs fallback
+  - powertop2tuned: fixed parser crash on binary garbage
+    resolves: rhbz#914933
+  - cpu plugin: dropped multicore_powersave as kernel upstream already did
+  - plugins: options manipulated by dynamic tuning are now correctly saved and restored
+  - powertop2tuned: added alias -e for --enable option
+  - powertop2tuned: new option -m, --merge-profile to select profile to merge
+  - prefer transparent_hugepage over redhat_transparent_hugepage
+  - recommend: use recommend.conf not autodetect.conf
+  - tuned.service: switched to dbus type service
+    resolves: rhbz#911445
+  - tuned: new option --pid, -P to write PID file
+  - tuned, tuned-adm: added new option --version, -v to show version
+  - disk plugin: use APM value 254 for cleanup / APM disable instead of 255
+    resolves: rhbz#905195
+  - tuned: new option --log, -l to select log file
+  - powertop2tuned: avoid circular deps in include (one level check only)
+  - powertop2tuned: do not crash if powertop is not installed
+  - net plugin: added support for wake_on_lan static tuning
+    resolves: rhbz#885504
+  - loader: fixed error handling
+  - spec: used systemd-rpm macros
+    resolves: rhbz#850347
+
+* Mon Jan 28 2013 Jan Vcelak <jvcelak@redhat.com> 2.2.0-1
+- new release:
+  - remove nobarrier from virtual-guest (data loss prevention)
+  - devices enumeration via udev, instead of manual retrieval
+  - support for dynamically inserted devices (currently disk plugin)
+  - dropped rfkill plugins (bluetooth and wifi), the code didn't work
+
+* Wed Jan  2 2013 Jaroslav Škarvada <jskarvad@redhat.com> - 2.1.2-1
+- new release:
+  - systemtap {disk,net}devstat: fix typo in usage
+  - switched to configobj parser
+  - latency-performance: disabled THP
+  - fixed fd leaks on subprocesses
+
+* Thu Dec 06 2012 Jan Vcelak <jvcelak@redhat.com> 2.1.1-1
+- fix: powertop2tuned execution
+- fix: ownership of /etc/tuned
+
+* Mon Dec 03 2012 Jan Vcelak <jvcelak@redhat.com> 2.1.0-1
+- new release:
+  - daemon: allow running without selected profile
+  - daemon: fix profile merging, allow only safe characters in profile names
+  - daemon: implement missing methods in DBus interface
+  - daemon: implement profile recommendation
+  - daemon: improve daemonization, PID file handling
+  - daemon: improved device matching in profiles, negation possible
+  - daemon: various internal improvements
+  - executables: check for EUID instead of UID
+  - executables: run python with -Es to increase security
+  - plugins: cpu - fix cpupower execution
+  - plugins: disk - fix option setting
+  - plugins: mounts - new, currently supports only barriers control
+  - plugins: sysctl - fix a bug preventing settings application
+  - powertop2tuned: speedup, fix crashes with non-C locales
+  - powertop2tuned: support for powertop 2.2 output
+  - profiles: progress on replacing scripts with plugins
+  - tuned-adm: bash completion - suggest profiles from all supported locations
+  - tuned-adm: complete switch to D-bus
+  - tuned-adm: full control to users with physical access
+
+* Mon Oct 08 2012 Jaroslav Škarvada <jskarvad@redhat.com> - 2.0.2-1
+- New version
+- Systemtap scripts moved to utils-systemtap subpackage
+
+* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jun 12 2012 Jaroslav Škarvada <jskarvad@redhat.com> - 2.0.1-3
+- another powertop-2.0 compatibility fix
+  Resolves: rhbz#830415
+
+* Tue Jun 12 2012 Jan Kaluza <jkaluza@redhat.com> - 2.0.1-2
+- fixed powertop2tuned compatibility with powertop-2.0
+
+* Tue Apr 03 2012 Jaroslav Škarvada <jskarvad@redhat.com> - 2.0.1-1
+- new version
+
+* Fri Mar 30 2012 Jan Vcelak <jvcelak@redhat.com> 2.0-1
+- first stable release