已合并
多线程更新插件包信息coredump修复 #2683
pantong创建于 6月8日
多线程更新插件包信息coredump修复 #2683
已合并
pantong创建于 6月8日
共 5 个文件变更+52-10
@@ -52,7 +52,7 @@ public:
52 PackConfDetail GetConfigDetailInfo(const std::string &srcPath);52 PackConfDetail GetConfigDetailInfo(const std::string &srcPath);
53 TSD_StatusT ParseConfigDataFromProtoBuf(const HDCMessage &hdcMsg);53 TSD_StatusT ParseConfigDataFromProtoBuf(const HDCMessage &hdcMsg);
54 TSD_StatusT ParseConfigDataFromFile(const std::string &pkgTitle);54 TSD_StatusT ParseConfigDataFromFile(const std::string &pkgTitle);
55- void ConstructPkgConfigMsg(HDCMessage &hdcMsg) const;55+ void ConstructPkgConfigMsg(HDCMessage &hdcMsg);
56 bool IsNeedToUpdateConfig(const HDCMessage &hdcMsg) const;56 bool IsNeedToUpdateConfig(const HDCMessage &hdcMsg) const;
57 bool IsConfigPackageInfo(const std::string &oriPkgName);57 bool IsConfigPackageInfo(const std::string &oriPkgName);
58 std::map<std::string, PackConfDetail> GetAllPackageConfigInfo() const58 std::map<std::string, PackConfDetail> GetAllPackageConfigInfo() const
@@ -64,7 +64,7 @@ public:
64 std::string GetPackageHostTruePath(const std::string &pkgName);64 std::string GetPackageHostTruePath(const std::string &pkgName);
65 // 遍历 configMap_ ,对 compat 插件包解析同名 .ini 文件,刷新 host 侧插件包版本信息65 // 遍历 configMap_ ,对 compat 插件包解析同名 .ini 文件,刷新 host 侧插件包版本信息
66 void RefreshHostPluginVersions();66 void RefreshHostPluginVersions();
67- PluginPkgVersion GetHostPluginVersion(const std::string &pkgName) const;67+ PluginPkgVersion GetHostPluginVersion(const std::string &pkgName);
68 bool HasCompatPluginPackage() const;68 bool HasCompatPluginPackage() const;
69private:69private:
70 bool SetConfigDataOnServer(const SinkPackageConfig &hdcConfig);70 bool SetConfigDataOnServer(const SinkPackageConfig &hdcConfig);
@@ -87,6 +87,7 @@ private:
87 std::string hashCode_;87 std::string hashCode_;
88 using SingleParaParseFunc = bool (PackageProcessConfig::*)(const std::string &, PackConfDetail &) const;88 using SingleParaParseFunc = bool (PackageProcessConfig::*)(const std::string &, PackConfDetail &) const;
89 const std::map<std::string, SingleParaParseFunc> configParaParseFuncMap_;89 const std::map<std::string, SingleParaParseFunc> configParaParseFuncMap_;
90+ std::mutex hostPluginVersionMut_;
90};91};
91}92}
92#endif // TSD_PACKAGE_PROCESS_CONFIG_H93#endif // TSD_PACKAGE_PROCESS_CONFIG_H
@@ -269,7 +269,7 @@ namespace tsd {
269 return true;269 return true;
270 }270 }
271 271 
272- void PackageProcessConfig::ConstructPkgConfigMsg(HDCMessage &hdcMsg) const272+ void PackageProcessConfig::ConstructPkgConfigMsg(HDCMessage &hdcMsg)
273 {273 {
274 for (auto iter = configMap_.begin(); iter != configMap_.end(); iter++) {274 for (auto iter = configMap_.begin(); iter != configMap_.end(); iter++) {
275 SinkPackageConfig *curConf = hdcMsg.add_sink_pkg_con_list();275 SinkPackageConfig *curConf = hdcMsg.add_sink_pkg_con_list();
@@ -279,6 +279,7 @@ namespace tsd {
279 if (iter->second.decDstDir != DeviceInstallPath::COMPAT_PLUGIN_PATH) {279 if (iter->second.decDstDir != DeviceInstallPath::COMPAT_PLUGIN_PATH) {
280 continue;280 continue;
281 }281 }
282+ std::lock_guard<std::mutex> lock(hostPluginVersionMut_);
282 const auto verIt = hostPluginVersions_.find(iter->first);283 const auto verIt = hostPluginVersions_.find(iter->first);
283 if (verIt == hostPluginVersions_.end() || verIt->second.Empty()) {284 if (verIt == hostPluginVersions_.end() || verIt->second.Empty()) {
284 continue;285 continue;
@@ -306,6 +307,7 @@ namespace tsd {
306 PluginPkgVersion info;307 PluginPkgVersion info;
307 if (hostFile.empty()) {308 if (hostFile.empty()) {
308 TSD_RUN_INFO("host plugin pkg:%s has empty host path, skip parse ini", pkgName.c_str());309 TSD_RUN_INFO("host plugin pkg:%s has empty host path, skip parse ini", pkgName.c_str());
310+ std::lock_guard<std::mutex> lock(hostPluginVersionMut_);
309 hostPluginVersions_[pkgName] = info;311 hostPluginVersions_[pkgName] = info;
310 continue;312 continue;
311 }313 }
@@ -325,12 +327,14 @@ namespace tsd {
325 TSD_RUN_INFO("host plugin pkg:%s ini parsed, version:%s timestamp:%s",327 TSD_RUN_INFO("host plugin pkg:%s ini parsed, version:%s timestamp:%s",
326 pkgName.c_str(), info.version.c_str(), info.timestamp.c_str());328 pkgName.c_str(), info.version.c_str(), info.timestamp.c_str());
327 }329 }
330+ std::lock_guard<std::mutex> lock(hostPluginVersionMut_);
328 hostPluginVersions_[pkgName] = info;331 hostPluginVersions_[pkgName] = info;
329 }332 }
330 }333 }
331 334 
332- PluginPkgVersion PackageProcessConfig::GetHostPluginVersion(const std::string &pkgName) const335+ PluginPkgVersion PackageProcessConfig::GetHostPluginVersion(const std::string &pkgName)
333 {336 {
337+ std::lock_guard<std::mutex> lock(hostPluginVersionMut_);
334 const auto it = hostPluginVersions_.find(pkgName);338 const auto it = hostPluginVersions_.find(pkgName);
335 if (it == hostPluginVersions_.end()) {339 if (it == hostPluginVersions_.end()) {
336 return PluginPkgVersion{};340 return PluginPkgVersion{};
@@ -428,7 +428,7 @@ private:
428 428 
429 TSD_StatusT GetDriverExtendPkgName(std::string &orgFile, std::string &dstFile, int32_t &peerNode);429 TSD_StatusT GetDriverExtendPkgName(std::string &orgFile, std::string &dstFile, int32_t &peerNode);
430 430 
431- TSD_StatusT LoadPackageConfigInfoToDevice();431+ TSD_StatusT LoadPackageConfigInfoToDevice(const bool hasPluginVersion);
432 432 
433 TSD_StatusT LoadPackageToDeviceByConfig();433 TSD_StatusT LoadPackageToDeviceByConfig();
434 434 
@@ -137,7 +137,7 @@ TSD_StatusT ProcessModeManager::OpenProcess(const uint32_t rankSize)
137 return TSD_OK;137 return TSD_OK;
138 }138 }
139 139 
140- TSD_StatusT ret = LoadPackageConfigInfoToDevice();140+ TSD_StatusT ret = LoadPackageConfigInfoToDevice(true);
141 TSD_CHECK(ret == TSD_OK, ret, "Load package config info to device failed.");141 TSD_CHECK(ret == TSD_OK, ret, "Load package config info to device failed.");
142 const TimePoint finLoadCfg = std::chrono::high_resolution_clock::now();142 const TimePoint finLoadCfg = std::chrono::high_resolution_clock::now();
143 143 
@@ -1329,7 +1329,7 @@ TSD_StatusT ProcessModeManager::LoadRuntimePkgToDevice()
1329 if (IsSupportCommonSink() &&1329 if (IsSupportCommonSink() &&
1330 (&drvHdcSendFileV2 != nullptr) &&1330 (&drvHdcSendFileV2 != nullptr) &&
1331 (&drvHdcGetTrustedBasePathV2 != nullptr)) {1331 (&drvHdcGetTrustedBasePathV2 != nullptr)) {
1332- (void)LoadPackageConfigInfoToDevice();1332+ (void)LoadPackageConfigInfoToDevice(false);
1333 if (LoadCannHsPkgToDevice(UDF_PKG_NAME) != TSD_OK) {1333 if (LoadCannHsPkgToDevice(UDF_PKG_NAME) != TSD_OK) {
1334 TSD_ERROR("Load package failed, package:%s", UDF_PKG_NAME.c_str());1334 TSD_ERROR("Load package failed, package:%s", UDF_PKG_NAME.c_str());
1335 return TSD_INTERNAL_ERROR;1335 return TSD_INTERNAL_ERROR;
@@ -2156,7 +2156,7 @@ TSD_StatusT ProcessModeManager::CloseNetService()
2156 }2156 }
2157}2157}
2158 2158 
2159-TSD_StatusT ProcessModeManager::LoadPackageConfigInfoToDevice()2159+TSD_StatusT ProcessModeManager::LoadPackageConfigInfoToDevice(const bool hasPluginVersion)
2160{2160{
2161 if ((IsSupportCommonSink() == false) ||2161 if ((IsSupportCommonSink() == false) ||
2162 (&drvHdcSendFileV2 == nullptr) ||2162 (&drvHdcSendFileV2 == nullptr) ||
@@ -2190,8 +2190,10 @@ TSD_StatusT ProcessModeManager::LoadPackageConfigInfoToDevice()
2190 TSD_ERROR("Parsing config data was not successful");2190 TSD_ERROR("Parsing config data was not successful");
2191 return TSD_INTERNAL_ERROR;2191 return TSD_INTERNAL_ERROR;
2192 }2192 }
2193- // 刷新 host 侧 compat 插件包版本信息,并随后随 CONFIG 消息一起下发2193+ if (hasPluginVersion) {
2194- pkgConInst->RefreshHostPluginVersions();2194+ // 刷新 host 侧 compat 插件包版本信息,并随后随 CONFIG 消息一起下发
2195+ pkgConInst->RefreshHostPluginVersions();
2196+ }
2195 2197 
2196 HDCMessage msg;2198 HDCMessage msg;
2197 msg.set_real_device_id(logicDeviceId_);2199 msg.set_real_device_id(logicDeviceId_);
@@ -427,4 +427,39 @@ TEST_F(PackageProcessConfigTest, ParseLoadAsPerSocFlag_Failed)
427 PackageProcessConfig *pkgcfg = PackageProcessConfig::GetInstance();427 PackageProcessConfig *pkgcfg = PackageProcessConfig::GetInstance();
428 const auto ret = pkgcfg->ParseLoadAsPerSocFlag(para, tempNode);428 const auto ret = pkgcfg->ParseLoadAsPerSocFlag(para, tempNode);
429 EXPECT_EQ(ret, false);429 EXPECT_EQ(ret, false);
430+}
431+ 
432+// 覆盖 RefreshHostPluginVersions 中加锁写 hostPluginVersions_ 的两条 lock_guard 分支:
433+// 1) compat 包 hostTruePath 为空 -> empty 分支加锁写入空版本
434+// 2) compat 包 hostTruePath 非空 -> 末尾加锁写入解析结果
435+TEST_F(PackageProcessConfigTest, RefreshHostPluginVersions_LockBranches)
436+{
437+ PackageProcessConfig *pkgcfg = PackageProcessConfig::GetInstance();
438+ pkgcfg->configMap_.clear();
439+ pkgcfg->hostPluginVersions_.clear();
440+ 
441+ // 分支1:compat 包,hostTruePath 为空 -> 命中 empty 分支的 lock_guard
442+ PackConfDetail compatEmptyPath = {};
443+ compatEmptyPath.decDstDir = DeviceInstallPath::COMPAT_PLUGIN_PATH;
444+ compatEmptyPath.hostTruePath = "";
445+ pkgcfg->configMap_["cann-emptypath-compat.tar.gz"] = compatEmptyPath;
446+ 
447+ // 分支2:compat 包,hostTruePath 非空(ini 不存在解析失败回退)-> 命中末尾的 lock_guard
448+ PackConfDetail compatNonEmptyPath = {};
449+ compatNonEmptyPath.decDstDir = DeviceInstallPath::COMPAT_PLUGIN_PATH;
450+ compatNonEmptyPath.hostTruePath = "./cann-nonexist-compat.tar.gz";
451+ pkgcfg->configMap_["cann-nonexist-compat.tar.gz"] = compatNonEmptyPath;
452+ 
453+ pkgcfg->RefreshHostPluginVersions();
454+ 
455+ // 两个包都应被加锁写入 hostPluginVersions_
456+ ASSERT_NE(pkgcfg->hostPluginVersions_.find("cann-emptypath-compat.tar.gz"),
457+ pkgcfg->hostPluginVersions_.end());
458+ EXPECT_TRUE(pkgcfg->hostPluginVersions_["cann-emptypath-compat.tar.gz"].Empty());
459+ ASSERT_NE(pkgcfg->hostPluginVersions_.find("cann-nonexist-compat.tar.gz"),
460+ pkgcfg->hostPluginVersions_.end());
461+ EXPECT_TRUE(pkgcfg->hostPluginVersions_["cann-nonexist-compat.tar.gz"].Empty());
462+ 
463+ pkgcfg->configMap_.clear();
464+ pkgcfg->hostPluginVersions_.clear();
430}465}