Merge "init: make CheckPropertyTriggers() more efficient"
diff --git a/adb/daemon/services.cpp b/adb/daemon/services.cpp
index a44c10b..4ec90d2 100644
--- a/adb/daemon/services.cpp
+++ b/adb/daemon/services.cpp
@@ -39,6 +39,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+#include <cutils/android_reboot.h>
#include <cutils/sockets.h>
#include <log/log_properties.h>
@@ -140,6 +141,26 @@
WriteFdExactly(fd.get(), "spinning\n");
}
+[[maybe_unused]] static unique_fd reboot_device(const std::string& name) {
+#if defined(__ANDROID_RECOVERY__)
+ if (!__android_log_is_debuggable()) {
+ auto reboot_service = [name](unique_fd fd) {
+ std::string reboot_string = android::base::StringPrintf("reboot,%s", name.c_str());
+ if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
+ WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str());
+ return;
+ }
+ while (true) pause();
+ };
+ return create_service_thread("reboot", reboot_service);
+ }
+#endif
+ // Fall through
+ std::string cmd = "/system/bin/reboot ";
+ cmd += name;
+ return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
+}
+
struct ServiceSocket : public asocket {
ServiceSocket() {
install_local_socket(this);
@@ -252,9 +273,7 @@
cmd += name;
return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if (android::base::ConsumePrefix(&name, "reboot:")) {
- std::string cmd = "/system/bin/reboot ";
- cmd += name;
- return StartSubprocess(cmd, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
+ return reboot_device(std::string(name));
} else if (name.starts_with("root:")) {
return create_service_thread("root", restart_root_service);
} else if (name.starts_with("unroot:")) {
diff --git a/fastboot/constants.h b/fastboot/constants.h
index 7fba67c..5a554a0 100644
--- a/fastboot/constants.h
+++ b/fastboot/constants.h
@@ -68,3 +68,4 @@
#define FB_VAR_BATTERY_SOC_OK "battery-soc-ok"
#define FB_VAR_SUPER_PARTITION_NAME "super-partition-name"
#define FB_VAR_SNAPSHOT_UPDATE_STATUS "snapshot-update-status"
+#define FB_VAR_CPU_ABI "cpu-abi"
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index dfd5690..a2c95d6 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -105,7 +105,8 @@
{FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
{FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
{FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}},
- {FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}}};
+ {FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}},
+ {FB_VAR_CPU_ABI, {GetCpuAbi, nullptr}}};
if (args.size() < 2) {
return device->WriteFail("Missing argument");
diff --git a/fastboot/device/variables.cpp b/fastboot/device/variables.cpp
index 6e613d6..717db06 100644
--- a/fastboot/device/variables.cpp
+++ b/fastboot/device/variables.cpp
@@ -458,3 +458,9 @@
}
return true;
}
+
+bool GetCpuAbi(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
+ std::string* message) {
+ *message = android::base::GetProperty("ro.product.cpu.abi", "");
+ return true;
+}
diff --git a/fastboot/device/variables.h b/fastboot/device/variables.h
index 4dec10f..90840d6 100644
--- a/fastboot/device/variables.h
+++ b/fastboot/device/variables.h
@@ -63,6 +63,7 @@
std::string* message);
bool GetSnapshotUpdateStatus(FastbootDevice* device, const std::vector<std::string>& args,
std::string* message);
+bool GetCpuAbi(FastbootDevice* device, const std::vector<std::string>& args, std::string* message);
// Helpers for getvar all.
std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 5ee928e..8f58145 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -65,6 +65,7 @@
#include "action_manager.h"
#include "bootchart.h"
+#include "builtin_arguments.h"
#include "fscrypt_init_extensions.h"
#include "init.h"
#include "mount_namespace.h"
@@ -140,14 +141,7 @@
if (!write_bootloader_message(options, &err)) {
return Error() << "Failed to set bootloader message: " << err;
}
- // This function should only be reached from init and not from vendor_init, and we want to
- // immediately trigger reboot instead of relaying through property_service. Older devices may
- // still have paths that reach here from vendor_init, so we keep the property_set as a fallback.
- if (getpid() == 1) {
- TriggerShutdown("reboot,recovery");
- } else {
- property_set("sys.powerctl", "reboot,recovery");
- }
+ trigger_shutdown("reboot,recovery");
return {};
}
@@ -554,7 +548,7 @@
// support userdata remount on FDE devices, this should never been triggered. Time to
// panic!
LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
- TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
+ trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
}
ActionManager::GetInstance().QueueEventTrigger("encrypt");
return {};
@@ -564,7 +558,7 @@
// don't support userdata remount on FDE devices, this should never been triggered.
// Time to panic!
LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?";
- TriggerShutdown("reboot,requested-userdata-remount-on-fde-device");
+ trigger_shutdown("reboot,requested-userdata-remount-on-fde-device");
}
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "block");
@@ -1148,7 +1142,7 @@
}
// TODO(b/135984674): check that fstab contains /data.
if (auto rc = fs_mgr_remount_userdata_into_checkpointing(&fstab); rc < 0) {
- TriggerShutdown("reboot,mount-userdata-failed");
+ trigger_shutdown("reboot,mount-userdata-failed");
}
if (auto result = queue_fs_event(initial_mount_fstab_return_code, true); !result) {
return Error() << "queue_fs_event() failed: " << result.error();
@@ -1223,6 +1217,15 @@
}
}
+static Result<void> do_finish_userspace_reboot(const BuiltinArguments&) {
+ LOG(INFO) << "Userspace reboot successfully finished";
+ boot_clock::time_point now = boot_clock::now();
+ property_set("sys.init.userspace_reboot.last_finished",
+ std::to_string(now.time_since_epoch().count()));
+ property_set(kUserspaceRebootInProgress, "0");
+ return {};
+}
+
// Builtin-function-map start
const BuiltinFunctionMap& GetBuiltinFunctionMap() {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@@ -1244,6 +1247,7 @@
{"exec_background", {1, kMax, {false, do_exec_background}}},
{"exec_start", {1, 1, {false, do_exec_start}}},
{"export", {2, 2, {false, do_export}}},
+ {"finish_userspace_reboot", {0, 0, {false, do_finish_userspace_reboot}}},
{"hostname", {1, 1, {true, do_hostname}}},
{"ifup", {1, 1, {true, do_ifup}}},
{"init_user0", {0, 0, {false, do_init_user0}}},
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index 9b33a1c..30d3129 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -35,11 +35,6 @@
namespace android {
namespace init {
-// init.h
-inline void TriggerShutdown(const std::string&) {
- abort();
-}
-
// property_service.h
inline bool CanReadProperty(const std::string&, const std::string&) {
return true;
diff --git a/init/init.cpp b/init/init.cpp
index ff86f8d..8e2da59 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -180,7 +180,7 @@
waiting_for_prop.reset();
}
-void TriggerShutdown(const std::string& command) {
+static void TriggerShutdown(const std::string& command) {
// We can't call HandlePowerctlMessage() directly in this function,
// because it modifies the contents of the action queue, which can cause the action queue
// to get into a bad state if this function is called from a command being executed by the
@@ -681,6 +681,8 @@
boot_clock::time_point start_time = boot_clock::now();
+ trigger_shutdown = TriggerShutdown;
+
SetStdioToDevNull(argv);
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
diff --git a/init/init.h b/init/init.h
index d884a94..0805940 100644
--- a/init/init.h
+++ b/init/init.h
@@ -31,8 +31,6 @@
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
Parser CreateServiceOnlyParser(ServiceList& service_list);
-void TriggerShutdown(const std::string& command);
-
bool start_waiting_for_property(const char *name, const char *value);
void DumpState();
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 4a16969..7040f26 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -69,10 +69,13 @@
using namespace std::literals;
+using android::base::boot_clock;
using android::base::GetBoolProperty;
+using android::base::SetProperty;
using android::base::Split;
using android::base::Timer;
using android::base::unique_fd;
+using android::base::WaitForProperty;
using android::base::WriteStringToFile;
namespace android {
@@ -728,16 +731,21 @@
static Result<void> DoUserspaceReboot() {
LOG(INFO) << "Userspace reboot initiated";
+ boot_clock::time_point now = boot_clock::now();
+ property_set("sys.init.userspace_reboot.last_started",
+ std::to_string(now.time_since_epoch().count()));
auto guard = android::base::make_scope_guard([] {
// Leave shutdown so that we can handle a full reboot.
LeaveShutdown();
- TriggerShutdown("reboot,abort-userspace-reboot");
+ trigger_shutdown("reboot,abort-userspace-reboot");
});
- // Triggering userspace-reboot-requested will result in a bunch of set_prop
+ // Triggering userspace-reboot-requested will result in a bunch of setprop
// actions. We should make sure, that all of them are propagated before
- // proceeding with userspace reboot.
- // TODO(b/135984674): implement proper synchronization logic.
- std::this_thread::sleep_for(500ms);
+ // proceeding with userspace reboot. Synchronously setting kUserspaceRebootInProgress property
+ // is not perfect, but it should do the trick.
+ if (property_set(kUserspaceRebootInProgress, "1") != 0) {
+ return Error() << "Failed to set property " << kUserspaceRebootInProgress;
+ }
EnterShutdown();
std::vector<Service*> stop_first;
// Remember the services that were enabled. We will need to manually enable them again otherwise
diff --git a/init/reboot.h b/init/reboot.h
index 81c3edc..cdfa024 100644
--- a/init/reboot.h
+++ b/init/reboot.h
@@ -22,6 +22,8 @@
namespace android {
namespace init {
+static const constexpr char* kUserspaceRebootInProgress = "sys.init.userspace_reboot.in_progress";
+
// Parses and handles a setprop sys.powerctl message.
void HandlePowerctlMessage(const std::string& command);
diff --git a/init/service.cpp b/init/service.cpp
index f8e98a2..574ff52 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -43,7 +43,6 @@
#if defined(__ANDROID__)
#include <ApexProperties.sysprop.h>
-#include "init.h"
#include "mount_namespace.h"
#include "property_service.h"
#else
@@ -260,7 +259,7 @@
if ((siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) && on_failure_reboot_target_) {
LOG(ERROR) << "Service with 'reboot_on_failure' option failed, shutting down system.";
- TriggerShutdown(*on_failure_reboot_target_);
+ trigger_shutdown(*on_failure_reboot_target_);
}
if (flags_ & SVC_EXEC) UnSetExec();
@@ -340,7 +339,7 @@
Result<void> Service::ExecStart() {
auto reboot_on_failure = make_scope_guard([this] {
if (on_failure_reboot_target_) {
- TriggerShutdown(*on_failure_reboot_target_);
+ trigger_shutdown(*on_failure_reboot_target_);
}
});
@@ -371,7 +370,7 @@
Result<void> Service::Start() {
auto reboot_on_failure = make_scope_guard([this] {
if (on_failure_reboot_target_) {
- TriggerShutdown(*on_failure_reboot_target_);
+ trigger_shutdown(*on_failure_reboot_target_);
}
});
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 79fc372..e55265b 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -51,6 +51,8 @@
namespace init {
namespace {
+std::string shutdown_command;
+
class SubcontextProcess {
public:
SubcontextProcess(const BuiltinFunctionMap* function_map, std::string context, int init_fd)
@@ -153,6 +155,11 @@
<< subcontext_command.command_case();
}
+ if (!shutdown_command.empty()) {
+ reply.set_trigger_shutdown(shutdown_command);
+ shutdown_command.clear();
+ }
+
if (auto result = SendMessage(init_fd_, reply); !result) {
LOG(FATAL) << "Failed to send message to init: " << result.error();
}
@@ -174,6 +181,8 @@
return 0;
};
+ trigger_shutdown = [](const std::string& command) { shutdown_command = command; };
+
auto subcontext_process = SubcontextProcess(function_map, context, init_fd);
subcontext_process.MainLoop();
return 0;
@@ -254,6 +263,11 @@
Restart();
return Error() << "Unable to parse message from subcontext";
}
+
+ if (subcontext_reply.has_trigger_shutdown()) {
+ trigger_shutdown(subcontext_reply.trigger_shutdown());
+ }
+
return subcontext_reply;
}
diff --git a/init/subcontext.proto b/init/subcontext.proto
index e68115e..068c7ce 100644
--- a/init/subcontext.proto
+++ b/init/subcontext.proto
@@ -38,4 +38,6 @@
Failure failure = 2;
ExpandArgsReply expand_args_reply = 3;
}
+
+ optional string trigger_shutdown = 4;
}
\ No newline at end of file
diff --git a/init/subcontext_test.cpp b/init/subcontext_test.cpp
index 9cac35e..9c1a788 100644
--- a/init/subcontext_test.cpp
+++ b/init/subcontext_test.cpp
@@ -26,6 +26,7 @@
#include <selinux/selinux.h>
#include "builtin_arguments.h"
+#include "util.h"
using namespace std::literals;
@@ -142,6 +143,18 @@
});
}
+TEST(subcontext, TriggerShutdown) {
+ static constexpr const char kTestShutdownCommand[] = "reboot,test-shutdown-command";
+ static std::string trigger_shutdown_command;
+ trigger_shutdown = [](const std::string& command) { trigger_shutdown_command = command; };
+ RunTest([](auto& subcontext, auto& context_string) {
+ auto result = subcontext.Execute(
+ std::vector<std::string>{"trigger_shutdown", kTestShutdownCommand});
+ ASSERT_TRUE(result);
+ });
+ EXPECT_EQ(kTestShutdownCommand, trigger_shutdown_command);
+}
+
TEST(subcontext, ExpandArgs) {
RunTest([](auto& subcontext, auto& context_string) {
auto args = std::vector<std::string>{
@@ -207,6 +220,11 @@
return Error() << args.context;
};
+ auto do_trigger_shutdown = [](const BuiltinArguments& args) -> Result<void> {
+ trigger_shutdown(args[1]);
+ return {};
+ };
+
// clang-format off
BuiltinFunctionMap test_function_map = {
{"return_pids_as_error", {0, 0, {true, do_return_pids_as_error}}},
@@ -216,6 +234,7 @@
{"cause_log_fatal", {0, 0, {true, do_cause_log_fatal}}},
{"generate_sane_error", {0, 0, {true, do_generate_sane_error}}},
{"return_context_as_error", {0, 0, {true, do_return_context_as_error}}},
+ {"trigger_shutdown", {1, 1, {true, do_trigger_shutdown}}},
};
// clang-format on
return test_function_map;
diff --git a/init/util.cpp b/init/util.cpp
index ada9e78..e5254dd 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -61,6 +61,8 @@
const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
+void (*trigger_shutdown)(const std::string& command) = nullptr;
+
// DecodeUid() - decodes and returns the given string, which can be either the
// numeric or name representation, into the integer uid or gid.
Result<uid_t> DecodeUid(const std::string& name) {
diff --git a/init/util.h b/init/util.h
index 3d81d72..9d89ed7 100644
--- a/init/util.h
+++ b/init/util.h
@@ -35,6 +35,8 @@
static const char kColdBootDoneProp[] = "ro.cold_boot_done";
+extern void (*trigger_shutdown)(const std::string& command);
+
Result<int> CreateSocket(const std::string& name, int type, bool passcred, mode_t perm, uid_t uid,
gid_t gid, const std::string& socketcon);
diff --git a/liblog/log_event_list.cpp b/liblog/log_event_list.cpp
index 7882c96..e9f4a32 100644
--- a/liblog/log_event_list.cpp
+++ b/liblog/log_event_list.cpp
@@ -47,9 +47,6 @@
uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
};
-// TODO(tomcherry): real C++ structs.
-typedef struct android_log_context_internal android_log_context_internal;
-
static void init_context(android_log_context_internal* context, uint32_t tag) {
context->tag = tag;
context->read_write_flag = kAndroidLoggerWrite;
@@ -110,11 +107,9 @@
return 0;
}
-int android_log_reset(android_log_context ctx) {
- android_log_context_internal* context;
+int android_log_reset(android_log_context context) {
uint32_t tag;
- context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -126,10 +121,7 @@
return 0;
}
-int android_log_parser_reset(android_log_context ctx, const char* msg, size_t len) {
- android_log_context_internal* context;
-
- context = (android_log_context_internal*)ctx;
+int android_log_parser_reset(android_log_context context, const char* msg, size_t len) {
if (!context || (kAndroidLoggerRead != context->read_write_flag)) {
return -EBADF;
}
@@ -140,10 +132,7 @@
return 0;
}
-int android_log_write_list_begin(android_log_context ctx) {
- android_log_context_internal* context;
-
- context = (android_log_context_internal*)ctx;
+int android_log_write_list_begin(android_log_context context) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -174,8 +163,7 @@
return 0;
}
-int android_log_write_int32(android_log_context ctx, int32_t value) {
- android_log_context_internal* context = (android_log_context_internal*)ctx;
+int android_log_write_int32(android_log_context context, int32_t value) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -195,8 +183,7 @@
return 0;
}
-int android_log_write_int64(android_log_context ctx, int64_t value) {
- android_log_context_internal* context = (android_log_context_internal*)ctx;
+int android_log_write_int64(android_log_context context, int64_t value) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -216,8 +203,7 @@
return 0;
}
-int android_log_write_string8_len(android_log_context ctx, const char* value, size_t maxlen) {
- android_log_context_internal* context = (android_log_context_internal*)ctx;
+int android_log_write_string8_len(android_log_context context, const char* value, size_t maxlen) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -252,8 +238,7 @@
return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
}
-int android_log_write_float32(android_log_context ctx, float value) {
- android_log_context_internal* context = (android_log_context_internal*)ctx;
+int android_log_write_float32(android_log_context context, float value) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -273,10 +258,7 @@
return 0;
}
-int android_log_write_list_end(android_log_context ctx) {
- android_log_context_internal* context;
-
- context = (android_log_context_internal*)ctx;
+int android_log_write_list_end(android_log_context context) {
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -303,8 +285,7 @@
/*
* Logs the list of elements to the event log.
*/
-int android_log_write_list(android_log_context ctx, log_id_t id) {
- android_log_context_internal* context;
+int android_log_write_list(android_log_context context, log_id_t id) {
const char* msg;
ssize_t len;
@@ -312,7 +293,6 @@
return -EINVAL;
}
- context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -337,12 +317,10 @@
: __android_log_security_bwrite(context->tag, msg, len));
}
-int android_log_write_list_buffer(android_log_context ctx, const char** buffer) {
- android_log_context_internal* context;
+int android_log_write_list_buffer(android_log_context context, const char** buffer) {
const char* msg;
ssize_t len;
- context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
@@ -375,12 +353,10 @@
* this and continues to call this function, the behavior is undefined
* (although it won't crash).
*/
-static android_log_list_element android_log_read_next_internal(android_log_context ctx, int peek) {
+static android_log_list_element android_log_read_next_internal(android_log_context context,
+ int peek) {
android_log_list_element elem;
unsigned pos;
- android_log_context_internal* context;
-
- context = (android_log_context_internal*)ctx;
memset(&elem, 0, sizeof(elem));
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index 619cf8c..eaa157a 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -39,47 +39,43 @@
#include "logd_reader.h"
#include "logger.h"
-static int logdAvailable(log_id_t LogId);
-static int logdVersion(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
-static int logdRead(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, struct log_msg* log_msg);
-static int logdPoll(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp);
-static void logdClose(struct android_log_logger_list* logger_list,
+static int LogdAvailable(log_id_t LogId);
+static int LogdVersion(struct logger* logger, struct android_log_transport_context* transp);
+static int LogdRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ struct log_msg* log_msg);
+static int LogdPoll(struct logger_list* logger_list, struct android_log_transport_context* transp);
+static void LogdClose(struct logger_list* logger_list,
struct android_log_transport_context* transp);
-static int logdClear(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
-static ssize_t logdSetSize(struct android_log_logger* logger,
- struct android_log_transport_context* transp, size_t size);
-static ssize_t logdGetSize(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
-static ssize_t logdGetReadableSize(struct android_log_logger* logger,
+static int LogdClear(struct logger* logger, struct android_log_transport_context* transp);
+static ssize_t LogdSetSize(struct logger* logger, struct android_log_transport_context* transp,
+ size_t size);
+static ssize_t LogdGetSize(struct logger* logger, struct android_log_transport_context* transp);
+static ssize_t LogdGetReadableSize(struct logger* logger,
struct android_log_transport_context* transp);
-static ssize_t logdGetPrune(struct android_log_logger_list* logger,
+static ssize_t LogdGetPrune(struct logger_list* logger,
struct android_log_transport_context* transp, char* buf, size_t len);
-static ssize_t logdSetPrune(struct android_log_logger_list* logger,
+static ssize_t LogdSetPrune(struct logger_list* logger,
struct android_log_transport_context* transp, char* buf, size_t len);
-static ssize_t logdGetStats(struct android_log_logger_list* logger,
+static ssize_t LogdGetStats(struct logger_list* logger,
struct android_log_transport_context* transp, char* buf, size_t len);
struct android_log_transport_read logdLoggerRead = {
.name = "logd",
- .available = logdAvailable,
- .version = logdVersion,
- .close = logdClose,
- .read = logdRead,
- .poll = logdPoll,
- .clear = logdClear,
- .setSize = logdSetSize,
- .getSize = logdGetSize,
- .getReadableSize = logdGetReadableSize,
- .getPrune = logdGetPrune,
- .setPrune = logdSetPrune,
- .getStats = logdGetStats,
+ .available = LogdAvailable,
+ .version = LogdVersion,
+ .close = LogdClose,
+ .read = LogdRead,
+ .poll = LogdPoll,
+ .clear = LogdClear,
+ .setSize = LogdSetSize,
+ .getSize = LogdGetSize,
+ .getReadableSize = LogdGetReadableSize,
+ .getPrune = LogdGetPrune,
+ .setPrune = LogdSetPrune,
+ .getStats = LogdGetStats,
};
-static int logdAvailable(log_id_t logId) {
+static int LogdAvailable(log_id_t logId) {
if (logId >= LOG_ID_MAX) {
return -EINVAL;
}
@@ -120,8 +116,7 @@
}
/* worker for sending the command to the logger */
-static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg, char* buf,
- size_t buf_size) {
+static ssize_t send_log_msg(struct logger* logger, const char* msg, char* buf, size_t buf_size) {
ssize_t ret;
size_t len;
char* cp;
@@ -202,16 +197,14 @@
return 0;
}
-static int logdClear(struct android_log_logger* logger,
- struct android_log_transport_context* transp __unused) {
+static int LogdClear(struct logger* logger, struct android_log_transport_context*) {
char buf[512];
return check_log_success(buf, send_log_msg(logger, "clear %d", buf, sizeof(buf)));
}
/* returns the total size of the log's ring buffer */
-static ssize_t logdGetSize(struct android_log_logger* logger,
- struct android_log_transport_context* transp __unused) {
+static ssize_t LogdGetSize(struct logger* logger, struct android_log_transport_context*) {
char buf[512];
ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));
@@ -226,8 +219,8 @@
return atol(buf);
}
-static ssize_t logdSetSize(struct android_log_logger* logger,
- struct android_log_transport_context* transp __unused, size_t size) {
+static ssize_t LogdSetSize(struct logger* logger, struct android_log_transport_context*,
+ size_t size) {
char buf[512];
snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size);
@@ -239,8 +232,7 @@
* returns the readable size of the log's ring buffer (that is, amount of the
* log consumed)
*/
-static ssize_t logdGetReadableSize(struct android_log_logger* logger,
- struct android_log_transport_context* transp __unused) {
+static ssize_t LogdGetReadableSize(struct logger* logger, struct android_log_transport_context*) {
char buf[512];
ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));
@@ -258,8 +250,7 @@
/*
* returns the logger version
*/
-static int logdVersion(struct android_log_logger* logger __unused,
- struct android_log_transport_context* transp __unused) {
+static int LogdVersion(struct logger*, struct android_log_transport_context*) {
uid_t uid = __android_log_uid();
return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4;
}
@@ -267,10 +258,9 @@
/*
* returns statistics
*/
-static ssize_t logdGetStats(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp __unused, char* buf,
- size_t len) {
- struct android_log_logger* logger;
+static ssize_t LogdGetStats(struct logger_list* logger_list, struct android_log_transport_context*,
+ char* buf, size_t len) {
+ struct logger* logger;
char* cp = buf;
size_t remaining = len;
size_t n;
@@ -294,14 +284,12 @@
return send_log_msg(NULL, NULL, buf, len);
}
-static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused,
- struct android_log_transport_context* transp __unused, char* buf,
+static ssize_t LogdGetPrune(struct logger_list*, struct android_log_transport_context*, char* buf,
size_t len) {
return send_log_msg(NULL, "getPruneList", buf, len);
}
-static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused,
- struct android_log_transport_context* transp __unused, char* buf,
+static ssize_t LogdSetPrune(struct logger_list*, struct android_log_transport_context*, char* buf,
size_t len) {
const char cmd[] = "setPruneList ";
const size_t cmdlen = sizeof(cmd) - 1;
@@ -316,9 +304,8 @@
return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
}
-static int logdOpen(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp) {
- struct android_log_logger* logger;
+static int logdOpen(struct logger_list* logger_list, struct android_log_transport_context* transp) {
+ struct logger* logger;
char buffer[256], *cp, c;
int ret, remaining, sock;
@@ -404,8 +391,8 @@
}
/* Read from the selected logs */
-static int logdRead(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, struct log_msg* log_msg) {
+static int LogdRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ struct log_msg* log_msg) {
int ret = logdOpen(logger_list, transp);
if (ret < 0) {
return ret;
@@ -425,8 +412,7 @@
return ret;
}
-static int logdPoll(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp) {
+static int LogdPoll(struct logger_list* logger_list, struct android_log_transport_context* transp) {
struct pollfd p;
int ret = logdOpen(logger_list, transp);
@@ -448,8 +434,7 @@
}
/* Close all the logs */
-static void logdClose(struct android_log_logger_list* logger_list __unused,
- struct android_log_transport_context* transp) {
+static void LogdClose(struct logger_list*, struct android_log_transport_context* transp) {
int sock = atomic_exchange(&transp->context.sock, -1);
if (sock > 0) {
close(sock);
diff --git a/liblog/logger.h b/liblog/logger.h
index 02cad22..9c488b6 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -46,49 +46,37 @@
size_t nr);
};
-struct android_log_logger_list;
struct android_log_transport_context;
-struct android_log_logger;
struct android_log_transport_read {
const char* name; /* human name to describe the transport */
/* Does not cause resources to be taken */
int (*available)(log_id_t logId);
- int (*version)(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
+ int (*version)(struct logger* logger, struct android_log_transport_context* transp);
/* Release resources taken by the following interfaces */
- void (*close)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp);
+ void (*close)(struct logger_list* logger_list, struct android_log_transport_context* transp);
/*
* Expect all to instantiate open automagically on any call,
* so we do not have an explicit open call.
*/
- int (*read)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp,
+ int (*read)(struct logger_list* logger_list, struct android_log_transport_context* transp,
struct log_msg* log_msg);
/* Must only be called if not ANDROID_LOG_NONBLOCK (blocking) */
- int (*poll)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp);
+ int (*poll)(struct logger_list* logger_list, struct android_log_transport_context* transp);
- int (*clear)(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
- ssize_t (*setSize)(struct android_log_logger* logger,
- struct android_log_transport_context* transp, size_t size);
- ssize_t (*getSize)(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
- ssize_t (*getReadableSize)(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
+ int (*clear)(struct logger* logger, struct android_log_transport_context* transp);
+ ssize_t (*setSize)(struct logger* logger, struct android_log_transport_context* transp,
+ size_t size);
+ ssize_t (*getSize)(struct logger* logger, struct android_log_transport_context* transp);
+ ssize_t (*getReadableSize)(struct logger* logger, struct android_log_transport_context* transp);
- ssize_t (*getPrune)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, char* buf,
- size_t len);
- ssize_t (*setPrune)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, char* buf,
- size_t len);
- ssize_t (*getStats)(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, char* buf,
- size_t len);
+ ssize_t (*getPrune)(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ char* buf, size_t len);
+ ssize_t (*setPrune)(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ char* buf, size_t len);
+ ssize_t (*getStats)(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ char* buf, size_t len);
};
struct android_log_transport_context {
@@ -98,7 +86,7 @@
unsigned logMask; /* mask of requested log buffers */
};
-struct android_log_logger_list {
+struct logger_list {
struct listnode logger;
android_log_transport_context transport_context;
bool transport_initialized;
@@ -108,22 +96,19 @@
pid_t pid;
};
-struct android_log_logger {
+struct logger {
struct listnode node;
- struct android_log_logger_list* parent;
+ struct logger_list* parent;
log_id_t logId;
};
/* assumes caller has structures read-locked, single threaded, or fenced */
-#define logger_for_each(logp, logger_list) \
- for ((logp) = node_to_item((logger_list)->logger.next, \
- struct android_log_logger, node); \
- ((logp) != node_to_item(&(logger_list)->logger, \
- struct android_log_logger, node)) && \
- ((logp)->parent == (logger_list)); \
- (logp) = \
- node_to_item((logp)->node.next, struct android_log_logger, node))
+#define logger_for_each(logp, logger_list) \
+ for ((logp) = node_to_item((logger_list)->logger.next, struct logger, node); \
+ ((logp) != node_to_item(&(logger_list)->logger, struct logger, node)) && \
+ ((logp)->parent == (logger_list)); \
+ (logp) = node_to_item((logp)->node.next, struct logger, node))
/* OS specific dribs and drabs */
diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp
index 4b4012a..5e10ada 100644
--- a/liblog/logger_read.cpp
+++ b/liblog/logger_read.cpp
@@ -35,25 +35,23 @@
/* android_logger_alloc unimplemented, no use case */
/* android_logger_free not exported */
static void android_logger_free(struct logger* logger) {
- struct android_log_logger* logger_internal = (struct android_log_logger*)logger;
-
- if (!logger_internal) {
+ if (!logger) {
return;
}
- list_remove(&logger_internal->node);
+ list_remove(&logger->node);
- free(logger_internal);
+ free(logger);
}
/* android_logger_alloc unimplemented, no use case */
/* method for getting the associated sublog id */
log_id_t android_logger_get_id(struct logger* logger) {
- return ((struct android_log_logger*)logger)->logId;
+ return ((struct logger*)logger)->logId;
}
-static int init_transport_context(struct android_log_logger_list* logger_list) {
+static int init_transport_context(struct logger_list* logger_list) {
if (!logger_list) {
return -EINVAL;
}
@@ -73,7 +71,7 @@
struct android_log_transport_read* transport;
transport = (logger_list->mode & ANDROID_LOG_PSTORE) ? &pmsgLoggerRead : &logdLoggerRead;
- struct android_log_logger* logger;
+ struct logger* logger;
unsigned logMask = 0;
logger_for_each(logger, logger_list) {
@@ -96,28 +94,26 @@
return 0;
}
-#define LOGGER_FUNCTION(logger, def, func, args...) \
- ssize_t ret = -EINVAL; \
- android_log_logger* logger_internal = reinterpret_cast<android_log_logger*>(logger); \
- \
- if (!logger_internal) { \
- return ret; \
- } \
- ret = init_transport_context(logger_internal->parent); \
- if (ret < 0) { \
- return ret; \
- } \
- \
- ret = (def); \
- android_log_transport_context* transport_context = &logger_internal->parent->transport_context; \
- if (transport_context->logMask & (1 << logger_internal->logId) && \
- transport_context->transport && transport_context->transport->func) { \
- ssize_t retval = \
- (transport_context->transport->func)(logger_internal, transport_context, ##args); \
- if (ret >= 0 || ret == (def)) { \
- ret = retval; \
- } \
- } \
+#define LOGGER_FUNCTION(logger, def, func, args...) \
+ ssize_t ret = -EINVAL; \
+ \
+ if (!logger) { \
+ return ret; \
+ } \
+ ret = init_transport_context(logger->parent); \
+ if (ret < 0) { \
+ return ret; \
+ } \
+ \
+ ret = (def); \
+ android_log_transport_context* transport_context = &logger->parent->transport_context; \
+ if (transport_context->logMask & (1 << logger->logId) && transport_context->transport && \
+ transport_context->transport->func) { \
+ ssize_t retval = (transport_context->transport->func)(logger, transport_context, ##args); \
+ if (ret >= 0 || ret == (def)) { \
+ ret = retval; \
+ } \
+ } \
return ret
int android_logger_clear(struct logger* logger) {
@@ -148,24 +144,20 @@
LOGGER_FUNCTION(logger, 4, version);
}
-#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
- android_log_logger_list* logger_list_internal = \
- reinterpret_cast<android_log_logger_list*>(logger_list); \
- \
- ssize_t ret = init_transport_context(logger_list_internal); \
- if (ret < 0) { \
- return ret; \
- } \
- \
- ret = (def); \
- android_log_transport_context* transport_context = &logger_list_internal->transport_context; \
- if (transport_context->transport && transport_context->transport->func) { \
- ssize_t retval = \
- (transport_context->transport->func)(logger_list_internal, transport_context, ##args); \
- if (ret >= 0 || ret == (def)) { \
- ret = retval; \
- } \
- } \
+#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
+ ssize_t ret = init_transport_context(logger_list); \
+ if (ret < 0) { \
+ return ret; \
+ } \
+ \
+ ret = (def); \
+ android_log_transport_context* transport_context = &logger_list->transport_context; \
+ if (transport_context->transport && transport_context->transport->func) { \
+ ssize_t retval = (transport_context->transport->func)(logger_list, transport_context, ##args); \
+ if (ret >= 0 || ret == (def)) { \
+ ret = retval; \
+ } \
+ } \
return ret
/*
@@ -184,9 +176,9 @@
}
struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
- struct android_log_logger_list* logger_list;
+ struct logger_list* logger_list;
- logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
+ logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(*logger_list)));
if (!logger_list) {
return NULL;
}
@@ -196,13 +188,13 @@
logger_list->tail = tail;
logger_list->pid = pid;
- return (struct logger_list*)logger_list;
+ return logger_list;
}
struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
- struct android_log_logger_list* logger_list;
+ struct logger_list* logger_list;
- logger_list = static_cast<android_log_logger_list*>(calloc(1, sizeof(*logger_list)));
+ logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(*logger_list)));
if (!logger_list) {
return NULL;
}
@@ -212,7 +204,7 @@
logger_list->start = start;
logger_list->pid = pid;
- return (struct logger_list*)logger_list;
+ return logger_list;
}
/* android_logger_list_register unimplemented, no use case */
@@ -220,33 +212,31 @@
/* Open the named log and add it to the logger list */
struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
- struct android_log_logger_list* logger_list_internal =
- (struct android_log_logger_list*)logger_list;
- struct android_log_logger* logger;
+ struct logger* logger;
- if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
+ if (!logger_list || (logId >= LOG_ID_MAX)) {
return nullptr;
}
- logger_for_each(logger, logger_list_internal) {
+ logger_for_each(logger, logger_list) {
if (logger->logId == logId) {
return reinterpret_cast<struct logger*>(logger);
}
}
- logger = static_cast<android_log_logger*>(calloc(1, sizeof(*logger)));
+ logger = static_cast<struct logger*>(calloc(1, sizeof(*logger)));
if (!logger) {
return nullptr;
}
logger->logId = logId;
- list_add_tail(&logger_list_internal->logger, &logger->node);
- logger->parent = logger_list_internal;
+ list_add_tail(&logger_list->logger, &logger->node);
+ logger->parent = logger_list;
// Reset known transport to re-evaluate, since we added a new logger.
- logger_list_internal->transport_initialized = false;
+ logger_list->transport_initialized = false;
- return (struct logger*)logger;
+ return logger;
}
/* Open the single named log and make it part of a new logger list */
@@ -267,7 +257,7 @@
}
/* Validate log_msg packet, read function has already been null checked */
-static int android_transport_read(struct android_log_logger_list* logger_list,
+static int android_transport_read(struct logger_list* logger_list,
struct android_log_transport_context* transp,
struct log_msg* log_msg) {
int ret = (*transp->transport->read)(logger_list, transp, log_msg);
@@ -297,38 +287,32 @@
/* Read from the selected logs */
int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
- struct android_log_logger_list* logger_list_internal =
- (struct android_log_logger_list*)logger_list;
-
- int ret = init_transport_context(logger_list_internal);
+ int ret = init_transport_context(logger_list);
if (ret < 0) {
return ret;
}
- android_log_transport_context* transport_context = &logger_list_internal->transport_context;
- return android_transport_read(logger_list_internal, transport_context, log_msg);
+ android_log_transport_context* transport_context = &logger_list->transport_context;
+ return android_transport_read(logger_list, transport_context, log_msg);
}
/* Close all the logs */
void android_logger_list_free(struct logger_list* logger_list) {
- struct android_log_logger_list* logger_list_internal =
- (struct android_log_logger_list*)logger_list;
-
- if (logger_list_internal == NULL) {
+ if (logger_list == NULL) {
return;
}
- android_log_transport_context* transport_context = &logger_list_internal->transport_context;
+ android_log_transport_context* transport_context = &logger_list->transport_context;
if (transport_context->transport && transport_context->transport->close) {
- (*transport_context->transport->close)(logger_list_internal, transport_context);
+ (*transport_context->transport->close)(logger_list, transport_context);
}
- while (!list_empty(&logger_list_internal->logger)) {
- struct listnode* node = list_head(&logger_list_internal->logger);
- struct android_log_logger* logger = node_to_item(node, struct android_log_logger, node);
+ while (!list_empty(&logger_list->logger)) {
+ struct listnode* node = list_head(&logger_list->logger);
+ struct logger* logger = node_to_item(node, struct logger, node);
android_logger_free((struct logger*)logger);
}
- free(logger_list_internal);
+ free(logger_list);
}
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index f43ce3a..cd83161 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -26,24 +26,22 @@
#include "logger.h"
-static int pmsgAvailable(log_id_t logId);
-static int pmsgVersion(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
-static int pmsgRead(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, struct log_msg* log_msg);
-static void pmsgClose(struct android_log_logger_list* logger_list,
+static int PmsgAvailable(log_id_t logId);
+static int PmsgVersion(struct logger* logger, struct android_log_transport_context* transp);
+static int PmsgRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ struct log_msg* log_msg);
+static void PmsgClose(struct logger_list* logger_list,
struct android_log_transport_context* transp);
-static int pmsgClear(struct android_log_logger* logger,
- struct android_log_transport_context* transp);
+static int PmsgClear(struct logger* logger, struct android_log_transport_context* transp);
struct android_log_transport_read pmsgLoggerRead = {
.name = "pmsg",
- .available = pmsgAvailable,
- .version = pmsgVersion,
- .close = pmsgClose,
- .read = pmsgRead,
+ .available = PmsgAvailable,
+ .version = PmsgVersion,
+ .close = PmsgClose,
+ .read = PmsgRead,
.poll = NULL,
- .clear = pmsgClear,
+ .clear = PmsgClear,
.setSize = NULL,
.getSize = NULL,
.getReadableSize = NULL,
@@ -52,7 +50,7 @@
.getStats = NULL,
};
-static int pmsgAvailable(log_id_t logId) {
+static int PmsgAvailable(log_id_t logId) {
if (logId > LOG_ID_SECURITY) {
return -EINVAL;
}
@@ -62,21 +60,19 @@
return -EBADF;
}
-static int pmsgClear(struct android_log_logger* logger __unused,
- struct android_log_transport_context* transp __unused) {
+static int PmsgClear(struct logger*, struct android_log_transport_context*) {
return unlink("/sys/fs/pstore/pmsg-ramoops-0");
}
/*
* returns the logger version
*/
-static int pmsgVersion(struct android_log_logger* logger __unused,
- struct android_log_transport_context* transp __unused) {
+static int PmsgVersion(struct logger*, struct android_log_transport_context*) {
return 4;
}
-static int pmsgRead(struct android_log_logger_list* logger_list,
- struct android_log_transport_context* transp, struct log_msg* log_msg) {
+static int PmsgRead(struct logger_list* logger_list, struct android_log_transport_context* transp,
+ struct log_msg* log_msg) {
ssize_t ret;
off_t current, next;
struct __attribute__((__packed__)) {
@@ -192,8 +188,7 @@
}
}
-static void pmsgClose(struct android_log_logger_list* logger_list __unused,
- struct android_log_transport_context* transp) {
+static void PmsgClose(struct logger_list*, struct android_log_transport_context* transp) {
int fd = atomic_exchange(&transp->context.fd, 0);
if (fd > 0) {
close(fd);
@@ -211,7 +206,7 @@
ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio, const char* prefix,
__android_log_pmsg_file_read_fn fn, void* arg) {
ssize_t ret;
- struct android_log_logger_list logger_list;
+ struct logger_list logger_list;
struct android_log_transport_context transp;
struct content {
struct listnode node;
@@ -268,7 +263,7 @@
/* Read the file content */
log_msg log_msg;
- while (pmsgRead(&logger_list, &transp, &log_msg) > 0) {
+ while (PmsgRead(&logger_list, &transp, &log_msg) > 0) {
const char* cp;
size_t hdr_size = log_msg.entry.hdr_size;
@@ -426,7 +421,7 @@
}
list_add_head(node, &content->node);
}
- pmsgClose(&logger_list, &transp);
+ PmsgClose(&logger_list, &transp);
/* Progress through all the collected files */
list_for_each_safe(node, n, &name_list) {
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 5871a63..0341902 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -39,6 +39,13 @@
"Mode": "0755",
"UID": "system",
"GID": "system"
+ },
+ {
+ "Controller": "freezer",
+ "Path": "/dev/freezer",
+ "Mode": "0755",
+ "UID": "system",
+ "GID": "system"
}
],
"Cgroups2": {
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 608f007..3f3dbd7 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -67,6 +67,32 @@
]
},
{
+ "Name": "Frozen",
+ "Actions": [
+ {
+ "Name": "JoinCgroup",
+ "Params":
+ {
+ "Controller": "freezer",
+ "Path": "frozen"
+ }
+ }
+ ]
+ },
+ {
+ "Name": "Unfrozen",
+ "Actions": [
+ {
+ "Name": "JoinCgroup",
+ "Params":
+ {
+ "Controller": "freezer",
+ "Path": ""
+ }
+ }
+ ]
+ },
+ {
"Name": "NormalPerformance",
"Actions": [
{
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index 81f8c0f..56f594a 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -111,7 +111,8 @@
static float CompressionRatio(int64_t uncompressed, int64_t compressed) {
if (uncompressed == 0) return 0;
- return static_cast<float>(100LL * (uncompressed - compressed)) / uncompressed;
+ return static_cast<float>(100LL * (uncompressed - compressed)) /
+ static_cast<float>(uncompressed);
}
static void MaybeShowHeader(ZipArchiveHandle zah) {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index bc18e27..6b61472 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -283,6 +283,16 @@
chmod 0664 /dev/cpuset/restricted/tasks
chmod 0664 /dev/cpuset/tasks
+ # freezer cgroup entries
+ mkdir /dev/freezer/frozen
+ write /dev/freezer/frozen/freezer.state FROZEN
+ chown system system /dev/freezer/cgroup.procs
+ chown system system /dev/freezer/frozen
+ chown system system /dev/freezer/frozen/freezer.state
+ chown system system /dev/freezer/frozen/cgroup.procs
+
+ chmod 0444 /dev/freezer/frozen/freezer.state
+
# make the PSI monitor accessible to others
chown system system /proc/pressure/memory
chmod 0664 /proc/pressure/memory
@@ -925,7 +935,6 @@
on userspace-reboot-requested
# TODO(b/135984674): reset all necessary properties here.
- setprop sys.init.userspace_reboot_in_progress 1
setprop sys.boot_completed 0
setprop sys.init.updatable_crashing 0
setprop apexd.status ""
@@ -945,3 +954,6 @@
trigger zygote-start
trigger early-boot
trigger boot
+
+on property:sys.boot_completed=1 && property:sys.init.userspace_reboot.in_progress=1
+ finish_userspace_reboot