blob: b81e1b1b071c605c3f78d580aaadffbd09004c19 [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
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070019#include <android/content/pm/BnDataLoaderStatusListener.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080020#include <android/content/pm/DataLoaderParamsParcel.h>
Alex Buynytskyycca2c112020-05-05 12:48:41 -070021#include <android/content/pm/FileSystemControlParcel.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070022#include <android/content/pm/IDataLoaderStatusListener.h>
Songchun Fan1b76ccf2021-02-24 22:25:59 +000023#include <android/os/incremental/BnIncrementalService.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070024#include <android/os/incremental/BnIncrementalServiceConnector.h>
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070025#include <android/os/incremental/BnStorageHealthListener.h>
Songchun Fana7098592020-09-03 11:45:53 -070026#include <android/os/incremental/BnStorageLoadingProgressListener.h>
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080027#include <android/os/incremental/PerUidReadTimeouts.h>
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070028#include <android/os/incremental/StorageHealthCheckParams.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070029#include <binder/IAppOpsCallback.h>
Songchun Fan1b76ccf2021-02-24 22:25:59 +000030#include <binder/PersistableBundle.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080031#include <utils/String16.h>
32#include <utils/StrongPointer.h>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070033#include <ziparchive/zip_archive.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080034
35#include <atomic>
36#include <chrono>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070037#include <condition_variable>
38#include <functional>
Songchun Fan3c82a302019-11-29 14:23:45 -080039#include <limits>
40#include <map>
41#include <mutex>
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -070042#include <set>
Songchun Fan9b753082020-02-26 13:08:06 -080043#include <span>
Songchun Fan3c82a302019-11-29 14:23:45 -080044#include <string>
45#include <string_view>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070046#include <thread>
Songchun Fan3c82a302019-11-29 14:23:45 -080047#include <unordered_map>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070048#include <unordered_set>
Songchun Fan3c82a302019-11-29 14:23:45 -080049#include <utility>
50#include <vector>
51
52#include "ServiceWrappers.h"
Songchun Fan3c82a302019-11-29 14:23:45 -080053#include "incfs.h"
54#include "path.h"
55
Songchun Fan3c82a302019-11-29 14:23:45 -080056namespace android::incremental {
57
58using MountId = int;
59using StorageId = int;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080060using FileId = incfs::FileId;
Songchun Fan3c82a302019-11-29 14:23:45 -080061using BlockIndex = incfs::BlockIndex;
62using RawMetadata = incfs::RawMetadata;
Songchun Fan3c82a302019-11-29 14:23:45 -080063using Seconds = std::chrono::seconds;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070064using BootClockTsUs = uint64_t;
Songchun Fan3c82a302019-11-29 14:23:45 -080065
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -070066using IDataLoaderStatusListener = ::android::content::pm::IDataLoaderStatusListener;
67using DataLoaderStatusListener = ::android::sp<IDataLoaderStatusListener>;
Alex Buynytskyy04f73912020-02-10 08:34:18 -080068
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070069using StorageHealthCheckParams = ::android::os::incremental::StorageHealthCheckParams;
70using IStorageHealthListener = ::android::os::incremental::IStorageHealthListener;
71using StorageHealthListener = ::android::sp<IStorageHealthListener>;
Songchun Fana7098592020-09-03 11:45:53 -070072using IStorageLoadingProgressListener = ::android::os::incremental::IStorageLoadingProgressListener;
73using StorageLoadingProgressListener = ::android::sp<IStorageLoadingProgressListener>;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070074
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080075using PerUidReadTimeouts = ::android::os::incremental::PerUidReadTimeouts;
76
Alex Buynytskyycb163f92021-03-18 21:21:27 -070077struct IfsState {
78 // If mount is fully loaded.
79 bool fullyLoaded = false;
80 // If read logs are enabled on this mount. Populated only if fullyLoaded == true.
81 bool readLogsEnabled = false;
82 // If there was an error fetching any of the above.
83 bool error = false;
84};
85// Returns true if wants to be called again.
86using IfsStateCallback = std::function<bool(StorageId, IfsState)>;
87
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080088class IncrementalService final {
Songchun Fan3c82a302019-11-29 14:23:45 -080089public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080090 explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
Songchun Fan3c82a302019-11-29 14:23:45 -080091
92#pragma GCC diagnostic push
93#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
94 ~IncrementalService();
95#pragma GCC diagnostic pop
96
97 static constexpr StorageId kInvalidStorageId = -1;
Yurii Zubrytskyi9acc9ac2021-03-24 00:48:24 -070098 static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max() - 1;
99 static constexpr StorageId kAllStoragesId = kMaxStorageId + 1;
Songchun Fan3c82a302019-11-29 14:23:45 -0800100
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700101 static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();
102
Songchun Fan3c82a302019-11-29 14:23:45 -0800103 enum CreateOptions {
104 TemporaryBind = 1,
105 PermanentBind = 2,
106 CreateNew = 4,
107 OpenExisting = 8,
108
109 Default = TemporaryBind | CreateNew
110 };
111
112 enum class BindKind {
113 Temporary = 0,
114 Permanent = 1,
115 };
116
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700117 enum StorageFlags {
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800118 ReadLogsAllowed = 1 << 0,
119 ReadLogsEnabled = 1 << 1,
Alex Buynytskyy50d83ff2021-03-23 22:37:02 -0700120 ReadLogsRequested = 1 << 2,
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700121
122 ReadTimeoutsEnabled = 1 << 3,
123 ReadTimeoutsRequested = 1 << 4,
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800124 };
125
126 struct LoadingProgress {
127 ssize_t filledBlocks;
128 ssize_t totalBlocks;
129
130 bool isError() const { return totalBlocks < 0; }
131 bool started() const { return totalBlocks > 0; }
132 bool fullyLoaded() const { return !isError() && (totalBlocks == filledBlocks); }
133
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800134 int blocksRemainingOrError() const {
135 return totalBlocks <= 0 ? totalBlocks : totalBlocks - filledBlocks;
136 }
137
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800138 float getProgress() const {
139 return totalBlocks < 0
140 ? totalBlocks
141 : totalBlocks > 0 ? double(filledBlocks) / double(totalBlocks) : 1.f;
142 }
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700143 };
144
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800145 static FileId idFromMetadata(std::span<const uint8_t> metadata);
146 static inline FileId idFromMetadata(std::span<const char> metadata) {
147 return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
148 }
149
Alex Buynytskyy18b07a42020-02-03 20:06:00 -0800150 void onDump(int fd);
151
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700152 void onSystemReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800153
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700154 StorageId createStorage(std::string_view mountPoint,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700155 content::pm::DataLoaderParamsParcel dataLoaderParams,
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800156 CreateOptions options);
Songchun Fan3c82a302019-11-29 14:23:45 -0800157 StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
158 CreateOptions options = CreateOptions::Default);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800159 StorageId openStorage(std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800160
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700161 bool startLoading(StorageId storage, content::pm::DataLoaderParamsParcel dataLoaderParams,
162 DataLoaderStatusListener statusListener,
163 const StorageHealthCheckParams& healthCheckParams,
164 StorageHealthListener healthListener,
165 std::vector<PerUidReadTimeouts> perUidReadTimeouts);
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700166 void onInstallationComplete(StorageId storage);
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800167
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800168 int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
Songchun Fan3c82a302019-11-29 14:23:45 -0800169 int unbind(StorageId storage, std::string_view target);
170 void deleteStorage(StorageId storage);
171
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800172 void disallowReadLogs(StorageId storage);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700173 int setStorageParams(StorageId storage, bool enableReadLogs);
174
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800175 int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700176 incfs::NewFileParams params, std::span<const uint8_t> data);
Songchun Fan96100932020-02-03 19:20:58 -0800177 int makeDir(StorageId storage, std::string_view path, int mode = 0755);
178 int makeDirs(StorageId storage, std::string_view path, int mode = 0755);
Songchun Fan3c82a302019-11-29 14:23:45 -0800179
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800180 int link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId,
181 std::string_view newPath);
182 int unlink(StorageId storage, std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800183
Yurii Zubrytskyi256a1a42021-03-18 14:21:54 -0700184 incfs::LoadingState isFileFullyLoaded(StorageId storage, std::string_view filePath) const;
185 incfs::LoadingState isMountFullyLoaded(StorageId storage) const;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800186
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -0700187 LoadingProgress getLoadingProgress(StorageId storage) const;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800188
Songchun Fana7098592020-09-03 11:45:53 -0700189 bool registerLoadingProgressListener(StorageId storage,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700190 StorageLoadingProgressListener progressListener);
Songchun Fana7098592020-09-03 11:45:53 -0700191 bool unregisterLoadingProgressListener(StorageId storage);
Songchun Fan5ada1502021-04-14 19:04:11 +0000192
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700193 RawMetadata getMetadata(StorageId storage, std::string_view path) const;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800194 RawMetadata getMetadata(StorageId storage, FileId node) const;
Songchun Fan3c82a302019-11-29 14:23:45 -0800195
Songchun Fan0f8b6fe2020-02-05 17:41:25 -0800196 bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
Songchun Fan14f6c3c2020-05-21 18:19:07 -0700197 std::string_view libDirRelativePath, std::string_view abi,
198 bool extractNativeLibs);
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700199 bool waitForNativeBinariesExtraction(StorageId storage);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700200
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000201 void getMetrics(int32_t storageId, android::os::PersistableBundle* _aidl_return);
202
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700203 class AppOpsListener : public android::BnAppOpsCallback {
204 public:
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700205 AppOpsListener(IncrementalService& incrementalService, std::string packageName)
206 : incrementalService(incrementalService), packageName(std::move(packageName)) {}
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700207 void opChanged(int32_t op, const String16& packageName) final;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700208
209 private:
210 IncrementalService& incrementalService;
211 const std::string packageName;
212 };
213
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700214 class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector {
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700215 public:
216 IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage)
Alex Buynytskyy5f9e3a02020-04-07 21:13:41 -0700217 : incrementalService(incrementalService), storage(storage) {}
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700218 binder::Status setStorageParams(bool enableReadLogs, int32_t* _aidl_return) final;
219
220 private:
221 IncrementalService& incrementalService;
Alex Buynytskyy5f9e3a02020-04-07 21:13:41 -0700222 int32_t const storage;
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700223 };
224
Songchun Fan3c82a302019-11-29 14:23:45 -0800225private:
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700226 struct IncFsMount;
227
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700228 class DataLoaderStub : public content::pm::BnDataLoaderStatusListener {
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700229 public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700230 DataLoaderStub(IncrementalService& service, MountId id,
231 content::pm::DataLoaderParamsParcel&& params,
232 content::pm::FileSystemControlParcel&& control,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700233 DataLoaderStatusListener&& statusListener,
234 const StorageHealthCheckParams& healthCheckParams,
235 StorageHealthListener&& healthListener, std::string&& healthPath);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700236 ~DataLoaderStub();
Alex Buynytskyy9a545792020-04-17 15:34:47 -0700237 // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
238 // result in an error.
239 void cleanupResources();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700240
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700241 bool requestCreate();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700242 bool requestStart();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700243 bool requestDestroy();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700244
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700245 void onDump(int fd);
246
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700247 MountId id() const { return mId.load(std::memory_order_relaxed); }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700248 const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700249 bool isSystemDataLoader() const;
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700250 void setHealthListener(const StorageHealthCheckParams& healthCheckParams,
251 StorageHealthListener&& healthListener);
Songchun Fan9471be52021-04-21 17:49:27 -0700252 void getMetrics(android::os::PersistableBundle* _aidl_return);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700253
254 private:
255 binder::Status onStatusChanged(MountId mount, int newStatus) final;
256
Alex Buynytskyy060c9d62021-02-18 20:55:17 -0800257 void setCurrentStatus(int newStatus);
Alex Buynytskyy4bafd4d2021-06-08 16:35:39 -0700258 void compareAndSetCurrentStatus(int expectedStatus, int newStatus);
Alex Buynytskyy060c9d62021-02-18 20:55:17 -0800259
Alex Buynytskyy0bdbccf2020-04-23 20:36:42 -0700260 sp<content::pm::IDataLoader> getDataLoader();
Alex Buynytskyy9a545792020-04-17 15:34:47 -0700261
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700262 bool bind();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700263 bool create();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700264 bool start();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700265 bool destroy();
266
267 bool setTargetStatus(int status);
Alex Buynytskyy7e0a1a82020-04-27 17:06:10 -0700268 void setTargetStatusLocked(int status);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700269
270 bool fsmStep();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700271
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -0700272 void onHealthStatus(const StorageHealthListener& healthListener, int healthStatus);
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700273 void updateHealthStatus(bool baseline = false);
274
275 bool isValid() const { return id() != kInvalidStorageId; }
276
277 bool isHealthParamsValid() const;
278
279 const incfs::UniqueControl& initializeHealthControl();
280 void resetHealthControl();
281
282 BootClockTsUs getOldestPendingReadTs();
Songchun Fan1b76ccf2021-02-24 22:25:59 +0000283 BootClockTsUs getOldestTsFromLastPendingReads();
284 Milliseconds elapsedMsSinceKernelTs(TimePoint now, BootClockTsUs kernelTsUs);
Songchun Fan9471be52021-04-21 17:49:27 -0700285 long elapsedMsSinceOldestPendingRead();
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700286
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800287 // If the stub has to bind to the DL.
288 // Returns {} if bind operation is already in progress.
289 // Or bind delay in ms.
290 std::optional<Milliseconds> needToBind();
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800291
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700292 void registerForPendingReads();
293 void unregisterFromPendingReads();
Alex Buynytskyyd0855a32020-05-07 18:40:51 -0700294
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700295 IncrementalService& mService;
Alex Buynytskyyb0ea4482020-05-04 18:39:58 -0700296
297 std::mutex mMutex;
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700298 std::atomic<MountId> mId = kInvalidStorageId;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700299 content::pm::DataLoaderParamsParcel mParams;
300 content::pm::FileSystemControlParcel mControl;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700301 DataLoaderStatusListener mStatusListener;
302 StorageHealthListener mHealthListener;
Songchun Fan9471be52021-04-21 17:49:27 -0700303 std::atomic<int> mHealthStatus = IStorageHealthListener::HEALTH_STATUS_OK;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700304
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700305 std::condition_variable mStatusCondition;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700306 int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800307 TimePoint mCurrentStatusTs = {};
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700308 int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700309 TimePoint mTargetStatusTs = {};
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700310
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800311 TimePoint mPreviousBindTs = {};
312 Milliseconds mPreviousBindDelay = {};
313
Alex Buynytskyyd0855a32020-05-07 18:40:51 -0700314 std::string mHealthPath;
315 incfs::UniqueControl mHealthControl;
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700316 struct {
317 TimePoint userTs;
318 BootClockTsUs kernelTsUs;
319 } mHealthBase = {TimePoint::max(), kMaxBootClockTsUs};
320 StorageHealthCheckParams mHealthCheckParams;
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700321 std::vector<incfs::ReadInfoWithUid> mLastPendingReads;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700322 };
323 using DataLoaderStubPtr = sp<DataLoaderStub>;
324
Songchun Fan3c82a302019-11-29 14:23:45 -0800325 struct IncFsMount {
326 struct Bind {
327 StorageId storage;
328 std::string savedFilename;
329 std::string sourceDir;
330 BindKind kind;
331 };
332
333 struct Storage {
334 std::string name;
Songchun Fan3c82a302019-11-29 14:23:45 -0800335 };
336
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800337 using Control = incfs::UniqueControl;
Songchun Fan3c82a302019-11-29 14:23:45 -0800338
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700339 using BindMap = std::map<std::string, Bind, path::PathLess>;
Songchun Fan3c82a302019-11-29 14:23:45 -0800340 using StorageMap = std::unordered_map<StorageId, Storage>;
341
342 mutable std::mutex lock;
343 const std::string root;
Alex Buynytskyye76e1ef2021-05-07 14:50:02 -0700344 const std::string metricsKey;
Songchun Fan3c82a302019-11-29 14:23:45 -0800345 Control control;
346 /*const*/ MountId mountId;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800347 int32_t flags = StorageFlags::ReadLogsAllowed;
Songchun Fan3c82a302019-11-29 14:23:45 -0800348 StorageMap storages;
349 BindMap bindPoints;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700350 DataLoaderStubPtr dataLoaderStub;
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700351 TimePoint startLoadingTs = {};
Songchun Fan3c82a302019-11-29 14:23:45 -0800352 std::atomic<int> nextStorageDirNo{0};
Songchun Fan3c82a302019-11-29 14:23:45 -0800353 const IncrementalService& incrementalService;
354
Alex Buynytskyye76e1ef2021-05-07 14:50:02 -0700355 IncFsMount(std::string root, std::string metricsKey, MountId mountId, Control control,
Songchun Fan3c82a302019-11-29 14:23:45 -0800356 const IncrementalService& incrementalService)
357 : root(std::move(root)),
Alex Buynytskyye76e1ef2021-05-07 14:50:02 -0700358 metricsKey(std::move(metricsKey)),
Songchun Fan3c82a302019-11-29 14:23:45 -0800359 control(std::move(control)),
360 mountId(mountId),
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700361 incrementalService(incrementalService) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800362 IncFsMount(IncFsMount&&) = delete;
363 IncFsMount& operator=(IncFsMount&&) = delete;
364 ~IncFsMount();
365
366 StorageMap::iterator makeStorage(StorageId id);
367
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800368 void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; }
369 int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); }
370
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700371 void setReadLogsEnabled(bool value) {
372 return setFlag(StorageFlags::ReadLogsEnabled, value);
373 }
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700374 int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
375
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700376 void setReadLogsRequested(bool value) {
377 return setFlag(StorageFlags::ReadLogsRequested, value);
378 }
Alex Buynytskyy50d83ff2021-03-23 22:37:02 -0700379 int32_t readLogsRequested() const { return (flags & StorageFlags::ReadLogsRequested); }
380
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700381 void setReadTimeoutsEnabled(bool value) {
382 return setFlag(StorageFlags::ReadTimeoutsEnabled, value);
383 }
384 int32_t readTimeoutsEnabled() const { return (flags & StorageFlags::ReadTimeoutsEnabled); }
385
386 void setReadTimeoutsRequested(bool value) {
387 return setFlag(StorageFlags::ReadTimeoutsRequested, value);
388 }
389 int32_t readTimeoutsRequested() const {
390 return (flags & StorageFlags::ReadTimeoutsRequested);
391 }
392
Songchun Fan3c82a302019-11-29 14:23:45 -0800393 static void cleanupFilesystem(std::string_view root);
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700394
395 private:
396 void setFlag(StorageFlags flag, bool value);
Songchun Fan3c82a302019-11-29 14:23:45 -0800397 };
398
399 using IfsMountPtr = std::shared_ptr<IncFsMount>;
400 using MountMap = std::unordered_map<MountId, IfsMountPtr>;
401 using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
402
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700403 static bool perfLoggingEnabled();
404
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800405 void setUidReadTimeouts(StorageId storage,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700406 std::vector<PerUidReadTimeouts>&& perUidReadTimeouts);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800407 void clearUidReadTimeouts(StorageId storage);
Alex Buynytskyycb163f92021-03-18 21:21:27 -0700408 bool checkUidReadTimeouts(StorageId storage, IfsState state, Clock::time_point timeLimit);
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800409
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700410 std::unordered_set<std::string_view> adoptMountedInstances();
411 void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
Yurii Zubrytskyi107ae352020-04-03 13:12:51 -0700412 bool mountExistingImage(std::string_view root);
Songchun Fan3c82a302019-11-29 14:23:45 -0800413
414 IfsMountPtr getIfs(StorageId storage) const;
415 const IfsMountPtr& getIfsLocked(StorageId storage) const;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800416 int addBindMount(IncFsMount& ifs, StorageId storage, std::string_view storageRoot,
417 std::string&& source, std::string&& target, BindKind kind,
418 std::unique_lock<std::mutex>& mainLock);
Songchun Fan3c82a302019-11-29 14:23:45 -0800419
420 int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800421 std::string&& source, std::string&& target, BindKind kind,
Songchun Fan3c82a302019-11-29 14:23:45 -0800422 std::unique_lock<std::mutex>& mainLock);
423
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700424 void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
425 std::string&& source, std::string&& target, BindKind kind);
426
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800427 bool needStartDataLoaderLocked(IncFsMount& ifs);
428
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700429 void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700430 DataLoaderStatusListener&& statusListener = {},
431 const StorageHealthCheckParams& healthCheckParams = {},
432 StorageHealthListener&& healthListener = {});
Alex Buynytskyybf1c0632020-03-10 15:49:29 -0700433
Songchun Fan3c82a302019-11-29 14:23:45 -0800434 BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
435 StorageId findStorageId(std::string_view path) const;
436
437 void deleteStorage(IncFsMount& ifs);
438 void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
439 MountMap::iterator getStorageSlotLocked();
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700440 std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700441 std::string_view path) const;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700442 std::string normalizePathToStorageLocked(const IncFsMount& incfs,
443 IncFsMount::StorageMap::const_iterator storageIt,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700444 std::string_view path) const;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700445 int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
Alex Buynytskyyd7aa3462021-03-14 22:20:20 -0700446
Alex Buynytskyycb163f92021-03-18 21:21:27 -0700447 int disableReadLogsLocked(IncFsMount& ifs);
Alex Buynytskyyc144cc42021-03-31 22:19:42 -0700448 int applyStorageParamsLocked(IncFsMount& ifs);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700449
Yurii Zubrytskyi883a27a2021-03-18 19:30:56 -0700450 LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const;
Songchun Fan374f7652020-08-20 08:40:29 -0700451
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700452 int setFileContent(const IfsMountPtr& ifs, const incfs::FileId& fileId,
453 std::string_view debugFilePath, std::span<const uint8_t> data) const;
454
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700455 void registerAppOpsCallback(const std::string& packageName);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700456 bool unregisterAppOpsCallback(const std::string& packageName);
457 void onAppOpChanged(const std::string& packageName);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700458
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700459 void runJobProcessing();
460 void extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle zipFile, ZipEntry& entry,
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700461 const incfs::FileId& libFileId, std::string_view debugLibPath,
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700462 Clock::time_point scheduledTs);
463
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700464 void runCmdLooper();
465
Songchun Fana7098592020-09-03 11:45:53 -0700466 bool addTimedJob(TimedQueueWrapper& timedQueue, MountId id, Milliseconds after, Job what);
467 bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
Alex Buynytskyycb163f92021-03-18 21:21:27 -0700468
469 void addIfsStateCallback(StorageId storageId, IfsStateCallback callback);
470 void removeIfsStateCallbacks(StorageId storageId);
471 void processIfsStateCallbacks();
472 void processIfsStateCallbacks(StorageId storageId, std::vector<IfsStateCallback>& callbacks);
473
Songchun Fana7098592020-09-03 11:45:53 -0700474 bool updateLoadingProgress(int32_t storageId,
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700475 StorageLoadingProgressListener&& progressListener);
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700476
Yurii Zubrytskyi4cd24922021-03-24 00:46:29 -0700477 void trimReservedSpaceV1(const IncFsMount& ifs);
Songchun Fan0dc77722021-05-03 17:13:52 -0700478 int64_t elapsedUsSinceMonoTs(uint64_t monoTsUs);
Yurii Zubrytskyi4cd24922021-03-24 00:46:29 -0700479
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700480private:
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700481 const std::unique_ptr<VoldServiceWrapper> mVold;
482 const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
483 const std::unique_ptr<IncFsWrapper> mIncFs;
484 const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
485 const std::unique_ptr<JniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700486 const std::unique_ptr<LooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700487 const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700488 const std::unique_ptr<TimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700489 const std::unique_ptr<FsWrapper> mFs;
Alex Buynytskyy7e06d712021-03-09 19:24:23 -0800490 const std::unique_ptr<ClockWrapper> mClock;
Songchun Fan3c82a302019-11-29 14:23:45 -0800491 const std::string mIncrementalDir;
492
493 mutable std::mutex mLock;
494 mutable std::mutex mMountOperationLock;
495 MountMap mMounts;
496 BindPathMap mBindsByPath;
497
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700498 std::mutex mCallbacksLock;
Yurii Zubrytskyif4769e22021-03-18 20:37:45 -0700499 std::unordered_map<std::string, sp<AppOpsListener>> mCallbackRegistered;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700500
Yurii Zubrytskyi9acc9ac2021-03-24 00:48:24 -0700501 using IfsStateCallbacks = std::map<StorageId, std::vector<IfsStateCallback>>;
Alex Buynytskyycb163f92021-03-18 21:21:27 -0700502 std::mutex mIfsStateCallbacksLock;
503 IfsStateCallbacks mIfsStateCallbacks;
504
Songchun Fan3c82a302019-11-29 14:23:45 -0800505 std::atomic_bool mSystemReady = false;
506 StorageId mNextId = 0;
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700507
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700508 std::atomic_bool mRunning{true};
509
Yurii Zubrytskyi721ac4d2020-04-13 11:34:32 -0700510 std::unordered_map<MountId, std::vector<Job>> mJobQueue;
511 MountId mPendingJobsMount = kInvalidStorageId;
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700512 std::condition_variable mJobCondition;
513 std::mutex mJobMutex;
514 std::thread mJobProcessor;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700515
516 std::thread mCmdLooperThread;
Songchun Fan3c82a302019-11-29 14:23:45 -0800517};
518
519} // namespace android::incremental