1 /* 2 * Copyright (C) 2017 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 #pragma once 18 19 #include <functional> 20 #include <map> 21 #include <string> 22 #include <vector> 23 24 #include "otautil/rangeset.h" 25 26 // The update verifier performs verification upon the first boot to a new slot on A/B devices. 27 // During the verification, it reads all the blocks in the care_map. And if a failure happens, 28 // it rejects the current boot and triggers a fallback. 29 30 // Note that update_verifier should be backward compatible to not reject care_map.txt from old 31 // releases, which could otherwise fail to boot into the new release. For example, we've changed 32 // the care_map format between N and O. An O update_verifier would fail to work with N care_map.txt. 33 // This could be a result of sideloading an O OTA while the device having a pending N update. 34 int update_verifier(int argc, char** argv); 35 36 // The UpdateVerifier parses the content in the care map, and continues to verify the 37 // partitions by reading the cared blocks if there's no format error in the file. Otherwise, 38 // it should skip the verification to avoid bricking the device. 39 class UpdateVerifier { 40 public: 41 UpdateVerifier(); 42 43 // This function tries to process the care_map.pb as protobuf message; and falls back to use 44 // care_map.txt if the pb format file doesn't exist. If the parsing succeeds, put the result 45 // of the pair <partition_name, ranges> into the |partition_map_|. 46 bool ParseCareMap(); 47 48 // Verifies the new boot by reading all the cared blocks for partitions in |partition_map_|. 49 bool VerifyPartitions(); 50 51 private: 52 friend class UpdateVerifierTest; 53 // Finds all the dm-enabled partitions, and returns a map of <partition_name, block_device>. 54 std::map<std::string, std::string> FindDmPartitions(); 55 56 // Returns true if we successfully read the blocks in |ranges| of the |dm_block_device|. 57 bool ReadBlocks(const std::string partition_name, const std::string& dm_block_device, 58 const RangeSet& ranges); 59 60 // Functions to override the care_map_prefix_ and property_reader_, used in test only. 61 void set_care_map_prefix(const std::string& prefix); 62 void set_property_reader(const std::function<std::string(const std::string&)>& property_reader); 63 64 std::map<std::string, RangeSet> partition_map_; 65 // The path to the care_map excluding the filename extension; default value: 66 // "/data/ota_package/care_map" 67 std::string care_map_prefix_; 68 69 // The function to read the device property; default value: android::base::GetProperty() 70 std::function<std::string(const std::string&)> property_reader_; 71 }; 72