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