]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Publish distribution information to xenstore
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 24 Nov 2015 11:52:50 +0000 (11:52 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Tue, 24 Nov 2015 12:00:18 +0000 (12:00 +0000)
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 XENBUS driver package.

Suggested-by: Owen Smith <owen.smith@citrix.com>
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
src/xenbus/fdo.c

index 354438f446d47e9cebccc760ff55316a6908b347..a9650e32c30f7f4bc16e87006a6e9cc7ae892c05 100644 (file)
@@ -2414,7 +2414,221 @@ FdoEvtchnCallback(
     return TRUE;
 }
 
-#define BALLOON_PAUSE   60
+static FORCEINLINE BOOLEAN
+__FdoMatchDistribution(
+    IN  PXENBUS_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(Text[Index])) {
+            if (Vendor[Index] != '_') {
+                Match = FALSE;
+                break;
+            }
+        } else {
+            if (Vendor[Index] != Text[Index]) {
+                Match = FALSE;
+                break;
+            }
+        }
+    }
+
+    Text = "XENBUS";
+
+    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  PXENBUS_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  PXENBUS_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(Vendor[Index]))
+            Vendor[Index] = '_';
+
+    Product = "XENBUS";
+
+#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(
@@ -2427,6 +2641,8 @@ __FdoD3ToD0(
 
     ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
 
+    (VOID) FdoSetDistribution(Fdo);
+
     Fdo->Channel = XENBUS_EVTCHN(Open,
                                  &Fdo->EvtchnInterface,
                                  XENBUS_EVTCHN_TYPE_VIRQ,
@@ -2571,6 +2787,8 @@ __FdoD0ToD3(
                   Fdo->Channel);
     Fdo->Channel = NULL;
 
+    FdoClearDistribution(Fdo);
+
     Trace("<====\n");
 }
 
@@ -3049,6 +3267,8 @@ FdoFilterCmPartialResourceList(
     }
 }
 
+#define BALLOON_PAUSE   60
+
 static NTSTATUS
 FdoStartDevice(
     IN  PXENBUS_FDO                 Fdo,