Addressing CL comments.
Bug: 153874006
Test: test PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest
Change-Id: Ie8b86cdc382955840cc3718d79a45991cf89b879
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index d412a19..a9dc92f 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1356,16 +1356,9 @@
fsControlParcel.incremental->log.reset(dup(ifs.control.logs()));
fsControlParcel.service = new IncrementalServiceConnector(*this, ifs.mountId);
- incfs::UniqueControl healthControl = mIncFs->openMount(ifs.root.c_str());
- if (healthControl.pendingReads() < 0) {
- LOG(ERROR) << "Failed to open health control for: " << ifs.root << "("
- << healthControl.cmd() << ":" << healthControl.pendingReads() << ":"
- << healthControl.logs() << ")";
- }
-
ifs.dataLoaderStub =
new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel),
- std::move(healthControl), externalListener);
+ externalListener, path::join(ifs.root, constants().mount));
}
template <class Duration>
@@ -1685,15 +1678,15 @@
IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id,
DataLoaderParamsParcel&& params,
FileSystemControlParcel&& control,
- incfs::UniqueControl&& healthControl,
- const DataLoaderStatusListener* externalListener)
+ const DataLoaderStatusListener* externalListener,
+ std::string&& healthPath)
: mService(service),
mId(id),
mParams(std::move(params)),
mControl(std::move(control)),
- mHealthControl(std::move(healthControl)),
- mListener(externalListener ? *externalListener : DataLoaderStatusListener()) {
- addToCmdLooperLocked();
+ mListener(externalListener ? *externalListener : DataLoaderStatusListener()),
+ mHealthPath(std::move(healthPath)) {
+ healthStatusOk();
}
IncrementalService::DataLoaderStub::~DataLoaderStub() {
@@ -1708,11 +1701,10 @@
auto now = Clock::now();
std::unique_lock lock(mMutex);
- removeFromCmdLooperLocked();
+ unregisterFromPendingReads();
mParams = {};
mControl = {};
- mHealthControl = {};
mStatusCondition.wait_until(lock, now + 60s, [this] {
return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
});
@@ -1832,7 +1824,7 @@
case IDataLoaderStatusListener::DATA_LOADER_STOPPED:
return start();
}
- // fallthrough
+ [[fallthrough]];
}
case IDataLoaderStatusListener::DATA_LOADER_CREATED:
switch (currentStatus) {
@@ -1895,23 +1887,48 @@
return binder::Status::ok();
}
-void IncrementalService::DataLoaderStub::addToCmdLooperLocked() {
- const auto pendingReadsFd = mHealthControl.pendingReads();
+void IncrementalService::DataLoaderStub::healthStatusOk() {
+ LOG(DEBUG) << "healthStatusOk: " << mId;
+ std::unique_lock lock(mMutex);
+ registerForPendingReads();
+}
+
+void IncrementalService::DataLoaderStub::healthStatusReadsPending() {
+ LOG(DEBUG) << "healthStatusReadsPending: " << mId;
+ requestStart();
+
+ std::unique_lock lock(mMutex);
+ unregisterFromPendingReads();
+}
+
+void IncrementalService::DataLoaderStub::healthStatusBlocked() {}
+
+void IncrementalService::DataLoaderStub::healthStatusUnhealthy() {}
+
+void IncrementalService::DataLoaderStub::registerForPendingReads() {
+ auto pendingReadsFd = mHealthControl.pendingReads();
if (pendingReadsFd < 0) {
- return;
+ mHealthControl = mService.mIncFs->openMount(mHealthPath);
+ pendingReadsFd = mHealthControl.pendingReads();
+ if (pendingReadsFd < 0) {
+ LOG(ERROR) << "Failed to open health control for: " << mId << ", path: " << mHealthPath
+ << "(" << mHealthControl.cmd() << ":" << mHealthControl.pendingReads() << ":"
+ << mHealthControl.logs() << ")";
+ return;
+ }
}
mService.mLooper->addFd(
pendingReadsFd, android::Looper::POLL_CALLBACK, android::Looper::EVENT_INPUT,
[](int, int, void* data) -> int {
auto&& self = (DataLoaderStub*)data;
- return self->onCmdLooperEvent();
+ return self->onPendingReads();
},
this);
mService.mLooper->wake();
}
-void IncrementalService::DataLoaderStub::removeFromCmdLooperLocked() {
+void IncrementalService::DataLoaderStub::unregisterFromPendingReads() {
const auto pendingReadsFd = mHealthControl.pendingReads();
if (pendingReadsFd < 0) {
return;
@@ -1919,41 +1936,17 @@
mService.mLooper->removeFd(pendingReadsFd);
mService.mLooper->wake();
+
+ mHealthControl = {};
}
-int IncrementalService::DataLoaderStub::onCmdLooperEvent() {
+int IncrementalService::DataLoaderStub::onPendingReads() {
if (!mService.mRunning.load(std::memory_order_relaxed)) {
return 0;
}
- bool pendingReadsOccur = false;
-
- {
- std::unique_lock lock(mMutex);
- const auto now = Clock::now();
- if (now < mEarliestMissingPageTs) {
- // Transition: duration::max -> now.
- mEarliestMissingPageTs = now;
- pendingReadsOccur = true;
- }
- }
-
- if (pendingReadsOccur) {
- LOG(INFO) << "Pending reads occur for, requesting start for: " << mId;
- requestStart();
- }
-
- {
- // Drop pending reads.
- static constexpr auto kMaxDropIterations = 3;
- std::unique_lock lock(mMutex);
- for (int i = 0; i < kMaxDropIterations; ++i) {
- if (IncFs_DropPendingReads(mHealthControl) <= 0) {
- break;
- }
- }
- }
- return 1;
+ healthStatusReadsPending();
+ return 0;
}
void IncrementalService::DataLoaderStub::onDump(int fd) {
@@ -1962,8 +1955,6 @@
dprintf(fd, " targetStatus: %d\n", mTargetStatus);
dprintf(fd, " targetStatusTs: %lldmcs\n",
(long long)(elapsedMcs(mTargetStatusTs, Clock::now())));
- dprintf(fd, " earliestMissingPageTs: %lldmcs\n",
- (long long)(elapsedMcs(mEarliestMissingPageTs, Clock::now())));
const auto& params = mParams;
dprintf(fd, " dataLoaderParams: {\n");
dprintf(fd, " type: %s\n", toString(params.type).c_str());
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 640ca53..f3fde2a 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -161,8 +161,7 @@
DataLoaderStub(IncrementalService& service, MountId id,
content::pm::DataLoaderParamsParcel&& params,
content::pm::FileSystemControlParcel&& control,
- incfs::UniqueControl&& healthControl,
- const DataLoaderStatusListener* externalListener);
+ const DataLoaderStatusListener* externalListener, std::string&& healthPath);
~DataLoaderStub();
// Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
// result in an error.
@@ -180,9 +179,9 @@
private:
binder::Status onStatusChanged(MountId mount, int newStatus) final;
- void addToCmdLooperLocked();
- void removeFromCmdLooperLocked();
- int onCmdLooperEvent();
+ void registerForPendingReads();
+ void unregisterFromPendingReads();
+ int onPendingReads();
bool isValid() const { return mId != kInvalidStorageId; }
sp<content::pm::IDataLoader> getDataLoader();
@@ -197,13 +196,22 @@
bool fsmStep();
+ // Watching for pending reads.
+ void healthStatusOk();
+ // Pending reads detected, waiting for Xsecs to confirm blocked state.
+ void healthStatusReadsPending();
+ // There are reads pending for X+secs, waiting for additional Ysecs to confirm unhealthy
+ // state.
+ void healthStatusBlocked();
+ // There are reads pending for X+Ysecs, marking storage as unhealthy.
+ void healthStatusUnhealthy();
+
IncrementalService& mService;
std::mutex mMutex;
MountId mId = kInvalidStorageId;
content::pm::DataLoaderParamsParcel mParams;
content::pm::FileSystemControlParcel mControl;
- incfs::UniqueControl mHealthControl;
DataLoaderStatusListener mListener;
std::condition_variable mStatusCondition;
@@ -211,7 +219,8 @@
int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
TimePoint mTargetStatusTs = {};
- TimePoint mEarliestMissingPageTs{Clock::duration::max()};
+ std::string mHealthPath;
+ incfs::UniqueControl mHealthControl;
};
using DataLoaderStubPtr = sp<DataLoaderStub>;