-1

I was trying to read/write a file from my kernel module (I know it is dangerous and not suggested at all, but I need to do it for various reasons)

I followed this answer How to read/write files within a Linux kernel module?, and it works fine.

This is the code that I execute to test if the basic functions work:

void test_file(){
   struct file * f = file_open("./test.txt", O_CREAT |  O_RDWR | 
                                   O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);

   if(f != NULL){
     char arr[100];

     char * str = "I just wrote something";
     file_write(f,0, str, strlen(str)); 

     memset(arr, '\0', 100);
     file_read(f, 0, arr, 20);
     printk(KERN_INFO "Read %s\n",arr); 

     file_close(f);
   }else{
     printk(KERN_ERR "Error! Cannot write into file\n");
   }
}

If I execute this code inside my __init function, test.txt is created/updated inside the current folder where the .ko file is.

However, I noticed that if I execute this code in a new kthread, the file is created in / folder, and I need to provide the absolute path in order to get it in the current location.

void test_function(){
   test_file(); // creates test.txt in /
} 

static int __init file_init(void) { 
 struct task_struct * test_thread = kthread_run((void *)test_function, NULL, "Test");
 test_file(); // creates test.txt in .
}
module_init(file_init)

Definitions of file_write, file_read, file_close and file_open are given in the linked stackoverflow answer

Anybody knows how to give a relative path also in the kthread?

John
  • 121
  • 3
  • 14
  • 1
    Your `__init` function is executed in the **context of user-space process**, which calls `insmod` for your module. And relative paths are counted against user-space *current directory*. But kthread isn't executed in the context of user-space process - it is pure kernel process. So it is unaware about *current directory* with all consequences. – Tsyvarev Feb 14 '18 at 21:14
  • so the only way to do it without hardcoding the path would be to create the file in user space and pass the `struct file *` to the kthread? – John Feb 15 '18 at 12:23
  • Hmm, I am unsure whether `struct file*` object can be passed from one kernel thread to another. It is better to pass path (abolute) to the file. – Tsyvarev Feb 15 '18 at 12:25
  • I tried to create a global variable `struct file*`, that points to the file opened by the user process, and it works. Why do you think that it shouldn't work? – John Feb 16 '18 at 15:37
  • I thought that a file opened in the context of some process is binding to that process. But probably this is not about the file opened by the kernel with `file_open()`. – Tsyvarev Feb 16 '18 at 16:38
  • I will post the code of what I did. I don't know a lot of multithreading, but if this was a single threaded application, it would work fine. However (correct me if I am wrong) since threads share the same data and files of process where they belong, this should work too. – John Feb 16 '18 at 21:43

1 Answers1

0

This is what I did:

struct file * f;

void test_file(){
  if(f != NULL){
     char arr[100];

     char * str = "I just wrote something";
     file_write(f,0, str, strlen(str)); 

     memset(arr, '\0', 100);
     file_read(f, 0, arr, 20);
     printk(KERN_INFO "Read %s\n",arr); 

     file_close(f);
    }else{
     printk(KERN_ERR "Error! Cannot open file\n");
    }
}


void test_function(){
   test_file(); // access the file from the kthread
} 


static int __init file_init(void) { 
    // Create and open the file in user space
    f = file_open("./test.txt", O_CREAT |  O_RDWR | O_APPEND, \
                                S_IRWXU | S_IRWXG | S_IRWXO);

   struct task_struct * test_thread = kthread_run((void *)test_function, \
                                                   NULL, "Test");
}


module_init(file_init)
John
  • 121
  • 3
  • 14