Merge "split first stage init into a separate executable"
diff --git a/init/Android.bp b/init/Android.bp
index d42ab8a..84a78e2 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -92,6 +92,7 @@
 
 cc_library_static {
     name: "libinit",
+    recovery_available: true,
     defaults: ["init_defaults"],
     srcs: [
         "action.cpp",
@@ -107,7 +108,6 @@
         "first_stage_mount.cpp",
         "import_parser.cpp",
         "init.cpp",
-        "init_first_stage.cpp",
         "keychords.cpp",
         "modalias_handler.cpp",
         "parser.cpp",
@@ -138,29 +138,21 @@
     },
 }
 
-/*
-This is not yet ready, see the below TODOs for what is missing
-
 cc_binary {
-    // TODO: Missing,
-    //LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
-    //LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
-
-    name: "init",
+    name: "init_second_stage",
+    recovery_available: true,
+    stem: "init",
     defaults: ["init_defaults"],
+    static_libs: ["libinit"],
     required: [
         "e2fsdroid",
         "mke2fs",
         "sload_f2fs",
         "make_f2fs",
     ],
-    static_executable: true,
     srcs: ["main.cpp"],
-    symlinks: [
-        "sbin/ueventd",
-    ],
+    symlinks: ["ueventd"],
 }
-*/
 
 // Tests
 // ------------------------------------------------------------------------------
diff --git a/init/Android.mk b/init/Android.mk
index 9d9d368..d20509b 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -41,35 +41,35 @@
 
 include $(CLEAR_VARS)
 LOCAL_CPPFLAGS := $(init_cflags)
-LOCAL_SRC_FILES := main.cpp
+LOCAL_SRC_FILES := \
+    devices.cpp \
+    first_stage_mount.cpp \
+    init_first_stage.cpp \
+    reboot_utils.cpp \
+    selinux.cpp \
+    uevent_listener.cpp \
+    util.cpp \
 
-LOCAL_MODULE:= init
+LOCAL_MODULE := init
+
+LOCAL_FORCE_STATIC_EXECUTABLE := true
 
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
 
 LOCAL_STATIC_LIBRARIES := \
-    libinit \
-    libbootloader_message \
     libfs_mgr \
     libfec \
     libfec_rs \
-    libhidl-gen-utils \
     libsquashfs_utils \
     liblogwrap \
     libext4_utils \
     libseccomp_policy \
     libcrypto_utils \
     libsparse \
-    libprocessgroup \
     libavb \
     libkeyutils \
-    libprotobuf-cpp-lite \
-    libpropertyinfoserializer \
-    libpropertyinfoparser \
     liblp \
-
-shared_libs := \
     libcutils \
     libbase \
     liblog \
@@ -77,27 +77,11 @@
     libdl \
     libz \
     libselinux \
-
-ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-# init is static executable for non-system-as-root devices, because the dynamic linker
-# and shared libs are not available before /system is mounted, but init has to run
-# before the partition is mounted.
-LOCAL_STATIC_LIBRARIES += $(shared_libs) libc++_static
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-else
-LOCAL_SHARED_LIBRARIES := $(shared_libs) libc++
-endif
-shared_libs :=
+    libcap \
 
 LOCAL_REQUIRED_MODULES := \
-    e2fsdroid \
-    mke2fs \
-    sload_f2fs \
-    make_f2fs \
-
-# Create symlinks.
-LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
-    ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
+    init_second_stage \
+    init_second_stage.recovery \
 
 LOCAL_SANITIZE := signed-integer-overflow
 include $(BUILD_EXECUTABLE)
diff --git a/init/init.cpp b/init/init.cpp
index ad80c98..b550f1b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -565,8 +565,6 @@
     android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
 }
 
-int first_stage_main(int argc, char** argv);
-
 int main(int argc, char** argv) {
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
@@ -578,10 +576,6 @@
         return SubcontextMain(argc, argv, &function_map);
     }
 
-    if (getenv("INIT_SECOND_STAGE") == nullptr) {
-        return first_stage_main(argc, argv);
-    }
-
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
     }
@@ -617,7 +611,6 @@
     if (avb_version) property_set("ro.boot.avb_version", avb_version);
 
     // Clean up our environment.
-    unsetenv("INIT_SECOND_STAGE");
     unsetenv("INIT_STARTED_AT");
     unsetenv("INIT_SELINUX_TOOK");
     unsetenv("INIT_AVB_VERSION");
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index ef9ce81..b367f2a 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -51,7 +51,7 @@
     });
 }
 
-int first_stage_main(int argc, char** argv) {
+int main(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
     }
@@ -141,17 +141,15 @@
     // Unneeded?  It's an ext4 file system so shouldn't it have the right domain already?
     // We're in the kernel domain, so re-exec init to transition to the init domain now
     // that the SELinux policy has been loaded.
-    if (selinux_android_restorecon("/init", 0) == -1) {
-        PLOG(FATAL) << "restorecon failed of /init failed";
+    if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
+        PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
     }
 
-    setenv("INIT_SECOND_STAGE", "true", 1);
-
     static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
     uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
     setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
 
-    const char* path = argv[0];
+    const char* path = "/system/bin/init";
     const char* args[] = {path, nullptr};
     execv(path, const_cast<char**>(args));
 
@@ -164,3 +162,7 @@
 
 }  // namespace init
 }  // namespace android
+
+int main(int argc, char** argv) {
+    return android::init::main(argc, argv);
+}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 486d096..ca8655f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -732,7 +732,7 @@
 
 ## Daemon processes to be run by init.
 ##
-service ueventd /sbin/ueventd
+service ueventd /system/bin/ueventd
     class core
     critical
     seclabel u:r:ueventd:s0