diff options
-rw-r--r-- | kernel/printk.c | 120 |
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 | ||
196 | enum log_flags { | 196 | enum 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 | ||
201 | struct log { | 203 | struct 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 */ |
218 | static u64 syslog_seq; | 220 | static u64 syslog_seq; |
219 | static u32 syslog_idx; | 221 | static u32 syslog_idx; |
222 | static enum log_flags syslog_prev; | ||
220 | static size_t syslog_partial; | 223 | static 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 | ||
842 | static size_t msg_print_text(const struct log *msg, bool syslog, | 845 | static 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 { | |||
1615 | static struct log *log_from_idx(u32 idx) { return NULL; } | 1643 | static struct log *log_from_idx(u32 idx) { return NULL; } |
1616 | static u32 log_next(u32 idx) { return 0; } | 1644 | static u32 log_next(u32 idx) { return 0; } |
1617 | static void call_console_drivers(int level, const char *text, size_t len) {} | 1645 | static void call_console_drivers(int level, const char *text, size_t len) {} |
1618 | static size_t msg_print_text(const struct log *msg, bool syslog, | 1646 | static 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; } |
1620 | static size_t cont_print_text(char *text, size_t size) { return 0; } | 1648 | static 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 */ |
1893 | static u64 console_seq; | 1921 | static u64 console_seq; |
1894 | static u32 console_idx; | 1922 | static u32 console_idx; |
1923 | static 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 | } |
1956 | skip: | 1986 | skip: |
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; |