aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c182
1 files changed, 148 insertions, 34 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 6712a252b306..ee54355cfdf1 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -33,6 +33,9 @@
33#include <linux/bootmem.h> 33#include <linux/bootmem.h>
34#include <linux/syscalls.h> 34#include <linux/syscalls.h>
35#include <linux/kexec.h> 35#include <linux/kexec.h>
36#include <linux/ratelimit.h>
37#include <linux/kmsg_dump.h>
38#include <linux/syslog.h>
36 39
37#include <asm/uaccess.h> 40#include <asm/uaccess.h>
38 41
@@ -67,8 +70,6 @@ int console_printk[4] = {
67 DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ 70 DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */
68}; 71};
69 72
70static int saved_console_loglevel = -1;
71
72/* 73/*
73 * divert printk() messages when there is a LITMUS^RT debug listener 74 * divert printk() messages when there is a LITMUS^RT debug listener
74 */ 75 */
@@ -150,6 +151,7 @@ static char __log_buf[__LOG_BUF_LEN];
150static char *log_buf = __log_buf; 151static char *log_buf = __log_buf;
151static int log_buf_len = __LOG_BUF_LEN; 152static int log_buf_len = __LOG_BUF_LEN;
152static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ 153static unsigned logged_chars; /* Number of chars produced since last read+clear operation */
154static int saved_console_loglevel = -1;
153 155
154#ifdef CONFIG_KEXEC 156#ifdef CONFIG_KEXEC
155/* 157/*
@@ -263,38 +265,23 @@ static inline void boot_delay_msec(void)
263} 265}
264#endif 266#endif
265 267
266/* 268int do_syslog(int type, char __user *buf, int len, bool from_file)
267 * Commands to do_syslog:
268 *
269 * 0 -- Close the log. Currently a NOP.
270 * 1 -- Open the log. Currently a NOP.
271 * 2 -- Read from the log.
272 * 3 -- Read all messages remaining in the ring buffer.
273 * 4 -- Read and clear all messages remaining in the ring buffer
274 * 5 -- Clear ring buffer.
275 * 6 -- Disable printk's to console
276 * 7 -- Enable printk's to console
277 * 8 -- Set level of messages printed to console
278 * 9 -- Return number of unread characters in the log buffer
279 * 10 -- Return size of the log buffer
280 */
281int do_syslog(int type, char __user *buf, int len)
282{ 269{
283 unsigned i, j, limit, count; 270 unsigned i, j, limit, count;
284 int do_clear = 0; 271 int do_clear = 0;
285 char c; 272 char c;
286 int error = 0; 273 int error = 0;
287 274
288 error = security_syslog(type); 275 error = security_syslog(type, from_file);
289 if (error) 276 if (error)
290 return error; 277 return error;
291 278
292 switch (type) { 279 switch (type) {
293 case 0: /* Close log */ 280 case SYSLOG_ACTION_CLOSE: /* Close log */
294 break; 281 break;
295 case 1: /* Open log */ 282 case SYSLOG_ACTION_OPEN: /* Open log */
296 break; 283 break;
297 case 2: /* Read from log */ 284 case SYSLOG_ACTION_READ: /* Read from log */
298 error = -EINVAL; 285 error = -EINVAL;
299 if (!buf || len < 0) 286 if (!buf || len < 0)
300 goto out; 287 goto out;
@@ -325,10 +312,12 @@ int do_syslog(int type, char __user *buf, int len)
325 if (!error) 312 if (!error)
326 error = i; 313 error = i;
327 break; 314 break;
328 case 4: /* Read/clear last kernel messages */ 315 /* Read/clear last kernel messages */
316 case SYSLOG_ACTION_READ_CLEAR:
329 do_clear = 1; 317 do_clear = 1;
330 /* FALL THRU */ 318 /* FALL THRU */
331 case 3: /* Read last kernel messages */ 319 /* Read last kernel messages */
320 case SYSLOG_ACTION_READ_ALL:
332 error = -EINVAL; 321 error = -EINVAL;
333 if (!buf || len < 0) 322 if (!buf || len < 0)
334 goto out; 323 goto out;
@@ -381,21 +370,25 @@ int do_syslog(int type, char __user *buf, int len)
381 } 370 }
382 } 371 }
383 break; 372 break;
384 case 5: /* Clear ring buffer */ 373 /* Clear ring buffer */
374 case SYSLOG_ACTION_CLEAR:
385 logged_chars = 0; 375 logged_chars = 0;
386 break; 376 break;
387 case 6: /* Disable logging to console */ 377 /* Disable logging to console */
378 case SYSLOG_ACTION_CONSOLE_OFF:
388 if (saved_console_loglevel == -1) 379 if (saved_console_loglevel == -1)
389 saved_console_loglevel = console_loglevel; 380 saved_console_loglevel = console_loglevel;
390 console_loglevel = minimum_console_loglevel; 381 console_loglevel = minimum_console_loglevel;
391 break; 382 break;
392 case 7: /* Enable logging to console */ 383 /* Enable logging to console */
384 case SYSLOG_ACTION_CONSOLE_ON:
393 if (saved_console_loglevel != -1) { 385 if (saved_console_loglevel != -1) {
394 console_loglevel = saved_console_loglevel; 386 console_loglevel = saved_console_loglevel;
395 saved_console_loglevel = -1; 387 saved_console_loglevel = -1;
396 } 388 }
397 break; 389 break;
398 case 8: /* Set level of messages printed to console */ 390 /* Set level of messages printed to console */
391 case SYSLOG_ACTION_CONSOLE_LEVEL:
399 error = -EINVAL; 392 error = -EINVAL;
400 if (len < 1 || len > 8) 393 if (len < 1 || len > 8)
401 goto out; 394 goto out;
@@ -406,10 +399,12 @@ int do_syslog(int type, char __user *buf, int len)
406 saved_console_loglevel = -1; 399 saved_console_loglevel = -1;
407 error = 0; 400 error = 0;
408 break; 401 break;
409 case 9: /* Number of chars in the log buffer */ 402 /* Number of chars in the log buffer */
403 case SYSLOG_ACTION_SIZE_UNREAD:
410 error = log_end - log_start; 404 error = log_end - log_start;
411 break; 405 break;
412 case 10: /* Size of the log buffer */ 406 /* Size of the log buffer */
407 case SYSLOG_ACTION_SIZE_BUFFER:
413 error = log_buf_len; 408 error = log_buf_len;
414 break; 409 break;
415 default: 410 default:
@@ -422,7 +417,7 @@ out:
422 417
423SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) 418SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
424{ 419{
425 return do_syslog(type, buf, len); 420 return do_syslog(type, buf, len, SYSLOG_FROM_CALL);
426} 421}
427 422
428/* 423/*
@@ -1386,11 +1381,11 @@ late_initcall(disable_boot_consoles);
1386 */ 1381 */
1387DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10); 1382DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10);
1388 1383
1389int printk_ratelimit(void) 1384int __printk_ratelimit(const char *func)
1390{ 1385{
1391 return __ratelimit(&printk_ratelimit_state); 1386 return ___ratelimit(&printk_ratelimit_state, func);
1392} 1387}
1393EXPORT_SYMBOL(printk_ratelimit); 1388EXPORT_SYMBOL(__printk_ratelimit);
1394 1389
1395/** 1390/**
1396 * printk_timed_ratelimit - caller-controlled printk ratelimiting 1391 * printk_timed_ratelimit - caller-controlled printk ratelimiting
@@ -1414,4 +1409,123 @@ bool printk_timed_ratelimit(unsigned long *caller_jiffies,
1414 return false; 1409 return false;
1415} 1410}
1416EXPORT_SYMBOL(printk_timed_ratelimit); 1411EXPORT_SYMBOL(printk_timed_ratelimit);
1412
1413static DEFINE_SPINLOCK(dump_list_lock);
1414static LIST_HEAD(dump_list);
1415
1416/**
1417 * kmsg_dump_register - register a kernel log dumper.
1418 * @dumper: pointer to the kmsg_dumper structure
1419 *
1420 * Adds a kernel log dumper to the system. The dump callback in the
1421 * structure will be called when the kernel oopses or panics and must be
1422 * set. Returns zero on success and %-EINVAL or %-EBUSY otherwise.
1423 */
1424int kmsg_dump_register(struct kmsg_dumper *dumper)
1425{
1426 unsigned long flags;
1427 int err = -EBUSY;
1428
1429 /* The dump callback needs to be set */
1430 if (!dumper->dump)
1431 return -EINVAL;
1432
1433 spin_lock_irqsave(&dump_list_lock, flags);
1434 /* Don't allow registering multiple times */
1435 if (!dumper->registered) {
1436 dumper->registered = 1;
1437 list_add_tail(&dumper->list, &dump_list);
1438 err = 0;
1439 }
1440 spin_unlock_irqrestore(&dump_list_lock, flags);
1441
1442 return err;
1443}
1444EXPORT_SYMBOL_GPL(kmsg_dump_register);
1445
1446/**
1447 * kmsg_dump_unregister - unregister a kmsg dumper.
1448 * @dumper: pointer to the kmsg_dumper structure
1449 *
1450 * Removes a dump device from the system. Returns zero on success and
1451 * %-EINVAL otherwise.
1452 */
1453int kmsg_dump_unregister(struct kmsg_dumper *dumper)
1454{
1455 unsigned long flags;
1456 int err = -EINVAL;
1457
1458 spin_lock_irqsave(&dump_list_lock, flags);
1459 if (dumper->registered) {
1460 dumper->registered = 0;
1461 list_del(&dumper->list);
1462 err = 0;
1463 }
1464 spin_unlock_irqrestore(&dump_list_lock, flags);
1465
1466 return err;
1467}
1468EXPORT_SYMBOL_GPL(kmsg_dump_unregister);
1469
1470static const char const *kmsg_reasons[] = {
1471 [KMSG_DUMP_OOPS] = "oops",
1472 [KMSG_DUMP_PANIC] = "panic",
1473 [KMSG_DUMP_KEXEC] = "kexec",
1474};
1475
1476static const char *kmsg_to_str(enum kmsg_dump_reason reason)
1477{
1478 if (reason >= ARRAY_SIZE(kmsg_reasons) || reason < 0)
1479 return "unknown";
1480
1481 return kmsg_reasons[reason];
1482}
1483
1484/**
1485 * kmsg_dump - dump kernel log to kernel message dumpers.
1486 * @reason: the reason (oops, panic etc) for dumping
1487 *
1488 * Iterate through each of the dump devices and call the oops/panic
1489 * callbacks with the log buffer.
1490 */
1491void kmsg_dump(enum kmsg_dump_reason reason)
1492{
1493 unsigned long end;
1494 unsigned chars;
1495 struct kmsg_dumper *dumper;
1496 const char *s1, *s2;
1497 unsigned long l1, l2;
1498 unsigned long flags;
1499
1500 /* Theoretically, the log could move on after we do this, but
1501 there's not a lot we can do about that. The new messages
1502 will overwrite the start of what we dump. */
1503 spin_lock_irqsave(&logbuf_lock, flags);
1504 end = log_end & LOG_BUF_MASK;
1505 chars = logged_chars;
1506 spin_unlock_irqrestore(&logbuf_lock, flags);
1507
1508 if (logged_chars > end) {
1509 s1 = log_buf + log_buf_len - logged_chars + end;
1510 l1 = logged_chars - end;
1511
1512 s2 = log_buf;
1513 l2 = end;
1514 } else {
1515 s1 = "";
1516 l1 = 0;
1517
1518 s2 = log_buf + end - logged_chars;
1519 l2 = logged_chars;
1520 }
1521
1522 if (!spin_trylock_irqsave(&dump_list_lock, flags)) {
1523 printk(KERN_ERR "dump_kmsg: dump list lock is held during %s, skipping dump\n",
1524 kmsg_to_str(reason));
1525 return;
1526 }
1527 list_for_each_entry(dumper, &dump_list, list)
1528 dumper->dump(dumper, reason, s1, l1, s2, l2);
1529 spin_unlock_irqrestore(&dump_list_lock, flags);
1530}
1417#endif 1531#endif