Move watchdogd out of init

We're moving past a world where static executables are needed,
including watchdogd, so treat this like any other executable and place
it in /system/bin.

Bug: 73660730
Test: watchdogd still runs
Change-Id: I1f7508fd55dce6e9ee72a6ab7a085011a76c0053
This commit is contained in:
Tom Cherry 2018-08-01 13:41:12 -07:00
parent 081b710b2e
commit 40acb379cd
16 changed files with 52 additions and 73 deletions

View file

@ -127,7 +127,6 @@ cc_library_static {
"ueventd.cpp",
"ueventd_parser.cpp",
"util.cpp",
"watchdogd.cpp",
],
whole_static_libs: ["libcap"],
header_libs: ["bootimg_headers"],
@ -157,7 +156,6 @@ cc_binary {
srcs: ["main.cpp"],
symlinks: [
"sbin/ueventd",
"sbin/watchdogd",
],
}
*/

View file

@ -98,7 +98,6 @@ LOCAL_REQUIRED_MODULES := \
# Create symlinks.
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \
ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd
LOCAL_SANITIZE := signed-integer-overflow
include $(BUILD_EXECUTABLE)

View file

@ -34,7 +34,7 @@
#include "util.h"
#ifdef _INIT_INIT_H
#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
#error "Do not include init.h in files used by ueventd; it will expose init's globals"
#endif
using android::base::Basename;

View file

@ -41,10 +41,9 @@ uint32_t HandlePropertySet(const std::string&, const std::string&, const std::st
}
// selinux.h
bool SelinuxHasVendorInit() {
return true;
int SelinuxGetVendorAndroidVersion() {
return 10000;
}
void SelabelInitialize() {}
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) {

View file

@ -23,6 +23,9 @@
#include <string>
// android/api-level.h
#define __ANDROID_API_P__ 28
// sys/system_properties.h
#define PROP_VALUE_MAX 92
@ -41,7 +44,7 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
const std::string& source_context, const ucred& cr, std::string* error);
// selinux.h
bool SelinuxHasVendorInit();
int SelinuxGetVendorAndroidVersion();
void SelabelInitialize();
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);

View file

