From 3e1c1730712817d97be9bda1459b18bd93894b59 Mon Sep 17 00:00:00 2001 From: Arian van Putten Date: Fri, 23 Aug 2024 11:37:08 +0200 Subject: [PATCH] daemon: SdNotify: add support for abstract unix sockets As per https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html# --- daemon/sdnotify.go | 23 ++++++++++++++++++----- daemon/sdnotify_test.go | 12 ++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/daemon/sdnotify.go b/daemon/sdnotify.go index ba4ae31f..d2094703 100644 --- a/daemon/sdnotify.go +++ b/daemon/sdnotify.go @@ -54,16 +54,29 @@ const ( // (false, err) - notification supported, but failure happened (e.g. error connecting to NOTIFY_SOCKET or while sending data) // (true, nil) - notification supported, data has been sent func SdNotify(unsetEnvironment bool, state string) (bool, error) { - socketAddr := &net.UnixAddr{ - Name: os.Getenv("NOTIFY_SOCKET"), - Net: "unixgram", - } + notifySocket := os.Getenv("NOTIFY_SOCKET") // NOTIFY_SOCKET not set - if socketAddr.Name == "" { + if notifySocket == "" { + return false, nil + } + + // socket type not supported. We only support unix domain sockets + // but NOTIFY_SOCKET can also use vsock + if notifySocket[0] != '@' && notifySocket[0] != '/' { return false, nil } + // abstract unix socket. Start with a 0-byte + if notifySocket[0] == '@' { + notifySocket = "\x00" + notifySocket[1:] + } + + socketAddr := &net.UnixAddr{ + Name: notifySocket, + Net: "unixgram", + } + if unsetEnvironment { if err := os.Unsetenv("NOTIFY_SOCKET"); err != nil { return false, err diff --git a/daemon/sdnotify_test.go b/daemon/sdnotify_test.go index 0a4cdb74..678d6ace 100644 --- a/daemon/sdnotify_test.go +++ b/daemon/sdnotify_test.go @@ -41,6 +41,14 @@ func TestSdNotify(t *testing.T) { panic(e) } + abstractLAddr := net.UnixAddr{ + Name: "\x00" + notifySocket, + } + _, e = net.ListenUnixgram("unixgram", &abstractLAddr) + if e != nil { + panic(e) + } + tests := []struct { unsetEnv bool envSocket string @@ -50,10 +58,14 @@ func TestSdNotify(t *testing.T) { }{ // (true, nil) - notification supported, data has been sent {false, notifySocket, true, false}, + {false, "@" + notifySocket, true, false}, + // (false, err) - notification supported, but failure happened {true, testDir + "/missing.sock", false, true}, // (false, nil) - notification not supported {true, "", false, false}, + + // (true, nil) - notification supported, data has been sent } for i, tt := range tests {