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

📄 mconsole_kern.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
static void mconsole_get_config(int (*get_config)(char *, char *, int, 						  char **),				struct mc_request *req, char *name){	char default_buf[CONFIG_BUF_SIZE], *error, *buf;	int n, size;	if(get_config == NULL){		mconsole_reply(req, "No get_config routine defined", 1, 0);		return;	}	error = NULL;	size = sizeof(default_buf)/sizeof(default_buf[0]);	buf = default_buf;	while(1){		n = (*get_config)(name, buf, size, &error);		if(error != NULL){			mconsole_reply(req, error, 1, 0);			goto out;		}		if(n <= size){			mconsole_reply(req, buf, 0, 0);			goto out;		}		if(buf != default_buf)			kfree(buf);		size = n;		buf = kmalloc(size, GFP_KERNEL);		if(buf == NULL){			mconsole_reply(req, "Failed to allocate buffer", 1, 0);			return;		}	} out:	if(buf != default_buf)		kfree(buf);	}void mconsole_config(struct mc_request *req){	struct mc_device *dev;	char *ptr = req->request.data, *name;	int err;	ptr += strlen("config");	while(isspace(*ptr)) ptr++;	dev = mconsole_find_dev(ptr);	if(dev == NULL){		mconsole_reply(req, "Bad configuration option", 1, 0);		return;	}	name = &ptr[strlen(dev->name)];	ptr = name;	while((*ptr != '=') && (*ptr != '\0'))		ptr++;	if(*ptr == '='){		err = (*dev->config)(name);		mconsole_reply(req, "", err, 0);	}	else mconsole_get_config(dev->get_config, req, name);}void mconsole_remove(struct mc_request *req){	struct mc_device *dev;		char *ptr = req->request.data, *err_msg = "";        char error[256];	int err, start, end, n;	ptr += strlen("remove");	while(isspace(*ptr)) ptr++;	dev = mconsole_find_dev(ptr);	if(dev == NULL){		mconsole_reply(req, "Bad remove option", 1, 0);		return;	}        ptr = &ptr[strlen(dev->name)];        err = 1;        n = (*dev->id)(&ptr, &start, &end);        if(n < 0){                err_msg = "Couldn't parse device number";                goto out;        }        else if((n < start) || (n > end)){                sprintf(error, "Invalid device number - must be between "                        "%d and %d", start, end);                err_msg = error;                goto out;        }	err = (*dev->remove)(n);        switch(err){        case -ENODEV:                err_msg = "Device doesn't exist";                break;        case -EBUSY:                err_msg = "Device is currently open";                break;        default:                break;        } out:	mconsole_reply(req, err_msg, err, 0);}#ifdef CONFIG_MAGIC_SYSRQvoid mconsole_sysrq(struct mc_request *req){	char *ptr = req->request.data;	ptr += strlen("sysrq");	while(isspace(*ptr)) ptr++;	mconsole_reply(req, "", 0, 0);	handle_sysrq(*ptr, &current->thread.regs, NULL);}#elsevoid mconsole_sysrq(struct mc_request *req){	mconsole_reply(req, "Sysrq not compiled in", 1, 0);}#endif/* Mconsole stack trace *  Added by Allan Graves, Jeff Dike *  Dumps a stacks registers to the linux console. *  Usage stack <pid>. */void do_stack(struct mc_request *req){        char *ptr = req->request.data;        int pid_requested= -1;        struct task_struct *from = NULL;	struct task_struct *to = NULL;        /* Would be nice:         * 1) Send showregs output to mconsole.	 * 2) Add a way to stack dump all pids.	 */        ptr += strlen("stack");        while(isspace(*ptr)) ptr++;        /* Should really check for multiple pids or reject bad args here */        /* What do the arguments in mconsole_reply mean? */        if(sscanf(ptr, "%d", &pid_requested) == 0){                mconsole_reply(req, "Please specify a pid", 1, 0);                return;        }        from = current;        to = find_task_by_pid(pid_requested);        if((to == NULL) || (pid_requested == 0)) {                mconsole_reply(req, "Couldn't find that pid", 1, 0);                return;        }        to->thread.saved_task = current;        switch_to(from, to, from);        mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);}void mconsole_stack(struct mc_request *req){	/* This command doesn't work in TT mode, so let's check and then	 * get out of here	 */	CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",				   1, 0),		    do_stack(req));}/* Changed by mconsole_setup, which is __setup, and called before SMP is * active. */static char *notify_socket = NULL; int mconsole_init(void){	/* long to avoid size mismatch warnings from gcc */	long sock;	int err;	char file[256];	if(umid_file_name("mconsole", file, sizeof(file))) return(-1);	snprintf(mconsole_socket_name, sizeof(file), "%s", file);	sock = os_create_unix_socket(file, sizeof(file), 1);	if (sock < 0){		printk("Failed to initialize management console\n");		return(1);	}	register_reboot_notifier(&reboot_notifier);	err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,			     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,			     "mconsole", (void *)sock);	if (err){		printk("Failed to get IRQ for management console\n");		return(1);	}	if(notify_socket != NULL){		notify_socket = uml_strdup(notify_socket);		if(notify_socket != NULL)			mconsole_notify(notify_socket, MCONSOLE_SOCKET,					mconsole_socket_name, 					strlen(mconsole_socket_name) + 1);		else printk(KERN_ERR "mconsole_setup failed to strdup "			    "string\n");	}	printk("mconsole (version %d) initialized on %s\n", 	       MCONSOLE_VERSION, mconsole_socket_name);	return(0);}__initcall(mconsole_init);static int write_proc_mconsole(struct file *file, const char __user *buffer,			       unsigned long count, void *data){	char *buf;	buf = kmalloc(count + 1, GFP_KERNEL);	if(buf == NULL) 		return(-ENOMEM);	if(copy_from_user(buf, buffer, count)){		count = -EFAULT;		goto out;	}	buf[count] = '\0';	mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count); out:	kfree(buf);	return(count);}static int create_proc_mconsole(void){	struct proc_dir_entry *ent;	if(notify_socket == NULL) return(0);	ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);	if(ent == NULL){		printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n");		return(0);	}	ent->read_proc = NULL;	ent->write_proc = write_proc_mconsole;	return(0);}static DEFINE_SPINLOCK(notify_spinlock);void lock_notify(void){	spin_lock(&notify_spinlock);}void unlock_notify(void){	spin_unlock(&notify_spinlock);}__initcall(create_proc_mconsole);#define NOTIFY "=notify:"static int mconsole_setup(char *str){	if(!strncmp(str, NOTIFY, strlen(NOTIFY))){		str += strlen(NOTIFY);		notify_socket = str;	}	else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);	return(1);}__setup("mconsole", mconsole_setup);__uml_help(mconsole_setup,"mconsole=notify:<socket>\n""    Requests that the mconsole driver send a message to the named Unix\n""    socket containing the name of the mconsole socket.  This also serves\n""    to notify outside processes when UML has booted far enough to respond\n""    to mconsole requests.\n\n");static int notify_panic(struct notifier_block *self, unsigned long unused1,			void *ptr){	char *message = ptr;	if(notify_socket == NULL) return(0);	mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 			strlen(message) + 1);	return(0);}static struct notifier_block panic_exit_notifier = {	.notifier_call 		= notify_panic,	.next 			= NULL,	.priority 		= 1};static int add_notifier(void){	notifier_chain_register(&panic_notifier_list, &panic_exit_notifier);	return(0);}__initcall(add_notifier);char *mconsole_notify_socket(void){	return(notify_socket);}EXPORT_SYMBOL(mconsole_notify_socket);/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-file-style: "linux" * End: */

⌨️ 快捷键说明

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