VSOCK - Linux手册页

Linux程序员手册 第7部分
更新日期: 2020-02-09

说明

VSOCK地址系列可促进虚拟机与运行它们的主机之间的通信。该地址系列供需要独立于虚拟机网络配置的通信通道的来宾代理和管理程序服务使用。

有效的套接字类型为SOCK_STREAM和SOCK_DGRAM。 SOCK_STREAM为面向连接的字节流提供有保证的有序交付。 SOCK_DGRAM提供具有尽力而为传送和尽力而为排序的无连接数据报包服务。这些套接字类型的可用性取决于基础虚拟机管理程序。

创建一个新的套接字

socket(AF_VSOCK, socket_type, 0);

当进程想要建立连接时,它将使用给定的目标套接字地址调用connect(2)。如果未绑定,套接字将自动绑定到空闲端口。

进程可以通过先使用bind(2)绑定到套接字地址,然后调用listen(2)来侦听传入的连接。

使用send(2)或write(2)系列系统调用来传输数据,并使用recv(2)或read(2)系列系统调用来接收数据。

Address format

套接字地址定义为32位上下文标识符(CID)和32位端口号的组合。 CID标识源或目标,它可以是虚拟机或主机。端口号区分在一台计算机上运行的多个服务。

struct sockaddr_vm {
    sa_family_t    svm_family;     /* Address family: AF_VSOCK */
    unsigned short svm_reserved1;
    unsigned int   svm_port;       /* Port # in host byte order */
    unsigned int   svm_cid;        /* Address in host byte order */
    unsigned char  svm_zero[sizeof(struct sockaddr) -
                            sizeof(sa_family_t) -
                            sizeof(unsigned short) -
                            sizeof(unsigned int) -
                            sizeof(unsigned int)];
};

svm_family始终设置为AF_VSOCK。 svm_reserved1始终设置为0。svm_port包含主机字节顺序的端口号。低于1024的端口号称为特权端口。只有具有CAP_NET_BIND_SERVICE功能的进程才能将(2)绑定到这些端口号。 svm_zero必须为零。

有几个特殊地址:VMADDR_CID_ANY(-1U)表示任何要绑定的地址; VMADDR_CID_HYPERVISOR(0)保留用于管理程序中内置的服务; VMADDR_CID_LOCAL(1)是本地通信(回送)的众所周知的地址; VMADDR_CID_HOST(2)是主机的众所周知的地址。

特殊常数VMADDR_PORT_ANY(-1U)表示要绑定的任何端口号。

Live migration

套接字受虚拟机实时迁移的影响。虚拟机迁移到新主机时,已连接的SOCK_STREAM套接字断开连接。发生这种情况时,应用程序必须重新连接。

如果旧的CID在新主机上不可用,则本地CID在整个实时迁移中可能会更改。绑定的套接字将自动更新为新的CID。

Ioctls

IOCTL_VM_SOCKETS_GET_LOCAL_CID
获取本地计算机的CID。该参数是一个指向无符号int的指针。
ioctl(socket, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid);
绑定时考虑使用VMADDR_CID_ANY,而不是使用IOCTL_VM_SOCKETS_GET_LOCAL_CID获取本地CID。

Local communication

VMADDR_CID_LOCAL(1)将数据包定向到生成数据包的同一主机。这对于在单个主机上测试应用程序和调试很有用。

可以将通过IOCTL_VM_SOCKETS_GET_LOCAL_CID获得的本地CID用于相同的目的,但是最好使用VMADDR_CID_LOCAL。

另外参见

绑定(2),连接(2),监听(2),接收(2),发送(2),套接字(2),功能(7)

错误说明

EACCES
没有CAP_NET_BIND_SERVICE功能,无法绑定到特权端口。
EADDRINUSE
无法绑定到已使用的端口。
EADDRNOTAVAIL
无法找到用于绑定的空闲端口或无法绑定到非本地CID。
EINVAL
无效的参数。这包括:尝试绑定已经绑定的套接字,提供无效的struct sockaddr_vm,以及其他输入验证错误。
ENOPROTOOPT
setsockopt(2)或getsockopt(2)中的套接字选项无效。
ENOTCONN
无法在未连接的套接字上执行操作。
EOPNOTSUPP
不支持该操作。这包括:未针对send(2)系列的系统调用实现的MSG_OOB标志和针对recv(2)系列的系统调用的MSG_PEEK。
EPROTONOSUPPORT
无效的套接字协议号。协议应始终为0。
ESOCKTNOSUPPORT
套接字(2)中不支持的套接字类型。仅SOCK_STREAM和SOCK_DGRAM有效。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

名称

vsock-Linux VSOCK地址家族

版本

从Linux 3.9开始,就已经支持VMware(VMCI)。从Linux 4.8开始支持KVM(virtio)。从Linux 4.14开始支持Hyper-V。

从Linux 5.6开始支持VMADDR_CID_LOCAL。从Linux 5.6开始,就可以在来宾和主机上进行本地通信。以前的版本仅支持来宾内部的本地通信(而不是主机上的本地通信),并且仅支持某些传输(VMCI和virtio)。

语法

#包括
#包括

stream_socket =套接字(AF_VSOCK,SOCK_STREAM,0);
数据报套接字=套接字(AF_VSOCK,SOCK_DGRAM,0);

日期:2019-08-20 18:02:04 来源:oir作者:oir