1 // Copyright (C) 2019 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 #pragma once 16 17 #include <functional> 18 #include <iostream> 19 #include <string> 20 21 #include <android-base/macros.h> 22 #include <fstab/fstab.h> 23 #include <libdm/dm.h> 24 #include <libfiemap/image_manager.h> 25 #include <liblp/builder.h> 26 #include <libsnapshot/snapshot.h> 27 #include <update_engine/update_metadata.pb.h> 28 29 #include <libsnapshot/auto_device.h> 30 #include <libsnapshot/snapshot.h> 31 32 namespace android { 33 namespace snapshot { 34 35 // Unit is sectors, this is a 4K chunk. 36 static constexpr uint32_t kSnapshotChunkSize = 8; 37 38 // A list of devices we created along the way. 39 // - Whenever a device is created that is subject to GC'ed at the end of 40 // this function, add it to this list. 41 // - If any error has occurred, the list is destroyed, and all these devices 42 // are cleaned up. 43 // - Upon success, Release() should be called so that the created devices 44 // are kept. 45 struct AutoDeviceList { 46 ~AutoDeviceList(); 47 template <typename T, typename... Args> EmplaceBackAutoDeviceList48 void EmplaceBack(Args&&... args) { 49 devices_.emplace_back(std::make_unique<T>(std::forward<Args>(args)...)); 50 } 51 void Release(); 52 53 private: 54 std::vector<std::unique_ptr<AutoDevice>> devices_; 55 }; 56 57 // Automatically unmap a device upon deletion. 58 struct AutoUnmapDevice : AutoDevice { 59 // On destruct, delete |name| from device mapper. AutoUnmapDeviceAutoUnmapDevice60 AutoUnmapDevice(android::dm::IDeviceMapper* dm, const std::string& name) 61 : AutoDevice(name), dm_(dm) {} 62 ~AutoUnmapDevice(); 63 64 private: 65 DISALLOW_COPY_AND_ASSIGN(AutoUnmapDevice); 66 android::dm::IDeviceMapper* dm_ = nullptr; 67 }; 68 69 // Automatically unmap an image upon deletion. 70 struct AutoUnmapImage : AutoDevice { 71 // On destruct, delete |name| from image manager. AutoUnmapImageAutoUnmapImage72 AutoUnmapImage(android::fiemap::IImageManager* images, const std::string& name) 73 : AutoDevice(name), images_(images) {} 74 ~AutoUnmapImage(); 75 76 private: 77 DISALLOW_COPY_AND_ASSIGN(AutoUnmapImage); 78 android::fiemap::IImageManager* images_ = nullptr; 79 }; 80 81 // Automatically deletes a snapshot. |name| should be the name of the partition, e.g. "system_a". 82 // Client is responsible for maintaining the lifetime of |manager| and |lock|. 83 struct AutoDeleteSnapshot : AutoDevice { AutoDeleteSnapshotAutoDeleteSnapshot84 AutoDeleteSnapshot(SnapshotManager* manager, SnapshotManager::LockedFile* lock, 85 const std::string& name) 86 : AutoDevice(name), manager_(manager), lock_(lock) {} 87 ~AutoDeleteSnapshot(); 88 89 private: 90 DISALLOW_COPY_AND_ASSIGN(AutoDeleteSnapshot); 91 SnapshotManager* manager_ = nullptr; 92 SnapshotManager::LockedFile* lock_ = nullptr; 93 }; 94 95 struct AutoUnmountDevice : AutoDevice { 96 // Empty object that does nothing. AutoUnmountDeviceAutoUnmountDevice97 AutoUnmountDevice() : AutoDevice("") {} 98 static std::unique_ptr<AutoUnmountDevice> New(const std::string& path); 99 ~AutoUnmountDevice(); 100 101 private: AutoUnmountDeviceAutoUnmountDevice102 AutoUnmountDevice(const std::string& path, android::fs_mgr::Fstab&& fstab) 103 : AutoDevice(path), fstab_(std::move(fstab)) {} 104 android::fs_mgr::Fstab fstab_; 105 }; 106 107 // Return a list of partitions in |builder| with the name ending in |suffix|. 108 std::vector<android::fs_mgr::Partition*> ListPartitionsWithSuffix( 109 android::fs_mgr::MetadataBuilder* builder, const std::string& suffix); 110 111 // Initialize a device before using it as the COW device for a dm-snapshot device. 112 Return InitializeKernelCow(const std::string& device); 113 114 // "Atomically" write string to file. This is done by a series of actions: 115 // 1. Write to path + ".tmp" 116 // 2. Move temporary file to path using rename() 117 // Note that rename() is an atomic operation. This function may not work properly if there 118 // is an open fd to |path|, because that fd has an old view of the file. 119 bool WriteStringToFileAtomic(const std::string& content, const std::string& path); 120 bool FsyncDirectory(const char* dirname); 121 122 // Writes current time to a given stream. 123 struct Now {}; 124 std::ostream& operator<<(std::ostream& os, const Now&); 125 126 // Append to |extents|. Merged into the last element if possible. 127 void AppendExtent(google::protobuf::RepeatedPtrField<chromeos_update_engine::Extent>* extents, 128 uint64_t start_block, uint64_t num_blocks); 129 130 bool KernelSupportsCompressedSnapshots(); 131 132 bool GetLegacyCompressionEnabledProperty(); 133 bool GetUserspaceSnapshotsEnabledProperty(); 134 bool GetIouringEnabledProperty(); 135 bool GetXorCompressionEnabledProperty(); 136 bool GetODirectEnabledProperty(); 137 138 bool CanUseUserspaceSnapshots(); 139 bool IsDmSnapshotTestingEnabled(); 140 bool IsVendorFromAndroid12(); 141 142 // Swap the suffix of a partition name. 143 std::string GetOtherPartitionName(const std::string& name); 144 145 } // namespace snapshot 146 } // namespace android 147