LINUX设备驱动学习(十一)–设备的访问控制

设备文件的访问控制:独享设备,限制每次只有一个用户访问(单用户访问),阻塞型用户访问,打开时复制设备。

独享设备主要是让驱动程序维护一个atomic_t变量,该变量初始化为1,表明可用,在open时会减小并测试scull_s_available,并在其他进程打开该设备时拒绝打开该设备。代码示例:

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_device;

if(!atomic_dec_and_test(&scull_s_availeable)){

atomic_inc(&scull_s_available);

return -EBUSY;

}

….

}

static int scull_s_release(struct inode *inode,struct file *filp)

{

atomic_inc(&scull_s_available); //释放设备

return 0;

}

单用户访问:open 调用在第一次打开记住了设备拥有者,此用户可多次打开设备,并协调多个进程对设备并发操作。同时,没有其他用户可打开它,避免了外部干扰。此时需要两个数据项一个打开计数和设备属主的UID。一般建议将这两个数据项放入到设备的数据结构中。示例代码:

static int singleUID_count; /* initialized to 0 by default */

static uid_t singleUID_owner; /* initialized to 0 by default */

static spinlock_t singleUID_lock = SPIN_LOCK_UNLOCKED;

static int singleUID_open(struct inode *inode,struct file *filp)

{

spin_lock(&singleUID_lock);

if(singleUID_count && //如果singleUID_count为一说明已经打开了

singleUID_owner != current->uid &&

singleUID_owner != current->euid && //如果权限不对,不允许打开

!capable(CAP_DAC_OVERRIDE){//capable用于描述用户空间可能拥有的权能操作。

spin_unlock(&singleUID_lock);

return -EBUSY;

}

if(singleUID_count == 0){

singleUID_OWNER = current->uid;

}

singleUID_count++;

spin_unlock(&singleUID_lock);

return 0;

}

static int singleUID_release(struct inode *inode,struct file *filp)

{

spin_lock(&singleUID_lock);

singleUID_count–;

spin_unlock(&singleUID_lock);

return 0;

}

上边看出在对singleUID_count,singleUID_owner等结构进行操作时都用锁保护起来。

代替EBUSY的阻塞型open:当设备不可访问时,并不直接返回EBUSY,而是用阻塞型I/O实现。

示例代码:

static int singleUID_count ;

static uid_t singleUID_owner;

static spinlock_t singleUID_lock = UNLOCKED;

static spinlock_t singleUID_lcok = UNLOCKED;

static inline int singleUID_available(void)

{

return singleUID_count == 0||singleUID_owner == current->uid||

singleUID_owner == current->euid || capable(CAP_DAC_OVERRIDE);

}

static int singleUID_open(struct inode *inode,struct file *filp)

{

spin_lock(&singleUID_lock);

while(!singleUID_available()){

spin_unlock(&singleUID_lock);

if(filp->f_flags & O_NONBLOCK)

return -EAGAIN;

if(wait_event_interruptible(singleUID_wait,singleUID_available()))

return -ERESTARTTSYS;

spin_lock(&singleUID_lock);

}

if(singleUID_count == 0)

singleUID_owner = current->uid;

singleUID_count ++;

spin_unlock(&singleUID_lock);

return 0;

}

static int singleUID_release(struct inode *inode,strct file *filp)

{

spin_lock(&singleUID_lock);

singleUID_count–;

spin_unlock(&singleUID_lock);

if(singleUID_count == 0)

wake_up_interruptible(&singleUID_wait);

return 0;

}

open时复制设备:如果复制的设备是由软件驱动程序创建的,我们称为“虚拟设备”——就像所有的虚拟终端都是用同一个物理设备一样。

没有什么可留恋,只有抑制不住的梦想,

LINUX设备驱动学习(十一)–设备的访问控制

相关文章:

你感兴趣的文章:

标签云: