[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH] Don't restore settings from emulated device more than once



If, for some reason, the VM boots with emulated networking then network
settings will be saved from the emulated network device. Then, when the
VM reboots with PV networking, those settings are restored to the PV
network device regardless of whether it was freshly installed or has
been around for some time.

This patch makes sure that settings are restored only to a freshly
installed PV device.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/driver.c   | 48 +++++++++++++++++++++++++++++++++++++
 src/xenvif/driver.h   |  5 ++++
 src/xenvif/pdo.c      | 65 +++++++++++++++++++++++++++++++++------------------
 src/xenvif/settings.c | 60 +++++++++++++++++++++++------------------------
 src/xenvif/settings.h | 24 +++++++++----------
 5 files changed, 136 insertions(+), 66 deletions(-)

diff --git a/src/xenvif/driver.c b/src/xenvif/driver.c
index 7b13521..43a9c7b 100644
--- a/src/xenvif/driver.c
+++ b/src/xenvif/driver.c
@@ -47,6 +47,7 @@ typedef struct _XENVIF_DRIVER {
     PDRIVER_OBJECT      DriverObject;
     HANDLE              ParametersKey;
     HANDLE              AddressesKey;
+    HANDLE              SettingsKey;
     BOOLEAN             NeedReboot;
 } XENVIF_DRIVER, *PXENVIF_DRIVER;
 
@@ -142,6 +143,30 @@ DriverGetAddressesKey(
     return __DriverGetAddressesKey();
 }
 
+static FORCEINLINE VOID
+__DriverSetSettingsKey(
+    IN  HANDLE  Key
+    )
+{
+    Driver.SettingsKey = Key;
+}
+
+static FORCEINLINE HANDLE
+__DriverGetSettingsKey(
+    VOID
+    )
+{
+    return Driver.SettingsKey;
+}
+
+HANDLE
+DriverGetSettingsKey(
+    VOID
+    )
+{
+    return __DriverGetSettingsKey();
+}
+
 #define MAXNAMELEN  256
 
 static FORCEINLINE VOID
