Windows Linux子系统:失去的潜力

2020-11-21 12:06:41

如果您在过去几年中完全遵循Windows 10,您就会知道Linux的Windows子系统(简称WSL)是开发人员中的热门话题。您最终可以在Windows上以一流的公民身份运行Linux工具,这意味着您不再需要学习PowerShell或天生就不能通过古老的CMD.EXE控制台受苦。

不幸的是,并非所有事情都像听起来那样乐观。我现在必须在Windows for Windows上进行开发,这是我在Azure中担任新角色的一部分……而WSL仍与本机Windows环境继续保持独立这一事实表明。即使我满怀希望,我也不能将WSL用作日常驱动程序,因为我需要与“本地” Windows工具进行交互。

我相信事情并不一定要这样,但是随着最近对WSL 2的推动,我认为替代世界的潜力已经消失了。但是,这是什么意思呢?为此,我们必须首先了解WSL 1和WSL 2之间的区别以及对WSL 2的推动如何关闭一些有趣的路径。

免责声明:我对WSL团队内部的情况或他们的未来计划没有任何见解。这纯粹是基于我作为用户所经历的个人观点。

首先让我们看一下WSL 1,为此,我们必须看一下尴尬名称中的含义。为什么将此功能命名为Windows子系统…for Linux?那不是倒退吗?这不是Linux中的子系统,它不能执行与Windows相关的任何事情;反过来!

好吧……您会发现,在考虑Windows NT内核的设计时,该名称在技术上是正确的。从Wikipedia的Windows NT体系结构页面中,我们发现(重点是我):

Windows NT中的用户模式由子系统组成,这些子系统能够使用I / O管理器将I / O请求传递到适当的内核模式设备驱动程序。 Windows NT的用户模式层由运行用于许多不同类型操作系统的应用程序的“环境子系统”和代表环境子系统运行系统特定功能的“集成子系统”组成。内核模式使用户模式服务和应用程序无法访问它们不应访问的操作系统的关键区域。

Windows NT是从头设计的,旨在支持多种操作系统中正在运行的进程,而Win32“只是”这些环境子系统之一。在这些坚实的基础上,WSL 1提供了一个新的环境子系统Linux子系统,以在Windows NT内核之上运行Linux二进制文件。 Win32和Linux环境子系统都共享公共的集成子系统。

这就是不同的系统调用“前端”。用户空间进程是处理器不间断执行(保留中断的地方)的二进制指令的集合。直到进程发出系统调用之前,操作系统的内核才知道进程在做什么:此时,内核重新获得控制权以代表用户执行操作,这可能类似于读取文件或暂停操作。几秒钟。

进程发出系统调用的方式以及这些系统调用的语义特定于操作系统。例如,在旧的x86上:在Win32上打开文件是通过INT 2Eh调用的系统调用号17h,而在Linux上打开文件是通过INT 80h调用的系统调用号5h。

但是...从概念上讲,打开文件就是打开文件,对吗?它们之间系统调用号或软件中断号不同的事实并不是特别有趣。这就是WSL 1的关键设计方面:简单地说,NT内核中的Linux子系统是在NT内核前面的Linux系统调用层的实现。这些系统调用以后将委托给NT原语,而不是Win32调用。重复这一点很重要:没有从Linux到Win32系统调用的转换。

考虑到在WSL 1下一般如何对Linux应用程序提供良好的支持以及NT在内部与Unix之间有很多不同,在很多方面,这是一项工程技术壮举,其中fork + exec是永恒的敌人。

该设计的真正优点在于,机器上运行的是单个内核,并且该内核具有其下所有进程的整体视图。内核了解有关Win32和Linux进程的所有信息。这些进程都与统一资源进行交互,例如单个网络堆栈,单个内存管理器和单个进程调度程序。

本质上,WSL 1必须“逐位”实现Linux的所有内核ABI。如果该接口中存在错误,则WSL 1必须对其进行复制。而且,如果某个功能很难在NT内核中表示,则该功能将无法实现,或者需要额外的内核逻辑(因此会变慢)。

WSL 1中的Linux子系统必须遵守NT内核与传统Unix设计之间存在的任何“限制”和固有差异。最明显的一个是NTFS文件系统及其语义,以及这些差异如何损害Linux二进制文件的性能。文件系统性能差似乎是WSL 1中的常见抱怨。

WSL 2“丢弃”了该名称的所有Linux子系统部分,并用功能完善(但功能齐全且快速运行)的虚拟机替换了所有内容。然后,虚拟机将在其中运行适当的Linux内核,适当的Linux文件系统和适当的Linux网络堆栈。

这意味着WSL 1设计的美已消失:Windows NT内核不再能看到Linux世界中发生的任何事情。它所知道的是,内部有一个大的黑匣子在其中进行“填充”,并且看到的只是虚拟机的VMENTER和VMEXIT挂钩点以及虚拟磁盘上的块级读/写请求。 NT内核现在不知道Linux进程和文件访问。同样,Linux内核不了解NT领域中的任何内容。

从用户的角度来看,WSL 2感觉更好:Linux应用程序现在运行得快得多,因为它们不受NT内核中笨拙的Linux系统调用的“模拟”。如果很难将NTFS与Linux语义结合使用,那没有问题,因为Linux环境现在在虚拟磁盘上使用ext4。而且对Linux应用程序的支持可以更加完善,因为WSL 2是Linux:如果您想用FUSE命名,就可以了。

您能想象如果您可以在WSL会话中键入ps或top并看到Linux和Windows进程并排运行,并能够通过kill改变它们的状态时,会有多酷?

您能想象从WSL会话操纵Windows服务会有多酷吗?

您能想象如果您可以在WSL会话中使用ifconfig(等待,是ip吗?)来检查和修改计算机的网络接口,会有多酷?

本质上,您是否可以想象在WSL中执行所有Windows系统管理任务?

尽管这从未存在过,但我可以想象得到这样一个世界……而这是只有WSL 1设计才能提供的世界。我可以想象的原因是macOS提供了这种模型(尽管作弊是因为macOS本质上是Unix)。

这就是让我感到沮丧的原因:即使我可以在用于Azure的开发计算机上安装WSL,也无法使用它。我仍然必须通过CMD.EXE与系统进行交互,因为我必须处理Windows本地进程和资源,并且因为我必须处理的工具仅适用于Windows。

WSL 2的FAQ声称不会放弃WSL 1,如果我们遵守Microsoft的向后兼容性保证,那可能是正确的。但是由于需要跟上Linux的变化,保持WSL 1的运行是一项艰巨的工作。无论如何,我希望情况确实如此,WSL 1继续存在。谁知道,也许WSL 1落后的原因是追求我所描述的这个神奇的世界? 🤔

我不能不谈各种BSD而结束这篇文章。一直落后于Linux和其他商业操作系统的BSD已有二进制级别的兼容性。我最早能找到的是1995年NetBSD内核中的Linux兼容性。那是25年前,而WSL 1首次亮相之前有21年。

而且,这不仅限于Linux。多年来,NetBSD一直支持模拟各种不同的操作系统。对SVR4的支持始于1994年,并且暂时来说,NetBSD甚至还支持……PE / COFF二进制文件—正确的是Win32二进制文件。因此,在某种程度上,NetBSD反向实现了WSL 1模型:它使您可以在2002年在NetBSD内核之上运行Win32二进制文件。