From 01ff416cce7330eccc43dbad0390ebf5f4b424ae Mon Sep 17 00:00:00 2001 From: yeshanshan Date: Mon, 11 May 2026 14:08:28 +0800 Subject: [PATCH] fix: support uppercase filenames and prevent reload abort on partial failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Updated regex patterns in dconfig_global.h to accept uppercase letters (A-Z) in config file paths, fixing parsing failures for files with uppercase names 2. Refactored update() by extracting updateInternal() that returns error messages instead of early-aborting via sendErrorReply on DBus 3. Modified reload() to continue processing remaining files when individual updates fail, instead of aborting the entire reload 4. Enhanced reload() to collect and report total failed file count for better debugging Log: Fixed config file matching for uppercase names and improved reload robustness Influence: 1. Verify config files with uppercase names (e.g., MyConfig.json) are correctly parsed 2. Test scenario: multiple files to update, one file update fails, verify reload continues processing remaining files 3. Verify error count is correctly reported in logs when partial reload failures occur 4. Test DBus update calls still report errors correctly via sendErrorReply 5. Verify no regression for existing lowercase-path config files 6. Test with mixed case paths in config directories fix: 支持大写文件名称并防止重新加载时因部分失败而终止 1. 修改了 dconfig_global.h 中的正则表达式,增加了对大写字母 (A-Z) 的支 持,修复了含有大写字母的配置文件路径解析失败的问题 2. 重构了 update() 方法,提取出 updateInternal() 返回错误信息,而不是通 过 sendErrorReply 提前终止 DBus 调用 3. 修改 reload() 方法,当个别文件更新失败时继续处理剩余文件,而不是整个 重载过程提前终止 4. 增强 reload() 日志,收集并报告失败的文件数量,方便调试 Log: 修复了配置文件名大写匹配问题,增强了重载的鲁棒性 Influence: 1. 验证包含大写的配置文件(如 MyConfig.json)能够正确解析 2. 测试多文件更新场景:其中一个文件更新失败,验证重载继续处理剩余文件 3. 验证部分重载失败时日志中正确报告错误数量 4. 测试 DBus 更新调用仍通过 sendErrorReply 正确报告错误 5. 验证现有小写路径配置文件无回归问题 6. 测试配置目录中混合大小写路径的情况 PMS: BUG-360197 Change-Id: I054dd047b2924d6475b357ec1a83643048e7e2ea --- .../dde-dconfig-daemon/dconfig_global.h | 12 ++++-- .../dde-dconfig-daemon/dconfigserver.cpp | 43 ++++++++++++------- .../dde-dconfig-daemon/dconfigserver.h | 4 ++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/dconfig-center/dde-dconfig-daemon/dconfig_global.h b/dconfig-center/dde-dconfig-daemon/dconfig_global.h index a9ea532..5fabc36 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfig_global.h +++ b/dconfig-center/dde-dconfig-daemon/dconfig_global.h @@ -96,7 +96,9 @@ inline ConfigureId getMetaConfigureId(const QString &path) ConfigureId info; // /usr/share/dsg/configs/[$appid]/[$subpath]/$resource.json // Use negative lookahead (?!overrides/) to exclude override paths which should be handled by getOverrideConfigureId - static QRegularExpression usrReg(R"(/configs/(?!overrides/)(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)?)(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)*)(?[a-z0-9\s\-_\@\-\^!#$%&.]+).json$)"); + static QRegularExpression usrReg( + R"(/configs/(?!overrides/)(?(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)?(?(?:(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)*)(?[a-zA-Z0-9\s_@^!#$%&.\-]+)\.json$)" + ); QRegularExpressionMatch match; match = usrReg.match(path); @@ -114,10 +116,14 @@ inline ConfigureId getOverrideConfigureId(const QString &path) { ConfigureId info; // /usr/share/dsg/configs/overrides/[$appid]/$resource/[$subpath]/$override_id.json - static QRegularExpression usrReg(R"(/configs/overrides/(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)?)(?[a-z0-9\s\-_\@\-\^!#$%&.]+)/(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)*)(?[a-z0-9\s\-_\@\-\^!#$%&.]+).json$)"); + static QRegularExpression usrReg( + R"(/configs/overrides/(?(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)?(?(?>[a-zA-Z0-9\s_@^!#$%&.\-]+))/(?(?:(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)*)(?[a-zA-Z0-9\s_@^!#$%&.\-]+)\.json$)" + ); // /etc/dsg/configs/overrides/[$appid]/$resource/[$subpath]/$override_id.json - static QRegularExpression etcReg(R"(^/etc/dsg/configs/overrides/(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)?)(?[a-z0-9\s\-_\@\-\^!#$%&.]+)/(?([a-z0-9\s\-_\@\-\^!#$%&.]+\/)*)(?[a-z0-9\s\-_\@\-\^!#$%&.]+).json$)"); + static QRegularExpression etcReg( + R"(^/etc/dsg/configs/overrides/(?(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)?(?(?>[a-zA-Z0-9\s_@^!#$%&.\-]+))/(?(?:(?>[a-zA-Z0-9\s_@^!#$%&.\-]+)\/)*)(?[a-zA-Z0-9\s_@^!#$%&.\-]+)\.json$)" + ); QRegularExpressionMatch match; match = usrReg.match(path); diff --git a/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp b/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp index 44efd78..ad9f68d 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp +++ b/dconfig-center/dde-dconfig-daemon/dconfigserver.cpp @@ -435,7 +435,7 @@ bool DSGConfigServer::isConfigurePath(const QString &path, const QString &appId) 当描述文件被修改或override目录新增、移除、修改文件时,需要重新解析对应的文件内容, 提供刷新服务,由配置工具调用来运行时刷新提供的文件访问信息。 */ -void DSGConfigServer::update(const QString &path) +std::optional DSGConfigServer::updateInternal(const QString &path) { qCInfo(cfLog()) << "Update resource:" << path; @@ -445,15 +445,9 @@ void DSGConfigServer::update(const QString &path) qPrintable(configureInfo.subpath), qPrintable(configureInfo.resource)); if (configureInfo.isInValid()) { - QString errorMsg = QString("It's illegal resource [%1].").arg(path); - if (calledFromDBus()) { - sendErrorReply(QDBusError::Failed, errorMsg); - } - qWarning() << errorMsg; - return; + return QString("It's illegal resource [%1].").arg(path); } - const GenericResourceKey resourceKey = getGenericResourceKey(configureInfo.resource, configureInfo.subpath); if (auto resource = resourceObject(resourceKey)) { qCInfo(cfLog, "Updated the resouce:[%s], for the appid:[%s].", @@ -461,11 +455,19 @@ void DSGConfigServer::update(const QString &path) qPrintable(configureInfo.appid)); const auto &innerAppid = outerAppidToInner(configureInfo.appid); if (!resource->reparse(innerAppid)) { - QString errorMsg = QString("Update the resource path[%1] error.").arg(path); - if (calledFromDBus()) { - sendErrorReply(QDBusError::Failed, errorMsg); - } - qWarning() << qPrintable(errorMsg); + return QString("Update the resource path[%1] error.").arg(path); + } + } + return std::nullopt; +} + +void DSGConfigServer::update(const QString &path) +{ + const auto errorMsg = updateInternal(path); + if (errorMsg) { + qWarning() << *errorMsg; + if (calledFromDBus()) { + sendErrorReply(QDBusError::Failed, *errorMsg); } } } @@ -557,12 +559,23 @@ void DSGConfigServer::reload() changedFiles.removeDuplicates(); + if (changedFiles.isEmpty()) { + qCInfo(cfLog()) << "Reload completed, no files changed"; + return; + } + // Process changed files + int failedCount = 0; for (const auto &file : std::as_const(changedFiles)) { - update(file); + const auto errorMsg = updateInternal(file); + if (errorMsg) { + qCWarning(cfLog()) << "Reload failed to update file:" << file << ", reason:" << *errorMsg; + ++failedCount; + } } - qCInfo(cfLog()) << "Reload completed, processed" << changedFiles.size() << "files"; + qCInfo(cfLog()) << "Reload completed, processed" << changedFiles.size() << "files," + << failedCount << "failed"; } // Get all configuration file signatures diff --git a/dconfig-center/dde-dconfig-daemon/dconfigserver.h b/dconfig-center/dde-dconfig-daemon/dconfigserver.h index 8c3af3f..f4127da 100644 --- a/dconfig-center/dde-dconfig-daemon/dconfigserver.h +++ b/dconfig-center/dde-dconfig-daemon/dconfigserver.h @@ -5,6 +5,7 @@ #pragma once #include "dconfig_global.h" +#include #include #include #include @@ -83,6 +84,9 @@ private Q_SLOTS: ConfigureId getConfigureIdByPath(const QString &path); bool isConfigurePath(const QString &path, const QString& appId) const; + + std::optional updateInternal(const QString &path); + // Reload interface related structures and methods struct FileSignature { qint64 size;