1 // 2 // Copyright (C) 2023 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 #pragma once 17 18 #include <stdint.h> 19 20 #include <memory> 21 #include <ostream> 22 #include <string> 23 #include <unordered_map> 24 #include <utility> 25 26 #include <android-base/unique_fd.h> 27 #include <liblp/builder.h> 28 29 namespace android { 30 namespace fs_mgr { 31 32 struct SuperImageExtent { 33 enum class Type { INVALID, DATA, PARTITION, ZERO, DONTCARE }; 34 35 SuperImageExtent(const SuperImageExtent& other) = default; 36 SuperImageExtent(SuperImageExtent&& other) = default; SuperImageExtentSuperImageExtent37 SuperImageExtent(uint64_t offset, uint64_t size, Type type) 38 : offset(offset), size(size), type(type) {} 39 SuperImageExtentSuperImageExtent40 SuperImageExtent(uint64_t offset, std::shared_ptr<std::string> blob) 41 : SuperImageExtent(offset, blob->size(), Type::DATA) { 42 this->blob = blob; 43 } 44 SuperImageExtentSuperImageExtent45 SuperImageExtent(uint64_t offset, uint64_t size, const std::string& image_name, 46 uint64_t image_offset) 47 : SuperImageExtent(offset, size, Type::PARTITION) { 48 this->image_name = image_name; 49 this->image_offset = image_offset; 50 } 51 52 SuperImageExtent& operator=(const SuperImageExtent& other) = default; 53 SuperImageExtent& operator=(SuperImageExtent&& other) = default; 54 55 bool operator<(const SuperImageExtent& other) const { return offset < other.offset; } 56 bool operator==(const SuperImageExtent& other) const; 57 58 // Location, size, and type of the extent. 59 uint64_t offset = 0; 60 uint64_t size = 0; 61 Type type = Type::INVALID; 62 63 // If type == DATA, this contains the bytes to write. 64 std::shared_ptr<std::string> blob; 65 // If type == PARTITION, this contains the partition image name and 66 // offset within that file. 67 std::string image_name; 68 uint64_t image_offset = 0; 69 }; 70 71 // The SuperLayoutBuilder allows building a sparse view of a super image. This 72 // is useful for efficient flashing, eg to bypass fastbootd and directly flash 73 // super without physically building and storing the image. 74 class SuperLayoutBuilder final { 75 public: 76 // Open a super_empty.img, return false on failure. This must be called to 77 // initialize the tool. If it returns false, either the image failed to 78 // parse, or the tool is not compatible with how the device is configured 79 // (in which case fastbootd should be preferred). 80 [[nodiscard]] bool Open(android::base::borrowed_fd fd); 81 [[nodiscard]] bool Open(const void* data, size_t bytes); 82 [[nodiscard]] bool Open(const LpMetadata& metadata); 83 84 // Add a partition's image and size to the work list. If false is returned, 85 // there was either a duplicate partition or not enough space in super. 86 bool AddPartition(const std::string& partition_name, const std::string& image_name, 87 uint64_t partition_size); 88 89 // Return the list of extents describing the super image. If this list is 90 // empty, then there was an unrecoverable error in building the list. 91 std::vector<SuperImageExtent> GetImageLayout(); 92 93 // Return the current metadata. Export()94 std::unique_ptr<LpMetadata> Export() const { return builder_->Export(); } 95 96 private: 97 std::unique_ptr<MetadataBuilder> builder_; 98 std::unordered_map<std::string, std::string> image_map_; 99 }; 100 101 std::ostream& operator<<(std::ostream& stream, const SuperImageExtent& extent); 102 103 } // namespace fs_mgr 104 } // namespace android 105