Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

daemon: add SdNotifyMonotonicUsec helper function #435

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

corhere
Copy link

@corhere corhere commented Feb 13, 2024

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.

While the Go standard library does utilize CLOCK_MONOTONIC in the implementation of package "time", the absolute monotonic timestamps in time.Time values are not made available to programmers. Users familiar with idiomatic usage of monotonic timestamps in Go might (incorrectly) try to implement MONOTONIC_USEC using process-relative monotonic timestamps, like so:

var processStart = time.Now()

func NotifyReloadingINCORRECT() {
	ts := time.Since(processStart)/time.Microsecond  // WRONG
	msg := fmt.Sprintf(
		daemon.SdNotifyReload+"\nMONOTONIC_USEC=%d", ts,
	)
	_, _ = daemon.SdNotify(false, msg)
}

Help users fall into the pit of success by providing a helper function SdNotifyMonotonicUsec() which returns a MONOTONIC_USEC string which encodes the system CLOCK_MONOTONIC timestamp in decimal microseconds, as systemd expects.

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.

While the Go standard library does utilize CLOCK_MONOTONIC in the
implementation of package "time", the absolute monotonic timestamps in
time.Time values are not made available to programmers. Users familiar
with idiomatic usage of monotonic timestamps in Go might (incorrectly)
try to implement MONOTONIC_USEC using process-relative monotonic
timestamps, like so:

    var processStart = time.Now()

    func NotifyReloadingINCORRECT() {
    	ts := time.Since(processStart)/time.Microsecond  // WRONG
    	msg := fmt.Sprintf(
    		daemon.SdNotifyReload+"\nMONOTONIC_USEC=%d", ts,
    	)
    	_, _ = daemon.SdNotify(false, msg)
    }

Help users fall into the pit of success by providing a helper function
SdNotifyMonotonicUsec() which returns a MONOTONIC_USEC string which
encodes the system CLOCK_MONOTONIC timestamp in decimal microseconds, as
systemd expects.

Signed-off-by: Cory Snider <[email protected]>
@thaJeztah
Copy link

@cgwalters ptal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants