Freigeben über


Erstellen eigener Integrationsdienste

Ab Windows 10 Anniversary Update können Sie selbst Anwendungen erstellen, die zwischen dem Hyper-V-Host und dessen virtuellen Computern kommunizieren, und zwar mithilfe von Hyper-V-Sockets. Das sind Windows-Sockets mit einer neuen Adressfamilie und speziellen Endpunkten für die Auswahl von virtuellen Computern. Die gesamte Kommunikation über Hyper-V-Sockets erfolgt ohne Networking, und alle Daten verbleiben auf dem gleichen physischen Speicher. Anwendungen, die Hyper-V-Sockets verwenden, ähneln den Hyper-V-Integrationsdiensten.

Dieses Dokument erläutert die Erstellung eines einfachen Programms für Hyper-V-Sockets.

Unterstützte Host-BS

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

Unterstütztes Gastbetriebssystem

Hinweis

Ein unterstütztes Linux-Gastbetriebssystem benötigt Kernel-Unterstützung für:

CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y

Funktionen und Einschränkungen

  • Unterstützt den Kernelmodus oder Benutzermodusaktionen
  • Nur Datenstrom
  • Kein Blockspeicher (für Sicherungen/Video nicht optimal)

Erste Schritte

Anforderungen:

  • C/C++-Compiler. Wenn Sie keinen besitzen, fragen Sie in der Visual Studio Community nach.
  • Windows SDK – vorinstalliert in Visual Studio 2015 mit Update 3 oder höher.
  • Ein Computer, auf dem eines der genannten Host-Betriebssysteme ausgeführt wird, und mindestens ein virtueller Computer (zum Testen der Anwendung).

Hinweis: Die API für Hyper-V-Sockets wurde mit Windows 10 Anniversary Update öffentlich verfügbar. Anwendungen, die HVSocket verwenden, sind auf jedem Host und Gast unter Windows 10 ausführbar, können jedoch nur einem Windows SDK ab Build 14290 entwickelt werden.

Registrieren einer neuen Anwendung

Damit Sie Hyper-V-Sockets verwenden können, muss die Anwendung in der Registrierung des Hyper-V-Hosts registriert werden.

Durch die Registrierung des Diensts in der Registrierung wird Folgendes verfügbar:

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

Mithilfe der folgenden PowerShell-Befehle wird eine neue Anwendung mit dem Namen „HV Socket Demo“ registriert. Diese muss als Administrator ausgeführt werden. Anweisungen dazu folgen weiter 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

Registrierungsschlüssel und Informationen:

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

An diesem Registrierungszweig sehen Sie mehrere GUIDs. Unsere integrierte Dienste sind.

Dienstbezogene Informationen in der Registrierung:

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

Um einen eigenen Dienst zu registrieren, erstellen Sie einen neuen Registrierungsschlüssel mit eigenen Angaben für GUID und Anzeigename.

Der Anzeigename wird Ihrer neuen Anwendung zugeordnet. Er wird in Leistungsindikatoren sowie an 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 ein Linux-Gastbetriebssystem verwendet das VSOCK-Protokoll, mit dem die Adressierung über svm_cid und svm_port anstatt über GUIDs erfolgt. Um diese Inkonsistenz mit Windows zu überbrücken, wird die bekannte GUID als Dienstvorlage auf dem Host verwendet, der in einen Port auf dem Gast übersetzt wird. Um die die 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
  */

Tipp: Mit folgender Anweisung können Sie eine GUID in PowerShell generieren und in die Zwischenablage kopieren:

(New-Guid).Guid | clip.exe

Erstellen eines Hyper-V-Sockets

Im einfachsten Fall erfordert die Definition eines Sockets eine Adressfamilie, einen Verbindungstyp und ein Protokoll.

Hier sehen Sie 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 ein Hyper-V-Socket:

  • Adressfamilie: AF_HYPERV (Windows) oder AF_VSOCK (Linux-Gastbetriebssystem)
  • Typ: SOCK_STREAM
  • Protokoll – HV_PROTOCOL_RAW (Windows) oder 0 (Linux-Gastbetriebssystem)

Hier sehen Sie eine Beispieldeklaration/-instanziierung:

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

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

Herstellen einer Bindung an ein Hyper-V-Socket

Über eine Bindung wird ein Socket mit Verbindungsinformationen verknüpft.

Nachstehend finden Sie die Funktionsdefinition. Weitere Informationen zu Bindungen erhalten 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 standardmäßige IP-Adressfamilie (AF_INET), die aus der IP-Adresse des Hostcomputers und einer Portnummer auf diesem Host besteht, setzt sich die Socketadresse für AF_HYPERV aus der ID des virtuellen Computers und der zuvor definierten Anwendungs-ID zusammen, um eine Verbindung herzustellen. Wenn die Bindung von einem Linux-Gastbetriebssystem erfolgt, verwendet AF_VSOCKsvm_cid und svm_port.

Da Hyper-V-Sockets nicht von einen Netzwerkstapel, TCP/IP, DNS usw. abhängen, benötigt der Socket-Endpunkt ein Format ohne IP-Adresse und Hostnamen, mit dem die Verbindung dennoch eindeutig beschrieben wird.

Hier die Definition der 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 von IP-Adresse oder Hostname arbeiten AF_HYPERV-Endpunkte hauptsächlich mit zwei GUIDs:

  • VM-ID: Dies ist die eindeutige ID, die VM-bezogen zugewiesen wird. Eine VM-ID kann mit dem folgenden PowerShell-Codeausschnitt gefunden werden.

    (Get-VM -Name $VMName).Id
    
  • Dienst-ID: Zuvor beschriebene GUID, mit der die Anwendung in der Registrierung des Hyper-V-Hosts registriert wird.

Es stehen auch verschiedene Platzhalter für VM-IDs zur Verfügung, wenn keine Verbindung mit einem spezifischen virtuellen Computer besteht.

VMID Wildcards

Name GUID Beschreibung
HV_GUID_ZERO 00000000-0000-0000-0000-000000000000 Listener müssen eine Bindung mit dieser VM-ID herstellen, um Verbindungen von allen Partitionen zu akzeptieren.
HV_GUID_WILDCARD 00000000-0000-0000-0000-000000000000 Listener müssen eine Bindung mit dieser VM-ID herstellen, um Verbindungen von allen Partitionen zu akzeptieren.
HV_GUID_BROADCAST FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
HV_GUID_CHILDREN 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd Platzhalteradresse für untergeordnete Elemente. Listener müssen eine Bindung mit dieser VM-ID herstellen, um Verbindungen von allen untergeordneten Partitionen zu akzeptieren.
HV_GUID_LOOPBACK e0e16197-dd56-4a10-9195-5ee7a155a838 Loopbackadresse. Bei Verwenden dieser VM-ID wird eine Verbindung mit derselben Partition wie bei Verwenden des Connectors hergestellt.
HV_GUID_PARENT a42e7cda-d03f-480c-9cc2-a4de20abb878 Übergeordnete Adresse. Bei Verwenden dieser VmId wird eine Verbindung mit der übergeordneten Partition des Connectors hergestellt.*

* 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 mithilfe eines Containers, in dem ein virtueller Computer ausgeführt wird, erfolgt eine Verbindung mit der VM, die den Container hostet. Beim Überwachen auf diese VM-ID werden Verbindungen von folgenden Quellen akzeptiert: (in Containern): Containerhost. (Innerhalb der VM: Containerhost/kein Container): VM-Host. (Außerhalb der VM: Containerhost/kein Container): Nicht unterstützt.

Unterstützte Socketbefehle

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

Socketoptionen für HvSocket

Name Typ Beschreibung
HVSOCKET_CONNECTED_SUSPEND ULONG Wenn diese Socketoption auf einen Wert ungleich null festgelegt ist, wird die Socketverbindung nicht getrennt, wenn der virtuelle Computer angehalten wird.

Vollständige WinSock-API

Referenz für Hyper-V-Integrationsdienste