vsock 介绍与使用
vsock介绍
vsock 使用
内核配置
虚拟机kernel
将下面三个选项编译进kernel,而不是编译成模块,原因下面会介绍
CONFIG_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS_COMMON=y
宿主机kernel
VHOST_VSOCK 只能够被编译成模块
CONFIG_VHOST_VSOCK=m
使用QEMU启动虚拟机
modprobe vhost_vsock
示例程序
Server (运行在宿主机上)
#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>
#include <stdio.h>
int main()
{
int s = socket(AF_VSOCK, SOCK_STREAM, 0);
struct sockaddr_vm addr;
memset(&addr, 0, sizeof(struct sockaddr_vm));
addr.svm_family = AF_VSOCK;
addr.svm_port = 9999;
addr.svm_cid = VMADDR_CID_HOST;
bind(s, &addr, sizeof(struct sockaddr_vm));
listen(s, 0);
struct sockaddr_vm peer_addr;
socklen_t peer_addr_size = sizeof(struct sockaddr_vm);
int peer_fd = accept(s, &peer_addr, &peer_addr_size);
char buf[64];
size_t msg_len;
while ((msg_len = recv(peer_fd, &buf, 64, 0)) > 0) {
printf("Received %lu bytes: %.*s\n", msg_len, msg_len, buf);
}
return 0;
}
Client (运行在虚拟机上)
#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>
int main()
{
int s = socket(AF_VSOCK, SOCK_STREAM, 0);
struct sockaddr_vm addr;
memset(&addr, 0, sizeof(struct sockaddr_vm));
addr.svm_family = AF_VSOCK;
addr.svm_port = 9999;
addr.svm_cid = VMADDR_CID_HOST;
connect(s, &addr, sizeof(struct sockaddr_vm));
send(s, "Hello, world!", 13, 0);
close(s);
return 0;
}
参考
https://gist.github.com/nrdmn/7971be650919b112343b1cb2757a3fe6