From 6c87fb70f912e2923918c1e2aa7ed8ed16b6d950 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Fri, 23 Oct 2026 16:02:33 -0700 Subject: [PATCH] server: skip local unix sockets that cannot be bound (#12000) server: skip default local unix sockets that cannot be bound weed server fatally exited during S3, filer, or SFTP startup when the default /tmp/seaweedfs--.sock path could not be removed or bound. On shared hosts (e.g. CI runners where another user's weed left a socket in the sticky /tmp directory) a stale socket file turns into 'operation not permitted' and kills the whole server, even though the TCP listeners are unaffected. Warn and skip the unix socket listener instead, matching how the gRPC local socket already degrades. An explicitly configured -localSocket path still fails fast, since a co-located S3 server may be configured to dial the filer through it. --- weed/command/filer.go | 20 ++++++++++++++------ weed/command/s3.go | 28 ++++++++++++++++++---------- weed/command/sftp.go | 16 ++++++++++++---- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/weed/command/filer.go b/weed/command/filer.go index 245182117a..7a9c1300f2 100644 --- a/weed/command/filer.go +++ b/weed/command/filer.go @@ -525,19 +525,27 @@ func (fo *FilerOptions) startFiler() { var socketServer *http.Server if runtime.GOOS != "windows" { localSocket := *fo.localSocket - if localSocket == "" { + explicit := localSocket != "" + if !explicit { localSocket = fmt.Sprintf("/tmp/seaweedfs-filer-%d.sock", *fo.port) } if err := os.Remove(localSocket); err != nil && !os.IsNotExist(err) { - glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + if explicit { + glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + } + glog.Warningf("Failed to remove %s, error: %s", localSocket, err.Error()) } filerSocketListener, err := net.Listen("unix", localSocket) if err != nil { - glog.Fatalf("Failed to listen on %s: %v", localSocket, err) + if explicit { + glog.Fatalf("Failed to listen on %s: %v", localSocket, err) + } + glog.Errorf("Failed to listen on %s, skipping local socket server: %v", localSocket, err) + } else { + socketServer = newHttpServer(defaultHandler, nil) + httpServers = append(httpServers, socketServer) + go socketServer.Serve(filerSocketListener) } - socketServer = newHttpServer(defaultHandler, nil) - httpServers = append(httpServers, socketServer) - go socketServer.Serve(filerSocketListener) } if viper.GetString("https.filer.key") != "" { diff --git a/weed/command/s3.go b/weed/command/s3.go index 958afb8eab..a37d7c8179 100644 --- a/weed/command/s3.go +++ b/weed/command/s3.go @@ -429,23 +429,31 @@ func (s3opt *S3Options) startS3Server() bool { if runtime.GOOS != "windows" { localSocket := *s3opt.localSocket - if localSocket == "" { + explicit := localSocket != "" + if !explicit { localSocket = fmt.Sprintf("/tmp/seaweedfs-s3-%d.sock", *s3opt.port) } if err := os.Remove(localSocket); err != nil && !os.IsNotExist(err) { - glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + if explicit { + glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + } + glog.Warningf("Failed to remove %s, error: %s", localSocket, err.Error()) } s3SocketListener, err := net.Listen("unix", localSocket) if err != nil { - glog.Fatalf("Failed to listen on %s: %v", localSocket, err) - } - socketServer := newHttpServer(router, nil) - httpServers = append(httpServers, socketServer) - go func() { - if err := socketServer.Serve(s3SocketListener); err != nil && err != http.ErrServerClosed { - glog.Fatalf("Failed to start S3 http server: %v", err) + if explicit { + glog.Fatalf("Failed to listen on %s: %v", localSocket, err) } - }() + glog.Errorf("Failed to listen on %s, skipping local socket server: %v", localSocket, err) + } else { + socketServer := newHttpServer(router, nil) + httpServers = append(httpServers, socketServer) + go func() { + if err := socketServer.Serve(s3SocketListener); err != nil && err != http.ErrServerClosed { + glog.Errorf("Failed to start S3 http server on %s: %v", localSocket, err) + } + }() + } } listenAddress := fmt.Sprintf("%s:%d", *s3opt.bindIp, *s3opt.port) diff --git a/weed/command/sftp.go b/weed/command/sftp.go index ed4a28b79c..054096392d 100644 --- a/weed/command/sftp.go +++ b/weed/command/sftp.go @@ -180,20 +180,28 @@ func (sftpOpt *SftpOptions) startSftpServer() bool { // Set up Unix socket if on non-Windows platforms if runtime.GOOS != "windows" { localSocket := *sftpOpt.localSocket - if localSocket == "" { + explicit := localSocket != "" + if !explicit { localSocket = fmt.Sprintf("/tmp/seaweedfs-sftp-%d.sock", *sftpOpt.port) } if err := os.Remove(localSocket); err != nil && !os.IsNotExist(err) { - glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + if explicit { + glog.Fatalf("Failed to remove %s, error: %s", localSocket, err.Error()) + } + glog.Warningf("Failed to remove %s, error: %s", localSocket, err.Error()) } go func() { // start on local unix socket sftpSocketListener, err := net.Listen("unix", localSocket) if err != nil { - glog.Fatalf("Failed to listen on %s: %v", localSocket, err) + if explicit { + glog.Fatalf("Failed to listen on %s: %v", localSocket, err) + } + glog.Errorf("Failed to listen on %s, skipping local socket server: %v", localSocket, err) + return } if err := service.Serve(sftpSocketListener); err != nil { - glog.Fatalf("Failed to serve SFTP on socket %s: %v", localSocket, err) + glog.Errorf("Failed to serve SFTP on socket %s: %v", localSocket, err) } }() }