vsock(7)

NUME
vsock - familia de adrese Linux VSOCK

SINOPSIS
#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);

DESCRIERE
Familia de adrese VSOCK facilitează comunicarea între mașinile virtuale și gazda pe care rulează. Această familie de adrese este utilizată de agenții invitați și de serviciile hipervizorului care au nevoie de un canal de comunicare independent de configurația rețelei mașinilor virtuale.

Tipurile de soclu valide sunt SOCK_STREAM și SOCK_DGRAM. SOCK_STREAM oferă fluxuri de octeți orientate spre conexiune cu livrare garantată, în ordine. SOCK_DGRAM oferă un serviciu de pachete de datagrame fără conexiune, cu livrare și ordonare cu cel mai puțin-efort. Disponibilitatea acestor tipuri de soclu depinde de hipervizorul de subiacent.

Un nou socket este creat cu

    socket(AF_VSOCK, socket_type, 0);

Când un proces dorește să stabilească o conexiune, acesta apelează connect(2) cu o anumită adresă de soclu de destinație. Soclul este asociat în mod automat unui port liber, dacă nu este asociat.

Un proces poate asculta conexiunile primite, mai întâi conectându-se la o adresă de soclu folosind bind(2) și apoi apelând listen(2).

Datele sunt transmise cu ajutorul familiilor de apeluri de sistem send(2) sau write(2), iar datele sunt primite cu ajutorul familiilor de apeluri de sistem recv(2) sau read(2).

  Formatul adreselor
O adresă de soclu este definită ca o combinație între un identificator de context („Context Identifier”: CID) pe 32 de biți și un număr de port pe 32 de biți. CID-ul identifică sursa sau destinația, care este fie o mașină virtuală, fie o gazdă. Numărul portului face diferența între mai multe servicii care rulează pe o singură mașină.

    struct sockaddr_vm {
        sa_family_t    svm_family;    /* Familia de adrese: AF_VSOCK */
        unsigned short svm_reserved1;
        unsigned int   svm_port;      /* Numărul portului în ordinea octeților gazdei */
        unsigned int   svm_cid;       /* Adresa în ordinea octeților gazdei */
        unsigned char  svm_zero[sizeof(struct sockaddr) -
                                sizeof(sa_family_t) -
                                sizeof(unsigned short) -
                                sizeof(unsigned int) -
                                sizeof(unsigned int)];
    };

svm_family este întotdeauna stabilit la AF_VSOCK. svm_reserved1 este întotdeauna stabilit la 0. svm_port conține numărul portului în ordinea octeților gazdă. Numerele de port mai mici de 1024 se numesc porturi privilegiate. Numai un proces cu capacitatea CAP_NET_BIND_SERVICE poate efectua bind(2) la aceste numere de port. svm_zero trebuie să fie umplut cu zerouri.

Există mai multe adrese speciale: VMADDR_CID_ANY (-1U) înseamnă orice adresă pentru conectare; VMADDR_CID_HYPERVISOR (0) este rezervată pentru serviciile integrate în hipervizor; VMADDR_CID_LOCAL (1) este adresa bine cunoscută pentru comunicarea locală (loopback); VMADDR_CID_HOST (2) este adresa bine cunoscută a gazdei.

Constanta specială VMADDR_PORT_ANY (-1U) înseamnă orice număr de port pentru asociere.

  Migrare la cald
Soclurile sunt afectate de migrarea la cald a mașinilor virtuale. Soclurile SOCK_STREAM conectate se deconectează atunci când mașina virtuală migrează către o nouă gazdă. Aplicațiile trebuie să se reconecteze atunci când se întâmplă acest lucru.

CID-ul local se poate schimba în timpul migrației la cald dacă vechiul CID nu este disponibil pe noua gazdă. Soclurile asociate sunt actualizate automat la noul CID.

  Ioctl-uri
Următoarele ioctl-uri sunt disponibile pe dispozitivul /dev/vsock.

IOCTL_VM_SOCKETS_GET_LOCAL_CID
    Obține CID-ul mașinii locale. Argumentul este un indicator către un unsigned int.

        ioctl(fd, IOCTL_VM_SOCKETS_GET_LOCAL_CID, &cid);

    Luați în considerare utilizarea VMADDR_CID_ANY atunci când vă conectați în loc să obțineți CID-ul local cu IOCTL_VM_SOCKETS_GET_LOCAL_CID.

  Comunicarea locală
VMADDR_CID_LOCAL (1) direcționează pachetele către aceeași gazdă care le-a generat. Acest lucru este util pentru testarea aplicațiilor pe o singură gazdă și pentru depanare.

CID-ul local obținut cu IOCTL_VM_SOCKETS_GET_LOCAL_CID poate fi utilizat în același scop, dar este preferabil să se utilizeze VMADDR_CID_LOCAL.

ERORI-IEȘIRE

EACCES
    Nu se poate face conectarea la un port privilegiat fără capacitatea CAP_NET_BIND_SERVICE.

EADDRINUSE
    Nu se poate face conectarea la un port care este deja utilizat.

EADDRNOTAVAIL
    Nu se poate găsi un port liber pentru conectare sau nu se poate conecta la un CID nelocal.

EINVAL
    Parametrii nevalabili. Aceasta include: încercarea de a asocia un soclu care este deja asociat, furnizarea unei structuri sockaddr_vm nevalide și alte erori de validare a datelor de intrare.

ENOPROTOOPT
    Opțiune de soclu nevalidă în setsockopt(2) sau getsockopt(2).

ENOTCONN
    Nu se poate efectua o operație pe un soclu neconectat.

EOPNOTSUPP
    Operația nu este acceptată. Aceasta include: fanionul MSG_OOB care nu este implementat pentru familia de apeluri de sistem send(2) și MSG_PEEK pentru familia de apeluri de sistem recv(2).

EPROTONOSUPPORT
    Număr de protocol de soclu nevalid. Protocolul trebuie să fie întotdeauna 0.

ESOCKTNOSUPPORT
    Tip de soclu neacceptat în socket(2). Numai SOCK_STREAM și SOCK_DGRAM sunt valabile.

VERSIUNI
Suportul pentru VMware (VMCI) a fost disponibil începând cu Linux 3.9. KVM (virtio) este disponibil începând cu Linux 4.8. Hyper-V este disponibil începând cu Linux 4.14.

VMADDR_CID_LOCAL este disponibil începând cu Linux 5.6. Comunicarea locală în invitat și pe gazdă este disponibilă începând cu Linux 5.6. Versiunile anterioare ofereau suport numai pentru comunicarea locală în cadrul unui oaspete (nu și pe gazdă) și numai cu anumite transporturi (VMCI și virtio).

CONSULTAȚI ȘI
bind(2), connect(2), listen(2), recv(2), send(2), socket(2), capabilities(7)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.