Merge "Add test of undefined return address."
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 01d8867..17d63fa 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -69,19 +69,24 @@
return {};
}
-Result<void> Epoll::Wait(std::optional<std::chrono::milliseconds> timeout) {
+Result<std::vector<std::function<void()>*>> Epoll::Wait(
+ std::optional<std::chrono::milliseconds> timeout) {
int timeout_ms = -1;
if (timeout && timeout->count() < INT_MAX) {
timeout_ms = timeout->count();
}
- epoll_event ev;
- auto nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, &ev, 1, timeout_ms));
- if (nr == -1) {
+ const auto max_events = epoll_handlers_.size();
+ epoll_event ev[max_events];
+ auto num_events = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd_, ev, max_events, timeout_ms));
+ if (num_events == -1) {
return ErrnoError() << "epoll_wait failed";
- } else if (nr == 1) {
- std::invoke(*reinterpret_cast<std::function<void()>*>(ev.data.ptr));
}
- return {};
+ std::vector<std::function<void()>*> pending_functions;
+ for (int i = 0; i < num_events; ++i) {
+ pending_functions.emplace_back(reinterpret_cast<std::function<void()>*>(ev[i].data.ptr));
+ }
+
+ return pending_functions;
}
} // namespace init
diff --git a/init/epoll.h b/init/epoll.h
index ca84266..c32a661 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _INIT_EPOLL_H
-#define _INIT_EPOLL_H
+#pragma once
#include <stdint.h>
#include <sys/epoll.h>
@@ -24,6 +23,7 @@
#include <functional>
#include <map>
#include <optional>
+#include <vector>
#include <android-base/unique_fd.h>
@@ -39,7 +39,8 @@
Result<void> Open();
Result<void> RegisterHandler(int fd, std::function<void()> handler, uint32_t events = EPOLLIN);
Result<void> UnregisterHandler(int fd);
- Result<void> Wait(std::optional<std::chrono::milliseconds> timeout);
+ Result<std::vector<std::function<void()>*>> Wait(
+ std::optional<std::chrono::milliseconds> timeout);
private:
android::base::unique_fd epoll_fd_;
@@ -48,5 +49,3 @@
} // namespace init
} // namespace android
-
-#endif
diff --git a/init/init.cpp b/init/init.cpp
index ce898de..d4cbb5f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -787,8 +787,17 @@
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}
- if (auto result = epoll.Wait(epoll_timeout); !result) {
- LOG(ERROR) << result.error();
+ auto pending_functions = epoll.Wait(epoll_timeout);
+ if (!pending_functions) {
+ LOG(ERROR) << pending_functions.error();
+ } else if (!pending_functions->empty()) {
+ // We always reap children before responding to the other pending functions. This is to
+ // prevent a race where other daemons see that a service has exited and ask init to
+ // start it again via ctl.start before init has reaped it.
+ ReapAnyOutstandingChildren();
+ for (const auto& function : *pending_functions) {
+ (*function)();
+ }
}
}
diff --git a/init/keychords_test.cpp b/init/keychords_test.cpp
index 33373d4..6e9b337 100644
--- a/init/keychords_test.cpp
+++ b/init/keychords_test.cpp
@@ -212,7 +212,11 @@
}
void TestFrame::RelaxForMs(std::chrono::milliseconds wait) {
- epoll_.Wait(wait);
+ auto pending_functions = epoll_.Wait(wait);
+ ASSERT_TRUE(pending_functions) << pending_functions.error();
+ for (const auto& function : *pending_functions) {
+ (*function)();
+ }
}
void TestFrame::SetChord(int key, bool value) {
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index 12144c1..0745148 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -91,22 +91,22 @@
return false;
}
- // Special casing for the runtime APEX
- constexpr const char kRuntimeApexMountPath[] = "/system/apex/com.android.runtime";
- static const std::vector<std::string> kRuntimeApexDirNames = {"com.android.runtime.release",
- "com.android.runtime.debug"};
+ // Special casing for the ART APEX
+ constexpr const char kArtApexMountPath[] = "/system/apex/com.android.art";
+ static const std::vector<std::string> kArtApexDirNames = {"com.android.art.release",
+ "com.android.art.debug"};
bool success = false;
- for (const auto& name : kRuntimeApexDirNames) {
+ for (const auto& name : kArtApexDirNames) {
std::string path = std::string(kSystemApex) + "/" + name;
if (access(path.c_str(), F_OK) == 0) {
- if (mount(path.c_str(), kRuntimeApexMountPath, nullptr, MS_BIND, nullptr) == 0) {
+ if (mount(path.c_str(), kArtApexMountPath, nullptr, MS_BIND, nullptr) == 0) {
success = true;
break;
}
}
}
if (!success) {
- PLOG(ERROR) << "Failed to bind mount the runtime APEX to " << kRuntimeApexMountPath;
+ PLOG(ERROR) << "Failed to bind mount the ART APEX to " << kArtApexMountPath;
}
return success;
}
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 6842820..4852cd0 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -439,7 +439,8 @@
bool is_enforcing = IsEnforcing();
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {
- PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
+ PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false")
+ << ") failed";
}
}
diff --git a/init/service.cpp b/init/service.cpp
index 9537843..7a20966 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -116,9 +116,10 @@
return execv(c_strings[0], c_strings.data()) == 0;
}
-static bool IsRuntimeApexReady() {
+static bool AreRuntimeApexesReady() {
struct stat buf;
- return stat("/apex/com.android.runtime/", &buf) == 0;
+ return stat("/apex/com.android.art/", &buf) == 0 &&
+ stat("/apex/com.android.runtime/", &buf) == 0;
}
unsigned long Service::next_start_order_ = 1;
@@ -406,11 +407,11 @@
scon = *result;
}
- if (!IsRuntimeApexReady() && !pre_apexd_) {
- // If this service is started before the runtime APEX gets available,
- // mark it as pre-apexd one. Note that this marking is permanent. So
- // for example, if the service is re-launched (e.g., due to crash),
- // it is still recognized as pre-apexd... for consistency.
+ if (!AreRuntimeApexesReady() && !pre_apexd_) {
+ // If this service is started before the Runtime and ART APEXes get
+ // available, mark it as pre-apexd one. Note that this marking is
+ // permanent. So for example, if the service is re-launched (e.g., due
+ // to crash), it is still recognized as pre-apexd... for consistency.
pre_apexd_ = true;
}
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 6d3c057..60d462f 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -63,6 +63,10 @@
LOG_ALWAYS_FATAL_IF((dot_index == std::string::npos),
"Error finding namespace of apex: no dot in apex name %s", caller_location);
std::string name = location.substr(dot_index + 1, slash_index - dot_index - 1);
+ // TODO(b/139408016): Rename the runtime namespace to "art".
+ if (name == "art") {
+ name = "runtime";
+ }
android_namespace_t* boot_namespace = android_get_exported_namespace(name.c_str());
LOG_ALWAYS_FATAL_IF((boot_namespace == nullptr),
"Error finding namespace of apex: no namespace called %s", name.c_str());
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index 3694360..93df1d0 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -49,12 +49,12 @@
constexpr const char* kLlndkLibrariesFile = "/system/etc/llndk.libraries.txt";
constexpr const char* kVndkLibrariesFile = "/system/etc/vndksp.libraries.txt";
-const std::vector<const std::string> kRuntimePublicLibraries = {
+const std::vector<const std::string> kArtApexPublicLibraries = {
"libicuuc.so",
"libicui18n.so",
};
-constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/" LIB;
+constexpr const char* kArtApexLibPath = "/apex/com.android.art/" LIB;
constexpr const char* kNeuralNetworksApexPublicLibrary = "libneuralnetworks.so";
@@ -182,8 +182,8 @@
// For example, libicuuc.so is exposed to classloader namespace from runtime namespace.
// Unfortunately, it does not have stable C symbols, and default namespace should only use
// stable symbols in libandroidicu.so. http://b/120786417
- for (const std::string& lib_name : kRuntimePublicLibraries) {
- std::string path(kRuntimeApexLibPath);
+ for (const std::string& lib_name : kArtApexPublicLibraries) {
+ std::string path(kArtApexLibPath);
path.append("/").append(lib_name);
struct stat s;
@@ -207,9 +207,9 @@
return android::base::Join(*sonames, ':');
}
-static std::string InitRuntimePublicLibraries() {
- CHECK(sizeof(kRuntimePublicLibraries) > 0);
- std::string list = android::base::Join(kRuntimePublicLibraries, ":");
+static std::string InitArtPublicLibraries() {
+ CHECK(sizeof(kArtApexPublicLibraries) > 0);
+ std::string list = android::base::Join(kArtApexPublicLibraries, ":");
std::string additional_libs = additional_public_libraries();
if (!additional_libs.empty()) {
@@ -277,7 +277,7 @@
}
const std::string& runtime_public_libraries() {
- static std::string list = InitRuntimePublicLibraries();
+ static std::string list = InitArtPublicLibraries();
return list;
}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 4559050..2fa110b 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -214,7 +214,7 @@
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-# Start of runtime APEX compatibility.
+# Start of i18n and ART APEX compatibility.
#
# Meta-comment:
# The placing of this section is somewhat arbitrary. The LOCAL_POST_INSTALL_CMD
@@ -226,7 +226,7 @@
# come to rely on them.
# http://b/121248172 - create a link from /system/usr/icu to
-# /apex/com.android.runtime/etc/icu so that apps can find the ICU .dat file.
+# /apex/com.android.i18n/etc/icu so that apps can find the ICU .dat file.
# A symlink can't overwrite a directory and the /system/usr/icu directory once
# existed so the required structure must be created whatever we find.
LOCAL_POST_INSTALL_CMD = mkdir -p $(TARGET_OUT)/usr && rm -rf $(TARGET_OUT)/usr/icu
@@ -248,10 +248,10 @@
LOCAL_POST_INSTALL_CMD += && mkdir -p $(TARGET_OUT)/bin
$(foreach b,$(ART_BINARIES), \
$(eval LOCAL_POST_INSTALL_CMD += \
- && ln -sf /apex/com.android.runtime/bin/$(b) $(TARGET_OUT)/bin/$(b)) \
+ && ln -sf /apex/com.android.art/bin/$(b) $(TARGET_OUT)/bin/$(b)) \
)
-# End of runtime APEX compatibilty.
+# End of i18n and ART APEX compatibilty.
ifeq ($(_enforce_vndk_at_runtime),true)
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index f0b1fd2..e598f05 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -85,8 +85,11 @@
# android_link_namespaces in libnativeloader.
namespace.runtime.visible = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# Need allow_all_shared_libs because libart.so can dlopen oat files in
# /system/framework and /data.
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index a603be2..c8c6387 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -166,8 +166,11 @@
# android_link_namespaces in libnativeloader.
namespace.runtime.visible = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# Need allow_all_shared_libs because libart.so can dlopen oat files in
# /system/framework and /data.
@@ -488,8 +491,11 @@
###############################################################################
namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = system
# TODO(b/130340935): Use a dynamically created linker namespace similar to
# classloader-namespace for oat files, and tighten this up.
@@ -695,8 +701,11 @@
# android_link_namespaces in libnativeloader.
namespace.runtime.visible = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# TODO(b/130340935): Use a dynamically created linker namespace similar to
# classloader-namespace for oat files, and tighten this up.
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 2e213ec..4beabd6 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -105,8 +105,11 @@
# android_link_namespaces in libnativeloader.
namespace.runtime.visible = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# Need allow_all_shared_libs because libart.so can dlopen oat files in
# /system/framework and /data.
@@ -419,8 +422,11 @@
###############################################################################
namespace.runtime.isolated = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# TODO(b/130340935): Use a dynamically created linker namespace similar to
# classloader-namespace for oat files, and tighten this up.
@@ -503,8 +509,11 @@
# android_link_namespaces in libnativeloader.
namespace.runtime.visible = true
-namespace.runtime.search.paths = /apex/com.android.runtime/${LIB}
-namespace.runtime.asan.search.paths = /apex/com.android.runtime/${LIB}
+# TODO(b/139408016): Split the namespaces for the ART and Runtime APEXes
+namespace.runtime.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.search.paths += /apex/com.android.runtime/${LIB}
+namespace.runtime.asan.search.paths = /apex/com.android.art/${LIB}
+namespace.runtime.asan.search.paths += /apex/com.android.runtime/${LIB}
namespace.runtime.links = default
# TODO(b/130340935): Use a dynamically created linker namespace similar to
# classloader-namespace for oat files, and tighten this up.
diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
index 93b7f43..17f6596 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -5,7 +5,7 @@
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
export ANDROID_STORAGE /storage
- export ANDROID_RUNTIME_ROOT /apex/com.android.runtime
+ export ANDROID_RUNTIME_ROOT /apex/com.android.art
export ANDROID_I18N_ROOT /apex/com.android.i18n
export ANDROID_TZDATA_ROOT /apex/com.android.tzdata
export EXTERNAL_STORAGE /sdcard