返回顶部
首页 > 资讯 > 精选 >匿名Inode的示例分析
  • 176
分享到

匿名Inode的示例分析

2023-06-15 13:06:46 176人浏览 安东尼
摘要

这篇文章将为大家详细讲解有关匿名Inode的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。01唯有文件得人心当一个女生让你替她抓100只萤火虫,她一定不是为了折磨你,而是因为她爱上了你。当你们之间

这篇文章将为大家详细讲解有关匿名Inode的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

匿名Inode的示例分析

01唯有文件得人心

当一个女生让你替她抓100只萤火虫,她一定不是为了折磨你,而是因为她爱上了你。当你们之间经历了无数的恩恩怨怨和彼此伤害,她再次让你替她抓100只萤火虫,那一定是因为她还爱着你。

为什么?因为这就是套路,是在下偶尔瞟一眼古装肥皂剧总结出来的套路。

linux里面最大的套路,就是“一切都是文件”。爱一个人,就为她捉萤火虫;做一件事,就让它成为一个“文件”。

为什么自古深情留不住,唯有“文件”得人心呢?因为文件在用户态最直观的形式是随着一次open,获得一个fd,有了这个fd,长城内外,你基本可以为所欲为:

  • 在本进程内,fd的最直观操作是open、close、mmap、ioctl、poll这些。mmap让你具备把fd透射到内存的能力,所以你可以通过指针访问文件的内容。再者,这个mmap,如果底层透射的是framebuffer、V4L2、DRM等,则让我们具备了从用户态操作底层显存、多媒体数据等的能力;比如,无论是V4L2还是DRM,都支持把底层的dma_buf导出为fd。poll则提供给用户阻塞等待某事件发生的能力。至于ioctl,就更加不用说了,你可以透过ioctl灵活地为fd添加控制命令。

  • 在跨进程的情况下,Linux支持fd的跨进程Socket传输,从而可以实现共享内存、dma_buf跨进程共享等。比如一个进程可以通过send_fd可以把fd发送出去:

匿名Inode的示例分析

而另外一个进程可以通过recv_fd把fd收过来:

匿名Inode的示例分析

这种fd在长城内外可以互访,fd最终可以指向dma_buf同时可以被mmap,而dma_buf又最终可以被显卡、显示控制器、video  decoder/encoder等设备访问的能力,让fd打通了设备、CPU和跨进程的障碍,从此可以横着走。

匿名Inode的示例分析

02inode源头file活水

我们把文件想象成一个object,那么inode描述的是本源,和最终的object一一对应;dentry是inode的一个路径马甲,比如我们可以通过"ln"命令为同一个inode创建很多的硬链接马甲;而file则是活水,进程对object的一次“open”,获得一个file,导致用户态得到一个"fd"的句柄来操作这个object。

经典的inode、dentry、file谁都不缺席的模型是这样的:

匿名Inode的示例分析

上图中,我们有一个inode,这个inode有2个dentry,进程A、B open的是第一个dentry;而进程C、D  open的是第二个dentry。变了的是file和fd,不变的是inode,中间的dentry马甲没那么重要。

但是在inode、dentry、file这个经典铁三角中,从来都是可以有一个缺席者的,那就是dentry,因为,有时候用户态想获得长城内外行走的便利,但是却不想这个inode在文件系统里面留下一个路径的痕迹。简单来说,我希望有个fd,但是这个fd,你在从"/"往下面搜索的任何一条路径下,你都找不到它,它根本在根文件系统以下不存在路径,它是无名氏,它没有马甲,它是个传说。

比如,近期名震江湖的剑客usefaultfd允许我们在用户空间处理page  fault,我们是通过userfaultfd这个系统调用先获得一个fd,之后就可以对它进行各种ioctl了:

匿名Inode的示例分析

我们透过userfaultfd系统获得了一个fd,它在/xxx/yyy/zzz这样的文件系统下没有路径。这种情况下的fd,对应着的是一个没有名字的匿名inode,你显然没有办法像fd  = open ("xxx", ..)那样来得到匿名inode的fd,因为"xxx"是一个路径,而匿名inode没有xxx,所以你是直接透过syscall  userfaultfd这样的系统调用,来获得anon_inode在你的进程里面对应的fd的:

匿名Inode的示例分析

人过留名,雁过留声;杀人者,打虎武松也。但是anon  inode不吃这一套,它是一个绝顶的轻功高手,它给与的,是透过fd长城内外行走的能力,但是,在文件系统里面却从未来过。这是用户真实的需求,如果这种需求一定要透过一个dentry的open才能实现,这未免有点画蛇添足了。

03匿名inode的内核实例

我们接下来可以随便打开个anon inode的实例来看看它是怎么工作的了。首先userfaultd是一个系统调用:

匿名Inode的示例分析

这个代码里面比较核心的是就是,它通过:

anon_inode_getfd_secure()

生成一个匿名inode,并获得一个句柄fd。重点别忘记了,这种“文件”也是可以有file_operations的,比如上面anon_inode_getfd_secure()参数中的userfaultfd_fops:

匿名Inode的示例分析

这样,我们就可以在file_operations的ioctl,poll,read等callback里面实现自己特别的“文件”逻辑,这是我们自由发挥的舞台。

说起anon_inode_getfd_secure(),它再往底层走一级是__anon_inode_getfd():

匿名Inode的示例分析

进而再走一级是__anon_inode_getfile():

匿名Inode的示例分析

所以本质上,是先造一个anon_inode,然后再在这个anon_inode上面造一个pseudo的file,最后通过fd_install(fd,  file),把fd和file缠在一起。再次强调,用户有了这个fd就可以为所欲为;而内核本身,则是通过file_operations的不同实现来为所欲为的。

anon_inode之上添加一个系统调用,造一种特殊的fd,让用户去poll,去ioctl,把想象空间拉大了。这种实现方法,如此拉风灵活,以至于它本身也成为了一种套路。比如内核里面fs目录下的:

匿名Inode的示例分析

eventfd,eventpoll,fscontext,io_uring,fanotify,inotify,signalfd,timerfd.......

正所谓, 待到秋来九月八,我花开后百花杀。冲天香阵透长安,满城尽带黄金甲。文件,哪怕最终是匿名的,都以冲天的香阵,弥漫整个Linux的世界。

04用户使用匿名inode

到了要说再见的时刻了,用户可见的就是fd,通过fd来使用匿名inode。下面我们来制造一个page  fault的例子,让用户态来处理它,这个例子直接简化自userfaultfd的man  page。我们在主线程中,通过mmap申请一页内存,然后通过userfaultfd的ioctl告诉内核这页的开始地址和长度,以及通过UFFDIO_REGISTER告诉内核这页的page  fault想用户空间处理:

匿名Inode的示例分析

然后我们在pthread_create()创建的fault_handler_thread线程中,poll  userfaultfd等待事件,之后把一页全是0x66的内容拷贝到page fault发生的那一页:

匿名Inode的示例分析

我们运行这个程序得到的输出如下:

匿名Inode的示例分析

我们主线程在执行addr[0]=0x5A5A5A5A的时候,触发了page fault。在fault线程里面,page  fault发生后,poll阻塞返回,之后用户通过read()读到了一个uffd_msg的结构体,里面的成员包含了page  fault的地址。之后,我们通过UFFDIO_COPY这个ioctl,把内容为0x66的页面拷贝给page fault的页面。

所以,最终主线程在执行printf打印的时候,addr[0]里面读到了5A5A5A5A,剩下的addr[1]里面读到了66666666。看到page  fault由用户态灵活这么灵活自如地处理,我的小伙伴们都吓尿了。

可以看出来:

  • poll()在等什么,完全被定制化了;

  • read()能读什么,完全被定制化了;

  • ioctl()能控制什么,完全被定制化了。

我们通过“文件”这个不变的“静”,制造了poll、read、ioctl的灵动自如。

关于“匿名Inode的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

--结束END--

本文标题: 匿名Inode的示例分析