@ -58,7 +58,6 @@
#include "sigchld_handler.h"
#include "ueventd.h"
#include "util.h"
#include "watchdogd.h"
using namespace std::chrono_literals;
using namespace std::string_literals;
@ -617,10 +616,6 @@ int main(int argc, char** argv) {
return ueventd_main(argc, argv);
}
if (!strcmp(basename(argv[0]), "watchdogd")) {
return watchdogd_main(argc, argv);
}
if (argc > 1 && !strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap function_map;

View file

@ -31,8 +31,8 @@
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.
// Note: These globals are *only* valid in init, so they should not be used in ueventd
// or any files that may be included in ueventd, such as devices.cpp and util.cpp.
// TODO: Have an Init class and remove all globals.
extern std::string default_console;
extern std::vector<std::string> late_import_paths;

View file

@ -16,6 +16,7 @@
#include "property_service.h"
#include <android/api-level.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@ -576,7 +577,7 @@ static void LoadProperties(char* data, const char* filter, const char* filename)
size_t flen = 0;
const char* context = kInitContext.c_str();
if (SelinuxHasVendorInit()) {
if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) {
for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
if (StartsWith(filename, path_prefix)) {
context = secontext;

View file

@ -47,6 +47,7 @@
#include "selinux.h"
#include <android/api-level.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
@ -470,29 +471,27 @@ void SelinuxSetupKernelLogging() {
selinux_set_callback(SELINUX_CB_LOG, cb);
}
// This function checks whether the sepolicy supports vendor init.
bool SelinuxHasVendorInit() {
// This function returns the Android version with which the vendor SEPolicy was compiled.
// It is used for version checks such as whether or not vendor_init should be used
int SelinuxGetVendorAndroidVersion() {
if (!IsSplitPolicyDevice()) {
// If this device does not split sepolicy files, vendor_init will be available in the latest
// monolithic sepolicy file.
return true;
// If this device does not split sepolicy files, it's not a Treble device and therefore,
// we assume it's always on the latest platform.
return __ANDROID_API_FUTURE__;
}
std::string version;
if (!GetVendorMappingVersion(&version)) {
// Return true as the default if we failed to load the vendor sepolicy version.
return true;
LOG(FATAL) << "Could not read vendor SELinux version";
}
int major_version;
std::string major_version_str(version, 0, version.find('.'));
if (!ParseInt(major_version_str, &major_version)) {
PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str;
// Return true as the default if we failed to parse the major version.
return true;
PLOG(FATAL) << "Failed to parse the vendor sepolicy major version " << major_version_str;
}
return major_version >= 28;
return major_version;
}
// selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache

View file

@ -27,7 +27,7 @@ void SelinuxInitialize();
void SelinuxRestoreContext();
void SelinuxSetupKernelLogging();
bool SelinuxHasVendorInit();
int SelinuxGetVendorAndroidVersion();
void SelabelInitialize();
bool SelabelLookupFileContext(const std::string& key, int type, std::string* result);

View file

@ -46,10 +46,12 @@
#include "util.h"
#if defined(__ANDROID__)
#include <android/api-level.h>
#include <sys/system_properties.h>
#include "init.h"
#include "property_service.h"
#include "selinux.h"
#else
#include "host_init_stubs.h"
#endif
@ -1211,6 +1213,13 @@ Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
}
std::vector<std::string> str_args(args.begin() + 2, args.end());
if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_P__) {
if (str_args[0] == "/sbin/watchdogd") {
str_args[0] = "/system/bin/watchdogd";
}
}
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
return Success();
}

View file

@ -30,6 +30,7 @@
#include "util.h"
#if defined(__ANDROID__)
#include <android/api-level.h>
#include "property_service.h"
#include "selinux.h"
#else
@ -355,7 +356,7 @@ static std::vector<Subcontext> subcontexts;
static bool shutting_down;
std::vector<Subcontext>* InitializeSubcontexts() {
if (SelinuxHasVendorInit()) {
if (SelinuxGetVendorAndroidVersion() >= __ANDROID_API_P__) {
for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
subcontexts.emplace_back(path_prefix, secontext);
}

View file

@ -47,7 +47,7 @@
#endif
#ifdef _INIT_INIT_H
#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
#error "Do not include init.h in files used by ueventd; it will expose init's globals"
#endif
using android::base::boot_clock;

View file

@ -1,28 +0,0 @@
/*
* Copyright (C) 2012 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.
*/
#ifndef _INIT_WATCHDOGD_H_
#define _INIT_WATCHDOGD_H_
namespace android {
namespace init {
int watchdogd_main(int argc, char **argv);
} // namespace init
} // namespace android
#endif

14
watchdogd/Android.bp Normal file
View file

@ -0,0 +1,14 @@
cc_binary {
name: "watchdogd",
recovery_available: true,
srcs: ["watchdogd.cpp"],
cflags: [
"-Wall",
"-Wextra",
"-Werror",
],
shared_libs: ["libbase"],
sanitize: {
misc_undefined: ["signed-integer-overflow"],
},
}

View file

@ -23,16 +23,9 @@
#include <android-base/logging.h>
#ifdef _INIT_INIT_H
#error "Do not include init.h in files used by ueventd or watchdogd; it will expose init's globals"
#endif
#define DEV_NAME "/dev/watchdog"
namespace android {
namespace init {
int watchdogd_main(int argc, char **argv) {
int main(int argc, char** argv) {
android::base::InitLogging(argv, &android::base::KernelLogger);
int interval = 10;
@ -43,7 +36,7 @@ int watchdogd_main(int argc, char **argv) {
LOG(INFO) << "watchdogd started (interval " << interval << ", margin " << margin << ")!";
int fd = open(DEV_NAME, O_RDWR|O_CLOEXEC);
int fd = open(DEV_NAME, O_RDWR | O_CLOEXEC);
if (fd == -1) {
PLOG(ERROR) << "Failed to open " << DEV_NAME;
return 1;
@ -63,9 +56,8 @@ int watchdogd_main(int argc, char **argv) {
interval = 1;
}
LOG(WARNING) << "Adjusted interval to timeout returned by driver: "
<< "timeout " << timeout
<< ", interval " << interval
<< ", margin " << margin;
<< "timeout " << timeout << ", interval " << interval << ", margin "
<< margin;
}
}
@ -74,6 +66,3 @@ int watchdogd_main(int argc, char **argv) {
sleep(interval);
}
}
} // namespace init
} // namespace android