Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a writable proc file by using seq_file in a driver module

In the book of Linux Device Driver 3rd ed, /proc file system is used as a output method to export the running state of a certain device driver.

However, in some circumstances, /proc file system is used as one interface to change the internal parameters of a driver module.

I googled a lot, and found some implementations on the Internet are too old that they used create_proc_entry() rather than proc_create().

What's more, I'm prefer to implement this by seq_file(actually, I'm not sure is it possible). I checked the seq_write() function, and obtained nothing.

Can anyone show me an example to finish this mission? seq_file implementation is more preferred.

like image 531
Douglas Su Avatar asked Jun 08 '15 13:06

Douglas Su


People also ask

What is seq_file?

The seq_file code manages positioning within the output created by the iterator and getting it into the user's buffer. But, for that to work, that output must be passed to the seq_file code. Some utility functions have been defined which make this task easy.

What is the proc filesystem in Linux?

Proc file system (procfs) is virtual file system created on fly when system boots and is dissolved at time of system shut down. It contains useful information about the processes that are currently running, it is regarded as control and information center for kernel.


1 Answers

seq_file provides helpers only for reading file. There is no similar helpers for write, but it is not difficult to implement .write callback for iterable data by hands:

Unlike to the reading, you can drop file's position handling in the .write callback, assuming that user always write to the beginning, or, optionally, to the end (using O_APPEND file's control flag). Second, again unlike to the reading, you can assume that user writes at once content of 1,2 or more elements, but not a half element.

The simplest way is allow to write by single element:

size_t write(struct file* file, const char __user* buf, size_t size, loff_t* pos)
{
    copy_from_user(str, buf, size); // Copy string from user space
    my_elem = my_parse(str, size); // Parse string
    if(file->f_flags & O_APPEND) {
         list_add_tail(my_elem, &my_list);//Append element to the end of list
    }
    else {
         clear_my_list(); // Clear old content of the list
         list_add_tail(my_elem, &my_list);// Add single element to it.
    }

    (void)pos; //Do not use file position at all
    return count; // Return number of bytes passed by the user
}

If user wants to write several elements, e.g., from a file on hard disk, any shell is able to split this file by, e.g., new lines, and feed lines to the your proc file one by one.

like image 189
Tsyvarev Avatar answered Sep 23 '22 04:09

Tsyvarev