]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/fsmonitor--daemon.c
Merge branch 'rs/parse-options-with-keep-unknown-abbrev-fix'
[thirdparty/git.git] / builtin / fsmonitor--daemon.c
CommitLineData
16d9d617 1#include "builtin.h"
0b027f6c 2#include "abspath.h"
16d9d617 3#include "config.h"
31d20faa 4#include "dir.h"
32a8f510 5#include "environment.h"
f394e093 6#include "gettext.h"
16d9d617 7#include "parse-options.h"
68d68646 8#include "fsmonitor-ll.h"
16d9d617 9#include "fsmonitor-ipc.h"
68d68646 10#include "fsmonitor-settings.h"
d0605550 11#include "compat/fsmonitor/fsm-health.h"
9dcba0ba
JH
12#include "compat/fsmonitor/fsm-listen.h"
13#include "fsmonitor--daemon.h"
ec2101ab 14#include "repository.h"
16d9d617
JH
15#include "simple-ipc.h"
16#include "khash.h"
31d20faa 17#include "run-command.h"
68d68646 18#include "trace.h"
74ea5c95 19#include "trace2.h"
16d9d617
JH
20
21static const char * const builtin_fsmonitor__daemon_usage[] = {
c284e27b 22 N_("git fsmonitor--daemon start [<options>]"),
9dcba0ba 23 N_("git fsmonitor--daemon run [<options>]"),
02cb8b9e
AH
24 "git fsmonitor--daemon stop",
25 "git fsmonitor--daemon status",
16d9d617
JH
26 NULL
27};
28
29#ifdef HAVE_FSMONITOR_DAEMON_BACKEND
9dcba0ba
JH
30/*
31 * Global state loaded from config.
32 */
33#define FSMONITOR__IPC_THREADS "fsmonitor.ipcthreads"
34static int fsmonitor__ipc_threads = 8;
35
c284e27b
JH
36#define FSMONITOR__START_TIMEOUT "fsmonitor.starttimeout"
37static int fsmonitor__start_timeout_sec = 60;
38
9dcba0ba
JH
39#define FSMONITOR__ANNOUNCE_STARTUP "fsmonitor.announcestartup"
40static int fsmonitor__announce_startup = 0;
41
a4e7e317
GC
42static int fsmonitor_config(const char *var, const char *value,
43 const struct config_context *ctx, void *cb)
9dcba0ba
JH
44{
45 if (!strcmp(var, FSMONITOR__IPC_THREADS)) {
8868b1eb 46 int i = git_config_int(var, value, ctx->kvi);
9dcba0ba
JH
47 if (i < 1)
48 return error(_("value of '%s' out of range: %d"),
49 FSMONITOR__IPC_THREADS, i);
50 fsmonitor__ipc_threads = i;
51 return 0;
52 }
53
c284e27b 54 if (!strcmp(var, FSMONITOR__START_TIMEOUT)) {
8868b1eb 55 int i = git_config_int(var, value, ctx->kvi);
c284e27b
JH
56 if (i < 0)
57 return error(_("value of '%s' out of range: %d"),
58 FSMONITOR__START_TIMEOUT, i);
59 fsmonitor__start_timeout_sec = i;
60 return 0;
61 }
62
9dcba0ba
JH
63 if (!strcmp(var, FSMONITOR__ANNOUNCE_STARTUP)) {
64 int is_bool;
8868b1eb 65 int i = git_config_bool_or_int(var, value, ctx->kvi, &is_bool);
9dcba0ba
JH
66 if (i < 0)
67 return error(_("value of '%s' not bool or int: %d"),
68 var, i);
69 fsmonitor__announce_startup = i;
70 return 0;
71 }
72
a4e7e317 73 return git_default_config(var, value, ctx, cb);
9dcba0ba
JH
74}
75
abc9dbc0
JH
76/*
77 * Acting as a CLIENT.
78 *
79 * Send a "quit" command to the `git-fsmonitor--daemon` (if running)
80 * and wait for it to shutdown.
81 */
82static int do_as_client__send_stop(void)
83{
84 struct strbuf answer = STRBUF_INIT;
85 int ret;
86
87 ret = fsmonitor_ipc__send_command("quit", &answer);
88
89 /* The quit command does not return any response data. */
90 strbuf_release(&answer);
91
92 if (ret)
93 return ret;
94
95 trace2_region_enter("fsm_client", "polling-for-daemon-exit", NULL);
96 while (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
97 sleep_millisec(50);
98 trace2_region_leave("fsm_client", "polling-for-daemon-exit", NULL);
99
100 return 0;
101}
102
103static int do_as_client__status(void)
104{
105 enum ipc_active_state state = fsmonitor_ipc__get_state();
106
107 switch (state) {
108 case IPC_STATE__LISTENING:
109 printf(_("fsmonitor-daemon is watching '%s'\n"),
110 the_repository->worktree);
111 return 0;
112
113 default:
114 printf(_("fsmonitor-daemon is not watching '%s'\n"),
115 the_repository->worktree);
116 return 1;
117 }
118}
16d9d617 119
b05880d3
JH
120enum fsmonitor_cookie_item_result {
121 FCIR_ERROR = -1, /* could not create cookie file ? */
122 FCIR_INIT,
123 FCIR_SEEN,
124 FCIR_ABORT,
125};
126
127struct fsmonitor_cookie_item {
128 struct hashmap_entry entry;
129 char *name;
130 enum fsmonitor_cookie_item_result result;
131};
132
1fe41944
JK
133static int cookies_cmp(const void *data UNUSED,
134 const struct hashmap_entry *he1,
135 const struct hashmap_entry *he2, const void *keydata)
b05880d3
JH
136{
137 const struct fsmonitor_cookie_item *a =
138 container_of(he1, const struct fsmonitor_cookie_item, entry);
139 const struct fsmonitor_cookie_item *b =
140 container_of(he2, const struct fsmonitor_cookie_item, entry);
141
142 return strcmp(a->name, keydata ? keydata : b->name);
143}
144
145static enum fsmonitor_cookie_item_result with_lock__wait_for_cookie(
146 struct fsmonitor_daemon_state *state)
147{
148 /* assert current thread holding state->main_lock */
149
150 int fd;
151 struct fsmonitor_cookie_item *cookie;
152 struct strbuf cookie_pathname = STRBUF_INIT;
153 struct strbuf cookie_filename = STRBUF_INIT;
154 enum fsmonitor_cookie_item_result result;
155 int my_cookie_seq;
156
157 CALLOC_ARRAY(cookie, 1);
158
159 my_cookie_seq = state->cookie_seq++;
160
161 strbuf_addf(&cookie_filename, "%i-%i", getpid(), my_cookie_seq);
162
163 strbuf_addbuf(&cookie_pathname, &state->path_cookie_prefix);
164 strbuf_addbuf(&cookie_pathname, &cookie_filename);
165
166 cookie->name = strbuf_detach(&cookie_filename, NULL);
167 cookie->result = FCIR_INIT;
168 hashmap_entry_init(&cookie->entry, strhash(cookie->name));
169
170 hashmap_add(&state->cookies, &cookie->entry);
171
172 trace_printf_key(&trace_fsmonitor, "cookie-wait: '%s' '%s'",
173 cookie->name, cookie_pathname.buf);
174
175 /*
176 * Create the cookie file on disk and then wait for a notification
177 * that the listener thread has seen it.
178 */
179 fd = open(cookie_pathname.buf, O_WRONLY | O_CREAT | O_EXCL, 0600);
180 if (fd < 0) {
181 error_errno(_("could not create fsmonitor cookie '%s'"),
182 cookie->name);
183
184 cookie->result = FCIR_ERROR;
185 goto done;
186 }
187
188 /*
189 * Technically, close() and unlink() can fail, but we don't
190 * care here. We only created the file to trigger a watch
191 * event from the FS to know that when we're up to date.
192 */
193 close(fd);
194 unlink(cookie_pathname.buf);
195
196 /*
197 * Technically, this is an infinite wait (well, unless another
198 * thread sends us an abort). I'd like to change this to
199 * use `pthread_cond_timedwait()` and return an error/timeout
200 * and let the caller do the trivial response thing, but we
201 * don't have that routine in our thread-utils.
202 *
203 * After extensive beta testing I'm not really worried about
204 * this. Also note that the above open() and unlink() calls
205 * will cause at least two FS events on that path, so the odds
206 * of getting stuck are pretty slim.
207 */
208 while (cookie->result == FCIR_INIT)
209 pthread_cond_wait(&state->cookies_cond,
210 &state->main_lock);
211
212done:
213 hashmap_remove(&state->cookies, &cookie->entry, NULL);
214
215 result = cookie->result;
216
217 free(cookie->name);
218 free(cookie);
219 strbuf_release(&cookie_pathname);
220
221 return result;
222}
223
224/*
225 * Mark these cookies as _SEEN and wake up the corresponding client threads.
226 */
227static void with_lock__mark_cookies_seen(struct fsmonitor_daemon_state *state,
228 const struct string_list *cookie_names)
229{
230 /* assert current thread holding state->main_lock */
231
232 int k;
233 int nr_seen = 0;
234
235 for (k = 0; k < cookie_names->nr; k++) {
236 struct fsmonitor_cookie_item key;
237 struct fsmonitor_cookie_item *cookie;
238
239 key.name = cookie_names->items[k].string;
240 hashmap_entry_init(&key.entry, strhash(key.name));
241
242 cookie = hashmap_get_entry(&state->cookies, &key, entry, NULL);
243 if (cookie) {
244 trace_printf_key(&trace_fsmonitor, "cookie-seen: '%s'",
245 cookie->name);
246 cookie->result = FCIR_SEEN;
247 nr_seen++;
248 }
249 }
250
251 if (nr_seen)
252 pthread_cond_broadcast(&state->cookies_cond);
253}
254
255/*
256 * Set _ABORT on all pending cookies and wake up all client threads.
257 */
258static void with_lock__abort_all_cookies(struct fsmonitor_daemon_state *state)
259{
260 /* assert current thread holding state->main_lock */
261
262 struct hashmap_iter iter;
263 struct fsmonitor_cookie_item *cookie;
264 int nr_aborted = 0;
265
266 hashmap_for_each_entry(&state->cookies, &iter, cookie, entry) {
267 trace_printf_key(&trace_fsmonitor, "cookie-abort: '%s'",
268 cookie->name);
269 cookie->result = FCIR_ABORT;
270 nr_aborted++;
271 }
272
273 if (nr_aborted)
274 pthread_cond_broadcast(&state->cookies_cond);
275}
276
aeef767a
JH
277/*
278 * Requests to and from a FSMonitor Protocol V2 provider use an opaque
279 * "token" as a virtual timestamp. Clients can request a summary of all
280 * created/deleted/modified files relative to a token. In the response,
281 * clients receive a new token for the next (relative) request.
282 *
283 *
284 * Token Format
285 * ============
286 *
287 * The contents of the token are private and provider-specific.
288 *
289 * For the built-in fsmonitor--daemon, we define a token as follows:
290 *
291 * "builtin" ":" <token_id> ":" <sequence_nr>
292 *
293 * The "builtin" prefix is used as a namespace to avoid conflicts
294 * with other providers (such as Watchman).
295 *
296 * The <token_id> is an arbitrary OPAQUE string, such as a GUID,
297 * UUID, or {timestamp,pid}. It is used to group all filesystem
298 * events that happened while the daemon was monitoring (and in-sync
299 * with the filesystem).
300 *
301 * Unlike FSMonitor Protocol V1, it is not defined as a timestamp
302 * and does not define less-than/greater-than relationships.
303 * (There are too many race conditions to rely on file system
304 * event timestamps.)
305 *
306 * The <sequence_nr> is a simple integer incremented whenever the
307 * daemon needs to make its state public. For example, if 1000 file
308 * system events come in, but no clients have requested the data,
309 * the daemon can continue to accumulate file changes in the same
310 * bin and does not need to advance the sequence number. However,
311 * as soon as a client does arrive, the daemon needs to start a new
312 * bin and increment the sequence number.
313 *
314 * The sequence number serves as the boundary between 2 sets
315 * of bins -- the older ones that the client has already seen
316 * and the newer ones that it hasn't.
317 *
318 * When a new <token_id> is created, the <sequence_nr> is reset to
319 * zero.
320 *
321 *
322 * About Token Ids
323 * ===============
324 *
325 * A new token_id is created:
326 *
327 * [1] each time the daemon is started.
328 *
329 * [2] any time that the daemon must re-sync with the filesystem
330 * (such as when the kernel drops or we miss events on a very
331 * active volume).
332 *
333 * [3] in response to a client "flush" command (for dropped event
334 * testing).
335 *
336 * When a new token_id is created, the daemon is free to discard all
337 * cached filesystem events associated with any previous token_ids.
338 * Events associated with a non-current token_id will never be sent
339 * to a client. A token_id change implicitly means that the daemon
340 * has gap in its event history.
341 *
342 * Therefore, clients that present a token with a stale (non-current)
343 * token_id will always be given a trivial response.
344 */
345struct fsmonitor_token_data {
346 struct strbuf token_id;
347 struct fsmonitor_batch *batch_head;
348 struct fsmonitor_batch *batch_tail;
349 uint64_t client_ref_count;
350};
351
bec486b9
JH
352struct fsmonitor_batch {
353 struct fsmonitor_batch *next;
354 uint64_t batch_seq_nr;
355 const char **interned_paths;
356 size_t nr, alloc;
357 time_t pinned_time;
358};
359
aeef767a
JH
360static struct fsmonitor_token_data *fsmonitor_new_token_data(void)
361{
362 static int test_env_value = -1;
363 static uint64_t flush_count = 0;
364 struct fsmonitor_token_data *token;
bec486b9 365 struct fsmonitor_batch *batch;
aeef767a
JH
366
367 CALLOC_ARRAY(token, 1);
bec486b9 368 batch = fsmonitor_batch__new();
aeef767a
JH
369
370 strbuf_init(&token->token_id, 0);
bec486b9
JH
371 token->batch_head = batch;
372 token->batch_tail = batch;
aeef767a
JH
373 token->client_ref_count = 0;
374
375 if (test_env_value < 0)
376 test_env_value = git_env_bool("GIT_TEST_FSMONITOR_TOKEN", 0);
377
378 if (!test_env_value) {
379 struct timeval tv;
380 struct tm tm;
381 time_t secs;
382
383 gettimeofday(&tv, NULL);
384 secs = tv.tv_sec;
385 gmtime_r(&secs, &tm);
386
387 strbuf_addf(&token->token_id,
388 "%"PRIu64".%d.%4d%02d%02dT%02d%02d%02d.%06ldZ",
389 flush_count++,
390 getpid(),
391 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
392 tm.tm_hour, tm.tm_min, tm.tm_sec,
393 (long)tv.tv_usec);
394 } else {
395 strbuf_addf(&token->token_id, "test_%08x", test_env_value++);
396 }
397
bec486b9
JH
398 /*
399 * We created a new <token_id> and are starting a new series
400 * of tokens with a zero <seq_nr>.
401 *
402 * Since clients cannot guess our new (non test) <token_id>
403 * they will always receive a trivial response (because of the
404 * mismatch on the <token_id>). The trivial response will
405 * tell them our new <token_id> so that subsequent requests
406 * will be relative to our new series. (And when sending that
407 * response, we pin the current head of the batch list.)
408 *
409 * Even if the client correctly guesses the <token_id>, their
410 * request of "builtin:<token_id>:0" asks for all changes MORE
411 * RECENT than batch/bin 0.
412 *
413 * This implies that it is a waste to accumulate paths in the
414 * initial batch/bin (because they will never be transmitted).
415 *
416 * So the daemon could be running for days and watching the
417 * file system, but doesn't need to actually accumulate any
418 * paths UNTIL we need to set a reference point for a later
419 * relative request.
420 *
421 * However, it is very useful for testing to always have a
422 * reference point set. Pin batch 0 to force early file system
423 * events to accumulate.
424 */
425 if (test_env_value)
426 batch->pinned_time = time(NULL);
427
aeef767a
JH
428 return token;
429}
430
bec486b9
JH
431struct fsmonitor_batch *fsmonitor_batch__new(void)
432{
433 struct fsmonitor_batch *batch;
434
435 CALLOC_ARRAY(batch, 1);
436
437 return batch;
438}
439
440void fsmonitor_batch__free_list(struct fsmonitor_batch *batch)
441{
442 while (batch) {
443 struct fsmonitor_batch *next = batch->next;
444
445 /*
446 * The actual strings within the array of this batch
447 * are interned, so we don't own them. We only own
448 * the array.
449 */
450 free(batch->interned_paths);
451 free(batch);
452
453 batch = next;
454 }
455}
456
457void fsmonitor_batch__add_path(struct fsmonitor_batch *batch,
458 const char *path)
459{
460 const char *interned_path = strintern(path);
461
462 trace_printf_key(&trace_fsmonitor, "event: %s", interned_path);
463
464 ALLOC_GROW(batch->interned_paths, batch->nr + 1, batch->alloc);
465 batch->interned_paths[batch->nr++] = interned_path;
466}
467
468static void fsmonitor_batch__combine(struct fsmonitor_batch *batch_dest,
469 const struct fsmonitor_batch *batch_src)
470{
471 size_t k;
472
473 ALLOC_GROW(batch_dest->interned_paths,
474 batch_dest->nr + batch_src->nr + 1,
475 batch_dest->alloc);
476
477 for (k = 0; k < batch_src->nr; k++)
478 batch_dest->interned_paths[batch_dest->nr++] =
479 batch_src->interned_paths[k];
480}
481
50c725d6
JH
482/*
483 * To keep the batch list from growing unbounded in response to filesystem
484 * activity, we try to truncate old batches from the end of the list as
485 * they become irrelevant.
486 *
487 * We assume that the .git/index will be updated with the most recent token
488 * any time the index is updated. And future commands will only ask for
489 * recent changes *since* that new token. So as tokens advance into the
490 * future, older batch items will never be requested/needed. So we can
491 * truncate them without loss of functionality.
492 *
493 * However, multiple commands may be talking to the daemon concurrently
494 * or perform a slow command, so a little "token skew" is possible.
495 * Therefore, we want this to be a little bit lazy and have a generous
496 * delay.
497 *
498 * The current reader thread walked backwards in time from `token->batch_head`
499 * back to `batch_marker` somewhere in the middle of the batch list.
500 *
501 * Let's walk backwards in time from that marker an arbitrary delay
502 * and truncate the list there. Note that these timestamps are completely
503 * artificial (based on when we pinned the batch item) and not on any
504 * filesystem activity.
505 *
506 * Return the obsolete portion of the list after we have removed it from
507 * the official list so that the caller can free it after leaving the lock.
508 */
509#define MY_TIME_DELAY_SECONDS (5 * 60) /* seconds */
510
511static struct fsmonitor_batch *with_lock__truncate_old_batches(
512 struct fsmonitor_daemon_state *state,
513 const struct fsmonitor_batch *batch_marker)
514{
515 /* assert current thread holding state->main_lock */
516
517 const struct fsmonitor_batch *batch;
518 struct fsmonitor_batch *remainder;
519
520 if (!batch_marker)
521 return NULL;
522
523 trace_printf_key(&trace_fsmonitor, "Truncate: mark (%"PRIu64",%"PRIu64")",
524 batch_marker->batch_seq_nr,
525 (uint64_t)batch_marker->pinned_time);
526
527 for (batch = batch_marker; batch; batch = batch->next) {
528 time_t t;
529
530 if (!batch->pinned_time) /* an overflow batch */
531 continue;
532
533 t = batch->pinned_time + MY_TIME_DELAY_SECONDS;
534 if (t > batch_marker->pinned_time) /* too close to marker */
535 continue;
536
537 goto truncate_past_here;
538 }
539
540 return NULL;
541
542truncate_past_here:
543 state->current_token_data->batch_tail = (struct fsmonitor_batch *)batch;
544
545 remainder = ((struct fsmonitor_batch *)batch)->next;
546 ((struct fsmonitor_batch *)batch)->next = NULL;
547
548 return remainder;
549}
550
bec486b9
JH
551static void fsmonitor_free_token_data(struct fsmonitor_token_data *token)
552{
553 if (!token)
554 return;
555
556 assert(token->client_ref_count == 0);
557
558 strbuf_release(&token->token_id);
559
560 fsmonitor_batch__free_list(token->batch_head);
561
562 free(token);
563}
564
565/*
566 * Flush all of our cached data about the filesystem. Call this if we
567 * lose sync with the filesystem and miss some notification events.
568 *
569 * [1] If we are missing events, then we no longer have a complete
570 * history of the directory (relative to our current start token).
571 * We should create a new token and start fresh (as if we just
572 * booted up).
573 *
b05880d3
JH
574 * [2] Some of those lost events may have been for cookie files. We
575 * should assume the worst and abort them rather letting them starve.
576 *
bec486b9
JH
577 * If there are no concurrent threads reading the current token data
578 * series, we can free it now. Otherwise, let the last reader free
579 * it.
580 *
581 * Either way, the old token data series is no longer associated with
582 * our state data.
583 */
584static void with_lock__do_force_resync(struct fsmonitor_daemon_state *state)
585{
586 /* assert current thread holding state->main_lock */
587
588 struct fsmonitor_token_data *free_me = NULL;
589 struct fsmonitor_token_data *new_one = NULL;
590
591 new_one = fsmonitor_new_token_data();
592
593 if (state->current_token_data->client_ref_count == 0)
594 free_me = state->current_token_data;
595 state->current_token_data = new_one;
596
597 fsmonitor_free_token_data(free_me);
b05880d3
JH
598
599 with_lock__abort_all_cookies(state);
bec486b9
JH
600}
601
602void fsmonitor_force_resync(struct fsmonitor_daemon_state *state)
603{
604 pthread_mutex_lock(&state->main_lock);
605 with_lock__do_force_resync(state);
606 pthread_mutex_unlock(&state->main_lock);
607}
608
518a522f
JH
609/*
610 * Format an opaque token string to send to the client.
611 */
612static void with_lock__format_response_token(
613 struct strbuf *response_token,
614 const struct strbuf *response_token_id,
615 const struct fsmonitor_batch *batch)
616{
617 /* assert current thread holding state->main_lock */
618
619 strbuf_reset(response_token);
620 strbuf_addf(response_token, "builtin:%s:%"PRIu64,
621 response_token_id->buf, batch->batch_seq_nr);
622}
623
624/*
625 * Parse an opaque token from the client.
626 * Returns -1 on error.
627 */
628static int fsmonitor_parse_client_token(const char *buf_token,
629 struct strbuf *requested_token_id,
630 uint64_t *seq_nr)
631{
632 const char *p;
633 char *p_end;
634
635 strbuf_reset(requested_token_id);
636 *seq_nr = 0;
637
638 if (!skip_prefix(buf_token, "builtin:", &p))
639 return -1;
640
641 while (*p && *p != ':')
642 strbuf_addch(requested_token_id, *p++);
643 if (!*p++)
644 return -1;
645
646 *seq_nr = (uint64_t)strtoumax(p, &p_end, 10);
647 if (*p_end)
648 return -1;
649
650 return 0;
651}
652
653KHASH_INIT(str, const char *, int, 0, kh_str_hash_func, kh_str_hash_equal)
654
655static int do_handle_client(struct fsmonitor_daemon_state *state,
656 const char *command,
657 ipc_server_reply_cb *reply,
658 struct ipc_server_reply_data *reply_data)
659{
660 struct fsmonitor_token_data *token_data = NULL;
661 struct strbuf response_token = STRBUF_INIT;
662 struct strbuf requested_token_id = STRBUF_INIT;
663 struct strbuf payload = STRBUF_INIT;
664 uint64_t requested_oldest_seq_nr = 0;
665 uint64_t total_response_len = 0;
666 const char *p;
667 const struct fsmonitor_batch *batch_head;
668 const struct fsmonitor_batch *batch;
50c725d6 669 struct fsmonitor_batch *remainder = NULL;
518a522f
JH
670 intmax_t count = 0, duplicates = 0;
671 kh_str_t *shown;
672 int hash_ret;
673 int do_trivial = 0;
674 int do_flush = 0;
b05880d3
JH
675 int do_cookie = 0;
676 enum fsmonitor_cookie_item_result cookie_result;
518a522f
JH
677
678 /*
679 * We expect `command` to be of the form:
680 *
681 * <command> := quit NUL
682 * | flush NUL
683 * | <V1-time-since-epoch-ns> NUL
684 * | <V2-opaque-fsmonitor-token> NUL
685 */
686
687 if (!strcmp(command, "quit")) {
688 /*
689 * A client has requested over the socket/pipe that the
690 * daemon shutdown.
691 *
692 * Tell the IPC thread pool to shutdown (which completes
693 * the await in the main thread (which can stop the
694 * fsmonitor listener thread)).
695 *
696 * There is no reply to the client.
697 */
698 return SIMPLE_IPC_QUIT;
699
700 } else if (!strcmp(command, "flush")) {
701 /*
702 * Flush all of our cached data and generate a new token
703 * just like if we lost sync with the filesystem.
704 *
705 * Then send a trivial response using the new token.
706 */
707 do_flush = 1;
708 do_trivial = 1;
709
710 } else if (!skip_prefix(command, "builtin:", &p)) {
711 /* assume V1 timestamp or garbage */
712
713 char *p_end;
714
715 strtoumax(command, &p_end, 10);
716 trace_printf_key(&trace_fsmonitor,
717 ((*p_end) ?
718 "fsmonitor: invalid command line '%s'" :
719 "fsmonitor: unsupported V1 protocol '%s'"),
720 command);
721 do_trivial = 1;
6692d454 722 do_cookie = 1;
518a522f
JH
723
724 } else {
725 /* We have "builtin:*" */
726 if (fsmonitor_parse_client_token(command, &requested_token_id,
727 &requested_oldest_seq_nr)) {
728 trace_printf_key(&trace_fsmonitor,
729 "fsmonitor: invalid V2 protocol token '%s'",
730 command);
731 do_trivial = 1;
6692d454 732 do_cookie = 1;
518a522f
JH
733
734 } else {
735 /*
736 * We have a V2 valid token:
737 * "builtin:<token_id>:<seq_nr>"
738 */
b05880d3 739 do_cookie = 1;
518a522f
JH
740 }
741 }
742
743 pthread_mutex_lock(&state->main_lock);
744
745 if (!state->current_token_data)
746 BUG("fsmonitor state does not have a current token");
747
b05880d3
JH
748 /*
749 * Write a cookie file inside the directory being watched in
750 * an effort to flush out existing filesystem events that we
751 * actually care about. Suspend this client thread until we
752 * see the filesystem events for this cookie file.
753 *
754 * Creating the cookie lets us guarantee that our FS listener
755 * thread has drained the kernel queue and we are caught up
756 * with the kernel.
757 *
758 * If we cannot create the cookie (or otherwise guarantee that
759 * we are caught up), we send a trivial response. We have to
760 * assume that there might be some very, very recent activity
761 * on the FS still in flight.
762 */
763 if (do_cookie) {
764 cookie_result = with_lock__wait_for_cookie(state);
765 if (cookie_result != FCIR_SEEN) {
766 error(_("fsmonitor: cookie_result '%d' != SEEN"),
767 cookie_result);
768 do_trivial = 1;
769 }
770 }
771
518a522f
JH
772 if (do_flush)
773 with_lock__do_force_resync(state);
774
775 /*
776 * We mark the current head of the batch list as "pinned" so
777 * that the listener thread will treat this item as read-only
778 * (and prevent any more paths from being added to it) from
779 * now on.
780 */
781 token_data = state->current_token_data;
782 batch_head = token_data->batch_head;
783 ((struct fsmonitor_batch *)batch_head)->pinned_time = time(NULL);
784
785 /*
786 * FSMonitor Protocol V2 requires that we send a response header
787 * with a "new current token" and then all of the paths that changed
788 * since the "requested token". We send the seq_nr of the just-pinned
789 * head batch so that future requests from a client will be relative
790 * to it.
791 */
792 with_lock__format_response_token(&response_token,
793 &token_data->token_id, batch_head);
794
795 reply(reply_data, response_token.buf, response_token.len + 1);
796 total_response_len += response_token.len + 1;
797
798 trace2_data_string("fsmonitor", the_repository, "response/token",
799 response_token.buf);
800 trace_printf_key(&trace_fsmonitor, "response token: %s",
801 response_token.buf);
802
803 if (!do_trivial) {
804 if (strcmp(requested_token_id.buf, token_data->token_id.buf)) {
805 /*
806 * The client last spoke to a different daemon
807 * instance -OR- the daemon had to resync with
808 * the filesystem (and lost events), so reject.
809 */
810 trace2_data_string("fsmonitor", the_repository,
811 "response/token", "different");
812 do_trivial = 1;
813
814 } else if (requested_oldest_seq_nr <
815 token_data->batch_tail->batch_seq_nr) {
816 /*
817 * The client wants older events than we have for
818 * this token_id. This means that the end of our
819 * batch list was truncated and we cannot give the
820 * client a complete snapshot relative to their
821 * request.
822 */
823 trace_printf_key(&trace_fsmonitor,
824 "client requested truncated data");
825 do_trivial = 1;
826 }
827 }
828
829 if (do_trivial) {
830 pthread_mutex_unlock(&state->main_lock);
831
832 reply(reply_data, "/", 2);
833
834 trace2_data_intmax("fsmonitor", the_repository,
835 "response/trivial", 1);
836
837 goto cleanup;
838 }
839
840 /*
841 * We're going to hold onto a pointer to the current
842 * token-data while we walk the list of batches of files.
843 * During this time, we will NOT be under the lock.
844 * So we ref-count it.
845 *
846 * This allows the listener thread to continue prepending
847 * new batches of items to the token-data (which we'll ignore).
848 *
849 * AND it allows the listener thread to do a token-reset
850 * (and install a new `current_token_data`).
851 */
852 token_data->client_ref_count++;
853
854 pthread_mutex_unlock(&state->main_lock);
855
856 /*
857 * The client request is relative to the token that they sent,
858 * so walk the batch list backwards from the current head back
859 * to the batch (sequence number) they named.
860 *
861 * We use khash to de-dup the list of pathnames.
862 *
863 * NEEDSWORK: each batch contains a list of interned strings,
864 * so we only need to do pointer comparisons here to build the
865 * hash table. Currently, we're still comparing the string
866 * values.
867 */
868 shown = kh_init_str();
869 for (batch = batch_head;
870 batch && batch->batch_seq_nr > requested_oldest_seq_nr;
871 batch = batch->next) {
872 size_t k;
873
874 for (k = 0; k < batch->nr; k++) {
875 const char *s = batch->interned_paths[k];
876 size_t s_len;
877
878 if (kh_get_str(shown, s) != kh_end(shown))
879 duplicates++;
880 else {
881 kh_put_str(shown, s, &hash_ret);
882
883 trace_printf_key(&trace_fsmonitor,
884 "send[%"PRIuMAX"]: %s",
885 count, s);
886
887 /* Each path gets written with a trailing NUL */
888 s_len = strlen(s) + 1;
889
890 if (payload.len + s_len >=
891 LARGE_PACKET_DATA_MAX) {
892 reply(reply_data, payload.buf,
893 payload.len);
894 total_response_len += payload.len;
895 strbuf_reset(&payload);
896 }
897
898 strbuf_add(&payload, s, s_len);
899 count++;
900 }
901 }
902 }
903
904 if (payload.len) {
905 reply(reply_data, payload.buf, payload.len);
906 total_response_len += payload.len;
907 }
908
909 kh_release_str(shown);
910
911 pthread_mutex_lock(&state->main_lock);
912
913 if (token_data->client_ref_count > 0)
914 token_data->client_ref_count--;
915
916 if (token_data->client_ref_count == 0) {
917 if (token_data != state->current_token_data) {
918 /*
919 * The listener thread did a token-reset while we were
920 * walking the batch list. Therefore, this token is
921 * stale and can be discarded completely. If we are
922 * the last reader thread using this token, we own
923 * that work.
924 */
925 fsmonitor_free_token_data(token_data);
50c725d6
JH
926 } else if (batch) {
927 /*
928 * We are holding the lock and are the only
929 * reader of the ref-counted portion of the
930 * list, so we get the honor of seeing if the
931 * list can be truncated to save memory.
932 *
933 * The main loop did not walk to the end of the
934 * list, so this batch is the first item in the
935 * batch-list that is older than the requested
936 * end-point sequence number. See if the tail
937 * end of the list is obsolete.
938 */
939 remainder = with_lock__truncate_old_batches(state,
940 batch);
518a522f
JH
941 }
942 }
943
944 pthread_mutex_unlock(&state->main_lock);
945
50c725d6
JH
946 if (remainder)
947 fsmonitor_batch__free_list(remainder);
948
518a522f
JH
949 trace2_data_intmax("fsmonitor", the_repository, "response/length", total_response_len);
950 trace2_data_intmax("fsmonitor", the_repository, "response/count/files", count);
951 trace2_data_intmax("fsmonitor", the_repository, "response/count/duplicates", duplicates);
952
953cleanup:
954 strbuf_release(&response_token);
955 strbuf_release(&requested_token_id);
956 strbuf_release(&payload);
957
958 return 0;
959}
960
9dcba0ba
JH
961static ipc_server_application_cb handle_client;
962
963static int handle_client(void *data,
964 const char *command, size_t command_len,
965 ipc_server_reply_cb *reply,
966 struct ipc_server_reply_data *reply_data)
967{
518a522f 968 struct fsmonitor_daemon_state *state = data;
9dcba0ba
JH
969 int result;
970
971 /*
972 * The Simple IPC API now supports {char*, len} arguments, but
973 * FSMonitor always uses proper null-terminated strings, so
974 * we can ignore the command_len argument. (Trust, but verify.)
975 */
976 if (command_len != strlen(command))
977 BUG("FSMonitor assumes text messages");
978
518a522f
JH
979 trace_printf_key(&trace_fsmonitor, "requested token: %s", command);
980
9dcba0ba
JH
981 trace2_region_enter("fsmonitor", "handle_client", the_repository);
982 trace2_data_string("fsmonitor", the_repository, "request", command);
983
518a522f 984 result = do_handle_client(state, command, reply, reply_data);
9dcba0ba
JH
985
986 trace2_region_leave("fsmonitor", "handle_client", the_repository);
987
988 return result;
989}
990
b05880d3
JH
991#define FSMONITOR_DIR "fsmonitor--daemon"
992#define FSMONITOR_COOKIE_DIR "cookies"
993#define FSMONITOR_COOKIE_PREFIX (FSMONITOR_DIR "/" FSMONITOR_COOKIE_DIR "/")
0ae7a1d9
JH
994
995enum fsmonitor_path_type fsmonitor_classify_path_workdir_relative(
996 const char *rel)
997{
998 if (fspathncmp(rel, ".git", 4))
999 return IS_WORKDIR_PATH;
1000 rel += 4;
1001
1002 if (!*rel)
1003 return IS_DOT_GIT;
1004 if (*rel != '/')
1005 return IS_WORKDIR_PATH; /* e.g. .gitignore */
1006 rel++;
1007
1008 if (!fspathncmp(rel, FSMONITOR_COOKIE_PREFIX,
1009 strlen(FSMONITOR_COOKIE_PREFIX)))
1010 return IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX;
1011
1012 return IS_INSIDE_DOT_GIT;
1013}
1014
1015enum fsmonitor_path_type fsmonitor_classify_path_gitdir_relative(
1016 const char *rel)
1017{
1018 if (!fspathncmp(rel, FSMONITOR_COOKIE_PREFIX,
1019 strlen(FSMONITOR_COOKIE_PREFIX)))
1020 return IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX;
1021
1022 return IS_INSIDE_GITDIR;
1023}
1024
1025static enum fsmonitor_path_type try_classify_workdir_abs_path(
1026 struct fsmonitor_daemon_state *state,
1027 const char *path)
1028{
1029 const char *rel;
1030
1031 if (fspathncmp(path, state->path_worktree_watch.buf,
1032 state->path_worktree_watch.len))
1033 return IS_OUTSIDE_CONE;
1034
1035 rel = path + state->path_worktree_watch.len;
1036
1037 if (!*rel)
1038 return IS_WORKDIR_PATH; /* it is the root dir exactly */
1039 if (*rel != '/')
1040 return IS_OUTSIDE_CONE;
1041 rel++;
1042
1043 return fsmonitor_classify_path_workdir_relative(rel);
1044}
1045
1046enum fsmonitor_path_type fsmonitor_classify_path_absolute(
1047 struct fsmonitor_daemon_state *state,
1048 const char *path)
1049{
1050 const char *rel;
1051 enum fsmonitor_path_type t;
1052
1053 t = try_classify_workdir_abs_path(state, path);
1054 if (state->nr_paths_watching == 1)
1055 return t;
1056 if (t != IS_OUTSIDE_CONE)
1057 return t;
1058
1059 if (fspathncmp(path, state->path_gitdir_watch.buf,
1060 state->path_gitdir_watch.len))
1061 return IS_OUTSIDE_CONE;
1062
1063 rel = path + state->path_gitdir_watch.len;
1064
1065 if (!*rel)
1066 return IS_GITDIR; /* it is the <gitdir> exactly */
1067 if (*rel != '/')
1068 return IS_OUTSIDE_CONE;
1069 rel++;
1070
1071 return fsmonitor_classify_path_gitdir_relative(rel);
1072}
1073
bec486b9
JH
1074/*
1075 * We try to combine small batches at the front of the batch-list to avoid
1076 * having a long list. This hopefully makes it a little easier when we want
1077 * to truncate and maintain the list. However, we don't want the paths array
1078 * to just keep growing and growing with realloc, so we insert an arbitrary
1079 * limit.
1080 */
1081#define MY_COMBINE_LIMIT (1024)
1082
1083void fsmonitor_publish(struct fsmonitor_daemon_state *state,
1084 struct fsmonitor_batch *batch,
1085 const struct string_list *cookie_names)
1086{
1087 if (!batch && !cookie_names->nr)
1088 return;
1089
1090 pthread_mutex_lock(&state->main_lock);
1091
1092 if (batch) {
1093 struct fsmonitor_batch *head;
1094
1095 head = state->current_token_data->batch_head;
1096 if (!head) {
1097 BUG("token does not have batch");
1098 } else if (head->pinned_time) {
1099 /*
1100 * We cannot alter the current batch list
1101 * because:
1102 *
1103 * [a] it is being transmitted to at least one
1104 * client and the handle_client() thread has a
1105 * ref-count, but not a lock on the batch list
1106 * starting with this item.
1107 *
1108 * [b] it has been transmitted in the past to
1109 * at least one client such that future
1110 * requests are relative to this head batch.
1111 *
1112 * So, we can only prepend a new batch onto
1113 * the front of the list.
1114 */
1115 batch->batch_seq_nr = head->batch_seq_nr + 1;
1116 batch->next = head;
1117 state->current_token_data->batch_head = batch;
1118 } else if (!head->batch_seq_nr) {
1119 /*
1120 * Batch 0 is unpinned. See the note in
1121 * `fsmonitor_new_token_data()` about why we
1122 * don't need to accumulate these paths.
1123 */
1124 fsmonitor_batch__free_list(batch);
1125 } else if (head->nr + batch->nr > MY_COMBINE_LIMIT) {
1126 /*
1127 * The head batch in the list has never been
1128 * transmitted to a client, but folding the
1129 * contents of the new batch onto it would
1130 * exceed our arbitrary limit, so just prepend
1131 * the new batch onto the list.
1132 */
1133 batch->batch_seq_nr = head->batch_seq_nr + 1;
1134 batch->next = head;
1135 state->current_token_data->batch_head = batch;
1136 } else {
1137 /*
1138 * We are free to add the paths in the given
1139 * batch onto the end of the current head batch.
1140 */
1141 fsmonitor_batch__combine(head, batch);
1142 fsmonitor_batch__free_list(batch);
1143 }
1144 }
1145
b05880d3
JH
1146 if (cookie_names->nr)
1147 with_lock__mark_cookies_seen(state, cookie_names);
1148
bec486b9
JH
1149 pthread_mutex_unlock(&state->main_lock);
1150}
1151
d0605550
JH
1152static void *fsm_health__thread_proc(void *_state)
1153{
1154 struct fsmonitor_daemon_state *state = _state;
1155
1156 trace2_thread_start("fsm-health");
1157
1158 fsm_health__loop(state);
1159
1160 trace2_thread_exit();
1161 return NULL;
1162}
1163
9dcba0ba
JH
1164static void *fsm_listen__thread_proc(void *_state)
1165{
1166 struct fsmonitor_daemon_state *state = _state;
1167
1168 trace2_thread_start("fsm-listen");
1169
1170 trace_printf_key(&trace_fsmonitor, "Watching: worktree '%s'",
1171 state->path_worktree_watch.buf);
1172 if (state->nr_paths_watching > 1)
1173 trace_printf_key(&trace_fsmonitor, "Watching: gitdir '%s'",
1174 state->path_gitdir_watch.buf);
1175
1176 fsm_listen__loop(state);
1177
bec486b9
JH
1178 pthread_mutex_lock(&state->main_lock);
1179 if (state->current_token_data &&
1180 state->current_token_data->client_ref_count == 0)
1181 fsmonitor_free_token_data(state->current_token_data);
1182 state->current_token_data = NULL;
1183 pthread_mutex_unlock(&state->main_lock);
1184
9dcba0ba
JH
1185 trace2_thread_exit();
1186 return NULL;
1187}
1188
1189static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state)
1190{
1191 struct ipc_server_opts ipc_opts = {
1192 .nr_threads = fsmonitor__ipc_threads,
1193
1194 /*
1195 * We know that there are no other active threads yet,
1196 * so we can let the IPC layer temporarily chdir() if
1197 * it needs to when creating the server side of the
1198 * Unix domain socket.
1199 */
1200 .uds_disallow_chdir = 0
1201 };
d0605550 1202 int health_started = 0;
802aa318
JH
1203 int listener_started = 0;
1204 int err = 0;
9dcba0ba
JH
1205
1206 /*
1207 * Start the IPC thread pool before the we've started the file
1208 * system event listener thread so that we have the IPC handle
1209 * before we need it.
1210 */
1211 if (ipc_server_run_async(&state->ipc_server_data,
39664e93 1212 state->path_ipc.buf, &ipc_opts,
9dcba0ba
JH
1213 handle_client, state))
1214 return error_errno(
1215 _("could not start IPC thread pool on '%s'"),
39664e93 1216 state->path_ipc.buf);
9dcba0ba
JH
1217
1218 /*
1219 * Start the fsmonitor listener thread to collect filesystem
1220 * events.
1221 */
1222 if (pthread_create(&state->listener_thread, NULL,
786e6761 1223 fsm_listen__thread_proc, state)) {
9dcba0ba 1224 ipc_server_stop_async(state->ipc_server_data);
802aa318
JH
1225 err = error(_("could not start fsmonitor listener thread"));
1226 goto cleanup;
9dcba0ba 1227 }
802aa318 1228 listener_started = 1;
9dcba0ba 1229
d0605550
JH
1230 /*
1231 * Start the health thread to watch over our process.
1232 */
1233 if (pthread_create(&state->health_thread, NULL,
786e6761 1234 fsm_health__thread_proc, state)) {
d0605550
JH
1235 ipc_server_stop_async(state->ipc_server_data);
1236 err = error(_("could not start fsmonitor health thread"));
1237 goto cleanup;
1238 }
1239 health_started = 1;
1240
9dcba0ba
JH
1241 /*
1242 * The daemon is now fully functional in background threads.
802aa318
JH
1243 * Our primary thread should now just wait while the threads
1244 * do all the work.
1245 */
1246cleanup:
1247 /*
9dcba0ba 1248 * Wait for the IPC thread pool to shutdown (whether by client
802aa318 1249 * request, from filesystem activity, or an error).
9dcba0ba
JH
1250 */
1251 ipc_server_await(state->ipc_server_data);
1252
1253 /*
1254 * The fsmonitor listener thread may have received a shutdown
1255 * event from the IPC thread pool, but it doesn't hurt to tell
1256 * it again. And wait for it to shutdown.
1257 */
802aa318
JH
1258 if (listener_started) {
1259 fsm_listen__stop_async(state);
1260 pthread_join(state->listener_thread, NULL);
1261 }
9dcba0ba 1262
d0605550
JH
1263 if (health_started) {
1264 fsm_health__stop_async(state);
1265 pthread_join(state->health_thread, NULL);
1266 }
1267
802aa318
JH
1268 if (err)
1269 return err;
207534e4
JH
1270 if (state->listen_error_code)
1271 return state->listen_error_code;
d0605550
JH
1272 if (state->health_error_code)
1273 return state->health_error_code;
802aa318 1274 return 0;
9dcba0ba
JH
1275}
1276
1277static int fsmonitor_run_daemon(void)
1278{
1279 struct fsmonitor_daemon_state state;
39664e93 1280 const char *home;
9dcba0ba
JH
1281 int err;
1282
1283 memset(&state, 0, sizeof(state));
1284
b05880d3 1285 hashmap_init(&state.cookies, cookies_cmp, NULL, 0);
9dcba0ba 1286 pthread_mutex_init(&state.main_lock, NULL);
b05880d3 1287 pthread_cond_init(&state.cookies_cond, NULL);
207534e4 1288 state.listen_error_code = 0;
d0605550 1289 state.health_error_code = 0;
aeef767a 1290 state.current_token_data = fsmonitor_new_token_data();
9dcba0ba
JH
1291
1292 /* Prepare to (recursively) watch the <worktree-root> directory. */
1293 strbuf_init(&state.path_worktree_watch, 0);
1294 strbuf_addstr(&state.path_worktree_watch, absolute_path(get_git_work_tree()));
1295 state.nr_paths_watching = 1;
1296
12fd27df
ED
1297 strbuf_init(&state.alias.alias, 0);
1298 strbuf_init(&state.alias.points_to, 0);
1299 if ((err = fsmonitor__get_alias(state.path_worktree_watch.buf, &state.alias)))
1300 goto done;
1301
9dcba0ba
JH
1302 /*
1303 * We create and delete cookie files somewhere inside the .git
1304 * directory to help us keep sync with the file system. If
1305 * ".git" is not a directory, then <gitdir> is not inside the
1306 * cone of <worktree-root>, so set up a second watch to watch
1307 * the <gitdir> so that we get events for the cookie files.
1308 */
1309 strbuf_init(&state.path_gitdir_watch, 0);
1310 strbuf_addbuf(&state.path_gitdir_watch, &state.path_worktree_watch);
1311 strbuf_addstr(&state.path_gitdir_watch, "/.git");
1312 if (!is_directory(state.path_gitdir_watch.buf)) {
1313 strbuf_reset(&state.path_gitdir_watch);
1314 strbuf_addstr(&state.path_gitdir_watch, absolute_path(get_git_dir()));
1315 state.nr_paths_watching = 2;
1316 }
1317
b05880d3
JH
1318 /*
1319 * We will write filesystem syncing cookie files into
1320 * <gitdir>/<fsmonitor-dir>/<cookie-dir>/<pid>-<seq>.
1321 *
1322 * The extra layers of subdirectories here keep us from
1323 * changing the mtime on ".git/" or ".git/foo/" when we create
1324 * or delete cookie files.
1325 *
1326 * There have been problems with some IDEs that do a
1327 * non-recursive watch of the ".git/" directory and run a
1328 * series of commands any time something happens.
1329 *
1330 * For example, if we place our cookie files directly in
1331 * ".git/" or ".git/foo/" then a `git status` (or similar
1332 * command) from the IDE will cause a cookie file to be
1333 * created in one of those dirs. This causes the mtime of
1334 * those dirs to change. This triggers the IDE's watch
1335 * notification. This triggers the IDE to run those commands
1336 * again. And the process repeats and the machine never goes
1337 * idle.
1338 *
1339 * Adding the extra layers of subdirectories prevents the
1340 * mtime of ".git/" and ".git/foo" from changing when a
1341 * cookie file is created.
1342 */
1343 strbuf_init(&state.path_cookie_prefix, 0);
1344 strbuf_addbuf(&state.path_cookie_prefix, &state.path_gitdir_watch);
1345
1346 strbuf_addch(&state.path_cookie_prefix, '/');
1347 strbuf_addstr(&state.path_cookie_prefix, FSMONITOR_DIR);
1348 mkdir(state.path_cookie_prefix.buf, 0777);
1349
1350 strbuf_addch(&state.path_cookie_prefix, '/');
1351 strbuf_addstr(&state.path_cookie_prefix, FSMONITOR_COOKIE_DIR);
1352 mkdir(state.path_cookie_prefix.buf, 0777);
1353
1354 strbuf_addch(&state.path_cookie_prefix, '/');
1355
39664e93
JH
1356 /*
1357 * We create a named-pipe or unix domain socket inside of the
1358 * ".git" directory. (Well, on Windows, we base our named
1359 * pipe in the NPFS on the absolute path of the git
1360 * directory.)
1361 */
1362 strbuf_init(&state.path_ipc, 0);
6beb2688
ED
1363 strbuf_addstr(&state.path_ipc,
1364 absolute_path(fsmonitor_ipc__get_path(the_repository)));
39664e93 1365
9dcba0ba
JH
1366 /*
1367 * Confirm that we can create platform-specific resources for the
1368 * filesystem listener before we bother starting all the threads.
1369 */
1370 if (fsm_listen__ctor(&state)) {
1371 err = error(_("could not initialize listener thread"));
1372 goto done;
1373 }
1374
d0605550
JH
1375 if (fsm_health__ctor(&state)) {
1376 err = error(_("could not initialize health thread"));
1377 goto done;
1378 }
1379
39664e93
JH
1380 /*
1381 * CD out of the worktree root directory.
1382 *
1383 * The common Git startup mechanism causes our CWD to be the
1384 * root of the worktree. On Windows, this causes our process
1385 * to hold a locked handle on the CWD. This prevents the
1386 * worktree from being moved or deleted while the daemon is
1387 * running.
1388 *
1389 * We assume that our FS and IPC listener threads have either
1390 * opened all of the handles that they need or will do
1391 * everything using absolute paths.
1392 */
1393 home = getenv("HOME");
1394 if (home && *home && chdir(home))
1395 die_errno(_("could not cd home '%s'"), home);
1396
9dcba0ba
JH
1397 err = fsmonitor_run_daemon_1(&state);
1398
1399done:
b05880d3 1400 pthread_cond_destroy(&state.cookies_cond);
9dcba0ba
JH
1401 pthread_mutex_destroy(&state.main_lock);
1402 fsm_listen__dtor(&state);
d0605550 1403 fsm_health__dtor(&state);
9dcba0ba
JH
1404
1405 ipc_server_free(state.ipc_server_data);
1406
1407 strbuf_release(&state.path_worktree_watch);
1408 strbuf_release(&state.path_gitdir_watch);
b05880d3 1409 strbuf_release(&state.path_cookie_prefix);
39664e93 1410 strbuf_release(&state.path_ipc);
12fd27df
ED
1411 strbuf_release(&state.alias.alias);
1412 strbuf_release(&state.alias.points_to);
9dcba0ba
JH
1413
1414 return err;
1415}
1416
f4c5778b 1417static int try_to_run_foreground_daemon(int detach_console MAYBE_UNUSED)
9dcba0ba
JH
1418{
1419 /*
1420 * Technically, we don't need to probe for an existing daemon
1421 * process, since we could just call `fsmonitor_run_daemon()`
1422 * and let it fail if the pipe/socket is busy.
1423 *
1424 * However, this method gives us a nicer error message for a
1425 * common error case.
1426 */
1427 if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
1428 die(_("fsmonitor--daemon is already running '%s'"),
1429 the_repository->worktree);
1430
1431 if (fsmonitor__announce_startup) {
1432 fprintf(stderr, _("running fsmonitor-daemon in '%s'\n"),
1433 the_repository->worktree);
1434 fflush(stderr);
1435 }
1436
c284e27b
JH
1437#ifdef GIT_WINDOWS_NATIVE
1438 if (detach_console)
1439 FreeConsole();
1440#endif
1441
9dcba0ba
JH
1442 return !!fsmonitor_run_daemon();
1443}
1444
c284e27b
JH
1445static start_bg_wait_cb bg_wait_cb;
1446
72da9832
JK
1447static int bg_wait_cb(const struct child_process *cp UNUSED,
1448 void *cb_data UNUSED)
c284e27b
JH
1449{
1450 enum ipc_active_state s = fsmonitor_ipc__get_state();
1451
1452 switch (s) {
1453 case IPC_STATE__LISTENING:
1454 /* child is "ready" */
1455 return 0;
1456
1457 case IPC_STATE__NOT_LISTENING:
1458 case IPC_STATE__PATH_NOT_FOUND:
1459 /* give child more time */
1460 return 1;
1461
1462 default:
1463 case IPC_STATE__INVALID_PATH:
1464 case IPC_STATE__OTHER_ERROR:
1465 /* all the time in world won't help */
1466 return -1;
1467 }
1468}
1469
1470static int try_to_start_background_daemon(void)
1471{
1472 struct child_process cp = CHILD_PROCESS_INIT;
1473 enum start_bg_result sbgr;
1474
1475 /*
1476 * Before we try to create a background daemon process, see
1477 * if a daemon process is already listening. This makes it
1478 * easier for us to report an already-listening error to the
1479 * console, since our spawn/daemon can only report the success
1480 * of creating the background process (and not whether it
1481 * immediately exited).
1482 */
1483 if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
1484 die(_("fsmonitor--daemon is already running '%s'"),
1485 the_repository->worktree);
1486
1487 if (fsmonitor__announce_startup) {
1488 fprintf(stderr, _("starting fsmonitor-daemon in '%s'\n"),
1489 the_repository->worktree);
1490 fflush(stderr);
1491 }
1492
1493 cp.git_cmd = 1;
1494
1495 strvec_push(&cp.args, "fsmonitor--daemon");
1496 strvec_push(&cp.args, "run");
1497 strvec_push(&cp.args, "--detach");
1498 strvec_pushf(&cp.args, "--ipc-threads=%d", fsmonitor__ipc_threads);
1499
1500 cp.no_stdin = 1;
1501 cp.no_stdout = 1;
1502 cp.no_stderr = 1;
1503
1504 sbgr = start_bg_command(&cp, bg_wait_cb, NULL,
1505 fsmonitor__start_timeout_sec);
1506
1507 switch (sbgr) {
1508 case SBGR_READY:
1509 return 0;
1510
1511 default:
1512 case SBGR_ERROR:
1513 case SBGR_CB_ERROR:
1514 return error(_("daemon failed to start"));
1515
1516 case SBGR_TIMEOUT:
1517 return error(_("daemon not online yet"));
1518
1519 case SBGR_DIED:
1520 return error(_("daemon terminated"));
1521 }
1522}
1523
16d9d617
JH
1524int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix)
1525{
1526 const char *subcmd;
62a62a28 1527 enum fsmonitor_reason reason;
c284e27b 1528 int detach_console = 0;
16d9d617
JH
1529
1530 struct option options[] = {
c284e27b 1531 OPT_BOOL(0, "detach", &detach_console, N_("detach from console")),
9dcba0ba
JH
1532 OPT_INTEGER(0, "ipc-threads",
1533 &fsmonitor__ipc_threads,
1534 N_("use <n> ipc worker threads")),
c284e27b
JH
1535 OPT_INTEGER(0, "start-timeout",
1536 &fsmonitor__start_timeout_sec,
1537 N_("max seconds to wait for background daemon startup")),
1538
16d9d617
JH
1539 OPT_END()
1540 };
1541
9dcba0ba 1542 git_config(fsmonitor_config, NULL);
16d9d617
JH
1543
1544 argc = parse_options(argc, argv, prefix, options,
1545 builtin_fsmonitor__daemon_usage, 0);
1546 if (argc != 1)
1547 usage_with_options(builtin_fsmonitor__daemon_usage, options);
1548 subcmd = argv[0];
1549
9dcba0ba
JH
1550 if (fsmonitor__ipc_threads < 1)
1551 die(_("invalid 'ipc-threads' value (%d)"),
1552 fsmonitor__ipc_threads);
1553
62a62a28
JH
1554 prepare_repo_settings(the_repository);
1555 /*
1556 * If the repo is fsmonitor-compatible, explicitly set IPC-mode
1557 * (without bothering to load the `core.fsmonitor` config settings).
1558 *
1559 * If the repo is not compatible, the repo-settings will be set to
1560 * incompatible rather than IPC, so we can use one of the __get
1561 * routines to detect the discrepancy.
1562 */
1563 fsm_settings__set_ipc(the_repository);
1564
1565 reason = fsm_settings__get_reason(the_repository);
1566 if (reason > FSMONITOR_REASON_OK)
1567 die("%s",
1568 fsm_settings__get_incompatible_msg(the_repository,
1569 reason));
1570
c284e27b
JH
1571 if (!strcmp(subcmd, "start"))
1572 return !!try_to_start_background_daemon();
1573
9dcba0ba 1574 if (!strcmp(subcmd, "run"))
c284e27b 1575 return !!try_to_run_foreground_daemon(detach_console);
9dcba0ba 1576
abc9dbc0
JH
1577 if (!strcmp(subcmd, "stop"))
1578 return !!do_as_client__send_stop();
1579
1580 if (!strcmp(subcmd, "status"))
1581 return !!do_as_client__status();
1582
16d9d617
JH
1583 die(_("Unhandled subcommand '%s'"), subcmd);
1584}
1585
1586#else
5247b762 1587int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED)
16d9d617
JH
1588{
1589 struct option options[] = {
1590 OPT_END()
1591 };
1592
1593 if (argc == 2 && !strcmp(argv[1], "-h"))
1594 usage_with_options(builtin_fsmonitor__daemon_usage, options);
1595
1596 die(_("fsmonitor--daemon not supported on this platform"));
1597}
1598#endif