From 1a3c1315d2c2c594714736b6d36554482a2de469 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Fri, 1 Nov 2024 09:35:33 +0100 Subject: [PATCH] Terminate programs in namespaces before deleting them --- main.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/main.go b/main.go index 6e3f1e1..85ddd3b 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,9 @@ import ( "os" "os/exec" "path/filepath" + "strconv" + "strings" + "syscall" ) func main() { @@ -42,6 +45,16 @@ func main() { // One namespace per node, named as the node's name ns := node.Name if netnsExists(ns) { + // Terminate processes in old namespaces + for _, x := range netnsPids(ns) { + log.Printf(" Killing old PID %d", x) + err := syscall.Kill(x, syscall.SIGTERM) + if err != nil { + log.Fatalf("failed to kill %d: %v", x, err) + } + // Also try SIGHUP to terminate shells which ignore SIGTERM + _ = syscall.Kill(x, syscall.SIGHUP) + } // Prevent any conflicts with existing data ip("netns", "del", ns) // Don't remove anything in /etc/netns/ as the user might store @@ -135,6 +148,30 @@ func netnsExists(name string) bool { return true } +func netnsPids(netns string) []int { + args := []string{"netns", "pids", netns} + xargs := append([]string{"ip"}, args...) + + cmd := exec.Command("ip", args...) + out, err := cmd.Output() + if err != nil { + log.Fatalf("failed to run %q: %v", xargs, err) + } + + var res []int + xs := strings.FieldsFunc(string(out), func(c rune) bool { + return c == '\n' + }) + for _, x := range xs { + y, err := strconv.Atoi(x) + if err != nil { + log.Fatal(err) + } + res = append(res, y) + } + return res +} + func ifaceExists(netns, name string) bool { args := []string{"-n", netns, "-json", "link"} xargs := append([]string{"ip"}, args...) -- 2.45.2