本文链接: https://www.lsjlt.com/news/280494.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 匿名Inode的示例分析
    这篇文章将为大家详细讲解有关匿名Inode的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。01唯有文件得人心当一个女生让你替她抓100只萤火虫,她一定不是为了折磨你,而是因为她爱上了你。当你们之间...
    99+
    2023-06-15
  • javascript之匿名函数和闭包的示例分析
    小编给大家分享一下javascript之匿名函数和闭包的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体内容如下匿名函数<script type="te...
    99+
    2024-04-02
  • scala匿名函数案例分析
    今天小编给大家分享一下scala匿名函数案例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1.匿名函数含义@1.说明没有...
    99+
    2023-07-05
  • sql之Oracle中匿名TABLE/VARRAY类型的示例分析
    这篇文章将为大家详细讲解有关sql之Oracle中匿名TABLE/VARRAY类型的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言关于sql Oracle匿名...
    99+
    2024-04-02
  • js匿名函数使用&传参的示例分析
    这篇文章将为大家详细讲解有关js匿名函数使用&传参的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。如下所示:function () {...
    99+
    2024-04-02
  • Java面向对象之匿名内部类的示例分析
    小编给大家分享一下Java面向对象之匿名内部类的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!public class TestMot...
    99+
    2023-06-02
  • Java面向对象中匿名内部类额示例分析
    这篇文章主要介绍Java面向对象中匿名内部类额示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!public class TestMoto {public static&n...
    99+
    2023-06-02
  • Linux Bash别名的示例分析
    这篇文章主要介绍了Linux Bash别名的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。有多少次您在命令行上多次输入一个长命令,并希望有一种方法将其保存到以后?这就...
    99+
    2023-06-27
  • Android匿名内存深入分析
    目录Android 匿名内存解析MemoryFile使用Service端Client端AshMemory 创建原理AshMemory 读写Linux共享机制简介总结Android 匿...
    99+
    2023-03-15
    Android 匿名内存 Android 内存
  • css命名规则的示例分析
    这篇文章主要为大家展示了“css命名规则的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“css命名规则的示例分析”这篇文章吧。头:header   内容...
    99+
    2024-04-02
  • html布局命名的示例分析
    小编给大家分享一下html布局命名的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! 头:header 模式:cont...
    99+
    2024-04-02
  • namesapce命名空间的示例分析
    这篇文章主要介绍了namesapce命名空间的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.命名空间的使用目的   在PHP中函数、类、常量是不允许同名...
    99+
    2023-06-06
  • Flex命名空间的示例分析
    这篇文章主要介绍了Flex命名空间的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Flex命名空间详解通过命名空间可以控制所创建的属性和方法的可见性。请将public...
    99+
    2023-06-17
  • VB.NET名字空间的示例分析
    小编给大家分享一下VB.NET名字空间的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!VB.NET名字空间在编写.NET软件时,我们会用到类和其他类型。为...
    99+
    2023-06-17
  • golang匿名函数和闭包的代码示例与最佳范例解析
    匿名函数:匿名函数是没有名称的函数,用于创建一次性函数或回调。闭包:闭包包含匿名函数和外部变量引用,可以访问和修改外部变量。 Go 语言中的匿名函数和闭包 什么是匿名函数? 匿名函数是...
    99+
    2024-05-05
    golang 闭包 匿名函数
  • vue.js过渡css类名的示例分析
    这篇文章主要为大家展示了“vue.js过渡css类名的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue.js过渡css类名的示例分析”这篇文章吧。首...
    99+
    2024-04-02
  • vue中命名视图的示例分析
    这篇文章给大家分享的是有关vue中命名视图的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在views 创建 UserProfile.vue UserProfilePre...
    99+
    2024-04-02
  • C++中名称空间的示例分析
    小编给大家分享一下C++中名称空间的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1.名称空间在C++当中,名称可以是变量、函数、结构体、枚举、类以及结构体和类的成员。这本身并没有问题,但随着项目的增大,名称之间相...
    99+
    2023-06-22
  • Vue中匿名插槽与作用域插槽合并和覆盖行为的示例分析
    小编给大家分享一下Vue中匿名插槽与作用域插槽合并和覆盖行为的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Vue 测试...
    99+
    2024-04-02
  • vue组件命名和props命名的示例分析
    这篇文章主要为大家展示了“vue组件命名和props命名的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue组件命名和props命名的示例分析”这篇文...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作