Partager via


Créer vos propres services d’intégration

À compter de la mise à jour anniversaire Windows 10, tout le monde peut faire communiquer des applications qui communiquent entre l’hôte Hyper-V et ses machines virtuelles à l’aide de sockets Hyper-V - un socket Windows avec une nouvelle famille d’adresses et un point de terminaison spécialisé pour cibler des machines virtuelles. Toutes les communications sur Hyper-V sockets s’exécutent sans utiliser de mise en réseau et toutes les données restent sur la même mémoire physique. Les applications utilisant des sockets Hyper-V sont similaires aux services d’intégration d’Hyper-V.

Ce document décrit la création d’un programme simple basé sur des sockets Hyper-V.

Système d’exploitation hôte pris en charge

  • Windows 10 et versions ultérieures
  • Windows Server 2016 et versions ultérieures

Système d’exploitation invité pris en charge

Note

Un invité Linux pris en charge doit prendre en charge le noyau pour :

CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y

Fonctionnalités et limitations

  • Prend en charge les actions en mode noyau ou en mode utilisateur
  • Flux de données uniquement
  • Aucune mémoire de bloc (pas le meilleur pour la sauvegarde/vidéo)

Mise en route

Conditions requises :

  • Compilateur C/C++. Si vous n’en avez pas, consultez Visual Studio Community
  • Kit de développement logiciel (SDK) Windows préinstallé dans Visual Studio 2015 avec Update 3 et versions ultérieures.
  • Un ordinateur exécutant l’un des systèmes d’exploitation hôtes spécifiés avec au moins un ordinateur vituel. -- il s’agit de tester votre application.

Note: L’API pour les sockets Hyper-V est devenue disponible publiquement dans la mise à jour anniversaire Windows 10. Les applications qui utilisent HVSocket s’exécutent sur n’importe quel hôte Windows 10 et invité, mais ne peuvent être développées qu’avec un Kit de développement logiciel (SDK) Windows ultérieurement à la build 14290.

Inscrire une nouvelle application

Pour utiliser des sockets Hyper-V, l’application doit être inscrite auprès du registre de l’hôte Hyper-V.

En inscrivant le service dans le Registre, vous obtenez :

  • Gestion WMI pour activer, désactiver et répertorier les services disponibles
  • Autorisation de communiquer directement avec les machines virtuelles

PowerShell suivant inscrit une nouvelle application nommée « Démonstration de socket HV ». Cela doit être exécuté en tant qu’administrateur. Instructions manuelles ci-dessous.

$friendlyName = "HV Socket Demo"

# Create a new random GUID.  Add it to the services list
$service = New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices" -Name ((New-Guid).Guid)

# Set a friendly name
$service.SetValue("ElementName", $friendlyName)

# Copy GUID to clipboard for later use
$service.PSChildName | clip.exe

Emplacement et informations du Registre :

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\

Dans cet emplacement de Registre, vous verrez plusieurs GUID. Ce sont nos services en boîte.

Informations dans le Registre par service :

  • Service GUID
    • ElementName (REG_SZ) -- il s’agit du nom convivial du service

Pour inscrire votre propre service, créez une clé de Registre à l’aide de votre propre GUID et de votre nom convivial.

Le nom convivial est associé à votre nouvelle application. Il apparaît dans les compteurs de performances et d’autres emplacements où un GUID n’est pas approprié.

L’entrée de Registre ressemble à ceci :

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Virtualization\GuestCommunicationServices\
    999E53D4-3D5C-4C3E-8779-BED06EC056E1\
        ElementName    REG_SZ    VM Session Service
    YourGUID\
        ElementName    REG_SZ    Your Service Friendly Name

Note

Le GUID de service d’un invité Linux utilise le protocole VSOCK qui s’adresse par le biais d’un svm_cid guid plutôt svm_port que d’un guid. Pour combler cette incohérence avec Windows, le GUID connu est utilisé comme modèle de service sur l’hôte qui se traduit par un port dans l’invité. Pour personnaliser votre GUID de service, remplacez simplement le premier « 0000000000 » par le numéro de port souhaité. Par exemple : « 00000ac9 » est le port 2761.

// Hyper-V Socket Linux guest VSOCK template GUID
struct __declspec(uuid("00000000-facb-11e6-bd58-64006a7986d3")) VSockTemplate{};

 /*
  * GUID example = __uuidof(VSockTemplate);
  * example.Data1 = 2761; // 0x00000AC9
  */

Pourboire: Pour générer un GUID dans PowerShell et le copier dans le Presse-papiers, exécutez :

(New-Guid).Guid | clip.exe

Créer un socket Hyper-V

Dans le cas le plus simple, la définition d’un socket nécessite une famille d’adresses, un type de connexion et un protocole.

Voici une définition de socket simple

// Windows
SOCKET WSAAPI socket(
  _In_ int af,
  _In_ int type,
  _In_ int protocol
);

// Linux guest
int socket(int domain, int type, int protocol);

