diff options
-rw-r--r-- | Annex/Ssh.hs | 21 | ||||
-rw-r--r-- | Command/Sync.hs | 2 | ||||
-rw-r--r-- | Locations.hs | 4 | ||||
-rw-r--r-- | Utility/FileSystemEncoding.hs | 30 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn | 8 |
6 files changed, 57 insertions, 10 deletions
diff --git a/Annex/Ssh.hs b/Annex/Ssh.hs index 8bd4fe33a..46885393c 100644 --- a/Annex/Ssh.hs +++ b/Annex/Ssh.hs @@ -42,7 +42,13 @@ sshInfo (host, port) = ifM caching ( do dir <- fromRepo gitAnnexSshDir let socketfile = dir </> hostport2socket host port - return (Just socketfile, cacheParams socketfile) + if valid_unix_socket_path socketfile + then return (Just socketfile, cacheParams socketfile) + else do + socketfile' <- liftIO $ relPathCwdToFile socketfile + if valid_unix_socket_path socketfile' + then return (Just socketfile', cacheParams socketfile') + else return (Nothing, []) , return (Nothing, []) ) where @@ -118,3 +124,16 @@ isLock f = lockExt `isSuffixOf` f lockExt :: String lockExt = ".lock" + +{- This is the size of the sun_path component of sockaddr_un, which + - is the limit to the total length of the filename of a unix socket. + - + - On Linux, this is 108. On OSX, 104. TODO: Probe + -} +sizeof_sockaddr_un_sun_path :: Int +sizeof_sockaddr_un_sun_path = 100 + +{- Note that this looks at the true length of the path in bytes, as it will + - appear on disk. -} +valid_unix_socket_path :: FilePath -> Bool +valid_unix_socket_path f = length (decodeW8 f) < sizeof_sockaddr_un_sun_path diff --git a/Command/Sync.hs b/Command/Sync.hs index 2a27bf870..630ceb053 100644 --- a/Command/Sync.hs +++ b/Command/Sync.hs @@ -267,7 +267,7 @@ mergeFile file key ++ takeExtension file shortHash :: String -> String -shortHash = take 4 . md5s . encodeFilePath +shortHash = take 4 . md5s . md5FilePath changed :: Remote -> Git.Ref -> Annex Bool changed remote b = do diff --git a/Locations.hs b/Locations.hs index be5fd6c2f..d68d5fb5f 100644 --- a/Locations.hs +++ b/Locations.hs @@ -248,12 +248,12 @@ hashDirMixed :: Hasher hashDirMixed k = addTrailingPathSeparator $ take 2 dir </> drop 2 dir where dir = take 4 $ display_32bits_as_dir =<< [a,b,c,d] - ABCD (a,b,c,d) = md5 $ encodeFilePath $ key2file k + ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file k hashDirLower :: Hasher hashDirLower k = addTrailingPathSeparator $ take 3 dir </> drop 3 dir where - dir = take 6 $ md5s $ encodeFilePath $ key2file k + dir = take 6 $ md5s $ md5FilePath $ key2file k {- modified version of display_32bits_as_hex from Data.Hash.MD5 - Copyright (C) 2001 Ian Lynagh diff --git a/Utility/FileSystemEncoding.hs b/Utility/FileSystemEncoding.hs index d027ede48..98f2f7755 100644 --- a/Utility/FileSystemEncoding.hs +++ b/Utility/FileSystemEncoding.hs @@ -5,7 +5,13 @@ - Licensed under the GNU GPL version 3 or higher. -} -module Utility.FileSystemEncoding where +module Utility.FileSystemEncoding ( + fileEncoding, + withFilePath, + md5FilePath, + decodeW8, + encodeW8 +) where import qualified GHC.Foreign as GHC import qualified GHC.IO.Encoding as Encoding @@ -31,19 +37,28 @@ withFilePath :: FilePath -> (CString -> IO a) -> IO a withFilePath fp f = Encoding.getFileSystemEncoding >>= \enc -> GHC.withCString enc fp f -{- Encodes a FilePath into a Md5.Str, applying the filesystem encoding. +{- Encodes a FilePath into a String, applying the filesystem encoding. + - + - There are very few things it makes sense to do with such an encoded + - string. It's not a legal filename; it should not be displayed. + - So this function is not exported, but instead used by the few functions + - that can usefully consume it. - - This use of unsafePerformIO is belived to be safe; GHC's interface - only allows doing this conversion with CStrings, and the CString buffer - is allocated, used, and deallocated within the call, with no side - effects. -} -{-# NOINLINE encodeFilePath #-} -encodeFilePath :: FilePath -> MD5.Str -encodeFilePath fp = MD5.Str $ unsafePerformIO $ do +{-# NOINLINE _encodeFilePath #-} +_encodeFilePath :: FilePath -> String +_encodeFilePath fp = unsafePerformIO $ do enc <- Encoding.getFileSystemEncoding GHC.withCString enc fp $ GHC.peekCString Encoding.char8 +{- Encodes a FilePath into a Md5.Str, applying the filesystem encoding. -} +md5FilePath :: FilePath -> MD5.Str +md5FilePath = MD5.Str . _encodeFilePath + {- Converts a [Word8] to a FilePath, encoding using the filesystem encoding. - - w82c produces a String, which may contain Chars that are invalid @@ -55,3 +70,8 @@ encodeW8 :: [Word8] -> FilePath encodeW8 w8 = unsafePerformIO $ do enc <- Encoding.getFileSystemEncoding GHC.withCString Encoding.char8 (w82s w8) $ GHC.peekCString enc + +{- Useful when you want the actual number of bytes that will be used to + - represent the FilePath on disk. -} +decodeW8 :: FilePath -> [Word8] +decodeW8 = s2w8 . _encodeFilePath diff --git a/debian/changelog b/debian/changelog index f35b0e05d..0c0b34e0e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,8 @@ git-annex (3.20120826) UNRELEASED; urgency=low * test: Set a lot of git environment variables so testing works in strange environments that normally need git config to set names, etc. Closes: #682351 Thanks, gregor herrmann + * Disable ssh connection caching if the path to the control socket would be + too long (and use relative path to minimise path to the control socket). -- Joey Hess <joeyh@debian.org> Mon, 27 Aug 2012 13:27:39 -0400 diff --git a/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn index 1bc498dba..a86bd597d 100644 --- a/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn +++ b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn @@ -41,4 +41,10 @@ stdout snippet from git-annex webapp: This data appears on both the sending and receiving git-annex stdout. At least for the initial sync. For later syncs it only appears on the sender, though the client system is using a lot of resources. - +> I've made git-annex detect if the control path would be too long, +> and disable ssh connection caching. It also tries a relative path +> to the file, which tends to make it shorter, and I think would +> keep ssh connection caching working in your example. +> +> Please test and see if it works, and also if the "looping" problem +> still happens. --[[Joey]] |