vsock(7) Miscellaneous Information Manual 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;    /* 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 is always set to AF_VSOCK. svm_reserved1 is always set to 0. svm_port contains the port number in host byte order. The port numbers below 1024 are called privileged ports. Only a process with the CAP_NET_BIND_SERVICE capability may bind(2) to these port numbers. svm_zero must be zero-filled.

There are several special addresses: VMADDR_CID_ANY (-1U) means any address for binding; VMADDR_CID_HYPERVISOR (0) is reserved for services built into the hypervisor; VMADDR_CID_LOCAL (1) is the well-known address for local communication (loopback); VMADDR_CID_HOST (2) is the well-known address of the host.

Специальная константа VMADDR_PORT_ANY (-1U) означает любой порт для связывания.

Живая миграция

На сокеты действует живая миграния виртуальных машин. Соединённые сокеты SOCK_STREAM становятся отключёнными, если виртуальная машина мигрирует на новый узел. Когда это происходит приложения должны выполнить переподключение.

Локальный CID при живой миграции может измениться, если старый CID недоступен на новом узле. Привязанные сокеты автоматически обновляются новым CID.

Вызовы ioctl

The following ioctls are available on the /dev/vsock device.

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

ioctl(fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid);

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

Локальное соединение

VMADDR_CID_LOCAL (1) directs packets to the same host that generated them. This is useful for testing applications on a single host and for debugging.

The local CID obtained with IOCTL_VM_SOCKETS_GET_LOCAL_CID can be used for the same purpose, but it is preferable to use VMADDR_CID_LOCAL .

ОШИБКИ

Невозможно привязаться к привилегированному порту не имея мандата CAP_NET_BIND_SERVICE.
Не могу привязаться к порту, который уже используется.
Не удалось найти свободный порт для привязки или невозможно привязаться к нелокальному CID.
Некорректные параметры. Сюда относятся: попытка привязать уже привязанный сокет, указание некорректной структуры sockaddr_vm и ошибки проверки правильности входных данных.
Недопустимый параметр сокета в setsockopt(2) или getsockopt(2).
Невозможно выполнить действие с неподключённым сокетом.
Операция не поддерживается. Сюда относятся: флаг MSG_OOB, не реализованный для семейства вызовов send(2), и MSG_PEEK для семейства вызовов recv(2).
Некорректный номер протокола сокета. Протокол всегда должен быть равен 0.
Неподдерживаемый тип сокета в socket(2). Допускаются только SOCK_STREAM и SOCK_DGRAM.

ВЕРСИИ

Поддержка для VMware (VMCI) доступна начиная с Linux 3.9. KVM (virtio) поддерживается начиная с Linux 4.8. Hyper-V поддерживается начиная с Linux 4.14.

VMADDR_CID_LOCAL is supported since Linux 5.6. Local communication in the guest and on the host is available since Linux 5.6. Previous versions supported only local communication within a guest (not on the host), and with only some transports (VMCI and virtio).

СМ. ТАКЖЕ

bind(2), connect(2), listen(2), recv(2), send(2), socket(2), capabilities(7)

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy Ovchinnikov <dmitriyxt5@gmail.com>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Katrin Kutepova <blackkatelv@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

30 октября 2022 г. Linux man-pages 6.05.01