Sdílet prostřednictvím


Vytvoření vlastních integračních služeb

Počínaje Windows 10 Anniversary Update může kdokoli vytvářet aplikace, které komunikují mezi hostitelem Hyper-V a jeho virtuálními počítači pomocí soketů Hyper-V – Windows Socket s novou řadou adres a specializovaným koncovým bodem pro cílení na virtuální počítače. Veškerá komunikace přes Hyper-V sokety běží bez použití sítě a všechna data zůstanou ve stejné fyzické paměti. Aplikace používající Hyper-V sokety se podobají integračním službám Hyper-V.

Tento dokument vás provede vytvořením jednoduchého programu založeného na Hyper-V soketech.

Podporovaný hostitelský operační systém

  • Platforma: Windows 10 a novější
  • Windows Server 2016 a novější

Podporovaný hostovaný operační systém

Poznámka:

Podporovaný host v Linuxu musí mít podporu jádra pro:

CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y

Možnosti a omezení

  • Podporuje akce režimu jádra nebo uživatelského režimu.
  • Pouze datový proud
  • Žádná bloková paměť (není to nejlepší pro zálohování nebo video)

Začínáme

Požadavky:

  • Kompilátor C/C++. Pokud ho nemáte, projděte si Visual Studio Community.
  • Sada Windows SDK – předinstalovaná v sadě Visual Studio 2015 s aktualizací Update 3 a novější.
  • Počítač se spuštěným jedním z hostitelských operačních systémů určeným alespoň jedním virtuálním počítačem. - Toto je pro testování vaší aplikace.

Poznámka: Rozhraní API pro Hyper-V sokety bylo veřejně dostupné ve Windows 10 Anniversary Update. Aplikace, které používají HVSocket, poběží na jakémkoli hostiteli a hostu Windows 10, ale dají se vyvíjet pouze pomocí sady Windows SDK později než build 14290.

Registrace nové aplikace

Aby bylo možné používat sokety Hyper-V, musí být aplikace zaregistrovaná v registru Hyper-V Hostitele.

Registrací služby v registru získáte:

  • Správa rozhraní WMI pro povolení, zakázání a výpis dostupných služeb
  • Oprávnění ke komunikaci s virtuálními počítači přímo

Následující PowerShell zaregistruje novou aplikaci s názvem HV Socket Demo. Musí se spustit jako správce. Níže uvedené ruční pokyny.

$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

Umístění a informace registru:

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

V tomto umístění registru uvidíte několik identifikátorů GUID. To jsou naše boxové služby.

Informace v registru na službu:

  • Service GUID
    • ElementName (REG_SZ) - Toto je popisný název služby.

Pokud chcete zaregistrovat vlastní službu, vytvořte nový klíč registru pomocí vlastního identifikátoru GUID a popisného názvu.

Popisný název bude přidružený k nové aplikaci. Zobrazí se v čítačích výkonu a dalších místech, kde není identifikátor GUID vhodný.

Položka registru vypadá takto:

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

Poznámka:

Identifikátor GUID služby hosta s Linuxem používá protokol VSOCK, který se zabývá prostřednictvím identifikátorů svm_cidsvm_port GUID a nikoli identifikátorů GUID. K přemostění této nekonzistence s Windows se známý identifikátor GUID používá jako šablona služby na hostiteli, který se překládá na port hosta. Pokud chcete přizpůsobit identifikátor GUID služby, jednoduše změňte první hodnotu 00000000 na požadované číslo portu. Příklad: "00000ac9" je 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
  */

Spropitné: Pokud chcete v PowerShellu vygenerovat identifikátor GUID a zkopírovat ho do schránky, spusťte:

(New-Guid).Guid | clip.exe

Vytvoření soketu Hyper-V

V nejzásadnějším případě definování soketu vyžaduje rodinu adres, typ připojení a protokol.

Tady je jednoduchá definice soketu.

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

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

Pro soket Hyper-V:

  • Řada adres – AF_HYPERV (Windows) nebo AF_VSOCK (host v Linuxu)
  • typ- SOCK_STREAM
  • protokol – HV_PROTOCOL_RAW (Windows) nebo 0 (host linuxu)

