[PATCH v7 08/15] config: Look up IPA configurables in configuration file
Milan Zamazal
mzamazal at redhat.com
Thu Feb 6 17:15:59 CET 2025
This patch adds configuration options for environment variables used in
the IPA proxy. Two utility functions configuration retrieval functions
are added, to retrieve lists of values.
The configuration snippet:
configuration:
ipa:
config_paths:
- config path 1
- config path 2
- ...
module_paths:
- module path 1
- module path 2
- ...
proxy_paths:
- proxy path 1
- proxy path 2
- ...
force_isolation: BOOL
ipas:
IPA_NAME:
tuning_file: TUNING FILE
Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
---
.../libcamera/internal/global_configuration.h | 4 ++
src/libcamera/base/global_configuration.cpp | 51 +++++++++++++++
src/libcamera/ipa_manager.cpp | 32 +++++----
src/libcamera/ipa_proxy.cpp | 65 ++++++++++---------
4 files changed, 109 insertions(+), 43 deletions(-)
diff --git a/include/libcamera/internal/global_configuration.h b/include/libcamera/internal/global_configuration.h
index a6e21a2d..ffa6454c 100644
--- a/include/libcamera/internal/global_configuration.h
+++ b/include/libcamera/internal/global_configuration.h
@@ -48,8 +48,12 @@ std::optional<T> option(const std::string &confPath)
return c->get<T>();
}
+std::vector<std::string> listOption(const std::string &confPath);
std::optional<std::string> envOption(const char *const envVariable,
const std::string &confPath);
+std::vector<std::string> envListOption(
+ const char *const envVariable,
+ const std::string &confPath);
} /* namespace GlobalConfiguration */
diff --git a/src/libcamera/base/global_configuration.cpp b/src/libcamera/base/global_configuration.cpp
index 3dc31c48..e69951b4 100644
--- a/src/libcamera/base/global_configuration.cpp
+++ b/src/libcamera/base/global_configuration.cpp
@@ -9,11 +9,14 @@
#include <filesystem>
#include <memory>
+#include <optional>
#include <string>
#include <sys/types.h>
+#include <vector>
#include <libcamera/base/file.h>
#include <libcamera/base/log.h>
+#include <libcamera/base/utils.h>
#include "libcamera/internal/yaml_parser.h"
@@ -152,6 +155,24 @@ void initialize()
* in the configuration file and matches type \a T, no value otherwise
*/
+/**
+ * \brief Return values of the configuration option identified by \a confPath
+ * \tparam T The type of the retrieved configuration value
+ * \param[in] confPath Sequence of the YAML section names (excluding
+ * `configuration') leading to the requested list option, separated by dots
+ * \return A vector of strings (empty one if the option is not found)
+ */
+std::vector<std::string> listOption(const std::string &confPath)
+{
+ const YamlObject *c = &configuration();
+ for (auto part : utils::split(confPath, ".")) {
+ c = &(*c)[part];
+ if (!*c)
+ return {};
+ }
+ return c->getList<std::string>().value_or(std::vector<std::string>());
+}
+
/**
* \brief Return value of the configuration option from a file or environment
* \param[in] envVariable Environment variable to get the value from
@@ -179,6 +200,36 @@ std::optional<std::string> envOption(
return option<std::string>(confPath);
}
+/**
+ * \brief Return values of the configuration option from a file or environment
+ * \param[in] envVariable Environment variable to get the value from
+ * \param[in] confPath The same as in GlobalConfiguration::option
+ *
+ * This helper looks first at the given environment variable and if it is
+ * defined (even if it is empty) then it splits its value by semicolons and
+ * returns the resulting list of strings. Otherwise it looks for \a confPath the
+ * same way as in GlobalConfiguration::option, value of which must be a list of
+ * strings.
+ *
+ * \note Support for using environment variables to configure libcamera behavior
+ * is provided here mostly for backward compatibility reasons. Introducing new
+ * configuration environment variables is discouraged.
+ *
+ * \return A vector of strings retrieved from the given environment option or
+ * configuration file (an empty vector is returned if nothing is found)
+ */
+std::vector<std::string> envListOption(
+ const char *const envVariable,
+ const std::string &confPath)
+{
+ const char *envValue = utils::secure_getenv(envVariable);
+ if (envValue) {
+ auto items = utils::split(envValue, ":");
+ return std::vector<std::string>(items.begin(), items.end());
+ }
+ return listOption(confPath);
+}
+
/**
* \brief Return configuration version
*
diff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp
index 33ae74e8..21753eb6 100644
--- a/src/libcamera/ipa_manager.cpp
+++ b/src/libcamera/ipa_manager.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include <dirent.h>
+#include <numeric>
#include <string.h>
#include <sys/types.h>
@@ -114,18 +115,25 @@ IPAManager::IPAManager()
unsigned int ipaCount = 0;
/* User-specified paths take precedence. */
- const char *modulePaths = utils::secure_getenv("LIBCAMERA_IPA_MODULE_PATH");
- if (modulePaths) {
- for (const auto &dir : utils::split(modulePaths, ":")) {
- if (dir.empty())
- continue;
+ const auto modulePaths =
+ GlobalConfiguration::envListOption(
+ "LIBCAMERA_IPA_MODULE_PATH", "ipa.module_paths");
+ for (const auto &dir : modulePaths) {
+ if (dir.empty())
+ continue;
- ipaCount += addDir(dir.c_str());
- }
+ ipaCount += addDir(dir.c_str());
+ }
- if (!ipaCount)
- LOG(IPAManager, Warning)
- << "No IPA found in '" << modulePaths << "'";
+ if (!ipaCount) {
+ std::string paths;
+ if (!modulePaths.empty()) {
+ paths = std::accumulate(std::next(modulePaths.begin()),
+ modulePaths.end(),
+ modulePaths[0],
+ [](std::string s1, std::string s2) { return s1 + ":" + s2; });
+ }
+ LOG(IPAManager, Warning) << "No IPA found in '" << paths << "'";
}
/*
@@ -289,7 +297,9 @@ bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const
{
#if HAVE_IPA_PUBKEY
char *force = utils::secure_getenv("LIBCAMERA_IPA_FORCE_ISOLATION");
- if (force && force[0] != '\0') {
+ if ((force && force[0] != '\0') ||
+ (!force && GlobalConfiguration::option<bool>("ipa.force_isolation")
+ .value_or(false))) {
LOG(IPAManager, Debug)
<< "Isolation of IPA module " << ipa->path()
<< " forced through environment variable";
diff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp
index 25f772a4..10c6ff8e 100644
--- a/src/libcamera/ipa_proxy.cpp
+++ b/src/libcamera/ipa_proxy.cpp
@@ -14,6 +14,7 @@
#include <libcamera/base/log.h>
#include <libcamera/base/utils.h>
+#include "libcamera/internal/global_configuration.h"
#include "libcamera/internal/ipa_module.h"
/**
@@ -105,37 +106,37 @@ std::string IPAProxy::configurationFile(const std::string &name,
const std::string ipaName = ipam_->info().name;
/*
- * Start with any user override through the module-specific environment
- * variable. Use the name of the IPA module up to the first '/' to
- * construct the variable name.
+ * Start with any user override through the module-specific configuration or
+ * environment variable. Use the name of the IPA module up to the first '/'
+ * to construct the configuration and variable names.
*/
- std::string ipaEnvName = ipaName.substr(0, ipaName.find('/'));
+ std::string ipaBaseName = ipaName.substr(0, ipaName.find('/'));
+ std::string ipaConfigName = "ipa.ipas." + ipaBaseName + ".tuning_file";
+ std::string ipaEnvName = ipaBaseName;
std::transform(ipaEnvName.begin(), ipaEnvName.end(), ipaEnvName.begin(),
[](unsigned char c) { return std::toupper(c); });
ipaEnvName = "LIBCAMERA_" + ipaEnvName + "_TUNING_FILE";
- char const *configFromEnv = utils::secure_getenv(ipaEnvName.c_str());
- if (configFromEnv && *configFromEnv == '\0')
- return { configFromEnv };
+ auto config = GlobalConfiguration::envOption(ipaEnvName.c_str(), ipaConfigName);
+ if (config)
+ return { config.value() };
struct stat statbuf;
int ret;
/*
- * Check the directory pointed to by the IPA config path environment
- * variable next.
+ * Check the directory pointed to by the IPA config path next.
*/
- const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH");
- if (confPaths) {
- for (const auto &dir : utils::split(confPaths, ":")) {
- if (dir.empty())
- continue;
-
- std::string confPath = dir + "/" + ipaName + "/" + name;
- ret = stat(confPath.c_str(), &statbuf);
- if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
- return confPath;
- }
+ auto confPaths =
+ GlobalConfiguration::envListOption(
+ "LIBCAMERA_IPA_CONFIG_PATH", "ipa.config_paths");
+ for (const auto &dir : confPaths) {
+ if (dir.empty())
+ continue;
+ std::string confPath = dir + "/" + ipaName + "/" + name;
+ ret = stat(confPath.c_str(), &statbuf);
+ if (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)
+ return confPath;
}
std::string root = utils::libcameraSourcePath();
@@ -199,18 +200,18 @@ std::string IPAProxy::resolvePath(const std::string &file) const
{
std::string proxyFile = "/" + file;
- /* Check env variable first. */
- const char *execPaths = utils::secure_getenv("LIBCAMERA_IPA_PROXY_PATH");
- if (execPaths) {
- for (const auto &dir : utils::split(execPaths, ":")) {
- if (dir.empty())
- continue;
-
- std::string proxyPath = dir;
- proxyPath += proxyFile;
- if (!access(proxyPath.c_str(), X_OK))
- return proxyPath;
- }
+ /* Check the configuration first. */
+ const auto execPaths =
+ GlobalConfiguration::envListOption(
+ "LIBCAMERA_IPA_PROXY_PATH", "ipa.proxy_paths");
+ for (const auto &dir : execPaths) {
+ if (dir.empty())
+ continue;
+
+ std::string proxyPath = dir;
+ proxyPath += proxyFile;
+ if (!access(proxyPath.c_str(), X_OK))
+ return proxyPath;
}
/*
--
2.48.1
More information about the libcamera-devel
mailing list