diff options
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 1751c456b71f..75077ad0b537 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/kexec.h> | 35 | #include <linux/kexec.h> |
| 36 | #include <linux/ratelimit.h> | 36 | #include <linux/ratelimit.h> |
| 37 | #include <linux/kmsg_dump.h> | 37 | #include <linux/kmsg_dump.h> |
| 38 | #include <linux/syslog.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 40 | 41 | ||
| @@ -69,8 +70,6 @@ int console_printk[4] = { | |||
| 69 | DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ | 70 | DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ |
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | static int saved_console_loglevel = -1; | ||
| 73 | |||
| 74 | /* | 73 | /* |
| 75 | * Low level drivers may need that to know if they can schedule in | 74 | * Low level drivers may need that to know if they can schedule in |
| 76 | * their unblank() callback or not. So let's export it. | 75 | * their unblank() callback or not. So let's export it. |
| @@ -145,6 +144,7 @@ static char __log_buf[__LOG_BUF_LEN]; | |||
| 145 | static char *log_buf = __log_buf; | 144 | static char *log_buf = __log_buf; |
| 146 | static int log_buf_len = __LOG_BUF_LEN; | 145 | static int log_buf_len = __LOG_BUF_LEN; |
| 147 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ | 146 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ |
| 147 | static int saved_console_loglevel = -1; | ||
| 148 | 148 | ||
| 149 | #ifdef CONFIG_KEXEC | 149 | #ifdef CONFIG_KEXEC |
| 150 | /* | 150 | /* |
| @@ -258,38 +258,23 @@ static inline void boot_delay_msec(void) | |||
| 258 | } | 258 | } |
| 259 | #endif | 259 | #endif |
| 260 | 260 | ||
| 261 | /* | 261 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
| 262 | * Commands to do_syslog: | ||
| 263 | * | ||
| 264 | * 0 -- Close the log. Currently a NOP. | ||
| 265 | * 1 -- Open the log. Currently a NOP. | ||
| 266 | * 2 -- Read from the log. | ||
| 267 | * 3 -- Read all messages remaining in the ring buffer. | ||
| 268 | * 4 -- Read and clear all messages remaining in the ring buffer | ||
| 269 | * 5 -- Clear ring buffer. | ||
| 270 | * 6 -- Disable printk's to console | ||
| 271 | * 7 -- Enable printk's to console | ||
| 272 | * 8 -- Set level of messages printed to console | ||
| 273 | * 9 -- Return number of unread characters in the log buffer | ||
| 274 | * 10 -- Return size of the log buffer | ||
| 275 | */ | ||
| 276 | int do_syslog(int type, char __user *buf, int len) | ||
| 277 | { | 262 | { |
| 278 | unsigned i, j, limit, count; | 263 | unsigned i, j, limit, count; |
| 279 | int do_clear = 0; | 264 | int do_clear = 0; |
| 280 | char c; | 265 | char c; |
| 281 | int error = 0; | 266 | int error = 0; |
| 282 | 267 | ||
| 283 | error = security_syslog(type); | 268 | error = security_syslog(type, from_file); |
| 284 | if (error) | 269 | if (error) |
| 285 | return error; | 270 | return error; |
| 286 | 271 | ||
| 287 | switch (type) { | 272 | switch (type) { |
| 288 | case 0: /* Close log */ | 273 | case SYSLOG_ACTION_CLOSE: /* Close log */ |
| 289 | break; | 274 | break; |
| 290 | case 1: /* Open log */ | 275 | case SYSLOG_ACTION_OPEN: /* Open log */ |
| 291 | break; | 276 | break; |
| 292 | case 2: /* Read from log */ | 277 | case SYSLOG_ACTION_READ: /* Read from log */ |
| 293 | error = -EINVAL; | 278 | error = -EINVAL; |
| 294 | if (!buf || len < 0) | 279 | if (!buf || len < 0) |
| 295 | goto out; | 280 | goto out; |
| @@ -320,10 +305,12 @@ int do_syslog(int type, char __user *buf, int len) | |||
| 320 | if (!error) | 305 | if (!error) |
| 321 | error = i; | 306 | error = i; |
| 322 | break; | 307 | break; |
| 323 | case 4: /* Read/clear last kernel messages */ | 308 | /* Read/clear last kernel messages */ |
| 309 | case SYSLOG_ACTION_READ_CLEAR: | ||
| 324 | do_clear = 1; | 310 | do_clear = 1; |
| 325 | /* FALL THRU */ | 311 | /* FALL THRU */ |
| 326 | case 3: /* Read last kernel messages */ | 312 | /* Read last kernel messages */ |
| 313 | case SYSLOG_ACTION_READ_ALL: | ||
| 327 | error = -EINVAL; | 314 | error = -EINVAL; |
| 328 | if (!buf || len < 0) | 315 | if (!buf || len < 0) |
| 329 | goto out; | 316 | goto out; |
| @@ -376,21 +363,25 @@ int do_syslog(int type, char __user *buf, int len) | |||
| 376 | } | 363 | } |
| 377 | } | 364 | } |
| 378 | break; | 365 | break; |
| 379 | case 5: /* Clear ring buffer */ | 366 | /* Clear ring buffer */ |
| 367 | case SYSLOG_ACTION_CLEAR: | ||
| 380 | logged_chars = 0; | 368 | logged_chars = 0; |
| 381 | break; | 369 | break; |
| 382 | case 6: /* Disable logging to console */ | 370 | /* Disable logging to console */ |
| 371 | case SYSLOG_ACTION_CONSOLE_OFF: | ||
| 383 | if (saved_console_loglevel == -1) | 372 | if (saved_console_loglevel == -1) |
| 384 | saved_console_loglevel = console_loglevel; | 373 | saved_console_loglevel = console_loglevel; |
| 385 | console_loglevel = minimum_console_loglevel; | 374 | console_loglevel = minimum_console_loglevel; |
| 386 | break; | 375 | break; |
| 387 | case 7: /* Enable logging to console */ | 376 | /* Enable logging to console */ |
| 377 | case SYSLOG_ACTION_CONSOLE_ON: | ||
| 388 | if (saved_console_loglevel != -1) { | 378 | if (saved_console_loglevel != -1) { |
| 389 | console_loglevel = saved_console_loglevel; | 379 | console_loglevel = saved_console_loglevel; |
| 390 | saved_console_loglevel = -1; | 380 | saved_console_loglevel = -1; |
| 391 | } | 381 | } |
| 392 | break; | 382 | break; |
| 393 | case 8: /* Set level of messages printed to console */ | 383 | /* Set level of messages printed to console */ |
| 384 | case SYSLOG_ACTION_CONSOLE_LEVEL: | ||
| 394 | error = -EINVAL; | 385 | error = -EINVAL; |
| 395 | if (len < 1 || len > 8) | 386 | if (len < 1 || len > 8) |
| 396 | goto out; | 387 | goto out; |
| @@ -401,10 +392,12 @@ int do_syslog(int type, char __user *buf, int len) | |||
| 401 | saved_console_loglevel = -1; | 392 | saved_console_loglevel = -1; |
| 402 | error = 0; | 393 | error = 0; |
| 403 | break; | 394 | break; |
| 404 | case 9: /* Number of chars in the log buffer */ | 395 | /* Number of chars in the log buffer */ |
| 396 | case SYSLOG_ACTION_SIZE_UNREAD: | ||
| 405 | error = log_end - log_start; | 397 | error = log_end - log_start; |
| 406 | break; | 398 | break; |
| 407 | case 10: /* Size of the log buffer */ | 399 | /* Size of the log buffer */ |
| 400 | case SYSLOG_ACTION_SIZE_BUFFER: | ||
| 408 | error = log_buf_len; | 401 | error = log_buf_len; |
| 409 | break; | 402 | break; |
| 410 | default: | 403 | default: |
| @@ -417,7 +410,7 @@ out: | |||
| 417 | 410 | ||
| 418 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) | 411 | SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) |
| 419 | { | 412 | { |
| 420 | return do_syslog(type, buf, len); | 413 | return do_syslog(type, buf, len, SYSLOG_FROM_CALL); |
| 421 | } | 414 | } |
| 422 | 415 | ||
| 423 | /* | 416 | /* |
