Задать вопрос
@egorggegor

Почему при записи в /proc/ система зависает?

Есть следующий код, он описывает файл в /proc/, при попытке записать что-либо в этот файл, система зависает и перестает отвечать. Может быть кто-то знает в чем проблема?
#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>

MODULE_DESCRIPTION("Process Setting Module");
MODULE_LICENSE("GPL");

/*PROC макросы*/
#define PROC_CONFIG_FILE_NAME	"process_sched_add"

/*Стандартные макросы*/
#define BASE_10 		10

/*Состояния процессов*/
enum process_state {
    
    eCreated        =    0, /*Процесс сощдан*/
    eRunning        =    1, /*Процесс выполняется*/
    eWaiting        =    2, /*Процесс в состоянии ожидания*/
    eBlocked        =    3, /*Процесс заблокирован*/
    eTerminated     =    4  /*Процесс завершен*/
};

/*Enum для выполнения функций*/
enum execution {

	eExecFailed 	= 	-1, /*Выполнение функции завершилось неудачно*/
	eExecSuccess 	=	 0  /*Выполнение функции завершилось успешно*/
};

/*PROC FS директива объекта*/
static struct proc_dir_entry *proc_sched_add_file_entry;


/*Прототипы  внешних  функций очереди процессов*/
extern int add_process_to_queue(int pid);
extern int remove_process_from_queue(int pid);
extern int print_process_queue(void);
extern int get_first_process_in_queue(void);
extern int remove_terminated_processes_from_queue(void);
extern int change_process_state_in_queue(int pid, int changeState);

/*Функция вызывается, когда читается файл process_sched_add.
 /proc/process_sched_add_module - это файл только для записи  */
static ssize_t process_sched_add_module_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
	
	printk(KERN_INFO "Process Scheduler Add Module read.\n");
	printk(KERN_INFO "Next Executable PID in the list if RR Scheduling: %d\n", get_first_process_in_queue());
	return 0;
}

/*Функция вызывается, когда записывается файл process_sched_add.
 /proc/process_sched_add_module - это файл только для записи*/
static ssize_t process_sched_add_module_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	int ret;
	long int new_proc_id;	
	
	printk(KERN_INFO "Process Scheduler Add Module write.\n");
	printk(KERN_INFO "Registered Process ID: %s\n", buf);
	
	ret = kstrtol(buf,BASE_10,&new_proc_id);
	if(ret < 0) {
		return -EINVAL;
	}
	
    /*Добавление процесса в очередь процессов*/
	ret = add_process_to_queue(new_proc_id);
    /*Проверка на то, успешно ли добавлен процесс в очередь процессов*/
	if(ret != eExecSuccess) {
		printk(KERN_ALERT "Process Set ERROR:add_process_to_queue function failed from sched set write method");
		return -ENOMEM;
	}

	return count;
}

/*Функция, которая вызывается, когда process_sched_add был открыт.
 /proc/process_sched_add_module - это файл только для записи*/
static int process_sched_add_module_open(struct inode * inode, struct file * file)
{
	printk(KERN_INFO "Process Scheduler Add Module open.\n");
	
	return 0;
}

/*Функция, которая вызывается, когда process_sched_add был закрыт.
 /proc/process_sched_add_module - это файл только для записи*/
static int process_sched_add_module_release(struct inode * inode, struct file * file)
{
	printk(KERN_INFO "Process Scheduler Add Module released.\n");
	return 0;
}

/*Файловые операции связанные с process_sched_add*/
static struct file_operations process_sched_add_module_fops = {
	.owner =	THIS_MODULE,
	.read =		process_sched_add_module_read,
	.write =	process_sched_add_module_write,
	.open =		process_sched_add_module_open,
	.release =	process_sched_add_module_release,
};

/*Функция инициализации модуля ядра. Вызывается при запуске модуля ядра*/
static int __init process_sched_add_module_init(void)
{
	printk(KERN_INFO "Process Add to Scheduler module is being loaded.\n");
	
    /*PROC FS создается с разрешениями RD&WR с именем process_sched_add*/
	proc_sched_add_file_entry = proc_create(PROC_CONFIG_FILE_NAME,0777,NULL,&process_sched_add_module_fops);
    /*Проверка на успешность создания process_sched_add*/
	if(proc_sched_add_file_entry == NULL) {
		printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",PROC_CONFIG_FILE_NAME);
		return -ENOMEM;
	}
	 
	return 0;
}

/*Функция очистки модуля ядра. Вызывается при удалении модуля ядра*/
static void __exit process_sched_add_module_cleanup(void)
{
	
	printk(KERN_INFO "Process Add to Scheduler module is being unloaded.\n");
    /*PROC FS объект был удален*/
	proc_remove(proc_sched_add_file_entry);
}
module_init(process_sched_add_module_init);
module_exit(process_sched_add_module_cleanup);
  • Вопрос задан
  • 393 просмотра
Подписаться 3 Сложный Комментировать
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
static struct file_operations process_sched_add_module_fops = {
…
proc_create(PROC_CONFIG_FILE_NAME,0777,NULL,&process_sched_add_module_fops);

Я думаю, что это основная ошибка: proc_create принимает указатель на структуру proc_ops, а не на file_operations. Компилятор должен был бы что-нибудь сказать в этом месте, ты не читаешь его предупреждения?

static ssize_t process_sched_add_module_write(struct file *file, const char *buf, size_t count, loff_t *ppos)

А здесь ты потерял аннотацию __user у параметра buf. Этот буфер приходит из юзерспейса, по этой причине ты не можешь лезть в него напрямую функцией kstrtol.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы