init: ignore ENOENT from fewer builtins
Previously we were ignoring ENOENT from all builtins as rootdir/init.rc has many legacy commands that we need to keep for backwards compatibility, but are otherwise no longer relevant. However, this wasn't catching actual issues, for example chown failing due to not finding the user or group name. This change therefore reduces the scope of ignoring ENOENT to the only the extraneous errors in builtins. Test: boot CF and walleye without seeing errors from init.rc Test: see errors from invalid users/groups in chown Change-Id: Ia8e14fa2591e083cb1736c313a3e55515bc5d15e
This commit is contained in:
parent
244d9b8fb9
commit
d17c37952d
2 changed files with 47 additions and 22 deletions
|
@ -123,18 +123,8 @@ void Action::ExecuteCommand(const Command& command) const {
|
|||
auto result = command.InvokeFunc(subcontext_);
|
||||
auto duration = t.duration();
|
||||
|
||||
// There are many legacy paths in rootdir/init.rc that will virtually never exist on a new
|
||||
// device, such as '/sys/class/leds/jogball-backlight/brightness'. As of this writing, there
|
||||
// are 198 such failures on bullhead. Instead of spamming the log reporting them, we do not
|
||||
// report such failures unless we're running at the DEBUG log level.
|
||||
bool report_failure = !result.has_value();
|
||||
if (report_failure && android::base::GetMinimumLogSeverity() > android::base::DEBUG &&
|
||||
result.error().code() == ENOENT) {
|
||||
report_failure = false;
|
||||
}
|
||||
|
||||
// Any action longer than 50ms will be warned to user as slow operation
|
||||
if (report_failure || duration > 50ms ||
|
||||
if (!result.has_value() || duration > 50ms ||
|
||||
android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
|
||||
std::string trigger_name = BuildTriggersString();
|
||||
std::string cmd_str = command.BuildCommandString();
|
||||
|
|
|
@ -89,6 +89,43 @@ using android::fs_mgr::ReadFstabFromFile;
|
|||
namespace android {
|
||||
namespace init {
|
||||
|
||||
// There are many legacy paths in rootdir/init.rc that will virtually never exist on a new
|
||||
// device, such as '/sys/class/leds/jogball-backlight/brightness'. As of this writing, there
|
||||
// are 81 such failures on cuttlefish. Instead of spamming the log reporting them, we do not
|
||||
// report such failures unless we're running at the DEBUG log level.
|
||||
class ErrorIgnoreEnoent {
|
||||
public:
|
||||
ErrorIgnoreEnoent()
|
||||
: ignore_error_(errno == ENOENT &&
|
||||
android::base::GetMinimumLogSeverity() > android::base::DEBUG) {}
|
||||
explicit ErrorIgnoreEnoent(int errno_to_append)
|
||||
: error_(errno_to_append),
|
||||
ignore_error_(errno_to_append == ENOENT &&
|
||||
android::base::GetMinimumLogSeverity() > android::base::DEBUG) {}
|
||||
|
||||
template <typename T>
|
||||
operator android::base::expected<T, ResultError>() {
|
||||
if (ignore_error_) {
|
||||
return {};
|
||||
}
|
||||
return error_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ErrorIgnoreEnoent& operator<<(T&& t) {
|
||||
error_ << t;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Error error_;
|
||||
bool ignore_error_;
|
||||
};
|
||||
|
||||
inline ErrorIgnoreEnoent ErrnoErrorIgnoreEnoent() {
|
||||
return ErrorIgnoreEnoent(errno);
|
||||
}
|
||||
|
||||
std::vector<std::string> late_import_paths;
|
||||
|
||||
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
|
||||
|
@ -330,7 +367,7 @@ static Result<void> do_mkdir(const BuiltinArguments& args) {
|
|||
return ErrnoError() << "fchmodat() failed";
|
||||
}
|
||||
} else {
|
||||
return ErrnoError() << "mkdir() failed";
|
||||
return ErrnoErrorIgnoreEnoent() << "mkdir() failed";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,7 +496,7 @@ static Result<void> do_mount(const BuiltinArguments& args) {
|
|||
if (wait)
|
||||
wait_for_file(source, kCommandRetryTimeout);
|
||||
if (mount(source, target, system, flags, options) < 0) {
|
||||
return ErrnoError() << "mount() failed";
|
||||
return ErrnoErrorIgnoreEnoent() << "mount() failed";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -683,7 +720,7 @@ static Result<void> do_start(const BuiltinArguments& args) {
|
|||
Service* svc = ServiceList::GetInstance().FindService(args[1]);
|
||||
if (!svc) return Error() << "service " << args[1] << " not found";
|
||||
if (auto result = svc->Start(); !result) {
|
||||
return Error() << "Could not start service: " << result.error();
|
||||
return ErrorIgnoreEnoent() << "Could not start service: " << result.error();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -729,10 +766,7 @@ static Result<void> do_symlink(const BuiltinArguments& args) {
|
|||
if (MakeSymlink(args[1], args[2]) < 0) {
|
||||
// The symlink builtin is often used to create symlinks for older devices to be backwards
|
||||
// compatible with new paths, therefore we skip reporting this error.
|
||||
if (errno == EEXIST && android::base::GetMinimumLogSeverity() > android::base::DEBUG) {
|
||||
return {};
|
||||
}
|
||||
return ErrnoError() << "symlink() failed";
|
||||
return ErrnoErrorIgnoreEnoent() << "symlink() failed";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -790,7 +824,8 @@ static Result<void> do_verity_update_state(const BuiltinArguments& args) {
|
|||
|
||||
static Result<void> do_write(const BuiltinArguments& args) {
|
||||
if (auto result = WriteFile(args[1], args[2]); !result) {
|
||||
return Error() << "Unable to write to file '" << args[1] << "': " << result.error();
|
||||
return ErrorIgnoreEnoent()
|
||||
<< "Unable to write to file '" << args[1] << "': " << result.error();
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -908,7 +943,7 @@ static Result<void> do_chown(const BuiltinArguments& args) {
|
|||
}
|
||||
|
||||
if (lchown(path.c_str(), *uid, *gid) == -1) {
|
||||
return ErrnoError() << "lchown() failed";
|
||||
return ErrnoErrorIgnoreEnoent() << "lchown() failed";
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -930,7 +965,7 @@ static mode_t get_mode(const char *s) {
|
|||
static Result<void> do_chmod(const BuiltinArguments& args) {
|
||||
mode_t mode = get_mode(args[1].c_str());
|
||||
if (fchmodat(AT_FDCWD, args[2].c_str(), mode, AT_SYMLINK_NOFOLLOW) < 0) {
|
||||
return ErrnoError() << "fchmodat() failed";
|
||||
return ErrnoErrorIgnoreEnoent() << "fchmodat() failed";
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -973,7 +1008,7 @@ static Result<void> do_restorecon(const BuiltinArguments& args) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ret) return ErrnoError() << "selinux_android_restorecon() failed";
|
||||
if (ret) return ErrnoErrorIgnoreEnoent() << "selinux_android_restorecon() failed";
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue