• 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 
136 class ImageManager final : public IImageManager {
137   public:
138     // Return an ImageManager for the given metadata and data directories. Both
139     // directories must already exist.
140     static std::unique_ptr<ImageManager> Open(const std::string& metadata_dir,
141                                               const std::string& data_dir,
142                                               const DeviceInfo& device_info = {});
143 
144     // Helper function that derives the metadata and data dirs given a single
145     // prefix.
146     static std::unique_ptr<ImageManager> Open(const std::string& dir_prefix,
147                                               const DeviceInfo& device_info = {});
148 
149     // Methods that must be implemented from IImageManager.
150     FiemapStatus CreateBackingImage(const std::string& name, uint64_t size, int flags,
151                                     std::function<bool(uint64_t, uint64_t)>&& on_progress) override;
152     bool DeleteBackingImage(const std::string& name) override;
153     bool MapImageDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
154                         std::string* path) override;
155     bool UnmapImageDevice(const std::string& name) override;
156     bool BackingImageExists(const std::string& name) override;
157     bool IsImageMapped(const std::string& name) override;
158     bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
159                                   std::string* dev) override;
160     bool RemoveAllImages() override;
161     bool DisableImage(const std::string& name) override;
162     bool RemoveDisabledImages() override;
163     bool GetMappedImageDevice(const std::string& name, std::string* device) override;
164     bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override;
165 
166     std::vector<std::string> GetAllBackingImages();
167 
168     // Validates that all images still have pinned extents. This will be removed
169     // once b/134588268 is fixed.
170     bool Validate();
171 
172     void set_partition_opener(std::unique_ptr<IPartitionOpener>&& opener);
173 
174     // Writes |bytes| zeros at the beginning of the passed image
175     FiemapStatus ZeroFillNewImage(const std::string& name, uint64_t bytes);
176 
177   private:
178     ImageManager(const std::string& metadata_dir, const std::string& data_dir,
179                  const DeviceInfo& device_info);
180     std::string GetImageHeaderPath(const std::string& name);
181     std::string GetStatusFilePath(const std::string& image_name);
182     bool MapWithLoopDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
183                            std::string* path);
184     bool MapWithLoopDeviceList(const std::vector<std::string>& device_list, const std::string& name,
185                                const std::chrono::milliseconds& timeout_ms, std::string* path);
186     bool MapWithDmLinear(const IPartitionOpener& opener, const std::string& name,
187                          const std::chrono::milliseconds& timeout_ms, std::string* path);
188     bool UnmapImageDevice(const std::string& name, bool force);
189     bool IsUnreliablePinningAllowed() const;
190     bool MetadataDirIsTest() const;
191 
192     ImageManager(const ImageManager&) = delete;
193     ImageManager& operator=(const ImageManager&) = delete;
194     ImageManager& operator=(ImageManager&&) = delete;
195     ImageManager(ImageManager&&) = delete;
196 
197     std::string metadata_dir_;
198     std::string data_dir_;
199     std::unique_ptr<IPartitionOpener> partition_opener_;
200     DeviceInfo device_info_;
201 };
202 
203 // RAII helper class for mapping and opening devices with an ImageManager.
204 class MappedDevice final {
205   public:
206     static std::unique_ptr<MappedDevice> Open(IImageManager* manager,
207                                               const std::chrono::milliseconds& timeout_ms,
208                                               const std::string& name);
209 
210     ~MappedDevice();
211 
fd()212     int fd() const { return fd_.get(); }
path()213     const std::string& path() const { return path_; }
214 
215   protected:
216     MappedDevice(IImageManager* manager, const std::string& name, const std::string& path);
217 
218     IImageManager* manager_;
219     std::string name_;
220     std::string path_;
221     android::base::unique_fd fd_;
222 };
223 
224 }  // namespace fiemap
225 }  // namespace android
226