Merge "Tweak linux_glibc properties for musl builds in system/core"
diff --git a/fastboot/device/flashing.cpp b/fastboot/device/flashing.cpp
index 22f8363..06ffe0f 100644
--- a/fastboot/device/flashing.cpp
+++ b/fastboot/device/flashing.cpp
@@ -76,7 +76,7 @@
} // namespace
-int FlashRawDataChunk(int fd, const char* data, size_t len) {
+int FlashRawDataChunk(PartitionHandle* handle, const char* data, size_t len) {
size_t ret = 0;
const size_t max_write_size = 1048576;
void* aligned_buffer;
@@ -91,7 +91,15 @@
while (ret < len) {
int this_len = std::min(max_write_size, len - ret);
memcpy(aligned_buffer_unique_ptr.get(), data, this_len);
- int this_ret = write(fd, aligned_buffer_unique_ptr.get(), this_len);
+ // In case of non 4KB aligned writes, reopen without O_DIRECT flag
+ if (this_len & 0xFFF) {
+ if (handle->Reset(O_WRONLY) != true) {
+ PLOG(ERROR) << "Failed to reset file descriptor";
+ return -1;
+ }
+ }
+
+ int this_ret = write(handle->fd(), aligned_buffer_unique_ptr.get(), this_len);
if (this_ret < 0) {
PLOG(ERROR) << "Failed to flash data of len " << len;
return -1;
@@ -102,8 +110,8 @@
return 0;
}
-int FlashRawData(int fd, const std::vector<char>& downloaded_data) {
- int ret = FlashRawDataChunk(fd, downloaded_data.data(), downloaded_data.size());
+int FlashRawData(PartitionHandle* handle, const std::vector<char>& downloaded_data) {
+ int ret = FlashRawDataChunk(handle, downloaded_data.data(), downloaded_data.size());
if (ret < 0) {
return -errno;
}
@@ -111,30 +119,30 @@
}
int WriteCallback(void* priv, const void* data, size_t len) {
- int fd = reinterpret_cast<long long>(priv);
+ PartitionHandle* handle = reinterpret_cast<PartitionHandle*>(priv);
if (!data) {
- return lseek64(fd, len, SEEK_CUR) >= 0 ? 0 : -errno;
+ return lseek64(handle->fd(), len, SEEK_CUR) >= 0 ? 0 : -errno;
}
- return FlashRawDataChunk(fd, reinterpret_cast<const char*>(data), len);
+ return FlashRawDataChunk(handle, reinterpret_cast<const char*>(data), len);
}
-int FlashSparseData(int fd, std::vector<char>& downloaded_data) {
+int FlashSparseData(PartitionHandle* handle, std::vector<char>& downloaded_data) {
struct sparse_file* file = sparse_file_import_buf(downloaded_data.data(),
downloaded_data.size(), true, false);
if (!file) {
// Invalid sparse format
return -EINVAL;
}
- return sparse_file_callback(file, false, false, WriteCallback, reinterpret_cast<void*>(fd));
+ return sparse_file_callback(file, false, false, WriteCallback, reinterpret_cast<void*>(handle));
}
-int FlashBlockDevice(int fd, std::vector<char>& downloaded_data) {
- lseek64(fd, 0, SEEK_SET);
+int FlashBlockDevice(PartitionHandle* handle, std::vector<char>& downloaded_data) {
+ lseek64(handle->fd(), 0, SEEK_SET);
if (downloaded_data.size() >= sizeof(SPARSE_HEADER_MAGIC) &&
*reinterpret_cast<uint32_t*>(downloaded_data.data()) == SPARSE_HEADER_MAGIC) {
- return FlashSparseData(fd, downloaded_data);
+ return FlashSparseData(handle, downloaded_data);
} else {
- return FlashRawData(fd, downloaded_data);
+ return FlashRawData(handle, downloaded_data);
}
}
@@ -181,7 +189,7 @@
if (android::base::GetProperty("ro.system.build.type", "") != "user") {
WipeOverlayfsForPartition(device, partition_name);
}
- int result = FlashBlockDevice(handle.fd(), data);
+ int result = FlashBlockDevice(&handle, data);
sync();
return result;
}
diff --git a/fastboot/device/utility.cpp b/fastboot/device/utility.cpp
index 97b5ad4..3302c43 100644
--- a/fastboot/device/utility.cpp
+++ b/fastboot/device/utility.cpp
@@ -90,14 +90,7 @@
return false;
}
- flags |= (O_EXCL | O_CLOEXEC | O_BINARY);
- unique_fd fd(TEMP_FAILURE_RETRY(open(handle->path().c_str(), flags)));
- if (fd < 0) {
- PLOG(ERROR) << "Failed to open block device: " << handle->path();
- return false;
- }
- handle->set_fd(std::move(fd));
- return true;
+ return handle->Open(flags);
}
std::optional<std::string> FindPhysicalPartition(const std::string& name) {
diff --git a/fastboot/device/utility.h b/fastboot/device/utility.h
index 1d81b7a..6e1453f 100644
--- a/fastboot/device/utility.h
+++ b/fastboot/device/utility.h
@@ -18,6 +18,8 @@
#include <optional>
#include <string>
+#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <fstab/fstab.h>
@@ -44,11 +46,51 @@
}
const std::string& path() const { return path_; }
int fd() const { return fd_.get(); }
- void set_fd(android::base::unique_fd&& fd) { fd_ = std::move(fd); }
+ bool Open(int flags) {
+ flags |= (O_EXCL | O_CLOEXEC | O_BINARY);
+ // Attempts to open a second device can fail with EBUSY if the device is already open.
+ // Explicitly close any previously opened devices as unique_fd won't close them until
+ // after the attempt to open.
+ fd_.reset();
+
+ fd_ = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path_.c_str(), flags)));
+ if (fd_ < 0) {
+ PLOG(ERROR) << "Failed to open block device: " << path_;
+ return false;
+ }
+ flags_ = flags;
+
+ return true;
+ }
+ bool Reset(int flags) {
+ if (fd_.ok() && (flags | O_EXCL | O_CLOEXEC | O_BINARY) == flags_) {
+ return true;
+ }
+
+ off_t offset = fd_.ok() ? lseek(fd_.get(), 0, SEEK_CUR) : 0;
+ if (offset < 0) {
+ PLOG(ERROR) << "Failed lseek on block device: " << path_;
+ return false;
+ }
+
+ sync();
+
+ if (Open(flags) == false) {
+ return false;
+ }
+
+ if (lseek(fd_.get(), offset, SEEK_SET) != offset) {
+ PLOG(ERROR) << "Failed lseek on block device: " << path_;
+ return false;
+ }
+
+ return true;
+ }
private:
std::string path_;
android::base::unique_fd fd_;
+ int flags_;
std::function<void()> closer_;
};
diff --git a/init/Android.bp b/init/Android.bp
index c39d163..dd67d04 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -532,8 +532,8 @@
cmd: "$(location host_builtin_map.py) --builtins $(location builtins.cpp) --check_builtins $(location check_builtins.cpp) > $(out)",
}
-cc_binary {
- name: "host_init_verifier",
+cc_defaults {
+ name: "init_host_defaults",
host_supported: true,
cflags: [
"-Wall",
@@ -556,7 +556,6 @@
"libprocessgroup",
"libprotobuf-cpp-lite",
],
- srcs: init_common_sources + init_host_sources,
proto: {
type: "lite",
},
@@ -574,6 +573,26 @@
},
}
+cc_binary {
+ name: "host_init_verifier",
+ defaults: ["init_host_defaults"],
+ srcs: init_common_sources + init_host_sources,
+}
+
+cc_library_host_static {
+ name: "libinit_host",
+ defaults: ["init_host_defaults"],
+ srcs: init_common_sources,
+ export_include_dirs: ["."],
+ proto: {
+ export_proto_headers: true,
+ },
+ visibility: [
+ // host_apex_verifier performs a subset of init.rc validation
+ "//system/apex/tools",
+ ],
+}
+
sh_binary {
name: "extra_free_kbytes.sh",
src: "extra_free_kbytes.sh",
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 0eb894b..01db4f5 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1306,58 +1306,11 @@
}
globfree(&glob_result);
- // Compare all files /apex/path.#rc and /apex/path.rc with the same "/apex/path" prefix,
- // choosing the one with the highest # that doesn't exceed the system's SDK.
- // (.rc == .0rc for ranking purposes)
- //
int active_sdk = android::base::GetIntProperty("ro.build.version.sdk", INT_MAX);
- std::map<std::string, std::pair<std::string, int>> script_map;
-
- for (const auto& c : configs) {
- int sdk = 0;
- const std::vector<std::string> parts = android::base::Split(c, ".");
- std::string base;
- if (parts.size() < 2) {
- continue;
- }
-
- // parts[size()-1], aka the suffix, should be "rc" or "#rc"
- // any other pattern gets discarded
-
- const auto& suffix = parts[parts.size() - 1];
- if (suffix == "rc") {
- sdk = 0;
- } else {
- char trailer[9] = {0};
- int r = sscanf(suffix.c_str(), "%d%8s", &sdk, trailer);
- if (r != 2) {
- continue;
- }
- if (strlen(trailer) > 2 || strcmp(trailer, "rc") != 0) {
- continue;
- }
- }
-
- if (sdk < 0 || sdk > active_sdk) {
- continue;
- }
-
- base = parts[0];
- for (unsigned int i = 1; i < parts.size() - 1; i++) {
- base = base + "." + parts[i];
- }
-
- // is this preferred over what we already have
- auto it = script_map.find(base);
- if (it == script_map.end() || it->second.second < sdk) {
- script_map[base] = std::make_pair(c, sdk);
- }
- }
-
bool success = true;
- for (const auto& m : script_map) {
- success &= parser.ParseConfigFile(m.second.first);
+ for (const auto& c : parser.FilterVersionedConfigs(configs, active_sdk)) {
+ success &= parser.ParseConfigFile(c);
}
ServiceList::GetInstance().MarkServicesUpdate();
if (success) {
diff --git a/init/parser.cpp b/init/parser.cpp
index 5c18551..abc2017 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -18,6 +18,8 @@
#include <dirent.h>
+#include <map>
+
#include <android-base/chrono_utils.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@@ -154,6 +156,58 @@
return true;
}
+std::vector<std::string> Parser::FilterVersionedConfigs(const std::vector<std::string>& configs,
+ int active_sdk) {
+ std::vector<std::string> filtered_configs;
+
+ std::map<std::string, std::pair<std::string, int>> script_map;
+ for (const auto& c : configs) {
+ int sdk = 0;
+ const std::vector<std::string> parts = android::base::Split(c, ".");
+ std::string base;
+ if (parts.size() < 2) {
+ continue;
+ }
+
+ // parts[size()-1], aka the suffix, should be "rc" or "#rc"
+ // any other pattern gets discarded
+
+ const auto& suffix = parts[parts.size() - 1];
+ if (suffix == "rc") {
+ sdk = 0;
+ } else {
+ char trailer[9] = {0};
+ int r = sscanf(suffix.c_str(), "%d%8s", &sdk, trailer);
+ if (r != 2) {
+ continue;
+ }
+ if (strlen(trailer) > 2 || strcmp(trailer, "rc") != 0) {
+ continue;
+ }
+ }
+
+ if (sdk < 0 || sdk > active_sdk) {
+ continue;
+ }
+
+ base = parts[0];
+ for (unsigned int i = 1; i < parts.size() - 1; i++) {
+ base = base + "." + parts[i];
+ }
+
+ // is this preferred over what we already have
+ auto it = script_map.find(base);
+ if (it == script_map.end() || it->second.second < sdk) {
+ script_map[base] = std::make_pair(c, sdk);
+ }
+ }
+
+ for (const auto& m : script_map) {
+ filtered_configs.push_back(m.second.first);
+ }
+ return filtered_configs;
+}
+
bool Parser::ParseConfigDir(const std::string& path) {
LOG(INFO) << "Parsing directory " << path << "...";
std::unique_ptr<DIR, decltype(&closedir)> config_dir(opendir(path.c_str()), closedir);
diff --git a/init/parser.h b/init/parser.h
index 95b0cd7..2f4108f 100644
--- a/init/parser.h
+++ b/init/parser.h
@@ -76,6 +76,12 @@
void AddSectionParser(const std::string& name, std::unique_ptr<SectionParser> parser);
void AddSingleLineParser(const std::string& prefix, LineCallback callback);
+ // Compare all files */path.#rc and */path.rc with the same path prefix.
+ // Keep the one with the highest # that doesn't exceed the system's SDK.
+ // (.rc == .0rc for ranking purposes)
+ std::vector<std::string> FilterVersionedConfigs(const std::vector<std::string>& configs,
+ int active_sdk);
+
// Host init verifier check file permissions.
bool ParseConfigFileInsecure(const std::string& path);
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index 17a0070..98ae0d4 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -209,6 +209,37 @@
}
/**
+ * Trace the beginning of an asynchronous event. In addition to the name and a
+ * cookie as in ATRACE_ASYNC_BEGIN/ATRACE_ASYNC_END, a track name argument is
+ * provided, which is the name of the row where this async event should be
+ * recorded. The track name, name, and cookie used to begin an event must be
+ * used to end it.
+ */
+#define ATRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie) \
+ atrace_async_for_track_begin(ATRACE_TAG, track_name, name, cookie)
+static inline void atrace_async_for_track_begin(uint64_t tag, const char* track_name,
+ const char* name, int32_t cookie) {
+ if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
+ void atrace_async_for_track_begin_body(const char*, const char*, int32_t);
+ atrace_async_for_track_begin_body(track_name, name, cookie);
+ }
+}
+
+/**
+ * Trace the end of an asynchronous event.
+ * This should correspond to a previous ATRACE_ASYNC_FOR_TRACK_BEGIN.
+ */
+#define ATRACE_ASYNC_FOR_TRACK_END(track_name, name, cookie) \
+ atrace_async_for_track_end(ATRACE_TAG, track_name, name, cookie)
+static inline void atrace_async_for_track_end(uint64_t tag, const char* track_name,
+ const char* name, int32_t cookie) {
+ if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
+ void atrace_async_for_track_end_body(const char*, const char*, int32_t);
+ atrace_async_for_track_end_body(track_name, name, cookie);
+ }
+}
+
+/**
* Trace an instantaneous context. name is used to identify the context.
*
* An "instant" is an event with no defined duration. Visually is displayed like a single marker
@@ -227,17 +258,18 @@
/**
* Trace an instantaneous context. name is used to identify the context.
- * trackName is the name of the row where the event should be recorded.
+ * track_name is the name of the row where the event should be recorded.
*
* An "instant" is an event with no defined duration. Visually is displayed like a single marker
* in the timeline (rather than a span, in the case of begin/end events).
*/
#define ATRACE_INSTANT_FOR_TRACK(trackName, name) \
atrace_instant_for_track(ATRACE_TAG, trackName, name)
-static inline void atrace_instant_for_track(uint64_t tag, const char* trackName, const char* name) {
+static inline void atrace_instant_for_track(uint64_t tag, const char* track_name,
+ const char* name) {
if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
void atrace_instant_for_track_body(const char*, const char*);
- atrace_instant_for_track_body(trackName, name);
+ atrace_instant_for_track_body(track_name, name);
}
}
diff --git a/libcutils/trace-container.cpp b/libcutils/trace-container.cpp
index f3fdda4..8901e4a 100644
--- a/libcutils/trace-container.cpp
+++ b/libcutils/trace-container.cpp
@@ -229,6 +229,28 @@
WRITE_MSG("F|%d|", "|%" PRId32, "", name, cookie);
}
+void atrace_async_for_track_begin_body(const char* track_name, const char* name, int32_t cookie) {
+ if (CC_LIKELY(atrace_use_container_sock)) {
+ WRITE_MSG_IN_CONTAINER("T", "|", "|%d", track_name, name, cookie);
+ return;
+ }
+
+ if (atrace_marker_fd < 0) return;
+
+ WRITE_MSG("T|%d|", "|%" PRId32, track_name, name, cookie);
+}
+
+void atrace_async_for_track_end_body(const char* track_name, const char* name, int32_t cookie) {
+ if (CC_LIKELY(atrace_use_container_sock)) {
+ WRITE_MSG_IN_CONTAINER("U", "|", "|%d", track_name, name, cookie);
+ return;
+ }
+
+ if (atrace_marker_fd < 0) return;
+
+ WRITE_MSG("U|%d|", "|%" PRId32, track_name, name, cookie);
+}
+
void atrace_instant_body(const char* name) {
if (CC_LIKELY(atrace_use_container_sock)) {
WRITE_MSG_IN_CONTAINER("I", "|", "%s", "", name, "");
diff --git a/libcutils/trace-dev.cpp b/libcutils/trace-dev.cpp
index 8bdeac5..eacc8ee 100644
--- a/libcutils/trace-dev.cpp
+++ b/libcutils/trace-dev.cpp
@@ -89,6 +89,14 @@
WRITE_MSG("F|%d|", "|%" PRId32, "", name, cookie);
}
+void atrace_async_for_track_begin_body(const char* track_name, const char* name, int32_t cookie) {
+ WRITE_MSG("T|%d|", "|%" PRId32, track_name, name, cookie);
+}
+
+void atrace_async_for_track_end_body(const char* track_name, const char* name, int32_t cookie) {
+ WRITE_MSG("U|%d|", "|%" PRId32, track_name, name, cookie);
+}
+
void atrace_instant_body(const char* name) {
WRITE_MSG("I|%d|", "%s", "", name, "");
}
diff --git a/libcutils/trace-dev_test.cpp b/libcutils/trace-dev_test.cpp
index 29a5590..841674a 100644
--- a/libcutils/trace-dev_test.cpp
+++ b/libcutils/trace-dev_test.cpp
@@ -195,6 +195,226 @@
ASSERT_STREQ(expected.c_str(), actual.c_str());
}
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_normal) {
+ atrace_async_for_track_begin_body("fake_track", "fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("T|%d|fake_track|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_exact_track_name) {
+ const int name_size = 5;
+ std::string expected = android::base::StringPrintf("T|%d|", getpid());
+ std::string track_name =
+ MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - name_size - 6);
+ atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += track_name + "|name|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify name truncation
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ track_name += '*';
+ expected = android::base::StringPrintf("T|%d|", getpid());
+ expected += track_name + "|nam|12345";
+ atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_track_name) {
+ std::string expected = android::base::StringPrintf("T|%d|", getpid());
+ std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 9;
+ expected += android::base::StringPrintf("%.*s|n|12345", expected_len, track_name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_exact_name) {
+ const int track_name_size = 11;
+ std::string expected = android::base::StringPrintf("T|%d|", getpid());
+ std::string name =
+ MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - track_name_size - 6);
+ atrace_async_for_track_begin_body("track_name", name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += "track_name|" + name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_for_track_begin_body("track_name", name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_name) {
+ std::string expected = android::base::StringPrintf("T|%d|track_name|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_begin_body("track_name", name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1 - 6;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_both) {
+ std::string expected = android::base::StringPrintf("T|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_begin_body(track_name.c_str(), name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 3 - 6;
+ expected += android::base::StringPrintf("%.*s|%.1s|12345", expected_len, track_name.c_str(),
+ name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_normal) {
+ atrace_async_for_track_end_body("fake_track", "fake_name", 12345);
+
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ std::string expected = android::base::StringPrintf("U|%d|fake_track|fake_name|12345", getpid());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_exact_track_name) {
+ const int name_size = 5;
+ std::string expected = android::base::StringPrintf("U|%d|", getpid());
+ std::string track_name =
+ MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - name_size - 6);
+ atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += track_name + "|name|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify name truncation
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ track_name += '*';
+ expected = android::base::StringPrintf("U|%d|", getpid());
+ expected += track_name + "|nam|12345";
+ atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_track_name) {
+ std::string expected = android::base::StringPrintf("U|%d|", getpid());
+ std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 9;
+ expected += android::base::StringPrintf("%.*s|n|12345", expected_len, track_name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_exact_name) {
+ const int track_name_size = 11;
+ std::string expected = android::base::StringPrintf("U|%d|", getpid());
+ std::string name =
+ MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - track_name_size - 6);
+ atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ expected += "track_name|" + name + "|12345";
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+ // Add a single character and verify we get the same value as before.
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ name += '*';
+ atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
+ EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_name) {
+ std::string expected = android::base::StringPrintf("U|%d|track_name|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1 - 6;
+ expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_both) {
+ std::string expected = android::base::StringPrintf("U|%d|", getpid());
+ std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+ atrace_async_for_track_end_body(track_name.c_str(), name.c_str(), 12345);
+
+ ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
+ ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+
+ std::string actual;
+ ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
+ int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 3 - 6;
+ expected += android::base::StringPrintf("%.*s|%.1s|12345", expected_len, track_name.c_str(),
+ name.c_str());
+ ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
TEST_F(TraceDevTest, atrace_instant_body_normal) {
atrace_instant_body("fake_name");
diff --git a/libcutils/trace-host.cpp b/libcutils/trace-host.cpp
index b01a0ec..c2a379b 100644
--- a/libcutils/trace-host.cpp
+++ b/libcutils/trace-host.cpp
@@ -28,9 +28,12 @@
void atrace_end_body() { }
void atrace_async_begin_body(const char* /*name*/, int32_t /*cookie*/) {}
void atrace_async_end_body(const char* /*name*/, int32_t /*cookie*/) {}
+void atrace_async_for_track_begin_body(const char* /*track_name*/, const char* /*name*/,
+ int32_t /*cookie*/) {}
+void atrace_async_for_track_end_body(const char* /*track_name*/, const char* /*name*/,
+ int32_t /*cookie*/) {}
void atrace_instant_body(const char* /*name*/) {}
-void atrace_instant_for_track_body(const char* /*trackName*/,
- const char* /*name*/) {}
+void atrace_instant_for_track_body(const char* /*track_name*/, const char* /*name*/) {}
void atrace_int_body(const char* /*name*/, int32_t /*value*/) {}
void atrace_int64_body(const char* /*name*/, int64_t /*value*/) {}
void atrace_init() {}
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index b0fcb5f..e910680 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -460,19 +460,17 @@
struct stat cgroup_stat;
mode_t cgroup_mode = 0750;
- uid_t cgroup_uid = AID_SYSTEM;
gid_t cgroup_gid = AID_SYSTEM;
int ret = 0;
- if (stat(cgroup.c_str(), &cgroup_stat) == 1) {
+ if (stat(cgroup.c_str(), &cgroup_stat) < 0) {
PLOG(ERROR) << "Failed to get stats for " << cgroup;
} else {
cgroup_mode = cgroup_stat.st_mode;
- cgroup_uid = cgroup_stat.st_uid;
cgroup_gid = cgroup_stat.st_gid;
}
- if (!MkdirAndChown(uid_path, cgroup_mode, cgroup_uid, cgroup_gid)) {
+ if (!MkdirAndChown(uid_path, cgroup_mode, uid, cgroup_gid)) {
PLOG(ERROR) << "Failed to make and chown " << uid_path;
return -errno;
}
@@ -486,7 +484,7 @@
auto uid_pid_path = ConvertUidPidToPath(cgroup.c_str(), uid, initialPid);
- if (!MkdirAndChown(uid_pid_path, cgroup_mode, cgroup_uid, cgroup_gid)) {
+ if (!MkdirAndChown(uid_pid_path, cgroup_mode, uid, cgroup_gid)) {
PLOG(ERROR) << "Failed to make and chown " << uid_pid_path;
return -errno;
}
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 3e4393d..23d76ee 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -1,13 +1,6 @@
{
"Cgroups": [
{
- "Controller": "blkio",
- "Path": "/dev/blkio",
- "Mode": "0775",
- "UID": "system",
- "GID": "system"
- },
- {
"Controller": "cpu",
"Path": "/dev/cpuctl",
"Mode": "0755",
@@ -39,6 +32,11 @@
{
"Controller": "freezer",
"Path": "."
+ },
+ {
+ "Controller": "io",
+ "Path": ".",
+ "NeedsActivation": true
}
]
}
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 7e03964..e73de79 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -76,6 +76,24 @@
"Name": "FreezerState",
"Controller": "freezer",
"File": "cgroup.freeze"
+ },
+ {
+ "Name": "BfqWeight",
+ "Controller": "io",
+ "File": "blkio.bfq.weight",
+ "FileV2": "io.bfq.weight"
+ },
+ {
+ "Name": "CfqGroupIdle",
+ "Controller": "io",
+ "File": "blkio.group_idle",
+ "FileV2": "io.group_idle"
+ },
+ {
+ "Name": "CfqWeight",
+ "Controller": "io",
+ "File": "blkio.weight",
+ "FileV2": "io.weight"
}
],
@@ -440,11 +458,30 @@
"Name": "LowIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": "background"
+ "Name": "BfqWeight",
+ "Value": "10",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "200",
+ "Optional": "true"
}
}
]
@@ -453,11 +490,30 @@
"Name": "NormalIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
@@ -466,11 +522,30 @@
"Name": "HighIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
@@ -479,11 +554,30 @@
"Name": "MaxIoPriority",
"Actions": [
{
- "Name": "JoinCgroup",
+ "Name": "SetAttribute",
"Params":
{
- "Controller": "blkio",
- "Path": ""
+ "Name": "BfqWeight",
+ "Value": "100",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqGroupIdle",
+ "Value": "0",
+ "Optional": "true"
+ }
+ },
+ {
+ "Name": "SetAttribute",
+ "Params":
+ {
+ "Name": "CfqWeight",
+ "Value": "1000",
+ "Optional": "true"
}
}
]
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 992cc2e..3831ef2 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -147,12 +147,17 @@
static void MergeCgroupToDescriptors(std::map<std::string, CgroupDescriptor>* descriptors,
const Json::Value& cgroup, const std::string& name,
const std::string& root_path, int cgroups_version) {
+ const std::string cgroup_path = cgroup["Path"].asString();
std::string path;
if (!root_path.empty()) {
- path = root_path + "/" + cgroup["Path"].asString();
+ path = root_path;
+ if (cgroup_path != ".") {
+ path += "/";
+ path += cgroup_path;
+ }
} else {
- path = cgroup["Path"].asString();
+ path = cgroup_path;
}
uint32_t controller_flags = 0;
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 78a316a..7a04100 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -207,7 +207,7 @@
}
if (!WriteStringToFile(value_, path)) {
- if (errno == ENOENT) {
+ if (access(path.c_str(), F_OK) < 0) {
if (optional_) {
return true;
} else {
diff --git a/libsystem/include/system/graphics.h b/libsystem/include/system/graphics.h
index 1b6060a..a3c23b2 100644
--- a/libsystem/include/system/graphics.h
+++ b/libsystem/include/system/graphics.h
@@ -59,12 +59,14 @@
/*
* Structure for describing YCbCr formats for consumption by applications.
- * This is used with HAL_PIXEL_FORMAT_YCbCr_*_888.
+ * This is used with HAL_PIXEL_FORMAT_YCbCr_*.
*
* Buffer chroma subsampling is defined in the format.
* e.g. HAL_PIXEL_FORMAT_YCbCr_420_888 has subsampling 4:2:0.
*
- * Buffers must have a 8 bit depth.
+ * Buffers must have a byte aligned channel depth or a byte aligned packed
+ * channel depth (e.g. 10 bits packed into 16 bits for
+ * HAL_PIXEL_FORMAT_YCbCr_P010).
*
* y, cb, and cr point to the first byte of their respective planes.
*
@@ -75,8 +77,8 @@
* cstride is the stride of the chroma planes.
*
* chroma_step is the distance in bytes from one chroma pixel value to the
- * next. This is 2 bytes for semiplanar (because chroma values are interleaved
- * and each chroma value is one byte) and 1 for planar.
+ * next. This is `2 * channel depth` bytes for semiplanar (because chroma
+ * values are interleaved) and `1 * channel depth` bytes for planar.
*/
struct android_ycbcr {
diff --git a/libutils/String8.cpp b/libutils/String8.cpp
index 419b2de..3690389 100644
--- a/libutils/String8.cpp
+++ b/libutils/String8.cpp
@@ -313,7 +313,7 @@
if (n > 0) {
size_t oldLength = length();
- if (n > std::numeric_limits<size_t>::max() - 1 ||
+ if (static_cast<size_t>(n) > std::numeric_limits<size_t>::max() - 1 ||
oldLength > std::numeric_limits<size_t>::max() - n - 1) {
return NO_MEMORY;
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 7ad1c3c..1bb7ac3 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -243,26 +243,6 @@
write /dev/stune/nnapi-hal/schedtune.boost 1
write /dev/stune/nnapi-hal/schedtune.prefer_idle 1
- # Create blkio group and apply initial settings.
- # This feature needs kernel to support it, and the
- # device's init.rc must actually set the correct values.
- mkdir /dev/blkio/background
- chown system system /dev/blkio
- chown system system /dev/blkio/background
- chown system system /dev/blkio/tasks
- chown system system /dev/blkio/background/tasks
- chown system system /dev/blkio/cgroup.procs
- chown system system /dev/blkio/background/cgroup.procs
- chmod 0664 /dev/blkio/tasks
- chmod 0664 /dev/blkio/background/tasks
- chmod 0664 /dev/blkio/cgroup.procs
- chmod 0664 /dev/blkio/background/cgroup.procs
- write /dev/blkio/blkio.weight 1000
- write /dev/blkio/background/blkio.weight 200
- write /dev/blkio/background/blkio.bfq.weight 10
- write /dev/blkio/blkio.group_idle 0
- write /dev/blkio/background/blkio.group_idle 0
-
restorecon_recursive /mnt
mount configfs none /config nodev noexec nosuid