Merge "Switch case to suite to follow new gtest naming."
diff --git a/adb/daemon/include/adbd/usb.h b/adb/daemon/include/adbd/usb.h
index fca3c58..85a5711 100644
--- a/adb/daemon/include/adbd/usb.h
+++ b/adb/daemon/include/adbd/usb.h
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+#include <linux/usb/functionfs.h>
+
#include <atomic>
#include <condition_variable>
#include <mutex>
@@ -62,5 +64,9 @@
};
usb_handle *create_usb_handle(unsigned num_bufs, unsigned io_size);
+
+struct usb_functionfs_event;
+const char* ffs_event_to_string(enum usb_functionfs_event_type type);
+bool read_functionfs_setup(android::base::borrowed_fd fd, usb_functionfs_event* event);
bool open_functionfs(android::base::unique_fd* control, android::base::unique_fd* bulk_out,
android::base::unique_fd* bulk_in);
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index f4aa9fb..48fa771 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -66,25 +66,6 @@
static constexpr size_t kUsbWriteQueueDepth = 8;
static constexpr size_t kUsbWriteSize = 4 * PAGE_SIZE;
-static const char* to_string(enum usb_functionfs_event_type type) {
- switch (type) {
- case FUNCTIONFS_BIND:
- return "FUNCTIONFS_BIND";
- case FUNCTIONFS_UNBIND:
- return "FUNCTIONFS_UNBIND";
- case FUNCTIONFS_ENABLE:
- return "FUNCTIONFS_ENABLE";
- case FUNCTIONFS_DISABLE:
- return "FUNCTIONFS_DISABLE";
- case FUNCTIONFS_SETUP:
- return "FUNCTIONFS_SETUP";
- case FUNCTIONFS_SUSPEND:
- return "FUNCTIONFS_SUSPEND";
- case FUNCTIONFS_RESUME:
- return "FUNCTIONFS_RESUME";
- }
-}
-
enum class TransferDirection : uint64_t {
READ = 0,
WRITE = 1,
@@ -169,12 +150,12 @@
};
struct UsbFfsConnection : public Connection {
- UsbFfsConnection(unique_fd control, unique_fd read, unique_fd write,
+ UsbFfsConnection(unique_fd* control, unique_fd read, unique_fd write,
std::promise<void> destruction_notifier)
: worker_started_(false),
stopped_(false),
destruction_notifier_(std::move(destruction_notifier)),
- control_fd_(std::move(control)),
+ control_fd_(control),
read_fd_(std::move(read)),
write_fd_(std::move(write)) {
LOG(INFO) << "UsbFfsConnection constructed";
@@ -183,11 +164,6 @@
PLOG(FATAL) << "failed to create eventfd";
}
- monitor_event_fd_.reset(eventfd(0, EFD_CLOEXEC));
- if (monitor_event_fd_ == -1) {
- PLOG(FATAL) << "failed to create eventfd";
- }
-
aio_context_ = ScopedAioContext::Create(kUsbReadQueueDepth + kUsbWriteQueueDepth);
}
@@ -199,7 +175,6 @@
// We need to explicitly close our file descriptors before we notify our destruction,
// because the thread listening on the future will immediately try to reopen the endpoint.
aio_context_.reset();
- control_fd_.reset();
read_fd_.reset();
write_fd_.reset();
@@ -246,13 +221,6 @@
PLOG(FATAL) << "failed to notify worker eventfd to stop UsbFfsConnection";
}
CHECK_EQ(static_cast<size_t>(rc), sizeof(notify));
-
- rc = adb_write(monitor_event_fd_.get(), ¬ify, sizeof(notify));
- if (rc < 0) {
- PLOG(FATAL) << "failed to notify monitor eventfd to stop UsbFfsConnection";
- }
-
- CHECK_EQ(static_cast<size_t>(rc), sizeof(notify));
}
private:
@@ -271,33 +239,24 @@
monitor_thread_ = std::thread([this]() {
adb_thread_setname("UsbFfs-monitor");
- bool bound = false;
bool enabled = false;
bool running = true;
while (running) {
adb_pollfd pfd[2] = {
- { .fd = control_fd_.get(), .events = POLLIN, .revents = 0 },
- { .fd = monitor_event_fd_.get(), .events = POLLIN, .revents = 0 },
+ {.fd = control_fd_->get(), .events = POLLIN, .revents = 0},
};
- // If we don't see our first bind within a second, try again.
- int timeout_ms = bound ? -1 : 1000;
-
- int rc = TEMP_FAILURE_RETRY(adb_poll(pfd, 2, timeout_ms));
+ int rc = TEMP_FAILURE_RETRY(adb_poll(pfd, 2, -1));
if (rc == -1) {
PLOG(FATAL) << "poll on USB control fd failed";
- } else if (rc == 0) {
- LOG(WARNING) << "timed out while waiting for FUNCTIONFS_BIND, trying again";
- break;
}
if (pfd[1].revents) {
- // We were told to die.
- break;
+ // We were told to die, continue reading until FUNCTIONFS_UNBIND.
}
struct usb_functionfs_event event;
- rc = TEMP_FAILURE_RETRY(adb_read(control_fd_.get(), &event, sizeof(event)));
+ rc = TEMP_FAILURE_RETRY(adb_read(control_fd_->get(), &event, sizeof(event)));
if (rc == -1) {
PLOG(FATAL) << "failed to read functionfs event";
} else if (rc == 0) {
@@ -309,32 +268,15 @@
}
LOG(INFO) << "USB event: "
- << to_string(static_cast<usb_functionfs_event_type>(event.type));
+ << ffs_event_to_string(
+ static_cast<usb_functionfs_event_type>(event.type));
switch (event.type) {
case FUNCTIONFS_BIND:
- if (bound) {
- LOG(WARNING) << "received FUNCTIONFS_BIND while already bound?";
- running = false;
- break;
- }
-
- if (enabled) {
- LOG(WARNING) << "received FUNCTIONFS_BIND while already enabled?";
- running = false;
- break;
- }
-
- bound = true;
+ LOG(FATAL) << "received FUNCTIONFS_BIND after already opened?";
break;
case FUNCTIONFS_ENABLE:
- if (!bound) {
- LOG(WARNING) << "received FUNCTIONFS_ENABLE while not bound?";
- running = false;
- break;
- }
-
if (enabled) {
LOG(WARNING) << "received FUNCTIONFS_ENABLE while already enabled?";
running = false;
@@ -346,10 +288,6 @@
break;
case FUNCTIONFS_DISABLE:
- if (!bound) {
- LOG(WARNING) << "received FUNCTIONFS_DISABLE while not bound?";
- }
-
if (!enabled) {
LOG(WARNING) << "received FUNCTIONFS_DISABLE while not enabled?";
}
@@ -363,44 +301,12 @@
LOG(WARNING) << "received FUNCTIONFS_UNBIND while still enabled?";
}
- if (!bound) {
- LOG(WARNING) << "received FUNCTIONFS_UNBIND when not bound?";
- }
-
- bound = false;
running = false;
break;
case FUNCTIONFS_SETUP: {
- LOG(INFO) << "received FUNCTIONFS_SETUP control transfer: bRequestType = "
- << static_cast<int>(event.u.setup.bRequestType)
- << ", bRequest = " << static_cast<int>(event.u.setup.bRequest)
- << ", wValue = " << static_cast<int>(event.u.setup.wValue)
- << ", wIndex = " << static_cast<int>(event.u.setup.wIndex)
- << ", wLength = " << static_cast<int>(event.u.setup.wLength);
-
- if ((event.u.setup.bRequestType & USB_DIR_IN)) {
- LOG(INFO) << "acking device-to-host control transfer";
- ssize_t rc = adb_write(control_fd_.get(), "", 0);
- if (rc != 0) {
- PLOG(ERROR) << "failed to write empty packet to host";
- break;
- }
- } else {
- std::string buf;
- buf.resize(event.u.setup.wLength + 1);
-
- ssize_t rc = adb_read(control_fd_.get(), buf.data(), buf.size());
- if (rc != event.u.setup.wLength) {
- LOG(ERROR)
- << "read " << rc
- << " bytes when trying to read control request, expected "
- << event.u.setup.wLength;
- }
-
- LOG(INFO) << "control request contents: " << buf;
- break;
- }
+ read_functionfs_setup(*control_fd_, &event);
+ break;
}
}
}
@@ -426,6 +332,12 @@
uint64_t dummy;
ssize_t rc = adb_read(worker_event_fd_.get(), &dummy, sizeof(dummy));
if (rc == -1) {
+ if (errno == EINTR) {
+ // We were interrupted either to stop, or because of a backtrace.
+ // Check stopped_ again to see if we need to exit.
+ continue;
+ }
+
PLOG(FATAL) << "failed to read from eventfd";
} else if (rc == 0) {
LOG(FATAL) << "hit EOF on eventfd";
@@ -462,6 +374,7 @@
}
worker_thread_.join();
+ worker_started_ = false;
}
void PrepareReadBlock(IoBlock* block, uint64_t id) {
@@ -692,10 +605,13 @@
std::once_flag error_flag_;
unique_fd worker_event_fd_;
- unique_fd monitor_event_fd_;
ScopedAioContext aio_context_;
- unique_fd control_fd_;
+
+ // We keep a pointer to the control fd, so that we can reuse it to avoid USB reconfiguration,
+ // and still be able to reset it to force a reopen after FUNCTIONFS_UNBIND or running into an
+ // unexpected situation.
+ unique_fd* control_fd_;
unique_fd read_fd_;
unique_fd write_fd_;
@@ -724,15 +640,16 @@
static void usb_ffs_open_thread() {
adb_thread_setname("usb ffs open");
+ unique_fd control;
+ unique_fd bulk_out;
+ unique_fd bulk_in;
+
while (true) {
if (gFfsAioSupported.has_value() && !gFfsAioSupported.value()) {
LOG(INFO) << "failed to use nonblocking ffs, falling back to legacy";
return usb_init_legacy();
}
- unique_fd control;
- unique_fd bulk_out;
- unique_fd bulk_in;
if (!open_functionfs(&control, &bulk_out, &bulk_in)) {
std::this_thread::sleep_for(1s);
continue;
@@ -743,7 +660,7 @@
std::promise<void> destruction_notifier;
std::future<void> future = destruction_notifier.get_future();
transport->SetConnection(std::make_unique<UsbFfsConnection>(
- std::move(control), std::move(bulk_out), std::move(bulk_in),
+ &control, std::move(bulk_out), std::move(bulk_in),
std::move(destruction_notifier)));
register_transport(transport);
future.wait();
diff --git a/adb/daemon/usb_ffs.cpp b/adb/daemon/usb_ffs.cpp
index a64ce40..5fbca3b 100644
--- a/adb/daemon/usb_ffs.cpp
+++ b/adb/daemon/usb_ffs.cpp
@@ -248,6 +248,56 @@
};
// clang-format on
+const char* ffs_event_to_string(enum usb_functionfs_event_type type) {
+ switch (type) {
+ case FUNCTIONFS_BIND:
+ return "FUNCTIONFS_BIND";
+ case FUNCTIONFS_UNBIND:
+ return "FUNCTIONFS_UNBIND";
+ case FUNCTIONFS_ENABLE:
+ return "FUNCTIONFS_ENABLE";
+ case FUNCTIONFS_DISABLE:
+ return "FUNCTIONFS_DISABLE";
+ case FUNCTIONFS_SETUP:
+ return "FUNCTIONFS_SETUP";
+ case FUNCTIONFS_SUSPEND:
+ return "FUNCTIONFS_SUSPEND";
+ case FUNCTIONFS_RESUME:
+ return "FUNCTIONFS_RESUME";
+ }
+}
+
+bool read_functionfs_setup(borrowed_fd fd, usb_functionfs_event* event) {
+ LOG(INFO) << "received FUNCTIONFS_SETUP control transfer: bRequestType = "
+ << static_cast<int>(event->u.setup.bRequestType)
+ << ", bRequest = " << static_cast<int>(event->u.setup.bRequest)
+ << ", wValue = " << static_cast<int>(event->u.setup.wValue)
+ << ", wIndex = " << static_cast<int>(event->u.setup.wIndex)
+ << ", wLength = " << static_cast<int>(event->u.setup.wLength);
+
+ if ((event->u.setup.bRequestType & USB_DIR_IN)) {
+ LOG(INFO) << "acking device-to-host control transfer";
+ ssize_t rc = adb_write(fd.get(), "", 0);
+ if (rc != 0) {
+ PLOG(ERROR) << "failed to write empty packet to host";
+ return false;
+ }
+ } else {
+ std::string buf;
+ buf.resize(event->u.setup.wLength + 1);
+
+ ssize_t rc = adb_read(fd.get(), buf.data(), buf.size());
+ if (rc != event->u.setup.wLength) {
+ LOG(ERROR) << "read " << rc << " bytes when trying to read control request, expected "
+ << event->u.setup.wLength;
+ }
+
+ LOG(INFO) << "control request contents: " << buf;
+ }
+
+ return true;
+}
+
bool open_functionfs(android::base::unique_fd* out_control, android::base::unique_fd* out_bulk_out,
android::base::unique_fd* out_bulk_in) {
unique_fd control, bulk_out, bulk_in;
@@ -297,11 +347,37 @@
PLOG(ERROR) << "failed to write USB strings";
return false;
}
- // Signal only when writing the descriptors to ffs
+
+ // Signal init after we've written our descriptors.
android::base::SetProperty("sys.usb.ffs.ready", "1");
*out_control = std::move(control);
}
+ // Read until we get FUNCTIONFS_BIND from the control endpoint.
+ while (true) {
+ struct usb_functionfs_event event;
+ ssize_t rc = TEMP_FAILURE_RETRY(adb_read(*out_control, &event, sizeof(event)));
+
+ if (rc == -1) {
+ PLOG(FATAL) << "failed to read from FFS control fd";
+ } else if (rc == 0) {
+ LOG(WARNING) << "hit EOF on functionfs control fd during initialization";
+ } else if (rc != sizeof(event)) {
+ LOG(FATAL) << "read functionfs event of unexpected size, expected " << sizeof(event)
+ << ", got " << rc;
+ }
+
+ LOG(INFO) << "USB event: "
+ << ffs_event_to_string(static_cast<usb_functionfs_event_type>(event.type));
+ if (event.type == FUNCTIONFS_BIND) {
+ break;
+ } else if (event.type == FUNCTIONFS_SETUP) {
+ read_functionfs_setup(*out_control, &event);
+ } else {
+ continue;
+ }
+ }
+
bulk_out.reset(adb_open(USB_FFS_ADB_OUT, O_RDONLY));
if (bulk_out < 0) {
PLOG(ERROR) << "cannot open bulk-out endpoint " << USB_FFS_ADB_OUT;
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index 788039d..d54b6ef 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -388,5 +388,13 @@
}
}
+std::string DeviceMapper::GetTargetType(const struct dm_target_spec& spec) {
+ if (const void* p = memchr(spec.target_type, '\0', sizeof(spec.target_type))) {
+ ptrdiff_t length = reinterpret_cast<const char*>(p) - spec.target_type;
+ return std::string{spec.target_type, static_cast<size_t>(length)};
+ }
+ return std::string{spec.target_type, sizeof(spec.target_type)};
+}
+
} // namespace dm
} // namespace android
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 6219923..c5881dd 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -179,6 +179,10 @@
EXPECT_EQ(targets[1].spec.sector_start, 1);
EXPECT_EQ(targets[1].spec.length, 1);
+ // Test GetTargetType().
+ EXPECT_EQ(DeviceMapper::GetTargetType(targets[0].spec), std::string{"linear"});
+ EXPECT_EQ(DeviceMapper::GetTargetType(targets[1].spec), std::string{"linear"});
+
// Normally the TestDevice destructor would delete this, but at least one
// test should ensure that device deletion works.
ASSERT_TRUE(dev.Destroy());
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index 3d223e3..afcb090 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -144,6 +144,8 @@
// mapper device from the kernel.
bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table);
+ static std::string GetTargetType(const struct dm_target_spec& spec);
+
private:
// Maximum possible device mapper targets registered in the kernel.
// This is only used to read the list of targets from kernel so we allocate
diff --git a/fs_mgr/libfiemap_writer/fiemap_writer.cpp b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
index f064436..0a3ba6c 100644
--- a/fs_mgr/libfiemap_writer/fiemap_writer.cpp
+++ b/fs_mgr/libfiemap_writer/fiemap_writer.cpp
@@ -89,6 +89,31 @@
return true;
}
+static bool ValidateDmTarget(const DeviceMapper::TargetInfo& target) {
+ const auto& entry = target.spec;
+ if (entry.sector_start != 0) {
+ LOG(INFO) << "Stopping at target with non-zero starting sector";
+ return false;
+ }
+
+ auto target_type = DeviceMapper::GetTargetType(entry);
+ if (target_type == "bow" || target_type == "default-key" || target_type == "crypt") {
+ return true;
+ }
+ if (target_type == "linear") {
+ auto pieces = android::base::Split(target.data, " ");
+ if (pieces[1] != "0") {
+ LOG(INFO) << "Stopping at complex linear target with non-zero starting sector: "
+ << pieces[1];
+ return false;
+ }
+ return true;
+ }
+
+ LOG(INFO) << "Stopping at complex target type " << target_type;
+ return false;
+}
+
static bool DeviceMapperStackPop(const std::string& bdev, std::string* bdev_raw) {
*bdev_raw = bdev;
@@ -128,15 +153,7 @@
LOG(INFO) << "Stopping at complex table for " << dm_name << " at " << bdev;
return true;
}
- const auto& entry = table[0].spec;
- std::string target_type(std::string(entry.target_type, sizeof(entry.target_type)).c_str());
- if (target_type != "bow" && target_type != "default-key" && target_type != "crypt") {
- LOG(INFO) << "Stopping at complex target-type " << target_type << " for " << dm_name
- << " at " << bdev;
- return true;
- }
- if (entry.sector_start != 0) {
- LOG(INFO) << "Stopping at target-type with non-zero starting sector";
+ if (!ValidateDmTarget(table[0])) {
return true;
}
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 7e6bf45..f73ec2d 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -39,6 +39,11 @@
bool UsePerAppMemcg();
+// Drop the fd cache of cgroup path. It is used for when resource caching is enabled and a process
+// loses the access to the path, the access checking (See SetCgroupAction::EnableResourceCaching)
+// should be active again. E.g. Zygote specialization for child process.
+void DropTaskProfilesResourceCaching();
+
// Return 0 and removes the cgroup if there are no longer any processes in it.
// Returns -1 in the case of an error occurring or if there are processes still running
// even after retrying for up to 200ms.
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index d3ac26b..7c191be 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -111,6 +111,10 @@
return memcg_supported;
}
+void DropTaskProfilesResourceCaching() {
+ TaskProfiles::GetInstance().DropResourceCaching();
+}
+
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
bool use_fd_cache) {
const TaskProfiles& tp = TaskProfiles::GetInstance();
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index edc316a..aee5f0c 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -173,6 +173,15 @@
fd_ = std::move(fd);
}
+void SetCgroupAction::DropResourceCaching() {
+ std::lock_guard<std::mutex> lock(fd_mutex_);
+ if (fd_ == FDS_NOT_CACHED) {
+ return;
+ }
+
+ fd_.reset(FDS_NOT_CACHED);
+}
+
bool SetCgroupAction::AddTidToCgroup(int tid, int fd) {
if (tid <= 0) {
return true;
@@ -292,6 +301,24 @@
res_cached_ = true;
}
+void TaskProfile::DropResourceCaching() {
+ if (!res_cached_) {
+ return;
+ }
+
+ for (auto& element : elements_) {
+ element->DropResourceCaching();
+ }
+
+ res_cached_ = false;
+}
+
+void TaskProfiles::DropResourceCaching() const {
+ for (auto& iter : profiles_) {
+ iter.second->DropResourceCaching();
+ }
+}
+
TaskProfiles& TaskProfiles::GetInstance() {
// Deliberately leak this object to avoid a race between destruction on
// process exit and concurrent access from another thread.
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 77bac2d..891d5b5 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -51,6 +51,7 @@
virtual bool ExecuteForTask(int) const { return false; };
virtual void EnableResourceCaching() {}
+ virtual void DropResourceCaching() {}
};
// Profile actions
@@ -114,6 +115,7 @@
virtual bool ExecuteForProcess(uid_t uid, pid_t pid) const;
virtual bool ExecuteForTask(int tid) const;
virtual void EnableResourceCaching();
+ virtual void DropResourceCaching();
const CgroupController* controller() const { return &controller_; }
std::string path() const { return path_; }
@@ -145,6 +147,7 @@
bool ExecuteForProcess(uid_t uid, pid_t pid) const;
bool ExecuteForTask(int tid) const;
void EnableResourceCaching();
+ void DropResourceCaching();
private:
bool res_cached_;
@@ -158,6 +161,7 @@
TaskProfile* GetProfile(const std::string& name) const;
const ProfileAttribute* GetAttribute(const std::string& name) const;
+ void DropResourceCaching() const;
private:
std::map<std::string, std::unique_ptr<TaskProfile>> profiles_;
diff --git a/usbd/usbd.cpp b/usbd/usbd.cpp
index 191fb92..6e24d8e 100644
--- a/usbd/usbd.cpp
+++ b/usbd/usbd.cpp
@@ -24,8 +24,6 @@
#include <hidl/HidlTransportSupport.h>
-#define PERSISTENT_USB_CONFIG "persist.sys.usb.config"
-
using android::base::GetProperty;
using android::base::SetProperty;
using android::hardware::configureRpcThreadpool;
@@ -34,14 +32,15 @@
using android::hardware::Return;
int main(int /*argc*/, char** /*argv*/) {
- configureRpcThreadpool(1, true /*callerWillJoin*/);
+ if (GetProperty("ro.bootmode", "") == "charger") exit(0);
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
android::sp<IUsbGadget> gadget = IUsbGadget::getService();
Return<void> ret;
if (gadget != nullptr) {
LOG(INFO) << "Usb HAL found.";
- std::string function = GetProperty(PERSISTENT_USB_CONFIG, "");
+ std::string function = GetProperty("persist.sys.usb.config", "");
if (function == "adb") {
LOG(INFO) << "peristent prop is adb";
SetProperty("ctl.start", "adbd");