From 0e24d86aa87b013964dd0445f0fa435405c07a99 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Tue, 24 Nov 2015 13:40:30 +0000 Subject: [PATCH] Publish distribution information to xenstore My recent patch series to Xen added a documented path and format for publishing information about PV driver distributions to xenstore. This patch adds code to populate the documented path (should it exist) with information about the XENVIF driver package. Suggested-by: Owen Smith Signed-off-by: Paul Durrant --- src/xenvif/fdo.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/src/xenvif/fdo.c b/src/xenvif/fdo.c index 67916d6..0e69ba6 100644 --- a/src/xenvif/fdo.c +++ b/src/xenvif/fdo.c @@ -1080,6 +1080,222 @@ FdoParseResources( } } +static FORCEINLINE BOOLEAN +__FdoMatchDistribution( + IN PXENVIF_FDO Fdo, + IN PCHAR Buffer + ) +{ + PCHAR Vendor; + PCHAR Product; + PCHAR Context; + const CHAR *Text; + BOOLEAN Match; + ULONG Index; + NTSTATUS status; + + UNREFERENCED_PARAMETER(Fdo); + + status = STATUS_INVALID_PARAMETER; + + Vendor = __strtok_r(Buffer, " ", &Context); + if (Vendor == NULL) + goto fail1; + + Product = __strtok_r(NULL, " ", &Context); + if (Product == NULL) + goto fail2; + + Match = TRUE; + + Text = VENDOR_NAME_STR; + + for (Index = 0; Text[Index] != 0; Index++) { + if (!isalnum((UCHAR)Text[Index])) { + if (Vendor[Index] != '_') { + Match = FALSE; + break; + } + } else { + if (Vendor[Index] != Text[Index]) { + Match = FALSE; + break; + } + } + } + + Text = "XENVIF"; + + if (_stricmp(Product, Text) != 0) + Match = FALSE; + + return Match; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + + return FALSE; +} + +static VOID +FdoClearDistribution( + IN PXENVIF_FDO Fdo + ) +{ + PCHAR Buffer; + PANSI_STRING Distributions; + ULONG Index; + NTSTATUS status; + + Trace("====>\n"); + + status = XENBUS_STORE(Directory, + &Fdo->StoreInterface, + NULL, + NULL, + "drivers", + &Buffer); + if (NT_SUCCESS(status)) { + Distributions = __FdoMultiSzToUpcaseAnsi(Buffer); + + XENBUS_STORE(Free, + &Fdo->StoreInterface, + Buffer); + } else { + Distributions = NULL; + } + + if (Distributions == NULL) + goto done; + + for (Index = 0; Distributions[Index].Buffer != NULL; Index++) { + PANSI_STRING Distribution = &Distributions[Index]; + + status = XENBUS_STORE(Read, + &Fdo->StoreInterface, + NULL, + "drivers", + Distribution->Buffer, + &Buffer); + if (!NT_SUCCESS(status)) + continue; + + if (__FdoMatchDistribution(Fdo, Buffer)) + (VOID) XENBUS_STORE(Remove, + &Fdo->StoreInterface, + NULL, + "drivers", + Distribution->Buffer); + + XENBUS_STORE(Free, + &Fdo->StoreInterface, + Buffer); + } + + __FdoFreeAnsi(Distributions); + +done: + Trace("<====\n"); +} + +#define MAXIMUM_INDEX 255 + +static NTSTATUS +FdoSetDistribution( + IN PXENVIF_FDO Fdo + ) +{ + ULONG Index; + CHAR Distribution[MAXNAMELEN]; + CHAR Vendor[MAXNAMELEN]; + const CHAR *Product; + NTSTATUS status; + + Trace("====>\n"); + + Index = 0; + while (Index <= MAXIMUM_INDEX) { + PCHAR Buffer; + + status = RtlStringCbPrintfA(Distribution, + MAXNAMELEN, + "%u", + Index); + ASSERT(NT_SUCCESS(status)); + + status = XENBUS_STORE(Read, + &Fdo->StoreInterface, + NULL, + "drivers", + Distribution, + &Buffer); + if (!NT_SUCCESS(status)) { + if (status == STATUS_OBJECT_NAME_NOT_FOUND) + goto update; + + goto fail1; + } + + XENBUS_STORE(Free, + &Fdo->StoreInterface, + Buffer); + + Index++; + } + + status = STATUS_UNSUCCESSFUL; + goto fail2; + +update: + status = RtlStringCbPrintfA(Vendor, + MAXNAMELEN, + "%s", + VENDOR_NAME_STR); + ASSERT(NT_SUCCESS(status)); + + for (Index = 0; Vendor[Index] != '\0'; Index++) + if (!isalnum((UCHAR)Vendor[Index])) + Vendor[Index] = '_'; + + Product = "XENVIF"; + +#if DBG +#define ATTRIBUTES "(DEBUG)" +#else +#define ATTRIBUTES "" +#endif + + (VOID) XENBUS_STORE(Printf, + &Fdo->StoreInterface, + NULL, + "drivers", + Distribution, + "%s %s %u.%u.%u %s", + Vendor, + Product, + MAJOR_VERSION, + MINOR_VERSION, + MICRO_VERSION, + ATTRIBUTES + ); + +#undef ATTRIBUTES + + Trace("<====\n"); + return STATUS_SUCCESS; + +fail2: + Error("fail2\n"); + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + static FORCEINLINE NTSTATUS __FdoD3ToD0( IN PXENVIF_FDO Fdo @@ -1091,6 +1307,8 @@ __FdoD3ToD0( ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL); + (VOID) FdoSetDistribution(Fdo); + status = XENBUS_STORE(WatchAdd, &Fdo->StoreInterface, "device", @@ -1124,6 +1342,8 @@ __FdoD0ToD3( Fdo->ScanWatch); Fdo->ScanWatch = NULL; + FdoClearDistribution(Fdo); + Trace("<====\n"); } -- 2.39.5