linux 一次对一个用户限制存取

本文深入探讨了Linux设备驱动中多进程独占访问设备的机制,介绍了如何通过在open方法中添加检查,实现用户在多个进程中打开设备,但确保一次只有一个用户能真正访问。文章详细解析了sculluid设备的实现原理,包括使用自旋锁保护的设备拥有者和打开计数等关键变量,以及open和release方法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单打开设备之外的下一步是使一个用户在多个进程中打开一个设备, 但是一次只允许一个 用户打开设备. 这个解决方案使得容易测试设备, 因为用户一次可从几个进程读写, 但是 假定这个用户负责维护在多次存取中的数据完整性. 这通过在 open 方法中添加检查来实 现; 这样的检查在通常的许可检查后进行, 并且只能使存取更加严格, 比由拥有者和组许 可位所指定的限制. 这是和 ttys 所用的存取策略是相同的, 但是它不依赖于外部的特权 程序.

 

这些存取策略实现地有些比单打开策略要奇怪. 在这个情况下, 需要 2 项: 一个打开计 数和设备拥有者 uid. 再一次, 给这个项的最好的地方是在设备结构中; 我们的例子使用 全局变量代替, 是因为之前为 scullsingle 所解释的的原因. 这个设备的名子是 sculluid.

 

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

 

注意 sculluid 代码有 2 个变量 ( scull_u_owner 和 scull_u_count)来控制对设备的 存取, 并且这样可被多个进程并发地存取. 为使这些变量安全, 我们使用一个自旋锁控制 对它们的存取( scull_u_lock ). 没有这个锁, 2 个(或多个)进程可同时测试 scull_u_count , 并且都可能认为它们拥有设备的拥有权. 这里使用一个自旋锁, 是因为 这个锁被持有极短的时间, 并且驱动在持有这个锁时不做任何可睡眠的事情.

 

我们选择返回 -EBUSY 而不是 -EPERM, 即便这个代码在进行许可检测, 为了给一个被拒 绝存取的用户指出正确的方向. 对于"许可拒绝"的反应常常是检查 /dev 文件的模式和拥 有者, 而"设备忙"正确地建议用户应当寻找一个已经在使用设备的进程.

 

这个代码也检查来看是否正在试图打开的进程有能力来覆盖文件存取许可; 如果是这样, open 被允许即便打开进程不是设备的拥有者. CAP_DAC_OVERRIDE 能力在这个情况中适合 这个任务.

 

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;

}

 

再次, 我们在修改计数之前必须获得锁, 来确保我们没有和另一个进程竞争.

转载于:https://www.cnblogs.com/fanweisheng/p/11141907.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值