1 // Copyright (C) 2023 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 16 #pragma once 17 18 #include <liburing.h> 19 #include <stdint.h> 20 #include <sys/types.h> 21 22 #include <condition_variable> 23 #include <mutex> 24 #include <string> 25 26 #include <liburing_cpp/IoUring.h> 27 #include <snapuserd/snapuserd_kernel.h> 28 #include <storage_literals/storage_literals.h> 29 30 namespace android { 31 namespace snapshot { 32 33 using namespace android::storage_literals; 34 35 class UpdateVerify { 36 public: 37 UpdateVerify(const std::string& misc_name, uint32_t verify_block_size, 38 uint32_t num_verification_threads); 39 void VerifyUpdatePartition(); 40 bool CheckPartitionVerification(); 41 42 private: 43 enum class UpdateVerifyState { 44 VERIFY_UNKNOWN, 45 VERIFY_FAILED, 46 VERIFY_SUCCESS, 47 }; 48 49 std::string misc_name_; 50 UpdateVerifyState state_; 51 std::mutex m_lock_; 52 std::condition_variable m_cv_; 53 54 int kMinThreadsToVerify = 1; 55 int kMaxThreadsToVerify = 3; 56 57 /* 58 * To optimize partition scanning speed without significantly impacting boot time, 59 * we employ O_DIRECT, bypassing the page-cache. However, O_DIRECT's memory 60 * allocation from CMA can be problematic on devices with restricted CMA space. 61 * To address this, io_uring_register_buffers() pre-registers I/O buffers, 62 * preventing CMA usage. See b/401952955 for more details. 63 * 64 * These numbers were derived by monitoring the memory and CPU pressure 65 * (/proc/pressure/{cpu,memory}; and monitoring the Inactive(file) and 66 * Active(file) pages from /proc/meminfo. 67 */ 68 uint64_t verify_block_size_ = 1_MiB; 69 uint64_t threshold_size_ = 2_GiB; 70 uint32_t num_verification_threads_; 71 int queue_depth_ = 4; 72 IsBlockAligned(uint64_t read_size)73 bool IsBlockAligned(uint64_t read_size) { return ((read_size & (BLOCK_SZ - 1)) == 0); } 74 void UpdatePartitionVerificationState(UpdateVerifyState state); 75 bool VerifyPartition(const std::string& partition_name, const std::string& dm_block_device); 76 bool VerifyBlocks(const std::string& partition_name, const std::string& dm_block_device, 77 off_t offset, int skip_blocks, uint64_t dev_sz); 78 }; 79 80 } // namespace snapshot 81 } // namespace android 82