1 // 2 // Copyright (C) 2019 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 <stdint.h> 20 21 #include <chrono> 22 #include <functional> 23 #include <memory> 24 #include <set> 25 #include <string> 26 27 #include <android-base/unique_fd.h> 28 #include <libfiemap/fiemap_status.h> 29 #include <liblp/partition_opener.h> 30 31 namespace android { 32 namespace fiemap { 33 34 class IImageManager { 35 public: 36 using IPartitionOpener = android::fs_mgr::IPartitionOpener; 37 ~IImageManager()38 virtual ~IImageManager() {} 39 40 // When linking to libfiemap_binder, the Open() call will use binder. 41 // Otherwise, the Open() call will use the ImageManager implementation 42 // below. 43 static std::unique_ptr<IImageManager> Open(const std::string& dir_prefix, 44 const std::chrono::milliseconds& timeout_ms); 45 46 // Flags for CreateBackingImage(). 47 static constexpr int CREATE_IMAGE_DEFAULT = 0x0; 48 static constexpr int CREATE_IMAGE_READONLY = 0x1; 49 static constexpr int CREATE_IMAGE_ZERO_FILL = 0x2; 50 51 // Create an image that can be mapped as a block-device. If |force_zero_fill| 52 // is true, the image will be zero-filled. Otherwise, the initial content 53 // of the image is undefined. If zero-fill is requested, and the operation 54 // cannot be completed, the image will be deleted and this function will 55 // return false. 56 virtual FiemapStatus CreateBackingImage( 57 const std::string& name, uint64_t size, int flags, 58 std::function<bool(uint64_t, uint64_t)>&& on_progress = nullptr) = 0; 59 60 // Delete an image created with CreateBackingImage. Its entry will be 61 // removed from the associated lp_metadata file. 62 virtual bool DeleteBackingImage(const std::string& name) = 0; 63 64 // Create a block device for an image previously created with 65 // CreateBackingImage. This will wait for at most |timeout_ms| milliseconds 66 // for |path| to be available, and will return false if not available in 67 // the requested time. If |timeout_ms| is zero, this is NOT guaranteed to 68 // return true. A timeout of 10s is recommended. 69 // 70 // Note that snapshots created with a readonly flag are always mapped 71 // writable. The flag is persisted in the lp_metadata file however, so if 72 // fs_mgr::CreateLogicalPartition(s) is used, the flag will be respected. 73 virtual bool MapImageDevice(const std::string& name, 74 const std::chrono::milliseconds& timeout_ms, std::string* path) = 0; 75 76 // Unmap a block device previously mapped with mapBackingImage. 77 virtual bool UnmapImageDevice(const std::string& name) = 0; 78 79 // Returns true whether the named backing image exists. This does not check 80 // consistency with the /data partition, so that it can return true in 81 // recovery. 82 virtual bool BackingImageExists(const std::string& name) = 0; 83 84 // Returns true if the specified image is mapped to a device. 85 virtual bool IsImageMapped(const std::string& name) = 0; 86 87 // Map an image using device-mapper. This is not available over binder, and 88 // is intended only for first-stage init. The returned device is a major:minor 89 // device string. 90 virtual bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name, 91 std::string* dev) = 0; 92 93 // If an image was mapped, return the path to its device. Otherwise, return 94 // false. Errors are not reported in this case, calling IsImageMapped is 95 // not necessary. 96 virtual bool GetMappedImageDevice(const std::string& name, std::string* device) = 0; 97 98 // Map all images owned by this manager. This is only intended to be used 99 // during first-stage init, and as such, it does not provide a timeout 100 // (meaning libdm races can't be resolved, as ueventd is not available), 101 // and is not available over binder. 102 // 103 // The callback provided is given the list of dependent block devices. 104 virtual bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) = 0; 105 106 // Mark an image as disabled. This is useful for marking an image as 107 // will-be-deleted in recovery, since recovery cannot mount /data. 108 // 109 // This is not available in binder, since it is intended for recovery. 110 // When binder is available, images can simply be removed. 111 virtual bool DisableImage(const std::string& name) = 0; 112 113 // Remove all images that been marked as disabled. 114 virtual bool RemoveDisabledImages() = 0; 115 116 // Get all backing image names. 117 virtual std::vector<std::string> GetAllBackingImages() = 0; 118 119 // Writes |bytes| zeros to |name| file. If |bytes| is 0, then the 120 // whole file if filled with zeros. 121 virtual FiemapStatus ZeroFillNewImage(const std::string& name, uint64_t bytes) = 0; 122 123 // Find and remove all images and metadata for this manager. 124 virtual bool RemoveAllImages() = 0; 125 126 virtual bool UnmapImageIfExists(const std::string& name); 127 }; 128 129 class ImageManager final : public IImageManager { 130 public: 131 // Return an ImageManager for the given metadata and data directories. Both 132 // directories must already exist. 133 static std::unique_ptr<ImageManager> Open(const std::string& metadata_dir, 134 const std::string& data_dir); 135 136 // Helper function that derives the metadata and data dirs given a single 137 // prefix. 138 static std::unique_ptr<ImageManager> Open(const std::string& dir_prefix); 139 140 // Methods that must be implemented from IImageManager. 141 FiemapStatus CreateBackingImage(const std::string& name, uint64_t size, int flags, 142 std::function<bool(uint64_t, uint64_t)>&& on_progress) override; 143 bool DeleteBackingImage(const std::string& name) override; 144 bool MapImageDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms, 145 std::string* path) override; 146 bool UnmapImageDevice(const std::string& name) override; 147 bool BackingImageExists(const std::string& name) override; 148 bool IsImageMapped(const std::string& name) override; 149 bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name, 150 std::string* dev) override; 151 bool RemoveAllImages() override; 152 bool DisableImage(const std::string& name) override; 153 bool RemoveDisabledImages() override; 154 bool GetMappedImageDevice(const std::string& name, std::string* device) override; 155 bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override; 156 157 std::vector<std::string> GetAllBackingImages(); 158 159 // Validates that all images still have pinned extents. This will be removed 160 // once b/134588268 is fixed. 161 bool Validate(); 162 163 void set_partition_opener(std::unique_ptr<IPartitionOpener>&& opener); 164 165 // Writes |bytes| zeros at the beginning of the passed image 166 FiemapStatus ZeroFillNewImage(const std::string& name, uint64_t bytes); 167 168 private: 169 ImageManager(const std::string& metadata_dir, const std::string& data_dir); 170 std::string GetImageHeaderPath(const std::string& name); 171 std::string GetStatusFilePath(const std::string& image_name); 172 bool MapWithLoopDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms, 173 std::string* path); 174 bool MapWithLoopDeviceList(const std::vector<std::string>& device_list, const std::string& name, 175 const std::chrono::milliseconds& timeout_ms, std::string* path); 176 bool MapWithDmLinear(const IPartitionOpener& opener, const std::string& name, 177 const std::chrono::milliseconds& timeout_ms, std::string* path); 178 bool UnmapImageDevice(const std::string& name, bool force); 179 180 ImageManager(const ImageManager&) = delete; 181 ImageManager& operator=(const ImageManager&) = delete; 182 ImageManager& operator=(ImageManager&&) = delete; 183 ImageManager(ImageManager&&) = delete; 184 185 std::string metadata_dir_; 186 std::string data_dir_; 187 std::unique_ptr<IPartitionOpener> partition_opener_; 188 }; 189 190 // RAII helper class for mapping and opening devices with an ImageManager. 191 class MappedDevice final { 192 public: 193 static std::unique_ptr<MappedDevice> Open(IImageManager* manager, 194 const std::chrono::milliseconds& timeout_ms, 195 const std::string& name); 196 197 ~MappedDevice(); 198 fd()199 int fd() const { return fd_; } path()200 const std::string& path() const { return path_; } 201 202 protected: 203 MappedDevice(IImageManager* manager, const std::string& name, const std::string& path); 204 205 IImageManager* manager_; 206 std::string name_; 207 std::string path_; 208 android::base::unique_fd fd_; 209 }; 210 211 } // namespace fiemap 212 } // namespace android 213