Merge "Mark libdemangle as vendor_available." into oc-dr1-dev
diff --git a/adb/client/usb_libusb.cpp b/adb/client/usb_libusb.cpp
index b2fdc07..e7f44c6 100644
--- a/adb/client/usb_libusb.cpp
+++ b/adb/client/usb_libusb.cpp
@@ -180,10 +180,6 @@
if (port_count < 0) return "";
return StringPrintf("/dev/bus/usb/%03u/%03u", libusb_get_bus_number(device), ports[0]);
}
-
-static bool is_device_accessible(libusb_device* device) {
- return access(get_device_dev_path(device).c_str(), R_OK | W_OK) == 0;
-}
#endif
static bool endpoint_is_output(uint8_t endpoint) {
@@ -377,9 +373,10 @@
{
std::unique_lock<std::mutex> lock(usb_handles_mutex);
usb_handles[device_address] = std::move(result);
- }
- register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(), writable);
+ register_usb_transport(usb_handle_raw, device_serial.c_str(), device_address.c_str(),
+ writable);
+ }
LOG(INFO) << "registered new usb device '" << device_serial << "'";
}
@@ -388,18 +385,12 @@
static void device_connected(libusb_device* device) {
#if defined(__linux__)
// Android's host linux libusb uses netlink instead of udev for device hotplug notification,
- // which means we can get hotplug notifications before udev has updated ownership/perms on
- // the device. Since we're not going to be able to link against the system's libudev any
- // time soon, hack around this by checking for accessibility in a loop.
+ // which means we can get hotplug notifications before udev has updated ownership/perms on the
+ // device. Since we're not going to be able to link against the system's libudev any time soon,
+ // hack around this by inserting a sleep.
auto thread = std::thread([device]() {
std::string device_path = get_device_dev_path(device);
- auto start = std::chrono::steady_clock::now();
- while (std::chrono::steady_clock::now() - start < 500ms) {
- if (is_device_accessible(device)) {
- break;
- }
- std::this_thread::sleep_for(10ms);
- }
+ std::this_thread::sleep_for(1s);
process_device(device);
if (--connecting_devices == 0) {
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 308ee8d..2bbbefd 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -603,15 +603,15 @@
static void transport_unref(atransport* t) {
CHECK(t != nullptr);
- std::lock_guard<std::mutex> lock(transport_lock);
- CHECK_GT(t->ref_count, 0u);
- t->ref_count--;
- if (t->ref_count == 0) {
+ size_t old_refcount = t->ref_count--;
+ CHECK_GT(old_refcount, 0u);
+
+ if (old_refcount == 1u) {
D("transport: %s unref (kicking and closing)", t->serial);
t->close(t);
remove_transport(t);
} else {
- D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
+ D("transport: %s unref (count=%zu)", t->serial, old_refcount - 1);
}
}
diff --git a/adb/transport.h b/adb/transport.h
index 57fc988..4a89ed9 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -61,7 +61,7 @@
// class in one go is a very large change. Given how bad our testing is,
// it's better to do this piece by piece.
- atransport(ConnectionState state = kCsOffline) : connection_state_(state) {
+ atransport(ConnectionState state = kCsOffline) : ref_count(0), connection_state_(state) {
transport_fde = {};
protocol_version = A_VERSION;
max_payload = MAX_PAYLOAD;
@@ -88,7 +88,7 @@
int fd = -1;
int transport_socket = -1;
fdevent transport_fde;
- size_t ref_count = 0;
+ std::atomic<size_t> ref_count;
uint32_t sync_token = 0;
bool online = false;
TransportType type = kTransportAny;
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 0a9f000..b4a2bde 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -23,7 +23,9 @@
#include <array>
#include <deque>
+#include <string>
#include <unordered_map>
+#include <utility>
#include <event2/event.h>
#include <event2/listener.h>
@@ -75,23 +77,24 @@
find_oldest_artifact();
}
- unique_fd get_output_fd() {
+ std::pair<unique_fd, std::string> get_output() {
unique_fd result;
- char buf[PATH_MAX];
- snprintf(buf, sizeof(buf), "%s%02d", file_name_prefix_.c_str(), next_artifact_);
+ std::string file_name = StringPrintf("%s%02d", file_name_prefix_.c_str(), next_artifact_);
+
// Unlink and create the file, instead of using O_TRUNC, to avoid two processes
// interleaving their output in case we ever get into that situation.
- if (unlinkat(dir_fd_, buf, 0) != 0 && errno != ENOENT) {
- PLOG(FATAL) << "failed to unlink tombstone at " << dir_path_ << buf;
+ if (unlinkat(dir_fd_, file_name.c_str(), 0) != 0 && errno != ENOENT) {
+ PLOG(FATAL) << "failed to unlink tombstone at " << dir_path_ << "/" << file_name;
}
- result.reset(openat(dir_fd_, buf, O_CREAT | O_EXCL | O_WRONLY | O_APPEND | O_CLOEXEC, 0640));
+ result.reset(openat(dir_fd_, file_name.c_str(),
+ O_CREAT | O_EXCL | O_WRONLY | O_APPEND | O_CLOEXEC, 0640));
if (result == -1) {
- PLOG(FATAL) << "failed to create tombstone at " << dir_path_ << buf;
+ PLOG(FATAL) << "failed to create tombstone at " << dir_path_ << "/" << file_name;
}
next_artifact_ = (next_artifact_ + 1) % max_artifacts_;
- return result;
+ return {std::move(result), dir_path_ + "/" + file_name};
}
bool maybe_enqueue_crash(Crash* crash) {
@@ -124,8 +127,7 @@
time_t oldest_time = std::numeric_limits<time_t>::max();
for (size_t i = 0; i < max_artifacts_; ++i) {
- std::string path = android::base::StringPrintf("%s/%s%02zu", dir_path_.c_str(),
- file_name_prefix_.c_str(), i);
+ std::string path = StringPrintf("%s/%s%02zu", dir_path_.c_str(), file_name_prefix_.c_str(), i);
struct stat st;
if (stat(path.c_str(), &st) != 0) {
if (errno == ENOENT) {
@@ -183,6 +185,7 @@
unique_fd crash_fd;
pid_t crash_pid;
event* crash_event = nullptr;
+ std::string crash_path;
DebuggerdDumpType crash_type;
};
@@ -203,7 +206,7 @@
static void perform_request(Crash* crash) {
unique_fd output_fd;
if (!intercept_manager->GetIntercept(crash->crash_pid, crash->crash_type, &output_fd)) {
- output_fd = get_crash_queue(crash)->get_output_fd();
+ std::tie(output_fd, crash->crash_path) = get_crash_queue(crash)->get_output();
}
TombstonedCrashPacket response = {
@@ -341,6 +344,10 @@
goto fail;
}
+ if (!crash->crash_path.empty()) {
+ LOG(ERROR) << "Tombstone written to: " << crash->crash_path;
+ }
+
fail:
CrashQueue* queue = get_crash_queue(crash);
delete crash;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 23bd664..6c527c5 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -389,16 +389,8 @@
dirent* dp;
while ((dp = readdir(fstabdir.get())) != NULL) {
- // skip over name and compatible
- if (dp->d_type != DT_DIR) {
- continue;
- }
-
- // skip if its not 'vendor', 'odm' or 'system'
- if (strcmp(dp->d_name, "odm") && strcmp(dp->d_name, "system") &&
- strcmp(dp->d_name, "vendor")) {
- continue;
- }
+ // skip over name, compatible and .
+ if (dp->d_type != DT_DIR || dp->d_name[0] == '.') continue;
// create <dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\n
std::vector<std::string> fstab_entry;
diff --git a/init/devices.cpp b/init/devices.cpp
index c52d8f8..2943fb7 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -147,21 +147,34 @@
}
}
-// Given a path that may start with a platform device, find the length of the
-// platform device prefix. If it doesn't start with a platform device, return false
-bool PlatformDeviceList::Find(const std::string& path, std::string* out_path) const {
- out_path->clear();
- // platform_devices is searched backwards, since parents are added before their children,
- // and we want to match as deep of a child as we can.
- for (auto it = platform_devices_.crbegin(); it != platform_devices_.crend(); ++it) {
- auto platform_device_path_length = it->length();
- if (platform_device_path_length < path.length() &&
- path[platform_device_path_length] == '/' &&
- android::base::StartsWith(path, it->c_str())) {
- *out_path = *it;
+// Given a path that may start with a platform device, find the parent platform device by finding a
+// parent directory with a 'subsystem' symlink that points to the platform bus.
+// If it doesn't start with a platform device, return false
+bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_device_path) const {
+ platform_device_path->clear();
+
+ // Uevents don't contain the mount point, so we need to add it here.
+ path.insert(0, sysfs_mount_point_);
+
+ std::string directory = android::base::Dirname(path);
+
+ while (directory != "/" && directory != ".") {
+ std::string subsystem_link_path;
+ if (android::base::Realpath(directory + "/subsystem", &subsystem_link_path) &&
+ subsystem_link_path == sysfs_mount_point_ + "/bus/platform") {
+ // We need to remove the mount point that we added above before returning.
+ directory.erase(0, sysfs_mount_point_.size());
+ *platform_device_path = directory;
return true;
}
+
+ auto last_slash = path.rfind('/');
+ if (last_slash == std::string::npos) return false;
+
+ path.erase(last_slash);
+ directory = android::base::Dirname(path);
}
+
return false;
}
@@ -258,7 +271,7 @@
std::vector<std::string> DeviceHandler::GetCharacterDeviceSymlinks(const Uevent& uevent) const {
std::string parent_device;
- if (!platform_devices_.Find(uevent.path, &parent_device)) return {};
+ if (!FindPlatformDevice(uevent.path, &parent_device)) return {};
// skip path to the parent driver
std::string path = uevent.path.substr(parent_device.length());
@@ -316,7 +329,7 @@
std::string device;
std::string type;
- if (platform_devices_.Find(uevent.path, &device)) {
+ if (FindPlatformDevice(uevent.path, &device)) {
// Skip /devices/platform or /devices/ if present
static const std::string devices_platform_prefix = "/devices/platform/";
static const std::string devices_prefix = "/devices/";
@@ -388,14 +401,6 @@
}
}
-void DeviceHandler::HandlePlatformDeviceEvent(const Uevent& uevent) {
- if (uevent.action == "add") {
- platform_devices_.Add(uevent.path);
- } else if (uevent.action == "remove") {
- platform_devices_.Remove(uevent.path);
- }
-}
-
void DeviceHandler::HandleBlockDeviceEvent(const Uevent& uevent) const {
// if it's not a /dev device, nothing to do
if (uevent.major < 0 || uevent.minor < 0) return;
@@ -458,8 +463,6 @@
if (uevent.subsystem == "block") {
HandleBlockDeviceEvent(uevent);
- } else if (uevent.subsystem == "platform") {
- HandlePlatformDeviceEvent(uevent);
} else {
HandleGenericDeviceEvent(uevent);
}
@@ -472,7 +475,8 @@
sysfs_permissions_(std::move(sysfs_permissions)),
subsystems_(std::move(subsystems)),
sehandle_(selinux_android_file_context_handle()),
- skip_restorecon_(skip_restorecon) {}
+ skip_restorecon_(skip_restorecon),
+ sysfs_mount_point_("/sys") {}
DeviceHandler::DeviceHandler()
: DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
diff --git a/init/devices.h b/init/devices.h
index 09a0ce3..362c38c 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -93,20 +93,6 @@
DevnameSource devname_source_;
};
-class PlatformDeviceList {
- public:
- void Add(const std::string& path) { platform_devices_.emplace_back(path); }
- void Remove(const std::string& path) {
- auto it = std::find(platform_devices_.begin(), platform_devices_.end(), path);
- if (it != platform_devices_.end()) platform_devices_.erase(it);
- }
- bool Find(const std::string& path, std::string* out_path) const;
- auto size() const { return platform_devices_.size(); }
-
- private:
- std::vector<std::string> platform_devices_;
-};
-
class DeviceHandler {
public:
friend class DeviceHandlerTester;
@@ -119,16 +105,11 @@
void HandleDeviceEvent(const Uevent& uevent);
- void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
-
- void HandlePlatformDeviceEvent(const Uevent& uevent);
- void HandleBlockDeviceEvent(const Uevent& uevent) const;
- void HandleGenericDeviceEvent(const Uevent& uevent) const;
-
std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;
void set_skip_restorecon(bool value) { skip_restorecon_ = value; }
private:
+ bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
const std::string& path, const std::vector<std::string>& links) const;
void MakeDevice(const std::string& path, int block, int major, int minor,
@@ -136,13 +117,17 @@
std::vector<std::string> GetCharacterDeviceSymlinks(const Uevent& uevent) const;
void HandleDevice(const std::string& action, const std::string& devpath, int block, int major,
int minor, const std::vector<std::string>& links) const;
+ void FixupSysPermissions(const std::string& upath, const std::string& subsystem) const;
+
+ void HandleBlockDeviceEvent(const Uevent& uevent) const;
+ void HandleGenericDeviceEvent(const Uevent& uevent) const;
std::vector<Permissions> dev_permissions_;
std::vector<SysfsPermissions> sysfs_permissions_;
std::vector<Subsystem> subsystems_;
- PlatformDeviceList platform_devices_;
selabel_handle* sehandle_;
bool skip_restorecon_;
+ std::string sysfs_mount_point_;
};
// Exposed for testing
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index 41b101b..e1e4e49 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -16,33 +16,29 @@
#include "devices.h"
-#include <string>
-#include <vector>
-
#include <android-base/scopeguard.h>
+#include <android-base/test_utils.h>
#include <gtest/gtest.h>
+#include "util.h"
+
+using namespace std::string_literals;
+
class DeviceHandlerTester {
public:
- void AddPlatformDevice(const std::string& path) {
- Uevent uevent = {
- .action = "add", .subsystem = "platform", .path = path,
- };
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
- void RemovePlatformDevice(const std::string& path) {
- Uevent uevent = {
- .action = "remove", .subsystem = "platform", .path = path,
- };
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
- void TestGetSymlinks(const std::string& platform_device_name, const Uevent& uevent,
+ void TestGetSymlinks(const std::string& platform_device, const Uevent& uevent,
const std::vector<std::string> expected_links, bool block) {
- AddPlatformDevice(platform_device_name);
- auto platform_device_remover = android::base::make_scope_guard(
- [this, &platform_device_name]() { RemovePlatformDevice(platform_device_name); });
+ TemporaryDir fake_sys_root;
+ device_handler_.sysfs_mount_point_ = fake_sys_root.path;
+
+ std::string platform_device_dir = fake_sys_root.path + platform_device;
+ mkdir_recursive(platform_device_dir, 0777, nullptr);
+
+ std::string platform_bus = fake_sys_root.path + "/bus/platform"s;
+ mkdir_recursive(platform_bus, 0777, nullptr);
+ symlink(platform_bus.c_str(), (platform_device_dir + "/subsystem").c_str());
+
+ mkdir_recursive(android::base::Dirname(fake_sys_root.path + uevent.path), 0777, nullptr);
std::vector<std::string> result;
if (block) {
@@ -65,30 +61,6 @@
DeviceHandler device_handler_;
};
-TEST(device_handler, PlatformDeviceList) {
- PlatformDeviceList platform_device_list;
-
- platform_device_list.Add("/devices/platform/some_device_name");
- platform_device_list.Add("/devices/platform/some_device_name/longer");
- platform_device_list.Add("/devices/platform/other_device_name");
- EXPECT_EQ(3U, platform_device_list.size());
-
- std::string out_path;
- EXPECT_FALSE(platform_device_list.Find("/devices/platform/not_found", &out_path));
- EXPECT_EQ("", out_path);
-
- EXPECT_FALSE(platform_device_list.Find("/devices/platform/some_device_name_with_same_prefix",
- &out_path));
-
- EXPECT_TRUE(platform_device_list.Find("/devices/platform/some_device_name/longer/longer_child",
- &out_path));
- EXPECT_EQ("/devices/platform/some_device_name/longer", out_path);
-
- EXPECT_TRUE(
- platform_device_list.Find("/devices/platform/some_device_name/other_child", &out_path));
- EXPECT_EQ("/devices/platform/some_device_name", out_path);
-}
-
TEST(device_handler, get_character_device_symlinks_success) {
const char* platform_device = "/devices/platform/some_device_name";
Uevent uevent = {
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 8a7d9a2..ebbe1cd 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -60,9 +60,8 @@
virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0;
bool need_dm_verity_;
- // Device tree fstab entries.
+
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
- // Eligible first stage mount candidates, only allow /system, /vendor and/or /odm.
std::vector<fstab_rec*> mount_fstab_recs_;
std::set<std::string> required_devices_partition_names_;
DeviceHandler device_handler_;
@@ -115,12 +114,10 @@
LOG(ERROR) << "Failed to read fstab from device tree";
return;
}
- for (auto mount_point : {"/system", "/vendor", "/odm"}) {
- fstab_rec* fstab_rec =
- fs_mgr_get_entry_for_mount_point(device_tree_fstab_.get(), mount_point);
- if (fstab_rec != nullptr) {
- mount_fstab_recs_.push_back(fstab_rec);
- }
+ // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
+ // for easier manipulation later, e.g., range-base for loop.
+ for (int i = 0; i < device_tree_fstab_->num_entries; i++) {
+ mount_fstab_recs_.push_back(&device_tree_fstab_->recs[i]);
}
}
@@ -184,12 +181,6 @@
}
RegenerationAction FirstStageMount::UeventCallback(const Uevent& uevent) {
- // We need platform devices to create symlinks.
- if (uevent.subsystem == "platform") {
- device_handler_.HandleDeviceEvent(uevent);
- return RegenerationAction::kContinue;
- }
-
// Ignores everything that is not a block device.
if (uevent.subsystem != "block") {
return RegenerationAction::kContinue;
@@ -420,7 +411,7 @@
// Public functions
// ----------------
-// Mounts /system, /vendor, and/or /odm if they are present in the fstab provided by device tree.
+// Mounts partitions specified by fstab in device tree.
bool DoFirstStageMount() {
// Skips first stage mount if we're in recovery mode.
if (IsRecoveryMode()) {
diff --git a/init/service.cpp b/init/service.cpp
index 7c931da..1a6474b 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -209,17 +209,6 @@
}
void Service::KillProcessGroup(int signal) {
- // We ignore reporting errors of ESRCH as this commonly happens in the below case,
- // 1) Terminate() is called, which sends SIGTERM to the process
- // 2) The process successfully exits
- // 3) ReapOneProcess() is called, which calls waitpid(-1, ...) which removes the pid entry.
- // 4) Reap() is called, which sends SIGKILL, but the pid no longer exists.
- // TODO: sigaction for SIGCHLD reports the pid of the exiting process,
- // we should do this kill with that pid first before calling waitpid().
- if (kill(-pid_, signal) == -1 && errno != ESRCH) {
- PLOG(ERROR) << "kill(" << pid_ << ", " << signal << ") failed";
- }
-
// If we've already seen a successful result from killProcessGroup*(), then we have removed
// the cgroup already and calling these functions a second time will simply result in an error.
// This is true regardless of which signal was sent.
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 31e4106..8cf9326 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -128,15 +128,7 @@
void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) {
for (unsigned int i = process_num; i < uevent_queue_.size(); i += total_processes) {
auto& uevent = uevent_queue_[i];
- if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
- device_handler_.FixupSysPermissions(uevent.path, uevent.subsystem);
- }
-
- if (uevent.subsystem == "block") {
- device_handler_.HandleBlockDeviceEvent(uevent);
- } else {
- device_handler_.HandleGenericDeviceEvent(uevent);
- }
+ device_handler_.HandleDeviceEvent(uevent);
}
_exit(EXIT_SUCCESS);
}
@@ -145,14 +137,6 @@
uevent_listener_.RegenerateUevents([this](const Uevent& uevent) {
HandleFirmwareEvent(uevent);
- // This is the one mutable part of DeviceHandler, in which platform devices are
- // added to a vector for later reference. Since there is no communication after
- // fork()'ing subprocess handlers, all platform devices must be in the vector before
- // we fork, and therefore they must be handled in this loop.
- if (uevent.subsystem == "platform") {
- device_handler_.HandlePlatformDeviceEvent(uevent);
- }
-
uevent_queue_.emplace_back(std::move(uevent));
return RegenerationAction::kContinue;
});
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index 3f47066..0792307 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -57,6 +57,12 @@
return;
}
}
+
+void LogResponseError(const std::string& message, const FuseResponse& response) {
+ LOG(ERROR) << message << ": header.len=" << response.header.len
+ << " header.error=" << response.header.error
+ << " header.unique=" << response.header.unique;
+}
}
class FuseBridgeEntry {
@@ -135,6 +141,7 @@
}
if (!buffer_.response.Write(device_fd_)) {
+ LogResponseError("Failed to write a reply from proxy to device", buffer_.response);
return FuseBridgeState::kClosing;
}
@@ -200,6 +207,7 @@
}
if (!buffer_.response.Write(device_fd_)) {
+ LogResponseError("Failed to write a response to device", buffer_.response);
return FuseBridgeState::kClosing;
}
@@ -215,6 +223,11 @@
case ResultOrAgain::kSuccess:
return FuseBridgeState::kWaitToReadEither;
case ResultOrAgain::kFailure:
+ LOG(ERROR) << "Failed to write a request to proxy:"
+ << " header.len=" << buffer_.request.header.len
+ << " header.opcode=" << buffer_.request.header.opcode
+ << " header.unique=" << buffer_.request.header.unique
+ << " header.nodeid=" << buffer_.request.header.nodeid;
return FuseBridgeState::kClosing;
case ResultOrAgain::kAgain:
return FuseBridgeState::kWaitToWriteProxy;
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index 653e96b..1b47e0a 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -115,7 +115,10 @@
case EAGAIN:
return ResultOrAgain::kAgain;
default:
- PLOG(ERROR) << "Failed to write a FUSE message";
+ PLOG(ERROR) << "Failed to write a FUSE message: "
+ << "fd=" << fd << " "
+ << "sockflag=" << sockflag << " "
+ << "data=" << data;
return ResultOrAgain::kFailure;
}
}
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index 4269eaa..cdac76b 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -23,7 +23,6 @@
cc_library_shared {
name: "libmemunreachable",
- vendor_available: true,
defaults: ["libmemunreachable_defaults"],
srcs: [
"Allocator.cpp",
diff --git a/libmemunreachable/MemUnreachable.cpp b/libmemunreachable/MemUnreachable.cpp
index e7c0beb..1c84744 100644
--- a/libmemunreachable/MemUnreachable.cpp
+++ b/libmemunreachable/MemUnreachable.cpp
@@ -502,7 +502,10 @@
std::string GetUnreachableMemoryString(bool log_contents, size_t limit) {
UnreachableMemoryInfo info;
if (!GetUnreachableMemory(info, limit)) {
- return "Failed to get unreachable memory\n";
+ return "Failed to get unreachable memory\n"
+ "If you are trying to get unreachable memory from a system app\n"
+ "(like com.android.systemui), disable selinux first using\n"
+ "setenforce 0\n";
}
return info.ToString(log_contents);
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 27b4065..f5d4e1c 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -27,10 +27,12 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
#include <chrono>
#include <memory>
#include <mutex>
+#include <set>
#include <thread>
#include <android-base/logging.h>
@@ -258,6 +260,12 @@
return -errno;
}
+ // We separate all of the pids in the cgroup into those pids that are also the leaders of
+ // process groups (stored in the pgids set) and those that are not (stored in the pids set).
+ std::set<pid_t> pgids;
+ pgids.emplace(initialPid);
+ std::set<pid_t> pids;
+
int ret;
pid_t pid;
int processes = 0;
@@ -269,8 +277,40 @@
LOG(WARNING) << "Yikes, we've been told to kill pid 0! How about we don't do that?";
continue;
}
+ pid_t pgid = getpgid(pid);
+ if (pgid == -1) PLOG(ERROR) << "getpgid(" << pid << ") failed";
+ if (pgid == pid) {
+ pgids.emplace(pid);
+ } else {
+ pids.emplace(pid);
+ }
+ }
+
+ // Erase all pids that will be killed when we kill the process groups.
+ for (auto it = pids.begin(); it != pids.end();) {
+ pid_t pgid = getpgid(pid);
+ if (pgids.count(pgid) == 1) {
+ it = pids.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ // Kill all process groups.
+ for (const auto pgid : pgids) {
+ LOG(VERBOSE) << "Killing process group " << -pgid << " in uid " << uid
+ << " as part of process cgroup " << initialPid;
+
+ if (kill(-pgid, signal) == -1) {
+ PLOG(WARNING) << "kill(" << -pgid << ", " << signal << ") failed";
+ }
+ }
+
+ // Kill remaining pids.
+ for (const auto pid : pids) {
LOG(VERBOSE) << "Killing pid " << pid << " in uid " << uid << " as part of process cgroup "
<< initialPid;
+
if (kill(pid, signal) == -1) {
PLOG(WARNING) << "kill(" << pid << ", " << signal << ") failed";
}
diff --git a/qemu_pipe/Android.bp b/qemu_pipe/Android.bp
new file mode 100644
index 0000000..93c347b
--- /dev/null
+++ b/qemu_pipe/Android.bp
@@ -0,0 +1,14 @@
+// Copyright 2011 The Android Open Source Project
+
+cc_library_static {
+ name: "libqemu_pipe",
+ vendor_available: true,
+ sanitize: {
+ misc_undefined: ["integer"],
+ },
+ srcs: ["qemu_pipe.cpp"],
+ local_include_dirs: ["include"],
+ static_libs: ["libbase"],
+ export_include_dirs: ["include"],
+ cflags: ["-Werror"],
+}
diff --git a/qemu_pipe/Android.mk b/qemu_pipe/Android.mk
deleted file mode 100644
index 6e0144c..0000000
--- a/qemu_pipe/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2011 The Android Open Source Project
-
-LOCAL_PATH:= $(call my-dir)
-
-common_static_libraries := \
- libbase
-include $(CLEAR_VARS)
-LOCAL_CLANG := true
-LOCAL_SANITIZE := integer
-LOCAL_SRC_FILES:= \
- qemu_pipe.cpp
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/include \
- system/base/include
-LOCAL_MODULE:= libqemu_pipe
-LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_CFLAGS := -Werror
-include $(BUILD_STATIC_LIBRARY)
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 6db9acd..621b632 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -84,7 +84,7 @@
namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data
namespace.rs.links = default,vndk
-namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libui.so:libvndksupport.so
+namespace.rs.link.default.shared_libs = libc.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libvndksupport.so
namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libion.so:libutils.so:libc++.so:libz.so
###############################################################################
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 4f4fc5d..6d35fed 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -3,6 +3,7 @@
required: [
"bzip2",
"grep",
+ "grep_vendor",
"gzip",
"mkshrc",
"mkshrc_vendor",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 1c9fb20..8db8327 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -28,8 +28,8 @@
}
// We build BSD grep separately, so it can provide egrep and fgrep too.
-cc_binary {
- name: "grep",
+cc_defaults {
+ name: "grep_common",
srcs: [
"upstream-netbsd/usr.bin/grep/fastgrep.c",
"upstream-netbsd/usr.bin/grep/file.c",
@@ -40,5 +40,19 @@
cflags: common_cflags,
local_include_dirs: ["upstream-netbsd/include/"],
symlinks: ["egrep", "fgrep"],
+}
+cc_binary {
+ name: "grep",
+ defaults: ["grep_common"],
+}
+
+// Build vendor grep.
+// TODO: Add vendor_available to "grep" module and remove "grep_vendor" module
+// when vendor_available is fully supported.
+cc_binary {
+ name: "grep_vendor",
+ stem: "grep",
+ vendor: true,
+ defaults: ["grep_common"],
}