Apply limit on keylime-policy workers

Resolves: RHEL-114482

Signed-off-by: Sergio Correia <scorreia@redhat.com>
This commit is contained in:
Sergio Correia 2026-05-22 21:31:01 +00:00
parent 0039f51ea0
commit 86d98c9da8
No known key found for this signature in database
GPG Key ID: D0D219ED1F7E762C
2 changed files with 154 additions and 1 deletions

View File

@ -0,0 +1,145 @@
From 6466fcd8071c6332db4c695797ca6a0573e8df23 Mon Sep 17 00:00:00 2001
From: Sergio Correia <scorreia@redhat.com>
Date: Sun, 24 May 2026 20:28:42 +0000
Subject: [PATCH 24/24] Apply limit on keylime-policy workers
Upstream backport: https://github.com/keylime/keylime/pull/1811
Signed-off-by: Sergio Correia <scorreia@redhat.com>
---
keylime/policy/create_runtime_policy.py | 24 ++++++++++++++++++++++--
keylime/policy/rpm_repo.py | 17 +++++++++++++----
2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/keylime/policy/create_runtime_policy.py b/keylime/policy/create_runtime_policy.py
index 8e1c687..2db9b73 100644
--- a/keylime/policy/create_runtime_policy.py
+++ b/keylime/policy/create_runtime_policy.py
@@ -434,6 +434,13 @@ def get_arg_parser(create_parser: _SubparserType, parent_parser: argparse.Argume
dest="remote_rpm_repo",
help="Remote RPM repo URL",
)
+ repo_group.add_argument(
+ "--max-workers",
+ dest="max_workers",
+ type=_positive_int,
+ default=rpm_repo.MAX_WORKERS_DEFAULT,
+ help=f"The maximum number of workers used for RPM processing (must be a positive integer; default {rpm_repo.MAX_WORKERS_DEFAULT}).",
+ )
fs_group.add_argument(
"--algo",
@@ -839,6 +846,19 @@ def _get_digest_algorithm_from_map_list(maplist: Dict[str, List[str]]) -> str:
return algo
+def _positive_int(value: str) -> int:
+ """
+ A custom type function for argparse that checks for a positive integer.
+ """
+ try:
+ ivalue = int(value)
+ if ivalue <= 0:
+ raise argparse.ArgumentTypeError(f"'{value}' is not a positive integer.")
+ return ivalue
+ except ValueError as exc:
+ raise argparse.ArgumentTypeError(f"'{value}' is not a positive integer.") from exc
+
+
def create_runtime_policy(args: argparse.Namespace) -> Optional[RuntimePolicyType]:
"""Create a runtime policy from the input arguments."""
policy = None
@@ -924,7 +944,7 @@ def create_runtime_policy(args: argparse.Namespace) -> Optional[RuntimePolicyTyp
# FIXME: pass the IMA sigs as well.
local_rpm_digests = {}
local_rpm_digests, _imasigs, ok = rpm_repo.analyze_local_repo(
- args.local_rpm_repo, digests=local_rpm_digests
+ args.local_rpm_repo, digests=local_rpm_digests, max_workers=args.max_workers
)
if not ok:
return None
@@ -932,7 +952,7 @@ def create_runtime_policy(args: argparse.Namespace) -> Optional[RuntimePolicyTyp
# FIXME: pass the IMA sigs as well.
remote_rpm_digests = {}
remote_rpm_digests, _imasigs, ok = rpm_repo.analyze_remote_repo(
- args.remote_rpm_repo, digests=remote_rpm_digests
+ args.remote_rpm_repo, digests=remote_rpm_digests, max_workers=args.max_workers
)
if not ok:
return None
diff --git a/keylime/policy/rpm_repo.py b/keylime/policy/rpm_repo.py
index d6a8bda..ab55484 100644
--- a/keylime/policy/rpm_repo.py
+++ b/keylime/policy/rpm_repo.py
@@ -25,6 +25,8 @@ from keylime.types import PathLike_str
logger = Logger().logger()
+MAX_WORKERS_DEFAULT = 8
+
def _parse_rpm_header(hdr: rpm.hdr) -> Tuple[Dict[str, List[str]], Dict[str, List[bytes]]]:
# First, the file digests.
@@ -110,6 +112,7 @@ def analyze_local_repo(
digests: Optional[Dict[str, List[str]]] = None,
imasigs: Optional[Dict[str, List[bytes]]] = None,
jobs: Optional[int] = None,
+ max_workers: int = MAX_WORKERS_DEFAULT,
) -> Tuple[Dict[str, List[str]], Dict[str, List[bytes]], bool]:
"""
Analyze a local repository.
@@ -121,6 +124,7 @@ def analyze_local_repo(
:param imasigs: dict of str and a list of bytes, to store the files and
their associated IMA signatures
:param jobs: integer, the number of jobs to use when processing the rpms
+ :param max_workers: integer, the maximum number of workers used for RPM processing
:return: tuple with the dict of digests, the dict of IMA signatures and a
boolean indicating the success of this method
"""
@@ -163,7 +167,7 @@ def analyze_local_repo(
else:
logger.warning("Warning. Unsigned repository. Continuing the RPM scanning")
- jobs = jobs if jobs else multiprocessing.cpu_count()
+ jobs = jobs if jobs else min(multiprocessing.cpu_count(), max_workers)
if not digests:
digests = {}
@@ -255,7 +259,11 @@ def _parse_xml_file(filepath: str) -> ET.ElementTree:
def _analyze_remote_repo(
- repo: str, digests: Optional[Dict[str, List[str]]], imasigs: Optional[Dict[str, List[bytes]]], jobs: Optional[int]
+ repo: str,
+ digests: Optional[Dict[str, List[str]]],
+ imasigs: Optional[Dict[str, List[bytes]]],
+ jobs: Optional[int],
+ max_workers: int = MAX_WORKERS_DEFAULT,
) -> Tuple[Dict[str, List[str]], Dict[str, List[bytes]], bool]:
# Make the repo ends with "/", so we can be considered as a base URL
repo = repo if (repo).endswith("/") else f"{repo}/"
@@ -319,7 +327,7 @@ def _analyze_remote_repo(
# single thread (asyncio) or multiple process. To avoid change
# all the stack, I go for synchronous functions but with many
# process. In the future we can move all to asyncio.
- jobs = jobs if jobs else (multiprocessing.cpu_count() * 8)
+ jobs = jobs if jobs else max_workers
# Analyze all the RPMs in parallel
with multiprocessing.Pool(jobs) as pool:
@@ -335,10 +343,11 @@ def analyze_remote_repo(
digests: Optional[Dict[str, List[str]]] = None,
imasigs: Optional[Dict[str, List[bytes]]] = None,
jobs: Optional[int] = None,
+ max_workers: int = MAX_WORKERS_DEFAULT,
) -> Tuple[Dict[str, List[str]], Dict[str, List[bytes]], bool]:
"""Analyze a remote repository."""
try:
- return _analyze_remote_repo(str(*repourl), digests, imasigs, jobs)
+ return _analyze_remote_repo(str(*repourl), digests, imasigs, jobs, max_workers)
except Exception as exc:
logger.error(exc)
return {}, {}, False
--
2.47.3

View File

@ -9,7 +9,7 @@
Name: keylime
Version: 7.12.1
Release: 16%{?dist}
Release: 17%{?dist}
Summary: Open source TPM software for Bootstrapping and Maintaining Trust
URL: https://github.com/keylime/keylime
@ -70,6 +70,10 @@ Patch: 0022-CVE-2026-1709.patch
# - https://github.com/keylime/keylime/pull/1845
Patch: 0023-Backport-tenant-version-negotiation-mechanism.patch
# Backport from:
# - https://github.com/keylime/keylime/pull/1811
Patch: 0024-Apply-limit-on-keylime-policy-workers.patch
License: ASL 2.0 and MIT
BuildRequires: git-core
@ -464,6 +468,10 @@ fi
%license LICENSE
%changelog
* Fri May 22 2026 Sergio Correia <scorreia@redhat.com> 7.12.1-17
- Apply limit on keylime-policy workers
Resolves: RHEL-114482
* Fri May 22 2026 Sergio Correia <scorreia@redhat.com> 7.12.1-16
- Add API version negotiation to keylime_tenant
Resolves: RHEL-151705