kernel proc file system and SEQ Interface (4)---seq_file Interface programming analysis

Source: Internet
Author: User
Tags data structures mutex printf

Because PROCFS's default action function uses only one page of caching, it is a bit cumbersome to handle large proc files, and is less flexible when outputting data from a series of structs, requiring you to implement iterations in the Read_proc function, which is prone to bugs. So kernel hackers to some/proc code to do research, abstract common, eventually formed the seq_file (Sequence file: Sequence files) interface. This interface provides a simple set of functions to solve the problem of programming the above Proc interface, making programming easier and reducing the chance of bugs appearing.

The Seq_file interface is recommended when you need to create a virtual file or a large virtual file that is composed of a series of data sequences. But I personally think, not only PROCFS can use this seq_file interface, because in fact Seq_file is implemented is an operation function set, this function set is not binding with proc, also can be used in other places. For the learning of a function interface layer, the first thing to look at is a related data structure struct Seq_file:

Cached page pointers used by the

include/linux/seq_file.h
struct seq_file {
char *buf;    //seq_file interface
size_t size;  //seq_file interface uses a cached page size size_t from;  //offset address to seq_file when copying from buf to user-state buffer
size_t count; //buf can be copied to the user state of the number of characters  
loff_t index; //start, next processing subscript pos value
loff_t read_pos;  //The amount of data currently copied to the user state
U64 version;
struct Mutex lock; //Mutex for this seq_file operation, all seq_* access will be locked
const struct Seq_operations *op; Functions that manipulate the actual underlying data
Void *private;
};     in this struct, almost all of the members are handled by Seq_file internal implementations, and programmers don't have to care unless you're going to study seq_ The internal principle of file. For this struct, the only thing programmers have to do is implement the Const struct Seq_operations *op. To access the different data structures using the Seq_file interface, you must create a simple set of object iteration operations functions.

struct Seq_operations {
void * (*start) (struct seq_file *m, loff_t *pos);
void (*stop) (struct seq_file *m, void *v);
void * (*next) (struct seq_file *m, void *v, loff_t *pos);
Int (*show) (struct seq_file *m, void *v);
};

Seq_file internal mechanisms Use these interface functions to access the underlying actual data structure body, and continue to move forward along the data sequence, while outputting data from the sequence sequentially to the Seq_file self-built cache (size is one page). That is to say, the seq_file internal mechanism helps you to read and cache the sequence data, you just need to implement the underlying iterative function interface, because these are related to the underlying data you want to access, and seq_file belong to the upper layer of abstraction. This may seem a little complicated, as you can see from the diagram below:

Here we outline the functions of each of the following struct seq_operations:

void * (*start) (struct seq_file *m, loff_t *pos); The Start method is called first, and its function is to set the starting point of the access. M: pointing to the structure of the seq_file, without the need for processing under normal circumstances. POS: is an integer position value that indicates where the read begins. The meaning of this position depends entirely on the underlying implementation, which is not necessarily the location of the byte unit, but may be the sequence number of an element. The return value, if non-null, is a pointer to a private data structure body that points to an iterator implementation. Returns NULL if an access error occurs.

When the access starting point is set, the Seq_file internal mechanism may use the Show method to get the data from the struct to which the start return value points to the internal cache and send it to the user space at the appropriate time.

Int (*show) (struct seq_file *m, void *v);

So the Show method is responsible for outputting the data in the V-pointing element to the internal cache of Seq_file, but it must be done with some printf-like interface functions provided by Seq_file:

int seq_printf (struct seq_file *sfile, const char *fmt, ...);
A printf-like function designed for Seq_file, and a format string and value-added parameter used for data.
You must pass the SET_FILE structure pointer to the show function to it. If seq_printf returns 1, it means that the buffer is full and some output is discarded. But most of the time, the return value is ignored.
int SEQ_PUTC (struct seq_file *sfile, char c);
int seq_puts (struct seq_file *sfile, const char *s);
Similar to the functions of the PUTC and puts functions, the sfile parameter and the return value are the same as seq_printf.
int Seq_escape (struct seq_file *m, const char *s, const char *ESC);
This function is similar to seq_puts, but it will output all the characters in s that appear in ESC to the cache in octal format. The common value of ESC is "\t\n\\", which causes the inline spaces to not clutter the output or confuse the shell script.

int seq_write (struct seq_file *seq, const void *data, size_t len)//writes data pointing directly to the Seq_file cache with data length len. Used for non-string data.
int Seq_path (struct seq_file *sfile, struct vfsmount *m, struct dentry *dentry, char *esc);
This function can be used to output the file name associated with a given directory entry, which is rarely used by the driver.

After the show function returns, the seq_file mechanism may need to be moved to the next data element, and the next method must be used.

void * (*next) (struct seq_file *m, void *v, loff_t *pos); V: is the element pointer that was previously returned by a call to start or next, possibly the element pointed to by the previous show's finished output. POS: The index value of the element that needs to be moved.
The value pointed to by POS should be incremented in the next implementation, but the specific increment is related to the implementation of the iterator, not necessarily 1. The return value of next, if not NULL, is the next element pointer that needs to be output to the cache, otherwise it indicates that the output has ended and the Stop method will be called to clean it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.