Skip to content

Commit

Permalink
daemon: Add systemd aware 'daemon is running' check
Browse files Browse the repository at this point in the history
Early in the daemon startup, we attempt to send 'version' HTTP request
to the daemon to check if it's running already.

When using systemd socket activation, this causes a 'chicken and egg'
issue. The daemon socket already exists, so the version check code can
attempt to connect/send data to it. However, the daemon hasn't taken
ownership of that socket yet, so it won't respond to the HTTP 'version'
request. This causes the version check to hang.

This commit enhances this check, if it detects socket activation is
being used, then it reports that the daemon is not running yet. If
socket activation is not being used, the regular 'daemon is running'
check is used.
  • Loading branch information
cfergeau authored and praveenkumar committed Aug 5, 2021
1 parent 47724ad commit 4b94bba
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 1 deletion.
9 changes: 8 additions & 1 deletion cmd/crc/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,20 @@ func init() {

const hostVirtualIP = "192.168.127.254"

func checkDaemonVersion() (bool, error) {
if _, err := daemonclient.New().APIClient.Version(); err == nil {
return true, errors.New("daemon is already running")
}
return false, nil
}

var daemonCmd = &cobra.Command{
Use: "daemon",
Short: "Run the crc daemon",
Long: "Run the crc daemon",
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
if _, err := daemonclient.New().APIClient.Version(); err == nil {
if running, _ := checkIfDaemonIsRunning(); running {
return errors.New("daemon is already running")
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/crc/cmd/daemon_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ func httpListener() (net.Listener, error) {
}
return ln, nil
}

func checkIfDaemonIsRunning() (bool, error) {
return checkDaemonVersion()
}
15 changes: 15 additions & 0 deletions cmd/crc/cmd/daemon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ const (
// startup, and then use `systemdListeners` in the rest of the code
var systemdListeners, _ = listenersWithNames()

func checkIfDaemonIsRunning() (bool, error) {
ln, _ := getSystemdListener(httpUnitName)
if ln != nil {
/* detect if the daemon is being started by systemd,
* and socket activation is in use. In this scenario,
* trying to send an HTTP version check on the daemon
* HTTP socket would hang as the socket is listening for
* connections but is not setup to handle them yet.
*/
return false, nil
}

return checkDaemonVersion()
}

// listenersWithNames maps a listener name to a set of net.Listener instances.
// This is the same code as https://github.com/coreos/go-systemd/blob/main/activation/listeners.go
// with support for vsock
Expand Down
4 changes: 4 additions & 0 deletions cmd/crc/cmd/daemon_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ func httpListener() (net.Listener, error) {
}
return ln, nil
}

func checkIfDaemonIsRunning() (bool, error) {
return checkDaemonVersion()
}

0 comments on commit 4b94bba

Please sign in to comment.