aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c532
1 files changed, 418 insertions, 114 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 32462d2b364a..dba18211685e 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -193,12 +193,19 @@ static int console_may_schedule;
193 * separated by ',', and find the message after the ';' character. 193 * separated by ',', and find the message after the ';' character.
194 */ 194 */
195 195
196enum log_flags {
197 LOG_DEFAULT = 0,
198 LOG_NOCONS = 1, /* already flushed, do not print to console */
199};
200
196struct log { 201struct log {
197 u64 ts_nsec; /* timestamp in nanoseconds */ 202 u64 ts_nsec; /* timestamp in nanoseconds */
198 u16 len; /* length of entire record */ 203 u16 len; /* length of entire record */
199 u16 text_len; /* length of text buffer */ 204 u16 text_len; /* length of text buffer */
200 u16 dict_len; /* length of dictionary buffer */ 205 u16 dict_len; /* length of dictionary buffer */
201 u16 level; /* syslog level + facility */ 206 u8 facility; /* syslog facility */
207 u8 flags:5; /* internal record flags */
208 u8 level:3; /* syslog level */
202}; 209};
203 210
204/* 211/*
@@ -227,10 +234,10 @@ static u32 clear_idx;
227#define LOG_LINE_MAX 1024 234#define LOG_LINE_MAX 1024
228 235
229/* record buffer */ 236/* record buffer */
230#if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 237#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
231#define LOG_ALIGN 4 238#define LOG_ALIGN 4
232#else 239#else
233#define LOG_ALIGN 8 240#define LOG_ALIGN __alignof__(struct log)
234#endif 241#endif
235#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) 242#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
236static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); 243static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
@@ -286,6 +293,7 @@ static u32 log_next(u32 idx)
286 293
287/* insert record into the buffer, discard old ones, update heads */ 294/* insert record into the buffer, discard old ones, update heads */
288static void log_store(int facility, int level, 295static void log_store(int facility, int level,
296 enum log_flags flags, u64 ts_nsec,
289 const char *dict, u16 dict_len, 297 const char *dict, u16 dict_len,
290 const char *text, u16 text_len) 298 const char *text, u16 text_len)
291{ 299{
@@ -329,8 +337,13 @@ static void log_store(int facility, int level,
329 msg->text_len = text_len; 337 msg->text_len = text_len;
330 memcpy(log_dict(msg), dict, dict_len); 338 memcpy(log_dict(msg), dict, dict_len);
331 msg->dict_len = dict_len; 339 msg->dict_len = dict_len;
332 msg->level = (facility << 3) | (level & 7); 340 msg->facility = facility;
333 msg->ts_nsec = local_clock(); 341 msg->level = level & 7;
342 msg->flags = flags & 0x1f;
343 if (ts_nsec > 0)
344 msg->ts_nsec = ts_nsec;
345 else
346 msg->ts_nsec = local_clock();
334 memset(log_dict(msg) + dict_len, 0, pad_len); 347 memset(log_dict(msg) + dict_len, 0, pad_len);
335 msg->len = sizeof(struct log) + text_len + dict_len + pad_len; 348 msg->len = sizeof(struct log) + text_len + dict_len + pad_len;
336 349
@@ -414,7 +427,9 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
414 if (!user) 427 if (!user)
415 return -EBADF; 428 return -EBADF;
416 429
417 mutex_lock(&user->lock); 430 ret = mutex_lock_interruptible(&user->lock);
431 if (ret)
432 return ret;
418 raw_spin_lock(&logbuf_lock); 433 raw_spin_lock(&logbuf_lock);
419 while (user->seq == log_next_seq) { 434 while (user->seq == log_next_seq) {
420 if (file->f_flags & O_NONBLOCK) { 435 if (file->f_flags & O_NONBLOCK) {
@@ -444,7 +459,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
444 ts_usec = msg->ts_nsec; 459 ts_usec = msg->ts_nsec;
445 do_div(ts_usec, 1000); 460 do_div(ts_usec, 1000);
446 len = sprintf(user->buf, "%u,%llu,%llu;", 461 len = sprintf(user->buf, "%u,%llu,%llu;",
447 msg->level, user->seq, ts_usec); 462 (msg->facility << 3) | msg->level, user->seq, ts_usec);
448 463
449 /* escape non-printable characters */ 464 /* escape non-printable characters */
450 for (i = 0; i < msg->text_len; i++) { 465 for (i = 0; i < msg->text_len; i++) {
@@ -785,6 +800,21 @@ static bool printk_time;
785#endif 800#endif
786module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); 801module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
787 802
803static size_t print_time(u64 ts, char *buf)
804{
805 unsigned long rem_nsec;
806
807 if (!printk_time)
808 return 0;
809
810 if (!buf)
811 return 15;
812
813 rem_nsec = do_div(ts, 1000000000);
814 return sprintf(buf, "[%5lu.%06lu] ",
815 (unsigned long)ts, rem_nsec / 1000);
816}
817
788static size_t print_prefix(const struct log *msg, bool syslog, char *buf) 818static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
789{ 819{
790 size_t len = 0; 820 size_t len = 0;
@@ -801,18 +831,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
801 } 831 }
802 } 832 }
803 833
804 if (printk_time) { 834 len += print_time(msg->ts_nsec, buf ? buf + len : NULL);
805 if (buf) {
806 unsigned long long ts = msg->ts_nsec;
807 unsigned long rem_nsec = do_div(ts, 1000000000);
808
809 len += sprintf(buf + len, "[%5lu.%06lu] ",
810 (unsigned long) ts, rem_nsec / 1000);
811 } else {
812 len += 15;
813 }
814 }
815
816 return len; 835 return len;
817} 836}
818 837
@@ -860,26 +879,49 @@ static int syslog_print(char __user *buf, int size)
860{ 879{
861 char *text; 880 char *text;
862 struct log *msg; 881 struct log *msg;
863 int len; 882 int len = 0;
864 883
865 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); 884 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
866 if (!text) 885 if (!text)
867 return -ENOMEM; 886 return -ENOMEM;
868 887
869 raw_spin_lock_irq(&logbuf_lock); 888 while (size > 0) {
870 if (syslog_seq < log_first_seq) { 889 size_t n;
871 /* messages are gone, move to first one */ 890
872 syslog_seq = log_first_seq; 891 raw_spin_lock_irq(&logbuf_lock);
873 syslog_idx = log_first_idx; 892 if (syslog_seq < log_first_seq) {
874 } 893 /* messages are gone, move to first one */
875 msg = log_from_idx(syslog_idx); 894 syslog_seq = log_first_seq;
876 len = msg_print_text(msg, true, text, LOG_LINE_MAX); 895 syslog_idx = log_first_idx;
877 syslog_idx = log_next(syslog_idx); 896 }
878 syslog_seq++; 897 if (syslog_seq == log_next_seq) {
879 raw_spin_unlock_irq(&logbuf_lock); 898 raw_spin_unlock_irq(&logbuf_lock);
899 break;
900 }
901 msg = log_from_idx(syslog_idx);
902 n = msg_print_text(msg, true, text, LOG_LINE_MAX);
903 if (n <= size) {
904 syslog_idx = log_next(syslog_idx);
905 syslog_seq++;
906 } else
907 n = 0;
908 raw_spin_unlock_irq(&logbuf_lock);
909
910 if (!n)
911 break;
912
913 len += n;
914 size -= n;
915 buf += n;
916 n = copy_to_user(buf - n, text, n);
880 917
881 if (len > 0 && copy_to_user(buf, text, len)) 918 if (n) {
882 len = -EFAULT; 919 len -= n;
920 if (!len)
921 len = -EFAULT;
922 break;
923 }
924 }
883 925
884 kfree(text); 926 kfree(text);
885 return len; 927 return len;
@@ -909,7 +951,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
909 /* 951 /*
910 * Find first record that fits, including all following records, 952 * Find first record that fits, including all following records,
911 * into the user-provided buffer for this dump. 953 * into the user-provided buffer for this dump.
912 */ 954 */
913 seq = clear_seq; 955 seq = clear_seq;
914 idx = clear_idx; 956 idx = clear_idx;
915 while (seq < log_next_seq) { 957 while (seq < log_next_seq) {
@@ -919,6 +961,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
919 idx = log_next(idx); 961 idx = log_next(idx);
920 seq++; 962 seq++;
921 } 963 }
964
965 /* move first record forward until length fits into the buffer */
922 seq = clear_seq; 966 seq = clear_seq;
923 idx = clear_idx; 967 idx = clear_idx;
924 while (len > size && seq < log_next_seq) { 968 while (len > size && seq < log_next_seq) {
@@ -929,7 +973,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
929 seq++; 973 seq++;
930 } 974 }
931 975
932 /* last message in this dump */ 976 /* last message fitting into this dump */
933 next_seq = log_next_seq; 977 next_seq = log_next_seq;
934 978
935 len = 0; 979 len = 0;
@@ -974,6 +1018,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
974{ 1018{
975 bool clear = false; 1019 bool clear = false;
976 static int saved_console_loglevel = -1; 1020 static int saved_console_loglevel = -1;
1021 static DEFINE_MUTEX(syslog_mutex);
977 int error; 1022 int error;
978 1023
979 error = check_syslog_permissions(type, from_file); 1024 error = check_syslog_permissions(type, from_file);
@@ -1000,11 +1045,17 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1000 error = -EFAULT; 1045 error = -EFAULT;
1001 goto out; 1046 goto out;
1002 } 1047 }
1048 error = mutex_lock_interruptible(&syslog_mutex);
1049 if (error)
1050 goto out;
1003 error = wait_event_interruptible(log_wait, 1051 error = wait_event_interruptible(log_wait,
1004 syslog_seq != log_next_seq); 1052 syslog_seq != log_next_seq);
1005 if (error) 1053 if (error) {
1054 mutex_unlock(&syslog_mutex);
1006 goto out; 1055 goto out;
1056 }
1007 error = syslog_print(buf, len); 1057 error = syslog_print(buf, len);
1058 mutex_unlock(&syslog_mutex);
1008 break; 1059 break;
1009 /* Read/clear last kernel messages */ 1060 /* Read/clear last kernel messages */
1010 case SYSLOG_ACTION_READ_CLEAR: 1061 case SYSLOG_ACTION_READ_CLEAR:
@@ -1027,6 +1078,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
1027 /* Clear ring buffer */ 1078 /* Clear ring buffer */
1028 case SYSLOG_ACTION_CLEAR: 1079 case SYSLOG_ACTION_CLEAR:
1029 syslog_print_all(NULL, 0, true); 1080 syslog_print_all(NULL, 0, true);
1081 break;
1030 /* Disable logging to console */ 1082 /* Disable logging to console */
1031 case SYSLOG_ACTION_CONSOLE_OFF: 1083 case SYSLOG_ACTION_CONSOLE_OFF:
1032 if (saved_console_loglevel == -1) 1084 if (saved_console_loglevel == -1)
@@ -1259,15 +1311,92 @@ static inline void printk_delay(void)
1259 } 1311 }
1260} 1312}
1261 1313
1314/*
1315 * Continuation lines are buffered, and not committed to the record buffer
1316 * until the line is complete, or a race forces it. The line fragments
1317 * though, are printed immediately to the consoles to ensure everything has
1318 * reached the console in case of a kernel crash.
1319 */
1320static struct cont {
1321 char buf[LOG_LINE_MAX];
1322 size_t len; /* length == 0 means unused buffer */
1323 size_t cons; /* bytes written to console */
1324 struct task_struct *owner; /* task of first print*/
1325 u64 ts_nsec; /* time of first print */
1326 u8 level; /* log level of first message */
1327 u8 facility; /* log level of first message */
1328 bool flushed:1; /* buffer sealed and committed */
1329} cont;
1330
1331static void cont_flush(void)
1332{
1333 if (cont.flushed)
1334 return;
1335 if (cont.len == 0)
1336 return;
1337
1338 log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
1339 NULL, 0, cont.buf, cont.len);
1340
1341 cont.flushed = true;
1342}
1343
1344static bool cont_add(int facility, int level, const char *text, size_t len)
1345{
1346 if (cont.len && cont.flushed)
1347 return false;
1348
1349 if (cont.len + len > sizeof(cont.buf)) {
1350 cont_flush();
1351 return false;
1352 }
1353
1354 if (!cont.len) {
1355 cont.facility = facility;
1356 cont.level = level;
1357 cont.owner = current;
1358 cont.ts_nsec = local_clock();
1359 cont.cons = 0;
1360 cont.flushed = false;
1361 }
1362
1363 memcpy(cont.buf + cont.len, text, len);
1364 cont.len += len;
1365 return true;
1366}
1367
1368static size_t cont_print_text(char *text, size_t size)
1369{
1370 size_t textlen = 0;
1371 size_t len;
1372
1373 if (cont.cons == 0) {
1374 textlen += print_time(cont.ts_nsec, text);
1375 size -= textlen;
1376 }
1377
1378 len = cont.len - cont.cons;
1379 if (len > 0) {
1380 if (len+1 > size)
1381 len = size-1;
1382 memcpy(text + textlen, cont.buf + cont.cons, len);
1383 textlen += len;
1384 cont.cons = cont.len;
1385 }
1386
1387 if (cont.flushed) {
1388 text[textlen++] = '\n';
1389 /* got everything, release buffer */
1390 cont.len = 0;
1391 }
1392 return textlen;
1393}
1394
1262asmlinkage int vprintk_emit(int facility, int level, 1395asmlinkage int vprintk_emit(int facility, int level,
1263 const char *dict, size_t dictlen, 1396 const char *dict, size_t dictlen,
1264 const char *fmt, va_list args) 1397 const char *fmt, va_list args)
1265{ 1398{
1266 static int recursion_bug; 1399 static int recursion_bug;
1267 static char cont_buf[LOG_LINE_MAX];
1268 static size_t cont_len;
1269 static int cont_level;
1270 static struct task_struct *cont_task;
1271 static char textbuf[LOG_LINE_MAX]; 1400 static char textbuf[LOG_LINE_MAX];
1272 char *text = textbuf; 1401 char *text = textbuf;
1273 size_t text_len; 1402 size_t text_len;
@@ -1313,7 +1442,8 @@ asmlinkage int vprintk_emit(int facility, int level,
1313 recursion_bug = 0; 1442 recursion_bug = 0;
1314 printed_len += strlen(recursion_msg); 1443 printed_len += strlen(recursion_msg);
1315 /* emit KERN_CRIT message */ 1444 /* emit KERN_CRIT message */
1316 log_store(0, 2, NULL, 0, recursion_msg, printed_len); 1445 log_store(0, 2, LOG_DEFAULT, 0,
1446 NULL, 0, recursion_msg, printed_len);
1317 } 1447 }
1318 1448
1319 /* 1449 /*
@@ -1351,55 +1481,37 @@ asmlinkage int vprintk_emit(int facility, int level,
1351 } 1481 }
1352 1482
1353 if (!newline) { 1483 if (!newline) {
1354 if (cont_len && (prefix || cont_task != current)) { 1484 /*
1355 /* 1485 * Flush the conflicting buffer. An earlier newline was missing,
1356 * Flush earlier buffer, which is either from a 1486 * or another task also prints continuation lines.
1357 * different thread, or when we got a new prefix. 1487 */
1358 */ 1488 if (cont.len && (prefix || cont.owner != current))
1359 log_store(facility, cont_level, NULL, 0, cont_buf, cont_len); 1489 cont_flush();
1360 cont_len = 0;
1361 }
1362
1363 if (!cont_len) {
1364 cont_level = level;
1365 cont_task = current;
1366 }
1367 1490
1368 /* buffer or append to earlier buffer from the same thread */ 1491 /* buffer line if possible, otherwise store it right away */
1369 if (cont_len + text_len > sizeof(cont_buf)) 1492 if (!cont_add(facility, level, text, text_len))
1370 text_len = sizeof(cont_buf) - cont_len; 1493 log_store(facility, level, LOG_DEFAULT, 0,
1371 memcpy(cont_buf + cont_len, text, text_len); 1494 dict, dictlen, text, text_len);
1372 cont_len += text_len;
1373 } else { 1495 } else {
1374 if (cont_len && cont_task == current) { 1496 bool stored = false;
1375 if (prefix) {
1376 /*
1377 * New prefix from the same thread; flush. We
1378 * either got no earlier newline, or we race
1379 * with an interrupt.
1380 */
1381 log_store(facility, cont_level,
1382 NULL, 0, cont_buf, cont_len);
1383 cont_len = 0;
1384 }
1385 1497
1386 /* append to the earlier buffer and flush */ 1498 /*
1387 if (cont_len + text_len > sizeof(cont_buf)) 1499 * If an earlier newline was missing and it was the same task,
1388 text_len = sizeof(cont_buf) - cont_len; 1500 * either merge it with the current buffer and flush, or if
1389 memcpy(cont_buf + cont_len, text, text_len); 1501 * there was a race with interrupts (prefix == true) then just
1390 cont_len += text_len; 1502 * flush it out and store this line separately.
1391 log_store(facility, cont_level, 1503 */
1392 NULL, 0, cont_buf, cont_len); 1504 if (cont.len && cont.owner == current) {
1393 cont_len = 0; 1505 if (!prefix)
1394 cont_task = NULL; 1506 stored = cont_add(facility, level, text, text_len);
1395 printed_len = cont_len; 1507 cont_flush();
1396 } else {
1397 /* ordinary single and terminated line */
1398 log_store(facility, level,
1399 dict, dictlen, text, text_len);
1400 printed_len = text_len;
1401 } 1508 }
1509
1510 if (!stored)
1511 log_store(facility, level, LOG_DEFAULT, 0,
1512 dict, dictlen, text, text_len);
1402 } 1513 }
1514 printed_len += text_len;
1403 1515
1404 /* 1516 /*
1405 * Try to acquire and then immediately release the console semaphore. 1517 * Try to acquire and then immediately release the console semaphore.
@@ -1486,11 +1598,18 @@ EXPORT_SYMBOL(printk);
1486#else 1598#else
1487 1599
1488#define LOG_LINE_MAX 0 1600#define LOG_LINE_MAX 0
1601static struct cont {
1602 size_t len;
1603 size_t cons;
1604 u8 level;
1605 bool flushed:1;
1606} cont;
1489static struct log *log_from_idx(u32 idx) { return NULL; } 1607static struct log *log_from_idx(u32 idx) { return NULL; }
1490static u32 log_next(u32 idx) { return 0; } 1608static u32 log_next(u32 idx) { return 0; }
1491static void call_console_drivers(int level, const char *text, size_t len) {} 1609static void call_console_drivers(int level, const char *text, size_t len) {}
1492static size_t msg_print_text(const struct log *msg, bool syslog, 1610static size_t msg_print_text(const struct log *msg, bool syslog,
1493 char *buf, size_t size) { return 0; } 1611 char *buf, size_t size) { return 0; }
1612static size_t cont_print_text(char *text, size_t size) { return 0; }
1494 1613
1495#endif /* CONFIG_PRINTK */ 1614#endif /* CONFIG_PRINTK */
1496 1615
@@ -1782,6 +1901,7 @@ static u32 console_idx;
1782 */ 1901 */
1783void console_unlock(void) 1902void console_unlock(void)
1784{ 1903{
1904 static char text[LOG_LINE_MAX];
1785 static u64 seen_seq; 1905 static u64 seen_seq;
1786 unsigned long flags; 1906 unsigned long flags;
1787 bool wake_klogd = false; 1907 bool wake_klogd = false;
@@ -1794,10 +1914,23 @@ void console_unlock(void)
1794 1914
1795 console_may_schedule = 0; 1915 console_may_schedule = 0;
1796 1916
1917 /* flush buffered message fragment immediately to console */
1918 raw_spin_lock_irqsave(&logbuf_lock, flags);
1919 if (cont.len && (cont.cons < cont.len || cont.flushed)) {
1920 size_t len;
1921
1922 len = cont_print_text(text, sizeof(text));
1923 raw_spin_unlock(&logbuf_lock);
1924 stop_critical_timings();
1925 call_console_drivers(cont.level, text, len);
1926 start_critical_timings();
1927 local_irq_restore(flags);
1928 } else
1929 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
1930
1797again: 1931again:
1798 for (;;) { 1932 for (;;) {
1799 struct log *msg; 1933 struct log *msg;
1800 static char text[LOG_LINE_MAX];
1801 size_t len; 1934 size_t len;
1802 int level; 1935 int level;
1803 1936
@@ -1812,13 +1945,22 @@ again:
1812 console_seq = log_first_seq; 1945 console_seq = log_first_seq;
1813 console_idx = log_first_idx; 1946 console_idx = log_first_idx;
1814 } 1947 }
1815 1948skip:
1816 if (console_seq == log_next_seq) 1949 if (console_seq == log_next_seq)
1817 break; 1950 break;
1818 1951
1819 msg = log_from_idx(console_idx); 1952 msg = log_from_idx(console_idx);
1820 level = msg->level & 7; 1953 if (msg->flags & LOG_NOCONS) {
1954 /*
1955 * Skip record we have buffered and already printed
1956 * directly to the console when we received it.
1957 */
1958 console_idx = log_next(console_idx);
1959 console_seq++;
1960 goto skip;
1961 }
1821 1962
1963 level = msg->level;
1822 len = msg_print_text(msg, false, text, sizeof(text)); 1964 len = msg_print_text(msg, false, text, sizeof(text));
1823 1965
1824 console_idx = log_next(console_idx); 1966 console_idx = log_next(console_idx);
@@ -2300,48 +2442,210 @@ module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR);
2300 * kmsg_dump - dump kernel log to kernel message dumpers. 2442 * kmsg_dump - dump kernel log to kernel message dumpers.
2301 * @reason: the reason (oops, panic etc) for dumping 2443 * @reason: the reason (oops, panic etc) for dumping
2302 * 2444 *
2303 * Iterate through each of the dump devices and call the oops/panic 2445 * Call each of the registered dumper's dump() callback, which can
2304 * callbacks with the log buffer. 2446 * retrieve the kmsg records with kmsg_dump_get_line() or
2447 * kmsg_dump_get_buffer().
2305 */ 2448 */
2306void kmsg_dump(enum kmsg_dump_reason reason) 2449void kmsg_dump(enum kmsg_dump_reason reason)
2307{ 2450{
2308 u64 idx;
2309 struct kmsg_dumper *dumper; 2451 struct kmsg_dumper *dumper;
2310 const char *s1, *s2;
2311 unsigned long l1, l2;
2312 unsigned long flags; 2452 unsigned long flags;
2313 2453
2314 if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump) 2454 if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
2315 return; 2455 return;
2316 2456
2317 /* Theoretically, the log could move on after we do this, but 2457 rcu_read_lock();
2318 there's not a lot we can do about that. The new messages 2458 list_for_each_entry_rcu(dumper, &dump_list, list) {
2319 will overwrite the start of what we dump. */ 2459 if (dumper->max_reason && reason > dumper->max_reason)
2460 continue;
2461
2462 /* initialize iterator with data about the stored records */
2463 dumper->active = true;
2464
2465 raw_spin_lock_irqsave(&logbuf_lock, flags);
2466 dumper->cur_seq = clear_seq;
2467 dumper->cur_idx = clear_idx;
2468 dumper->next_seq = log_next_seq;
2469 dumper->next_idx = log_next_idx;
2470 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2471
2472 /* invoke dumper which will iterate over records */
2473 dumper->dump(dumper, reason);
2474
2475 /* reset iterator */
2476 dumper->active = false;
2477 }
2478 rcu_read_unlock();
2479}
2480
2481/**
2482 * kmsg_dump_get_line - retrieve one kmsg log line
2483 * @dumper: registered kmsg dumper
2484 * @syslog: include the "<4>" prefixes
2485 * @line: buffer to copy the line to
2486 * @size: maximum size of the buffer
2487 * @len: length of line placed into buffer
2488 *
2489 * Start at the beginning of the kmsg buffer, with the oldest kmsg
2490 * record, and copy one record into the provided buffer.
2491 *
2492 * Consecutive calls will return the next available record moving
2493 * towards the end of the buffer with the youngest messages.
2494 *
2495 * A return value of FALSE indicates that there are no more records to
2496 * read.
2497 */
2498bool kmsg_dump_get_line(struct kmsg_dumper *dumper, bool syslog,
2499 char *line, size_t size, size_t *len)
2500{
2501 unsigned long flags;
2502 struct log *msg;
2503 size_t l = 0;
2504 bool ret = false;
2505
2506 if (!dumper->active)
2507 goto out;
2320 2508
2321 raw_spin_lock_irqsave(&logbuf_lock, flags); 2509 raw_spin_lock_irqsave(&logbuf_lock, flags);
2322 if (syslog_seq < log_first_seq) 2510 if (dumper->cur_seq < log_first_seq) {
2323 idx = syslog_idx; 2511 /* messages are gone, move to first available one */
2324 else 2512 dumper->cur_seq = log_first_seq;
2325 idx = log_first_idx; 2513 dumper->cur_idx = log_first_idx;
2514 }
2326 2515
2327 if (idx > log_next_idx) { 2516 /* last entry */
2328 s1 = log_buf; 2517 if (dumper->cur_seq >= log_next_seq) {
2329 l1 = log_next_idx; 2518 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2519 goto out;
2520 }
2330 2521
2331 s2 = log_buf + idx; 2522 msg = log_from_idx(dumper->cur_idx);
2332 l2 = log_buf_len - idx; 2523 l = msg_print_text(msg, syslog,
2333 } else { 2524 line, size);
2334 s1 = "";
2335 l1 = 0;
2336 2525
2337 s2 = log_buf + idx; 2526 dumper->cur_idx = log_next(dumper->cur_idx);
2338 l2 = log_next_idx - idx; 2527 dumper->cur_seq++;
2528 ret = true;
2529 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2530out:
2531 if (len)
2532 *len = l;
2533 return ret;
2534}
2535EXPORT_SYMBOL_GPL(kmsg_dump_get_line);
2536
2537/**
2538 * kmsg_dump_get_buffer - copy kmsg log lines
2539 * @dumper: registered kmsg dumper
2540 * @syslog: include the "<4>" prefixes
2541 * @buf: buffer to copy the line to
2542 * @size: maximum size of the buffer
2543 * @len: length of line placed into buffer
2544 *
2545 * Start at the end of the kmsg buffer and fill the provided buffer
2546 * with as many of the the *youngest* kmsg records that fit into it.
2547 * If the buffer is large enough, all available kmsg records will be
2548 * copied with a single call.
2549 *
2550 * Consecutive calls will fill the buffer with the next block of
2551 * available older records, not including the earlier retrieved ones.
2552 *
2553 * A return value of FALSE indicates that there are no more records to
2554 * read.
2555 */
2556bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
2557 char *buf, size_t size, size_t *len)
2558{
2559 unsigned long flags;
2560 u64 seq;
2561 u32 idx;
2562 u64 next_seq;
2563 u32 next_idx;
2564 size_t l = 0;
2565 bool ret = false;
2566
2567 if (!dumper->active)
2568 goto out;
2569
2570 raw_spin_lock_irqsave(&logbuf_lock, flags);
2571 if (dumper->cur_seq < log_first_seq) {
2572 /* messages are gone, move to first available one */
2573 dumper->cur_seq = log_first_seq;
2574 dumper->cur_idx = log_first_idx;
2339 } 2575 }
2576
2577 /* last entry */
2578 if (dumper->cur_seq >= dumper->next_seq) {
2579 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2580 goto out;
2581 }
2582
2583 /* calculate length of entire buffer */
2584 seq = dumper->cur_seq;
2585 idx = dumper->cur_idx;
2586 while (seq < dumper->next_seq) {
2587 struct log *msg = log_from_idx(idx);
2588
2589 l += msg_print_text(msg, true, NULL, 0);
2590 idx = log_next(idx);
2591 seq++;
2592 }
2593
2594 /* move first record forward until length fits into the buffer */
2595 seq = dumper->cur_seq;
2596 idx = dumper->cur_idx;
2597 while (l > size && seq < dumper->next_seq) {
2598 struct log *msg = log_from_idx(idx);
2599
2600 l -= msg_print_text(msg, true, NULL, 0);
2601 idx = log_next(idx);
2602 seq++;
2603 }
2604
2605 /* last message in next interation */
2606 next_seq = seq;
2607 next_idx = idx;
2608
2609 l = 0;
2610 while (seq < dumper->next_seq) {
2611 struct log *msg = log_from_idx(idx);
2612
2613 l += msg_print_text(msg, syslog,
2614 buf + l, size - l);
2615
2616 idx = log_next(idx);
2617 seq++;
2618 }
2619
2620 dumper->next_seq = next_seq;
2621 dumper->next_idx = next_idx;
2622 ret = true;
2340 raw_spin_unlock_irqrestore(&logbuf_lock, flags); 2623 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2624out:
2625 if (len)
2626 *len = l;
2627 return ret;
2628}
2629EXPORT_SYMBOL_GPL(kmsg_dump_get_buffer);
2341 2630
2342 rcu_read_lock(); 2631/**
2343 list_for_each_entry_rcu(dumper, &dump_list, list) 2632 * kmsg_dump_rewind - reset the interator
2344 dumper->dump(dumper, reason, s1, l1, s2, l2); 2633 * @dumper: registered kmsg dumper
2345 rcu_read_unlock(); 2634 *
2635 * Reset the dumper's iterator so that kmsg_dump_get_line() and
2636 * kmsg_dump_get_buffer() can be called again and used multiple
2637 * times within the same dumper.dump() callback.
2638 */
2639void kmsg_dump_rewind(struct kmsg_dumper *dumper)
2640{
2641 unsigned long flags;
2642
2643 raw_spin_lock_irqsave(&logbuf_lock, flags);
2644 dumper->cur_seq = clear_seq;
2645 dumper->cur_idx = clear_idx;
2646 dumper->next_seq = log_next_seq;
2647 dumper->next_idx = log_next_idx;
2648 raw_spin_unlock_irqrestore(&logbuf_lock, flags);
2346} 2649}
2650EXPORT_SYMBOL_GPL(kmsg_dump_rewind);
2347#endif 2651#endif