Доброго времени суток,изучаю vfs,знаю что это не хороший тон, с кода ядра создавать писать читать и удалять файлы,но я хочу научиться это делать
я написал код,когда я в onload() открывал файл и делал set_fs(),то файл создавался ,но ругался supervisor,но когда я это сделал в kernel thread ,то файл не создаётся хотя есть его структура file :)
я не могу понять почему callback функции могут,а потоки ядра не могут?
Я даже начал думать может поток имеет uid не рута или gid не рута и из за этого он не может создать файл с правами ,но когда я вывел в лог креденшелы потока то там был всё в ноль(в рут)
Потом я начал думать может поток не имеет fs или files в task_struct ,но и они есть ,указатели не нулевые.
вот моё логирование:
[ 173.839495] kmodule: onload [ 173.839496] before run main [ 173.839615] kmodule: Complete init module [ 173.839698] 1 [ 173.839700] 2 [ 173.839701] 3 [ 173.839702] 4 [ 173.839707] kmodule: struct file:00000000f6821bf4, s8 *buf:0000000004d4437e,size_t size_buf:1024,*f_pos:00000000005817e6 [ 173.839708] 5 [ 173.840182] 6 [ 173.840185] 7 [ 173.840186] 8
Мой код:
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/sched.h> #include <linux/sched/signal.h> #include <linux/types.h> #include <linux/kthread.h> #include <linux/slab.h> //#include <linux/kallsyms.h>
MODULE_LICENSE(«GPL»);
struct module_struct { s8 *buf; size_t size_buf; struct file *f; mm_segment_t oldfs; } module_data;
void strrev(unsigned char *str) { int i; int j; unsigned char a; unsigned len = strlen((const char *)str); for (i = 0, j = len - 1; i < j; i++, j–) { a = str[i]; str[i] = str[j]; str[j] = a; } }
int itoa(int num, unsigned char* str, int len, int base) { int sum = num; int i = 0; int digit; if (len == 0) return -1; do { digit = sum % base; if (digit < 0xA) str[i++] = ‘0’ + digit; else str[i++] = ‘A’ + digit - 0xA; sum /= base; }while (sum && (i < (len - 1))); if (i == (len - 1) && sum) return -1; str[i] = ‘\0’; strrev(str); return 0; }
static int module_main(void *local_data) { module_data.oldfs = get_fs(); set_fs(KERNEL_DS);
module_data.f = filp_open("kernel_log.dump",O_RDWR | O_CREAT,0);
if(IS_ERR(module_data.f))
{
printk(KERN_ALERT "kmodule: cannot create kernel file log\n");
set_fs(module_data.oldfs);
kfree(module_data.buf);
return -EPERM;
}
printk(KERN_INFO "1\n");
struct task_struct *task;
printk(KERN_INFO «2\n»);
s8 *pnum = kmalloc(256,GFP_KERNEL);
printk(KERN_INFO «3\n»);
if(pnum == NULL)
{
printk(KERN_ALERT "kmodule: cannot alloc kern mem\n");
filp_close(module_data.f,NULL);
kfree(module_data.buf);
set_fs(module_data.oldfs);
return -ENOMEM;
}
printk(KERN_INFO «4\n»);
strcat(module_data.buf,
"kernel dump,dumped by kmodule kernel process\n");
/* for_each_process(task) { strcat(module_data.buf,«process_name: «); strcat(module_data.buf,task->comm); strcat(module_data.buf,» pid: «); itoa(task->pid,pnum,256,10); strcat(module_data.buf,pnum); strcat(module_data.buf,» \n»); vfs_write(module_data.f,module_data.buf,module_data.size_buf,&module_data.f->f_pos); memset(module_data.buf,0,module_data.size_buf); } */
printk(KERN_INFO "kmodule: struct file:%p, s8 *buf:%p,size_t size_buf:%lld,*f_pos:%p\n",module_data.f,module_data.buf,module_data.size_buf,&module_data.f->f_pos);
printk(KERN_INFO "5\n");
if(vfs_write(module_data.f,module_data.buf,module_data.size_buf,&module_data.f->f_pos) < 0)
{
printk(KERN_ALERT "kmodule: cannot write data\n");
kfree(pnum);
set_fs(module_data.oldfs);
return -EPERM;
}
printk(KERN_INFO «6\n»);
if(filp_close(module_data.f,NULL) < 0) {
kfree(pnum);
set_fs(module_data.oldfs);
printk(KERN_ALERT "kmodule cannot close file\n");
return -EAGAIN;
}
kfree(pnum);
printk(KERN_INFO «7\n»);
set_fs(module_data.oldfs);
printk(KERN_INFO «8\n»);
return 0;
}
static int __init onload(void) {
printk(KERN_INFO "kmodule: onload\n");
module_data.buf = kmalloc(1024,GFP_KERNEL);
module_data.size_buf = 1024;
if(module_data.buf == NULL)
{
printk(KERN_ALERT "kmodule: cannot alloc kernel mem\n");
return -ENOMEM;
}
printk(KERN_INFO "before run main\n");
if(kthread_run(module_main,NULL,"module_main") == NULL)
{
printk(KERN_ALERT "kmodule: cannot create main thread\n");
// filp_close(module_data.f,NULL); // set_fs(module_data.oldfs); kfree(module_data.buf); return -EPERM; }
printk(KERN_INFO "kmodule: Complete init module\n");
return 0;
}
static void __exit unload(void) { printk(KERN_INFO «kmodule: unload\n»); kfree(module_data.buf); }
module_init(onload); module_exit(unload);