|
16 | 16 |
|
17 | 17 | #include <stdio.h> |
18 | 18 | #include <fstream> |
| 19 | +#include <future> |
19 | 20 | #include <string> |
20 | 21 |
|
| 22 | +#include <android-base/file.h> |
21 | 23 | #include <android-base/logging.h> |
22 | 24 | #include <android-base/strings.h> |
23 | 25 | #include <gflags/gflags.h> |
24 | 26 |
|
25 | 27 | #include "common/libs/fs/shared_fd.h" |
26 | 28 | #include "common/libs/fs/shared_select.h" |
27 | 29 | #include "common/libs/utils/files.h" |
| 30 | +#include "common/libs/utils/subprocess.h" |
28 | 31 | #include "common/libs/utils/tee_logging.h" |
29 | 32 | #include "host/libs/config/cuttlefish_config.h" |
30 | 33 | #include "ziparchive/zip_writer.h" |
@@ -71,6 +74,19 @@ void AddNetsimdLogs(ZipWriter& writer) { |
71 | 74 | } |
72 | 75 | } |
73 | 76 |
|
| 77 | +Result<void> CreateDeviceBugreport( |
| 78 | + const CuttlefishConfig::InstanceSpecific& ins, const std::string& out_dir) { |
| 79 | + Command adb_command(HostBinaryPath("adb")); |
| 80 | + adb_command.SetWorkingDirectory( |
| 81 | + "/"); // Use a deterministic working directory |
| 82 | + adb_command.AddParameter("-s").AddParameter(ins.adb_ip_and_port()); |
| 83 | + adb_command.AddParameter("wait-for-device"); |
| 84 | + adb_command.AddParameter("bugreport"); |
| 85 | + adb_command.AddParameter(out_dir); |
| 86 | + CF_EXPECT_EQ(adb_command.Start().Wait(), 0); |
| 87 | + return {}; |
| 88 | +} |
| 89 | + |
74 | 90 | Result<void> CvdHostBugreportMain(int argc, char** argv) { |
75 | 91 | ::android::base::InitLogging(argv, android::base::StderrLogger); |
76 | 92 | google::ParseCommandLineFlags(&argc, &argv, true); |
@@ -99,6 +115,14 @@ Result<void> CvdHostBugreportMain(int argc, char** argv) { |
99 | 115 | save("cuttlefish_config.json"); |
100 | 116 |
|
101 | 117 | for (const auto& instance : config->Instances()) { |
| 118 | + std::string device_br_dir = "/tmp/cvd_dbrXXXXXX"; |
| 119 | + CF_EXPECTF(mkdtemp(device_br_dir.data()) != nullptr, "mkdtemp failed: '{}'", |
| 120 | + strerror(errno)); |
| 121 | + std::future<Result<void>> create_device_br = |
| 122 | + std::async(std::launch::async, [&instance, &device_br_dir] { |
| 123 | + return CreateDeviceBugreport(instance, device_br_dir); |
| 124 | + }); |
| 125 | + |
102 | 126 | auto save = [&writer, instance](const std::string& path) { |
103 | 127 | const auto& zip_name = instance.instance_name() + "/" + path; |
104 | 128 | const auto& file_name = instance.PerInstancePath(path.c_str()); |
@@ -146,6 +170,26 @@ Result<void> CvdHostBugreportMain(int argc, char** argv) { |
146 | 170 | << result.error().FormatForEnv(/* color = */ false); |
147 | 171 | } |
148 | 172 | } |
| 173 | + |
| 174 | + { |
| 175 | + auto result = create_device_br.get(); |
| 176 | + if (result.ok()) { |
| 177 | + auto names = DirectoryContents(device_br_dir); |
| 178 | + if (names.ok()) { |
| 179 | + for (const auto& name : names.value()) { |
| 180 | + std::string filename = device_br_dir + "/" + name; |
| 181 | + SaveFile(writer, cpp_basename(filename), filename); |
| 182 | + } |
| 183 | + } else { |
| 184 | + LOG(ERROR) << "Cannot read from device bugreport directory: " |
| 185 | + << names.error().FormatForEnv(/* color = */ false); |
| 186 | + } |
| 187 | + } else { |
| 188 | + LOG(ERROR) << "Failed to create device bugreport: " |
| 189 | + << result.error().FormatForEnv(/* color = */ false); |
| 190 | + } |
| 191 | + static_cast<void>(RecursivelyRemoveDirectory(device_br_dir)); |
| 192 | + } |
149 | 193 | } |
150 | 194 |
|
151 | 195 | AddNetsimdLogs(writer); |
|
0 commit comments