init: create android::init:: namespace
With some small fixups along the way Test: Boot bullhead Test: init unit tests Change-Id: I7beaa473cfa9397f845f810557d1631b4a462d6a
This commit is contained in:
parent
84c2eebbdd
commit
81f5d3ebef
54 changed files with 379 additions and 44 deletions
|
@ -24,6 +24,9 @@
|
|||
|
||||
using android::base::Join;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
Command::Command(BuiltinFunction f, const std::vector<std::string>& args, int line)
|
||||
: func_(f), args_(args), line_(line) {}
|
||||
|
||||
|
@ -349,3 +352,6 @@ void ActionParser::EndSection() {
|
|||
action_manager_->AddAction(std::move(action_));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include "init_parser.h"
|
||||
#include "keyword_map.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class Command {
|
||||
public:
|
||||
Command(BuiltinFunction f, const std::vector<std::string>& args, int line);
|
||||
|
@ -126,4 +129,7 @@ class ActionParser : public SectionParser {
|
|||
std::unique_ptr<Action> action_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
using android::base::StringPrintf;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static std::thread* g_bootcharting_thread;
|
||||
|
||||
static std::mutex g_bootcharting_finished_mutex;
|
||||
|
@ -192,3 +195,6 @@ int do_bootchart(const std::vector<std::string>& args) {
|
|||
if (args[1] == "start") return do_bootchart_start();
|
||||
return do_bootchart_stop();
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -20,6 +20,12 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int do_bootchart(const std::vector<std::string>& args);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif /* _BOOTCHART_H */
|
||||
|
|
|
@ -67,6 +67,9 @@ using namespace std::literals::string_literals;
|
|||
|
||||
#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
|
||||
|
||||
static int insmod(const char *filename, const char *options, int flags) {
|
||||
|
@ -924,3 +927,6 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
|||
// clang-format on
|
||||
return builtin_functions;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
#include "keyword_map.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
using BuiltinFunction = std::function<int(const std::vector<std::string>&)>;
|
||||
class BuiltinFunctionMap : public KeywordMap<BuiltinFunction> {
|
||||
public:
|
||||
|
@ -33,4 +36,7 @@ class BuiltinFunctionMap : public KeywordMap<BuiltinFunction> {
|
|||
const Map& map() const override;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
#define CAP_MAP_ENTRY(cap) { #cap, CAP_##cap }
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static const std::map<std::string, int> cap_map = {
|
||||
CAP_MAP_ENTRY(CHOWN),
|
||||
CAP_MAP_ENTRY(DAC_OVERRIDE),
|
||||
|
@ -192,3 +195,6 @@ bool SetCapsForExec(const CapSet& to_keep) {
|
|||
// See http://man7.org/linux/man-pages/man7/capabilities.7.html.
|
||||
return SetAmbientCaps(to_keep);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
using CapSet = std::bitset<CAP_LAST_CAP + 1>;
|
||||
|
||||
int LookupCap(const std::string& cap_name);
|
||||
|
@ -27,4 +30,7 @@ bool CapAmbientSupported();
|
|||
unsigned int GetLastValidCap();
|
||||
bool SetCapsForExec(const CapSet& to_keep);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif // _INIT_CAPABILITIES_H
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include "init.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
DescriptorInfo::DescriptorInfo(const std::string& name, const std::string& type, uid_t uid,
|
||||
gid_t gid, int perm, const std::string& context)
|
||||
: name_(name), type_(type), uid_(uid), gid_(gid), perm_(perm), context_(context) {
|
||||
|
@ -126,3 +129,6 @@ int FileInfo::Create(const std::string&) const {
|
|||
const std::string FileInfo::key() const {
|
||||
return ANDROID_FILE_ENV_PREFIX;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class DescriptorInfo {
|
||||
public:
|
||||
DescriptorInfo(const std::string& name, const std::string& type, uid_t uid,
|
||||
|
@ -75,4 +78,7 @@ class FileInfo : public DescriptorInfo {
|
|||
virtual const std::string key() const override;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,13 +37,23 @@
|
|||
#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
|
||||
#endif
|
||||
|
||||
using android::base::Basename;
|
||||
using android::base::Dirname;
|
||||
using android::base::Readlink;
|
||||
using android::base::Realpath;
|
||||
using android::base::StartsWith;
|
||||
using android::base::StringPrintf;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
/* Given a path that may start with a PCI device, populate the supplied buffer
|
||||
* with the PCI domain/bus number and the peripheral ID and return 0.
|
||||
* If it doesn't start with a PCI device, or there is some error, return -1 */
|
||||
static bool FindPciDevicePrefix(const std::string& path, std::string* result) {
|
||||
result->clear();
|
||||
|
||||
if (!android::base::StartsWith(path, "/devices/pci")) return false;
|
||||
if (!StartsWith(path, "/devices/pci")) return false;
|
||||
|
||||
/* Beginning of the prefix is the initial "pci" after "/devices/" */
|
||||
std::string::size_type start = 9;
|
||||
|
@ -74,7 +84,7 @@ static bool FindPciDevicePrefix(const std::string& path, std::string* result) {
|
|||
static bool FindVbdDevicePrefix(const std::string& path, std::string* result) {
|
||||
result->clear();
|
||||
|
||||
if (!android::base::StartsWith(path, "/devices/vbd-")) return false;
|
||||
if (!StartsWith(path, "/devices/vbd-")) return false;
|
||||
|
||||
/* Beginning of the prefix is the initial "vbd-" after "/devices/" */
|
||||
std::string::size_type start = 13;
|
||||
|
@ -116,14 +126,14 @@ Permissions::Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t
|
|||
}
|
||||
|
||||
bool Permissions::Match(const std::string& path) const {
|
||||
if (prefix_) return android::base::StartsWith(path, name_.c_str());
|
||||
if (prefix_) return StartsWith(path, name_.c_str());
|
||||
if (wildcard_) return fnmatch(name_.c_str(), path.c_str(), FNM_PATHNAME) == 0;
|
||||
return path == name_;
|
||||
}
|
||||
|
||||
bool SysfsPermissions::MatchWithSubsystem(const std::string& path,
|
||||
const std::string& subsystem) const {
|
||||
std::string path_basename = android::base::Basename(path);
|
||||
std::string path_basename = Basename(path);
|
||||
if (name().find(subsystem) != std::string::npos) {
|
||||
if (Match("/sys/class/" + subsystem + "/" + path_basename)) return true;
|
||||
if (Match("/sys/bus/" + subsystem + "/devices/" + path_basename)) return true;
|
||||
|
@ -156,11 +166,11 @@ bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_d
|
|||
// Uevents don't contain the mount point, so we need to add it here.
|
||||
path.insert(0, sysfs_mount_point_);
|
||||
|
||||
std::string directory = android::base::Dirname(path);
|
||||
std::string directory = Dirname(path);
|
||||
|
||||
while (directory != "/" && directory != ".") {
|
||||
std::string subsystem_link_path;
|
||||
if (android::base::Realpath(directory + "/subsystem", &subsystem_link_path) &&
|
||||
if (Realpath(directory + "/subsystem", &subsystem_link_path) &&
|
||||
subsystem_link_path == sysfs_mount_point_ + "/bus/platform") {
|
||||
// We need to remove the mount point that we added above before returning.
|
||||
directory.erase(0, sysfs_mount_point_.size());
|
||||
|
@ -172,7 +182,7 @@ bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_d
|
|||
if (last_slash == std::string::npos) return false;
|
||||
|
||||
path.erase(last_slash);
|
||||
directory = android::base::Dirname(path);
|
||||
directory = Dirname(path);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -276,7 +286,7 @@ std::vector<std::string> DeviceHandler::GetCharacterDeviceSymlinks(const Uevent&
|
|||
// skip path to the parent driver
|
||||
std::string path = uevent.path.substr(parent_device.length());
|
||||
|
||||
if (!android::base::StartsWith(path, "/usb")) return {};
|
||||
if (!StartsWith(path, "/usb")) return {};
|
||||
|
||||
// skip root hub name and device. use device interface
|
||||
// skip 3 slashes, including the first / by starting the search at the 1st character, not 0th.
|
||||
|
@ -334,9 +344,9 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
|
|||
static const std::string devices_platform_prefix = "/devices/platform/";
|
||||
static const std::string devices_prefix = "/devices/";
|
||||
|
||||
if (android::base::StartsWith(device, devices_platform_prefix.c_str())) {
|
||||
if (StartsWith(device, devices_platform_prefix.c_str())) {
|
||||
device = device.substr(devices_platform_prefix.length());
|
||||
} else if (android::base::StartsWith(device, devices_prefix.c_str())) {
|
||||
} else if (StartsWith(device, devices_prefix.c_str())) {
|
||||
device = device.substr(devices_prefix.length());
|
||||
}
|
||||
|
||||
|
@ -380,8 +390,8 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
|
|||
if (action == "add") {
|
||||
MakeDevice(devpath, block, major, minor, links);
|
||||
for (const auto& link : links) {
|
||||
if (mkdir_recursive(android::base::Dirname(link), 0755, sehandle_)) {
|
||||
PLOG(ERROR) << "Failed to create directory " << android::base::Dirname(link);
|
||||
if (mkdir_recursive(Dirname(link), 0755, sehandle_)) {
|
||||
PLOG(ERROR) << "Failed to create directory " << Dirname(link);
|
||||
}
|
||||
|
||||
if (symlink(devpath.c_str(), link.c_str()) && errno != EEXIST) {
|
||||
|
@ -393,7 +403,7 @@ void DeviceHandler::HandleDevice(const std::string& action, const std::string& d
|
|||
if (action == "remove") {
|
||||
for (const auto& link : links) {
|
||||
std::string link_path;
|
||||
if (android::base::Readlink(link, &link_path) && link_path == devpath) {
|
||||
if (Readlink(link, &link_path) && link_path == devpath) {
|
||||
unlink(link.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -408,11 +418,11 @@ void DeviceHandler::HandleBlockDeviceEvent(const Uevent& uevent) const {
|
|||
const char* base = "/dev/block/";
|
||||
make_dir(base, 0755, sehandle_);
|
||||
|
||||
std::string name = android::base::Basename(uevent.path);
|
||||
std::string name = Basename(uevent.path);
|
||||
std::string devpath = base + name;
|
||||
|
||||
std::vector<std::string> links;
|
||||
if (android::base::StartsWith(uevent.path, "/devices")) {
|
||||
if (StartsWith(uevent.path, "/devices")) {
|
||||
links = GetBlockDeviceSymlinks(uevent);
|
||||
}
|
||||
|
||||
|
@ -425,7 +435,7 @@ void DeviceHandler::HandleGenericDeviceEvent(const Uevent& uevent) const {
|
|||
|
||||
std::string devpath;
|
||||
|
||||
if (android::base::StartsWith(uevent.subsystem, "usb")) {
|
||||
if (StartsWith(uevent.subsystem, "usb")) {
|
||||
if (uevent.subsystem == "usb") {
|
||||
if (!uevent.device_name.empty()) {
|
||||
devpath = "/dev/" + uevent.device_name;
|
||||
|
@ -435,7 +445,7 @@ void DeviceHandler::HandleGenericDeviceEvent(const Uevent& uevent) const {
|
|||
// Minors are broken up into groups of 128, starting at "001"
|
||||
int bus_id = uevent.minor / 128 + 1;
|
||||
int device_id = uevent.minor % 128 + 1;
|
||||
devpath = android::base::StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
|
||||
devpath = StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
|
||||
}
|
||||
} else {
|
||||
// ignore other USB events
|
||||
|
@ -446,10 +456,10 @@ void DeviceHandler::HandleGenericDeviceEvent(const Uevent& uevent) const {
|
|||
subsystem != subsystems_.cend()) {
|
||||
devpath = subsystem->ParseDevPath(uevent);
|
||||
} else {
|
||||
devpath = "/dev/" + android::base::Basename(uevent.path);
|
||||
devpath = "/dev/" + Basename(uevent.path);
|
||||
}
|
||||
|
||||
mkdir_recursive(android::base::Dirname(devpath), 0755, sehandle_);
|
||||
mkdir_recursive(Dirname(devpath), 0755, sehandle_);
|
||||
|
||||
auto links = GetCharacterDeviceSymlinks(uevent);
|
||||
|
||||
|
@ -481,3 +491,6 @@ DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
|
|||
DeviceHandler::DeviceHandler()
|
||||
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
|
||||
std::vector<Subsystem>{}, false) {}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "uevent.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class Permissions {
|
||||
public:
|
||||
Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid);
|
||||
|
@ -133,4 +136,7 @@ class DeviceHandler {
|
|||
// Exposed for testing
|
||||
void SanitizePartitionName(std::string* string);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class DeviceHandlerTester {
|
||||
public:
|
||||
void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
|
||||
|
@ -400,3 +403,6 @@ TEST(device_handler, SysfsPermissionsMatchWithSubsystemBus) {
|
|||
EXPECT_EQ(0U, permissions.uid());
|
||||
EXPECT_EQ(1001U, permissions.gid());
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -30,10 +30,16 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
using android::base::unique_fd;
|
||||
using android::base::WriteFully;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_fd, size_t fw_size,
|
||||
int loading_fd, int data_fd) {
|
||||
// Start transfer.
|
||||
android::base::WriteFully(loading_fd, "1", 1);
|
||||
WriteFully(loading_fd, "1", 1);
|
||||
|
||||
// Copy the firmware.
|
||||
int rc = sendfile(data_fd, fw_fd, nullptr, fw_size);
|
||||
|
@ -44,7 +50,7 @@ static void LoadFirmware(const Uevent& uevent, const std::string& root, int fw_f
|
|||
|
||||
// Tell the firmware whether to abort or commit.
|
||||
const char* response = (rc != -1) ? "0" : "-1";
|
||||
android::base::WriteFully(loading_fd, response, strlen(response));
|
||||
WriteFully(loading_fd, response, strlen(response));
|
||||
}
|
||||
|
||||
static bool IsBooting() {
|
||||
|
@ -60,13 +66,13 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
|
|||
std::string loading = root + "/loading";
|
||||
std::string data = root + "/data";
|
||||
|
||||
android::base::unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC));
|
||||
unique_fd loading_fd(open(loading.c_str(), O_WRONLY | O_CLOEXEC));
|
||||
if (loading_fd == -1) {
|
||||
PLOG(ERROR) << "couldn't open firmware loading fd for " << uevent.firmware;
|
||||
return;
|
||||
}
|
||||
|
||||
android::base::unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC));
|
||||
unique_fd data_fd(open(data.c_str(), O_WRONLY | O_CLOEXEC));
|
||||
if (data_fd == -1) {
|
||||
PLOG(ERROR) << "couldn't open firmware data fd for " << uevent.firmware;
|
||||
return;
|
||||
|
@ -78,7 +84,7 @@ static void ProcessFirmwareEvent(const Uevent& uevent) {
|
|||
try_loading_again:
|
||||
for (size_t i = 0; i < arraysize(firmware_dirs); i++) {
|
||||
std::string file = firmware_dirs[i] + uevent.firmware;
|
||||
android::base::unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
|
||||
unique_fd fw_fd(open(file.c_str(), O_RDONLY | O_CLOEXEC));
|
||||
struct stat sb;
|
||||
if (fw_fd != -1 && fstat(fw_fd, &sb) != -1) {
|
||||
LoadFirmware(uevent, root, fw_fd, sb.st_size, loading_fd, data_fd);
|
||||
|
@ -130,3 +136,6 @@ void HandleFirmwareEvent(const Uevent& uevent) {
|
|||
|
||||
waitpid(pid, nullptr, 0);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
|
||||
#include "uevent.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void HandleFirmwareEvent(const Uevent& uevent);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
bool ImportParser::ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line, std::string* err) {
|
||||
if (args.size() != 2) {
|
||||
|
@ -50,3 +53,6 @@ void ImportParser::EndFile() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class ImportParser : public SectionParser {
|
||||
public:
|
||||
ImportParser(Parser* parser) : parser_(parser) {}
|
||||
|
@ -37,4 +40,7 @@ class ImportParser : public SectionParser {
|
|||
std::vector<std::pair<std::string, int>> imports_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include <libavb/libavb.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <selinux/android.h>
|
||||
#include <selinux/label.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
#include <fstream>
|
||||
|
@ -75,6 +74,9 @@ using namespace std::string_literals;
|
|||
using android::base::boot_clock;
|
||||
using android::base::GetProperty;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
struct selabel_handle *sehandle;
|
||||
struct selabel_handle *sehandle_prop;
|
||||
|
||||
|
@ -1156,3 +1158,10 @@ int main(int argc, char** argv) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
android::init::main(argc, argv);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include <selinux/label.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
// Note: These globals are *only* valid in init, so they should not be used in ueventd,
|
||||
// watchdogd, or any files that may be included in those, such as devices.cpp and util.cpp.
|
||||
// TODO: Have an Init class and remove all globals.
|
||||
|
@ -39,4 +44,7 @@ bool start_waiting_for_property(const char *name, const char *value);
|
|||
|
||||
void DumpState();
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif /* _INIT_INIT_H */
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
// Class Declarations
|
||||
// ------------------
|
||||
class FirstStageMount {
|
||||
|
@ -493,3 +496,6 @@ void SetInitAvbVersionInRecovery() {
|
|||
}
|
||||
setenv("INIT_AVB_VERSION", avb_handle->avb_version().c_str(), 1);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -17,7 +17,13 @@
|
|||
#ifndef _INIT_FIRST_STAGE_H
|
||||
#define _INIT_FIRST_STAGE_H
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
bool DoFirstStageMount();
|
||||
void SetInitAvbVersionInRecovery();
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "parser.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
Parser::Parser() {
|
||||
}
|
||||
|
||||
|
@ -159,3 +162,6 @@ bool Parser::ParseConfig(const std::string& path) {
|
|||
}
|
||||
return ParseConfigFile(path);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
// This function is called at the end of the file.
|
||||
// It indicates that the parsing has completed and any relevant objects should be committed.
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class SectionParser {
|
||||
public:
|
||||
virtual ~SectionParser() {}
|
||||
|
@ -93,4 +96,7 @@ class Parser {
|
|||
bool is_odm_etc_init_loaded_ = false;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
TEST(init_parser, make_exec_oneshot_service_invalid_syntax) {
|
||||
ServiceManager& sm = ServiceManager::GetInstance();
|
||||
std::vector<std::string> args;
|
||||
|
@ -141,3 +144,6 @@ TEST(init_parser, make_exec_oneshot_service_with_just_command) {
|
|||
TEST(init_parser, make_exec_oneshot_service_with_just_command_no_dash) {
|
||||
Test_make_exec_oneshot_service(false, false, false, false, false);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include "keyword_map.h"
|
||||
#include "util.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class TestFunctionMap : public KeywordMap<BuiltinFunction> {
|
||||
public:
|
||||
// Helper for argument-less functions
|
||||
|
@ -185,3 +188,6 @@ TEST(init, EventTriggerOrderMultipleFiles) {
|
|||
|
||||
EXPECT_EQ(6, num_executed);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "keychords.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -25,7 +27,9 @@
|
|||
#include <android-base/properties.h>
|
||||
|
||||
#include "init.h"
|
||||
#include "service.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static struct input_keychord *keychords = 0;
|
||||
static int keychords_count = 0;
|
||||
|
@ -112,3 +116,6 @@ void keychord_init() {
|
|||
|
||||
register_epoll_handler(keychord_fd, handle_keychord);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -17,9 +17,15 @@
|
|||
#ifndef _INIT_KEYCHORDS_H_
|
||||
#define _INIT_KEYCHORDS_H_
|
||||
|
||||
struct service;
|
||||
#include "service.h"
|
||||
|
||||
void add_service_keycodes(service*);
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void add_service_keycodes(Service* svc);
|
||||
void keychord_init();
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
template <typename Function>
|
||||
class KeywordMap {
|
||||
public:
|
||||
|
@ -79,4 +82,7 @@ class KeywordMap {
|
|||
virtual const Map& map() const = 0;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <android-base/logging.h>
|
||||
#include <selinux/selinux.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void InitKernelLogging(char* argv[]) {
|
||||
// Make stdin/stdout/stderr all point to /dev/null.
|
||||
int fd = open("/sys/fs/selinux/null", O_RDWR);
|
||||
|
@ -55,3 +58,6 @@ int selinux_klog_callback(int type, const char *fmt, ...) {
|
|||
android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -19,8 +19,14 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void InitKernelLogging(char* argv[]);
|
||||
|
||||
int selinux_klog_callback(int level, const char* fmt, ...) __printflike(2, 3);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "parser.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int next_token(struct parse_state *state)
|
||||
{
|
||||
char *x = state->ptr;
|
||||
|
@ -116,3 +119,6 @@ textresume:
|
|||
}
|
||||
return T_EOF;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#define T_TEXT 1
|
||||
#define T_NEWLINE 2
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
struct parse_state
|
||||
{
|
||||
char *ptr;
|
||||
|
@ -31,4 +34,7 @@ struct parse_state
|
|||
|
||||
int next_token(struct parse_state *state);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif /* PARSER_H_ */
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#define PERSISTENT_PROPERTY_DIR "/data/property"
|
||||
#define RECOVERY_MOUNT_POINT "/recovery"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static int persistent_properties_loaded = 0;
|
||||
|
||||
static int property_set_fd = -1;
|
||||
|
@ -741,3 +744,6 @@ void start_property_service() {
|
|||
|
||||
register_epoll_handler(property_set_fd, handle_property_set_fd);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
struct property_audit_data {
|
||||
ucred *cr;
|
||||
const char* name;
|
||||
|
@ -36,5 +39,7 @@ void start_property_service(void);
|
|||
uint32_t property_set(const std::string& name, const std::string& value);
|
||||
bool is_legal_property_name(const std::string& name);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif /* _INIT_PROPERTY_H */
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
TEST(property_service, very_long_name_35166374) {
|
||||
// Connect to the property service directly...
|
||||
int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
|
@ -46,3 +49,6 @@ TEST(property_service, very_long_name_35166374) {
|
|||
ASSERT_EQ(static_cast<ssize_t>(sizeof(data)), send(fd, &data, sizeof(data), 0));
|
||||
ASSERT_EQ(0, close(fd));
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
|
||||
using android::base::StringPrintf;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
// represents umount status during reboot / shutdown.
|
||||
enum UmountStat {
|
||||
/* umount succeeded. */
|
||||
|
@ -468,3 +471,6 @@ bool HandlePowerctlMessage(const std::string& command) {
|
|||
DoReboot(cmd, command, reboot_target, run_fsck);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
/* Reboot / shutdown the system.
|
||||
* cmd ANDROID_RB_* as defined in android_reboot.h
|
||||
* reason Reason string like "reboot", "userrequested"
|
||||
|
@ -32,4 +35,7 @@ void DoReboot(unsigned int cmd, const std::string& reason, const std::string& re
|
|||
// Parses and handles a setprop sys.powerctl message.
|
||||
bool HandlePowerctlMessage(const std::string& command);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,10 +45,16 @@
|
|||
#include "util.h"
|
||||
|
||||
using android::base::boot_clock;
|
||||
using android::base::GetProperty;
|
||||
using android::base::Join;
|
||||
using android::base::ParseInt;
|
||||
using android::base::StartsWith;
|
||||
using android::base::StringPrintf;
|
||||
using android::base::WriteStringToFile;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static std::string ComputeContextFromExecutable(std::string& service_name,
|
||||
const std::string& service_path) {
|
||||
std::string computed_context;
|
||||
|
@ -321,8 +327,8 @@ void Service::Reap() {
|
|||
|
||||
void Service::DumpState() const {
|
||||
LOG(INFO) << "service " << name_;
|
||||
LOG(INFO) << " class '" << android::base::Join(classnames_, " ") << "'";
|
||||
LOG(INFO) << " exec "<< android::base::Join(args_, " ");
|
||||
LOG(INFO) << " class '" << Join(classnames_, " ") << "'";
|
||||
LOG(INFO) << " exec " << Join(args_, " ");
|
||||
std::for_each(descriptors_.begin(), descriptors_.end(),
|
||||
[] (const auto& info) { LOG(INFO) << *info; });
|
||||
}
|
||||
|
@ -525,9 +531,8 @@ bool Service::AddDescriptor(const std::vector<std::string>& args, std::string* e
|
|||
|
||||
// name type perm [ uid gid context ]
|
||||
bool Service::ParseSocket(const std::vector<std::string>& args, std::string* err) {
|
||||
if (!android::base::StartsWith(args[2], "dgram") &&
|
||||
!android::base::StartsWith(args[2], "stream") &&
|
||||
!android::base::StartsWith(args[2], "seqpacket")) {
|
||||
if (!StartsWith(args[2], "dgram") && !StartsWith(args[2], "stream") &&
|
||||
!StartsWith(args[2], "seqpacket")) {
|
||||
*err = "socket type must be 'dgram', 'stream' or 'seqpacket'";
|
||||
return false;
|
||||
}
|
||||
|
@ -695,13 +700,13 @@ bool Service::Start() {
|
|||
|
||||
// See if there were "writepid" instructions to write to files under /dev/cpuset/.
|
||||
auto cpuset_predicate = [](const std::string& path) {
|
||||
return android::base::StartsWith(path, "/dev/cpuset/");
|
||||
return StartsWith(path, "/dev/cpuset/");
|
||||
};
|
||||
auto iter = std::find_if(writepid_files_.begin(), writepid_files_.end(), cpuset_predicate);
|
||||
if (iter == writepid_files_.end()) {
|
||||
// There were no "writepid" instructions for cpusets, check if the system default
|
||||
// cpuset is specified to be used for the process.
|
||||
std::string default_cpuset = android::base::GetProperty("ro.cpuset.default", "");
|
||||
std::string default_cpuset = GetProperty("ro.cpuset.default", "");
|
||||
if (!default_cpuset.empty()) {
|
||||
// Make sure the cpuset name starts and ends with '/'.
|
||||
// A single '/' means the 'root' cpuset.
|
||||
|
@ -954,8 +959,7 @@ Service* ServiceManager::MakeExecOneshotService(const std::vector<std::string>&
|
|||
std::vector<std::string> str_args(args.begin() + command_arg, args.end());
|
||||
|
||||
exec_count_++;
|
||||
std::string name =
|
||||
"exec " + std::to_string(exec_count_) + " (" + android::base::Join(str_args, " ") + ")";
|
||||
std::string name = "exec " + std::to_string(exec_count_) + " (" + Join(str_args, " ") + ")";
|
||||
|
||||
unsigned flags = SVC_EXEC | SVC_ONESHOT | SVC_TEMPORARY;
|
||||
CapSet no_capabilities;
|
||||
|
@ -1093,14 +1097,12 @@ bool ServiceManager::ReapOneProcess() {
|
|||
std::string name;
|
||||
std::string wait_string;
|
||||
if (svc) {
|
||||
name = android::base::StringPrintf("Service '%s' (pid %d)",
|
||||
svc->name().c_str(), pid);
|
||||
name = StringPrintf("Service '%s' (pid %d)", svc->name().c_str(), pid);
|
||||
if (svc->flags() & SVC_EXEC) {
|
||||
wait_string =
|
||||
android::base::StringPrintf(" waiting took %f seconds", exec_waiter_->duration_s());
|
||||
wait_string = StringPrintf(" waiting took %f seconds", exec_waiter_->duration_s());
|
||||
}
|
||||
} else {
|
||||
name = android::base::StringPrintf("Untracked pid %d", pid);
|
||||
name = StringPrintf("Untracked pid %d", pid);
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
|
@ -1175,3 +1177,6 @@ bool ServiceParser::IsValidName(const std::string& name) const {
|
|||
// the service name to the "ctl.start" and "ctl.stop" properties.)
|
||||
return is_legal_property_name("init.svc." + name) && name.size() <= PROP_VALUE_MAX;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
|
||||
#define NR_SVC_SUPP_GIDS 12 // twelve supplementary groups
|
||||
|
||||
class Action;
|
||||
class ServiceManager;
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
struct ServiceEnvironmentInfo {
|
||||
ServiceEnvironmentInfo();
|
||||
|
@ -236,4 +236,7 @@ class ServiceParser : public SectionParser {
|
|||
std::unique_ptr<Service> service_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
TEST(service, pod_initialized) {
|
||||
constexpr auto memory_size = sizeof(Service);
|
||||
alignas(alignof(Service)) char old_memory[memory_size];
|
||||
|
@ -67,3 +70,6 @@ TEST(service, pod_initialized) {
|
|||
EXPECT_EQ(-1000, service_in_old_memory2->oom_score_adjust());
|
||||
EXPECT_FALSE(service_in_old_memory->process_cgroup_empty());
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include "init.h"
|
||||
#include "service.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static int signal_write_fd = -1;
|
||||
static int signal_read_fd = -1;
|
||||
|
||||
|
@ -64,3 +67,6 @@ void signal_handler_init() {
|
|||
|
||||
register_epoll_handler(signal_read_fd, handle_signal);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
#ifndef _INIT_SIGNAL_HANDLER_H_
|
||||
#define _INIT_SIGNAL_HANDLER_H_
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
void signal_handler_init(void);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
struct Uevent {
|
||||
std::string action;
|
||||
std::string path;
|
||||
|
@ -31,4 +34,7 @@ struct Uevent {
|
|||
int minor;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include <android-base/logging.h>
|
||||
#include <cutils/uevent.h>
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
static void ParseEvent(const char* msg, Uevent* uevent) {
|
||||
uevent->partition_num = -1;
|
||||
uevent->major = -1;
|
||||
|
@ -212,3 +215,6 @@ void UeventListener::Poll(const ListenerCallback& callback,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
enum class ListenerAction {
|
||||
kStop = 0, // Stop regenerating uevents as we've handled the one(s) we're interested in.
|
||||
kContinue, // Continue regenerating uevents as we haven't seen the one(s) we're interested in.
|
||||
|
@ -53,4 +56,7 @@ class UeventListener {
|
|||
android::base::unique_fd device_fd_;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
// the uevent listener resumes in polling mode and will handle the uevents that occurred during
|
||||
// coldboot.
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class ColdBoot {
|
||||
public:
|
||||
ColdBoot(UeventListener& uevent_listener, DeviceHandler& device_handler)
|
||||
|
@ -273,3 +276,6 @@ int ueventd_main(int argc, char** argv) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
#ifndef _INIT_UEVENTD_H_
|
||||
#define _INIT_UEVENTD_H_
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int ueventd_main(int argc, char** argv);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
#include "keyword_map.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
||||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions) {
|
||||
|
@ -143,3 +146,6 @@ bool SubsystemParser::ParseLineSection(std::vector<std::string>&& args, int line
|
|||
void SubsystemParser::EndSection() {
|
||||
subsystems_->emplace_back(std::move(subsystem_));
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "devices.h"
|
||||
#include "init_parser.h"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
class SubsystemParser : public SectionParser {
|
||||
public:
|
||||
SubsystemParser(std::vector<Subsystem>* subsystems) : subsystems_(subsystems) {}
|
||||
|
@ -43,4 +46,7 @@ bool ParsePermissionsLine(std::vector<std::string>&& args, std::string* err,
|
|||
std::vector<SysfsPermissions>* out_sysfs_permissions,
|
||||
std::vector<Permissions>* out_dev_permissions);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
using android::base::boot_clock;
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
// DecodeUid() - decodes and returns the given string, which can be either the
|
||||
// numeric or name representation, into the integer uid or gid. Returns
|
||||
// UINT_MAX on error.
|
||||
|
@ -397,3 +400,6 @@ bool is_android_dt_value_expected(const std::string& sub_path, const std::string
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -35,6 +35,9 @@ const std::string kAndroidDtDir("/proc/device-tree/firmware/android/");
|
|||
using android::base::boot_clock;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid,
|
||||
const char* socketcon, selabel_handle* sehandle);
|
||||
|
||||
|
@ -78,4 +81,7 @@ void panic() __attribute__((__noreturn__));
|
|||
bool read_android_dt_file(const std::string& sub_path, std::string* dt_content);
|
||||
bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
TEST(util, ReadFile_ENOENT) {
|
||||
std::string s("hello");
|
||||
std::string err;
|
||||
|
@ -187,3 +190,6 @@ TEST(util, mkdir_recursive_extra_slashes) {
|
|||
std::string path3 = android::base::StringPrintf("%s/three/directories/deep", test_dir.path);
|
||||
EXPECT_TRUE(is_dir(path1.c_str()));
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
|
||||
#define DEV_NAME "/dev/watchdog"
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int watchdogd_main(int argc, char **argv) {
|
||||
InitKernelLogging(argv);
|
||||
|
||||
|
@ -73,3 +76,6 @@ int watchdogd_main(int argc, char **argv) {
|
|||
sleep(interval);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
#ifndef _INIT_WATCHDOGD_H_
|
||||
#define _INIT_WATCHDOGD_H_
|
||||
|
||||
namespace android {
|
||||
namespace init {
|
||||
|
||||
int watchdogd_main(int argc, char **argv);
|
||||
|
||||
} // namespace init
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue