Move linker config under /linkerconfig

Currently linker config locates under /dev, but this makes some problem
in case of using two system partitions with chroot. To match system
image and configuration, linker config better stays under /linkerconfig

Bug: 144966380
Test: m -j passed && tested from cuttelfish
Change-Id: Iaae5af65721eee8106311c1efb4760a9db13564a
diff --git a/init/init.cpp b/init/init.cpp
index 6ba64ee..5f97e44 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -512,10 +512,24 @@
 
 static void UmountDebugRamdisk() {
     if (umount("/debug_ramdisk") != 0) {
-        LOG(ERROR) << "Failed to umount /debug_ramdisk";
+        PLOG(ERROR) << "Failed to umount /debug_ramdisk";
     }
 }
 
+static void MountExtraFilesystems() {
+#define CHECKCALL(x) \
+    if ((x) != 0) PLOG(FATAL) << #x " failed.";
+
+    // /apex is used to mount APEXes
+    CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+                    "mode=0755,uid=0,gid=0"));
+
+    // /linkerconfig is used to keep generated linker configuration
+    CHECKCALL(mount("tmpfs", "/linkerconfig", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+                    "mode=0755,uid=0,gid=0"));
+#undef CHECKCALL
+}
+
 static void RecordStageBoottimes(const boot_clock::time_point& second_stage_start_time) {
     int64_t first_stage_start_time_ns = -1;
     if (auto first_stage_start_time_str = getenv(kEnvFirstStageStartedAt);
@@ -656,6 +670,9 @@
         UmountDebugRamdisk();
     }
 
+    // Mount extra filesystems required during second stage init
+    MountExtraFilesystems();
+
     // Now set up SELinux for second stage.
     SelinuxSetupKernelLogging();
     SelabelInitialize();