BpfLoader: split legacy bpfloader into 3 phases, simplify arguments
Should make integration with BpfLoader written in rust easier.
While at it add simple wrappers around ALOG{V,D,I,W,E}(),
which may come in handy as bpfloader runs early enough that
logging must be to the kernel dmesg ringbuffer instead...
Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ia49c605bae63241b74d04e2e0f58fd089c23993d
This commit is contained in:
parent
6d4d9d89c2
commit
dd4bd2d655
3 changed files with 69 additions and 14 deletions
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#include <libbpf_android.h>
|
||||
|
||||
int main(int argc, char** argv, char * const envp[]) {
|
||||
return android::bpf::legacyBpfLoader(argc, argv, envp);
|
||||
__noreturn int main() {
|
||||
initLogging();
|
||||
legacyBpfLoader();
|
||||
execNetBpfLoadDone();
|
||||
// unreachable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -975,27 +975,58 @@ int createSysFsBpfSubDir(const char* const prefix) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int legacyBpfLoader(int __unused argc, char** argv, char * const envp[]) {
|
||||
base::InitLogging(argv, &base::KernelLogger);
|
||||
} // namespace bpf
|
||||
} // namespace android
|
||||
|
||||
// ----- extern C stuff for rust below here -----
|
||||
|
||||
void initLogging() {
|
||||
// since we only ever get called from mainline NetBpfLoad
|
||||
// (see packages/modules/Connectivity/netbpfload/NetBpfLoad.cpp around line 516)
|
||||
// and there no arguments, so we can just pretend/assume this is the case.
|
||||
const char* argv[] = {"/system/bin/bpfloader", NULL};
|
||||
android::base::InitLogging(const_cast<char**>(argv), &android::base::KernelLogger);
|
||||
}
|
||||
|
||||
void legacyBpfLoader() {
|
||||
// Load all ELF objects, create programs and maps, and pin them
|
||||
for (const auto& location : locations) {
|
||||
if (createSysFsBpfSubDir(location.prefix) || loadAllElfObjects(location)) {
|
||||
for (const auto& location : android::bpf::locations) {
|
||||
if (android::bpf::createSysFsBpfSubDir(location.prefix) ||
|
||||
android::bpf::loadAllElfObjects(location)) {
|
||||
ALOGE("=== CRITICAL FAILURE LOADING BPF PROGRAMS FROM %s ===", location.dir);
|
||||
ALOGE("If this triggers reliably, you're probably missing kernel options or patches.");
|
||||
ALOGE("If this triggers randomly, you might be hitting some memory allocation "
|
||||
"problems or startup script race.");
|
||||
ALOGE("--- DO NOT EXPECT SYSTEM TO BOOT SUCCESSFULLY ---");
|
||||
sleep(20);
|
||||
return 120;
|
||||
exit(120);
|
||||
}
|
||||
}
|
||||
|
||||
const char * args[] = { "/apex/com.android.tethering/bin/netbpfload", "done", NULL, };
|
||||
execve(args[0], (char**)args, envp);
|
||||
ALOGE("FATAL: execve(): %d[%s]", errno, strerror(errno));
|
||||
return 121;
|
||||
}
|
||||
|
||||
} // namespace bpf
|
||||
} // namespace android
|
||||
void execNetBpfLoadDone() {
|
||||
const char* args[] = {"/apex/com.android.tethering/bin/netbpfload", "done", NULL};
|
||||
execve(args[0], (char**)args, environ);
|
||||
ALOGE("FATAL: execve(): %d[%s]", errno, strerror(errno));
|
||||
exit(121);
|
||||
}
|
||||
|
||||
void logVerbose(const char* msg) {
|
||||
ALOGV("%s", msg);
|
||||
}
|
||||
|
||||
void logDebug(const char* msg) {
|
||||
ALOGD("%s", msg);
|
||||
}
|
||||
|
||||
void logInfo(const char* msg) {
|
||||
ALOGI("%s", msg);
|
||||
}
|
||||
|
||||
void logWarn(const char* msg) {
|
||||
ALOGW("%s", msg);
|
||||
}
|
||||
|
||||
void logError(const char* msg) {
|
||||
ALOGE("%s", msg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#include <fstream>
|
||||
|
|
@ -37,7 +39,26 @@ int loadProg(const char* elfPath, bool* isCritical, const Location &location = {
|
|||
// Exposed for testing
|
||||
unsigned int readSectionUint(const char* name, std::ifstream& elfFile, unsigned int defVal);
|
||||
|
||||
int legacyBpfLoader(int argc, char** argv, char * const envp[]);
|
||||
|
||||
} // namespace bpf
|
||||
} // namespace android
|
||||
|
||||
extern "C" {
|
||||
#else // __cplusplus
|
||||
#define __noreturn
|
||||
#endif // __cplusplus
|
||||
|
||||
// The C++ portion of the BpfLoader is exposed as 3 functions to be called in order.
|
||||
void initLogging();
|
||||
void legacyBpfLoader();
|
||||
__noreturn void execNetBpfLoadDone();
|
||||
|
||||
// For logging from rust
|
||||
void logVerbose(const char* msg);
|
||||
void logDebug(const char* msg);
|
||||
void logInfo(const char* msg);
|
||||
void logWarn(const char* msg);
|
||||
void logError(const char* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern C
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue