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 "storage_files.h" 18 19 #include <android-base/logging.h> 20 #include <unistd.h> 21 22 #include <aconfig_storage/aconfig_storage_file.hpp> 23 24 #include "aconfigd.h" 25 #include "aconfigd_util.h" 26 #include "com_android_aconfig_new_storage.h" 27 28 using namespace aconfig_storage; 29 30 namespace android { 31 namespace aconfigd { 32 33 /// constructor for a new storage file set StorageFiles(const std::string & container,const std::string & package_map,const std::string & flag_map,const std::string & flag_val,const std::string & flag_info,const std::string & root_dir,base::Result<void> & status)34 StorageFiles::StorageFiles(const std::string& container, 35 const std::string& package_map, 36 const std::string& flag_map, 37 const std::string& flag_val, 38 const std::string& flag_info, 39 const std::string& root_dir, 40 base::Result<void>& status) 41 : container_(container) 42 , storage_record_() 43 , package_map_(nullptr) 44 , flag_map_(nullptr) 45 , flag_val_(nullptr) 46 , boot_flag_val_(nullptr) 47 , boot_flag_info_(nullptr) 48 , persist_flag_val_(nullptr) 49 , persist_flag_info_(nullptr) { 50 auto version = get_storage_file_version(flag_val); 51 if (!version.ok()) { 52 status = base::Error() << "failed to get file version: " << version.error(); 53 return; 54 } 55 56 auto digest = GetFilesDigest({package_map, flag_map, flag_val, flag_info}); 57 if (!digest.ok()) { 58 status = base::Error() << "failed to get files digest: " << digest.error(); 59 return; 60 } 61 62 storage_record_.version = *version; 63 storage_record_.container = container; 64 storage_record_.package_map = package_map; 65 storage_record_.flag_map = flag_map; 66 storage_record_.flag_val = flag_val; 67 storage_record_.flag_info = flag_info; 68 storage_record_.persist_package_map = 69 root_dir + "/maps/" + container + ".package.map"; 70 storage_record_.persist_flag_map = 71 root_dir + "/maps/" + container + ".flag.map"; 72 storage_record_.persist_flag_val = 73 root_dir + "/flags/" + container + ".val"; 74 storage_record_.persist_flag_info = 75 root_dir + "/flags/" + container + ".info"; 76 storage_record_.local_overrides = 77 root_dir + "/flags/" + container + "_local_overrides.pb"; 78 storage_record_.boot_flag_val = 79 root_dir + "/boot/" + container + ".val"; 80 storage_record_.boot_flag_info = 81 root_dir + "/boot/" + container + ".info"; 82 storage_record_.digest= *digest; 83 84 // copy package map file 85 auto copy_result = CopyFile(package_map, storage_record_.persist_package_map, 0444); 86 if (!copy_result.ok()) { 87 status = base::Error() << "CopyFile failed for " << package_map << ": " 88 << copy_result.error(); 89 return; 90 } 91 92 // copy flag map file 93 copy_result = CopyFile(flag_map, storage_record_.persist_flag_map, 0444); 94 if (!copy_result.ok()) { 95 status = base::Error() << "CopyFile failed for " << flag_map << ": " 96 << copy_result.error(); 97 return; 98 } 99 100 // copy flag value file 101 copy_result = CopyFile(flag_val, storage_record_.persist_flag_val, 0644); 102 if (!copy_result.ok()) { 103 status = base::Error() << "CopyFile failed for " << flag_val << ": " 104 << copy_result.error(); 105 return; 106 } 107 108 // copy flag info file 109 copy_result = CopyFile(flag_info, storage_record_.persist_flag_info, 0644); 110 if (!copy_result.ok()) { 111 status = base::Error() << "CopyFile failed for " << flag_info << ": " 112 << copy_result.error(); 113 return; 114 } 115 } 116 117 /// constructor for existing new storage file set StorageFiles(const PersistStorageRecord & pb,const std::string & root_dir)118 StorageFiles::StorageFiles(const PersistStorageRecord& pb, 119 const std::string& root_dir) 120 : container_(pb.container()) 121 , storage_record_() 122 , package_map_(nullptr) 123 , flag_map_(nullptr) 124 , flag_val_(nullptr) 125 , boot_flag_val_(nullptr) 126 , boot_flag_info_(nullptr) 127 , persist_flag_val_(nullptr) 128 , persist_flag_info_(nullptr) { 129 storage_record_.version = pb.version(); 130 storage_record_.container = pb.container(); 131 storage_record_.package_map = pb.package_map(); 132 storage_record_.flag_map = pb.flag_map(); 133 storage_record_.flag_val = pb.flag_val(); 134 if (pb.has_flag_info()) { 135 storage_record_.flag_info = pb.flag_info(); 136 } else { 137 auto val_file = storage_record_.flag_val; 138 storage_record_.flag_info = val_file.substr(0, val_file.size()-3) + "info"; 139 } 140 storage_record_.persist_package_map = 141 root_dir + "/maps/" + pb.container() + ".package.map"; 142 storage_record_.persist_flag_map = 143 root_dir + "/maps/" + pb.container() + ".flag.map"; 144 storage_record_.persist_flag_val = 145 root_dir + "/flags/" + pb.container() + ".val"; 146 storage_record_.persist_flag_info = 147 root_dir + "/flags/" + pb.container() + ".info"; 148 storage_record_.local_overrides = 149 root_dir + "/flags/" + pb.container() + "_local_overrides.pb"; 150 storage_record_.boot_flag_val = 151 root_dir + "/boot/" + pb.container() + ".val"; 152 storage_record_.boot_flag_info = 153 root_dir + "/boot/" + pb.container() + ".info"; 154 storage_record_.digest = pb.digest(); 155 } 156 157 /// move constructor StorageFiles(StorageFiles && rhs)158 StorageFiles::StorageFiles(StorageFiles&& rhs) { 159 if (this != &rhs) { 160 *this = std::move(rhs); 161 } 162 } 163 164 /// move assignment operator =(StorageFiles && rhs)165 StorageFiles& StorageFiles::operator=(StorageFiles&& rhs) { 166 if (this != &rhs) { 167 container_ = rhs.container_; 168 storage_record_ = std::move(rhs.storage_record_); 169 package_map_ = std::move(rhs.package_map_); 170 flag_map_ = std::move(rhs.flag_map_); 171 flag_val_ = std::move(rhs.flag_val_); 172 boot_flag_val_ = std::move(rhs.boot_flag_val_); 173 boot_flag_info_ = std::move(rhs.boot_flag_info_); 174 persist_flag_val_ = std::move(rhs.persist_flag_val_); 175 persist_flag_info_ = std::move(rhs.persist_flag_info_); 176 } 177 return *this; 178 } 179 180 /// get package map GetPackageMap()181 base::Result<const MappedStorageFile*> StorageFiles::GetPackageMap() { 182 if (!package_map_) { 183 if (storage_record_.persist_package_map.empty()) { 184 return base::Error() << "Missing persist package map file"; 185 } 186 auto package_map = map_storage_file(storage_record_.persist_package_map); 187 RETURN_IF_ERROR(package_map, "Failed to map persist package map file for " + container_); 188 package_map_.reset(*package_map); 189 } 190 return package_map_.get(); 191 } 192 193 /// get flag map GetFlagMap()194 base::Result<const MappedStorageFile*> StorageFiles::GetFlagMap() { 195 if (!flag_map_) { 196 if (storage_record_.persist_flag_map.empty()) { 197 return base::Error() << "Missing persist flag map file"; 198 } 199 auto flag_map = map_storage_file(storage_record_.persist_flag_map); 200 RETURN_IF_ERROR(flag_map, "Failed to map persist flag map file for " + container_); 201 flag_map_.reset(*flag_map); 202 } 203 return flag_map_.get(); 204 } 205 206 /// get default flag val GetFlagVal()207 base::Result<const MappedStorageFile*> StorageFiles::GetFlagVal() { 208 if (!flag_val_) { 209 if (storage_record_.flag_val.empty()) { 210 return base::Error() << "Missing flag val file"; 211 } 212 auto flag_val = map_storage_file(storage_record_.flag_val); 213 RETURN_IF_ERROR(flag_val, "Failed to map flag val file for " + container_); 214 flag_val_.reset(*flag_val); 215 } 216 return flag_val_.get(); 217 } 218 219 /// get boot flag val GetBootFlagVal()220 base::Result<const MappedStorageFile*> StorageFiles::GetBootFlagVal() { 221 if (!boot_flag_val_) { 222 if (storage_record_.boot_flag_val.empty()) { 223 return base::Error() << "Missing boot flag val file"; 224 } 225 auto flag_val = map_storage_file(storage_record_.boot_flag_val); 226 RETURN_IF_ERROR(flag_val, "Failed to map boot flag val file for " + container_); 227 boot_flag_val_.reset(*flag_val); 228 } 229 return boot_flag_val_.get(); 230 } 231 232 /// get boot flag info GetBootFlagInfo()233 base::Result<const MappedStorageFile*> StorageFiles::GetBootFlagInfo() { 234 if (!boot_flag_info_) { 235 if (storage_record_.boot_flag_info.empty()) { 236 return base::Error() << "Missing boot flag info file"; 237 } 238 auto flag_info = map_storage_file(storage_record_.boot_flag_info); 239 RETURN_IF_ERROR(flag_info, "Failed to map boot flag info file for " + container_); 240 boot_flag_info_.reset(*flag_info); 241 } 242 return boot_flag_info_.get(); 243 } 244 245 /// get persist flag val GetPersistFlagVal()246 base::Result<const MutableMappedStorageFile*> StorageFiles::GetPersistFlagVal() { 247 if (!persist_flag_val_) { 248 if (storage_record_.persist_flag_val.empty()) { 249 return base::Error() << "Missing persist flag value file"; 250 } 251 auto flag_val = map_mutable_storage_file(storage_record_.persist_flag_val); 252 RETURN_IF_ERROR(flag_val, "Failed to map persist flag val file for " + container_); 253 persist_flag_val_.reset(*flag_val); 254 } 255 return persist_flag_val_.get(); 256 } 257 258 /// get persist flag info GetPersistFlagInfo()259 base::Result<const MutableMappedStorageFile*> StorageFiles::GetPersistFlagInfo() { 260 if (!persist_flag_info_) { 261 if (storage_record_.persist_flag_info.empty()) { 262 return base::Error() << "Missing persist flag info file"; 263 } 264 auto flag_info = map_mutable_storage_file(storage_record_.persist_flag_info); 265 RETURN_IF_ERROR(flag_info, "Failed to map persist flag info file for " + container_); 266 persist_flag_info_.reset(*flag_info); 267 } 268 return persist_flag_info_.get(); 269 } 270 271 /// check if flag is read only IsFlagReadOnly(const PackageFlagContext & context)272 base::Result<bool> StorageFiles::IsFlagReadOnly(const PackageFlagContext& context) { 273 if (!context.flag_exists) { 274 return base::Error() << "Flag does not exist"; 275 } 276 277 auto flag_info_file = GetPersistFlagInfo(); 278 if (!flag_info_file.ok()) { 279 return base::Error() << flag_info_file.error(); 280 } 281 282 auto attribute = get_flag_attribute( 283 **flag_info_file, context.value_type, context.flag_index); 284 285 if (!attribute.ok()) { 286 return base::Error() << "Failed to get flag attribute"; 287 } 288 289 return !(*attribute & FlagInfoBit::IsReadWrite); 290 } 291 292 /// apply local update to boot flag value copy ApplyLocalOverrideToBootFlagValue()293 base::Result<void> StorageFiles::ApplyLocalOverrideToBootFlagValue() { 294 auto flag_value_result = map_mutable_storage_file(storage_record_.boot_flag_val); 295 if (!flag_value_result.ok()) { 296 return base::Error() << "Failed to map boot flag value file for local override: " 297 << flag_value_result.error(); 298 } 299 auto flag_value = std::unique_ptr<MutableMappedStorageFile>(*flag_value_result); 300 301 auto pb_file = storage_record_.local_overrides; 302 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 303 if (!pb.ok()) { 304 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 305 } 306 307 auto applied_overrides = LocalFlagOverrides(); 308 for (auto& entry : pb->overrides()) { 309 310 // find flag value type and index 311 auto context = GetPackageFlagContext(entry.package_name(), entry.flag_name()); 312 if (!context.ok()) { 313 return base::Error() << "Failed to find flag: " << context.error(); 314 } 315 316 if (!context->flag_exists) { 317 continue; 318 } 319 320 // apply a local override 321 switch (context->value_type) { 322 case FlagValueType::Boolean: { 323 // validate value 324 if (entry.flag_value() != "true" && entry.flag_value() != "false") { 325 return base::Error() << "Invalid boolean flag value, it should be true|false"; 326 } 327 328 // update flag value 329 auto update_result = set_boolean_flag_value( 330 *flag_value, context->flag_index, entry.flag_value() == "true"); 331 if (!update_result.ok()) { 332 return base::Error() << "Failed to update flag value: " << update_result.error(); 333 } 334 335 break; 336 } 337 default: 338 return base::Error() << "Unsupported flag value type"; 339 } 340 341 // mark it applied 342 auto new_applied = applied_overrides.add_overrides(); 343 new_applied->set_package_name(entry.package_name()); 344 new_applied->set_flag_name(entry.flag_name()); 345 new_applied->set_flag_value(entry.flag_value()); 346 } 347 348 if (pb->overrides_size() != applied_overrides.overrides_size()) { 349 auto result = WritePbToFile<LocalFlagOverrides>(applied_overrides, pb_file); 350 if (!result.ok()) { 351 return base::Error() << result.error(); 352 } 353 } 354 355 return {}; 356 } 357 358 /// has boot copy HasBootCopy()359 bool StorageFiles::HasBootCopy() { 360 return FileExists(storage_record_.boot_flag_val) 361 && FileExists(storage_record_.boot_flag_info); 362 } 363 364 /// Find flag value type and global index GetPackageFlagContext(const std::string & package,const std::string & flag)365 base::Result<StorageFiles::PackageFlagContext> StorageFiles::GetPackageFlagContext( 366 const std::string& package, 367 const std::string& flag) { 368 auto result = PackageFlagContext(package, flag); 369 370 // early return 371 if (package.empty()) { 372 result.package_exists = false; 373 result.flag_exists = false; 374 return result; 375 } 376 377 // find package context 378 auto package_map = GetPackageMap(); 379 if (!package_map.ok()) { 380 return base::Error() << package_map.error(); 381 } 382 383 auto package_context = get_package_read_context(**package_map, package); 384 if (!package_context.ok()) { 385 return base::Error() << "Failed to get package context for " << package 386 << " in " << container_ << " :" << package_context.error(); 387 } 388 389 if (!package_context->package_exists) { 390 result.flag_exists = false; 391 return result; 392 } else { 393 result.package_exists = true; 394 } 395 396 // early return 397 if (flag.empty()) { 398 return result; 399 } 400 401 uint32_t package_id = package_context->package_id; 402 uint32_t boolean_flag_start_index = package_context->boolean_start_index; 403 404 // find flag context 405 auto flag_map = GetFlagMap(); 406 if (!flag_map.ok()) { 407 return base::Error() << flag_map.error(); 408 } 409 410 auto flag_context = get_flag_read_context(**flag_map, package_id, flag); 411 if (!flag_context.ok()) { 412 return base::Error() << "Failed to get flag context of " << package << "/" 413 << flag << " in " << container_ << " :" 414 << flag_context.error(); 415 } 416 417 if (!flag_context->flag_exists) { 418 result.flag_exists = false; 419 return result; 420 } 421 422 StoredFlagType stored_type = flag_context->flag_type; 423 uint16_t within_package_flag_index = flag_context->flag_index; 424 auto value_type = map_to_flag_value_type(stored_type); 425 if (!value_type.ok()) { 426 return base::Error() << "Failed to get flag value type :" << value_type.error(); 427 } 428 429 result.flag_exists = true; 430 result.value_type = *value_type; 431 result.flag_index = boolean_flag_start_index + within_package_flag_index; 432 return result; 433 } 434 435 /// check if has package HasPackage(const std::string & package)436 base::Result<bool> StorageFiles::HasPackage(const std::string& package) { 437 auto type_and_index = GetPackageFlagContext(package, ""); 438 if (!type_and_index.ok()) { 439 return base::Error() << type_and_index.error(); 440 } 441 return type_and_index->package_exists; 442 } 443 444 /// check if has flag HasFlag(const std::string & package,const std::string & flag)445 base::Result<bool> StorageFiles::HasFlag(const std::string& package, 446 const std::string& flag) { 447 auto type_and_index = GetPackageFlagContext(package, flag); 448 if (!type_and_index.ok()) { 449 return base::Error() << type_and_index.error(); 450 } 451 return type_and_index->flag_exists; 452 } 453 454 /// get persistent flag attribute GetFlagAttribute(const PackageFlagContext & context)455 base::Result<uint8_t> StorageFiles::GetFlagAttribute( 456 const PackageFlagContext& context) { 457 if (!context.flag_exists) { 458 return base::Error() << "Flag does not exist"; 459 } 460 461 auto flag_info_file = GetPersistFlagInfo(); 462 if (!flag_info_file.ok()) { 463 return base::Error() << flag_info_file.error(); 464 } 465 466 auto attribute = get_flag_attribute(**flag_info_file, context.value_type, context.flag_index); 467 if (!attribute.ok()) { 468 return base::Error() << "Failed to get flag info: " << attribute.error(); 469 } 470 471 return *attribute; 472 } 473 474 /// get server flag value GetServerFlagValue(const PackageFlagContext & context)475 base::Result<std::string> StorageFiles::GetServerFlagValue( 476 const PackageFlagContext& context) { 477 auto attribute = GetFlagAttribute(context); 478 RETURN_IF_ERROR(attribute, "Failed to get flag attribute"); 479 480 if (!(*attribute & FlagInfoBit::HasServerOverride)) { 481 return std::string(); 482 } 483 484 if (!context.flag_exists) { 485 return base::Error() << "Flag does not exist"; 486 } 487 488 auto flag_value_file = GetPersistFlagVal(); 489 if (!flag_value_file.ok()) { 490 return base::Error() << flag_value_file.error(); 491 } 492 493 switch (context.value_type) { 494 case FlagValueType::Boolean: { 495 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 496 if (!value.ok()) { 497 return base::Error() << "Failed to get flag value: " << value.error(); 498 } 499 return *value ? "true" : "false"; 500 break; 501 } 502 default: 503 return base::Error() << "Unsupported flag value type"; 504 } 505 506 return base::Error() << "Failed to find flag in value file"; 507 } 508 509 /// get local flag value GetLocalFlagValue(const PackageFlagContext & context)510 base::Result<std::string> StorageFiles::GetLocalFlagValue( 511 const PackageFlagContext& context) { 512 auto attribute = GetFlagAttribute(context); 513 RETURN_IF_ERROR(attribute, "Failed to get flag attribute"); 514 515 if (!(*attribute & FlagInfoBit::HasLocalOverride)) { 516 return std::string(); 517 } 518 519 if (!context.flag_exists) { 520 return base::Error() << "Flag does not exist"; 521 } 522 523 auto pb_file = storage_record_.local_overrides; 524 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 525 if (!pb.ok()) { 526 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 527 } 528 529 for (auto& entry : pb->overrides()) { 530 if (context.package == entry.package_name() 531 && context.flag == entry.flag_name()) { 532 return entry.flag_value(); 533 } 534 } 535 536 return base::Error() << "Failed to find flag local override value"; 537 } 538 539 /// get boot flag value GetBootFlagValue(const PackageFlagContext & context)540 base::Result<std::string> StorageFiles::GetBootFlagValue( 541 const PackageFlagContext& context) { 542 if (!context.flag_exists) { 543 return base::Error() << "Flag does not exist"; 544 } 545 546 auto flag_value_file = GetBootFlagVal(); 547 if (!flag_value_file.ok()) { 548 return base::Error() << flag_value_file.error(); 549 } 550 551 switch (context.value_type) { 552 case FlagValueType::Boolean: { 553 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 554 if (!value.ok()) { 555 return base::Error() << "Failed to get boot flag value: " << value.error(); 556 } 557 return *value ? "true" : "false"; 558 break; 559 } 560 default: 561 return base::Error() << "Unsupported flag value type"; 562 } 563 564 return base::Error() << "Failed to find flag in value file"; 565 } 566 567 /// get default flag value GetDefaultFlagValue(const PackageFlagContext & context)568 base::Result<std::string> StorageFiles::GetDefaultFlagValue( 569 const PackageFlagContext& context) { 570 if (!context.flag_exists) { 571 return base::Error() << "Flag does not exist"; 572 } 573 574 auto flag_value_file = GetFlagVal(); 575 if (!flag_value_file.ok()) { 576 return base::Error() << flag_value_file.error(); 577 } 578 579 switch (context.value_type) { 580 case FlagValueType::Boolean: { 581 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 582 if (!value.ok()) { 583 return base::Error() << "Failed to get default flag value: " << value.error(); 584 } 585 return *value ? "true" : "false"; 586 break; 587 } 588 default: 589 return base::Error() << "Unsupported flag value type"; 590 } 591 592 return base::Error() << "Failed to find flag in value file"; 593 } 594 595 /// server flag override, update persistent flag value SetServerFlagValue(const PackageFlagContext & context,const std::string & flag_value)596 base::Result<void> StorageFiles::SetServerFlagValue(const PackageFlagContext& context, 597 const std::string& flag_value) { 598 if (!context.flag_exists) { 599 return base::Error() << "Flag does not exist"; 600 } 601 602 auto readonly = IsFlagReadOnly(context); 603 RETURN_IF_ERROR(readonly, "Failed to check if flag is readonly"); 604 if (*readonly) { 605 return base::Error() << "Cannot update read only flag"; 606 } 607 608 auto flag_value_file = GetPersistFlagVal(); 609 RETURN_IF_ERROR(flag_value_file, "Cannot get persist flag value file"); 610 611 switch (context.value_type) { 612 case FlagValueType::Boolean: { 613 if (flag_value != "true" && flag_value != "false") { 614 return base::Error() << "Invalid boolean flag value, it should be true|false"; 615 } 616 617 auto update = set_boolean_flag_value( 618 **flag_value_file, context.flag_index, flag_value == "true"); 619 RETURN_IF_ERROR(update, "Failed to update flag value"); 620 621 update = SetHasServerOverride(context, true); 622 RETURN_IF_ERROR(update, "Failed to set flag has server override"); 623 624 break; 625 } 626 default: 627 return base::Error() << "Unsupported flag value type"; 628 } 629 630 return {}; 631 } 632 633 /// Set value and has_local_override for boot copy immediately. UpdateBootValueAndInfoImmediately(const PackageFlagContext & context,const std::string & flag_value,bool has_local_override)634 base::Result<void> StorageFiles::UpdateBootValueAndInfoImmediately( 635 const PackageFlagContext& context, const std::string& flag_value, 636 bool has_local_override) { 637 if (chmod(storage_record_.boot_flag_val.c_str(), 0644) == -1) { 638 return base::ErrnoError() << "chmod() failed to set boot val to 0644"; 639 } 640 641 auto flag_value_file = 642 map_mutable_storage_file(storage_record_.boot_flag_val); 643 auto update_result = set_boolean_flag_value( 644 **flag_value_file, context.flag_index, flag_value == "true"); 645 RETURN_IF_ERROR(update_result, "Failed to update boot flag value"); 646 647 if (chmod(storage_record_.boot_flag_val.c_str(), 0444) == -1) { 648 return base::ErrnoError() << "chmod() failed to set boot val to 0444"; 649 } 650 651 if (chmod(storage_record_.boot_flag_info.c_str(), 0644) == -1) { 652 return base::ErrnoError() << "chmod() failed to set boot info to 0644"; 653 } 654 655 auto flag_info_file = 656 map_mutable_storage_file(storage_record_.boot_flag_info); 657 auto update_info_result = 658 set_flag_has_local_override(**flag_info_file, context.value_type, 659 context.flag_index, has_local_override); 660 RETURN_IF_ERROR(update_info_result, "Failed to update boot flag info"); 661 662 if (chmod(storage_record_.boot_flag_info.c_str(), 0444) == -1) { 663 return base::ErrnoError() << "chmod() failed to set boot info to 0444"; 664 } 665 666 return {}; 667 } 668 669 /// local flag override, update local flag override pb filee SetLocalFlagValue(const PackageFlagContext & context,const std::string & flag_value)670 base::Result<void> StorageFiles::SetLocalFlagValue( 671 const PackageFlagContext& context, const std::string& flag_value) { 672 if (!context.flag_exists) { 673 return base::Error() << "Flag does not exist"; 674 } 675 676 auto readonly = IsFlagReadOnly(context); 677 RETURN_IF_ERROR(readonly, "Failed to check if flag is readonly") 678 if (*readonly) { 679 return base::Error() << "Cannot update read only flag"; 680 } 681 682 auto pb_file = storage_record_.local_overrides; 683 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 684 if (!pb.ok()) { 685 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 686 } 687 688 bool exist = false; 689 for (auto& entry : *(pb->mutable_overrides())) { 690 if (entry.package_name() == context.package 691 && entry.flag_name() == context.flag) { 692 if (entry.flag_value() == flag_value) { 693 return {}; 694 } 695 exist = true; 696 entry.set_flag_value(flag_value); 697 break; 698 } 699 } 700 701 if (!exist) { 702 auto new_override = pb->add_overrides(); 703 new_override->set_package_name(context.package); 704 new_override->set_flag_name(context.flag); 705 new_override->set_flag_value(flag_value); 706 } 707 708 auto write = WritePbToFile<LocalFlagOverrides>(*pb, pb_file); 709 if (!write.ok()) { 710 return base::Error() << "Failed to write pb to " << pb_file << ": " << write.error(); 711 } 712 713 auto update = SetHasLocalOverride(context, true); 714 RETURN_IF_ERROR(update, "Failed to set flag has local override"); 715 716 return {}; 717 } 718 719 /// set has server override in flag info SetHasServerOverride(const PackageFlagContext & context,bool has_server_override)720 base::Result<void> StorageFiles::SetHasServerOverride(const PackageFlagContext& context, 721 bool has_server_override) { 722 if (!context.flag_exists) { 723 return base::Error() << "Flag does not exist"; 724 } 725 726 auto flag_info_file = GetPersistFlagInfo(); 727 if (!flag_info_file.ok()) { 728 return base::Error() << flag_info_file.error(); 729 } 730 731 auto update_result = set_flag_has_server_override( 732 **flag_info_file, context.value_type, context.flag_index, has_server_override); 733 if (!update_result.ok()) { 734 return base::Error() << "Failed to update flag has server override: " 735 << update_result.error(); 736 } 737 738 return {}; 739 } 740 741 /// set has local override in flag info SetHasLocalOverride(const PackageFlagContext & context,bool has_local_override)742 base::Result<void> StorageFiles::SetHasLocalOverride(const PackageFlagContext& context, 743 bool has_local_override) { 744 if (!context.flag_exists) { 745 return base::Error() << "Flag does not exist"; 746 } 747 748 auto flag_info_file = GetPersistFlagInfo(); 749 if (!flag_info_file.ok()) { 750 return base::Error() << flag_info_file.error(); 751 } 752 753 auto update_result = set_flag_has_local_override( 754 **flag_info_file, context.value_type, context.flag_index, has_local_override); 755 if (!update_result.ok()) { 756 return base::Error() << "Failed to update flag has local override: " 757 << update_result.error(); 758 } 759 760 return {}; 761 } 762 763 /// remove a single flag local override, return if removed RemoveLocalFlagValue(const PackageFlagContext & context,bool immediate)764 base::Result<bool> StorageFiles::RemoveLocalFlagValue( 765 const PackageFlagContext& context, bool immediate) { 766 auto pb_file = storage_record_.local_overrides; 767 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 768 if (!pb.ok()) { 769 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 770 } 771 772 auto remaining_overrides = LocalFlagOverrides(); 773 for (auto entry : pb->overrides()) { 774 if (entry.package_name() == context.package 775 && entry.flag_name() == context.flag) { 776 continue; 777 } 778 auto kept_override = remaining_overrides.add_overrides(); 779 kept_override->set_package_name(entry.package_name()); 780 kept_override->set_flag_name(entry.flag_name()); 781 kept_override->set_flag_value(entry.flag_value()); 782 } 783 784 bool return_result; 785 if (remaining_overrides.overrides_size() != pb->overrides_size()) { 786 auto result = WritePbToFile<LocalFlagOverrides>(remaining_overrides, pb_file); 787 if (!result.ok()) { 788 return base::Error() << result.error(); 789 } 790 791 auto update = SetHasLocalOverride(context, false); 792 RETURN_IF_ERROR(update, "Failed to unset flag has local override"); 793 794 return_result = true; 795 } else { 796 return_result = false; 797 } 798 799 if (immediate) { 800 auto attribute = GetFlagAttribute(context); 801 RETURN_IF_ERROR( 802 attribute, 803 "Failed to get flag attribute for removing override immediately"); 804 805 auto value = ((*attribute) & FlagInfoBit::HasServerOverride) 806 ? GetServerFlagValue(context) 807 : GetDefaultFlagValue(context); 808 RETURN_IF_ERROR(value, "Failed to get server or default value"); 809 810 auto update = UpdateBootValueAndInfoImmediately(context, *value, false); 811 RETURN_IF_ERROR(update, 812 "Failed to remove local override boot flag value"); 813 } 814 815 return return_result; 816 } 817 818 /// remove all local overrides RemoveAllLocalFlagValue(bool immediate)819 base::Result<void> StorageFiles::RemoveAllLocalFlagValue(bool immediate) { 820 auto pb_file = storage_record_.local_overrides; 821 auto overrides_pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 822 RETURN_IF_ERROR(overrides_pb, "Failed to read local overrides"); 823 824 for (auto& entry : overrides_pb->overrides()) { 825 auto context = GetPackageFlagContext(entry.package_name(), entry.flag_name()); 826 RETURN_IF_ERROR(context, "Failed to find package flag context for flag " 827 + entry.package_name() + "/" + entry.flag_name()); 828 829 auto update = SetHasLocalOverride(*context, false); 830 RETURN_IF_ERROR(update, "Failed to unset flag has local override"); 831 832 if (immediate) { 833 auto attribute = GetFlagAttribute(*context); 834 RETURN_IF_ERROR( 835 attribute, 836 "Failed to get flag attribute for removing override immediately"); 837 838 auto value = ((*attribute) & FlagInfoBit::HasServerOverride) 839 ? GetServerFlagValue(*context) 840 : GetDefaultFlagValue(*context); 841 RETURN_IF_ERROR(value, "Failed to get server or default value"); 842 843 auto boot_update = 844 UpdateBootValueAndInfoImmediately(*context, *value, false); 845 RETURN_IF_ERROR(boot_update, 846 "Failed to remove local override boot flag value"); 847 } 848 } 849 850 if (overrides_pb->overrides_size()) { 851 auto result = WritePbToFile<LocalFlagOverrides>( 852 LocalFlagOverrides(), pb_file); 853 RETURN_IF_ERROR(result, "Failed to flush local overrides pb file"); 854 } 855 856 return {}; 857 } 858 859 /// get all current server override 860 base::Result<std::vector<StorageFiles::ServerOverride>> GetServerFlagValues()861 StorageFiles::GetServerFlagValues() { 862 auto listed_flags = list_flags_with_info(storage_record_.persist_package_map, 863 storage_record_.persist_flag_map, 864 storage_record_.persist_flag_val, 865 storage_record_.persist_flag_info); 866 RETURN_IF_ERROR( 867 listed_flags, "Failed to list all flags for " + storage_record_.container); 868 869 auto server_updated_flags = std::vector<ServerOverride>(); 870 for (const auto& flag : *listed_flags) { 871 if (flag.has_server_override) { 872 auto server_override = ServerOverride(); 873 server_override.package_name = std::move(flag.package_name); 874 server_override.flag_name = std::move(flag.flag_name); 875 server_override.flag_value = std::move(flag.flag_value); 876 server_updated_flags.push_back(server_override); 877 } 878 } 879 880 return server_updated_flags; 881 } 882 883 /// remove all storage files RemoveAllPersistFiles()884 base::Result<void> StorageFiles::RemoveAllPersistFiles() { 885 package_map_.reset(nullptr); 886 flag_map_.reset(nullptr); 887 flag_val_.reset(nullptr); 888 boot_flag_val_.reset(nullptr); 889 boot_flag_info_.reset(nullptr); 890 persist_flag_val_.reset(nullptr); 891 persist_flag_info_.reset(nullptr); 892 if (unlink(storage_record_.persist_package_map.c_str()) == -1) { 893 return base::ErrnoError() << "unlink() failed for " 894 << storage_record_.persist_package_map; 895 } 896 if (unlink(storage_record_.persist_flag_map.c_str()) == -1) { 897 return base::ErrnoError() << "unlink() failed for " 898 << storage_record_.persist_flag_map; 899 } 900 if (unlink(storage_record_.persist_flag_val.c_str()) == -1) { 901 return base::ErrnoError() << "unlink() failed for " 902 << storage_record_.persist_flag_val; 903 } 904 if (unlink(storage_record_.persist_flag_info.c_str()) == -1) { 905 return base::ErrnoError() << "unlink() failed for " 906 << storage_record_.persist_flag_info; 907 } 908 if (unlink(storage_record_.local_overrides.c_str()) == -1) { 909 return base::ErrnoError() << "unlink() failed for " << storage_record_.local_overrides; 910 } 911 return {}; 912 } 913 914 /// create boot flag value and info files CreateBootStorageFiles()915 base::Result<void> StorageFiles::CreateBootStorageFiles() { 916 // If the boot copy already exists, do nothing. Never update the boot copy, the boot 917 // copy should be boot stable. So in the following scenario: a container storage 918 // file boot copy is created, then an updated container is mounted along side existing 919 // container. In this case, we should update the persistent storage file copy. But 920 // never touch the current boot copy. 921 if (FileExists(storage_record_.boot_flag_val) 922 && FileExists(storage_record_.boot_flag_info)) { 923 return {}; 924 } 925 926 auto copy = CopyFile( 927 storage_record_.persist_flag_val, storage_record_.boot_flag_val, 0444); 928 RETURN_IF_ERROR(copy, "CopyFile failed for " + storage_record_.persist_flag_val); 929 930 copy = CopyFile( 931 storage_record_.persist_flag_info, storage_record_.boot_flag_info, 0444); 932 RETURN_IF_ERROR(copy, "CopyFile failed for " + storage_record_.persist_flag_info); 933 934 // change boot flag value file to 0644 to allow write 935 if (chmod(storage_record_.boot_flag_val.c_str(), 0644) == -1) { 936 return base::ErrnoError() << "chmod() failed to set to 0644"; 937 }; 938 939 auto apply_result = ApplyLocalOverrideToBootFlagValue(); 940 941 // change boot flag value file back to 0444 942 if (chmod(storage_record_.boot_flag_val.c_str(), 0444) == -1) { 943 if (!apply_result.ok()) { 944 return base::ErrnoError() << apply_result.error() << ": " 945 << "chmod() failed to set to 0444"; 946 } else { 947 return base::ErrnoError() << "chmod() failed to set to 0444"; 948 } 949 }; 950 951 return apply_result; 952 } 953 954 /// list a flag ListFlag(const std::string & package,const std::string & flag)955 base::Result<StorageFiles::FlagSnapshot> StorageFiles::ListFlag( 956 const std::string& package, 957 const std::string& flag) { 958 959 auto context = GetPackageFlagContext(package, flag); 960 RETURN_IF_ERROR(context, "Failed to find package flag context"); 961 962 if (!context->flag_exists) { 963 return base::Error() << "Flag " << package << "/" << flag << " does not exist"; 964 } 965 966 auto attribute = GetFlagAttribute(*context); 967 RETURN_IF_ERROR(context, "Failed to get flag attribute"); 968 969 auto server_value = GetServerFlagValue(*context); 970 RETURN_IF_ERROR(server_value, "Failed to get server flag value"); 971 972 auto local_value = GetLocalFlagValue(*context); 973 RETURN_IF_ERROR(local_value, "Failed to get local flag value"); 974 975 auto boot_value = GetBootFlagValue(*context); 976 RETURN_IF_ERROR(boot_value, "Failed to get boot flag value"); 977 978 auto default_value = GetDefaultFlagValue(*context); 979 RETURN_IF_ERROR(default_value, "Failed to get default flag value"); 980 981 auto snapshot = FlagSnapshot(); 982 snapshot.package_name = package; 983 snapshot.flag_name = flag; 984 snapshot.default_flag_value = *default_value; 985 snapshot.boot_flag_value = *boot_value; 986 snapshot.server_flag_value = *server_value; 987 snapshot.local_flag_value = *local_value; 988 snapshot.is_readwrite = *attribute & FlagInfoBit::IsReadWrite; 989 snapshot.has_server_override = *attribute & FlagInfoBit::HasServerOverride; 990 snapshot.has_local_override = *attribute & FlagInfoBit::HasLocalOverride; 991 992 return snapshot; 993 } 994 995 /// list flags ListFlags(const std::string & package)996 base::Result<std::vector<StorageFiles::FlagSnapshot>> StorageFiles::ListFlags( 997 const std::string& package) { 998 if (!package.empty()) { 999 auto has_package = HasPackage(package); 1000 RETURN_IF_ERROR( 1001 has_package, package + " does not exist in " + storage_record_.container); 1002 } 1003 1004 // fill default value 1005 auto snapshots = std::vector<FlagSnapshot>(); 1006 auto idxs = std::unordered_map<std::string, size_t>(); 1007 1008 auto listed_flags = list_flags(storage_record_.package_map, 1009 storage_record_.flag_map, 1010 storage_record_.flag_val); 1011 RETURN_IF_ERROR( 1012 listed_flags, "Failed to list default flags for " + storage_record_.container); 1013 1014 for (auto const& flag : *listed_flags) { 1015 if (package.empty() || package == flag.package_name) { 1016 idxs[flag.package_name + "/" + flag.flag_name] = snapshots.size(); 1017 snapshots.emplace_back(); 1018 auto& snapshot = snapshots.back(); 1019 snapshot.package_name = std::move(flag.package_name); 1020 snapshot.flag_name = std::move(flag.flag_name); 1021 snapshot.default_flag_value = std::move(flag.flag_value); 1022 } 1023 } 1024 1025 // fill boot value 1026 auto listed_flags_boot = list_flags_with_info( 1027 storage_record_.package_map, storage_record_.flag_map, 1028 storage_record_.boot_flag_val, storage_record_.boot_flag_info); 1029 RETURN_IF_ERROR(listed_flags_boot, "Failed to list boot flags for " + 1030 storage_record_.container); 1031 1032 for (auto const& flag : *listed_flags_boot) { 1033 auto full_flag_name = flag.package_name + "/" + flag.flag_name; 1034 if (!idxs.count(full_flag_name)) { 1035 continue; 1036 } 1037 auto idx = idxs[full_flag_name]; 1038 snapshots[idx].boot_flag_value = std::move(flag.flag_value); 1039 snapshots[idx].has_boot_local_override = flag.has_local_override; 1040 } 1041 1042 // fill server value and attribute 1043 auto listed_flags_with_info = list_flags_with_info(storage_record_.package_map, 1044 storage_record_.flag_map, 1045 storage_record_.persist_flag_val, 1046 storage_record_.persist_flag_info); 1047 RETURN_IF_ERROR(listed_flags_with_info, 1048 "Failed to list persist flags for " + storage_record_.container); 1049 1050 for (auto const& flag : *listed_flags_with_info) { 1051 auto full_flag_name = flag.package_name + "/" + flag.flag_name; 1052 if (!idxs.count(full_flag_name)) { 1053 continue; 1054 } 1055 auto idx = idxs[full_flag_name]; 1056 if (flag.has_server_override) { 1057 snapshots[idx].server_flag_value = std::move(flag.flag_value); 1058 } 1059 snapshots[idx].is_readwrite = flag.is_readwrite; 1060 snapshots[idx].has_server_override = flag.has_server_override; 1061 snapshots[idx].has_local_override = flag.has_local_override; 1062 } 1063 1064 // fill local value 1065 auto const& pb_file = storage_record_.local_overrides; 1066 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 1067 RETURN_IF_ERROR(pb, "Failed to read pb from " + pb_file); 1068 for (const auto& flag : pb->overrides()) { 1069 auto full_flag_name = flag.package_name() + "/" + flag.flag_name(); 1070 if (!idxs.count(full_flag_name)) { 1071 continue; 1072 } 1073 auto idx = idxs[full_flag_name]; 1074 snapshots[idx].local_flag_value = flag.flag_value(); 1075 } 1076 1077 auto comp = [](const auto& v1, const auto& v2){ 1078 return (v1.package_name + "/" + v1.flag_name) < 1079 (v2.package_name + "/" + v2.flag_name); 1080 }; 1081 std::sort(snapshots.begin(), snapshots.end(), comp); 1082 1083 return snapshots; 1084 } 1085 1086 } // namespace aconfigd 1087 } // namespace android 1088