奥秘与Xorg:功能奇偶性和超越

2020-12-04 20:44:36

这是“ Arcan与Xorg:接近功能对等”文章的后续文章,如果您尚未阅读,建议阅读。

在那篇文章之后,只剩下一个(一半)真实特征可以安全地声明奇偶校验,并且可以很快覆盖。此后,我们可以ni咬Arcan而不是Xorg中的叮咬-范围差异的原因最好在不同的时间保存,尽管这是一个很好的选择。

首先,让我们不要忘记,对于用户而言,重要的质量矢量不仅仅是功能。客户端兼容性在优先级列表中一直处于较低的水平,但它是一项重要的素质。

原因是过早在工具包,游戏引擎或窗口库中增加了对新显示服务器后端之类的支持,而没有适当的必要和足够的功能,这将导致分散的实际功能集。将具有理论上的功能,然后某些客户实际上可能会使用某些版本或解释的功能。除非每个受影响的项目都特别提醒开发人员,并且参考实现在一致性验证和确认工具方面具有基本的卫生知识,否则这两组将越来越远。

当然,我们已经试验了这种实现,但这主要是为了测试设计和当前实现。找出烦人的API在哪里使用,从而使其他人免受痛苦。

降低兼容性的另一个原因是,客户端应用程序在“应该”如何工作方面存在很大的偏见,最严重的违规者只是“ GUI工具箱”。微小的更改可能会对应用程序设计产生重大影响,并且您不得不采用某种世界观,从而削弱了您的视野。作为一项琐碎的思维练习,在世界上虽然没有发明触摸输入,但是眼动追踪却完美无缺,但考虑一下像智能手机之类的东西。

如此再次强调Arcan项目的重点。不是,也从来没有,X曾经被发明过。原则性程序(针对多样化台式机未来的12项原则)说了很多。该项目的目的是展示大公司没有采取的其他道路,并暗示当遵循他们的逻辑结论时,这些道路会提供什么。

此处的大多数课程并非来自勤奋研究的惊人发现。相反,他们正在发现隐藏在旧街机机器电路中的智慧。这就是标题栏图像仍然是那个时代裁剪过的PCB的原因。

对Xorgcism进行足够的编辑!这又会又长又干。为此,请提前申请。 Quicknav链接如下:

主要缺少的功能是有关网络支持的。幸运的是,我不必再次讨论这一问题,有关该主题的文章已有两篇:一篇深入探讨Xorg的情况;一种涵盖我们的解决方案。如果还有什么需要强调的地方,那就是联网部分是一个完全独立的过程,可以重新解释联网的客户端数据。

造成这种情况的原因有三个-首先是最佳的本地渲染和最佳的远程渲染是不兼容的想法,这些想法在历史上足够相似,可以容忍差异。如今,我们希望两者兼而有之,这需要一种不同的体系结构,其中涉及的每个人都可以适应当前所需的两者之一。

第二是为了安全;客户端IPC是特权边界。网络访问是另一个特权边界。在这种情况下,在同一进程中混合多个特权边界实际上会将两者合并为一个,从而大大降低了安全性。即使您有一个单独的网络进程,它应该做的只是代理修补程序包,您获得的实际保护也很少。这是因为您的“网络进程”只是特权进程中通往真正解析器的另一路路由器或代理,并且通常唯一需要(写文件描述符)的原语很难或不可能被“沙盒”使用。

第三是恢复力。回忆一下我们先前为了获得碰撞复原力而经历的时间。自从链接文章以来,在该方向上还有很多工作要做,最后阶段之一是确保客户端状态可以适当地承受GPU丢失以及在情况允许的情况下避免机器丢失的风险。这些事情不能像事后的想法那样干净地工作-后果渗透到一切中。

剩下的另一个功能是寓言中的绘图API(我也将其视为字体管理),因为它位于中间位置。字体已在上一篇文章中作为“混合DPI”绘图部分的一部分进行了介绍。

事实是,Arcan从绘图API开始-最初用于指定交互式动画演示文稿,文档和一些ehrm,较暗的东西,其中只有阴影遮盖的酒吧中的啤酒和鸡尾酒可以短暂地带回表面。在某些演员无法“留下足够的孤独”之后,显示服务器的角度变成了弯路和必要的邪恶。

