import os
import time
import ctypes
from pathlib import Path
_DEFUALT_KCAL_LIB_PATH = "/usr/local/lib"
_KCAL_LIBS = [
"libdata_guard_common.so",
"libdata_guard.so",
"libhitls_bsl.so",
"libhitls_crypto.so",
"libmpc_tee.so",
"libsecurec.so",
]
def preload_lib():
kcal_lib_path = os.getenv("KCAL_LIB_PATH", _DEFUALT_KCAL_LIB_PATH)
if not os.path.isdir(kcal_lib_path):
raise FileNotFoundError(f"kcal lib path is not exist: {kcal_lib_path}")
if not os.path.isabs(kcal_lib_path):
raise ValueError(f"The kcal lib path {kcal_lib_path} must be an absolute path.")
if kcal_lib_path != _DEFUALT_KCAL_LIB_PATH:
old_ld = os.environ.get("LD_LIBRARY_PATH", "")
os.environ["LD_LIBRARY_PATH"] = kcal_lib_path + os.pathsep + old_ld
failed_files = []
for kcal_lib_name in _KCAL_LIBS:
kcal_lib_abs_path = os.path.join(kcal_lib_path, kcal_lib_name)
if not os.path.isfile(kcal_lib_abs_path):
raise FileNotFoundError(
f"kcal lib {kcal_lib_name} is not in {kcal_lib_path}"
)
try:
ctypes.CDLL(kcal_lib_abs_path, mode=ctypes.RTLD_GLOBAL)
print(f"Preloaded {kcal_lib_abs_path} (RTLD_GLOBAL)")
except OSError as e:
failed_files.append(kcal_lib_abs_path)
for _ in range(15):
if failed_files:
for so_file in failed_files:
time.sleep(0.1)
try:
ctypes.CDLL(str(so_file), mode=ctypes.RTLD_GLOBAL)
print(f"Preloaded {so_file} (RTLD_GLOBAL)")
failed_files.remove(so_file)
except OSError as e:
print(f"Failed to load {so_file} {e}")
continue
if failed_files:
raise RuntimeError(f"kcal {failed_files} so lib failed to load")