finally properly fixed ssh zombie leak

The leak was caused by the thread that sshd'd to send transferinfo
not waiting on its ssh. Doh.
This commit is contained in:
Joey Hess 2014-08-03 20:14:20 -04:00
parent 8587cd40ed
commit 1cd2273035
2 changed files with 9 additions and 9 deletions

View file

@ -390,6 +390,7 @@ copyFromRemote' r key file dest
Just (cmd, params) <- Ssh.git_annex_shell (repo r) "transferinfo" Just (cmd, params) <- Ssh.git_annex_shell (repo r) "transferinfo"
[Param $ key2file key] fields [Param $ key2file key] fields
v <- liftIO (newEmptySV :: IO (MSampleVar Integer)) v <- liftIO (newEmptySV :: IO (MSampleVar Integer))
pidv <- liftIO $ newEmptyMVar
tid <- liftIO $ forkIO $ void $ tryIO $ do tid <- liftIO $ forkIO $ void $ tryIO $ do
bytes <- readSV v bytes <- readSV v
p <- createProcess $ p <- createProcess $
@ -397,6 +398,7 @@ copyFromRemote' r key file dest
{ std_in = CreatePipe { std_in = CreatePipe
, std_err = CreatePipe , std_err = CreatePipe
} }
putMVar pidv (processHandle p)
hClose $ stderrHandle p hClose $ stderrHandle p
let h = stdinHandle p let h = stdinHandle p
let send b = do let send b = do
@ -406,7 +408,12 @@ copyFromRemote' r key file dest
forever $ forever $
send =<< readSV v send =<< readSV v
let feeder = writeSV v . fromBytesProcessed let feeder = writeSV v . fromBytesProcessed
bracketIO noop (const $ tryIO $ killThread tid) (const $ a feeder) let cleanup = do
void $ tryIO $ killThread tid
tryNonAsync $
maybe noop (void . waitForProcess)
=<< tryTakeMVar pidv
bracketIO noop (const cleanup) (const $ a feeder)
copyFromRemoteCheap :: Remote -> Key -> FilePath -> Annex Bool copyFromRemoteCheap :: Remote -> Key -> FilePath -> Annex Bool
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS

View file

@ -102,20 +102,13 @@ dropKey r key = onRemote r (boolSystem, False) "dropkey"
rsyncHelper :: Maybe MeterUpdate -> [CommandParam] -> Annex Bool rsyncHelper :: Maybe MeterUpdate -> [CommandParam] -> Annex Bool
rsyncHelper callback params = do rsyncHelper callback params = do
showOutput -- make way for progress bar showOutput -- make way for progress bar
ok <- ifM (liftIO $ (maybe rsync rsyncProgress callback) params) ifM (liftIO $ (maybe rsync rsyncProgress callback) params)
( return True ( return True
, do , do
showLongNote "rsync failed -- run git annex again to resume file transfer" showLongNote "rsync failed -- run git annex again to resume file transfer"
return False return False
) )
{- For an unknown reason, this causes rsync to run a second
- ssh process, which it neglects to wait on.
- Reap the resulting zombie. -}
liftIO reapZombies
return ok
{- Generates rsync parameters that ssh to the remote and asks it {- Generates rsync parameters that ssh to the remote and asks it
- to either receive or send the key's content. -} - to either receive or send the key's content. -}
rsyncParamsRemote :: Bool -> Remote -> Direction -> Key -> FilePath -> AssociatedFile -> Annex [CommandParam] rsyncParamsRemote :: Bool -> Remote -> Direction -> Key -> FilePath -> AssociatedFile -> Annex [CommandParam]