天天看點

linux kernel ioctl系統調用

Q:使用者空間調用ioctl操作網卡裝置行為時,調用鍊是什麼樣的?不同的socket類型是否也不一樣?

先來看一下系統調用ioctl的調用鍊是什麼樣的,請看下表

函數名稱 檔案名 做了什麼
SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) fs/ioctl.c ioctl函數入口
do_vfs_ioctl fs/ioctl.c 真正入口,這個函數裡邊會區分哪些是針對真正的檔案進行操作的,哪些是針對虛拟檔案進行操作的,顯然socket這類的ioctl就屬于虛拟檔案
vfs_ioctl fs/ioctl.c 這個函數會根據檔案描述符的指針找到檔案操作指針f_op對應的指針接口函數unlocked_ioctl,那麼這個unlocked_ioctl的函數指針在哪裡注冊的呢?net/socket.c裡邊調用系統調用socket建立sock檔案描述符的時候通過sock_map_fd函數再調用函數sock_alloc_file,這個函數裡邊會将socket_file_ops注入到socket檔案描述符裡邊,有的人會好奇網卡驅動裡邊也有關于unlocked_ioctl函數指針的注冊,那網卡驅動的ioctl是怎麼被調用的呢?網卡驅動的ioctl是先open一個/dev/netdeviceName,然後再調用ioctl傳遞裝置的檔案描述符。
sock_ioctl net/socket.c 函數入口則判斷輸入的cmd指令是否屬于[SIOCDEVPRIVATE, SIOCDEVPRIVATE+15]這個區間,如果屬于則調用dev_ioctl函數去操作裝置驅動相關功能接口進行設定,如果不在這個區間則針對各個cmd進行處理,如果這個函數的cmd都沒對應的處理動作,則調用sock_do_ioctl進行處理
sock_do_ioctl net/socket.c 這個函數根據sock->ops調用各自的ioctl指針,這裡就是轉到各family子產品去處理了,比如netlink子產品就去調用net/netlink/af_netlink.c下的sock_no_ioctl,pf_packet則調用net/packet/af_packet.c下的packet_ioctl,如果各子產品的ioctl函數處理之後傳回ENOIOCTLCMD錯誤即找不到指令,則仍然調用dev_ioctl去處理
dev_ioctl net/core/dev_ioctl.c 這個函數主要針對真實網卡驅動進行設定,比如設定多點傳播接收以及混雜模式等。

有了上面的分析,我們可以回答第二個問題,如果是針對網卡進行的操作,無論通過哪種family類型的socket,就是可以的,但是針對指定family特有的CMD則需要區分。

參考文章: IOCTL in Linux (I/O Control) – Linux Device Driver Tutorial Part 8

繼續閱讀