net/tstun: diagnose /dev/net/tun fd leak, give better failure message
Updates #5029 Change-Id: Ibee5e0c9076fe764eb5d856d5ef8b09f4d0e2921 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>pull/5071/head
parent
931f18b575
commit
0d52674a84
|
@ -515,7 +515,7 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer, na
|
||||||
} else {
|
} else {
|
||||||
dev, devName, err := tstun.New(logf, name)
|
dev, devName, err := tstun.New(logf, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tstun.Diagnose(logf, name)
|
tstun.Diagnose(logf, name, err)
|
||||||
return nil, false, fmt.Errorf("tstun.New(%q): %w", name, err)
|
return nil, false, fmt.Errorf("tstun.New(%q): %w", name, err)
|
||||||
}
|
}
|
||||||
conf.Tun = dev
|
conf.Tun = dev
|
||||||
|
|
|
@ -74,15 +74,18 @@ func New(logf logger.Logf, tunName string) (tun.Device, string, error) {
|
||||||
|
|
||||||
// tunDiagnoseFailure, if non-nil, does OS-specific diagnostics of why
|
// tunDiagnoseFailure, if non-nil, does OS-specific diagnostics of why
|
||||||
// TUN failed to work.
|
// TUN failed to work.
|
||||||
var tunDiagnoseFailure func(tunName string, logf logger.Logf)
|
var tunDiagnoseFailure func(tunName string, logf logger.Logf, err error)
|
||||||
|
|
||||||
// Diagnose tries to explain a tuntap device creation failure.
|
// Diagnose tries to explain a tuntap device creation failure.
|
||||||
// It pokes around the system and logs some diagnostic info that might
|
// It pokes around the system and logs some diagnostic info that might
|
||||||
// help debug why tun creation failed. Because device creation has
|
// help debug why tun creation failed. Because device creation has
|
||||||
// already failed and the program's about to end, log a lot.
|
// already failed and the program's about to end, log a lot.
|
||||||
func Diagnose(logf logger.Logf, tunName string) {
|
//
|
||||||
|
// The tunName is the name of the tun device that was requested but failed.
|
||||||
|
// The err error is how the tun creation failed.
|
||||||
|
func Diagnose(logf logger.Logf, tunName string, err error) {
|
||||||
if tunDiagnoseFailure != nil {
|
if tunDiagnoseFailure != nil {
|
||||||
tunDiagnoseFailure(tunName, logf)
|
tunDiagnoseFailure(tunName, logf, err)
|
||||||
} else {
|
} else {
|
||||||
logf("no TUN failure diagnostics for OS %q", runtime.GOOS)
|
logf("no TUN failure diagnostics for OS %q", runtime.GOOS)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package tstun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -19,7 +20,14 @@ func init() {
|
||||||
tunDiagnoseFailure = diagnoseLinuxTUNFailure
|
tunDiagnoseFailure = diagnoseLinuxTUNFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf) {
|
func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error) {
|
||||||
|
if errors.Is(createErr, syscall.EBUSY) {
|
||||||
|
logf("TUN device %s is busy; another process probably still has it open (from old version of Tailscale that had a bug)", tunName)
|
||||||
|
logf("To fix, kill the process that has it open. Find with:\n\n$ sudo lsof -n /dev/net/tun\n\n")
|
||||||
|
logf("... and then kill those PID(s)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var un syscall.Utsname
|
var un syscall.Utsname
|
||||||
err := syscall.Uname(&un)
|
err := syscall.Uname(&un)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -17,7 +17,7 @@ func init() {
|
||||||
tunDiagnoseFailure = diagnoseDarwinTUNFailure
|
tunDiagnoseFailure = diagnoseDarwinTUNFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
func diagnoseDarwinTUNFailure(tunName string, logf logger.Logf) {
|
func diagnoseDarwinTUNFailure(tunName string, logf logger.Logf, err error) {
|
||||||
if os.Getuid() != 0 {
|
if os.Getuid() != 0 {
|
||||||
logf("failed to create TUN device as non-root user; use 'sudo tailscaled', or run under launchd with 'sudo tailscaled install-system-daemon'")
|
logf("failed to create TUN device as non-root user; use 'sudo tailscaled', or run under launchd with 'sudo tailscaled install-system-daemon'")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue