本章主要介紹使用者空間程式與核心通訊或讀取核心資訊的幾種機制。
1)procfs(/proc )
procfs和sysctl都可以匯出核心內部資訊,但procfs用於匯出唯讀資料,而sysctl匯出的資料是可讀寫的。
大多數網路功能初始化時都會在/proc中註冊一個或多個檔案。當使用者讀取這個檔案時,核心會調用一組核心功能來輸出相應的資料。這組核心功能是在建立檔案時初始化的檔案操作函數控制代碼定義的;
static struct file_operation xx_fops={ //函數控制代碼xx_fops
.open = xx_open; //也是初始化工作,註冊一組函數指標,用與遍鄰和定位返回給使用者的資料
.read = xx_read,
....
};
static int__init xx_proc_init(void){
if(!proc_net_fops_create("xx",s_irugo,&xx_fops)){..} //建立檔案,初始化的檔案函數控制代碼
..
};
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){ //定義xx_open()
rc=seq_open(file,&xx_op)
...
};
static ... xx_read (..){
....
};
2)sysctl(/proc/sys )
/proc/sys中看到的每個檔案實際上都是一個核心變數,讀取和設定核心變數都是通過ctl_table結構(/proc/sys中的每個目錄和檔案都是一個ctl_table結構,對於檔案
的ctl_table存在proc_handler指定操作,而對於目錄存在child指定子目錄或該目錄中的檔案)中的proc_handler域指定的核心功能作具體操作的;
static ctl_table scsi_table[]={
.ctl_name=dev_scsi_logging_level,
.procname="logging_level", // /proc/sys/下的檔案名稱
.data=&scsi_logging_level, //相關聯的核心變數
.maxlen=sizeof(scsi_logging_level), //核心變數大小
.mode=0644, //檔案目錄許可權
.proc_handler=&proc_dointvec }, //核心調用的函數 proc_dointvec--讀寫一個整數數組,類似的函數很多在kernel/sysctl.c中
{}
};
static ctl_table scsi_dir_table[]={
.ctl_name=dev_scsi,
.procname="scsi",
.mode=0555,
.child=scsi_table ], //目錄關係
{}
};
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); //註冊/proc/sys/dev/scsi/logging_level檔案
}
比如我們cat /proc/sys/dev/scsi/logging_level 實際上是對scsi_logging_level變數執行proc_dointvec函數,具體操作要看proc_dointvec的實現
3)sysfs(/sys )
比procfs和sysctl更新的檔案系統
4)ioctl
ioctl介面實際上是通過開啟一個socket,並根據這個socket初始化一個資料結構,然後把這個資料結構傳遞給ioctl,再經由sock_ioctl指派到正確的處理函數
以ifconfig eth0 mtu xxx為例
struct ifreq data;
fd=socket(PF_INET,SOCK_DGRAM,0); //建立通訊端描述符, pf_inet--tcp/ip, sock_dgram--資料通訊端類型
err=ioctl(fd,siocsifmtu,&data);
....
(未涉及sock_ioctl代碼)
5)netlink socket
netlink socket直接使用標準的socket api開啟、關閉、發送和接收資訊
socket(pf_netlink,sock_dgram,...)
netlink socket支援多播資訊