Dela via


Skapa egna integrationstjänster

Från och med Windows 10 Anniversary Update kan vem som helst skapa applikationer som kommunicerar mellan Hyper-V-värdar och deras virtuella datorer med hjälp av Hyper-V-sockets – en Windows Socket med en ny adressfamilj och specialiserad endpoint för att kommunicera med virtuella datorer. All kommunikation över Hyper-V sockets körs utan nätverk och alla data förblir på samma fysiska minne. Program som använder Hyper-V sockets liknar Hyper-V:s integreringstjänster.

Det här dokumentet beskriver hur du skapar ett enkelt program som bygger på Hyper-V sockets.

Värdoperativsystem som stöds

  • Windows 10 och senare
  • Windows Server 2016 och senare

Gästoperativsystem som stöds

Anmärkning

En Linux-gäst som stöds måste ha kernelstöd för:

CONFIG_VSOCKET=y
CONFIG_HYPERV_VSOCKETS=y

Funktioner och begränsningar

  • Stöder åtgärder i kernelläge eller användarläge
  • Endast dataström
  • Inget blockminne (inte det bästa för säkerhetskopiering/video)

Komma igång

Krav:

  • C/C++-kompilator. Om du inte har en kan du checka ut Visual Studio Community
  • Windows SDK – förinstallerat i Visual Studio 2015 med uppdatering 3 och senare.
  • En dator som kör ett av de angivna värdoperativsystemen och har minst en virtuell dator. - detta är för att testa ditt program.

Observera: API för Hyper-V sockets blev offentligt tillgängligt i Windows 10 Anniversary Update. Program som använder HVSocket körs på valfri Windows 10-värd och -gäst, men kan bara utvecklas med en Windows SDK senare än version 14290.

Registrera ett nytt program

För att kunna använda Hyper-V sockets måste programmet registreras med Hyper-V Värdens register.

Genom att registrera tjänsten i registret får du:

  • WMI-hantering för att aktivera, inaktivera och visa tillgängliga tjänster
  • Behörighet att kommunicera direkt med virtuella datorer

Följande PowerShell registrerar ett nytt program med namnet "HV Socket Demo". Detta måste köras som administratör. Manuella instruktioner nedan.

$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

Registerplats och information:

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

På den här registerplatsen visas flera GUID:er. Det är våra inkorgstjänster.

Information i registret per tjänst:

  • Service GUID
    • ElementName (REG_SZ) - Det här är tjänstens vänliga namn

Om du vill registrera din egen tjänst skapar du en ny registernyckel med ditt eget GUID och ett vänligt namn.

Det användarvänliga namnet kommer att associeras med din nya applikation. Det visas i prestandaräknare och andra platser där ett GUID inte är lämpligt.

Registerposten ser ut så här:

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

Anmärkning

Tjänst-GUID för en Linux-gäst använder VSOCK-protokollet som adresserar via ett svm_cid och svm_port snarare än ett guids. För att överbrygga den här inkonsekvensen med Windows används det välkända GUID:et som tjänstmall på värden och som sedan översätts till en port i gästoperativsystemet. Om du vill anpassa tjänst-GUID ändrar du helt enkelt det första "00000000" till önskat portnummer. T.ex. "00000ac9" är 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
  */

Tips: Om du vill generera ett GUID i PowerShell och kopiera det till urklipp kör du:

(New-Guid).Guid | clip.exe

Skapa en Hyper-V socket

I det mest grundläggande fallet kräver definitionen av en socket en adressfamilj, anslutningstyp och protokoll.

Här är en enkel 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 en Hyper-V socket:

  • Adressfamilj – AF_HYPERV (Windows) eller AF_VSOCK (Linux-gäst)
  • typ- SOCK_STREAM
  • protocol – HV_PROTOCOL_RAW (Windows) eller 0 (Linux-gäst)

Här är ett exempel på en deklaration/instansiering:

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

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

Binda till en Hyper-V socket

Bind associerar en socket med anslutningsinformation.

Funktionsdefinitionen kopieras nedan för konvektion, läs mer om bindning här.

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

Till skillnad från socketadressen (sockaddr) för en standardadressfamilj för Internet Protocol (AF_INET) som består av värddatorns IP-adress och ett portnummer på värden använder socketadressen för den virtuella datorns ID och det program-ID som definieras ovan för AF_HYPERV att upprätta en anslutning. Om bindning från en Linux-gäst AF_VSOCK använder svm_cid och svm_port.

Eftersom Hyper-V socketar inte är beroende av en nätverksstack, TCP/IP, DNS osv. behövde socketslutpunkten ett icke-IP-format, inte värdnamn, som fortfarande entydigt beskriver anslutningen.

Här är definitionen för en Hyper-V sockets socketadress:

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

I stället för ett IP- eller värdnamn är AF_HYPERV slutpunkter starkt beroende av två GUID:er:

  • VM-ID – det här är det unika ID som tilldelats per virtuell dator. Du hittar en virtuell dators ID med hjälp av följande PowerShell-kodfragment.

    (Get-VM -Name $VMName).Id
    
  • Tjänst-ID – GUID, som beskrivs ovan, med vilket programmet är registrerat i Hyper-V värdregistret.

Det finns också en uppsättning VMID-jokertecken tillgängliga när en anslutning inte är till en specifik virtuell dator.

VMID-jokertecken

Namn GUID Description
HV_GUID_ZERO 00000000-0000-0000-0000-000000000000 Lyssnare bör binda till detta VmId för att acceptera anslutning från alla partitioner.
HV_GUID_WILDCARD 00000000-0000-0000-0000-000000000000 Lyssnare bör binda till detta VmId för att acceptera anslutning från alla partitioner.
HV_GUID_BROADCAST FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
HV_GUID_CHILDREN 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd Wildcardadress för barn. Lyssnare bör ansluta till detta VmId för att acceptera anslutningar från sina underordnade.
HV_GUID_LOOPBACK e0e16197-dd56-4a10-9195-5ee7a155a838 Loopback-adress. Med det här VmId ansluter du till samma partition som anslutningsappen.
HV_GUID_PARENT a42e7cda-d03f-480c-9cc2-a4de20abb878 Föräldradress Med hjälp av detta VmId ansluter du till den överordnade partitionen av connectorn.*

* HV_GUID_PARENT Den överordnade noden för en virtuell dator är dess värd. En containers förälder är containerns värd. Om du ansluter från en container som körs på en virtuell dator kommer att anslutas till den virtuella maskin som är värd för containern. Om du lyssnar på det här VmId:et accepteras anslutningen från: (Inuti containrar): Containervärd. (Inuti virtuell dator: Containervärd/ingen container): VM-värd. (Inte i VM: Containerhost/ingen container): Stöds inte.

Socket-kommandon som stöds

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

Alternativ för HvSocket Socket

Namn Typ Description
HVSOCKET_CONNECTED_SUSPEND ULONG När det här socketalternativet är inställt på ett värde som inte är noll, kopplas socketar inte från när den virtuella maskinen pausas.

Fullständigt WinSock-API

Hyper-V Integration Services-referens