Merge "Refactorings to match adb_abb to adb_shell code."
diff --git a/init/Android.bp b/init/Android.bp
index 6bc581d..86dcb4c 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -26,6 +26,7 @@
"-Wextra",
"-Wno-unused-parameter",
"-Werror",
+ "-DALLOW_FIRST_STAGE_CONSOLE=0",
"-DALLOW_LOCAL_PROP_OVERRIDE=0",
"-DALLOW_PERMISSIVE_SELINUX=0",
"-DREBOOT_BOOTLOADER_ON_PANIC=0",
@@ -36,6 +37,8 @@
product_variables: {
debuggable: {
cppflags: [
+ "-UALLOW_FIRST_STAGE_CONSOLE",
+ "-DALLOW_FIRST_STAGE_CONSOLE=1",
"-UALLOW_LOCAL_PROP_OVERRIDE",
"-DALLOW_LOCAL_PROP_OVERRIDE=1",
"-UALLOW_PERMISSIVE_SELINUX",
diff --git a/init/Android.mk b/init/Android.mk
index b24f757..9017772 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -8,6 +8,7 @@
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += \
+ -DALLOW_FIRST_STAGE_CONSOLE=1 \
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
@@ -15,6 +16,7 @@
-DDUMP_ON_UMOUNT_FAILURE=1
else
init_options += \
+ -DALLOW_FIRST_STAGE_CONSOLE=0 \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=0 \
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 17387e2..36eece8 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -24,10 +24,12 @@
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <filesystem>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/chrono_utils.h>
@@ -92,9 +94,50 @@
}
}
-bool ForceNormalBoot() {
- std::string cmdline;
- android::base::ReadFileToString("/proc/cmdline", &cmdline);
+void StartConsole() {
+ if (mknod("/dev/console", S_IFCHR | 0600, makedev(5, 1))) {
+ PLOG(ERROR) << "unable to create /dev/console";
+ return;
+ }
+ pid_t pid = fork();
+ if (pid != 0) {
+ int status;
+ waitpid(pid, &status, 0);
+ LOG(ERROR) << "console shell exited with status " << status;
+ return;
+ }
+ int fd = -1;
+ int tries = 10;
+ // The device driver for console may not be ready yet so retry for a while in case of failure.
+ while (tries--) {
+ fd = open("/dev/console", O_RDWR);
+ if (fd != -1) {
+ break;
+ }
+ std::this_thread::sleep_for(100ms);
+ }
+ if (fd == -1) {
+ LOG(ERROR) << "Could not open /dev/console, errno = " << errno;
+ _exit(127);
+ }
+ ioctl(fd, TIOCSCTTY, 0);
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
+
+ const char* path = "/system/bin/sh";
+ const char* args[] = {path, nullptr};
+ int rv = execv(path, const_cast<char**>(args));
+ LOG(ERROR) << "unable to execv, returned " << rv << " errno " << errno;
+ _exit(127);
+}
+
+bool FirstStageConsole(const std::string& cmdline) {
+ return cmdline.find("androidboot.first_stage_console=1") != std::string::npos;
+}
+
+bool ForceNormalBoot(const std::string& cmdline) {
return cmdline.find("androidboot.force_normal_boot=1") != std::string::npos;
}
@@ -127,6 +170,8 @@
#undef MAKE_STR
// Don't expose the raw commandline to unprivileged processes.
CHECKCALL(chmod("/proc/cmdline", 0440));
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
@@ -198,7 +243,11 @@
LOG(FATAL) << "Failed to load kernel modules";
}
- if (ForceNormalBoot()) {
+ if (ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline)) {
+ StartConsole();
+ }
+
+ if (ForceNormalBoot(cmdline)) {
mkdir("/first_stage_ramdisk", 0755);
// SwitchRoot() must be called with a mount point as the target, so we bind mount the
// target directory to itself here.
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index caf6e86..a8b43c1 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -312,12 +312,12 @@
cur_page * sizeof(uint64_t));
if (bytes != total_bytes) {
if (bytes == -1) {
- PLOG(ERROR) << "Failed to read page data at offset "
+ PLOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
<< cur_page * sizeof(uint64_t);
} else {
- LOG(ERROR) << "Failed to read page data at offset "
- << cur_page * sizeof(uint64_t) << " read bytes " << sizeof(uint64_t)
- << " expected bytes " << bytes;
+ LOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
+ << cur_page * sizeof(uint64_t) << std::dec << " read bytes " << bytes
+ << " expected bytes " << total_bytes;
}
return false;
}