diff --git a/pkg/util/sdnotify/clock.go b/pkg/util/sdnotify/clock.go new file mode 100644 index 00000000..f5419d02 --- /dev/null +++ b/pkg/util/sdnotify/clock.go @@ -0,0 +1,10 @@ +package sdnotify + +import ( + // For go:linkname to work. + _ "unsafe" +) + +//go:noescape +//go:linkname nanotime runtime.nanotime +func nanotime() int64 diff --git a/pkg/util/sdnotify/clock.s b/pkg/util/sdnotify/clock.s new file mode 100644 index 00000000..ad033ff4 --- /dev/null +++ b/pkg/util/sdnotify/clock.s @@ -0,0 +1,2 @@ +// The file is intentionally empty. +// It is a workaround for https://github.com/golang/go/issues/15006 diff --git a/pkg/util/sdnotify/sdnotify.go b/pkg/util/sdnotify/sdnotify.go index fe4ad1c3..16a3f11c 100644 --- a/pkg/util/sdnotify/sdnotify.go +++ b/pkg/util/sdnotify/sdnotify.go @@ -38,6 +38,21 @@ func InitSocket() error { // FlagAndStatus sends systemd a combination of a // well-known status and STATUS=%s{status}, separated by newline. func FlagAndStatus(status string) error { + if status == ReloadingEnabled { + // From https://www.man7.org/linux/man-pages/man5/systemd.service.5.html + // + // When initiating the reload process the service is + // expected to reply with a notification message via + // sd_notify(3) that contains the "RELOADING=1" field in + // combination with "MONOTONIC_USEC=" set to the current + // monotonic time (i.e. CLOCK_MONOTONIC in + // clock_gettime(2)) in μs, formatted as decimal string. + // Once reloading is complete another notification message + // must be sent, containing "READY=1". + // + // 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 */) + } status += "\nSTATUS=" + strings.TrimSuffix(status, "=1") return Send(status) }