@@ -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 */
@@ -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
*
@@ -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";
@@ -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"
/**
@@ -107,18 +108,18 @@ std::string IPAProxy::configurationFile(const std::string &name,
*/
std::string ipaName = ipam_->info().name;
- /* Check the environment variable first. */
- const char *confPaths = utils::secure_getenv("LIBCAMERA_IPA_CONFIG_PATH");
- if (confPaths) {
- for (const auto &dir : utils::split(confPaths, ":")) {
- if (dir.empty())
- continue;
+ /* Check the configuration first. */
+ 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 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();
@@ -182,18 +183,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;
}
/*
The configuration snippet: configuration: ipa: config_paths: - config path 1 - config path 2 - ... module_paths: - module path 1 - module path 2 - ... force_isolation: BOOL Signed-off-by: Milan Zamazal <mzamazal@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 | 47 ++++++++--------- 4 files changed, 100 insertions(+), 34 deletions(-)