无论如何,“动画演示文稿”位引入了各种输入设备以及音频和视频。最好的时候,视频解析和解码是一个棘手的过程,而典型的库是明显的利用向量。这意味着显然需要以最小特权进行流程分离。这样,您将获得一个实时/媒体IPC系统,因此请进行清理,添加按钮,然后便有了基本的显示服务器。

附带说明一下:在消费者端拥有“绘图API”本身并不难,事实上,获胜的策略是成功的,本地栅格是一个遥远的后备。如果要通过OpenGL或Vulkan加速渲染,则最终将其发送到GPU的命令缓冲区(嘿,绘制命令!)实际上会将其转换为信号和/或像素-绘图不会在整个过程中进行“放置像素”的宽限期。您可以在wl_shm上添加一行以将非加速图形添加到Wayland中,从而将缓冲区格式定义为SVG,那不会很有趣😉

我要指责! –我听到你们佐拉达特胜利地宣布。 ‽现在不供客户使用。所以我要解释这个故事的两个方面。包含图表和代码以及所有内容的较长版本可以在AWK for Multimedia上的文章中找到。

关于绘图API的最大点是它提供的抽象级别。如果它处于“ putPixel()”的较低级别,则会丢失—帧缓冲区已死,帧缓冲区寿命长。如果是关于“制服,缓冲区,gpu程序和供应命令的绑定集”,那么您将获得高端图形库已经提供的东西。真正的挑战是找到正确的中级功能集,以提供更多的功能,而又不致使这些流行的“吸收所有人” UI工具包变得病态肥胖。了解JS / HTML5 / CSS /…汤如何,何时何地失败。

因此,目标是网络友好,紧凑,中级绘图++相关的API。可以在过程外使用,并且可以作为“中间语言”(例如LLVM-IR)用于更高级别的UI组件或文档解释器进行渲染,同时具有“ Web应用程序”预期的功能集就像目标。

“ ++”代表过程控制,音频和元IPC路由,这对于覆盖“台式机”的预期范围也是必不可少的。这些命令的处理转换为另一个中间层“ AGP”,它是OpenGL的简化子集,需要使用它作为解耦机制来最终切换到/提供Vulkan和软件光栅化。它的目标是达到大约DOOM3 / WebGL的质量(不是很好)的网络友好级别,但是此后视频压缩开始取得成功。

下图说明了运行Arcan来覆盖“绘图API”的所有组合的不同方式:

因此,尽管Arcan是一个单独的二进制文件(arcan_lwa –(轻量级应用程序),在图中标记为ArcanLW),但它可以成为其客户。

ArcanLW将“作为显示服务器”连接到Arcan,并像普通客户端一样工作。这里的附带好处是,如果您知道如何用一个应用程序编写应用程序,则可以在另一个应用程序中编写或修补窗口管理器。您将获得一个API来控制,操纵或检查整个台式机的所有路由。它的特权是按设计分开的,它已经稳定了多年。

这个难题的最后一部分是能够提供类似于RPC的对此API的访问。这就是Lua更重要的原因。

对于那些不知道的人,向Lua VM公开C API就像它变得一样简单,并且适合于其他低级调用约定。在VM名称空间中注册函数的符号名称和函数指针;根据所需的类型从堆栈中弹出参数;处理;将函数推回堆栈。

它可以比此更多地参与其中,但参与的范围不大。实际上,它是协议解码器的两倍,因此可以用作解耦机制。定义一个字节码,这里是您的\ out of process \制图/ WM API以绑定到其他语言。

尽管我们在上一篇文章以及关于该主题的上一篇文章中确实提到了崩溃恢复,但仍有很多事情要做。此后,已经做了足够的工作以保证再发表一篇文章。

知道某些GTK历史记录的人都知道,它实际上具有在X显示器之间跳转的未被充分利用的能力。 “未充分利用”的部分可能归因于人体工程学,即旋转和维护多个X服务器之间的过渡。礼貌地说,这不是为了胆小的人。

