acm-header
登录

ACM通信

Kode恶性

出现内核


爆玉米粒,插图照片

信贷:艾拉图片

回到顶部

亲爱的KV,

我在同一家公司工作了十多年,我们制造的是你可以想象成一个设备的东西——基本上是一个功能强大的服务器,用来做单一的工作,而不是作为一个通用系统运行。当我们第一次开始构建这个系统时,我们实现的几乎所有功能都作为扩展和内核模块添加到操作系统内核中。我们是一个小的团队和有能力的C程序员,我们觉得这样构建系统可以让我们对系统有更多的控制,而且由于我们不需要在内核和用户空间之间复制内存来完成工作,所以我们的性能得到了显著的提高。

随着系统的扩展和更多的开发人员加入到项目中,管理人员开始询问为什么我们要在这样一个难以编程的环境中使用过时的语言来构建软件。人力资源部抱怨说,他们找不到足够的、合格的工程师来满足管理层的需求,需要更多的人手来制作更多的功能。最终,我们决定将许多函数移出内核,放到用户空间中。这导致了一个分裂的系统,几乎所有东西都必须通过内核才能到达系统的任何其他部分,这导致了较低的性能和大量的系统错误。我必须承认,如果这些错误发生在内核中,将导致系统崩溃并重新启动,但即使在用户空间中,它们也会导致函数重新启动、失去状态并导致服务中断。

对于我们的下一个产品,管理层希望将几乎所有的功能都转移到用户空间中,他们相信通过拥有一个更安全的编程环境,团队可以更快地创建更多功能,出错更少。您不时地写过关于内核编程的文章:您是否也认为内核不适合“凡人”,大多数程序员应该坚持在更安全的用户空间环境中工作?

安全第一

亲爱的安全,

因果报应的车轮不停地转啊转,不放过任何人,包括程序员、内核、用户空间等等。

在用户空间中编程更安全的原因非常少,其中最重要的原因是虚拟内存系统,它欺骗程序相信它们对系统内存有完全的控制,并捕获少量常见的c语言编程错误,例如碰触程序无权碰触的一块内存。其他原因包括操作系统在过去30年里为程序提供的可靠的编程api。所有这一切都意味着程序员可以在他们的代码发布之前捕获更多的错误,这是一个很好的新闻,但也是一个好消息。用户空间中的构建代码不能解决隔离、组合和效率等老问题。

如果您试图构建的是一个接受某些输入并将其转换为另一种形式的单一程序,请考虑sed、diff和awk等常用工具,然后,是的,这些程序非常适合用户空间。您所描述的系统可能与外部世界有更多的交互,而不是与典型的终端用户。

一旦我们进入用于处理数据的高吞吐量和/或低延迟系统的世界,如路由器、高端存储设备,甚至是物联网中当前的一些设备(参见我2017年10月的专栏物联网:恐怖互联网;10.1145/3132728),那么您的系统有一个完全不同的约束集,并且大多数程序员没有被教过如何为这种环境编写代码;相反,他们通过非常痛苦的经历来学习。当然,试图向人力资源部或管理层解释这一点,就像用头敲桌子一样——只有当你停下来的时候才会感觉良好。

您说您在这方面已经有一段时间了,所以您肯定已经看到,在内核中难以正确执行的事情在用户空间中几乎同样难以正确执行,而且很少有同样好的性能。如果必须将您的问题分解为一组协作的进程,那么在用户空间中进行编程与在内核中进行编程完全相同,只是要为您使用的任何混合进程间通信形式付出更多的开销。我个人最喜欢的这种愚蠢形式是程序员在用户空间中构建系统,使用共享内存,然后再现内核编程中看到的锁定问题的所有可能扭曲。协调就是协调,无论您是在内核中、在用户空间中还是在鸽子传递消息中进行协调,尽管前两个地方需要清理的粪便较少。


这些系统的紧张关系都是在性能和隔离之间。


这些系统的紧张关系都是在性能和隔离之间。虚拟内存为我们提供了用户/内核空间分割和编程的进程模型,程序之间相互保护,这只是最普遍的隔离形式。如果程序员真的相互信任,那么他们就会把所有的代码混合到一个可执行文件中,在这个文件中,每一段代码都可以接触到每一段内存,但我们知道这是如何进行的。它非常。该怎么办呢?

在过去的几年里,有一些技术创新可能有助于解决这个问题,包括新的系统编程语言,如Rust和Go,它们具有更多的内置安全性,但它们还没有在操作系统等系统环境中证明自己的价值。目前还没有人用Go或Rust编写的东西来取代类似unix的操作系统。新的计算机体系结构,如在CHERI项目中进行的能力工作,由SRI国际和剑桥大学开发,也可能使分解软件的安全性和保留整个系统的高水平的性能成为可能,但再次强调,这还需要在技术的实际部署中得到证明。

目前,我们被用户空间的错误安全性所困,我们认为当程序崩溃时整个系统不会重新启动是一件幸事,我们知道在操作系统内核的广阔的、单一的地址空间中编程是多么困难。

在一个高性能代码继续用花哨的汇编程序(也就是C)编写的世界里,没有内存安全性和大量其他风险,唯一的办法就是坚持软件工程的基础知识。减少有害的代码数量(也称为攻击面),保持子系统之间的耦合高效和显式,并致力于为工作提供更好的工具,如静态代码检查器和大型运行时测试套件。

或者,您知道,只是将所有精心编写的内核代码扔到用户空间中,并希望得到最好的结果。因为,我们都知道,希望绝对是编程的最佳实践。

KV

ACM队列的q戳相关文章
queue.acm.org

一段不错的代码
乔治诉Neville-Neil丰富多彩的隐喻和正确地重用函数
https://queue.acm.org/detail.cfm?id=2246038

虚拟化的成本
乌尔里希Drepper软件开发人员需要意识到他们在使用虚拟化技术时所面临的妥协。
https://queue.acm.org/detail.cfm?id=1348591

unikernel:虚拟图书馆操作系统的兴起
Anil Madhavapeddy和David J. Scott如果虚拟设备中的所有软件层都是在同一个安全的高级语言框架中编译的呢?
https://queue.acm.org/detail.cfm?id=2566628

回到顶部

作者

乔治诉Neville-Neilkv@acm.org)是Neville-Neil Consulting的东主及ACM的联席主席队列编辑委员会。他从事网络和操作系统代码方面的工作,教授各种与编程相关的课程,并鼓励您的评论、俏皮话和与他相关的代码片段通信列。


版权归作者所有。
向所有者/作者请求(重新)发布权限

数字图书馆是由计算机协会出版的。版权所有©2018 ACM, Inc.


没有发现记录

登录为完全访问
»忘记密码? »创建ACM Web帐号
文章内容:
Baidu
map