summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debuggerd/Android.bp1
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp14
-rwxr-xr-x[-rw-r--r--]fs_mgr/fs_mgr.cpp36
-rw-r--r--fs_mgr/fs_mgr_format.cpp4
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp1
-rw-r--r--fs_mgr/include/fs_mgr.h2
-rw-r--r--fs_mgr/include_fstab/fstab/fstab.h1
-rw-r--r--fs_mgr/libdm/dm.cpp32
-rw-r--r--fs_mgr/libdm/dm_test.cpp15
-rw-r--r--fs_mgr/libdm/include/libdm/dm.h13
-rw-r--r--fs_mgr/libsnapshot/dm_snapshot_internals.h59
-rw-r--r--healthd/healthd_draw.cpp16
-rw-r--r--healthd/healthd_draw.h8
-rw-r--r--healthd/healthd_mode_charger.cpp10
-rw-r--r--init/builtins.cpp22
-rw-r--r--init/first_stage_init.cpp1
-rw-r--r--init/first_stage_mount.cpp14
-rw-r--r--init/init.cpp30
-rw-r--r--init/property_service.cpp105
-rw-r--r--init/reboot.cpp12
-rw-r--r--libasyncio/Android.bp6
-rw-r--r--libprocessgroup/profiles/cgroups.json4
-rw-r--r--libprocessgroup/profiles/task_profiles.json59
-rw-r--r--libprocessgroup/sched_policy.cpp21
-rw-r--r--libsystem/include/system/camera.h53
-rw-r--r--libutils/RefBase.cpp2
-rw-r--r--rootdir/init.rc37
-rw-r--r--trusty/storage/interface/include/trusty/interface/storage.h40
-rw-r--r--trusty/storage/proxy/Android.bp3
-rw-r--r--trusty/storage/proxy/checkpoint_handling.cpp77
-rw-r--r--trusty/storage/proxy/checkpoint_handling.h37
-rw-r--r--trusty/storage/proxy/proxy.c16
32 files changed, 630 insertions, 121 deletions
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 198e4defb..6b4071925 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -31,7 +31,6 @@ cc_defaults {
cflags: [
"-Wall",
"-Wextra",
- "-Werror",
"-Wno-unused-argument",
"-Wno-unused-function",
"-Wno-nullability-completeness",
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index b60739794..74b5c719e 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -553,9 +553,8 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
};
// Set PR_SET_DUMPABLE to 1, so that crash_dump can ptrace us.
- int orig_dumpable = prctl(PR_GET_DUMPABLE);
if (prctl(PR_SET_DUMPABLE, 1) != 0) {
- fatal_errno("failed to set dumpable");
+ fatal_errno("failed to set dumpable");
}
// On kernels with yama_ptrace enabled, also allow any process to attach.
@@ -585,9 +584,14 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
// and then wait for it to terminate.
futex_wait(&thread_info.pseudothread_tid, child_pid);
- // Restore PR_SET_DUMPABLE to its original value.
- if (prctl(PR_SET_DUMPABLE, orig_dumpable) != 0) {
- fatal_errno("failed to restore dumpable");
+ // Signals can either be fatal or nonfatal.
+ // For fatal signals, crash_dump will PTRACE_CONT us with the signal we
+ // crashed with, so that processes using waitpid on us will see that we
+ // exited with the correct exit status (e.g. so that sh will report
+ // "Segmentation fault" instead of "Killed"). For this to work, we need
+ // to deregister our signal handler for that signal before continuing.
+ if (signal_number != DEBUGGER_SIGNAL) {
+ signal(signal_number, SIG_DFL);
}
// Restore PR_SET_PTRACER to its original value.
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 21df8af8c..82f8ab485 100644..100755
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -185,7 +185,14 @@ static void check_fs(const std::string& blk_device, const std::string& fs_type,
Timer t;
/* Check for the types of filesystems we know how to check */
- if (is_extfs(fs_type)) {
+ if (fs_type == "vfat") {
+ const char* vfat_fsck_argv[] = {"/system/bin/fsck_msdos", "-y", blk_device.c_str()};
+ ret = logwrap_fork_execvp(ARRAY_SIZE(vfat_fsck_argv), vfat_fsck_argv, &status,
+ false, LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
+ if (ret < 0)
+ LERROR << "Failed running '/system/bin/fsck_msdos' on '" << blk_device.c_str()
+ << "' - " << ret;
+ } else if (is_extfs(fs_type)) {
/*
* First try to mount and unmount the filesystem. We do this because
* the kernel is more efficient than e2fsck in running the journal and
@@ -1369,6 +1376,8 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
int encryptable = FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE;
int error_count = 0;
CheckpointManager checkpoint_manager;
+ char propbuf[PROPERTY_VALUE_MAX];
+ bool is_ffbm = false;
AvbUniquePtr avb_handle(nullptr);
bool wiped = false;
@@ -1376,12 +1385,21 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
if (fstab->empty()) {
return {FS_MGR_MNTALL_FAIL, userdata_mounted};
}
+ /**get boot mode*/
+ property_get("ro.bootmode", propbuf, "");
+ if ((strncmp(propbuf, "ffbm-00", 7) == 0) || (strncmp(propbuf, "ffbm-01", 7) == 0))
+ is_ffbm = true;
// Keep i int to prevent unsigned integer overflow from (i = top_idx - 1),
// where top_idx is 0. It will give SIGABRT
for (int i = 0; i < static_cast<int>(fstab->size()); i++) {
auto& current_entry = (*fstab)[i];
+ /* Skip userdata partition in ffbm mode */
+ if (is_ffbm && !strcmp(current_entry.mount_point.c_str(), "/data")){
+ continue;
+ }
+
// If a filesystem should have been mounted in the first stage, we
// ignore it here. With one exception, if the filesystem is
// formattable, then it can only be formatted in the second stage,
@@ -1391,7 +1409,6 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
IsMountPointMounted(current_entry.mount_point))) {
continue;
}
-
// Don't mount entries that are managed by vold or not for the mount mode.
if (current_entry.fs_mgr_flags.vold_managed || current_entry.fs_mgr_flags.recovery_only ||
((mount_mode == MOUNT_MODE_LATE) && !current_entry.fs_mgr_flags.late_mount) ||
@@ -1605,11 +1622,18 @@ MountAllResult fs_mgr_mount_all(Fstab* fstab, int mount_mode) {
if (!call_vdc({"cryptfs", "mountFstab", attempted_entry.blk_device,
attempted_entry.mount_point},
nullptr)) {
- ++error_count;
- } else if (current_entry.mount_point == "/data") {
- userdata_mounted = true;
+ PERROR << android::base::StringPrintf(
+ "Failure while mounting metadata, setting flag to needing recovery "
+ "partition on %s at %s options: %s",
+ attempted_entry.blk_device.c_str(), attempted_entry.mount_point.c_str(),
+ attempted_entry.fs_options.c_str());
+ encryptable = FS_MGR_MNTALL_DEV_NEEDS_RECOVERY_WIPE_PROMPT;
+ } else {
+ if (current_entry.mount_point == "/data") {
+ userdata_mounted = true;
+ }
+ encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
}
- encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
continue;
} else {
// fs_options might be null so we cannot use PERROR << directly.
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 301c90755..7367dd54d 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -176,6 +176,10 @@ int fs_mgr_do_format(const FstabEntry& entry, bool crypt_footer) {
} else if (entry.fs_type == "ext4") {
return format_ext4(entry.blk_device, entry.mount_point, crypt_footer, needs_projid,
entry.fs_mgr_flags.ext_meta_csum);
+ } else if (entry.fs_type == "vfat") {
+ std::vector<const char*> args = {"/system/bin/newfs_msdos",
+ entry.blk_device.c_str()};
+ return logwrap_fork_execvp(args.size(), args.data(), nullptr, false, LOG_KLOG, false, nullptr);
} else {
LERROR << "File system type '" << entry.fs_type << "' is not supported";
return -EINVAL;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f5ab5571f..7fc73bdc5 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -181,6 +181,7 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) {
CheckFlag("fsverity", fs_verity);
CheckFlag("metadata_csum", ext_meta_csum);
CheckFlag("fscompress", fs_compress);
+ CheckFlag("wrappedkey", wrapped_key);
#undef CheckFlag
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 4d3ecc9dc..a825a63d9 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -51,6 +51,8 @@ enum mount_mode {
MOUNT_MODE_ONLY_USERDATA = 3
};
+
+#define FS_MGR_MNTALL_DEV_NEEDS_RECOVERY_WIPE_PROMPT 8
#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6
#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index f33768b9d..0d1e935c0 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -86,6 +86,7 @@ struct FstabEntry {
bool fs_verity : 1;
bool ext_meta_csum : 1;
bool fs_compress : 1;
+ bool wrapped_key : 1;
} fs_mgr_flags = {};
bool is_encryptable() const {
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index e43c00b44..b1d5b397a 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -170,19 +170,18 @@ static bool IsRecovery() {
return access("/system/bin/recovery", F_OK) == 0;
}
-bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, std::string* path,
- const std::chrono::milliseconds& timeout_ms) {
+bool DeviceMapper::CreateEmptyDevice(const std::string& name) {
std::string uuid = GenerateUuid();
- if (!CreateDevice(name, uuid)) {
- return false;
- }
+ return CreateDevice(name, uuid);
+}
+bool DeviceMapper::WaitForDevice(const std::string& name,
+ const std::chrono::milliseconds& timeout_ms, std::string* path) {
// We use the unique path for testing whether the device is ready. After
// that, it's safe to use the dm-N path which is compatible with callers
// that expect it to be formatted as such.
std::string unique_path;
- if (!LoadTableAndActivate(name, table) || !GetDeviceUniquePath(name, &unique_path) ||
- !GetDmDevicePathByName(name, path)) {
+ if (!GetDeviceUniquePath(name, &unique_path) || !GetDmDevicePathByName(name, path)) {
DeleteDevice(name);
return false;
}
@@ -208,6 +207,25 @@ bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, s
return true;
}
+bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, std::string* path,
+ const std::chrono::milliseconds& timeout_ms) {
+ if (!CreateEmptyDevice(name)) {
+ return false;
+ }
+
+ if (!LoadTableAndActivate(name, table)) {
+ DeleteDevice(name);
+ return false;
+ }
+
+ if (!WaitForDevice(name, timeout_ms, path)) {
+ DeleteDevice(name);
+ return false;
+ }
+
+ return true;
+}
+
bool DeviceMapper::GetDeviceUniquePath(const std::string& name, std::string* path) {
struct dm_ioctl io;
InitIo(&io, name);
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 8006db220..8314ec596 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -29,6 +29,7 @@
#include <thread>
#include <android-base/file.h>
+#include <android-base/scopeguard.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
@@ -679,3 +680,17 @@ TEST(libdm, DeleteDeviceDeferredWaitsForLastReference) {
ASSERT_NE(0, access(path.c_str(), F_OK));
ASSERT_EQ(ENOENT, errno);
}
+
+TEST(libdm, CreateEmptyDevice) {
+ DeviceMapper& dm = DeviceMapper::Instance();
+ ASSERT_TRUE(dm.CreateEmptyDevice("empty-device"));
+ auto guard = android::base::make_scope_guard([&]() { dm.DeleteDevice("empty-device", 5s); });
+
+ // Empty device should be in suspended state.
+ ASSERT_EQ(DmDeviceState::SUSPENDED, dm.GetState("empty-device"));
+
+ std::string path;
+ ASSERT_TRUE(dm.WaitForDevice("empty-device", 5s, &path));
+ // Path should exist.
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+}
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index bdbbf9112..e6698ea38 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -119,6 +119,19 @@ class DeviceMapper final {
// - ACTIVE: resumes the device.
bool ChangeState(const std::string& name, DmDeviceState state);
+ // Creates empty device.
+ // This supports a use case when a caller doesn't need a device straight away, but instead
+ // asks kernel to create it beforehand, thus avoiding blocking itself from waiting for ueventd
+ // to create user space paths.
+ // Callers are expected to then activate their device by calling LoadTableAndActivate function.
+ // To avoid race conditions, callers must still synchronize with ueventd by calling
+ // WaitForDevice function.
+ bool CreateEmptyDevice(const std::string& name);
+
+ // Waits for device paths to be created in the user space.
+ bool WaitForDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
+ std::string* path);
+
// Creates a device, loads the given table, and activates it. If the device
// is not able to be activated, it is destroyed, and false is returned.
// After creation, |path| contains the result of calling
diff --git a/fs_mgr/libsnapshot/dm_snapshot_internals.h b/fs_mgr/libsnapshot/dm_snapshot_internals.h
index ed77c1526..4a3625197 100644
--- a/fs_mgr/libsnapshot/dm_snapshot_internals.h
+++ b/fs_mgr/libsnapshot/dm_snapshot_internals.h
@@ -17,8 +17,9 @@
#include <android-base/logging.h>
#include <stdint.h>
+#include <limits>
#include <optional>
-#include <vector>
+#include <unordered_set>
namespace android {
namespace snapshot {
@@ -37,21 +38,16 @@ class DmSnapCowSizeCalculator {
return;
}
- if (modified_chunks_.size() <= chunk_id) {
- if (modified_chunks_.max_size() <= chunk_id) {
- LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
- valid_ = false;
- return;
- }
- modified_chunks_.resize(chunk_id + 1, false);
- if (modified_chunks_.size() <= chunk_id) {
- LOG(ERROR) << "Invalid COW size, chunk_id is too large.";
- valid_ = false;
- return;
- }
+ if (chunk_id > std::numeric_limits<uint32_t>::max()) {
+ LOG(ERROR) << "Chunk exceeds maximum size: " << chunk_id;
+ valid_ = false;
+ return;
+ }
+ if (modified_chunks_.count(chunk_id) > 0) {
+ return;
}
- modified_chunks_[chunk_id] = true;
+ modified_chunks_.emplace(chunk_id);
}
std::optional<uint64_t> cow_size_bytes() const {
@@ -91,23 +87,16 @@ class DmSnapCowSizeCalculator {
return std::nullopt;
}
- uint64_t modified_chunks_count = 0;
uint64_t cow_chunks = 0;
- for (const auto& c : modified_chunks_) {
- if (c) {
- ++modified_chunks_count;
- }
- }
-
/* disk header + padding = 1 chunk */
cow_chunks += 1;
/* snapshot modified chunks */
- cow_chunks += modified_chunks_count;
+ cow_chunks += modified_chunks_.size();
/* snapshot chunks index metadata */
- cow_chunks += 1 + modified_chunks_count / exceptions_per_chunk;
+ cow_chunks += 1 + modified_chunks_.size() / exceptions_per_chunk;
return cow_chunks;
}
@@ -150,30 +139,8 @@ class DmSnapCowSizeCalculator {
/*
* |modified_chunks_| is a container that keeps trace of the modified
* chunks.
- * Multiple options were considered when choosing the most appropriate data
- * structure for this container. Here follows a summary of why vector<bool>
- * has been chosen, taking as a reference a snapshot partition of 4 GiB and
- * chunk size of 4 KiB.
- * - std::set<uint64_t> is very space-efficient for a small number of
- * operations, but if the whole snapshot is changed, it would need to
- * store
- * 4 GiB / 4 KiB * (64 bit / 8) = 8 MiB
- * just for the data, plus the additional data overhead for the red-black
- * tree used for data sorting (if each rb-tree element stores 3 address
- * and the word-aligne color, the total size grows to 32 MiB).
- * - std::bitset<N> is not a good fit because requires a priori knowledge,
- * at compile time, of the bitset size.
- * - std::vector<bool> is a special case of vector, which uses a data
- * compression that allows reducing the space utilization of each element
- * to 1 bit. In detail, this data structure is composed of a resizable
- * array of words, each of them representing a bitmap. On a 64 bit
- * device, modifying the whole 4 GiB snapshot grows this container up to
- * 4 * GiB / 4 KiB / 64 = 64 KiB
- * that, even if is the same space requirement to change a single byte at
- * the highest address of the snapshot, is a very affordable space
- * requirement.
*/
- std::vector<bool> modified_chunks_;
+ std::unordered_set<uint32_t> modified_chunks_;
};
} // namespace snapshot
diff --git a/healthd/healthd_draw.cpp b/healthd/healthd_draw.cpp
index 50eee198f..9a47f6b2b 100644
--- a/healthd/healthd_draw.cpp
+++ b/healthd/healthd_draw.cpp
@@ -46,14 +46,6 @@ static int get_split_offset() {
HealthdDraw::HealthdDraw(animation* anim)
: kSplitScreen(get_split_screen()), kSplitOffset(get_split_offset()) {
- int ret = gr_init();
-
- if (ret < 0) {
- LOGE("gr_init failed\n");
- graphics_available = false;
- return;
- }
-
graphics_available = true;
sys_font = gr_sys_font();
if (sys_font == nullptr) {
@@ -235,3 +227,11 @@ void HealthdDraw::draw_unknown(GRSurface* surf_unknown) {
LOGW("Charging, level unknown\n");
}
}
+
+std::unique_ptr<HealthdDraw> HealthdDraw::Create(animation *anim) {
+ if (gr_init() < 0) {
+ LOGE("gr_init failed\n");
+ return nullptr;
+ }
+ return std::unique_ptr<HealthdDraw>(new HealthdDraw(anim));
+}
diff --git a/healthd/healthd_draw.h b/healthd/healthd_draw.h
index 7c847bdbf..0b48ce842 100644
--- a/healthd/healthd_draw.h
+++ b/healthd/healthd_draw.h
@@ -26,8 +26,6 @@ using namespace android;
class HealthdDraw {
public:
- // Configures font using given animation.
- HealthdDraw(animation* anim);
virtual ~HealthdDraw();
// Redraws screen.
@@ -36,6 +34,8 @@ class HealthdDraw {
// Blanks screen if true, unblanks if false.
virtual void blank_screen(bool blank);
+ static std::unique_ptr<HealthdDraw> Create(animation *anim);
+
protected:
virtual void clear_screen();
@@ -76,6 +76,10 @@ class HealthdDraw {
// true if minui init'ed OK, false if minui init failed
bool graphics_available;
+
+ private:
+ // Configures font using given animation.
+ HealthdDraw(animation* anim);
};
#endif // HEALTHD_DRAW_H
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index e95efc04c..6b503f4a8 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -218,9 +218,7 @@ static void dump_last_kmsg(void) {
char* ptr;
size_t len;
- LOGW("\n");
LOGW("*************** LAST KMSG ***************\n");
- LOGW("\n");
const char* kmsg[] = {
// clang-format off
"/sys/fs/pstore/console-ramoops-0",
@@ -263,9 +261,7 @@ static void dump_last_kmsg(void) {
}
out:
- LOGW("\n");
LOGW("************* END LAST KMSG *************\n");
- LOGW("\n");
}
static int request_suspend(bool enable) {
@@ -325,7 +321,8 @@ void Charger::UpdateScreenState(int64_t now) {
}
}
- healthd_draw_.reset(new HealthdDraw(&batt_anim_));
+ healthd_draw_ = HealthdDraw::Create(&batt_anim_);
+ if (healthd_draw_ == nullptr) return;
if (android::sysprop::ChargerProperties::disable_init_blank().value_or(false)) {
healthd_draw_->blank_screen(true);
@@ -346,6 +343,9 @@ void Charger::UpdateScreenState(int64_t now) {
disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time;
+ /* unblank the screen on first cycle and first frame */
+ if (batt_anim_.cur_cycle == 0 && batt_anim_.cur_frame == 0) healthd_draw_->blank_screen(false);
+
if (screen_blanked_) {
healthd_draw_->blank_screen(false);
screen_blanked_ = false;
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 035038f32..058f84aa5 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -621,6 +621,13 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) {
PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
return reboot_into_recovery(options);
+ } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY_WIPE_PROMPT) {
+ /* Setup a wipe via recovery with prompt, and reboot into recovery if chosen */
+ PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery "
+ "with prompt.";
+ const std::vector<std::string> options = {"--prompt_and_wipe_data",
+ "--reason=fs_mgr_mount_all" };
+ return reboot_into_recovery(options);
/* If reboot worked, there is no return. */
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (!FscryptInstallKeyring()) {
@@ -1114,6 +1121,19 @@ static Result<void> do_loglevel(const BuiltinArguments& args) {
return {};
}
+static int check_rlim_action() {
+ struct rlimit rl;
+ std::string value = android::base::GetProperty("persist.debug.trace", "");
+ if(value == "1") {
+ rl.rlim_cur = RLIM_INFINITY;
+ rl.rlim_max = RLIM_INFINITY;
+ if (setrlimit(RLIMIT_CORE, &rl) < 0) {
+ PLOG(ERROR) << "could not enable core file generation";
+ }
+ }
+ return 0;
+}
+
static Result<void> do_load_persist_props(const BuiltinArguments& args) {
// Devices with FDE have load_persist_props called twice; the first time when the temporary
// /data partition is mounted and then again once /data is truly mounted. We do not want to
@@ -1129,6 +1149,8 @@ static Result<void> do_load_persist_props(const BuiltinArguments& args) {
SendLoadPersistentPropertiesMessage();
start_waiting_for_property("ro.persistent_properties.ready", "true");
+ /*check for coredump*/
+ check_rlim_action();
return {};
}
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 78e5b60a1..a86e0733f 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -368,6 +368,7 @@ int FirstStageMain(int argc, char** argv) {
setenv(kEnvFirstStageStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(),
1);
+ LOG(INFO) << "init first stage completed!";
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index f5c10bbd4..52b4aa24e 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -74,6 +74,16 @@ using namespace std::literals;
namespace android {
namespace init {
+namespace {
+
+bool DeferOverlayfsMount() {
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
+ return cmdline.find("androidboot.defer_overlayfs_mount=1") != std::string::npos;
+}
+} // namespace
+
+
// Class Declarations
// ------------------
class FirstStageMount {
@@ -607,7 +617,9 @@ bool FirstStageMount::MountPartitions() {
};
MapScratchPartitionIfNeeded(&fstab_, init_devices);
- fs_mgr_overlayfs_mount_all(&fstab_);
+ if (!DeferOverlayfsMount()) {
+ fs_mgr_overlayfs_mount_all(&fstab_);
+ }
return true;
}
diff --git a/init/init.cpp b/init/init.cpp
index 942feb939..6dcf4a30b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -50,11 +50,16 @@
#include <android-base/strings.h>
#include <backtrace/Backtrace.h>
#include <fs_avb/fs_avb.h>
+#include <fs_mgr.h>
+#include <fs_mgr_dm_linear.h>
+#include <fs_mgr_overlayfs.h>
#include <fs_mgr_vendor_overlay.h>
+
#include <keyutils.h>
#include <libavb/libavb.h>
#include <libgsi/libgsi.h>
#include <libsnapshot/snapshot.h>
+#include <private/android_filesystem_config.h>
#include <processgroup/processgroup.h>
#include <processgroup/setup.h>
#include <selinux/android.h>
@@ -98,10 +103,20 @@ using android::base::Timer;
using android::base::Trim;
using android::fs_mgr::AvbHandle;
using android::snapshot::SnapshotManager;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::ReadDefaultFstab;
namespace android {
namespace init {
+namespace {
+bool DeferOverlayfsMount() {
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
+ return cmdline.find("androidboot.defer_overlayfs_mount=1") != std::string::npos;
+}
+}
+
static int property_triggers_enabled = 0;
static int signal_fd = -1;
@@ -768,6 +783,20 @@ int SecondStageMain(int argc, char** argv) {
sigaction(SIGPIPE, &action, nullptr);
}
+ if (DeferOverlayfsMount()) {
+ Fstab fstab;
+ if (ReadDefaultFstab(&fstab)) {
+ fstab.erase(std::remove_if(fstab.begin(), fstab.end(),
+ [](const auto& entry) {
+ return !entry.fs_mgr_flags.first_stage_mount;
+ }),
+ fstab.end());
+ LOG(INFO) << "Running deferred mounting of overlayfs";
+ fs_mgr_overlayfs_mount_all(&fstab);
+ }
+
+ }
+
// Set init and its forked children's oom_adj.
if (auto result =
WriteFile("/proc/1/oom_score_adj", StringPrintf("%d", DEFAULT_OOM_SCORE_ADJUST));
@@ -790,6 +819,7 @@ int SecondStageMain(int argc, char** argv) {
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true"s == force_debuggable_env;
}
+
unsetenv("INIT_FORCE_DEBUGGABLE");
// Umount the debug ramdisk so property service doesn't read .prop files from there, when it
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 2d67bf5d7..600f27919 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -954,6 +954,109 @@ static void property_derive_build_fingerprint() {
}
}
+// Initialize ro.build.product property with the value of ro.product.device, if it has not been set.
+static void property_derive_build_product() {
+ std::string build_product = GetProperty("ro.build.product", "");
+ if (!build_product.empty()) {
+ return;
+ }
+
+ const std::string UNKNOWN = "unknown";
+ build_product = GetProperty("ro.product.device", UNKNOWN);
+
+ LOG(INFO) << "Setting property 'ro.build.product' to '" << build_product << "'";
+
+ std::string error;
+ uint32_t res = PropertySet("ro.build.product", build_product, &error);
+ if (res != PROP_SUCCESS) {
+ LOG(ERROR) << "Error setting property 'ro.build.product': err=" << res << " (" << error
+ << ")";
+ }
+}
+
+// If the ro.build.description property has not been set, derive it from constituent pieces
+static void property_derive_build_description() {
+ std::string build_description = GetProperty("ro.build.description", "");
+ if (!build_description.empty()) {
+ return;
+ }
+
+ const std::string UNKNOWN = "unknown";
+ build_description = GetProperty("ro.product.name", UNKNOWN);
+ build_description += '-';
+ build_description += GetProperty("ro.build.type", UNKNOWN);
+ build_description += ' ';
+ build_description += GetProperty("ro.build.version.release", UNKNOWN);
+ build_description += ' ';
+ build_description += GetProperty("ro.build.id", UNKNOWN);
+ build_description += ' ';
+ build_description += GetProperty("ro.build.version.incremental", UNKNOWN);
+ build_description += ' ';
+ build_description += GetProperty("ro.build.tags", UNKNOWN);
+
+ LOG(INFO) << "Setting property 'ro.build.description' to '" << build_description << "'";
+
+ std::string error;
+ uint32_t res = PropertySet("ro.build.description", build_description, &error);
+ if (res != PROP_SUCCESS) {
+ LOG(ERROR) << "Error setting property 'ro.build.description': err=" << res << " (" << error
+ << ")";
+ }
+}
+
+// If the ro.build.display.id property has not been set, derive it from constituent pieces
+static void property_derive_build_display_id() {
+ std::string build_display_id = GetProperty("ro.build.display.id", "");
+ if (!build_display_id.empty()) {
+ return;
+ }
+
+ const std::string UNKNOWN = "unknown";
+ std::string build_type = GetProperty("ro.build.type", "");
+ if (build_type == "user") {
+ std::string display_build_number = GetProperty("ro.build.display_build_number", "");
+ if (display_build_number == "true") {
+ build_display_id = GetProperty("ro.build.id", UNKNOWN);
+ build_display_id += '.';
+ build_display_id += GetProperty("ro.build.version.incremental", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.keys", UNKNOWN);
+ } else {
+ build_display_id = GetProperty("ro.build.id", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.keys", UNKNOWN);
+ }
+ } else {
+ build_display_id = GetProperty("ro.product.name", UNKNOWN);
+ build_display_id += '-';
+ build_display_id += GetProperty("ro.build.type", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.version.release", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.id", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.version.incremental", UNKNOWN);
+ build_display_id += ' ';
+ build_display_id += GetProperty("ro.build.tags", UNKNOWN);
+ }
+
+ LOG(INFO) << "Setting property 'ro.build.display.id' to '" << build_display_id << "'";
+
+ std::string error;
+ uint32_t res = PropertySet("ro.build.display.id", build_display_id, &error);
+ if (res != PROP_SUCCESS) {
+ LOG(ERROR) << "Error setting property 'ro.build.display.id': err=" << res << " (" << error
+ << ")";
+ }
+}
+
+static void property_derive_build_props() {
+ property_derive_build_fingerprint();
+ property_derive_build_product();
+ property_derive_build_description();
+ property_derive_build_display_id();
+}
+
// If the ro.product.cpu.abilist* properties have not been explicitly
// set, derive them from ro.${partition}.product.cpu.abilist* properties.
static void property_initialize_ro_cpu_abilist() {
@@ -1099,7 +1202,7 @@ void PropertyLoadBootDefaults() {
property_initialize_ro_product_props();
property_initialize_build_id();
- property_derive_build_fingerprint();
+ property_derive_build_props();
property_derive_legacy_build_fingerprint();
property_initialize_ro_cpu_abilist();
diff --git a/init/reboot.cpp b/init/reboot.cpp
index a0ae4b4d4..845bdb949 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -54,6 +54,8 @@
#include <private/android_filesystem_config.h>
#include <selinux/selinux.h>
+#include <cutils/properties.h>
+
#include "action.h"
#include "action_manager.h"
#include "builtin_arguments.h"
@@ -425,11 +427,17 @@ static UmountStat TryUmountAndFsck(unsigned int cmd, bool run_fsck,
UmountStat stat = UmountPartitions(timeout - t.duration());
if (stat != UMOUNT_STAT_SUCCESS) {
LOG(INFO) << "umount timeout, last resort, kill all and try";
- if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
+ bool dumpUmountDebugInfo = property_get_bool("persist.sys.dumpUmountDebugInfo",false);
+ if (dumpUmountDebugInfo) {
+ if (DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
+ }
KillAllProcesses();
// even if it succeeds, still it is timeout and do not run fsck with all processes killed
UmountStat st = UmountPartitions(0ms);
- if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE) DumpUmountDebuggingInfo();
+ if (dumpUmountDebugInfo) {
+ if ((st != UMOUNT_STAT_SUCCESS) && DUMP_ON_UMOUNT_FAILURE)
+ DumpUmountDebuggingInfo();
+ }
}
if (stat == UMOUNT_STAT_SUCCESS && run_fsck) {
diff --git a/libasyncio/Android.bp b/libasyncio/Android.bp
index 692e223a1..694b0a3c9 100644
--- a/libasyncio/Android.bp
+++ b/libasyncio/Android.bp
@@ -20,11 +20,7 @@ package {
cc_defaults {
name: "libasyncio_defaults",
- cflags: [
- "-Wall",
- "-Werror",
- "-Wextra",
- ],
+ cflags: ["-Wall", "-Werror", "-Wextra"],
}
cc_library {
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 063422091..23e4575cb 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -24,8 +24,8 @@
{
"Controller": "memory",
"Path": "/dev/memcg",
- "Mode": "0700",
- "UID": "root",
+ "Mode": "0755",
+ "UID": "system",
"GID": "system",
"Optional": true
}
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 449a50546..b133769a3 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -16,6 +16,12 @@
"File": "top-app/cpus"
},
{
+ "Name": "AudioAppCapacityCPUs",
+ "Controller": "cpuset",
+ "File": "audio-app/cpus"
+ },
+
+ {
"Name": "MemLimit",
"Controller": "memory",
"File": "memory.limit_in_bytes"
@@ -171,6 +177,19 @@
]
},
{
+ "Name": "AudioAppPerformance",
+ "Actions" : [
+ {
+ "Name" : "JoinCgroup",
+ "Params" :
+ {
+ "Controller": "schedtune",
+ "Path": "audio-app"
+ }
+ }
+ ]
+ },
+ {
"Name": "NNApiHALPerformance",
"Actions": [
{
@@ -396,6 +415,46 @@
}
]
},
+ {
+ "Name": "AudioAppCapacity",
+ "Actions" : [
+ {
+ "Name" : "JoinCgroup",
+ "Params" :
+ {
+ "Controller": "cpuset",
+ "Path": "audio-app"
+ }
+ }
+ ]
+ },
+
+ {
+ "Name": "BlkIOForeground",
+ "Actions" : [
+ {
+ "Name" : "JoinCgroup",
+ "Params" :
+ {
+ "Controller": "blkio",
+ "Path": ""
+ }
+ }
+ ]
+ },
+ {
+ "Name": "BlkIOBackground",
+ "Actions" : [
+ {
+ "Name" : "JoinCgroup",
+ "Params" :
+ {
+ "Controller": "blkio",
+ "Path": "bg"
+ }
+ }
+ ]
+ },
{
"Name": "LowIoPriority",
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index 1a4196a4d..03d347973 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -46,15 +46,16 @@ int set_cpuset_policy(int tid, SchedPolicy policy) {
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"CPUSET_SP_BACKGROUND"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"CPUSET_SP_BACKGROUND", "BlkIOBackground"}, true) ? 0 : -1;
case SP_FOREGROUND:
+ return SetTaskProfiles(tid, {"CPUSET_SP_FOREGROUND", "BlkIOForeground"}, true) ? 0 : -1;
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"CPUSET_SP_FOREGROUND"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"CPUSET_SP_FOREGROUND", "AudioAppCapacity", "BlkIOForeground"}, true) ? 0 : -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"CPUSET_SP_TOP_APP"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"CPUSET_SP_TOP_APP", "BlkIOBackground"}, true) ? 0 : -1;
case SP_SYSTEM:
- return SetTaskProfiles(tid, {"CPUSET_SP_SYSTEM"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"CPUSET_SP_SYSTEM", "BlkIOForeground"}, true) ? 0 : -1;
case SP_RESTRICTED:
return SetTaskProfiles(tid, {"CPUSET_SP_RESTRICTED"}, true) ? 0 : -1;
default:
@@ -101,7 +102,7 @@ int set_sched_policy(int tid, SchedPolicy policy) {
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
case SP_TOP_APP:
- SLOGD("^^^ tid %d (%s)", tid, thread_name);
+ SLOGD("^^^ tid %d policy %d (%s)", tid, policy, thread_name);
break;
case SP_SYSTEM:
SLOGD("/// tid %d (%s)", tid, thread_name);
@@ -117,17 +118,17 @@ int set_sched_policy(int tid, SchedPolicy policy) {
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND", "BlkIOBackground"}, true) ? 0 : -1;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"SCHED_SP_FOREGROUND"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"SCHED_SP_FOREGROUND", "BlkIOForeground"}, true) ? 0 : -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"SCHED_SP_TOP_APP"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"SCHED_SP_TOP_APP", "BlkIOForeground"}, true) ? 0 : -1;
case SP_SYSTEM:
return SetTaskProfiles(tid, {"SCHED_SP_SYSTEM"}, true) ? 0 : -1;
case SP_RT_APP:
- return SetTaskProfiles(tid, {"SCHED_SP_RT_APP"}, true) ? 0 : -1;
+ return SetTaskProfiles(tid, {"SCHED_SP_RT_APP", "BlkIOForeground"}, true) ? 0 : -1;
default:
return SetTaskProfiles(tid, {"SCHED_SP_DEFAULT"}, true) ? 0 : -1;
}
@@ -198,6 +199,8 @@ int get_sched_policy(int tid, SchedPolicy* policy) {
*policy = SP_TOP_APP;
} else if (group == "restricted") {
*policy = SP_RESTRICTED;
+ } else if (group == "audio-app") {
+ *policy = SP_AUDIO_APP;
} else {
errno = ERANGE;
return -1;
diff --git a/libsystem/include/system/camera.h b/libsystem/include/system/camera.h
index 2ca90c395..990edcf32 100644
--- a/libsystem/include/system/camera.h
+++ b/libsystem/include/system/camera.h
@@ -88,9 +88,20 @@ enum {
// Notify on autofocus start and stop. This is useful in continuous
// autofocus - FOCUS_MODE_CONTINUOUS_VIDEO and FOCUS_MODE_CONTINUOUS_PICTURE.
CAMERA_MSG_FOCUS_MOVE = 0x0800, // notifyCallback
+ CAMERA_MSG_VENDOR_START = 0x1000,
+ CAMERA_MSG_STATS_DATA = CAMERA_MSG_VENDOR_START,
+ CAMERA_MSG_META_DATA = 0x2000,
+ CAMERA_MSG_VENDOR_END = 0x8000,
CAMERA_MSG_ALL_MSGS = 0xFFFF
};
+/** meta data type in CameraMetaDataCallback */
+enum {
+ CAMERA_META_DATA_ASD = 0x001, //ASD data
+ CAMERA_META_DATA_FD = 0x002, //FD/FP data
+ CAMERA_META_DATA_HDR = 0x003, //Auto HDR data
+};
+
/** cmdType in sendCommand functions */
enum {
CAMERA_CMD_START_SMOOTH_ZOOM = 1,
@@ -189,7 +200,25 @@ enum {
* IMPLEMENTATION_DEFINED, then HALv3 devices will use gralloc usage flags
* of SW_READ_OFTEN.
*/
- CAMERA_CMD_SET_VIDEO_FORMAT = 11
+ CAMERA_CMD_SET_VIDEO_FORMAT = 11,
+
+ CAMERA_CMD_VENDOR_START = 20,
+ /**
+ * Commands to enable/disable preview histogram
+ *
+ * Based on user's input to enable/disable histogram from the camera
+ * UI, send the appropriate command to the HAL to turn on/off the histogram
+ * stats and start sending the data to the application.
+ */
+ CAMERA_CMD_HISTOGRAM_ON = CAMERA_CMD_VENDOR_START,
+ CAMERA_CMD_HISTOGRAM_OFF = CAMERA_CMD_VENDOR_START + 1,
+ CAMERA_CMD_HISTOGRAM_SEND_DATA = CAMERA_CMD_VENDOR_START + 2,
+ CAMERA_CMD_LONGSHOT_ON = CAMERA_CMD_VENDOR_START + 3,
+ CAMERA_CMD_LONGSHOT_OFF = CAMERA_CMD_VENDOR_START + 4,
+ CAMERA_CMD_STOP_LONGSHOT = CAMERA_CMD_VENDOR_START + 5,
+ CAMERA_CMD_METADATA_ON = CAMERA_CMD_VENDOR_START + 6,
+ CAMERA_CMD_METADATA_OFF = CAMERA_CMD_VENDOR_START + 7,
+ CAMERA_CMD_VENDOR_END = 200,
};
/** camera fatal errors */
@@ -284,10 +313,32 @@ typedef struct camera_face {
* -2000, -2000 if this is not supported.
*/
int32_t mouth[2];
+ int32_t smile_degree;
+ int32_t smile_score;
+ int32_t blink_detected;
+ int32_t face_recognised;
+ int32_t gaze_angle;
+ int32_t updown_dir;
+ int32_t leftright_dir;
+ int32_t roll_dir;
+ int32_t left_right_gaze;
+ int32_t top_bottom_gaze;
+ int32_t leye_blink;
+ int32_t reye_blink;
} camera_face_t;
/**
+ * The information of a data type received in a camera frame.
+ */
+typedef enum {
+ /** Data buffer */
+ CAMERA_FRAME_DATA_BUF = 0x000,
+ /** File descriptor */
+ CAMERA_FRAME_DATA_FD = 0x100
+} camera_frame_data_type_t;
+
+/**
* The metadata of the frame data.
*/
typedef struct camera_frame_metadata {
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index b57e28741..9d359b805 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -549,7 +549,7 @@ void RefBase::weakref_type::decWeak(const void* id)
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);
const int32_t c = impl->mWeak.fetch_sub(1, std::memory_order_release);
- LOG_ALWAYS_FATAL_IF(BAD_WEAK(c), "decWeak called on %p too many times",
+ ALOGW_IF(BAD_WEAK(c), "decWeak called on %p too many times",
this);
if (c != 1) return;
atomic_thread_fence(std::memory_order_acquire);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d10689a01..8272654c7 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -32,10 +32,14 @@ on early-init
# memory.pressure_level used by lmkd
chown root system /dev/memcg/memory.pressure_level
chmod 0040 /dev/memcg/memory.pressure_level
+
# app mem cgroups, used by activity manager, lmkd and zygote
mkdir /dev/memcg/apps/ 0755 system system
+ write /dev/memcg/apps/memory.swappiness 100
+
# cgroup for system_server and surfaceflinger
mkdir /dev/memcg/system 0550 system system
+ write /dev/memcg/system/memory.swappiness 100
# symlink the Android specific /dev/tun to Linux expected /dev/net/tun
mkdir /dev/net 0755 root root
@@ -132,21 +136,25 @@ on init
mkdir /dev/stune/background
mkdir /dev/stune/top-app
mkdir /dev/stune/rt
+ mkdir /dev/stune/audio-app
chown system system /dev/stune
chown system system /dev/stune/foreground
chown system system /dev/stune/background
chown system system /dev/stune/top-app
chown system system /dev/stune/rt
+ chown system system /dev/stune/audio-app
chown system system /dev/stune/tasks
chown system system /dev/stune/foreground/tasks
chown system system /dev/stune/background/tasks
chown system system /dev/stune/top-app/tasks
chown system system /dev/stune/rt/tasks
+ chown system system /dev/stune/audio-app/tasks
chmod 0664 /dev/stune/tasks
chmod 0664 /dev/stune/foreground/tasks
chmod 0664 /dev/stune/background/tasks
chmod 0664 /dev/stune/top-app/tasks
chmod 0664 /dev/stune/rt/tasks
+ chmod 0664 /dev/stune/audio-app/tasks
# cpuctl hierarchy for devices using utilclamp
mkdir /dev/cpuctl/foreground
@@ -348,12 +356,17 @@ on init
copy /dev/cpuset/cpus /dev/cpuset/camera-daemon/cpus
copy /dev/cpuset/mems /dev/cpuset/camera-daemon/mems
+ mkdir /dev/cpuset/audio-app
+ copy /dev/cpuset/cpus /dev/cpuset/audio-app/cpus
+ copy /dev/cpuset/mems /dev/cpuset/audio-app/mems
+
# change permissions for all cpusets we'll touch at runtime
chown system system /dev/cpuset
chown system system /dev/cpuset/foreground
chown system system /dev/cpuset/background
chown system system /dev/cpuset/system-background
chown system system /dev/cpuset/top-app
+ chown system system /dev/cpuset/audio-app
chown system system /dev/cpuset/restricted
chown system system /dev/cpuset/camera-daemon
chown system system /dev/cpuset/tasks
@@ -361,6 +374,7 @@ on init
chown system system /dev/cpuset/background/tasks
chown system system /dev/cpuset/system-background/tasks
chown system system /dev/cpuset/top-app/tasks
+ chown system system /dev/cpuset/audio-app/tasks
chown system system /dev/cpuset/restricted/tasks
chown system system /dev/cpuset/camera-daemon/tasks
@@ -371,6 +385,7 @@ on init
chmod 0664 /dev/cpuset/background/tasks
chmod 0664 /dev/cpuset/system-background/tasks
chmod 0664 /dev/cpuset/top-app/tasks
+ chmod 0664 /dev/cpuset/audio-app/tasks
chmod 0664 /dev/cpuset/restricted/tasks
chmod 0664 /dev/cpuset/tasks
chmod 0664 /dev/cpuset/camera-daemon/tasks
@@ -472,6 +487,7 @@ on late-init
# '--early' can be specified to skip entries with 'latemount'.
# /system and /vendor must be mounted by the end of the fs stage,
# while /data is optional.
+ trigger factory-fs
trigger fs
trigger post-fs
@@ -500,6 +516,7 @@ on late-init
trigger early-boot
trigger boot
+ trigger mmi
on early-fs
# Once metadata has been mounted, we'll need vold to deal with userdata checkpointing
@@ -590,7 +607,20 @@ on late-fs
# Load trusted keys from dm-verity protected partitions
exec -- /system/bin/fsverity_init --load-verified-keys
-on late-fs && property:ro.product.cpu.abilist64=*
+# Only enable the bootreceiver tracing instance for kernels 5.10 and above.
+on late-fs && property:ro.kernel.version=4.9
+ setprop bootreceiver.enable 0
+on late-fs && property:ro.kernel.version=4.14
+ setprop bootreceiver.enable 0
+on late-fs && property:ro.kernel.version=4.19
+ setprop bootreceiver.enable 0
+on late-fs && property:ro.kernel.version=5.4
+ setprop bootreceiver.enable 0
+on late-fs
+ # Bootreceiver tracing instance is enabled by default.
+ setprop bootreceiver.enable ${bootreceiver.enable:-1}
+
+on property:ro.product.cpu.abilist64=* && property:bootreceiver.enable=1
# Set up a tracing instance for system_server to monitor error_report_end events.
# These are sent by kernel tools like KASAN and KFENCE when a memory corruption
# is detected. This is only needed for 64-bit systems.
@@ -1099,6 +1129,11 @@ on property:vold.decrypt=trigger_load_persist_props
start logd
start logd-reinit
+# corefile limit
+on property:persist.debug.trace=1
+ mkdir /data/core 0777 root root
+ write /proc/sys/kernel/core_pattern "/data/core/%E.%p.%e"
+
on property:vold.decrypt=trigger_post_fs_data
trigger post-fs-data
trigger zygote-start
diff --git a/trusty/storage/interface/include/trusty/interface/storage.h b/trusty/storage/interface/include/trusty/interface/storage.h
index b196d88b3..3f1dcb8c6 100644
--- a/trusty/storage/interface/include/trusty/interface/storage.h
+++ b/trusty/storage/interface/include/trusty/interface/storage.h
@@ -112,26 +112,30 @@ enum storage_file_open_flag {
/**
* enum storage_msg_flag - protocol-level flags in struct storage_msg
- * @STORAGE_MSG_FLAG_BATCH: if set, command belongs to a batch transaction.
- * No response will be sent by the server until
- * it receives a command with this flag unset, at
- * which point a cummulative result for all messages
- * sent with STORAGE_MSG_FLAG_BATCH will be sent.
- * This is only supported by the non-secure disk proxy
- * server.
- * @STORAGE_MSG_FLAG_PRE_COMMIT: if set, indicates that server need to commit
- * pending changes before processing this message.
- * @STORAGE_MSG_FLAG_POST_COMMIT: if set, indicates that server need to commit
- * pending changes after processing this message.
- * @STORAGE_MSG_FLAG_TRANSACT_COMPLETE: if set, indicates that server need to commit
- * current transaction after processing this message.
- * It is an alias for STORAGE_MSG_FLAG_POST_COMMIT.
+ * @STORAGE_MSG_FLAG_BATCH: if set, command belongs to a batch transaction.
+ * No response will be sent by the server until
+ * it receives a command with this flag unset, at
+ * which point a cumulative result for all messages
+ * sent with STORAGE_MSG_FLAG_BATCH will be sent.
+ * This is only supported by the non-secure disk proxy
+ * server.
+ * @STORAGE_MSG_FLAG_PRE_COMMIT: if set, indicates that server need to commit
+ * pending changes before processing this message.
+ * @STORAGE_MSG_FLAG_POST_COMMIT: if set, indicates that server need to commit
+ * pending changes after processing this message.
+ * @STORAGE_MSG_FLAG_TRANSACT_COMPLETE: if set, indicates that server need to commit
+ * current transaction after processing this message.
+ * It is an alias for STORAGE_MSG_FLAG_POST_COMMIT.
+ * @STORAGE_MSG_FLAG_PRE_COMMIT_CHECKPOINT: if set, indicates that server needs to ensure
+ * that there is not a pending checkpoint for
+ * userdata before processing this message.
*/
enum storage_msg_flag {
- STORAGE_MSG_FLAG_BATCH = 0x1,
- STORAGE_MSG_FLAG_PRE_COMMIT = 0x2,
- STORAGE_MSG_FLAG_POST_COMMIT = 0x4,
- STORAGE_MSG_FLAG_TRANSACT_COMPLETE = STORAGE_MSG_FLAG_POST_COMMIT,
+ STORAGE_MSG_FLAG_BATCH = 0x1,
+ STORAGE_MSG_FLAG_PRE_COMMIT = 0x2,
+ STORAGE_MSG_FLAG_POST_COMMIT = 0x4,
+ STORAGE_MSG_FLAG_TRANSACT_COMPLETE = STORAGE_MSG_FLAG_POST_COMMIT,
+ STORAGE_MSG_FLAG_PRE_COMMIT_CHECKPOINT = 0x8,
};
/*
diff --git a/trusty/storage/proxy/Android.bp b/trusty/storage/proxy/Android.bp
index d67089fb2..38d868508 100644
--- a/trusty/storage/proxy/Android.bp
+++ b/trusty/storage/proxy/Android.bp
@@ -23,6 +23,7 @@ cc_binary {
vendor: true,
srcs: [
+ "checkpoint_handling.cpp",
"ipc.c",
"rpmb.c",
"storage.c",
@@ -30,12 +31,14 @@ cc_binary {
],
shared_libs: [
+ "libbase",
"liblog",
"libhardware_legacy",
],
header_libs: ["libcutils_headers"],
static_libs: [
+ "libfstab",
"libtrustystorageinterface",
"libtrusty",
],
diff --git a/trusty/storage/proxy/checkpoint_handling.cpp b/trusty/storage/proxy/checkpoint_handling.cpp
new file mode 100644
index 000000000..6c2fd363e
--- /dev/null
+++ b/trusty/storage/proxy/checkpoint_handling.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 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 "checkpoint_handling.h"
+#include "log.h"
+
+#include <fstab/fstab.h>
+#include <cstring>
+#include <string>
+
+namespace {
+
+bool checkpointingDoneForever = false;
+
+} // namespace
+
+int is_data_checkpoint_active(bool* active) {
+ if (!active) {
+ ALOGE("active out parameter is null");
+ return 0;
+ }
+
+ *active = false;
+
+ if (checkpointingDoneForever) {
+ return 0;
+ }
+
+ android::fs_mgr::Fstab procMounts;
+ bool success = android::fs_mgr::ReadFstabFromFile("/proc/mounts", &procMounts);
+ if (!success) {
+ ALOGE("Could not parse /proc/mounts\n");
+ /* Really bad. Tell the caller to abort the write. */
+ return -1;
+ }
+
+ android::fs_mgr::FstabEntry* dataEntry =
+ android::fs_mgr::GetEntryForMountPoint(&procMounts, "/data");
+ if (dataEntry == NULL) {
+ ALOGE("/data is not mounted yet\n");
+ return 0;
+ }
+
+ /* We can't handle e.g., ext4. Nothing we can do about it for now. */
+ if (dataEntry->fs_type != "f2fs") {
+ ALOGW("Checkpoint status not supported for filesystem %s\n", dataEntry->fs_type.c_str());
+ checkpointingDoneForever = true;
+ return 0;
+ }
+
+ /*
+ * The data entry looks like "... blah,checkpoint=disable:0,blah ...".
+ * checkpoint=disable means checkpointing is on (yes, arguably reversed).
+ */
+ size_t checkpointPos = dataEntry->fs_options.find("checkpoint=disable");
+ if (checkpointPos == std::string::npos) {
+ /* Assumption is that once checkpointing turns off, it stays off */
+ checkpointingDoneForever = true;
+ } else {
+ *active = true;
+ }
+
+ return 0;
+}
diff --git a/trusty/storage/proxy/checkpoint_handling.h b/trusty/storage/proxy/checkpoint_handling.h
new file mode 100644
index 000000000..f1bf27c8d
--- /dev/null
+++ b/trusty/storage/proxy/checkpoint_handling.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * is_data_checkpoint_active() - Check for an active, uncommitted checkpoint of
+ * /data. If a checkpoint is active, storage should not commit any
+ * rollback-protected writes to /data.
+ * @active: Out parameter that will be set to the result of the check.
+ *
+ * Return: 0 if active was set and is valid, non-zero otherwise.
+ */
+int is_data_checkpoint_active(bool* active);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/trusty/storage/proxy/proxy.c b/trusty/storage/proxy/proxy.c
index e23094183..c690a2876 100644
--- a/trusty/storage/proxy/proxy.c
+++ b/trusty/storage/proxy/proxy.c
@@ -26,6 +26,7 @@
#include <cutils/android_filesystem_config.h>
+#include "checkpoint_handling.h"
#include "ipc.h"
#include "log.h"
#include "rpmb.h"
@@ -130,6 +131,21 @@ static int handle_req(struct storage_msg* msg, const void* req, size_t req_len)
}
}
+ if (msg->flags & STORAGE_MSG_FLAG_PRE_COMMIT_CHECKPOINT) {
+ bool is_checkpoint_active = false;
+
+ rc = is_data_checkpoint_active(&is_checkpoint_active);
+ if (rc != 0) {
+ ALOGE("is_data_checkpoint_active failed in an unexpected way. Aborting.\n");
+ msg->result = STORAGE_ERR_GENERIC;
+ return ipc_respond(msg, NULL, 0);
+ } else if (is_checkpoint_active) {
+ ALOGE("Checkpoint in progress, dropping write ...\n");
+ msg->result = STORAGE_ERR_GENERIC;
+ return ipc_respond(msg, NULL, 0);
+ }
+ }
+
switch (msg->cmd) {
case STORAGE_FILE_DELETE:
rc = storage_file_delete(msg, req, req_len);