Skip to content

Commit

Permalink
notify_socket.go: use sd_notify_barrier mechanism
Browse files Browse the repository at this point in the history
Signed-off-by: Jonas Eschenburg <jonas.eschenburg@kuka.com>
  • Loading branch information
Jonas Eschenburg committed Nov 24, 2021
1 parent eba6097 commit f109dab
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion notify_socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package main

import (
"bytes"
"errors"
"io"
"net"
"os"
"path"
"path/filepath"
"strconv"
"syscall"
"time"

"github.com/opencontainers/runc/libcontainer"
Expand Down Expand Up @@ -164,7 +167,58 @@ func (n *notifySocket) run(pid1 int) error {
if err != nil {
return err
}
return nil

// wait for systemd to acknowledge the communication
return sdNotifyBarrier(client)
}
}
}

// Error reported when actual data was read from the pipe used to synchronize with
// systemd. Usually, that pipe is only closed.
var errUnexpectedRead = errors.New("unexpected read from synchronization pipe")

// Synchronizes with systemd by means of the sd_notify_barrier protocol.
func sdNotifyBarrier(client *net.UnixConn) error {
// Create a pipe for communicating with systemd daemon.
pipeR, pipeW, err := os.Pipe()
if err != nil {
return err
}

// Get the FD for the unix socket file to be able to do perform syscall.Sendmsg.
clientFd, err := client.File()
if err != nil {
return err
}

// Send the write end of the pipe along with a BARRIER=1 message.
fdRights := syscall.UnixRights(int(pipeW.Fd()))
err = syscall.Sendmsg(int(clientFd.Fd()), []byte("BARRIER=1"), fdRights, nil, 0)
if err != nil {
return err
}

// Close our copy of pipeW.
err = pipeW.Close()
if err != nil {
return err
}

// Expect the read end of the pipe to be closed after 5 seconds.
err = pipeR.SetReadDeadline(time.Now().Add(5 * time.Second))
if err != nil {
return nil
}

// Read a single byte expecting EOF.
var buf [1]byte
n, err := pipeR.Read(buf[:])
if n != 0 || err == nil {
return errUnexpectedRead
} else if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit.
return nil
} else {
return err
}
}

0 comments on commit f109dab

Please sign in to comment.