xref: /aosp_15_r20/system/server_configurable_flags/aconfigd/aconfigd.cpp (revision 207333786ba243bc7d4d69ef6b05487aa7071806)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <memory>
18 #include <string>
19 #include <dirent.h>
20 
21 #include <android-base/file.h>
22 #include <android-base/logging.h>
23 #include <android-base/properties.h>
24 
25 #include "storage_files_manager.h"
26 #include "aconfigd_util.h"
27 #include "aconfigd.h"
28 
29 using namespace android::base;
30 
31 namespace android {
32 namespace aconfigd {
33 
34 /// Handle a flag override request
HandleFlagOverride(const StorageRequestMessage::FlagOverrideMessage & msg,StorageReturnMessage & return_msg)35 Result<void> Aconfigd::HandleFlagOverride(
36     const StorageRequestMessage::FlagOverrideMessage& msg,
37     StorageReturnMessage& return_msg) {
38   auto result = storage_files_manager_->UpdateFlagValue(
39       msg.package_name(), msg.flag_name(), msg.flag_value(),
40       msg.override_type());
41   RETURN_IF_ERROR(result, "Failed to set flag override");
42   return_msg.mutable_flag_override_message();
43   return {};
44 }
45 
46 /// Handle ota flag staging request
HandleOTAStaging(const StorageRequestMessage::OTAFlagStagingMessage & msg,StorageReturnMessage & return_msg)47 Result<void> Aconfigd::HandleOTAStaging(
48     const StorageRequestMessage::OTAFlagStagingMessage& msg,
49     StorageReturnMessage& return_msg) {
50   auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
51   auto stored_pb_result =
52       ReadPbFromFile<StorageRequestMessage::OTAFlagStagingMessage>(
53           ota_flags_pb_file);
54 
55   if (!stored_pb_result.ok() ||
56       (msg.build_id() != (*stored_pb_result).build_id())) {
57     LOG(INFO) << "discarding staged flags from " +
58                      (*stored_pb_result).build_id() +
59                      "; staging new flags for " + msg.build_id();
60     auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
61         msg, ota_flags_pb_file);
62     RETURN_IF_ERROR(result, "Failed to stage OTA flags");
63     return_msg.mutable_ota_staging_message();
64     return {};
65   }
66 
67   std::set<std::string> qualified_names;
68 
69   std::map<std::string, android::aconfigd::FlagOverride> new_name_to_override;
70   for (const auto& flag_override : msg.overrides()) {
71     auto qualified_name =
72         flag_override.package_name() + "." + flag_override.flag_name();
73     new_name_to_override[qualified_name] = flag_override;
74 
75     qualified_names.insert(qualified_name);
76   }
77 
78   std::map<std::string, android::aconfigd::FlagOverride> prev_name_to_override;
79   for (const auto& flag_override : (*stored_pb_result).overrides()) {
80     auto qualified_name =
81         flag_override.package_name() + "." + flag_override.flag_name();
82     prev_name_to_override[qualified_name] = flag_override;
83 
84     qualified_names.insert(qualified_name);
85   }
86 
87   std::vector<android::aconfigd::FlagOverride> overrides;
88   for (const auto& qualified_name : qualified_names) {
89     if (new_name_to_override.contains(qualified_name)) {
90       overrides.push_back(new_name_to_override[qualified_name]);
91     } else {
92       overrides.push_back(prev_name_to_override[qualified_name]);
93     }
94   }
95 
96   StorageRequestMessage::OTAFlagStagingMessage message_to_persist;
97   message_to_persist.set_build_id(msg.build_id());
98   for (const auto& flag_override : overrides) {
99     auto override_ = message_to_persist.add_overrides();
100     override_->set_flag_name(flag_override.flag_name());
101     override_->set_package_name(flag_override.package_name());
102     override_->set_flag_value(flag_override.flag_value());
103   }
104 
105   auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
106       message_to_persist, ota_flags_pb_file);
107   RETURN_IF_ERROR(result, "Failed to stage OTA flags");
108   return_msg.mutable_ota_staging_message();
109   return {};
110 }
111 
112 /// Handle new storage request
HandleNewStorage(const StorageRequestMessage::NewStorageMessage & msg,StorageReturnMessage & return_msg)113 Result<void> Aconfigd::HandleNewStorage(
114     const StorageRequestMessage::NewStorageMessage& msg,
115     StorageReturnMessage& return_msg) {
116   auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
117       msg.container(), msg.package_map(), msg.flag_map(), msg.flag_value(),
118       msg.flag_info());
119   RETURN_IF_ERROR(updated, "Failed to add or update container");
120 
121   auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
122       persist_storage_records_);
123   RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
124 
125   auto copy = storage_files_manager_->CreateStorageBootCopy(msg.container());
126   RETURN_IF_ERROR(copy, "Failed to make a boot copy for " + msg.container());
127 
128   auto result_msg = return_msg.mutable_new_storage_message();
129   result_msg->set_storage_updated(*updated);
130   return {};
131 }
132 
133 /// Handle a flag query request
HandleFlagQuery(const StorageRequestMessage::FlagQueryMessage & msg,StorageReturnMessage & return_msg)134 Result<void> Aconfigd::HandleFlagQuery(
135     const StorageRequestMessage::FlagQueryMessage& msg,
136     StorageReturnMessage& return_msg) {
137   auto snapshot = storage_files_manager_->ListFlag(msg.package_name(), msg.flag_name());
138   RETURN_IF_ERROR(snapshot, "Failed query failed");
139   auto result_msg = return_msg.mutable_flag_query_message();
140   result_msg->set_package_name(snapshot->package_name);
141   result_msg->set_flag_name(snapshot->flag_name);
142   result_msg->set_server_flag_value(snapshot->server_flag_value);
143   result_msg->set_local_flag_value(snapshot->local_flag_value);
144   result_msg->set_boot_flag_value(snapshot->boot_flag_value);
145   result_msg->set_default_flag_value(snapshot->default_flag_value);
146   result_msg->set_has_server_override(snapshot->has_server_override);
147   result_msg->set_is_readwrite(snapshot->is_readwrite);
148   result_msg->set_has_local_override(snapshot->has_local_override);
149   return {};
150 }
151 
152 /// Handle override removal request
HandleLocalOverrideRemoval(const StorageRequestMessage::RemoveLocalOverrideMessage & msg,StorageReturnMessage & return_msg)153 Result<void> Aconfigd::HandleLocalOverrideRemoval(
154     const StorageRequestMessage::RemoveLocalOverrideMessage& msg,
155     StorageReturnMessage& return_msg) {
156   auto result = Result<void>();
157   if (msg.remove_all()) {
158     result = storage_files_manager_->RemoveAllLocalOverrides(
159         msg.remove_override_type());
160   } else {
161     result = storage_files_manager_->RemoveFlagLocalOverride(
162         msg.package_name(), msg.flag_name(), msg.remove_override_type());
163   }
164   RETURN_IF_ERROR(result, "");
165   return_msg.mutable_remove_local_override_message();
166   return {};
167 }
168 
169 /// Handle storage reset
HandleStorageReset(StorageReturnMessage & return_msg)170 Result<void> Aconfigd::HandleStorageReset(StorageReturnMessage& return_msg) {
171   auto result = storage_files_manager_->ResetAllStorage();
172   RETURN_IF_ERROR(result, "Failed to reset all storage");
173 
174   result = storage_files_manager_->WritePersistStorageRecordsToFile(
175       persist_storage_records_);
176   RETURN_IF_ERROR(result, "Failed to write persist storage records");
177 
178   return_msg.mutable_reset_storage_message();
179   return {};
180 }
181 
182 /// Handle list storage
HandleListStorage(const StorageRequestMessage::ListStorageMessage & msg,StorageReturnMessage & return_message)183 Result<void> Aconfigd::HandleListStorage(
184     const StorageRequestMessage::ListStorageMessage& msg,
185     StorageReturnMessage& return_message) {
186   auto flags = Result<std::vector<StorageFiles::FlagSnapshot>>();
187   switch (msg.msg_case()) {
188     case StorageRequestMessage::ListStorageMessage::kAll: {
189       flags = storage_files_manager_->ListAllAvailableFlags();
190       break;
191     }
192     case StorageRequestMessage::ListStorageMessage::kContainer: {
193       flags = storage_files_manager_->ListFlagsInContainer(msg.container());
194       break;
195     }
196     case StorageRequestMessage::ListStorageMessage::kPackageName: {
197       flags = storage_files_manager_->ListFlagsInPackage(msg.package_name());
198       break;
199     }
200     default:
201       return Error() << "Unknown list storage message type from aconfigd socket";
202   }
203   RETURN_IF_ERROR(flags, "Failed to list flags");
204 
205   auto* result_msg = return_message.mutable_list_storage_message();
206   for (const auto& flag : *flags) {
207     auto* flag_msg = result_msg->add_flags();
208     flag_msg->set_package_name(flag.package_name);
209     flag_msg->set_flag_name(flag.flag_name);
210     flag_msg->set_server_flag_value(flag.server_flag_value);
211     flag_msg->set_local_flag_value(flag.local_flag_value);
212     flag_msg->set_boot_flag_value(flag.boot_flag_value);
213     flag_msg->set_default_flag_value(flag.default_flag_value);
214     flag_msg->set_is_readwrite(flag.is_readwrite);
215     flag_msg->set_has_server_override(flag.has_server_override);
216     flag_msg->set_has_local_override(flag.has_local_override);
217     flag_msg->set_has_boot_local_override(flag.has_boot_local_override);
218   }
219   return {};
220 }
221 
222 /// Read OTA flag overrides to be applied for current build
ReadOTAFlagOverridesToApply()223 Result<std::vector<FlagOverride>> Aconfigd::ReadOTAFlagOverridesToApply() {
224   auto ota_flags = std::vector<FlagOverride>();
225   auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
226   if (FileExists(ota_flags_pb_file)) {
227     auto build_id = GetProperty("ro.build.fingerprint", "");
228     auto ota_flags_pb = ReadPbFromFile<StorageRequestMessage::OTAFlagStagingMessage>(
229         ota_flags_pb_file);
230     RETURN_IF_ERROR(ota_flags_pb, "Failed to read ota flags from pb file");
231     if (ota_flags_pb->build_id() == build_id) {
232       for (const auto& entry : ota_flags_pb->overrides()) {
233         ota_flags.push_back(entry);
234       }
235       // delete staged ota flags file if it matches current build id, so that
236       // it will not be reapplied in the future boots
237       unlink(ota_flags_pb_file.c_str());
238     }
239   }
240   return ota_flags;
241 }
242 
243 /// Initialize in memory aconfig storage records
InitializeInMemoryStorageRecords()244 Result<void> Aconfigd::InitializeInMemoryStorageRecords() {
245   auto records_pb = ReadPbFromFile<PersistStorageRecords>(persist_storage_records_);
246   RETURN_IF_ERROR(records_pb, "Unable to read persistent storage records");
247   for (const auto& entry : records_pb->records()) {
248     storage_files_manager_->RestoreStorageFiles(entry);
249   }
250   return {};
251 }
252 
253 /// Initialize platform RO partition flag storage
InitializePlatformStorage()254 Result<void> Aconfigd::InitializePlatformStorage() {
255   auto init_result = InitializeInMemoryStorageRecords();
256   RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
257 
258   auto remove_result = RemoveFilesInDir(root_dir_ + "/boot");
259   RETURN_IF_ERROR(remove_result, "Failed to clean boot dir");
260 
261   auto ota_flags = ReadOTAFlagOverridesToApply();
262   RETURN_IF_ERROR(ota_flags, "Failed to get remaining staged OTA flags");
263   bool apply_ota_flag = !(ota_flags->empty());
264 
265   auto partitions = std::vector<std::pair<std::string, std::string>>{
266     {"system", "/system/etc/aconfig"},
267     {"vendor", "/vendor/etc/aconfig"},
268     {"product", "/product/etc/aconfig"}};
269 
270   for (auto const& [container, storage_dir] : partitions) {
271     auto package_file = std::string(storage_dir) + "/package.map";
272     auto flag_file = std::string(storage_dir) + "/flag.map";
273     auto value_file = std::string(storage_dir) + "/flag.val";
274     auto info_file = std::string(storage_dir) + "/flag.info";
275 
276     if (!FileNonZeroSize(value_file)) {
277       continue;
278     }
279 
280     auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
281         container, package_file, flag_file, value_file, info_file);
282     RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
283                     + container);
284 
285     if (apply_ota_flag) {
286       ota_flags = storage_files_manager_->ApplyOTAFlagsForContainer(
287           container, *ota_flags);
288       RETURN_IF_ERROR(ota_flags, "Failed to apply staged OTA flags");
289     }
290 
291     auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
292         persist_storage_records_);
293     RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
294 
295     auto copied = storage_files_manager_->CreateStorageBootCopy(container);
296     RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
297                     + container);
298   }
299 
300   return {};
301 }
302 
303 /// Initialize mainline flag storage
InitializeMainlineStorage()304 Result<void> Aconfigd::InitializeMainlineStorage() {
305   auto init_result = InitializeInMemoryStorageRecords();
306   RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
307 
308   auto apex_dir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/apex"), closedir);
309   if (!apex_dir) {
310     return {};
311   }
312 
313   struct dirent* entry;
314   while ((entry = readdir(apex_dir.get())) != nullptr) {
315     if (entry->d_type != DT_DIR) continue;
316 
317     auto container = std::string(entry->d_name);
318     if (container[0] == '.') continue;
319     if (container.find('@') != std::string::npos) continue;
320     if (container == "sharedlibs") continue;
321 
322     auto storage_dir = std::string("/apex/") + container + "/etc";
323     auto package_file = std::string(storage_dir) + "/package.map";
324     auto flag_file = std::string(storage_dir) + "/flag.map";
325     auto value_file = std::string(storage_dir) + "/flag.val";
326     auto info_file = std::string(storage_dir) + "/flag.info";
327 
328     if (!FileExists(value_file) || !FileNonZeroSize(value_file)) {
329       continue;
330     }
331 
332     auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
333         container, package_file, flag_file, value_file, info_file);
334     RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
335                     + container);
336 
337     auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
338         persist_storage_records_);
339     RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
340 
341     auto copied = storage_files_manager_->CreateStorageBootCopy(container);
342     RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
343                     + container);
344   }
345 
346   return {};
347 }
348 
349 /// Handle incoming messages to aconfigd socket
HandleSocketRequest(const StorageRequestMessage & message,StorageReturnMessage & return_message)350 Result<void> Aconfigd::HandleSocketRequest(const StorageRequestMessage& message,
351                                            StorageReturnMessage& return_message) {
352   auto result = Result<void>();
353 
354   switch (message.msg_case()) {
355     case StorageRequestMessage::kNewStorageMessage: {
356       auto msg = message.new_storage_message();
357       LOG(INFO) << "received a new storage request for " << msg.container()
358                 << " with storage files " << msg.package_map() << " "
359                 << msg.flag_map() << " " << msg.flag_value();
360       result = HandleNewStorage(msg, return_message);
361       break;
362     }
363     case StorageRequestMessage::kFlagOverrideMessage: {
364       auto msg = message.flag_override_message();
365       LOG(DEBUG) << "received a '" << OverrideTypeToStr(msg.override_type())
366                 << "' flag override request for " << msg.package_name() << "/"
367                 << msg.flag_name() << " to " << msg.flag_value();
368       result = HandleFlagOverride(msg, return_message);
369       break;
370     }
371     case StorageRequestMessage::kOtaStagingMessage: {
372       auto msg = message.ota_staging_message();
373       LOG(INFO) << "received ota flag staging requests for " << msg.build_id();
374       result = HandleOTAStaging(msg, return_message);
375       break;
376     }
377     case StorageRequestMessage::kFlagQueryMessage: {
378       auto msg = message.flag_query_message();
379       LOG(INFO) << "received a flag query request for " << msg.package_name()
380                 << "/" << msg.flag_name();
381       result = HandleFlagQuery(msg, return_message);
382       break;
383     }
384     case StorageRequestMessage::kRemoveLocalOverrideMessage: {
385       auto msg = message.remove_local_override_message();
386       if (msg.remove_all()) {
387         LOG(INFO) << "received a global local override removal request";
388       } else {
389         LOG(INFO) << "received local override removal request for "
390                   << msg.package_name() << "/" << msg.flag_name();
391       }
392       result = HandleLocalOverrideRemoval(msg, return_message);
393       break;
394     }
395     case StorageRequestMessage::kResetStorageMessage: {
396       LOG(INFO) << "received reset storage request";
397       result = HandleStorageReset(return_message);
398       break;
399     }
400     case StorageRequestMessage::kListStorageMessage: {
401       auto msg = message.list_storage_message();
402       LOG(INFO) << "received list storage request";
403       result = HandleListStorage(msg, return_message);
404       break;
405     }
406     default:
407       result = Error() << "Unknown message type from aconfigd socket";
408       break;
409   }
410 
411   return result;
412 }
413 
414 } // namespace aconfigd
415 } // namespace android
416