Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 557946e5 authored by Tom Cherry's avatar Tom Cherry
Browse files

init: use Result<T> for builtin functions

We currently throw out the return values from builtin functions and
occasionally log errors with no supporting context.  This change uses
the newly introduced Result<T> class to communicate a successful result
or an error back to callers in order to print an error with clear
context when a builtin fails.

Example:

init: Command 'write /sys/class/leds/vibrator/trigger transient' action=init (/init.rc:245) took 0ms and failed: Unable to write to file '/sys/class/leds/vibrator/trigger': open() failed: No such file or directory

Test: boot bullhead
Merged-In: Idc18f331d2d646629c6093c1e0f2996cf9b42aec
Change-Id: Idc18f331d2d646629c6093c1e0f2996cf9b42aec
parent 11a3aeea
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -31,14 +31,13 @@ namespace init {
Command::Command(BuiltinFunction f, const std::vector<std::string>& args, int line)
    : func_(f), args_(args), line_(line) {}

int Command::InvokeFunc() const {
Result<Success> Command::InvokeFunc() const {
    std::vector<std::string> expanded_args;
    expanded_args.resize(args_.size());
    expanded_args[0] = args_[0];
    for (std::size_t i = 1; i < args_.size(); ++i) {
        if (!expand_props(args_[i], &expanded_args[i])) {
            LOG(ERROR) << args_[0] << ": cannot expand '" << args_[i] << "'";
            return -EINVAL;
            return Error() << "cannot expand '" << args_[i] << "'";
        }
    }

@@ -92,17 +91,17 @@ void Action::ExecuteAllCommands() const {

void Action::ExecuteCommand(const Command& command) const {
    android::base::Timer t;
    int result = command.InvokeFunc();

    auto result = command.InvokeFunc();
    auto duration = t.duration();

    // Any action longer than 50ms will be warned to user as slow operation
    if (duration > 50ms || android::base::GetMinimumLogSeverity() <= android::base::DEBUG) {
        std::string trigger_name = BuildTriggersString();
        std::string cmd_str = command.BuildCommandString();

        LOG(INFO) << "Command '" << cmd_str << "' action=" << trigger_name << " (" << filename_
                  << ":" << command.line() << ") returned " << result << " took "
                  << duration.count() << "ms.";
                  << ":" << command.line() << ") took " << duration.count() << "ms and "
                  << (result ? "succeeded" : "failed: " + result.error());
    }
}

+2 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "builtins.h"
#include "keyword_map.h"
#include "parser.h"
#include "result.h"

namespace android {
namespace init {
@@ -34,7 +35,7 @@ class Command {
  public:
    Command(BuiltinFunction f, const std::vector<std::string>& args, int line);

    int InvokeFunc() const;
    Result<Success> InvokeFunc() const;
    std::string BuildCommandString() const;

    int line() const { return line_; }
+24 −24
Original line number Diff line number Diff line
@@ -163,20 +163,20 @@ static void bootchart_thread_main() {
  LOG(INFO) << "Bootcharting finished";
}

static int do_bootchart_start() {
static Result<Success> do_bootchart_start() {
    // We don't care about the content, but we do care that /data/bootchart/enabled actually exists.
    std::string start;
    if (!android::base::ReadFileToString("/data/bootchart/enabled", &start)) {
        LOG(VERBOSE) << "Not bootcharting";
    return 0;
        return Success();
    }

    g_bootcharting_thread = new std::thread(bootchart_thread_main);
  return 0;
    return Success();
}

static int do_bootchart_stop() {
  if (!g_bootcharting_thread) return 0;
static Result<Success> do_bootchart_stop() {
    if (!g_bootcharting_thread) return Success();

    // Tell the worker thread it's time to quit.
    {
@@ -188,10 +188,10 @@ static int do_bootchart_stop() {
    g_bootcharting_thread->join();
    delete g_bootcharting_thread;
    g_bootcharting_thread = nullptr;
  return 0;
    return Success();
}

int do_bootchart(const std::vector<std::string>& args) {
Result<Success> do_bootchart(const std::vector<std::string>& args) {
    if (args[1] == "start") return do_bootchart_start();
    return do_bootchart_stop();
}
+3 −1
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@
#include <string>
#include <vector>

#include "result.h"

namespace android {
namespace init {

int do_bootchart(const std::vector<std::string>& args);
Result<Success> do_bootchart(const std::vector<std::string>& args);

}  // namespace init
}  // namespace android
+240 −233

File changed.

Preview size limit exceeded, changes collapsed.

Loading