Merge "healthd: BatteryMonitor: Fix compiler warning"
diff --git a/adb/daemon/remount_service.cpp b/adb/daemon/remount_service.cpp
index ae02525..2dcfb53 100644
--- a/adb/daemon/remount_service.cpp
+++ b/adb/daemon/remount_service.cpp
@@ -78,7 +78,13 @@
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
fs_mgr_free_fstab);
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab.get(), dir);
- return rec ? rec->blk_device : "";
+ if (!rec) {
+ return "";
+ }
+ if (fs_mgr_is_logical(rec)) {
+ fs_mgr_update_logical_partition(rec);
+ }
+ return rec->blk_device;
}
// The proc entry for / is full of lies, so check fstab instead.
@@ -87,7 +93,7 @@
if (is_root) {
return find_fstab_mount(dir);
} else {
- return find_proc_mount(dir);
+ return find_proc_mount(dir);
}
}
@@ -155,11 +161,12 @@
return true;
}
bool is_root = strcmp(dir, "/") == 0;
- if (is_root && !find_mount("/system", false).empty()) {
- dir = "/system";
- is_root = false;
- }
std::string dev = find_mount(dir, is_root);
+ if (is_root && dev.empty()) {
+ // The fstab entry will be /system if the device switched roots during
+ // first-stage init.
+ dev = find_mount("/system", true);
+ }
// Even if the device for the root is not found, we still try to remount it
// as rw. This typically only happens when running Android in a container:
// the root will almost always be in a loop device, which is dynamic, so
diff --git a/base/include/android-base/unique_fd.h b/base/include/android-base/unique_fd.h
index cd2dc04..4e3879b 100644
--- a/base/include/android-base/unique_fd.h
+++ b/base/include/android-base/unique_fd.h
@@ -19,6 +19,7 @@
#include <fcntl.h>
#if !defined(_WIN32)
+#include <dirent.h>
#include <sys/socket.h>
#endif
@@ -211,6 +212,17 @@
return file;
}
+// Using fdopendir with unique_fd correctly is more annoying than it should be,
+// because fdopen doesn't close the file descriptor received upon failure.
+inline DIR* Fdopendir(unique_fd&& ufd) {
+ int fd = ufd.release();
+ DIR* dir = fdopendir(fd);
+ if (dir == nullptr) {
+ close(fd);
+ }
+ return dir;
+}
+
#endif // !defined(_WIN32)
} // namespace base
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 6e45133..11c838a 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -329,7 +329,6 @@
private:
std::string super_device_;
- uint32_t slot_number_;
std::unique_ptr<MetadataBuilder> builder_;
};
@@ -341,8 +340,8 @@
super_device_ = *super_device;
std::string slot = device->GetCurrentSlot();
- slot_number_ = SlotNumberForSlotSuffix(slot);
- builder_ = MetadataBuilder::New(super_device_, slot_number_);
+ uint32_t slot_number = SlotNumberForSlotSuffix(slot);
+ builder_ = MetadataBuilder::New(super_device_, slot_number);
}
bool PartitionBuilder::Write() {
@@ -350,7 +349,11 @@
if (!metadata) {
return false;
}
- return UpdatePartitionTable(super_device_, *metadata.get(), slot_number_);
+ bool ok = true;
+ for (uint32_t i = 0; i < metadata->geometry.metadata_slot_count; i++) {
+ ok &= UpdatePartitionTable(super_device_, *metadata.get(), i);
+ }
+ return ok;
}
bool CreatePartitionHandler(FastbootDevice* device, const std::vector<std::string>& args) {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index ae2e2fe..c321fe3 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1588,6 +1588,25 @@
return true;
}
-std::string fs_mgr_get_super_partition_name(int /* slot */) {
+std::string fs_mgr_get_super_partition_name(int slot) {
+ // Devices upgrading to dynamic partitions are allowed to specify a super
+ // partition name, assumed to be A/B (non-A/B retrofit is not supported).
+ // For devices launching with dynamic partition support, the partition
+ // name must be "super".
+ std::string super_partition;
+ if (fs_mgr_get_boot_config_from_kernel_cmdline("super_partition", &super_partition)) {
+ std::string suffix;
+ if (slot == 0) {
+ suffix = "_a";
+ } else if (slot == 1) {
+ suffix = "_b";
+ } else if (slot == -1) {
+ suffix = fs_mgr_get_slot_suffix();
+ }
+ if (suffix.empty()) {
+ LFATAL << "Super partition name can only be overridden on A/B devices.";
+ }
+ return super_partition + suffix;
+ }
return LP_METADATA_DEFAULT_PARTITION_NAME;
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index f06b819..49ecc06 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <selinux/selinux.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/param.h>
@@ -692,13 +693,21 @@
errno = 0;
}
- auto ret = system((mnt_type == "f2fs")
- ? ((kMkF2fs + " -d1 " + scratch_device).c_str())
- : ((kMkExt4 + " -b 4096 -t ext4 -m 0 -M " + kScratchMountPoint +
- " -O has_journal " + scratch_device)
- .c_str()));
+ // Force mkfs by design for overlay support of adb remount, simplify and
+ // thus do not rely on fsck to correct problems that could creep in.
+ auto command = ""s;
+ if (mnt_type == "f2fs") {
+ command = kMkF2fs + " -w 4096 -f -d1 -l" + android::base::Basename(kScratchMountPoint);
+ } else if (mnt_type == "ext4") {
+ command = kMkExt4 + " -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
+ } else {
+ LERROR << mnt_type << " has no mkfs cookbook";
+ return false;
+ }
+ command += " " + scratch_device;
+ auto ret = system(command.c_str());
if (ret) {
- LERROR << "make " << mnt_type << " filesystem on " << scratch_device << " error=" << ret;
+ LERROR << "make " << mnt_type << " filesystem on " << scratch_device << " return=" << ret;
return false;
}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 5e83cfb..23a92d3 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -39,11 +39,13 @@
#define LINFO LOG(INFO) << FS_MGR_TAG
#define LWARNING LOG(WARNING) << FS_MGR_TAG
#define LERROR LOG(ERROR) << FS_MGR_TAG
+#define LFATAL LOG(FATAL) << FS_MGR_TAG
// Logs a message with strerror(errno) at the end
#define PINFO PLOG(INFO) << FS_MGR_TAG
#define PWARNING PLOG(WARNING) << FS_MGR_TAG
#define PERROR PLOG(ERROR) << FS_MGR_TAG
+#define PFATAL PLOG(FATAL) << FS_MGR_TAG
#define CRYPTO_TMPFS_OPTIONS "size=512m,mode=0771,uid=1000,gid=1000"
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index b6a8eef..6b908d3 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -198,39 +198,80 @@
# Do something
adb_wait || die "wait for device failed"
-adb_sh ls -d /sys/module/overlay </dev/null || die "overlay module not present"
-adb_su ls /sys/module/overlay/parameters/override_creds </dev/null ||
+adb_sh ls -d /sys/module/overlay </dev/null >/dev/null &&
+ echo "${GREEN}[ OK ]${NORMAL} overlay module present" >&2 ||
+ die "overlay module not present"
+adb_su ls /sys/module/overlay/parameters/override_creds </dev/null >/dev/null &&
+ echo "${GREEN}[ OK ]${NORMAL} overlay module supports override_creds" >&2 ||
die "overlay module can not be used on ANDROID"
adb_root &&
- adb_wait &&
- D=`adb disable-verity 2>&1` ||
- die "setup for overlay"
+ adb_wait ||
+ die "initial setup"
+reboot=false
+OVERLAYFS_BACKING="cache mnt/scratch"
+for d in ${OVERLAYFS_BACKING}; do
+ if adb_sh ls -d /${d}/overlay </dev/null >/dev/null 2>&1; then
+ echo "${ORANGE}[ WARNING ]${NORMAL} /${d}/overlay is setup, wiping" >&2
+ adb_sh rm -rf /${d}/overlay </dev/null ||
+ die "/${d}/overlay wipe"
+ reboot=true
+ fi
+done
+if ${reboot}; then
+ echo "${ORANGE}[ WARNING ]${NORMAL} rebooting before test" >&2
+ adb_reboot &&
+ adb_wait 2m &&
+ adb_root &&
+ adb_wait ||
+ die "reboot after wipe"
+fi
+D=`adb_sh df -k </dev/null` &&
+ H=`echo "${D}" | head -1` &&
+ D=`echo "${D}" | grep "^overlay "` &&
+ echo "${H}" &&
+ echo "${D}" &&
+ echo "${ORANGE}[ WARNING ]${NORMAL} overlays present before setup" >&2 ||
+ echo "${GREEN}[ OK ]${NORMAL} no overlay present before setup" >&2
+
+D=`adb disable-verity 2>&1` ||
+ die "setup for overlay ${D}"
echo "${D}"
if [ X"${D}" != X"${D##*using overlayfs}" ]; then
echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2
fi
-if adb_sh ls -d /data/overlay </dev/null >/dev/null 2>&1; then
- echo "/data/overlay setup, clearing out" >&2
- adb_sh rm -rf /data/overlay </dev/null ||
- die "/data/overlay removal"
-fi
-adb_sh ls -d /cache/overlay </dev/null >/dev/null 2>&1 ||
- adb_sh ls -d /mnt/scratch/overlay </dev/null >/dev/null 2>&1 ||
- die "overlay directory setup"
adb_reboot &&
adb_wait &&
- adb_sh df -k </dev/null | head -1 &&
- adb_sh df -k </dev/null | grep "^overlay " ||
+ D=`adb_sh df -k </dev/null` &&
+ H=`echo "${D}" | head -1` &&
+ D=`echo "${D}" | grep "^overlay "` &&
+ echo "${H}" &&
+ echo "${D}" ||
die "overlay takeover failed"
-adb_sh df -k </dev/null | grep "^overlay .* /system\$" >/dev/null ||
+echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
echo "${ORANGE}[ WARNING ]${NORMAL} overlay takeover before remount not complete" >&2
adb_root &&
adb_wait &&
adb remount &&
- adb_sh df -k </dev/null | head -1 &&
- adb_sh df -k </dev/null | grep "^overlay " &&
- adb_sh df -k </dev/null | grep "^overlay .* /system\$" >/dev/null ||
+ D=`adb_sh df -k </dev/null` ||
+ die "can not collect filesystem data"
+if echo "${D}" | grep " /mnt/scratch" >/dev/null; then
+ echo "${ORANGE}[ INFO ]${NORMAL} using scratch dynamic partition for overrides" >&2
+ H=`adb_sh cat /proc/mounts | sed -n 's@\([^ ]*\) /mnt/scratch \([^ ]*\) .*@\2 on \1@p'`
+ [ -n "${H}" ] &&
+ echo "${ORANGE}[ INFO ]${NORMAL} scratch filesystem ${H}"
+fi
+for d in ${OVERLAYFS_BACKING}; do
+ if adb_sh ls -d /${d}/overlay/system/upper </dev/null >/dev/null 2>&1; then
+ echo "${ORANGE}[ INFO ]${NORMAL} /${d}/overlay is setup" >&2
+ fi
+done
+
+H=`echo "${D}" | head -1` &&
+ D=`echo "${D}" | grep "^overlay "` &&
+ echo "${H}" &&
+ echo "${D}" &&
+ echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
die "overlay takeover after remount"
!(adb_sh grep "^overlay " /proc/mounts </dev/null | grep " overlay ro,") &&
!(adb_sh grep " rw," /proc/mounts </dev/null |
@@ -275,11 +316,14 @@
adb_wait &&
adb_root &&
adb_wait &&
- adb_sh df -k </dev/null | head -1 &&
- adb_sh df -k </dev/null | grep "^overlay " &&
- adb_sh df -k </dev/null | grep "^overlay .* /system\$" >/dev/null ||
+ D=`adb_sh df -k </dev/null` &&
+ H=`echo "${D}" | head -1` &&
+ D=`echo "${D}" | grep "^overlay "` &&
+ echo "${H}" &&
+ echo "${D}" &&
+ echo "${D}" | grep "^overlay .* /system\$" >/dev/null ||
die "overlay system takeover after flash vendor"
-adb_sh df -k </dev/null | grep "^overlay .* /vendor\$" >/dev/null &&
+echo "${D}" | grep "^overlay .* /vendor\$" >/dev/null &&
die "overlay minus vendor takeover after flash vendor"
B="`adb_cat /system/hello`" ||
die "re-read system hello after flash vendor"
diff --git a/init/Android.mk b/init/Android.mk
index c85727c..dc46d21 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -90,6 +90,8 @@
libcap \
LOCAL_SANITIZE := signed-integer-overflow
+# First stage init is weird: it may start without stdout/stderr, and no /proc.
+LOCAL_NOSANITIZE := hwaddress
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
diff --git a/init/devices.cpp b/init/devices.cpp
index 58c8b2e..45b17a2 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -419,7 +419,7 @@
}
void DeviceHandler::ColdbootDone() {
- skip_restorecon_ = true;
+ skip_restorecon_ = false;
}
DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h
index ee9220d..b2f0ed9 100644
--- a/liblog/include/android/log.h
+++ b/liblog/include/android/log.h
@@ -14,25 +14,7 @@
* limitations under the License.
*/
-#ifndef _ANDROID_LOG_H
-#define _ANDROID_LOG_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- * This file is part of Android's set of stable system headers
- * exposed by the Android NDK (Native Development Kit) since
- * platform release 1.5
- *
- * Third-party source AND binary code relies on the definitions
- * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
+#pragma once
/**
* @addtogroup Logging
@@ -154,27 +136,51 @@
#ifndef log_id_t_defined
#define log_id_t_defined
+/**
+ * Identifies a specific log buffer for __android_log_buf_write()
+ * and __android_log_buf_print().
+ */
typedef enum log_id {
LOG_ID_MIN = 0,
+ /** The main log buffer. This is the only log buffer available to apps. */
LOG_ID_MAIN = 0,
+ /** The radio log buffer. */
LOG_ID_RADIO = 1,
+ /** The event log buffer. */
LOG_ID_EVENTS = 2,
+ /** The system log buffer. */
LOG_ID_SYSTEM = 3,
+ /** The crash log buffer. */
LOG_ID_CRASH = 4,
+ /** The statistics log buffer. */
LOG_ID_STATS = 5,
+ /** The security log buffer. */
LOG_ID_SECURITY = 6,
- LOG_ID_KERNEL = 7, /* place last, third-parties can not use it */
+ /** The kernel log buffer. */
+ LOG_ID_KERNEL = 7,
LOG_ID_MAX
} log_id_t;
#endif
-/*
- * Send a simple string to the log.
+/**
+ * Writes the constant string `text` to the log buffer `id`,
+ * with priority `prio` and tag `tag`.
+ *
+ * Apps should use __android_log_write() instead.
*/
int __android_log_buf_write(int bufID, int prio, const char* tag,
const char* text);
+
+/**
+ * Writes a formatted string to log buffer `id`,
+ * with priority `prio` and tag `tag`.
+ * The details of formatting are the same as for
+ * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html).
+ *
+ * Apps should use __android_log_print() instead.
+ */
int __android_log_buf_print(int bufID, int prio, const char* tag,
const char* fmt, ...)
#if defined(__GNUC__)
@@ -187,5 +193,3 @@
#endif
/** @} */
-
-#endif /* _ANDROID_LOG_H */
diff --git a/llkd/README.md b/llkd/README.md
index e5be850..3da7a2f 100644
--- a/llkd/README.md
+++ b/llkd/README.md
@@ -44,7 +44,8 @@
ABA detection since forward scheduling progress is allowed, thus the condition
for the symbols are:
-- Check is looking for " " + __symbol__+ "0x" in /proc/<pid>/stack.
+- Check is looking for " __symbol__+0x" or " __symbol__.cfi+0x" in
+ /proc/__pid__/stack.
- The __symbol__ should be rare and short lived enough that on a typical
system the function is seen at most only once in a sample over the timeout
period of ro.llk.stack.timeout_ms, samples occur every ro.llk.check_ms. This
@@ -88,7 +89,14 @@
Android Properties llkd respond to (*prop*_ms parms are in milliseconds):
#### ro.config.low_ram
-default false, if true do not sysrq t (dump all threads).
+device is configured with limited memory.
+
+#### ro.debuggable
+device is configured for userdebug or eng build.
+
+#### ro.llk.sysrq_t
+default not ro.config.low_ram, or ro.debuggable if property is "eng".
+if true do sysrq t (dump all threads).
#### ro.llk.enable
default false, allow live-lock daemon to be enabled.
@@ -121,14 +129,14 @@
#### ro.llk.stack.timeout_ms
default ro.llk.timeout_ms,
checking for persistent stack symbols maximum timelimit.
-Only active on userdebug and eng builds.
+Only active on userdebug or eng builds.
#### ro.llk.check_ms
default 2 minutes samples of threads for D or Z.
#### ro.llk.stack
-default cma_alloc,__get_user_pages, comma separated list of kernel symbols.
-The string "*false*" is the equivalent to an *empty* list.
+default cma_alloc,__get_user_pages,bit_wait_io comma separated list of kernel
+symbols. The string "*false*" is the equivalent to an *empty* list.
Look for kernel stack symbols that if ever persistently present can
indicate a subsystem is locked up.
Beware, check does not on purpose do forward scheduling ABA except by polling
@@ -136,11 +144,14 @@
should be exceptionally rare and fleeting.
One must be convinced that it is virtually *impossible* for symbol to show up
persistently in all samples of the stack.
-Only active on userdebug and eng builds.
+Again, looks for a match for either " **symbol**+0x" or " **symbol**.cfi+0x"
+in stack expansion.
+Only available on userdebug or eng builds, limited privileges due to security
+concerns on user builds prevents this checking.
#### ro.llk.blacklist.process
default 0,1,2 (kernel, init and [kthreadd]) plus process names
-init,[kthreadd],[khungtaskd],lmkd,lmkd.llkd,llkd,watchdogd,
+init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd,
[watchdogd],[watchdogd/0],...,[watchdogd/***get_nprocs**-1*].
The string "*false*" is the equivalent to an *empty* list.
Do not watch these processes. A process can be comm, cmdline or pid reference.
@@ -160,7 +171,7 @@
Do not watch processes that match this uid.
#### ro.llk.blacklist.process.stack
-default process names init,lmkd,lmkd.llkd,llkd,keystore,logd.
+default process names init,lmkd.llkd,llkd,keystore,ueventd,apexd,logd.
The string "*false*" is the equivalent to an *empty* list.
This subset of processes are not monitored for live lock stack signatures.
Also prevents the sepolicy violation associated with processes that block
diff --git a/llkd/include/llkd.h b/llkd/include/llkd.h
index 2c62fca..b16b1d8 100644
--- a/llkd/include/llkd.h
+++ b/llkd/include/llkd.h
@@ -35,6 +35,8 @@
#define LLK_ENABLE_DEFAULT false /* "eng" and userdebug true */
#define KHT_ENABLE_WRITEABLE_PROPERTY "khungtask.enable"
#define KHT_ENABLE_PROPERTY "ro." KHT_ENABLE_WRITEABLE_PROPERTY
+#define LLK_ENABLE_SYSRQ_T_PROPERTY "ro.llk.sysrq_t"
+#define LLK_ENABLE_SYSRQ_T_DEFAULT true
#define LLK_MLOCKALL_PROPERTY "ro.llk.mlockall"
#define LLK_MLOCKALL_DEFAULT true
#define LLK_KILLTEST_PROPERTY "ro.llk.killtest"
@@ -48,7 +50,7 @@
/* LLK_CHECK_MS_DEFAULT = actual timeout_ms / LLK_CHECKS_PER_TIMEOUT_DEFAULT */
#define LLK_CHECKS_PER_TIMEOUT_DEFAULT 5
#define LLK_CHECK_STACK_PROPERTY "ro.llk.stack"
-#define LLK_CHECK_STACK_DEFAULT "cma_alloc,__get_user_pages"
+#define LLK_CHECK_STACK_DEFAULT "cma_alloc,__get_user_pages,bit_wait_io"
#define LLK_BLACKLIST_PROCESS_PROPERTY "ro.llk.blacklist.process"
#define LLK_BLACKLIST_PROCESS_DEFAULT \
"0,1,2,init,[kthreadd],[khungtaskd],lmkd,llkd,watchdogd,[watchdogd],[watchdogd/0]"
diff --git a/llkd/libllkd.cpp b/llkd/libllkd.cpp
index 2727aab..0827470 100644
--- a/llkd/libllkd.cpp
+++ b/llkd/libllkd.cpp
@@ -85,6 +85,7 @@
milliseconds llkCheckMs; // checking interval to inspect any
// persistent live-locked states
bool llkLowRam; // ro.config.low_ram
+bool llkEnableSysrqT = LLK_ENABLE_SYSRQ_T_DEFAULT; // sysrq stack trace dump
bool khtEnable = LLK_ENABLE_DEFAULT; // [khungtaskd] panic
// [khungtaskd] should have a timeout beyond the granularity of llkTimeoutMs.
// Provides a wide angle of margin b/c khtTimeout is also its granularity.
@@ -509,8 +510,10 @@
return android::base::Trim(content) == string;
}
-void llkPanicKernel(bool dump, pid_t tid, const char* state) __noreturn;
-void llkPanicKernel(bool dump, pid_t tid, const char* state) {
+void llkPanicKernel(bool dump, pid_t tid, const char* state,
+ const std::string& message = "") __noreturn;
+void llkPanicKernel(bool dump, pid_t tid, const char* state, const std::string& message) {
+ if (!message.empty()) LOG(ERROR) << message;
auto sysrqTriggerFd = llkFileToWriteFd("/proc/sysrq-trigger");
if (sysrqTriggerFd < 0) {
// DYB
@@ -523,14 +526,24 @@
if (dump) {
// Show all locks that are held
android::base::WriteStringToFd("d", sysrqTriggerFd);
+ // Show all waiting tasks
+ android::base::WriteStringToFd("w", sysrqTriggerFd);
// This can trigger hardware watchdog, that is somewhat _ok_.
// But useless if pstore configured for <256KB, low ram devices ...
- if (!llkLowRam) {
+ if (llkEnableSysrqT) {
android::base::WriteStringToFd("t", sysrqTriggerFd);
+ // Show all locks that are held (in case 't' overflows ramoops)
+ android::base::WriteStringToFd("d", sysrqTriggerFd);
+ // Show all waiting tasks (in case 't' overflows ramoops)
+ android::base::WriteStringToFd("w", sysrqTriggerFd);
}
::usleep(200000); // let everything settle
}
- llkWriteStringToFile("SysRq : Trigger a crash : 'livelock,"s + state + "'\n", "/dev/kmsg");
+ // SysRq message matches kernel format, and propagates through bootstat
+ // ultimately to the boot reason into panic,livelock,<state>.
+ llkWriteStringToFile(message + (message.empty() ? "" : "\n") +
+ "SysRq : Trigger a crash : 'livelock,"s + state + "'\n",
+ "/dev/kmsg");
android::base::WriteStringToFd("c", sysrqTriggerFd);
// NOTREACHED
// DYB
@@ -726,7 +739,8 @@
char match = -1;
for (const auto& stack : llkCheckStackSymbols) {
if (++idx < 0) break;
- if (kernel_stack.find(" "s + stack + "+0x") != std::string::npos) {
+ if ((kernel_stack.find(" "s + stack + "+0x") != std::string::npos) ||
+ (kernel_stack.find(" "s + stack + ".cfi+0x") != std::string::npos)) {
match = idx;
break;
}
@@ -798,6 +812,7 @@
void llkLogConfig(void) {
LOG(INFO) << "ro.config.low_ram=" << llkFormat(llkLowRam) << "\n"
+ << LLK_ENABLE_SYSRQ_T_PROPERTY "=" << llkFormat(llkEnableSysrqT) << "\n"
<< LLK_ENABLE_PROPERTY "=" << llkFormat(llkEnable) << "\n"
<< KHT_ENABLE_PROPERTY "=" << llkFormat(khtEnable) << "\n"
<< LLK_MLOCKALL_PROPERTY "=" << llkFormat(llkMlockall) << "\n"
@@ -1089,10 +1104,12 @@
}
}
// We are here because we have confirmed kernel live-lock
- LOG(ERROR) << state << ' ' << llkFormat(procp->count) << ' ' << ppid << "->" << pid
- << "->" << tid << ' ' << procp->getComm() << " [panic]";
+ const auto message = state + " "s + llkFormat(procp->count) + " " +
+ std::to_string(ppid) + "->" + std::to_string(pid) + "->" +
+ std::to_string(tid) + " " + procp->getComm() + " [panic]";
llkPanicKernel(true, tid,
- (state == 'Z') ? "zombie" : (state == 'D') ? "driver" : "sleeping");
+ (state == 'Z') ? "zombie" : (state == 'D') ? "driver" : "sleeping",
+ message);
}
LOG(VERBOSE) << "+closedir()";
}
@@ -1149,13 +1166,22 @@
return duration_cast<milliseconds>(llkCheck()).count();
}
+bool llkCheckEng(const std::string& property) {
+ return android::base::GetProperty(property, "eng") == "eng";
+}
+
bool llkInit(const char* threadname) {
auto debuggable = android::base::GetBoolProperty("ro.debuggable", false);
llkLowRam = android::base::GetBoolProperty("ro.config.low_ram", false);
- if (!LLK_ENABLE_DEFAULT && debuggable) {
- llkEnable = android::base::GetProperty(LLK_ENABLE_PROPERTY, "eng") == "eng";
- khtEnable = android::base::GetProperty(KHT_ENABLE_PROPERTY, "eng") == "eng";
+ llkEnableSysrqT &= !llkLowRam;
+ if (debuggable) {
+ llkEnableSysrqT |= llkCheckEng(LLK_ENABLE_SYSRQ_T_PROPERTY);
+ if (!LLK_ENABLE_DEFAULT) { // NB: default is currently true ...
+ llkEnable |= llkCheckEng(LLK_ENABLE_PROPERTY);
+ khtEnable |= llkCheckEng(KHT_ENABLE_PROPERTY);
+ }
}
+ llkEnableSysrqT = android::base::GetBoolProperty(LLK_ENABLE_SYSRQ_T_PROPERTY, llkEnableSysrqT);
llkEnable = android::base::GetBoolProperty(LLK_ENABLE_PROPERTY, llkEnable);
if (llkEnable && !llkTopDirectory.reset(procdir)) {
// Most likely reason we could be here is llkd was started