已合并
多线程更新插件包信息coredump修复 #2683
pantong创建于 6月8日
多线程更新插件包信息coredump修复 #2683
已合并
共 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() const | 58 | 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; |
| 69 | private: | 69 | private: |
| 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_H | 93 | #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) const | 272 | + 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) const | 335 | + 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 | } |