Skip to content

feat: support system-wide runtime configuration#1657

Merged
ComixHe merged 1 commit into
OpenAtom-Linyaps:masterfrom
reddevillg:feat_sysconf
May 13, 2026
Merged

feat: support system-wide runtime configuration#1657
ComixHe merged 1 commit into
OpenAtom-Linyaps:masterfrom
reddevillg:feat_sysconf

Conversation

@reddevillg

Copy link
Copy Markdown
Collaborator

Add system configuration directory at /etc/linglong. Configs are now merged merged in order: system global, system app-specific, user global, then user global and user app-specific, allowing user configs to override system defaults.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for system-wide runtime configurations by adding a new system configuration directory and a function to load configurations from it. The configuration loading logic was updated to merge system-level settings (global and app-specific) before user-level settings. Review feedback suggests refactoring the loading logic to reduce code duplication between system and user configuration functions and using std::move to optimize the insertion of configuration objects into the results vector.

Comment thread libs/utils/src/linglong/utils/runtime_config.cpp
Comment thread libs/utils/src/linglong/utils/runtime_config.cpp Outdated
Comment thread libs/utils/src/linglong/utils/runtime_config.cpp Outdated
@codecov

codecov Bot commented May 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 3.57143% with 27 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
libs/utils/src/linglong/utils/runtime_config.cpp 3.84% 25 Missing ⚠️
libs/common/src/linglong/common/dir.cpp 0.00% 2 Missing ⚠️
Files with missing lines Coverage Δ
libs/common/src/linglong/common/dir.cpp 25.00% <0.00%> (-2.78%) ⬇️
libs/utils/src/linglong/utils/runtime_config.cpp 25.67% <3.84%> (-3.36%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@reddevillg reddevillg force-pushed the feat_sysconf branch 2 times, most recently from e989e1b to 879203d Compare May 13, 2026 01:48
@reddevillg reddevillg requested review from ComixHe and dengbo11 May 13, 2026 02:01
Add system configuration directory at /etc/linglong. Configs are now
merged merged in order: system global, system app-specific, user global,
then user global and user app-specific, allowing user configs to
override system defaults.

Signed-off-by: reddevillg <reddevillg@gmail.com>
@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

deepin pr auto review

你好!我是CodeGeeX。我已仔细审查了你提供的Git Diff。本次修改的主要目的是引入系统级运行时配置的加载,并重构了配置加载逻辑,将公共逻辑提取为 loadRuntimeConfigFromDir,同时调整了配置的合并顺序(系统全局 -> 系统应用 -> 用户全局 -> 用户应用)。

整体来看,这次重构逻辑清晰,提取公共函数有效减少了代码冗余,配置的层级合并顺序也非常合理。不过,在语法逻辑、代码质量、性能和安全方面,我还有以下几点改进建议供你参考:

1. 语法与逻辑

1.1 宏定义拼接潜在的语法问题

  • 文件: configure.h.in
  • 问题: #define LINGLONG_SYSCONFDIR SYSCONFDIR "/linglong" 这种写法依赖于C/C++相邻字符串字面量自动拼接的特性。但是,如果 SYSCONFDIR 在CMake中被替换为一个宏(如 #define SYSCONFDIR "/etc"),拼接没问题;但如果 SYSCONFDIR 没有被正确定义为字符串字面量,或者在某些上下文中不被视为宏,就会导致编译错误或逻辑异常。
  • 建议: 确保CMake在生成 configure.h.in 时,SYSCONFDIR 被正确地用双引号包裹替换(例如CMake中配置为 "-DSYSCONFDIR=\"${CMAKE_INSTALL_FULL_SYSCONFDIR}\""),或者直接在宏中体现完整路径:
    // 更稳妥的写法,确保引号被正确处理
    #define LINGLONG_SYSCONFDIR "/etc/linglong" // 假设SYSCONFDIR就是/etc
    // 或者如果一定要拼接,确保 SYSCONFDIR 带引号
    #define LINGLONG_SYSCONFDIR SYSCONFDIR "/linglong"

1.2 空路径检查缺失

  • 文件: libs/utils/src/linglong/utils/runtime_config.cpp
  • 问题: loadUserRuntimeConfig 中对 configDir.empty() 进行了检查,但 loadSystemRuntimeConfig 中调用 getSystemRuntimeConfigDir() 后直接将其传给了 loadRuntimeConfigFromDir,没有进行空路径检查。虽然 LINGLONG_SYSCONFDIR 是编译期硬编码的宏,正常情况下不会为空,但为了防御性编程,保持与用户配置加载逻辑的一致性更好。
  • 建议: 在 loadSystemRuntimeConfig 中也加上空路径判断,或者在 loadRuntimeConfigFromDir 内部统一处理:
    linglong::utils::error::Result<std::optional<RuntimeConfigure>>
    loadSystemRuntimeConfig(const std::string &appId)
    {
        LINGLONG_TRACE(
          fmt::format("load system runtime config for {}", appId.empty() ? "global" : appId));
    
        auto configDir = linglong::common::dir::getSystemRuntimeConfigDir();
        if (configDir.empty()) {
            return std::nullopt;
        }
        return loadRuntimeConfigFromDir(configDir, appId);
    }

2. 代码质量

2.1 std::optional 的值提取方式

  • 文件: libs/utils/src/linglong/utils/runtime_config.cpp
  • 问题: 旧代码使用了 (*userGlobal).has_value()(*userGlobal).value(),新代码修改为了 userGlobal->has_value()userGlobal->value()。使用 -> 确实比 (*). 更简洁,但 value()std::optional 为空时(尽管前面已经用 has_value() 守卫)会抛出异常,且带有运行时检查开销。
  • 建议: 推荐使用 * 解引用操作符,因为前面已经确认了 has_value(),使用 * 是零开销的解引用,更符合C++的性能导向习惯:
    if (userGlobal->has_value()) {
        configs.emplace_back(std::move(*userGlobal)); // 使用 * 代替 ->value()
    }

2.2 std::move 的多余使用

  • 文件: libs/utils/src/linglong/utils/runtime_config.cpp
  • 问题: 旧代码中有一句 return std::move(result).value();,新代码中修改为 return result;,这是一个非常好的改进!因为当函数返回局部变量时,C++11起会自动应用返回值优化(RVO/NRVO)或隐式移动,显式使用 std::move 反而会阻止拷贝消除(Copy Elision)。
  • 建议: 同理,在 configs.emplace_back(std::move(userGlobal->value())) 中,如果 userGlobal->value() 返回的是左值引用,std::move 是必要的;但如果它返回的是右值或值类型,请确认 std::move 是否必要。目前的写法是可以接受的,但需保持警惕。

3. 代码性能

3.1 字符串拼接构造 std::filesystem::path 的开销

  • 文件: libs/common/src/linglong/common/dir.cpp
  • 问题: return LINGLONG_SYSCONFDIR; 这里 LINGLONG_SYSCONFDIR 是一个C风格字符串(如 "/etc/linglong"),隐式转换为 std::filesystem::path。由于 getSystemRuntimeConfigDir() 可能会被频繁调用,每次都会触发 std::filesystem::path 的构造和内存分配。
  • 建议: 如果该函数在热点路径上被频繁调用,建议将其实现为静态局部变量,只构造一次:
    std::filesystem::path getSystemRuntimeConfigDir() noexcept
    {
        static const auto dir = std::filesystem::path(LINGLONG_SYSCONFDIR);
        return dir;
    }

4. 代码安全

4.1 配置文件加载的路径遍历风险

  • 文件: libs/utils/src/linglong/utils/runtime_config.cpp
  • 问题: loadRuntimeConfigFromDir 掄将 appId 直接拼接到路径中(configDir / (appId + ".json"))。如果 appId 是从外部输入获取的(例如来自IPC请求或不可信的数据源),且未经过过滤,攻击者可能会构造类似 ../../etc/passwdappId,导致路径遍历漏洞,读取到系统中的敏感文件。
  • 建议:
    1. 在拼接路径前,校验 appId 的合法性(例如只允许包含字母、数字、下划线、中划线等)。
    2. 拼接后,使用 std::filesystem::canonical 或检查最终路径是否以 configDir 开头,确保没有逃逸出预期的配置目录。
    // 示例:简单的合法性校验
    if (!appId.empty() && appId.find('/') == std::string::npos && appId.find('\\') == std::string::npos) {
        configPath = configDir / (appId + ".json");
    } else if (!appId.empty()) {
        // 非法 appId 处理
        return LINGLONG_ERR("Invalid appId format");
    }

4.2 竞态条件 (TOCTOU)

  • 文件: libs/utils/src/linglong/utils/runtime_config.cpp
  • 问题: loadRuntimeConfigFromDir 中先使用 std::filesystem::exists(configPath) 检查文件是否存在,然后再进行读取。在检查和读取之间,文件可能被删除或替换(符号链接攻击),这属于典型的 TOCTOU (Time-of-check to time-of-use) 漏洞。
  • 建议: 直接尝试打开并读取文件,通过读取操作的返回值来判断文件是否存在或读取失败,避免先检查再使用:
    // 移除 exists 检查,直接让 loadRuntimeConfig 处理文件不存在的逻辑
    // if (!std::filesystem::exists(configPath)) {
    //     return std::nullopt;
    // }
    // auto result = linglong::utils::loadRuntimeConfig(configPath);
    // 如果 loadRuntimeConfig 内部能够正确处理文件不存在的情况(返回特定错误或 nullopt)

总结

本次代码修改整体质量不错,重构思路正确。重点需要关注的是路径拼接的安全性(防路径遍历)以及TOCTOU问题,这两个属于安全漏洞范畴,建议优先修复。其他关于性能和代码风格的建议可作为后续优化的参考。

@deepin-ci-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: ComixHe, reddevillg

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ComixHe ComixHe merged commit c7f3a69 into OpenAtom-Linyaps:master May 13, 2026
16 of 17 checks passed
@reddevillg reddevillg deleted the feat_sysconf branch May 13, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants