blob: 406b32e510443053ea99fedd21ebe50e5db52d9e [file] [log] [blame]
Songchun Fan3c82a302019-11-29 14:23:45 -08001/*
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 <android-base/strings.h>
20#include <android-base/unique_fd.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080021#include <android/content/pm/DataLoaderParamsParcel.h>
22#include <binder/IServiceManager.h>
23#include <utils/String16.h>
24#include <utils/StrongPointer.h>
25#include <utils/Vector.h>
26
27#include <atomic>
28#include <chrono>
29#include <future>
30#include <limits>
31#include <map>
32#include <mutex>
Songchun Fan9b753082020-02-26 13:08:06 -080033#include <span>
Songchun Fan3c82a302019-11-29 14:23:45 -080034#include <string>
35#include <string_view>
36#include <unordered_map>
37#include <utility>
38#include <vector>
39
40#include "ServiceWrappers.h"
41#include "android/content/pm/BnDataLoaderStatusListener.h"
42#include "incfs.h"
43#include "path.h"
44
45using namespace android::os::incremental;
46
47namespace android::os {
48class IVold;
49}
50
51namespace android::incremental {
52
53using MountId = int;
54using StorageId = int;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080055using FileId = incfs::FileId;
Songchun Fan3c82a302019-11-29 14:23:45 -080056using BlockIndex = incfs::BlockIndex;
57using RawMetadata = incfs::RawMetadata;
58using Clock = std::chrono::steady_clock;
59using TimePoint = std::chrono::time_point<Clock>;
60using Seconds = std::chrono::seconds;
61
Alex Buynytskyy04f73912020-02-10 08:34:18 -080062using DataLoaderStatusListener = ::android::sp<::android::content::pm::IDataLoaderStatusListener>;
63
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080064class IncrementalService final {
Songchun Fan3c82a302019-11-29 14:23:45 -080065public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080066 explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
Songchun Fan3c82a302019-11-29 14:23:45 -080067
68#pragma GCC diagnostic push
69#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
70 ~IncrementalService();
71#pragma GCC diagnostic pop
72
73 static constexpr StorageId kInvalidStorageId = -1;
74 static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();
75
76 enum CreateOptions {
77 TemporaryBind = 1,
78 PermanentBind = 2,
79 CreateNew = 4,
80 OpenExisting = 8,
81
82 Default = TemporaryBind | CreateNew
83 };
84
85 enum class BindKind {
86 Temporary = 0,
87 Permanent = 1,
88 };
89
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080090 static FileId idFromMetadata(std::span<const uint8_t> metadata);
91 static inline FileId idFromMetadata(std::span<const char> metadata) {
92 return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
93 }
94
Alex Buynytskyy18b07a42020-02-03 20:06:00 -080095 void onDump(int fd);
96
Songchun Fan3c82a302019-11-29 14:23:45 -080097 std::optional<std::future<void>> onSystemReady();
98
Songchun Fan9b753082020-02-26 13:08:06 -080099 StorageId createStorage(std::string_view mountPoint, DataLoaderParamsParcel&& dataLoaderParams,
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800100 const DataLoaderStatusListener& dataLoaderStatusListener,
Songchun Fan3c82a302019-11-29 14:23:45 -0800101 CreateOptions options = CreateOptions::Default);
102 StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
103 CreateOptions options = CreateOptions::Default);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800104 StorageId openStorage(std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800105
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800106 FileId nodeFor(StorageId storage, std::string_view path) const;
107 std::pair<FileId, std::string_view> parentAndNameFor(StorageId storage,
108 std::string_view path) const;
Songchun Fan3c82a302019-11-29 14:23:45 -0800109
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800110 int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
Songchun Fan3c82a302019-11-29 14:23:45 -0800111 int unbind(StorageId storage, std::string_view target);
112 void deleteStorage(StorageId storage);
113
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800114 int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
115 incfs::NewFileParams params);
Songchun Fan96100932020-02-03 19:20:58 -0800116 int makeDir(StorageId storage, std::string_view path, int mode = 0755);
117 int makeDirs(StorageId storage, std::string_view path, int mode = 0755);
Songchun Fan3c82a302019-11-29 14:23:45 -0800118
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800119 int link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId,
120 std::string_view newPath);
121 int unlink(StorageId storage, std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800122
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800123 bool isRangeLoaded(StorageId storage, FileId file, std::pair<BlockIndex, BlockIndex> range) {
Songchun Fan3c82a302019-11-29 14:23:45 -0800124 return false;
125 }
126
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800127 RawMetadata getMetadata(StorageId storage, FileId node) const;
Songchun Fan3c82a302019-11-29 14:23:45 -0800128
129 std::vector<std::string> listFiles(StorageId storage) const;
130 bool startLoading(StorageId storage) const;
Songchun Fan0f8b6fe2020-02-05 17:41:25 -0800131 bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
132 std::string_view libDirRelativePath, std::string_view abi);
Songchun Fan3c82a302019-11-29 14:23:45 -0800133 class IncrementalDataLoaderListener : public android::content::pm::BnDataLoaderStatusListener {
134 public:
Songchun Fan9b753082020-02-26 13:08:06 -0800135 IncrementalDataLoaderListener(IncrementalService& incrementalService,
136 DataLoaderStatusListener externalListener)
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800137 : incrementalService(incrementalService), externalListener(externalListener) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800138 // Callbacks interface
139 binder::Status onStatusChanged(MountId mount, int newStatus) override;
140
141 private:
142 IncrementalService& incrementalService;
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800143 DataLoaderStatusListener externalListener;
Songchun Fan3c82a302019-11-29 14:23:45 -0800144 };
145
146private:
147 struct IncFsMount {
148 struct Bind {
149 StorageId storage;
150 std::string savedFilename;
151 std::string sourceDir;
152 BindKind kind;
153 };
154
155 struct Storage {
156 std::string name;
Songchun Fan3c82a302019-11-29 14:23:45 -0800157 };
158
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800159 using Control = incfs::UniqueControl;
Songchun Fan3c82a302019-11-29 14:23:45 -0800160
161 using BindMap = std::map<std::string, Bind>;
162 using StorageMap = std::unordered_map<StorageId, Storage>;
163
164 mutable std::mutex lock;
165 const std::string root;
166 Control control;
167 /*const*/ MountId mountId;
168 StorageMap storages;
169 BindMap bindPoints;
170 std::optional<DataLoaderParamsParcel> savedDataLoaderParams;
171 std::atomic<int> nextStorageDirNo{0};
172 std::atomic<int> dataLoaderStatus = -1;
Alex Buynytskyybf1c0632020-03-10 15:49:29 -0700173 bool dataLoaderStartRequested = false;
Songchun Fan3c82a302019-11-29 14:23:45 -0800174 TimePoint connectionLostTime = TimePoint();
175 const IncrementalService& incrementalService;
176
177 IncFsMount(std::string root, MountId mountId, Control control,
178 const IncrementalService& incrementalService)
179 : root(std::move(root)),
180 control(std::move(control)),
181 mountId(mountId),
182 incrementalService(incrementalService) {}
183 IncFsMount(IncFsMount&&) = delete;
184 IncFsMount& operator=(IncFsMount&&) = delete;
185 ~IncFsMount();
186
187 StorageMap::iterator makeStorage(StorageId id);
188
189 static void cleanupFilesystem(std::string_view root);
190 };
191
192 using IfsMountPtr = std::shared_ptr<IncFsMount>;
193 using MountMap = std::unordered_map<MountId, IfsMountPtr>;
194 using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
195
196 void mountExistingImages();
197 bool mountExistingImage(std::string_view root, std::string_view key);
198
199 IfsMountPtr getIfs(StorageId storage) const;
200 const IfsMountPtr& getIfsLocked(StorageId storage) const;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800201 int addBindMount(IncFsMount& ifs, StorageId storage, std::string_view storageRoot,
202 std::string&& source, std::string&& target, BindKind kind,
203 std::unique_lock<std::mutex>& mainLock);
Songchun Fan3c82a302019-11-29 14:23:45 -0800204
205 int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800206 std::string&& source, std::string&& target, BindKind kind,
Songchun Fan3c82a302019-11-29 14:23:45 -0800207 std::unique_lock<std::mutex>& mainLock);
208
Songchun Fan9b753082020-02-26 13:08:06 -0800209 bool prepareDataLoader(IncFsMount& ifs, DataLoaderParamsParcel* params = nullptr,
210 const DataLoaderStatusListener* externalListener = nullptr);
Alex Buynytskyybf1c0632020-03-10 15:49:29 -0700211 bool startDataLoader(MountId mountId) const;
212
Songchun Fan3c82a302019-11-29 14:23:45 -0800213 BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
214 StorageId findStorageId(std::string_view path) const;
215
216 void deleteStorage(IncFsMount& ifs);
217 void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
218 MountMap::iterator getStorageSlotLocked();
Songchun Fan103ba1d2020-02-03 17:32:32 -0800219 std::string normalizePathToStorage(const IfsMountPtr incfs, StorageId storage,
220 std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800221
222 // Member variables
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800223 std::unique_ptr<VoldServiceWrapper> mVold;
Songchun Fan68645c42020-02-27 15:57:35 -0800224 std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800225 std::unique_ptr<IncFsWrapper> mIncFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800226 const std::string mIncrementalDir;
227
228 mutable std::mutex mLock;
229 mutable std::mutex mMountOperationLock;
230 MountMap mMounts;
231 BindPathMap mBindsByPath;
232
233 std::atomic_bool mSystemReady = false;
234 StorageId mNextId = 0;
235 std::promise<void> mPrepareDataLoaders;
236};
237
238} // namespace android::incremental