Scull access device driver
note
Learner: 山涛
Date: 2007-7-5
参考代码:ldd3_example/scull/access.c
设备驱动说明:
Scull access device
driver与scull device driver的不同之处仅仅在于前者添加了一些访问限制(策略)。
1. Restricting access to a single process at a time: The
brute-force way to provide access control is to permit a device to be opened by
only one process at a time (single openness)
在open方法中,使用一个原子计数器(静态全局变量)作为对设备文件访问的临界条件,通过调用atomic_dec_and_test()函数进行访问判断权限的判断。
在release方法中,调用atomic_inc()函数,释放临界区。
这个方法,简单有效的显示了利用原子操作访问一个公共资源(设备)的方法;然而,它不实用,因为这样给用户造成很大的不方便。
2. restricting access to a single user at a time: a single
user open a device in multiple processes but allow only one user to have the
device open at a time.
在open方法中,检查一些列check来限制访问权限(检查uid, euid,
CAP_DAC_OVERRIDE):
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); |
在open方法中,增加打开的次数计数;在release方法中,减少打开次数计数。
3. restricting access to a single user at a time, but with
block-open method.
在open方法中增加了阻塞,如果访问条件不满足,则睡眠等待;
在release方法中,减少打开次数计数;如果其计数为0, 则调用wake_up_interruptible_sync()唤醒其他user的进程。
4. clone the device on open: Another technique to manage access
control is to create different private copies of the device, depending on the
process opening it. Clearly, this is possible only if the device is not bound to
a hardware object; scull is an example of such a "software" device. The
internals of /dev/tty use a similar technique in order to give its process a
different "view" of what the /dev entry point represents. When copies of the
device are created by the software driver, we call them virtual devices—just as
virtual consoles use a single physical tty device.
这种方法借助链表和key值来实现对”soft device”的拷贝和管理。Key值的选取由用户的不同策略所决定。
struct scull_listitem
{
struct scull_dev
device;
dev_t key;
struct list_head
list;
}; |