【专业技术】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;
}

以上就是设备存取控制最常用方法,还有一些不常用的点没有仔细介绍。有兴趣的可以自行了解,也欢迎随时交流。

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-08-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏移动端开发

iOS设备唯一标识的前世今生

设备唯一标识 ----       估计很多开发都有被要求过获取一下设备的唯一标识,获取设备的唯一标识经常使用在我们做统计或者是在保证一台设备登录亦或者是做IM...

3855
来自专栏CSDN技术头条

Java 程序如何正确地打日志

我们 Java 程序员在开发项目时都是依赖 Eclipse/ Idea 等开发工具的 Debug 调试功能来跟踪解决 Bug,在开发环境可以这么做,但项目发布到...

843
来自专栏SAP最佳业务实践

SAP最佳业务实践:FI–总账(156)-7周期性分录

4.10 周期性分录 本功能支持可以定期创建的过帐。周期性分录类似于银行长期订单,用于扣除租金、缴纳付款、或直接的贷款偿还。周期性分录程序将基于周期性分录凭证...

3376
来自专栏WeTest质量开放平台团队的专栏

了解和分析iOS Crash

北京时间凌晨一点,苹果一年一度的发布会如期而至。新机型的发布又会让适配相关的同学忙上一阵子啦,并且iOS Crash的问题始终伴随着移动开发者。本文将从三个阶段...

713
来自专栏杨建荣的学习笔记

初探Redis

大概在2010年的时候,有一次和一个同事聊天,那个时候知道了Redis,对于技术的追随至今,还没有下载一个Redis版本玩玩, 只有1万多行代码,以性...

4089
来自专栏破晓之歌

数据库设计那些事 原

612
来自专栏向治洪

android系统分层

  Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户...

18510
来自专栏WeTest质量开放平台团队的专栏

了解和分析iOS Crash

原文链接:http://wetest.qq.com/lab/view/404.html

1102
来自专栏张善友的专栏

系统性能优化一例

上周接到一位从事电子产品生产的大学同学的QQ说他的一个ERP系统有问题,帮他看看,周末他过来详细的了解了一下情况:周一到周五使用的用户数是10-20个人,系统慢...

1725
来自专栏phodal

后台优化:使用应用性能管理工具

在没有应用性能管理工具(APM,即application performance management )的时候,当我们需要对应用优化,我们就需要不断的调试、阅...

1998

扫码关注云+社区