summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Android.bp22
-rw-r--r--init/Android.mk30
-rw-r--r--init/init.cpp52
-rw-r--r--init/parser.cpp24
4 files changed, 76 insertions, 52 deletions
diff --git a/init/Android.bp b/init/Android.bp
index 25877c083..7d863c884 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -67,24 +67,26 @@ cc_defaults {
67 "libsquashfs_utils", 67 "libsquashfs_utils",
68 "liblogwrap", 68 "liblogwrap",
69 "libext4_utils", 69 "libext4_utils",
70 "libcutils",
71 "libbase",
72 "libc",
73 "libseccomp_policy", 70 "libseccomp_policy",
74 "libselinux",
75 "liblog",
76 "libcrypto_utils", 71 "libcrypto_utils",
77 "libcrypto",
78 "libc++_static",
79 "libdl",
80 "libsparse", 72 "libsparse",
81 "libz",
82 "libprocessgroup", 73 "libprocessgroup",
83 "libavb", 74 "libavb",
84 "libkeyutils", 75 "libkeyutils",
85 "libprotobuf-cpp-lite", 76 "libprotobuf-cpp-lite",
86 "libpropertyinfoserializer", 77 "libpropertyinfoserializer",
87 "libpropertyinfoparser", 78 "libpropertyinfoparser",
79 "libselinux",
80 ],
81 shared_libs: [
82 "libcutils",
83 "libbase",
84 "libc",
85 "liblog",
86 "libcrypto",
87 "libc++",
88 "libdl",
89 "libz",
88 ], 90 ],
89} 91}
90 92
@@ -166,7 +168,6 @@ cc_binary {
166cc_test { 168cc_test {
167 name: "init_tests", 169 name: "init_tests",
168 defaults: ["init_defaults"], 170 defaults: ["init_defaults"],
169 static_executable: true,
170 srcs: [ 171 srcs: [
171 "devices_test.cpp", 172 "devices_test.cpp",
172 "init_test.cpp", 173 "init_test.cpp",
@@ -187,7 +188,6 @@ cc_test {
187 188
188cc_benchmark { 189cc_benchmark {
189 name: "init_benchmarks", 190 name: "init_benchmarks",
190 static_executable: true,
191 defaults: ["init_defaults"], 191 defaults: ["init_defaults"],
192 srcs: [ 192 srcs: [
193 "subcontext_benchmark.cpp", 193 "subcontext_benchmark.cpp",
diff --git a/init/Android.mk b/init/Android.mk
index c4a6a50e5..da27a73f4 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -45,7 +45,6 @@ LOCAL_SRC_FILES := main.cpp
45 45
46LOCAL_MODULE:= init 46LOCAL_MODULE:= init
47 47
48LOCAL_FORCE_STATIC_EXECUTABLE := true
49LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) 48LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
50LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) 49LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
51 50
@@ -59,18 +58,10 @@ LOCAL_STATIC_LIBRARIES := \
59 libsquashfs_utils \ 58 libsquashfs_utils \
60 liblogwrap \ 59 liblogwrap \
61 libext4_utils \ 60 libext4_utils \
62 libcutils \
63 libbase \
64 libc \
65 libseccomp_policy \ 61 libseccomp_policy \
66 libselinux \
67 liblog \
68 libcrypto_utils \ 62 libcrypto_utils \
69 libcrypto \
70 libc++_static \
71 libdl \
72 libsparse \ 63 libsparse \
73 libz \ 64 libselinux \
74 libprocessgroup \ 65 libprocessgroup \
75 libavb \ 66 libavb \
76 libkeyutils \ 67 libkeyutils \
@@ -78,6 +69,25 @@ LOCAL_STATIC_LIBRARIES := \
78 libpropertyinfoserializer \ 69 libpropertyinfoserializer \
79 libpropertyinfoparser \ 70 libpropertyinfoparser \
80 71
72shared_libs := \
73 libcutils \
74 libbase \
75 liblog \
76 libcrypto \
77 libdl \
78 libz \
79
80ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
81# init is static executable for non-system-as-root devices, because the dynamic linker
82# and shared libs are not available before /system is mounted, but init has to run
83# before the partition is mounted.
84LOCAL_STATIC_LIBRARIES += $(shared_libs) libc++_static
85LOCAL_FORCE_STATIC_EXECUTABLE := true
86else
87LOCAL_SHARED_LIBRARIES := $(shared_libs) libc++
88endif
89shared_libs :=
90
81LOCAL_REQUIRED_MODULES := \ 91LOCAL_REQUIRED_MODULES := \
82 e2fsdroid \ 92 e2fsdroid \
83 mke2fs \ 93 mke2fs \
diff --git a/init/init.cpp b/init/init.cpp
index 82648d991..b494bcc09 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -604,47 +604,61 @@ int main(int argc, char** argv) {
604 if (is_first_stage) { 604 if (is_first_stage) {
605 boot_clock::time_point start_time = boot_clock::now(); 605 boot_clock::time_point start_time = boot_clock::now();
606 606
607 std::vector<std::pair<std::string, int>> errors;
608#define CHECKCALL(x) \
609 if (x != 0) errors.emplace_back(#x " failed", errno);
610
607 // Clear the umask. 611 // Clear the umask.
608 umask(0); 612 umask(0);
609 613
610 clearenv(); 614 CHECKCALL(clearenv());
611 setenv("PATH", _PATH_DEFPATH, 1); 615 CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
612 // Get the basic filesystem setup we need put together in the initramdisk 616 // Get the basic filesystem setup we need put together in the initramdisk
613 // on / and then we'll let the rc file figure out the rest. 617 // on / and then we'll let the rc file figure out the rest.
614 mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); 618 CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
615 mkdir("/dev/pts", 0755); 619 CHECKCALL(mkdir("/dev/pts", 0755));
616 mkdir("/dev/socket", 0755); 620 CHECKCALL(mkdir("/dev/socket", 0755));
617 mount("devpts", "/dev/pts", "devpts", 0, NULL); 621 CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
618 #define MAKE_STR(x) __STRING(x) 622#define MAKE_STR(x) __STRING(x)
619 mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)); 623 CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));
624#undef MAKE_STR
620 // Don't expose the raw commandline to unprivileged processes. 625 // Don't expose the raw commandline to unprivileged processes.
621 chmod("/proc/cmdline", 0440); 626 CHECKCALL(chmod("/proc/cmdline", 0440));
622 gid_t groups[] = { AID_READPROC }; 627 gid_t groups[] = { AID_READPROC };
623 setgroups(arraysize(groups), groups); 628 CHECKCALL(setgroups(arraysize(groups), groups));
624 mount("sysfs", "/sys", "sysfs", 0, NULL); 629 CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
625 mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL); 630 CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));
626 631
627 mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)); 632 CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));
628 633
629 if constexpr (WORLD_WRITABLE_KMSG) { 634 if constexpr (WORLD_WRITABLE_KMSG) {
630 mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)); 635 CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));
631 } 636 }
632 637
633 mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)); 638 CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
634 mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)); 639 CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
635 640
636 // Mount staging areas for devices managed by vold 641 // Mount staging areas for devices managed by vold
637 // See storage config details at http://source.android.com/devices/storage/ 642 // See storage config details at http://source.android.com/devices/storage/
638 mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, 643 CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
639 "mode=0755,uid=0,gid=1000"); 644 "mode=0755,uid=0,gid=1000"));
640 // /mnt/vendor is used to mount vendor-specific partitions that can not be 645 // /mnt/vendor is used to mount vendor-specific partitions that can not be
641 // part of the vendor partition, e.g. because they are mounted read-write. 646 // part of the vendor partition, e.g. because they are mounted read-write.
642 mkdir("/mnt/vendor", 0755); 647 CHECKCALL(mkdir("/mnt/vendor", 0755));
648
649#undef CHECKCALL
643 650
644 // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually 651 // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
645 // talk to the outside world... 652 // talk to the outside world...
646 InitKernelLogging(argv); 653 InitKernelLogging(argv);
647 654
655 if (!errors.empty()) {
656 for (const auto& [error_string, error_errno] : errors) {
657 LOG(ERROR) << error_string << " " << strerror(error_errno);
658 }
659 LOG(FATAL) << "Init encountered errors starting first stage, aborting";
660 }
661
648 LOG(INFO) << "init first stage started!"; 662 LOG(INFO) << "init first stage started!";
649 663
650 if (!DoFirstStageMount()) { 664 if (!DoFirstStageMount()) {
diff --git a/init/parser.cpp b/init/parser.cpp
index ee6ee06db..4f1cac495 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -70,24 +70,23 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
70 case T_EOF: 70 case T_EOF:
71 end_section(); 71 end_section();
72 return; 72 return;
73 case T_NEWLINE: 73 case T_NEWLINE: {
74 state.line++; 74 state.line++;
75 if (args.empty()) break; 75 if (args.empty()) break;
76 // If we have a line matching a prefix we recognize, call its callback and unset any 76 // If we have a line matching a prefix we recognize, call its callback and unset any
77 // current section parsers. This is meant for /sys/ and /dev/ line entries for 77 // current section parsers. This is meant for /sys/ and /dev/ line entries for
78 // uevent. 78 // uevent.
79 for (const auto& [prefix, callback] : line_callbacks_) { 79 auto line_callback = std::find_if(
80 if (android::base::StartsWith(args[0], prefix)) { 80 line_callbacks_.begin(), line_callbacks_.end(),
81 end_section(); 81 [&args](const auto& c) { return android::base::StartsWith(args[0], c.first); });
82 82 if (line_callback != line_callbacks_.end()) {
83 if (auto result = callback(std::move(args)); !result) { 83 end_section();
84 parse_error_count_++; 84
85 LOG(ERROR) << filename << ": " << state.line << ": " << result.error(); 85 if (auto result = line_callback->second(std::move(args)); !result) {
86 } 86 parse_error_count_++;
87 break; 87 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
88 } 88 }
89 } 89 } else if (section_parsers_.count(args[0])) {
90 if (section_parsers_.count(args[0])) {
91 end_section(); 90 end_section();
92 section_parser = section_parsers_[args[0]].get(); 91 section_parser = section_parsers_[args[0]].get();
93 section_start_line = state.line; 92 section_start_line = state.line;
@@ -111,6 +110,7 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
111 } 110 }
112 args.clear(); 111 args.clear();
113 break; 112 break;
113 }
114 case T_TEXT: 114 case T_TEXT:
115 args.emplace_back(state.text); 115 args.emplace_back(state.text);
116 break; 116 break;