From b0c330ca0c8b6103892f63ce496e569453b7abbf Mon Sep 17 00:00:00 2001 From: Daniel Hofer Date: Thu, 19 Feb 2026 13:34:52 +0100 Subject: [PATCH 1/2] Fix for DPDK on Debian 13 The path for dpdk-devbind changed in Debian 13 (Trixie). This commit alone is probably not backward compatible. Signed-off-by: Daniel Hofer --- setup_ovs/ovs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup_ovs/ovs.py b/setup_ovs/ovs.py index b140559..2a44a87 100644 --- a/setup_ovs/ovs.py +++ b/setup_ovs/ovs.py @@ -122,7 +122,7 @@ def _bind_dpdk_interfaces(dpdk_interfaces): for nic in dpdk_interfaces: logging.info("Attach {} to DPDK".format(nic)) helpers.run_command( - "/usr/sbin/dpdk-devbind", "--force", "--bind=vfio-pci", nic + "/usr/bin/dpdk-devbind.py", "--force", "--bind=vfio-pci", nic ) From 0d07b778fbb53135127d9a50aa09e6d5da337553 Mon Sep 17 00:00:00 2001 From: Daniel Hofer Date: Fri, 27 Feb 2026 10:18:08 +0100 Subject: [PATCH 2/2] Dynamic DPDK lookup The location of the dpdk-devbind script is now looked up from a list of possible locations. The result of the lookup is cached. Co-authored-by: Claude Signed-off-by: Daniel Hofer --- setup_ovs/helpers.py | 21 +++++++++++++++++++++ setup_ovs/ovs.py | 11 ++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/setup_ovs/helpers.py b/setup_ovs/helpers.py index 5e396ce..2d39215 100644 --- a/setup_ovs/helpers.py +++ b/setup_ovs/helpers.py @@ -1,7 +1,10 @@ # Copyright (C) 2021, RTE (http://www.rte-france.com) # SPDX-License-Identifier: Apache-2.0 +import functools +import os import re +import shutil import subprocess import logging @@ -17,6 +20,24 @@ dry_run = False +@functools.lru_cache(maxsize=None) +def find_command(logical_name, *candidates): + """Locate a system command by trying candidate names/paths.""" + for candidate in candidates: + if os.path.isabs(candidate): + if os.path.isfile(candidate) and os.access(candidate, os.X_OK): + logging.debug("Found %s at %s", logical_name, candidate) + return candidate + else: + resolved = shutil.which(candidate) + if resolved: + logging.debug("Found %s at %s (via PATH)", logical_name, resolved) + return resolved + raise FileNotFoundError( + "Could not find {}: looked for {}".format(logical_name, ", ".join(candidates)) + ) + + def run_command(*cmd_args, **kargs): """ Shell runner helper diff --git a/setup_ovs/ovs.py b/setup_ovs/ovs.py index 2a44a87..959c8c2 100644 --- a/setup_ovs/ovs.py +++ b/setup_ovs/ovs.py @@ -115,15 +115,20 @@ def clear_tap(config): interface, ) +_DPDK_DEVBIND_CANDIDATES = ( + "/usr/bin/dpdk-devbind.py", + "/usr/sbin/dpdk-devbind", +) + + def _bind_dpdk_interfaces(dpdk_interfaces): """ Bind NIC in DPDK """ + dpdk_devbind = helpers.find_command("dpdk-devbind", *_DPDK_DEVBIND_CANDIDATES) for nic in dpdk_interfaces: logging.info("Attach {} to DPDK".format(nic)) - helpers.run_command( - "/usr/bin/dpdk-devbind.py", "--force", "--bind=vfio-pci", nic - ) + helpers.run_command(dpdk_devbind, "--force", "--bind=vfio-pci", nic) def _create_bridges(config, dpdk_bridges):