m/n/c/mgmt: disable interfaces before kexec
This is done to prevent network interface DMA transactions from
interfering with an in-progress kexec. [1]
[1] https://lists.infradead.org/pipermail/kexec/2011-January/004795.html
Change-Id: I12ab22c095fcff56873d980d524c461b1b2d57ee
Reviewed-on: https://review.monogon.dev/c/monogon/+/2783
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/metropolis/node/core/mgmt/BUILD.bazel b/metropolis/node/core/mgmt/BUILD.bazel
index e683eee..a274013 100644
--- a/metropolis/node/core/mgmt/BUILD.bazel
+++ b/metropolis/node/core/mgmt/BUILD.bazel
@@ -18,6 +18,7 @@
"//metropolis/pkg/supervisor",
"//metropolis/proto/api",
"//metropolis/proto/common",
+ "@com_github_vishvananda_netlink//:netlink",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes",
"@org_golang_google_grpc//status",
diff --git a/metropolis/node/core/mgmt/update.go b/metropolis/node/core/mgmt/update.go
index 69b8744..ab31682 100644
--- a/metropolis/node/core/mgmt/update.go
+++ b/metropolis/node/core/mgmt/update.go
@@ -4,6 +4,7 @@
"context"
"time"
+ "github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -40,9 +41,29 @@
s.LogTree.MustLeveledFor("update").Info("activating now...")
unix.Unmount(s.UpdateService.ESPPath, 0)
unix.Sync()
+ disableNetworkInterfaces()
unix.Reboot(method)
}()
}
return &apb.UpdateNodeResponse{}, nil
}
+
+// For kexec it's recommended to disable all physical network interfaces
+// before doing it. This function doesn't return any errors as it's best-
+// effort anyways as we cannot reliably log the error anymore.
+func disableNetworkInterfaces() {
+ links, err := netlink.LinkList()
+ if err != nil {
+ return
+ }
+ for _, link := range links {
+ d, ok := link.(*netlink.Device)
+ if !ok {
+ continue
+ }
+ if err := netlink.LinkSetDown(d); err != nil {
+ continue
+ }
+ }
+}