Merge "fastbootd: exporting CPU ABI info"
diff --git a/init/Android.bp b/init/Android.bp
index d939fcc..c7021c3 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -185,9 +185,11 @@
static_libs: ["libinit"],
required: [
"e2fsdroid",
+ "init.rc",
"mke2fs",
"sload_f2fs",
"make_f2fs",
+ "ueventd.rc",
],
srcs: ["main.cpp"],
symlinks: ["ueventd"],
@@ -281,6 +283,8 @@
static_libs: [
"libbase",
"libselinux",
+ "libpropertyinfoserializer",
+ "libpropertyinfoparser",
],
whole_static_libs: ["libcap"],
shared_libs: [
@@ -304,6 +308,7 @@
"host_import_parser.cpp",
"host_init_verifier.cpp",
"parser.cpp",
+ "property_type.cpp",
"rlimit_parser.cpp",
"tokenizer.cpp",
"service.cpp",
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 5ee928e..a55514b 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -140,14 +140,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 +547,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 +557,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 +1141,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();
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index 9d23921..bef6966 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -29,7 +29,9 @@
#include <android-base/strings.h>
#include "builtin_arguments.h"
+#include "host_init_verifier.h"
#include "interface_utils.h"
+#include "property_type.h"
#include "rlimit_parser.h"
#include "service.h"
#include "util.h"
@@ -171,6 +173,15 @@
<< "' from init; use the restorecon builtin directly";
}
+ const char* target_context = nullptr;
+ const char* type = nullptr;
+ property_info_area->GetPropertyInfo(name.c_str(), &target_context, &type);
+
+ if (!CheckType(type, value)) {
+ return Error() << "Property type check failed, value doesn't match expected type '"
+ << (type ?: "(null)") << "'";
+ }
+
return {};
}
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/host_init_verifier.cpp b/init/host_init_verifier.cpp
index 522709e..3acc3cc 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include "host_init_verifier.h"
+
#include <errno.h>
#include <getopt.h>
#include <pwd.h>
@@ -31,6 +33,7 @@
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <hidl/metadata.h>
+#include <property_info_serializer/property_info_serializer.h>
#include "action.h"
#include "action_manager.h"
@@ -53,6 +56,10 @@
using android::base::ParseInt;
using android::base::ReadFileToString;
using android::base::Split;
+using android::properties::BuildTrie;
+using android::properties::ParsePropertyInfoFile;
+using android::properties::PropertyInfoArea;
+using android::properties::PropertyInfoEntry;
static std::vector<std::string> passwd_files;
@@ -143,11 +150,12 @@
#include "generated_stub_builtin_function_map.h"
void PrintUsage() {
- std::cout << "usage: host_init_verifier [-p FILE] <init rc file>\n"
+ std::cout << "usage: host_init_verifier [options] <init rc file>\n"
"\n"
"Tests an init script for correctness\n"
"\n"
"-p FILE\tSearch this passwd file for users and groups\n"
+ "--property_contexts=FILE\t Use this file for property_contexts\n"
<< std::endl;
}
@@ -172,23 +180,53 @@
return result;
}
+const PropertyInfoArea* property_info_area;
+
+void HandlePropertyContexts(const std::string& filename,
+ std::vector<PropertyInfoEntry>* property_infos) {
+ auto file_contents = std::string();
+ if (!ReadFileToString(filename, &file_contents)) {
+ PLOG(ERROR) << "Could not read properties from '" << filename << "'";
+ exit(EXIT_FAILURE);
+ }
+
+ auto errors = std::vector<std::string>{};
+ ParsePropertyInfoFile(file_contents, property_infos, &errors);
+ for (const auto& error : errors) {
+ LOG(ERROR) << "Could not read line from '" << filename << "': " << error;
+ }
+ if (!errors.empty()) {
+ exit(EXIT_FAILURE);
+ }
+}
+
int main(int argc, char** argv) {
android::base::InitLogging(argv, &android::base::StdioLogger);
android::base::SetMinimumLogSeverity(android::base::ERROR);
+ auto property_infos = std::vector<PropertyInfoEntry>();
+
while (true) {
+ static const char kPropertyContexts[] = "property-contexts=";
static const struct option long_options[] = {
{"help", no_argument, nullptr, 'h'},
+ {kPropertyContexts, required_argument, nullptr, 0},
{nullptr, 0, nullptr, 0},
};
- int arg = getopt_long(argc, argv, "p:", long_options, nullptr);
+ int option_index;
+ int arg = getopt_long(argc, argv, "p:", long_options, &option_index);
if (arg == -1) {
break;
}
switch (arg) {
+ case 0:
+ if (long_options[option_index].name == kPropertyContexts) {
+ HandlePropertyContexts(optarg, &property_infos);
+ }
+ break;
case 'h':
PrintUsage();
return EXIT_FAILURE;
@@ -216,6 +254,16 @@
}
SetKnownInterfaces(*interface_inheritance_hierarchy_map);
+ std::string serialized_contexts;
+ std::string trie_error;
+ if (!BuildTrie(property_infos, "u:object_r:default_prop:s0", "string", &serialized_contexts,
+ &trie_error)) {
+ LOG(ERROR) << "Unable to serialize property contexts: " << trie_error;
+ return EXIT_FAILURE;
+ }
+
+ property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_contexts.c_str());
+
const BuiltinFunctionMap& function_map = GetBuiltinFunctionMap();
Action::set_function_map(&function_map);
ActionManager& am = ActionManager::GetInstance();
diff --git a/init/host_init_verifier.h b/init/host_init_verifier.h
new file mode 100644
index 0000000..5d24f2a
--- /dev/null
+++ b/init/host_init_verifier.h
@@ -0,0 +1,27 @@
+/*
+ * 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
+
+#include <property_info_parser/property_info_parser.h>
+
+namespace android {
+namespace init {
+
+extern const android::properties::PropertyInfoArea* property_info_area;
+
+} // namespace init
+} // namespace android
diff --git a/init/init.cpp b/init/init.cpp
index 6ea2d00..8e2da59 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -136,7 +136,7 @@
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
- parser.ParseConfig("/init.rc");
+ parser.ParseConfig("/system/etc/init/hw/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
@@ -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/property_service.cpp b/init/property_service.cpp
index 3baaf7c..7d707cc 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -478,7 +478,7 @@
return PROP_ERROR_PERMISSION_DENIED;
}
- if (type == nullptr || !CheckType(type, value)) {
+ if (!CheckType(type, value)) {
*error = StringPrintf("Property type check failed, value doesn't match expected type '%s'",
(type ?: "(null)"));
return PROP_ERROR_INVALID_VALUE;
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 4a16969..64ec1fb 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -731,7 +731,7 @@
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
// actions. We should make sure, that all of them are propagated before
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/uevent_listener.cpp b/init/uevent_listener.cpp
index 416d942..d8d9b36 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -100,7 +100,7 @@
int n = uevent_kernel_multicast_recv(device_fd_, msg, UEVENT_MSG_LEN);
if (n <= 0) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
- LOG(ERROR) << "Error reading from Uevent Fd";
+ PLOG(ERROR) << "Error reading from Uevent Fd";
}
return false;
}
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 59f91ee..d2b503b 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -288,7 +288,7 @@
// TODO: cleanup platform ueventd.rc to remove vendor specific device node entries (b/34968103)
auto hardware = android::base::GetProperty("ro.hardware", "");
- auto ueventd_configuration = ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc",
+ auto ueventd_configuration = ParseConfig({"/system/etc/ueventd.rc", "/vendor/ueventd.rc",
"/odm/ueventd.rc", "/ueventd." + hardware + ".rc"});
uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
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/libcutils/Android.bp b/libcutils/Android.bp
index 88e1bdb..334364e 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -197,7 +197,10 @@
cc_defaults {
name: "libcutils_test_default",
- srcs: ["sockets_test.cpp"],
+ srcs: [
+ "native_handle_test.cpp",
+ "sockets_test.cpp",
+ ],
target: {
android: {
diff --git a/libcutils/native_handle.cpp b/libcutils/native_handle.cpp
index b409e5b..5804ab1 100644
--- a/libcutils/native_handle.cpp
+++ b/libcutils/native_handle.cpp
@@ -81,6 +81,8 @@
}
int native_handle_close(const native_handle_t* h) {
+ if (!h) return 0;
+
if (h->version != sizeof(native_handle_t)) return -EINVAL;
int saved_errno = errno;
diff --git a/libcutils/native_handle_test.cpp b/libcutils/native_handle_test.cpp
new file mode 100644
index 0000000..c1e2f0b
--- /dev/null
+++ b/libcutils/native_handle_test.cpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#include <cutils/native_handle.h>
+
+#include <gtest/gtest.h>
+
+TEST(native_handle, native_handle_delete) {
+ ASSERT_EQ(0, native_handle_delete(nullptr));
+}
+
+TEST(native_handle, native_handle_close) {
+ ASSERT_EQ(0, native_handle_close(nullptr));
+}
diff --git a/libcutils/uevent.cpp b/libcutils/uevent.cpp
index 721de7c..bf244d2 100644
--- a/libcutils/uevent.cpp
+++ b/libcutils/uevent.cpp
@@ -60,7 +60,7 @@
struct ucred* cred;
*uid = -1;
- ssize_t n = recvmsg(socket, &hdr, 0);
+ ssize_t n = TEMP_FAILURE_RETRY(recvmsg(socket, &hdr, 0));
if (n <= 0) {
return n;
}
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/Android.bp b/rootdir/Android.bp
new file mode 100644
index 0000000..96b5e0d
--- /dev/null
+++ b/rootdir/Android.bp
@@ -0,0 +1,26 @@
+// Copyright 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.
+
+prebuilt_etc {
+ name: "init.rc",
+ src: "init.rc",
+ sub_dir: "init/hw",
+ required: ["fsverity_init"],
+}
+
+prebuilt_etc {
+ name: "ueventd.rc",
+ src: "ueventd.rc",
+ recovery_available: true,
+}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 19f117f..994d9ae 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -1,22 +1,6 @@
LOCAL_PATH:= $(call my-dir)
#######################################
-# init.rc
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := init.rc
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
-LOCAL_REQUIRED_MODULES := fsverity_init
-
-# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
-# Since init.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
-LOCAL_POST_INSTALL_CMD := ln -sf /system/bin/init $(TARGET_ROOT_OUT)/init
-
-include $(BUILD_PREBUILT)
-
-#######################################
# init-debug.rc
include $(CLEAR_VARS)
@@ -148,6 +132,10 @@
LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/postinstall
endif
+# The init symlink must be a post install command of a file that is to TARGET_ROOT_OUT.
+# Since init.environ.rc is required for init and satisfies that requirement, we hijack it to create the symlink.
+LOCAL_POST_INSTALL_CMD += ; ln -sf /system/bin/init $(TARGET_ROOT_OUT)/init
+
include $(BUILD_SYSTEM)/base_rules.mk
$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/init.environ.rc.in
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 0827247..674b737 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -5,11 +5,11 @@
#
import /init.environ.rc
-import /init.usb.rc
+import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
-import /init.usb.configfs.rc
-import /init.${ro.zygote}.rc
+import /system/etc/init/hw/init.usb.configfs.rc
+import /system/etc/init/hw/init.${ro.zygote}.rc
# Cgroups are mounted right before early-init using list from /etc/cgroups.json
on early-init
@@ -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