Merge "Add new caps from kernel 5.8."
diff --git a/adb/Android.bp b/adb/Android.bp
index 87ac54d..8addf95 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -117,6 +117,7 @@
static_libs: [
"libadb_crypto",
"libadb_pairing_connection",
+ "libadb_sysdeps",
"libadb_tls_connection",
"libadbd",
"libadbd_core",
@@ -167,6 +168,7 @@
"services.cpp",
"sockets.cpp",
"socket_spec.cpp",
+ "sysdeps/env.cpp",
"sysdeps/errno.cpp",
"transport.cpp",
"transport_fd.cpp",
@@ -261,6 +263,43 @@
],
}
+cc_library {
+ name: "libadb_sysdeps",
+ defaults: ["adb_defaults"],
+ recovery_available: true,
+ host_supported: true,
+ compile_multilib: "both",
+ min_sdk_version: "apex_inherit",
+
+ srcs: [
+ "sysdeps/env.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ ],
+
+ target: {
+ windows: {
+ enabled: true,
+ ldflags: ["-municode"],
+ },
+ },
+
+ export_include_dirs: ["."],
+
+ visibility: [
+ "//system/core/adb:__subpackages__",
+ "//bootable/recovery/minadbd:__subpackages__",
+ ],
+
+ apex_available: [
+ "com.android.adbd",
+ "test_com.android.adbd",
+ ],
+}
+
cc_test_host {
name: "adb_test",
defaults: ["adb_defaults"],
@@ -274,6 +313,7 @@
"libadb_pairing_auth_static",
"libadb_pairing_connection_static",
"libadb_protos_static",
+ "libadb_sysdeps",
"libadb_tls_connection_static",
"libbase",
"libcutils",
@@ -330,6 +370,7 @@
"libadb_pairing_auth",
"libadb_pairing_connection",
"libadb_protos",
+ "libadb_sysdeps",
"libadb_tls_connection",
"libandroidfw",
"libapp_processes_protos_full",
@@ -831,6 +872,7 @@
"libadb_pairing_auth_static",
"libadb_pairing_connection_static",
"libadb_protos_static",
+ "libadb_sysdeps",
"libadb_tls_connection_static",
"libandroidfw",
"libbase",
diff --git a/adb/crypto/Android.bp b/adb/crypto/Android.bp
index 9d14b03..e2c27f1 100644
--- a/adb/crypto/Android.bp
+++ b/adb/crypto/Android.bp
@@ -48,6 +48,7 @@
shared_libs: [
"libadb_protos",
+ "libadb_sysdeps",
"libbase",
"liblog",
"libcrypto",
@@ -76,5 +77,6 @@
static_libs: [
"libadb_protos_static",
+ "libadb_sysdeps",
],
}
diff --git a/adb/crypto/rsa_2048_key.cpp b/adb/crypto/rsa_2048_key.cpp
index 7911af9..6d9ee30 100644
--- a/adb/crypto/rsa_2048_key.cpp
+++ b/adb/crypto/rsa_2048_key.cpp
@@ -20,32 +20,11 @@
#include <crypto_utils/android_pubkey.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
+#include <sysdeps/env.h>
namespace adb {
namespace crypto {
-namespace {
-std::string get_user_info() {
- std::string hostname;
- if (getenv("HOSTNAME")) hostname = getenv("HOSTNAME");
-#if !defined(_WIN32)
- char buf[64];
- if (hostname.empty() && gethostname(buf, sizeof(buf)) != -1) hostname = buf;
-#endif
- if (hostname.empty()) hostname = "unknown";
-
- std::string username;
- if (getenv("LOGNAME")) username = getenv("LOGNAME");
-#if !defined(_WIN32)
- if (username.empty() && getlogin()) username = getlogin();
-#endif
- if (username.empty()) hostname = "unknown";
-
- return " " + username + "@" + hostname;
-}
-
-} // namespace
-
bool CalculatePublicKey(std::string* out, RSA* private_key) {
uint8_t binary_key_data[ANDROID_PUBKEY_ENCODED_SIZE];
if (!android_pubkey_encode(private_key, binary_key_data, sizeof(binary_key_data))) {
@@ -63,7 +42,10 @@
size_t actual_length = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(out->data()), binary_key_data,
sizeof(binary_key_data));
out->resize(actual_length);
- out->append(get_user_info());
+ out->append(" ");
+ out->append(sysdeps::GetLoginNameUTF8());
+ out->append("@");
+ out->append(sysdeps::GetHostNameUTF8());
return true;
}
diff --git a/adb/crypto/tests/Android.bp b/adb/crypto/tests/Android.bp
index b32dcf7..b041055 100644
--- a/adb/crypto/tests/Android.bp
+++ b/adb/crypto/tests/Android.bp
@@ -35,6 +35,7 @@
static_libs: [
"libadb_crypto_static",
"libadb_protos_static",
+ "libadb_sysdeps",
],
test_suites: ["device-tests"],
diff --git a/adb/sysdeps/env.cpp b/adb/sysdeps/env.cpp
new file mode 100644
index 0000000..4058728
--- /dev/null
+++ b/adb/sysdeps/env.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sysdeps/env.h"
+
+#ifdef _WIN32
+#include <lmcons.h>
+#include <windows.h>
+#endif // _WIN32
+
+#include <android-base/utf8.h>
+
+namespace adb {
+namespace sysdeps {
+
+std::optional<std::string> GetEnvironmentVariable(std::string_view var) {
+ if (var.empty()) {
+ return std::nullopt;
+ }
+
+#ifdef _WIN32
+ constexpr size_t kMaxEnvVarSize = 32767;
+ wchar_t wbuf[kMaxEnvVarSize];
+ std::wstring wvar;
+ if (!android::base::UTF8ToWide(var.data(), &wvar)) {
+ return std::nullopt;
+ }
+
+ auto sz = ::GetEnvironmentVariableW(wvar.data(), wbuf, sizeof(wbuf));
+ if (sz == 0) {
+ return std::nullopt;
+ }
+
+ std::string val;
+ if (!android::base::WideToUTF8(wbuf, &val)) {
+ return std::nullopt;
+ }
+
+ return std::make_optional(val);
+#else // !_WIN32
+ const char* val = getenv(var.data());
+ if (val == nullptr) {
+ return std::nullopt;
+ }
+
+ return std::make_optional(std::string(val));
+#endif
+}
+
+#ifdef _WIN32
+constexpr char kHostNameEnvVar[] = "COMPUTERNAME";
+constexpr char kUserNameEnvVar[] = "USERNAME";
+#else
+constexpr char kHostNameEnvVar[] = "HOSTNAME";
+constexpr char kUserNameEnvVar[] = "LOGNAME";
+#endif
+
+std::string GetHostNameUTF8() {
+ const auto hostName = GetEnvironmentVariable(kHostNameEnvVar);
+ if (hostName && !hostName->empty()) {
+ return *hostName;
+ }
+
+#ifdef _WIN32
+ wchar_t wbuf[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD size = sizeof(wbuf);
+ if (!GetComputerNameW(wbuf, &size) || size == 0) {
+ return "";
+ }
+
+ std::string name;
+ if (!android::base::WideToUTF8(wbuf, &name)) {
+ return "";
+ }
+
+ return name;
+#else // !_WIN32
+ char buf[256];
+ return (gethostname(buf, sizeof(buf)) == -1) ? "" : buf;
+#endif // _WIN32
+}
+
+std::string GetLoginNameUTF8() {
+ const auto userName = GetEnvironmentVariable(kUserNameEnvVar);
+ if (userName && !userName->empty()) {
+ return *userName;
+ }
+
+#ifdef _WIN32
+ wchar_t wbuf[UNLEN + 1];
+ DWORD size = sizeof(wbuf);
+ if (!GetUserNameW(wbuf, &size) || size == 0) {
+ return "";
+ }
+
+ std::string login;
+ if (!android::base::WideToUTF8(wbuf, &login)) {
+ return "";
+ }
+
+ return login;
+#else // !_WIN32
+ const char* login = getlogin();
+ return login ? login : "";
+#endif // _WIN32
+}
+
+} // namespace sysdeps
+} // namespace adb
diff --git a/adb/sysdeps/env.h b/adb/sysdeps/env.h
new file mode 100644
index 0000000..b39b675
--- /dev/null
+++ b/adb/sysdeps/env.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <optional>
+#include <string>
+
+namespace adb {
+namespace sysdeps {
+
+// Attempts to retrieve the environment variable value for |var|. Returns std::nullopt
+// if unset.
+std::optional<std::string> GetEnvironmentVariableUTF8(std::string_view var);
+
+// Gets the host name of the system. Returns empty string on failure.
+std::string GetHostNameUTF8();
+// Gets the current login user. Returns empty string on failure.
+std::string GetLoginNameUTF8();
+
+} // namespace sysdeps
+} // namespace adb
diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp
index be82bc0..217a6b7 100644
--- a/adb/sysdeps_win32.cpp
+++ b/adb/sysdeps_win32.cpp
@@ -1010,55 +1010,6 @@
return _fh_to_int(f);
}
-static bool isBlankStr(const char* str) {
- for (; *str != '\0'; ++str) {
- if (!isblank(*str)) {
- return false;
- }
- }
- return true;
-}
-
-int adb_gethostname(char* name, size_t len) {
- const char* computerName = adb_getenv("COMPUTERNAME");
- if (computerName && !isBlankStr(computerName)) {
- strncpy(name, computerName, len);
- name[len - 1] = '\0';
- return 0;
- }
-
- wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD size = sizeof(buffer);
- if (!GetComputerNameW(buffer, &size)) {
- return -1;
- }
- std::string name_utf8;
- if (!android::base::WideToUTF8(buffer, &name_utf8)) {
- return -1;
- }
-
- strncpy(name, name_utf8.c_str(), len);
- name[len - 1] = '\0';
- return 0;
-}
-
-int adb_getlogin_r(char* buf, size_t bufsize) {
- wchar_t buffer[UNLEN + 1];
- DWORD len = sizeof(buffer);
- if (!GetUserNameW(buffer, &len)) {
- return -1;
- }
-
- std::string login;
- if (!android::base::WideToUTF8(buffer, &login)) {
- return -1;
- }
-
- strncpy(buf, login.c_str(), bufsize);
- buf[bufsize - 1] = '\0';
- return 0;
-}
-
#undef accept
int adb_socket_accept(borrowed_fd serverfd, struct sockaddr* addr, socklen_t* addrlen) {
FH serverfh = _fh_from_int(serverfd, __func__);
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 88bb234..9f22be5 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -301,13 +301,10 @@
return true;
}
-static bool needs_block_encryption(const FstabEntry& entry);
-static bool should_use_metadata_encryption(const FstabEntry& entry);
-
// Read the primary superblock from an ext4 filesystem. On failure return
// false. If it's not an ext4 filesystem, also set FS_STAT_INVALID_MAGIC.
-static bool read_ext4_superblock(const std::string& blk_device, const FstabEntry& entry,
- struct ext4_super_block* sb, int* fs_stat) {
+static bool read_ext4_superblock(const std::string& blk_device, struct ext4_super_block* sb,
+ int* fs_stat) {
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
if (fd < 0) {
@@ -324,29 +321,7 @@
LINFO << "Invalid ext4 superblock on '" << blk_device << "'";
// not a valid fs, tune2fs, fsck, and mount will all fail.
*fs_stat |= FS_STAT_INVALID_MAGIC;
-
- bool encrypted = should_use_metadata_encryption(entry) || needs_block_encryption(entry);
- if (entry.mount_point == "/data" &&
- (!encrypted || android::base::StartsWith(blk_device, "/dev/block/dm-"))) {
- // try backup superblock, if main superblock is corrupted
- for (unsigned int blocksize = EXT4_MIN_BLOCK_SIZE; blocksize <= EXT4_MAX_BLOCK_SIZE;
- blocksize *= 2) {
- uint64_t superblock = blocksize * 8;
- if (blocksize == EXT4_MIN_BLOCK_SIZE) superblock++;
-
- if (TEMP_FAILURE_RETRY(pread(fd, sb, sizeof(*sb), superblock * blocksize)) !=
- sizeof(*sb)) {
- PERROR << "Can't read '" << blk_device << "' superblock";
- return false;
- }
- if (is_ext4_superblock_valid(sb) &&
- (1 << (10 + sb->s_log_block_size) == blocksize)) {
- *fs_stat &= ~FS_STAT_INVALID_MAGIC;
- break;
- }
- }
- }
- if (*fs_stat & FS_STAT_INVALID_MAGIC) return false;
+ return false;
}
*fs_stat |= FS_STAT_IS_EXT4;
LINFO << "superblock s_max_mnt_count:" << sb->s_max_mnt_count << "," << blk_device;
@@ -687,7 +662,7 @@
if (is_extfs(entry.fs_type)) {
struct ext4_super_block sb;
- if (read_ext4_superblock(blk_device, entry, &sb, &fs_stat)) {
+ if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
(sb.s_state & EXT4_VALID_FS) == 0) {
LINFO << "Filesystem on " << blk_device << " was not cleanly shutdown; "
@@ -717,7 +692,7 @@
entry.fs_mgr_flags.fs_verity || entry.fs_mgr_flags.ext_meta_csum)) {
struct ext4_super_block sb;
- if (read_ext4_superblock(blk_device, entry, &sb, &fs_stat)) {
+ if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
tune_reserved_size(blk_device, entry, &sb, &fs_stat);
tune_encrypt(blk_device, entry, &sb, &fs_stat);
tune_verity(blk_device, entry, &sb, &fs_stat);
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index 23d76f4..1736934 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -81,10 +81,17 @@
log_id_t android_logger_get_id(struct logger* logger);
+/* Clears the given log buffer. */
int android_logger_clear(struct logger* logger);
+/* Return the allotted size for the given log buffer. */
long android_logger_get_log_size(struct logger* logger);
+/* Set the allotted size for the given log buffer. */
int android_logger_set_log_size(struct logger* logger, unsigned long size);
+/* Return the actual, uncompressed size that can be read from the given log buffer. */
long android_logger_get_log_readable_size(struct logger* logger);
+/* Return the actual, compressed size that the given log buffer is consuming. */
+long android_logger_get_log_consumed_size(struct logger* logger);
+/* Deprecated. Always returns '4' regardless of input. */
int android_logger_get_log_version(struct logger* logger);
struct logger_list;
diff --git a/liblog/logd_reader.cpp b/liblog/logd_reader.cpp
index 82ed6b2..611caed 100644
--- a/liblog/logd_reader.cpp
+++ b/liblog/logd_reader.cpp
@@ -35,13 +35,14 @@
#include <string>
+#include <android-base/parseint.h>
#include <private/android_logger.h>
#include "logger.h"
// Connects to /dev/socket/<name> and returns the associated fd or returns -1 on error.
// O_CLOEXEC is always set.
-static int socket_local_client(const std::string& name, int type) {
+static int socket_local_client(const std::string& name, int type, bool timeout) {
sockaddr_un addr = {.sun_family = AF_LOCAL};
std::string path = "/dev/socket/" + name;
@@ -55,6 +56,18 @@
return -1;
}
+ if (timeout) {
+ // Sending and receiving messages should be instantaneous, but we don't want to wait forever if
+ // logd is hung, so we set a gracious 2s timeout.
+ struct timeval t = {2, 0};
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t)) == -1) {
+ return -1;
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t)) == -1) {
+ return -1;
+ }
+ }
+
if (connect(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
close(fd);
return -1;
@@ -69,7 +82,7 @@
size_t len;
char* cp;
int errno_save = 0;
- int sock = socket_local_client("logd", SOCK_STREAM);
+ int sock = socket_local_client("logd", SOCK_STREAM, true);
if (sock < 0) {
return sock;
}
@@ -148,26 +161,56 @@
return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
}
-/* returns the total size of the log's ring buffer */
-long android_logger_get_log_size(struct logger* logger) {
+enum class LogSizeType : uint32_t {
+ kAllotted = 0,
+ kReadable,
+ kConsumed,
+};
+
+static long GetLogSize(struct logger* logger, LogSizeType type) {
if (!android_logger_is_logd(logger)) {
return -EINVAL;
}
uint32_t log_id = android_logger_get_id(logger);
char buf[512];
- snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id);
+ switch (type) {
+ case LogSizeType::kAllotted:
+ snprintf(buf, sizeof(buf), "getLogSize %" PRIu32, log_id);
+ break;
+ case LogSizeType::kReadable:
+ snprintf(buf, sizeof(buf), "getLogSizeReadable %" PRIu32, log_id);
+ break;
+ case LogSizeType::kConsumed:
+ snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id);
+ break;
+ default:
+ abort();
+ }
ssize_t ret = SendLogdControlMessage(buf, sizeof(buf));
if (ret < 0) {
return ret;
}
- if ((buf[0] < '0') || ('9' < buf[0])) {
+ long size;
+ if (!android::base::ParseInt(buf, &size)) {
return -1;
}
- return atol(buf);
+ return size;
+}
+
+long android_logger_get_log_size(struct logger* logger) {
+ return GetLogSize(logger, LogSizeType::kAllotted);
+}
+
+long android_logger_get_log_readable_size(struct logger* logger) {
+ return GetLogSize(logger, LogSizeType::kReadable);
+}
+
+long android_logger_get_log_consumed_size(struct logger* logger) {
+ return GetLogSize(logger, LogSizeType::kConsumed);
}
int android_logger_set_log_size(struct logger* logger, unsigned long size) {
@@ -182,31 +225,6 @@
return check_log_success(buf, SendLogdControlMessage(buf, sizeof(buf)));
}
-/*
- * returns the readable size of the log's ring buffer (that is, amount of the
- * log consumed)
- */
-long android_logger_get_log_readable_size(struct logger* logger) {
- if (!android_logger_is_logd(logger)) {
- return -EINVAL;
- }
-
- uint32_t log_id = android_logger_get_id(logger);
- char buf[512];
- snprintf(buf, sizeof(buf), "getLogSizeUsed %" PRIu32, log_id);
-
- ssize_t ret = SendLogdControlMessage(buf, sizeof(buf));
- if (ret < 0) {
- return ret;
- }
-
- if ((buf[0] < '0') || ('9' < buf[0])) {
- return -1;
- }
-
- return atol(buf);
-}
-
int android_logger_get_log_version(struct logger*) {
return 4;
}
@@ -268,7 +286,7 @@
return sock;
}
- sock = socket_local_client("logdr", SOCK_SEQPACKET);
+ sock = socket_local_client("logdr", SOCK_SEQPACKET, false);
if (sock <= 0) {
if ((sock == -1) && errno) {
return -errno;
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index bbdd317..ceabf62 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -336,7 +336,6 @@
}
ParseKernelCmdlineOptions();
- android::base::SetMinimumLogSeverity(android::base::INFO);
}
void Modprobe::EnableBlocklist(bool enable) {
diff --git a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
index 94f5a73..0415ef6 100644
--- a/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
+++ b/libunwindstack/tests/fuzz/UnwinderComponentCreator.cpp
@@ -16,6 +16,11 @@
#include "UnwinderComponentCreator.h"
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
std::unique_ptr<Regs> GetRegisters(ArchEnum arch) {
switch (arch) {
case unwindstack::ARCH_ARM: {
@@ -109,13 +114,28 @@
return elf;
}
+static constexpr size_t kPageSize = 4096;
+
+static constexpr uint64_t AlignToPage(uint64_t address) {
+ return (address + kPageSize - 1) & ~(kPageSize - 1);
+}
+
std::unique_ptr<Maps> GetMaps(FuzzedDataProvider* data_provider) {
std::unique_ptr<Maps> maps = std::make_unique<Maps>();
+ std::map<uint64_t, uint64_t> map_ends;
uint8_t entry_count = data_provider->ConsumeIntegralInRange<uint8_t>(0, kMaxMapEntryCount);
for (uint8_t i = 0; i < entry_count; i++) {
- uint64_t start = data_provider->ConsumeIntegral<uint64_t>();
- uint64_t end = data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX);
- uint64_t offset = data_provider->ConsumeIntegral<uint64_t>();
+ uint64_t start = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
+ uint64_t end = AlignToPage(data_provider->ConsumeIntegralInRange<uint64_t>(start, UINT64_MAX));
+ // Make sure not to add overlapping maps, that is not something that can
+ // happen in the real world.
+ auto entry = map_ends.upper_bound(start);
+ if (entry != map_ends.end() && end > entry->second) {
+ continue;
+ }
+ map_ends[end] = start;
+
+ uint64_t offset = AlignToPage(data_provider->ConsumeIntegral<uint64_t>());
std::string map_info_name = data_provider->ConsumeRandomLengthString(kMaxMapInfoNameLen);
uint8_t flags = PROT_READ | PROT_WRITE;
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index c7d1634..6b7e016 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -64,6 +64,7 @@
using android::base::ParseUint;
using android::base::Split;
using android::base::StringPrintf;
+using android::base::WriteFully;
class Logcat {
public:
@@ -864,8 +865,7 @@
if (consolePipe) {
// need the trailing '\0'
- if (!android::base::WriteFully(fd, pipePurpose.c_str(),
- pipePurpose.size() + 1)) {
+ if (!WriteFully(fd, pipePurpose.c_str(), pipePurpose.size() + 1)) {
close(fd);
return EXIT_FAILURE;
}
@@ -1064,19 +1064,23 @@
if (getLogSize) {
long size = android_logger_get_log_size(logger);
long readable = android_logger_get_log_readable_size(logger);
+ long consumed = android_logger_get_log_consumed_size(logger);
if (size < 0 || readable < 0) {
ReportErrorName(buffer_name, security_buffer_selected, &get_size_failures);
} else {
auto size_format = format_of_size(size);
auto readable_format = format_of_size(readable);
+ auto consumed_format = format_of_size(consumed);
std::string str = android::base::StringPrintf(
- "%s: ring buffer is %lu %sB (%lu %sB consumed),"
+ "%s: ring buffer is %lu %sB (%lu %sB consumed, %lu %sB readable),"
" max entry is %d B, max payload is %d B\n",
- buffer_name, size_format.first, size_format.second, readable_format.first,
- readable_format.second, (int)LOGGER_ENTRY_MAX_LEN,
- (int)LOGGER_ENTRY_MAX_PAYLOAD);
- TEMP_FAILURE_RETRY(write(output_fd_.get(), str.data(), str.length()));
+ buffer_name, size_format.first, size_format.second, consumed_format.first,
+ consumed_format.second, readable_format.first, readable_format.second,
+ (int)LOGGER_ENTRY_MAX_LEN, (int)LOGGER_ENTRY_MAX_PAYLOAD);
+ if (!WriteFully(output_fd_, str.data(), str.length())) {
+ error(EXIT_FAILURE, errno, "Failed to write to output fd");
+ }
}
}
}
@@ -1146,7 +1150,9 @@
if (*cp == '\n') ++cp;
size_t len = strlen(cp);
- TEMP_FAILURE_RETRY(write(output_fd_.get(), cp, len));
+ if (!WriteFully(output_fd_, cp, len)) {
+ error(EXIT_FAILURE, errno, "Failed to write to output fd");
+ }
return EXIT_SUCCESS;
}
@@ -1190,7 +1196,9 @@
PrintDividers(log_msg.id(), printDividers);
if (print_binary_) {
- TEMP_FAILURE_RETRY(write(output_fd_.get(), &log_msg, log_msg.len()));
+ if (!WriteFully(output_fd_, &log_msg, log_msg.len())) {
+ error(EXIT_FAILURE, errno, "Failed to write to output fd");
+ }
} else {
ProcessBuffer(&log_msg);
}
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 2eeb0d9..6381ffa 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -46,6 +46,7 @@
registerCmd(new ClearCmd(this));
registerCmd(new GetBufSizeCmd(this));
registerCmd(new SetBufSizeCmd(this));
+ registerCmd(new GetBufSizeReadableCmd(this));
registerCmd(new GetBufSizeUsedCmd(this));
registerCmd(new GetStatisticsCmd(this));
registerCmd(new SetPruneListCmd(this));
@@ -136,6 +137,26 @@
return 0;
}
+int CommandListener::GetBufSizeReadableCmd::runCommand(SocketClient* cli, int argc, char** argv) {
+ setname();
+ if (argc < 2) {
+ cli->sendMsg("Missing Argument");
+ return 0;
+ }
+
+ int id = atoi(argv[1]);
+ if (id < LOG_ID_MIN || LOG_ID_MAX <= id) {
+ cli->sendMsg("Range Error");
+ return 0;
+ }
+
+ unsigned long size = stats()->SizeReadable((log_id_t)id);
+ char buf[512];
+ snprintf(buf, sizeof(buf), "%lu", size);
+ cli->sendMsg(buf);
+ return 0;
+}
+
int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc,
char** argv) {
setname();
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
index c3080ab..8e12634 100644
--- a/logd/CommandListener.h
+++ b/logd/CommandListener.h
@@ -57,6 +57,7 @@
LogCmd(Clear, clear);
LogCmd(GetBufSize, getLogSize);
LogCmd(SetBufSize, setLogSize);
+ LogCmd(GetBufSizeReadable, getLogSizeReadable);
LogCmd(GetBufSizeUsed, getLogSizeUsed);
LogCmd(GetStatistics, getStatistics);
LogCmd(GetPruneList, getPruneList);
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index e222d3f..faf9283 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -544,7 +544,7 @@
bool ShouldPrune(log_id id, unsigned long max_size, unsigned long* prune_rows) const
EXCLUDES(lock_);
- // Snapshot of the sizes for a given log buffer.
+ // Return the consumed size of the given buffer.
size_t Sizes(log_id_t id) const EXCLUDES(lock_) {
auto lock = std::lock_guard{lock_};
if (overhead_[id]) {
@@ -552,6 +552,13 @@
}
return mSizes[id];
}
+
+ // Return the uncompressed size of the contents of the given buffer.
+ size_t SizeReadable(log_id_t id) const EXCLUDES(lock_) {
+ auto lock = std::lock_guard{lock_};
+ return mSizes[id];
+ }
+
// TODO: Get rid of this entirely.
static size_t sizesTotal() {
return SizesTotal;