我正在使用内核版本 3.x 开发内核模块。
我有一个函数负责确定正在运行的进程是否打开了给定的文件。
这是我的代码(见我之后的评论):
struct task_struct * process = NULL;
struct files_struct * task_files = NULL;
struct fdtable * fdt = NULL;
int fd_i;
char tmpbuf[256];
char * process_path = "";
for_each_process(process)
{
// Ignore processes without files
if (process->files == NULL)
continue;
printk(KERN_INFO "task_lock()...\n");
task_lock(process);
printk(KERN_INFO "task_lock() DONE\n");
task_files = process->files;
printk(KERN_INFO "task_unlock()...\n");
task_unlock(process);
printk(KERN_INFO "task_unlock() DONE\n");
printk(KERN_INFO "files_fdtable()...\n");
fdt = files_fdtable(task_files);
printk(KERN_INFO "files_fdtable() DONE\n");
printk(KERN_INFO "Iterating files...\n");
for (fd_i = 0; fd_i < fdt->max_fds; fd_i++)
{
if (fcheck_files(task_files, fd_i) == my_file)
{
if (process->mm)
{
if (process->mm->exe_file)
{
process_path = d_path(&process->mm->exe_file->f_path, tmpbuf, sizeof(tmpbuf));
break;
} else {
printk(KERN_INFO "process->mm->exe_file is NULL\n");
}
} else {
printk(KERN_INFO "process->mm is NULL\n");
}
}
}
printk(KERN_INFO "Files iteration finished\n");
}
此代码正在运行,并且变量process_path
包含打开给定文件的进程的路径。但是当机器上有巨大的负载时(所以经常通过这段代码),机器会冻结(在一定时间后)并且最新的打印调试是:
task_unlock() DONE
然后我看不出我做错了什么。
- for_each_process没有在进程上调用spin_lock和spin_unlock所以我使用task_lock和task_unlock。
- files_fdtable正在调用spin_lock和spin_unlock所以我没有。
- fcheck_files也在调用spin_lock和spin_unlock所以我没有。
- d_path正在注意锁定,所以我不这样做。
您能否解释一下为什么我的代码会冻结机器以及如何修复它?