[#1262] sdnotify: Send system monotonic time on reload

The synchronized service reload protocol added in systemd version 253
requires that the service provides a MONOTONIC_USEC field alongside the
RELOADING=1 notification message for synchronization purposes. The value
carried in this field must be the system CLOCK_MONOTONIC timestamp at
the time the notification message was generated as systemd compares it
to other CLOCK_MONOTONIC timestamps taken by pid1.

Signed-off-by: Ekaterina Lebedeva <ekaterina.lebedeva@yadro.com>
This commit is contained in:
Ekaterina Lebedeva 2024-08-15 17:12:38 +03:00
parent 5da41f1fe5
commit ec1509de4e
3 changed files with 8 additions and 13 deletions

View file

@ -1,10 +0,0 @@
package sdnotify
import (
// For go:linkname to work.
_ "unsafe"
)
//go:noescape
//go:linkname nanotime runtime.nanotime
func nanotime() int64

View file

@ -1,2 +0,0 @@
// The file is intentionally empty.
// It is a workaround for https://github.com/golang/go/issues/15006

View file

@ -5,7 +5,10 @@ import (
"fmt" "fmt"
"net" "net"
"os" "os"
"strconv"
"strings" "strings"
"golang.org/x/sys/unix"
) )
const ( const (
@ -51,7 +54,11 @@ func FlagAndStatus(status string) error {
// must be sent, containing "READY=1". // must be sent, containing "READY=1".
// //
// For MONOTONIC_USEC format refer to https://www.man7.org/linux/man-pages/man3/sd_notify.3.html // For MONOTONIC_USEC format refer to https://www.man7.org/linux/man-pages/man3/sd_notify.3.html
status += fmt.Sprintf("\nMONOTONIC_USEC=%d", uint64(nanotime())/1e3 /* microseconds in nanoseconds */) var ts unix.Timespec
if err := unix.ClockGettime(unix.CLOCK_MONOTONIC, &ts); err != nil {
return fmt.Errorf("clock_gettime: %w", err)
}
status += "\nMONOTONIC_USEC=" + strconv.FormatInt(ts.Nano()/1000, 10)
} }
status += "\nSTATUS=" + strings.TrimSuffix(status, "=1") status += "\nSTATUS=" + strings.TrimSuffix(status, "=1")
return Send(status) return Send(status)