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