Skip to content

Instantly share code, notes, and snippets.

@updateing
Created January 11, 2020 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save updateing/4851d8978b35d4f3f70fc31b5a7bf0d3 to your computer and use it in GitHub Desktop.
Save updateing/4851d8978b35d4f3f70fc31b5a7bf0d3 to your computer and use it in GitHub Desktop.
Save a copy of kernel log to /cache during Android init. NOTE: this code is NOT complete!
diff --git a/init/reboot_utils.cpp b/init/reboot_utils.cpp
index de085cc9b..80edeb237 100644
--- a/init/reboot_utils.cpp
+++ b/init/reboot_utils.cpp
@@ -33,6 +33,75 @@
namespace android {
namespace init {
+extern "C" {
+ #include <errno.h>
+ #include <sys/mount.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/klog.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <fcntl.h>
+
+ /* Must be an existing directory */
+ #define CACHE_TMP_PATH "/cache"
+ #define KLOG_FILE "/cache/dmesg"
+ #define SYSLOG_BUF_SIZE (2*1024*1024)
+
+ void copy_dmesg_to_cache(const char *cache_dev, const char *fs) {
+ int ret = 0;
+ struct stat statbuf;
+ char *syslog_buf = NULL;
+ int syslog_len = -1;
+ int fd_to = -1;
+
+ if (fs == NULL) {
+ fs = "ext4";
+ }
+
+ memset(&statbuf, 0, sizeof(statbuf));
+ ret = stat(CACHE_TMP_PATH, &statbuf);
+ if (ret != 0 && errno == -ENOENT) {
+ /* Error and it does exist */
+ goto error;
+ } else if (!(statbuf.st_mode & S_IFDIR)) {
+ /* No error or it does not exist or it's a file */
+ unlink(CACHE_TMP_PATH);
+ }
+
+ ret = mount(cache_dev, CACHE_TMP_PATH, fs, 0, NULL);
+ if (ret != 0) {
+ goto error;
+ }
+
+ /* Must be read at once */
+ syslog_buf = (char *)malloc(SYSLOG_BUF_SIZE);
+ if (syslog_buf == NULL) {
+ goto error;
+ }
+
+ if ((syslog_len = klogctl(3 /* SYSLOG_ACTION_READ_ALL */, syslog_buf, SYSLOG_BUF_SIZE)) < 0) {
+ goto error;
+ }
+
+ fd_to = open(KLOG_FILE, O_WRONLY | O_CREAT | O_EXCL, 0666);
+ if (fd_to < 0) {
+ goto error;
+ }
+
+ write(fd_to, syslog_buf, syslog_len);
+ close(fd_to);
+ umount(CACHE_TMP_PATH);
+
+ error:
+ if (syslog_buf) {
+ free(syslog_buf);
+ }
+ return;
+ }
+}
+
static std::string init_fatal_reboot_target = "bootloader";
void SetFatalRebootTarget() {
@@ -150,6 +219,7 @@ void InstallRebootSignalHandlers() {
_exit(signal);
}
+ copy_dmesg_to_cache("/dev/block/mmcblk0p6", "ext4");
// Calling DoReboot() or LOG(FATAL) is not a good option as this is a signal handler.
// RebootSystem uses syscall() which isn't actually async-signal-safe, but our only option
// and probably good enough given this is already an error case and only enabled for
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment