aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/printk.c120
1 files changed, 78 insertions, 42 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 50c33411442d..177fa49357a5 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -194,8 +194,10 @@ static int console_may_schedule;
194 */ 194 */
195 195
196enum log_flags { 196enum log_flags {
197 LOG_DEFAULT = 0, 197 LOG_NOCONS = 1, /* already flushed, do not print to console */
198 LOG_NOCONS = 1, /* already flushed, do not print to console */ 198 LOG_NEWLINE = 2, /* text ended with a newline */
199 LOG_PREFIX = 4, /* text started with a prefix */
200 LOG_CONT = 8, /* text is a fragment of a continuation line */
199}; 201};
200 202
201struct log { 203struct log {
@@ -217,6 +219,7 @@ static DEFINE_RAW_SPINLOCK(logbuf_lock);
217/* the next printk record to read by syslog(READ) or /proc/kmsg */ 219/* the next printk record to read by syslog(READ) or /proc/kmsg */
218static u64 syslog_seq; 220static u64 syslog_seq;
219static u32 syslog_idx; 221static u32 syslog_idx;
222static enum log_flags syslog_prev;
220static size_t syslog_partial; 223static size_t syslog_partial;
221 224
222/* index and sequence number of the first record stored in the buffer */ 225/* index and sequence number of the first record stored in the buffer */
@@ -839,13 +842,26 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
839 return len; 842 return len;
840} 843}
841 844
842static size_t msg_print_text(const struct log *msg, bool syslog, 845static size_t msg_print_text(const struct log *msg, enum log_flags prev,
843 char *buf, size_t size) 846 bool syslog, char *buf, size_t size)
844{ 847{
845 const char *text = log_text(msg); 848 const char *text = log_text(msg);
846 size_t text_size = msg->text_len; 849 size_t text_size = msg->text_len;
850 bool prefix = true;
851 bool newline = true;
847 size_t len = 0; 852 size_t len = 0;
848 853
854 if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
855 prefix = false;
856
857 if (msg->flags & LOG_CONT) {
858 if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
859 prefix = false;
860
861 if (!(msg->flags & LOG_NEWLINE))
862 newline = false;
863 }
864
849 do { 865 do {
850 const char *next = memchr(text, '\n', text_size); 866 const char *next = memchr(text, '\n', text_size);
851 size_t text_len; 867 size_t text_len;
@@ -863,16 +879,22 @@ static size_t msg_print_text(const struct log *msg, bool syslog,
863 text_len + 1>= size - len) 879 text_len + 1>= size - len)
864 break; 880 break;
865 881
866 len += print_prefix(msg, syslog, buf + len); 882 if (prefix)
883 len += print_prefix(msg, syslog, buf + len);
867 memcpy(buf + len, text, text_len); 884 memcpy(buf + len, text, text_len);
868 len += text_len; 885 len += text_len;
869 buf[len++] = '\n'; 886 if (next || newline)
887 buf[len++] = '\n';
870 } else { 888 } else {
871 /* SYSLOG_ACTION_* buffer size only calculation */ 889 /* SYSLOG_ACTION_* buffer size only calculation */
872 len += print_prefix(msg, syslog, NULL); 890 if (prefix)
873 len += text_len + 1; 891 len += print_prefix(msg, syslog, NULL);
892 len += text_len;
893 if (next || newline)
894 len++;
874 } 895 }
875 896
897 prefix = true;
876 text = next; 898 text = next;
877 } while (text); 899 } while (text);
878 900
@@ -898,6 +920,7 @@ static int syslog_print(char __user *buf, int size)
898 /* messages are gone, move to first one */ 920 /* messages are gone, move to first one */
899 syslog_seq = log_first_seq; 921 syslog_seq = log_first_seq;
900 syslog_idx = log_first_idx; 922 syslog_idx = log_first_idx;
923 syslog_prev = 0;
901 syslog_partial = 0; 924 syslog_partial = 0;
902 } 925 }
903 if (syslog_seq == log_next_seq) { 926 if (syslog_seq == log_next_seq) {
@@ -907,11 +930,12 @@ static int syslog_print(char __user *buf, int size)
907 930
908 skip = syslog_partial; 931 skip = syslog_partial;
909 msg = log_from_idx(syslog_idx); 932 msg = log_from_idx(syslog_idx);
910 n = msg_print_text(msg, true, text, LOG_LINE_MAX); 933 n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
911 if (n - syslog_partial <= size) { 934 if (n - syslog_partial <= size) {
912 /* message fits into buffer, move forward */ 935 /* message fits into buffer, move forward */
913 syslog_idx = log_next(syslog_idx); 936 syslog_idx = log_next(syslog_idx);
914 syslog_seq++; 937 syslog_seq++;
938 syslog_prev = msg->flags;
915 n -= syslog_partial; 939 n -= syslog_partial;
916 syslog_partial = 0; 940 syslog_partial = 0;
917 } else if (!len){ 941 } else if (!len){
@@ -954,6 +978,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
954 u64 next_seq; 978 u64 next_seq;
955 u64 seq; 979 u64 seq;
956 u32 idx; 980 u32 idx;
981 enum log_flags prev;
957 982
958 if (clear_seq < log_first_seq) { 983 if (clear_seq < log_first_seq) {
959 /* messages are gone, move to first available one */ 984 /* messages are gone, move to first available one */
@@ -967,10 +992,11 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
967 */ 992 */
968 seq = clear_seq; 993 seq = clear_seq;
969 idx = clear_idx; 994 idx = clear_idx;
995 prev = 0;
970 while (seq < log_next_seq) { 996 while (seq < log_next_seq) {
971 struct log *msg = log_from_idx(idx); 997 struct log *msg = log_from_idx(idx);
972 998
973 len += msg_print_text(msg, true, NULL, 0); 999 len += msg_print_text(msg, prev, true, NULL, 0);
974 idx = log_next(idx); 1000 idx = log_next(idx);
975 seq++; 1001 seq++;
976 } 1002 }
@@ -978,10 +1004,11 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
978 /* move first record forward until length fits into the buffer */ 1004 /* move first record forward until length fits into the buffer */
979 seq = clear_seq; 1005 seq = clear_seq;
980 idx = clear_idx; 1006 idx = clear_idx;
1007 prev = 0;
981 while (len > size && seq < log_next_seq) { 1008 while (len > size && seq < log_next_seq) {
982 struct log *msg = log_from_idx(idx); 1009 struct log *msg = log_from_idx(idx);
983 1010
984 len -= msg_print_text(msg, true, NULL, 0); 1011 len -= msg_print_text(msg, prev, true, NULL, 0);
985 idx = log_next(idx); 1012 idx = log_next(idx);
986 seq++; 1013 seq++;
987 } 1014 }
@@ -990,17 +1017,19 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
990 next_seq = log_next_seq; 1017 next_seq = log_next_seq;
991 1018
992 len = 0; 1019 len = 0;
1020 prev = 0;
993 while (len >= 0 && seq < next_seq) { 1021 while (len >= 0 && seq < next_seq) {
994 struct log *msg = log_from_idx(idx); 1022 struct log *msg = log_from_idx(idx);
995 int textlen; 1023 int textlen;
996 1024
997 textlen = msg_print_text(msg, true, text, LOG_LINE_MAX); 1025 textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
998 if (textlen < 0) { 1026 if (textlen < 0) {
999 len = textlen; 1027 len = textlen;
1000 break; 1028 break;
1001 } 1029 }
1002 idx = log_next(idx); 1030 idx = log_next(idx);
1003 seq++; 1031 seq++;
1032 prev = msg->flags;
1004 1033
1005 raw_spin_unlock_irq(&logbuf_lock); 1034 raw_spin_unlock_irq(&logbuf_lock);
1006 if (copy_to_user(buf + len, text, textlen)) 1035 if (copy_to_user(buf + len, text, textlen))
@@ -1013,6 +1042,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1013 /* messages are gone, move to next one */ 1042 /* messages are gone, move to next one */
1014 seq = log_first_seq; 1043 seq = log_first_seq;
1015 idx = log_first_idx; 1044 idx = log_first_idx;
1045 prev = 0;
1016 } 1046 }
1017 } 1047 }
1018 } 1048 }
@@ -1117,6 +1147,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1117 /* messages are gone, move to first one */ 1147 /* messages are gone, move to first one */
1118 syslog_seq = log_first_seq; 1148 syslog_seq = log_first_seq;
1119 syslog_idx = log_first_idx; 1149 syslog_idx = log_first_idx;
1150 syslog_prev = 0;
1120 syslog_partial = 0; 1151 syslog_partial = 0;
1121 } 1152 }
1122 if (from_file) { 1153 if (from_file) {
@@ -1127,18 +1158,18 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1127 */ 1158 */
1128 error = log_next_idx - syslog_idx; 1159 error = log_next_idx - syslog_idx;
1129 } else { 1160 } else {
1130 u64 seq; 1161 u64 seq = syslog_seq;
1131 u32 idx; 1162 u32 idx = syslog_idx;
1163 enum log_flags prev = syslog_prev;
1132 1164
1133 error = 0; 1165 error = 0;
1134 seq = syslog_seq;
1135 idx = syslog_idx;
1136 while (seq < log_next_seq) { 1166 while (seq < log_next_seq) {
1137 struct log *msg = log_from_idx(idx); 1167 struct log *msg = log_from_idx(idx);
1138 1168
1139 error += msg_print_text(msg, true, NULL, 0); 1169 error += msg_print_text(msg, prev, true, NULL, 0);
1140 idx = log_next(idx); 1170 idx = log_next(idx);
1141 seq++; 1171 seq++;
1172 prev = msg->flags;
1142 } 1173 }
1143 error -= syslog_partial; 1174 error -= syslog_partial;
1144 } 1175 }
@@ -1408,10 +1439,9 @@ asmlinkage int vprintk_emit(int facility, int level,
1408 static char textbuf[LOG_LINE_MAX]; 1439 static char textbuf[LOG_LINE_MAX];
1409 char *text = textbuf; 1440 char *text = textbuf;
1410 size_t text_len; 1441 size_t text_len;
1442 enum log_flags lflags = 0;
1411 unsigned long flags; 1443 unsigned long flags;
1412 int this_cpu; 1444 int this_cpu;
1413 bool newline = false;
1414 bool prefix = false;
1415 int printed_len = 0; 1445 int printed_len = 0;
1416 1446
1417 boot_delay_msec(); 1447 boot_delay_msec();
@@ -1450,7 +1480,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1450 recursion_bug = 0; 1480 recursion_bug = 0;
1451 printed_len += strlen(recursion_msg); 1481 printed_len += strlen(recursion_msg);
1452 /* emit KERN_CRIT message */ 1482 /* emit KERN_CRIT message */
1453 log_store(0, 2, LOG_DEFAULT, 0, 1483 log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0,
1454 NULL, 0, recursion_msg, printed_len); 1484 NULL, 0, recursion_msg, printed_len);
1455 } 1485 }
1456 1486
@@ -1463,7 +1493,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1463 /* mark and strip a trailing newline */ 1493 /* mark and strip a trailing newline */
1464 if (text_len && text[text_len-1] == '\n') { 1494 if (text_len && text[text_len-1] == '\n') {
1465 text_len--; 1495 text_len--;
1466 newline = true; 1496 lflags |= LOG_NEWLINE;
1467 } 1497 }
1468 1498
1469 /* strip syslog prefix and extract log level or control flags */ 1499 /* strip syslog prefix and extract log level or control flags */
@@ -1473,7 +1503,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1473 if (level == -1) 1503 if (level == -1)
1474 level = text[1] - '0'; 1504 level = text[1] - '0';
1475 case 'd': /* KERN_DEFAULT */ 1505 case 'd': /* KERN_DEFAULT */
1476 prefix = true; 1506 lflags |= LOG_PREFIX;
1477 case 'c': /* KERN_CONT */ 1507 case 'c': /* KERN_CONT */
1478 text += 3; 1508 text += 3;
1479 text_len -= 3; 1509 text_len -= 3;
@@ -1483,22 +1513,20 @@ asmlinkage int vprintk_emit(int facility, int level,
1483 if (level == -1) 1513 if (level == -1)
1484 level = default_message_loglevel; 1514 level = default_message_loglevel;
1485 1515
1486 if (dict) { 1516 if (dict)
1487 prefix = true; 1517 lflags |= LOG_PREFIX|LOG_NEWLINE;
1488 newline = true;
1489 }
1490 1518
1491 if (!newline) { 1519 if (!(lflags & LOG_NEWLINE)) {
1492 /* 1520 /*
1493 * Flush the conflicting buffer. An earlier newline was missing, 1521 * Flush the conflicting buffer. An earlier newline was missing,
1494 * or another task also prints continuation lines. 1522 * or another task also prints continuation lines.
1495 */ 1523 */
1496 if (cont.len && (prefix || cont.owner != current)) 1524 if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
1497 cont_flush(); 1525 cont_flush();
1498 1526
1499 /* buffer line if possible, otherwise store it right away */ 1527 /* buffer line if possible, otherwise store it right away */
1500 if (!cont_add(facility, level, text, text_len)) 1528 if (!cont_add(facility, level, text, text_len))
1501 log_store(facility, level, LOG_DEFAULT, 0, 1529 log_store(facility, level, lflags | LOG_CONT, 0,
1502 dict, dictlen, text, text_len); 1530 dict, dictlen, text, text_len);
1503 } else { 1531 } else {
1504 bool stored = false; 1532 bool stored = false;
@@ -1510,13 +1538,13 @@ asmlinkage int vprintk_emit(int facility, int level,
1510 * flush it out and store this line separately. 1538 * flush it out and store this line separately.
1511 */ 1539 */
1512 if (cont.len && cont.owner == current) { 1540 if (cont.len && cont.owner == current) {
1513 if (!prefix) 1541 if (!(lflags & LOG_PREFIX))
1514 stored = cont_add(facility, level, text, text_len); 1542 stored = cont_add(facility, level, text, text_len);
1515 cont_flush(); 1543 cont_flush();
1516 } 1544 }
1517 1545
1518 if (!stored) 1546 if (!stored)
1519 log_store(facility, level, LOG_DEFAULT, 0, 1547 log_store(facility, level, lflags, 0,
1520 dict, dictlen, text, text_len); 1548 dict, dictlen, text, text_len);
1521 } 1549 }
1522 printed_len += text_len; 1550 printed_len += text_len;
@@ -1615,8 +1643,8 @@ static struct cont {
1615static struct log *log_from_idx(u32 idx) { return NULL; } 1643static struct log *log_from_idx(u32 idx) { return NULL; }
1616static u32 log_next(u32 idx) { return 0; } 1644static u32 log_next(u32 idx) { return 0; }
1617static void call_console_drivers(int level, const char *text, size_t len) {} 1645static void call_console_drivers(int level, const char *text, size_t len) {}
1618static size_t msg_print_text(const struct log *msg, bool syslog, 1646static size_t msg_print_text(const struct log *msg, enum log_flags prev,
1619 char *buf, size_t size) { return 0; } 1647 bool syslog, char *buf, size_t size) { return 0; }
1620static size_t cont_print_text(char *text, size_t size) { return 0; } 1648static size_t cont_print_text(char *text, size_t size) { return 0; }
1621 1649
1622#endif /* CONFIG_PRINTK */ 1650#endif /* CONFIG_PRINTK */
@@ -1892,6 +1920,7 @@ void wake_up_klogd(void)
1892/* the next printk record to write to the console */ 1920/* the next printk record to write to the console */
1893static u64 console_seq; 1921static u64 console_seq;
1894static u32 console_idx; 1922static u32 console_idx;
1923static enum log_flags console_prev;
1895 1924
1896/** 1925/**
1897 * console_unlock - unlock the console system 1926 * console_unlock - unlock the console system
@@ -1952,6 +1981,7 @@ again:
1952 /* messages are gone, move to first one */ 1981 /* messages are gone, move to first one */
1953 console_seq = log_first_seq; 1982 console_seq = log_first_seq;
1954 console_idx = log_first_idx; 1983 console_idx = log_first_idx;
1984 console_prev = 0;
1955 } 1985 }
1956skip: 1986skip:
1957 if (console_seq == log_next_seq) 1987 if (console_seq == log_next_seq)
@@ -1975,10 +2005,11 @@ skip:
1975 } 2005 }
1976 2006
1977 level = msg->level; 2007 level = msg->level;
1978 len = msg_print_text(msg, false, text, sizeof(text)); 2008 len = msg_print_text(msg, console_prev, false,
1979 2009 text, sizeof(text));
1980 console_idx = log_next(console_idx); 2010 console_idx = log_next(console_idx);
1981 console_seq++; 2011 console_seq++;
2012 console_prev = msg->flags;
1982 raw_spin_unlock(&logbuf_lock); 2013 raw_spin_unlock(&logbuf_lock);
1983 2014
1984 stop_critical_timings(); /* don't trace print latency */ 2015 stop_critical_timings(); /* don't trace print latency */
@@ -2241,6 +2272,7 @@ void register_console(struct console *newcon)
2241 raw_spin_lock_irqsave(&logbuf_lock, flags); 2272 raw_spin_lock_irqsave(&logbuf_lock, flags);
2242 console_seq = syslog_seq; 2273 console_seq = syslog_seq;
2243 console_idx = syslog_idx; 2274 console_idx = syslog_idx;
2275 console_prev = syslog_prev;
2244 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2276 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2245 /* 2277 /*
2246 * We're about to replay the log buffer. Only do this to the 2278 * We're about to replay the log buffer. Only do this to the
@@ -2534,8 +2566,7 @@ bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
2534 } 2566 }
2535 2567
2536 msg = log_from_idx(dumper->cur_idx); 2568 msg = log_from_idx(dumper->cur_idx);
2537 l = msg_print_text(msg, syslog, 2569 l = msg_print_text(msg, 0, syslog, line, size);
2538 line, size);
2539 2570
2540 dumper->cur_idx = log_next(dumper->cur_idx); 2571 dumper->cur_idx = log_next(dumper->cur_idx);
2541 dumper->cur_seq++; 2572 dumper->cur_seq++;
@@ -2575,6 +2606,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
2575 u32 idx; 2606 u32 idx;
2576 u64 next_seq; 2607 u64 next_seq;
2577 u32 next_idx; 2608 u32 next_idx;
2609 enum log_flags prev;
2578 size_t l = 0; 2610 size_t l = 0;
2579 bool ret = false; 2611 bool ret = false;
2580 2612
@@ -2597,23 +2629,27 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
2597 /* calculate length of entire buffer */ 2629 /* calculate length of entire buffer */
2598 seq = dumper->cur_seq; 2630 seq = dumper->cur_seq;
2599 idx = dumper->cur_idx; 2631 idx = dumper->cur_idx;
2632 prev = 0;
2600 while (seq < dumper->next_seq) { 2633 while (seq < dumper->next_seq) {
2601 struct log *msg = log_from_idx(idx); 2634 struct log *msg = log_from_idx(idx);
2602 2635
2603 l += msg_print_text(msg, true, NULL, 0); 2636 l += msg_print_text(msg, prev, true, NULL, 0);
2604 idx = log_next(idx); 2637 idx = log_next(idx);
2605 seq++; 2638 seq++;
2639 prev = msg->flags;
2606 } 2640 }
2607 2641
2608 /* move first record forward until length fits into the buffer */ 2642 /* move first record forward until length fits into the buffer */
2609 seq = dumper->cur_seq; 2643 seq = dumper->cur_seq;
2610 idx = dumper->cur_idx; 2644 idx = dumper->cur_idx;
2645 prev = 0;
2611 while (l > size && seq < dumper->next_seq) { 2646 while (l > size && seq < dumper->next_seq) {
2612 struct log *msg = log_from_idx(idx); 2647 struct log *msg = log_from_idx(idx);
2613 2648
2614 l -= msg_print_text(msg, true, NULL, 0); 2649 l -= msg_print_text(msg, prev, true, NULL, 0);
2615 idx = log_next(idx); 2650 idx = log_next(idx);
2616 seq++; 2651 seq++;
2652 prev = msg->flags;
2617 } 2653 }
2618 2654
2619 /* last message in next interation */ 2655 /* last message in next interation */
@@ -2621,14 +2657,14 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
2621 next_idx = idx; 2657 next_idx = idx;
2622 2658
2623 l = 0; 2659 l = 0;
2660 prev = 0;
2624 while (seq < dumper->next_seq) { 2661 while (seq < dumper->next_seq) {
2625 struct log *msg = log_from_idx(idx); 2662 struct log *msg = log_from_idx(idx);
2626 2663
2627 l += msg_print_text(msg, syslog, 2664 l += msg_print_text(msg, prev, syslog, buf + l, size - l);
2628 buf + l, size - l);
2629
2630 idx = log_next(idx); 2665 idx = log_next(idx);
2631 seq++; 2666 seq++;
2667 prev = msg->flags;
2632 } 2668 }
2633 2669
2634 dumper->next_seq = next_seq; 2670 dumper->next_seq = next_seq;