Freigeben über


Eigene Integrationsdienste erstellen

Ab Windows 10 Anniversary Update können alle Anwendungen erstellen, die zwischen dem Hyper-V Host und seinen virtuellen Computern kommunizieren, indem Hyper-V Sockets verwendet werden – ein Windows-Socket mit einer neuen Adressfamilie und einem speziellen Endpunkt für die Zielbestimmung virtueller Computer. Die gesamte Kommunikation über Hyper-V Sockets wird ohne Netzwerkausführung ausgeführt, und alle Daten bleiben auf demselben physischen Speicher. Anwendungen, die Hyper-V Sockets verwenden, ähneln den Integrationsdiensten von Hyper-V.

Dieses Dokument führt Sie durch die Erstellung eines einfachen Programms, das auf Hyper-V Sockets basiert.

Unterstütztes Hostbetriebssystem

  • Windows 10 und höher
  • Windows Server 2016 und höher

Unterstütztes Gastbetriebssystem

Hinweis

Ein unterstützter Linux-Gast muss Kernelunterstützung für Folgendes haben:

CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y

Funktionen und Einschränkungen

  • Unterstützt Kernelmodus- oder Benutzermodusaktionen
  • Nur Datenstrom
  • Kein Blockspeicher (nicht am besten für Sicherung/Video)

Erste Schritte

Anforderungen:

  • C/C++-Compiler. Wenn Sie keins haben, schauen Sie sich visual Studio Community an
  • Windows SDK – vorinstalliert in Visual Studio 2015 mit Update 3 und höher.
  • Ein Computer, auf dem eines der Hostbetriebssysteme ausgeführt wird, die mit mindestens einem vitualen Computer angegeben sind. -- Dies dient zum Testen Ihrer Anwendung.

Anmerkung: Die API für Hyper-V Sockets wurde in Windows 10 Anniversary Update öffentlich verfügbar. Anwendungen, die HVSocket verwenden, werden auf jedem Windows 10-Host und -Gast ausgeführt, können aber nur mit einem Windows SDK später als Build 14290 entwickelt werden.

Registrieren einer neuen Anwendung

Um Hyper-V Sockets verwenden zu können, muss die Anwendung bei der Registrierung des Hyper-V Hosts registriert werden.

Durch die Registrierung des Diensts in der Registrierung erhalten Sie Folgendes:

  • WMI-Verwaltung zum Aktivieren, Deaktivieren und Auflisten verfügbarer Dienste
  • Berechtigung für die direkte Kommunikation mit virtuellen Computern

Die folgende PowerShell registriert eine neue Anwendung namens "HV Socket Demo". Dies muss als Administrator ausgeführt werden. Manuelle Anweisungen unten.

$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

Registrierungsspeicherort und Informationen:

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

An diesem Registrierungsspeicherort werden mehrere GUIDs angezeigt. Dies sind unsere Box-Dienstleistungen.

Informationen in der Registrierung pro Dienst:

  • Service GUID
    • ElementName (REG_SZ) -- Dies ist der Anzeigename des Diensts.

Um Ihren eigenen Dienst zu registrieren, erstellen Sie einen neuen Registrierungsschlüssel mit Ihrer eigenen GUID und Ihrem Anzeigenamen.

Der Anzeigename wird Ihrer neuen Anwendung zugeordnet. Er wird in Leistungsindikatoren und anderen Stellen angezeigt, an denen eine GUID nicht geeignet ist.

Der Registrierungseintrag sieht wie folgt aus:

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

Hinweis

Die Dienst-GUID für einen Linux-Gast verwendet das VSOCK-Protokoll, das über eine svm_cid und svm_port keine GUIDs adressiert. Um diese Inkonsistenz mit Windows zu überbrücken, wird die bekannte GUID als Dienstvorlage auf dem Host verwendet, die in einen Port im Gast übersetzt wird. Um Ihre Dienst-GUID anzupassen, ändern Sie einfach die erste "00000000" in die gewünschte Portnummer. Beispiel: "00000ac9" ist 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
  */

Trinkgeld: Um eine GUID in PowerShell zu generieren und in die Zwischenablage zu kopieren, führen Sie Folgendes aus:

(New-Guid).Guid | clip.exe

Erstellen eines Hyper-V Sockets

Im einfachsten Fall erfordert das Definieren eines Sockets eine Adressfamilie, einen Verbindungstyp und ein Protokoll.