Tady je příklad deklarace/vytvoření instance:

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

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

Vytvoření vazby k soketu Hyper-V

Vazba přidruží soket k informacím o připojení.

Definice funkce se zkopíruje níže pro konvinience, přečtěte si další informace o vazbě zde.

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

Na rozdíl od adresy soketu (sockaddr) pro standardní řaduAF_INET IP adres protokolu (), která se skládá z IP adresy hostitelského počítače a čísla portu na daném hostiteli, adresa soketu pro AF_HYPERV použití ID virtuálního počítače a ID aplikace definované výše k navázání připojení. Pokud vazba z hosta AF_VSOCK s Linuxem používá a svm_cidsvm_port .

Vzhledem k tomu, že Hyper-V sokety nezávisí na síťovém zásobníku, PROTOKOLU TCP/IP, DNS atd. koncový bod soketu potřeboval jiný než IP, nikoli název hostitele, formát, který stále jednoznačně popisuje připojení.

Tady je definice adresy soketu 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)];
};

V případě IP adresy nebo názvu hostitele se koncové body AF_HYPERV silně spoléhají na dvě identifikátory GUID:

  • ID virtuálního počítače – toto je jedinečné ID přiřazené pro každý virtuální počítač. ID virtuálního počítače najdete pomocí následujícího fragmentu kódu PowerShellu.

    (Get-VM -Name $VMName).Id
    
  • ID služby – IDENTIFIKÁTOR GUID popsaný výše, se kterým je aplikace zaregistrovaná v registru hostitele Hyper-V.

K dispozici je také sada zástupných znaků VMID, pokud připojení není k určitému virtuálnímu počítači.

Zástupné cardy VMID

Název Globálně jedinečný identifikátor (GUID) Popis
HV_GUID_ZERO 00000000-0000-0000-0000-000000000000 Naslouchací procesy by se měly svázat s tímto id virtuálního počítače, aby přijímaly připojení ze všech oddílů.
HV_GUID_WILDCARD 00000000-0000-0000-0000-000000000000 Naslouchací procesy by se měly svázat s tímto id virtuálního počítače, aby přijímaly připojení ze všech oddílů.
HV_GUID_BROADCAST FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
HV_GUID_CHILDREN 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd Adresa se zástupným znakem pro podřízené položky Naslouchací procesy by se měly svázat s tímto id virtuálního počítače, aby přijímaly připojení z podřízených položek.
HV_GUID_LOOPBACK e0e16197-dd56-4a10-9195-5ee7a155a838 Adresa zpětné smyčky. Pomocí tohoto VmId se připojíte ke stejnému oddílu jako konektor.
HV_GUID_PARENT a42e7cda-d03f-480c-9cc2-a4de20abb878 Nadřazená adresa Použití tohoto VmId se připojí k nadřazeného oddílu konektoru.*

* HV_GUID_PARENT Nadřazený objekt virtuálního počítače je jeho hostitelem. Nadřazeným objektem kontejneru je hostitel kontejneru. Připojení z kontejneru spuštěného na virtuálním počítači se připojí k virtuálnímu počítači, který je hostitelem kontejneru. Naslouchání na tomto VmId přijímá připojení z: (Uvnitř kontejnerů): Hostitel kontejneru. (Uvnitř virtuálního počítače: Hostitel kontejneru/ žádný kontejner): Hostitel virtuálního počítače. (Není uvnitř virtuálního počítače: Hostitel kontejneru/ žádný kontejner): Nepodporuje se.

Podporované příkazy soketů

Socket() (zásuvka) Bind() (svázat) Connect() (připojit) Send() (odeslat) Listen() (poslouchat) Accept() (přijmout)

Možnosti soketu HvSocket

Název Typ Popis
HVSOCKET_CONNECTED_SUSPEND ULONG Pokud je tato možnost soketu nastavená na nenulovou hodnotu soketů, při pozastavení virtuálního počítače se neodpojí.

Dokončení rozhraní WINSock API

Referenční informace ke služběHyper-V Integration Services