diff --git a/liblog/Android.bp b/liblog/Android.bp index 3a9196977..6051ac7fa 100644 --- a/liblog/Android.bp +++ b/liblog/Android.bp @@ -17,7 +17,6 @@ liblog_sources = [ "log_event_list.cpp", "log_event_write.cpp", - "log_size.cpp", "logger_name.cpp", "logger_read.cpp", "logger_write.cpp", diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h index de4c430e3..166f387c7 100644 --- a/liblog/include/private/android_logger.h +++ b/liblog/include/private/android_logger.h @@ -144,13 +144,6 @@ int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len); int __android_log_security_bswrite(int32_t tag, const char* payload); int __android_log_security(); /* Device Owner is present */ -#define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform \ - */ -#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) -#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) -unsigned long __android_logger_get_buffer_size(log_id_t logId); -bool __android_logger_valid_buffer_size(unsigned long value); - /* Retrieve the composed event buffer */ int android_log_write_list_buffer(android_log_context ctx, const char** msg); diff --git a/liblog/liblog.map.txt b/liblog/liblog.map.txt index 2e0110171..8beb679c3 100644 --- a/liblog/liblog.map.txt +++ b/liblog/liblog.map.txt @@ -84,7 +84,6 @@ LIBLOG_PRIVATE { global: __android_log_pmsg_file_read; __android_log_pmsg_file_write; - __android_logger_get_buffer_size; android_openEventTagMap; android_log_processBinaryLogBuffer; android_log_processLogBuffer; diff --git a/liblog/log_size.cpp b/liblog/log_size.cpp deleted file mode 100644 index 7f13c8c2b..000000000 --- a/liblog/log_size.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 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 - -#include -#include -#include - -#include - -#ifdef __ANDROID__ -#include -#endif - -bool __android_logger_valid_buffer_size(unsigned long value) { - return LOG_BUFFER_MIN_SIZE <= value && value <= LOG_BUFFER_MAX_SIZE; -} - -#ifdef __ANDROID__ - -static std::optional GetBufferSizeProperty(const std::string& key) { - char value[PROP_VALUE_MAX] = {}; - if (__system_property_get(key.c_str(), value) <= 0) { - return {}; - } - - uint32_t size; - if (!android::base::ParseByteCount(value, &size)) { - return {}; - } - - if (!__android_logger_valid_buffer_size(size)) { - return {}; - } - - return size; -} - -unsigned long __android_logger_get_buffer_size(log_id_t log_id) { - std::string buffer_name = android_log_id_to_name(log_id); - std::array properties = { - "persist.logd.size." + buffer_name, - "ro.logd.size." + buffer_name, - "persist.logd.size", - "ro.logd.size", - }; - - for (const auto& property : properties) { - if (auto size = GetBufferSizeProperty(property)) { - return *size; - } - } - - char value[PROP_VALUE_MAX] = {}; - if (__system_property_get("ro.config.low_ram", value) > 0 && !strcmp(value, "true")) { - return LOG_BUFFER_MIN_SIZE; - } - - return LOG_BUFFER_SIZE; -} - -#else - -// Default to 1MB for host. -unsigned long __android_logger_get_buffer_size(log_id_t) { - return 1024 * 1024; -} - -#endif \ No newline at end of file diff --git a/logd/Android.bp b/logd/Android.bp index 265e19e8f..7f67ab0be 100644 --- a/logd/Android.bp +++ b/logd/Android.bp @@ -57,6 +57,7 @@ cc_library_static { "LogReaderList.cpp", "LogReaderThread.cpp", "LogBufferElement.cpp", + "LogSize.cpp", "LogStatistics.cpp", "LogTags.cpp", "PruneList.cpp", diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp index 6381ffaca..f2fe7ef3c 100644 --- a/logd/CommandListener.cpp +++ b/logd/CommandListener.cpp @@ -101,9 +101,9 @@ int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc, return 0; } - unsigned long size = buf()->GetSize((log_id_t)id); + size_t size = buf()->GetSize(static_cast(id)); char buf[512]; - snprintf(buf, sizeof(buf), "%lu", size); + snprintf(buf, sizeof(buf), "%zu", size); cli->sendMsg(buf); return 0; } @@ -127,8 +127,8 @@ int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc, return 0; } - unsigned long size = atol(argv[2]); - if (buf()->SetSize((log_id_t)id, size)) { + size_t size = atol(argv[2]); + if (!buf()->SetSize(static_cast(id), size)) { cli->sendMsg("Range Error"); return 0; } @@ -150,9 +150,9 @@ int CommandListener::GetBufSizeReadableCmd::runCommand(SocketClient* cli, int ar return 0; } - unsigned long size = stats()->SizeReadable((log_id_t)id); + size_t size = stats()->SizeReadable(static_cast(id)); char buf[512]; - snprintf(buf, sizeof(buf), "%lu", size); + snprintf(buf, sizeof(buf), "%zu", size); cli->sendMsg(buf); return 0; } @@ -171,9 +171,9 @@ int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc, return 0; } - unsigned long size = stats()->Sizes((log_id_t)id); + size_t size = stats()->Sizes(static_cast(id)); char buf[512]; - snprintf(buf, sizeof(buf), "%lu", size); + snprintf(buf, sizeof(buf), "%zu", size); cli->sendMsg(buf); return 0; } diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index c5d333a9e..a98c4b971 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -68,8 +68,8 @@ class LogBuffer { log_time realtime)>& filter) = 0; virtual bool Clear(log_id_t id, uid_t uid) = 0; - virtual unsigned long GetSize(log_id_t id) = 0; - virtual int SetSize(log_id_t id, unsigned long size) = 0; + virtual size_t GetSize(log_id_t id) = 0; + virtual bool SetSize(log_id_t id, size_t size) = 0; virtual uint64_t sequence() const = 0; }; diff --git a/logd/LogBufferTest.h b/logd/LogBufferTest.h index 1fd22c236..eeeb98095 100644 --- a/logd/LogBufferTest.h +++ b/logd/LogBufferTest.h @@ -75,6 +75,8 @@ class LogBufferTest : public testing::TestWithParam { } else { FAIL() << "Unknown buffer type selected for test"; } + + log_id_for_each(i) { log_buffer_->SetSize(i, 1024 * 1024); } } void LogMessages(const std::vector& messages) { diff --git a/logd/LogSize.cpp b/logd/LogSize.cpp new file mode 100644 index 000000000..fe829baac --- /dev/null +++ b/logd/LogSize.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 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 + +#include +#include +#include + +#include +#include + +bool IsValidBufferSize(size_t value) { + return kLogBufferMinSize <= value && value <= kLogBufferMaxSize; +} + +static std::optional GetBufferSizeProperty(const std::string& key) { + std::string value = android::base::GetProperty(key, ""); + if (value.empty()) { + return {}; + } + + uint32_t size; + if (!android::base::ParseByteCount(value, &size)) { + return {}; + } + + if (!IsValidBufferSize(size)) { + return {}; + } + + return size; +} + +size_t GetBufferSizeFromProperties(log_id_t log_id) { + std::string buffer_name = android_log_id_to_name(log_id); + std::array properties = { + "persist.logd.size." + buffer_name, + "ro.logd.size." + buffer_name, + "persist.logd.size", + "ro.logd.size", + }; + + for (const auto& property : properties) { + if (auto size = GetBufferSizeProperty(property)) { + return *size; + } + } + + if (android::base::GetBoolProperty("ro.config.low_ram", false)) { + return kLogBufferMinSize; + } + + return kDefaultLogBufferSize; +} diff --git a/logd/LogSize.h b/logd/LogSize.h new file mode 100644 index 000000000..d5716ff48 --- /dev/null +++ b/logd/LogSize.h @@ -0,0 +1,34 @@ +/* + * Copyright 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 + +#include + +static constexpr size_t kDefaultLogBufferSize = 256 * 1024; +static constexpr size_t kLogBufferMinSize = 64 * 1024; +static constexpr size_t kLogBufferMaxSize = 256 * 1024 * 1024; + +bool IsValidBufferSize(size_t value); + +// This returns the buffer size as set in system properties for use in LogBuffer::Init(). +// Note that `logcat -G` calls LogBuffer::SetSize(), which configures log buffer sizes without +// setting these properties, so this function should never be used except for LogBuffer::Init(). +// LogBuffer::GetSize() should be used instead within logd. Other processes can use +// android_logger_get_log_size() or `logcat -g` to query the actual allotted buffer size. +size_t GetBufferSizeFromProperties(log_id_t log_id); diff --git a/logd/SerializedLogBuffer.cpp b/logd/SerializedLogBuffer.cpp index 972a3f3a9..65fedb026 100644 --- a/logd/SerializedLogBuffer.cpp +++ b/logd/SerializedLogBuffer.cpp @@ -23,6 +23,7 @@ #include #include +#include "LogSize.h" #include "LogStatistics.h" #include "SerializedFlushToState.h" @@ -34,8 +35,8 @@ SerializedLogBuffer::SerializedLogBuffer(LogReaderList* reader_list, LogTags* ta void SerializedLogBuffer::Init() { log_id_for_each(i) { - if (SetSize(i, __android_logger_get_buffer_size(i))) { - SetSize(i, LOG_BUFFER_MIN_SIZE); + if (!SetSize(i, GetBufferSizeFromProperties(i))) { + SetSize(i, kLogBufferMinSize); } } @@ -299,7 +300,7 @@ bool SerializedLogBuffer::Clear(log_id_t id, uid_t uid) { return Prune(id, ULONG_MAX, uid); } -unsigned long SerializedLogBuffer::GetSizeUsed(log_id_t id) { +size_t SerializedLogBuffer::GetSizeUsed(log_id_t id) { size_t total_size = 0; for (const auto& chunk : logs_[id]) { total_size += chunk.PruneSize(); @@ -307,7 +308,7 @@ unsigned long SerializedLogBuffer::GetSizeUsed(log_id_t id) { return total_size; } -unsigned long SerializedLogBuffer::GetSize(log_id_t id) { +size_t SerializedLogBuffer::GetSize(log_id_t id) { auto lock = std::lock_guard{lock_}; return max_size_[id]; } @@ -315,10 +316,10 @@ unsigned long SerializedLogBuffer::GetSize(log_id_t id) { // New SerializedLogChunk objects will be allocated according to the new size, but older one are // unchanged. MaybePrune() is called on the log buffer to reduce it to an appropriate size if the // new size is lower. -int SerializedLogBuffer::SetSize(log_id_t id, unsigned long size) { +bool SerializedLogBuffer::SetSize(log_id_t id, size_t size) { // Reasonable limits ... - if (!__android_logger_valid_buffer_size(size)) { - return -1; + if (!IsValidBufferSize(size)) { + return false; } auto lock = std::lock_guard{lock_}; @@ -326,5 +327,5 @@ int SerializedLogBuffer::SetSize(log_id_t id, unsigned long size) { MaybePrune(id); - return 0; + return true; } diff --git a/logd/SerializedLogBuffer.h b/logd/SerializedLogBuffer.h index a03050e22..32fbe5e98 100644 --- a/logd/SerializedLogBuffer.h +++ b/logd/SerializedLogBuffer.h @@ -47,8 +47,8 @@ class SerializedLogBuffer final : public LogBuffer { log_time realtime)>& filter) override; bool Clear(log_id_t id, uid_t uid) override; - unsigned long GetSize(log_id_t id) override; - int SetSize(log_id_t id, unsigned long size) override; + size_t GetSize(log_id_t id) override; + bool SetSize(log_id_t id, size_t size) override; uint64_t sequence() const override { return sequence_.load(std::memory_order_relaxed); } @@ -61,13 +61,13 @@ class SerializedLogBuffer final : public LogBuffer { void NotifyReadersOfPrune(log_id_t log_id, const std::list::iterator& chunk) REQUIRES(reader_list_->reader_threads_lock()); void RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk); - unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_); + size_t GetSizeUsed(log_id_t id) REQUIRES(lock_); LogReaderList* reader_list_; LogTags* tags_; LogStatistics* stats_; - unsigned long max_size_[LOG_ID_MAX] GUARDED_BY(lock_) = {}; + size_t max_size_[LOG_ID_MAX] GUARDED_BY(lock_) = {}; std::list logs_[LOG_ID_MAX] GUARDED_BY(lock_); RwLock lock_; diff --git a/logd/SimpleLogBuffer.cpp b/logd/SimpleLogBuffer.cpp index ec08d54d4..b00dd25be 100644 --- a/logd/SimpleLogBuffer.cpp +++ b/logd/SimpleLogBuffer.cpp @@ -19,6 +19,7 @@ #include #include "LogBufferElement.h" +#include "LogSize.h" SimpleLogBuffer::SimpleLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats) : reader_list_(reader_list), tags_(tags), stats_(stats) { @@ -29,8 +30,8 @@ SimpleLogBuffer::~SimpleLogBuffer() {} void SimpleLogBuffer::Init() { log_id_for_each(i) { - if (SetSize(i, __android_logger_get_buffer_size(i))) { - SetSize(i, LOG_BUFFER_MIN_SIZE); + if (!SetSize(i, GetBufferSizeFromProperties(i))) { + SetSize(i, kLogBufferMinSize); } } @@ -247,22 +248,22 @@ bool SimpleLogBuffer::Clear(log_id_t id, uid_t uid) { } // get the total space allocated to "id" -unsigned long SimpleLogBuffer::GetSize(log_id_t id) { +size_t SimpleLogBuffer::GetSize(log_id_t id) { auto lock = SharedLock{lock_}; size_t retval = max_size_[id]; return retval; } // set the total space allocated to "id" -int SimpleLogBuffer::SetSize(log_id_t id, unsigned long size) { +bool SimpleLogBuffer::SetSize(log_id_t id, size_t size) { // Reasonable limits ... - if (!__android_logger_valid_buffer_size(size)) { - return -1; + if (!IsValidBufferSize(size)) { + return false; } auto lock = std::lock_guard{lock_}; max_size_[id] = size; - return 0; + return true; } void SimpleLogBuffer::MaybePrune(log_id_t id) { diff --git a/logd/SimpleLogBuffer.h b/logd/SimpleLogBuffer.h index 9f7d69903..8e5b50eb5 100644 --- a/logd/SimpleLogBuffer.h +++ b/logd/SimpleLogBuffer.h @@ -41,8 +41,8 @@ class SimpleLogBuffer : public LogBuffer { log_time realtime)>& filter) override; bool Clear(log_id_t id, uid_t uid) override; - unsigned long GetSize(log_id_t id) override; - int SetSize(log_id_t id, unsigned long size) override final; + size_t GetSize(log_id_t id) override; + bool SetSize(log_id_t id, size_t size) override final; uint64_t sequence() const override { return sequence_.load(std::memory_order_relaxed); } @@ -60,7 +60,7 @@ class SimpleLogBuffer : public LogBuffer { LogStatistics* stats() { return stats_; } LogReaderList* reader_list() { return reader_list_; } - unsigned long max_size(log_id_t id) REQUIRES_SHARED(lock_) { return max_size_[id]; } + size_t max_size(log_id_t id) REQUIRES_SHARED(lock_) { return max_size_[id]; } std::list& logs() { return logs_; } RwLock lock_; @@ -75,7 +75,7 @@ class SimpleLogBuffer : public LogBuffer { std::atomic sequence_ = 1; - unsigned long max_size_[LOG_ID_MAX] GUARDED_BY(lock_); + size_t max_size_[LOG_ID_MAX] GUARDED_BY(lock_); std::list logs_ GUARDED_BY(lock_); // Keeps track of the iterator to the oldest log message of a given log type, as an // optimization when pruning logs. Use GetOldest() to retrieve.