diff options
author | 2019-01-22 12:10:16 +0000 | |
---|---|---|
committer | 2019-01-22 21:03:25 +0000 | |
commit | 235864b47896d308f56a012b1d509588a5069daf (patch) | |
tree | 40796f37cd810135864670741b1ffaabd7b49c97 | |
parent | 9a76d20e4fa6d4a3c29bb1aba662f0d839077782 (diff) |
Add a flag that makes dumpstate wait for options
There are 2 ways of running bugreports. Running dumpstate binary
directly with command line options (existing flow), or running the
binary to start the binder service, which waits for a caller to supply
arguments like file descriptors to write output to (new flow to support
the bugreport triggering API).
Support the second flow with a new commandline flag.
Also add a new service that uses the flag, to be used in the API.
BUG:111441001
Test: adb shell setprop "ctl.start" "bugreportd" -> starts service &
waits.
Test: interactive bugreport still works
Change-Id: I64cd03d15f45a896692d7462998d4faa6e413ef1
-rw-r--r-- | cmds/dumpstate/dumpstate.cpp | 6 | ||||
-rw-r--r-- | cmds/dumpstate/dumpstate.rc | 6 | ||||
-rw-r--r-- | cmds/dumpstate/main.cpp | 49 |
3 files changed, 59 insertions, 2 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index b226a7d89e..ec8393be55 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -1654,6 +1654,7 @@ static void ShowUsage() { "progress (requires -o and -B)\n" " -R: take bugreport in remote mode (requires -o, -z, -d and -B, " "shouldn't be used with -P)\n" + " -w: start binder service and make it wait for a call to startBugreport\n" " -v: prints the dumpstate header and exit\n"); } @@ -2112,7 +2113,7 @@ void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode, Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) { RunStatus status = RunStatus::OK; int c; - while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) { + while ((c = getopt(argc, argv, "dho:svqzpPBRSV:w")) != -1) { switch (c) { // clang-format off case 'd': do_add_date = true; break; @@ -2129,6 +2130,9 @@ Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) case 'R': is_remote_mode = true; break; case 'B': do_broadcast = true; break; case 'V': break; // compatibility no-op + case 'w': + // This was already processed + break; case 'h': status = RunStatus::HELP; break; diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc index 2e72574738..14937b80b9 100644 --- a/cmds/dumpstate/dumpstate.rc +++ b/cmds/dumpstate/dumpstate.rc @@ -17,3 +17,9 @@ service dumpstatez /system/bin/dumpstate -S -d -z \ class main disabled oneshot + +# bugreportd starts dumpstate binder service and makes it wait for a listener to connect. +service bugreportd /system/bin/dumpstate -w + class main + disabled + oneshot diff --git a/cmds/dumpstate/main.cpp b/cmds/dumpstate/main.cpp index 78aad1137b..68d373377c 100644 --- a/cmds/dumpstate/main.cpp +++ b/cmds/dumpstate/main.cpp @@ -14,8 +14,55 @@ * limitations under the License. */ +#define LOG_TAG "dumpstate" + +#include <binder/IPCThreadState.h> + +#include "DumpstateInternal.h" +#include "DumpstateService.h" #include "dumpstate.h" +namespace { + +// Returns true if we should start the service and wait for a listener +// to bind with bugreport options. +bool ShouldStartServiceAndWait(int argc, char* argv[]) { + bool do_wait = false; + int c; + // Keep flags in sync with Dumpstate::DumpOptions::Initialize. + while ((c = getopt(argc, argv, "wdho:svqzpPBRSV:")) != -1 && !do_wait) { + switch (c) { + case 'w': + do_wait = true; + break; + default: + // Ignore all other options + break; + } + } + + // Reset next index used by getopt so getopt can be called called again in Dumpstate::Run to + // parse bugreport options. + optind = 1; + return do_wait; +} + +} // namespace + int main(int argc, char* argv[]) { - return run_main(argc, argv); + if (ShouldStartServiceAndWait(argc, argv)) { + int ret; + if ((ret = android::os::DumpstateService::Start()) != android::OK) { + MYLOGE("Unable to start 'dumpstate' service: %d", ret); + exit(1); + } + MYLOGI("'dumpstate' service started and will wait for a call to startBugreport()"); + + // Waits forever for an incoming connection. + // TODO(b/111441001): should this time out? + android::IPCThreadState::self()->joinThreadPool(); + return 0; + } else { + return run_main(argc, argv); + } } |