diff options
-rw-r--r-- | init/persistent_properties.cpp | 110 |
1 files changed, 9 insertions, 101 deletions
diff --git a/init/persistent_properties.cpp b/init/persistent_properties.cpp index 71f235532..21adce914 100644 --- a/init/persistent_properties.cpp +++ b/init/persistent_properties.cpp | |||
@@ -43,7 +43,6 @@ std::string persistent_property_filename = "/data/property/persistent_properties | |||
43 | 43 | ||
44 | namespace { | 44 | namespace { |
45 | 45 | ||
46 | constexpr const uint32_t kMagic = 0x8495E0B4; | ||
47 | constexpr const char kLegacyPersistentPropertyDir[] = "/data/property"; | 46 | constexpr const char kLegacyPersistentPropertyDir[] = "/data/property"; |
48 | 47 | ||
49 | void AddPersistentProperty(const std::string& name, const std::string& value, | 48 | void AddPersistentProperty(const std::string& name, const std::string& value, |
@@ -140,85 +139,6 @@ PersistentProperties LoadPersistentPropertiesFromMemory() { | |||
140 | return persistent_properties; | 139 | return persistent_properties; |
141 | } | 140 | } |
142 | 141 | ||
143 | class PersistentPropertyFileParser { | ||
144 | public: | ||
145 | PersistentPropertyFileParser(const std::string& contents) : contents_(contents), position_(0) {} | ||
146 | Result<PersistentProperties> Parse(); | ||
147 | |||
148 | private: | ||
149 | Result<std::string> ReadString(); | ||
150 | Result<uint32_t> ReadUint32(); | ||
151 | |||
152 | const std::string& contents_; | ||
153 | size_t position_; | ||
154 | }; | ||
155 | |||
156 | Result<PersistentProperties> PersistentPropertyFileParser::Parse() { | ||
157 | if (auto magic = ReadUint32(); magic) { | ||
158 | if (*magic != kMagic) { | ||
159 | return Error() << "Magic value '0x" << std::hex << *magic | ||
160 | << "' does not match expected value '0x" << kMagic << "'"; | ||
161 | } | ||
162 | } else { | ||
163 | return Error() << "Could not read magic value: " << magic.error(); | ||
164 | } | ||
165 | |||
166 | if (auto version = ReadUint32(); version) { | ||
167 | if (*version != 1) { | ||
168 | return Error() << "Version '" << *version | ||
169 | << "' does not match any compatible version: (1)"; | ||
170 | } | ||
171 | } else { | ||
172 | return Error() << "Could not read version: " << version.error(); | ||
173 | } | ||
174 | |||
175 | auto num_properties = ReadUint32(); | ||
176 | if (!num_properties) { | ||
177 | return Error() << "Could not read num_properties: " << num_properties.error(); | ||
178 | } | ||
179 | |||
180 | PersistentProperties result; | ||
181 | while (position_ < contents_.size()) { | ||
182 | auto name = ReadString(); | ||
183 | if (!name) { | ||
184 | return Error() << "Could not read name: " << name.error(); | ||
185 | } | ||
186 | if (!StartsWith(*name, "persist.")) { | ||
187 | return Error() << "Property '" << *name << "' does not starts with 'persist.'"; | ||
188 | } | ||
189 | auto value = ReadString(); | ||
190 | if (!value) { | ||
191 | return Error() << "Could not read value: " << value.error(); | ||
192 | } | ||
193 | AddPersistentProperty(*name, *value, &result); | ||
194 | } | ||
195 | |||
196 | return result; | ||
197 | } | ||
198 | |||
199 | Result<std::string> PersistentPropertyFileParser::ReadString() { | ||
200 | auto string_length = ReadUint32(); | ||
201 | if (!string_length) { | ||
202 | return Error() << "Could not read size for string"; | ||
203 | } | ||
204 | |||
205 | if (position_ + *string_length > contents_.size()) { | ||
206 | return Error() << "String size would cause it to overflow the input buffer"; | ||
207 | } | ||
208 | auto result = std::string(contents_, position_, *string_length); | ||
209 | position_ += *string_length; | ||
210 | return result; | ||
211 | } | ||
212 | |||
213 | Result<uint32_t> PersistentPropertyFileParser::ReadUint32() { | ||
214 | if (position_ + 3 > contents_.size()) { | ||
215 | return Error() << "Input buffer not large enough to read uint32_t"; | ||
216 | } | ||
217 | uint32_t result = *reinterpret_cast<const uint32_t*>(&contents_[position_]); | ||
218 | position_ += sizeof(uint32_t); | ||
219 | return result; | ||
220 | } | ||
221 | |||
222 | Result<std::string> ReadPersistentPropertyFile() { | 142 | Result<std::string> ReadPersistentPropertyFile() { |
223 | const std::string temp_filename = persistent_property_filename + ".tmp"; | 143 | const std::string temp_filename = persistent_property_filename + ".tmp"; |
224 | if (access(temp_filename.c_str(), F_OK) == 0) { | 144 | if (access(temp_filename.c_str(), F_OK) == 0) { |
@@ -240,24 +160,13 @@ Result<PersistentProperties> LoadPersistentPropertyFile() { | |||
240 | auto file_contents = ReadPersistentPropertyFile(); | 160 | auto file_contents = ReadPersistentPropertyFile(); |
241 | if (!file_contents) return file_contents.error(); | 161 | if (!file_contents) return file_contents.error(); |
242 | 162 | ||
243 | // Check the intermediate "I should have used protobufs from the start" format. | ||
244 | // TODO: Remove this. | ||
245 | auto parsed_contents = PersistentPropertyFileParser(*file_contents).Parse(); | ||
246 | if (parsed_contents) { | ||
247 | LOG(INFO) << "Intermediate format persistent property file found, converting to protobuf"; | ||
248 | |||
249 | // Update to the protobuf format | ||
250 | WritePersistentPropertyFile(*parsed_contents); | ||
251 | return parsed_contents; | ||
252 | } | ||
253 | |||
254 | PersistentProperties persistent_properties; | 163 | PersistentProperties persistent_properties; |
255 | if (persistent_properties.ParseFromString(*file_contents)) return persistent_properties; | 164 | if (persistent_properties.ParseFromString(*file_contents)) return persistent_properties; |
256 | 165 | ||
257 | // If the file cannot be parsed in either format, then we don't have any recovery | 166 | // If the file cannot be parsed in either format, then we don't have any recovery |
258 | // mechanisms, so we delete it to allow for future writes to take place successfully. | 167 | // mechanisms, so we delete it to allow for future writes to take place successfully. |
259 | unlink(persistent_property_filename.c_str()); | 168 | unlink(persistent_property_filename.c_str()); |
260 | return Error() << "Unable to parse persistent property file: " << parsed_contents.error(); | 169 | return Error() << "Unable to parse persistent property file: Could not parse protobuf"; |
261 | } | 170 | } |
262 | 171 | ||
263 | Result<Success> WritePersistentPropertyFile(const PersistentProperties& persistent_properties) { | 172 | Result<Success> WritePersistentPropertyFile(const PersistentProperties& persistent_properties) { |
@@ -288,25 +197,24 @@ Result<Success> WritePersistentPropertyFile(const PersistentProperties& persiste | |||
288 | // Persistent properties are not written often, so we rather not keep any data in memory and read | 197 | // Persistent properties are not written often, so we rather not keep any data in memory and read |
289 | // then rewrite the persistent property file for each update. | 198 | // then rewrite the persistent property file for each update. |
290 | void WritePersistentProperty(const std::string& name, const std::string& value) { | 199 | void WritePersistentProperty(const std::string& name, const std::string& value) { |
291 | auto file_contents = ReadPersistentPropertyFile(); | 200 | auto persistent_properties = LoadPersistentPropertyFile(); |
292 | PersistentProperties persistent_properties; | ||
293 | 201 | ||
294 | if (!file_contents || !persistent_properties.ParseFromString(*file_contents)) { | 202 | if (!persistent_properties) { |
295 | LOG(ERROR) << "Recovering persistent properties from memory: " | 203 | LOG(ERROR) << "Recovering persistent properties from memory: " |
296 | << (!file_contents ? file_contents.error_string() : "Could not parse protobuf"); | 204 | << persistent_properties.error(); |
297 | persistent_properties = LoadPersistentPropertiesFromMemory(); | 205 | persistent_properties = LoadPersistentPropertiesFromMemory(); |
298 | } | 206 | } |
299 | auto it = std::find_if(persistent_properties.mutable_properties()->begin(), | 207 | auto it = std::find_if(persistent_properties->mutable_properties()->begin(), |
300 | persistent_properties.mutable_properties()->end(), | 208 | persistent_properties->mutable_properties()->end(), |
301 | [&name](const auto& record) { return record.name() == name; }); | 209 | [&name](const auto& record) { return record.name() == name; }); |
302 | if (it != persistent_properties.mutable_properties()->end()) { | 210 | if (it != persistent_properties->mutable_properties()->end()) { |
303 | it->set_name(name); | 211 | it->set_name(name); |
304 | it->set_value(value); | 212 | it->set_value(value); |
305 | } else { | 213 | } else { |
306 | AddPersistentProperty(name, value, &persistent_properties); | 214 | AddPersistentProperty(name, value, &persistent_properties.value()); |
307 | } | 215 | } |
308 | 216 | ||
309 | if (auto result = WritePersistentPropertyFile(persistent_properties); !result) { | 217 | if (auto result = WritePersistentPropertyFile(*persistent_properties); !result) { |
310 | LOG(ERROR) << "Could not store persistent property: " << result.error(); | 218 | LOG(ERROR) << "Could not store persistent property: " << result.error(); |
311 | } | 219 | } |
312 | } | 220 | } |