]> xenbits.xensource.com Git - people/pauldu/xenvif.git/commitdiff
Don't restore settings from emulated device more than once
authorPaul Durrant <paul.durrant@citrix.com>
Thu, 8 Sep 2016 10:09:17 +0000 (11:09 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 8 Sep 2016 10:09:17 +0000 (11:09 +0100)
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@citrix.com>
src/xenvif/driver.c
src/xenvif/driver.h
src/xenvif/pdo.c
src/xenvif/settings.c
src/xenvif/settings.h

index 7b13521afee001fac17f1d30f2051d65f76b1366..43a9c7b895816ff45d7d87582f51e8593aed0b14 100644 (file)
@@ -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");
 
index b2f1615481dd374d7880c0e55af1ef5faa4bd60e..0d7ca8d2345468202b131f316cb27d14163d3473 100644 (file)
@@ -52,6 +52,11 @@ DriverGetAddressesKey(
     VOID
     );
 
+extern HANDLE
+DriverGetSettingsKey(
+    VOID
+    );
+
 extern VOID
 DriverRequestReboot(
     VOID
index 1b773a1c8d01c72a77d590ff6efa1df95da42ada..8e46566bd50ab6f4c2b25d165d8f4a4936ec8868 100644 (file)
@@ -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);
         }
     }
 
index 5cb99840cd5bdfcb9e6054d28c0c910366d42f8b..214248b307d09ab86f86b6de70118d9345d07333 100644 (file)
@@ -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;
index 7bd1824cde70ef915951cf13fbf9c663f71c9c52..a77ef00806187f967a513c8556c3c60d6c7edaeb 100644 (file)
 
 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