Merge changes I845d2250,I4faa0785
* changes:
libsnapshot: proto use correct index
libsnapshot: Export COW image size
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index 9c80765..c653167 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -146,7 +146,7 @@
},
};
-#define STR_INTERFACE_ "fastboot"
+#define STR_INTERFACE_ "fastbootd"
static const struct {
struct usb_functionfs_strings_head header;
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 7f6e723..7abc936 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -258,6 +258,10 @@
static int list_devices_callback(usb_ifc_info* info) {
if (match_fastboot_with_serial(info, nullptr) == 0) {
std::string serial = info->serial_number;
+ std::string interface = info->interface;
+ if (interface.empty()) {
+ interface = "fastboot";
+ }
if (!info->writable) {
serial = UsbNoPermissionsShortHelpText();
}
@@ -266,9 +270,9 @@
}
// output compatible with "adb devices"
if (!g_long_listing) {
- printf("%s\tfastboot", serial.c_str());
+ printf("%s\t%s", serial.c_str(), interface.c_str());
} else {
- printf("%-22s fastboot", serial.c_str());
+ printf("%-22s %s", serial.c_str(), interface.c_str());
if (strlen(info->device_path) > 0) printf(" %s", info->device_path);
}
putchar('\n');
diff --git a/fastboot/usb.h b/fastboot/usb.h
index 7ca44c4..e5f56e2 100644
--- a/fastboot/usb.h
+++ b/fastboot/usb.h
@@ -50,6 +50,8 @@
char serial_number[256];
char device_path[256];
+
+ char interface[256];
};
class UsbTransport : public Transport {
diff --git a/fastboot/usb_linux.cpp b/fastboot/usb_linux.cpp
index 6363aa5..964488c 100644
--- a/fastboot/usb_linux.cpp
+++ b/fastboot/usb_linux.cpp
@@ -43,6 +43,8 @@
#include <linux/version.h>
#include <linux/usb/ch9.h>
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
#include <chrono>
#include <memory>
#include <thread>
@@ -263,6 +265,13 @@
info.has_bulk_in = (in != -1);
info.has_bulk_out = (out != -1);
+ std::string interface;
+ auto path = android::base::StringPrintf("/sys/bus/usb/devices/%s/%s:1.%d/interface",
+ sysfs_name, sysfs_name, ifc->bInterfaceNumber);
+ if (android::base::ReadFileToString(path, &interface)) {
+ snprintf(info.interface, sizeof(info.interface), "%s", interface.c_str());
+ }
+
if(callback(&info) == 0) {
*ept_in_id = in;
*ept_out_id = out;
diff --git a/fastboot/usb_osx.cpp b/fastboot/usb_osx.cpp
index 8a3c213..610eebf 100644
--- a/fastboot/usb_osx.cpp
+++ b/fastboot/usb_osx.cpp
@@ -368,6 +368,7 @@
// device has no serial number
handle->info.serial_number[0] = 0;
}
+ handle->info.interface[0] = 0;
handle->info.writable = 1;
if (try_interfaces(dev, handle)) {
diff --git a/fastboot/usb_windows.cpp b/fastboot/usb_windows.cpp
index bf840f8..67bf8a3 100644
--- a/fastboot/usb_windows.cpp
+++ b/fastboot/usb_windows.cpp
@@ -319,6 +319,7 @@
&serial_number_len, true)) {
info.serial_number[0] = 0;
}
+ info.interface[0] = 0;
info.device_path[0] = 0;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 0825a77..f333a85 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -408,16 +408,17 @@
return fstab_result;
}
-// Identify path to fstab file. Lookup is based on pattern fstab.<hardware>,
-// fstab.<hardware.platform> in folders /odm/etc, vendor/etc, or /.
+// Identify path to fstab file. Lookup is based on pattern
+// fstab.<fstab_suffix>, fstab.<hardware>, fstab.<hardware.platform> in
+// folders /odm/etc, vendor/etc, or /.
std::string GetFstabPath() {
- for (const char* prop : {"hardware", "hardware.platform"}) {
- std::string hw;
+ for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
+ std::string suffix;
- if (!fs_mgr_get_boot_config(prop, &hw)) continue;
+ if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
- std::string fstab_path = prefix + hw;
+ std::string fstab_path = prefix + suffix;
if (access(fstab_path.c_str(), F_OK) == 0) {
return fstab_path;
}
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index 673e145..7912688 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -29,6 +29,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <android-base/properties.h>
#include <android-base/strings.h>
#include <uuid/uuid.h>
@@ -140,6 +141,10 @@
return std::string{uuid_chars};
}
+static bool IsRecovery() {
+ return access("/system/bin/recovery", F_OK) == 0;
+}
+
bool DeviceMapper::CreateDevice(const std::string& name, const DmTable& table, std::string* path,
const std::chrono::milliseconds& timeout_ms) {
std::string uuid = GenerateUuid();
@@ -160,6 +165,16 @@
if (timeout_ms <= std::chrono::milliseconds::zero()) {
return true;
}
+
+ if (IsRecovery()) {
+ bool non_ab_device = android::base::GetProperty("ro.build.ab_update", "").empty();
+ int sdk = android::base::GetIntProperty("ro.build.version.sdk", 0);
+ if (non_ab_device && sdk && sdk <= 29) {
+ LOG(INFO) << "Detected ueventd incompatibility, reverting to legacy libdm behavior.";
+ unique_path = *path;
+ }
+ }
+
if (!WaitForFile(unique_path, timeout_ms)) {
LOG(ERROR) << "Failed waiting for device path: " << unique_path;
DeleteDevice(name);
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 732dbea..89a47b1 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -144,7 +144,6 @@
std::vector<std::unique_ptr<Extent>> extents_;
uint32_t attributes_;
uint64_t size_;
- bool disabled_;
};
// An interval in the metadata. This is similar to a LinearExtent with one difference.
@@ -321,9 +320,6 @@
// Set the LP_HEADER_FLAG_VIRTUAL_AB_DEVICE flag.
void SetVirtualABDeviceFlag();
- // If set, checks for slot suffixes will be ignored internally.
- void IgnoreSlotSuffixing();
-
bool GetBlockDeviceInfo(const std::string& partition_name, BlockDeviceInfo* info) const;
bool UpdateBlockDeviceInfo(const std::string& partition_name, const BlockDeviceInfo& info);
diff --git a/init/README.md b/init/README.md
index b70366b..0dd1490 100644
--- a/init/README.md
+++ b/init/README.md
@@ -547,13 +547,16 @@
* `ref`: use the systemwide DE key
* `per_boot_ref`: use the key freshly generated on each boot.
-`mount_all <fstab> [ <path> ]\* [--<option>]`
+`mount_all [ <fstab> ] [--<option>]`
> Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
options "early" and "late".
With "--early" set, the init executable will skip mounting entries with
"latemount" flag and triggering fs encryption state event. With "--late" set,
init executable will only mount entries with "latemount" flag. By default,
no option is set, and mount\_all will process all entries in the given fstab.
+ If the fstab parameter is not specified, fstab.${ro.boot.fstab_suffix},
+ fstab.${ro.hardware} or fstab.${ro.hardware.platform} will be scanned for
+ under /odm/etc, /vendor/etc, or / at runtime, in that order.
`mount <type> <device> <dir> [ <flag>\* ] [<options>]`
> Attempt to mount the named device at the directory _dir_
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 149a766..e918e12 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -518,21 +518,21 @@
/* Imports .rc files from the specified paths. Default ones are applied if none is given.
*
- * start_index: index of the first path in the args list
+ * rc_paths: list of paths to rc files to import
*/
-static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
+static void import_late(const std::vector<std::string>& rc_paths) {
auto& action_manager = ActionManager::GetInstance();
auto& service_list = ServiceList::GetInstance();
Parser parser = CreateParser(action_manager, service_list);
- if (end_index <= start_index) {
+ if (rc_paths.empty()) {
// Fallbacks for partitions on which early mount isn't enabled.
for (const auto& path : late_import_paths) {
parser.ParseConfig(path);
}
late_import_paths.clear();
} else {
- for (size_t i = start_index; i < end_index; ++i) {
- parser.ParseConfig(args[i]);
+ for (const auto& rc_path : rc_paths) {
+ parser.ParseConfig(rc_path);
}
}
@@ -633,48 +633,44 @@
static int initial_mount_fstab_return_code = -1;
-/* mount_all <fstab> [ <path> ]* [--<options>]*
+/* <= Q: mount_all <fstab> [ <path> ]* [--<options>]*
+ * >= R: mount_all [ <fstab> ] [--<options>]*
*
* This function might request a reboot, in which case it will
* not return.
*/
static Result<void> do_mount_all(const BuiltinArguments& args) {
- std::size_t na = 0;
- bool import_rc = true;
- bool queue_event = true;
- int mount_mode = MOUNT_MODE_DEFAULT;
- const auto& fstab_file = args[1];
- std::size_t path_arg_end = args.size();
- const char* prop_post_fix = "default";
+ auto mount_all = ParseMountAll(args.args);
+ if (!mount_all.ok()) return mount_all.error();
- for (na = args.size() - 1; na > 1; --na) {
- if (args[na] == "--early") {
- path_arg_end = na;
- queue_event = false;
- mount_mode = MOUNT_MODE_EARLY;
- prop_post_fix = "early";
- } else if (args[na] == "--late") {
- path_arg_end = na;
- import_rc = false;
- mount_mode = MOUNT_MODE_LATE;
- prop_post_fix = "late";
- }
+ const char* prop_post_fix = "default";
+ bool queue_event = true;
+ if (mount_all->mode == MOUNT_MODE_EARLY) {
+ prop_post_fix = "early";
+ queue_event = false;
+ } else if (mount_all->mode == MOUNT_MODE_LATE) {
+ prop_post_fix = "late";
}
std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
android::base::Timer t;
Fstab fstab;
- if (!ReadFstabFromFile(fstab_file, &fstab)) {
- return Error() << "Could not read fstab";
+ if (mount_all->fstab_path.empty()) {
+ if (!ReadDefaultFstab(&fstab)) {
+ return Error() << "Could not read default fstab";
+ }
+ } else {
+ if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
+ return Error() << "Could not read fstab";
+ }
}
- auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode);
+ auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
SetProperty(prop_name, std::to_string(t.duration().count()));
- if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
- /* Paths of .rc files are specified at the 2nd argument and beyond */
- import_late(args.args, 2, path_arg_end);
+ if (mount_all->import_rc) {
+ import_late(mount_all->rc_paths);
}
if (queue_event) {
@@ -690,11 +686,20 @@
return {};
}
-/* umount_all <fstab> */
+/* umount_all [ <fstab> ] */
static Result<void> do_umount_all(const BuiltinArguments& args) {
+ auto umount_all = ParseUmountAll(args.args);
+ if (!umount_all.ok()) return umount_all.error();
+
Fstab fstab;
- if (!ReadFstabFromFile(args[1], &fstab)) {
- return Error() << "Could not read fstab";
+ if (umount_all->empty()) {
+ if (!ReadDefaultFstab(&fstab)) {
+ return Error() << "Could not read default fstab";
+ }
+ } else {
+ if (!ReadFstabFromFile(*umount_all, &fstab)) {
+ return Error() << "Could not read fstab";
+ }
}
if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
@@ -1349,11 +1354,11 @@
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
// imports rc scripts, etc. It should be simplified and run in vendor_init context.
// mount and umount are run in the same context as mount_all for symmetry.
- {"mount_all", {1, kMax, {false, do_mount_all}}},
+ {"mount_all", {0, kMax, {false, do_mount_all}}},
{"mount", {3, kMax, {false, do_mount}}},
{"perform_apex_config", {0, 0, {false, do_perform_apex_config}}},
{"umount", {1, 1, {false, do_umount}}},
- {"umount_all", {1, 1, {false, do_umount_all}}},
+ {"umount_all", {0, 1, {false, do_umount_all}}},
{"update_linker_config", {0, 0, {false, do_update_linker_config}}},
{"readahead", {1, 2, {true, do_readahead}}},
{"remount_userdata", {0, 0, {false, do_remount_userdata}}},
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index d1a84f3..450c079 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -123,6 +123,14 @@
return {};
}
+Result<void> check_mount_all(const BuiltinArguments& args) {
+ auto options = ParseMountAll(args.args);
+ if (!options.ok()) {
+ return options.error();
+ }
+ return {};
+}
+
Result<void> check_mkdir(const BuiltinArguments& args) {
auto options = ParseMkdir(args.args);
if (!options.ok()) {
@@ -204,6 +212,14 @@
return {};
}
+Result<void> check_umount_all(const BuiltinArguments& args) {
+ auto options = ParseUmountAll(args.args);
+ if (!options.ok()) {
+ return options.error();
+ }
+ return {};
+}
+
Result<void> check_wait(const BuiltinArguments& args) {
if (args.size() == 3 && !args[2].empty()) {
double timeout_double;
diff --git a/init/check_builtins.h b/init/check_builtins.h
index fb34556..725a6fd 100644
--- a/init/check_builtins.h
+++ b/init/check_builtins.h
@@ -32,11 +32,13 @@
Result<void> check_load_system_props(const BuiltinArguments& args);
Result<void> check_loglevel(const BuiltinArguments& args);
Result<void> check_mkdir(const BuiltinArguments& args);
+Result<void> check_mount_all(const BuiltinArguments& args);
Result<void> check_restorecon(const BuiltinArguments& args);
Result<void> check_restorecon_recursive(const BuiltinArguments& args);
Result<void> check_setprop(const BuiltinArguments& args);
Result<void> check_setrlimit(const BuiltinArguments& args);
Result<void> check_sysclktz(const BuiltinArguments& args);
+Result<void> check_umount_all(const BuiltinArguments& args);
Result<void> check_wait(const BuiltinArguments& args);
Result<void> check_wait_for_prop(const BuiltinArguments& args);
diff --git a/init/util.cpp b/init/util.cpp
index f9be055..40f24b1 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -572,6 +572,48 @@
return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
}
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
+ bool compat_mode = false;
+ bool import_rc = false;
+ if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+ if (args.size() <= 1) {
+ return Error() << "mount_all requires at least 1 argument";
+ }
+ compat_mode = true;
+ import_rc = true;
+ }
+
+ std::size_t first_option_arg = args.size();
+ enum mount_mode mode = MOUNT_MODE_DEFAULT;
+
+ // If we are <= Q, then stop looking for non-fstab arguments at slot 2.
+ // Otherwise, stop looking at slot 1 (as the fstab path argument is optional >= R).
+ for (std::size_t na = args.size() - 1; na > (compat_mode ? 1 : 0); --na) {
+ if (args[na] == "--early") {
+ first_option_arg = na;
+ mode = MOUNT_MODE_EARLY;
+ } else if (args[na] == "--late") {
+ first_option_arg = na;
+ mode = MOUNT_MODE_LATE;
+ import_rc = false;
+ }
+ }
+
+ std::string fstab_path;
+ if (first_option_arg > 1) {
+ fstab_path = args[1];
+ } else if (compat_mode) {
+ return Error() << "mount_all argument 1 must be the fstab path";
+ }
+
+ std::vector<std::string> rc_paths;
+ for (std::size_t na = 2; na < first_option_arg; ++na) {
+ rc_paths.push_back(args[na]);
+ }
+
+ return MountAllOptions{rc_paths, fstab_path, mode, import_rc};
+}
+
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
const std::vector<std::string>& args) {
struct flag_type {
@@ -612,6 +654,15 @@
return std::pair(flag, paths);
}
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args) {
+ if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+ if (args.size() <= 1) {
+ return Error() << "umount_all requires at least 1 argument";
+ }
+ }
+ return args[1];
+}
+
static void InitAborter(const char* abort_message) {
// When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
// simply abort instead of trying to reboot the system.
diff --git a/init/util.h b/init/util.h
index 8167b02..28f6b18 100644
--- a/init/util.h
+++ b/init/util.h
@@ -22,6 +22,7 @@
#include <chrono>
#include <functional>
#include <string>
+#include <vector>
#include <android-base/chrono_utils.h>
@@ -33,6 +34,12 @@
namespace android {
namespace init {
+enum mount_mode {
+ MOUNT_MODE_DEFAULT = 0,
+ MOUNT_MODE_EARLY = 1,
+ MOUNT_MODE_LATE = 2,
+};
+
static const char kColdBootDoneProp[] = "ro.cold_boot_done";
extern void (*trigger_shutdown)(const std::string& command);
@@ -73,9 +80,20 @@
Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
+struct MountAllOptions {
+ std::vector<std::string> rc_paths;
+ std::string fstab_path;
+ mount_mode mode;
+ bool import_rc;
+};
+
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args);
+
Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
const std::vector<std::string>& args);
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args);
+
void SetStdioToDevNull(char** argv);
void InitKernelLogging(char** argv);
void InitSecondStageLogging(char** argv);
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 0f7044a..ea39d34 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -246,6 +246,7 @@
"String8_test.cpp",
"String16_test.cpp",
"StrongPointer_test.cpp",
+ "Timers_test.cpp",
"Unicode_test.cpp",
"Vector_test.cpp",
],
diff --git a/libutils/Timers.cpp b/libutils/Timers.cpp
index 1172ae7..fd3f4a9 100644
--- a/libutils/Timers.cpp
+++ b/libutils/Timers.cpp
@@ -20,31 +20,37 @@
#include <utils/Timers.h>
#include <limits.h>
+#include <stdlib.h>
#include <time.h>
-// host linux support requires Linux 2.6.39+
+#include <android-base/macros.h>
+
+static constexpr size_t clock_id_max = 5;
+
+static void checkClockId(int clock) {
+ if (clock < 0 || clock >= clock_id_max) abort();
+}
+
#if defined(__linux__)
-nsecs_t systemTime(int clock)
-{
- static const clockid_t clocks[] = {
- CLOCK_REALTIME,
- CLOCK_MONOTONIC,
- CLOCK_PROCESS_CPUTIME_ID,
- CLOCK_THREAD_CPUTIME_ID,
- CLOCK_BOOTTIME
- };
- struct timespec t;
- t.tv_sec = t.tv_nsec = 0;
+nsecs_t systemTime(int clock) {
+ checkClockId(clock);
+ static constexpr clockid_t clocks[] = {CLOCK_REALTIME, CLOCK_MONOTONIC,
+ CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID,
+ CLOCK_BOOTTIME};
+ static_assert(clock_id_max == arraysize(clocks));
+ timespec t = {};
clock_gettime(clocks[clock], &t);
return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}
#else
-nsecs_t systemTime(int /*clock*/)
-{
+nsecs_t systemTime(int clock) {
+ // TODO: is this ever called with anything but REALTIME on mac/windows?
+ checkClockId(clock);
+
// Clock support varies widely across hosts. Mac OS doesn't support
- // CLOCK_BOOTTIME, and Windows is windows.
- struct timeval t;
- t.tv_sec = t.tv_usec = 0;
+ // CLOCK_BOOTTIME (and doesn't even have clock_gettime until 10.12).
+ // Windows is windows.
+ timeval t = {};
gettimeofday(&t, nullptr);
return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL;
}
diff --git a/libutils/Timers_test.cpp b/libutils/Timers_test.cpp
new file mode 100644
index 0000000..ec0051e
--- /dev/null
+++ b/libutils/Timers_test.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 <utils/Timers.h>
+
+#include <gtest/gtest.h>
+
+TEST(Timers, systemTime_invalid) {
+ EXPECT_EXIT(systemTime(-1), testing::KilledBySignal(SIGABRT), "");
+ systemTime(SYSTEM_TIME_REALTIME);
+ systemTime(SYSTEM_TIME_MONOTONIC);
+ systemTime(SYSTEM_TIME_PROCESS);
+ systemTime(SYSTEM_TIME_THREAD);
+ systemTime(SYSTEM_TIME_BOOTTIME);
+ EXPECT_EXIT(systemTime(SYSTEM_TIME_BOOTTIME + 1), testing::KilledBySignal(SIGABRT), "");
+}
diff --git a/libutils/include/utils/Timers.h b/libutils/include/utils/Timers.h
index 54ec474..197fc26 100644
--- a/libutils/include/utils/Timers.h
+++ b/libutils/include/utils/Timers.h
@@ -14,11 +14,7 @@
* limitations under the License.
*/
-//
-// Timer functions.
-//
-#ifndef _LIBS_UTILS_TIMERS_H
-#define _LIBS_UTILS_TIMERS_H
+#pragma once
#include <stdint.h>
#include <sys/types.h>
@@ -77,11 +73,11 @@
static CONSTEXPR inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
enum {
- SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock
- SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
- SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock
- SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock
- SYSTEM_TIME_BOOTTIME = 4 // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
+ SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock
+ SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
+ SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock
+ SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock
+ SYSTEM_TIME_BOOTTIME = 4, // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time
};
// return the system-time according to the specified clock
@@ -104,5 +100,3 @@
#ifdef __cplusplus
} // extern "C"
#endif
-
-#endif // _LIBS_UTILS_TIMERS_H
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 7f1e128..859d740 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -21,13 +21,11 @@
#include <functional>
#include <log/log.h>
-#include <sysutils/SocketClient.h>
+#include <log/log_read.h>
-#include "LogBufferElement.h"
+#include "LogWriter.h"
-class LogWriter;
-
-enum class FlushToResult {
+enum class FilterResult {
kSkip,
kStop,
kWrite,
@@ -45,10 +43,11 @@
// valid message was from the same source so we can differentiate chatty
// filter types (identical or expired)
static const uint64_t FLUSH_ERROR = 0;
- virtual uint64_t FlushTo(
- LogWriter* writer, uint64_t start,
- pid_t* last_tid, // nullable
- const std::function<FlushToResult(const LogBufferElement* element)>& filter) = 0;
+ virtual uint64_t FlushTo(LogWriter* writer, uint64_t start,
+ pid_t* last_tid, // nullable
+ const std::function<FilterResult(log_id_t log_id, pid_t pid,
+ uint64_t sequence, log_time realtime,
+ uint16_t dropped_count)>& filter) = 0;
virtual bool Clear(log_id_t id, uid_t uid) = 0;
virtual unsigned long GetSize(log_id_t id) = 0;
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 234ddc7..35c46aa 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -171,27 +171,29 @@
if (start != log_time::EPOCH) {
bool start_time_set = false;
uint64_t last = sequence;
- auto log_find_start = [pid, logMask, start, &sequence, &start_time_set,
- &last](const LogBufferElement* element) -> FlushToResult {
- if (pid && pid != element->getPid()) {
- return FlushToResult::kSkip;
+ auto log_find_start = [pid, logMask, start, &sequence, &start_time_set, &last](
+ log_id_t element_log_id, pid_t element_pid,
+ uint64_t element_sequence, log_time element_realtime,
+ uint16_t) -> FilterResult {
+ if (pid && pid != element_pid) {
+ return FilterResult::kSkip;
}
- if ((logMask & (1 << element->getLogId())) == 0) {
- return FlushToResult::kSkip;
+ if ((logMask & (1 << element_log_id)) == 0) {
+ return FilterResult::kSkip;
}
- if (start == element->getRealTime()) {
- sequence = element->getSequence();
+ if (start == element_realtime) {
+ sequence = element_sequence;
start_time_set = true;
- return FlushToResult::kStop;
+ return FilterResult::kStop;
} else {
- if (start < element->getRealTime()) {
+ if (start < element_realtime) {
sequence = last;
start_time_set = true;
- return FlushToResult::kStop;
+ return FilterResult::kStop;
}
- last = element->getSequence();
+ last = element_sequence;
}
- return FlushToResult::kSkip;
+ return FilterResult::kSkip;
};
log_buffer_->FlushTo(socket_log_writer.get(), sequence, nullptr, log_find_start);
diff --git a/logd/LogReaderThread.cpp b/logd/LogReaderThread.cpp
index b2001b5..3a83f3f 100644
--- a/logd/LogReaderThread.cpp
+++ b/logd/LogReaderThread.cpp
@@ -75,13 +75,21 @@
if (tail_) {
log_buffer_->FlushTo(writer_.get(), start, nullptr,
- std::bind(&LogReaderThread::FilterFirstPass, this, _1));
+ [this](log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count) {
+ return FilterFirstPass(log_id, pid, sequence, realtime,
+ dropped_count);
+ });
leading_dropped_ =
true; // TODO: Likely a bug, if leading_dropped_ was not true before calling
// flushTo(), then it should not be reset to true after.
}
start = log_buffer_->FlushTo(writer_.get(), start, last_tid_,
- std::bind(&LogReaderThread::FilterSecondPass, this, _1));
+ [this](log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count) {
+ return FilterSecondPass(log_id, pid, sequence, realtime,
+ dropped_count);
+ });
// We only ignore entries before the original start time for the first flushTo(), if we
// get entries after this first flush before the original start time, then the client
@@ -123,65 +131,67 @@
}
// A first pass to count the number of elements
-FlushToResult LogReaderThread::FilterFirstPass(const LogBufferElement* element) {
+FilterResult LogReaderThread::FilterFirstPass(log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count) {
auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
if (leading_dropped_) {
- if (element->getDropped()) {
- return FlushToResult::kSkip;
+ if (dropped_count) {
+ return FilterResult::kSkip;
}
leading_dropped_ = false;
}
if (count_ == 0) {
- start_ = element->getSequence();
+ start_ = sequence;
}
- if ((!pid_ || pid_ == element->getPid()) && IsWatching(element->getLogId()) &&
- (start_time_ == log_time::EPOCH || start_time_ <= element->getRealTime())) {
+ if ((!pid_ || pid_ == pid) && IsWatching(log_id) &&
+ (start_time_ == log_time::EPOCH || start_time_ <= realtime)) {
++count_;
}
- return FlushToResult::kSkip;
+ return FilterResult::kSkip;
}
// A second pass to send the selected elements
-FlushToResult LogReaderThread::FilterSecondPass(const LogBufferElement* element) {
+FilterResult LogReaderThread::FilterSecondPass(log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count) {
auto lock = std::lock_guard{reader_list_->reader_threads_lock()};
- start_ = element->getSequence();
+ start_ = sequence;
- if (skip_ahead_[element->getLogId()]) {
- skip_ahead_[element->getLogId()]--;
- return FlushToResult::kSkip;
+ if (skip_ahead_[log_id]) {
+ skip_ahead_[log_id]--;
+ return FilterResult::kSkip;
}
if (leading_dropped_) {
- if (element->getDropped()) {
- return FlushToResult::kSkip;
+ if (dropped_count) {
+ return FilterResult::kSkip;
}
leading_dropped_ = false;
}
// Truncate to close race between first and second pass
if (non_block_ && tail_ && index_ >= count_) {
- return FlushToResult::kStop;
+ return FilterResult::kStop;
}
- if (!IsWatching(element->getLogId())) {
- return FlushToResult::kSkip;
+ if (!IsWatching(log_id)) {
+ return FilterResult::kSkip;
}
- if (pid_ && pid_ != element->getPid()) {
- return FlushToResult::kSkip;
+ if (pid_ && pid_ != pid) {
+ return FilterResult::kSkip;
}
- if (start_time_ != log_time::EPOCH && element->getRealTime() <= start_time_) {
- return FlushToResult::kSkip;
+ if (start_time_ != log_time::EPOCH && realtime <= start_time_) {
+ return FilterResult::kSkip;
}
if (release_) {
- return FlushToResult::kStop;
+ return FilterResult::kStop;
}
if (!tail_) {
@@ -191,7 +201,7 @@
++index_;
if (count_ > tail_ && index_ <= (count_ - tail_)) {
- return FlushToResult::kSkip;
+ return FilterResult::kSkip;
}
if (!non_block_) {
@@ -199,10 +209,10 @@
}
ok:
- if (!skip_ahead_[element->getLogId()]) {
- return FlushToResult::kWrite;
+ if (!skip_ahead_[log_id]) {
+ return FilterResult::kWrite;
}
- return FlushToResult::kSkip;
+ return FilterResult::kSkip;
}
void LogReaderThread::cleanSkip_Locked(void) {
diff --git a/logd/LogReaderThread.h b/logd/LogReaderThread.h
index e48a3ca..ba81063 100644
--- a/logd/LogReaderThread.h
+++ b/logd/LogReaderThread.h
@@ -30,7 +30,6 @@
#include <sysutils/SocketClient.h>
#include "LogBuffer.h"
-#include "LogBufferElement.h"
#include "LogWriter.h"
class LogReaderList;
@@ -63,8 +62,10 @@
private:
void ThreadFunction();
// flushTo filter callbacks
- FlushToResult FilterFirstPass(const LogBufferElement* element);
- FlushToResult FilterSecondPass(const LogBufferElement* element);
+ FilterResult FilterFirstPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime,
+ uint16_t dropped_count);
+ FilterResult FilterSecondPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime,
+ uint16_t dropped_count);
std::condition_variable thread_triggered_condition_;
LogBuffer* log_buffer_;
diff --git a/logd/SimpleLogBuffer.cpp b/logd/SimpleLogBuffer.cpp
index 1c83428..8a11b92 100644
--- a/logd/SimpleLogBuffer.cpp
+++ b/logd/SimpleLogBuffer.cpp
@@ -112,7 +112,8 @@
uint64_t SimpleLogBuffer::FlushTo(
LogWriter* writer, uint64_t start, pid_t* last_tid,
- const std::function<FlushToResult(const LogBufferElement* element)>& filter) {
+ const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count)>& filter) {
auto shared_lock = SharedLock{lock_};
std::list<LogBufferElement>::iterator it;
@@ -146,11 +147,12 @@
}
if (filter) {
- FlushToResult ret = filter(&element);
- if (ret == FlushToResult::kSkip) {
+ FilterResult ret = filter(element.getLogId(), element.getPid(), element.getSequence(),
+ element.getRealTime(), element.getDropped());
+ if (ret == FilterResult::kSkip) {
continue;
}
- if (ret == FlushToResult::kStop) {
+ if (ret == FilterResult::kStop) {
break;
}
}
diff --git a/logd/SimpleLogBuffer.h b/logd/SimpleLogBuffer.h
index 9a2d01a..72d26b0 100644
--- a/logd/SimpleLogBuffer.h
+++ b/logd/SimpleLogBuffer.h
@@ -35,9 +35,10 @@
int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
uint16_t len) override;
- uint64_t FlushTo(
- LogWriter* writer, uint64_t start, pid_t* lastTid,
- const std::function<FlushToResult(const LogBufferElement* element)>& filter) override;
+ uint64_t FlushTo(LogWriter* writer, uint64_t start, pid_t* lastTid,
+ const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
+ log_time realtime, uint16_t dropped_count)>&
+ filter) override;
bool Clear(log_id_t id, uid_t uid) override;
unsigned long GetSize(log_id_t id) override;