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

UDS: use lock file #272

Open
om26er opened this issue Jun 8, 2022 · 1 comment
Open

UDS: use lock file #272

om26er opened this issue Jun 8, 2022 · 1 comment

Comments

@om26er
Copy link
Contributor

om26er commented Jun 8, 2022

If nexus is running a unix domain socket transport and the system crashes, on next boot, the sock file exist and nexus fails to start.

Nexus should

  1. Create a lock file
  2. Start the unix transport

Some reading https://gavv.net/articles/unix-socket-reuse/

@om26er
Copy link
Contributor Author

om26er commented Jun 8, 2022

As a PoC the below change achieved what I wanted. But of course below code would only run on UNIX based systems

diff --git a/router/rawsocketserver.go b/router/rawsocketserver.go
index 23c2f67..ea310f5 100644
--- a/router/rawsocketserver.go
+++ b/router/rawsocketserver.go
@@ -5,9 +5,11 @@ import (
        "fmt"
        "io"
        "net"
+       "os"
        "time"
 
        "github.com/gammazero/nexus/v3/transport"
+       "golang.org/x/sys/unix"
 )
 
 // RawSocketServer handles socket connections.
@@ -36,6 +38,18 @@ func NewRawSocketServer(r Router) *RawSocketServer {
 // ListenAndServe listens on the specified endpoint and starts a goroutine that
 // accepts new client connections until the returned io.closer is closed.
 func (s *RawSocketServer) ListenAndServe(network, address string) (io.Closer, error) {
+       file, err := unix.Open(address+".lock", os.O_RDONLY|os.O_CREATE, 0600)
+       if err != nil {
+               return nil, err
+       }
+
+       err = unix.Flock(file, unix.LOCK_EX|unix.LOCK_NB)
+       if err != nil {
+               return nil, err
+       }
+
+       _ = unix.Unlink(address)
+
        l, err := net.Listen(network, address)
        if err != nil {
                return nil, err

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

No branches or pull requests

1 participant