new release

rebased tuned to latest upstream
    resolves: RHEL-94809
  tuned-ppd: renamed thinkpad_function_keys as sysfs_acpi_monitor
  tuned-ppd: enabled sysfs_acpi_monitor by default
  tuned-ppd: fixed inotify watch for performance degradation
  tuned-ppd: pinned virtual files in memory for inotify
  fixed instance priority inheritance
    resolves: RHEL-94842
  hotplug: added fixes for device remove race condition
  tuned-main.conf: added startup_udev_settle_wait option
    resolves: RHEL-88238
  functions: silenced errors if module kvm_intel does not exist
  functions: make calc_isolated_cores return CPU ranges
  scsi: used 'med_power_with_dipm' for SATA ALPM
  scsi: do not set ALPM on external SATA ports
    resolves: RHEL-79913
  network_latency: Set non-zero rcutree.nohz_full_patience_delay
  realtime: disable appropriate P-State drivers
  plugin_disk: added support for MMC (MultiMediaCard) devices
  udev: fix possible traceback in device matcher
    resolves: RHEL-97087
  udev-settle: obey udev buffer size and handle possible tracebacks
    resolves: RHEL-92637
  daemon: re-raise daemon init exception in no-daemon mode
  vm: deprecate dirty_ratio in favour of dirty_bytes with percents
  gui: fix the profile deleter script
This commit is contained in:
Jaroslav Škarvada 2025-08-18 01:02:11 +02:00
parent 4bf638ab64
commit 1b1e8461f1
3 changed files with 53 additions and 328 deletions

View File

@ -1 +1 @@
SHA512 (tuned-2.25.1.tar.gz) = fa5ac9d818d11b118fb7c26db28993b704f590070edbece570fee1a6c60a1f5f850b711683c45b46f33d9b056a84e43ced2c4c1ee58e9ef3d1fd035a4c1d4de4 SHA512 (tuned-2.26.0-rc.1.tar.gz) = 31a54a43db676761610723e46abc7d280f5e547291146af9c210ac2d60376fa73941f7c39ffc197a443b459abe0bfe29e813c1450f5d0304ec148f3b2ce96c2a

View File

