Sets dumpstate version using system properties.
Android N introduced a '-V' argument to change dumpstate's version, but
such argument can only be used when running dumpstate directly (as
root).
This CL uses a system property instead (dumpstate.version), so different
versions can be used while taking bugreports.
It also introduces a '-v' argument line to display the dumpstate header,
and removes the redundant dry_run check from _dump_file_from_fd().
Test: DumpstateTest passes
Change-Id: I46ec4bca133d16d8431358bb9f16eb89bb082be1
diff --git a/cmds/dumpstate/bugreport-format.md b/cmds/dumpstate/bugreport-format.md
index c33fc1f..388b506 100644
--- a/cmds/dumpstate/bugreport-format.md
+++ b/cmds/dumpstate/bugreport-format.md
@@ -63,8 +63,8 @@
For example, the initial version during _Android N_ development was
**1.0-dev1**. When `dumpsys` was split in 2 sections but not all tools were
ready to parse that format, the version was named **1.0-dev2**,
-which had to be passed do `dumpsys` explicitly (i.e., trhough a
-`-V 1.0-dev2` argument). Once that format became stable and tools
+which had to be passed to `dumpsys` explicitly (by setting the `dumpstate.version` system property).
+Once that format became stable and tools
knew how to parse it, the default version became **1.0-dev2**.
Similarly, if changes in the file format are made after the initial release of
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ea07cdb..e898301 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -112,6 +112,7 @@
static constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
+static constexpr char PROPERTY_VERSION[] = "dumpstate.version";
/* gets the tombstone data, according to the bugreport type: if zipped, gets all tombstones;
* otherwise, gets just those modified in the last half an hour. */
@@ -702,7 +703,7 @@
JustDumpFile("", "/proc/version");
printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
printf("Bugreport format version: %s\n", version_.c_str());
- printf("Dumpstate info: id=%lu pid=%d dryRun=%d args=%s extraOptions=%s\n", id_, getpid(),
+ printf("Dumpstate info: id=%lu pid=%d dry_run=%d args=%s extra_options=%s\n", id_, getpid(),
dry_run_, args_.c_str(), extra_options_.c_str());
printf("\n");
}
@@ -1153,8 +1154,7 @@
"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"
- " -V: sets the bugreport format version (valid values: %s)\n",
- VERSION_DEFAULT.c_str());
+ " -v: prints the dumpstate header and exit\n");
exit(exitCode);
}
@@ -1284,42 +1284,12 @@
int do_fb = 0;
int do_broadcast = 0;
int is_remote_mode = 0;
-
- MYLOGI("begin\n");
-
- if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
- MYLOGE("Failed to acquire wake lock: %s \n", strerror(errno));
- } else {
- MYLOGD("Wake lock acquired.\n");
- atexit(wake_lock_releaser);
- register_sig_handler();
- }
-
- if (ds.IsDryRun()) {
- MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
- }
-
- // TODO: use helper function to convert argv into a string
- for (int i = 0; i < argc; i++) {
- ds.args_ += argv[i];
- if (i < argc - 1) {
- ds.args_ += " ";
- }
- }
-
- ds.extra_options_ = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
- MYLOGI("Dumpstate args: %s (extra options: %s)\n", ds.args_.c_str(), ds.extra_options_.c_str());
-
- /* gets the sequential id */
- int last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
- ds.id_ = ++last_id;
- android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
- MYLOGI("dumpstate id: %lu\n", ds.id_);
+ bool show_header_only = false;
/* set as high priority, and protect from OOM killer */
setpriority(PRIO_PROCESS, 0, -20);
- FILE *oom_adj = fopen("/proc/self/oom_score_adj", "we");
+ FILE* oom_adj = fopen("/proc/self/oom_score_adj", "we");
if (oom_adj) {
fputs("-1000", oom_adj);
fclose(oom_adj);
@@ -1337,18 +1307,18 @@
while ((c = getopt(argc, argv, "dho:svqzpPBRSV:")) != -1) {
switch (c) {
// clang-format off
- case 'd': do_add_date = 1; break;
- case 'z': do_zip_file = 1; break;
- case 'o': use_outfile = optarg; break;
- case 's': use_socket = 1; break;
- case 'S': use_control_socket = 1; break;
- case 'v': break; // compatibility no-op
- case 'q': do_vibrate = 0; break;
- case 'p': do_fb = 1; break;
+ case 'd': do_add_date = 1; break;
+ case 'z': do_zip_file = 1; break;
+ case 'o': use_outfile = optarg; break;
+ case 's': use_socket = 1; break;
+ case 'S': use_control_socket = 1; break;
+ case 'v': show_header_only = true; break;
+ case 'q': do_vibrate = 0; break;
+ case 'p': do_fb = 1; break;
case 'P': ds.update_progress_ = true; break;
- case 'R': is_remote_mode = 1; break;
- case 'B': do_broadcast = 1; break;
- case 'V': ds.version_ = optarg; break;
+ case 'R': is_remote_mode = 1; break;
+ case 'B': do_broadcast = 1; break;
+ case 'V': break; // compatibility no-op
case 'h':
ShowUsageAndExit(0);
break;
@@ -1359,20 +1329,26 @@
}
}
+ // TODO: use helper function to convert argv into a string
+ for (int i = 0; i < argc; i++) {
+ ds.args_ += argv[i];
+ if (i < argc - 1) {
+ ds.args_ += " ";
+ }
+ }
+
+ ds.extra_options_ = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
if (!ds.extra_options_.empty()) {
// Framework uses a system property to override some command-line args.
// Currently, it contains the type of the requested bugreport.
if (ds.extra_options_ == "bugreportplus") {
- MYLOGD("Running as bugreportplus: add -P, remove -p\n");
ds.update_progress_ = true;
do_fb = 0;
} else if (ds.extra_options_ == "bugreportremote") {
- MYLOGD("Running as bugreportremote: add -q -R, remove -p\n");
do_vibrate = 0;
is_remote_mode = 1;
do_fb = 0;
} else if (ds.extra_options_ == "bugreportwear") {
- MYLOGD("Running as bugreportwear: add -P\n");
ds.update_progress_ = true;
} else {
MYLOGE("Unknown extra option: %s\n", ds.extra_options_.c_str());
@@ -1397,10 +1373,43 @@
ExitOnInvalidArgs();
}
- if (ds.version_ != VERSION_DEFAULT) {
- ShowUsageAndExit();
+ if (ds.version_ == VERSION_DEFAULT) {
+ ds.version_ = VERSION_CURRENT;
}
+ if (ds.version_ != VERSION_CURRENT) {
+ MYLOGE("invalid version requested ('%s'); suppported values are: ('%s', '%s')\n",
+ ds.version_.c_str(), VERSION_DEFAULT.c_str(), VERSION_CURRENT.c_str());
+ exit(1);
+ }
+
+ if (show_header_only) {
+ ds.PrintHeader();
+ exit(0);
+ }
+
+ /* gets the sequential id */
+ int last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
+ ds.id_ = ++last_id;
+ android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
+
+ MYLOGI("begin\n");
+
+ if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
+ MYLOGE("Failed to acquire wake lock: %s \n", strerror(errno));
+ } else {
+ MYLOGD("Wake lock acquired.\n");
+ atexit(wake_lock_releaser);
+ register_sig_handler();
+ }
+
+ if (ds.IsDryRun()) {
+ MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
+ }
+
+ MYLOGI("dumpstate info: id=%lu, args='%s', extra_options= %s)\n", ds.id_, ds.args_.c_str(),
+ ds.extra_options_.c_str());
+
MYLOGI("bugreport format version: %s\n", ds.version_.c_str());
ds.do_early_screenshot_ = ds.update_progress_;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 29d3c0b..568256a 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -197,7 +197,12 @@
*
* See bugreport-format.md for more info.
*/
-static std::string VERSION_DEFAULT = "1.0";
+static std::string VERSION_CURRENT = "1.0";
+
+/*
+ * "Alias" for the current version.
+ */
+static std::string VERSION_DEFAULT = "default";
/*
* Main class driving a bugreport generation.
@@ -332,7 +337,7 @@
int control_socket_fd_ = -1;
// Bugreport format version;
- std::string version_ = VERSION_DEFAULT;
+ std::string version_ = VERSION_CURRENT;
// Command-line arguments as string
std::string args_;
@@ -370,7 +375,8 @@
private:
// Used by GetInstance() only.
- Dumpstate(bool dry_run = false, const std::string& build_type = "user");
+ Dumpstate(const std::string& version = VERSION_CURRENT, bool dry_run = false,
+ const std::string& build_type = "user");
// Internal version of RunCommand that just runs it, without updating progress.
int JustRunCommand(const char* command, const char* path, std::vector<const char*>& args,
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 527cf91..31c8697 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -163,12 +163,13 @@
return CommandOptions::CommandOptionsBuilder(timeout);
}
-Dumpstate::Dumpstate(bool dry_run, const std::string& build_type)
- : now_(time(nullptr)), dry_run_(dry_run), build_type_(build_type) {
+Dumpstate::Dumpstate(const std::string& version, bool dry_run, const std::string& build_type)
+ : version_(version), now_(time(nullptr)), dry_run_(dry_run), build_type_(build_type) {
}
Dumpstate& Dumpstate::GetInstance() {
- static Dumpstate singleton_(android::base::GetBoolProperty("dumpstate.dry_run", false),
+ static Dumpstate singleton_(android::base::GetProperty("dumpstate.version", VERSION_CURRENT),
+ android::base::GetBoolProperty("dumpstate.dry_run", false),
android::base::GetProperty("ro.build.type", "(unknown)"));
return singleton_;
}
@@ -546,11 +547,6 @@
}
printf(") ------\n");
}
- if (IsDryRun()) {
- UpdateProgress(WEIGHT_FILE);
- close(fd);
- return 0;
- }
bool newline = false;
fd_set read_set;