D-Bus,kdbus和Binder
http://blog.sina.com.cn/s/blog_4af327e10101irie.html
(2014-02-01 16:35:59)
材料来自:The unveiling of kdbus 和 Kdbus Details 。后一篇文章里很多链接的内容也很有价值。
D-Bus的优缺点
Linux没有一个很好的IPC机制。Windows、Mac OS有;Android也有"binder"子系统。Linux有socket、FIFO、共享内存等机制,这些对于应用层来说不是很好。Kdbus试图为Linux创建一个和其它系统相仿的机制。
D-Bus是Linux上最接近这个标准的方案。优点:提供不错的事务处理机制(支持发送消息并等待回应)和给其它子系统发送信号;可以知晓D-Bus上还有哪些子系统在运作、提供哪些服务等。D-Bus还提供对安全策略的支持、在初次使用是启动服务、数据结构的类型安全组织、在总线上传递凭据和文件描述符。此外,很多编程语言有D-Bus的绑定接口,还有网络传输透明等。
缺限:D-Bus适合于控制任务,但并不适合传输大量的数据。例如,D-Bus能通知音频服务程序改变音量(D-Bus著名的例子,呵呵),却不适合传送音频数据。因为D-Bus在用户空间实现,效率很低:一个调用-返回消息需要10次消息拷贝,4次消息验证,4次上下文切换。此外,凭据传递能力有限,消息没有时间戳,boot时D-Bus不可用(此时D-Bus还没启动),和安全框架(如SELinux)的连接在用户空间,激活服务时可能有竞态条件等。D-Bus在实现上也过于复杂,且严重依赖于XML。
移入内核
kdbus是在内核里实现D-Bus。可传输大块数据,用于GB级的消息流。可以做到消息传递的零拷贝,在最坏情况下,一条消息及其回复过程不超过2次拷贝操作,2次验证,2次上下文切换。全部的凭据信息(用户ID,进程ID,SELinux标签,cgroup信息,权限等)随每个消息传递,而且所有消息都有时间戳。kdbus随时可用,不需要等待D-Bus守护进程启动,Linux安全模块可以直接与其挂钩,可避免竞态条件,API也得到简化。
kdbus在内核中作为一个字符设备;要连接的进程open设备,再调用mmap()将一个消息传递区域映射到自己的地址空间。消息在这个区域组装后交给内核传输;内核简单地将消息从一个进程映射的区域拷贝到另一个进程的区域。消息可以携带对收到回复的时间限制(“方法调用窗口”)。有一个和D-Bus类似的名字记录表。
kdbus通过memfd机制实现消息传递的零拷贝。memfd是一块带有文件描述符的内存区域,有点类似于内存映射的临时文件(差别其实很大)。一个memfd可以被“密封”——拥有它的进程不能再改变其内容。要传递一条消息,进程先在memfd区域构造消息,密封,然后交给kdbus传输。内核可以把相应的内存页面映射到接收进程的地址空间,从而避免拷贝数据,这取决于消息的大小。消息比较小时(大约512KB以下)内存映射的开销比较大,这时是直接拷贝数据。
信号广播机制采用Bloom过滤器来选择接受者。这一改动提高了广播机制的效率。
目前计划是在2014年把代码合并到内核的主干上。不过此前两次把D-Bus功能移入内核的努力失败了,这次也不能保证成功(看上去希望很大,Redhat已经在systemd里采用了kdbus)。
kdbus和binder的差别——CPU中心和RAM中心
binder在Android中提供从一个任务到另一个任务里的线程的同步调用(CPU)。这个过程中调用线程挂起直到应答线程返回,不需要消息队列。RAM只是用来在不同的调用者间共享数据。Android里binder库的关键是调用进程把自己的CPU时间片让给应答进程。这就像mutex系统调用。相互通信的进程之间有直接的联系。在系统里能同时使用binder的进程数有个上限,大部分系统估计在16个左右。
D-Bus是异步的,它把消息有序排入队列(RAM),接收者从队列里取消息。CPU的任务是在RAM里搬运数据。这类似于网络通信协议。属于进程间“无连接”的通信方式。其上限大约是每个连接8Mb,一个消息通常在200-800字节。
Binder是为微内核类设备创建的。功能有限,缺乏灵活性,但开销低、速度快。Binder保证CPU时间片从调用进程传给被调用进程的线程,工作完成后再返回给调用进程。其中几乎不需要进程调度,非常适合RAM和CPU配置很低的设备。
D-Bus是创建-存储-转发,构建回复,再创建-存储-转发的消息模型。比bind复杂得多,也更灵活、通用、网络透明、易于管理,且可以容易的管理不被信任的对端参加的通信(不要让binder面对这种情况,否则...)D-Bus可以处理大块的数据,在kdbus实现里可以将GB级别的数据传送给总线上的每个连接。从CPU的角度看,D-Bus没有biander有效率,但是通用性更好。
在D-Bus里可以实现类似binder的功能。D-Bus以后是否会替代binder现在还不好说。
================================================
kdbus已经被内核剔除主线了
https://www.phoronix.com/scan.php?page=news_item&px=Fedora-Drops-KDBUS
Written by Michael Larabel in Fedora on 30 October 2015 at 07:14 AM EDT. 57 Comments
In somewhat of an embarrassing move and indicating that KDBUS likely won't be proposed for Linux 4.4, this in-kernel IPC mechanism is being temporarily stripped out of Fedora.
Fedora developers added KDBUS to their Rawhide kernel this summer at the request of the systemd developers involved in KDBUS development. With systemd 221, the upstream developers also encouraged Linux distributions to begin shipping KDBUS even though it wasn't part of the mainline kernel. This turned out to be a mistake.
The developers requested KDBUS be removed from Fedora as they want to "rethink some of the approach they are taking with kdbus." Fedora kernel maintainer Josh Boyer noted this on their mailing list.
With now coming to the point of re-thinking some design decisions, it's good that it didn't land as originally planned for Linux 4.1 and it hasn't ended up being proposed since then. The Linux 4.4 merge window is expected to open next week, but given this latest communication, it seems highly unlikely KDBUS will be proposed for this next kernel cycle if they're going back to the drawing board. On the user-space side, KDBUS support has already been shipping with systemd for several stable releases.