aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/printk/printk.c109
1 files changed, 24 insertions, 85 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index a3ce35e0fa1e..50b2703d6d6a 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -356,7 +356,6 @@ DECLARE_WAIT_QUEUE_HEAD(log_wait);
356/* the next printk record to read by syslog(READ) or /proc/kmsg */ 356/* the next printk record to read by syslog(READ) or /proc/kmsg */
357static u64 syslog_seq; 357static u64 syslog_seq;
358static u32 syslog_idx; 358static u32 syslog_idx;
359static enum log_flags syslog_prev;
360static size_t syslog_partial; 359static size_t syslog_partial;
361 360
362/* index and sequence number of the first record stored in the buffer */ 361/* index and sequence number of the first record stored in the buffer */
@@ -370,7 +369,6 @@ static u32 log_next_idx;
370/* the next printk record to write to the console */ 369/* the next printk record to write to the console */
371static u64 console_seq; 370static u64 console_seq;
372static u32 console_idx; 371static u32 console_idx;
373static enum log_flags console_prev;
374 372
375/* the next printk record to read after the last 'clear' command */ 373/* the next printk record to read after the last 'clear' command */
376static u64 clear_seq; 374static u64 clear_seq;
@@ -639,27 +637,15 @@ static void append_char(char **pp, char *e, char c)
639} 637}
640 638
641static ssize_t msg_print_ext_header(char *buf, size_t size, 639static ssize_t msg_print_ext_header(char *buf, size_t size,
642 struct printk_log *msg, u64 seq, 640 struct printk_log *msg, u64 seq)
643 enum log_flags prev_flags)
644{ 641{
645 u64 ts_usec = msg->ts_nsec; 642 u64 ts_usec = msg->ts_nsec;
646 char cont = '-';
647 643
648 do_div(ts_usec, 1000); 644 do_div(ts_usec, 1000);
649 645
650 /*
651 * If we couldn't merge continuation line fragments during the print,
652 * export the stored flags to allow an optional external merge of the
653 * records. Merging the records isn't always neccessarily correct, like
654 * when we hit a race during printing. In most cases though, it produces
655 * better readable output. 'c' in the record flags mark the first
656 * fragment of a line, '+' the following.
657 */
658 if (msg->flags & LOG_CONT)
659 cont = (prev_flags & LOG_CONT) ? '+' : 'c';
660
661 return scnprintf(buf, size, "%u,%llu,%llu,%c;", 646 return scnprintf(buf, size, "%u,%llu,%llu,%c;",
662 (msg->facility << 3) | msg->level, seq, ts_usec, cont); 647 (msg->facility << 3) | msg->level, seq, ts_usec,
648 msg->flags & LOG_CONT ? 'c' : '-');
663} 649}
664 650
665static ssize_t msg_print_ext_body(char *buf, size_t size, 651static ssize_t msg_print_ext_body(char *buf, size_t size,
@@ -714,7 +700,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t size,
714struct devkmsg_user { 700struct devkmsg_user {
715 u64 seq; 701 u64 seq;
716 u32 idx; 702 u32 idx;
717 enum log_flags prev;
718 struct ratelimit_state rs; 703 struct ratelimit_state rs;
719 struct mutex lock; 704 struct mutex lock;
720 char buf[CONSOLE_EXT_LOG_MAX]; 705 char buf[CONSOLE_EXT_LOG_MAX];
@@ -824,12 +809,11 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
824 809
825 msg = log_from_idx(user->idx); 810 msg = log_from_idx(user->idx);
826 len = msg_print_ext_header(user->buf, sizeof(user->buf), 811 len = msg_print_ext_header(user->buf, sizeof(user->buf),
827 msg, user->seq, user->prev); 812 msg, user->seq);
828 len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len, 813 len += msg_print_ext_body(user->buf + len, sizeof(user->buf) - len,
829 log_dict(msg), msg->dict_len, 814 log_dict(msg), msg->dict_len,
830 log_text(msg), msg->text_len); 815 log_text(msg), msg->text_len);
831 816
832 user->prev = msg->flags;
833 user->idx = log_next(user->idx); 817 user->idx = log_next(user->idx);
834 user->seq++; 818 user->seq++;
835 raw_spin_unlock_irq(&logbuf_lock); 819 raw_spin_unlock_irq(&logbuf_lock);
@@ -1210,26 +1194,12 @@ static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
1210 return len; 1194 return len;
1211} 1195}
1212 1196
1213static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, 1197static size_t msg_print_text(const struct printk_log *msg, bool syslog, char *buf, size_t size)
1214 bool syslog, char *buf, size_t size)
1215{ 1198{
1216 const char *text = log_text(msg); 1199 const char *text = log_text(msg);
1217 size_t text_size = msg->text_len; 1200 size_t text_size = msg->text_len;
1218 bool prefix = true;
1219 bool newline = true;
1220 size_t len = 0; 1201 size_t len = 0;
1221 1202
1222 if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX))
1223 prefix = false;
1224
1225 if (msg->flags & LOG_CONT) {
1226 if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE))
1227 prefix = false;
1228
1229 if (!(msg->flags & LOG_NEWLINE))
1230 newline = false;
1231 }
1232
1233 do { 1203 do {
1234 const char *next = memchr(text, '\n', text_size); 1204 const char *next = memchr(text, '\n', text_size);
1235 size_t text_len; 1205 size_t text_len;
@@ -1247,22 +1217,17 @@ static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
1247 text_len + 1 >= size - len) 1217 text_len + 1 >= size - len)
1248 break; 1218 break;
1249 1219
1250 if (prefix) 1220 len += print_prefix(msg, syslog, buf + len);
1251 len += print_prefix(msg, syslog, buf + len);
1252 memcpy(buf + len, text, text_len); 1221 memcpy(buf + len, text, text_len);
1253 len += text_len; 1222 len += text_len;
1254 if (next || newline) 1223 buf[len++] = '\n';
1255 buf[len++] = '\n';
1256 } else { 1224 } else {
1257 /* SYSLOG_ACTION_* buffer size only calculation */ 1225 /* SYSLOG_ACTION_* buffer size only calculation */
1258 if (prefix) 1226 len += print_prefix(msg, syslog, NULL);
1259 len += print_prefix(msg, syslog, NULL);
1260 len += text_len; 1227 len += text_len;
1261 if (next || newline) 1228 len++;
1262 len++;
1263 } 1229 }
1264 1230
1265 prefix = true;
1266 text = next; 1231 text = next;
1267 } while (text); 1232 } while (text);
1268 1233
@@ -1288,7 +1253,6 @@ static int syslog_print(char __user *buf, int size)
1288 /* messages are gone, move to first one */ 1253 /* messages are gone, move to first one */
1289 syslog_seq = log_first_seq; 1254 syslog_seq = log_first_seq;
1290 syslog_idx = log_first_idx; 1255 syslog_idx = log_first_idx;
1291 syslog_prev = 0;
1292 syslog_partial = 0; 1256 syslog_partial = 0;
1293 } 1257 }
1294 if (syslog_seq == log_next_seq) { 1258 if (syslog_seq == log_next_seq) {
@@ -1298,13 +1262,11 @@ static int syslog_print(char __user *buf, int size)
1298 1262
1299 skip = syslog_partial; 1263 skip = syslog_partial;
1300 msg = log_from_idx(syslog_idx); 1264 msg = log_from_idx(syslog_idx);
1301 n = msg_print_text(msg, syslog_prev, true, text, 1265 n = msg_print_text(msg, true, text, LOG_LINE_MAX + PREFIX_MAX);
1302 LOG_LINE_MAX + PREFIX_MAX);
1303 if (n - syslog_partial <= size) { 1266 if (n - syslog_partial <= size) {
1304 /* message fits into buffer, move forward */ 1267 /* message fits into buffer, move forward */
1305 syslog_idx = log_next(syslog_idx); 1268 syslog_idx = log_next(syslog_idx);
1306 syslog_seq++; 1269 syslog_seq++;
1307 syslog_prev = msg->flags;
1308 n -= syslog_partial; 1270 n -= syslog_partial;
1309 syslog_partial = 0; 1271 syslog_partial = 0;
1310 } else if (!len){ 1272 } else if (!len){
@@ -1347,7 +1309,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1347 u64 next_seq; 1309 u64 next_seq;
1348 u64 seq; 1310 u64 seq;
1349 u32 idx; 1311 u32 idx;
1350 enum log_flags prev;
1351 1312
1352 /* 1313 /*
1353 * Find first record that fits, including all following records, 1314 * Find first record that fits, including all following records,
@@ -1355,12 +1316,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1355 */ 1316 */
1356 seq = clear_seq; 1317 seq = clear_seq;
1357 idx = clear_idx; 1318 idx = clear_idx;
1358 prev = 0;
1359 while (seq < log_next_seq) { 1319 while (seq < log_next_seq) {
1360 struct printk_log *msg = log_from_idx(idx); 1320 struct printk_log *msg = log_from_idx(idx);
1361 1321
1362 len += msg_print_text(msg, prev, true, NULL, 0); 1322 len += msg_print_text(msg, true, NULL, 0);
1363 prev = msg->flags;
1364 idx = log_next(idx); 1323 idx = log_next(idx);
1365 seq++; 1324 seq++;
1366 } 1325 }
@@ -1368,12 +1327,10 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1368 /* move first record forward until length fits into the buffer */ 1327 /* move first record forward until length fits into the buffer */
1369 seq = clear_seq; 1328 seq = clear_seq;
1370 idx = clear_idx; 1329 idx = clear_idx;
1371 prev = 0;
1372 while (len > size && seq < log_next_seq) { 1330 while (len > size && seq < log_next_seq) {
1373 struct printk_log *msg = log_from_idx(idx); 1331 struct printk_log *msg = log_from_idx(idx);
1374 1332
1375 len -= msg_print_text(msg, prev, true, NULL, 0); 1333 len -= msg_print_text(msg, true, NULL, 0);
1376 prev = msg->flags;
1377 idx = log_next(idx); 1334 idx = log_next(idx);
1378 seq++; 1335 seq++;
1379 } 1336 }
@@ -1386,7 +1343,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1386 struct printk_log *msg = log_from_idx(idx); 1343 struct printk_log *msg = log_from_idx(idx);
1387 int textlen; 1344 int textlen;
1388 1345
1389 textlen = msg_print_text(msg, prev, true, text, 1346 textlen = msg_print_text(msg, true, text,
1390 LOG_LINE_MAX + PREFIX_MAX); 1347 LOG_LINE_MAX + PREFIX_MAX);
1391 if (textlen < 0) { 1348 if (textlen < 0) {
1392 len = textlen; 1349 len = textlen;
@@ -1394,7 +1351,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1394 } 1351 }
1395 idx = log_next(idx); 1352 idx = log_next(idx);
1396 seq++; 1353 seq++;
1397 prev = msg->flags;
1398 1354
1399 raw_spin_unlock_irq(&logbuf_lock); 1355 raw_spin_unlock_irq(&logbuf_lock);
1400 if (copy_to_user(buf + len, text, textlen)) 1356 if (copy_to_user(buf + len, text, textlen))
@@ -1407,7 +1363,6 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1407 /* messages are gone, move to next one */ 1363 /* messages are gone, move to next one */
1408 seq = log_first_seq; 1364 seq = log_first_seq;
1409 idx = log_first_idx; 1365 idx = log_first_idx;
1410 prev = 0;
1411 } 1366 }
1412 } 1367 }
1413 } 1368 }
@@ -1508,7 +1463,6 @@ int do_syslog(int type, char __user *buf, int len, int source)
1508 /* messages are gone, move to first one */ 1463 /* messages are gone, move to first one */
1509 syslog_seq = log_first_seq; 1464 syslog_seq = log_first_seq;
1510 syslog_idx = log_first_idx; 1465 syslog_idx = log_first_idx;
1511 syslog_prev = 0;
1512 syslog_partial = 0; 1466 syslog_partial = 0;
1513 } 1467 }
1514 if (source == SYSLOG_FROM_PROC) { 1468 if (source == SYSLOG_FROM_PROC) {
@@ -1521,16 +1475,14 @@ int do_syslog(int type, char __user *buf, int len, int source)
1521 } else { 1475 } else {
1522 u64 seq = syslog_seq; 1476 u64 seq = syslog_seq;
1523 u32 idx = syslog_idx; 1477 u32 idx = syslog_idx;
1524 enum log_flags prev = syslog_prev;
1525 1478
1526 error = 0; 1479 error = 0;
1527 while (seq < log_next_seq) { 1480 while (seq < log_next_seq) {
1528 struct printk_log *msg = log_from_idx(idx); 1481 struct printk_log *msg = log_from_idx(idx);
1529 1482
1530 error += msg_print_text(msg, prev, true, NULL, 0); 1483 error += msg_print_text(msg, true, NULL, 0);
1531 idx = log_next(idx); 1484 idx = log_next(idx);
1532 seq++; 1485 seq++;
1533 prev = msg->flags;
1534 } 1486 }
1535 error -= syslog_partial; 1487 error -= syslog_partial;
1536 } 1488 }
@@ -1712,7 +1664,7 @@ static size_t cont_print_text(char *text, size_t size)
1712 size_t textlen = 0; 1664 size_t textlen = 0;
1713 size_t len; 1665 size_t len;
1714 1666
1715 if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) { 1667 if (cont.cons == 0) {
1716 textlen += print_time(cont.ts_nsec, text); 1668 textlen += print_time(cont.ts_nsec, text);
1717 size -= textlen; 1669 size -= textlen;
1718 } 1670 }
@@ -1981,11 +1933,9 @@ static u64 syslog_seq;
1981static u32 syslog_idx; 1933static u32 syslog_idx;
1982static u64 console_seq; 1934static u64 console_seq;
1983static u32 console_idx; 1935static u32 console_idx;
1984static enum log_flags syslog_prev;
1985static u64 log_first_seq; 1936static u64 log_first_seq;
1986static u32 log_first_idx; 1937static u32 log_first_idx;
1987static u64 log_next_seq; 1938static u64 log_next_seq;
1988static enum log_flags console_prev;
1989static struct cont { 1939static struct cont {
1990 size_t len; 1940 size_t len;
1991 size_t cons; 1941 size_t cons;
@@ -1997,15 +1947,15 @@ static char *log_dict(const struct printk_log *msg) { return NULL; }
1997static struct printk_log *log_from_idx(u32 idx) { return NULL; } 1947static struct printk_log *log_from_idx(u32 idx) { return NULL; }
1998static u32 log_next(u32 idx) { return 0; } 1948static u32 log_next(u32 idx) { return 0; }
1999static ssize_t msg_print_ext_header(char *buf, size_t size, 1949static ssize_t msg_print_ext_header(char *buf, size_t size,
2000 struct printk_log *msg, u64 seq, 1950 struct printk_log *msg,
2001 enum log_flags prev_flags) { return 0; } 1951 u64 seq) { return 0; }
2002static ssize_t msg_print_ext_body(char *buf, size_t size, 1952static ssize_t msg_print_ext_body(char *buf, size_t size,
2003 char *dict, size_t dict_len, 1953 char *dict, size_t dict_len,
2004 char *text, size_t text_len) { return 0; } 1954 char *text, size_t text_len) { return 0; }
2005static void call_console_drivers(int level, 1955static void call_console_drivers(int level,
2006 const char *ext_text, size_t ext_len, 1956 const char *ext_text, size_t ext_len,
2007 const char *text, size_t len) {} 1957 const char *text, size_t len) {}
2008static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev, 1958static size_t msg_print_text(const struct printk_log *msg,
2009 bool syslog, char *buf, size_t size) { return 0; } 1959 bool syslog, char *buf, size_t size) { return 0; }
2010static size_t cont_print_text(char *text, size_t size) { return 0; } 1960static size_t cont_print_text(char *text, size_t size) { return 0; }
2011static bool suppress_message_printing(int level) { return false; } 1961static bool suppress_message_printing(int level) { return false; }
@@ -2382,7 +2332,6 @@ again:
2382 /* messages are gone, move to first one */ 2332 /* messages are gone, move to first one */
2383 console_seq = log_first_seq; 2333 console_seq = log_first_seq;
2384 console_idx = log_first_idx; 2334 console_idx = log_first_idx;
2385 console_prev = 0;
2386 } else { 2335 } else {
2387 len = 0; 2336 len = 0;
2388 } 2337 }
@@ -2407,16 +2356,14 @@ skip:
2407 * will properly dump everything later. 2356 * will properly dump everything later.
2408 */ 2357 */
2409 msg->flags &= ~LOG_NOCONS; 2358 msg->flags &= ~LOG_NOCONS;
2410 console_prev = msg->flags;
2411 goto skip; 2359 goto skip;
2412 } 2360 }
2413 2361
2414 len += msg_print_text(msg, console_prev, false, 2362 len += msg_print_text(msg, false, text + len, sizeof(text) - len);
2415 text + len, sizeof(text) - len);
2416 if (nr_ext_console_drivers) { 2363 if (nr_ext_console_drivers) {
2417 ext_len = msg_print_ext_header(ext_text, 2364 ext_len = msg_print_ext_header(ext_text,
2418 sizeof(ext_text), 2365 sizeof(ext_text),
2419 msg, console_seq, console_prev); 2366 msg, console_seq);
2420 ext_len += msg_print_ext_body(ext_text + ext_len, 2367 ext_len += msg_print_ext_body(ext_text + ext_len,
2421 sizeof(ext_text) - ext_len, 2368 sizeof(ext_text) - ext_len,
2422 log_dict(msg), msg->dict_len, 2369 log_dict(msg), msg->dict_len,
@@ -2424,7 +2371,6 @@ skip:
2424 } 2371 }
2425 console_idx = log_next(console_idx); 2372 console_idx = log_next(console_idx);
2426 console_seq++; 2373 console_seq++;
2427 console_prev = msg->flags;
2428 raw_spin_unlock(&logbuf_lock); 2374 raw_spin_unlock(&logbuf_lock);
2429 2375
2430 stop_critical_timings(); /* don't trace print latency */ 2376 stop_critical_timings(); /* don't trace print latency */
@@ -2719,7 +2665,6 @@ void register_console(struct console *newcon)
2719 raw_spin_lock_irqsave(&logbuf_lock, flags); 2665 raw_spin_lock_irqsave(&logbuf_lock, flags);
2720 console_seq = syslog_seq; 2666 console_seq = syslog_seq;
2721 console_idx = syslog_idx; 2667 console_idx = syslog_idx;
2722 console_prev = syslog_prev;
2723 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2668 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2724 /* 2669 /*
2725 * We're about to replay the log buffer. Only do this to the 2670 * We're about to replay the log buffer. Only do this to the
@@ -3075,7 +3020,7 @@ bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
3075 goto out; 3020 goto out;
3076 3021
3077 msg = log_from_idx(dumper->cur_idx); 3022 msg = log_from_idx(dumper->cur_idx);
3078 l = msg_print_text(msg, 0, syslog, line, size); 3023 l = msg_print_text(msg, syslog, line, size);
3079 3024
3080 dumper->cur_idx = log_next(dumper->cur_idx); 3025 dumper->cur_idx = log_next(dumper->cur_idx);
3081 dumper->cur_seq++; 3026 dumper->cur_seq++;
@@ -3144,7 +3089,6 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3144 u32 idx; 3089 u32 idx;
3145 u64 next_seq; 3090 u64 next_seq;
3146 u32 next_idx; 3091 u32 next_idx;
3147 enum log_flags prev;
3148 size_t l = 0; 3092 size_t l = 0;
3149 bool ret = false; 3093 bool ret = false;
3150 3094
@@ -3167,27 +3111,23 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3167 /* calculate length of entire buffer */ 3111 /* calculate length of entire buffer */
3168 seq = dumper->cur_seq; 3112 seq = dumper->cur_seq;
3169 idx = dumper->cur_idx; 3113 idx = dumper->cur_idx;
3170 prev = 0;
3171 while (seq < dumper->next_seq) { 3114 while (seq < dumper->next_seq) {
3172 struct printk_log *msg = log_from_idx(idx); 3115 struct printk_log *msg = log_from_idx(idx);
3173 3116
3174 l += msg_print_text(msg, prev, true, NULL, 0); 3117 l += msg_print_text(msg, true, NULL, 0);
3175 idx = log_next(idx); 3118 idx = log_next(idx);
3176 seq++; 3119 seq++;
3177 prev = msg->flags;
3178 } 3120 }
3179 3121
3180 /* move first record forward until length fits into the buffer */ 3122 /* move first record forward until length fits into the buffer */
3181 seq = dumper->cur_seq; 3123 seq = dumper->cur_seq;
3182 idx = dumper->cur_idx; 3124 idx = dumper->cur_idx;
3183 prev = 0;
3184 while (l > size && seq < dumper->next_seq) { 3125 while (l > size && seq < dumper->next_seq) {
3185 struct printk_log *msg = log_from_idx(idx); 3126 struct printk_log *msg = log_from_idx(idx);
3186 3127
3187 l -= msg_print_text(msg, prev, true, NULL, 0); 3128 l -= msg_print_text(msg, true, NULL, 0);
3188 idx = log_next(idx); 3129 idx = log_next(idx);
3189 seq++; 3130 seq++;
3190 prev = msg->flags;
3191 } 3131 }
3192 3132
3193 /* last message in next interation */ 3133 /* last message in next interation */
@@ -3198,10 +3138,9 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
3198 while (seq < dumper->next_seq) { 3138 while (seq < dumper->next_seq) {
3199 struct printk_log *msg = log_from_idx(idx); 3139 struct printk_log *msg = log_from_idx(idx);
3200 3140
3201 l += msg_print_text(msg, prev, syslog, buf + l, size - l); 3141 l += msg_print_text(msg, syslog, buf + l, size - l);
3202 idx = log_next(idx); 3142 idx = log_next(idx);
3203 seq++; 3143 seq++;
3204 prev = msg->flags;
3205 } 3144 }
3206 3145
3207 dumper->next_seq = next_seq; 3146 dumper->next_seq = next_seq;