From 9e9a3729fe671ca7aaf8b82473217ead8121a4cf Mon Sep 17 00:00:00 2001 From: John Estabrook Date: Tue, 23 Jun 2026 13:39:35 -0500 Subject: T8993: initialize ReferenceTree module from string not file Avoid initialization error in threaded applications, for example when calling libvyosconfig functions from FastAPI background tasks. The read_internal function from file relies on the inherently non thread-safe Unix module; read string first and pass to lib read_string. --- python/vyos/referencetree.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'python') diff --git a/python/vyos/referencetree.py b/python/vyos/referencetree.py index 87ed310b4..b535615dd 100644 --- a/python/vyos/referencetree.py +++ b/python/vyos/referencetree.py @@ -14,6 +14,7 @@ # along with this library. If not, see . from ctypes import cdll, c_char_p, c_void_p, c_bool +from pathlib import Path from vyos.defaults import reference_tree_cache @@ -25,7 +26,7 @@ class ReferenceTreeError(Exception): class ReferenceTree: - # pylint: disable=too-many-instance-attributes + # pylint: disable=too-many-instance-attributes,raise-missing-from def __init__(self, cache_file=reference_tree_cache, libpath=LIBPATH): self.__pointer = None self.__lib = cdll.LoadLibrary(libpath) @@ -35,9 +36,9 @@ class ReferenceTree: self.__get_error.argtypes = [] self.__get_error.restype = c_char_p - self.__read_internal = self.__lib.read_internal_reference_tree - self.__read_internal.argtypes = [c_char_p] - self.__read_internal.restype = c_void_p + self.__read_internal_string = self.__lib.read_internal_string_reference_tree + self.__read_internal_string.argtypes = [c_char_p] + self.__read_internal_string.restype = c_void_p self.__write_internal = self.__lib.write_internal_reference_tree self.__write_internal.argtypes = [c_void_p, c_char_p] @@ -53,7 +54,12 @@ class ReferenceTree: self.__equal.argtypes = [c_void_p, c_void_p] self.__equal.restype = c_bool - pointer = self.__read_internal(cache_file.encode()) + try: + cache_string = Path(cache_file).read_bytes() + except OSError as e: + raise ValueError(f'Failed to read cache_file: {e}') + + pointer = self.__read_internal_string(cache_string) if pointer is None: msg = self.__get_error().decode() raise ValueError(f'Failed to read internal rep: {msg}') -- cgit v1.2.3