Merge "libsnapshot: update resume offset calculation" into main
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index eed81fc..e44dc10 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -28,7 +28,6 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
-#include <async_safe/log.h>
#include <bionic/macros.h>
#include "tombstone.pb.h"
@@ -138,7 +137,8 @@
break;
default:
- async_safe_fatal("unknown architecture");
+ CBL("Unknown architecture %d printing thread registers", tombstone.arch());
+ return;
}
for (const auto& reg : thread.registers()) {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index d55f8d3..faea5eb 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -828,7 +828,14 @@
<< ",type=" << entry.fs_type << ", gc_allowance=" << gc_allowance << "%)=" << ret
<< "(" << save_errno << ")";
}
- ret = mount(source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
+
+ // Let's get the raw dm target, if it's a symlink, since some existing applications
+ // rely on /proc/mounts to find the userdata's dm target path. Don't break that assumption.
+ std::string real_source;
+ if (!android::base::Realpath(source, &real_source)) {
+ real_source = source;
+ }
+ ret = mount(real_source.c_str(), target.c_str(), entry.fs_type.c_str(), mountflags,
opts.c_str());
save_errno = errno;
if (try_f2fs_gc_allowance) gc_allowance += 10;
diff --git a/init/security.cpp b/init/security.cpp
index 0c73fae..3e15447 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/perf_event.h>
+#include <math.h>
#include <selinux/selinux.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
@@ -121,8 +122,12 @@
}
#elif defined(__x86_64__)
// x86_64 supports 28 - 32 rnd bits, but Android wants to ensure that the
- // theoretical maximum of 32 bits is always supported and used.
- if (SetMmapRndBitsMin(32, 32, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
+ // theoretical maximum of 32 bits is always supported and used; except in
+ // the case of the x86 page size emulator which supports a maximum
+ // of 30 bits for 16k page size, or 28 bits for 64k page size.
+ int max_bits = 32 - (static_cast<int>(log2(getpagesize())) - 12);
+ if (SetMmapRndBitsMin(max_bits, max_bits, false) &&
+ (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
return {};
}
#elif defined(__arm__) || defined(__i386__)
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index a319c63..9107838 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -87,7 +87,6 @@
bool setProcessGroupSoftLimit(uid_t uid, int initialPid, int64_t softLimitInBytes);
bool setProcessGroupLimit(uid_t uid, int initialPid, int64_t limitInBytes);
-void removeAllProcessGroups(void);
void removeAllEmptyProcessGroups(void);
// Provides the path for an attribute in a specific process group
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index d352f0e..b4482d0 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -233,7 +233,7 @@
return ret;
}
-static bool RemoveUidCgroups(const std::string& uid_path, bool empty_only) {
+static bool RemoveEmptyUidCgroups(const std::string& uid_path) {
std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path.c_str()), closedir);
bool empty = true;
if (uid != NULL) {
@@ -248,21 +248,6 @@
}
auto path = StringPrintf("%s/%s", uid_path.c_str(), dir->d_name);
- if (empty_only) {
- struct stat st;
- auto procs_file = StringPrintf("%s/%s", path.c_str(),
- PROCESSGROUP_CGROUP_PROCS_FILE);
- if (stat(procs_file.c_str(), &st) == -1) {
- PLOG(ERROR) << "Failed to get stats for " << procs_file;
- continue;
- }
- if (st.st_size > 0) {
- // skip non-empty groups
- LOG(VERBOSE) << "Skipping non-empty group " << path;
- empty = false;
- continue;
- }
- }
LOG(VERBOSE) << "Removing " << path;
if (rmdir(path.c_str()) == -1) {
if (errno != EBUSY) {
@@ -275,7 +260,9 @@
return empty;
}
-static void removeAllProcessGroupsInternal(bool empty_only) {
+void removeAllEmptyProcessGroups() {
+ LOG(VERBOSE) << "removeAllEmptyProcessGroups()";
+
std::vector<std::string> cgroups;
std::string path, memcg_apps_path;
@@ -302,7 +289,7 @@
}
auto path = StringPrintf("%s/%s", cgroup_root_path.c_str(), dir->d_name);
- if (!RemoveUidCgroups(path, empty_only)) {
+ if (!RemoveEmptyUidCgroups(path)) {
LOG(VERBOSE) << "Skip removing " << path;
continue;
}
@@ -315,16 +302,6 @@
}
}
-void removeAllProcessGroups() {
- LOG(VERBOSE) << "removeAllProcessGroups()";
- removeAllProcessGroupsInternal(false);
-}
-
-void removeAllEmptyProcessGroups() {
- LOG(VERBOSE) << "removeAllEmptyProcessGroups()";
- removeAllProcessGroupsInternal(true);
-}
-
/**
* Process groups are primarily created by the Zygote, meaning that uid/pid groups are created by
* the user root. Ownership for the newly created cgroup and all of its files must thus be
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 3e4393d..d013ec8 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -1,13 +1,6 @@
{
"Cgroups": [
{
- "Controller": "blkio",
- "Path": "/dev/blkio",
- "Mode": "0775",
- "UID": "system",
- "GID": "system"
- },
- {
"Controller": "cpu",
"Path": "/dev/cpuctl",
"Mode": "0755",
@@ -39,6 +32,12 @@
{
"Controller": "freezer",
"Path": "."
+ },
+ {
+ "Controller": "io",
+ "Path": ".",
+ "NeedsActivation": true,
+ "Optional": true
}
]
}
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 1fc66ba..2c08b0b 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -76,6 +76,21 @@
"Name": "FreezerState",
"Controller": "freezer",
"File": "cgroup.freeze"
+ },
+ {
+ "Name": "BfqWeight",
+ "Controller": "io",
+ "File": "io.bfq.weight"
+ },
+ {
+ "Name": "CfqGroupIdle",
+ "Controller": "io",
+ "File": "io.group_idle"
+ },
+ {
+ "Name": "CfqWeight",
+ "Controller": "io",
+ "File": "io.weight"
}
],
@@ -439,11 +454,30 @@
"Name": "LowIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": "background"
+ "Name": "BfqWeight",
+ "Value": "10",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "200",
+ "Optional": "true"
}
}
]
@@ -452,11 +486,30 @@
"Name": "NormalIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
@@ -465,11 +518,30 @@
"Name": "HighIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
@@ -478,11 +550,30 @@
"Name": "MaxIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index f51b076..d5bd47c 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -316,7 +316,7 @@
FdCacheHelper::Init(controller_.GetProcsFilePath(path_, 0, 0), fd_[ProfileAction::RCT_PROCESS]);
}
-bool SetCgroupAction::AddTidToCgroup(int tid, int fd, const char* controller_name) {
+bool SetCgroupAction::AddTidToCgroup(int tid, int fd, ResourceCacheType cache_type) const {
if (tid <= 0) {
return true;
}
@@ -332,6 +332,7 @@
return true;
}
+ const char* controller_name = controller()->name();
// ENOSPC is returned when cpuset cgroup that we are joining has no online cpus
if (errno == ENOSPC && !strcmp(controller_name, "cpuset")) {
// This is an abnormal case happening only in testing, so report it only once
@@ -345,7 +346,8 @@
<< "' into cpuset because all cpus in that cpuset are offline";
empty_cpuset_reported = true;
} else {
- PLOG(ERROR) << "AddTidToCgroup failed to write '" << value << "'; fd=" << fd;
+ PLOG(ERROR) << "AddTidToCgroup failed to write '" << value << "'; path=" << path_ << "; "
+ << (cache_type == RCT_TASK ? "task" : "process");
}
return false;
@@ -356,7 +358,7 @@
std::lock_guard<std::mutex> lock(fd_mutex_);
if (FdCacheHelper::IsCached(fd_[cache_type])) {
// fd is cached, reuse it
- if (!AddTidToCgroup(id, fd_[cache_type], controller()->name())) {
+ if (!AddTidToCgroup(id, fd_[cache_type], cache_type)) {
LOG(ERROR) << "Failed to add task into cgroup";
return ProfileAction::FAIL;
}
@@ -391,7 +393,7 @@
PLOG(WARNING) << Name() << "::" << __func__ << ": failed to open " << procs_path;
return false;
}
- if (!AddTidToCgroup(pid, tmp_fd, controller()->name())) {
+ if (!AddTidToCgroup(pid, tmp_fd, RCT_PROCESS)) {
LOG(ERROR) << "Failed to add task into cgroup";
return false;
}
@@ -412,7 +414,7 @@
PLOG(WARNING) << Name() << "::" << __func__ << ": failed to open " << tasks_path;
return false;
}
- if (!AddTidToCgroup(tid, tmp_fd, controller()->name())) {
+ if (!AddTidToCgroup(tid, tmp_fd, RCT_TASK)) {
LOG(ERROR) << "Failed to add task into cgroup";
return false;
}
@@ -866,7 +868,13 @@
auto controller = cg_map.FindController(controller_name);
if (controller.HasValue()) {
- profile->Add(std::make_unique<SetCgroupAction>(controller, path));
+ if (controller.version() == 1) {
+ profile->Add(std::make_unique<SetCgroupAction>(controller, path));
+ } else {
+ LOG(WARNING) << "A JoinCgroup action in the " << profile_name
+ << " profile is used for controller " << controller_name
+ << " in the cgroup v2 hierarchy and will be ignored";
+ }
} else {
LOG(WARNING) << "JoinCgroup: controller " << controller_name << " is not found";
}
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 4663f64..16ffe63 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -160,7 +160,7 @@
android::base::unique_fd fd_[ProfileAction::RCT_COUNT];
mutable std::mutex fd_mutex_;
- static bool AddTidToCgroup(int tid, int fd, const char* controller_name);
+ bool AddTidToCgroup(int tid, int fd, ResourceCacheType cache_type) const;
CacheUseResult UseCachedFd(ResourceCacheType cache_type, int id) const;
};
diff --git a/libutils/binder/StrongPointer_test.cpp b/libutils/binder/StrongPointer_test.cpp
index f27c1f1..aa993c3 100644
--- a/libutils/binder/StrongPointer_test.cpp
+++ b/libutils/binder/StrongPointer_test.cpp
@@ -106,3 +106,17 @@
EXPECT_DEATH(sp<TypeParam>::fromExisting(foo), "");
delete foo;
}
+
+TYPED_TEST(StrongPointer, release) {
+ bool isDeleted = false;
+ TypeParam* foo = nullptr;
+ {
+ sp<TypeParam> sp1 = sp<TypeParam>::make(&isDeleted);
+ ASSERT_EQ(1, sp1->getStrongCount());
+ foo = sp1.release();
+ }
+ ASSERT_FALSE(isDeleted) << "release failed, deleted anyway when sp left scope";
+ ASSERT_EQ(1, foo->getStrongCount()) << "release mismanaged refcount";
+ foo->decStrong(nullptr);
+ ASSERT_TRUE(isDeleted) << "foo was leaked!";
+}
diff --git a/libutils/binder/include/utils/StrongPointer.h b/libutils/binder/include/utils/StrongPointer.h
index 54aa691..43c00c9 100644
--- a/libutils/binder/include/utils/StrongPointer.h
+++ b/libutils/binder/include/utils/StrongPointer.h
@@ -98,6 +98,15 @@
void clear();
+ // Releases the ownership of the object managed by this instance of sp, if any.
+ // The caller is now responsible for managing it. That is, the caller must ensure
+ // decStrong() is called when the pointer is no longer used.
+ [[nodiscard]] inline T* release() noexcept {
+ auto ret = m_ptr;
+ m_ptr = nullptr;
+ return ret;
+ }
+
// Accessors
inline T& operator* () const { return *m_ptr; }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 317f809..fb64736 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -219,26 +219,6 @@
write /dev/stune/nnapi-hal/schedtune.boost 1
write /dev/stune/nnapi-hal/schedtune.prefer_idle 1
- # Create blkio group and apply initial settings.
- # This feature needs kernel to support it, and the
- # device's init.rc must actually set the correct values.
- mkdir /dev/blkio/background
- chown system system /dev/blkio
- chown system system /dev/blkio/background
- chown system system /dev/blkio/tasks
- chown system system /dev/blkio/background/tasks
- chown system system /dev/blkio/cgroup.procs
- chown system system /dev/blkio/background/cgroup.procs
- chmod 0664 /dev/blkio/tasks
- chmod 0664 /dev/blkio/background/tasks
- chmod 0664 /dev/blkio/cgroup.procs
- chmod 0664 /dev/blkio/background/cgroup.procs
- write /dev/blkio/blkio.weight 1000
- write /dev/blkio/background/blkio.weight 200
- write /dev/blkio/background/blkio.bfq.weight 10
- write /dev/blkio/blkio.group_idle 0
- write /dev/blkio/background/blkio.group_idle 0
-
restorecon_recursive /mnt
mount configfs none /config nodev noexec nosuid