Merge commit 'a63ccea6abc7ea02e2d98e41c80793ca97237bd3' from
oc-mr1-dev-plus-aosp into stage-aosp-master Change-Id: Ia33311cd1fd26dfaea59a69317b306fb91203c40 Merged-In: I03d06b10807e8a313c9654c2e1db36bfb59e3f99
This commit is contained in:
commit
23e27db576
10
CleanSpec.mk
10
CleanSpec.mk
|
@ -60,4 +60,14 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.$(TARGET_D
|
|||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.$(TARGET_DEVICE).so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/vendor)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/init.rc)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libtrusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libtrusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/keystore.trusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/keystore.trusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/hw/gatekeeper.trusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/hw/gatekeeper.trusty.so)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/secure-storage-unit-test)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/storageproxyd)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/tipc-test)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/trusty_keymaster_tipc)
|
||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/root)
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
cc_library_static {
|
||||
cc_library {
|
||||
name: "libadf",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
srcs: ["adf.cpp"],
|
||||
cflags: ["-Werror"],
|
||||
local_include_dirs: ["include"],
|
||||
|
|
|
@ -38,7 +38,6 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
|
|||
{
|
||||
uint64_t dev_sz;
|
||||
int fd, rc = 0;
|
||||
int status;
|
||||
|
||||
if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
|
||||
PERROR << "Cannot open block device";
|
||||
|
@ -62,7 +61,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
|
|||
const char* const mke2fs_args[] = {
|
||||
"/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
|
||||
|
||||
rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), &status,
|
||||
rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
|
||||
true, LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
if (rc) {
|
||||
LERROR << "mke2fs returned " << rc;
|
||||
|
@ -78,7 +77,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
|
|||
nullptr};
|
||||
|
||||
rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
|
||||
&status, true, LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
if (rc) {
|
||||
LERROR << "e2fsdroid returned " << rc;
|
||||
}
|
||||
|
@ -88,10 +87,9 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
|
|||
|
||||
static int format_f2fs(char *fs_blkdev)
|
||||
{
|
||||
int status;
|
||||
const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
|
||||
|
||||
return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), &status, true,
|
||||
return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
|
||||
LOG_KLOG, true, nullptr, nullptr, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
|
|||
LOCAL_SRC_FILES := \
|
||||
SoftGateKeeperDevice.cpp \
|
||||
IGateKeeperService.cpp \
|
||||
gatekeeperd.cpp \
|
||||
IUserManager.cpp
|
||||
gatekeeperd.cpp
|
||||
|
||||
LOCAL_MODULE := gatekeeperd
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "IUserManager"
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Log.h>
|
||||
#include <binder/Parcel.h>
|
||||
|
||||
#include "IUserManager.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
class BpUserManager : public BpInterface<IUserManager>
|
||||
{
|
||||
public:
|
||||
explicit BpUserManager(const sp<IBinder>& impl) :
|
||||
BpInterface<IUserManager>(impl) {
|
||||
}
|
||||
virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
|
||||
data.writeInt32(user_id);
|
||||
status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
|
||||
if (rc != NO_ERROR) {
|
||||
ALOGE("%s: failed (%d)\n", __func__, rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t exception = reply.readExceptionCode();
|
||||
if (exception != 0) {
|
||||
ALOGE("%s: got exception (%d)\n", __func__, exception);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reply.readInt32();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
|
||||
|
||||
}; // namespace android
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef IUSERMANAGER_H_
|
||||
#define IUSERMANAGER_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <binder/IInterface.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Communication channel to UserManager
|
||||
*/
|
||||
class IUserManager : public IInterface {
|
||||
public:
|
||||
// must be kept in sync with IUserManager.aidl
|
||||
enum {
|
||||
GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
|
||||
};
|
||||
|
||||
virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
|
||||
|
||||
DECLARE_META_INTERFACE(UserManager);
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // IUSERMANAGER_H_
|
||||
|
|
@ -38,7 +38,6 @@
|
|||
#include <utils/String16.h>
|
||||
|
||||
#include "SoftGateKeeperDevice.h"
|
||||
#include "IUserManager.h"
|
||||
|
||||
#include <hidl/HidlSupport.h>
|
||||
#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
|
||||
|
@ -335,23 +334,7 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
virtual uint64_t getSecureUserId(uint32_t uid) {
|
||||
uint64_t sid = read_sid(uid);
|
||||
if (sid == 0) {
|
||||
// might be a work profile, look up the parent
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sp<IBinder> binder = sm->getService(String16("user"));
|
||||
sp<IUserManager> um = interface_cast<IUserManager>(binder);
|
||||
int32_t parent = um->getCredentialOwnerProfile(uid);
|
||||
if (parent < 0) {
|
||||
return 0;
|
||||
} else if (parent != (int32_t) uid) {
|
||||
return read_sid(parent);
|
||||
}
|
||||
}
|
||||
return sid;
|
||||
|
||||
}
|
||||
virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
|
||||
|
||||
virtual void clearSecureUserId(uint32_t uid) {
|
||||
IPCThreadState* ipc = IPCThreadState::self();
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
cc_library_headers {
|
||||
name: "libhealthd_headers",
|
||||
vendor_available: true,
|
||||
export_include_dirs: ["include"],
|
||||
header_libs: ["libbatteryservice_headers"],
|
||||
export_header_lib_headers: ["libbatteryservice_headers"],
|
||||
}
|
|
@ -418,7 +418,6 @@ void SelinuxRestoreContext() {
|
|||
selinux_android_restorecon("/dev/urandom", 0);
|
||||
selinux_android_restorecon("/dev/__properties__", 0);
|
||||
|
||||
selinux_android_restorecon("/file_contexts.bin", 0);
|
||||
selinux_android_restorecon("/plat_file_contexts", 0);
|
||||
selinux_android_restorecon("/nonplat_file_contexts", 0);
|
||||
selinux_android_restorecon("/plat_property_contexts", 0);
|
||||
|
|
|
@ -179,7 +179,11 @@ class FuseBridgeEntry {
|
|||
}
|
||||
|
||||
const uint32_t opcode = buffer_.request.header.opcode;
|
||||
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode;
|
||||
const uint64_t unique = buffer_.request.header.unique;
|
||||
LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
|
||||
if (unique == 0) {
|
||||
return FuseBridgeState::kWaitToReadEither;
|
||||
}
|
||||
switch (opcode) {
|
||||
case FUSE_FORGET:
|
||||
// Do not reply to FUSE_FORGET.
|
||||
|
|
|
@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
|
|||
memset(&request_, 0, sizeof(FuseRequest));
|
||||
request_.header.opcode = opcode;
|
||||
request_.header.len = sizeof(fuse_in_header);
|
||||
request_.header.unique = 1;
|
||||
ASSERT_TRUE(request_.Write(dev_sockets_[0]));
|
||||
|
||||
memset(&response_, 0, sizeof(FuseResponse));
|
||||
|
|
|
@ -54,7 +54,7 @@ test_c_flags := \
|
|||
-Werror \
|
||||
-fno-builtin \
|
||||
|
||||
test_src_files := \
|
||||
cts_src_files := \
|
||||
libc_test.cpp \
|
||||
liblog_test_default.cpp \
|
||||
liblog_test_local.cpp \
|
||||
|
@ -67,6 +67,9 @@ test_src_files := \
|
|||
log_time_test.cpp \
|
||||
log_wrap_test.cpp
|
||||
|
||||
test_src_files := \
|
||||
$(cts_src_files) \
|
||||
|
||||
# Build tests for the device (with .so). Run with:
|
||||
# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
|
||||
include $(CLEAR_VARS)
|
||||
|
@ -82,15 +85,15 @@ cts_executable := CtsLiblogTestCases
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := $(cts_executable)
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
LOCAL_CFLAGS += $(test_c_flags)
|
||||
LOCAL_SRC_FILES := $(test_src_files)
|
||||
LOCAL_CFLAGS += $(test_c_flags) -DNO_PSTORE
|
||||
LOCAL_SRC_FILES := $(cts_src_files)
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativetest
|
||||
LOCAL_MULTILIB := both
|
||||
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
|
||||
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
|
||||
LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
|
||||
LOCAL_COMPATIBILITY_SUITE := cts
|
||||
LOCAL_COMPATIBILITY_SUITE := cts vts
|
||||
LOCAL_CTS_TEST_PACKAGE := android.core.liblog
|
||||
include $(BUILD_CTS_EXECUTABLE)
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ static std::string popenToString(const std::string& command) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NO_PSTORE
|
||||
static bool isPmsgActive() {
|
||||
pid_t pid = getpid();
|
||||
|
||||
|
@ -125,6 +126,7 @@ static bool isPmsgActive() {
|
|||
|
||||
return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
|
||||
}
|
||||
#endif /* NO_PSTORE */
|
||||
|
||||
static bool isLogdwActive() {
|
||||
std::string logdwSignature =
|
||||
|
@ -189,22 +191,25 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
|
|||
EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
|
||||
#ifdef USING_LOGGER_DEFAULT
|
||||
// Check that we can close and reopen the logger
|
||||
bool pmsgActiveAfter__android_log_btwrite;
|
||||
bool logdwActiveAfter__android_log_btwrite;
|
||||
if (getuid() == AID_ROOT) {
|
||||
tested__android_log_close = true;
|
||||
pmsgActiveAfter__android_log_btwrite = isPmsgActive();
|
||||
logdwActiveAfter__android_log_btwrite = isLogdwActive();
|
||||
#ifndef NO_PSTORE
|
||||
bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
|
||||
EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
|
||||
#endif /* NO_PSTORE */
|
||||
logdwActiveAfter__android_log_btwrite = isLogdwActive();
|
||||
EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
|
||||
} else if (!tested__android_log_close) {
|
||||
fprintf(stderr, "WARNING: can not test __android_log_close()\n");
|
||||
}
|
||||
__android_log_close();
|
||||
if (getuid() == AID_ROOT) {
|
||||
#ifndef NO_PSTORE
|
||||
bool pmsgActiveAfter__android_log_close = isPmsgActive();
|
||||
bool logdwActiveAfter__android_log_close = isLogdwActive();
|
||||
EXPECT_FALSE(pmsgActiveAfter__android_log_close);
|
||||
#endif /* NO_PSTORE */
|
||||
bool logdwActiveAfter__android_log_close = isLogdwActive();
|
||||
EXPECT_FALSE(logdwActiveAfter__android_log_close);
|
||||
}
|
||||
#endif
|
||||
|
@ -213,9 +218,11 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
|
|||
EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
|
||||
#ifdef USING_LOGGER_DEFAULT
|
||||
if (getuid() == AID_ROOT) {
|
||||
pmsgActiveAfter__android_log_btwrite = isPmsgActive();
|
||||
logdwActiveAfter__android_log_btwrite = isLogdwActive();
|
||||
#ifndef NO_PSTORE
|
||||
bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
|
||||
EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
|
||||
#endif /* NO_PSTORE */
|
||||
logdwActiveAfter__android_log_btwrite = isLogdwActive();
|
||||
EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
|
||||
}
|
||||
#endif
|
||||
|
@ -3036,12 +3043,15 @@ TEST(liblog, android_log_write_list_buffer) {
|
|||
|
||||
#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality
|
||||
#ifdef __ANDROID__
|
||||
#ifndef NO_PSTORE
|
||||
static const char __pmsg_file[] =
|
||||
"/data/william-shakespeare/MuchAdoAboutNothing.txt";
|
||||
#endif /* NO_PSTORE */
|
||||
#endif
|
||||
|
||||
TEST(liblog, __android_log_pmsg_file_write) {
|
||||
#ifdef __ANDROID__
|
||||
#ifndef NO_PSTORE
|
||||
__android_log_close();
|
||||
if (getuid() == AID_ROOT) {
|
||||
tested__android_log_close = true;
|
||||
|
@ -3092,12 +3102,16 @@ TEST(liblog, __android_log_pmsg_file_write) {
|
|||
EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
|
||||
EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
|
||||
}
|
||||
#else /* NO_PSTORE */
|
||||
GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
|
||||
#endif /* NO_PSTORE */
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#ifndef NO_PSTORE
|
||||
static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
|
||||
const char* buf, size_t len, void* arg) {
|
||||
EXPECT_TRUE(NULL == arg);
|
||||
|
@ -3118,10 +3132,12 @@ static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename,
|
|||
? -ENOEXEC
|
||||
: 1;
|
||||
}
|
||||
#endif /* NO_PSTORE */
|
||||
#endif
|
||||
|
||||
TEST(liblog, __android_log_pmsg_file_read) {
|
||||
#ifdef __ANDROID__
|
||||
#ifndef NO_PSTORE
|
||||
signaled = 0;
|
||||
|
||||
__android_log_close();
|
||||
|
@ -3155,6 +3171,9 @@ TEST(liblog, __android_log_pmsg_file_read) {
|
|||
|
||||
EXPECT_LT(0, ret);
|
||||
EXPECT_EQ(1U, signaled);
|
||||
#else /* NO_PSTORE */
|
||||
GTEST_LOG_(INFO) << "This test does nothing because of NO_PSTORE.\n";
|
||||
#endif /* NO_PSTORE */
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
|
|||
int32_t target_sdk_version,
|
||||
jobject class_loader,
|
||||
bool is_shared,
|
||||
bool is_for_vendor,
|
||||
jstring library_path,
|
||||
jstring permitted_path);
|
||||
|
||||
|
|
|
@ -82,6 +82,11 @@ static constexpr const char* kPublicNativeLibrariesSystemConfigPathFromRoot =
|
|||
"/etc/public.libraries.txt";
|
||||
static constexpr const char* kPublicNativeLibrariesVendorConfig =
|
||||
"/vendor/etc/public.libraries.txt";
|
||||
static constexpr const char* kLlndkNativeLibrariesSystemConfigPathFromRoot =
|
||||
"/etc/llndk.libraries.txt";
|
||||
static constexpr const char* kVndkspNativeLibrariesSystemConfigPathFromRoot =
|
||||
"/etc/vndksp.libraries.txt";
|
||||
|
||||
|
||||
// The device may be configured to have the vendor libraries loaded to a separate namespace.
|
||||
// For historical reasons this namespace was named sphal but effectively it is intended
|
||||
|
@ -89,6 +94,11 @@ static constexpr const char* kPublicNativeLibrariesVendorConfig =
|
|||
// vendor and system namespaces.
|
||||
static constexpr const char* kVendorNamespaceName = "sphal";
|
||||
|
||||
static constexpr const char* kVndkNamespaceName = "vndk";
|
||||
|
||||
static constexpr const char* kClassloaderNamespaceName = "classloader-namespace";
|
||||
static constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace";
|
||||
|
||||
// (http://b/27588281) This is a workaround for apps using custom classloaders and calling
|
||||
// System.load() with an absolute path which is outside of the classloader library search path.
|
||||
// This list includes all directories app is allowed to access this way.
|
||||
|
@ -108,6 +118,7 @@ class LibraryNamespaces {
|
|||
uint32_t target_sdk_version,
|
||||
jobject class_loader,
|
||||
bool is_shared,
|
||||
bool is_for_vendor,
|
||||
jstring java_library_path,
|
||||
jstring java_permitted_path,
|
||||
NativeLoaderNamespace* ns,
|
||||
|
@ -163,9 +174,39 @@ class LibraryNamespaces {
|
|||
is_native_bridge = NativeBridgeIsPathSupported(library_path.c_str());
|
||||
}
|
||||
|
||||
std::string system_exposed_libraries = system_public_libraries_;
|
||||
const char* namespace_name = kClassloaderNamespaceName;
|
||||
android_namespace_t* vndk_ns = nullptr;
|
||||
if (is_for_vendor && !is_shared) {
|
||||
LOG_FATAL_IF(is_native_bridge, "Unbundled vendor apk must not use translated architecture");
|
||||
|
||||
// For vendor apks, give access to the vendor lib even though
|
||||
// they are treated as unbundled; the libs and apks are still bundled
|
||||
// together in the vendor partition.
|
||||
#if defined(__LP64__)
|
||||
std::string vendor_lib_path = "/vendor/lib64";
|
||||
#else
|
||||
std::string vendor_lib_path = "/vendor/lib";
|
||||
#endif
|
||||
library_path = library_path + ":" + vendor_lib_path.c_str();
|
||||
permitted_path = permitted_path + ":" + vendor_lib_path.c_str();
|
||||
|
||||
// Also give access to LLNDK libraries since they are available to vendors
|
||||
system_exposed_libraries = system_exposed_libraries + ":" + system_llndk_libraries_.c_str();
|
||||
|
||||
// Give access to VNDK-SP libraries from the 'vndk' namespace.
|
||||
vndk_ns = android_get_exported_namespace(kVndkNamespaceName);
|
||||
LOG_ALWAYS_FATAL_IF(vndk_ns == nullptr,
|
||||
"Cannot find \"%s\" namespace for vendor apks", kVndkNamespaceName);
|
||||
|
||||
// Different name is useful for debugging
|
||||
namespace_name = kVendorClassloaderNamespaceName;
|
||||
ALOGD("classloader namespace configured for unbundled vendor apk. library_path=%s", library_path.c_str());
|
||||
}
|
||||
|
||||
NativeLoaderNamespace native_loader_ns;
|
||||
if (!is_native_bridge) {
|
||||
android_namespace_t* ns = android_create_namespace("classloader-namespace",
|
||||
android_namespace_t* ns = android_create_namespace(namespace_name,
|
||||
nullptr,
|
||||
library_path.c_str(),
|
||||
namespace_type,
|
||||
|
@ -181,11 +222,19 @@ class LibraryNamespaces {
|
|||
// which is expected behavior in this case.
|
||||
android_namespace_t* vendor_ns = android_get_exported_namespace(kVendorNamespaceName);
|
||||
|
||||
if (!android_link_namespaces(ns, nullptr, system_public_libraries_.c_str())) {
|
||||
if (!android_link_namespaces(ns, nullptr, system_exposed_libraries.c_str())) {
|
||||
*error_msg = dlerror();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (vndk_ns != nullptr && !system_vndksp_libraries_.empty()) {
|
||||
// vendor apks are allowed to use VNDK-SP libraries.
|
||||
if (!android_link_namespaces(ns, vndk_ns, system_vndksp_libraries_.c_str())) {
|
||||
*error_msg = dlerror();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vendor_public_libraries_.empty()) {
|
||||
if (!android_link_namespaces(ns, vendor_ns, vendor_public_libraries_.c_str())) {
|
||||
*error_msg = dlerror();
|
||||
|
@ -195,7 +244,7 @@ class LibraryNamespaces {
|
|||
|
||||
native_loader_ns = NativeLoaderNamespace(ns);
|
||||
} else {
|
||||
native_bridge_namespace_t* ns = NativeBridgeCreateNamespace("classloader-namespace",
|
||||
native_bridge_namespace_t* ns = NativeBridgeCreateNamespace(namespace_name,
|
||||
nullptr,
|
||||
library_path.c_str(),
|
||||
namespace_type,
|
||||
|
@ -209,7 +258,7 @@ class LibraryNamespaces {
|
|||
|
||||
native_bridge_namespace_t* vendor_ns = NativeBridgeGetVendorNamespace();
|
||||
|
||||
if (!NativeBridgeLinkNamespaces(ns, nullptr, system_public_libraries_.c_str())) {
|
||||
if (!NativeBridgeLinkNamespaces(ns, nullptr, system_exposed_libraries.c_str())) {
|
||||
*error_msg = NativeBridgeGetError();
|
||||
return false;
|
||||
}
|
||||
|
@ -259,6 +308,10 @@ class LibraryNamespaces {
|
|||
std::string root_dir = android_root_env != nullptr ? android_root_env : "/system";
|
||||
std::string public_native_libraries_system_config =
|
||||
root_dir + kPublicNativeLibrariesSystemConfigPathFromRoot;
|
||||
std::string llndk_native_libraries_system_config =
|
||||
root_dir + kLlndkNativeLibrariesSystemConfigPathFromRoot;
|
||||
std::string vndksp_native_libraries_system_config =
|
||||
root_dir + kVndkspNativeLibrariesSystemConfigPathFromRoot;
|
||||
|
||||
std::string error_msg;
|
||||
LOG_ALWAYS_FATAL_IF(!ReadConfig(public_native_libraries_system_config, &sonames, &error_msg),
|
||||
|
@ -293,6 +346,14 @@ class LibraryNamespaces {
|
|||
|
||||
system_public_libraries_ = base::Join(sonames, ':');
|
||||
|
||||
sonames.clear();
|
||||
ReadConfig(kLlndkNativeLibrariesSystemConfigPathFromRoot, &sonames);
|
||||
system_llndk_libraries_ = base::Join(sonames, ':');
|
||||
|
||||
sonames.clear();
|
||||
ReadConfig(kVndkspNativeLibrariesSystemConfigPathFromRoot, &sonames);
|
||||
system_vndksp_libraries_ = base::Join(sonames, ':');
|
||||
|
||||
sonames.clear();
|
||||
// This file is optional, quietly ignore if the file does not exist.
|
||||
ReadConfig(kPublicNativeLibrariesVendorConfig, &sonames);
|
||||
|
@ -404,6 +465,8 @@ class LibraryNamespaces {
|
|||
std::vector<std::pair<jweak, NativeLoaderNamespace>> namespaces_;
|
||||
std::string system_public_libraries_;
|
||||
std::string vendor_public_libraries_;
|
||||
std::string system_llndk_libraries_;
|
||||
std::string system_vndksp_libraries_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LibraryNamespaces);
|
||||
};
|
||||
|
@ -430,6 +493,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
|
|||
int32_t target_sdk_version,
|
||||
jobject class_loader,
|
||||
bool is_shared,
|
||||
bool is_for_vendor,
|
||||
jstring library_path,
|
||||
jstring permitted_path) {
|
||||
#if defined(__ANDROID__)
|
||||
|
@ -441,6 +505,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
|
|||
target_sdk_version,
|
||||
class_loader,
|
||||
is_shared,
|
||||
is_for_vendor,
|
||||
library_path,
|
||||
permitted_path,
|
||||
&ns,
|
||||
|
@ -449,7 +514,7 @@ jstring CreateClassLoaderNamespace(JNIEnv* env,
|
|||
return env->NewStringUTF(error_msg.c_str());
|
||||
}
|
||||
#else
|
||||
UNUSED(env, target_sdk_version, class_loader, is_shared,
|
||||
UNUSED(env, target_sdk_version, class_loader, is_shared, is_for_vendor,
|
||||
library_path, permitted_path);
|
||||
#endif
|
||||
return nullptr;
|
||||
|
@ -478,7 +543,8 @@ void* OpenNativeLibrary(JNIEnv* env,
|
|||
if (!g_namespaces->Create(env,
|
||||
target_sdk_version,
|
||||
class_loader,
|
||||
false,
|
||||
false /* is_shared */,
|
||||
false /* is_for_vendor */,
|
||||
library_path,
|
||||
nullptr,
|
||||
&ns,
|
||||
|
|
|
@ -55,6 +55,9 @@ enum {
|
|||
/* ui service treads might want to run at a urgent display (uncommon) */
|
||||
ANDROID_PRIORITY_URGENT_DISPLAY = HAL_PRIORITY_URGENT_DISPLAY,
|
||||
|
||||
/* all normal video threads */
|
||||
ANDROID_PRIORITY_VIDEO = -10,
|
||||
|
||||
/* all normal audio threads */
|
||||
ANDROID_PRIORITY_AUDIO = -16,
|
||||
|
||||
|
|
|
@ -180,7 +180,15 @@ ssize_t utf32_to_utf8_length(const char32_t *src, size_t src_len)
|
|||
size_t ret = 0;
|
||||
const char32_t *end = src + src_len;
|
||||
while (src < end) {
|
||||
ret += utf32_codepoint_utf8_length(*src++);
|
||||
size_t char_len = utf32_codepoint_utf8_length(*src++);
|
||||
if (SSIZE_MAX - char_len < ret) {
|
||||
// If this happens, we would overflow the ssize_t type when
|
||||
// returning from this function, so we cannot express how
|
||||
// long this string is in an ssize_t.
|
||||
android_errorWriteLog(0x534e4554, "37723026");
|
||||
return -1;
|
||||
}
|
||||
ret += char_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -439,14 +447,23 @@ ssize_t utf16_to_utf8_length(const char16_t *src, size_t src_len)
|
|||
size_t ret = 0;
|
||||
const char16_t* const end = src + src_len;
|
||||
while (src < end) {
|
||||
size_t char_len;
|
||||
if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
|
||||
&& (*(src + 1) & 0xFC00) == 0xDC00) {
|
||||
// surrogate pairs are always 4 bytes.
|
||||
ret += 4;
|
||||
char_len = 4;
|
||||
src += 2;
|
||||
} else {
|
||||
ret += utf32_codepoint_utf8_length((char32_t) *src++);
|
||||
char_len = utf32_codepoint_utf8_length((char32_t)*src++);
|
||||
}
|
||||
if (SSIZE_MAX - char_len < ret) {
|
||||
// If this happens, we would overflow the ssize_t type when
|
||||
// returning from this function, so we cannot express how
|
||||
// long this string is in an ssize_t.
|
||||
android_errorWriteLog(0x534e4554, "37723026");
|
||||
return -1;
|
||||
}
|
||||
ret += char_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -379,6 +379,22 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lfh_start_bytes;
|
||||
if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes),
|
||||
sizeof(uint32_t), 0)) {
|
||||
ALOGW("Zip: Unable to read header for entry at offset == 0.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfh_start_bytes != LocalFileHeader::kSignature) {
|
||||
ALOGW("Zip: Entry at offset zero has invalid LFH signature %" PRIx32, lfh_start_bytes);
|
||||
#if defined(__ANDROID__)
|
||||
android_errorWriteLog(0x534e4554, "64211847");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries);
|
||||
|
||||
return 0;
|
||||
|
|
230
lmkd/lmkd.c
230
lmkd/lmkd.c
|
@ -18,19 +18,21 @@
|
|||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include <log/log.h>
|
||||
#include <processgroup/processgroup.h>
|
||||
|
@ -40,7 +42,10 @@
|
|||
#endif
|
||||
|
||||
#define MEMCG_SYSFS_PATH "/dev/memcg/"
|
||||
#define MEMPRESSURE_WATCH_LEVEL "low"
|
||||
#define MEMCG_MEMORY_USAGE "/dev/memcg/memory.usage_in_bytes"
|
||||
#define MEMCG_MEMORYSW_USAGE "/dev/memcg/memory.memsw.usage_in_bytes"
|
||||
#define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium"
|
||||
#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
|
||||
#define ZONEINFO_PATH "/proc/zoneinfo"
|
||||
#define LINE_MAX 128
|
||||
|
||||
|
@ -48,6 +53,7 @@
|
|||
#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|
||||
#define EIGHT_MEGA (1 << 23)
|
||||
|
||||
enum lmk_cmd {
|
||||
LMK_TARGET,
|
||||
|
@ -64,17 +70,28 @@ enum lmk_cmd {
|
|||
|
||||
/* default to old in-kernel interface if no memory pressure events */
|
||||
static int use_inkernel_interface = 1;
|
||||
static bool has_inkernel_module;
|
||||
|
||||
/* memory pressure level medium event */
|
||||
static int mpevfd;
|
||||
static int mpevfd[2];
|
||||
#define CRITICAL_INDEX 1
|
||||
#define MEDIUM_INDEX 0
|
||||
|
||||
static int medium_oomadj;
|
||||
static int critical_oomadj;
|
||||
static bool debug_process_killing;
|
||||
static bool enable_pressure_upgrade;
|
||||
static int64_t upgrade_pressure;
|
||||
static int64_t downgrade_pressure;
|
||||
static bool is_go_device;
|
||||
|
||||
/* control socket listen and data */
|
||||
static int ctrl_lfd;
|
||||
static int ctrl_dfd = -1;
|
||||
static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */
|
||||
|
||||
/* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */
|
||||
#define MAX_EPOLL_EVENTS 3
|
||||
/* 2 memory pressure levels, 1 ctrl listen socket, 1 ctrl data socket */
|
||||
#define MAX_EPOLL_EVENTS 4
|
||||
static int epollfd;
|
||||
static int maxevents;
|
||||
|
||||
|
@ -113,14 +130,6 @@ static struct proc *pidhash[PIDHASH_SZ];
|
|||
#define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN)
|
||||
static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
|
||||
|
||||
/*
|
||||
* Wait 1-2 seconds for the death report of a killed process prior to
|
||||
* considering killing more processes.
|
||||
*/
|
||||
#define KILL_TIMEOUT 2
|
||||
/* Time of last process kill we initiated, stop me before I kill again */
|
||||
static time_t kill_lasttime;
|
||||
|
||||
/* PAGE_SIZE / 1024 */
|
||||
static long page_k;
|
||||
|
||||
|
@ -241,6 +250,7 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
|
|||
struct proc *procp;
|
||||
char path[80];
|
||||
char val[20];
|
||||
int soft_limit_mult;
|
||||
|
||||
if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
|
||||
ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
|
||||
|
@ -254,6 +264,38 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
|
|||
if (use_inkernel_interface)
|
||||
return;
|
||||
|
||||
if (oomadj >= 900) {
|
||||
soft_limit_mult = 0;
|
||||
} else if (oomadj >= 800) {
|
||||
soft_limit_mult = 0;
|
||||
} else if (oomadj >= 700) {
|
||||
soft_limit_mult = 0;
|
||||
} else if (oomadj >= 600) {
|
||||
// Launcher should be perceptible, don't kill it.
|
||||
oomadj = 200;
|
||||
soft_limit_mult = 1;
|
||||
} else if (oomadj >= 500) {
|
||||
soft_limit_mult = 0;
|
||||
} else if (oomadj >= 400) {
|
||||
soft_limit_mult = 0;
|
||||
} else if (oomadj >= 300) {
|
||||
soft_limit_mult = 1;
|
||||
} else if (oomadj >= 200) {
|
||||
soft_limit_mult = 2;
|
||||
} else if (oomadj >= 100) {
|
||||
soft_limit_mult = 10;
|
||||
} else if (oomadj >= 0) {
|
||||
soft_limit_mult = 20;
|
||||
} else {
|
||||
// Persistent processes will have a large
|
||||
// soft limit 512MB.
|
||||
soft_limit_mult = 64;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid);
|
||||
snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
|
||||
writefilestring(path, val);
|
||||
|
||||
procp = pid_lookup(pid);
|
||||
if (!procp) {
|
||||
procp = malloc(sizeof(struct proc));
|
||||
|
@ -278,7 +320,6 @@ static void cmd_procremove(int pid) {
|
|||
return;
|
||||
|
||||
pid_remove(pid);
|
||||
kill_lasttime = 0;
|
||||
}
|
||||
|
||||
static void cmd_target(int ntargets, int *params) {
|
||||
|
@ -294,7 +335,7 @@ static void cmd_target(int ntargets, int *params) {
|
|||
|
||||
lowmem_targets_size = ntargets;
|
||||
|
||||
if (use_inkernel_interface) {
|
||||
if (has_inkernel_module) {
|
||||
char minfreestr[128];
|
||||
char killpriostr[128];
|
||||
|
||||
|
@ -309,9 +350,9 @@ static void cmd_target(int ntargets, int *params) {
|
|||
strlcat(killpriostr, ",", sizeof(killpriostr));
|
||||
}
|
||||
|
||||
snprintf(val, sizeof(val), "%d", lowmem_minfree[i]);
|
||||
snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_minfree[i] : 0);
|
||||
strlcat(minfreestr, val, sizeof(minfreestr));
|
||||
snprintf(val, sizeof(val), "%d", lowmem_adj[i]);
|
||||
snprintf(val, sizeof(val), "%d", use_inkernel_interface ? lowmem_adj[i] : 0);
|
||||
strlcat(killpriostr, val, sizeof(killpriostr));
|
||||
}
|
||||
|
||||
|
@ -546,9 +587,7 @@ static struct proc *proc_adj_lru(int oomadj) {
|
|||
}
|
||||
|
||||
/* Kill one process specified by procp. Returns the size of the process killed */
|
||||
static int kill_one_process(struct proc *procp, int other_free, int other_file,
|
||||
int minfree, int min_score_adj, bool first)
|
||||
{
|
||||
static int kill_one_process(struct proc* procp, int min_score_adj, bool is_critical) {
|
||||
int pid = procp->pid;
|
||||
uid_t uid = procp->uid;
|
||||
char *taskname;
|
||||
|
@ -567,14 +606,12 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
|
|||
return -1;
|
||||
}
|
||||
|
||||
ALOGI("Killing '%s' (%d), uid %d, adj %d\n"
|
||||
" to free %ldkB because cache %s%ldkB is below limit %ldkB for oom_adj %d\n"
|
||||
" Free memory is %s%ldkB %s reserved",
|
||||
taskname, pid, uid, procp->oomadj, tasksize * page_k,
|
||||
first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj,
|
||||
first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below");
|
||||
ALOGI(
|
||||
"Killing '%s' (%d), uid %d, adj %d\n"
|
||||
" to free %ldkB because system is under %s memory pressure oom_adj %d\n",
|
||||
taskname, pid, uid, procp->oomadj, tasksize * page_k, is_critical ? "critical" : "medium",
|
||||
min_score_adj);
|
||||
r = kill(pid, SIGKILL);
|
||||
killProcessGroup(uid, pid, SIGKILL);
|
||||
pid_remove(pid);
|
||||
|
||||
if (r) {
|
||||
|
@ -589,23 +626,10 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
|
|||
* Find a process to kill based on the current (possibly estimated) free memory
|
||||
* and cached memory sizes. Returns the size of the killed processes.
|
||||
*/
|
||||
static int find_and_kill_process(int other_free, int other_file, bool first)
|
||||
{
|
||||
static int find_and_kill_process(bool is_critical) {
|
||||
int i;
|
||||
int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
|
||||
int minfree = 0;
|
||||
int killed_size = 0;
|
||||
|
||||
for (i = 0; i < lowmem_targets_size; i++) {
|
||||
minfree = lowmem_minfree[i];
|
||||
if (other_free < minfree && other_file < minfree) {
|
||||
min_score_adj = lowmem_adj[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_score_adj == OOM_SCORE_ADJ_MAX + 1)
|
||||
return 0;
|
||||
int min_score_adj = is_critical ? critical_oomadj : medium_oomadj;
|
||||
|
||||
for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
|
||||
struct proc *procp;
|
||||
|
@ -614,7 +638,7 @@ retry:
|
|||
procp = proc_adj_lru(i);
|
||||
|
||||
if (procp) {
|
||||
killed_size = kill_one_process(procp, other_free, other_file, minfree, min_score_adj, first);
|
||||
killed_size = kill_one_process(procp, min_score_adj, is_critical);
|
||||
if (killed_size < 0) {
|
||||
goto retry;
|
||||
} else {
|
||||
|
@ -626,42 +650,91 @@ retry:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mp_event(uint32_t events __unused) {
|
||||
static int64_t get_memory_usage(const char* path) {
|
||||
int ret;
|
||||
int64_t mem_usage;
|
||||
char buf[32];
|
||||
int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
ALOGE("%s open: errno=%d", path, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = read_all(fd, buf, sizeof(buf) - 1);
|
||||
close(fd);
|
||||
if (ret < 0) {
|
||||
ALOGE("%s error: errno=%d", path, errno);
|
||||
return -1;
|
||||
}
|
||||
sscanf(buf, "%" SCNd64, &mem_usage);
|
||||
if (mem_usage == 0) {
|
||||
ALOGE("No memory!");
|
||||
return -1;
|
||||
}
|
||||
return mem_usage;
|
||||
}
|
||||
|
||||
static void mp_event_common(bool is_critical) {
|
||||
int ret;
|
||||
unsigned long long evcount;
|
||||
struct sysmeminfo mi;
|
||||
int other_free;
|
||||
int other_file;
|
||||
int killed_size;
|
||||
bool first = true;
|
||||
int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
|
||||
int64_t mem_usage, memsw_usage;
|
||||
int64_t mem_pressure;
|
||||
|
||||
ret = read(mpevfd, &evcount, sizeof(evcount));
|
||||
ret = read(mpevfd[index], &evcount, sizeof(evcount));
|
||||
if (ret < 0)
|
||||
ALOGE("Error reading memory pressure event fd; errno=%d",
|
||||
errno);
|
||||
|
||||
if (time(NULL) - kill_lasttime < KILL_TIMEOUT)
|
||||
mem_usage = get_memory_usage(MEMCG_MEMORY_USAGE);
|
||||
memsw_usage = get_memory_usage(MEMCG_MEMORYSW_USAGE);
|
||||
if (memsw_usage < 0 || mem_usage < 0) {
|
||||
find_and_kill_process(is_critical);
|
||||
return;
|
||||
|
||||
while (zoneinfo_parse(&mi) < 0) {
|
||||
// Failed to read /proc/zoneinfo, assume ENOMEM and kill something
|
||||
find_and_kill_process(0, 0, true);
|
||||
}
|
||||
|
||||
other_free = mi.nr_free_pages - mi.totalreserve_pages;
|
||||
other_file = mi.nr_file_pages - mi.nr_shmem;
|
||||
// Calculate percent for swappinness.
|
||||
mem_pressure = (mem_usage * 100) / memsw_usage;
|
||||
|
||||
do {
|
||||
killed_size = find_and_kill_process(other_free, other_file, first);
|
||||
if (killed_size > 0) {
|
||||
first = false;
|
||||
other_free += killed_size;
|
||||
other_file += killed_size;
|
||||
if (enable_pressure_upgrade && !is_critical) {
|
||||
// We are swapping too much.
|
||||
if (mem_pressure < upgrade_pressure) {
|
||||
ALOGI("Event upgraded to critical.");
|
||||
is_critical = true;
|
||||
}
|
||||
} while (killed_size > 0);
|
||||
}
|
||||
|
||||
// If the pressure is larger than downgrade_pressure lmk will not
|
||||
// kill any process, since enough memory is available.
|
||||
if (mem_pressure > downgrade_pressure) {
|
||||
if (debug_process_killing) {
|
||||
ALOGI("Ignore %s memory pressure", is_critical ? "critical" : "medium");
|
||||
}
|
||||
return;
|
||||
} else if (is_critical && mem_pressure > upgrade_pressure) {
|
||||
if (debug_process_killing) {
|
||||
ALOGI("Downgrade critical memory pressure");
|
||||
}
|
||||
// Downgrade event to medium, since enough memory available.
|
||||
is_critical = false;
|
||||
}
|
||||
|
||||
if (find_and_kill_process(is_critical) == 0) {
|
||||
if (debug_process_killing) {
|
||||
ALOGI("Nothing to kill");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int init_mp(char *levelstr, void *event_handler)
|
||||
static void mp_event(uint32_t events __unused) {
|
||||
mp_event_common(false);
|
||||
}
|
||||
|
||||
static void mp_event_critical(uint32_t events __unused) {
|
||||
mp_event_common(true);
|
||||
}
|
||||
|
||||
static int init_mp_common(char *levelstr, void *event_handler, bool is_critical)
|
||||
{
|
||||
int mpfd;
|
||||
int evfd;
|
||||
|
@ -669,6 +742,7 @@ static int init_mp(char *levelstr, void *event_handler)
|
|||
char buf[256];
|
||||
struct epoll_event epev;
|
||||
int ret;
|
||||
int mpevfd_index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
|
||||
|
||||
mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
|
||||
if (mpfd < 0) {
|
||||
|
@ -709,7 +783,7 @@ static int init_mp(char *levelstr, void *event_handler)
|
|||
goto err;
|
||||
}
|
||||
maxevents++;
|
||||
mpevfd = evfd;
|
||||
mpevfd[mpevfd_index] = evfd;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
@ -722,6 +796,16 @@ err_open_mpfd:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int init_mp_medium()
|
||||
{
|
||||
return init_mp_common(MEMPRESSURE_WATCH_MEDIUM_LEVEL, (void *)&mp_event, false);
|
||||
}
|
||||
|
||||
static int init_mp_critical()
|
||||
{
|
||||
return init_mp_common(MEMPRESSURE_WATCH_CRITICAL_LEVEL, (void *)&mp_event_critical, true);
|
||||
}
|
||||
|
||||
static int init(void) {
|
||||
struct epoll_event epev;
|
||||
int i;
|
||||
|
@ -758,12 +842,14 @@ static int init(void) {
|
|||
}
|
||||
maxevents++;
|
||||
|
||||
use_inkernel_interface = !access(INKERNEL_MINFREE_PATH, W_OK);
|
||||
has_inkernel_module = !access(INKERNEL_MINFREE_PATH, W_OK);
|
||||
use_inkernel_interface = has_inkernel_module && !is_go_device;
|
||||
|
||||
if (use_inkernel_interface) {
|
||||
ALOGI("Using in-kernel low memory killer interface");
|
||||
} else {
|
||||
ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event);
|
||||
ret = init_mp_medium();
|
||||
ret |= init_mp_critical();
|
||||
if (ret)
|
||||
ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer");
|
||||
}
|
||||
|
@ -806,6 +892,14 @@ int main(int argc __unused, char **argv __unused) {
|
|||
.sched_priority = 1,
|
||||
};
|
||||
|
||||
medium_oomadj = property_get_int32("ro.lmk.medium", 800);
|
||||
critical_oomadj = property_get_int32("ro.lmk.critical", 0);
|
||||
debug_process_killing = property_get_bool("ro.lmk.debug", false);
|
||||
enable_pressure_upgrade = property_get_bool("ro.lmk.critical_upgrade", false);
|
||||
upgrade_pressure = (int64_t)property_get_int32("ro.lmk.upgrade_pressure", 50);
|
||||
downgrade_pressure = (int64_t)property_get_int32("ro.lmk.downgrade_pressure", 60);
|
||||
is_go_device = property_get_bool("ro.config.low_ram", false);
|
||||
|
||||
mlockall(MCL_FUTURE);
|
||||
sched_setscheduler(0, SCHED_FIFO, ¶m);
|
||||
if (!init())
|
||||
|
|
|
@ -63,7 +63,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
|
|||
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
|
||||
LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
|
||||
LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
|
||||
LOCAL_COMPATIBILITY_SUITE := cts
|
||||
LOCAL_COMPATIBILITY_SUITE := cts vts
|
||||
LOCAL_CTS_TEST_PACKAGE := android.core.logd
|
||||
include $(BUILD_CTS_EXECUTABLE)
|
||||
|
||||
|
|
|
@ -257,3 +257,45 @@ LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
|||
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
|
||||
include $(BUILD_PREBUILT)
|
||||
endif
|
||||
|
||||
#######################################
|
||||
# llndk.libraries.txt
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := llndk.libraries.txt
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
||||
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
|
||||
include $(BUILD_SYSTEM)/base_rules.mk
|
||||
llndk_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
|
||||
llndk_dep = $(intermediates)/$(llndk_md5).dep
|
||||
$(llndk_dep):
|
||||
$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
|
||||
|
||||
$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES := $(LLNDK_LIBRARIES)
|
||||
$(LOCAL_BUILT_MODULE): $(llndk_dep)
|
||||
@echo "Generate: $@"
|
||||
@mkdir -p $(dir $@)
|
||||
$(hide) echo -n > $@
|
||||
$(hide) $(foreach lib,$(PRIVATE_LLNDK_LIBRARIES), \
|
||||
echo $(lib).so >> $@;)
|
||||
|
||||
#######################################
|
||||
# vndksp.libraries.txt
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := vndksp.libraries.txt
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
|
||||
LOCAL_MODULE_STEM := $(LOCAL_MODULE)
|
||||
include $(BUILD_SYSTEM)/base_rules.mk
|
||||
vndksp_md5 = $(word 1, $(shell echo $(LLNDK_LIBRARIES) | $(MD5SUM)))
|
||||
vndksp_dep = $(intermediates)/$(vndksp_md5).dep
|
||||
$(vndksp_dep):
|
||||
$(hide) mkdir -p $(dir $@) && rm -rf $(dir $@)*.dep && touch $@
|
||||
|
||||
$(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SAMEPROCESS_LIBRARIES := $(VNDK_SAMEPROCESS_LIBRARIES)
|
||||
$(LOCAL_BUILT_MODULE): $(vndksp_dep)
|
||||
@echo "Generate: $@"
|
||||
@mkdir -p $(dir $@)
|
||||
$(hide) echo -n > $@
|
||||
$(hide) $(foreach lib,$(PRIVATE_VNDK_SAMEPROCESS_LIBRARIES), \
|
||||
echo $(lib).so >> $@;)
|
||||
|
|
|
@ -27,16 +27,12 @@ additional.namespaces = sphal,vndk,rs
|
|||
# can't be loaded in this namespace.
|
||||
###############################################################################
|
||||
namespace.default.isolated = true
|
||||
# TODO(b/63553457): remove /vendor/lib from the search path. For now, this is
|
||||
# required since the classloader namespace for vendor apks should have access
|
||||
# vendor libraries in the directory. These search paths are copied to the search
|
||||
# paths of the classloader namespace.
|
||||
namespace.default.search.paths = /system/${LIB}:/vendor/${LIB}
|
||||
namespace.default.search.paths = /system/${LIB}
|
||||
# /vendor/app, /vendor/framework were added since libart should be able to dlopen
|
||||
# the odex files from the directory.
|
||||
namespace.default.permitted.paths = /system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/data:/mnt/expand
|
||||
|
||||
namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}:/data/asan/vendor/${LIB}:/vendor/${LIB}
|
||||
namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}
|
||||
namespace.default.asan.permitted.paths = /data:/system/${LIB}/drm:/system/${LIB}/hw:/system/framework:/system/app:/system/priv-app:/vendor/app:/vendor/framework:/oem/app:/mnt/expand
|
||||
|
||||
###############################################################################
|
||||
|
@ -99,6 +95,7 @@ namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
|
|||
# This namespace is exclusively for vndk-sp libs.
|
||||
###############################################################################
|
||||
namespace.vndk.isolated = true
|
||||
namespace.vndk.visible = true
|
||||
namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
|
||||
namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
|
||||
|
||||
|
@ -135,9 +132,7 @@ namespace.default.asan.search.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}
|
|||
namespace.default.asan.permitted.paths = /data/asan/vendor:/vendor:/data/asan/system/${LIB}/vndk:/system/${LIB}/vndk:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
|
||||
|
||||
namespace.default.links = system
|
||||
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%:libmedia.so:libandroid_runtime.so
|
||||
# libmedia.so must be removed after we have fix for lib-dplmedia.so (b/64427765)
|
||||
# libandroid_runtime.so must be removed after we have a fix for qseeproxydaemon (b/64820887)
|
||||
namespace.default.link.system.shared_libs = %LLNDK_LIBRARIES%
|
||||
|
||||
###############################################################################
|
||||
# "system" namespace
|
||||
|
|
|
@ -15,6 +15,7 @@ liblog.so
|
|||
libmediandk.so
|
||||
libm.so
|
||||
libnativewindow.so
|
||||
libneuralnetworks.so
|
||||
libOpenMAXAL.so
|
||||
libOpenSLES.so
|
||||
libRS.so
|
||||
|
|
|
@ -15,6 +15,7 @@ liblog.so
|
|||
libmediandk.so
|
||||
libm.so
|
||||
libnativewindow.so
|
||||
libneuralnetworks.so
|
||||
libOpenMAXAL.so
|
||||
libOpenSLES.so
|
||||
libRS.so
|
||||
|
|
|
@ -148,6 +148,9 @@ on init
|
|||
write /proc/sys/net/ipv4/conf/all/accept_redirects 0
|
||||
write /proc/sys/net/ipv6/conf/all/accept_redirects 0
|
||||
|
||||
# /proc/net/fib_trie leaks interface IP addresses
|
||||
chmod 0400 /proc/net/fib_trie
|
||||
|
||||
# Create cgroup mount points for process groups
|
||||
mkdir /dev/cpuctl
|
||||
mount cgroup none /dev/cpuctl cpu
|
||||
|
|
|
@ -319,17 +319,31 @@ static void run(const char* source_path, const char* label, uid_t uid,
|
|||
LOG(FATAL) << "terminated prematurely";
|
||||
}
|
||||
|
||||
static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path, uid_t fsuid,
|
||||
gid_t fsgid, bool multi_user, userid_t userid, gid_t gid, mode_t mask) {
|
||||
std::string opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
|
||||
fsuid, fsgid, multi_user?"multiuser,":"", mask, userid, gid);
|
||||
static bool sdcardfs_setup(const std::string& source_path, const std::string& dest_path,
|
||||
uid_t fsuid, gid_t fsgid, bool multi_user, userid_t userid, gid_t gid,
|
||||
mode_t mask, bool derive_gid) {
|
||||
std::string opts = android::base::StringPrintf(
|
||||
"fsuid=%d,fsgid=%d,%s%smask=%d,userid=%d,gid=%d", fsuid, fsgid,
|
||||
multi_user ? "multiuser," : "", derive_gid ? "derive_gid," : "", mask, userid, gid);
|
||||
|
||||
if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
|
||||
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
|
||||
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
|
||||
return false;
|
||||
if (derive_gid) {
|
||||
PLOG(ERROR) << "trying to mount sdcardfs filesystem without derive_gid";
|
||||
/* Maybe this isn't supported on this kernel. Try without. */
|
||||
opts = android::base::StringPrintf("fsuid=%d,fsgid=%d,%smask=%d,userid=%d,gid=%d",
|
||||
fsuid, fsgid, multi_user ? "multiuser," : "", mask,
|
||||
userid, gid);
|
||||
if (mount(source_path.c_str(), dest_path.c_str(), "sdcardfs",
|
||||
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()) == -1) {
|
||||
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
PLOG(ERROR) << "failed to mount sdcardfs filesystem";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -355,7 +369,8 @@ static bool sdcardfs_setup_bind_remount(const std::string& source_path, const st
|
|||
}
|
||||
|
||||
static void run_sdcardfs(const std::string& source_path, const std::string& label, uid_t uid,
|
||||
gid_t gid, userid_t userid, bool multi_user, bool full_write) {
|
||||
gid_t gid, userid_t userid, bool multi_user, bool full_write,
|
||||
bool derive_gid) {
|
||||
std::string dest_path_default = "/mnt/runtime/default/" + label;
|
||||
std::string dest_path_read = "/mnt/runtime/read/" + label;
|
||||
std::string dest_path_write = "/mnt/runtime/write/" + label;
|
||||
|
@ -365,10 +380,10 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe
|
|||
// Multi-user storage is fully isolated per user, so "other"
|
||||
// permissions are completely masked off.
|
||||
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
|
||||
AID_SDCARD_RW, 0006)
|
||||
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027)
|
||||
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
|
||||
AID_EVERYBODY, full_write ? 0007 : 0027)) {
|
||||
AID_SDCARD_RW, 0006, derive_gid) ||
|
||||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY, 0027) ||
|
||||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
|
||||
full_write ? 0007 : 0027)) {
|
||||
LOG(FATAL) << "failed to sdcardfs_setup";
|
||||
}
|
||||
} else {
|
||||
|
@ -376,11 +391,11 @@ static void run_sdcardfs(const std::string& source_path, const std::string& labe
|
|||
// the Android directories are masked off to a single user
|
||||
// deep inside attr_from_stat().
|
||||
if (!sdcardfs_setup(source_path, dest_path_default, uid, gid, multi_user, userid,
|
||||
AID_SDCARD_RW, 0006)
|
||||
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_read,
|
||||
AID_EVERYBODY, full_write ? 0027 : 0022)
|
||||
|| !sdcardfs_setup_bind_remount(dest_path_default, dest_path_write,
|
||||
AID_EVERYBODY, full_write ? 0007 : 0022)) {
|
||||
AID_SDCARD_RW, 0006, derive_gid) ||
|
||||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_read, AID_EVERYBODY,
|
||||
full_write ? 0027 : 0022) ||
|
||||
!sdcardfs_setup_bind_remount(dest_path_default, dest_path_write, AID_EVERYBODY,
|
||||
full_write ? 0007 : 0022)) {
|
||||
LOG(FATAL) << "failed to sdcardfs_setup";
|
||||
}
|
||||
}
|
||||
|
@ -437,7 +452,8 @@ static int usage() {
|
|||
<< " -g: specify GID to run as"
|
||||
<< " -U: specify user ID that owns device"
|
||||
<< " -m: source_path is multi-user"
|
||||
<< " -w: runtime write mount has full write access";
|
||||
<< " -w: runtime write mount has full write access"
|
||||
<< " -P preserve owners on the lower file system";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -449,12 +465,13 @@ int main(int argc, char **argv) {
|
|||
userid_t userid = 0;
|
||||
bool multi_user = false;
|
||||
bool full_write = false;
|
||||
bool derive_gid = false;
|
||||
int i;
|
||||
struct rlimit rlim;
|
||||
int fs_version;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "u:g:U:mw")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "u:g:U:mwG")) != -1) {
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
uid = strtoul(optarg, NULL, 10);
|
||||
|
@ -471,6 +488,9 @@ int main(int argc, char **argv) {
|
|||
case 'w':
|
||||
full_write = true;
|
||||
break;
|
||||
case 'G':
|
||||
derive_gid = true;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
return usage();
|
||||
|
@ -514,7 +534,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (should_use_sdcardfs()) {
|
||||
run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write);
|
||||
run_sdcardfs(source_path, label, uid, gid, userid, multi_user, full_write, derive_gid);
|
||||
} else {
|
||||
run(source_path, label, uid, gid, userid, multi_user, full_write);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ LIBSTORAGED_SHARED_LIBRARIES := \
|
|||
libcutils \
|
||||
liblog \
|
||||
libsysutils \
|
||||
libpackagelistparser \
|
||||
libbatteryservice \
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
|
@ -256,6 +256,7 @@ private:
|
|||
uid_monitor mUidm;
|
||||
time_t mStarttime;
|
||||
sp<IBatteryPropertiesRegistrar> battery_properties;
|
||||
std::unique_ptr<storage_info_t> storage_info;
|
||||
public:
|
||||
storaged_t(void);
|
||||
~storaged_t() {}
|
||||
|
@ -285,6 +286,8 @@ public:
|
|||
void init_battery_service();
|
||||
virtual void batteryPropertiesChanged(struct BatteryProperties props);
|
||||
void binderDied(const wp<IBinder>& who);
|
||||
|
||||
void report_storage_info();
|
||||
};
|
||||
|
||||
// Eventlog tag
|
||||
|
|
|
@ -27,39 +27,46 @@ using namespace std;
|
|||
class storage_info_t {
|
||||
protected:
|
||||
FRIEND_TEST(storaged_test, storage_info_t);
|
||||
// emmc lifetime
|
||||
uint16_t eol; // pre-eol (end of life) information
|
||||
uint16_t lifetime_a; // device life time estimation (type A)
|
||||
uint16_t lifetime_b; // device life time estimation (type B)
|
||||
string version; // version string
|
||||
// free space
|
||||
const string userdata_path = "/data";
|
||||
uint64_t userdata_total_kb;
|
||||
uint64_t userdata_free_kb;
|
||||
|
||||
storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0),
|
||||
userdata_total_kb(0), userdata_free_kb(0) {}
|
||||
void publish();
|
||||
storage_info_t* s_info;
|
||||
public:
|
||||
storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {}
|
||||
static storage_info_t* get_storage_info();
|
||||
virtual ~storage_info_t() {}
|
||||
virtual bool report() = 0;
|
||||
virtual void report() {};
|
||||
void refresh();
|
||||
};
|
||||
|
||||
class emmc_info_t : public storage_info_t {
|
||||
private:
|
||||
const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
|
||||
const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
|
||||
const char* emmc_ver_str[9] = {
|
||||
"4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
|
||||
};
|
||||
public:
|
||||
virtual ~emmc_info_t() {}
|
||||
bool report();
|
||||
bool report_sysfs();
|
||||
bool report_debugfs();
|
||||
public:
|
||||
static const string emmc_sysfs;
|
||||
static const string emmc_debugfs;
|
||||
static const char* emmc_ver_str[];
|
||||
|
||||
virtual ~emmc_info_t() {}
|
||||
virtual void report();
|
||||
};
|
||||
|
||||
class ufs_info_t : public storage_info_t {
|
||||
private:
|
||||
const string health_file = "/sys/devices/soc/624000.ufshc/health";
|
||||
public:
|
||||
static const string health_file;
|
||||
|
||||
virtual ~ufs_info_t() {}
|
||||
bool report();
|
||||
virtual void report();
|
||||
};
|
||||
|
||||
void report_storage_health();
|
||||
|
||||
#endif /* _STORAGED_INFO_H_ */
|
||||
|
|
|
@ -49,6 +49,7 @@ void* storaged_main(void* /* unused */) {
|
|||
storaged = new storaged_t();
|
||||
|
||||
storaged->init_battery_service();
|
||||
storaged->report_storage_info();
|
||||
|
||||
LOG_TO(SYSTEM, INFO) << "storaged: Start";
|
||||
|
||||
|
@ -113,7 +114,6 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (flag_main_service) { // start main thread
|
||||
report_storage_health();
|
||||
// Start the main thread of storaged
|
||||
pthread_t storaged_main_thread;
|
||||
errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL);
|
||||
|
|
|
@ -200,6 +200,10 @@ void storaged_t::binderDied(const wp<IBinder>& who) {
|
|||
}
|
||||
}
|
||||
|
||||
void storaged_t::report_storage_info() {
|
||||
storage_info->report();
|
||||
}
|
||||
|
||||
/* storaged_t */
|
||||
storaged_t::storaged_t(void) {
|
||||
if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) {
|
||||
|
@ -222,6 +226,8 @@ storaged_t::storaged_t(void) {
|
|||
mConfig.periodic_chores_interval_uid_io =
|
||||
property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO);
|
||||
|
||||
storage_info.reset(storage_info_t::get_storage_info());
|
||||
|
||||
mStarttime = time(NULL);
|
||||
}
|
||||
|
||||
|
@ -229,6 +235,7 @@ void storaged_t::event(void) {
|
|||
if (mConfig.diskstats_available) {
|
||||
mDiskStats.update();
|
||||
mDsm.update();
|
||||
storage_info->refresh();
|
||||
if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) {
|
||||
mDiskStats.publish();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/parseint.h>
|
||||
|
@ -30,13 +31,42 @@
|
|||
using namespace std;
|
||||
using namespace android::base;
|
||||
|
||||
void report_storage_health()
|
||||
{
|
||||
emmc_info_t mmc;
|
||||
ufs_info_t ufs;
|
||||
const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
|
||||
const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
|
||||
const char* emmc_info_t::emmc_ver_str[9] = {
|
||||
"4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
|
||||
};
|
||||
|
||||
mmc.report();
|
||||
ufs.report();
|
||||
const string ufs_info_t::health_file = "/sys/devices/soc/624000.ufshc/health";
|
||||
|
||||
static bool FileExists(const std::string& filename)
|
||||
{
|
||||
struct stat buffer;
|
||||
return stat(filename.c_str(), &buffer) == 0;
|
||||
}
|
||||
|
||||
storage_info_t* storage_info_t::get_storage_info()
|
||||
{
|
||||
if (FileExists(emmc_info_t::emmc_sysfs) ||
|
||||
FileExists(emmc_info_t::emmc_debugfs)) {
|
||||
return new emmc_info_t;
|
||||
}
|
||||
if (FileExists(ufs_info_t::health_file)) {
|
||||
return new ufs_info_t;
|
||||
}
|
||||
return new storage_info_t;
|
||||
}
|
||||
|
||||
void storage_info_t::refresh()
|
||||
{
|
||||
struct statvfs buf;
|
||||
if (statvfs(userdata_path.c_str(), &buf) != 0) {
|
||||
PLOG_TO(SYSTEM, WARNING) << "Failed to get userdata info";
|
||||
return;
|
||||
}
|
||||
|
||||
userdata_total_kb = buf.f_bsize * buf.f_blocks >> 10;
|
||||
userdata_free_kb = buf.f_bfree * buf.f_blocks >> 10;
|
||||
}
|
||||
|
||||
void storage_info_t::publish()
|
||||
|
@ -46,13 +76,12 @@ void storage_info_t::publish()
|
|||
<< LOG_ID_EVENTS;
|
||||
}
|
||||
|
||||
bool emmc_info_t::report()
|
||||
void emmc_info_t::report()
|
||||
{
|
||||
if (!report_sysfs() && !report_debugfs())
|
||||
return false;
|
||||
return;
|
||||
|
||||
publish();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool emmc_info_t::report_sysfs()
|
||||
|
@ -136,21 +165,21 @@ bool emmc_info_t::report_debugfs()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ufs_info_t::report()
|
||||
void ufs_info_t::report()
|
||||
{
|
||||
string buffer;
|
||||
if (!ReadFileToString(health_file, &buffer)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> lines = Split(buffer, "\n");
|
||||
if (lines.empty()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
char rev[8];
|
||||
if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
version = "ufs " + string(rev);
|
||||
|
@ -175,10 +204,9 @@ bool ufs_info_t::report()
|
|||
}
|
||||
|
||||
if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
publish();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,33 +22,24 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <android/content/pm/IPackageManagerNative.h>
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/logging.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <android-base/parseint.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <log/log_event_list.h>
|
||||
#include <packagelistparser/packagelistparser.h>
|
||||
|
||||
#include "storaged.h"
|
||||
#include "storaged_uid_monitor.h"
|
||||
|
||||
using namespace android;
|
||||
using namespace android::base;
|
||||
using namespace android::content::pm;
|
||||
|
||||
static bool packagelist_parse_cb(pkg_info* info, void* userdata)
|
||||
{
|
||||
std::unordered_map<uint32_t, struct uid_info>* uids =
|
||||
reinterpret_cast<std::unordered_map<uint32_t, struct uid_info>*>(userdata);
|
||||
|
||||
if (uids->find(info->uid) != uids->end()) {
|
||||
(*uids)[info->uid].name = info->name;
|
||||
}
|
||||
|
||||
packagelist_free(info);
|
||||
return true;
|
||||
}
|
||||
static bool refresh_uid_names;
|
||||
|
||||
std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats()
|
||||
{
|
||||
|
@ -56,6 +47,38 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats()
|
|||
return get_uid_io_stats_locked();
|
||||
};
|
||||
|
||||
static void get_uid_names(const vector<int>& uids, const vector<std::string*>& uid_names)
|
||||
{
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
if (sm == NULL) {
|
||||
LOG_TO(SYSTEM, ERROR) << "defaultServiceManager failed";
|
||||
return;
|
||||
}
|
||||
|
||||
sp<IBinder> binder = sm->getService(String16("package_native"));
|
||||
if (binder == NULL) {
|
||||
LOG_TO(SYSTEM, ERROR) << "getService package_native failed";
|
||||
return;
|
||||
}
|
||||
|
||||
sp<IPackageManagerNative> package_mgr = interface_cast<IPackageManagerNative>(binder);
|
||||
std::vector<std::string> names;
|
||||
binder::Status status = package_mgr->getNamesForUids(uids, &names);
|
||||
if (!status.isOk()) {
|
||||
LOG_TO(SYSTEM, ERROR) << "package_native::getNamesForUids failed: "
|
||||
<< status.exceptionMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < uid_names.size(); i++) {
|
||||
if (!names[i].empty()) {
|
||||
*uid_names[i] = names[i];
|
||||
}
|
||||
}
|
||||
|
||||
refresh_uid_names = false;
|
||||
}
|
||||
|
||||
std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_locked()
|
||||
{
|
||||
std::unordered_map<uint32_t, struct uid_info> uid_io_stats;
|
||||
|
@ -67,7 +90,8 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_lock
|
|||
|
||||
std::vector<std::string> io_stats = Split(buffer, "\n");
|
||||
struct uid_info u;
|
||||
bool refresh_uid = false;
|
||||
vector<int> uids;
|
||||
vector<std::string*> uid_names;
|
||||
|
||||
for (uint32_t i = 0; i < io_stats.size(); i++) {
|
||||
if (io_stats[i].empty()) {
|
||||
|
@ -91,17 +115,19 @@ std::unordered_map<uint32_t, struct uid_info> uid_monitor::get_uid_io_stats_lock
|
|||
continue;
|
||||
}
|
||||
|
||||
if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) {
|
||||
refresh_uid = true;
|
||||
u.name = std::to_string(u.uid);
|
||||
} else {
|
||||
u.name = last_uid_io_stats[u.uid].name;
|
||||
}
|
||||
uid_io_stats[u.uid] = u;
|
||||
uid_io_stats[u.uid].name = std::to_string(u.uid);
|
||||
uids.push_back(u.uid);
|
||||
uid_names.push_back(&uid_io_stats[u.uid].name);
|
||||
if (last_uid_io_stats.find(u.uid) == last_uid_io_stats.end()) {
|
||||
refresh_uid_names = true;
|
||||
} else {
|
||||
uid_io_stats[u.uid].name = last_uid_io_stats[u.uid].name;
|
||||
}
|
||||
}
|
||||
|
||||
if (refresh_uid) {
|
||||
packagelist_parse(packagelist_parse_cb, &uid_io_stats);
|
||||
if (!uids.empty() && refresh_uid_names) {
|
||||
get_uid_names(uids, uid_names);
|
||||
}
|
||||
|
||||
return uid_io_stats;
|
||||
|
@ -228,13 +254,13 @@ void uid_monitor::update_curr_io_stats_locked()
|
|||
last_uid_io_stats[uid.uid].io[BACKGROUND].write_bytes;
|
||||
|
||||
usage.bytes[READ][FOREGROUND][charger_stat] +=
|
||||
(fg_rd_delta < 0) ? uid.io[FOREGROUND].read_bytes : fg_rd_delta;
|
||||
(fg_rd_delta < 0) ? 0 : fg_rd_delta;
|
||||
usage.bytes[READ][BACKGROUND][charger_stat] +=
|
||||
(bg_rd_delta < 0) ? uid.io[BACKGROUND].read_bytes : bg_rd_delta;
|
||||
(bg_rd_delta < 0) ? 0 : bg_rd_delta;
|
||||
usage.bytes[WRITE][FOREGROUND][charger_stat] +=
|
||||
(fg_wr_delta < 0) ? uid.io[FOREGROUND].write_bytes : fg_wr_delta;
|
||||
(fg_wr_delta < 0) ? 0 : fg_wr_delta;
|
||||
usage.bytes[WRITE][BACKGROUND][charger_stat] +=
|
||||
(bg_wr_delta < 0) ? uid.io[BACKGROUND].write_bytes : bg_wr_delta;
|
||||
(bg_wr_delta < 0) ? 0 : bg_wr_delta;
|
||||
}
|
||||
|
||||
last_uid_io_stats = uid_io_stats;
|
||||
|
|
|
@ -2,6 +2,5 @@ subdirs = [
|
|||
"gatekeeper",
|
||||
"keymaster",
|
||||
"libtrusty",
|
||||
"nvram",
|
||||
"storage/*",
|
||||
]
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
cc_library_shared {
|
||||
name: "gatekeeper.trusty",
|
||||
vendor: true,
|
||||
|
||||
relative_install_path: "hw",
|
||||
|
||||
|
@ -43,4 +44,5 @@ cc_library_shared {
|
|||
"libcutils",
|
||||
"libtrusty",
|
||||
],
|
||||
header_libs: ["libhardware_headers"],
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
// and ECDSA keys.
|
||||
cc_binary {
|
||||
name: "trusty_keymaster_tipc",
|
||||
vendor: true,
|
||||
srcs: [
|
||||
"trusty_keymaster_device.cpp",
|
||||
"trusty_keymaster_ipc.cpp",
|
||||
|
@ -46,6 +47,7 @@ cc_binary {
|
|||
// keystore.trusty is the HAL used by keystore on Trusty devices.
|
||||
cc_library_shared {
|
||||
name: "keystore.trusty",
|
||||
vendor: true,
|
||||
relative_install_path: "hw",
|
||||
srcs: [
|
||||
"module.cpp",
|
||||
|
@ -66,4 +68,5 @@ cc_library_shared {
|
|||
"liblog",
|
||||
"libcutils",
|
||||
],
|
||||
header_libs: ["libhardware_headers"],
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ subdirs = [
|
|||
|
||||
cc_library {
|
||||
name: "libtrusty",
|
||||
vendor: true,
|
||||
|
||||
srcs: ["trusty.c"],
|
||||
export_include_dirs: ["include"],
|
||||
|
|
|
@ -14,12 +14,14 @@
|
|||
|
||||
cc_test {
|
||||
name: "tipc-test",
|
||||
static_executable: true,
|
||||
vendor: true,
|
||||
|
||||
srcs: ["tipc_test.c"],
|
||||
static_libs: [
|
||||
"libc",
|
||||
"libtrusty",
|
||||
],
|
||||
shared_libs: [
|
||||
"libc",
|
||||
"liblog",
|
||||
],
|
||||
gtest: false,
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2016 The Android Open-Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// nvram.trusty is the Trusty NVRAM HAL module.
|
||||
cc_library_shared {
|
||||
name: "nvram.trusty",
|
||||
relative_install_path: "hw",
|
||||
srcs: [
|
||||
"module.c",
|
||||
"trusty_nvram_device.cpp",
|
||||
"trusty_nvram_implementation.cpp",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
"-fvisibility=hidden",
|
||||
],
|
||||
static_libs: ["libnvram-hal"],
|
||||
shared_libs: [
|
||||
"libtrusty",
|
||||
"libnvram-messages",
|
||||
"liblog",
|
||||
],
|
||||
}
|
||||
|
||||
// nvram-wipe is a helper tool for clearing NVRAM state.
|
||||
cc_binary {
|
||||
name: "nvram-wipe",
|
||||
srcs: [
|
||||
"nvram_wipe.cpp",
|
||||
"trusty_nvram_implementation.cpp",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wextra",
|
||||
"-fvisibility=hidden",
|
||||
],
|
||||
static_libs: ["libnvram-hal"],
|
||||
shared_libs: [
|
||||
"libtrusty",
|
||||
"libnvram-messages",
|
||||
"liblog",
|
||||
],
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <hardware/nvram.h>
|
||||
|
||||
// This function is defined in trusty_nvram_device.cpp.
|
||||
int trusty_nvram_open(const hw_module_t* module,
|
||||
const char* device_id,
|
||||
hw_device_t** device_ptr);
|
||||
|
||||
static struct hw_module_methods_t nvram_module_methods = {
|
||||
.open = trusty_nvram_open,
|
||||
};
|
||||
|
||||
struct nvram_module HAL_MODULE_INFO_SYM
|
||||
__attribute__((visibility("default"))) = {
|
||||
.common = {.tag = HARDWARE_MODULE_TAG,
|
||||
.module_api_version = NVRAM_MODULE_API_VERSION_0_1,
|
||||
.hal_api_version = HARDWARE_HAL_API_VERSION,
|
||||
.id = NVRAM_HARDWARE_MODULE_ID,
|
||||
.name = "Trusty NVRAM HAL",
|
||||
.author = "The Android Open Source Project",
|
||||
.methods = &nvram_module_methods,
|
||||
.dso = 0,
|
||||
.reserved = {}},
|
||||
};
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nvram/messages/nvram_messages.h>
|
||||
|
||||
#include "trusty_nvram_implementation.h"
|
||||
|
||||
void usage(const char* program_name) {
|
||||
fprintf(stderr, "Usage: %s [status|disable|wipe]\n", program_name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
nvram::TrustyNvramImplementation nvram_proxy;
|
||||
nvram::Request request;
|
||||
nvram::Response response;
|
||||
|
||||
if (!strcmp(argv[1], "status")) {
|
||||
request.payload.Activate<nvram::COMMAND_GET_INFO>();
|
||||
nvram_proxy.Execute(request, &response);
|
||||
const nvram::GetInfoResponse* get_info_response =
|
||||
response.payload.get<nvram::COMMAND_GET_INFO>();
|
||||
if (response.result == NV_RESULT_SUCCESS) {
|
||||
int status = get_info_response && get_info_response->wipe_disabled;
|
||||
printf("Wiping disabled: %d\n", status);
|
||||
return status;
|
||||
}
|
||||
} else if (!strcmp(argv[1], "disable")) {
|
||||
request.payload.Activate<nvram::COMMAND_DISABLE_WIPE>();
|
||||
nvram_proxy.Execute(request, &response);
|
||||
} else if (!strcmp(argv[1], "wipe")) {
|
||||
request.payload.Activate<nvram::COMMAND_WIPE_STORAGE>();
|
||||
nvram_proxy.Execute(request, &response);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (response.result != NV_RESULT_SUCCESS) {
|
||||
fprintf(stderr, "Command execution failure: %u\n", response.result);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <nvram/hal/nvram_device_adapter.h>
|
||||
|
||||
#include "trusty_nvram_implementation.h"
|
||||
|
||||
extern "C" int trusty_nvram_open(const hw_module_t* module,
|
||||
const char* device_id,
|
||||
hw_device_t** device_ptr) {
|
||||
if (strcmp(NVRAM_HARDWARE_DEVICE_ID, device_id) != 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nvram::NvramDeviceAdapter* adapter = new nvram::NvramDeviceAdapter(
|
||||
module, new nvram::TrustyNvramImplementation);
|
||||
*device_ptr = adapter->as_device();
|
||||
return 0;
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "TrustyNVRAM"
|
||||
|
||||
#include "trusty_nvram_implementation.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <hardware/nvram.h>
|
||||
#include <log/log.h>
|
||||
#include <trusty/tipc.h>
|
||||
|
||||
#include <nvram/messages/blob.h>
|
||||
|
||||
namespace nvram {
|
||||
namespace {
|
||||
|
||||
// Character device to open for Trusty IPC connections.
|
||||
const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
|
||||
|
||||
// App identifier of the NVRAM app.
|
||||
const char kTrustyNvramAppId[] = "com.android.trusty.nvram";
|
||||
|
||||
} // namespace
|
||||
|
||||
TrustyNvramImplementation::~TrustyNvramImplementation() {
|
||||
if (tipc_nvram_fd_ != -1) {
|
||||
tipc_close(tipc_nvram_fd_);
|
||||
tipc_nvram_fd_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void TrustyNvramImplementation::Execute(const nvram::Request& request,
|
||||
nvram::Response* response) {
|
||||
if (!SendRequest(request, response)) {
|
||||
response->result = NV_RESULT_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
bool TrustyNvramImplementation::Connect() {
|
||||
if (tipc_nvram_fd_ != -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int rc = tipc_connect(kTrustyDeviceName, kTrustyNvramAppId);
|
||||
if (rc < 0) {
|
||||
ALOGE("Failed to connect to Trusty NVRAM app: %s\n", strerror(-rc));
|
||||
return false;
|
||||
}
|
||||
|
||||
tipc_nvram_fd_ = rc;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TrustyNvramImplementation::SendRequest(const nvram::Request& request,
|
||||
nvram::Response* response) {
|
||||
if (!Connect()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nvram::Blob request_buffer;
|
||||
if (!nvram::Encode(request, &request_buffer)) {
|
||||
ALOGE("Failed to encode NVRAM request.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t rc =
|
||||
write(tipc_nvram_fd_, request_buffer.data(), request_buffer.size());
|
||||
if (rc < 0) {
|
||||
ALOGE("Failed to send NVRAM request: %s\n", strerror(-rc));
|
||||
return false;
|
||||
}
|
||||
if (static_cast<size_t>(rc) != request_buffer.size()) {
|
||||
ALOGE("Failed to send full request buffer: %zd\n", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = read(tipc_nvram_fd_, response_buffer_, sizeof(response_buffer_));
|
||||
if (rc < 0) {
|
||||
ALOGE("Failed to read NVRAM response: %s\n", strerror(-rc));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static_cast<size_t>(rc) >= sizeof(response_buffer_)) {
|
||||
ALOGE("NVRAM response exceeds response buffer size.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nvram::Decode(response_buffer_, static_cast<size_t>(rc), response)) {
|
||||
ALOGE("Failed to decode NVRAM response.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace nvram
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
|
||||
#define TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <nvram/hal/nvram_device_adapter.h>
|
||||
#include <nvram/messages/nvram_messages.h>
|
||||
|
||||
namespace nvram {
|
||||
|
||||
// |TrustyNvramImplementation| proxies requests to the Trusty NVRAM app. It
|
||||
// serializes the request objects, sends it to the Trusty app and finally reads
|
||||
// back the result and decodes it.
|
||||
class TrustyNvramImplementation : public nvram::NvramImplementation {
|
||||
public:
|
||||
~TrustyNvramImplementation() override;
|
||||
|
||||
void Execute(const nvram::Request& request,
|
||||
nvram::Response* response) override;
|
||||
|
||||
private:
|
||||
// Connects the IPC channel to the Trusty app if it is not already open.
|
||||
// Returns true if the channel is open, false on errors.
|
||||
bool Connect();
|
||||
|
||||
// Dispatches a command to the trust app. Returns true if successful (note
|
||||
// that the response may still indicate an error on the Trusty side), false if
|
||||
// there are any I/O or encoding/decoding errors.
|
||||
bool SendRequest(const nvram::Request& request,
|
||||
nvram::Response* response);
|
||||
|
||||
// The file descriptor for the IPC connection to the Trusty app.
|
||||
int tipc_nvram_fd_ = -1;
|
||||
|
||||
// Response buffer. This puts a hard size limit on the responses from the
|
||||
// Trusty app. 4096 matches the maximum IPC message size currently supported
|
||||
// by Trusty.
|
||||
uint8_t response_buffer_[4096];
|
||||
};
|
||||
|
||||
} // namespace nvram
|
||||
|
||||
#endif // TRUSTY_NVRAM_TRUSTY_NVRAM_IMPLEMENTATION_H_
|
|
@ -16,5 +16,6 @@
|
|||
|
||||
cc_library_static {
|
||||
name: "libtrustystorageinterface",
|
||||
vendor: true,
|
||||
export_include_dirs: ["include"],
|
||||
}
|
||||
|
|
|
@ -16,16 +16,19 @@
|
|||
|
||||
cc_library_static {
|
||||
name: "libtrustystorage",
|
||||
vendor: true,
|
||||
|
||||
srcs: ["storage.c"],
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
static_libs: [
|
||||
"liblog",
|
||||
"libtrusty",
|
||||
"libtrustystorageinterface",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
],
|
||||
|
||||
cflags: [
|
||||
"-fvisibility=hidden",
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
cc_binary {
|
||||
name: "storageproxyd",
|
||||
vendor: true,
|
||||
|
||||
srcs: [
|
||||
"ipc.c",
|
||||
|
@ -25,6 +26,7 @@ cc_binary {
|
|||
],
|
||||
|
||||
shared_libs: ["liblog"],
|
||||
header_libs: ["libcutils_headers"],
|
||||
|
||||
static_libs: [
|
||||
"libtrustystorageinterface",
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <cutils/android_filesystem_config.h>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "log.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
cc_test {
|
||||
name: "secure-storage-unit-test",
|
||||
vendor: true,
|
||||
|
||||
cflags: [
|
||||
"-g",
|
||||
|
@ -28,6 +29,8 @@ cc_test {
|
|||
"libtrustystorageinterface",
|
||||
"libtrustystorage",
|
||||
"libtrusty",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
],
|
||||
|
||||
|
|
Loading…
Reference in New Issue