@ -1,311 +0,0 @@
From 91cb383ad7339873da3480463061500a308ba825 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavol=20=C5=BD=C3=A1=C4=8Dik?= <zacik.pa@gmail.com>
Date: Fri, 31 Jan 2025 12:43:08 +0100
Subject: [PATCH 1/2] bootloader: Simplify tuning of rpm-ostree kargs
The bootloader plugin claims that it does not mess
with existing kernel parameters; make sure we adhere
to that also for rpm-ostree systems:
1. Only append a new karg if the same key=value pair
does not already appear in kernel parameters. If we would
duplicate it, it would not be possible to determine which
one to delete when unapplying the profile.
2. Do not delete existing key=value pairs when the profile
adds a karg with another value for the key. A single key can
appear multiple times in the kernel parameter list with different
values.
Also make sure new kargs are added exactly in the order in which
they appear in the profile. This is especially important for kargs
related to hugepages.
Resolves: RHEL-45836
---
tuned/consts.py | 1 -
tuned/plugins/plugin_bootloader.py | 142 +++++++++++------------------
2 files changed, 53 insertions(+), 90 deletions(-)
diff --git a/tuned/consts.py b/tuned/consts.py
index 577ad9583..a92c78060 100644
--- a/tuned/consts.py
+++ b/tuned/consts.py
@@ -43,7 +43,6 @@
INITRD_IMAGE_DIR = "/boot"
BOOT_CMDLINE_TUNED_VAR = "TUNED_BOOT_CMDLINE"
BOOT_CMDLINE_INITRD_ADD_VAR = "TUNED_BOOT_INITRD_ADD"
-BOOT_CMDLINE_KARGS_DELETED_VAR = "TUNED_BOOT_KARGS_DELETED"
BOOT_CMDLINE_FILE = "/etc/tuned/bootcmdline"
PETITBOOT_DETECT_DIR = "/sys/firmware/opal"
MACHINE_ID_FILE = "/etc/machine-id"
diff --git a/tuned/plugins/plugin_bootloader.py b/tuned/plugins/plugin_bootloader.py
index 4c66189fb..07a66d265 100644
--- a/tuned/plugins/plugin_bootloader.py
+++ b/tuned/plugins/plugin_bootloader.py
@@ -209,24 +209,6 @@ def _get_config_options(cls):
"skip_grub_config": None,
}
- @staticmethod
- def _options_to_dict(options, omit=""):
- """
- Returns dict created from options
- e.g.: _options_to_dict("A=A A=B A B=A C=A", "A=B B=A B=B") returns {'A': ['A', None], 'C': ['A']}
- """
- d = {}
- omit = omit.split()
- for o in options.split():
- if o not in omit:
- arr = o.split('=', 1)
- d.setdefault(arr[0], []).append(arr[1] if len(arr) > 1 else None)
- return d
-
- @staticmethod
- def _dict_to_options(d):
- return " ".join([k + "=" + v1 if v1 is not None else k for k, v in d.items() for v1 in v])
-
def _rpm_ostree_status(self):
"""
Returns status of rpm-ostree transactions or None if not run on rpm-ostree system
@@ -241,68 +223,45 @@ def _rpm_ostree_status(self):
return None
return splited[1]
- def _wait_till_idle(self):
+ def _wait_till_rpm_ostree_idle(self):
+ """Check that rpm-ostree is idle, allowing some waiting time."""
sleep_cycles = 10
sleep_secs = 1.0
- for i in range(sleep_cycles):
+ for _ in range(sleep_cycles):
if self._rpm_ostree_status() == "idle":
return True
sleep(sleep_secs)
- if self._rpm_ostree_status() == "idle":
- return True
- return False
+ return self._rpm_ostree_status() == "idle"
+
+ def _get_rpm_ostree_kargs(self):
+ """Retrieve the output of rpm-ostree kargs, i.e., current default kernel arguments."""
+ if not self._wait_till_rpm_ostree_idle():
+ log.error("Error getting rpm-ostree kargs: rpm-ostree is busy")
+ return None
+ (rc, out, err) = self._cmd.execute(["rpm-ostree", "kargs"], return_err=True)
+ if out:
+ log.debug("rpm-ostree kargs: %s" % out)
+ if rc != 0:
+ log.error("Error getting rpm-ostree kargs: %s" % err)
+ return None
+ return out
- def _rpm_ostree_kargs(self, append={}, delete={}):
+ def _modify_rpm_ostree_kargs(self, delete_kargs=[], append_kargs=[]):
"""
- Method for appending or deleting rpm-ostree karg
- returns None if rpm-ostree not present or is run on not ostree system
- or tuple with new kargs, appended kargs and deleted kargs
+ Modify (delete and append) kernel arguments in a rpm-ostree system.
+ Return a boolean indicating whether the operation was successful.
"""
- (rc, out, err) = self._cmd.execute(['rpm-ostree', 'kargs'], return_err=True)
- log.debug("rpm-ostree output stdout:\n%s\nstderr:\n%s" % (out, err))
- if rc != 0:
- return None, None, None
- kargs = self._options_to_dict(out)
-
- if not self._wait_till_idle():
- log.error("Cannot wait for transaction end")
- return None, None, None
-
- deleted = {}
- delete_params = self._dict_to_options(delete).split()
- # Deleting kargs, e.g. deleting added kargs by profile
- for k, val in delete.items():
- for v in val:
- kargs[k].remove(v)
- deleted[k] = val
-
- appended = {}
- append_params = self._dict_to_options(append).split()
- # Appending kargs, e.g. new kargs by profile or restoring kargs replaced by profile
- for k, val in append.items():
- if kargs.get(k):
- # If there is karg that we add with new value we want to delete it
- # and store old value for restoring after profile unload
- log.debug("adding rpm-ostree kargs %s: %s for delete" % (k, kargs[k]))
- deleted.setdefault(k, []).extend(kargs[k])
- delete_params.extend([k + "=" + v if v is not None else k for v in kargs[k]])
- kargs[k] = []
- kargs.setdefault(k, []).extend(val)
- appended[k] = val
-
- if append_params == delete_params:
- log.info("skipping rpm-ostree kargs - append == deleting (%s)" % append_params)
- return kargs, appended, deleted
-
- log.info("rpm-ostree kargs - appending: '%s'; deleting: '%s'" % (append_params, delete_params))
- (rc, _, err) = self._cmd.execute(['rpm-ostree', 'kargs'] +
- ['--append=%s' % v for v in append_params] +
- ['--delete=%s' % v for v in delete_params], return_err=True)
+ if not self._wait_till_rpm_ostree_idle():
+ log.error("Error modifying rpm-ostree kargs: rpm-ostree is busy")
+ return False
+ (rc, _, err) = self._cmd.execute(
+ ["rpm-ostree", "kargs"] +
+ ["--delete=%s" % karg for karg in delete_kargs] +
+ ["--append=%s" % karg for karg in append_kargs], return_err=True)
if rc != 0:
- log.error("Something went wrong with rpm-ostree kargs\n%s" % (err))
- return self._options_to_dict(out), None, None
- else:
- return kargs, appended, deleted
+ log.error("Error modifying rpm-ostree kargs: %s" % err)
+ return False
+ return True
def _get_effective_options(self, options):
"""Merge provided options with plugin default options and merge all cmdline.* options."""
@@ -368,18 +327,16 @@ def _remove_grub2_tuning(self):
log.info("removing initrd image '%s'" % self._initrd_dst_img_val)
self._cmd.unlink(self._initrd_dst_img_val)
- def _get_rpm_ostree_changes(self):
+ def _get_appended_rpm_ostree_kargs(self):
+ """Return the list of kernel arguments that were appended by this profile (in a rpm-ostree system)."""
f = self._cmd.read_file(consts.BOOT_CMDLINE_FILE)
appended = re.search(consts.BOOT_CMDLINE_TUNED_VAR + r"=\"(.*)\"", f, flags=re.MULTILINE)
- appended = appended[1] if appended else ""
- deleted = re.search(consts.BOOT_CMDLINE_KARGS_DELETED_VAR + r"=\"(.*)\"", f, flags=re.MULTILINE)
- deleted = deleted[1] if deleted else ""
- return appended, deleted
+ return appended[1].split() if appended else []
def _remove_rpm_ostree_tuning(self):
- appended, deleted = self._get_rpm_ostree_changes()
- self._rpm_ostree_kargs(append=self._options_to_dict(deleted), delete=self._options_to_dict(appended))
- self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR: "", consts.BOOT_CMDLINE_KARGS_DELETED_VAR: ""})
+ """Remove kernel parameter tuning in a rpm-ostree system."""
+ self._modify_rpm_ostree_kargs(delete_kargs=self._get_appended_rpm_ostree_kargs())
+ self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR: ""})
def _instance_unapply_static(self, instance, rollback = consts.ROLLBACK_SOFT):
if rollback == consts.ROLLBACK_FULL and not self._skip_grub_config_val:
@@ -489,14 +446,22 @@ def _grub2_cfg_patch(self, d):
return True
def _rpm_ostree_update(self):
- appended, _ = self._get_rpm_ostree_changes()
- _cmdline_dict = self._options_to_dict(self._cmdline_val, appended)
- if not _cmdline_dict:
- return None
- (_, _, d) = self._rpm_ostree_kargs(append=_cmdline_dict)
- if d is None:
+ """Apply kernel parameter tuning in a rpm-ostree system."""
+ if self._get_appended_rpm_ostree_kargs():
+ # The kargs are already set in /etc/tuned/bootcmldine,
+ # we are likely post-reboot and done.
+ return
+ profile_kargs = self._cmdline_val.split()
+ active_kargs = self._get_rpm_ostree_kargs()
+ if active_kargs is None:
+ log.error("Not updating kernel arguments, could not read the current ones.")
return
- self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR : self._cmdline_val, consts.BOOT_CMDLINE_KARGS_DELETED_VAR : self._dict_to_options(d)})
+ # Only append key=value pairs that do not yet appear in kernel parameters,
+ # otherwise we would not be able to restore the cmdline to the previous state
+ # via rpm-ostree kargs --delete.
+ kargs_to_append = [karg for karg in profile_kargs if karg not in active_kargs.split()]
+ if self._modify_rpm_ostree_kargs(append_kargs=kargs_to_append):
+ self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR : " ".join(kargs_to_append)})
def _grub2_update(self):
self._grub2_cfg_patch({consts.GRUB2_TUNED_VAR : self._cmdline_val, consts.GRUB2_TUNED_INITRD_VAR : self._initrd_val})
@@ -646,11 +611,10 @@ def _cmdline(self, enabling, value, verify, ignore_missing, instance):
v = self._variables.expand(self._cmd.unquote(value))
if verify:
if self._rpm_ostree:
- rpm_ostree_kargs = self._rpm_ostree_kargs()[0]
- cmdline = self._dict_to_options(rpm_ostree_kargs)
+ cmdline = self._get_rpm_ostree_kargs()
else:
cmdline = self._cmd.read_file("/proc/cmdline")
- if len(cmdline) == 0:
+ if cmdline is None or len(cmdline) == 0:
return None
cmdline_set = set(cmdline.split())
value_set = set(v.split())
From 3e05cb783ee10ea78efb113c54bd2ad7d73a0e2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavol=20=C5=BD=C3=A1=C4=8Dik?= <zacik.pa@gmail.com>
Date: Fri, 16 May 2025 15:13:25 +0200
Subject: [PATCH 2/2] bootloader: Remove previously appended rpm-ostree kargs
If TuneD-appended kargs are present and do not match
the kargs to be appended, we should remove them. This
can happen if there was no profile rollback, e.g.,
when using the no-daemon mode.
Resolves: RHEL-86814
---
tuned/plugins/plugin_bootloader.py | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/tuned/plugins/plugin_bootloader.py b/tuned/plugins/plugin_bootloader.py
index 07a66d265..2711e116f 100644
--- a/tuned/plugins/plugin_bootloader.py
+++ b/tuned/plugins/plugin_bootloader.py
@@ -105,7 +105,7 @@ class BootloaderPlugin(base.Plugin):
----
[main]
include=profile_1
-
+
[bootloader]
cmdline_profile_2=-quiet
----
@@ -114,7 +114,7 @@ class BootloaderPlugin(base.Plugin):
----
[main]
include=profile_1
-
+
[bootloader]
cmdline_profile_1=-quiet
----
@@ -447,20 +447,28 @@ def _grub2_cfg_patch(self, d):
def _rpm_ostree_update(self):
"""Apply kernel parameter tuning in a rpm-ostree system."""
- if self._get_appended_rpm_ostree_kargs():
- # The kargs are already set in /etc/tuned/bootcmldine,
- # we are likely post-reboot and done.
- return
+ appended_kargs = self._get_appended_rpm_ostree_kargs()
profile_kargs = self._cmdline_val.split()
active_kargs = self._get_rpm_ostree_kargs()
if active_kargs is None:
log.error("Not updating kernel arguments, could not read the current ones.")
return
+ # Ignore kargs previously appended by TuneD, these will be removed later.
+ non_tuned_kargs = active_kargs.split()
+ for karg in appended_kargs:
+ non_tuned_kargs.remove(karg)
# Only append key=value pairs that do not yet appear in kernel parameters,
# otherwise we would not be able to restore the cmdline to the previous state
# via rpm-ostree kargs --delete.
- kargs_to_append = [karg for karg in profile_kargs if karg not in active_kargs.split()]
- if self._modify_rpm_ostree_kargs(append_kargs=kargs_to_append):
+ kargs_to_append = [karg for karg in profile_kargs if karg not in non_tuned_kargs]
+ if appended_kargs == kargs_to_append:
+ # The correct kargs are already set in /etc/tuned/bootcmldine,
+ # we are likely post-reboot and done.
+ log.info("Kernel arguments already set, not updating.")
+ return
+ # If there are kargs in /etc/bootcmdline and they do not match
+ # the requested ones, there was no rollback, so remove them now.
+ if self._modify_rpm_ostree_kargs(delete_kargs=appended_kargs, append_kargs=kargs_to_append):
self._patch_bootcmdline({consts.BOOT_CMDLINE_TUNED_VAR : " ".join(kargs_to_append)})
def _grub2_update(self):

View File

@ -34,23 +34,24 @@
%endif %endif
%endif %endif
#%%global prerelease rc %global prerelease rc
#%%global prereleasenum 1 %global prereleasenum 1
%global prerel1 %{?prerelease:.%{prerelease}%{prereleasenum}} %global prerel1 %{?prerelease:.%{prerelease}%{prereleasenum}}
%global prerel2 %{?prerelease:-%{prerelease}.%{prereleasenum}} %global prerel2 %{?prerelease:-%{prerelease}.%{prereleasenum}}
Summary: A dynamic adaptive system tuning daemon Summary: A dynamic adaptive system tuning daemon
Name: tuned Name: tuned
Version: 2.25.1 Version: 2.26.0
Release: 2%{?prerel1}%{?dist} Release: 0.1%{?prerel1}%{?dist}
License: GPL-2.0-or-later AND CC-BY-SA-3.0 License: GPL-2.0-or-later AND CC-BY-SA-3.0
Source0: https://github.com/redhat-performance/%{name}/archive/v%{version}%{?prerel2}/%{name}-%{version}%{?prerel2}.tar.gz Source0: https://github.com/redhat-performance/%{name}/archive/v%{version}%{?prerel2}/%{name}-%{version}%{?prerel2}.tar.gz
# RHEL-9 specific recommend.conf: # RHEL-9 specific recommend.conf:
Source1: recommend.conf Source1: recommend.conf
URL: http://www.tuned-project.org/ URL: http://www.tuned-project.org/
BuildArch: noarch BuildArch: noarch
BuildRequires: systemd, desktop-file-utils BuildRequires: systemd
BuildRequires: desktop-file-utils
%if 0%{?rhel} %if 0%{?rhel}
BuildRequires: asciidoc BuildRequires: asciidoc
%else %else
@ -60,7 +61,8 @@ Requires(post): systemd, virt-what
Requires(preun): systemd Requires(preun): systemd
Requires(postun): systemd Requires(postun): systemd
BuildRequires: make BuildRequires: make
BuildRequires: %{_py}, %{_py}-devel BuildRequires: %{_py}
BuildRequires: %{_py}-devel
# BuildRequires for 'make test' # BuildRequires for 'make test'
# python-mock is needed for python-2.7, but it's not available on RHEL-7, only in the EPEL # python-mock is needed for python-2.7, but it's not available on RHEL-7, only in the EPEL
%if %{without python3} && ( ! 0%{?rhel} || 0%{?rhel} >= 8 || 0%{?epel}) %if %{without python3} && ( ! 0%{?rhel} || 0%{?rhel} >= 8 || 0%{?epel})
@ -76,15 +78,23 @@ Requires: %{_py}-schedutils
# requires for packages with inconsistent python2/3 names # requires for packages with inconsistent python2/3 names
%if %{with python3} %if %{with python3}
# BuildRequires for 'make test' # BuildRequires for 'make test'
BuildRequires: python3-dbus, python3-gobject-base BuildRequires: python3-dbus
Requires: python3-dbus, python3-gobject-base BuildRequires: python3-gobject-base
Requires: python3-dbus
Requires: python3-gobject-base
%else %else
# BuildRequires for 'make test' # BuildRequires for 'make test'
BuildRequires: dbus-python, pygobject3-base BuildRequires: dbus-python
Requires: dbus-python, pygobject3-base BuildRequires: pygobject3-base
Requires: dbus-python
Requires: pygobject3-base
%endif %endif
Requires: virt-what, ethtool, gawk Requires: virt-what
Requires: util-linux, dbus, polkit Requires: ethtool
Requires: gawk
Requires: util-linux
Requires: dbus
Requires: polkit
%if 0%{?fedora} > 22 || 0%{?rhel} > 7 %if 0%{?fedora} > 22 || 0%{?rhel} > 7
Recommends: dmidecode Recommends: dmidecode
# https://src.fedoraproject.org/rpms/tuned/pull-request/8 # https://src.fedoraproject.org/rpms/tuned/pull-request/8
@ -108,7 +118,6 @@ Recommends: subscription-manager
Requires: python3-syspurpose Requires: python3-syspurpose
%endif %endif
%endif %endif
Patch0: tuned-2.25.1-bootc-kargs.patch
%description %description
The tuned package contains a daemon that tunes system settings dynamically. The tuned package contains a daemon that tunes system settings dynamically.
@ -281,7 +290,7 @@ to TuneD from power-profiles-daemon (PPD).
%prep %prep
%autosetup -p1 -n %{name}-%{version}%{?prerel2} %autosetup -p1 -n %{name}-%{version}%{?prerel2}
# Replace the upstream recommend.conf with a RHEL-9-specific one # Replace the upstream recommend.conf with a RHEL-10-specific one
rm -f recommend.conf rm -f recommend.conf
cp -p %{SOURCE1} recommend.conf cp -p %{SOURCE1} recommend.conf
@ -296,10 +305,8 @@ make install DESTDIR="%{buildroot}" BINDIR="%{_bindir}" SBINDIR="%{_sbindir}" \
make install-ppd DESTDIR="%{buildroot}" BINDIR="%{_bindir}" \ make install-ppd DESTDIR="%{buildroot}" BINDIR="%{_bindir}" \
SBINDIR="%{_sbindir}" DOCDIR="%{docdir}" %{make_python_arg} SBINDIR="%{_sbindir}" DOCDIR="%{docdir}" %{make_python_arg}
%if ! 0%{?rhel}
# manual # manual
make install-html DESTDIR=%{buildroot} DOCDIR=%{docdir} make install-html DESTDIR=%{buildroot} DOCDIR=%{docdir}
%endif
# conditional support for grub2, grub2 is not available on all architectures # conditional support for grub2, grub2 is not available on all architectures
# and tuned is noarch package, thus the following hack is needed # and tuned is noarch package, thus the following hack is needed
@ -628,6 +635,35 @@ fi
%config(noreplace) %{_sysconfdir}/tuned/ppd.conf %config(noreplace) %{_sysconfdir}/tuned/ppd.conf
%changelog %changelog
* Sun Aug 17 2025 Jaroslav Škarvada <jskarvad@redhat.com> - 2.26.0-0.1.rc1
- new release
- rebased tuned to latest upstream
resolves: RHEL-94809
- tuned-ppd: renamed thinkpad_function_keys as sysfs_acpi_monitor
- tuned-ppd: enabled sysfs_acpi_monitor by default
- tuned-ppd: fixed inotify watch for performance degradation
- tuned-ppd: pinned virtual files in memory for inotify
- fixed instance priority inheritance
resolves: RHEL-94842
- hotplug: added fixes for device remove race condition
- tuned-main.conf: added startup_udev_settle_wait option
resolves: RHEL-88238
- functions: silenced errors if module kvm_intel does not exist
- functions: make calc_isolated_cores return CPU ranges
- scsi: used 'med_power_with_dipm' for SATA ALPM
- scsi: do not set ALPM on external SATA ports
resolves: RHEL-79913
- network_latency: Set non-zero rcutree.nohz_full_patience_delay
- realtime: disable appropriate P-State drivers
- plugin_disk: added support for MMC (MultiMediaCard) devices
- udev: fix possible traceback in device matcher
resolves: RHEL-97087
- udev-settle: obey udev buffer size and handle possible tracebacks
resolves: RHEL-92637
- daemon: re-raise daemon init exception in no-daemon mode
- vm: deprecate dirty_ratio in favour of dirty_bytes with percents
- gui: fix the profile deleter script
* Thu Jun 05 2025 Pavol Žáčik <pzacik@redhat.com> - 2.25.1-2 * Thu Jun 05 2025 Pavol Žáčik <pzacik@redhat.com> - 2.25.1-2
- Fix handling of kernel arguments on bootc systems - Fix handling of kernel arguments on bootc systems
resolves: RHEL-94185 resolves: RHEL-94185