ipanic_log.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <linux/version.h>
  2. #include <linux/module.h>
  3. #include "ipanic.h"
  4. #include "ipanic_version.h"
  5. u8 *log_temp;
  6. /*
  7. * The function is used to dump kernel log after *Linux 3.5*
  8. */
  9. size_t log_rest;
  10. u8 *log_idx;
  11. int ipanic_kmsg_dump3(struct kmsg_dumper *dumper, char *buf, size_t len)
  12. {
  13. size_t rc = 0;
  14. size_t sum = 0;
  15. /* if log_rest is no 0, it means that there some bytes left by previous log entry need to write to buf */
  16. if (log_rest != 0) {
  17. memcpy(buf, log_idx, log_rest);
  18. sum += log_rest;
  19. log_rest = 0;
  20. }
  21. while (kmsg_dump_get_line_nolock(dumper, false, log_temp, len, &rc)
  22. && dumper->cur_seq <= dumper->next_seq) {
  23. if (sum + rc >= len) {
  24. memcpy(buf + sum, log_temp, len - sum);
  25. log_rest = rc - (len - sum);
  26. log_idx = log_temp + (len - sum);
  27. sum += (len - sum);
  28. return len;
  29. }
  30. memcpy(buf + sum, log_temp, rc);
  31. sum += rc;
  32. }
  33. return sum;
  34. }
  35. EXPORT_SYMBOL(ipanic_kmsg_dump3);
  36. void ipanic_klog_region(struct kmsg_dumper *dumper)
  37. {
  38. static struct ipanic_log_index next = { 0 };
  39. dumper->cur_idx = next.seq ? next.idx : log_first_idx;
  40. dumper->cur_seq = next.seq ? next.seq : log_first_seq;
  41. dumper->next_idx = log_next_idx;
  42. dumper->next_seq = log_next_seq;
  43. next.idx = log_next_idx;
  44. next.seq = log_next_seq;
  45. LOGD("kernel log region: [%x:%llx,%x:%llx]", dumper->cur_idx, dumper->cur_seq,
  46. dumper->next_idx, dumper->next_seq);
  47. }
  48. int ipanic_klog_buffer(void *data, unsigned char *buffer, size_t sz_buf)
  49. {
  50. int rc = 0;
  51. struct kmsg_dumper *dumper = (struct kmsg_dumper *)data;
  52. dumper->active = true;
  53. rc = ipanic_kmsg_dump3(dumper, buffer, sz_buf);
  54. if (rc < 0)
  55. rc = -1;
  56. return rc;
  57. }
  58. void ipanic_log_temp_init(void)
  59. {
  60. log_temp = (u8 *) __get_free_page(GFP_KERNEL);
  61. }