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