kmsg_dump.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kmsg_dump.h>
  3. #include <linux/spinlock.h>
  4. #include <linux/console.h>
  5. #include <linux/string.h>
  6. #include <shared/init.h>
  7. #include <shared/kern.h>
  8. #include <os.h>
  9. static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
  10. struct kmsg_dump_detail *detail)
  11. {
  12. static struct kmsg_dump_iter iter;
  13. static DEFINE_SPINLOCK(lock);
  14. static char line[1024];
  15. struct console *con;
  16. unsigned long flags;
  17. size_t len = 0;
  18. int cookie;
  19. /*
  20. * If no consoles are available to output crash information, dump
  21. * the kmsg buffer to stdout.
  22. */
  23. cookie = console_srcu_read_lock();
  24. for_each_console_srcu(con) {
  25. /*
  26. * The ttynull console and disabled consoles are ignored
  27. * since they cannot output. All other consoles are
  28. * expected to output the crash information.
  29. */
  30. if (strcmp(con->name, "ttynull") != 0 &&
  31. (console_srcu_read_flags(con) & CON_ENABLED)) {
  32. break;
  33. }
  34. }
  35. console_srcu_read_unlock(cookie);
  36. if (con)
  37. return;
  38. if (!spin_trylock_irqsave(&lock, flags))
  39. return;
  40. kmsg_dump_rewind(&iter);
  41. printf("kmsg_dump:\n");
  42. while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
  43. line[len] = '\0';
  44. printf("%s", line);
  45. }
  46. spin_unlock_irqrestore(&lock, flags);
  47. }
  48. static struct kmsg_dumper kmsg_dumper = {
  49. .dump = kmsg_dumper_stdout
  50. };
  51. static int __init kmsg_dumper_stdout_init(void)
  52. {
  53. return kmsg_dump_register(&kmsg_dumper);
  54. }
  55. __uml_postsetup(kmsg_dumper_stdout_init);