diff options
Diffstat (limited to 'kernel/printk.c')
| -rw-r--r-- | kernel/printk.c | 1390 |
1 files changed, 965 insertions, 425 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index b663c2c95d39..32462d2b364a 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/cpu.h> | 41 | #include <linux/cpu.h> |
| 42 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
| 43 | #include <linux/rculist.h> | 43 | #include <linux/rculist.h> |
| 44 | #include <linux/poll.h> | ||
| 44 | 45 | ||
| 45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
| 46 | 47 | ||
| @@ -54,8 +55,6 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) | |||
| 54 | { | 55 | { |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | ||
| 58 | |||
| 59 | /* printk's without a loglevel use this.. */ | 58 | /* printk's without a loglevel use this.. */ |
| 60 | #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL | 59 | #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL |
| 61 | 60 | ||
| @@ -99,24 +98,6 @@ EXPORT_SYMBOL_GPL(console_drivers); | |||
| 99 | static int console_locked, console_suspended; | 98 | static int console_locked, console_suspended; |
| 100 | 99 | ||
| 101 | /* | 100 | /* |
| 102 | * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars | ||
| 103 | * It is also used in interesting ways to provide interlocking in | ||
| 104 | * console_unlock();. | ||
| 105 | */ | ||
| 106 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | ||
| 107 | |||
| 108 | #define LOG_BUF_MASK (log_buf_len-1) | ||
| 109 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) | ||
| 110 | |||
| 111 | /* | ||
| 112 | * The indices into log_buf are not constrained to log_buf_len - they | ||
| 113 | * must be masked before subscripting | ||
| 114 | */ | ||
| 115 | static unsigned log_start; /* Index into log_buf: next char to be read by syslog() */ | ||
| 116 | static unsigned con_start; /* Index into log_buf: next char to be sent to consoles */ | ||
| 117 | static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ | ||
| 118 | |||
| 119 | /* | ||
| 120 | * If exclusive_console is non-NULL then only this console is to be printed to. | 101 | * If exclusive_console is non-NULL then only this console is to be printed to. |
| 121 | */ | 102 | */ |
| 122 | static struct console *exclusive_console; | 103 | static struct console *exclusive_console; |
| @@ -145,13 +126,491 @@ EXPORT_SYMBOL(console_set_on_cmdline); | |||
| 145 | /* Flag: console code may call schedule() */ | 126 | /* Flag: console code may call schedule() */ |
| 146 | static int console_may_schedule; | 127 | static int console_may_schedule; |
| 147 | 128 | ||
| 129 | /* | ||
| 130 | * The printk log buffer consists of a chain of concatenated variable | ||
| 131 | * length records. Every record starts with a record header, containing | ||
| 132 | * the overall length of the record. | ||
| 133 | * | ||
| 134 | * The heads to the first and last entry in the buffer, as well as the | ||
| 135 | * sequence numbers of these both entries are maintained when messages | ||
| 136 | * are stored.. | ||
| 137 | * | ||
| 138 | * If the heads indicate available messages, the length in the header | ||
| 139 | * tells the start next message. A length == 0 for the next message | ||
| 140 | * indicates a wrap-around to the beginning of the buffer. | ||
| 141 | * | ||
| 142 | * Every record carries the monotonic timestamp in microseconds, as well as | ||
| 143 | * the standard userspace syslog level and syslog facility. The usual | ||
| 144 | * kernel messages use LOG_KERN; userspace-injected messages always carry | ||
| 145 | * a matching syslog facility, by default LOG_USER. The origin of every | ||
| 146 | * message can be reliably determined that way. | ||
| 147 | * | ||
| 148 | * The human readable log message directly follows the message header. The | ||
| 149 | * length of the message text is stored in the header, the stored message | ||
| 150 | * is not terminated. | ||
| 151 | * | ||
| 152 | * Optionally, a message can carry a dictionary of properties (key/value pairs), | ||
| 153 | * to provide userspace with a machine-readable message context. | ||
| 154 | * | ||
| 155 | * Examples for well-defined, commonly used property names are: | ||
| 156 | * DEVICE=b12:8 device identifier | ||
| 157 | * b12:8 block dev_t | ||
| 158 | * c127:3 char dev_t | ||
| 159 | * n8 netdev ifindex | ||
| 160 | * +sound:card0 subsystem:devname | ||
| 161 | * SUBSYSTEM=pci driver-core subsystem name | ||
| 162 | * | ||
| 163 | * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value | ||
| 164 | * follows directly after a '=' character. Every property is terminated by | ||
| 165 | * a '\0' character. The last property is not terminated. | ||
| 166 | * | ||
| 167 | * Example of a message structure: | ||
| 168 | * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec | ||
| 169 | * 0008 34 00 record is 52 bytes long | ||
| 170 | * 000a 0b 00 text is 11 bytes long | ||
| 171 | * 000c 1f 00 dictionary is 23 bytes long | ||
| 172 | * 000e 03 00 LOG_KERN (facility) LOG_ERR (level) | ||
| 173 | * 0010 69 74 27 73 20 61 20 6c "it's a l" | ||
| 174 | * 69 6e 65 "ine" | ||
| 175 | * 001b 44 45 56 49 43 "DEVIC" | ||
| 176 | * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D" | ||
| 177 | * 52 49 56 45 52 3d 62 75 "RIVER=bu" | ||
| 178 | * 67 "g" | ||
| 179 | * 0032 00 00 00 padding to next message header | ||
| 180 | * | ||
| 181 | * The 'struct log' buffer header must never be directly exported to | ||
| 182 | * userspace, it is a kernel-private implementation detail that might | ||
| 183 | * need to be changed in the future, when the requirements change. | ||
| 184 | * | ||
| 185 | * /dev/kmsg exports the structured data in the following line format: | ||
| 186 | * "level,sequnum,timestamp;<message text>\n" | ||
| 187 | * | ||
| 188 | * The optional key/value pairs are attached as continuation lines starting | ||
| 189 | * with a space character and terminated by a newline. All possible | ||
| 190 | * non-prinatable characters are escaped in the "\xff" notation. | ||
| 191 | * | ||
| 192 | * Users of the export format should ignore possible additional values | ||
| 193 | * separated by ',', and find the message after the ';' character. | ||
| 194 | */ | ||
| 195 | |||
| 196 | struct log { | ||
| 197 | u64 ts_nsec; /* timestamp in nanoseconds */ | ||
| 198 | u16 len; /* length of entire record */ | ||
| 199 | u16 text_len; /* length of text buffer */ | ||
| 200 | u16 dict_len; /* length of dictionary buffer */ | ||
| 201 | u16 level; /* syslog level + facility */ | ||
| 202 | }; | ||
| 203 | |||
| 204 | /* | ||
| 205 | * The logbuf_lock protects kmsg buffer, indices, counters. It is also | ||
| 206 | * used in interesting ways to provide interlocking in console_unlock(); | ||
| 207 | */ | ||
| 208 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | ||
| 209 | |||
| 210 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ | ||
| 211 | static u64 syslog_seq; | ||
| 212 | static u32 syslog_idx; | ||
| 213 | |||
| 214 | /* index and sequence number of the first record stored in the buffer */ | ||
| 215 | static u64 log_first_seq; | ||
| 216 | static u32 log_first_idx; | ||
| 217 | |||
| 218 | /* index and sequence number of the next record to store in the buffer */ | ||
| 219 | static u64 log_next_seq; | ||
| 148 | #ifdef CONFIG_PRINTK | 220 | #ifdef CONFIG_PRINTK |
| 221 | static u32 log_next_idx; | ||
| 222 | |||
| 223 | /* the next printk record to read after the last 'clear' command */ | ||
| 224 | static u64 clear_seq; | ||
| 225 | static u32 clear_idx; | ||
| 226 | |||
| 227 | #define LOG_LINE_MAX 1024 | ||
| 149 | 228 | ||
| 150 | static char __log_buf[__LOG_BUF_LEN]; | 229 | /* record buffer */ |
| 230 | #if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
| 231 | #define LOG_ALIGN 4 | ||
| 232 | #else | ||
| 233 | #define LOG_ALIGN 8 | ||
| 234 | #endif | ||
| 235 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | ||
| 236 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); | ||
| 151 | static char *log_buf = __log_buf; | 237 | static char *log_buf = __log_buf; |
| 152 | static int log_buf_len = __LOG_BUF_LEN; | 238 | static u32 log_buf_len = __LOG_BUF_LEN; |
| 153 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ | 239 | |
| 154 | static int saved_console_loglevel = -1; | 240 | /* cpu currently holding logbuf_lock */ |
| 241 | static volatile unsigned int logbuf_cpu = UINT_MAX; | ||
| 242 | |||
| 243 | /* human readable text of the record */ | ||
| 244 | static char *log_text(const struct log *msg) | ||
| 245 | { | ||
| 246 | return (char *)msg + sizeof(struct log); | ||
| 247 | } | ||
| 248 | |||
| 249 | /* optional key/value pair dictionary attached to the record */ | ||
| 250 | static char *log_dict(const struct log *msg) | ||
| 251 | { | ||
| 252 | return (char *)msg + sizeof(struct log) + msg->text_len; | ||
| 253 | } | ||
| 254 | |||
| 255 | /* get record by index; idx must point to valid msg */ | ||
| 256 | static struct log *log_from_idx(u32 idx) | ||
| 257 | { | ||
| 258 | struct log *msg = (struct log *)(log_buf + idx); | ||
| 259 | |||
| 260 | /* | ||
| 261 | * A length == 0 record is the end of buffer marker. Wrap around and | ||
| 262 | * read the message at the start of the buffer. | ||
| 263 | */ | ||
| 264 | if (!msg->len) | ||
| 265 | return (struct log *)log_buf; | ||
| 266 | return msg; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* get next record; idx must point to valid msg */ | ||
| 270 | static u32 log_next(u32 idx) | ||
| 271 | { | ||
| 272 | struct log *msg = (struct log *)(log_buf + idx); | ||
| 273 | |||
| 274 | /* length == 0 indicates the end of the buffer; wrap */ | ||
| 275 | /* | ||
| 276 | * A length == 0 record is the end of buffer marker. Wrap around and | ||
| 277 | * read the message at the start of the buffer as *this* one, and | ||
| 278 | * return the one after that. | ||
| 279 | */ | ||
| 280 | if (!msg->len) { | ||
| 281 | msg = (struct log *)log_buf; | ||
| 282 | return msg->len; | ||
| 283 | } | ||
| 284 | return idx + msg->len; | ||
| 285 | } | ||
| 286 | |||
| 287 | /* insert record into the buffer, discard old ones, update heads */ | ||
| 288 | static void log_store(int facility, int level, | ||
| 289 | const char *dict, u16 dict_len, | ||
| 290 | const char *text, u16 text_len) | ||
| 291 | { | ||
| 292 | struct log *msg; | ||
| 293 | u32 size, pad_len; | ||
| 294 | |||
| 295 | /* number of '\0' padding bytes to next message */ | ||
| 296 | size = sizeof(struct log) + text_len + dict_len; | ||
| 297 | pad_len = (-size) & (LOG_ALIGN - 1); | ||
| 298 | size += pad_len; | ||
| 299 | |||
| 300 | while (log_first_seq < log_next_seq) { | ||
| 301 | u32 free; | ||
| 302 | |||
| 303 | if (log_next_idx > log_first_idx) | ||
| 304 | free = max(log_buf_len - log_next_idx, log_first_idx); | ||
| 305 | else | ||
| 306 | free = log_first_idx - log_next_idx; | ||
| 307 | |||
| 308 | if (free > size + sizeof(struct log)) | ||
| 309 | break; | ||
| 310 | |||
| 311 | /* drop old messages until we have enough contiuous space */ | ||
| 312 | log_first_idx = log_next(log_first_idx); | ||
| 313 | log_first_seq++; | ||
| 314 | } | ||
| 315 | |||
| 316 | if (log_next_idx + size + sizeof(struct log) >= log_buf_len) { | ||
| 317 | /* | ||
| 318 | * This message + an additional empty header does not fit | ||
| 319 | * at the end of the buffer. Add an empty header with len == 0 | ||
| 320 | * to signify a wrap around. | ||
| 321 | */ | ||
| 322 | memset(log_buf + log_next_idx, 0, sizeof(struct log)); | ||
| 323 | log_next_idx = 0; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* fill message */ | ||
| 327 | msg = (struct log *)(log_buf + log_next_idx); | ||
| 328 | memcpy(log_text(msg), text, text_len); | ||
| 329 | msg->text_len = text_len; | ||
| 330 | memcpy(log_dict(msg), dict, dict_len); | ||
| 331 | msg->dict_len = dict_len; | ||
| 332 | msg->level = (facility << 3) | (level & 7); | ||
| 333 | msg->ts_nsec = local_clock(); | ||
| 334 | memset(log_dict(msg) + dict_len, 0, pad_len); | ||
| 335 | msg->len = sizeof(struct log) + text_len + dict_len + pad_len; | ||
| 336 | |||
| 337 | /* insert message */ | ||
| 338 | log_next_idx += msg->len; | ||
| 339 | log_next_seq++; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* /dev/kmsg - userspace message inject/listen interface */ | ||
| 343 | struct devkmsg_user { | ||
| 344 | u64 seq; | ||
| 345 | u32 idx; | ||
| 346 | struct mutex lock; | ||
| 347 | char buf[8192]; | ||
| 348 | }; | ||
| 349 | |||
| 350 | static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, | ||
| 351 | unsigned long count, loff_t pos) | ||
| 352 | { | ||
| 353 | char *buf, *line; | ||
| 354 | int i; | ||
| 355 | int level = default_message_loglevel; | ||
| 356 | int facility = 1; /* LOG_USER */ | ||
| 357 | size_t len = iov_length(iv, count); | ||
| 358 | ssize_t ret = len; | ||
| 359 | |||
| 360 | if (len > LOG_LINE_MAX) | ||
| 361 | return -EINVAL; | ||
| 362 | buf = kmalloc(len+1, GFP_KERNEL); | ||
| 363 | if (buf == NULL) | ||
| 364 | return -ENOMEM; | ||
| 365 | |||
| 366 | line = buf; | ||
| 367 | for (i = 0; i < count; i++) { | ||
| 368 | if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) | ||
| 369 | goto out; | ||
| 370 | line += iv[i].iov_len; | ||
| 371 | } | ||
| 372 | |||
| 373 | /* | ||
| 374 | * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace | ||
| 375 | * the decimal value represents 32bit, the lower 3 bit are the log | ||
| 376 | * level, the rest are the log facility. | ||
| 377 | * | ||
| 378 | * If no prefix or no userspace facility is specified, we | ||
| 379 | * enforce LOG_USER, to be able to reliably distinguish | ||
| 380 | * kernel-generated messages from userspace-injected ones. | ||
| 381 | */ | ||
| 382 | line = buf; | ||
| 383 | if (line[0] == '<') { | ||
| 384 | char *endp = NULL; | ||
| 385 | |||
| 386 | i = simple_strtoul(line+1, &endp, 10); | ||
| 387 | if (endp && endp[0] == '>') { | ||
| 388 | level = i & 7; | ||
| 389 | if (i >> 3) | ||
| 390 | facility = i >> 3; | ||
| 391 | endp++; | ||
| 392 | len -= endp - line; | ||
| 393 | line = endp; | ||
| 394 | } | ||
| 395 | } | ||
| 396 | line[len] = '\0'; | ||
| 397 | |||
| 398 | printk_emit(facility, level, NULL, 0, "%s", line); | ||
| 399 | out: | ||
| 400 | kfree(buf); | ||
| 401 | return ret; | ||
| 402 | } | ||
| 403 | |||
| 404 | static ssize_t devkmsg_read(struct file *file, char __user *buf, | ||
| 405 | size_t count, loff_t *ppos) | ||
| 406 | { | ||
| 407 | struct devkmsg_user *user = file->private_data; | ||
| 408 | struct log *msg; | ||
| 409 | u64 ts_usec; | ||
| 410 | size_t i; | ||
| 411 | size_t len; | ||
| 412 | ssize_t ret; | ||
| 413 | |||
| 414 | if (!user) | ||
| 415 | return -EBADF; | ||
| 416 | |||
| 417 | mutex_lock(&user->lock); | ||
| 418 | raw_spin_lock(&logbuf_lock); | ||
| 419 | while (user->seq == log_next_seq) { | ||
| 420 | if (file->f_flags & O_NONBLOCK) { | ||
| 421 | ret = -EAGAIN; | ||
| 422 | raw_spin_unlock(&logbuf_lock); | ||
| 423 | goto out; | ||
| 424 | } | ||
| 425 | |||
| 426 | raw_spin_unlock(&logbuf_lock); | ||
| 427 | ret = wait_event_interruptible(log_wait, | ||
| 428 | user->seq != log_next_seq); | ||
| 429 | if (ret) | ||
| 430 | goto out; | ||
| 431 | raw_spin_lock(&logbuf_lock); | ||
| 432 | } | ||
| 433 | |||
| 434 | if (user->seq < log_first_seq) { | ||
| 435 | /* our last seen message is gone, return error and reset */ | ||
| 436 | user->idx = log_first_idx; | ||
| 437 | user->seq = log_first_seq; | ||
| 438 | ret = -EPIPE; | ||
| 439 | raw_spin_unlock(&logbuf_lock); | ||
| 440 | goto out; | ||
| 441 | } | ||
| 442 | |||
| 443 | msg = log_from_idx(user->idx); | ||
| 444 | ts_usec = msg->ts_nsec; | ||
| 445 | do_div(ts_usec, 1000); | ||
| 446 | len = sprintf(user->buf, "%u,%llu,%llu;", | ||
| 447 | msg->level, user->seq, ts_usec); | ||
| 448 | |||
| 449 | /* escape non-printable characters */ | ||
| 450 | for (i = 0; i < msg->text_len; i++) { | ||
| 451 | unsigned char c = log_text(msg)[i]; | ||
| 452 | |||
| 453 | if (c < ' ' || c >= 128) | ||
| 454 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
| 455 | else | ||
| 456 | user->buf[len++] = c; | ||
| 457 | } | ||
| 458 | user->buf[len++] = '\n'; | ||
| 459 | |||
| 460 | if (msg->dict_len) { | ||
| 461 | bool line = true; | ||
| 462 | |||
| 463 | for (i = 0; i < msg->dict_len; i++) { | ||
| 464 | unsigned char c = log_dict(msg)[i]; | ||
| 465 | |||
| 466 | if (line) { | ||
| 467 | user->buf[len++] = ' '; | ||
| 468 | line = false; | ||
| 469 | } | ||
| 470 | |||
| 471 | if (c == '\0') { | ||
| 472 | user->buf[len++] = '\n'; | ||
| 473 | line = true; | ||
| 474 | continue; | ||
| 475 | } | ||
| 476 | |||
| 477 | if (c < ' ' || c >= 128) { | ||
| 478 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
| 479 | continue; | ||
| 480 | } | ||
| 481 | |||
| 482 | user->buf[len++] = c; | ||
| 483 | } | ||
| 484 | user->buf[len++] = '\n'; | ||
| 485 | } | ||
| 486 | |||
| 487 | user->idx = log_next(user->idx); | ||
| 488 | user->seq++; | ||
| 489 | raw_spin_unlock(&logbuf_lock); | ||
| 490 | |||
| 491 | if (len > count) { | ||
| 492 | ret = -EINVAL; | ||
| 493 | goto out; | ||
| 494 | } | ||
| 495 | |||
| 496 | if (copy_to_user(buf, user->buf, len)) { | ||
| 497 | ret = -EFAULT; | ||
| 498 | goto out; | ||
| 499 | } | ||
| 500 | ret = len; | ||
| 501 | out: | ||
| 502 | mutex_unlock(&user->lock); | ||
| 503 | return ret; | ||
| 504 | } | ||
| 505 | |||
| 506 | static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence) | ||
| 507 | { | ||
| 508 | struct devkmsg_user *user = file->private_data; | ||
| 509 | loff_t ret = 0; | ||
| 510 | |||
| 511 | if (!user) | ||
| 512 | return -EBADF; | ||
| 513 | if (offset) | ||
| 514 | return -ESPIPE; | ||
| 515 | |||
| 516 | raw_spin_lock(&logbuf_lock); | ||
| 517 | switch (whence) { | ||
| 518 | case SEEK_SET: | ||
| 519 | /* the first record */ | ||
| 520 | user->idx = log_first_idx; | ||
| 521 | user->seq = log_first_seq; | ||
| 522 | break; | ||
| 523 | case SEEK_DATA: | ||
| 524 | /* | ||
| 525 | * The first record after the last SYSLOG_ACTION_CLEAR, | ||
| 526 | * like issued by 'dmesg -c'. Reading /dev/kmsg itself | ||
| 527 | * changes no global state, and does not clear anything. | ||
| 528 | */ | ||
| 529 | user->idx = clear_idx; | ||
| 530 | user->seq = clear_seq; | ||
| 531 | break; | ||
| 532 | case SEEK_END: | ||
| 533 | /* after the last record */ | ||
| 534 | user->idx = log_next_idx; | ||
| 535 | user->seq = log_next_seq; | ||
| 536 | break; | ||
| 537 | default: | ||
| 538 | ret = -EINVAL; | ||
| 539 | } | ||
| 540 | raw_spin_unlock(&logbuf_lock); | ||
| 541 | return ret; | ||
| 542 | } | ||
| 543 | |||
| 544 | static unsigned int devkmsg_poll(struct file *file, poll_table *wait) | ||
| 545 | { | ||
| 546 | struct devkmsg_user *user = file->private_data; | ||
| 547 | int ret = 0; | ||
| 548 | |||
| 549 | if (!user) | ||
| 550 | return POLLERR|POLLNVAL; | ||
| 551 | |||
| 552 | poll_wait(file, &log_wait, wait); | ||
| 553 | |||
| 554 | raw_spin_lock(&logbuf_lock); | ||
| 555 | if (user->seq < log_next_seq) { | ||
| 556 | /* return error when data has vanished underneath us */ | ||
| 557 | if (user->seq < log_first_seq) | ||
| 558 | ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; | ||
| 559 | ret = POLLIN|POLLRDNORM; | ||
| 560 | } | ||
| 561 | raw_spin_unlock(&logbuf_lock); | ||
| 562 | |||
| 563 | return ret; | ||
| 564 | } | ||
| 565 | |||
| 566 | static int devkmsg_open(struct inode *inode, struct file *file) | ||
| 567 | { | ||
| 568 | struct devkmsg_user *user; | ||
| 569 | int err; | ||
| 570 | |||
| 571 | /* write-only does not need any file context */ | ||
| 572 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | ||
| 573 | return 0; | ||
| 574 | |||
| 575 | err = security_syslog(SYSLOG_ACTION_READ_ALL); | ||
| 576 | if (err) | ||
| 577 | return err; | ||
| 578 | |||
| 579 | user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL); | ||
| 580 | if (!user) | ||
| 581 | return -ENOMEM; | ||
| 582 | |||
| 583 | mutex_init(&user->lock); | ||
| 584 | |||
| 585 | raw_spin_lock(&logbuf_lock); | ||
| 586 | user->idx = log_first_idx; | ||
| 587 | user->seq = log_first_seq; | ||
| 588 | raw_spin_unlock(&logbuf_lock); | ||
| 589 | |||
| 590 | file->private_data = user; | ||
| 591 | return 0; | ||
| 592 | } | ||
| 593 | |||
| 594 | static int devkmsg_release(struct inode *inode, struct file *file) | ||
| 595 | { | ||
| 596 | struct devkmsg_user *user = file->private_data; | ||
| 597 | |||
| 598 | if (!user) | ||
| 599 | return 0; | ||
| 600 | |||
| 601 | mutex_destroy(&user->lock); | ||
| 602 | kfree(user); | ||
| 603 | return 0; | ||
| 604 | } | ||
| 605 | |||
| 606 | const struct file_operations kmsg_fops = { | ||
| 607 | .open = devkmsg_open, | ||
| 608 | .read = devkmsg_read, | ||
| 609 | .aio_write = devkmsg_writev, | ||
| 610 | .llseek = devkmsg_llseek, | ||
| 611 | .poll = devkmsg_poll, | ||
| 612 | .release = devkmsg_release, | ||
| 613 | }; | ||
| 155 | 614 | ||
| 156 | #ifdef CONFIG_KEXEC | 615 | #ifdef CONFIG_KEXEC |
| 157 | /* | 616 | /* |
| @@ -165,9 +624,9 @@ static int saved_console_loglevel = -1; | |||
| 165 | void log_buf_kexec_setup(void) | 624 | void log_buf_kexec_setup(void) |
| 166 | { | 625 | { |
| 167 | VMCOREINFO_SYMBOL(log_buf); | 626 | VMCOREINFO_SYMBOL(log_buf); |
| 168 | VMCOREINFO_SYMBOL(log_end); | ||
| 169 | VMCOREINFO_SYMBOL(log_buf_len); | 627 | VMCOREINFO_SYMBOL(log_buf_len); |
| 170 | VMCOREINFO_SYMBOL(logged_chars); | 628 | VMCOREINFO_SYMBOL(log_first_idx); |
| 629 | VMCOREINFO_SYMBOL(log_next_idx); | ||
| 171 | } | 630 | } |
| 172 | #endif | 631 | #endif |
| 173 | 632 | ||
| @@ -191,7 +650,6 @@ early_param("log_buf_len", log_buf_len_setup); | |||
| 191 | void __init setup_log_buf(int early) | 650 | void __init setup_log_buf(int early) |
| 192 | { | 651 | { |
| 193 | unsigned long flags; | 652 | unsigned long flags; |
| 194 | unsigned start, dest_idx, offset; | ||
| 195 | char *new_log_buf; | 653 | char *new_log_buf; |
| 196 | int free; | 654 | int free; |
| 197 | 655 | ||
| @@ -219,20 +677,8 @@ void __init setup_log_buf(int early) | |||
| 219 | log_buf_len = new_log_buf_len; | 677 | log_buf_len = new_log_buf_len; |
| 220 | log_buf = new_log_buf; | 678 | log_buf = new_log_buf; |
| 221 | new_log_buf_len = 0; | 679 | new_log_buf_len = 0; |
| 222 | free = __LOG_BUF_LEN - log_end; | 680 | free = __LOG_BUF_LEN - log_next_idx; |
| 223 | 681 | memcpy(log_buf, __log_buf, __LOG_BUF_LEN); | |
| 224 | offset = start = min(con_start, log_start); | ||
| 225 | dest_idx = 0; | ||
| 226 | while (start != log_end) { | ||
| 227 | unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1); | ||
| 228 | |||
| 229 | log_buf[dest_idx] = __log_buf[log_idx_mask]; | ||
| 230 | start++; | ||
| 231 | dest_idx++; | ||
| 232 | } | ||
| 233 | log_start -= offset; | ||
| 234 | con_start -= offset; | ||
| 235 | log_end -= offset; | ||
| 236 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 682 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| 237 | 683 | ||
| 238 | pr_info("log_buf_len: %d\n", log_buf_len); | 684 | pr_info("log_buf_len: %d\n", log_buf_len); |
| @@ -332,11 +778,202 @@ static int check_syslog_permissions(int type, bool from_file) | |||
| 332 | return 0; | 778 | return 0; |
| 333 | } | 779 | } |
| 334 | 780 | ||
| 781 | #if defined(CONFIG_PRINTK_TIME) | ||
| 782 | static bool printk_time = 1; | ||
| 783 | #else | ||
| 784 | static bool printk_time; | ||
| 785 | #endif | ||
| 786 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | ||
| 787 | |||
| 788 | static size_t print_prefix(const struct log *msg, bool syslog, char *buf) | ||
| 789 | { | ||
| 790 | size_t len = 0; | ||
| 791 | |||
| 792 | if (syslog) { | ||
| 793 | if (buf) { | ||
| 794 | len += sprintf(buf, "<%u>", msg->level); | ||
| 795 | } else { | ||
| 796 | len += 3; | ||
| 797 | if (msg->level > 9) | ||
| 798 | len++; | ||
| 799 | if (msg->level > 99) | ||
| 800 | len++; | ||
| 801 | } | ||
| 802 | } | ||
| 803 | |||
| 804 | if (printk_time) { | ||
| 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; | ||
| 817 | } | ||
| 818 | |||
| 819 | static size_t msg_print_text(const struct log *msg, bool syslog, | ||
| 820 | char *buf, size_t size) | ||
| 821 | { | ||
| 822 | const char *text = log_text(msg); | ||
| 823 | size_t text_size = msg->text_len; | ||
| 824 | size_t len = 0; | ||
| 825 | |||
| 826 | do { | ||
| 827 | const char *next = memchr(text, '\n', text_size); | ||
| 828 | size_t text_len; | ||
| 829 | |||
| 830 | if (next) { | ||
| 831 | text_len = next - text; | ||
| 832 | next++; | ||
| 833 | text_size -= next - text; | ||
| 834 | } else { | ||
| 835 | text_len = text_size; | ||
| 836 | } | ||
| 837 | |||
| 838 | if (buf) { | ||
| 839 | if (print_prefix(msg, syslog, NULL) + | ||
| 840 | text_len + 1>= size - len) | ||
| 841 | break; | ||
| 842 | |||
| 843 | len += print_prefix(msg, syslog, buf + len); | ||
| 844 | memcpy(buf + len, text, text_len); | ||
| 845 | len += text_len; | ||
| 846 | buf[len++] = '\n'; | ||
| 847 | } else { | ||
| 848 | /* SYSLOG_ACTION_* buffer size only calculation */ | ||
| 849 | len += print_prefix(msg, syslog, NULL); | ||
| 850 | len += text_len + 1; | ||
| 851 | } | ||
| 852 | |||
| 853 | text = next; | ||
| 854 | } while (text); | ||
| 855 | |||
| 856 | return len; | ||
| 857 | } | ||
| 858 | |||
| 859 | static int syslog_print(char __user *buf, int size) | ||
| 860 | { | ||
| 861 | char *text; | ||
| 862 | struct log *msg; | ||
| 863 | int len; | ||
| 864 | |||
| 865 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | ||
| 866 | if (!text) | ||
| 867 | return -ENOMEM; | ||
| 868 | |||
| 869 | raw_spin_lock_irq(&logbuf_lock); | ||
| 870 | if (syslog_seq < log_first_seq) { | ||
| 871 | /* messages are gone, move to first one */ | ||
| 872 | syslog_seq = log_first_seq; | ||
| 873 | syslog_idx = log_first_idx; | ||
| 874 | } | ||
| 875 | msg = log_from_idx(syslog_idx); | ||
| 876 | len = msg_print_text(msg, true, text, LOG_LINE_MAX); | ||
| 877 | syslog_idx = log_next(syslog_idx); | ||
| 878 | syslog_seq++; | ||
| 879 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 880 | |||
| 881 | if (len > 0 && copy_to_user(buf, text, len)) | ||
| 882 | len = -EFAULT; | ||
| 883 | |||
| 884 | kfree(text); | ||
| 885 | return len; | ||
| 886 | } | ||
| 887 | |||
| 888 | static int syslog_print_all(char __user *buf, int size, bool clear) | ||
| 889 | { | ||
| 890 | char *text; | ||
| 891 | int len = 0; | ||
| 892 | |||
| 893 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | ||
| 894 | if (!text) | ||
| 895 | return -ENOMEM; | ||
| 896 | |||
| 897 | raw_spin_lock_irq(&logbuf_lock); | ||
| 898 | if (buf) { | ||
| 899 | u64 next_seq; | ||
| 900 | u64 seq; | ||
| 901 | u32 idx; | ||
| 902 | |||
| 903 | if (clear_seq < log_first_seq) { | ||
| 904 | /* messages are gone, move to first available one */ | ||
| 905 | clear_seq = log_first_seq; | ||
| 906 | clear_idx = log_first_idx; | ||
| 907 | } | ||
| 908 | |||
| 909 | /* | ||
| 910 | * Find first record that fits, including all following records, | ||
| 911 | * into the user-provided buffer for this dump. | ||
| 912 | */ | ||
| 913 | seq = clear_seq; | ||
| 914 | idx = clear_idx; | ||
| 915 | while (seq < log_next_seq) { | ||
| 916 | struct log *msg = log_from_idx(idx); | ||
| 917 | |||
| 918 | len += msg_print_text(msg, true, NULL, 0); | ||
| 919 | idx = log_next(idx); | ||
| 920 | seq++; | ||
| 921 | } | ||
| 922 | seq = clear_seq; | ||
| 923 | idx = clear_idx; | ||
| 924 | while (len > size && seq < log_next_seq) { | ||
| 925 | struct log *msg = log_from_idx(idx); | ||
| 926 | |||
| 927 | len -= msg_print_text(msg, true, NULL, 0); | ||
| 928 | idx = log_next(idx); | ||
| 929 | seq++; | ||
| 930 | } | ||
| 931 | |||
| 932 | /* last message in this dump */ | ||
| 933 | next_seq = log_next_seq; | ||
| 934 | |||
| 935 | len = 0; | ||
| 936 | while (len >= 0 && seq < next_seq) { | ||
| 937 | struct log *msg = log_from_idx(idx); | ||
| 938 | int textlen; | ||
| 939 | |||
| 940 | textlen = msg_print_text(msg, true, text, LOG_LINE_MAX); | ||
| 941 | if (textlen < 0) { | ||
| 942 | len = textlen; | ||
| 943 | break; | ||
| 944 | } | ||
| 945 | idx = log_next(idx); | ||
| 946 | seq++; | ||
| 947 | |||
| 948 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 949 | if (copy_to_user(buf + len, text, textlen)) | ||
| 950 | len = -EFAULT; | ||
| 951 | else | ||
| 952 | len += textlen; | ||
| 953 | raw_spin_lock_irq(&logbuf_lock); | ||
| 954 | |||
| 955 | if (seq < log_first_seq) { | ||
| 956 | /* messages are gone, move to next one */ | ||
| 957 | seq = log_first_seq; | ||
| 958 | idx = log_first_idx; | ||
| 959 | } | ||
| 960 | } | ||
| 961 | } | ||
| 962 | |||
| 963 | if (clear) { | ||
| 964 | clear_seq = log_next_seq; | ||
| 965 | clear_idx = log_next_idx; | ||
| 966 | } | ||
| 967 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 968 | |||
| 969 | kfree(text); | ||
| 970 | return len; | ||
| 971 | } | ||
| 972 | |||
| 335 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 973 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
| 336 | { | 974 | { |
| 337 | unsigned i, j, limit, count; | 975 | bool clear = false; |
| 338 | int do_clear = 0; | 976 | static int saved_console_loglevel = -1; |
| 339 | char c; | ||
| 340 | int error; | 977 | int error; |
| 341 | 978 | ||
| 342 | error = check_syslog_permissions(type, from_file); | 979 | error = check_syslog_permissions(type, from_file); |
| @@ -364,28 +1001,14 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 364 | goto out; | 1001 | goto out; |
| 365 | } | 1002 | } |
| 366 | error = wait_event_interruptible(log_wait, | 1003 | error = wait_event_interruptible(log_wait, |
| 367 | (log_start - log_end)); | 1004 | syslog_seq != log_next_seq); |
| 368 | if (error) | 1005 | if (error) |
| 369 | goto out; | 1006 | goto out; |
| 370 | i = 0; | 1007 | error = syslog_print(buf, len); |
| 371 | raw_spin_lock_irq(&logbuf_lock); | ||
| 372 | while (!error && (log_start != log_end) && i < len) { | ||
| 373 | c = LOG_BUF(log_start); | ||
| 374 | log_start++; | ||
| 375 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 376 | error = __put_user(c,buf); | ||
| 377 | buf++; | ||
| 378 | i++; | ||
| 379 | cond_resched(); | ||
| 380 | raw_spin_lock_irq(&logbuf_lock); | ||
| 381 | } | ||
| 382 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 383 | if (!error) | ||
| 384 | error = i; | ||
| 385 | break; | 1008 | break; |
| 386 | /* Read/clear last kernel messages */ | 1009 | /* Read/clear last kernel messages */ |
| 387 | case SYSLOG_ACTION_READ_CLEAR: | 1010 | case SYSLOG_ACTION_READ_CLEAR: |
| 388 | do_clear = 1; | 1011 | clear = true; |
| 389 | /* FALL THRU */ | 1012 | /* FALL THRU */ |
| 390 | /* Read last kernel messages */ | 1013 | /* Read last kernel messages */ |
| 391 | case SYSLOG_ACTION_READ_ALL: | 1014 | case SYSLOG_ACTION_READ_ALL: |
| @@ -399,52 +1022,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 399 | error = -EFAULT; | 1022 | error = -EFAULT; |
| 400 | goto out; | 1023 | goto out; |
| 401 | } | 1024 | } |
| 402 | count = len; | 1025 | error = syslog_print_all(buf, len, clear); |
| 403 | if (count > log_buf_len) | ||
| 404 | count = log_buf_len; | ||
| 405 | raw_spin_lock_irq(&logbuf_lock); | ||
| 406 | if (count > logged_chars) | ||
| 407 | count = logged_chars; | ||
| 408 | if (do_clear) | ||
| 409 | logged_chars = 0; | ||
| 410 | limit = log_end; | ||
| 411 | /* | ||
| 412 | * __put_user() could sleep, and while we sleep | ||
| 413 | * printk() could overwrite the messages | ||
| 414 | * we try to copy to user space. Therefore | ||
| 415 | * the messages are copied in reverse. <manfreds> | ||
| 416 | */ | ||
| 417 | for (i = 0; i < count && !error; i++) { | ||
| 418 | j = limit-1-i; | ||
| 419 | if (j + log_buf_len < log_end) | ||
| 420 | break; | ||
| 421 | c = LOG_BUF(j); | ||
| 422 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 423 | error = __put_user(c,&buf[count-1-i]); | ||
| 424 | cond_resched(); | ||
| 425 | raw_spin_lock_irq(&logbuf_lock); | ||
| 426 | } | ||
| 427 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 428 | if (error) | ||
| 429 | break; | ||
| 430 | error = i; | ||
| 431 | if (i != count) { | ||
| 432 | int offset = count-error; | ||
| 433 | /* buffer overflow during copy, correct user buffer. */ | ||
| 434 | for (i = 0; i < error; i++) { | ||
| 435 | if (__get_user(c,&buf[i+offset]) || | ||
| 436 | __put_user(c,&buf[i])) { | ||
| 437 | error = -EFAULT; | ||
| 438 | break; | ||
| 439 | } | ||
| 440 | cond_resched(); | ||
| 441 | } | ||
| 442 | } | ||
| 443 | break; | 1026 | break; |
| 444 | /* Clear ring buffer */ | 1027 | /* Clear ring buffer */ |
| 445 | case SYSLOG_ACTION_CLEAR: | 1028 | case SYSLOG_ACTION_CLEAR: |
| 446 | logged_chars = 0; | 1029 | syslog_print_all(NULL, 0, true); |
| 447 | break; | ||
| 448 | /* Disable logging to console */ | 1030 | /* Disable logging to console */ |
| 449 | case SYSLOG_ACTION_CONSOLE_OFF: | 1031 | case SYSLOG_ACTION_CONSOLE_OFF: |
| 450 | if (saved_console_loglevel == -1) | 1032 | if (saved_console_loglevel == -1) |
| @@ -472,7 +1054,35 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
| 472 | break; | 1054 | break; |
| 473 | /* Number of chars in the log buffer */ | 1055 | /* Number of chars in the log buffer */ |
| 474 | case SYSLOG_ACTION_SIZE_UNREAD: | 1056 | case SYSLOG_ACTION_SIZE_UNREAD: |
| 475 | error = log_end - log_start; | 1057 | raw_spin_lock_irq(&logbuf_lock); |
| 1058 | if (syslog_seq < log_first_seq) { | ||
| 1059 | /* messages are gone, move to first one */ | ||
| 1060 | syslog_seq = log_first_seq; | ||
| 1061 | syslog_idx = log_first_idx; | ||
| 1062 | } | ||
| 1063 | if (from_file) { | ||
| 1064 | /* | ||
| 1065 | * Short-cut for poll(/"proc/kmsg") which simply checks | ||
| 1066 | * for pending data, not the size; return the count of | ||
| 1067 | * records, not the length. | ||
| 1068 | */ | ||
| 1069 | error = log_next_idx - syslog_idx; | ||
| 1070 | } else { | ||
| 1071 | u64 seq; | ||
| 1072 | u32 idx; | ||
| 1073 | |||
| 1074 | error = 0; | ||
| 1075 | seq = syslog_seq; | ||
| 1076 | idx = syslog_idx; | ||
| 1077 | while (seq < log_next_seq) { | ||
| 1078 | struct log *msg = log_from_idx(idx); | ||
| 1079 | |||
| 1080 | error += msg_print_text(msg, true, NULL, 0); | ||
| 1081 | idx = log_next(idx); | ||
| 1082 | seq++; | ||
| 1083 | } | ||
| 1084 | } | ||
| 1085 | raw_spin_unlock_irq(&logbuf_lock); | ||
| 476 | break; | 1086 | break; |
| 477 | /* Size of the log buffer */ | 1087 | /* Size of the log buffer */ |
| 478 | case SYSLOG_ACTION_SIZE_BUFFER: | 1088 | case SYSLOG_ACTION_SIZE_BUFFER: |
| @@ -501,29 +1111,11 @@ void kdb_syslog_data(char *syslog_data[4]) | |||
| 501 | { | 1111 | { |
| 502 | syslog_data[0] = log_buf; | 1112 | syslog_data[0] = log_buf; |
| 503 | syslog_data[1] = log_buf + log_buf_len; | 1113 | syslog_data[1] = log_buf + log_buf_len; |
| 504 | syslog_data[2] = log_buf + log_end - | 1114 | syslog_data[2] = log_buf + log_first_idx; |
| 505 | (logged_chars < log_buf_len ? logged_chars : log_buf_len); | 1115 | syslog_data[3] = log_buf + log_next_idx; |
| 506 | syslog_data[3] = log_buf + log_end; | ||
| 507 | } | 1116 | } |
| 508 | #endif /* CONFIG_KGDB_KDB */ | 1117 | #endif /* CONFIG_KGDB_KDB */ |
| 509 | 1118 | ||
| 510 | /* | ||
| 511 | * Call the console drivers on a range of log_buf | ||
| 512 | */ | ||
| 513 | static void __call_console_drivers(unsigned start, unsigned end) | ||
| 514 | { | ||
| 515 | struct console *con; | ||
| 516 | |||
| 517 | for_each_console(con) { | ||
| 518 | if (exclusive_console && con != exclusive_console) | ||
| 519 | continue; | ||
| 520 | if ((con->flags & CON_ENABLED) && con->write && | ||
| 521 | (cpu_online(smp_processor_id()) || | ||
| 522 | (con->flags & CON_ANYTIME))) | ||
| 523 | con->write(con, &LOG_BUF(start), end - start); | ||
| 524 | } | ||
| 525 | } | ||
| 526 | |||
| 527 | static bool __read_mostly ignore_loglevel; | 1119 | static bool __read_mostly ignore_loglevel; |
| 528 | 1120 | ||
| 529 | static int __init ignore_loglevel_setup(char *str) | 1121 | static int __init ignore_loglevel_setup(char *str) |
| @@ -540,142 +1132,33 @@ MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to" | |||
| 540 | "print all kernel messages to the console."); | 1132 | "print all kernel messages to the console."); |
| 541 | 1133 | ||
| 542 | /* | 1134 | /* |
| 543 | * Write out chars from start to end - 1 inclusive | ||
| 544 | */ | ||
| 545 | static void _call_console_drivers(unsigned start, | ||
| 546 | unsigned end, int msg_log_level) | ||
| 547 | { | ||
| 548 | trace_console(&LOG_BUF(0), start, end, log_buf_len); | ||
| 549 | |||
| 550 | if ((msg_log_level < console_loglevel || ignore_loglevel) && | ||
| 551 | console_drivers && start != end) { | ||
| 552 | if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { | ||
| 553 | /* wrapped write */ | ||
| 554 | __call_console_drivers(start & LOG_BUF_MASK, | ||
| 555 | log_buf_len); | ||
| 556 | __call_console_drivers(0, end & LOG_BUF_MASK); | ||
| 557 | } else { | ||
| 558 | __call_console_drivers(start, end); | ||
| 559 | } | ||
| 560 | } | ||
| 561 | } | ||
| 562 | |||
| 563 | /* | ||
| 564 | * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the | ||
| 565 | * lower 3 bit are the log level, the rest are the log facility. In case | ||
| 566 | * userspace passes usual userspace syslog messages to /dev/kmsg or | ||
| 567 | * /dev/ttyprintk, the log prefix might contain the facility. Printk needs | ||
| 568 | * to extract the correct log level for in-kernel processing, and not mangle | ||
| 569 | * the original value. | ||
| 570 | * | ||
| 571 | * If a prefix is found, the length of the prefix is returned. If 'level' is | ||
| 572 | * passed, it will be filled in with the log level without a possible facility | ||
| 573 | * value. If 'special' is passed, the special printk prefix chars are accepted | ||
| 574 | * and returned. If no valid header is found, 0 is returned and the passed | ||
| 575 | * variables are not touched. | ||
| 576 | */ | ||
| 577 | static size_t log_prefix(const char *p, unsigned int *level, char *special) | ||
| 578 | { | ||
| 579 | unsigned int lev = 0; | ||
| 580 | char sp = '\0'; | ||
| 581 | size_t len; | ||
| 582 | |||
| 583 | if (p[0] != '<' || !p[1]) | ||
| 584 | return 0; | ||
| 585 | if (p[2] == '>') { | ||
| 586 | /* usual single digit level number or special char */ | ||
| 587 | switch (p[1]) { | ||
| 588 | case '0' ... '7': | ||
| 589 | lev = p[1] - '0'; | ||
| 590 | break; | ||
| 591 | case 'c': /* KERN_CONT */ | ||
| 592 | case 'd': /* KERN_DEFAULT */ | ||
| 593 | sp = p[1]; | ||
| 594 | break; | ||
| 595 | default: | ||
| 596 | return 0; | ||
| 597 | } | ||
| 598 | len = 3; | ||
| 599 | } else { | ||
| 600 | /* multi digit including the level and facility number */ | ||
| 601 | char *endp = NULL; | ||
| 602 | |||
| 603 | lev = (simple_strtoul(&p[1], &endp, 10) & 7); | ||
| 604 | if (endp == NULL || endp[0] != '>') | ||
| 605 | return 0; | ||
| 606 | len = (endp + 1) - p; | ||
| 607 | } | ||
| 608 | |||
| 609 | /* do not accept special char if not asked for */ | ||
| 610 | if (sp && !special) | ||
| 611 | return 0; | ||
| 612 | |||
| 613 | if (special) { | ||
| 614 | *special = sp; | ||
| 615 | /* return special char, do not touch level */ | ||
| 616 | if (sp) | ||
| 617 | return len; | ||
| 618 | } | ||
| 619 | |||
| 620 | if (level) | ||
| 621 | *level = lev; | ||
| 622 | return len; | ||
| 623 | } | ||
| 624 | |||
| 625 | /* | ||
| 626 | * Call the console drivers, asking them to write out | 1135 | * Call the console drivers, asking them to write out |
| 627 | * log_buf[start] to log_buf[end - 1]. | 1136 | * log_buf[start] to log_buf[end - 1]. |
| 628 | * The console_lock must be held. | 1137 | * The console_lock must be held. |
| 629 | */ | 1138 | */ |
| 630 | static void call_console_drivers(unsigned start, unsigned end) | 1139 | static void call_console_drivers(int level, const char *text, size_t len) |
| 631 | { | 1140 | { |
| 632 | unsigned cur_index, start_print; | 1141 | struct console *con; |
| 633 | static int msg_level = -1; | ||
| 634 | 1142 | ||
| 635 | BUG_ON(((int)(start - end)) > 0); | 1143 | trace_console(text, 0, len, len); |
| 636 | 1144 | ||
| 637 | cur_index = start; | 1145 | if (level >= console_loglevel && !ignore_loglevel) |
| 638 | start_print = start; | 1146 | return; |
| 639 | while (cur_index != end) { | 1147 | if (!console_drivers) |
| 640 | if (msg_level < 0 && ((end - cur_index) > 2)) { | 1148 | return; |
| 641 | /* strip log prefix */ | ||
| 642 | cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL); | ||
| 643 | start_print = cur_index; | ||
| 644 | } | ||
| 645 | while (cur_index != end) { | ||
| 646 | char c = LOG_BUF(cur_index); | ||
| 647 | |||
| 648 | cur_index++; | ||
| 649 | if (c == '\n') { | ||
| 650 | if (msg_level < 0) { | ||
| 651 | /* | ||
| 652 | * printk() has already given us loglevel tags in | ||
| 653 | * the buffer. This code is here in case the | ||
| 654 | * log buffer has wrapped right round and scribbled | ||
| 655 | * on those tags | ||
| 656 | */ | ||
| 657 | msg_level = default_message_loglevel; | ||
| 658 | } | ||
| 659 | _call_console_drivers(start_print, cur_index, msg_level); | ||
| 660 | msg_level = -1; | ||
| 661 | start_print = cur_index; | ||
| 662 | break; | ||
| 663 | } | ||
| 664 | } | ||
| 665 | } | ||
| 666 | _call_console_drivers(start_print, end, msg_level); | ||
| 667 | } | ||
| 668 | 1149 | ||
| 669 | static void emit_log_char(char c) | 1150 | for_each_console(con) { |
| 670 | { | 1151 | if (exclusive_console && con != exclusive_console) |
| 671 | LOG_BUF(log_end) = c; | 1152 | continue; |
| 672 | log_end++; | 1153 | if (!(con->flags & CON_ENABLED)) |
| 673 | if (log_end - log_start > log_buf_len) | 1154 | continue; |
| 674 | log_start = log_end - log_buf_len; | 1155 | if (!con->write) |
| 675 | if (log_end - con_start > log_buf_len) | 1156 | continue; |
| 676 | con_start = log_end - log_buf_len; | 1157 | if (!cpu_online(smp_processor_id()) && |
| 677 | if (logged_chars < log_buf_len) | 1158 | !(con->flags & CON_ANYTIME)) |
| 678 | logged_chars++; | 1159 | continue; |
| 1160 | con->write(con, text, len); | ||
| 1161 | } | ||
| 679 | } | 1162 | } |
| 680 | 1163 | ||
| 681 | /* | 1164 | /* |
| @@ -700,16 +1183,6 @@ static void zap_locks(void) | |||
| 700 | sema_init(&console_sem, 1); | 1183 | sema_init(&console_sem, 1); |
| 701 | } | 1184 | } |
| 702 | 1185 | ||
| 703 | #if defined(CONFIG_PRINTK_TIME) | ||
| 704 | static bool printk_time = 1; | ||
| 705 | #else | ||
| 706 | static bool printk_time = 0; | ||
| 707 | #endif | ||
| 708 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | ||
| 709 | |||
| 710 | static bool always_kmsg_dump; | ||
| 711 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); | ||
| 712 | |||
| 713 | /* Check if we have any console registered that can be called early in boot. */ | 1186 | /* Check if we have any console registered that can be called early in boot. */ |
| 714 | static int have_callable_console(void) | 1187 | static int have_callable_console(void) |
| 715 | { | 1188 | { |
| @@ -722,51 +1195,6 @@ static int have_callable_console(void) | |||
| 722 | return 0; | 1195 | return 0; |
| 723 | } | 1196 | } |
| 724 | 1197 | ||
| 725 | /** | ||
| 726 | * printk - print a kernel message | ||
| 727 | * @fmt: format string | ||
| 728 | * | ||
| 729 | * This is printk(). It can be called from any context. We want it to work. | ||
| 730 | * | ||
| 731 | * We try to grab the console_lock. If we succeed, it's easy - we log the output and | ||
| 732 | * call the console drivers. If we fail to get the semaphore we place the output | ||
| 733 | * into the log buffer and return. The current holder of the console_sem will | ||
| 734 | * notice the new output in console_unlock(); and will send it to the | ||
| 735 | * consoles before releasing the lock. | ||
| 736 | * | ||
| 737 | * One effect of this deferred printing is that code which calls printk() and | ||
| 738 | * then changes console_loglevel may break. This is because console_loglevel | ||
| 739 | * is inspected when the actual printing occurs. | ||
| 740 | * | ||
| 741 | * See also: | ||
| 742 | * printf(3) | ||
| 743 | * | ||
| 744 | * See the vsnprintf() documentation for format string extensions over C99. | ||
| 745 | */ | ||
| 746 | |||
| 747 | asmlinkage int printk(const char *fmt, ...) | ||
| 748 | { | ||
| 749 | va_list args; | ||
| 750 | int r; | ||
| 751 | |||
| 752 | #ifdef CONFIG_KGDB_KDB | ||
| 753 | if (unlikely(kdb_trap_printk)) { | ||
| 754 | va_start(args, fmt); | ||
| 755 | r = vkdb_printf(fmt, args); | ||
| 756 | va_end(args); | ||
| 757 | return r; | ||
| 758 | } | ||
| 759 | #endif | ||
| 760 | va_start(args, fmt); | ||
| 761 | r = vprintk(fmt, args); | ||
| 762 | va_end(args); | ||
| 763 | |||
| 764 | return r; | ||
| 765 | } | ||
| 766 | |||
| 767 | /* cpu currently holding logbuf_lock */ | ||
| 768 | static volatile unsigned int printk_cpu = UINT_MAX; | ||
| 769 | |||
| 770 | /* | 1198 | /* |
| 771 | * Can we actually use the console at this time on this cpu? | 1199 | * Can we actually use the console at this time on this cpu? |
| 772 | * | 1200 | * |
| @@ -810,17 +1238,12 @@ static int console_trylock_for_printk(unsigned int cpu) | |||
| 810 | retval = 0; | 1238 | retval = 0; |
| 811 | } | 1239 | } |
| 812 | } | 1240 | } |
| 813 | printk_cpu = UINT_MAX; | 1241 | logbuf_cpu = UINT_MAX; |
| 814 | if (wake) | 1242 | if (wake) |
| 815 | up(&console_sem); | 1243 | up(&console_sem); |
| 816 | raw_spin_unlock(&logbuf_lock); | 1244 | raw_spin_unlock(&logbuf_lock); |
| 817 | return retval; | 1245 | return retval; |
| 818 | } | 1246 | } |
| 819 | static const char recursion_bug_msg [] = | ||
| 820 | KERN_CRIT "BUG: recent printk recursion!\n"; | ||
| 821 | static int recursion_bug; | ||
| 822 | static int new_text_line = 1; | ||
| 823 | static char printk_buf[1024]; | ||
| 824 | 1247 | ||
| 825 | int printk_delay_msec __read_mostly; | 1248 | int printk_delay_msec __read_mostly; |
| 826 | 1249 | ||
| @@ -836,15 +1259,23 @@ static inline void printk_delay(void) | |||
| 836 | } | 1259 | } |
| 837 | } | 1260 | } |
| 838 | 1261 | ||
| 839 | asmlinkage int vprintk(const char *fmt, va_list args) | 1262 | asmlinkage int vprintk_emit(int facility, int level, |
| 1263 | const char *dict, size_t dictlen, | ||
| 1264 | const char *fmt, va_list args) | ||
| 840 | { | 1265 | { |
| 841 | int printed_len = 0; | 1266 | static int recursion_bug; |
| 842 | int current_log_level = default_message_loglevel; | 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]; | ||
| 1272 | char *text = textbuf; | ||
| 1273 | size_t text_len; | ||
| 843 | unsigned long flags; | 1274 | unsigned long flags; |
| 844 | int this_cpu; | 1275 | int this_cpu; |
| 845 | char *p; | 1276 | bool newline = false; |
| 846 | size_t plen; | 1277 | bool prefix = false; |
| 847 | char special; | 1278 | int printed_len = 0; |
| 848 | 1279 | ||
| 849 | boot_delay_msec(); | 1280 | boot_delay_msec(); |
| 850 | printk_delay(); | 1281 | printk_delay(); |
| @@ -856,7 +1287,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
| 856 | /* | 1287 | /* |
| 857 | * Ouch, printk recursed into itself! | 1288 | * Ouch, printk recursed into itself! |
| 858 | */ | 1289 | */ |
| 859 | if (unlikely(printk_cpu == this_cpu)) { | 1290 | if (unlikely(logbuf_cpu == this_cpu)) { |
| 860 | /* | 1291 | /* |
| 861 | * If a crash is occurring during printk() on this CPU, | 1292 | * If a crash is occurring during printk() on this CPU, |
| 862 | * then try to get the crash message out but make sure | 1293 | * then try to get the crash message out but make sure |
| @@ -873,97 +1304,110 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
| 873 | 1304 | ||
| 874 | lockdep_off(); | 1305 | lockdep_off(); |
| 875 | raw_spin_lock(&logbuf_lock); | 1306 | raw_spin_lock(&logbuf_lock); |
| 876 | printk_cpu = this_cpu; | 1307 | logbuf_cpu = this_cpu; |
| 877 | 1308 | ||
| 878 | if (recursion_bug) { | 1309 | if (recursion_bug) { |
| 1310 | static const char recursion_msg[] = | ||
| 1311 | "BUG: recent printk recursion!"; | ||
| 1312 | |||
| 879 | recursion_bug = 0; | 1313 | recursion_bug = 0; |
| 880 | strcpy(printk_buf, recursion_bug_msg); | 1314 | printed_len += strlen(recursion_msg); |
| 881 | printed_len = strlen(recursion_bug_msg); | 1315 | /* emit KERN_CRIT message */ |
| 1316 | log_store(0, 2, NULL, 0, recursion_msg, printed_len); | ||
| 882 | } | 1317 | } |
| 883 | /* Emit the output into the temporary buffer */ | ||
| 884 | printed_len += vscnprintf(printk_buf + printed_len, | ||
| 885 | sizeof(printk_buf) - printed_len, fmt, args); | ||
| 886 | 1318 | ||
| 887 | p = printk_buf; | 1319 | /* |
| 1320 | * The printf needs to come first; we need the syslog | ||
| 1321 | * prefix which might be passed-in as a parameter. | ||
| 1322 | */ | ||
| 1323 | text_len = vscnprintf(text, sizeof(textbuf), fmt, args); | ||
| 888 | 1324 | ||
| 889 | /* Read log level and handle special printk prefix */ | 1325 | /* mark and strip a trailing newline */ |
| 890 | plen = log_prefix(p, ¤t_log_level, &special); | 1326 | if (text_len && text[text_len-1] == '\n') { |
| 891 | if (plen) { | 1327 | text_len--; |
| 892 | p += plen; | 1328 | newline = true; |
| 1329 | } | ||
| 893 | 1330 | ||
| 894 | switch (special) { | 1331 | /* strip syslog prefix and extract log level or control flags */ |
| 895 | case 'c': /* Strip <c> KERN_CONT, continue line */ | 1332 | if (text[0] == '<' && text[1] && text[2] == '>') { |
| 896 | plen = 0; | 1333 | switch (text[1]) { |
| 897 | break; | 1334 | case '0' ... '7': |
| 898 | case 'd': /* Strip <d> KERN_DEFAULT, start new line */ | 1335 | if (level == -1) |
| 899 | plen = 0; | 1336 | level = text[1] - '0'; |
| 900 | default: | 1337 | case 'd': /* KERN_DEFAULT */ |
| 901 | if (!new_text_line) { | 1338 | prefix = true; |
| 902 | emit_log_char('\n'); | 1339 | case 'c': /* KERN_CONT */ |
| 903 | new_text_line = 1; | 1340 | text += 3; |
| 904 | } | 1341 | text_len -= 3; |
| 905 | } | 1342 | } |
| 906 | } | 1343 | } |
| 907 | 1344 | ||
| 908 | /* | 1345 | if (level == -1) |
| 909 | * Copy the output into log_buf. If the caller didn't provide | 1346 | level = default_message_loglevel; |
| 910 | * the appropriate log prefix, we insert them here | ||
| 911 | */ | ||
| 912 | for (; *p; p++) { | ||
| 913 | if (new_text_line) { | ||
| 914 | new_text_line = 0; | ||
| 915 | |||
| 916 | if (plen) { | ||
| 917 | /* Copy original log prefix */ | ||
| 918 | int i; | ||
| 919 | |||
| 920 | for (i = 0; i < plen; i++) | ||
| 921 | emit_log_char(printk_buf[i]); | ||
| 922 | printed_len += plen; | ||
| 923 | } else { | ||
| 924 | /* Add log prefix */ | ||
| 925 | emit_log_char('<'); | ||
| 926 | emit_log_char(current_log_level + '0'); | ||
| 927 | emit_log_char('>'); | ||
| 928 | printed_len += 3; | ||
| 929 | } | ||
| 930 | 1347 | ||
| 931 | if (printk_time) { | 1348 | if (dict) { |
| 932 | /* Add the current time stamp */ | 1349 | prefix = true; |
| 933 | char tbuf[50], *tp; | 1350 | newline = true; |
| 934 | unsigned tlen; | 1351 | } |
| 935 | unsigned long long t; | ||
| 936 | unsigned long nanosec_rem; | ||
| 937 | |||
| 938 | t = cpu_clock(printk_cpu); | ||
| 939 | nanosec_rem = do_div(t, 1000000000); | ||
| 940 | tlen = sprintf(tbuf, "[%5lu.%06lu] ", | ||
| 941 | (unsigned long) t, | ||
| 942 | nanosec_rem / 1000); | ||
| 943 | |||
| 944 | for (tp = tbuf; tp < tbuf + tlen; tp++) | ||
| 945 | emit_log_char(*tp); | ||
| 946 | printed_len += tlen; | ||
| 947 | } | ||
| 948 | 1352 | ||
| 949 | if (!*p) | 1353 | if (!newline) { |
| 950 | break; | 1354 | if (cont_len && (prefix || cont_task != current)) { |
| 1355 | /* | ||
| 1356 | * Flush earlier buffer, which is either from a | ||
| 1357 | * different thread, or when we got a new prefix. | ||
| 1358 | */ | ||
| 1359 | log_store(facility, cont_level, NULL, 0, cont_buf, cont_len); | ||
| 1360 | cont_len = 0; | ||
| 951 | } | 1361 | } |
| 952 | 1362 | ||
| 953 | emit_log_char(*p); | 1363 | if (!cont_len) { |
| 954 | if (*p == '\n') | 1364 | cont_level = level; |
| 955 | new_text_line = 1; | 1365 | cont_task = current; |
| 1366 | } | ||
| 1367 | |||
| 1368 | /* buffer or append to earlier buffer from the same thread */ | ||
| 1369 | if (cont_len + text_len > sizeof(cont_buf)) | ||
| 1370 | text_len = sizeof(cont_buf) - cont_len; | ||
| 1371 | memcpy(cont_buf + cont_len, text, text_len); | ||
| 1372 | cont_len += text_len; | ||
| 1373 | } else { | ||
| 1374 | if (cont_len && cont_task == current) { | ||
| 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 | |||
| 1386 | /* append to the earlier buffer and flush */ | ||
| 1387 | if (cont_len + text_len > sizeof(cont_buf)) | ||
| 1388 | text_len = sizeof(cont_buf) - cont_len; | ||
| 1389 | memcpy(cont_buf + cont_len, text, text_len); | ||
| 1390 | cont_len += text_len; | ||
| 1391 | log_store(facility, cont_level, | ||
| 1392 | NULL, 0, cont_buf, cont_len); | ||
| 1393 | cont_len = 0; | ||
| 1394 | cont_task = NULL; | ||
| 1395 | printed_len = cont_len; | ||
| 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 | } | ||
| 956 | } | 1402 | } |
| 957 | 1403 | ||
| 958 | /* | 1404 | /* |
| 959 | * Try to acquire and then immediately release the | 1405 | * Try to acquire and then immediately release the console semaphore. |
| 960 | * console semaphore. The release will do all the | 1406 | * The release will print out buffers and wake up /dev/kmsg and syslog() |
| 961 | * actual magic (print out buffers, wake up klogd, | 1407 | * users. |
| 962 | * etc). | ||
| 963 | * | 1408 | * |
| 964 | * The console_trylock_for_printk() function | 1409 | * The console_trylock_for_printk() function will release 'logbuf_lock' |
| 965 | * will release 'logbuf_lock' regardless of whether it | 1410 | * regardless of whether it actually gets the console semaphore or not. |
| 966 | * actually gets the semaphore or not. | ||
| 967 | */ | 1411 | */ |
| 968 | if (console_trylock_for_printk(this_cpu)) | 1412 | if (console_trylock_for_printk(this_cpu)) |
| 969 | console_unlock(); | 1413 | console_unlock(); |
| @@ -974,16 +1418,81 @@ out_restore_irqs: | |||
| 974 | 1418 | ||
| 975 | return printed_len; | 1419 | return printed_len; |
| 976 | } | 1420 | } |
| 977 | EXPORT_SYMBOL(printk); | 1421 | EXPORT_SYMBOL(vprintk_emit); |
| 978 | EXPORT_SYMBOL(vprintk); | ||
| 979 | 1422 | ||
| 980 | #else | 1423 | asmlinkage int vprintk(const char *fmt, va_list args) |
| 1424 | { | ||
| 1425 | return vprintk_emit(0, -1, NULL, 0, fmt, args); | ||
| 1426 | } | ||
| 1427 | EXPORT_SYMBOL(vprintk); | ||
| 981 | 1428 | ||
| 982 | static void call_console_drivers(unsigned start, unsigned end) | 1429 | asmlinkage int printk_emit(int facility, int level, |
| 1430 | const char *dict, size_t dictlen, | ||
| 1431 | const char *fmt, ...) | ||
| 983 | { | 1432 | { |
| 1433 | va_list args; | ||
| 1434 | int r; | ||
| 1435 | |||
| 1436 | va_start(args, fmt); | ||
| 1437 | r = vprintk_emit(facility, level, dict, dictlen, fmt, args); | ||
| 1438 | va_end(args); | ||
| 1439 | |||
| 1440 | return r; | ||
| 984 | } | 1441 | } |
| 1442 | EXPORT_SYMBOL(printk_emit); | ||
| 985 | 1443 | ||
| 1444 | /** | ||
| 1445 | * printk - print a kernel message | ||
| 1446 | * @fmt: format string | ||
| 1447 | * | ||
| 1448 | * This is printk(). It can be called from any context. We want it to work. | ||
| 1449 | * | ||
| 1450 | * We try to grab the console_lock. If we succeed, it's easy - we log the | ||
| 1451 | * output and call the console drivers. If we fail to get the semaphore, we | ||
| 1452 | * place the output into the log buffer and return. The current holder of | ||
| 1453 | * the console_sem will notice the new output in console_unlock(); and will | ||
| 1454 | * send it to the consoles before releasing the lock. | ||
| 1455 | * | ||
| 1456 | * One effect of this deferred printing is that code which calls printk() and | ||
| 1457 | * then changes console_loglevel may break. This is because console_loglevel | ||
| 1458 | * is inspected when the actual printing occurs. | ||
| 1459 | * | ||
| 1460 | * See also: | ||
| 1461 | * printf(3) | ||
| 1462 | * | ||
| 1463 | * See the vsnprintf() documentation for format string extensions over C99. | ||
| 1464 | */ | ||
| 1465 | asmlinkage int printk(const char *fmt, ...) | ||
| 1466 | { | ||
| 1467 | va_list args; | ||
| 1468 | int r; | ||
| 1469 | |||
| 1470 | #ifdef CONFIG_KGDB_KDB | ||
| 1471 | if (unlikely(kdb_trap_printk)) { | ||
| 1472 | va_start(args, fmt); | ||
| 1473 | r = vkdb_printf(fmt, args); | ||
| 1474 | va_end(args); | ||
| 1475 | return r; | ||
| 1476 | } | ||
| 986 | #endif | 1477 | #endif |
| 1478 | va_start(args, fmt); | ||
| 1479 | r = vprintk_emit(0, -1, NULL, 0, fmt, args); | ||
| 1480 | va_end(args); | ||
| 1481 | |||
| 1482 | return r; | ||
| 1483 | } | ||
| 1484 | EXPORT_SYMBOL(printk); | ||
| 1485 | |||
| 1486 | #else | ||
| 1487 | |||
| 1488 | #define LOG_LINE_MAX 0 | ||
| 1489 | static struct log *log_from_idx(u32 idx) { return NULL; } | ||
| 1490 | static u32 log_next(u32 idx) { return 0; } | ||
| 1491 | static void call_console_drivers(int level, const char *text, size_t len) {} | ||
| 1492 | static size_t msg_print_text(const struct log *msg, bool syslog, | ||
| 1493 | char *buf, size_t size) { return 0; } | ||
| 1494 | |||
| 1495 | #endif /* CONFIG_PRINTK */ | ||
| 987 | 1496 | ||
| 988 | static int __add_preferred_console(char *name, int idx, char *options, | 1497 | static int __add_preferred_console(char *name, int idx, char *options, |
| 989 | char *brl_options) | 1498 | char *brl_options) |
| @@ -1217,7 +1726,7 @@ int is_console_locked(void) | |||
| 1217 | } | 1726 | } |
| 1218 | 1727 | ||
| 1219 | /* | 1728 | /* |
| 1220 | * Delayed printk facility, for scheduler-internal messages: | 1729 | * Delayed printk version, for scheduler-internal messages: |
| 1221 | */ | 1730 | */ |
| 1222 | #define PRINTK_BUF_SIZE 512 | 1731 | #define PRINTK_BUF_SIZE 512 |
| 1223 | 1732 | ||
| @@ -1253,6 +1762,10 @@ void wake_up_klogd(void) | |||
| 1253 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); | 1762 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); |
| 1254 | } | 1763 | } |
| 1255 | 1764 | ||
| 1765 | /* the next printk record to write to the console */ | ||
| 1766 | static u64 console_seq; | ||
| 1767 | static u32 console_idx; | ||
| 1768 | |||
| 1256 | /** | 1769 | /** |
| 1257 | * console_unlock - unlock the console system | 1770 | * console_unlock - unlock the console system |
| 1258 | * | 1771 | * |
| @@ -1263,15 +1776,16 @@ void wake_up_klogd(void) | |||
| 1263 | * by printk(). If this is the case, console_unlock(); emits | 1776 | * by printk(). If this is the case, console_unlock(); emits |
| 1264 | * the output prior to releasing the lock. | 1777 | * the output prior to releasing the lock. |
| 1265 | * | 1778 | * |
| 1266 | * If there is output waiting for klogd, we wake it up. | 1779 | * If there is output waiting, we wake /dev/kmsg and syslog() users. |
| 1267 | * | 1780 | * |
| 1268 | * console_unlock(); may be called from any context. | 1781 | * console_unlock(); may be called from any context. |
| 1269 | */ | 1782 | */ |
| 1270 | void console_unlock(void) | 1783 | void console_unlock(void) |
| 1271 | { | 1784 | { |
| 1785 | static u64 seen_seq; | ||
| 1272 | unsigned long flags; | 1786 | unsigned long flags; |
| 1273 | unsigned _con_start, _log_end; | 1787 | bool wake_klogd = false; |
| 1274 | unsigned wake_klogd = 0, retry = 0; | 1788 | bool retry; |
| 1275 | 1789 | ||
| 1276 | if (console_suspended) { | 1790 | if (console_suspended) { |
| 1277 | up(&console_sem); | 1791 | up(&console_sem); |
| @@ -1281,17 +1795,38 @@ void console_unlock(void) | |||
| 1281 | console_may_schedule = 0; | 1795 | console_may_schedule = 0; |
| 1282 | 1796 | ||
| 1283 | again: | 1797 | again: |
| 1284 | for ( ; ; ) { | 1798 | for (;;) { |
| 1799 | struct log *msg; | ||
| 1800 | static char text[LOG_LINE_MAX]; | ||
| 1801 | size_t len; | ||
| 1802 | int level; | ||
| 1803 | |||
| 1285 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 1804 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 1286 | wake_klogd |= log_start - log_end; | 1805 | if (seen_seq != log_next_seq) { |
| 1287 | if (con_start == log_end) | 1806 | wake_klogd = true; |
| 1288 | break; /* Nothing to print */ | 1807 | seen_seq = log_next_seq; |
| 1289 | _con_start = con_start; | 1808 | } |
| 1290 | _log_end = log_end; | 1809 | |
| 1291 | con_start = log_end; /* Flush */ | 1810 | if (console_seq < log_first_seq) { |
| 1811 | /* messages are gone, move to first one */ | ||
| 1812 | console_seq = log_first_seq; | ||
| 1813 | console_idx = log_first_idx; | ||
| 1814 | } | ||
| 1815 | |||
| 1816 | if (console_seq == log_next_seq) | ||
| 1817 | break; | ||
| 1818 | |||
| 1819 | msg = log_from_idx(console_idx); | ||
| 1820 | level = msg->level & 7; | ||
| 1821 | |||
| 1822 | len = msg_print_text(msg, false, text, sizeof(text)); | ||
| 1823 | |||
| 1824 | console_idx = log_next(console_idx); | ||
| 1825 | console_seq++; | ||
| 1292 | raw_spin_unlock(&logbuf_lock); | 1826 | raw_spin_unlock(&logbuf_lock); |
| 1827 | |||
| 1293 | stop_critical_timings(); /* don't trace print latency */ | 1828 | stop_critical_timings(); /* don't trace print latency */ |
| 1294 | call_console_drivers(_con_start, _log_end); | 1829 | call_console_drivers(level, text, len); |
| 1295 | start_critical_timings(); | 1830 | start_critical_timings(); |
| 1296 | local_irq_restore(flags); | 1831 | local_irq_restore(flags); |
| 1297 | } | 1832 | } |
| @@ -1312,8 +1847,7 @@ again: | |||
| 1312 | * flush, no worries. | 1847 | * flush, no worries. |
| 1313 | */ | 1848 | */ |
| 1314 | raw_spin_lock(&logbuf_lock); | 1849 | raw_spin_lock(&logbuf_lock); |
| 1315 | if (con_start != log_end) | 1850 | retry = console_seq != log_next_seq; |
| 1316 | retry = 1; | ||
| 1317 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 1851 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| 1318 | 1852 | ||
| 1319 | if (retry && console_trylock()) | 1853 | if (retry && console_trylock()) |
| @@ -1549,7 +2083,8 @@ void register_console(struct console *newcon) | |||
| 1549 | * for us. | 2083 | * for us. |
| 1550 | */ | 2084 | */ |
| 1551 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2085 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 1552 | con_start = log_start; | 2086 | console_seq = syslog_seq; |
| 2087 | console_idx = syslog_idx; | ||
| 1553 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2088 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
| 1554 | /* | 2089 | /* |
| 1555 | * We're about to replay the log buffer. Only do this to the | 2090 | * We're about to replay the log buffer. Only do this to the |
| @@ -1758,6 +2293,9 @@ int kmsg_dump_unregister(struct kmsg_dumper *dumper) | |||
| 1758 | } | 2293 | } |
| 1759 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | 2294 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); |
| 1760 | 2295 | ||
| 2296 | static bool always_kmsg_dump; | ||
| 2297 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); | ||
| 2298 | |||
| 1761 | /** | 2299 | /** |
| 1762 | * kmsg_dump - dump kernel log to kernel message dumpers. | 2300 | * kmsg_dump - dump kernel log to kernel message dumpers. |
| 1763 | * @reason: the reason (oops, panic etc) for dumping | 2301 | * @reason: the reason (oops, panic etc) for dumping |
| @@ -1767,8 +2305,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | |||
| 1767 | */ | 2305 | */ |
| 1768 | void kmsg_dump(enum kmsg_dump_reason reason) | 2306 | void kmsg_dump(enum kmsg_dump_reason reason) |
| 1769 | { | 2307 | { |
| 1770 | unsigned long end; | 2308 | u64 idx; |
| 1771 | unsigned chars; | ||
| 1772 | struct kmsg_dumper *dumper; | 2309 | struct kmsg_dumper *dumper; |
| 1773 | const char *s1, *s2; | 2310 | const char *s1, *s2; |
| 1774 | unsigned long l1, l2; | 2311 | unsigned long l1, l2; |
| @@ -1780,24 +2317,27 @@ void kmsg_dump(enum kmsg_dump_reason reason) | |||
| 1780 | /* Theoretically, the log could move on after we do this, but | 2317 | /* Theoretically, the log could move on after we do this, but |
| 1781 | there's not a lot we can do about that. The new messages | 2318 | there's not a lot we can do about that. The new messages |
| 1782 | will overwrite the start of what we dump. */ | 2319 | will overwrite the start of what we dump. */ |
| 2320 | |||
| 1783 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2321 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
| 1784 | end = log_end & LOG_BUF_MASK; | 2322 | if (syslog_seq < log_first_seq) |
| 1785 | chars = logged_chars; | 2323 | idx = syslog_idx; |
| 1786 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2324 | else |
| 2325 | idx = log_first_idx; | ||
| 1787 | 2326 | ||
| 1788 | if (chars > end) { | 2327 | if (idx > log_next_idx) { |
| 1789 | s1 = log_buf + log_buf_len - chars + end; | 2328 | s1 = log_buf; |
| 1790 | l1 = chars - end; | 2329 | l1 = log_next_idx; |
| 1791 | 2330 | ||
| 1792 | s2 = log_buf; | 2331 | s2 = log_buf + idx; |
| 1793 | l2 = end; | 2332 | l2 = log_buf_len - idx; |
| 1794 | } else { | 2333 | } else { |
| 1795 | s1 = ""; | 2334 | s1 = ""; |
| 1796 | l1 = 0; | 2335 | l1 = 0; |
| 1797 | 2336 | ||
| 1798 | s2 = log_buf + end - chars; | 2337 | s2 = log_buf + idx; |
| 1799 | l2 = chars; | 2338 | l2 = log_next_idx - idx; |
| 1800 | } | 2339 | } |
| 2340 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
| 1801 | 2341 | ||
| 1802 | rcu_read_lock(); | 2342 | rcu_read_lock(); |
| 1803 | list_for_each_entry_rcu(dumper, &dump_list, list) | 2343 | list_for_each_entry_rcu(dumper, &dump_list, list) |
