VM socket(简称vsock)是一种虚拟套接字,用于在不同虚拟机或虚拟机和宿主机之间提供高性能、可靠的通信。vsock内核模块的设计原理如下:
总之,vsock内核模块通过VMCI提供高性能、低延迟的虚拟机间通信,为虚拟化环境提供了一个快速、可靠的通信机制
注册:
构造一个struct socket并初始化好socket的struct proto_ops,指定SOCK_DGRAM还是SOCK_STREAM类型操作:
SOCK_STREAM: Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported.
SOCK_DGRAM: Supports datagrams (connectionless, unreliable messages of a fixed maximum length).
此外,改过程还初始化了vsock_transport,改结构体是VM socket规定的方法接口,这些方法可以通过VMCI设备、virtio设备以及hyper-v实现。 Transport有4类交互情况:
VSOCK_TRANSPORT_F_H2G: Transport provides host->guest communication
VSOCK_TRANSPORT_F_G2H: Transport provides guest->host communication
VSOCK_TRANSPORT_F_DGRAM: Transport provides DGRAM communication
VSOCK_TRANSPORT_F_LOCAL: Transport provides local (loopback) communication
这四类情况对应不同的vsock_transport结构,以VMCI为例,它的初始化过程为:
初始化vmci_transport模块:注册vmci_vsock_transport_cb回调函数,该函数在guest或者host激活(active)时调用,该函数的实现为:
static void vmci_vsock_transport_cb(bool is_host)
{
int features;
if (is_host)
features = VSOCK_TRANSPORT_F_H2G;
else
features = VSOCK_TRANSPORT_F_G2H;
vsock_core_register(&vmci_transport, features);
}
vsock_core_register根据当前的Host/Guest的环境初始化相应的接口结构:
int vsock_core_register(const struct vsock_transport *t, int features)
{
const struct vsock_transport *t_h2g, *t_g2h, *t_dgram, *t_local;
...
if (features & VSOCK_TRANSPORT_F_H2G) {
if (t_h2g) {
err = -EBUSY;
goto err_busy;
}
t_h2g = t;
}
...
transport_h2g = t_h2g;
transport_g2h = t_g2h;
transport_dgram = t_dgram;
transport_local = t_local;
err_busy:
...
}
这样,在vsock_create初始化transport结构的时候,才能保证相应的结构体不为空。
VMCI(Virtual Machine Communication Interface)是一种VMware虚拟化平台的通信机制,它提供了一种高效可靠的通信方式,允许虚拟机之间、虚拟机与主机之间进行通信。 内核VMCI设备的框架提供了一种直接在内核空间中与VMCI设备进行交互的方法。它包含了以下几个主要组件:
总体来说,内核VMCI设备的框架提供了一种高效可靠的VMCI通信方式,使得虚拟机和主机之间的通信更加方便快捷。
TODO
在QEMU中,实现对设备的热插拔需要使用ACPI(Advanced Configuration and Power Interface,高级配置与电源管理)模块实现,虚拟化ACPI包含了内核的驱动部分和QEMU的设备模拟部分。而安全容器Kata-containers为了保持轻量级虚拟化,没有实现对ACPI设备的模拟。因此,为了依然能具备设备热插拔功能,Kata-containers开发了upcall技术用于实现VMM对虚拟机的设备热插拔通信,目前代码已经开源,kernel patch。upcall主要设计原理是:(1)将ACPI中与CPU、MMIO设备相关的部分抽出来(其实只有简洁的几个函数),并增加一个divice manager作为Guest内核的驱动设备热插拔部分;(2)封装vsock成upcall server用于Guest和Host交互,控制Guest内device manager驱动进行设备热插拔操作。
以下是整个过程: