mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-23 00:56:20 +00:00
Revert "ipn/ipnlocal: shut down old control client synchronously on reset"
It appears (*controlclient.Auto).Shutdown() can still deadlock when called with b.mu held, and therefore the changes in #18127 are unsafe.
This reverts #18127 until we figure out what causes it.
This reverts commit d199ecac80.
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -950,8 +950,12 @@ func (b *LocalBackend) pauseOrResumeControlClientLocked() {
|
|||||||
// down, clients switch over to other replicas whilst the existing connections are kept alive for some period of time.
|
// down, clients switch over to other replicas whilst the existing connections are kept alive for some period of time.
|
||||||
func (b *LocalBackend) DisconnectControl() {
|
func (b *LocalBackend) DisconnectControl() {
|
||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
cc := b.resetControlClientLocked()
|
||||||
b.resetControlClientLocked()
|
b.mu.Unlock()
|
||||||
|
|
||||||
|
if cc != nil {
|
||||||
|
cc.Shutdown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// linkChange is our network monitor callback, called whenever the network changes.
|
// linkChange is our network monitor callback, called whenever the network changes.
|
||||||
@@ -2417,6 +2421,14 @@ func (b *LocalBackend) startLocked(opts ipn.Options) error {
|
|||||||
logf := logger.WithPrefix(b.logf, "Start: ")
|
logf := logger.WithPrefix(b.logf, "Start: ")
|
||||||
b.startOnce.Do(b.initOnce)
|
b.startOnce.Do(b.initOnce)
|
||||||
|
|
||||||
|
var clientToShutdown controlclient.Client
|
||||||
|
defer func() {
|
||||||
|
if clientToShutdown != nil {
|
||||||
|
// Shutdown outside of b.mu to avoid deadlocks.
|
||||||
|
b.goTracker.Go(clientToShutdown.Shutdown)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if opts.UpdatePrefs != nil {
|
if opts.UpdatePrefs != nil {
|
||||||
if err := b.checkPrefsLocked(opts.UpdatePrefs); err != nil {
|
if err := b.checkPrefsLocked(opts.UpdatePrefs); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -2459,7 +2471,7 @@ func (b *LocalBackend) startLocked(opts ipn.Options) error {
|
|||||||
// into sync with the minimal changes. But that's not how it
|
// into sync with the minimal changes. But that's not how it
|
||||||
// is right now, which is a sign that the code is still too
|
// is right now, which is a sign that the code is still too
|
||||||
// complicated.
|
// complicated.
|
||||||
b.resetControlClientLocked()
|
clientToShutdown = b.resetControlClientLocked()
|
||||||
httpTestClient := b.httpTestClient
|
httpTestClient := b.httpTestClient
|
||||||
|
|
||||||
if b.hostinfo != nil {
|
if b.hostinfo != nil {
|
||||||
@@ -5812,12 +5824,13 @@ func (b *LocalBackend) setControlClientLocked(cc controlclient.Client) {
|
|||||||
b.ignoreControlClientUpdates.Store(cc == nil)
|
b.ignoreControlClientUpdates.Store(cc == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// resetControlClientLocked sets b.cc to nil and shuts down the previous
|
// resetControlClientLocked sets b.cc to nil and returns the old value. If the
|
||||||
// control client, if any.
|
// returned value is non-nil, the caller must call Shutdown on it after
|
||||||
func (b *LocalBackend) resetControlClientLocked() {
|
// releasing b.mu.
|
||||||
|
func (b *LocalBackend) resetControlClientLocked() controlclient.Client {
|
||||||
syncs.RequiresMutex(&b.mu)
|
syncs.RequiresMutex(&b.mu)
|
||||||
if b.cc == nil {
|
if b.cc == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
b.resetAuthURLLocked()
|
b.resetAuthURLLocked()
|
||||||
@@ -5837,7 +5850,7 @@ func (b *LocalBackend) resetControlClientLocked() {
|
|||||||
}
|
}
|
||||||
prev := b.cc
|
prev := b.cc
|
||||||
b.setControlClientLocked(nil)
|
b.setControlClientLocked(nil)
|
||||||
prev.Shutdown()
|
return prev
|
||||||
}
|
}
|
||||||
|
|
||||||
// resetAuthURLLocked resets authURL, canceling any pending interactive login.
|
// resetAuthURLLocked resets authURL, canceling any pending interactive login.
|
||||||
@@ -6931,7 +6944,10 @@ func (b *LocalBackend) resetForProfileChangeLocked() error {
|
|||||||
b.updateFilterLocked(ipn.PrefsView{})
|
b.updateFilterLocked(ipn.PrefsView{})
|
||||||
// Reset the NetworkMap in the engine
|
// Reset the NetworkMap in the engine
|
||||||
b.e.SetNetworkMap(new(netmap.NetworkMap))
|
b.e.SetNetworkMap(new(netmap.NetworkMap))
|
||||||
b.resetControlClientLocked()
|
if prevCC := b.resetControlClientLocked(); prevCC != nil {
|
||||||
|
// Shutdown outside of b.mu to avoid deadlocks.
|
||||||
|
b.goTracker.Go(prevCC.Shutdown)
|
||||||
|
}
|
||||||
// TKA errors should not prevent resetting the backend state.
|
// TKA errors should not prevent resetting the backend state.
|
||||||
// However, we should still return the error to the caller.
|
// However, we should still return the error to the caller.
|
||||||
tkaErr := b.initTKALocked()
|
tkaErr := b.initTKALocked()
|
||||||
@@ -7010,7 +7026,10 @@ func (b *LocalBackend) ResetAuth() error {
|
|||||||
b.mu.Lock()
|
b.mu.Lock()
|
||||||
defer b.mu.Unlock()
|
defer b.mu.Unlock()
|
||||||
|
|
||||||
b.resetControlClientLocked()
|
if prevCC := b.resetControlClientLocked(); prevCC != nil {
|
||||||
|
// Shutdown outside of b.mu to avoid deadlocks.
|
||||||
|
b.goTracker.Go(prevCC.Shutdown)
|
||||||
|
}
|
||||||
if err := b.clearMachineKeyLocked(); err != nil {
|
if err := b.clearMachineKeyLocked(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user