The Boot#### variables that have become unreferenced in the new BootOrder
variable won't ever be automatically reused for booting. They are
"unreachable" resources that take up room in the variable store. Make an
effort to remove them.

This should plug the leak which, given sufficient reboots, exhausts the
variable store with stale Boot#### variables and renders the VM
unbootable.

Reported-by: Michael Chang <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <[email protected]>
---
 OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c | 54 +++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 6 deletions(-)

diff --git a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c 
b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
index c8379b8..7f81fc3 100644
--- a/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
+++ b/OvmfPkg/Library/PlatformBdsLib/QemuBootOrder.c
@@ -1119,10 +1119,51 @@ BootOrderComplete (
   return Status;
 }
 
 
 /**
+  Delete Boot#### variables that stand for such active boot options that have
+  been dropped (ie. have not been selected by either matching or "survival
+  policy").
+
+  @param[in]  ActiveOption  The array of active boot options to scan. Each
+                            entry not marked as appended will trigger the
+                            deletion of the matching Boot#### variable.
+
+  @param[in]  ActiveCount   Number of elements in ActiveOption.
+**/
+STATIC
+VOID
+PruneBootVariables (
+  IN  CONST ACTIVE_OPTION *ActiveOption,
+  IN  UINTN               ActiveCount
+  )
+{
+  UINTN Idx;
+
+  for (Idx = 0; Idx < ActiveCount; ++Idx) {
+    if (!ActiveOption[Idx].Appended) {
+      CHAR16 VariableName[9];
+
+      UnicodeSPrintAsciiFormat (VariableName, sizeof VariableName, "Boot%04x",
+        ActiveOption[Idx].BootOption->BootCurrent);
+
+      //
+      // "The space consumed by the deleted variable may not be available until
+      // the next power cycle", but that's good enough.
+      //
+      gRT->SetVariable (VariableName, &gEfiGlobalVariableGuid,
+             0,   // Attributes, 0 means deletion
+             0,   // DataSize, 0 means deletion
+             NULL // Data
+             );
+    }
+  }
+}
+
+
+/**
 
   Set the boot order based on configuration retrieved from QEMU.
 
   Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate the
   OpenFirmware device paths therein to UEFI device path fragments. Match the
@@ -1267,16 +1308,17 @@ SetBootOrderFromQemu (
                       EFI_VARIABLE_BOOTSERVICE_ACCESS |
                       EFI_VARIABLE_RUNTIME_ACCESS,
                     BootOrder.Produced * sizeof (*BootOrder.Data),
                     BootOrder.Data
                     );
-    DEBUG ((
-      DEBUG_INFO,
-      "%a: setting BootOrder: %a\n",
-      __FUNCTION__,
-      Status == EFI_SUCCESS ? "success" : "error"
-      ));
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: setting BootOrder: %r\n", __FUNCTION__, 
Status));
+      goto ErrorFreeActiveOption;
+    }
+
+    DEBUG ((DEBUG_INFO, "%a: setting BootOrder: success\n", __FUNCTION__));
+    PruneBootVariables (ActiveOption, ActiveCount);
   }
 
 ErrorFreeActiveOption:
   FreePool (ActiveOption);
 
-- 
1.8.3.1


------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to