【專業技術】Linux裝置驅動第八篇:高階字元驅動操作之裝置存取控制
上一篇中介紹了阻塞IO等的一些用法,本來這一篇準備介紹一下poll/select等的一些高階IO操作,後來想想,在實際工作中開發驅動的時候很少會使用到poll/select這些操作,就不再介紹,有興趣的可以自己查詢資料學習一下。這一篇會介紹下相對比較實用的裝置檔案的存取控制的一些內容。
存取控制主要用於裝置的使用控制,只有授權的使用者才能訪問裝置或者同時只有一個程序訪問裝置。這也是存取控制使用最廣的地方。下面分別簡單說明。
單open裝置
單open裝置就是同時只有一個程序允許開啟一次所要訪問的裝置。此種方法是最簡單方便的訪問控制策略,可以防止多程序的競爭問題,但是這樣也造成了其侷限性。不能同時被多個程序多個使用者訪問。下面是一個單open裝置的簡單實現:
static atomic_t scull_s_available = ATOMIC_INIT(1); static int scull_s_open(struct inode *inode, struct file *filp) { struct scull_dev *dev = &scull_s_device; /* device information */ if (! atomic_dec_and_test (&scull_s_available)) { atomic_inc(&scull_s_available); return -EBUSY; /* already open */ } /* then, everything else is copied from the bare scull device */ if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) scull_trim(dev); filp->private_data = dev; return 0; /* success */ }
這段程式碼維護一個 atiomic_t 變數,稱為 scull_s_available;這個變數被初始化為值 1,表示裝置確實可用。open 呼叫遞減並測試 scull_s_available 並拒絕存取如果其他人已經使裝置開啟。
release呼叫,標識裝置不再忙。
static int scull_s_release(struct inode *inode, struct file *filp)
{
atomic_inc(&scull_s_available); /* release the device */
return 0;
}
單使用者多程序使用裝置
這種方式更高階一些,可以允許單個使用者的多個程序同時使用裝置。這種方式在第一次開啟裝置是會記住裝置擁有著,當下一次同一個使用者開啟裝置時也會得到允許。在上面介紹的open實現中需要加入類似下面的程式碼:
spin_lock(&scull_u_lock);
if (scull_u_count &&
(scull_u_owner != current->uid) && /* allow user */
(scull_u_owner != current->euid) && /* allow whoever did su */
!capable(CAP_DAC_OVERRIDE))
{ /* still allow root */
spin_unlock(&scull_u_lock);
return -EBUSY; /* -EPERM would confuse the user */
}
if (scull_u_count == 0)
scull_u_owner = current->uid; /* grab it */
scull_u_count++;
spin_unlock(&scull_u_lock);
這裡有幾個注意點,scull_u_owner 和 scull_u_count來控制對裝置的存取,並且可被多個程序併發地存取,為了使這倆個變數安全,使用自旋鎖來控制。
返回-EBUSY而不是-EPERM,我們這種情況雖然看著是在檢查許可權,但如果返回-EPERM,使用者一般會去檢查裝置節點的檔案mode已經擁有著,這是一個錯誤的方向。所以返回裝置忙更合理。
相應的release方法如下:
static int scull_u_release(struct inode *inode, struct file *filp)
{
spin_lock(&scull_u_lock);
scull_u_count--; /* nothing else */
spin_unlock(&scull_u_lock);
return 0;
}
以上就是裝置存取控制最常用方法,還有一些不常用的點沒有仔細介紹。有興趣的可以自行了解,也歡迎隨時交流。