原则上讲,这是一个好主意,尽管在工具包级别上与在IPC级别上这样做并没有太大好处,而且事实证明,这要容易得多-无论工具包是否具有足够的远见和资源,该功能始终适用是否实施它。

在X中,如果窗口管理器崩溃—没什么大不了的,因为新的窗口管理者作为客户端可以重新连接并开始重建其世界观。在现实中,它相当简陋,当Xorg中的窗口管理器添加到场景图中时,窗口管理器的性质可能更为复杂。

要从中学习,我们回到Arcan中的资源分配:每个客户端都有一个主要段(window ++),然后动态地重新协商更多内容(默认为拒绝)。窗口管理器可以销毁所有辅助分配,并“重置”主要分配-迫使它尝试重新协商新资源。

这意味着您有一个保证的“窗口”,其余的可以来去去。这部分是为了允许使用更疯狂的窗口管理方案,而同时又不会丢失更简单的窗口管理方案。客户开发人员可以获得一组已知且有保证的可用功能,以用作基准,并添加或响应其他功能。

WM还可以访问键/值存储,以跟踪有关其客户的WM特定信息。客户端和WM都获得了GUID,用于将客户端修复为该信息,以便在预期的地方重新出现。它还具有将客户端动态重定向到其他显示服务器的功能,并在当前的显示服务器消失时通知备用服务器。

WM还获得了一个特定的事件入口点“采用”,该入口引用了来源不明的客户。这允许在WM之间进行受控切换,以便仅实时切换相关客户端,以及WM可以从自身错误中恢复的恢复机制。

错误的WM代码→Lua虚拟机错误处理程序→引擎重新加载WM(相同的WM或“后备”)→客户端收到“ RESET”事件→调用了WM“采用”入口点。

引擎崩溃→客户端IPC库检测到,连接循环(相同或新地址)→注入“ RESET”事件。

WM可以为一个或多个客户端“伪造”崩溃,从而使命令中的3可以触发。它还可以发送新地址供客户端连接。这为在本地和远程服务器之间动态迁移客户端打开了大门。下面的简短剪辑显示了从本地到远程的过程:

尽管所有这些工作原理的内部结构非常复杂,但是WM和客户端都很琐碎。

从XTEST,XRANDR和利用这些扩展的工具中可以吸取的教训是,无论您的需求工程做得如何好,人们都会不同意您的世界观,有时甚至会大声反对。为此,有些人仅需要“骇客”,即骇客行为和它带来的代理感觉具有不可被完全摒弃的价值。

是否可以在不将自己绘画到设计角落的情况下提供此类表达的出口?答案是“挂钩脚本”。要了解如何以及为什么,我们需要一些示意图。

这为拦截和操纵WM行为提供了两种可能的途径。在预阶段,在WM脚本本身有机会运行之前,可以拦截并修补WM看到的API。

另一个发生在初始化入口点之后但在实际事件循环开始之前。这使您可以拦截事件处理程序本身,也可以对其进行预钩和后钩。

结合使用这些功能后,您就可以在“仓库管理”视图的任何部分“猴子修补”,并解决“您不喜欢的东西”的问题。无论出于何种原因,它也可以用于注入Arcan本身不允许的功能。

每次添加挂钩脚本时,这将打开一个一次性连接点(extio_1)和其他连接点(_2,_3,…)。然后将您的外部输入驱动程序设置为连接到该名称,从而使“ myapp”将输入视为来自引擎本身。

这是Lua策略显示其力量的另一个方面-如果成千上万的初学者到中级开发人员设法为《魔兽世界》及其后的许多游戏做到这一点;任何能够像bourne shell脚本一样笨拙地处理事情的人,都应该能够轻松“抓痒”。

现在我们有了更多独特的东西。在大多数其他显示系统中,客户端执行以下操作的某些版本:

添加控制其位置和组成顺序的各个部分的功能,您就快完成了。

Arcan对客户有不同的看法。尽管客户端可以执行上述顺序,但是WM还可以告诉客户端具有新窗口-并知道客户端是否接受它。

在“利用显示服务器改善调试”一文中对此进行了详细介绍-请转到此处进行详细说明。简短的形式是,如果我们在窗口中添加更多抽象类型的概念,例如“调试”或“可访问性”等,则意味着要求客户“您能提供这样的视图吗”。

