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