linux/kernel/printk.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/printk.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 * Modified to make sys_syslog() more flexible: added commands to
   7 * return the last 4k of kernel messages, regardless of whether
   8 * they've been read or not.  Added option to suppress kernel printk's
   9 * to the console.  Added hook for sending the console messages
  10 * elsewhere, in preparation for a serial line console (someday).
  11 * Ted Ts'o, 2/11/93.
  12 * Modified for sysctl support, 1/8/97, Chris Horn.
  13 * Fixed SMP synchronization, 08/08/99, Manfred Spraul 
  14 *     manfreds@colorfullife.com
  15 * Rewrote bits to get rid of console_lock
  16 *      01Mar01 Andrew Morton <andrewm@uow.edu.au>
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/mm.h>
  21#include <linux/tty.h>
  22#include <linux/tty_driver.h>
  23#include <linux/smp_lock.h>
  24#include <linux/console.h>
  25#include <linux/init.h>
  26#include <linux/module.h>
  27#include <linux/interrupt.h>                    /* For in_interrupt() */
  28#include <linux/config.h>
  29#include <linux/delay.h>
  30#include <linux/smp.h>
  31#include <linux/security.h>
  32#include <linux/bootmem.h>
  33#include <linux/syscalls.h>
  34
  35#include <asm/uaccess.h>
  36
  37#define __LOG_BUF_LEN   (1 << CONFIG_LOG_BUF_SHIFT)
  38
  39/* printk's without a loglevel use this.. */
  40#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
  41
  42/* We show everything that is MORE important than this.. */
  43#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
  44#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
  45
  46DECLARE_WAIT_QUEUE_HEAD(log_wait);
  47
  48int console_printk[4] = {
  49        DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */
  50        DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */
  51        MINIMUM_CONSOLE_LOGLEVEL,       /* minimum_console_loglevel */
  52        DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */
  53};
  54
  55EXPORT_SYMBOL(console_printk);
  56
  57int oops_in_progress;
  58
  59/*
  60 * console_sem protects the console_drivers list, and also
  61 * provides serialisation for access to the entire console
  62 * driver system.
  63 */
  64static DECLARE_MUTEX(console_sem);
  65struct console *console_drivers;
  66/*
  67 * This is used for debugging the mess that is the VT code by
  68 * keeping track if we have the console semaphore held. It's
  69 * definitely not the perfect debug tool (we don't know if _WE_
  70 * hold it are racing, but it helps tracking those weird code
  71 * path in the console code where we end up in places I want
  72 * locked without the console sempahore held
  73 */
  74static int console_locked;
  75
  76/*
  77 * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
  78 * It is also used in interesting ways to provide interlocking in
  79 * release_console_sem().
  80 */
  81static DEFINE_SPINLOCK(logbuf_lock);
  82
  83static char __log_buf[__LOG_BUF_LEN];
  84static char *log_buf = __log_buf;
  85static int log_buf_len = __LOG_BUF_LEN;
  86
  87#define LOG_BUF_MASK    (log_buf_len-1)
  88#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK])
  89
  90/*
  91 * The indices into log_buf are not constrained to log_buf_len - they
  92 * must be masked before subscripting
  93 */
  94static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */
  95static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */
  96static unsigned long log_end;   /* Index into log_buf: most-recently-written-char + 1 */
  97static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */
  98
  99/*
 100 *      Array of consoles built from command line options (console=)
 101 */
 102struct console_cmdline
 103{
 104        char    name[8];                        /* Name of the driver       */
 105        int     index;                          /* Minor dev. to use        */
 106        char    *options;                       /* Options for the driver   */
 107};
 108
 109#define MAX_CMDLINECONSOLES 8
 110
 111static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 112static int selected_console = -1;
 113static int preferred_console = -1;
 114
 115/* Flag: console code may call schedule() */
 116static int console_may_schedule;
 117
 118/*
 119 *      Setup a list of consoles. Called from init/main.c
 120 */
 121static int __init console_setup(char *str)
 122{
 123        char name[sizeof(console_cmdline[0].name)];
 124        char *s, *options;
 125        int idx;
 126
 127        /*
 128         *      Decode str into name, index, options.
 129         */
 130        if (str[0] >= '0' && str[0] <= '9') {
 131                strcpy(name, "ttyS");
 132                strncpy(name + 4, str, sizeof(name) - 5);
 133        } else
 134                strncpy(name, str, sizeof(name) - 1);
 135        name[sizeof(name) - 1] = 0;
 136        if ((options = strchr(str, ',')) != NULL)
 137                *(options++) = 0;
 138#ifdef __sparc__
 139        if (!strcmp(str, "ttya"))
 140                strcpy(name, "ttyS0");
 141        if (!strcmp(str, "ttyb"))
 142                strcpy(name, "ttyS1");
 143#endif
 144        for(s = name; *s; s++)
 145                if ((*s >= '0' && *s <= '9') || *s == ',')
 146                        break;
 147        idx = simple_strtoul(s, NULL, 10);
 148        *s = 0;
 149
 150        add_preferred_console(name, idx, options);
 151        return 1;
 152}
 153
 154__setup("console=", console_setup);
 155
 156/**
 157 * add_preferred_console - add a device to the list of preferred consoles.
 158 *
 159 * The last preferred console added will be used for kernel messages
 160 * and stdin/out/err for init.  Normally this is used by console_setup
 161 * above to handle user-supplied console arguments; however it can also
 162 * be used by arch-specific code either to override the user or more
 163 * commonly to provide a default console (ie from PROM variables) when
 164 * the user has not supplied one.
 165 */
 166int __init add_preferred_console(char *name, int idx, char *options)
 167{
 168        struct console_cmdline *c;
 169        int i;
 170
 171        /*
 172         *      See if this tty is not yet registered, and
 173         *      if we have a slot free.
 174         */
 175        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
 176                if (strcmp(console_cmdline[i].name, name) == 0 &&
 177                          console_cmdline[i].index == idx) {
 178                                selected_console = i;
 179                                return 0;
 180                }
 181        if (i == MAX_CMDLINECONSOLES)
 182                return -E2BIG;
 183        selected_console = i;
 184        c = &console_cmdline[i];
 185        memcpy(c->name, name, sizeof(c->name));
 186        c->name[sizeof(c->name) - 1] = 0;
 187        c->options = options;
 188        c->index = idx;
 189        return 0;
 190}
 191
 192static int __init log_buf_len_setup(char *str)
 193{
 194        unsigned long size = memparse(str, &str);
 195        unsigned long flags;
 196
 197        if (size)
 198                size = roundup_pow_of_two(size);
 199        if (size > log_buf_len) {
 200                unsigned long start, dest_idx, offset;
 201                char * new_log_buf;
 202
 203                new_log_buf = alloc_bootmem(size);
 204                if (!new_log_buf) {
 205                        printk("log_buf_len: allocation failed\n");
 206                        goto out;
 207                }
 208
 209                spin_lock_irqsave(&logbuf_lock, flags);
 210                log_buf_len = size;
 211                log_buf = new_log_buf;
 212
 213                offset = start = min(con_start, log_start);
 214                dest_idx = 0;
 215                while (start != log_end) {
 216                        log_buf[dest_idx] = __log_buf[start & (__LOG_BUF_LEN - 1)];
 217                        start++;
 218                        dest_idx++;
 219                }
 220                log_start -= offset;
 221                con_start -= offset;
 222                log_end -= offset;
 223                spin_unlock_irqrestore(&logbuf_lock, flags);
 224
 225                printk("log_buf_len: %d\n", log_buf_len);
 226        }
 227out:
 228
 229        return 1;
 230}
 231
 232__setup("log_buf_len=", log_buf_len_setup);
 233
 234/*
 235 * Commands to do_syslog:
 236 *
 237 *      0 -- Close the log.  Currently a NOP.
 238 *      1 -- Open the log. Currently a NOP.
 239 *      2 -- Read from the log.
 240 *      3 -- Read all messages remaining in the ring buffer.
 241 *      4 -- Read and clear all messages remaining in the ring buffer
 242 *      5 -- Clear ring buffer.
 243 *      6 -- Disable printk's to console
 244 *      7 -- Enable printk's to console
 245 *      8 -- Set level of messages printed to console
 246 *      9 -- Return number of unread characters in the log buffer
 247 *     10 -- Return size of the log buffer
 248 */
 249int do_syslog(int type, char __user * buf, int len)
 250{
 251        unsigned long i, j, limit, count;
 252        int do_clear = 0;
 253        char c;
 254        int error = 0;
 255
 256        error = security_syslog(type);
 257        if (error)
 258                return error;
 259
 260        switch (type) {
 261        case 0:         /* Close log */
 262                break;
 263        case 1:         /* Open log */
 264                break;
 265        case 2:         /* Read from log */
 266                error = -EINVAL;
 267                if (!buf || len < 0)
 268                        goto out;
 269                error = 0;
 270                if (!len)
 271                        goto out;
 272                error = verify_area(VERIFY_WRITE,buf,len);
 273                if (error)
 274                        goto out;
 275                error = wait_event_interruptible(log_wait, (log_start - log_end));
 276                if (error)
 277                        goto out;
 278                i = 0;
 279                spin_lock_irq(&logbuf_lock);
 280                while (!error && (log_start != log_end) && i < len) {
 281                        c = LOG_BUF(log_start);
 282                        log_start++;
 283                        spin_unlock_irq(&logbuf_lock);
 284                        error = __put_user(c,buf);
 285                        buf++;
 286                        i++;
 287                        cond_resched();
 288                        spin_lock_irq(&logbuf_lock);
 289                }
 290                spin_unlock_irq(&logbuf_lock);
 291                if (!error)
 292                        error = i;
 293                break;
 294        case 4:         /* Read/clear last kernel messages */
 295                do_clear = 1; 
 296                /* FALL THRU */
 297        case 3:         /* Read last kernel messages */
 298                error = -EINVAL;
 299                if (!buf || len < 0)
 300                        goto out;
 301                error = 0;
 302                if (!len)
 303                        goto out;
 304                error = verify_area(VERIFY_WRITE,buf,len);
 305                if (error)
 306                        goto out;
 307                count = len;
 308                if (count > log_buf_len)
 309                        count = log_buf_len;
 310                spin_lock_irq(&logbuf_lock);
 311                if (count > logged_chars)
 312                        count = logged_chars;
 313                if (do_clear)
 314                        logged_chars = 0;
 315                limit = log_end;
 316                /*
 317                 * __put_user() could sleep, and while we sleep
 318                 * printk() could overwrite the messages 
 319                 * we try to copy to user space. Therefore
 320                 * the messages are copied in reverse. <manfreds>
 321                 */
 322                for(i = 0; i < count && !error; i++) {
 323                        j = limit-1-i;
 324                        if (j + log_buf_len < log_end)
 325                                break;
 326                        c = LOG_BUF(j);
 327                        spin_unlock_irq(&logbuf_lock);
 328                        error = __put_user(c,&buf[count-1-i]);
 329                        cond_resched();
 330                        spin_lock_irq(&logbuf_lock);
 331                }
 332                spin_unlock_irq(&logbuf_lock);
 333                if (error)
 334                        break;
 335                error = i;
 336                if(i != count) {
 337                        int offset = count-error;
 338                        /* buffer overflow during copy, correct user buffer. */
 339                        for(i=0;i<error;i++) {
 340                                if (__get_user(c,&buf[i+offset]) ||
 341                                    __put_user(c,&buf[i])) {
 342                                        error = -EFAULT;
 343                                        break;
 344                                }
 345                                cond_resched();
 346                        }
 347                }
 348                break;
 349        case 5:         /* Clear ring buffer */
 350                logged_chars = 0;
 351                break;
 352        case 6:         /* Disable logging to console */
 353                console_loglevel = minimum_console_loglevel;
 354                break;
 355        case 7:         /* Enable logging to console */
 356                console_loglevel = default_console_loglevel;
 357                break;
 358        case 8:         /* Set level of messages printed to console */
 359                error = -EINVAL;
 360                if (len < 1 || len > 8)
 361                        goto out;
 362                if (len < minimum_console_loglevel)
 363                        len = minimum_console_loglevel;
 364                console_loglevel = len;
 365                error = 0;
 366                break;
 367        case 9:         /* Number of chars in the log buffer */
 368                error = log_end - log_start;
 369                break;
 370        case 10:        /* Size of the log buffer */
 371                error = log_buf_len;
 372                break;
 373        default:
 374                error = -EINVAL;
 375                break;
 376        }
 377out:
 378        return error;
 379}
 380
 381asmlinkage long sys_syslog(int type, char __user * buf, int len)
 382{
 383        return do_syslog(type, buf, len);
 384}
 385
 386/*
 387 * Call the console drivers on a range of log_buf
 388 */
 389static void __call_console_drivers(unsigned long start, unsigned long end)
 390{
 391        struct console *con;
 392
 393        for (con = console_drivers; con; con = con->next) {
 394                if ((con->flags & CON_ENABLED) && con->write)
 395                        con->write(con, &LOG_BUF(start), end - start);
 396        }
 397}
 398
 399/*
 400 * Write out chars from start to end - 1 inclusive
 401 */
 402static void _call_console_drivers(unsigned long start,
 403                                unsigned long end, int msg_log_level)
 404{
 405        if (msg_log_level < console_loglevel &&
 406                        console_drivers && start != end) {
 407                if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) {
 408                        /* wrapped write */
 409                        __call_console_drivers(start & LOG_BUF_MASK,
 410                                                log_buf_len);
 411                        __call_console_drivers(0, end & LOG_BUF_MASK);
 412                } else {
 413                        __call_console_drivers(start, end);
 414                }
 415        }
 416}
 417
 418/*
 419 * Call the console drivers, asking them to write out
 420 * log_buf[start] to log_buf[end - 1].
 421 * The console_sem must be held.
 422 */
 423static void call_console_drivers(unsigned long start, unsigned long end)
 424{
 425        unsigned long cur_index, start_print;
 426        static int msg_level = -1;
 427
 428        if (((long)(start - end)) > 0)
 429                BUG();
 430
 431        cur_index = start;
 432        start_print = start;
 433        while (cur_index != end) {
 434                if (    msg_level < 0 &&
 435                        ((end - cur_index) > 2) &&
 436                        LOG_BUF(cur_index + 0) == '<' &&
 437                        LOG_BUF(cur_index + 1) >= '0' &&
 438                        LOG_BUF(cur_index + 1) <= '7' &&
 439                        LOG_BUF(cur_index + 2) == '>')
 440                {
 441                        msg_level = LOG_BUF(cur_index + 1) - '0';
 442                        cur_index += 3;
 443                        start_print = cur_index;
 444                }
 445                while (cur_index != end) {
 446                        char c = LOG_BUF(cur_index);
 447                        cur_index++;
 448
 449                        if (c == '\n') {
 450                                if (msg_level < 0) {
 451                                        /*
 452                                         * printk() has already given us loglevel tags in
 453                                         * the buffer.  This code is here in case the
 454                                         * log buffer has wrapped right round and scribbled
 455                                         * on those tags
 456                                         */
 457                                        msg_level = default_message_loglevel;
 458                                }
 459                                _call_console_drivers(start_print, cur_index, msg_level);
 460                                msg_level = -1;
 461                                start_print = cur_index;
 462                                break;
 463                        }
 464                }
 465        }
 466        _call_console_drivers(start_print, end, msg_level);
 467}
 468
 469static void emit_log_char(char c)
 470{
 471        LOG_BUF(log_end) = c;
 472        log_end++;
 473        if (log_end - log_start > log_buf_len)
 474                log_start = log_end - log_buf_len;
 475        if (log_end - con_start > log_buf_len)
 476                con_start = log_end - log_buf_len;
 477        if (logged_chars < log_buf_len)
 478                logged_chars++;
 479}
 480
 481/*
 482 * Zap console related locks when oopsing. Only zap at most once
 483 * every 10 seconds, to leave time for slow consoles to print a
 484 * full oops.
 485 */
 486static void zap_locks(void)
 487{
 488        static unsigned long oops_timestamp;
 489
 490        if (time_after_eq(jiffies, oops_timestamp) &&
 491                        !time_after(jiffies, oops_timestamp + 30*HZ))
 492                return;
 493
 494        oops_timestamp = jiffies;
 495
 496        /* If a crash is occurring, make sure we can't deadlock */
 497        spin_lock_init(&logbuf_lock);
 498        /* And make sure that we print immediately */
 499        init_MUTEX(&console_sem);
 500}
 501
 502/*
 503 * This is printk.  It can be called from any context.  We want it to work.
 504 * 
 505 * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
 506 * call the console drivers.  If we fail to get the semaphore we place the output
 507 * into the log buffer and return.  The current holder of the console_sem will
 508 * notice the new output in release_console_sem() and will send it to the
 509 * consoles before releasing the semaphore.
 510 *
 511 * One effect of this deferred printing is that code which calls printk() and
 512 * then changes console_loglevel may break. This is because console_loglevel
 513 * is inspected when the actual printing occurs.
 514 */
 515asmlinkage int printk(const char *fmt, ...)
 516{
 517        va_list args;
 518        int r;
 519
 520        va_start(args, fmt);
 521        r = vprintk(fmt, args);
 522        va_end(args);
 523
 524        return r;
 525}
 526
 527asmlinkage int vprintk(const char *fmt, va_list args)
 528{
 529        unsigned long flags;
 530        int printed_len;
 531        char *p;
 532        static char printk_buf[1024];
 533        static int log_level_unknown = 1;
 534
 535        if (unlikely(oops_in_progress))
 536                zap_locks();
 537
 538        /* This stops the holder of console_sem just where we want him */
 539        spin_lock_irqsave(&logbuf_lock, flags);
 540
 541        /* Emit the output into the temporary buffer */
 542        printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 543
 544        /*
 545         * Copy the output into log_buf.  If the caller didn't provide
 546         * appropriate log level tags, we insert them here
 547         */
 548        for (p = printk_buf; *p; p++) {
 549                if (log_level_unknown) {
 550                        if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') {
 551                                emit_log_char('<');
 552                                emit_log_char(default_message_loglevel + '0');
 553                                emit_log_char('>');
 554                        }
 555                        log_level_unknown = 0;
 556                }
 557                emit_log_char(*p);
 558                if (*p == '\n')
 559                        log_level_unknown = 1;
 560        }
 561
 562        if (!cpu_online(smp_processor_id()) &&
 563            system_state != SYSTEM_RUNNING) {
 564                /*
 565                 * Some console drivers may assume that per-cpu resources have
 566                 * been allocated.  So don't allow them to be called by this
 567                 * CPU until it is officially up.  We shouldn't be calling into
 568                 * random console drivers on a CPU which doesn't exist yet..
 569                 */
 570                spin_unlock_irqrestore(&logbuf_lock, flags);
 571                goto out;
 572        }
 573        if (!down_trylock(&console_sem)) {
 574                console_locked = 1;
 575                /*
 576                 * We own the drivers.  We can drop the spinlock and let
 577                 * release_console_sem() print the text
 578                 */
 579                spin_unlock_irqrestore(&logbuf_lock, flags);
 580                console_may_schedule = 0;
 581                release_console_sem();
 582        } else {
 583                /*
 584                 * Someone else owns the drivers.  We drop the spinlock, which
 585                 * allows the semaphore holder to proceed and to call the
 586                 * console drivers with the output which we just produced.
 587                 */
 588                spin_unlock_irqrestore(&logbuf_lock, flags);
 589        }
 590out:
 591        return printed_len;
 592}
 593EXPORT_SYMBOL(printk);
 594EXPORT_SYMBOL(vprintk);
 595
 596/**
 597 * acquire_console_sem - lock the console system for exclusive use.
 598 *
 599 * Acquires a semaphore which guarantees that the caller has
 600 * exclusive access to the console system and the console_drivers list.
 601 *
 602 * Can sleep, returns nothing.
 603 */
 604void acquire_console_sem(void)
 605{
 606        if (in_interrupt())
 607                BUG();
 608        down(&console_sem);
 609        console_locked = 1;
 610        console_may_schedule = 1;
 611}
 612EXPORT_SYMBOL(acquire_console_sem);
 613
 614int try_acquire_console_sem(void)
 615{
 616        if (down_trylock(&console_sem))
 617                return -1;
 618        console_locked = 1;
 619        console_may_schedule = 0;
 620        return 0;
 621}
 622EXPORT_SYMBOL(try_acquire_console_sem);
 623
 624int is_console_locked(void)
 625{
 626        return console_locked;
 627}
 628EXPORT_SYMBOL(is_console_locked);
 629
 630/**
 631 * release_console_sem - unlock the console system
 632 *
 633 * Releases the semaphore which the caller holds on the console system
 634 * and the console driver list.
 635 *
 636 * While the semaphore was held, console output may have been buffered
 637 * by printk().  If this is the case, release_console_sem() emits
 638 * the output prior to releasing the semaphore.
 639 *
 640 * If there is output waiting for klogd, we wake it up.
 641 *
 642 * release_console_sem() may be called from any context.
 643 */
 644void release_console_sem(void)
 645{
 646        unsigned long flags;
 647        unsigned long _con_start, _log_end;
 648        unsigned long wake_klogd = 0;
 649
 650        for ( ; ; ) {
 651                spin_lock_irqsave(&logbuf_lock, flags);
 652                wake_klogd |= log_start - log_end;
 653                if (con_start == log_end)
 654                        break;                  /* Nothing to print */
 655                _con_start = con_start;
 656                _log_end = log_end;
 657                con_start = log_end;            /* Flush */
 658                spin_unlock(&logbuf_lock);
 659                call_console_drivers(_con_start, _log_end);
 660                local_irq_restore(flags);
 661        }
 662        console_locked = 0;
 663        console_may_schedule = 0;
 664        up(&console_sem);
 665        spin_unlock_irqrestore(&logbuf_lock, flags);
 666        if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait))
 667                wake_up_interruptible(&log_wait);
 668}
 669EXPORT_SYMBOL(release_console_sem);
 670
 671/** console_conditional_schedule - yield the CPU if required
 672 *
 673 * If the console code is currently allowed to sleep, and
 674 * if this CPU should yield the CPU to another task, do
 675 * so here.
 676 *
 677 * Must be called within acquire_console_sem().
 678 */
 679void __sched console_conditional_schedule(void)
 680{
 681        if (console_may_schedule)
 682                cond_resched();
 683}
 684EXPORT_SYMBOL(console_conditional_schedule);
 685
 686void console_print(const char *s)
 687{
 688        printk(KERN_EMERG "%s", s);
 689}
 690EXPORT_SYMBOL(console_print);
 691
 692void console_unblank(void)
 693{
 694        struct console *c;
 695
 696        /*
 697         * Try to get the console semaphore. If someone else owns it
 698         * we have to return without unblanking because console_unblank
 699         * may be called in interrupt context.
 700         */
 701        if (down_trylock(&console_sem) != 0)
 702                return;
 703        console_locked = 1;
 704        console_may_schedule = 0;
 705        for (c = console_drivers; c != NULL; c = c->next)
 706                if ((c->flags & CON_ENABLED) && c->unblank)
 707                        c->unblank();
 708        release_console_sem();
 709}
 710EXPORT_SYMBOL(console_unblank);
 711
 712/*
 713 * Return the console tty driver structure and its associated index
 714 */
 715struct tty_driver *console_device(int *index)
 716{
 717        struct console *c;
 718        struct tty_driver *driver = NULL;
 719
 720        acquire_console_sem();
 721        for (c = console_drivers; c != NULL; c = c->next) {
 722                if (!c->device)
 723                        continue;
 724                driver = c->device(c, index);
 725                if (driver)
 726                        break;
 727        }
 728        release_console_sem();
 729        return driver;
 730}
 731
 732/*
 733 * Prevent further output on the passed console device so that (for example)
 734 * serial drivers can disable console output before suspending a port, and can
 735 * re-enable output afterwards.
 736 */
 737void console_stop(struct console *console)
 738{
 739        acquire_console_sem();
 740        console->flags &= ~CON_ENABLED;
 741        release_console_sem();
 742}
 743EXPORT_SYMBOL(console_stop);
 744
 745void console_start(struct console *console)
 746{
 747        acquire_console_sem();
 748        console->flags |= CON_ENABLED;
 749        release_console_sem();
 750}
 751EXPORT_SYMBOL(console_start);
 752
 753/*
 754 * The console driver calls this routine during kernel initialization
 755 * to register the console printing procedure with printk() and to
 756 * print any messages that were printed by the kernel before the
 757 * console driver was initialized.
 758 */
 759void register_console(struct console * console)
 760{
 761        int     i;
 762        unsigned long flags;
 763
 764        if (preferred_console < 0)
 765                preferred_console = selected_console;
 766
 767        /*
 768         *      See if we want to use this console driver. If we
 769         *      didn't select a console we take the first one
 770         *      that registers here.
 771         */
 772        if (preferred_console < 0) {
 773                if (console->index < 0)
 774                        console->index = 0;
 775                if (console->setup == NULL ||
 776                    console->setup(console, NULL) == 0) {
 777                        console->flags |= CON_ENABLED | CON_CONSDEV;
 778                        preferred_console = 0;
 779                }
 780        }
 781
 782        /*
 783         *      See if this console matches one we selected on
 784         *      the command line.
 785         */
 786        for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) {
 787                if (strcmp(console_cmdline[i].name, console->name) != 0)
 788                        continue;
 789                if (console->index >= 0 &&
 790                    console->index != console_cmdline[i].index)
 791                        continue;
 792                if (console->index < 0)
 793                        console->index = console_cmdline[i].index;
 794                if (console->setup &&
 795                    console->setup(console, console_cmdline[i].options) != 0)
 796                        break;
 797                console->flags |= CON_ENABLED;
 798                console->index = console_cmdline[i].index;
 799                if (i == preferred_console)
 800                        console->flags |= CON_CONSDEV;
 801                break;
 802        }
 803
 804        if (!(console->flags & CON_ENABLED))
 805                return;
 806
 807        /*
 808         *      Put this console in the list - keep the
 809         *      preferred driver at the head of the list.
 810         */
 811        acquire_console_sem();
 812        if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
 813                console->next = console_drivers;
 814                console_drivers = console;
 815        } else {
 816                console->next = console_drivers->next;
 817                console_drivers->next = console;
 818        }
 819        if (console->flags & CON_PRINTBUFFER) {
 820                /*
 821                 * release_console_sem() will print out the buffered messages
 822                 * for us.
 823                 */
 824                spin_lock_irqsave(&logbuf_lock, flags);
 825                con_start = log_start;
 826                spin_unlock_irqrestore(&logbuf_lock, flags);
 827        }
 828        release_console_sem();
 829}
 830EXPORT_SYMBOL(register_console);
 831
 832int unregister_console(struct console * console)
 833{
 834        struct console *a,*b;
 835        int res = 1;
 836
 837        acquire_console_sem();
 838        if (console_drivers == console) {
 839                console_drivers=console->next;
 840                res = 0;
 841        } else {
 842                for (a=console_drivers->next, b=console_drivers ;
 843                     a; b=a, a=b->next) {
 844                        if (a == console) {
 845                                b->next = a->next;
 846                                res = 0;
 847                                break;
 848                        }  
 849                }
 850        }
 851        
 852        /* If last console is removed, we re-enable picking the first
 853         * one that gets registered. Without that, pmac early boot console
 854         * would prevent fbcon from taking over.
 855         */
 856        if (console_drivers == NULL)
 857                preferred_console = selected_console;
 858                
 859
 860        release_console_sem();
 861        return res;
 862}
 863EXPORT_SYMBOL(unregister_console);
 864        
 865/**
 866 * tty_write_message - write a message to a certain tty, not just the console.
 867 *
 868 * This is used for messages that need to be redirected to a specific tty.
 869 * We don't put it into the syslog queue right now maybe in the future if
 870 * really needed.
 871 */
 872void tty_write_message(struct tty_struct *tty, char *msg)
 873{
 874        if (tty && tty->driver->write)
 875                tty->driver->write(tty, msg, strlen(msg));
 876        return;
 877}
 878
 879/*
 880 * printk rate limiting, lifted from the networking subsystem.
 881 *
 882 * This enforces a rate limit: not more than one kernel message
 883 * every printk_ratelimit_jiffies to make a denial-of-service
 884 * attack impossible.
 885 */
 886int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
 887{
 888        static DEFINE_SPINLOCK(ratelimit_lock);
 889        static unsigned long toks = 10*5*HZ;
 890        static unsigned long last_msg;
 891        static int missed;
 892        unsigned long flags;
 893        unsigned long now = jiffies;
 894
 895        spin_lock_irqsave(&ratelimit_lock, flags);
 896        toks += now - last_msg;
 897        last_msg = now;
 898        if (toks > (ratelimit_burst * ratelimit_jiffies))
 899                toks = ratelimit_burst * ratelimit_jiffies;
 900        if (toks >= ratelimit_jiffies) {
 901                int lost = missed;
 902                missed = 0;
 903                toks -= ratelimit_jiffies;
 904                spin_unlock_irqrestore(&ratelimit_lock, flags);
 905                if (lost)
 906                        printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
 907                return 1;
 908        }
 909        missed++;
 910        spin_unlock_irqrestore(&ratelimit_lock, flags);
 911        return 0;
 912}
 913EXPORT_SYMBOL(__printk_ratelimit);
 914
 915/* minimum time in jiffies between messages */
 916int printk_ratelimit_jiffies = 5*HZ;
 917
 918/* number of messages we send before ratelimiting */
 919int printk_ratelimit_burst = 10;
 920
 921int printk_ratelimit(void)
 922{
 923        return __printk_ratelimit(printk_ratelimit_jiffies,
 924                                printk_ratelimit_burst);
 925}
 926EXPORT_SYMBOL(printk_ratelimit);
 927
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.