This chapter describes several mechanisms for user space programs to communicate with the kernel or read kernel information.
1) procfs (/proc)
Both procfs and sysctl can export internal kernel information, but procfs is used to export read-only data, while sysctl exports data that can be read and written.
Most network functions register one or more files in/proc during initialization. When you read this file, the kernel will call a set of kernel functions to output the corresponding data. This set of kernel functions are defined by the file operation function handle initialized during file creation;
Static struct file_operation xx_fops = {// function handle xx_fops
. Open = xx_open; // It is also initialization. Register a set of function pointers, and use the adjacent data to locate the data returned to the user.
. Read = xx_read,
....
};
Static int _ init xx_proc_init (void ){
If (! Proc_net_fops_create ("XX", s_irugo, & xx_fops) {..} // create a file and initialize the file function handle
..
};
Static struct seq_operations xx_op = {// xx_open
. Start = clip_seq_start,
. Next = neigh_seq_next,
....
};
Static in xx_open (struct inode * inode, struct file * file) {// defines xx_open ()
Rc = seq_open (file, & xx_op)
...
};
Static... xx_read (..){
....
};
2) sysctl (/proc/sys)
Every file in/proc/sys is actually a kernel variable. Reading and setting kernel variables are all in the ctl_table structure (each directory and file in/proc/sys is a ctl_table structure, for Files
The ctl_table of has the proc_handler specified operation, and the kernel function specified by the proc_handler field in the directory contains the child specified subdirectory or files in the directory;
Static ctl_table scsi_table [] = {
. Ctl_name = dev_scsi_logging_level,
. Procname = "logging_level", // file name under proc/sys/
. Data = & scsi_logging_level, // The associated kernel variable
. Maxlen = sizeof (scsi_logging_level), // kernel variable size
. Mode = 0644, // file directory permission
. Proc_handler = & proc_dointvec}, // The proc_dointvec function called by the kernel -- reads and writes an integer array. Many similar functions are in kernel/sysctl. C.
{}
};
Static ctl_table scsi_dir_table [] = {
. Ctl_name = dev_scsi,
. Procname = "SCSI ",
. Mode = 0555,
. Child = scsi_table], // directory relationship
{}
};
Static ctl_table scsi_root_table [] = {
. Ctl_name = ctl_dev,
. Procname = "Dev ",
. Mode = 0555,
. Child = scsi_dir_table },
{}
};
Int _ init scsi_init_sysctl (void ){
Scsi_table_header = register_sysctl_table (scsi_root_table, 1); // register the/proc/sys/dev/SCSI/logging_level File
}
For example, CAT/proc/sys/dev/SCSI/logging_level actually executes the proc_dointvec function for the scsi_logging_level variable. The specific operation depends on the implementation of proc_dointvec.
3) sysfs (/sys)
File Systems newer than procfs and sysctl
4) IOCTL
The ioctl interface is actually used to open a socket, initialize a Data Structure Based on the socket, pass the data structure to ioctl, and then assign the correct processing function through sock_ioctl.
Take ifconfig eth0 MTU xxx As An Example
Struct ifreq data;
FD = socket (pf_inet, sock_dgram, 0); // create socket descriptor, pf_inet -- TCP/IP, sock_dgram -- datagram socket type
Err = IOCTL (FD, siocsifmtu, & data );
....
(No sock_ioctl code is involved)
5) netlink socket
Netlink socket directly uses standard socket API to open, close, send, and receive messages
Socket (pf_netlink, sock_dgram ,...)
Netlink socket supports multicast Information