resolve merge conflicts of 66277db to stage-aosp-master
am: 23a574a195

Change-Id: Id3e18ffa3a9e40755bd65bfbab79f79a7f8373a0
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 63cc3bc..70f3cde 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -36,6 +36,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <linux/loop.h>
+#include <linux/module.h>
 #include <ext4_crypt.h>
 #include <ext4_crypt_init_extensions.h>
 
@@ -45,6 +46,7 @@
 #include <fs_mgr.h>
 #include <android-base/file.h>
 #include <android-base/parseint.h>
+#include <android-base/strings.h>
 #include <android-base/stringprintf.h>
 #include <bootloader_message_writer.h>
 #include <cutils/partition_utils.h>
@@ -68,13 +70,13 @@
 
 static const int kTerminateServiceDelayMicroSeconds = 50000;
 
-static int insmod(const char *filename, const char *options) {
+static int insmod(const char *filename, const char *options, int flags) {
     int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
     if (fd == -1) {
         ERROR("insmod: open(\"%s\") failed: %s", filename, strerror(errno));
         return -1;
     }
-    int rc = syscall(__NR_finit_module, fd, options, 0);
+    int rc = syscall(__NR_finit_module, fd, options, flags);
     if (rc == -1) {
         ERROR("finit_module for \"%s\" failed: %s", filename, strerror(errno));
     }
@@ -282,17 +284,17 @@
 }
 
 static int do_insmod(const std::vector<std::string>& args) {
-    std::string options;
+    int flags = 0;
+    auto it = args.begin() + 1;
 
-    if (args.size() > 2) {
-        options += args[2];
-        for (std::size_t i = 3; i < args.size(); ++i) {
-            options += ' ';
-            options += args[i];
-        }
+    if (!(*it).compare("-f")) {
+        flags = MODULE_INIT_IGNORE_VERMAGIC | MODULE_INIT_IGNORE_MODVERSIONS;
+        it++;
     }
 
-    return insmod(args[1].c_str(), options.c_str());
+    std::string filename = *it++;
+    std::string options = android::base::Join(std::vector<std::string>(it, args.end()), ' ');
+    return insmod(filename.c_str(), options.c_str(), flags);
 }
 
 static int do_mkdir(const std::vector<std::string>& args) {
diff --git a/init/readme.txt b/init/readme.txt
index 8130806..e75b4b2 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -281,8 +281,11 @@
 ifup <interface>
    Bring the network interface <interface> online.
 
-insmod <path>
-   Install the module at <path>
+insmod [-f] <path> [<options>]
+   Install the module at <path> with the specified options.
+   -f
+   Force installation of the module even if the version of the running kernel
+   and the version of the kernel for which the module was compiled do not match.
 
 load_all_props
    Loads properties from /system, /vendor, et cetera.