时钟虚拟化

作者:Zack Brown

Dmitry Safonov 希望为时间信息实现命名空间。关于虚拟机,一件既曲折又奇异的事情是,它们一直在变得更加虚拟化。总是有一些新的宿主系统元素可以被赋予自己的命名空间,并进入虚拟机的领域。但是,随着这个过程向前推进,虚拟系统必须与其他虚拟系统和宿主系统本身共享自身的某些方面——例如,日期和时间。

Dmitry 的想法是,用户应该能够在他们的虚拟系统上设置日期和时间,而不用担心其他系统被赋予相同的日期和时间。这实际上是有用的,超越了生活在过去或未来的愿望。正如 Dmitry 在他的帖子中指出的那样,能够在一个容器中设置时间显然是将容器从一个物理主机迁移到另一个物理主机的关键要素之一。

正如他所说

内核提供了对几个时钟的访问:CLOCK_REALTIME、CLOCK_MONOTONIC、CLOCK_BOOTTIME。后两个时钟是单调的,但它们的起始点未定义,并且对于每个运行的系统都不同。当容器从一个节点迁移到另一个节点时,所有时钟都必须恢复到一致的状态;换句话说,它们必须从它们被转储的同一点继续运行。

Dmitry 的补丁并非功能完整。还有各种问题需要考虑。例如,虚拟机应该如何解释宿主硬件上的时间变化?虚拟时间应该改变相同的偏移量吗?还是保持不变?文件创建和修改时间应该反映虚拟机的时间还是宿主机的时间?

Eric W. Biederman 总体上支持这个项目,并且喜欢补丁中的代码,但他确实认为这个补丁可以做得更多。他认为它有点太轻量级了。他希望用户能够在瞬间建立新的时间命名空间,以便他们可以在实际发生之前测试像闰秒这样的事情,并了解他们自己的项目代码在这些不同条件下是如何工作的。

为了做到这一点,他认为每个命名空间都应该有一个完整的“struct timekeeper”数据结构。然后,指向这些结构的指针可以被传递,虚拟机的时间将像宿主系统上的时间一样可操作和有用。

然而,在文件系统的文件时间戳方面,Eric 认为最好稍微限制一下功能集。如果用户可以创建时间戳在过去的文件,可能会引入一些糟糕的安全问题。他认为简单地“做分布式文件系统在处理具有不同时钟的主机时所做的事情”就足够了。

两人就技术实现细节来回讨论。在某一点上,Eric 在为他的偏好辩护时评论道

我对命名空间的经验是,如果我们不让高级功能工作,代码的核心开发人员就几乎没有兴趣,而且命名空间也无法解决其他问题。这使得命名空间很难推销。特别是当它没有解决子系统开发人员的问题时。

在某个时候,Thomas Gleixner 加入对话,提醒 Eric 时间代码需要保持快速。他说,虚拟化是好的,但是“timekeeping_update() 已经很重了,遍历大量的命名空间只会让它变得可怕。”

他提醒 Eric 和 Dmitry

这不仅是时间保持,即读取时间,这也影响到从命名空间武装起来的所有定时器。

这变得非常糟糕,因为当您为特定的命名空间执行 settimeofday() 或 adjtimex() 时,您必须搜索该命名空间的所有武装定时器并调整它们。

最初的 posix 定时器代码也有同样的问题,因为它将实时时钟定时器映射到定时器轮,因此任何时钟设置都会导致对所有武装定时器的完全遍历,解除武装,调整和重新排队它们。这不仅在性能方面是可怕的,而且是各种各样的锁定噩梦。

将通过 NTP/PTP 的时间偏差添加到图中,您可能也需要调整定时器,因为您需要保证它们不会过早过期。

因此,显然有很多细微之处需要考虑。讨论在那里结束了,但这很好地说明了扩展 Linux 以创建虚拟机的问题。几乎从来没有一个功能可以完全虚拟化并与宿主系统隔离。安全问题、速度问题,甚至代码复杂性和可维护性都随之而来。即使是非常优雅的解决方案也可能被例如恶意用户创建具有异常旧时间戳的文件的可能性所击倒。

注意:如果您在上面被提及并希望在评论区上方发布回复,请将包含您的回复文本的消息发送至 ljeditor@linuxjournal.com。

Zack Brown 是 Linux JournalLinux Magazine 的技术记者,并且曾是每周通讯 "Kernel Traffic" 和 "Learn Plover" 速记打字教程的作者。他于 1993 年在他的 386 电脑上安装了 Slackware Linux,配备了 8MB 内存,并被开源社区彻底震撼。他是纯策略棋盘游戏 Crumble 的发明者,您可以用几块纸板自己制作。他还喜欢写小说、尝试动画、改革拉班舞谱、设计和缝制自己的衣服、学习法语以及与朋友和家人共度时光。

加载Disqus评论