memevents: Create new API to verify listener state
Expose an API that allows the client to know whether or not the bpf ring
buffer manager was initialized correctly.
Test: atest memevents_test
Bug: 330393131
Change-Id: I69400486bfa942f446620bce3868b5a24bd8bf84
Signed-off-by: Carlos Galo <carlosgalo@google.com>
diff --git a/libmemevents/include/memevents/memevents.h b/libmemevents/include/memevents/memevents.h
index e17270c..9282ab9 100644
--- a/libmemevents/include/memevents/memevents.h
+++ b/libmemevents/include/memevents/memevents.h
@@ -47,10 +47,28 @@
class MemEventListener final {
public:
+ /*
+ * MemEventListener will `std::abort` when failing to initialize
+ * the bpf ring buffer manager, on a bpf-rb supported kernel.
+ *
+ * If running on a kernel that doesn't support bpf-rb, the listener
+ * will initialize in an invalid state, preventing it from making
+ * any actions/calls.
+ * To check if the listener initialized correctly use `ok()`.
+ */
MemEventListener(MemEventClient client, bool attachTpForTests = false);
~MemEventListener();
/**
+ * Check if the listener was initialized correctly, with a valid bpf
+ * ring buffer manager on a bpf-rb supported kernel.
+ *
+ * @return true if initialized with a valid bpf rb manager, false
+ * otherwise.
+ */
+ bool ok();
+
+ /**
* Registers the requested memory event to the listener.
*
* @param event_type Memory event type to listen for.
diff --git a/libmemevents/memevents.cpp b/libmemevents/memevents.cpp
index eefbd46..db61612 100644
--- a/libmemevents/memevents.cpp
+++ b/libmemevents/memevents.cpp
@@ -43,6 +43,8 @@
static const std::string kClientRingBuffers[MemEventClient::NR_CLIENTS] = {
MEM_EVENTS_AMS_RB, MEM_EVENTS_LMKD_RB, MEM_EVENTS_TEST_RB};
+static const bool isBpfRingBufferSupported = isAtLeastKernelVersion(5, 8, 0);
+
class MemBpfRingbuf : public BpfRingbufBase {
public:
using EventCallback = std::function<void(const mem_event_t&)>;
@@ -174,9 +176,14 @@
* throughout the public APIs to prevent the listener to do any actions.
*/
memBpfRb.reset(nullptr);
- if (isAtLeastKernelVersion(5, 8, 0)) {
+ if (isBpfRingBufferSupported) {
LOG(ERROR) << "memevent listener MemBpfRingbuf init failed: "
<< status.error().message();
+ /*
+ * Do not perform an `std::abort()`, there are some AMS test suites inadvertently
+ * initialize a memlistener to resolve test dependencies. We don't expect it
+ * to succeed since the test doesn't have the correct permissions.
+ */
} else {
LOG(ERROR) << "memevent listener failed to initialize, not supported kernel";
}
@@ -187,8 +194,12 @@
deregisterAllEvents();
}
+bool MemEventListener::ok() {
+ return isBpfRingBufferSupported && memBpfRb;
+}
+
bool MemEventListener::registerEvent(mem_event_type_t event_type) {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent register failed, failure to initialize";
return false;
}
@@ -247,7 +258,7 @@
}
bool MemEventListener::listen(int timeout_ms) {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent listen failed, failure to initialize";
return false;
}
@@ -260,7 +271,7 @@
}
bool MemEventListener::deregisterEvent(mem_event_type_t event_type) {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent failed to deregister, failure to initialize";
return false;
}
@@ -301,7 +312,7 @@
}
void MemEventListener::deregisterAllEvents() {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent deregister all events failed, failure to initialize";
return;
}
@@ -312,7 +323,7 @@
}
bool MemEventListener::getMemEvents(std::vector<mem_event_t>& mem_events) {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent failed getting memory events, failure to initialize";
return false;
}
@@ -330,7 +341,7 @@
}
int MemEventListener::getRingBufferFd() {
- if (!memBpfRb) {
+ if (!ok()) {
LOG(ERROR) << "memevent failed getting ring-buffer fd, failure to initialize";
return -1;
}
diff --git a/libmemevents/memevents_test.cpp b/libmemevents/memevents_test.cpp
index 611912c..b846e38 100644
--- a/libmemevents/memevents_test.cpp
+++ b/libmemevents/memevents_test.cpp
@@ -69,6 +69,10 @@
}
}
+ void SetUp() override {
+ ASSERT_FALSE(memevent_listener.ok()) << "BPF ring buffer manager shouldn't initialize";
+ }
+
void TearDown() override { memevent_listener.deregisterAllEvents(); }
};
@@ -190,6 +194,11 @@
}
}
+ void SetUp() override {
+ ASSERT_TRUE(memevent_listener.ok())
+ << "Memory listener failed to initialize bpf ring buffer manager";
+ }
+
void TearDown() override { memevent_listener.deregisterAllEvents(); }
};
@@ -226,6 +235,7 @@
listener = std::make_unique<MemEventListener>(client);
ASSERT_TRUE(listener) << "MemEventListener failed to initialize with valid client value: "
<< client;
+ ASSERT_TRUE(listener->ok()) << "MemEventListener failed to initialize with bpf rb manager";
}
}
@@ -396,6 +406,10 @@
}
}
+ void SetUp() override {
+ ASSERT_TRUE(mem_listener.ok()) << "Listener failed to initialize bpf rb manager";
+ }
+
void TearDown() override { mem_listener.deregisterAllEvents(); }
/*
@@ -587,6 +601,10 @@
protected:
MemEventListener mem_listener = MemEventListener(mem_test_client, true);
+ void SetUp() override {
+ ASSERT_TRUE(mem_listener.ok()) << "listener failed to initialize bpf ring buffer manager";
+ }
+
void TearDown() override { mem_listener.deregisterAllEvents(); }
/**