Merge "libprocessgroup: ensure schedboost_enabled is true with uclamp"
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/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/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