Merge "add nodad argument to ifc_act_on_address() and add it to header file"
diff --git a/base/include/android-base/expected.h b/base/include/android-base/expected.h
index 030ef35e..b3f5adb 100644
--- a/base/include/android-base/expected.h
+++ b/base/include/android-base/expected.h
@@ -111,6 +111,7 @@
!(!std::is_convertible_v<const U&, T> ||
!std::is_convertible_v<const G&, E>) /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(const expected<U, G>& rhs) {
if (rhs.has_value()) var_ = rhs.value();
else var_ = unexpected(rhs.error());
@@ -149,6 +150,7 @@
!(!std::is_convertible_v<const U&, T> ||
!std::is_convertible_v<const G&, E>) /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(expected<U, G>&& rhs) {
if (rhs.has_value()) var_ = std::move(rhs.value());
else var_ = unexpected(std::move(rhs.error()));
@@ -180,6 +182,7 @@
!std::is_same_v<unexpected<E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
std::is_convertible_v<U&&, T> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(U&& v) : var_(std::in_place_index<0>, std::forward<U>(v)) {}
template <class U = T _ENABLE_IF(
@@ -195,6 +198,7 @@
std::is_constructible_v<E, const G&> &&
std::is_convertible_v<const G&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(const unexpected<G>& e)
: var_(std::in_place_index<1>, e.value()) {}
@@ -209,6 +213,7 @@
std::is_constructible_v<E, G&&> &&
std::is_convertible_v<G&&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(unexpected<G>&& e)
: var_(std::in_place_index<1>, std::move(e.value())) {}
@@ -457,6 +462,7 @@
std::is_void_v<U> &&
std::is_convertible_v<const G&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(const expected<U, G>& rhs) {
if (!rhs.has_value()) var_ = unexpected(rhs.error());
}
@@ -473,6 +479,7 @@
std::is_void_v<U> &&
std::is_convertible_v<const G&&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(expected<U, G>&& rhs) {
if (!rhs.has_value()) var_ = unexpected(std::move(rhs.error()));
}
@@ -489,6 +496,7 @@
std::is_constructible_v<E, const G&> &&
std::is_convertible_v<const G&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(const unexpected<G>& e)
: var_(std::in_place_index<1>, e.value()) {}
@@ -503,6 +511,7 @@
std::is_constructible_v<E, G&&> &&
std::is_convertible_v<G&&, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr expected(unexpected<G>&& e)
: var_(std::in_place_index<1>, std::move(e.value())) {}
@@ -640,6 +649,7 @@
std::is_constructible_v<E, Err> &&
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, std::in_place_t> &&
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, unexpected>)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr unexpected(Err&& e) : val_(std::forward<Err>(e)) {}
template<class U, class... Args _ENABLE_IF(
@@ -660,6 +670,7 @@
!std::is_convertible_v<const unexpected<Err>, E> &&
std::is_convertible_v<Err, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr unexpected(const unexpected<Err>& rhs)
: val_(rhs.value()) {}
@@ -690,6 +701,7 @@
!std::is_convertible_v<const unexpected<Err>, E> &&
std::is_convertible_v<Err, E> /* non-explicit */
)>
+ // NOLINTNEXTLINE(google-explicit-constructor)
constexpr unexpected(unexpected<Err>&& rhs)
: val_(std::move(rhs.value())) {}
diff --git a/base/include/android-base/result.h b/base/include/android-base/result.h
index 1b763af..b6d26e7 100644
--- a/base/include/android-base/result.h
+++ b/base/include/android-base/result.h
@@ -90,6 +90,7 @@
ResultError(T&& message, int code) : message_(std::forward<T>(message)), code_(code) {}
template <typename T>
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator android::base::expected<T, ResultError>() {
return android::base::unexpected(ResultError(message_, code_));
}
@@ -118,9 +119,11 @@
class Error {
public:
Error() : errno_(0), append_errno_(false) {}
+ // NOLINTNEXTLINE(google-explicit-constructor)
Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
template <typename T>
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator android::base::expected<T, ResultError>() {
return android::base::unexpected(ResultError(str(), errno_));
}
diff --git a/base/logging.cpp b/base/logging.cpp
index 1d8ef57..a868706 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -608,7 +608,6 @@
// we need to fall back to using gMinimumLogSeverity, since __android_log_is_loggable() will not
// take into consideration the value from SetMinimumLogSeverity().
if (liblog_functions) {
- // TODO: It is safe to pass nullptr for tag, but it will be better to use the default log tag.
int priority = LogSeverityToPriority(severity);
return __android_log_is_loggable(priority, tag, ANDROID_LOG_INFO);
} else {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 3463a68..9180a06 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -101,6 +101,7 @@
using android::base::unique_fd;
using android::dm::DeviceMapper;
using android::dm::DmDeviceState;
+using android::dm::DmTargetLinear;
// Realistically, this file should be part of the android::fs_mgr namespace;
using namespace android::fs_mgr;
@@ -1114,6 +1115,83 @@
}
}
+static constexpr const char* kUserdataWrapperName = "userdata-wrapper";
+
+static void WrapUserdata(FstabEntry* entry, dev_t dev, const std::string& block_device) {
+ DeviceMapper& dm = DeviceMapper::Instance();
+ if (dm.GetState(kUserdataWrapperName) != DmDeviceState::INVALID) {
+ // This will report failure for us. If we do fail to get the path,
+ // we leave the device unwrapped.
+ dm.GetDmDevicePathByName(kUserdataWrapperName, &entry->blk_device);
+ return;
+ }
+
+ unique_fd fd(open(block_device.c_str(), O_RDONLY | O_CLOEXEC));
+ if (fd < 0) {
+ PLOG(ERROR) << "open failed: " << entry->blk_device;
+ return;
+ }
+
+ auto dev_str = android::base::StringPrintf("%u:%u", major(dev), minor(dev));
+ uint64_t sectors = get_block_device_size(fd) / 512;
+
+ android::dm::DmTable table;
+ table.Emplace<DmTargetLinear>(0, sectors, dev_str, 0);
+
+ std::string dm_path;
+ if (!dm.CreateDevice(kUserdataWrapperName, table, &dm_path, 20s)) {
+ LOG(ERROR) << "Failed to create userdata wrapper device";
+ return;
+ }
+ entry->blk_device = dm_path;
+}
+
+// When using Virtual A/B, partitions can be backed by /data and mapped with
+// device-mapper in first-stage init. This can happen when merging an OTA or
+// when using adb remount to house "scratch". In this case, /data cannot be
+// mounted directly off the userdata block device, and e2fsck will refuse to
+// scan it, because the kernel reports the block device as in-use.
+//
+// As a workaround, when mounting /data, we create a trivial dm-linear wrapper
+// if the underlying block device already has dependencies. Note that we make
+// an exception for metadata-encrypted devices, since dm-default-key is already
+// a wrapper.
+static void WrapUserdataIfNeeded(FstabEntry* entry, const std::string& actual_block_device = {}) {
+ const auto& block_device =
+ actual_block_device.empty() ? entry->blk_device : actual_block_device;
+ if (entry->mount_point != "/data" || !entry->key_dir.empty() ||
+ android::base::StartsWith(block_device, "/dev/block/dm-")) {
+ return;
+ }
+
+ struct stat st;
+ if (stat(block_device.c_str(), &st) < 0) {
+ PLOG(ERROR) << "stat failed: " << block_device;
+ return;
+ }
+
+ std::string path = android::base::StringPrintf("/sys/dev/block/%u:%u/holders",
+ major(st.st_rdev), minor(st.st_rdev));
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
+ if (!dir) {
+ PLOG(ERROR) << "opendir failed: " << path;
+ return;
+ }
+
+ struct dirent* d;
+ bool has_holders = false;
+ while ((d = readdir(dir.get())) != nullptr) {
+ if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
+ has_holders = true;
+ break;
+ }
+ }
+
+ if (has_holders) {
+ WrapUserdata(entry, st.st_rdev, block_device);
+ }
+}
+
static bool IsMountPointMounted(const std::string& mount_point) {
// Check if this is already mounted.
Fstab fstab;
@@ -1193,6 +1271,8 @@
}
}
+ WrapUserdataIfNeeded(¤t_entry);
+
if (!checkpoint_manager.Update(¤t_entry)) {
continue;
}
@@ -1463,6 +1543,9 @@
}
std::string block_device;
if (auto entry = GetEntryForMountPoint(&proc_mounts, "/data"); entry != nullptr) {
+ // Note: we don't care about a userdata wrapper here, since it's safe
+ // to remount on top of the bow device instead, there will be no
+ // conflicts.
block_device = entry->blk_device;
} else {
LERROR << "/data is not mounted";
@@ -1581,6 +1664,8 @@
}
}
+ WrapUserdataIfNeeded(&fstab_entry, n_blk_device);
+
if (!checkpoint_manager.Update(&fstab_entry, n_blk_device)) {
LERROR << "Could not set up checkpoint partition, skipping!";
continue;
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index f9a3df9..ff6b036 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -130,6 +130,7 @@
#define AID_GSID 1074 /* GSI service daemon */
#define AID_FSVERITY_CERT 1075 /* fs-verity key ownership in keystore */
#define AID_CREDSTORE 1076 /* identity credential manager service */
+#define AID_EXTERNAL_STORAGE 1077 /* Full external storage access including USB OTG volumes */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
#define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index e86d9ec..3733357 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "logger_write.h"
+
#include <errno.h>
#include <inttypes.h>
#include <libgen.h>
@@ -136,11 +138,11 @@
// It's possible for logging to happen during static initialization before our globals are
// initialized, so we place this std::string in a function such that it is initialized on the first
// call.
-static std::string& GetDefaultTag() {
+std::string& GetDefaultTag() {
static std::string default_tag = getprogname();
return default_tag;
}
-static RwLock default_tag_lock;
+RwLock default_tag_lock;
void __android_log_set_default_tag(const char* tag) {
auto lock = std::unique_lock{default_tag_lock};
diff --git a/liblog/logger_write.h b/liblog/logger_write.h
new file mode 100644
index 0000000..065fd55
--- /dev/null
+++ b/liblog/logger_write.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2020 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 <string>
+
+#include "rwlock.h"
+
+std::string& GetDefaultTag(); // Must read lock default_tag_lock
+extern RwLock default_tag_lock;
\ No newline at end of file
diff --git a/liblog/properties.cpp b/liblog/properties.cpp
index a53c92b..b13662f 100644
--- a/liblog/properties.cpp
+++ b/liblog/properties.cpp
@@ -25,9 +25,12 @@
#include <unistd.h>
#include <algorithm>
+#include <shared_mutex>
#include <private/android_logger.h>
+#include "logger_write.h"
+
static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;
static int lock() {
@@ -93,10 +96,17 @@
/* sizeof() is used on this array below */
static const char log_namespace[] = "persist.log.tag.";
static const size_t base_offset = 8; /* skip "persist." */
- /* calculate the size of our key temporary buffer */
- const size_t taglen = tag ? len : 0;
+
+ auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
+ if (tag == nullptr || len == 0) {
+ tag_lock.lock();
+ auto& tag_string = GetDefaultTag();
+ tag = tag_string.c_str();
+ len = tag_string.size();
+ }
+
/* sizeof(log_namespace) = strlen(log_namespace) + 1 */
- char key[sizeof(log_namespace) + taglen];
+ char key[sizeof(log_namespace) + len];
char* kp;
size_t i;
char c = 0;
@@ -146,7 +156,7 @@
}
}
- if (taglen) {
+ if (len) {
int local_change_detected = change_detected;
if (!not_locked) {
if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) ||
diff --git a/liblog/tests/liblog_default_tag.cpp b/liblog/tests/liblog_default_tag.cpp
index a5baa9f..5643f63 100644
--- a/liblog/tests/liblog_default_tag.cpp
+++ b/liblog/tests/liblog_default_tag.cpp
@@ -96,4 +96,48 @@
LOG(WARNING) << "message";
EXPECT_TRUE(message_seen);
+}
+
+TEST(liblog_default_tag, default_tag_plus_log_severity) {
+ using namespace android::base;
+ bool message_seen = false;
+ std::string expected_tag = "liblog_test_tag";
+ SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
+ message_seen = true;
+ EXPECT_EQ(expected_tag, tag);
+ });
+ __android_log_set_default_tag(expected_tag.c_str());
+
+ auto log_tag_property = "log.tag." + expected_tag;
+ SetProperty(log_tag_property, "V");
+
+ __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
+ EXPECT_TRUE(message_seen);
+ message_seen = false;
+
+ LOG(VERBOSE) << "message";
+ EXPECT_TRUE(message_seen);
+}
+
+TEST(liblog_default_tag, generated_default_tag_plus_log_severity) {
+ using namespace android::base;
+ bool message_seen = false;
+ std::string expected_tag = getprogname();
+ SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
+ message_seen = true;
+ EXPECT_EQ(expected_tag, tag);
+ });
+
+ // Even without any calls to SetDefaultTag(), the first message that attempts to log, will
+ // generate a default tag from getprogname() and check log.tag.<default tag> for loggability. This
+ // case checks that we can log a Verbose message when log.tag.<getprogname()> is set to 'V'.
+ auto log_tag_property = "log.tag." + expected_tag;
+ SetProperty(log_tag_property, "V");
+
+ __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
+ EXPECT_TRUE(message_seen);
+ message_seen = false;
+
+ LOG(VERBOSE) << "message";
+ EXPECT_TRUE(message_seen);
}
\ No newline at end of file
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index 16339d3..698e74d 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -138,8 +138,17 @@
return enabled;
}
+static bool schedtune_enabled() {
+ return (CgroupMap::GetInstance().FindController("schedtune").IsUsable());
+}
+
+static bool cpuctl_enabled() {
+ return (CgroupMap::GetInstance().FindController("cpu").IsUsable());
+}
+
bool schedboost_enabled() {
- static bool enabled = (CgroupMap::GetInstance().FindController("schedtune").IsUsable());
+ static bool enabled = schedtune_enabled() || cpuctl_enabled();
+
return enabled;
}
@@ -162,7 +171,9 @@
std::string group;
if (schedboost_enabled()) {
- if (getCGroupSubsys(tid, "schedtune", group) < 0) return -1;
+ if ((getCGroupSubsys(tid, "schedtune", group) < 0) &&
+ (getCGroupSubsys(tid, "cpu", group) < 0))
+ return -1;
}
if (group.empty() && cpusets_enabled()) {
if (getCGroupSubsys(tid, "cpuset", group) < 0) return -1;
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 9447f86..72f01af 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -288,6 +288,11 @@
return true;
}
+void TaskProfile::MoveTo(TaskProfile* profile) {
+ profile->elements_ = std::move(elements_);
+ profile->res_cached_ = res_cached_;
+}
+
bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const {
for (const auto& element : elements_) {
if (!element->ExecuteForProcess(uid, pid)) {
@@ -458,7 +463,15 @@
LOG(WARNING) << "Unknown profile action: " << action_name;
}
}
- profiles_[profile_name] = profile;
+ auto iter = profiles_.find(profile_name);
+ if (iter == profiles_.end()) {
+ profiles_[profile_name] = profile;
+ } else {
+ // Move the content rather that replace the profile because old profile might be
+ // referenced from an aggregate profile if vendor overrides task profiles
+ profile->MoveTo(iter->second.get());
+ profile.reset();
+ }
}
const Json::Value& aggregateprofiles_val = root["AggregateProfiles"];
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 9f2308c..a64ca50 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -143,6 +143,7 @@
TaskProfile() : res_cached_(false) {}
void Add(std::unique_ptr<ProfileAction> e) { elements_.push_back(std::move(e)); }
+ void MoveTo(TaskProfile* profile);
bool ExecuteForProcess(uid_t uid, pid_t pid) const;
bool ExecuteForTask(int tid) const;
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp
index 1df1dff..00b3367 100644
--- a/libunwindstack/RegsArm64.cpp
+++ b/libunwindstack/RegsArm64.cpp
@@ -100,8 +100,8 @@
fn("x27", regs_[ARM64_REG_R27]);
fn("x28", regs_[ARM64_REG_R28]);
fn("x29", regs_[ARM64_REG_R29]);
- fn("sp", regs_[ARM64_REG_SP]);
fn("lr", regs_[ARM64_REG_LR]);
+ fn("sp", regs_[ARM64_REG_SP]);
fn("pc", regs_[ARM64_REG_PC]);
fn("pst", regs_[ARM64_REG_PSTATE]);
}
@@ -110,10 +110,10 @@
arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
RegsArm64* regs = new RegsArm64();
- memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
+ memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R30 + 1) * sizeof(uint64_t));
uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
- reg_data[ARM64_REG_PC] = user->pc;
reg_data[ARM64_REG_SP] = user->sp;
+ reg_data[ARM64_REG_PC] = user->pc;
reg_data[ARM64_REG_PSTATE] = user->pstate;
return regs;
}
diff --git a/libunwindstack/tests/RegsIterateTest.cpp b/libunwindstack/tests/RegsIterateTest.cpp
index bc95851..47e605a 100644
--- a/libunwindstack/tests/RegsIterateTest.cpp
+++ b/libunwindstack/tests/RegsIterateTest.cpp
@@ -111,8 +111,8 @@
result.push_back({"x27", ARM64_REG_R27});
result.push_back({"x28", ARM64_REG_R28});
result.push_back({"x29", ARM64_REG_R29});
- result.push_back({"sp", ARM64_REG_SP});
result.push_back({"lr", ARM64_REG_LR});
+ result.push_back({"sp", ARM64_REG_SP});
result.push_back({"pc", ARM64_REG_PC});
result.push_back({"pst", ARM64_REG_PSTATE});
return result;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e575808..7d27c3a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -165,7 +165,7 @@
mkdir /mnt/secure/asec 0700 root root
mkdir /mnt/asec 0755 root system
mkdir /mnt/obb 0755 root system
- mkdir /mnt/media_rw 0750 root media_rw
+ mkdir /mnt/media_rw 0750 root external_storage
mkdir /mnt/user 0755 root root
mkdir /mnt/user/0 0755 root root
mkdir /mnt/user/0/self 0755 root root