diff options
author | 2013-03-10 20:26:16 -0700 | |
---|---|---|
committer | 2013-03-11 15:47:02 -0700 | |
commit | bd86bccf1b47f1151842152ee52cf5d46d6b34ab (patch) | |
tree | c0c110b47435c6e8548f1b7126f9ea20da7fd934 | |
parent | 5d021c7399fa8090910d5b47ed00465a4e0e7e0f (diff) |
Tracking rebase to jb-mr1-release
Change-Id: Ic2ae1a27682cc4152003a68d59068b2c5c5eb09b
-rw-r--r-- | src/compiler/driver/compiler_driver.cc | 2 | ||||
-rw-r--r-- | src/compiler/driver/compiler_driver_test.cc | 3 | ||||
-rw-r--r-- | src/compiler/jni/jni_compiler_test.cc | 6 | ||||
-rw-r--r-- | src/compiler/llvm/intrinsic_helper.cc | 2 | ||||
-rw-r--r-- | src/compiler/llvm/ir_builder.h | 2 | ||||
-rw-r--r-- | src/compiler/llvm/llvm_compilation_unit.cc | 2 | ||||
-rw-r--r-- | src/compiler/llvm/md_builder.cc | 2 | ||||
-rw-r--r-- | src/compiler/llvm/md_builder.h | 2 | ||||
-rw-r--r-- | src/dex_file.cc | 2 | ||||
-rw-r--r-- | src/exception_test.cc | 3 | ||||
-rw-r--r-- | src/jni_internal.cc | 8 | ||||
-rw-r--r-- | src/jni_internal_test.cc | 3 | ||||
-rw-r--r-- | src/native/dalvik_system_Zygote.cc | 123 | ||||
-rw-r--r-- | src/runtime.cc | 50 | ||||
-rw-r--r-- | src/runtime.h | 5 | ||||
-rw-r--r-- | src/runtime_test.cc | 2 |
16 files changed, 170 insertions, 47 deletions
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc index 8556cc8366..9ed763cdfd 100644 --- a/src/compiler/driver/compiler_driver.cc +++ b/src/compiler/driver/compiler_driver.cc @@ -1329,6 +1329,7 @@ static const char* class_initializer_black_list[] = { "Landroid/net/Uri$StringUri;", // Requires Uri. "Landroid/net/WebAddress;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. "Landroid/nfc/NdefRecord;", // Calls String.getBytes -> java.nio.charset.Charset. + "Landroid/opengl/EGL14;", // Calls android.opengl.EGL14._nativeClassInit. "Landroid/opengl/GLES10;", // Calls android.opengl.GLES10._nativeClassInit. "Landroid/opengl/GLES10Ext;", // Calls android.opengl.GLES10Ext._nativeClassInit. "Landroid/opengl/GLES11;", // Requires GLES10. @@ -1350,6 +1351,7 @@ static const char* class_initializer_black_list[] = { "Landroid/server/BluetoothService;", // Calls android.server.BluetoothService.classInitNative. "Landroid/server/BluetoothEventLoop;", // Calls android.server.BluetoothEventLoop.classInitNative. "Landroid/telephony/PhoneNumberUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl. + "Landroid/telephony/TelephonyManager;", // Calls OsConstants.initConstants. "Landroid/text/AutoText;", // Requires android.util.DisplayMetrics -..-> android.os.SystemProperties.native_get_int. "Landroid/text/Layout;", // Calls com.android.internal.util.ArrayUtils.emptyArray -> System.identityHashCode. "Landroid/text/BoringLayout;", // Requires Layout. diff --git a/src/compiler/driver/compiler_driver_test.cc b/src/compiler/driver/compiler_driver_test.cc index dee448d33f..cbfc2ae948 100644 --- a/src/compiler/driver/compiler_driver_test.cc +++ b/src/compiler/driver/compiler_driver_test.cc @@ -44,7 +44,8 @@ class CompilerDriverTest : public CommonTest { LOCKS_EXCLUDED(Locks::mutator_lock_) { CompileAll(class_loader); Thread::Current()->TransitionFromSuspendedToRunnable(); - runtime_->Start(); + bool started = runtime_->Start(); + CHECK(started); env_ = Thread::Current()->GetJniEnv(); class_ = env_->FindClass(class_name); CHECK(class_ != NULL) << "Class not found: " << class_name; diff --git a/src/compiler/jni/jni_compiler_test.cc b/src/compiler/jni/jni_compiler_test.cc index 5176752a9d..77dd51ef6f 100644 --- a/src/compiler/jni/jni_compiler_test.cc +++ b/src/compiler/jni/jni_compiler_test.cc @@ -75,7 +75,8 @@ class JniCompilerTest : public CommonTest { CompileForTest(class_loader_, direct, method_name, method_sig); // Start runtime. Thread::Current()->TransitionFromSuspendedToRunnable(); - runtime_->Start(); + bool started = runtime_->Start(); + CHECK(started); } // JNI operations after runtime start. env_ = Thread::Current()->GetJniEnv(); @@ -532,7 +533,8 @@ TEST_F(JniCompilerTest, ExceptionHandling) { } // Start runtime to avoid re-initialization in SetupForTest. Thread::Current()->TransitionFromSuspendedToRunnable(); - runtime_->Start(); + bool started = runtime_->Start(); + CHECK(started); gJava_MyClassNatives_foo_calls = 0; diff --git a/src/compiler/llvm/intrinsic_helper.cc b/src/compiler/llvm/intrinsic_helper.cc index 39c4a586e2..ac34f7078f 100644 --- a/src/compiler/llvm/intrinsic_helper.cc +++ b/src/compiler/llvm/intrinsic_helper.cc @@ -20,8 +20,8 @@ #include <llvm/DerivedTypes.h> #include <llvm/Function.h> +#include <llvm/IRBuilder.h> #include <llvm/Intrinsics.h> -#include <llvm/Support/IRBuilder.h> namespace art { namespace llvm { diff --git a/src/compiler/llvm/ir_builder.h b/src/compiler/llvm/ir_builder.h index 9362a751da..32f0bf9696 100644 --- a/src/compiler/llvm/ir_builder.h +++ b/src/compiler/llvm/ir_builder.h @@ -26,8 +26,8 @@ #include <llvm/Constants.h> #include <llvm/DerivedTypes.h> +#include <llvm/IRBuilder.h> #include <llvm/LLVMContext.h> -#include <llvm/Support/IRBuilder.h> #include <llvm/Support/NoFolder.h> #include <llvm/Type.h> diff --git a/src/compiler/llvm/llvm_compilation_unit.cc b/src/compiler/llvm/llvm_compilation_unit.cc index 3783ae99e0..41c603f349 100644 --- a/src/compiler/llvm/llvm_compilation_unit.cc +++ b/src/compiler/llvm/llvm_compilation_unit.cc @@ -26,7 +26,6 @@ #include <llvm/ADT/StringSet.h> #include <llvm/ADT/Triple.h> #include <llvm/Analysis/CallGraph.h> -#include <llvm/Analysis/DebugInfo.h> #include <llvm/Analysis/Dominators.h> #include <llvm/Analysis/LoopInfo.h> #include <llvm/Analysis/LoopPass.h> @@ -39,6 +38,7 @@ #include <llvm/CodeGen/MachineFrameInfo.h> #include <llvm/CodeGen/MachineFunction.h> #include <llvm/CodeGen/MachineFunctionPass.h> +#include <llvm/DebugInfo.h> #include <llvm/DerivedTypes.h> #include <llvm/LLVMContext.h> #include <llvm/Module.h> diff --git a/src/compiler/llvm/md_builder.cc b/src/compiler/llvm/md_builder.cc index afb36111eb..657adc5f11 100644 --- a/src/compiler/llvm/md_builder.cc +++ b/src/compiler/llvm/md_builder.cc @@ -17,7 +17,7 @@ #include "md_builder.h" -#include "llvm/Support/MDBuilder.h" +#include "llvm/MDBuilder.h" #include <string> diff --git a/src/compiler/llvm/md_builder.h b/src/compiler/llvm/md_builder.h index 5231c14f07..5272ee5a95 100644 --- a/src/compiler/llvm/md_builder.h +++ b/src/compiler/llvm/md_builder.h @@ -19,7 +19,7 @@ #include "backend_types.h" -#include "llvm/Support/MDBuilder.h" +#include "llvm/MDBuilder.h" #include <cstring> diff --git a/src/dex_file.cc b/src/dex_file.cc index e67e767dba..12c11e8c91 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -299,7 +299,7 @@ void DexFile::InitMembers() { method_ids_ = reinterpret_cast<const MethodId*>(b + h->method_ids_off_); proto_ids_ = reinterpret_cast<const ProtoId*>(b + h->proto_ids_off_); class_defs_ = reinterpret_cast<const ClassDef*>(b + h->class_defs_off_); - DCHECK_EQ(size_, header_->file_size_); + DCHECK_EQ(size_, header_->file_size_) << GetLocation(); } bool DexFile::CheckMagicAndVersion() const { diff --git a/src/exception_test.cc b/src/exception_test.cc index 1d32f1bb6a..f0bec1b2c3 100644 --- a/src/exception_test.cc +++ b/src/exception_test.cc @@ -137,7 +137,8 @@ TEST_F(ExceptionTest, FindCatchHandler) { TEST_F(ExceptionTest, StackTraceElement) { Thread* thread = Thread::Current(); thread->TransitionFromSuspendedToRunnable(); - runtime_->Start(); + bool started = runtime_->Start(); + CHECK(started); JNIEnv* env = thread->GetJniEnv(); ScopedObjectAccess soa(env); diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 0ee4c21ce4..726c80bbe0 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -2564,7 +2564,13 @@ extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, void** p_env, void* vm_args) { return JNI_ERR; } Runtime* runtime = Runtime::Current(); - runtime->Start(); + bool started = runtime->Start(); + if (!started) { + delete Thread::Current()->GetJniEnv(); + delete runtime->GetJavaVM(); + LOG(WARNING) << "CreateJavaVM failed"; + return JNI_ERR; + } *p_env = Thread::Current()->GetJniEnv(); *p_vm = runtime->GetJavaVM(); return JNI_OK; diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc index deff290c33..4b820f9126 100644 --- a/src/jni_internal_test.cc +++ b/src/jni_internal_test.cc @@ -1179,7 +1179,8 @@ TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) { TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { Thread::Current()->TransitionFromSuspendedToRunnable(); LoadDex("AllFields"); - runtime_->Start(); + bool started = runtime_->Start(); + CHECK(started); jclass c = env_->FindClass("AllFields"); ASSERT_TRUE(c != NULL); diff --git a/src/native/dalvik_system_Zygote.cc b/src/native/dalvik_system_Zygote.cc index d33c67fb0e..9b995f421d 100644 --- a/src/native/dalvik_system_Zygote.cc +++ b/src/native/dalvik_system_Zygote.cc @@ -14,15 +14,20 @@ * limitations under the License. */ +// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc +#include <sys/mount.h> +#include <linux/fs.h> + #include <grp.h> #include <paths.h> #include <signal.h> #include <stdlib.h> -#include <sys/mount.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> +#include "cutils/fs.h" +#include "cutils/multiuser.h" #include "cutils/sched_policy.h" #include "debugger.h" #include "jni_internal.h" @@ -53,6 +58,7 @@ enum MountExternalKind { MOUNT_EXTERNAL_NONE = 0, MOUNT_EXTERNAL_SINGLEUSER = 1, MOUNT_EXTERNAL_MULTIUSER = 2, + MOUNT_EXTERNAL_MULTIUSER_ALL = 3, }; // This signal handler is for zygote mode, since the zygote must reap its children @@ -303,45 +309,91 @@ static void EnableDebugFeatures(uint32_t debug_flags) { } } -// Create private mount space for this process and mount SD card -// into it, based on the active user. -static void MountExternalStorage(uid_t uid, jint mount_external) { - if (mount_external == MOUNT_EXTERNAL_NONE) { - return; +// Create a private mount namespace and bind mount appropriate emulated +// storage for the given user. +static bool MountEmulatedStorage(uid_t uid, jint mount_mode) { + if (mount_mode == MOUNT_EXTERNAL_NONE) { + return true; } -#if 0 - userid_t user_id = multiuser_getUserId(uid); + // See storage config details at http://source.android.com/tech/storage/ + userid_t user_id = multiuser_get_user_id(uid); - // Create private mount namespace for our process. + // Create a second private mount namespace for our process if (unshare(CLONE_NEWNS) == -1) { - PLOG(FATAL) << "unshare(CLONE_NEWNS) failed"; + PLOG(WARNING) << "Failed to unshare()"; + return false; } - // Mark rootfs as being a slave in our process so that changes - // from parent namespace flow into our process. - if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) { - PLOG(FATAL) << "mount(\"rootfs\", \"/\", NULL, (MS_SLAVE | MS_REC), NULL) failed"; - } + // Create bind mounts to expose external storage + if (mount_mode == MOUNT_EXTERNAL_MULTIUSER || mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) { + // These paths must already be created by init.rc + const char* source = getenv("EMULATED_STORAGE_SOURCE"); + const char* target = getenv("EMULATED_STORAGE_TARGET"); + const char* legacy = getenv("EXTERNAL_STORAGE"); + if (source == NULL || target == NULL || legacy == NULL) { + LOG(WARNING) << "Storage environment undefined; unable to provide external storage"; + return false; + } + + // Prepare source paths + + // /mnt/shell/emulated/0 + std::string source_user(StringPrintf("%s/%d", source, user_id)); + // /mnt/shell/emulated/obb + std::string source_obb(StringPrintf("%s/obb", source)); + // /storage/emulated/0 + std::string target_user(StringPrintf("%s/%d", target, user_id)); - // Create bind mount from specific path. - if (mount_external == MOUNT_EXTERNAL_SINGLEUSER) { - if (mount(EXTERNAL_STORAGE_SYSTEM, EXTERNAL_STORAGE_APP, "none", MS_BIND, NULL) == -1) { - PLOG(FATAL) << "mount(\"" << EXTERNAL_STORAGE_SYSTEM << "\", \"" << EXTERNAL_STORAGE_APP << "\", \"none\", MS_BIND, NULL) failed"; + if (fs_prepare_dir(source_user.c_str(), 0000, 0, 0) == -1 + || fs_prepare_dir(source_obb.c_str(), 0000, 0, 0) == -1 + || fs_prepare_dir(target_user.c_str(), 0000, 0, 0) == -1) { + return false; } - } else if (mount_external == MOUNT_EXTERNAL_MULTIUSER) { - // Assume path has already been created by installd. - std::string source_path(StringPrintf("%s/%d", EXTERNAL_STORAGE_SYSTEM, user_id)); - if (mount(source_path.c_str(), EXTERNAL_STORAGE_APP, "none", MS_BIND, NULL) == -1) { - PLOG(FATAL) << "mount(\"" << source_path.c_str() << "\", \"" << EXTERNAL_STORAGE_APP << "\", \"none\", MS_BIND, NULL) failed"; + + if (mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) { + // Mount entire external storage tree for all users + if (mount(source, target, NULL, MS_BIND, NULL) == -1) { + PLOG(WARNING) << "Failed to mount " << source << " to " << target; + return false; + } + } else { + // Only mount user-specific external storage + if (mount(source_user.c_str(), target_user.c_str(), NULL, MS_BIND, NULL) == -1) { + PLOG(WARNING) << "Failed to mount " << source_user << " to " << target_user; + return false; + } + } + + // Now that user is mounted, prepare and mount OBB storage + // into place for current user + + // /storage/emulated/0/Android + std::string target_android(StringPrintf("%s/%d/Android", target, user_id)); + // /storage/emulated/0/Android/obb + std::string target_obb(StringPrintf("%s/%d/Android/obb", target, user_id)); + + if (fs_prepare_dir(target_android.c_str(), 0000, 0, 0) == -1 + || fs_prepare_dir(target_obb.c_str(), 0000, 0, 0) == -1 + || fs_prepare_dir(legacy, 0000, 0, 0) == -1) { + return false; + } + if (mount(source_obb.c_str(), target_obb.c_str(), NULL, MS_BIND, NULL) == -1) { + PLOG(WARNING) << "Failed to mount " << source_obb << " to " << target_obb; + return false; + } + + // Finally, mount user-specific path into place for legacy users + if (mount(target_user.c_str(), legacy, NULL, MS_BIND | MS_REC, NULL) == -1) { + PLOG(WARNING) << "Failed to mount " << target_user << " to " << legacy; + return false; } } else { - LOG(FATAL) << "Mount mode unsupported: " << mount_external; + LOG(WARNING) << "Mount mode " << mount_mode << " unsupported"; + return false; } -#else - UNUSED(uid); - UNIMPLEMENTED(FATAL); -#endif + + return true; } #if defined(__linux__) @@ -397,7 +449,18 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra DropCapabilitiesBoundingSet(); - MountExternalStorage(uid, mount_external); + if (!MountEmulatedStorage(uid, mount_external)) { + PLOG(WARNING) << "Failed to mount emulated storage"; + if (errno == ENOTCONN || errno == EROFS) { + // When device is actively encrypting, we get ENOTCONN here + // since FUSE was mounted before the framework restarted. + // When encrypted device is booting, we get EROFS since + // FUSE hasn't been created yet by init. + // In either case, continue without external storage. + } else { + LOG(FATAL) << "Cannot continue without emulated storage"; + } + } SetGids(env, javaGids); diff --git a/src/runtime.cc b/src/runtime.cc index 414bef4093..9b2dca72a4 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -16,6 +16,10 @@ #include "runtime.h" +// sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc +#include <sys/mount.h> +#include <linux/fs.h> + #include <signal.h> #include <sys/syscall.h> @@ -472,7 +476,7 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b double value; iss >> value; // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range. - const bool sane_val = iss.good() && (value >= 0.1) && (value <= 0.9); + const bool sane_val = iss.eof() && (value >= 0.1) && (value <= 0.9); if (!sane_val) { if (ignore_unrecognized) { continue; @@ -640,7 +644,7 @@ static void CreateSystemClassLoader() { contextClassLoader->SetObject(soa.Self()->GetPeer(), class_loader); } -void Runtime::Start() { +bool Runtime::Start() { VLOG(startup) << "Runtime::Start entering"; CHECK(host_prefix_.empty()) << host_prefix_; @@ -666,7 +670,11 @@ void Runtime::Start() { Thread::FinishStartup(); - if (!is_zygote_) { + if (is_zygote_) { + if (!InitZygote()) { + return false; + } + } else { DidForkFromZygote(); } @@ -679,6 +687,8 @@ void Runtime::Start() { VLOG(startup) << "Runtime::Start exiting"; finished_starting_ = true; + + return true; } void Runtime::EndThreadBirth() EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) { @@ -689,6 +699,40 @@ void Runtime::EndThreadBirth() EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_ } } +// Do zygote-mode-only initialization. +bool Runtime::InitZygote() { + // zygote goes into its own process group + setpgid(0,0); + + // See storage config details at http://source.android.com/tech/storage/ + // Create private mount namespace shared by all children + if (unshare(CLONE_NEWNS) == -1) { + PLOG(WARNING) << "Failed to unshare()"; + return false; + } + + // Mark rootfs as being a slave so that changes from default + // namespace only flow into our children. + if (mount("rootfs", "/", NULL, (MS_SLAVE | MS_REC), NULL) == -1) { + PLOG(WARNING) << "Failed to mount() rootfs as MS_SLAVE"; + return false; + } + + // Create a staging tmpfs that is shared by our children; they will + // bind mount storage into their respective private namespaces, which + // are isolated from each other. + const char* target_base = getenv("EMULATED_STORAGE_TARGET"); + if (target_base != NULL) { + if (mount("tmpfs", target_base, "tmpfs", MS_NOSUID | MS_NODEV, + "uid=0,gid=1028,mode=0050") == -1) { + LOG(WARNING) << "Failed to mount tmpfs to " << target_base; + return false; + } + } + + return true; +} + void Runtime::DidForkFromZygote() { is_zygote_ = false; diff --git a/src/runtime.h b/src/runtime.h index 696f2317e9..f8788ad934 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -126,7 +126,7 @@ class Runtime { } // Starts a runtime, which may cause threads to be started and code to run. - void Start() UNLOCK_FUNCTION(Locks::mutator_lock_); + bool Start() UNLOCK_FUNCTION(Locks::mutator_lock_); bool IsShuttingDown() const EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) { return shutting_down_; @@ -346,8 +346,9 @@ class Runtime { void SetStatsEnabled(bool new_state); - void DidForkFromZygote(); bool PreZygoteFork(); + bool InitZygote(); + void DidForkFromZygote(); void EnableMethodTracing(Trace* trace); void DisableMethodTracing(); diff --git a/src/runtime_test.cc b/src/runtime_test.cc index e147749346..d53b4a62a1 100644 --- a/src/runtime_test.cc +++ b/src/runtime_test.cc @@ -46,6 +46,7 @@ TEST_F(RuntimeTest, ParsedOptions) { options.push_back(std::make_pair("-Xms2048", null)); options.push_back(std::make_pair("-Xmx4k", null)); options.push_back(std::make_pair("-Xss1m", null)); + options.push_back(std::make_pair("-XX:HeapTargetUtilization=0.75", null)); options.push_back(std::make_pair("-Dfoo=bar", null)); options.push_back(std::make_pair("-Dbaz=qux", null)); options.push_back(std::make_pair("-verbose:gc,class,jni", null)); @@ -63,6 +64,7 @@ TEST_F(RuntimeTest, ParsedOptions) { EXPECT_EQ(2048U, parsed->heap_initial_size_); EXPECT_EQ(4 * KB, parsed->heap_maximum_size_); EXPECT_EQ(1 * MB, parsed->stack_size_); + EXPECT_EQ(0.75, parsed->heap_target_utilization_); EXPECT_EQ("host_prefix", parsed->host_prefix_); EXPECT_TRUE(test_vfprintf == parsed->hook_vfprintf_); EXPECT_TRUE(test_exit == parsed->hook_exit_); |