因此,不需要单独的“输入-访问-总线”或这种性质的复杂性-都是关于重新利用现有机制来形成新功能。

此类功能的显而易见的正常情况是“屏幕共享”-完全不需要客户端枚举资源和显示以实现共享和协作功能;它不需要知道如何制作香肠。

桌面的其余部分完全能够提供UI语言,以使用户烦恼此类细节,或自动映射并提供上下文相关的子集。共享客户是为了接受和服务,而不是进行定义和控制。

Arcan可以充当应用程序的启动器。这样,它知道应用程序是否死亡,并将对此做出响应。这样做是为了提高安全性,并能够提供游戏机,智能电话,机顶盒等通用的控制流。

此功能的大部分并非来自严格的想法,即充当“启动前端”,而是作为希望能够特权分离任何不可信内容的副作用。这实际上意味着产生新的有限流程,这些流程可以将结果发送回去,并控制其生命周期。

使用启动器路径,这意味着客户端不会作为外部源“连接”,而是在运行时继承其IPC连接。实际上,锁定“外部连接”路径只是一个“挂钩脚本”,它阻止了“ target_alloc(str)”功能。

它为我们提供的是客户身份和真实性。这是一个很难解决的问题,因为它是使用POSIX风格的用户空间为您提供的原语的事后思考,最终最终导致壮观的失败或弄乱了加密原语并巧妙地失败了。信任链断裂。

它还为我们提供了用于元数据配置的客户端唯一键值存储,以“记住”与客户端相关的某些窗口在崩溃,重新启动和重新启动后所做的操作。它还使我们可以通知我们的调度程序,资源分配等,以特殊方式对待这些客户,以使“拒绝服务”攻击之类的“叉子炸弹”更加困难。

与此不同的是“切换分配”。客户本身可能希望通过生成新过程(作为预期功能集的一部分)以及自身的特权分离/沙箱来重复该过程。另一种选择是“过早合成”,在这种方式下,客户端将成为自己的显示服务器,这是个坏主意。

下图说明了“启动器”路径和“移交”形式:

用户通过“ arcan_db”工具和图底部所示的“ add_target”命令定义“ MyWM”可以执行的允许目标集(二进制+参数+元数据)。

MyWM通过调用内建的launch_target函数来实现此目的,该函数设置资源并根据数据库中的“事物”运行“ mybin”来生成新进程。 mybin中的代码决定要一个新窗口来委派某些内容,例如嵌入特权分离的视频播放。它请求特殊切换类型的新窗口。

MyWM足够友好,并且通过与launch_target调用绑定的eventloop的一部分通过对accept_target的调用来接受,新的原语被分配并推送到mybin。 Mybin启动新程序“ somebin”,该程序继承并打开与Arcan的连接,就像“ mybin”一样。同时,mybin获得了一个抽象cookie,可用于在其自己的坐标系和场景图子图中定义和重新定位“ somebin”。 X风格的重排,但没有大多数混乱。

有关此功能的某些用法的更多详细信息,请参见以下文章:“另一个低级的Arcan应用程序:托盘图标处理程序”

关于客户端兼容性的一个(不是最大的赌注)是,在未来,我们确实需要改善虚拟机(包括“终端”,仿真器和“现代”浏览器的一类应用程序)如何与更高级的系统集成。

所有主要参与者都朝着这个不祥的方向发展,以“云化”这些虚拟机,然后将其保留在那里。

虚拟机类客户端的特殊需求之一就是状态控制-挂起,恢复,快照和还原。

自从一开始我们就将仿真器用作此类客户“需求”的参考模型,因此Arcan处于领先地位。从那时起,它们就一直被用于测试性能,吞吐量和延迟-仿真毕竟具有严格的实时要求。另一件事是,“状态控制”在编写良好的模拟器中是很自然的事情。

在Arcan API中,这可以归结为WM层中的琐碎命令-类似于:

实际上足以告诉一个客户端打包其状态并将其转发到client_b,并告诉客户端b从传入状态恢复-即使client_b已联网。

这也意味着可以将“共享”窗口功能与“替代表示”功能结合使用,以伪造新设备 ......