BpfLoader: split bpffs subdir creation out

Needs to be before program loading, this should eventually allow loading programs in parallel.

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I95933a5ffbe2230c19d0f91c167e1256ea2f3713
diff --git a/loader/Loader.cpp b/loader/Loader.cpp
index 341a9c3..ac3d39d 100644
--- a/loader/Loader.cpp
+++ b/loader/Loader.cpp
@@ -973,18 +973,25 @@
     android::base::InitLogging(const_cast<char**>(argv), &android::base::KernelLogger);
 }
 
+void createBpfFsSubDirectories() {
+    for (const auto& location : android::bpf::locations) {
+        if (android::bpf::createSysFsBpfSubDir(location.prefix)) {
+            exit(120);
+        }
+    }
+}
+
 void legacyBpfLoader() {
     // Load all ELF objects, create programs and maps, and pin them
     for (const auto& location : android::bpf::locations) {
-        if (android::bpf::createSysFsBpfSubDir(location.prefix) ||
-            android::bpf::loadAllElfObjects(location)) {
+        if (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);
-            exit(120);
+            exit(121);
         }
     }
 }
@@ -993,7 +1000,7 @@
     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);
+    exit(122);
 }
 
 void logVerbose(const char* msg) {
diff --git a/loader/bpfloader.rs b/loader/bpfloader.rs
index 0cd5e0e..b934d98 100644
--- a/loader/bpfloader.rs
+++ b/loader/bpfloader.rs
@@ -18,10 +18,11 @@
 
 fn main() {
     // SAFETY: Linking in the existing legacy bpfloader functionality.
-    // Any of the three following bindgen functions can abort() or exit()
+    // Any of the four following bindgen functions can abort() or exit()
     // on failure and execNetBpfLoadDone() execve()'s.
     unsafe {
         bpf_android_bindgen::initLogging();
+        bpf_android_bindgen::createBpfFsSubDirectories();
         bpf_android_bindgen::legacyBpfLoader();
         bpf_android_bindgen::execNetBpfLoadDone();
     }
diff --git a/loader/include/libbpf_android.h b/loader/include/libbpf_android.h
index fbdae6f..8e5a887 100644
--- a/loader/include/libbpf_android.h
+++ b/loader/include/libbpf_android.h
@@ -49,6 +49,7 @@
 
 // The C++ portion of the BpfLoader is exposed as 3 functions to be called in order.
 void initLogging();
+void createBpfFsSubDirectories();
 void legacyBpfLoader();
 __noreturn void execNetBpfLoadDone();