Merge "fastboot: Use copy constructor to copy fastboot match callback"
diff --git a/fastboot/README.md b/fastboot/README.md
index d3b6c1a..63db5c3 100644
--- a/fastboot/README.md
+++ b/fastboot/README.md
@@ -29,20 +29,27 @@
2. Client response with a single packet no greater than 256 bytes.
The first four bytes of the response are "OKAY", "FAIL", "DATA",
- or "INFO". Additional bytes may contain an (ascii) informative
+ "INFO" or "TEXT". Additional bytes may contain an (ascii) informative
message.
a. INFO -> the remaining 252 bytes are an informative message
(providing progress or diagnostic messages). They should
- be displayed and then step #2 repeats
+ be displayed and then step #2 repeats. The print format is:
+ "(bootloader) " + InfoMessagePayload + '\n'
- b. FAIL -> the requested command failed. The remaining 252 bytes
+ b. TEXT -> the remaining 252 bytes are arbitrary. They should
+ be displayed and then step #2 repeats.
+ It differs from info in that no formatting is applied.
+ The payload is printed as-is with no newline at the end.
+ Payload is expected to be NULL terminated.
+
+ c. FAIL -> the requested command failed. The remaining 252 bytes
of the response (if present) provide a textual failure message
to present to the user. Stop.
- c. OKAY -> the requested command completed successfully. Go to #5
+ d. OKAY -> the requested command completed successfully. Go to #5
- d. DATA -> the requested command is ready for the data phase.
+ e. DATA -> the requested command is ready for the data phase.
A DATA response packet will be 12 bytes long, in the form of
DATA00000000 where the 8 digit hexadecimal number represents
the total data size to transfer.
@@ -54,15 +61,17 @@
in the "DATA" response above.
4. Client responds with a single packet no greater than 256 bytes.
- The first four bytes of the response are "OKAY", "FAIL", or "INFO".
- Similar to #2:
+ The first four bytes of the response are "OKAY", "FAIL",
+ "INFO" or "TEXT". Similar to #2:
- a. INFO -> display the remaining 252 bytes and return to #4
+ a. INFO -> display the formatted remaining 252 bytes and return to #4
- b. FAIL -> display the remaining 252 bytes (if present) as a failure
+ b. TEXT -> display the unformatted remaining 252 bytes and return to #4
+
+ c. FAIL -> display the remaining 252 bytes (if present) as a failure
reason and consider the command failed. Stop.
- c. OKAY -> success. Go to #5
+ d. OKAY -> success. Go to #5
5. Success. Stop.
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c9cb228..799c9f9 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -255,6 +255,10 @@
fprintf(stderr, "(bootloader) %s\n", info.c_str());
}
+static void TextMessage(const std::string& text) {
+ fprintf(stderr, "%s", text.c_str());
+}
+
bool ReadFileToVector(const std::string& file, std::vector<char>* out) {
out->clear();
@@ -428,7 +432,7 @@
transport = open_device(device.c_str(), false, false);
if (print) {
- PrintDevice(device.c_str(), transport == nullptr ? "offline" : "device");
+ PrintDevice(device.c_str(), transport == nullptr ? "offline" : "fastboot");
}
if (transport != nullptr) {
@@ -2305,7 +2309,9 @@
.prolog = Status,
.epilog = Epilog,
.info = InfoMessage,
+ .text = TextMessage,
};
+
fastboot::FastBootDriver fastboot_driver(transport, driver_callbacks, false);
fb = &fastboot_driver;
diff --git a/fastboot/fastboot_driver.cpp b/fastboot/fastboot_driver.cpp
index 99a4873..9770ab2 100644
--- a/fastboot/fastboot_driver.cpp
+++ b/fastboot/fastboot_driver.cpp
@@ -64,6 +64,7 @@
prolog_(std::move(driver_callbacks.prolog)),
epilog_(std::move(driver_callbacks.epilog)),
info_(std::move(driver_callbacks.info)),
+ text_(std::move(driver_callbacks.text)),
disable_checks_(no_checks) {}
FastBootDriver::~FastBootDriver() {
@@ -498,6 +499,10 @@
error_ = android::base::StringPrintf("remote: '%s'", status + strlen("FAIL"));
set_response(input.substr(strlen("FAIL")));
return DEVICE_FAIL;
+ } else if (android::base::StartsWith(input, "TEXT")) {
+ text_(input.substr(strlen("TEXT")));
+ // Reset timeout as many more TEXT may come
+ start = std::chrono::steady_clock::now();
} else if (android::base::StartsWith(input, "DATA")) {
std::string tmp = input.substr(strlen("DATA"));
uint32_t num = strtol(tmp.c_str(), 0, 16);
diff --git a/fastboot/fastboot_driver.h b/fastboot/fastboot_driver.h
index b422c91..f60c9f1 100644
--- a/fastboot/fastboot_driver.h
+++ b/fastboot/fastboot_driver.h
@@ -60,6 +60,7 @@
std::function<void(const std::string&)> prolog = [](const std::string&) {};
std::function<void(int)> epilog = [](int) {};
std::function<void(const std::string&)> info = [](const std::string&) {};
+ std::function<void(const std::string&)> text = [](const std::string&) {};
};
class FastBootDriver {
@@ -169,6 +170,7 @@
std::function<void(const std::string&)> prolog_;
std::function<void(int)> epilog_;
std::function<void(const std::string&)> info_;
+ std::function<void(const std::string&)> text_;
bool disable_checks_;
};
diff --git a/fastboot/fastboot_driver_test.cpp b/fastboot/fastboot_driver_test.cpp
index e874c3a..6f6cf8c 100644
--- a/fastboot/fastboot_driver_test.cpp
+++ b/fastboot/fastboot_driver_test.cpp
@@ -58,3 +58,38 @@
ASSERT_EQ(info.size(), size_t(1));
ASSERT_EQ(info[0], "this is an info line");
}
+
+TEST_F(DriverTest, TextMessage) {
+ MockTransport transport;
+ std::string text;
+
+ DriverCallbacks callbacks{[](const std::string&) {}, [](int) {}, [](const std::string&) {},
+ [&text](const std::string& extra_text) { text += extra_text; }};
+
+ FastBootDriver driver(&transport, callbacks);
+
+ EXPECT_CALL(transport, Write(_, _))
+ .With(AllArgs(RawData("oem trusty runtest trusty.hwaes.bench")))
+ .WillOnce(ReturnArg<1>());
+ EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("TEXTthis is a text line")));
+ EXPECT_CALL(transport, Read(_, _))
+ .WillOnce(Invoke(
+ CopyData("TEXT, albeit very long and split over multiple TEXT messages.")));
+ EXPECT_CALL(transport, Read(_, _))
+ .WillOnce(Invoke(CopyData("TEXT Indeed we can do that now with a TEXT message whenever "
+ "we feel like it.")));
+ EXPECT_CALL(transport, Read(_, _))
+ .WillOnce(Invoke(CopyData("TEXT Isn't that truly super cool?")));
+
+ EXPECT_CALL(transport, Read(_, _)).WillOnce(Invoke(CopyData("OKAY")));
+
+ std::vector<std::string> info;
+ ASSERT_EQ(driver.RawCommand("oem trusty runtest trusty.hwaes.bench", "", nullptr, &info),
+ SUCCESS)
+ << driver.Error();
+ ASSERT_EQ(text,
+ "this is a text line"
+ ", albeit very long and split over multiple TEXT messages."
+ " Indeed we can do that now with a TEXT message whenever we feel like it."
+ " Isn't that truly super cool?");
+}
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
index d670f1e..1421403 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_test.cpp
@@ -99,9 +99,9 @@
bool valid_;
};
-class SnapuserTest final {
+class SnapuserdTest : public ::testing::Test {
public:
- bool Setup();
+ bool SetupDefault();
bool SetupOrderedOps();
bool SetupOrderedOpsInverted();
bool SetupCopyOverlap_1();
@@ -118,6 +118,10 @@
static const uint64_t kSectorSize = 512;
+ protected:
+ void SetUp() override {}
+ void TearDown() override { Shutdown(); }
+
private:
void SetupImpl();
@@ -172,7 +176,7 @@
return fd;
}
-void SnapuserTest::Shutdown() {
+void SnapuserdTest::Shutdown() {
ASSERT_TRUE(dmuser_dev_->Destroy());
auto misc_device = "/dev/dm-user/" + system_device_ctrl_name_;
@@ -181,36 +185,36 @@
ASSERT_TRUE(client_->DetachSnapuserd());
}
-bool SnapuserTest::Setup() {
+bool SnapuserdTest::SetupDefault() {
SetupImpl();
return setup_ok_;
}
-bool SnapuserTest::SetupOrderedOps() {
+bool SnapuserdTest::SetupOrderedOps() {
CreateBaseDevice();
CreateCowDeviceOrderedOps();
return SetupDaemon();
}
-bool SnapuserTest::SetupOrderedOpsInverted() {
+bool SnapuserdTest::SetupOrderedOpsInverted() {
CreateBaseDevice();
CreateCowDeviceOrderedOpsInverted();
return SetupDaemon();
}
-bool SnapuserTest::SetupCopyOverlap_1() {
+bool SnapuserdTest::SetupCopyOverlap_1() {
CreateBaseDevice();
CreateCowDeviceWithCopyOverlap_1();
return SetupDaemon();
}
-bool SnapuserTest::SetupCopyOverlap_2() {
+bool SnapuserdTest::SetupCopyOverlap_2() {
CreateBaseDevice();
CreateCowDeviceWithCopyOverlap_2();
return SetupDaemon();
}
-bool SnapuserTest::SetupDaemon() {
+bool SnapuserdTest::SetupDaemon() {
SetDeviceControlName();
StartSnapuserdDaemon();
@@ -224,7 +228,7 @@
return setup_ok_;
}
-void SnapuserTest::StartSnapuserdDaemon() {
+void SnapuserdTest::StartSnapuserdDaemon() {
pid_t pid = fork();
ASSERT_GE(pid, 0);
if (pid == 0) {
@@ -238,7 +242,7 @@
}
}
-void SnapuserTest::CreateBaseDevice() {
+void SnapuserdTest::CreateBaseDevice() {
unique_fd rnd_fd;
total_base_size_ = (size_ * 5);
@@ -261,7 +265,7 @@
ASSERT_TRUE(base_loop_->valid());
}
-void SnapuserTest::ReadSnapshotDeviceAndValidate() {
+void SnapuserdTest::ReadSnapshotDeviceAndValidate() {
unique_fd fd(open(dmuser_dev_->path().c_str(), O_RDONLY));
ASSERT_GE(fd, 0);
std::unique_ptr<uint8_t[]> snapuserd_buffer = std::make_unique<uint8_t[]>(size_);
@@ -292,7 +296,7 @@
ASSERT_EQ(memcmp(snapuserd_buffer.get(), (char*)orig_buffer_.get() + (size_ * 4), size_), 0);
}
-void SnapuserTest::CreateCowDeviceWithCopyOverlap_2() {
+void SnapuserdTest::CreateCowDeviceWithCopyOverlap_2() {
std::string path = android::base::GetExecutableDirectory();
cow_system_ = std::make_unique<TemporaryFile>(path);
@@ -344,7 +348,7 @@
}
}
-void SnapuserTest::CreateCowDeviceWithCopyOverlap_1() {
+void SnapuserdTest::CreateCowDeviceWithCopyOverlap_1() {
std::string path = android::base::GetExecutableDirectory();
cow_system_ = std::make_unique<TemporaryFile>(path);
@@ -387,7 +391,7 @@
true);
}
-void SnapuserTest::CreateCowDeviceOrderedOpsInverted() {
+void SnapuserdTest::CreateCowDeviceOrderedOpsInverted() {
unique_fd rnd_fd;
loff_t offset = 0;
@@ -450,7 +454,7 @@
}
}
-void SnapuserTest::CreateCowDeviceOrderedOps() {
+void SnapuserdTest::CreateCowDeviceOrderedOps() {
unique_fd rnd_fd;
loff_t offset = 0;
@@ -511,7 +515,7 @@
}
}
-void SnapuserTest::CreateCowDevice() {
+void SnapuserdTest::CreateCowDevice() {
unique_fd rnd_fd;
loff_t offset = 0;
@@ -601,13 +605,13 @@
}
}
-void SnapuserTest::InitCowDevice() {
+void SnapuserdTest::InitCowDevice() {
uint64_t num_sectors = client_->InitDmUserCow(system_device_ctrl_name_, cow_system_->path,
base_loop_->device(), base_loop_->device());
ASSERT_NE(num_sectors, 0);
}
-void SnapuserTest::SetDeviceControlName() {
+void SnapuserdTest::SetDeviceControlName() {
system_device_name_.clear();
system_device_ctrl_name_.clear();
@@ -619,7 +623,7 @@
system_device_ctrl_name_ = system_device_name_ + "-ctrl";
}
-void SnapuserTest::CreateDmUserDevice() {
+void SnapuserdTest::CreateDmUserDevice() {
unique_fd fd(TEMP_FAILURE_RETRY(open(base_loop_->device().c_str(), O_RDONLY | O_CLOEXEC)));
ASSERT_TRUE(fd > 0);
@@ -641,12 +645,12 @@
ASSERT_TRUE(android::fs_mgr::WaitForFile(misc_device, 10s));
}
-void SnapuserTest::InitDaemon() {
+void SnapuserdTest::InitDaemon() {
bool ok = client_->AttachDmUser(system_device_ctrl_name_);
ASSERT_TRUE(ok);
}
-void SnapuserTest::CheckMergeCompletion() {
+void SnapuserdTest::CheckMergeCompletion() {
while (true) {
double percentage = client_->GetMergePercent();
if ((int)percentage == 100) {
@@ -657,7 +661,7 @@
}
}
-void SnapuserTest::SetupImpl() {
+void SnapuserdTest::SetupImpl() {
CreateBaseDevice();
CreateCowDevice();
@@ -672,26 +676,26 @@
setup_ok_ = true;
}
-bool SnapuserTest::Merge() {
+bool SnapuserdTest::Merge() {
StartMerge();
CheckMergeCompletion();
merge_ok_ = true;
return merge_ok_;
}
-void SnapuserTest::StartMerge() {
+void SnapuserdTest::StartMerge() {
bool ok = client_->InitiateMerge(system_device_ctrl_name_);
ASSERT_TRUE(ok);
}
-void SnapuserTest::ValidateMerge() {
+void SnapuserdTest::ValidateMerge() {
merged_buffer_ = std::make_unique<uint8_t[]>(total_base_size_);
ASSERT_EQ(android::base::ReadFullyAtOffset(base_fd_, merged_buffer_.get(), total_base_size_, 0),
true);
ASSERT_EQ(memcmp(merged_buffer_.get(), orig_buffer_.get(), total_base_size_), 0);
}
-void SnapuserTest::SimulateDaemonRestart() {
+void SnapuserdTest::SimulateDaemonRestart() {
Shutdown();
std::this_thread::sleep_for(500ms);
SetDeviceControlName();
@@ -701,7 +705,7 @@
InitDaemon();
}
-void SnapuserTest::MergeInterruptRandomly(int max_duration) {
+void SnapuserdTest::MergeInterruptRandomly(int max_duration) {
std::srand(std::time(nullptr));
StartMerge();
@@ -716,7 +720,7 @@
ASSERT_TRUE(Merge());
}
-void SnapuserTest::MergeInterruptFixed(int duration) {
+void SnapuserdTest::MergeInterruptFixed(int duration) {
StartMerge();
for (int i = 0; i < 25; i++) {
@@ -729,7 +733,7 @@
ASSERT_TRUE(Merge());
}
-void SnapuserTest::MergeInterrupt() {
+void SnapuserdTest::MergeInterrupt() {
// Interrupt merge at various intervals
StartMerge();
std::this_thread::sleep_for(250ms);
@@ -758,104 +762,93 @@
ASSERT_TRUE(Merge());
}
-TEST(Snapuserd_Test, Snapshot_IO_TEST) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.Setup());
+TEST_F(SnapuserdTest, Snapshot_IO_TEST) {
+ ASSERT_TRUE(SetupDefault());
// I/O before merge
- harness.ReadSnapshotDeviceAndValidate();
- ASSERT_TRUE(harness.Merge());
- harness.ValidateMerge();
+ ReadSnapshotDeviceAndValidate();
+ ASSERT_TRUE(Merge());
+ ValidateMerge();
// I/O after merge - daemon should read directly
// from base device
- harness.ReadSnapshotDeviceAndValidate();
- harness.Shutdown();
+ ReadSnapshotDeviceAndValidate();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_MERGE_IO_TEST) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.Setup());
+TEST_F(SnapuserdTest, Snapshot_MERGE_IO_TEST) {
+ ASSERT_TRUE(SetupDefault());
// Issue I/O before merge begins
- std::async(std::launch::async, &SnapuserTest::ReadSnapshotDeviceAndValidate, &harness);
+ std::async(std::launch::async, &SnapuserdTest::ReadSnapshotDeviceAndValidate, this);
// Start the merge
- ASSERT_TRUE(harness.Merge());
- harness.ValidateMerge();
- harness.Shutdown();
+ ASSERT_TRUE(Merge());
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_MERGE_IO_TEST_1) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.Setup());
+TEST_F(SnapuserdTest, Snapshot_MERGE_IO_TEST_1) {
+ ASSERT_TRUE(SetupDefault());
// Start the merge
- harness.StartMerge();
+ StartMerge();
// Issue I/O in parallel when merge is in-progress
- std::async(std::launch::async, &SnapuserTest::ReadSnapshotDeviceAndValidate, &harness);
- harness.CheckMergeCompletion();
- harness.ValidateMerge();
- harness.Shutdown();
+ std::async(std::launch::async, &SnapuserdTest::ReadSnapshotDeviceAndValidate, this);
+ CheckMergeCompletion();
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_Merge_Resume) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.Setup());
- harness.MergeInterrupt();
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_Merge_Resume) {
+ ASSERT_TRUE(SetupDefault());
+ MergeInterrupt();
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_COPY_Overlap_TEST_1) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupCopyOverlap_1());
- ASSERT_TRUE(harness.Merge());
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_TEST_1) {
+ ASSERT_TRUE(SetupCopyOverlap_1());
+ ASSERT_TRUE(Merge());
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_COPY_Overlap_TEST_2) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupCopyOverlap_2());
- ASSERT_TRUE(harness.Merge());
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_TEST_2) {
+ ASSERT_TRUE(SetupCopyOverlap_2());
+ ASSERT_TRUE(Merge());
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_COPY_Overlap_Merge_Resume_TEST) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupCopyOverlap_1());
- harness.MergeInterrupt();
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_COPY_Overlap_Merge_Resume_TEST) {
+ ASSERT_TRUE(SetupCopyOverlap_1());
+ MergeInterrupt();
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_Merge_Crash_Fixed_Ordered) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupOrderedOps());
- harness.MergeInterruptFixed(300);
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Fixed_Ordered) {
+ ASSERT_TRUE(SetupOrderedOps());
+ MergeInterruptFixed(300);
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_Merge_Crash_Random_Ordered) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupOrderedOps());
- harness.MergeInterruptRandomly(500);
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Random_Ordered) {
+ ASSERT_TRUE(SetupOrderedOps());
+ MergeInterruptRandomly(500);
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_Merge_Crash_Fixed_Inverted) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupOrderedOpsInverted());
- harness.MergeInterruptFixed(50);
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Fixed_Inverted) {
+ ASSERT_TRUE(SetupOrderedOpsInverted());
+ MergeInterruptFixed(50);
+ ValidateMerge();
+ Shutdown();
}
-TEST(Snapuserd_Test, Snapshot_Merge_Crash_Random_Inverted) {
- SnapuserTest harness;
- ASSERT_TRUE(harness.SetupOrderedOpsInverted());
- harness.MergeInterruptRandomly(50);
- harness.ValidateMerge();
- harness.Shutdown();
+TEST_F(SnapuserdTest, Snapshot_Merge_Crash_Random_Inverted) {
+ ASSERT_TRUE(SetupOrderedOpsInverted());
+ MergeInterruptRandomly(50);
+ ValidateMerge();
+ Shutdown();
}
} // namespace snapshot
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 7bb5c90..305bf95 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <fstream>
#include <functional>
#include <string_view>
#include <thread>
@@ -22,6 +23,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
#include <android/api-level.h>
#include <gtest/gtest.h>
#include <selinux/selinux.h>
@@ -44,6 +46,7 @@
using android::base::GetIntProperty;
using android::base::GetProperty;
using android::base::SetProperty;
+using android::base::StringPrintf;
using android::base::StringReplace;
using android::base::WaitForProperty;
using namespace std::literals;
@@ -643,34 +646,32 @@
ASSERT_LE(curr_limit.rlim_max, max_limit);
}
-static std::vector<const char*> ConvertToArgv(const std::vector<std::string>& args) {
- std::vector<const char*> argv;
- argv.reserve(args.size() + 1);
- for (const auto& arg : args) {
- if (argv.empty()) {
- LOG(DEBUG) << arg;
- } else {
- LOG(DEBUG) << " " << arg;
+void CloseAllFds() {
+ DIR* dir;
+ struct dirent* ent;
+ int fd;
+
+ if ((dir = opendir("/proc/self/fd"))) {
+ while ((ent = readdir(dir))) {
+ if (sscanf(ent->d_name, "%d", &fd) == 1) {
+ close(fd);
+ }
}
- argv.emplace_back(arg.data());
+ closedir(dir);
}
- argv.emplace_back(nullptr);
- return argv;
}
-pid_t ForkExecvpAsync(const std::vector<std::string>& args) {
- auto argv = ConvertToArgv(args);
-
+pid_t ForkExecvpAsync(const char* argv[]) {
pid_t pid = fork();
if (pid == 0) {
- close(STDIN_FILENO);
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
+ // Child process.
+ CloseAllFds();
- execvp(argv[0], const_cast<char**>(argv.data()));
+ execvp(argv[0], const_cast<char**>(argv));
PLOG(ERROR) << "exec in ForkExecvpAsync init test";
_exit(EXIT_FAILURE);
}
+ // Parent process.
if (pid == -1) {
PLOG(ERROR) << "fork in ForkExecvpAsync init test";
return -1;
@@ -678,6 +679,18 @@
return pid;
}
+pid_t TracerPid(pid_t pid) {
+ static constexpr std::string_view prefix{"TracerPid:"};
+ std::ifstream is(StringPrintf("/proc/%d/status", pid));
+ std::string line;
+ while (std::getline(is, line)) {
+ if (line.find(prefix) == 0) {
+ return atoi(line.substr(prefix.length()).c_str());
+ }
+ }
+ return -1;
+}
+
TEST(init, GentleKill) {
if (getuid() != 0) {
GTEST_SKIP() << "Must be run as root.";
@@ -709,18 +722,15 @@
logfile.DoNotRemove();
ASSERT_TRUE(logfile.fd != -1);
- std::vector<std::string> cmd;
- cmd.push_back("system/bin/strace");
- cmd.push_back("-o");
- cmd.push_back(logfile.path);
- cmd.push_back("-e");
- cmd.push_back("signal");
- cmd.push_back("-p");
- cmd.push_back(std::to_string(pid));
- pid_t strace_pid = ForkExecvpAsync(cmd);
+ std::string pid_str = std::to_string(pid);
+ const char* argv[] = {"/system/bin/strace", "-o", logfile.path, "-e", "signal", "-p",
+ pid_str.c_str(), nullptr};
+ pid_t strace_pid = ForkExecvpAsync(argv);
- // Give strace a moment to connect
- std::this_thread::sleep_for(1s);
+ // Give strace the chance to connect
+ while (TracerPid(pid) == 0) {
+ std::this_thread::sleep_for(10ms);
+ }
service->Stop();
int status;
@@ -728,8 +738,7 @@
std::string logs;
android::base::ReadFdToString(logfile.fd, &logs);
- int pos = logs.find("killed by SIGTERM");
- ASSERT_NE(pos, (int)std::string::npos);
+ ASSERT_NE(logs.find("killed by SIGTERM"), std::string::npos);
}
class TestCaseLogger : public ::testing::EmptyTestEventListener {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 86c6eaa..2929da4 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -993,6 +993,7 @@
# Create directories for statsd
mkdir /data/misc/stats-active-metric/ 0770 statsd system
mkdir /data/misc/stats-data/ 0770 statsd system
+ mkdir /data/misc/stats-data/restricted-data 0770 statsd system
mkdir /data/misc/stats-metadata/ 0770 statsd system
mkdir /data/misc/stats-service/ 0770 statsd system
mkdir /data/misc/train-info/ 0770 statsd system
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index eb0acb5..81c9881 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -596,6 +596,7 @@
TEST_PASSED = 0,
TEST_FAILED = 1,
TEST_MESSAGE = 2,
+ TEST_TEXT = 3,
};
int fd;
@@ -625,7 +626,7 @@
break;
} else if (rx_buf[0] == TEST_FAILED) {
break;
- } else if (rx_buf[0] == TEST_MESSAGE) {
+ } else if (rx_buf[0] == TEST_MESSAGE || rx_buf[0] == TEST_TEXT) {
write(STDOUT_FILENO, rx_buf + 1, ret - 1);
} else {
fprintf(stderr, "%s: Bad message header: %d\n", __func__, rx_buf[0]);
diff --git a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c
index 9e72af3..6cc6670 100644
--- a/trusty/utils/trusty-ut-ctrl/ut-ctrl.c
+++ b/trusty/utils/trusty-ut-ctrl/ut-ctrl.c
@@ -94,6 +94,7 @@
TEST_PASSED = 0,
TEST_FAILED = 1,
TEST_MESSAGE = 2,
+ TEST_TEXT = 3,
};
static int run_trusty_unitest(const char* utapp) {
@@ -121,7 +122,7 @@
break;
} else if (rx_buf[0] == TEST_FAILED) {
break;
- } else if (rx_buf[0] == TEST_MESSAGE) {
+ } else if (rx_buf[0] == TEST_MESSAGE || rx_buf[0] == TEST_TEXT) {
write(STDOUT_FILENO, rx_buf + 1, rc - 1);
} else {
fprintf(stderr, "%s: Bad message header: %d\n", __func__, rx_buf[0]);