VSOCK(7) | Руководство программиста Linux | VSOCK(7) |
vsock - семейство адресов Linux VSOCK
#include <sys/socket.h> #include <linux/vm_sockets.h>
stream_socket = socket(AF_VSOCK, SOCK_STREAM, 0); datagram_socket = socket(AF_VSOCK, SOCK_DGRAM, 0);
Семейство адресов 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).
Адрес сокета определяется как комбинация 32-битного идентификатора контекста (CID) и 32-битного номера порта. В CID задаётся источник или назначение, то есть виртуальная машина или узел. Номер порта определяет службу, выполняемую в определённой машине.
struct sockaddr_vm { sa_family_t svm_family; /* семейство адресов: AF_VSOCK */ unsigned short svm_reserved1; unsigned int svm_port; /* номер порта в порядке байт узла */ unsigned int svm_cid; /* адрес в порядке байт узла */ };
Значение svm_family всегда равно AF_VSOCK. Значение svm_reserved1 всегда равно to 0. Значение svm_port содержит номер порта в порядке байт узла. Номера портов меньше 1024 называются привилегированными портами. Только процесс с мандатом CAP_NET_BIND_SERVICE может вызывать bind(2) с такими номерами.
Существует несколько специальных адресов: VMADDR_CID_ANY (-1U) означает любой адрес при привязывании; VMADDR_CID_HYPERVISOR (0) зарезервирован для служб встроенных в супервизор; VMADDR_CID_RESERVED (1) не должен использоваться; VMADDR_CID_HOST (2) общеизвестный (well-known) адрес узла.
Специальная константа VMADDR_PORT_ANY (-1U) означает любой порт для связывания.
На сокеты действует живая миграния виртуальных машин. Соединённые сокеты SOCK_STREAM становятся отключёнными, если виртуальная машина мигрирует на новый узел. Когда это происходит приложения должны выполнить переподключение.
Локальный CID при живой миграции может измениться, если старый CID недоступен на новом узле. Привязанные сокеты автоматически обновляются новым CID.
ioctl(socket, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid);
Поддержка для VMware (VMCI) доступна начиная с Linux 3.9. KVM (virtio) поддерживается начиная с Linux 4.8. Hyper-V поддерживается начиная с Linux 4.14.
bind(2), connect(2), listen(2), recv(2), send(2), socket(2), capabilities(7)
2017-11-30 | Linux |