Merge "Implement the functions to parse zip64 structs"
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index b3f059c..bb3c260 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -457,8 +457,8 @@
return;
}
- logger_list = android_logger_list_open(
- android_name_to_log_id(filename), ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tail, pid);
+ logger_list =
+ android_logger_list_open(android_name_to_log_id(filename), ANDROID_LOG_NONBLOCK, tail, pid);
if (!logger_list) {
ALOGE("Unable to open %s: %s\n", filename, strerror(errno));
diff --git a/fs_mgr/tests/Android.bp b/fs_mgr/tests/Android.bp
index 4f6ec5a..28dee88 100644
--- a/fs_mgr/tests/Android.bp
+++ b/fs_mgr/tests/Android.bp
@@ -18,6 +18,7 @@
"cts",
"device-tests",
"vts",
+ "vts10",
],
compile_multilib: "both",
multilib: {
diff --git a/init/Android.bp b/init/Android.bp
index d2bdf98..d512a4e 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -36,6 +36,7 @@
"util.cpp",
]
init_device_sources = [
+ "block_dev_initializer.cpp",
"bootchart.cpp",
"builtins.cpp",
"devices.cpp",
@@ -258,6 +259,7 @@
"cts",
"device-tests",
"vts",
+ "vts10",
],
}
diff --git a/init/Android.mk b/init/Android.mk
index 207b5e7..b49fb3b 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -48,6 +48,7 @@
include $(CLEAR_VARS)
LOCAL_CPPFLAGS := $(init_cflags)
LOCAL_SRC_FILES := \
+ block_dev_initializer.cpp \
devices.cpp \
first_stage_init.cpp \
first_stage_main.cpp \
diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp
new file mode 100644
index 0000000..b423f86
--- /dev/null
+++ b/init/block_dev_initializer.cpp
@@ -0,0 +1,148 @@
+// 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 <chrono>
+#include <string_view>
+#include <vector>
+
+#include <android-base/chrono_utils.h>
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <fs_mgr.h>
+
+#include "block_dev_initializer.h"
+
+namespace android {
+namespace init {
+
+using android::base::Timer;
+using namespace std::chrono_literals;
+
+BlockDevInitializer::BlockDevInitializer() : uevent_listener_(16 * 1024 * 1024) {
+ auto boot_devices = android::fs_mgr::GetBootDevices();
+ device_handler_ = std::make_unique<DeviceHandler>(
+ std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
+ std::move(boot_devices), false);
+}
+
+bool BlockDevInitializer::InitDeviceMapper() {
+ const std::string dm_path = "/devices/virtual/misc/device-mapper";
+ bool found = false;
+ auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
+ if (uevent.path == dm_path) {
+ device_handler_->HandleUevent(uevent);
+ found = true;
+ return ListenerAction::kStop;
+ }
+ return ListenerAction::kContinue;
+ };
+ uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
+ if (!found) {
+ LOG(INFO) << "device-mapper device not found in /sys, waiting for its uevent";
+ Timer t;
+ uevent_listener_.Poll(dm_callback, 10s);
+ LOG(INFO) << "Wait for device-mapper returned after " << t;
+ }
+ if (!found) {
+ LOG(ERROR) << "device-mapper device not found after polling timeout";
+ return false;
+ }
+ return true;
+}
+
+ListenerAction BlockDevInitializer::HandleUevent(const Uevent& uevent,
+ std::set<std::string>* devices) {
+ // Ignore everything that is not a block device.
+ if (uevent.subsystem != "block") {
+ return ListenerAction::kContinue;
+ }
+
+ auto name = uevent.partition_name;
+ if (name.empty()) {
+ size_t base_idx = uevent.path.rfind('/');
+ if (base_idx == std::string::npos) {
+ return ListenerAction::kContinue;
+ }
+ name = uevent.path.substr(base_idx + 1);
+ }
+
+ auto iter = devices->find(name);
+ if (iter == devices->end()) {
+ return ListenerAction::kContinue;
+ }
+
+ LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;
+
+ devices->erase(iter);
+ device_handler_->HandleUevent(uevent);
+ return devices->empty() ? ListenerAction::kStop : ListenerAction::kContinue;
+}
+
+bool BlockDevInitializer::InitDevices(std::set<std::string> devices) {
+ auto uevent_callback = [&, this](const Uevent& uevent) -> ListenerAction {
+ return HandleUevent(uevent, &devices);
+ };
+ uevent_listener_.RegenerateUevents(uevent_callback);
+
+ // UeventCallback() will remove found partitions from |devices|. So if it
+ // isn't empty here, it means some partitions are not found.
+ if (!devices.empty()) {
+ LOG(INFO) << __PRETTY_FUNCTION__
+ << ": partition(s) not found in /sys, waiting for their uevent(s): "
+ << android::base::Join(devices, ", ");
+ Timer t;
+ uevent_listener_.Poll(uevent_callback, 10s);
+ LOG(INFO) << "Wait for partitions returned after " << t;
+ }
+
+ if (!devices.empty()) {
+ LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found after polling timeout: "
+ << android::base::Join(devices, ", ");
+ return false;
+ }
+ return true;
+}
+
+// Creates "/dev/block/dm-XX" for dm nodes by running coldboot on /sys/block/dm-XX.
+bool BlockDevInitializer::InitDmDevice(const std::string& device) {
+ const std::string device_name(basename(device.c_str()));
+ const std::string syspath = "/sys/block/" + device_name;
+ bool found = false;
+
+ auto uevent_callback = [&device_name, &device, this, &found](const Uevent& uevent) {
+ if (uevent.device_name == device_name) {
+ LOG(VERBOSE) << "Creating device-mapper device : " << device;
+ device_handler_->HandleUevent(uevent);
+ found = true;
+ return ListenerAction::kStop;
+ }
+ return ListenerAction::kContinue;
+ };
+
+ uevent_listener_.RegenerateUeventsForPath(syspath, uevent_callback);
+ if (!found) {
+ LOG(INFO) << "dm device '" << device << "' not found in /sys, waiting for its uevent";
+ Timer t;
+ uevent_listener_.Poll(uevent_callback, 10s);
+ LOG(INFO) << "wait for dm device '" << device << "' returned after " << t;
+ }
+ if (!found) {
+ LOG(ERROR) << "dm device '" << device << "' not found after polling timeout";
+ return false;
+ }
+ return true;
+}
+
+} // namespace init
+} // namespace android
diff --git a/init/block_dev_initializer.h b/init/block_dev_initializer.h
new file mode 100644
index 0000000..0d4c6e9
--- /dev/null
+++ b/init/block_dev_initializer.h
@@ -0,0 +1,41 @@
+// 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 <memory>
+#include <set>
+#include <string>
+
+#include "devices.h"
+#include "uevent_listener.h"
+
+namespace android {
+namespace init {
+
+class BlockDevInitializer final {
+ public:
+ BlockDevInitializer();
+
+ bool InitDeviceMapper();
+ bool InitDevices(std::set<std::string> devices);
+ bool InitDmDevice(const std::string& device);
+
+ private:
+ ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);
+
+ std::unique_ptr<DeviceHandler> device_handler_;
+ UeventListener uevent_listener_;
+};
+
+} // namespace init
+} // namespace android
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 3451264..8eb2f97 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -42,6 +42,7 @@
#include <liblp/liblp.h>
#include <libsnapshot/snapshot.h>
+#include "block_dev_initializer.h"
#include "devices.h"
#include "switch_root.h"
#include "uevent.h"
@@ -84,11 +85,7 @@
bool InitDevices();
protected:
- ListenerAction HandleBlockDevice(const std::string& name, const Uevent&,
- std::set<std::string>* required_devices);
bool InitRequiredDevices(std::set<std::string> devices);
- bool InitMappedDevice(const std::string& verity_device);
- bool InitDeviceMapper();
bool CreateLogicalPartitions();
bool MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
Fstab::iterator* end = nullptr);
@@ -106,8 +103,6 @@
// revocation check by DSU installation service.
void CopyDsuAvbKeys();
- ListenerAction UeventCallback(const Uevent& uevent, std::set<std::string>* required_devices);
-
// Pure virtual functions.
virtual bool GetDmVerityDevices(std::set<std::string>* devices) = 0;
virtual bool SetUpDmVerity(FstabEntry* fstab_entry) = 0;
@@ -119,8 +114,7 @@
// The super path is only set after InitDevices, and is invalid before.
std::string super_path_;
std::string super_partition_name_;
- std::unique_ptr<DeviceHandler> device_handler_;
- UeventListener uevent_listener_;
+ BlockDevInitializer block_dev_init_;
// Reads all AVB keys before chroot into /system, as they might be used
// later when mounting other partitions, e.g., /vendor and /product.
std::map<std::string, std::vector<std::string>> preload_avb_key_blobs_;
@@ -234,13 +228,7 @@
// Class Definitions
// -----------------
-FirstStageMount::FirstStageMount(Fstab fstab)
- : need_dm_verity_(false), fstab_(std::move(fstab)), uevent_listener_(16 * 1024 * 1024) {
- auto boot_devices = android::fs_mgr::GetBootDevices();
- device_handler_ = std::make_unique<DeviceHandler>(
- std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
- std::move(boot_devices), false);
-
+FirstStageMount::FirstStageMount(Fstab fstab) : need_dm_verity_(false), fstab_(std::move(fstab)) {
super_partition_name_ = fs_mgr_get_super_partition_name();
}
@@ -308,62 +296,13 @@
// Found partitions will then be removed from it for the subsequent member
// function to check which devices are NOT created.
bool FirstStageMount::InitRequiredDevices(std::set<std::string> devices) {
- if (!InitDeviceMapper()) {
+ if (!block_dev_init_.InitDeviceMapper()) {
return false;
}
-
if (devices.empty()) {
return true;
}
-
- auto uevent_callback = [&, this](const Uevent& uevent) {
- return UeventCallback(uevent, &devices);
- };
- uevent_listener_.RegenerateUevents(uevent_callback);
-
- // UeventCallback() will remove found partitions from |devices|. So if it
- // isn't empty here, it means some partitions are not found.
- if (!devices.empty()) {
- LOG(INFO) << __PRETTY_FUNCTION__
- << ": partition(s) not found in /sys, waiting for their uevent(s): "
- << android::base::Join(devices, ", ");
- Timer t;
- uevent_listener_.Poll(uevent_callback, 10s);
- LOG(INFO) << "Wait for partitions returned after " << t;
- }
-
- if (!devices.empty()) {
- LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found after polling timeout: "
- << android::base::Join(devices, ", ");
- return false;
- }
-
- return true;
-}
-
-bool FirstStageMount::InitDeviceMapper() {
- const std::string dm_path = "/devices/virtual/misc/device-mapper";
- bool found = false;
- auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) {
- if (uevent.path == dm_path) {
- device_handler_->HandleUevent(uevent);
- found = true;
- return ListenerAction::kStop;
- }
- return ListenerAction::kContinue;
- };
- uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback);
- if (!found) {
- LOG(INFO) << "device-mapper device not found in /sys, waiting for its uevent";
- Timer t;
- uevent_listener_.Poll(dm_callback, 10s);
- LOG(INFO) << "Wait for device-mapper returned after " << t;
- }
- if (!found) {
- LOG(ERROR) << "device-mapper device not found after polling timeout";
- return false;
- }
- return true;
+ return block_dev_init_.InitDevices(std::move(devices));
}
bool FirstStageMount::InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata) {
@@ -419,75 +358,6 @@
return android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_path_);
}
-ListenerAction FirstStageMount::HandleBlockDevice(const std::string& name, const Uevent& uevent,
- std::set<std::string>* required_devices) {
- // Matches partition name to create device nodes.
- // Both required_devices_partition_names_ and uevent->partition_name have A/B
- // suffix when A/B is used.
- auto iter = required_devices->find(name);
- if (iter != required_devices->end()) {
- LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter;
- required_devices->erase(iter);
- device_handler_->HandleUevent(uevent);
- if (required_devices->empty()) {
- return ListenerAction::kStop;
- } else {
- return ListenerAction::kContinue;
- }
- }
- return ListenerAction::kContinue;
-}
-
-ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent,
- std::set<std::string>* required_devices) {
- // Ignores everything that is not a block device.
- if (uevent.subsystem != "block") {
- return ListenerAction::kContinue;
- }
-
- if (!uevent.partition_name.empty()) {
- return HandleBlockDevice(uevent.partition_name, uevent, required_devices);
- } else {
- size_t base_idx = uevent.path.rfind('/');
- if (base_idx != std::string::npos) {
- return HandleBlockDevice(uevent.path.substr(base_idx + 1), uevent, required_devices);
- }
- }
- // Not found a partition or find an unneeded partition, continue to find others.
- return ListenerAction::kContinue;
-}
-
-// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
-bool FirstStageMount::InitMappedDevice(const std::string& dm_device) {
- const std::string device_name(basename(dm_device.c_str()));
- const std::string syspath = "/sys/block/" + device_name;
- bool found = false;
-
- auto verity_callback = [&device_name, &dm_device, this, &found](const Uevent& uevent) {
- if (uevent.device_name == device_name) {
- LOG(VERBOSE) << "Creating device-mapper device : " << dm_device;
- device_handler_->HandleUevent(uevent);
- found = true;
- return ListenerAction::kStop;
- }
- return ListenerAction::kContinue;
- };
-
- uevent_listener_.RegenerateUeventsForPath(syspath, verity_callback);
- if (!found) {
- LOG(INFO) << "dm device '" << dm_device << "' not found in /sys, waiting for its uevent";
- Timer t;
- uevent_listener_.Poll(verity_callback, 10s);
- LOG(INFO) << "wait for dm device '" << dm_device << "' returned after " << t;
- }
- if (!found) {
- LOG(ERROR) << "dm device '" << dm_device << "' not found after polling timeout";
- return false;
- }
-
- return true;
-}
-
bool FirstStageMount::MountPartition(const Fstab::iterator& begin, bool erase_same_mounts,
Fstab::iterator* end) {
// Sets end to begin + 1, so we can just return on failure below.
@@ -499,7 +369,7 @@
if (!fs_mgr_update_logical_partition(&(*begin))) {
return false;
}
- if (!InitMappedDevice(begin->blk_device)) {
+ if (!block_dev_init_.InitDmDevice(begin->blk_device)) {
return false;
}
}
@@ -666,7 +536,9 @@
auto init_devices = [this](std::set<std::string> devices) -> bool {
for (auto iter = devices.begin(); iter != devices.end();) {
if (android::base::StartsWith(*iter, "/dev/block/dm-")) {
- if (!InitMappedDevice(*iter)) return false;
+ if (!block_dev_init_.InitDmDevice(*iter)) {
+ return false;
+ }
iter = devices.erase(iter);
} else {
iter++;
@@ -782,7 +654,7 @@
// The exact block device name (fstab_rec->blk_device) is changed to
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage.
- return InitMappedDevice(fstab_entry->blk_device);
+ return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
default:
return false;
}
@@ -902,7 +774,7 @@
// The exact block device name (fstab_rec->blk_device) is changed to
// "/dev/block/dm-XX". Needs to create it because ueventd isn't started in init
// first stage.
- return InitMappedDevice(fstab_entry->blk_device);
+ return block_dev_init_.InitDmDevice(fstab_entry->blk_device);
default:
return false;
}
diff --git a/liblog/README.md b/liblog/README.md
index 871399a..f64f376 100644
--- a/liblog/README.md
+++ b/liblog/README.md
@@ -118,10 +118,9 @@
finally a call closing the logs. A single log can be opened with `android_logger_list_open()`; or
multiple logs can be opened with `android_logger_list_alloc()`, calling in turn the
`android_logger_open()` for each log id. Each entry can be retrieved with
-`android_logger_list_read()`. The log(s) can be closed with `android_logger_list_free()`. The logs
-should be opened with an `ANDROID_LOG_RDONLY` mode. `ANDROID_LOG_NONBLOCK` mode will report when
-the log reading is done with an `EAGAIN` error return code, otherwise the
-`android_logger_list_read()` call will block for new entries.
+`android_logger_list_read()`. The log(s) can be closed with `android_logger_list_free()`.
+`ANDROID_LOG_NONBLOCK` mode will report when the log reading is done with an `EAGAIN` error return
+code, otherwise the `android_logger_list_read()` call will block for new entries.
The `ANDROID_LOG_WRAP` mode flag to the `android_logger_list_alloc_time()` signals logd to quiesce
the reader until the buffer is about to prune at the start time then proceed to dumping content.
@@ -130,14 +129,12 @@
logs to the persistent logs from before the last reboot.
The value returned by `android_logger_open()` can be used as a parameter to the
-`android_logger_clear()` function to empty the sub-log. It is recommended to only open log
-`ANDROID_LOG_WRONLY` in that case.
+`android_logger_clear()` function to empty the sub-log.
The value returned by `android_logger_open()` can be used as a parameter to the
`android_logger_get_log_(size|readable_size|version)` to retrieve the sub-log maximum size, readable
size and log buffer format protocol version respectively. `android_logger_get_id()` returns the id
-that was used when opening the sub-log. It is recommended to open the log `ANDROID_LOG_RDONLY` in
-these cases.
+that was used when opening the sub-log.
Errors
------
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index 18c1c33..05ad25f 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -141,10 +141,6 @@
char* buf, size_t len);
int android_logger_set_prune_list(struct logger_list* logger_list, const char* buf, size_t len);
-#define ANDROID_LOG_RDONLY O_RDONLY
-#define ANDROID_LOG_WRONLY O_WRONLY
-#define ANDROID_LOG_RDWR O_RDWR
-#define ANDROID_LOG_ACCMODE O_ACCMODE
#ifndef O_NONBLOCK
#define ANDROID_LOG_NONBLOCK 0x00000800
#else
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index 64a92b7..129d767 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -185,7 +185,7 @@
/* Add just enough clues in logger_list and transp to make API function */
memset(&logger_list, 0, sizeof(logger_list));
- logger_list.mode = ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK | ANDROID_LOG_RDONLY;
+ logger_list.mode = ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK;
logger_list.log_mask = (unsigned)-1;
if (logId != LOG_ID_ANY) {
logger_list.log_mask = (1 << logId);
diff --git a/liblog/tests/Android.bp b/liblog/tests/Android.bp
index b4bb77f..fffb809 100644
--- a/liblog/tests/Android.bp
+++ b/liblog/tests/Android.bp
@@ -97,6 +97,7 @@
test_suites: [
"cts",
"vts",
+ "vts10",
],
}
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 4366f3d..3a6ed90 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -648,8 +648,7 @@
static void BM_log_latency(benchmark::State& state) {
pid_t pid = getpid();
- struct logger_list* logger_list =
- android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 0, pid);
+ struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
if (!logger_list) {
fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
@@ -723,8 +722,7 @@
static void BM_log_delay(benchmark::State& state) {
pid_t pid = getpid();
- struct logger_list* logger_list =
- android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 0, pid);
+ struct logger_list* logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 0, pid);
if (!logger_list) {
fprintf(stderr, "Unable to open events log: %s\n", strerror(errno));
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 773bac2..a031531 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -82,7 +82,7 @@
pid_t pid = getpid();
auto logger_list = std::unique_ptr<struct logger_list, ListCloser>{
- android_logger_list_open(log_buffer, ANDROID_LOG_RDONLY, 1000, pid)};
+ android_logger_list_open(log_buffer, 0, 1000, pid)};
ASSERT_TRUE(logger_list);
write_messages();
@@ -106,7 +106,7 @@
}
auto logger_list_non_block = std::unique_ptr<struct logger_list, ListCloser>{
- android_logger_list_open(log_buffer, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)};
+ android_logger_list_open(log_buffer, ANDROID_LOG_NONBLOCK, 1000, pid)};
ASSERT_TRUE(logger_list_non_block);
size_t count = 0;
@@ -572,8 +572,7 @@
v += pid & 0xFFFF;
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid)));
int count = 0;
@@ -728,8 +727,7 @@
v += pid & 0xFFFF;
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_EVENTS, 0, 1000, pid)));
int count = 0;
@@ -1093,11 +1091,11 @@
pid_t pid = getpid();
auto logger_list1 = std::unique_ptr<struct logger_list, ListCloser>{
- android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_RDONLY, expected_count1, pid)};
+ android_logger_list_open(LOG_ID_MAIN, 0, expected_count1, pid)};
ASSERT_TRUE(logger_list1);
auto logger_list2 = std::unique_ptr<struct logger_list, ListCloser>{
- android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_RDONLY, expected_count2, pid)};
+ android_logger_list_open(LOG_ID_MAIN, 0, expected_count2, pid)};
ASSERT_TRUE(logger_list2);
for (int i = 25; i > 0; --i) {
@@ -1128,14 +1126,12 @@
}
// Test again with the nonblocking reader.
- auto logger_list_non_block1 =
- std::unique_ptr<struct logger_list, ListCloser>{android_logger_list_open(
- LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, expected_count1, pid)};
+ auto logger_list_non_block1 = std::unique_ptr<struct logger_list, ListCloser>{
+ android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count1, pid)};
ASSERT_TRUE(logger_list_non_block1);
- auto logger_list_non_block2 =
- std::unique_ptr<struct logger_list, ListCloser>{android_logger_list_open(
- LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, expected_count2, pid)};
+ auto logger_list_non_block2 = std::unique_ptr<struct logger_list, ListCloser>{
+ android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_NONBLOCK, expected_count2, pid)};
ASSERT_TRUE(logger_list_non_block2);
count1 = 0;
count2 = 0;
@@ -1542,8 +1538,8 @@
pid_t pid = getpid();
- struct logger_list* logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid);
+ struct logger_list* logger_list =
+ android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_NONBLOCK, 1000, pid);
int count = 0;
if (logger_list == NULL) return count;
@@ -1832,10 +1828,8 @@
gid = getgid();
pid_t pid = getpid();
- ASSERT_TRUE(NULL !=
- (logger_list = android_logger_list_open(
- LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- 1000, pid)));
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(LOG_ID_SECURITY, ANDROID_LOG_NONBLOCK,
+ 1000, pid)));
log_time ts(CLOCK_MONOTONIC);
diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp
index 1be99aa..3e09617 100644
--- a/liblog/tests/log_read_test.cpp
+++ b/liblog/tests/log_read_test.cpp
@@ -34,8 +34,7 @@
// This test assumes the log buffers are filled with noise from
// normal operations. It will fail if done immediately after a
// logcat -c.
- struct logger_list* logger_list =
- android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
+ struct logger_list* logger_list = android_logger_list_alloc(0, 0, 0);
for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
diff --git a/liblog/tests/log_wrap_test.cpp b/liblog/tests/log_wrap_test.cpp
index e06964f..755898a 100644
--- a/liblog/tests/log_wrap_test.cpp
+++ b/liblog/tests/log_wrap_test.cpp
@@ -32,7 +32,7 @@
static void read_with_wrap() {
// Read the last line in the log to get a starting timestamp. We're assuming
// the log is not empty.
- const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
+ const int mode = ANDROID_LOG_NONBLOCK;
struct logger_list* logger_list =
android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0);
diff --git a/libziparchive/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
index a17127d..435bfb6 100644
--- a/libziparchive/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -188,6 +188,15 @@
const std::string_view optional_suffix = "");
/*
+ * Start iterating over all entries of a zip file. Use the matcher functor to
+ * restrict iteration to entry names that make the functor return true.
+ *
+ * Returns 0 on success and negative values on failure.
+ */
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+ std::function<bool(std::string_view entry_name)> matcher);
+
+/*
* Advance to the next element in the zipfile in iteration order.
*
* Returns 0 on success, -1 if there are no more elements in this
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 5b976d0..9812026 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -32,6 +32,7 @@
#include <unistd.h>
#include <memory>
+#include <optional>
#include <vector>
#if defined(__APPLE__)
@@ -872,31 +873,40 @@
struct IterationHandle {
ZipArchive* archive;
- std::string prefix;
- std::string suffix;
+ std::function<bool(std::string_view)> matcher;
uint32_t position = 0;
- IterationHandle(ZipArchive* archive, std::string_view in_prefix, std::string_view in_suffix)
- : archive(archive), prefix(in_prefix), suffix(in_suffix) {}
+ IterationHandle(ZipArchive* archive, std::function<bool(std::string_view)> in_matcher)
+ : archive(archive), matcher(std::move(in_matcher)) {}
+
+ bool Match(std::string_view entry_name) const { return matcher(entry_name); }
};
int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
const std::string_view optional_prefix,
const std::string_view optional_suffix) {
- if (archive == nullptr || archive->cd_entry_map == nullptr) {
- ALOGW("Zip: Invalid ZipArchiveHandle");
- return kInvalidHandle;
- }
-
if (optional_prefix.size() > static_cast<size_t>(UINT16_MAX) ||
optional_suffix.size() > static_cast<size_t>(UINT16_MAX)) {
ALOGW("Zip: prefix/suffix too long");
return kInvalidEntryName;
}
+ auto matcher = [prefix = std::string(optional_prefix),
+ suffix = std::string(optional_suffix)](std::string_view name) mutable {
+ return android::base::StartsWith(name, prefix) && android::base::EndsWith(name, suffix);
+ };
+ return StartIteration(archive, cookie_ptr, std::move(matcher));
+}
+
+int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr,
+ std::function<bool(std::string_view)> matcher) {
+ if (archive == nullptr || archive->cd_entry_map == nullptr) {
+ ALOGW("Zip: Invalid ZipArchiveHandle");
+ return kInvalidHandle;
+ }
archive->cd_entry_map->ResetIteration();
- *cookie_ptr = new IterationHandle(archive, optional_prefix, optional_suffix);
+ *cookie_ptr = new IterationHandle(archive, matcher);
return 0;
}
@@ -946,8 +956,7 @@
auto entry = archive->cd_entry_map->Next(archive->central_directory.GetBasePtr());
while (entry != std::pair<std::string_view, uint64_t>()) {
const auto [entry_name, offset] = entry;
- if (android::base::StartsWith(entry_name, handle->prefix) &&
- android::base::EndsWith(entry_name, handle->suffix)) {
+ if (handle->Match(entry_name)) {
const int error = FindEntry(archive, entry_name, offset, data);
if (!error && name) {
*name = entry_name;
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 10050da..fbabf96 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -230,6 +230,22 @@
CloseArchive(handle);
}
+static void AssertIterationNames(void* iteration_cookie,
+ const std::vector<std::string>& expected_names_sorted) {
+ ZipEntry data;
+ std::vector<std::string> names;
+ std::string name;
+ for (size_t i = 0; i < expected_names_sorted.size(); ++i) {
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ names.push_back(name);
+ }
+ // End of iteration.
+ ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+ // Assert that the names are as expected.
+ std::sort(names.begin(), names.end());
+ ASSERT_EQ(expected_names_sorted, names);
+}
+
static void AssertIterationOrder(const std::string_view prefix, const std::string_view suffix,
const std::vector<std::string>& expected_names_sorted) {
ZipArchiveHandle handle;
@@ -237,23 +253,19 @@
void* iteration_cookie;
ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, prefix, suffix));
-
- ZipEntry data;
- std::vector<std::string> names;
-
- std::string name;
- for (size_t i = 0; i < expected_names_sorted.size(); ++i) {
- ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
- names.push_back(name);
- }
-
- // End of iteration.
- ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+ AssertIterationNames(iteration_cookie, expected_names_sorted);
CloseArchive(handle);
+}
- // Assert that the names are as expected.
- std::sort(names.begin(), names.end());
- ASSERT_EQ(expected_names_sorted, names);
+static void AssertIterationOrderWithMatcher(std::function<bool(std::string_view)> matcher,
+ const std::vector<std::string>& expected_names_sorted) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+
+ void* iteration_cookie;
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, matcher));
+ AssertIterationNames(iteration_cookie, expected_names_sorted);
+ CloseArchive(handle);
}
TEST(ziparchive, Iteration) {
@@ -282,6 +294,30 @@
AssertIterationOrder("b", ".txt", kExpectedMatchesSorted);
}
+TEST(ziparchive, IterationWithAdditionalMatchesExactly) {
+ static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt"};
+ auto matcher = [](std::string_view name) { return name == "a.txt"; };
+ AssertIterationOrderWithMatcher(matcher, kExpectedMatchesSorted);
+}
+
+TEST(ziparchive, IterationWithAdditionalMatchesWithSuffix) {
+ static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b.txt", "b/c.txt",
+ "b/d.txt"};
+ auto matcher = [](std::string_view name) {
+ return name == "a.txt" || android::base::EndsWith(name, ".txt");
+ };
+ AssertIterationOrderWithMatcher(matcher, kExpectedMatchesSorted);
+}
+
+TEST(ziparchive, IterationWithAdditionalMatchesWithPrefixAndSuffix) {
+ static const std::vector<std::string> kExpectedMatchesSorted = {"a.txt", "b/c.txt", "b/d.txt"};
+ auto matcher = [](std::string_view name) {
+ return name == "a.txt" ||
+ (android::base::EndsWith(name, ".txt") && android::base::StartsWith(name, "b/"));
+ };
+ AssertIterationOrderWithMatcher(matcher, kExpectedMatchesSorted);
+}
+
TEST(ziparchive, IterationWithBadPrefixAndSuffix) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 76a970f..b065855 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -513,7 +513,7 @@
unsigned long setLogSize = 0;
const char* setPruneList = nullptr;
const char* setId = nullptr;
- int mode = ANDROID_LOG_RDONLY;
+ int mode = 0;
std::string forceFilters;
size_t tail_lines = 0;
log_time tail_time(log_time::EPOCH);
@@ -591,8 +591,7 @@
break;
}
if (long_options[option_index].name == wrap_str) {
- mode |= ANDROID_LOG_WRAP | ANDROID_LOG_RDONLY |
- ANDROID_LOG_NONBLOCK;
+ mode |= ANDROID_LOG_WRAP | ANDROID_LOG_NONBLOCK;
// ToDo: implement API that supports setting a wrap timeout
size_t dummy = ANDROID_LOG_WRAP_DEFAULT_TIMEOUT;
if (optarg && (!ParseUint(optarg, &dummy) || dummy < 1)) {
@@ -626,21 +625,19 @@
case 'c':
clearLog = true;
- mode |= ANDROID_LOG_WRONLY;
break;
case 'L':
- mode |= ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE |
- ANDROID_LOG_NONBLOCK;
+ mode |= ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK;
break;
case 'd':
- mode |= ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
+ mode |= ANDROID_LOG_NONBLOCK;
break;
case 't':
got_t = true;
- mode |= ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK;
+ mode |= ANDROID_LOG_NONBLOCK;
FALLTHROUGH_INTENDED;
case 'T':
if (strspn(optarg, "0123456789") != strlen(optarg)) {
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index 0cc7886..8299e66 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -289,9 +289,8 @@
// special pmsg event for log tags, and build up our internal
// database with any found.
void LogTags::ReadPersistEventLogTags() {
- struct logger_list* logger_list = android_logger_list_alloc(
- ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0,
- (pid_t)0);
+ struct logger_list* logger_list =
+ android_logger_list_alloc(ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK, 0, (pid_t)0);
if (!logger_list) return;
struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS);
diff --git a/logd/tests/Android.bp b/logd/tests/Android.bp
index d39da8a..2519a84 100644
--- a/logd/tests/Android.bp
+++ b/logd/tests/Android.bp
@@ -64,5 +64,6 @@
test_suites: [
"cts",
"vts",
+ "vts10",
],
}
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index f47bee1..c7f3480 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -870,10 +870,8 @@
ASSERT_EQ(0, info.si_status);
struct logger_list* logger_list;
- ASSERT_TRUE(nullptr !=
- (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- 0, pid)));
+ ASSERT_TRUE(nullptr != (logger_list = android_logger_list_open(LOG_ID_EVENTS,
+ ANDROID_LOG_NONBLOCK, 0, pid)));
int expected_count = (count < 2) ? count : 2;
int expected_chatty_count = (count <= 2) ? 0 : 1;