]>
Commit | Line | Data |
---|---|---|
a85ad67b JH |
1 | #include "cache.h" |
2 | #include "config.h" | |
3 | #include "repository.h" | |
4 | #include "fsmonitor-settings.h" | |
1e7be10d JH |
5 | #include "fsmonitor.h" |
6 | #include <sys/param.h> | |
7 | #include <sys/mount.h> | |
8 | ||
9 | /* | |
ddc5dacf | 10 | * [1] Remote working directories are problematic for FSMonitor. |
1e7be10d JH |
11 | * |
12 | * The underlying file system on the server machine and/or the remote | |
13 | * mount type (NFS, SAMBA, etc.) dictates whether notification events | |
14 | * are available at all to remote client machines. | |
15 | * | |
16 | * Kernel differences between the server and client machines also | |
17 | * dictate the how (buffering, frequency, de-dup) the events are | |
18 | * delivered to client machine processes. | |
19 | * | |
20 | * A client machine (such as a laptop) may choose to suspend/resume | |
21 | * and it is unclear (without lots of testing) whether the watcher can | |
22 | * resync after a resume. We might be able to treat this as a normal | |
23 | * "events were dropped by the kernel" event and do our normal "flush | |
24 | * and resync" --or-- we might need to close the existing (zombie?) | |
25 | * notification fd and create a new one. | |
26 | * | |
27 | * In theory, the above issues need to be addressed whether we are | |
28 | * using the Hook or IPC API. | |
29 | * | |
30 | * For the builtin FSMonitor, we create the Unix domain socket for the | |
31 | * IPC in the .git directory. If the working directory is remote, | |
32 | * then the socket will be created on the remote file system. This | |
33 | * can fail if the remote file system does not support UDS file types | |
34 | * (e.g. smbfs to a Windows server) or if the remote kernel does not | |
35 | * allow a non-local process to bind() the socket. (These problems | |
36 | * could be fixed by moving the UDS out of the .git directory and to a | |
37 | * well-known local directory on the client machine, but care should | |
38 | * be taken to ensure that $HOME is actually local and not a managed | |
39 | * file share.) | |
40 | * | |
41 | * So (for now at least), mark remote working directories as | |
42 | * incompatible. | |
ddc5dacf JH |
43 | * |
44 | * | |
45 | * [2] FAT32 and NTFS working directories are problematic too. | |
46 | * | |
47 | * The builtin FSMonitor uses a Unix domain socket in the .git | |
48 | * directory for IPC. These Windows drive formats do not support | |
49 | * Unix domain sockets, so mark them as incompatible for the daemon. | |
50 | * | |
1e7be10d | 51 | */ |
ddc5dacf | 52 | static enum fsmonitor_reason check_volume(struct repository *r) |
1e7be10d JH |
53 | { |
54 | struct statfs fs; | |
55 | ||
56 | if (statfs(r->worktree, &fs) == -1) { | |
57 | int saved_errno = errno; | |
58 | trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s", | |
59 | r->worktree, strerror(saved_errno)); | |
60 | errno = saved_errno; | |
61 | return FSMONITOR_REASON_ERROR; | |
62 | } | |
63 | ||
64 | trace_printf_key(&trace_fsmonitor, | |
65 | "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'", | |
66 | r->worktree, fs.f_type, fs.f_flags, fs.f_fstypename); | |
67 | ||
68 | if (!(fs.f_flags & MNT_LOCAL)) | |
69 | return FSMONITOR_REASON_REMOTE; | |
70 | ||
ddc5dacf JH |
71 | if (!strcmp(fs.f_fstypename, "msdos")) /* aka FAT32 */ |
72 | return FSMONITOR_REASON_NOSOCKETS; | |
73 | ||
74 | if (!strcmp(fs.f_fstypename, "ntfs")) | |
75 | return FSMONITOR_REASON_NOSOCKETS; | |
76 | ||
1e7be10d JH |
77 | return FSMONITOR_REASON_OK; |
78 | } | |
a85ad67b JH |
79 | |
80 | enum fsmonitor_reason fsm_os__incompatible(struct repository *r) | |
81 | { | |
1e7be10d JH |
82 | enum fsmonitor_reason reason; |
83 | ||
ddc5dacf | 84 | reason = check_volume(r); |
1e7be10d JH |
85 | if (reason != FSMONITOR_REASON_OK) |
86 | return reason; | |
87 | ||
a85ad67b JH |
88 | return FSMONITOR_REASON_OK; |
89 | } |