fixing deadlocks, remove daemonization as it would be handled by init system

This commit is contained in:
mykola2312 2025-01-29 04:18:26 +02:00
parent 2411a58a09
commit 3051a1b5ea
5 changed files with 20 additions and 79 deletions

5
go.mod
View file

@ -8,7 +8,6 @@ require (
) )
require ( require (
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/linkdata/deadlock v0.5.2 // indirect
github.com/sevlyar/go-daemon v0.1.6 github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
golang.org/x/sys v0.29.0 // indirect
) )

4
go.sum
View file

@ -2,8 +2,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/linkdata/deadlock v0.5.2 h1:clEEeRsMJCrEm5SuBI3v2l3sdCSP74p0ii+C1rR9nA0=
github.com/linkdata/deadlock v0.5.2/go.mod h1:M3Td2tmYASdLm6xblKGlFvfu8SI+nPjrB7mDeFDEz/k=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw=
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs= github.com/sevlyar/go-daemon v0.1.6 h1:EUh1MDjEM4BI109Jign0EaknA2izkOyi0LV3ro3QQGs=
github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/sevlyar/go-daemon v0.1.6/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=

63
main.go
View file

@ -14,13 +14,11 @@ import (
"net/netip" "net/netip"
"os" "os"
"os/signal" "os/signal"
"strconv"
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/op/go-logging" "github.com/op/go-logging"
"github.com/sevlyar/go-daemon"
) )
var isNode bool var isNode bool
@ -29,8 +27,6 @@ var isRpc bool
var configPath string var configPath string
var bootstrap bool var bootstrap bool
var justNodeId bool var justNodeId bool
var daemonize bool
var pidPath string
type LogConfig struct { type LogConfig struct {
XMLName xml.Name `xml:"log"` XMLName xml.Name `xml:"log"`
@ -128,49 +124,6 @@ func bootstrapNode() {
var log = logging.MustGetLogger("main") var log = logging.MustGetLogger("main")
func becomeDaemon() {
cwd, err := os.Getwd()
if err != nil {
log.Criticalf("Getwd failed: %v", err)
os.Exit(1)
}
ctx := &daemon.Context{
PidFileName: pidPath,
PidFilePerm: 0644,
WorkDir: cwd,
Umask: 002,
}
dmn, err := ctx.Reborn()
if err != nil {
log.Criticalf("ctx.Reborn failed: %v", err)
os.Exit(1)
}
if dmn != nil {
// parent process no longer needed
os.Exit(0)
}
// -- WE ARE NOW THE DAEMON --
// write pid
if pidPath != "" {
pidFile, err := os.OpenFile(pidPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(0644))
if err != nil {
log.Errorf("failed to create pidfile: %v", err)
}
defer pidFile.Close()
pidBytes := []byte(strconv.Itoa(os.Getpid()))
_, err = pidFile.Write(pidBytes)
if err != nil {
log.Errorf("failed to write pidfile: %v", err)
}
}
}
func nodeMain() { func nodeMain() {
xmlBytes, err := os.ReadFile(configPath) xmlBytes, err := os.ReadFile(configPath)
if err != nil { if err != nil {
@ -187,11 +140,6 @@ func nodeMain() {
// setup logging // setup logging
setupLogging(config.Log) setupLogging(config.Log)
// only after logging setup, we may became daemon
if daemonize {
becomeDaemon()
}
// check presense of keystore and id in config // check presense of keystore and id in config
if config.KeyStore == "" { if config.KeyStore == "" {
log.Critical("no keystore path specified!") log.Critical("no keystore path specified!")
@ -324,9 +272,7 @@ signaling:
sig := <-sigs sig := <-sigs
log.Debug(sig) log.Debug(sig)
switch sig { switch sig {
case syscall.SIGINT: case syscall.SIGINT, syscall.SIGTERM:
break signaling
case syscall.SIGTERM:
break signaling break signaling
} }
} }
@ -537,11 +483,6 @@ func hostMain() {
// setup logging // setup logging
setupLogging(config.Log) setupLogging(config.Log)
// daemonize if needed
if daemonize {
becomeDaemon()
}
// create host // create host
host := host.NewLuxHost(config.Hostname, hostKey, ks) host := host.NewLuxHost(config.Hostname, hostKey, ks)
@ -861,8 +802,6 @@ func main() {
flag.StringVar(&configPath, "config", "", "node or host config") flag.StringVar(&configPath, "config", "", "node or host config")
flag.BoolVar(&bootstrap, "bootstrap", false, "bootstrap node keystore. config must be specified") flag.BoolVar(&bootstrap, "bootstrap", false, "bootstrap node keystore. config must be specified")
flag.BoolVar(&justNodeId, "just-node-id", false, "when bootstrapping only output node id to stdout") flag.BoolVar(&justNodeId, "just-node-id", false, "when bootstrapping only output node id to stdout")
flag.BoolVar(&daemonize, "daemon", false, "run LUX as daemon in background")
flag.StringVar(&pidPath, "pid", "", "after daemonization LUX will write its PID here")
flag.StringVar(&rpcPath, "rpc", "", "Run as RPC client, specify path to RPC UNIX socket or TCP socket, must be in unix:// or tcp:// form") flag.StringVar(&rpcPath, "rpc", "", "Run as RPC client, specify path to RPC UNIX socket or TCP socket, must be in unix:// or tcp:// form")
flag.StringVar(&rpcNewHost, "rpc-new-host", "", "RPC node create new host, specifies path for new keystore") flag.StringVar(&rpcNewHost, "rpc-new-host", "", "RPC node create new host, specifies path for new keystore")

View file

@ -8,7 +8,8 @@ import (
"lux/proto" "lux/proto"
"lux/rpc" "lux/rpc"
"net" "net"
"sync"
"github.com/linkdata/deadlock"
) )
type LuxRouteType int type LuxRouteType int
@ -83,7 +84,7 @@ type LuxRouter struct {
routes map[proto.LuxID]*LuxRoute routes map[proto.LuxID]*LuxRoute
channelLock sync.RWMutex channelLock deadlock.RWMutex
outbound []LuxChannel outbound []LuxChannel
inbound []LuxChannel inbound []LuxChannel
@ -242,18 +243,15 @@ func (r *LuxRouter) Start() {
} }
func (r *LuxRouter) Stop() { func (r *LuxRouter) Stop() {
// close all channels // close all channel
r.channelLock.Lock()
for _, inbound := range r.inbound { for _, inbound := range r.inbound {
inbound.Close() //inbound.Close()
r.CloseChannel(&inbound, true)
} }
r.inbound = r.inbound[0:]
for _, outbound := range r.outbound { for _, outbound := range r.outbound {
outbound.Close() //outbound.Close()
r.CloseChannel(&outbound, false)
} }
r.outbound = r.outbound[0:]
r.channelLock.Unlock()
r.routes = make(map[proto.LuxID]*LuxRoute) r.routes = make(map[proto.LuxID]*LuxRoute)
} }

View file

@ -7,9 +7,10 @@ import (
"lux/net" "lux/net"
"lux/proto" "lux/proto"
"lux/rpc" "lux/rpc"
"sync"
ipnet "net" ipnet "net"
"github.com/linkdata/deadlock"
) )
type LuxNode struct { type LuxNode struct {
@ -18,10 +19,10 @@ type LuxNode struct {
running bool running bool
neighbors map[proto.LuxID]*ipnet.UDPAddr neighbors map[proto.LuxID]*ipnet.UDPAddr
neighborLock sync.RWMutex neighborLock deadlock.RWMutex
state LuxNodeState state LuxNodeState
stateLock sync.RWMutex stateLock deadlock.RWMutex
genlist net.LuxNonceList genlist net.LuxNonceList
@ -96,7 +97,7 @@ func (node *LuxNode) GetState() *LuxNodeState {
return &node.state return &node.state
} }
func (node *LuxNode) GetStateLock() *sync.RWMutex { func (node *LuxNode) GetStateLock() *deadlock.RWMutex {
return &node.stateLock return &node.stateLock
} }