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

IOCTL_VM_SOCKETS_GET_LOCAL_CID
    Получить CID локальной машины. Аргументом является указатель на unsigned int.

        ioctl(socket, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid);

    Рассматривать использование VMADDR_CID_ANY при привязывании, вместо получения локального CID с помощью IOCTL_VM_SOCKETS_GET_LOCAL_CID.

ОШИБКИ

EACCES
    Невозможно привязаться к привилегированному порту не имея мандата CAP_NET_BIND_SERVICE.

EADDRINUSE
    Не могу привязаться к порту, который уже используется.

EADDRNOTAVAIL
    Не удалось найти свободный порт для привязки или невозможно привязаться к нелокальному CID.

EINVAL
    Некорректные параметры. Сюда относятся: попытка привязать уже привязанный сокет, указание некорректной структуры sockaddr_vm и ошибки проверки правильности входных данных.

ENOPROTOOPT
    Недопустимый параметр сокета в setsockopt(2) или getsockopt(2).

ENOTCONN
    Невозможно выполнить действие с неподключённым сокетом.

EOPNOTSUPP
    Операция не поддерживается. Сюда относятся: флаг MSG_OOB, не реализованный для семейства вызовов send(2), и MSG_PEEK для семейства вызовов recv(2).

EPROTONOSUPPORT
    Некорректный номер протокола сокета. Протокол всегда должен быть равен 0.

ESOCKTNOSUPPORT
    Неподдерживаемый тип сокета в socket(2). Допускаются только SOCK_STREAM и SOCK_DGRAM.

ВЕРСИИ
Поддержка для 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)