Merge changes from topic "modprobe-pgsize-fix" into main am: 0cb931b1ce am: e8d6ed0547

Original change: https://android-review.googlesource.com/c/platform/system/core/+/3110063

Change-Id: I1d2e30a5d6fd96f26fda48a8a0502a499ea0d3a1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/toolbox/modprobe.cpp b/toolbox/modprobe.cpp
index b0e76ea..7fde491 100644
--- a/toolbox/modprobe.cpp
+++ b/toolbox/modprobe.cpp
@@ -15,9 +15,9 @@
  */
 
 #include <ctype.h>
-#include <fcntl.h>
 #include <getopt.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <string>
 
@@ -28,7 +28,6 @@
 #include <modprobe/modprobe.h>
 
 #include <sys/utsname.h>
-#include <unistd.h>
 
 namespace {
 
@@ -87,6 +86,20 @@
     }
 }
 
+static bool ModDirMatchesKernelPageSize(const char* mod_dir) {
+    static const unsigned int kernel_pgsize_kb = getpagesize() / 1024;
+    const char* mod_sfx = strrchr(mod_dir, '_');
+    unsigned int mod_pgsize_kb;
+    int mod_sfx_len;
+
+    if (mod_sfx == NULL || sscanf(mod_sfx, "_%uk%n", &mod_pgsize_kb, &mod_sfx_len) != 1 ||
+        strlen(mod_sfx) != mod_sfx_len) {
+        mod_pgsize_kb = 4;
+    }
+
+    return kernel_pgsize_kb == mod_pgsize_kb;
+}
+
 // Find directories in format of "/lib/modules/x.y.z-*".
 static int KernelVersionNameFilter(const dirent* de) {
     unsigned int major, minor;
@@ -102,16 +115,11 @@
     }
 
     if (android::base::StartsWith(de->d_name, kernel_version)) {
-        return 1;
+        return ModDirMatchesKernelPageSize(de->d_name);
     }
     return 0;
 }
 
-std::string GetPageSizeSuffix() {
-    static const size_t page_size = sysconf(_SC_PAGE_SIZE);
-    return android::base::StringPrintf("_%zuk", page_size / 1024);
-}
-
 }  // anonymous namespace
 
 extern "C" int modprobe_main(int argc, char** argv) {
@@ -240,19 +248,6 @@
         // Allow modules to be directly inside /lib/modules
         mod_dirs.emplace_back(LIB_MODULES_PREFIX);
     }
-    if (getpagesize() != 4096) {
-        struct utsname uts {};
-        if (uname(&uts)) {
-            PLOG(FATAL) << "Failed to get kernel version";
-        }
-        const auto module_dir = android::base::StringPrintf("/lib/modules/%s%s", uts.release,
-                                                            GetPageSizeSuffix().c_str());
-        struct stat st {};
-        if (stat(module_dir.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
-            mod_dirs.clear();
-            mod_dirs.emplace_back(module_dir);
-        }
-    }
 
     LOG(DEBUG) << "mode is " << mode;
     LOG(DEBUG) << "mod_dirs is: " << android::base::Join(mod_dirs, " ");