(本文独家发布在金蝶云社区上)
CELLS 架构
CELLS的体系结构有两种模式,即用户模式和内核模式。 让我们来看看下面的主要架构图:
有一个名为CellD的命令行工具,由哥伦比亚大学开发,如图所示。此工具用于创建,管理,启动VP(虚拟电话)。 在任何时候,前台中只有一个VP,其他都在后台。因此,内核代码需要检查当前活动的VP,然后为此活动VP调度相关资源。现在,我将在下一节介绍这种隔离技术背后的一些原理。
基本原理
命名空间是Linux内核的一项功能,可隔离和虚拟化进程集合的系统资源。可虚拟化的资源包括进程ID,主机名,用户ID,网络访问,进程间通信和文件系统。命名空间是Linux上实现容器功能的基本方式。
CellD主要使用这种技术。 在Linux内核版本3.12之后,Linux支持6个命名空间:
UTS: 域名
IPC: 进程间通信
PID: “chroot” 进程树
NS: 挂载点
NET: 网络接口的访问
USER: 将虚拟的,本地的user id映射到真实的本地用户。
实现简单容器的源代码的逻辑非常简单。父进程使用相关的Namespaces参数调用clone系统函数,在调用之前,我们需要提供将由子进程调用的函数和堆栈内存,例如:
int child_pid = clone(child_main, child_stack+STACK_SIZE, CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);
在调用clone函数之后,将生成子进程,并且子进程将调用函数“childmain”。我们可以在新的命名空间下在这个函数中创建我们的虚拟世界,我们可以使用与其他命名空间中的其他进程相同的PID,我们可以创建虚拟的enthernet接口,我们可以挂载我们自己的文件系统,等等。 因此,CellD毫无疑问利用这个机会调用Android的init进程来创建新的虚拟电话。
在了解了原理之后,启动VP的过程如下:
CellD挂载VP文件系统,将自身克隆到具有单独命名空间的新进程中,并启动VP的init进程以启动用户空间环境。
CellD还设置了VP中可供进程访问的有限的IPC套接字集,用于与根名称空间进行通信。(这些IPC套接字是唯一可用于与根名称空间通信的套接字;所有其他IPC套接字都是内部的 到相应的VP。)
内核级别的设备虚拟化
CellD工具可以管理多个虚拟电话实例。 但是还需要在内核中完成更多的工作。
CELLS方案将设备命名空间添加到原始命名空间子系统。它被设计为由各个设备驱动程序或内核子系统用于标记数据结构和注册回调函数。当设备命名空间改变状态时,将调用回调函数。每个VP使用唯一的设备命名空间进行设备交互。CELLS利用其前台后台VP使用模型来注册回调函数,当VP在前台和后台状态之间切换时会调用注册的回调函数。这使设备能够了解各个VP状态,并根据VP是否对用户可见来改变对VP的响应方式。处在前台的VP是对用户可见的,而不可见的VP则可能是几个处在后台的VP之一。
Cells基于实现设备命名空间功能的三种方法来虚拟化现有内核接口:
第一种方法是使用新设备驱动程序为虚拟设备创建设备驱动程序的包装器。然后,包装器设备代表应用程序通过多路复用访问与真实设备驱动程序通信。 比如Android的 framebuffer复用就是使用这个方法。
第二种方法是修改设备子系统来支持设备名称空间。例如,Linux中的输入设备子系统管理各种设备,触摸屏,导航轮,指南针,GPS,距离传感器,光传感器,耳机输入控件和输入按钮。我们只需要修改输入子系统内的一些组件,所有输入设备都可以拥有多路复用到不同VP的能力。
第三种方法是修改设备驱动程序来支持设备名称空间。Android特有的实现进程间通信机制需要用这种方式修改 需要以这种方式修改称为binder的Android特殊IPC机制。除了binder之外,GPU驱动程序的多路复用就用这种方式。
用户模式的设备虚拟化
除了内核级设备命名空间机制之外,CELLS还引入了用户级设备命名空间代理机制,该机制为专有且完全闭源的设备(如基带处理器)提供类似功能。CELLS还使用此机制来虚拟化设备配置,例如在用户空间的Wi-Fi。
主要工作量
我认为我们有四类工作需要做:
第一类是我们可以完全使用CELLS源代码,这些代码与平台无关。我们可以简单地将这些提交从CELLS的repo合并到我们的repo。 这并不难。 这包括:
T可工作的CellD工具.
设备Namespaces机制
framebuffer 子系统
Input子系统
背光lcd子系统
Android logger驱动
Android binder驱动
Led子系统
Android alarm-dev驱动
workqueue对于namespace的支持
wakelock/earlysuspend 驱动
fbearlysuspend
第二个是关于我们自己的特有设备的一些驱动程序,包括GPU。这将是一项更加困难和耗时的工作。首先,我们需要了解整个架构和驱动程序的一些关键细节,然后应用设备命名空间机制来实现多路复用功能。
这个类别并不比第二个类别容易。正如我在上面的“用户级设备虚拟化”部分所述,由于其闭源的特性,WIFI和移动网络服务需要在CellD tool的用户模式下实现。不幸的是,相关的功能代码没有发布,我们只有论文来研究他们的想法,然后尝试实现。
最后一个是有关于产品化的工作。如果我们要将方案发布给终端用户,我们需要开发Android 用户界面来管理虚拟电话实例。
References
[1] The ConDroid official site. http://condroid.github.io.
[2] Introduction-to-linux-namespace blog.yadutaf.fr
[3] The Cells officail site http://systems.cs.columbia.edu/projects/cells/
[4] LXC - Official Site [https://linuxcontainers.org/](https://linuxcontainers.org/
[5] Wikipedia for Linux Namespaces https://en.wikipedia.org/wiki/Linux_namespaces