diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/Android.bp | 22 | ||||
-rw-r--r-- | init/Android.mk | 30 | ||||
-rw-r--r-- | init/init.cpp | 52 | ||||
-rw-r--r-- | init/parser.cpp | 24 |
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 { | |||
166 | cc_test { | 168 | cc_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 | ||
188 | cc_benchmark { | 189 | cc_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 | ||
46 | LOCAL_MODULE:= init | 46 | LOCAL_MODULE:= init |
47 | 47 | ||
48 | LOCAL_FORCE_STATIC_EXECUTABLE := true | ||
49 | LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) | 48 | LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) |
50 | LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) | 49 | LOCAL_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 | ||
72 | shared_libs := \ | ||
73 | libcutils \ | ||
74 | libbase \ | ||
75 | liblog \ | ||
76 | libcrypto \ | ||
77 | libdl \ | ||
78 | libz \ | ||
79 | |||
80 | ifneq ($(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. | ||
84 | LOCAL_STATIC_LIBRARIES += $(shared_libs) libc++_static | ||
85 | LOCAL_FORCE_STATIC_EXECUTABLE := true | ||
86 | else | ||
87 | LOCAL_SHARED_LIBRARIES := $(shared_libs) libc++ | ||
88 | endif | ||
89 | shared_libs := | ||
90 | |||
81 | LOCAL_REQUIRED_MODULES := \ | 91 | LOCAL_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; |