summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Annex/Ssh.hs21
-rw-r--r--Command/Sync.hs2
-rw-r--r--Locations.hs4
-rw-r--r--Utility/FileSystemEncoding.hs30
-rw-r--r--debian/changelog2
-rw-r--r--doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn8
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]]