Revive ACgroupController_getFlags LLNDK function to detect missing cgroups

ACgroupController_getFlags was reverted due to LLNDK breakage, however
it allows detection of cgroups that failed to mount in a more efficient
way. Revive the function as a weakly linked symbol to allow for it to
be missing in case older LLNDK library is being used with the new
system software. This effectively reverts the commit
aa1d54f0cc "Remove ACgroupController_getFlags to fix API breakage"'
except it declares ACgroupController_getFlags function as weak and
targets it for API level 30. If LLNKD library does not contain
ACgroupController_getFlags the behavior falls back to the current
way of identifying cgroups that failed to mount.

Test: build and verify correct operation with a missing cgroup
Change-Id: I9158ef53aba97972d41d71dd3396ac43796a7004
Merged-In: I9158ef53aba97972d41d71dd3396ac43796a7004
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
Suren Baghdasaryan 2020-01-23 16:18:13 -08:00
parent 20610c3082
commit cee468fb79
4 changed files with 40 additions and 5 deletions

View file

@ -71,7 +71,12 @@ bool CgroupController::IsUsable() {
if (!HasValue()) return false;
if (state_ == UNKNOWN) {
state_ = access(GetProcsFilePath("", 0, 0).c_str(), F_OK) == 0 ? USABLE : MISSING;
if (ACgroupController_getFlags != nullptr) {
uint32_t flags = ACgroupController_getFlags(controller_);
state_ = (flags & CGROUPRC_CONTROLLER_FLAG_MOUNTED) != 0 ? USABLE : MISSING;
} else {
state_ = access(GetProcsFilePath("", 0, 0).c_str(), F_OK) == 0 ? USABLE : MISSING;
}
}
return state_ == USABLE;
@ -161,9 +166,16 @@ void CgroupMap::Print() const {
auto controller_count = ACgroupFile_getControllerCount();
for (uint32_t i = 0; i < controller_count; ++i) {
const ACgroupController* controller = ACgroupFile_getController(i);
LOG(INFO) << "\t" << ACgroupController_getName(controller) << " ver "
<< ACgroupController_getVersion(controller) << " path "
<< ACgroupController_getPath(controller);
if (ACgroupController_getFlags != nullptr) {
LOG(INFO) << "\t" << ACgroupController_getName(controller) << " ver "
<< ACgroupController_getVersion(controller) << " path "
<< ACgroupController_getPath(controller) << " flags "
<< ACgroupController_getFlags(controller);
} else {
LOG(INFO) << "\t" << ACgroupController_getName(controller) << " ver "
<< ACgroupController_getVersion(controller) << " path "
<< ACgroupController_getPath(controller);
}
}
}

View file

@ -27,6 +27,11 @@ uint32_t ACgroupController_getVersion(const ACgroupController* controller) {
return controller->version();
}
uint32_t ACgroupController_getFlags(const ACgroupController* controller) {
CHECK(controller != nullptr);
return controller->flags();
}
const char* ACgroupController_getName(const ACgroupController* controller) {
CHECK(controller != nullptr);
return controller->name();

View file

@ -66,10 +66,21 @@ __attribute__((warn_unused_result)) uint32_t ACgroupController_getVersion(const
__INTRODUCED_IN(29);
/**
* Flag bitmask to be used when ACgroupController_getFlags can be exported
* Flag bitmask used in ACgroupController_getFlags
*/
#define CGROUPRC_CONTROLLER_FLAG_MOUNTED 0x1
#if __ANDROID_API__ >= __ANDROID_API_R__
/**
* Returns the flags bitmask of the given controller.
* If the given controller is null, return 0.
*/
__attribute__((warn_unused_result, weak)) uint32_t ACgroupController_getFlags(
const ACgroupController*) __INTRODUCED_IN(30);
#endif
/**
* Returns the name of the given controller.
* If the given controller is null, return nullptr.

View file

@ -9,3 +9,10 @@ LIBCGROUPRC { # introduced=29
local:
*;
};
LIBCGROUPRC_30 { # introduced=30
global:
ACgroupController_getFlags;
local:
*;
};