Hier ist eine einfache Socketdefinition.

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

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

Für einen Hyper-V Socket:

  • Adressfamilie - AF_HYPERV (Windows) oder AF_VSOCK (Linux-Gast)
  • Art- SOCK_STREAM
  • Protokoll – HV_PROTOCOL_RAW (Windows) oder 0 (Linux-Gast)

Hier ist eine Beispieldeklaration/Instanziierung:

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

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

Binden an einen Hyper-V Socket

Binden ordnet einen Socket mit Verbindungsinformationen zu.

Die Funktionsdefinition wird unten für Konvinience kopiert, weitere Informationen zur Bindung finden Sie hier.

// 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);

Im Gegensatz zur Socketadresse (Sockaddr) für eine Standard-Internetprotokoll-Adressfamilie (AF_INET), die aus der IP-Adresse des Hostcomputers und einer Portnummer auf diesem Host besteht, verwendet die Socketadresse für AF_HYPERV die Verwendung der ID des virtuellen Computers und der oben definierten Anwendungs-ID eine Verbindung. Wenn die Bindung von einem Linux-Gast AF_VSOCK die svm_cid und die svm_port.

Da Hyper-V Sockets nicht von einem Netzwerkstapel, TCP/IP, DNS usw. abhängen, benötigt der Socketendpunkt ein Nicht-IP- und kein Hostnamen- Format, das die Verbindung immer noch eindeutig beschreibt.

Dies ist die Definition für die Socketadresse eines Hyper-V Sockets:

// 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)];
};

Anstelle einer IP oder eines Hostnamens basieren AF_HYPERV Endpunkte stark auf zwei GUIDs:

  • VM-ID – dies ist die eindeutige ID, die pro VM zugewiesen ist. Die ID eines virtuellen Computers kann mithilfe des folgenden PowerShell-Codeausschnitts gefunden werden.

    (Get-VM -Name $VMName).Id
    
  • Dienst-ID – GUID, wie oben beschrieben, mit der die Anwendung in der Hyper-V Hostregistrierung registriert ist.

Es gibt auch eine Reihe von VMID-Wildcards, die verfügbar sind, wenn eine Verbindung nicht mit einem bestimmten virtuellen Computer besteht.

VMID-Wildcards

Name GUID Description
HV_GUID_ZERO 00000000-0000-0000-0000-000000000000 Listener sollten eine Bindung an diese VMId herstellen, um die Verbindung von allen Partitionen zu akzeptieren.
HV_GUID_WILDCARD 00000000-0000-0000-0000-000000000000 Listener sollten eine Bindung an diese VMId herstellen, um die Verbindung von allen Partitionen zu akzeptieren.
HV_GUID_BROADCAST FFFFFF-FFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
HV_GUID_CHILDREN 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd Die Wildcardadresse für Kinder. Listener sollten eine Bindung an diese VMId herstellen, um die Verbindung von den untergeordneten Elementen zu akzeptieren.
HV_GUID_LOOPBACK e0e16197-dd56-4a10-9195-5ee7a155a838 Loopbackadresse. Die Verwendung dieser VmId stellt eine Verbindung mit derselben Partition wie der Connector her.
HV_GUID_PARENT a42e7cda-d03f-480c-9cc2-a4de20abb878 Übergeordnete Adresse. Die Verwendung dieser VmId stellt eine Verbindung mit der übergeordneten Partition des Connectors her.*

* HV_GUID_PARENT Das übergeordnete Element eines virtuellen Computers ist sein Host. Das übergeordnete Element eines Containers ist der Host des Containers. Beim Herstellen einer Verbindung von einem Container, der auf einem virtuellen Computer ausgeführt wird, wird eine Verbindung mit dem virtuellen Computer hergestellt, auf dem der Container gehostet wird. Überwachung auf diese VmId akzeptiert die Verbindung von: (Innerhalb von Containern): Containerhost. (Innerhalb der VM: Containerhost/ kein Container): VM-Host. (Nicht innerhalb der VM: Containerhost/ kein Container): Nicht unterstützt.

Unterstützte Socketbefehle

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

HvSocket Socketoptionen

Name Typ Description
HVSOCKET_CONNECTED_SUSPEND ULONG Wenn diese Socketoption auf einen Nicht-Null-Wert festgelegt ist, trennen Sockets nicht, wenn der virtuelle Computer angehalten wird.

Vollständige WinSock-API

Referenz zuHyper-V Integration Services