summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs_mgr/Android.mk1
-rw-r--r--fs_mgr/fs_mgr_format.cpp91
-rw-r--r--gatekeeperd/Android.mk3
-rw-r--r--gatekeeperd/IUserManager.cpp57
-rw-r--r--gatekeeperd/IUserManager.h46
-rw-r--r--gatekeeperd/gatekeeperd.cpp19
-rw-r--r--healthd/Android.bp7
-rw-r--r--init/init.cpp1
-rw-r--r--libappfuse/FuseBridgeLoop.cc6
-rw-r--r--libappfuse/tests/FuseBridgeLoopTest.cc1
-rw-r--r--liblog/Android.bp23
-rw-r--r--liblog/include/log/log_main.h9
-rw-r--r--liblog/tests/Android.mk2
-rw-r--r--libsync/libsync.map.txt4
-rw-r--r--libutils/Android.bp7
-rw-r--r--lmkd/lmkd.c120
-rw-r--r--logd/tests/Android.mk2
-rw-r--r--rootdir/Android.mk2
-rw-r--r--rootdir/etc/ld.config.txt4
-rw-r--r--rootdir/init.rc5
-rw-r--r--storaged/include/storaged.h3
-rw-r--r--storaged/include/storaged_info.h37
-rw-r--r--storaged/main.cpp2
-rw-r--r--storaged/storaged.cpp7
-rw-r--r--storaged/storaged_info.cpp56
25 files changed, 229 insertions, 286 deletions
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index f3ca7246f..924934308 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -21,6 +21,7 @@ LOCAL_SRC_FILES:= fs_mgr_main.cpp
21LOCAL_C_INCLUDES := $(LOCAL_PATH)/include 21LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
22LOCAL_MODULE:= fs_mgr 22LOCAL_MODULE:= fs_mgr
23LOCAL_MODULE_TAGS := optional 23LOCAL_MODULE_TAGS := optional
24LOCAL_REQUIRED_MODULES := mke2fs mke2fs.conf e2fsdroid
24LOCAL_FORCE_STATIC_EXECUTABLE := true 25LOCAL_FORCE_STATIC_EXECUTABLE := true
25LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin 26LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
26LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) 27LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index a03d92c6b..fc88217ce 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -24,21 +24,16 @@
24#include <cutils/partition_utils.h> 24#include <cutils/partition_utils.h>
25#include <sys/mount.h> 25#include <sys/mount.h>
26 26
27#include <ext4_utils/ext4_utils.h>
28#include <ext4_utils/ext4.h> 27#include <ext4_utils/ext4.h>
29#include <ext4_utils/make_ext4fs.h> 28#include <ext4_utils/ext4_utils.h>
30#include <selinux/selinux.h> 29#include <logwrap/logwrap.h>
31#include <selinux/label.h>
32#include <selinux/android.h> 30#include <selinux/android.h>
31#include <selinux/label.h>
32#include <selinux/selinux.h>
33 33
34#include "fs_mgr_priv.h" 34#include "fs_mgr_priv.h"
35#include "cryptfs.h" 35#include "cryptfs.h"
36 36
37extern "C" {
38extern struct fs_info info; /* magic global from ext4_utils */
39extern void reset_ext4fs_info();
40}
41
42static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer) 37static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
43{ 38{
44 uint64_t dev_sz; 39 uint64_t dev_sz;
@@ -55,30 +50,36 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
55 return -1; 50 return -1;
56 } 51 }
57 52
58 struct selabel_handle *sehandle = selinux_android_file_context_handle(); 53 close(fd);
59 if (!sehandle) {
60 /* libselinux logs specific error */
61 LERROR << "Cannot initialize android file_contexts";
62 close(fd);
63 return -1;
64 }
65 54
66 /* Format the partition using the calculated length */ 55 /* Format the partition using the calculated length */
67 reset_ext4fs_info();
68 info.len = (off64_t)dev_sz;
69 if (crypt_footer) { 56 if (crypt_footer) {
70 info.len -= CRYPT_FOOTER_OFFSET; 57 dev_sz -= CRYPT_FOOTER_OFFSET;
71 } 58 }
72 59
73 /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */ 60 std::string size_str = std::to_string(dev_sz / 4096);
74 rc = make_ext4fs_internal(fd, NULL, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, sehandle, 0, 0, NULL, NULL, NULL); 61 const char* const mke2fs_args[] = {
62 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
63
64 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
65 true, LOG_KLOG, true, nullptr, nullptr, 0);
75 if (rc) { 66 if (rc) {
76 LERROR << "make_ext4fs returned " << rc; 67 LERROR << "mke2fs returned " << rc;
68 return rc;
77 } 69 }
78 close(fd);
79 70
80 if (sehandle) { 71 const char* const e2fsdroid_args[] = {
81 selabel_close(sehandle); 72 "/system/bin/e2fsdroid",
73 "-e",
74 "-a",
75 fs_mnt_point,
76 fs_blkdev,
77 nullptr};
78
79 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
80 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
81 if (rc) {
82 LERROR << "e2fsdroid returned " << rc;
82 } 83 }
83 84
84 return rc; 85 return rc;
@@ -86,44 +87,10 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
86 87
87static int format_f2fs(char *fs_blkdev) 88static int format_f2fs(char *fs_blkdev)
88{ 89{
89 char * args[5]; 90 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
90 int pid;
91 int rc = 0;
92
93 args[0] = (char *)"/system/bin/make_f2fs";
94 args[1] = (char *)"-f";
95 args[2] = (char *)"-O encrypt";
96 args[3] = fs_blkdev;
97 args[4] = (char *)0;
98
99 pid = fork();
100 if (pid < 0) {
101 return pid;
102 }
103 if (!pid) {
104 /* This doesn't return */
105 execv(args[0], args);
106 exit(1);
107 }
108 for(;;) {
109 pid_t p = waitpid(pid, &rc, 0);
110 if (p != pid) {
111 LERROR << "Error waiting for child process - " << p;
112 rc = -1;
113 break;
114 }
115 if (WIFEXITED(rc)) {
116 rc = WEXITSTATUS(rc);
117 LINFO << args[0] << " done, status " << rc;
118 if (rc) {
119 rc = -1;
120 }
121 break;
122 }
123 LERROR << "Still waiting for " << args[0] << "...";
124 }
125 91
126 return rc; 92 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
93 LOG_KLOG, true, nullptr, nullptr, 0);
127} 94}
128 95
129int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer) 96int fs_mgr_do_format(struct fstab_rec *fstab, bool crypt_footer)
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 0dfd9d8a9..28f0b07ab 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
21LOCAL_SRC_FILES := \ 21LOCAL_SRC_FILES := \
22 SoftGateKeeperDevice.cpp \ 22 SoftGateKeeperDevice.cpp \
23 IGateKeeperService.cpp \ 23 IGateKeeperService.cpp \
24 gatekeeperd.cpp \ 24 gatekeeperd.cpp
25 IUserManager.cpp
26 25
27LOCAL_MODULE := gatekeeperd 26LOCAL_MODULE := gatekeeperd
28LOCAL_SHARED_LIBRARIES := \ 27LOCAL_SHARED_LIBRARIES := \
diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserManager.cpp
deleted file mode 100644
index 8167d1919..000000000
--- a/gatekeeperd/IUserManager.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "IUserManager"
18#include <stdint.h>
19#include <sys/types.h>
20#include <utils/Log.h>
21#include <binder/Parcel.h>
22
23#include "IUserManager.h"
24
25namespace android {
26
27class BpUserManager : public BpInterface<IUserManager>
28{
29public:
30 explicit BpUserManager(const sp<IBinder>& impl) :
31 BpInterface<IUserManager>(impl) {
32 }
33 virtual int32_t getCredentialOwnerProfile(int32_t user_id) {
34 Parcel data, reply;
35 data.writeInterfaceToken(IUserManager::getInterfaceDescriptor());
36 data.writeInt32(user_id);
37 status_t rc = remote()->transact(GET_CREDENTIAL_OWNER_PROFILE, data, &reply, 0);
38 if (rc != NO_ERROR) {
39 ALOGE("%s: failed (%d)\n", __func__, rc);
40 return -1;
41 }
42
43 int32_t exception = reply.readExceptionCode();
44 if (exception != 0) {
45 ALOGE("%s: got exception (%d)\n", __func__, exception);
46 return -1;
47 }
48
49 return reply.readInt32();
50 }
51
52};
53
54IMPLEMENT_META_INTERFACE(UserManager, "android.os.IUserManager");
55
56}; // namespace android
57
diff --git a/gatekeeperd/IUserManager.h b/gatekeeperd/IUserManager.h
deleted file mode 100644
index 640e9b511..000000000
--- a/gatekeeperd/IUserManager.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef IUSERMANAGER_H_
18#define IUSERMANAGER_H_
19
20#include <inttypes.h>
21#include <utils/Errors.h>
22#include <binder/IInterface.h>
23#include <binder/Parcel.h>
24#include <utils/Vector.h>
25
26namespace android {
27
28/*
29* Communication channel to UserManager
30*/
31class IUserManager : public IInterface {
32 public:
33 // must be kept in sync with IUserManager.aidl
34 enum {
35 GET_CREDENTIAL_OWNER_PROFILE = IBinder::FIRST_CALL_TRANSACTION + 0,
36 };
37
38 virtual int32_t getCredentialOwnerProfile(int32_t user_id) = 0;
39
40 DECLARE_META_INTERFACE(UserManager);
41};
42
43}; // namespace android
44
45#endif // IUSERMANAGER_H_
46
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index c6369f9ed..184c6d222 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -37,7 +37,6 @@
37#include <utils/String16.h> 37#include <utils/String16.h>
38 38
39#include "SoftGateKeeperDevice.h" 39#include "SoftGateKeeperDevice.h"
40#include "IUserManager.h"
41 40
42#include <hidl/HidlSupport.h> 41#include <hidl/HidlSupport.h>
43#include <android/hardware/gatekeeper/1.0/IGatekeeper.h> 42#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
@@ -334,23 +333,7 @@ public:
334 return ret; 333 return ret;
335 } 334 }
336 335
337 virtual uint64_t getSecureUserId(uint32_t uid) { 336 virtual uint64_t getSecureUserId(uint32_t uid) { return read_sid(uid); }
338 uint64_t sid = read_sid(uid);
339 if (sid == 0) {
340 // might be a work profile, look up the parent
341 sp<IServiceManager> sm = defaultServiceManager();
342 sp<IBinder> binder = sm->getService(String16("user"));
343 sp<IUserManager> um = interface_cast<IUserManager>(binder);
344 int32_t parent = um->getCredentialOwnerProfile(uid);
345 if (parent < 0) {
346 return 0;
347 } else if (parent != (int32_t) uid) {
348 return read_sid(parent);
349 }
350 }
351 return sid;
352
353 }
354 337
355 virtual void clearSecureUserId(uint32_t uid) { 338 virtual void clearSecureUserId(uint32_t uid) {
356 IPCThreadState* ipc = IPCThreadState::self(); 339 IPCThreadState* ipc = IPCThreadState::self();
diff --git a/healthd/Android.bp b/healthd/Android.bp
new file mode 100644
index 000000000..56f5148ca
--- /dev/null
+++ b/healthd/Android.bp
@@ -0,0 +1,7 @@
1cc_library_headers {
2 name: "libhealthd_headers",
3 vendor_available: true,
4 export_include_dirs: ["include"],
5 header_libs: ["libbatteryservice_headers"],
6 export_header_lib_headers: ["libbatteryservice_headers"],
7}
diff --git a/init/init.cpp b/init/init.cpp
index 8f726d89a..24f863c74 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -920,7 +920,6 @@ static void selinux_restore_context() {
920 selinux_android_restorecon("/dev/urandom", 0); 920 selinux_android_restorecon("/dev/urandom", 0);
921 selinux_android_restorecon("/dev/__properties__", 0); 921 selinux_android_restorecon("/dev/__properties__", 0);
922 922
923 selinux_android_restorecon("/file_contexts.bin", 0);
924 selinux_android_restorecon("/plat_file_contexts", 0); 923 selinux_android_restorecon("/plat_file_contexts", 0);
925 selinux_android_restorecon("/nonplat_file_contexts", 0); 924 selinux_android_restorecon("/nonplat_file_contexts", 0);
926 selinux_android_restorecon("/plat_property_contexts", 0); 925 selinux_android_restorecon("/plat_property_contexts", 0);
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 07923071b..8b0c53eb2 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -179,7 +179,11 @@ class FuseBridgeEntry {
179 } 179 }
180 180
181 const uint32_t opcode = buffer_.request.header.opcode; 181 const uint32_t opcode = buffer_.request.header.opcode;
182 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode; 182 const uint64_t unique = buffer_.request.header.unique;
183 LOG(VERBOSE) << "Read a fuse packet, opcode=" << opcode << " unique=" << unique;
184 if (unique == 0) {
185 return FuseBridgeState::kWaitToReadEither;
186 }
183 switch (opcode) { 187 switch (opcode) {
184 case FUSE_FORGET: 188 case FUSE_FORGET:
185 // Do not reply to FUSE_FORGET. 189 // Do not reply to FUSE_FORGET.
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index 51d605136..0a28451bf 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -67,6 +67,7 @@ class FuseBridgeLoopTest : public ::testing::Test {
67 memset(&request_, 0, sizeof(FuseRequest)); 67 memset(&request_, 0, sizeof(FuseRequest));
68 request_.header.opcode = opcode; 68 request_.header.opcode = opcode;
69 request_.header.len = sizeof(fuse_in_header); 69 request_.header.len = sizeof(fuse_in_header);
70 request_.header.unique = 1;
70 ASSERT_TRUE(request_.Write(dev_sockets_[0])); 71 ASSERT_TRUE(request_.Write(dev_sockets_[0]));
71 72
72 memset(&response_, 0, sizeof(FuseResponse)); 73 memset(&response_, 0, sizeof(FuseResponse));
diff --git a/liblog/Android.bp b/liblog/Android.bp
index e74aa8283..b98d18ff6 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -42,6 +42,24 @@ liblog_target_sources = [
42 "logd_writer.c", 42 "logd_writer.c",
43] 43]
44 44
45cc_library_headers {
46 name: "liblog_headers",
47 host_supported: true,
48 vendor_available: true,
49 export_include_dirs: ["include"],
50 target: {
51 windows: {
52 enabled: true,
53 },
54 linux_bionic: {
55 enabled: true,
56 },
57 vendor: {
58 export_include_dirs: ["include_vndk"],
59 },
60 },
61}
62
45// Shared and static library for host and device 63// Shared and static library for host and device
46// ======================================================== 64// ========================================================
47cc_library { 65cc_library {
@@ -81,7 +99,8 @@ cc_library {
81 }, 99 },
82 }, 100 },
83 101
84 export_include_dirs: ["include"], 102 header_libs: ["liblog_headers"],
103 export_header_lib_headers: ["liblog_headers"],
85 104
86 cflags: [ 105 cflags: [
87 "-Werror", 106 "-Werror",
@@ -100,7 +119,7 @@ cc_library {
100} 119}
101 120
102ndk_headers { 121ndk_headers {
103 name: "liblog_headers", 122 name: "liblog_ndk_headers",
104 from: "include/android", 123 from: "include/android",
105 to: "android", 124 to: "android",
106 srcs: ["include/android/log.h"], 125 srcs: ["include/android/log.h"],
diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h
index da1615828..68c2e9af6 100644
--- a/liblog/include/log/log_main.h
+++ b/liblog/include/log/log_main.h
@@ -18,10 +18,9 @@
18#define _LIBS_LOG_LOG_MAIN_H 18#define _LIBS_LOG_LOG_MAIN_H
19 19
20#include <android/log.h> 20#include <android/log.h>
21#include <sys/cdefs.h>
21 22
22#ifdef __cplusplus 23__BEGIN_DECLS
23extern "C" {
24#endif
25 24
26/* 25/*
27 * Normally we strip the effects of ALOGV (VERBOSE messages), 26 * Normally we strip the effects of ALOGV (VERBOSE messages),
@@ -385,8 +384,6 @@ int __android_log_is_loggable_len(int prio, const char* tag, size_t len,
385#pragma clang diagnostic pop 384#pragma clang diagnostic pop
386#endif 385#endif
387 386
388#ifdef __cplusplus 387__END_DECLS
389}
390#endif
391 388
392#endif /* _LIBS_LOG_LOG_MAIN_H */ 389#endif /* _LIBS_LOG_LOG_MAIN_H */
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index ab964295c..91044ab75 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -89,7 +89,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
89LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 89LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
90LOCAL_SHARED_LIBRARIES := liblog libcutils libbase 90LOCAL_SHARED_LIBRARIES := liblog libcutils libbase
91LOCAL_STATIC_LIBRARIES := libgtest libgtest_main 91LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
92LOCAL_COMPATIBILITY_SUITE := cts 92LOCAL_COMPATIBILITY_SUITE := cts vts
93LOCAL_CTS_TEST_PACKAGE := android.core.liblog 93LOCAL_CTS_TEST_PACKAGE := android.core.liblog
94include $(BUILD_CTS_EXECUTABLE) 94include $(BUILD_CTS_EXECUTABLE)
95 95
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index daa28ae92..f9057bd7f 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -17,8 +17,8 @@
17LIBSYNC { 17LIBSYNC {
18 global: 18 global:
19 sync_merge; # introduced=26 19 sync_merge; # introduced=26
20 sync_get_fence_info; # introduced=26 20 sync_file_info; # introduced=26
21 sync_free_fence_info; # introduced=26 21 sync_file_info_free; # introduced=26
22 local: 22 local:
23 *; 23 *;
24}; 24};
diff --git a/libutils/Android.bp b/libutils/Android.bp
index a1bdbf32f..9e7cc138c 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -18,10 +18,12 @@ cc_library_headers {
18 host_supported: true, 18 host_supported: true,
19 19
20 header_libs: [ 20 header_libs: [
21 "liblog_headers",
21 "libsystem_headers", 22 "libsystem_headers",
22 "libcutils_headers" 23 "libcutils_headers"
23 ], 24 ],
24 export_header_lib_headers: [ 25 export_header_lib_headers: [
26 "liblog_headers",
25 "libsystem_headers", 27 "libsystem_headers",
26 "libcutils_headers" 28 "libcutils_headers"
27 ], 29 ],
@@ -78,6 +80,10 @@ cc_library {
78 "libutils_headers", 80 "libutils_headers",
79 ], 81 ],
80 82
83 shared_libs: [
84 "liblog",
85 ],
86
81 arch: { 87 arch: {
82 mips: { 88 mips: {
83 cflags: ["-DALIGN_DOUBLE"], 89 cflags: ["-DALIGN_DOUBLE"],
@@ -98,7 +104,6 @@ cc_library {
98 "libbacktrace", 104 "libbacktrace",
99 "libcutils", 105 "libcutils",
100 "libdl", 106 "libdl",
101 "liblog",
102 "libvndksupport", 107 "libvndksupport",
103 ], 108 ],
104 109
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 8a6168cd3..c0953158d 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -40,7 +40,8 @@
40#endif 40#endif
41 41
42#define MEMCG_SYSFS_PATH "/dev/memcg/" 42#define MEMCG_SYSFS_PATH "/dev/memcg/"
43#define MEMPRESSURE_WATCH_LEVEL "low" 43#define MEMPRESSURE_WATCH_MEDIUM_LEVEL "medium"
44#define MEMPRESSURE_WATCH_CRITICAL_LEVEL "critical"
44#define ZONEINFO_PATH "/proc/zoneinfo" 45#define ZONEINFO_PATH "/proc/zoneinfo"
45#define LINE_MAX 128 46#define LINE_MAX 128
46 47
@@ -48,6 +49,7 @@
48#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj" 49#define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
49 50
50#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) 51#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
52#define EIGHT_MEGA (1 << 23)
51 53
52enum lmk_cmd { 54enum lmk_cmd {
53 LMK_TARGET, 55 LMK_TARGET,
@@ -66,15 +68,17 @@ enum lmk_cmd {
66static int use_inkernel_interface = 1; 68static int use_inkernel_interface = 1;
67 69
68/* memory pressure level medium event */ 70/* memory pressure level medium event */
69static int mpevfd; 71static int mpevfd[2];
72#define CRITICAL_INDEX 1
73#define MEDIUM_INDEX 0
70 74
71/* control socket listen and data */ 75/* control socket listen and data */
72static int ctrl_lfd; 76static int ctrl_lfd;
73static int ctrl_dfd = -1; 77static int ctrl_dfd = -1;
74static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */ 78static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */
75 79
76/* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */ 80/* 2 memory pressure levels, 1 ctrl listen socket, 1 ctrl data socket */
77#define MAX_EPOLL_EVENTS 3 81#define MAX_EPOLL_EVENTS 4
78static int epollfd; 82static int epollfd;
79static int maxevents; 83static int maxevents;
80 84
@@ -113,14 +117,6 @@ static struct proc *pidhash[PIDHASH_SZ];
113#define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN) 117#define ADJTOSLOT(adj) ((adj) + -OOM_SCORE_ADJ_MIN)
114static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1]; 118static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
115 119
116/*
117 * Wait 1-2 seconds for the death report of a killed process prior to
118 * considering killing more processes.
119 */
120#define KILL_TIMEOUT 2
121/* Time of last process kill we initiated, stop me before I kill again */
122static time_t kill_lasttime;
123
124/* PAGE_SIZE / 1024 */ 120/* PAGE_SIZE / 1024 */
125static long page_k; 121static long page_k;
126 122
@@ -241,6 +237,7 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
241 struct proc *procp; 237 struct proc *procp;
242 char path[80]; 238 char path[80];
243 char val[20]; 239 char val[20];
240 int soft_limit_mult;
244 241
245 if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) { 242 if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
246 ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj); 243 ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
@@ -254,6 +251,36 @@ static void cmd_procprio(int pid, int uid, int oomadj) {
254 if (use_inkernel_interface) 251 if (use_inkernel_interface)
255 return; 252 return;
256 253
254 if (oomadj >= 900) {
255 soft_limit_mult = 0;
256 } else if (oomadj >= 800) {
257 soft_limit_mult = 0;
258 } else if (oomadj >= 700) {
259 soft_limit_mult = 0;
260 } else if (oomadj >= 600) {
261 soft_limit_mult = 0;
262 } else if (oomadj >= 500) {
263 soft_limit_mult = 0;
264 } else if (oomadj >= 400) {
265 soft_limit_mult = 0;
266 } else if (oomadj >= 300) {
267 soft_limit_mult = 1;
268 } else if (oomadj >= 200) {
269 soft_limit_mult = 2;
270 } else if (oomadj >= 100) {
271 soft_limit_mult = 10;
272 } else if (oomadj >= 0) {
273 soft_limit_mult = 20;
274 } else {
275 // Persistent processes will have a large
276 // soft limit 512MB.
277 soft_limit_mult = 64;
278 }
279
280 snprintf(path, sizeof(path), "/dev/memcg/apps/uid_%d/pid_%d/memory.soft_limit_in_bytes", uid, pid);
281 snprintf(val, sizeof(val), "%d", soft_limit_mult * EIGHT_MEGA);
282 writefilestring(path, val);
283
257 procp = pid_lookup(pid); 284 procp = pid_lookup(pid);
258 if (!procp) { 285 if (!procp) {
259 procp = malloc(sizeof(struct proc)); 286 procp = malloc(sizeof(struct proc));
@@ -278,7 +305,6 @@ static void cmd_procremove(int pid) {
278 return; 305 return;
279 306
280 pid_remove(pid); 307 pid_remove(pid);
281 kill_lasttime = 0;
282} 308}
283 309
284static void cmd_target(int ntargets, int *params) { 310static void cmd_target(int ntargets, int *params) {
@@ -574,7 +600,6 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
574 first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj, 600 first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj,
575 first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below"); 601 first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below");
576 r = kill(pid, SIGKILL); 602 r = kill(pid, SIGKILL);
577 killProcessGroup(uid, pid, SIGKILL);
578 pid_remove(pid); 603 pid_remove(pid);
579 604
580 if (r) { 605 if (r) {
@@ -589,24 +614,12 @@ static int kill_one_process(struct proc *procp, int other_free, int other_file,
589 * Find a process to kill based on the current (possibly estimated) free memory 614 * Find a process to kill based on the current (possibly estimated) free memory
590 * and cached memory sizes. Returns the size of the killed processes. 615 * and cached memory sizes. Returns the size of the killed processes.
591 */ 616 */
592static int find_and_kill_process(int other_free, int other_file, bool first) 617static int find_and_kill_process(int other_free, int other_file, bool first, int min_score_adj)
593{ 618{
594 int i; 619 int i;
595 int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
596 int minfree = 0; 620 int minfree = 0;
597 int killed_size = 0; 621 int killed_size = 0;
598 622
599 for (i = 0; i < lowmem_targets_size; i++) {
600 minfree = lowmem_minfree[i];
601 if (other_free < minfree && other_file < minfree) {
602 min_score_adj = lowmem_adj[i];
603 break;
604 }
605 }
606
607 if (min_score_adj == OOM_SCORE_ADJ_MAX + 1)
608 return 0;
609
610 for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) { 623 for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
611 struct proc *procp; 624 struct proc *procp;
612 625
@@ -626,42 +639,33 @@ retry:
626 return 0; 639 return 0;
627} 640}
628 641
629static void mp_event(uint32_t events __unused) { 642static void mp_event_common(bool is_critical) {
630 int ret; 643 int ret;
631 unsigned long long evcount; 644 unsigned long long evcount;
632 struct sysmeminfo mi;
633 int other_free;
634 int other_file;
635 int killed_size;
636 bool first = true; 645 bool first = true;
646 int min_adj_score = is_critical ? 0 : 800;
647 int index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
637 648
638 ret = read(mpevfd, &evcount, sizeof(evcount)); 649 ret = read(mpevfd[index], &evcount, sizeof(evcount));
639 if (ret < 0) 650 if (ret < 0)
640 ALOGE("Error reading memory pressure event fd; errno=%d", 651 ALOGE("Error reading memory pressure event fd; errno=%d",
641 errno); 652 errno);
642 653
643 if (time(NULL) - kill_lasttime < KILL_TIMEOUT) 654 if (find_and_kill_process(0, 0, first, min_adj_score) == 0) {
644 return; 655 ALOGI("Nothing to kill");
645
646 while (zoneinfo_parse(&mi) < 0) {
647 // Failed to read /proc/zoneinfo, assume ENOMEM and kill something
648 find_and_kill_process(0, 0, true);
649 } 656 }
657}
650 658
651 other_free = mi.nr_free_pages - mi.totalreserve_pages; 659static void mp_event(uint32_t events __unused) {
652 other_file = mi.nr_file_pages - mi.nr_shmem; 660 mp_event_common(false);
661}
653 662
654 do { 663static void mp_event_critical(uint32_t events __unused) {
655 killed_size = find_and_kill_process(other_free, other_file, first); 664 ALOGI("Memory pressure critical");
656 if (killed_size > 0) { 665 mp_event_common(true);
657 first = false;
658 other_free += killed_size;
659 other_file += killed_size;
660 }
661 } while (killed_size > 0);
662} 666}
663 667
664static int init_mp(char *levelstr, void *event_handler) 668static int init_mp_common(char *levelstr, void *event_handler, bool is_critical)
665{ 669{
666 int mpfd; 670 int mpfd;
667 int evfd; 671 int evfd;
@@ -669,6 +673,7 @@ static int init_mp(char *levelstr, void *event_handler)
669 char buf[256]; 673 char buf[256];
670 struct epoll_event epev; 674 struct epoll_event epev;
671 int ret; 675 int ret;
676 int mpevfd_index = is_critical ? CRITICAL_INDEX : MEDIUM_INDEX;
672 677
673 mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC); 678 mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
674 if (mpfd < 0) { 679 if (mpfd < 0) {
@@ -709,7 +714,7 @@ static int init_mp(char *levelstr, void *event_handler)
709 goto err; 714 goto err;
710 } 715 }
711 maxevents++; 716 maxevents++;
712 mpevfd = evfd; 717 mpevfd[mpevfd_index] = evfd;
713 return 0; 718 return 0;
714 719
715err: 720err:
@@ -722,6 +727,16 @@ err_open_mpfd:
722 return -1; 727 return -1;
723} 728}
724 729
730static int init_mp_medium()
731{
732 return init_mp_common(MEMPRESSURE_WATCH_MEDIUM_LEVEL, (void *)&mp_event, false);
733}
734
735static int init_mp_critical()
736{
737 return init_mp_common(MEMPRESSURE_WATCH_CRITICAL_LEVEL, (void *)&mp_event_critical, true);
738}
739
725static int init(void) { 740static int init(void) {
726 struct epoll_event epev; 741 struct epoll_event epev;
727 int i; 742 int i;
@@ -763,7 +778,8 @@ static int init(void) {
763 if (use_inkernel_interface) { 778 if (use_inkernel_interface) {
764 ALOGI("Using in-kernel low memory killer interface"); 779 ALOGI("Using in-kernel low memory killer interface");
765 } else { 780 } else {
766 ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event); 781 ret = init_mp_medium();
782 ret |= init_mp_critical();
767 if (ret) 783 if (ret)
768 ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer"); 784 ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer");
769 } 785 }
diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk
index 191567721..a0875ea99 100644
--- a/logd/tests/Android.mk
+++ b/logd/tests/Android.mk
@@ -63,7 +63,7 @@ LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
63LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64 63LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
64LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux 64LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
65LOCAL_STATIC_LIBRARIES := libgtest libgtest_main 65LOCAL_STATIC_LIBRARIES := libgtest libgtest_main
66LOCAL_COMPATIBILITY_SUITE := cts 66LOCAL_COMPATIBILITY_SUITE := cts vts
67LOCAL_CTS_TEST_PACKAGE := android.core.logd 67LOCAL_CTS_TEST_PACKAGE := android.core.logd
68include $(BUILD_CTS_EXECUTABLE) 68include $(BUILD_CTS_EXECUTABLE)
69 69
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 2e5575fd0..046557eb2 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -194,7 +194,7 @@ bcp_dep :=
194include $(CLEAR_VARS) 194include $(CLEAR_VARS)
195 195
196LOCAL_MODULE := ld.config.txt 196LOCAL_MODULE := ld.config.txt
197ifeq ($(PRODUCT_FULL_TREBLE),true) 197ifeq ($(PRODUCT_FULL_TREBLE)|$(SANITIZE_TARGET),true|)
198LOCAL_SRC_FILES := etc/ld.config.txt 198LOCAL_SRC_FILES := etc/ld.config.txt
199else 199else
200LOCAL_SRC_FILES := etc/ld.config.legacy.txt 200LOCAL_SRC_FILES := etc/ld.config.legacy.txt
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 56066bcf2..3cb5c1dde 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -97,10 +97,10 @@ namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:androi
97# This namespace is exclusively for vndk-sp libs. 97# This namespace is exclusively for vndk-sp libs.
98############################################################################### 98###############################################################################
99namespace.vndk.isolated = true 99namespace.vndk.isolated = true
100namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB} 100namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
101namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl 101namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
102 102
103namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB} 103namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp
104namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl 104namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl
105 105
106# When these NDK libs are required inside this namespace, then it is redirected 106# When these NDK libs are required inside this namespace, then it is redirected
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 424dbee75..901d06636 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -321,7 +321,6 @@ on post-fs
321 # Make sure /sys/kernel/debug (if present) is labeled properly 321 # Make sure /sys/kernel/debug (if present) is labeled properly
322 # Note that tracefs may be mounted under debug, so we need to cross filesystems 322 # Note that tracefs may be mounted under debug, so we need to cross filesystems
323 restorecon --recursive --cross-filesystems /sys/kernel/debug 323 restorecon --recursive --cross-filesystems /sys/kernel/debug
324 chmod 0755 /sys/kernel/debug/tracing
325 324
326 # We chown/chmod /cache again so because mount is run as root + defaults 325 # We chown/chmod /cache again so because mount is run as root + defaults
327 chown system cache /cache 326 chown system cache /cache
@@ -359,6 +358,10 @@ on post-fs
359 mkdir /cache/lost+found 0770 root root 358 mkdir /cache/lost+found 0770 root root
360 359
361on late-fs 360on late-fs
361 # Ensure that tracefs has the correct permissions.
362 # This does not work correctly if it is called in post-fs.
363 chmod 0755 /sys/kernel/debug/tracing
364
362 # HALs required before storage encryption can get unlocked (FBE/FDE) 365 # HALs required before storage encryption can get unlocked (FBE/FDE)
363 class_start early_hal 366 class_start early_hal
364 367
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 514798bff..fa6840638 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -256,6 +256,7 @@ private:
256 uid_monitor mUidm; 256 uid_monitor mUidm;
257 time_t mStarttime; 257 time_t mStarttime;
258 sp<IBatteryPropertiesRegistrar> battery_properties; 258 sp<IBatteryPropertiesRegistrar> battery_properties;
259 std::unique_ptr<storage_info_t> storage_info;
259public: 260public:
260 storaged_t(void); 261 storaged_t(void);
261 ~storaged_t() {} 262 ~storaged_t() {}
@@ -285,6 +286,8 @@ public:
285 void init_battery_service(); 286 void init_battery_service();
286 virtual void batteryPropertiesChanged(struct BatteryProperties props); 287 virtual void batteryPropertiesChanged(struct BatteryProperties props);
287 void binderDied(const wp<IBinder>& who); 288 void binderDied(const wp<IBinder>& who);
289
290 void report_storage_info();
288}; 291};
289 292
290// Eventlog tag 293// Eventlog tag
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index 913c814ac..7d04c7a0d 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -27,39 +27,46 @@ using namespace std;
27class storage_info_t { 27class storage_info_t {
28protected: 28protected:
29 FRIEND_TEST(storaged_test, storage_info_t); 29 FRIEND_TEST(storaged_test, storage_info_t);
30 // emmc lifetime
30 uint16_t eol; // pre-eol (end of life) information 31 uint16_t eol; // pre-eol (end of life) information
31 uint16_t lifetime_a; // device life time estimation (type A) 32 uint16_t lifetime_a; // device life time estimation (type A)
32 uint16_t lifetime_b; // device life time estimation (type B) 33 uint16_t lifetime_b; // device life time estimation (type B)
33 string version; // version string 34 string version; // version string
35 // free space
36 const string userdata_path = "/data";
37 uint64_t userdata_total_kb;
38 uint64_t userdata_free_kb;
39
40 storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0),
41 userdata_total_kb(0), userdata_free_kb(0) {}
34 void publish(); 42 void publish();
43 storage_info_t* s_info;
35public: 44public:
36 storage_info_t() : eol(0), lifetime_a(0), lifetime_b(0) {} 45 static storage_info_t* get_storage_info();
37 virtual ~storage_info_t() {} 46 virtual ~storage_info_t() {}
38 virtual bool report() = 0; 47 virtual void report() {};
48 void refresh();
39}; 49};
40 50
41class emmc_info_t : public storage_info_t { 51class emmc_info_t : public storage_info_t {
42private: 52private:
43 const string emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
44 const string emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
45 const char* emmc_ver_str[9] = {
46 "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
47 };
48public:
49 virtual ~emmc_info_t() {}
50 bool report();
51 bool report_sysfs(); 53 bool report_sysfs();
52 bool report_debugfs(); 54 bool report_debugfs();
55public:
56 static const string emmc_sysfs;
57 static const string emmc_debugfs;
58 static const char* emmc_ver_str[];
59
60 virtual ~emmc_info_t() {}
61 virtual void report();
53}; 62};
54 63
55class ufs_info_t : public storage_info_t { 64class ufs_info_t : public storage_info_t {
56private:
57 const string health_file = "/sys/devices/soc/624000.ufshc/health";
58public: 65public:
66 static const string health_file;
67
59 virtual ~ufs_info_t() {} 68 virtual ~ufs_info_t() {}
60 bool report(); 69 virtual void report();
61}; 70};
62 71
63void report_storage_health();
64
65#endif /* _STORAGED_INFO_H_ */ 72#endif /* _STORAGED_INFO_H_ */
diff --git a/storaged/main.cpp b/storaged/main.cpp
index 4d1e43014..6b82904d2 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -49,6 +49,7 @@ void* storaged_main(void* /* unused */) {
49 storaged = new storaged_t(); 49 storaged = new storaged_t();
50 50
51 storaged->init_battery_service(); 51 storaged->init_battery_service();
52 storaged->report_storage_info();
52 53
53 LOG_TO(SYSTEM, INFO) << "storaged: Start"; 54 LOG_TO(SYSTEM, INFO) << "storaged: Start";
54 55
@@ -113,7 +114,6 @@ int main(int argc, char** argv) {
113 } 114 }
114 115
115 if (flag_main_service) { // start main thread 116 if (flag_main_service) { // start main thread
116 report_storage_health();
117 // Start the main thread of storaged 117 // Start the main thread of storaged
118 pthread_t storaged_main_thread; 118 pthread_t storaged_main_thread;
119 errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL); 119 errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL);
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 54d429cd8..06afea693 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -200,6 +200,10 @@ void storaged_t::binderDied(const wp<IBinder>& who) {
200 } 200 }
201} 201}
202 202
203void storaged_t::report_storage_info() {
204 storage_info->report();
205}
206
203/* storaged_t */ 207/* storaged_t */
204storaged_t::storaged_t(void) { 208storaged_t::storaged_t(void) {
205 if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) { 209 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) {
222 mConfig.periodic_chores_interval_uid_io = 226 mConfig.periodic_chores_interval_uid_io =
223 property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO); 227 property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO);
224 228
229 storage_info.reset(storage_info_t::get_storage_info());
230
225 mStarttime = time(NULL); 231 mStarttime = time(NULL);
226} 232}
227 233
@@ -229,6 +235,7 @@ void storaged_t::event(void) {
229 if (mConfig.diskstats_available) { 235 if (mConfig.diskstats_available) {
230 mDiskStats.update(); 236 mDiskStats.update();
231 mDsm.update(); 237 mDsm.update();
238 storage_info->refresh();
232 if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) { 239 if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) {
233 mDiskStats.publish(); 240 mDiskStats.publish();
234 } 241 }
diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp
index 434bd74ae..b5fb13e0c 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -18,6 +18,7 @@
18 18
19#include <stdio.h> 19#include <stdio.h>
20#include <string.h> 20#include <string.h>
21#include <sys/statvfs.h>
21 22
22#include <android-base/file.h> 23#include <android-base/file.h>
23#include <android-base/parseint.h> 24#include <android-base/parseint.h>
@@ -30,13 +31,42 @@
30using namespace std; 31using namespace std;
31using namespace android::base; 32using namespace android::base;
32 33
33void report_storage_health() 34const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
35const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
36const char* emmc_info_t::emmc_ver_str[9] = {
37 "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0", "5.1"
38};
39
40const string ufs_info_t::health_file = "/sys/devices/soc/624000.ufshc/health";
41
42static bool FileExists(const std::string& filename)
43{
44 struct stat buffer;
45 return stat(filename.c_str(), &buffer) == 0;
46}
47
48storage_info_t* storage_info_t::get_storage_info()
49{
50 if (FileExists(emmc_info_t::emmc_sysfs) ||
51 FileExists(emmc_info_t::emmc_debugfs)) {
52 return new emmc_info_t;
53 }
54 if (FileExists(ufs_info_t::health_file)) {
55 return new ufs_info_t;
56 }
57 return new storage_info_t;
58}
59
60void storage_info_t::refresh()
34{ 61{
35 emmc_info_t mmc; 62 struct statvfs buf;
36 ufs_info_t ufs; 63 if (statvfs(userdata_path.c_str(), &buf) != 0) {
64 PLOG_TO(SYSTEM, WARNING) << "Failed to get userdata info";
65 return;
66 }
37 67
38 mmc.report(); 68 userdata_total_kb = buf.f_bsize * buf.f_blocks >> 10;
39 ufs.report(); 69 userdata_free_kb = buf.f_bfree * buf.f_blocks >> 10;
40} 70}
41 71
42void storage_info_t::publish() 72void storage_info_t::publish()
@@ -46,13 +76,12 @@ void storage_info_t::publish()
46 << LOG_ID_EVENTS; 76 << LOG_ID_EVENTS;
47} 77}
48 78
49bool emmc_info_t::report() 79void emmc_info_t::report()
50{ 80{
51 if (!report_sysfs() && !report_debugfs()) 81 if (!report_sysfs() && !report_debugfs())
52 return false; 82 return;
53 83
54 publish(); 84 publish();
55 return true;
56} 85}
57 86
58bool emmc_info_t::report_sysfs() 87bool emmc_info_t::report_sysfs()
@@ -136,21 +165,21 @@ bool emmc_info_t::report_debugfs()
136 return true; 165 return true;
137} 166}
138 167
139bool ufs_info_t::report() 168void ufs_info_t::report()
140{ 169{
141 string buffer; 170 string buffer;
142 if (!ReadFileToString(health_file, &buffer)) { 171 if (!ReadFileToString(health_file, &buffer)) {
143 return false; 172 return;
144 } 173 }
145 174
146 vector<string> lines = Split(buffer, "\n"); 175 vector<string> lines = Split(buffer, "\n");
147 if (lines.empty()) { 176 if (lines.empty()) {
148 return false; 177 return;
149 } 178 }
150 179
151 char rev[8]; 180 char rev[8];
152 if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) { 181 if (sscanf(lines[0].c_str(), "ufs version: 0x%7s\n", rev) < 1) {
153 return false; 182 return;
154 } 183 }
155 184
156 version = "ufs " + string(rev); 185 version = "ufs " + string(rev);
@@ -175,10 +204,9 @@ bool ufs_info_t::report()
175 } 204 }
176 205
177 if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) { 206 if (eol == 0 || (lifetime_a == 0 && lifetime_b == 0)) {
178 return false; 207 return;
179 } 208 }
180 209
181 publish(); 210 publish();
182 return true;
183} 211}
184 212