Ядро Linux в комментариях




Kernel/printk.c


25610 /* 25611 * linux/kernel/printk.c 25612 * 25613 * Copyright (C) 1991, 1992 Linus Torvalds 25614 * 25615 * Modified to make sys_syslog() more flexible: added 25616 * commands to return the last 4k of kernel messages, 25617 * regardless of whether they've been read or not. Added 25618 * option to suppress kernel printk's to the console. 25619 * Added hook for sending the console messages elsewhere, 25620 * in preparation for a serial line console (someday). 25621 * Ted Ts'o, 2/11/93. 25622 * Modified for sysctl support, 1/8/97, Chris Horn. 25623 */ 25624 #include <linux/mm.h> 25625 #include <linux/tty_driver.h> 25626 #include <linux/smp_lock.h> 25627 #include <linux/console.h> 25628 #include <linux/init.h> 25629 25630 #include <asm/uaccess.h> 25631 25632 #define LOG_BUF_LEN (16384) 25633 25634 static char buf[1024]; 25635 25636 /* printk's without a loglevel use this.. */ 25637 #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ 25638 25639 /* We show everything that is MORE important than 25640 * this.. */ 25641 /* Minimum loglevel we let people use */ 25642 #define MINIMUM_CONSOLE_LOGLEVEL 1 25643 /* anything MORE serious than KERN_DEBUG */ 25644 #define DEFAULT_CONSOLE_LOGLEVEL 7 25645 25646 unsigned long log_size = 0; 25647 struct wait_queue * log_wait = NULL; 25648 25649 /* Keep together for sysctl support */ 25650 int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; 25651 int default_message_loglevel = DEFAULT_MESSAGE_LOGLEVEL; 25652 int minimum_console_loglevel = MINIMUM_CONSOLE_LOGLEVEL; 25653 int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; 25654 25655 struct console *console_drivers = NULL; 25656 static char log_buf[LOG_BUF_LEN]; 25657 static unsigned long log_start = 0; 25658 static unsigned long logged_chars = 0; 25659 struct console_cmdline 25660 console_cmdline[MAX_CMDLINECONSOLES]; 25661 static int preferred_console = -1; 25662 25663 /* Setup a list of consoles. Called from init/main.c */ 25664 void __init console_setup(char *str, int *ints) 25665 { 25666 struct console_cmdline *c; 25667 char name[sizeof(c->name)]; 25668 char *s, *options; 25669 int i, idx; 25670 25671 /* Decode str into name, index, options. */ 25672 if (str[0] >= '0' && str[0] <= '9') { 25673 strcpy(name, "ttyS"); 25674 strncpy(name + 4, str, sizeof(name) - 5); 25675 } else 25676 strncpy(name, str, sizeof(name) - 1); 25677 name[sizeof(name) - 1] = 0; 25678 if ((options = strchr(str, ',')) != NULL) 25679 *(options++) = 0; 25680 #ifdef __sparc__ 25681 if (!strcmp(str, "ttya")) 25682 strcpy(name, "ttyS0"); 25683 if (!strcmp(str, "ttyb")) 25684 strcpy(name, "ttyS1"); 25685 #endif 25686 for(s = name; *s; s++) 25687 if (*s >= '0' && *s <= '9') 25688 break; 25689 idx = simple_strtoul(s, NULL, 10); 25690 *s = 0; 25691 25692 /* See if this tty is not yet registered, and if we 25693 * have a slot free. */ 25694 for(i = 0; i < MAX_CMDLINECONSOLES && 25695 console_cmdline[i].name[0]; i++) 25696 if (strcmp(console_cmdline[i].name, name) == 0 && 25697 console_cmdline[i].index == idx) { 25698 preferred_console = i; 25699 return; 25700 } 25701 if (i == MAX_CMDLINECONSOLES) 25702 return; 25703 preferred_console = i; 25704 c = &console_cmdline[i]; 25705 memcpy(c->name, name, sizeof(c->name)); 25706 c->options = options; 25707 c->index = idx; 25708 } 25709 25710 /* Commands to do_syslog: 25711 * 25712 * 0 -- Close the log. Currently a NOP. 25713 * 1 -- Open the log. Currently a NOP. 25714 * 2 -- Read from the log. 25715 * 3 -- Read up to the last 4k of messages in the 25716 * ring buffer. 25717 * 4 -- Read and clear last 4k of messages in the 25718 * ring buffer. 25719 * 5 -- Clear ring buffer. 25720 * 6 -- Disable printk's to console 25721 * 7 -- Enable printk's to console 25722 * 8 -- Set level of messages printed to console 25723 */ 25724 int do_syslog(int type, char * buf, int len) 25725 { 25726 unsigned long i, j, count, flags; 25727 int do_clear = 0; 25728 char c; 25729 int error = -EPERM; 25730 25731 lock_kernel(); 25732 error = 0; 25733 switch (type) { 25734 case 0: /* Close log */ 25735 break; 25736 case 1: /* Open log */ 25737 break; 25738 case 2: /* Read from log */ 25739 error = -EINVAL; 25740 if (!buf len < 0) 25741 goto out; 25742 error = 0; 25743 if (!len) 25744 goto out; 25745 error = verify_area(VERIFY_WRITE,buf,len); 25746 if (error) 25747 goto out; 25748 error = wait_event_interruptible(log_wait, log_size); 25749 if (error) 25750 goto out; 25751 i = 0; 25752 while (log_size && i < len) { 25753 c = *((char *) log_buf+log_start); 25754 log_start++; 25755 log_size--; 25756 log_start &= LOG_BUF_LEN-1; 25757 sti(); 25758 __put_user(c,buf); 25759 buf++; 25760 i++; 25761 cli(); 25762 } 25763 sti(); 25764 error = i; 25765 break; 25766 case 4: /* Read/clear last kernel messages */ 25767 do_clear = 1; 25768 /* FALL THRU */ 25769 case 3: /* Read last kernel messages */ 25770 error = -EINVAL; 25771 if (!buf len < 0) 25772 goto out; 25773 error = 0; 25774 if (!len) 25775 goto out; 25776 error = verify_area(VERIFY_WRITE,buf,len); 25777 if (error) 25778 goto out; 25779 /* The logged_chars, log_start, and log_size values 25780 * may change from an interrupt, so we disable 25781 * interrupts. */ 25782 __save_flags(flags); 25783 __cli(); 25784 count = len; 25785 if (count > LOG_BUF_LEN) 25786 count = LOG_BUF_LEN; 25787 if (count > logged_chars) 25788 count = logged_chars; 25789 j = log_start + log_size - count; 25790 __restore_flags(flags); 25791 for (i = 0; i < count; i++) { 25792 c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1))); 25793 __put_user(c, buf++); 25794 } 25795 if (do_clear) 25796 logged_chars = 0; 25797 error = i; 25798 break; 25799 case 5: /* Clear ring buffer */ 25800 logged_chars = 0; 25801 break; 25802 case 6: /* Disable logging to console */ 25803 console_loglevel = minimum_console_loglevel; 25804 break; 25805 case 7: /* Enable logging to console */ 25806 console_loglevel = default_console_loglevel; 25807 break; 25808 case 8: 25809 error = -EINVAL; 25810 if (len < 1 len > 8) 25811 goto out; 25812 if (len < minimum_console_loglevel) 25813 len = minimum_console_loglevel; 25814 console_loglevel = len; 25815 error = 0; 25816 break; 25817 default: 25818 error = -EINVAL; 25819 break; 25820 } 25821 out: 25822 unlock_kernel(); 25823 return error; 25824 } 25825 25826 asmlinkage int sys_syslog(int type, char * buf, int len) 25827 { 25828 if ((type != 3) && !capable(CAP_SYS_ADMIN)) 25829 return -EPERM; 25830 return do_syslog(type, buf, len); 25831 } 25832 25833 25834 spinlock_t console_lock; 25835




Содержание  Назад  Вперед