⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    (void)vsnprintf(buf, sizeof(buf), fmt, args);    va_end(args);            p = buf;    while ( (q = strchr(p, '\n')) != NULL )    {        *q = '\0';        if ( start_of_line )            do_print = printk_prefix_check(p, &p);        if ( do_print )        {            if ( start_of_line )                printk_start_of_line();            __putstr(p);            __putstr("\n");        }        start_of_line = 1;        p = q + 1;    }    if ( *p != '\0' )    {        if ( start_of_line )            do_print = printk_prefix_check(p, &p);        if ( do_print )        {            if ( start_of_line )                printk_start_of_line();            __putstr(p);        }        start_of_line = 0;    }    spin_unlock_recursive(&console_lock);    local_irq_restore(flags);}void __init init_console(void){    char *p;    /* Where should console output go? */    for ( p = opt_console; p != NULL; p = strchr(p, ',') )    {        if ( *p == ',' )            p++;        if ( strncmp(p, "com", 3) == 0 )            sercon_handle = serial_parse_handle(p);        else if ( strncmp(p, "vga", 3) == 0 )            vga_init();    }    serial_set_rx_handler(sercon_handle, serial_rx);    /* HELLO WORLD --- start-of-day banner text. */    spin_lock(&console_lock);    __putstr(xen_banner());    spin_unlock(&console_lock);    printk("Xen version %d.%d%s (%s@%s) (%s) %s\n",           xen_major_version(), xen_minor_version(), xen_extra_version(),           xen_compile_by(), xen_compile_domain(),           xen_compiler(), xen_compile_date());    printk("Latest ChangeSet: %s\n", xen_changeset());    if ( opt_sync_console )    {        serial_start_sync(sercon_handle);        add_taint(TAINT_SYNC_CONSOLE);        printk("Console output is synchronous.\n");    }}void __init console_endboot(void){    int i, j;    printk("Std. Loglevel: %s", loglvl_str(xenlog_lower_thresh));    if ( xenlog_upper_thresh != xenlog_lower_thresh )        printk(" (Rate-limited: %s)", loglvl_str(xenlog_upper_thresh));    printk("\nGuest Loglevel: %s", loglvl_str(xenlog_guest_lower_thresh));    if ( xenlog_guest_upper_thresh != xenlog_guest_lower_thresh )        printk(" (Rate-limited: %s)", loglvl_str(xenlog_guest_upper_thresh));    printk("\n");    if ( opt_sync_console )    {        printk("**********************************************\n");        printk("******* WARNING: CONSOLE OUTPUT IS SYNCHRONOUS\n");        printk("******* This option is intended to aid debugging "               "of Xen by ensuring\n");        printk("******* that all output is synchronously delivered "               "on the serial line.\n");        printk("******* However it can introduce SIGNIFICANT latencies "               "and affect\n");        printk("******* timekeeping. It is NOT recommended for "               "production use!\n");        printk("**********************************************\n");        for ( i = 0; i < 3; i++ )        {            printk("%d... ", 3-i);            for ( j = 0; j < 100; j++ )            {                process_pending_timers();                mdelay(10);            }        }        printk("\n");    }    vga_endboot();    /*     * If user specifies so, we fool the switch routine to redirect input     * straight back to Xen. I use this convoluted method so we still print     * a useful 'how to switch' message.     */    if ( opt_conswitch[1] == 'x' )        xen_rx = !xen_rx;    /* Serial input is directed to DOM0 by default. */    switch_serial_input();}int console_has(const char *device){    char *p;    for ( p = opt_console; p != NULL; p = strchr(p, ',') )    {        if ( *p == ',' )            p++;        if ( strncmp(p, device, strlen(device)) == 0 )            return 1;    }    return 0;}void console_start_log_everything(void){    serial_start_log_everything(sercon_handle);    atomic_inc(&print_everything);}void console_end_log_everything(void){    serial_end_log_everything(sercon_handle);    atomic_dec(&print_everything);}void console_force_unlock(void){    spin_lock_init(&console_lock);    serial_force_unlock(sercon_handle);    console_start_sync();}void console_force_lock(void){    spin_lock(&console_lock);}void console_start_sync(void){    atomic_inc(&print_everything);    serial_start_sync(sercon_handle);}void console_end_sync(void){    serial_end_sync(sercon_handle);    atomic_dec(&print_everything);}void console_putc(char c){    serial_putc(sercon_handle, c);}int console_getc(void){    return serial_getc(sercon_handle);}/* * printk rate limiting, lifted from Linux. * * This enforces a rate limit: not more than one kernel message * every printk_ratelimit_ms (millisecs). */int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst){    static DEFINE_SPINLOCK(ratelimit_lock);    static unsigned long toks = 10 * 5 * 1000;    static unsigned long last_msg;    static int missed;    unsigned long flags;    unsigned long long now = NOW(); /* ns */    unsigned long ms;    do_div(now, 1000000);    ms = (unsigned long)now;    spin_lock_irqsave(&ratelimit_lock, flags);    toks += ms - last_msg;    last_msg = ms;    if ( toks > (ratelimit_burst * ratelimit_ms))        toks = ratelimit_burst * ratelimit_ms;    if ( toks >= ratelimit_ms )    {        int lost = missed;        missed = 0;        toks -= ratelimit_ms;        spin_unlock(&ratelimit_lock);        if ( lost )        {            char lost_str[8];            snprintf(lost_str, sizeof(lost_str), "%d", lost);            /* console_lock may already be acquired by printk(). */            spin_lock_recursive(&console_lock);            printk_start_of_line();            __putstr("printk: ");            __putstr(lost_str);            __putstr(" messages suppressed.\n");            spin_unlock_recursive(&console_lock);        }        local_irq_restore(flags);        return 1;    }    missed++;    spin_unlock_irqrestore(&ratelimit_lock, flags);    return 0;}/* minimum time in ms between messages */int printk_ratelimit_ms = 5 * 1000;/* number of messages we send before ratelimiting */int printk_ratelimit_burst = 10;int printk_ratelimit(void){    return __printk_ratelimit(printk_ratelimit_ms, printk_ratelimit_burst);}/* * ************************************************************** * *************** Serial console ring buffer ******************* * ************************************************************** */#ifdef DEBUG_TRACE_DUMP/* Send output direct to console, or buffer it? */static volatile int debugtrace_send_to_console;static char        *debugtrace_buf; /* Debug-trace buffer */static unsigned int debugtrace_prd; /* Producer index     */static unsigned int debugtrace_kilobytes = 128, debugtrace_bytes;static unsigned int debugtrace_used;static DEFINE_SPINLOCK(debugtrace_lock);integer_param("debugtrace", debugtrace_kilobytes);static void debugtrace_dump_worker(void){    if ( (debugtrace_bytes == 0) || !debugtrace_used )        return;    printk("debugtrace_dump() starting\n");    /* Print oldest portion of the ring. */    ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);    sercon_puts(&debugtrace_buf[debugtrace_prd]);    /* Print youngest portion of the ring. */    debugtrace_buf[debugtrace_prd] = '\0';    sercon_puts(&debugtrace_buf[0]);    memset(debugtrace_buf, '\0', debugtrace_bytes);    printk("debugtrace_dump() finished\n");}static void debugtrace_toggle(void){    unsigned long flags;    watchdog_disable();    spin_lock_irqsave(&debugtrace_lock, flags);    /*     * Dump the buffer *before* toggling, in case the act of dumping the     * buffer itself causes more printk() invocations.     */    printk("debugtrace_printk now writing to %s.\n",           !debugtrace_send_to_console ? "console": "buffer");    if ( !debugtrace_send_to_console )        debugtrace_dump_worker();    debugtrace_send_to_console = !debugtrace_send_to_console;    spin_unlock_irqrestore(&debugtrace_lock, flags);    watchdog_enable();}void debugtrace_dump(void){    unsigned long flags;    watchdog_disable();    spin_lock_irqsave(&debugtrace_lock, flags);    debugtrace_dump_worker();    spin_unlock_irqrestore(&debugtrace_lock, flags);    watchdog_enable();}void debugtrace_printk(const char *fmt, ...){    static char    buf[1024];    static u32 count;    va_list       args;    char         *p;    unsigned long flags;    if ( debugtrace_bytes == 0 )        return;    debugtrace_used = 1;    spin_lock_irqsave(&debugtrace_lock, flags);    ASSERT(debugtrace_buf[debugtrace_bytes - 1] == 0);    snprintf(buf, sizeof(buf), "%u ", ++count);    va_start(args, fmt);    (void)vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, args);    va_end(args);    if ( debugtrace_send_to_console )    {        serial_puts(sercon_handle, buf);    }    else    {        for ( p = buf; *p != '\0'; p++ )        {            debugtrace_buf[debugtrace_prd++] = *p;                        /* Always leave a nul byte at the end of the buffer. */            if ( debugtrace_prd == (debugtrace_bytes - 1) )                debugtrace_prd = 0;        }    }    spin_unlock_irqrestore(&debugtrace_lock, flags);}static void debugtrace_key(unsigned char key){    debugtrace_toggle();}static int __init debugtrace_init(void){    int order;    unsigned int kbytes, bytes;    /* Round size down to next power of two. */    while ( (kbytes = (debugtrace_kilobytes & (debugtrace_kilobytes-1))) != 0 )        debugtrace_kilobytes = kbytes;    bytes = debugtrace_kilobytes << 10;    if ( bytes == 0 )        return 0;    order = get_order_from_bytes(bytes);    debugtrace_buf = alloc_xenheap_pages(order);    ASSERT(debugtrace_buf != NULL);    memset(debugtrace_buf, '\0', bytes);    debugtrace_bytes = bytes;    register_keyhandler(        'T', debugtrace_key, "toggle debugtrace to console/buffer");    return 0;}__initcall(debugtrace_init);#endif /* !NDEBUG *//* * ************************************************************** * *************** Debugging/tracing/error-report *************** * ************************************************************** */void panic(const char *fmt, ...){    va_list args;    unsigned long flags;    static DEFINE_SPINLOCK(lock);    static char buf[128];        debugtrace_dump();    /* Protects buf[] and ensure multi-line message prints atomically. */    spin_lock_irqsave(&lock, flags);    va_start(args, fmt);    (void)vsnprintf(buf, sizeof(buf), fmt, args);    va_end(args);    console_start_sync();    printk("\n****************************************\n");    printk("Panic on CPU %d:\n", smp_processor_id());    printk(buf);    printk("****************************************\n\n");    if ( opt_noreboot )        printk("Manual reset required ('noreboot' specified)\n");    else        printk("Reboot in five seconds...\n");    spin_unlock_irqrestore(&lock, flags);    debugger_trap_immediate();    kexec_crash();    if ( opt_noreboot )    {        machine_halt();    }    else    {        watchdog_disable();        machine_restart(5000);    }}void __bug(char *file, int line){    console_start_sync();    printk("Xen BUG at %s:%d\n", file, line);    dump_execution_state();    panic("Xen BUG at %s:%d\n", file, line);    for ( ; ; ) ;}void __warn(char *file, int line){    printk("Xen WARN at %s:%d\n", file, line);    dump_execution_state();}/* * ************************************************************** * ****************** Console suspend/resume ******************** * ************************************************************** */static void suspend_steal_fn(const char *str) { }static int suspend_steal_id;int console_suspend(void){    suspend_steal_id = console_steal(sercon_handle, suspend_steal_fn);    serial_suspend();    return 0;}int console_resume(void){    serial_resume();    console_giveback(suspend_steal_id);    return 0;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -