watcher: Avoid loop when adding a file owned by someone else fails in indirect mode because its permissions cannot be modified.
Adding the file moved it to the annex, and then tried to set the mode. Error unwind then moved the file back, and so the watcher saw the file get deleted and then added back, and so tried again..
This commit is contained in:
parent
4f373503f2
commit
9ff229a798
3 changed files with 21 additions and 11 deletions
|
@ -26,7 +26,6 @@ import qualified Annex.Queue
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
import Utility.Touch
|
import Utility.Touch
|
||||||
#endif
|
#endif
|
||||||
import Utility.FileMode
|
|
||||||
import Config
|
import Config
|
||||||
import Utility.InodeCache
|
import Utility.InodeCache
|
||||||
import Annex.FileMatcher
|
import Annex.FileMatcher
|
||||||
|
@ -86,11 +85,6 @@ start file = ifAnnexed file addpresent add
|
||||||
- So a KeySource is returned. Its inodeCache can be used to detect any
|
- So a KeySource is returned. Its inodeCache can be used to detect any
|
||||||
- changes that might be made to the file after it was locked down.
|
- changes that might be made to the file after it was locked down.
|
||||||
-
|
-
|
||||||
- In indirect mode, the write bit is removed from the file as part of lock
|
|
||||||
- down to guard against further writes, and because objects in the annex
|
|
||||||
- have their write bit disabled anyway. This is not done in direct mode,
|
|
||||||
- because files there need to remain writable at all times.
|
|
||||||
-
|
|
||||||
- When possible, the file is hard linked to a temp directory. This guards
|
- When possible, the file is hard linked to a temp directory. This guards
|
||||||
- against some changes, like deletion or overwrite of the file, and
|
- against some changes, like deletion or overwrite of the file, and
|
||||||
- allows lsof checks to be done more efficiently when adding a lot of files.
|
- allows lsof checks to be done more efficiently when adding a lot of files.
|
||||||
|
@ -103,16 +97,28 @@ lockDown file = ifM crippledFileSystem
|
||||||
, do
|
, do
|
||||||
tmp <- fromRepo gitAnnexTmpDir
|
tmp <- fromRepo gitAnnexTmpDir
|
||||||
createAnnexDirectory tmp
|
createAnnexDirectory tmp
|
||||||
unlessM isDirect $
|
eitherToMaybe <$> tryAnnexIO (go tmp)
|
||||||
void $ liftIO $ tryIO $ preventWrite file
|
)
|
||||||
liftIO $ catchMaybeIO $ do
|
where
|
||||||
|
{- In indirect mode, the write bit is removed from the file as part
|
||||||
|
- of lock down to guard against further writes, and because objects
|
||||||
|
- in the annex have their write bit disabled anyway.
|
||||||
|
-
|
||||||
|
- Freezing the content early also lets us fail early when
|
||||||
|
- someone else owns the file.
|
||||||
|
-
|
||||||
|
- This is not done in direct mode, because files there need to
|
||||||
|
- remain writable at all times.
|
||||||
|
-}
|
||||||
|
go tmp = do
|
||||||
|
unlessM isDirect $
|
||||||
|
freezeContent file
|
||||||
|
liftIO $ do
|
||||||
(tmpfile, h) <- openTempFile tmp $
|
(tmpfile, h) <- openTempFile tmp $
|
||||||
relatedTemplate $ takeFileName file
|
relatedTemplate $ takeFileName file
|
||||||
hClose h
|
hClose h
|
||||||
nukeFile tmpfile
|
nukeFile tmpfile
|
||||||
withhardlink tmpfile `catchIO` const nohardlink
|
withhardlink tmpfile `catchIO` const nohardlink
|
||||||
)
|
|
||||||
where
|
|
||||||
nohardlink = do
|
nohardlink = do
|
||||||
cache <- genInodeCache file
|
cache <- genInodeCache file
|
||||||
return KeySource
|
return KeySource
|
||||||
|
|
2
debian/changelog
vendored
2
debian/changelog
vendored
|
@ -13,6 +13,8 @@ git-annex (5.20131102) UNRELEASED; urgency=low
|
||||||
git-annex, but it is passed along to every git command git-annex runs.
|
git-annex, but it is passed along to every git command git-annex runs.
|
||||||
* sync: When there are merge conflicts that get automatically resolved,
|
* sync: When there are merge conflicts that get automatically resolved,
|
||||||
exit nonzero at the end.
|
exit nonzero at the end.
|
||||||
|
* watcher: Avoid loop when adding a file owned by someone else fails
|
||||||
|
in indirect mode because its permissions cannot be modified.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Sat, 02 Nov 2013 14:54:36 -0400
|
-- Joey Hess <joeyh@debian.org> Sat, 02 Nov 2013 14:54:36 -0400
|
||||||
|
|
||||||
|
|
|
@ -52,3 +52,5 @@ failed
|
||||||
Turns out that file is owned by root, so it's an expected failure. But the webapp should simply skip this file, not loop over it.
|
Turns out that file is owned by root, so it's an expected failure. But the webapp should simply skip this file, not loop over it.
|
||||||
|
|
||||||
The workaround is obviously to give this file to the proper user. --[[anarcat]]
|
The workaround is obviously to give this file to the proper user. --[[anarcat]]
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue