Commit graph

105 commits

Author SHA1 Message Date
Joey Hess
c908672f3d fix another potential race with the watcher and direct mode
Watcher wants to rewrite symlink to fix it. But in direct mode, the symlink
could be replaced at any time with file content that has finished being
transferred by some other process. So, just don't touch it.

FWIW, I audited the rest of the assistant for places where it removes
files, and the rest is ok. I have not audited the rest of git-annex.
2013-03-04 15:09:32 -04:00
Joey Hess
1d388d5579 fixed the race breaking moving files from archive in direct mode
assistant: Fix bug in direct mode that could occur when a symlink is moved
out of an archive directory, and resulted in the file not being set to
direct mode when it was transferred.

The bug was that the direct mode mapping was not up-to-date when the
transferrer finished. So, finding no direct mode place to store the object,
it was put into .git/annex in indirect mode.

To fix this, just make the watcher update the direct mode mapping to
include the new file before it starts the transfer. (Seems we don't need to
update it to remove the old file if the link was moved, because the direct
mode code will notice it's not present and the mapping gets updated for its
removal later.)

The reason this was a race, and was probably not seen often is because
the committer came along and updated the direct mode mapping as part of
adding the moved symlink. But when the file was sufficiently small or
the remote sufficiently fast, this could happen after the transfer
finished.
2013-03-04 14:25:22 -04:00
Joey Hess
a733271a9c add additional debug info about reasons for drops 2013-03-01 15:58:44 -04:00
Joey Hess
46c9cbeb1e add additional debug info about reasons for transfers 2013-03-01 15:23:59 -04:00
Joey Hess
08854afa10 fix inverted logic 2013-02-22 17:01:48 -04:00
Joey Hess
d7c93b8913 fully support core.symlinks=false in all relevant symlink handling code
Refactored annex link code into nice clean new library.

Audited and dealt with calls to createSymbolicLink.
Remaining calls are all safe, because:

Annex/Link.hs:  ( liftIO $ createSymbolicLink linktarget file
  only when core.symlinks=true
Assistant/WebApp/Configurators/Local.hs:                createSymbolicLink link link
  test if symlinks can be made
Command/Fix.hs: liftIO $ createSymbolicLink link file
  command only works in indirect mode
Command/FromKey.hs:     liftIO $ createSymbolicLink link file
  command only works in indirect mode
Command/Indirect.hs:                    liftIO $ createSymbolicLink l f
  refuses to run if core.symlinks=false
Init.hs:                createSymbolicLink f f2
  test if symlinks can be made
Remote/Directory.hs:    go [file] = catchBoolIO $ createSymbolicLink file f >> return True
  fast key linking; catches failure to make symlink and falls back to copy
Remote/Git.hs:          liftIO $ catchBoolIO $ createSymbolicLink loc file >> return True
  ditto
Upgrade/V1.hs:                          liftIO $ createSymbolicLink link f
  v1 repos could not be on a filesystem w/o symlinks

Audited and dealt with calls to readSymbolicLink.
Remaining calls are all safe, because:

Annex/Link.hs:		( liftIO $ catchMaybeIO $ readSymbolicLink file
  only when core.symlinks=true
Assistant/Threads/Watcher.hs:		ifM ((==) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file))
  code that fixes real symlinks when inotify sees them
  It's ok to not fix psdueo-symlinks.
Assistant/Threads/Watcher.hs:		mlink <- liftIO (catchMaybeIO $ readSymbolicLink file)
  ditto
Command/Fix.hs:	stopUnless ((/=) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file)) $ do
  command only works in indirect mode
Upgrade/V1.hs:	getsymlink = takeFileName <$> readSymbolicLink file
  v1 repos could not be on a filesystem w/o symlinks

Audited and dealt with calls to isSymbolicLink.
(Typically used with getSymbolicLinkStatus, but that is just used because
getFileStatus is not as robust; it also works on pseudolinks.)
Remaining calls are all safe, because:

Assistant/Threads/SanityChecker.hs:                             | isSymbolicLink s -> addsymlink file ms
  only handles staging of symlinks that were somehow not staged
  (might need to be updated to support pseudolinks, but this is
  only a belt-and-suspenders check anyway, and I've never seen the code run)
Command/Add.hs:         if isSymbolicLink s || not (isRegularFile s)
  avoids adding symlinks to the annex, so not relevant
Command/Indirect.hs:                            | isSymbolicLink s -> void $ flip whenAnnexed f $
  only allowed on systems that support symlinks
Command/Indirect.hs:            whenM (liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f) $ do
  ditto
Seek.hs:notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
  used to find unlocked files, only relevant in indirect mode
Utility/FSEvents.hs:                    | Files.isSymbolicLink s = runhook addSymlinkHook $ Just s
Utility/FSEvents.hs:                                            | Files.isSymbolicLink s ->
Utility/INotify.hs:                             | Files.isSymbolicLink s ->
Utility/INotify.hs:                     checkfiletype Files.isSymbolicLink addSymlinkHook f
Utility/Kqueue.hs:              | Files.isSymbolicLink s = callhook addSymlinkHook (Just s) change
  all above are lower-level, not relevant

Audited and dealt with calls to isSymLink.
Remaining calls are all safe, because:

Annex/Direct.hs:			| isSymLink (getmode item) =
  This is looking at git diff-tree objects, not files on disk
Command/Unused.hs:		| isSymLink (LsTree.mode l) = do
  This is looking at git ls-tree, not file on disk
Utility/FileMode.hs:isSymLink :: FileMode -> Bool
Utility/FileMode.hs:isSymLink = checkMode symbolicLinkMode
  low-level

Done!!
2013-02-17 16:43:14 -04:00
Joey Hess
a261412c25 close 2013-01-28 15:39:51 +11:00
Joey Hess
a8bb2749b2 assistant: Ignore .DS_Store on OSX. 2013-01-28 15:13:22 +11:00
Joey Hess
5cd152b8a9 annex.autocommit
New setting, can be used to disable autocommit of changed files by the
assistant, while it still does data syncing and other tasks.

Also wired into webapp UI
2013-01-27 22:43:05 +11:00
Joey Hess
76ddf9b6d3 webapp: Now allows restarting any threads that crash. 2013-01-26 17:09:33 +11:00
Joey Hess
d7ca6fb856 webapp: Now always logs to .git/annex/daemon.log
It used to not log to daemon.log when a repository was first created, and
when starting the webapp. Now both do. Redirecting stdout and stderr to the
log is tricky when starting the webapp, because the web browser may want to
communicate with the user. (Either a console web browser, or web.browser = echo)
This is handled by restoring the original fds when running the browser.
2013-01-15 13:34:59 -04:00
Joey Hess
aedfcde969 guard readSymbolicLink
throws an exception if the file is not a symlink
2013-01-05 16:07:27 -04:00
Joey Hess
1cdf2b923d assistant: Make expensive transfer scan work fully in direct mode.
The expensive scan uses lookupFile, but in direct mode, that doesn't work
for files that are present. So the scan was not finding things that are
present that need to be uploaded. (It did find things not present that
needed to be downloaded.)

Now lookupFile also works in direct mode. Note that it still prefers
symlinks on disk to info committed to git, in direct mode. This is
necessary to make things like Assistant.Threads.Watcher.onAddSymlink
work correctly, when given a new symlink not yet checked into git (or
replacing a file checked into git).
2013-01-05 15:57:53 -04:00
Joey Hess
8cc27b8afc avoid double commits with inotify when direct mode file is created 2012-12-29 14:58:13 -04:00
Joey Hess
bf3270c5b7 add missing modifyHook for watcher
Needed for FSEvents, which calls that hook for modified files.
inotify seems to call the add hook, so I didn't notice it before.
2012-12-28 16:00:45 -04:00
Joey Hess
eb40227d15 assistant direct mode file add/change bookkeeping
When a file is changed in direct mode, the old content is probably lost
(at least from the local repo), and bookeeping needs to be updated to
reflect this.

Also, synthetic add events are generated at assistant startup, so
make it detect when the file has not really changed, and avoid re-adding
it.

This does add the overhead of querying the runing git cat-file for the
key that's recorded in git for the file, each time a file is added or
modified in direct mode.
2012-12-25 15:48:15 -04:00
Joey Hess
cc5140d295 assistant adding of modified files in direct mode
Works with inotify, but I think in kqueue we don't get events
existing files that get modified.
2012-12-24 14:42:19 -04:00
Joey Hess
95db595e91 make startup scan for deleted files work in direct mode
git add --update cannot be used, because it'll stage typechanged direct
mode files. Intead, use ls-files to find deleted files, and stage them
ourselves.

It seems that no commit was made before when the scan staged deleted files.
(Probably masked since if files were added, a commit happened then..)
Now that I'm doing the staging, I was also able to fix that bug.
2012-12-24 14:24:13 -04:00
Joey Hess
c6d2bbe402 assistant adding of files in direct mode 2012-12-24 13:37:29 -04:00
Joey Hess
82617b92e9 move thirdparty program installation for standalone bundle into haskell program
This allows it to use Build.SysConfig to always install the programs
configure detected. Amoung other fixes, this ensures the right uuid
generator and checksum programs are installed.

I also cleaned up the handling of lsof's path; configure now checks for
it in PATH, but falls back to looking for it in sbin directories.
2012-12-14 16:07:59 -04:00
Joey Hess
463cf58140 webapp and assistant glacier support 2012-11-24 16:30:15 -04:00
Joey Hess
c282c8b492 queue uploads when a new or renamed symlink is handled 2012-11-24 15:38:24 -04:00
Joey Hess
93ffd47d76 finished pushing Assistant monad into all relevant files
All temporary and old functions are removed.
2012-10-30 17:14:51 -04:00
Joey Hess
47d94eb9a4 pushed Assistant monad down into DaemonStatus code
Currently have three old versions of functions that more reworking is
needed to remove: getDaemonStatusOld, modifyDaemonStatusOld_, and
modifyDaemonStatusOld
2012-10-30 15:39:15 -04:00
Joey Hess
ea8df8fe9f cleanup daemonStatus accessors 2012-10-30 14:44:18 -04:00
Joey Hess
d2294f0dfa split Changes and lifted 2012-10-29 19:30:23 -04:00
Joey Hess
1852eddce6 lift alertWhile 2012-10-29 16:49:47 -04:00
Joey Hess
0ba4df3c1a tweak 2012-10-29 11:58:29 -04:00
Joey Hess
76768ad977 converted 6 more threads 2012-10-29 11:40:22 -04:00
Joey Hess
bad88e404a convert Watcher thread to Assistant monad
This is a nice win; much less code runs in Annex, so other threads have
more chances to run concurrently.

I do notice that renaming a file has gone from 1 to 2 commits. I think this
is due to the above improvement letting the committer run more frequently,
so it commits the rm first.
2012-10-29 09:55:40 -04:00
Joey Hess
4dbdc2b666 Assistant monad, stage 2.5
Converted several threads to run in the monad.

Added a lot of useful combinators for working with the monad.

Now the monad includes the name of the thread.

Some debugging messages are disabled pending converting other threads.
2012-10-29 02:21:04 -04:00
Joey Hess
4e765327ca Assistant monad, stage 1
This adds the Assistant monad, and an AssistantData structure.
So far, none of the assistant's threads run in the monad yet.
2012-10-29 00:15:43 -04:00
Joey Hess
f4c3a45da0 check preferred content when a file is moved or created
This can result in the file being dropped, or being downloaded, or even
being dropped from some other repo.

It's even possible to create a file in a directory where content is not
wanted, which will make the assistant immediately send it elsewhere, and
then drop it.
2012-10-19 14:22:13 -04:00
Joey Hess
9aab70de66 always check with ls-files before adding new files
Makes it safe to use git annex unlock with the watcher/assistant.
And also to mix use of the watcher/assistant with regular files stored in git.

Long ago, I had avoided doing this check, except during the startup scan,
because it would be slow to run ls-files repeatedly.

But then I added the lsof check, and to make that fast, got it to detect
batch file adds. So let's move the ls-files check to also occur when it'll
have a batch, and can check them all with one call.

This does slow down adding a single file by just a bit, but really only
a little bit. (The lsof check is probably more expensive.) It also
speeds up the startup scan, especially when there are lots of new files
found by the scan.

Also, fixed the sleep for annex.delayadd to not run while the threadstate
lock is held, so it doesn't unnecessarily freeze everything else.

Also, --force no longer makes it skip the lsof check, which was not
documented, and seems never a good idea.
2012-10-02 17:41:23 -04:00
Joey Hess
2840105ec4 default annex.delayadd to 1 on OSX 2012-09-21 19:43:15 -04:00
Joey Hess
68ad7de4d0 watch for changes to transfer info files, to update progress bars on upload
This is handled differently for inotify, which can track modifications of
existing files, and kqueue, which cannot (TTBOMK). On the inotify side,
the TransferWatcher just waits for the file to be updated and reads the new
bytesComplete. On the kqueue side, the TransferPoller has to re-read the
file every update (currently 0.5 seconds, might need to increase that).

I did think about working around kqueue's limitations by somehow creating
a new file each time the size changed. But cleaning up all the files that
would result seemed difficult. And really, this is not a lot worse than
the TransferWatcher's behavior for downloads, which stats a file every 0.5
seconds. As long as the OS has decent file caching behavior..
2012-09-20 17:24:40 -04:00
Joey Hess
355ef8f3ea add annex.delayadd configuration 2012-09-19 13:30:25 -04:00
Joey Hess
df337bb63b hlint 2012-09-13 00:57:52 -04:00
Joey Hess
a00f1d26bc display errors when any named thread crashes 2012-09-06 14:56:04 -04:00
Joey Hess
d11ded822c display alert for inotify/kqueue errors 2012-09-06 13:56:23 -04:00
Joey Hess
5de897e8d7 remove the "running" alert 2012-07-30 18:26:36 -04:00
Joey Hess
b2e359a15d fix kqueue build 2012-07-30 16:32:32 -04:00
Joey Hess
3dce75fb23 make old activiy alerts stay visible
They're updated to show whether the activity succeeded or failed.

This adds several TODOs to the code to fix later.
2012-07-30 02:39:24 -04:00
Joey Hess
d62b157194 better ordering of alerts 2012-07-29 19:05:51 -04:00
Joey Hess
d52c932424 moved all alert messages into one file
Makes it easier to edit for consistent voice etc.
2012-07-29 18:09:24 -04:00
Joey Hess
09e77a0cf0 add some alerts 2012-07-29 13:22:08 -04:00
Joey Hess
c2f3e66d8c show alerts in the sidebar
This has a bug -- it seems long polling can only wait on one page at a
time. Need to re-unify the notifiers.
2012-07-29 11:31:06 -04:00
Joey Hess
3cc1885793 move DaemonStatus manipulation out of the Annex monad to IO
I've convinced myself that nothing in DaemonStatus can deadlock,
as it always keepts the TMVar full. That was the only reason it was in the
Annex monad.
2012-07-28 18:02:11 -04:00
Joey Hess
a9dbfdf28d better transfer queue management
Allow transfers to be added with blocking until the queue is sufficiently
small.

Better control over which end of the queue to add a transfer to.
2012-07-25 13:12:34 -04:00
Joey Hess
b48d7747a3 debugging improvements
add timestamps to debug messages

Add lots of debug output in the assistant's threads.
2012-07-20 19:29:59 -04:00
Joey Hess
f20a40f9d4 MountWatcher thread
Currently only prints mount points when mounts happen.
2012-07-19 13:04:33 -04:00
Joey Hess
62876502c5 wait on child transfer processes, and invalidate cache
There's still a bug; if the child updates its transfer info file,
then the data from it will superscede the TransferInfo, losing the
info that we should wait on this child.
2012-07-06 16:44:13 -06:00
Joey Hess
6af319d8cd enqueue Downloads when new symlinks appear to content we don't have 2012-07-05 10:58:49 -06:00
Joey Hess
4888c5b042 improve thread termination handling
The reason the DirWatcher had to wait for program termination was because
it used withINotify, so when it finished, its watcher threads were killed.
But since I have two DirWatcher threads now, that was not good, and could
perhaps explain the MVar problem I saw yesterday. In any case, fixed this
part of the code by making the DirWatcher return a handle that can be used
to stop it, and now the main Assistant thread is the only one calling
waitForTermination.
2012-06-28 13:37:03 -04:00
Joey Hess
0b146f9ecc reorg threads 2012-06-25 16:10:24 -04:00
Renamed from Assistant/Watcher.hs (Browse further)