Merge "Adding adb_debug.prop into debug ramdisk"
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index f25955d..552df41 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -838,26 +838,25 @@
#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
-/*
- * The sideload-host protocol serves the data in a file (given on the
- * command line) to the client, using a simple protocol:
- *
- * - The connect message includes the total number of bytes in the
- * file and a block size chosen by us.
- *
- * - The other side sends the desired block number as eight decimal
- * digits (eg "00000023" for block 23). Blocks are numbered from
- * zero.
- *
- * - We send back the data of the requested block. The last block is
- * likely to be partial; when the last block is requested we only
- * send the part of the block that exists, it's not padded up to the
- * block size.
- *
- * - When the other side sends "DONEDONE" instead of a block number,
- * we hang up.
- */
-static int adb_sideload_host(const char* filename) {
+// Connects to the sideload / rescue service on the device (served by minadbd) and sends over the
+// data in an OTA package.
+//
+// It uses a simple protocol as follows.
+//
+// - The connect message includes the total number of bytes in the file and a block size chosen by
+// us.
+//
+// - The other side sends the desired block number as eight decimal digits (e.g. "00000023" for
+// block 23). Blocks are numbered from zero.
+//
+// - We send back the data of the requested block. The last block is likely to be partial; when the
+// last block is requested we only send the part of the block that exists, it's not padded up to
+// the block size.
+//
+// - When the other side sends "DONEDONE" or "FAILFAIL" instead of a block number, we have done all
+// the data transfer.
+//
+static int adb_sideload_install(const char* filename, bool rescue_mode) {
// TODO: use a LinePrinter instead...
struct stat sb;
if (stat(filename, &sb) == -1) {
@@ -870,14 +869,18 @@
return -1;
}
- std::string service =
- android::base::StringPrintf("sideload-host:%" PRId64 ":%d",
- static_cast<int64_t>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
+ std::string service = android::base::StringPrintf(
+ "%s:%" PRId64 ":%d", rescue_mode ? "rescue-install" : "sideload-host",
+ static_cast<int64_t>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
std::string error;
unique_fd device_fd(adb_connect(service, &error));
if (device_fd < 0) {
fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
+ if (rescue_mode) {
+ return -1;
+ }
+
// If this is a small enough package, maybe this is an older device that doesn't
// support sideload-host. Try falling back to the older (<= K) sideload method.
if (sb.st_size > INT_MAX) {
@@ -901,10 +904,14 @@
}
buf[8] = '\0';
- if (strcmp("DONEDONE", buf) == 0) {
+ if (strcmp(kSideloadServiceExitSuccess, buf) == 0 ||
+ strcmp(kSideloadServiceExitFailure, buf) == 0) {
printf("\rTotal xfer: %.2fx%*s\n",
static_cast<double>(xfer) / (sb.st_size ? sb.st_size : 1),
static_cast<int>(strlen(filename) + 10), "");
+ if (strcmp(kSideloadServiceExitFailure, buf) == 0) {
+ return 1;
+ }
return 0;
}
@@ -1628,11 +1635,25 @@
return adb_kill_server() ? 0 : 1;
} else if (!strcmp(argv[0], "sideload")) {
if (argc != 2) error_exit("sideload requires an argument");
- if (adb_sideload_host(argv[1])) {
+ if (adb_sideload_install(argv[1], false /* rescue_mode */)) {
return 1;
} else {
return 0;
}
+ } else if (!strcmp(argv[0], "rescue")) {
+ // adb rescue getprop <prop>
+ // adb rescue install <filename>
+ if (argc != 3) error_exit("rescue requires two arguments");
+ if (!strcmp(argv[1], "getprop")) {
+ return adb_connect_command(android::base::StringPrintf("rescue-getprop:%s", argv[2]));
+ } else if (!strcmp(argv[1], "install")) {
+ if (adb_sideload_install(argv[2], true /* rescue_mode */) != 0) {
+ return 1;
+ }
+ } else {
+ error_exit("invalid rescue argument");
+ }
+ return 0;
} else if (!strcmp(argv[0], "tcpip")) {
if (argc != 2) error_exit("tcpip requires an argument");
int port;
diff --git a/adb/services.h b/adb/services.h
index 0ce25ba..8f3919b 100644
--- a/adb/services.h
+++ b/adb/services.h
@@ -23,5 +23,9 @@
constexpr char kShellServiceArgPty[] = "pty";
constexpr char kShellServiceArgShellProtocol[] = "v2";
+// Special flags sent by minadbd that indicate the end of sideload transfer and install result.
+constexpr char kSideloadServiceExitSuccess[] = "DONEDONE";
+constexpr char kSideloadServiceExitFailure[] = "FAILFAIL";
+
unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func);
#endif // SERVICES_H_
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 8984752..e46e497 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -636,7 +636,7 @@
LERROR << mnt_type << " has no mkfs cookbook";
return false;
}
- command += " " + scratch_device;
+ command += " " + scratch_device + " >/dev/null 2>/dev/null </dev/null";
fs_mgr_set_blk_ro(scratch_device, false);
auto ret = system(command.c_str());
if (ret) {
diff --git a/init/Android.bp b/init/Android.bp
index 69ee34f..69498ac 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -61,6 +61,7 @@
static_libs: [
"libseccomp_policy",
"libavb",
+ "libc++fs",
"libcgrouprc_format",
"libprotobuf-cpp-lite",
"libpropertyinfoserializer",
diff --git a/init/Android.mk b/init/Android.mk
index 7ab5c48..b02c926 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -73,12 +73,14 @@
# Set up the same mount points on the ramdisk that system-as-root contains.
LOCAL_POST_INSTALL_CMD := mkdir -p \
$(TARGET_RAMDISK_OUT)/apex \
+ $(TARGET_RAMDISK_OUT)/debug_ramdisk \
$(TARGET_RAMDISK_OUT)/dev \
$(TARGET_RAMDISK_OUT)/mnt \
$(TARGET_RAMDISK_OUT)/proc \
$(TARGET_RAMDISK_OUT)/sys \
LOCAL_STATIC_LIBRARIES := \
+ libc++fs \
libfs_avb \
libfs_mgr \
libfec \
diff --git a/init/debug_ramdisk.h b/init/debug_ramdisk.h
new file mode 100644
index 0000000..4e3a395
--- /dev/null
+++ b/init/debug_ramdisk.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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
+
+namespace android {
+namespace init {
+
+constexpr const char kDebugRamdiskProp[] = "/debug_ramdisk/adb_debug.prop";
+constexpr const char kDebugRamdiskSEPolicy[] = "/debug_ramdisk/userdebug_plat_sepolicy.cil";
+
+} // namespace init
+} // namespace android
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index c566676..8b95e38 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <filesystem>
#include <string>
#include <vector>
@@ -35,6 +36,7 @@
#include <cutils/android_reboot.h>
#include <private/android_filesystem_config.h>
+#include "debug_ramdisk.h"
#include "first_stage_mount.h"
#include "reboot_utils.h"
#include "switch_root.h"
@@ -44,6 +46,8 @@
using namespace std::literals;
+namespace fs = std::filesystem;
+
namespace android {
namespace init {
@@ -159,6 +163,9 @@
CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
+ // /debug_ramdisk is used to preserve additional files from the debug ramdisk
+ CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+ "mode=0755,uid=0,gid=0"));
#undef CHECKCALL
// Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
@@ -202,7 +209,14 @@
// If this file is present, the second-stage init will use a userdebug sepolicy
// and load adb_debug.prop to allow adb root, if the device is unlocked.
if (access("/force_debuggable", F_OK) == 0) {
- setenv("INIT_FORCE_DEBUGGABLE", "true", 1);
+ std::error_code ec; // to invoke the overloaded copy_file() that won't throw.
+ if (!fs::copy_file("/adb_debug.prop", kDebugRamdiskProp, ec) ||
+ !fs::copy_file("/userdebug_plat_sepolicy.cil", kDebugRamdiskSEPolicy, ec)) {
+ LOG(ERROR) << "Failed to setup debug ramdisk";
+ } else {
+ // setenv for second-stage init to read above kDebugRamdisk* files.
+ setenv("INIT_FORCE_DEBUGGABLE", "true", 1);
+ }
}
if (!DoFirstStageMount()) {
diff --git a/init/init.cpp b/init/init.cpp
index ac0e67a..c79e459 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -621,6 +621,12 @@
});
}
+static void UmountDebugRamdisk() {
+ if (umount("/debug_ramdisk") != 0) {
+ LOG(ERROR) << "Failed to umount /debug_ramdisk";
+ }
+}
+
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
@@ -690,6 +696,7 @@
InstallSignalFdHandler(&epoll);
property_load_boot_defaults(load_debug_prop);
+ UmountDebugRamdisk();
fs_mgr_vendor_overlay_mount_all();
export_oem_lock_status();
StartPropertyService(&epoll);
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 467568c..bf3b317 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -56,6 +56,7 @@
#include <selinux/label.h>
#include <selinux/selinux.h>
+#include "debug_ramdisk.h"
#include "epoll.h"
#include "init.h"
#include "persistent_properties.h"
@@ -887,9 +888,8 @@
load_properties_from_file("/factory/factory.prop", "ro.*", &properties);
if (load_debug_prop) {
- constexpr static const char kAdbDebugProp[] = "/system/etc/adb_debug.prop";
- LOG(INFO) << "Loading " << kAdbDebugProp;
- load_properties_from_file(kAdbDebugProp, nullptr, &properties);
+ LOG(INFO) << "Loading " << kDebugRamdiskProp;
+ load_properties_from_file(kDebugRamdiskProp, nullptr, &properties);
}
for (const auto& [name, value] : properties) {
diff --git a/init/selinux.cpp b/init/selinux.cpp
index aa66baa..132fc13 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -64,6 +64,7 @@
#include <fs_avb/fs_avb.h>
#include <selinux/android.h>
+#include "debug_ramdisk.h"
#include "reboot_utils.h"
#include "util.h"
@@ -271,8 +272,6 @@
}
constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
-constexpr const char userdebug_plat_policy_cil_file[] =
- "/system/etc/selinux/userdebug_plat_sepolicy.cil";
bool IsSplitPolicyDevice() {
return access(plat_policy_cil_file, R_OK) != -1;
@@ -292,7 +291,7 @@
const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
bool use_userdebug_policy =
((force_debuggable_env && "true"s == force_debuggable_env) &&
- AvbHandle::IsDeviceUnlocked() && access(userdebug_plat_policy_cil_file, F_OK) == 0);
+ AvbHandle::IsDeviceUnlocked() && access(kDebugRamdiskSEPolicy, F_OK) == 0);
if (use_userdebug_policy) {
LOG(WARNING) << "Using userdebug system sepolicy";
}
@@ -367,7 +366,7 @@
// clang-format off
std::vector<const char*> compile_args {
"/system/bin/secilc",
- use_userdebug_policy ? userdebug_plat_policy_cil_file : plat_policy_cil_file,
+ use_userdebug_policy ? kDebugRamdiskSEPolicy: plat_policy_cil_file,
"-m", "-M", "true", "-G", "-N",
"-c", version_as_string.c_str(),
plat_mapping_file.c_str(),
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 86e6035..7e6bf45 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -24,16 +24,20 @@
__BEGIN_DECLS
static constexpr const char* CGROUPV2_CONTROLLER_NAME = "cgroup2";
-static constexpr const char* CGROUPS_RC_PATH = "/dev/cgroup_info/cgroup.rc";
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path);
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path);
bool CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path);
-bool UsePerAppMemcg();
+bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache = false);
+bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
+ bool use_fd_cache = false);
-bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles);
-bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles);
+#ifndef __ANDROID_VNDK__
+
+static constexpr const char* CGROUPS_RC_PATH = "/dev/cgroup_info/cgroup.rc";
+
+bool UsePerAppMemcg();
// Return 0 and removes the cgroup if there are no longer any processes in it.
// Returns -1 in the case of an error occurring or if there are processes still running
@@ -54,4 +58,6 @@
void removeAllProcessGroups(void);
+#endif // __ANDROID_VNDK__
+
__END_DECLS
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index abe63dd..1485ae9 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -112,12 +112,16 @@
return memcg_supported;
}
-bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles) {
+bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
+ bool use_fd_cache) {
const TaskProfiles& tp = TaskProfiles::GetInstance();
for (const auto& name : profiles) {
- const TaskProfile* profile = tp.GetProfile(name);
+ TaskProfile* profile = tp.GetProfile(name);
if (profile != nullptr) {
+ if (use_fd_cache) {
+ profile->EnableResourceCaching();
+ }
if (!profile->ExecuteForProcess(uid, pid)) {
PLOG(WARNING) << "Failed to apply " << name << " process profile";
}
@@ -129,12 +133,15 @@
return true;
}
-bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles) {
+bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache) {
const TaskProfiles& tp = TaskProfiles::GetInstance();
for (const auto& name : profiles) {
- const TaskProfile* profile = tp.GetProfile(name);
+ TaskProfile* profile = tp.GetProfile(name);
if (profile != nullptr) {
+ if (use_fd_cache) {
+ profile->EnableResourceCaching();
+ }
if (!profile->ExecuteForTask(tid)) {
PLOG(WARNING) << "Failed to apply " << name << " task profile";
}
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index ab0f1ca..fe4f93b 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -46,26 +46,34 @@
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"HighEnergySaving", "ProcessCapacityLow", "LowIoPriority",
- "TimerSlackHigh"})
+ return SetTaskProfiles(tid,
+ {"HighEnergySaving", "ProcessCapacityLow", "LowIoPriority",
+ "TimerSlackHigh"},
+ true)
? 0
: -1;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"HighPerformance", "ProcessCapacityHigh", "HighIoPriority",
- "TimerSlackNormal"})
+ return SetTaskProfiles(tid,
+ {"HighPerformance", "ProcessCapacityHigh", "HighIoPriority",
+ "TimerSlackNormal"},
+ true)
? 0
: -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"MaxPerformance", "ProcessCapacityMax", "MaxIoPriority",
- "TimerSlackNormal"})
+ return SetTaskProfiles(tid,
+ {"MaxPerformance", "ProcessCapacityMax", "MaxIoPriority",
+ "TimerSlackNormal"},
+ true)
? 0
: -1;
case SP_SYSTEM:
- return SetTaskProfiles(tid, {"ServiceCapacityLow", "TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"ServiceCapacityLow", "TimerSlackNormal"}, true) ? 0 : -1;
case SP_RESTRICTED:
- return SetTaskProfiles(tid, {"ServiceCapacityRestricted", "TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"ServiceCapacityRestricted", "TimerSlackNormal"}, true)
+ ? 0
+ : -1;
default:
break;
}
@@ -126,17 +134,17 @@
switch (policy) {
case SP_BACKGROUND:
- return SetTaskProfiles(tid, {"HighEnergySaving", "TimerSlackHigh"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"HighEnergySaving", "TimerSlackHigh"}, true) ? 0 : -1;
case SP_FOREGROUND:
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
- return SetTaskProfiles(tid, {"HighPerformance", "TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"HighPerformance", "TimerSlackNormal"}, true) ? 0 : -1;
case SP_TOP_APP:
- return SetTaskProfiles(tid, {"MaxPerformance", "TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"MaxPerformance", "TimerSlackNormal"}, true) ? 0 : -1;
case SP_RT_APP:
- return SetTaskProfiles(tid, {"RealtimePerformance", "TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"RealtimePerformance", "TimerSlackNormal"}, true) ? 0 : -1;
default:
- return SetTaskProfiles(tid, {"TimerSlackNormal"}) ? 0 : -1;
+ return SetTaskProfiles(tid, {"TimerSlackNormal"}, true) ? 0 : -1;
}
return 0;
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 4b45c87..40d8d90 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -138,31 +138,38 @@
SetCgroupAction::SetCgroupAction(const CgroupController& c, const std::string& p)
: controller_(c), path_(p) {
-#ifdef CACHE_FILE_DESCRIPTORS
- // cache file descriptor only if path is app independent
+ // file descriptors for app-dependent paths can't be cached
if (IsAppDependentPath(path_)) {
// file descriptor is not cached
- fd_.reset(-2);
+ fd_.reset(FDS_APP_DEPENDENT);
return;
}
- std::string tasks_path = c.GetTasksFilePath(p);
+ // file descriptor can be cached later on request
+ fd_.reset(FDS_NOT_CACHED);
+}
+
+void SetCgroupAction::EnableResourceCaching() {
+ if (fd_ != FDS_NOT_CACHED) {
+ return;
+ }
+
+ std::string tasks_path = controller_.GetTasksFilePath(path_);
if (access(tasks_path.c_str(), W_OK) != 0) {
// file is not accessible
- fd_.reset(-1);
+ fd_.reset(FDS_INACCESSIBLE);
return;
}
unique_fd fd(TEMP_FAILURE_RETRY(open(tasks_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (fd < 0) {
PLOG(ERROR) << "Failed to cache fd '" << tasks_path << "'";
- fd_.reset(-1);
+ fd_.reset(FDS_INACCESSIBLE);
return;
}
fd_ = std::move(fd);
-#endif
}
bool SetCgroupAction::AddTidToCgroup(int tid, int fd) {
@@ -184,8 +191,7 @@
}
bool SetCgroupAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
-#ifdef CACHE_FILE_DESCRIPTORS
- if (fd_ >= 0) {
+ if (IsFdValid()) {
// fd is cached, reuse it
if (!AddTidToCgroup(pid, fd_)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -194,12 +200,12 @@
return true;
}
- if (fd_ == -1) {
+ if (fd_ == FDS_INACCESSIBLE) {
// no permissions to access the file, ignore
return true;
}
- // this is app-dependent path, file descriptor is not cached
+ // this is app-dependent path and fd is not cached or cached fd can't be used
std::string procs_path = controller()->GetProcsFilePath(path_, uid, pid);
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(procs_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (tmp_fd < 0) {
@@ -212,25 +218,10 @@
}
return true;
-#else
- std::string procs_path = controller()->GetProcsFilePath(path_, uid, pid);
- unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(procs_path.c_str(), O_WRONLY | O_CLOEXEC)));
- if (tmp_fd < 0) {
- // no permissions to access the file, ignore
- return true;
- }
- if (!AddTidToCgroup(pid, tmp_fd)) {
- LOG(ERROR) << "Failed to add task into cgroup";
- return false;
- }
-
- return true;
-#endif
}
bool SetCgroupAction::ExecuteForTask(int tid) const {
-#ifdef CACHE_FILE_DESCRIPTORS
- if (fd_ >= 0) {
+ if (IsFdValid()) {
// fd is cached, reuse it
if (!AddTidToCgroup(tid, fd_)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -239,20 +230,23 @@
return true;
}
- if (fd_ == -1) {
+ if (fd_ == FDS_INACCESSIBLE) {
// no permissions to access the file, ignore
return true;
}
- // application-dependent path can't be used with tid
- LOG(ERROR) << "Application profile can't be applied to a thread";
- return false;
-#else
+ if (fd_ == FDS_APP_DEPENDENT) {
+ // application-dependent path can't be used with tid
+ PLOG(ERROR) << "Application profile can't be applied to a thread";
+ return false;
+ }
+
+ // fd was not cached because cached fd can't be used
std::string tasks_path = controller()->GetTasksFilePath(path_);
unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(tasks_path.c_str(), O_WRONLY | O_CLOEXEC)));
if (tmp_fd < 0) {
- // no permissions to access the file, ignore
- return true;
+ PLOG(WARNING) << "Failed to open " << tasks_path << ": " << strerror(errno);
+ return false;
}
if (!AddTidToCgroup(tid, tmp_fd)) {
LOG(ERROR) << "Failed to add task into cgroup";
@@ -260,7 +254,6 @@
}
return true;
-#endif
}
bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const {
@@ -284,6 +277,18 @@
return true;
}
+void TaskProfile::EnableResourceCaching() {
+ if (res_cached_) {
+ return;
+ }
+
+ for (auto& element : elements_) {
+ element->EnableResourceCaching();
+ }
+
+ res_cached_ = true;
+}
+
TaskProfiles& TaskProfiles::GetInstance() {
// Deliberately leak this object to avoid a race between destruction on
// process exit and concurrent access from another thread.
@@ -411,7 +416,7 @@
return true;
}
-const TaskProfile* TaskProfiles::GetProfile(const std::string& name) const {
+TaskProfile* TaskProfiles::GetProfile(const std::string& name) const {
auto iter = profiles_.find(name);
if (iter != profiles_.end()) {
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 37cc305..445647d 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -48,6 +48,8 @@
// Default implementations will fail
virtual bool ExecuteForProcess(uid_t, pid_t) const { return false; };
virtual bool ExecuteForTask(int) const { return false; };
+
+ virtual void EnableResourceCaching() {}
};
// Profile actions
@@ -110,31 +112,40 @@
virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
virtual bool ExecuteForTask(int tid) const;
+ virtual void EnableResourceCaching();
const CgroupController* controller() const { return &controller_; }
std::string path() const { return path_; }
private:
+ enum FdState {
+ FDS_INACCESSIBLE = -1,
+ FDS_APP_DEPENDENT = -2,
+ FDS_NOT_CACHED = -3,
+ };
+
CgroupController controller_;
std::string path_;
-#ifdef CACHE_FILE_DESCRIPTORS
android::base::unique_fd fd_;
-#endif
static bool IsAppDependentPath(const std::string& path);
static bool AddTidToCgroup(int tid, int fd);
+
+ bool IsFdValid() const { return fd_ > FDS_INACCESSIBLE; }
};
class TaskProfile {
public:
- TaskProfile() {}
+ TaskProfile() : res_cached_(false) {}
void Add(std::unique_ptr<ProfileAction> e) { elements_.push_back(std::move(e)); }
bool ExecuteForProcess(uid_t uid, pid_t pid) const;
bool ExecuteForTask(int tid) const;
+ void EnableResourceCaching();
private:
+ bool res_cached_;
std::vector<std::unique_ptr<ProfileAction>> elements_;
};
@@ -143,7 +154,7 @@
// Should be used by all users
static TaskProfiles& GetInstance();
- const TaskProfile* GetProfile(const std::string& name) const;
+ TaskProfile* GetProfile(const std::string& name) const;
const ProfileAttribute* GetAttribute(const std::string& name) const;
private:
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 620bc95..f084cd2 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -97,7 +97,7 @@
#
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \
+ dev proc sys system data odm oem acct config storage mnt apex debug_ramdisk $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9bb624a..295e704 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -608,6 +608,10 @@
# IOCTLs on ashmem fds any more.
setprop sys.use_memfd false
+ # Set fscklog permission
+ chown root system /dev/fscklogs/log
+ chmod 0770 /dev/fscklogs/log
+
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start && property:ro.crypto.state=unencrypted