NetWatcher: When dbus connection is lost, try to reconnect.
MountWatcher can't do this, because it uses the session dbus, and won't have access to the new DBUS_SESSION_BUS_ADDRESS if a new session is started. Bumped dbus library version, FD leak in it is fixed.
This commit is contained in:
parent
87c250da5b
commit
8e4620a6c7
6 changed files with 25 additions and 18 deletions
|
@ -72,6 +72,11 @@ dbusThread st dstatus scanremotes = E.catch (runClient getSessionAddress go) one
|
||||||
)
|
)
|
||||||
onerr :: E.SomeException -> IO ()
|
onerr :: E.SomeException -> IO ()
|
||||||
onerr e = do
|
onerr e = do
|
||||||
|
{- If the session dbus fails, the user probably
|
||||||
|
- logged out of their desktop. Even if they log
|
||||||
|
- back in, we won't have access to the dbus
|
||||||
|
- session key, so polling is the best that can be
|
||||||
|
- done in this situation. -}
|
||||||
runThreadState st $
|
runThreadState st $
|
||||||
warning $ "dbus failed; falling back to mtab polling (" ++ show e ++ ")"
|
warning $ "dbus failed; falling back to mtab polling (" ++ show e ++ ")"
|
||||||
pollinstead
|
pollinstead
|
||||||
|
|
|
@ -24,7 +24,6 @@ import Utility.DBus
|
||||||
import DBus.Client
|
import DBus.Client
|
||||||
import DBus
|
import DBus
|
||||||
import Data.Word (Word32)
|
import Data.Word (Word32)
|
||||||
import qualified Control.Exception as E
|
|
||||||
#else
|
#else
|
||||||
#warning Building without dbus support; will poll for network connection changes
|
#warning Building without dbus support; will poll for network connection changes
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,22 +56,24 @@ netWatcherFallbackThread st dstatus scanremotes = thread $
|
||||||
#if WITH_DBUS
|
#if WITH_DBUS
|
||||||
|
|
||||||
dbusThread :: ThreadState -> DaemonStatusHandle -> ScanRemoteMap -> IO ()
|
dbusThread :: ThreadState -> DaemonStatusHandle -> ScanRemoteMap -> IO ()
|
||||||
dbusThread st dstatus scanremotes = E.catch (runClient getSystemAddress go) onerr
|
dbusThread st dstatus scanremotes = persistentClient getSystemAddress () onerr go
|
||||||
where
|
where
|
||||||
go client = ifM (checkNetMonitor client)
|
go client = ifM (checkNetMonitor client)
|
||||||
( do
|
( do
|
||||||
listenNMConnections client handle
|
listenNMConnections client handleconn
|
||||||
listenWicdConnections client handle
|
listenWicdConnections client handleconn
|
||||||
, do
|
, do
|
||||||
runThreadState st $
|
runThreadState st $
|
||||||
warning "No known network monitor available through dbus; falling back to polling"
|
warning "No known network monitor available through dbus; falling back to polling"
|
||||||
)
|
)
|
||||||
onerr :: E.SomeException -> IO ()
|
handleconn = do
|
||||||
onerr e = runThreadState st $
|
|
||||||
warning $ "dbus failed; falling back to polling (" ++ show e ++ ")"
|
|
||||||
handle = do
|
|
||||||
debug thisThread ["detected network connection"]
|
debug thisThread ["detected network connection"]
|
||||||
handleConnection st dstatus scanremotes
|
handleConnection st dstatus scanremotes
|
||||||
|
onerr e _ = do
|
||||||
|
runThreadState st $
|
||||||
|
warning $ "lost dbus connection; falling back to polling (" ++ show e ++ ")"
|
||||||
|
{- Wait, in hope that dbus will come back -}
|
||||||
|
threadDelaySeconds (Seconds 60)
|
||||||
|
|
||||||
{- Examine the list of services connected to dbus, to see if there
|
{- Examine the list of services connected to dbus, to see if there
|
||||||
- are any we can use to monitor network connections. -}
|
- are any we can use to monitor network connections. -}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
|
||||||
|
|
||||||
module Utility.DBus where
|
module Utility.DBus where
|
||||||
|
|
||||||
|
@ -65,15 +65,15 @@ runClient getaddr clientaction = do
|
||||||
- If the connection is lost, runs onretry, which can do something like
|
- If the connection is lost, runs onretry, which can do something like
|
||||||
- a delay, or printing a warning, and has a state value (useful for
|
- a delay, or printing a warning, and has a state value (useful for
|
||||||
- exponential backoff). Once onretry returns, the connection is retried.
|
- exponential backoff). Once onretry returns, the connection is retried.
|
||||||
-
|
-}
|
||||||
- Warning: Currently connectWith can throw a SocketError and leave behind
|
|
||||||
- an open FD. So each retry leaks one FD. -}
|
|
||||||
persistentClient :: IO (Maybe Address) -> v -> (SomeException -> v -> IO v) -> (Client -> IO ()) -> IO ()
|
persistentClient :: IO (Maybe Address) -> v -> (SomeException -> v -> IO v) -> (Client -> IO ()) -> IO ()
|
||||||
persistentClient getaddr v onretry clientaction = do
|
persistentClient getaddr v onretry clientaction =
|
||||||
{- runClient can fail with not just ClientError, but also other
|
{- runClient can fail with not just ClientError, but also other
|
||||||
- things, if dbus is not running. -}
|
- things, if dbus is not running. Let async exceptions through. -}
|
||||||
r <- E.try (runClient getaddr clientaction) :: IO (Either SomeException ())
|
runClient getaddr clientaction `E.catches`
|
||||||
either retry return r
|
[ Handler (\ (e :: AsyncException) -> E.throw e)
|
||||||
|
, Handler (\ (e :: SomeException) -> retry e)
|
||||||
|
]
|
||||||
where
|
where
|
||||||
retry e = do
|
retry e = do
|
||||||
v' <- onretry e v
|
v' <- onretry e v
|
||||||
|
|
1
debian/changelog
vendored
1
debian/changelog
vendored
|
@ -24,6 +24,7 @@ git-annex (3.20121018) UNRELEASED; urgency=low
|
||||||
* configure: Check that checksum programs produce correct checksums.
|
* configure: Check that checksum programs produce correct checksums.
|
||||||
* Re-enable dbus, using a new version of the library that fixes the memory
|
* Re-enable dbus, using a new version of the library that fixes the memory
|
||||||
leak.
|
leak.
|
||||||
|
* NetWatcher: When dbus connection is lost, try to reconnect.
|
||||||
* Use USER and HOME environment when set, and only fall back to getpwent,
|
* Use USER and HOME environment when set, and only fall back to getpwent,
|
||||||
which doesn't work with LDAP or NIS.
|
which doesn't work with LDAP or NIS.
|
||||||
|
|
||||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -22,7 +22,7 @@ Build-Depends:
|
||||||
libghc-edit-distance-dev,
|
libghc-edit-distance-dev,
|
||||||
libghc-hinotify-dev [linux-any],
|
libghc-hinotify-dev [linux-any],
|
||||||
libghc-stm-dev (>= 2.3),
|
libghc-stm-dev (>= 2.3),
|
||||||
libghc-dbus-dev [linux-any] (>= 0.10.2),
|
libghc-dbus-dev [linux-any] (>= 0.10.3),
|
||||||
libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
||||||
libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
||||||
libghc-yesod-default-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
libghc-yesod-default-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64],
|
||||||
|
|
|
@ -77,7 +77,7 @@ Executable git-annex
|
||||||
C-Sources: Utility/libkqueue.c
|
C-Sources: Utility/libkqueue.c
|
||||||
|
|
||||||
if os(linux) && flag(Dbus)
|
if os(linux) && flag(Dbus)
|
||||||
Build-Depends: dbus (>= 0.10.2)
|
Build-Depends: dbus (>= 0.10.3)
|
||||||
CPP-Options: -DWITH_DBUS
|
CPP-Options: -DWITH_DBUS
|
||||||
|
|
||||||
if flag(Webapp) && flag(Assistant)
|
if flag(Webapp) && flag(Assistant)
|
||||||
|
|
Loading…
Add table
Reference in a new issue