Installation hardening: reducing read timeout during installation.
And then restoring post-install.
Bug: 160635296
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest PackageManagerServiceTest ChecksumsTest
Change-Id: I0821458bf92db162518a2cbcb7499cd7544e64f2
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 6695ba8..388f932 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -100,6 +100,12 @@
return (s & (Constants::blockSize - 1)) == 0;
}
+static bool getAlwaysEnableReadTimeoutsForSystemDataLoaders() {
+ return android::base::
+ GetBoolProperty("debug.incremental.always_enable_read_timeouts_for_system_dataloaders",
+ true);
+}
+
static bool getEnforceReadLogsMaxIntervalForSystemDataLoaders() {
return android::base::GetBoolProperty("debug.incremental.enforce_readlogs_max_interval_for_"
"system_dataloaders",
@@ -315,19 +321,11 @@
::rmdir(path::c_str(root));
}
-void IncrementalService::IncFsMount::setReadLogsEnabled(bool value) {
+void IncrementalService::IncFsMount::setFlag(StorageFlags flag, bool value) {
if (value) {
- flags |= StorageFlags::ReadLogsEnabled;
+ flags |= flag;
} else {
- flags &= ~StorageFlags::ReadLogsEnabled;
- }
-}
-
-void IncrementalService::IncFsMount::setReadLogsRequested(bool value) {
- if (value) {
- flags |= StorageFlags::ReadLogsRequested;
- } else {
- flags &= ~StorageFlags::ReadLogsRequested;
+ flags &= ~flag;
}
}
@@ -728,10 +726,17 @@
LOG(INFO) << "Skipped data loader stub creation because it already exists";
return false;
}
+
prepareDataLoaderLocked(*ifs, std::move(dataLoaderParams), std::move(statusListener),
healthCheckParams, std::move(healthListener));
CHECK(ifs->dataLoaderStub);
dataLoaderStub = ifs->dataLoaderStub;
+
+ // Disable long read timeouts for non-system dataloaders.
+ // To be re-enabled after installation is complete.
+ ifs->setReadTimeoutsRequested(dataLoaderStub->isSystemDataLoader() &&
+ getAlwaysEnableReadTimeoutsForSystemDataLoaders());
+ applyStorageParamsLocked(*ifs);
}
if (dataLoaderStub->isSystemDataLoader() &&
@@ -765,6 +770,18 @@
return dataLoaderStub->requestStart();
}
+void IncrementalService::onInstallationComplete(StorageId storage) {
+ IfsMountPtr ifs = getIfs(storage);
+ if (!ifs) {
+ return;
+ }
+
+ // Always enable long read timeouts after installation is complete.
+ std::unique_lock l(ifs->lock);
+ ifs->setReadTimeoutsRequested(true);
+ applyStorageParamsLocked(*ifs);
+}
+
IncrementalService::BindPathMap::const_iterator IncrementalService::findStorageLocked(
std::string_view path) const {
return findParentPath(mBindsByPath, path);
@@ -868,7 +885,7 @@
if (!ifs->readLogsRequested()) {
return 0;
}
- if (auto status = applyStorageParamsLocked(*ifs, /*enableReadLogs=*/true); status != 0) {
+ if (auto status = applyStorageParamsLocked(*ifs); status != 0) {
return status;
}
}
@@ -880,10 +897,10 @@
int IncrementalService::disableReadLogsLocked(IncFsMount& ifs) {
ifs.setReadLogsRequested(false);
- return applyStorageParamsLocked(ifs, /*enableReadLogs=*/false);
+ return applyStorageParamsLocked(ifs);
}
-int IncrementalService::applyStorageParamsLocked(IncFsMount& ifs, bool enableReadLogs) {
+int IncrementalService::applyStorageParamsLocked(IncFsMount& ifs) {
os::incremental::IncrementalFileSystemControlParcel control;
control.cmd.reset(dup(ifs.control.cmd()));
control.pendingReads.reset(dup(ifs.control.pendingReads()));
@@ -892,11 +909,15 @@
control.log.reset(dup(logsFd));
}
+ bool enableReadLogs = ifs.readLogsRequested();
+ bool enableReadTimeouts = ifs.readTimeoutsRequested();
+
std::lock_guard l(mMountOperationLock);
- auto status = mVold->setIncFsMountOptions(control, enableReadLogs);
+ auto status = mVold->setIncFsMountOptions(control, enableReadLogs, enableReadTimeouts);
if (status.isOk()) {
- // Store enabled state.
+ // Store states.
ifs.setReadLogsEnabled(enableReadLogs);
+ ifs.setReadTimeoutsEnabled(enableReadTimeouts);
} else {
LOG(ERROR) << "applyStorageParams failed: " << status.toString8();
}
@@ -1271,7 +1292,7 @@
maxPendingTimeUs = std::max(maxPendingTimeUs, microseconds(timeouts.maxPendingTimeUs));
}
if (maxPendingTimeUs < Constants::minPerUidTimeout) {
- LOG(ERROR) << "Skip setting read timeouts (maxPendingTime < Constants::minPerUidTimeout): "
+ LOG(ERROR) << "Skip setting read timeouts (maxPendingTime < Constants::minPerUidTimeout): "
<< duration_cast<milliseconds>(maxPendingTimeUs).count() << "ms < "
<< Constants::minPerUidTimeout.count() << "ms";
return;
@@ -2946,8 +2967,10 @@
return result;
}
- LOG(DEBUG) << id() << ": pendingReads: " << control.pendingReads() << ", "
- << mLastPendingReads.size() << ": " << mLastPendingReads.front().bootClockTsUs;
+ LOG(DEBUG) << id() << ": pendingReads: fd(" << control.pendingReads() << "), count("
+ << mLastPendingReads.size() << "), block: " << mLastPendingReads.front().block
+ << ", time: " << mLastPendingReads.front().bootClockTsUs
+ << ", uid: " << mLastPendingReads.front().uid;
return getOldestTsFromLastPendingReads();
}