Pour un socket Hyper-V :

  • Famille d’adresses - AF_HYPERV (Windows) ou AF_VSOCK (invité Linux)
  • type- SOCK_STREAM
  • protocole - HV_PROTOCOL_RAW (Windows) ou 0 (invité Linux)

Voici un exemple de déclaration/instanciation :

// Windows
SOCKET sock = socket(AF_HYPERV, SOCK_STREAM, HV_PROTOCOL_RAW);

// Linux guest
int sock = socket(AF_VSOCK, SOCK_STREAM, 0);

Lier à un socket Hyper-V

L’association associe un socket aux informations de connexion.

La définition de fonction est copiée ci-dessous pour la convinience, en savoir plus sur la liaison ici.

// Windows
int bind(
  _In_ SOCKET                s,
  _In_ const struct sockaddr *name,
  _In_ int                   namelen
);

// Linux guest
int bind(int sockfd, const struct sockaddr *addr,
         socklen_t addrlen);

Contrairement à l’adresse de socket (sockaddr) d’une famille d’adresses De protocole Internet standard (AF_INET) qui se compose de l’adresse IP de l’ordinateur hôte et d’un numéro de port sur cet hôte, l’adresse du socket pour AF_HYPERV utiliser l’ID de la machine virtuelle et l’ID d’application défini ci-dessus pour établir une connexion. Si la liaison à partir d’un invité AF_VSOCK Linux utilise le svm_cid et le svm_port.

Étant donné que Hyper-V sockets ne dépendent pas d’une pile réseau, TCP/IP, DNS, etc. le point de terminaison de socket a besoin d’une non-IP, et non d’un nom d’hôte, format qui décrit toujours sans ambiguïté la connexion.

Voici la définition de l’adresse de socket d’un socket Hyper-V :

// Windows
struct SOCKADDR_HV
{
     ADDRESS_FAMILY Family;
     USHORT Reserved;
     GUID VmId;
     GUID ServiceId;
};

// Linux guest
// See include/uapi/linux/vm_sockets.h for more information.
struct sockaddr_vm {
    __kernel_sa_family_t svm_family;
    unsigned short svm_reserved1;
    unsigned int svm_port;
    unsigned int svm_cid;
    unsigned char svm_zero[sizeof(struct sockaddr) -
                   sizeof(sa_family_t) -
                   sizeof(unsigned short) -
                   sizeof(unsigned int) - sizeof(unsigned int)];
};

Au lieu d’une adresse IP ou d’un nom d’hôte, AF_HYPERV points de terminaison reposent fortement sur deux GUID :

  • ID de machine virtuelle : il s’agit de l’ID unique affecté par machine virtuelle. L’ID d’une machine virtuelle est disponible à l’aide de l’extrait de code PowerShell suivant.

    (Get-VM -Name $VMName).Id
    
  • ID de service : GUID , décrit ci-dessus, avec lequel l’application est inscrite dans le registre hôte Hyper-V.

Il existe également un ensemble de caractères génériques VMID disponibles lorsqu’une connexion n’est pas à une machine virtuelle spécifique.

Caractères génériques VMID

Nom GUID Descriptif
HV_GUID_ZERO 00000000-0000-0000-0000-000000000000 Les écouteurs doivent se lier à ce VmId pour accepter la connexion à partir de toutes les partitions.
HV_GUID_WILDCARD 00000000-0000-0000-0000-000000000000 Les écouteurs doivent se lier à ce VmId pour accepter la connexion à partir de toutes les partitions.
HV_GUID_BROADCAST FFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
HV_GUID_CHILDREN 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd Adresse générique pour les enfants. Les écouteurs doivent se lier à ce VmId pour accepter la connexion de ses enfants.
HV_GUID_LOOPBACK e0e16197-dd56-4a10-9195-5ee7a155a838 Adresse de bouclage. L’utilisation de cette vmId se connecte à la même partition que le connecteur.
HV_GUID_PARENT a42e7cda-d03f-480c-9cc2-a4de20abb878 Adresse parente. L’utilisation de cette vmId se connecte à la partition parente du connecteur.*

* HV_GUID_PARENT Le parent d’une machine virtuelle est son hôte. Le parent d’un conteneur est l’hôte du conteneur. La connexion à partir d’un conteneur s’exécutant sur une machine virtuelle se connecte à la machine virtuelle hébergeant le conteneur. L’écoute sur ce VmId accepte la connexion à partir de : (à l’intérieur des conteneurs) : hôte de conteneur. (À l’intérieur de la machine virtuelle : hôte de conteneur/ aucun conteneur) : hôte de machine virtuelle. (Pas à l’intérieur de la machine virtuelle : hôte de conteneur/ aucun conteneur) : non pris en charge.

Commandes de socket prises en charge

Socket() Bind() Connect() Send() Listen() Accept()

HvSocket Socket Options

Nom Type Descriptif
HVSOCKET_CONNECTED_SUSPEND ULONG Lorsque cette option de socket est définie sur un socket de valeur différente de zéro, ne se déconnecte pas lorsque la machine virtuelle est suspendue.

Terminer l’API WinSock

Informations de référenceHyper-V Integration Services