1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <fstream> 17 #include <string> 18 19 #include "xml_helper.h" 20 #include "memmgr_config_manager.h" 21 22 namespace OHOS { 23 namespace Memory { 24 namespace { 25 const std::string TAG = "MemmgrConfigManager"; 26 const std::string XML_PATH = "/etc/memmgr/"; 27 const std::string MEMCG_PATH = KernelInterface::MEMCG_BASE_PATH; 28 } // namespace 29 IMPLEMENT_SINGLE_INSTANCE(MemmgrConfigManager); 30 Init()31 bool MemmgrConfigManager::Init() 32 { 33 killConfig_.ClearKillLevelsMap(); 34 ReadParamFromXml(); 35 WriteReclaimRatiosConfigToKernel(); 36 return this->xmlLoaded_; 37 } 38 MemmgrConfigManager()39 MemmgrConfigManager::MemmgrConfigManager() 40 { 41 InitDefaultConfig(); 42 } 43 ~MemmgrConfigManager()44 MemmgrConfigManager::~MemmgrConfigManager() 45 { 46 ClearReclaimConfigSet(); 47 killConfig_.ClearKillLevelsMap(); 48 } 49 InitDefaultConfig()50 void MemmgrConfigManager::InitDefaultConfig() 51 { 52 availBufferConfig_.SetDefaultConfig(AVAIL_BUFFER, MIN_AVAIL_BUFFER, HIGH_AVAIL_BUFFER, SWAP_RESERVE); 53 reclaimConfig_.SetDefaultConfig(RECLAIM_PRIORITY_MIN, RECLAIM_PRIORITY_MAX, 54 MEMCG_MEM_2_ZRAM_RATIO, MEMCG_ZRAM_2_UFS_RATIO, MEMCG_REFAULT_THRESHOLD); 55 } 56 GetXmlLoaded()57 bool MemmgrConfigManager::GetXmlLoaded() 58 { 59 return xmlLoaded_; 60 } 61 ClearExistConfig()62 void MemmgrConfigManager::ClearExistConfig() 63 { 64 ClearReclaimConfigSet(); 65 } 66 ReadParamFromXml()67 bool MemmgrConfigManager::ReadParamFromXml() 68 { 69 std::string path = KernelInterface::GetInstance().JoinPath(XML_PATH, "memmgr_config.xml"); 70 char absPatch[PATH_MAX] = {0}; 71 HILOGI(":%{public}s", path.c_str()); 72 if (path.length() > PATH_MAX || realpath(path.c_str(), absPatch) == NULL) { 73 return false; 74 } 75 if (!XmlHelper::CheckPathExist(path.c_str())) { 76 HILOGE("bad profile path! path:%{public}s", path.c_str()); 77 return false; 78 } 79 std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr( 80 xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc); 81 if (docPtr == nullptr) { 82 HILOGE("xmlReadFile error!"); 83 return false; 84 } 85 ClearExistConfig(); 86 xmlNodePtr rootNodePtr = xmlDocGetRootElement(docPtr.get()); 87 this->xmlLoaded_ = ParseXmlRootNode(rootNodePtr); 88 return this->xmlLoaded_; 89 } 90 ParseXmlRootNode(const xmlNodePtr & rootNodePtr)91 bool MemmgrConfigManager::ParseXmlRootNode(const xmlNodePtr &rootNodePtr) 92 { 93 for (xmlNodePtr currNode = rootNodePtr->xmlChildrenNode; currNode != nullptr; currNode = currNode->next) { 94 std::string name = std::string(reinterpret_cast<const char *>(currNode->name)); 95 if (name.compare("availBufferConfig") == 0) { 96 availBufferConfig_.ParseConfig(currNode); 97 continue; 98 } 99 100 if (name.compare("reclaimConfig") == 0) { 101 reclaimConfig_.ParseConfig(currNode); 102 continue; 103 } 104 105 if (name.compare("killConfig") == 0) { 106 killConfig_.ParseConfig(currNode); 107 continue; 108 } 109 if (name.compare("systemMemoryLevelConfig") == 0) { 110 systemMemoryLevelConfig_.ParseConfig(currNode); 111 continue; 112 } 113 if (name.compare("reclaimPriorityConfig") == 0) { 114 reclaimPriorityConfig_.ParseConfig(currNode); 115 continue; 116 } 117 if (name.compare("nandLifeConfig") == 0) { 118 nandLifeConfig_.ParseConfig(currNode); 119 continue; 120 } 121 if (name.compare("switchConfig") == 0) { 122 switchConfig_.ParseConfig(currNode); 123 continue; 124 } 125 if (name.compare("purgeablememConfig") == 0) { 126 purgeablememConfig_.ParseConfig(currNode); 127 continue; 128 } 129 HILOGW("unknown node :<%{public}s>", name.c_str()); 130 return false; 131 } 132 return true; 133 } 134 ClearReclaimConfigSet()135 void MemmgrConfigManager::ClearReclaimConfigSet() 136 { 137 reclaimConfig_.ClearReclaimConfigSet(); 138 } 139 GetNandLifeConfig()140 const NandLifeConfig &MemmgrConfigManager::GetNandLifeConfig() 141 { 142 return nandLifeConfig_; 143 } 144 GetSwitchConfig()145 const SwitchConfig &MemmgrConfigManager::GetSwitchConfig() 146 { 147 return switchConfig_; 148 } 149 GetReclaimPriorityConfig()150 const ReclaimPriorityConfig& MemmgrConfigManager::GetReclaimPriorityConfig() 151 { 152 return reclaimPriorityConfig_; 153 } 154 GetKillLevelsMap()155 const KillConfig::KillLevelsMap& MemmgrConfigManager::GetKillLevelsMap() 156 { 157 return killConfig_.GetKillLevelsMap(); 158 } 159 WriteReclaimRatiosConfigToKernel()160 bool MemmgrConfigManager::WriteReclaimRatiosConfigToKernel() 161 { 162 std::string path = KernelInterface::GetInstance().JoinPath(MEMCG_PATH, "memory.zswapd_memcgs_param"); 163 std::string content; 164 165 unsigned int paramNum = reclaimConfig_.GetReclaimConfigSet().size(); 166 content = std::to_string(paramNum); 167 for (auto i = reclaimConfig_.GetReclaimConfigSet().begin(); i != reclaimConfig_.GetReclaimConfigSet().end(); ++i) { 168 content += " " + std::to_string((*i)->GetMinScore()); 169 content += " " + std::to_string((*i)->GetMaxScore()); 170 content += " " + std::to_string((*i)->GetMem2zramRatio()); 171 content += " " + std::to_string((*i)->GetZram2ufsRatio()); 172 content += " " + std::to_string((*i)->GetRefaultThreshold()); 173 } 174 175 HILOGI("Write to kernel: <%{public}s>", content.c_str()); 176 return KernelInterface::GetInstance().WriteToFile(path, content); 177 } 178 GetAvailBufferConfig()179 AvailBufferConfig MemmgrConfigManager::GetAvailBufferConfig() 180 { 181 return availBufferConfig_; 182 } 183 GetReclaimConfigSet()184 const ReclaimConfig::ReclaimConfigSet& MemmgrConfigManager::GetReclaimConfigSet() 185 { 186 return reclaimConfig_.GetReclaimConfigSet(); 187 } 188 GetKillConfig()189 const KillConfig& MemmgrConfigManager::GetKillConfig() 190 { 191 return killConfig_; 192 } 193 GetSystemMemoryLevelConfig()194 SystemMemoryLevelConfig MemmgrConfigManager::GetSystemMemoryLevelConfig() 195 { 196 return systemMemoryLevelConfig_; 197 } 198 GetPurgeablememConfig()199 const PurgeablememConfig& MemmgrConfigManager::GetPurgeablememConfig() 200 { 201 return purgeablememConfig_; 202 } 203 Dump(int fd)204 void MemmgrConfigManager::Dump(int fd) 205 { 206 availBufferConfig_.Dump(fd); 207 killConfig_.Dump(fd); 208 reclaimConfig_.Dump(fd); 209 nandLifeConfig_.Dump(fd); 210 systemMemoryLevelConfig_.Dump(fd); 211 switchConfig_.Dump(fd); 212 reclaimPriorityConfig_.Dump(fd); 213 purgeablememConfig_.Dump(fd); 214 } 215 } // namespace Memory 216 } // namespace OHOS 217