summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Shen <dzshen@google.com>2024-03-05 15:22:51 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-03-05 15:22:51 +0000
commit28062be20f4e92dd8d0b7a6457487780f4efc18f (patch)
tree1548b19da66fd5e5eb8e39ca46867cf661fb208b
parent4fa145dc8132ad1ad5d754f115d7ce325198c26c (diff)
parentb869ff6d80b035e211a01027cd075bff00ea2f2e (diff)
downloadserver_configurable_flags-temp_319669529.tar.gz
aconfig_storage: update aconfig storage daemon am: b869ff6d80temp_319669529
Original change: https://android-review.googlesource.com/c/platform/system/server_configurable_flags/+/2984891 Change-Id: I4481e400506f952f4d27305f59121b678be5236b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--aconfigd/aconfigd.cpp128
1 files changed, 95 insertions, 33 deletions
diff --git a/aconfigd/aconfigd.cpp b/aconfigd/aconfigd.cpp
index 731c59c..7c991fe 100644
--- a/aconfigd/aconfigd.cpp
+++ b/aconfigd/aconfigd.cpp
@@ -37,6 +37,10 @@ namespace aconfigd {
static constexpr char kPersistentStorageRecordsFileName[] =
"/metadata/aconfig/persistent_storage_file_records.pb";
+/// Persistent storage records pb file full path
+static constexpr char kAvailableStorageRecordsFileName[] =
+ "/metadata/aconfig/available_storage_file_records.pb";
+
/// In memory data structure for storage file locations for each container
struct StorageRecord {
int version;
@@ -62,7 +66,7 @@ struct StorageRecord {
using StorageRecords = std::unordered_map<std::string, StorageRecord>;
/// In memort storage file records. Parsed from the pb.
-static StorageRecords storage_records;
+static StorageRecords persist_storage_records;
namespace {
@@ -82,10 +86,25 @@ Result<storage_records_pb> ReadPersistentStorageRecordsPb() {
return records;
}
+/// Write aconfig storage records protobuf to file
+Result<void> WriteStorageRecordsPbToFile(const storage_records_pb& records_pb,
+ const std::string& file_name) {
+ auto content = std::string();
+ if (!records_pb.SerializeToString(&content)) {
+ return ErrnoError() << "Unable to serialize storage records protobuf";
+ }
+
+ if (!WriteStringToFile(content, file_name)) {
+ return ErrnoError() << "WriteStringToFile failed";
+ }
+
+ return {};
+}
+
/// Write in memory aconfig storage records to the persistent pb file
Result<void> WritePersistentStorageRecordsToFile() {
auto records_pb = storage_records_pb();
- for (auto const& [container, entry] : storage_records) {
+ for (auto const& [container, entry] : persist_storage_records) {
auto* record_pb = records_pb.add_files();
record_pb->set_version(entry.version);
record_pb->set_container(entry.container);
@@ -95,16 +114,7 @@ Result<void> WritePersistentStorageRecordsToFile() {
record_pb->set_timestamp(entry.timestamp);
}
- auto content = std::string();
- if (!records_pb.SerializeToString(&content)) {
- return ErrnoError() << "Unable to serialize storage records protobuf";
- }
-
- if (!WriteStringToFile(content, kPersistentStorageRecordsFileName)) {
- return ErrnoError() << "ReadStringToFile failed";
- }
-
- return {};
+ return WriteStorageRecordsPbToFile(records_pb, kPersistentStorageRecordsFileName);
}
/// Initialize in memory aconfig storage records
@@ -115,14 +125,74 @@ Result<void> InitializeInMemoryStorageRecords() {
<< records_pb.error();
}
- storage_records.clear();
+ persist_storage_records.clear();
for (auto& entry : records_pb->files()) {
- storage_records.insert({entry.container(), StorageRecord(entry)});
+ persist_storage_records.insert({entry.container(), StorageRecord(entry)});
+ }
+
+ return {};
+}
+
+/// Create boot flag value copy for a container
+Result<void> CreateBootSnapshotForContainer(const std::string& container,
+ storage_records_pb& available_storage) {
+ auto src_value_file = std::string("/metadata/aconfig/flags/") + container + ".val";
+ auto dst_value_file = std::string("/metadata/aconfig/boot/") + container + ".val";
+ auto copy_result = CopyFile(src_value_file, dst_value_file);
+ if (!copy_result.ok()) {
+ return Error() << "CopyFile failed for " << src_value_file << " :"
+ << copy_result.error();
+ }
+
+ if (!persist_storage_records.count(container)) {
+ return Error() << "Missing persistent storage records for " << container;
}
+ auto const& entry = persist_storage_records[container];
+ auto* record_pb = available_storage.add_files();
+ record_pb->set_container(entry.container);
+ record_pb->set_package_map(entry.package_map);
+ record_pb->set_flag_map(entry.flag_map);
+ record_pb->set_flag_val(dst_value_file);
+ record_pb->set_timestamp(entry.timestamp);
+
return {};
}
+/// Handle container update, returns if container has been updated
+Result<bool> HandleContainerUpdate(const std::string& container,
+ const std::string& package_file,
+ const std::string& flag_file,
+ const std::string& value_file) {
+ auto timestamp = GetFileTimeStamp(value_file);
+ if (!timestamp.ok()) {
+ return Error() << "Failed to get timestamp of " << value_file
+ << ": "<< timestamp.error();
+ }
+
+ // check if a partition has been updated by checking timestamp
+ auto it = persist_storage_records.find(container);
+ if (it == persist_storage_records.end() || it->second.timestamp != *timestamp) {
+ auto target_value_file = std::string("/metadata/aconfig/flags/") + container + ".val";
+ auto copy_result = CopyFile(value_file, target_value_file);
+ if (!copy_result.ok()) {
+ return Error() << "CopyFile failed for " << value_file << " :"
+ << copy_result.error();
+ }
+
+ auto& record = persist_storage_records[container];
+ record.container = container;
+ record.package_map = package_file;
+ record.flag_map = flag_file;
+ record.flag_val = target_value_file;
+ record.timestamp = *timestamp;
+
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
/// Initialize platform RO partition flag storage
@@ -139,6 +209,7 @@ Result<void> InitializePlatformStorage() {
{"vendor", "/vendor/etc/aconfig"},
{"product", "/product/etc/aconfig"}};
+ auto available_storage_pb = storage_records_pb();
bool update_persistent_storage_records = false;
for (auto const& [container, storage_dir] : value_files) {
auto package_file = std::string(storage_dir) + "/package.map";
@@ -149,27 +220,16 @@ Result<void> InitializePlatformStorage() {
continue;
}
- auto timestamp = GetFileTimeStamp(value_file);
- if (!timestamp.ok()) {
- return Error() << "Failed to get timestamp of " << value_file
- << ": "<< timestamp.error();
+ auto updated_result = HandleContainerUpdate(container, package_file, flag_file, value_file);
+ if (!updated_result.ok()) {
+ return Error() << updated_result.error();
+ } else {
+ update_persistent_storage_records |= *updated_result;
}
- auto it = storage_records.find(container);
- if (it == storage_records.end() || it->second.timestamp != *timestamp) {
- update_persistent_storage_records = true;
- auto target_value_file = std::string("/metadata/aconfig/flags/") + container + ".val";
- auto copy_result = CopyFile(value_file, target_value_file);
- if (!copy_result.ok()) {
- return Error() << "CopyFile failed for " << value_file << " :"
- << copy_result.error();
- }
- auto& record = storage_records[container];
- record.container = container;
- record.package_map = package_file;
- record.flag_map = flag_file;
- record.flag_val = value_file;
- record.timestamp = *timestamp;
+ auto copy_result = CreateBootSnapshotForContainer(container, available_storage_pb);
+ if (!copy_result.ok()) {
+ return Error() << copy_result.error();
}
}
@@ -181,6 +241,8 @@ Result<void> InitializePlatformStorage() {
}
}
+ WriteStorageRecordsPbToFile(available_storage_pb, kAvailableStorageRecordsFileName);
+
return {};
}