@@ -239,6 +264,7 @@ DriverUnload(
     IN  PDRIVER_OBJECT  DriverObject
     )
 {
+    HANDLE              SettingsKey;
     HANDLE              AddressesKey;
     HANDLE              ParametersKey;
 
@@ -248,6 +274,11 @@ DriverUnload(
 
     Driver.NeedReboot = FALSE;
 
+    SettingsKey = __DriverGetSettingsKey();
+    __DriverSetSettingsKey(NULL);
+
+    RegistryCloseKey(SettingsKey);
+
     AddressesKey = __DriverGetAddressesKey();
     __DriverSetAddressesKey(NULL);
 
@@ -360,6 +391,7 @@ DriverEntry(
     HANDLE              ServiceKey;
     HANDLE              ParametersKey;
     HANDLE              AddressesKey;
+    HANDLE              SettingsKey;
     ULONG               Index;
     NTSTATUS            status;
 
@@ -409,6 +441,15 @@ DriverEntry(
 
     __DriverSetAddressesKey(AddressesKey);
 
+    status = RegistryCreateSubKey(ServiceKey,
+                                  "Settings",
+                                  REG_OPTION_NON_VOLATILE,
+                                  &SettingsKey);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    __DriverSetSettingsKey(SettingsKey);
+
     RegistryCloseKey(ServiceKey);
 
     DriverObject->DriverExtension->AddDevice = AddDevice;
@@ -423,6 +464,13 @@ DriverEntry(
 
     return STATUS_SUCCESS;
 
+fail5:
+    Error("fail5\n");
+
+    __DriverSetAddressesKey(NULL);
+
+    RegistryCloseKey(AddressesKey);
+
 fail4:
     Error("fail4\n");
 
diff --git a/src/xenvif/driver.h b/src/xenvif/driver.h
index b2f1615..0d7ca8d 100644
--- a/src/xenvif/driver.h
+++ b/src/xenvif/driver.h
@@ -52,6 +52,11 @@ DriverGetAddressesKey(
     VOID
     );
 
+extern HANDLE
+DriverGetSettingsKey(
+    VOID
+    );
+
 extern VOID
 DriverRequestReboot(
     VOID
diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c
index 1b773a1..8e46566 100644
--- a/src/xenvif/pdo.c
+++ b/src/xenvif/pdo.c
@@ -1220,6 +1220,7 @@ PdoStartDevice(
     PIO_STACK_LOCATION  StackLocation;
     HANDLE              SoftwareKey;
     HANDLE              HardwareKey;
+    ULONG               HasSettings;
     GUID                Guid;
     NTSTATUS            status;
 
@@ -1274,11 +1275,12 @@ PdoStartDevice(
     for (Index = 0; Index < Table->NumEntries; Index++) {
         PMIB_IF_ROW2    Row = &Table->Table[Index];
 
-        if (!(Row->InterfaceAndOperStatusFlags.HardwareInterface) ||
-            !(Row->InterfaceAndOperStatusFlags.ConnectorPresent))
-            continue;
+        Trace("%s: CHECKING %ws (%ws)\n",
+              __PdoGetName(Pdo),
+              Row->Alias,
+              Row->Description);
 
-        if (Row->OperStatus != IfOperStatusUp)
+        if (!Row->InterfaceAndOperStatusFlags.ConnectorPresent)
             continue;
 
         if (Row->PhysicalAddressLength != sizeof (ETHERNET_ADDRESS))
@@ -1289,7 +1291,10 @@ PdoStartDevice(
                    sizeof (ETHERNET_ADDRESS)) != 0)
             continue;
 
-        (VOID) SettingsSave(SoftwareKey,
+        if (Row->OperStatus != IfOperStatusUp)
+            continue;
+
+        (VOID) SettingsSave(__PdoGetName(Pdo),
                             Row->Alias,
                             Row->Description,
                             &Row->InterfaceGuid,
@@ -1306,24 +1311,38 @@ PdoStartDevice(
         goto fail9;
     }
 
-    //
-    // If there is a stack bound then restore any settings that
-    // may have been saved from an aliasing emulated device.
-    //
-    status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid);
-    if (NT_SUCCESS(status)) {
-        for (Index = 0; Index < Table->NumEntries; Index++) {
-            PMIB_IF_ROW2    Row = &Table->Table[Index];
-
-            if (!IsEqualGUID(&Row->InterfaceGuid, &Guid))
-                continue;
-
-            (VOID) SettingsRestore(SoftwareKey,
-                                   Row->Alias,
-                                   Row->Description,
-                                   &Row->InterfaceGuid,
-                                   &Row->InterfaceLuid);
-            break;
+    status = RegistryQueryDwordValue(SoftwareKey,
+                                     "HasSettings",
+                                     &HasSettings);
+    if (!NT_SUCCESS(status))
+        HasSettings = 0;
+
+    if (HasSettings == 0) {
+        //
+        // If there is a stack bound then restore any settings that
+        // may have been saved from an aliasing emulated device.
+        //
+        status = PdoGetInterfaceGuid(Pdo, SoftwareKey, &Guid);
+        if (NT_SUCCESS(status)) {
+            for (Index = 0; Index < Table->NumEntries; Index++) {
+                PMIB_IF_ROW2    Row = &Table->Table[Index];
+
+                if (!IsEqualGUID(&Row->InterfaceGuid, &Guid))
+                    continue;
+
+                (VOID) SettingsRestore(__PdoGetName(Pdo),
+                                       Row->Alias,
+                                       Row->Description,
+                                       &Row->InterfaceGuid,
+                                       &Row->InterfaceLuid);
+                break;
+            }
+
+            HasSettings = 1;
+
+            (VOID) RegistryUpdateDwordValue(SoftwareKey,
+                                            "HasSettings",
+                                             HasSettings);
         }
     }
 
diff --git a/src/xenvif/settings.c b/src/xenvif/settings.c
index 5cb9984..214248b 100644
--- a/src/xenvif/settings.c
+++ b/src/xenvif/settings.c
@@ -245,9 +245,6 @@ SettingsCopyInterface(
 
     RegistryCloseKey(SaveKey);
 
-    if (!Save)
-        (VOID) RegistryDeleteSubKey(SettingsKey, SaveKeyName);
-
     RegistryCloseKey(Key);
 
     __SettingsFree(KeyName);
@@ -467,9 +464,6 @@ SettingsCopyIpAddresses(
 
     RegistryCloseKey(SaveKey);
 
-    if (!Save)
-        (VOID) RegistryDeleteSubKey(SettingsKey, (PCHAR)SaveKeyName);
-
     __SettingsFree(ValuePrefix);
 
     RegistryCloseKey(Key);
@@ -540,28 +534,31 @@ SettingsCopy(
 
 NTSTATUS
 SettingsSave(
-     IN HANDLE      SoftwareKey,
-     IN PWCHAR      Alias,
-     IN PWCHAR      Description,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid
-     )
+    IN  PCHAR       SubKeyName,
+    IN  PWCHAR      Alias,
+    IN  PWCHAR      Description,
+    IN  LPGUID      InterfaceGuid,
+    IN  PNET_LUID   InterfaceLuid
+    )
 {
     HANDLE          SettingsKey;
+    HANDLE          SubKey;
     NTSTATUS        status;
 
     Info("FROM %ws (%ws)\n", Alias, Description);
 
-    status = RegistryCreateSubKey(SoftwareKey,
-                                  "Settings",
+    SettingsKey = DriverGetSettingsKey();
+
+    status = RegistryCreateSubKey(SettingsKey,
+                                  SubKeyName,
                                   REG_OPTION_NON_VOLATILE,
-                                  &SettingsKey);
+                                  &SubKey);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, TRUE);
+    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, TRUE);
 
-    RegistryCloseKey(SettingsKey);
+    RegistryCloseKey(SubKey);
 
     return STATUS_SUCCESS;
 
@@ -573,20 +570,23 @@ fail1:
 
 NTSTATUS
 SettingsRestore(
-     IN HANDLE      SoftwareKey,
-     IN PWCHAR      Alias,
-     IN PWCHAR      Description,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid
-     )
+    IN  PCHAR       SubKeyName,
+    IN  PWCHAR      Alias,
+    IN  PWCHAR      Description,
+    IN  LPGUID      InterfaceGuid,
+    IN  PNET_LUID   InterfaceLuid
+    )
 {
     HANDLE          SettingsKey;
+    HANDLE          SubKey;
     NTSTATUS        status;
 
-    status = RegistryOpenSubKey(SoftwareKey,
-                                "Settings",
-                                KEY_ALL_ACCESS,
-                                &SettingsKey);
+    SettingsKey = DriverGetSettingsKey();
+
+    status = RegistryOpenSubKey(SettingsKey,
+                                SubKeyName,
+                                KEY_READ,
+                                &SubKey);
     if (!NT_SUCCESS(status)) {
         if (status == STATUS_OBJECT_NAME_NOT_FOUND)
             goto done;
@@ -596,11 +596,9 @@ SettingsRestore(
 
     Info("TO %ws (%ws)\n", Alias, Description);
 
-    SettingsCopy(SettingsKey, InterfaceGuid, InterfaceLuid, FALSE);
-
-    RegistryCloseKey(SettingsKey);
+    SettingsCopy(SubKey, InterfaceGuid, InterfaceLuid, FALSE);
 
-    (VOID) RegistryDeleteSubKey(SoftwareKey, "Settings");
+    RegistryCloseKey(SubKey);
 
 done:
     return STATUS_SUCCESS;
diff --git a/src/xenvif/settings.h b/src/xenvif/settings.h
index 7bd1824..a77ef00 100644
--- a/src/xenvif/settings.h
+++ b/src/xenvif/settings.h
@@ -34,20 +34,20 @@
 
 extern NTSTATUS
 SettingsSave(
-     IN HANDLE      SoftwareKey,
-     IN PWCHAR      Alias,
-     IN PWCHAR      Description,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid
-     );
+    IN  PCHAR       SubKeyName,
+    IN  PWCHAR      Alias,
+    IN  PWCHAR      Description,
+    IN  LPGUID      InterfaceGuid,
+    IN  PNET_LUID   InterfaceLuid
+    );
 
 extern NTSTATUS
 SettingsRestore(
-     IN HANDLE      SoftwareKey,
-     IN PWCHAR      Alias,
-     IN PWCHAR      Description,
-     IN LPGUID      InterfaceGuid,
-     IN PNET_LUID   InterfaceLuid
-     );
+    IN  PCHAR       SubKeyName,
+    IN  PWCHAR      Alias,
+    IN  PWCHAR      Description,
+    IN  LPGUID      InterfaceGuid,
+    IN  PNET_LUID   InterfaceLuid
+    );
 
 #endif  // _XENVIF_SETTINGS_H
-- 
2.5.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.